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;
 
 	/*