--- /dev/null
+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;
+
+ /*