diff --git a/net/p910nd/Makefile b/net/p910nd/Makefile index f96edb6f3..b4aeebeea 100644 --- a/net/p910nd/Makefile +++ b/net/p910nd/Makefile @@ -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 index 000000000..19d99cfa4 --- /dev/null +++ b/net/p910nd/patches/001-ipv6_support.patch @@ -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; + + /*