-diff --git a/p910nd.c b/p910nd.c
-index e32cca5..4395128 100644
---- a/p910nd.c
-+++ b/p910nd.c
-@@ -16,6 +16,9 @@
- * Port 9100+n will then be passively opened
- * n defaults to 0
- *
-+ * Version 0.94
-+ * Support IPv6
-+ *
- * Version 0.93
- * Fix open call to include mode, required for O_CREAT
- *
-@@ -141,6 +144,40 @@ static char *device = 0;
- static int bidir = 0;
- static char *bindaddr = 0;
-
-+
-+/* Helper function: convert a struct sockaddr address (IPv4 and IPv6) to a string */
-+char *get_ip_str(const struct sockaddr *sa, char *s, size_t maxlen)
-+{
-+ switch(sa->sa_family) {
-+ case AF_INET:
-+ inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), s, maxlen);
-+ break;
-+ case AF_INET6:
-+ inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), s, maxlen);
-+ break;
-+ default:
-+ strncpy(s, "Unknown AF", maxlen);
-+ return NULL;
-+ }
-+ return s;
-+}
-+
-+uint16_t get_port(const struct sockaddr *sa)
-+{
-+ uint16_t port;
-+ switch(sa->sa_family) {
-+ case AF_INET:
-+ port = ntohs(((struct sockaddr_in *)sa)->sin_port);
-+ break;
-+ case AF_INET6:
-+ port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
-+ break;
-+ default:
-+ return 0;
-+ }
-+ return port;
-+}
-+
- void usage(void)
- {
- fprintf(stderr, "%s %s %s\n", progname, version, copyright);
-@@ -399,11 +436,13 @@ int copy_stream(int fd, int lp)
- void one_job(int lpnumber)
- {
- int lp;
-- struct sockaddr_in client;
-+ struct sockaddr_storage client;
- socklen_t clientlen = sizeof(client);
-
-- if (getpeername(0, (struct sockaddr *)&client, &clientlen) >= 0)
-- syslog(LOG_NOTICE, "Connection from %s port %hu\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
-+ if (getpeername(0, (struct sockaddr *)&client, &clientlen) >= 0) {
-+ char host[INET6_ADDRSTRLEN];
-+ syslog(LOG_NOTICE, "Connection from %s port %hu\n", get_ip_str((struct sockaddr *)&client, host, sizeof(host)), get_port((struct sockaddr *)&client));
-+ }
- if (get_lock(lpnumber) == 0)
- return;
- /* Make sure lp device is open... */
-@@ -423,10 +462,11 @@ void server(int lpnumber)
- #endif
- int netfd, fd, lp, one = 1;
- socklen_t clientlen;
-- struct sockaddr_in netaddr, client;
-+ struct sockaddr_storage client;
-+ struct addrinfo hints, *res, *ressave;
- char pidfilename[sizeof(PIDFILE)];
-+ char service[sizeof(BASEPORT+lpnumber-'0')+1];
- FILE *f;
-- int ipret;
-
- #ifndef TESTING
- switch (fork()) {
-@@ -465,47 +505,55 @@ void server(int lpnumber)
- if (get_lock(lpnumber) == 0)
- exit(1);
- #endif
--#ifdef USE_GETPROTOBYNAME
-- if ((proto = getprotobyname("tcp")) == NULL) {
-- syslog(LOGOPTS, "Cannot find protocol for TCP!\n");
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_flags = AI_PASSIVE;
-+ hints.ai_socktype = SOCK_STREAM;
-+ (void)snprintf(service, sizeof(service), "%hu", (BASEPORT + lpnumber - '0'));
-+ if (getaddrinfo(bindaddr, service, &hints, &res) != 0) {
-+ syslog(LOGOPTS, "getaddr: %m\n");
- exit(1);
- }
-- if ((netfd = socket(AF_INET, SOCK_STREAM, proto->p_proto)) < 0)
-+ ressave = res;
-+ while (res) {
-+#ifdef USE_GETPROTOBYNAME
-+ if ((proto = getprotobyname("tcp6")) == NULL) {
-+ if ((proto = getprotobyname("tcp")) == NULL) {
-+ syslog(LOGOPTS, "Cannot find protocol for TCP!\n");
-+ exit(1);
-+ }
-+ }
-+ if ((netfd = socket(res->ai_family, res->ai_socktype, proto->p_proto)) < 0)
- #else
-- if ((netfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)
-+ if ((netfd = socket(res->ai_family, res->ai_socktype, IPPROTO_IP)) < 0)
- #endif
-- {
-- syslog(LOGOPTS, "socket: %m\n");
-- exit(1);
-- }
-- if (setsockopt(netfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))
-- < 0) {
-- syslog(LOGOPTS, "setsocketopt: %m\n");
-- exit(1);
-- }
-- netaddr.sin_family = AF_INET;
-- netaddr.sin_port = htons(BASEPORT + lpnumber - '0');
-- if (bindaddr == 0) {
-- netaddr.sin_addr.s_addr = htonl(INADDR_ANY);
-- } else {
-- ipret = inet_pton(AF_INET, bindaddr, &netaddr.sin_addr.s_addr);
-- if (ipret < 0) {
-- syslog(LOGOPTS, "inet_pton: %m\n");
-- exit(1);
-- } else if (ipret == 0) {
-- syslog(LOGOPTS, "inet_pton: invalid bind IP address\n");
-- exit(1);
-+ {
-+ syslog(LOGOPTS, "socket: %m\n");
-+ close(netfd);
-+ res = res->ai_next;
-+ continue;
- }
-+ if (setsockopt(netfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
-+ syslog(LOGOPTS, "setsocketopt: %m\n");
-+ close(netfd);
-+ res = res->ai_next;
-+ continue;
-+ }
-+ if (bind(netfd, res->ai_addr, res->ai_addrlen) < 0) {
-+ syslog(LOGOPTS, "bind: %m\n");
-+ close(netfd);
-+ res = res->ai_next;
-+ continue;
-+ }
-+ if (listen(netfd, 5) < 0) {
-+ syslog(LOGOPTS, "listen: %m\n");
-+ close(netfd);
-+ res = res->ai_next;
-+ continue;
-+ }
-+ break;
- }
-- memset(netaddr.sin_zero, 0, sizeof(netaddr.sin_zero));
-- if (bind(netfd, (struct sockaddr *)&netaddr, sizeof(netaddr)) < 0) {
-- syslog(LOGOPTS, "bind: %m\n");
-- exit(1);
-- }
-- if (listen(netfd, 5) < 0) {
-- syslog(LOGOPTS, "listen: %m\n");
-- exit(1);
-- }
-+ freeaddrinfo(ressave);
- clientlen = sizeof(client);
- memset(&client, 0, sizeof(client));
- while ((fd = accept(netfd, (struct sockaddr *)&client, &clientlen)) >= 0) {
-@@ -517,7 +565,8 @@ void server(int lpnumber)
- continue;
- }
- #endif
-- syslog(LOG_NOTICE, "Connection from %s port %hu accepted\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
-+ char host[INET6_ADDRSTRLEN];
-+ syslog(LOG_NOTICE, "Connection from %s port %hu accepted\n", get_ip_str((struct sockaddr *)&client, host, sizeof(host)), get_port((struct sockaddr *)&client));
- /*write(fd, "Printing", 8); */
-
- /* Make sure lp device is open... */
-@@ -536,7 +585,7 @@ void server(int lpnumber)
-
- int is_standalone(void)
- {
-- struct sockaddr_in bind_addr;
-+ struct sockaddr_storage bind_addr;
- socklen_t ba_len;
-
- /*