[package] p910nd: add IPv6 support (#7646)
authorFlorian Fainelli <florian@openwrt.org>
Sat, 31 Jul 2010 11:39:16 +0000 (11:39 +0000)
committerFlorian Fainelli <florian@openwrt.org>
Sat, 31 Jul 2010 11:39:16 +0000 (11:39 +0000)
SVN-Revision: 22432

net/p910nd/Makefile
net/p910nd/patches/001-ipv6_support.patch [new file with mode: 0644]

index f96edb6..b4aeebe 100644 (file)
@@ -1,5 +1,5 @@
 # 
-# Copyright (C) 2009 OpenWrt.org
+# Copyright (C) 2009-2010 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=p910nd
 PKG_VERSION:=0.93
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=@SF/p910nd
diff --git a/net/p910nd/patches/001-ipv6_support.patch b/net/p910nd/patches/001-ipv6_support.patch
new file mode 100644 (file)
index 0000000..19d99cf
--- /dev/null
@@ -0,0 +1,196 @@
+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;
+       /*