From c3173ff6428433b885c95fe1b6a6b57eb218d4b9 Mon Sep 17 00:00:00 2001 From: Fedor Kozhevnikov Date: Sun, 19 Jun 2011 11:53:52 -0400 Subject: [PATCH] Miniupnpd v. 1.5 (20110618) Conflicts: release/src/router/miniupnpd/genconfig.sh release/src/router/miniupnpd/upnpredirect.c release/src/router/miniupnpd/upnpsoap.c --- release/src/router/miniupnpd/Changelog.txt | 17 ++- release/src/router/miniupnpd/bsd/ifacewatcher.c | 4 +- release/src/router/miniupnpd/commonrdr.h | 3 +- release/src/router/miniupnpd/genconfig.sh | 12 +- release/src/router/miniupnpd/ipfw/ipfwrdr.c | 29 +++-- release/src/router/miniupnpd/ipfw/ipfwrdr.h | 4 +- release/src/router/miniupnpd/ipfw/testipfwrdr.c | 54 ++++++++- release/src/router/miniupnpd/natpmp.c | 10 +- release/src/router/miniupnpd/netfilter/iptcrdr.c | 63 ++++++++-- release/src/router/miniupnpd/netfilter/iptcrdr.h | 19 ++- release/src/router/miniupnpd/pf/obsdrdr.c | 36 +++++- release/src/router/miniupnpd/pf/obsdrdr.h | 12 +- release/src/router/miniupnpd/pf/testobsdrdr.c | 17 ++- release/src/router/miniupnpd/upnpevents.c | 4 +- release/src/router/miniupnpd/upnphttp.c | 3 +- release/src/router/miniupnpd/upnpredirect.c | 147 +++++++++-------------- release/src/router/miniupnpd/upnpredirect.h | 10 +- release/src/router/miniupnpd/upnpsoap.c | 63 ++++++---- 18 files changed, 328 insertions(+), 179 deletions(-) diff --git a/release/src/router/miniupnpd/Changelog.txt b/release/src/router/miniupnpd/Changelog.txt index 578d5b1fc1..ba9d7bc857 100644 --- a/release/src/router/miniupnpd/Changelog.txt +++ b/release/src/router/miniupnpd/Changelog.txt @@ -1,7 +1,22 @@ -$Id: Changelog.txt,v 1.229 2011/05/28 09:05:49 nanard Exp $ +$Id: Changelog.txt,v 1.233 2011/06/17 22:51:50 nanard Exp $ + +2011/06/18: + Remote host support for pf version + +2011/06/04: + Supporting RemoteHost (mandatory in IGD v2) + +2011/06/03: + Enabling events by default + +2011/06/01: + Fixing Timeout missing in SUBSCRIBE renewal responses + (thanks to Pranesh Kulkarni) + Added comments about changes between IGD v1 and IGD v2 2011/05/28: Description and leaseduration kept in ipfw version of the code. + Fixing ipfw code after testing under Mac OS X 10.6.7 (darwin 10.7.0) 2011/05/27: Finishing and testing LeaseDuration support under OpenBSD. diff --git a/release/src/router/miniupnpd/bsd/ifacewatcher.c b/release/src/router/miniupnpd/bsd/ifacewatcher.c index 61f2d013ad..aa5af0081c 100644 --- a/release/src/router/miniupnpd/bsd/ifacewatcher.c +++ b/release/src/router/miniupnpd/bsd/ifacewatcher.c @@ -1,4 +1,4 @@ -/* $Id: ifacewatcher.c,v 1.2 2011/05/20 09:57:44 nanard Exp $ */ +/* $Id: ifacewatcher.c,v 1.3 2011/06/04 16:19:51 nanard Exp $ */ /* Project MiniUPnP * web : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2011 Thomas BERNARD @@ -68,7 +68,7 @@ ProcessInterfaceWatchNotify(int s) ext_if_name_index = if_nametoindex(ext_if_name); } rtm = (struct rt_msghdr *)buf; - syslog(LOG_DEBUG, "%u rt_msg : msglen=%d version=%d type=%d", len, + syslog(LOG_DEBUG, "%u rt_msg : msglen=%d version=%d type=%d", (unsigned)len, rtm->rtm_msglen, rtm->rtm_version, rtm->rtm_type); switch(rtm->rtm_type) { case RTM_IFINFO: /* iface going up/down etc. */ diff --git a/release/src/router/miniupnpd/commonrdr.h b/release/src/router/miniupnpd/commonrdr.h index 22e0e5d375..5a13d41b56 100644 --- a/release/src/router/miniupnpd/commonrdr.h +++ b/release/src/router/miniupnpd/commonrdr.h @@ -1,4 +1,4 @@ -/* $Id: commonrdr.h,v 1.5 2011/05/26 21:17:15 nanard Exp $ */ +/* $Id: commonrdr.h,v 1.6 2011/06/04 08:58:12 nanard Exp $ */ /* MiniUPnP project * (c) 2006-2011 Thomas Bernard * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ @@ -30,6 +30,7 @@ get_redirect_rule_by_index(int index, char * ifname, unsigned short * eport, char * iaddr, int iaddrlen, unsigned short * iport, int * proto, char * desc, int desclen, + char * rhost, int rhostlen, unsigned int * timestamp, u_int64_t * packets, u_int64_t * bytes); diff --git a/release/src/router/miniupnpd/genconfig.sh b/release/src/router/miniupnpd/genconfig.sh index 50a9b14dac..a182bc4c72 100755 --- a/release/src/router/miniupnpd/genconfig.sh +++ b/release/src/router/miniupnpd/genconfig.sh @@ -1,5 +1,5 @@ #! /bin/sh -# $Id: genconfig.sh,v 1.47 2011/05/20 09:33:06 nanard Exp $ +# $Id: genconfig.sh,v 1.49 2011/06/04 16:20:31 nanard Exp $ # miniupnp daemon # http://miniupnp.free.fr or http://miniupnp.tuxfamily.org/ # (c) 2006-2011 Thomas Bernard @@ -240,6 +240,13 @@ esac echo "Configuring compilation for [$OS_NAME] [$OS_VERSION] with [$FW] firewall software." echo "Please edit config.h for more compilation options." +# define SUPPORT_REMOTEHOST if the FW related code really supports setting +# a RemoteHost +if [ "$FW" = "netfilter" ] ; then + echo "#define SUPPORT_REMOTEHOST" >> ${CONFIGFILE} +fi + +echo "" >> ${CONFIGFILE} echo "#define OS_NAME \"$OS_NAME\"" >> ${CONFIGFILE} echo "#define OS_VERSION \"$OS_NAME/$OS_VERSION\"" >> ${CONFIGFILE} echo "#define OS_URL \"${OS_URL}\"" >> ${CONFIGFILE} @@ -313,7 +320,8 @@ echo "#endif /* ENABLE_IPV6 */" >> ${CONFIGFILE} echo "#endif /* IGD_V2 */" >> ${CONFIGFILE} echo "" >> ${CONFIGFILE} -echo "/* Experimental UPnP Events support. */" >> ${CONFIGFILE} +echo "/* UPnP Events support. Working well enough to be enabled by default." >> ${CONFIGFILE} +echo " * It can be disabled to save a few bytes. */" >> ${CONFIGFILE} echo "#define ENABLE_EVENTS" >> ${CONFIGFILE} echo "" >> ${CONFIGFILE} diff --git a/release/src/router/miniupnpd/ipfw/ipfwrdr.c b/release/src/router/miniupnpd/ipfw/ipfwrdr.c index a110793f6b..bef22ed62f 100644 --- a/release/src/router/miniupnpd/ipfw/ipfwrdr.c +++ b/release/src/router/miniupnpd/ipfw/ipfwrdr.c @@ -1,4 +1,4 @@ -/* $Id: ipfwrdr.c,v 1.7 2011/05/28 09:29:08 nanard Exp $ */ +/* $Id: ipfwrdr.c,v 1.9 2011/06/04 15:47:18 nanard Exp $ */ /* * MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ @@ -72,8 +72,7 @@ struct file; /* init and shutdown functions */ int init_redirect(void) { - ipfw_exec(IP_FW_INIT, NULL, 0); - return 0; + return ipfw_exec(IP_FW_INIT, NULL, 0); } void shutdown_redirect(void) { @@ -156,6 +155,7 @@ get_desc_time(unsigned short eport, int proto, /* --- */ int add_redirect_rule2( const char * ifname, + const char * rhost, unsigned short eport, const char * iaddr, unsigned short iport, @@ -196,6 +196,7 @@ int add_redirect_rule2( IP_FW_SETNDSTP(&rule, 1); // number of external ports rule.fw_uar.fw_pts[0] = eport; // external port rule.fw_fwd_ip.sin_port = iport; // internal port + /* TODO : use rhost ! */ r = ipfw_exec(IP_FW_ADD, &rule, sizeof(rule)); if(r >= 0) @@ -245,7 +246,9 @@ int get_redirect_rule( if (iport != NULL) *iport = ptr->fw_fwd_ip.sin_port; if (iaddr != NULL && iaddrlen > 0) { - if (inet_ntop(AF_INET, &ptr->fw_out_if.fu_via_ip, iaddr, iaddrlen) == NULL) { + /* looks like fw_out_if.fu_via_ip is zero */ + //if (inet_ntop(AF_INET, &ptr->fw_out_if.fu_via_ip, iaddr, iaddrlen) == NULL) { + if (inet_ntop(AF_INET, &ptr->fw_fwd_ip.sin_addr, iaddr, iaddrlen) == NULL) { syslog(LOG_ERR, "inet_ntop(): %m"); goto error; } @@ -302,13 +305,15 @@ error: int add_filter_rule2( const char * ifname, + const char * rhost, const char * iaddr, unsigned short eport, unsigned short iport, int proto, const char * desc) { - return -1; + //return -1; + return 0; /* nothing to do, always success */ } int delete_filter_rule( @@ -316,7 +321,8 @@ int delete_filter_rule( unsigned short eport, int proto) { - return -1; + //return -1; + return 0; /* nothing to do, always success */ } int get_redirect_rule_by_index( @@ -329,6 +335,8 @@ int get_redirect_rule_by_index( int * proto, char * desc, int desclen, + char * rhost, + int rhostlen, unsigned int * timestamp, u_int64_t * packets, u_int64_t * bytes) @@ -344,8 +352,10 @@ int get_redirect_rule_by_index( ipfw_fetch_ruleset(&rules, &total_rules, index + 1); - if (total_rules == index + 1) { + if (total_rules > index) { const struct ip_fw const * ptr = &rules[index]; + if (ptr->fw_prot == 0) // invalid rule + goto error; if (proto != NULL) *proto = ptr->fw_prot; if (eport != NULL) @@ -361,11 +371,14 @@ int get_redirect_rule_by_index( if (iport != NULL) *iport = ptr->fw_fwd_ip.sin_port; if (iaddr != NULL && iaddrlen > 0) { - if (inet_ntop(AF_INET, &ptr->fw_out_if.fu_via_ip, iaddr, iaddrlen) == NULL) { + /* looks like fw_out_if.fu_via_ip is zero */ + //if (inet_ntop(AF_INET, &ptr->fw_out_if.fu_via_ip, iaddr, iaddrlen) == NULL) { + if (inet_ntop(AF_INET, &ptr->fw_fwd_ip.sin_addr, iaddr, iaddrlen) == NULL) { syslog(LOG_ERR, "inet_ntop(): %m"); goto error; } } + /* TODO : get rhost */ ipfw_free_ruleset(&rules); get_desc_time(*eport, *proto, desc, desclen, timestamp); return 0; diff --git a/release/src/router/miniupnpd/ipfw/ipfwrdr.h b/release/src/router/miniupnpd/ipfw/ipfwrdr.h index 2478d21089..cdadbfe220 100644 --- a/release/src/router/miniupnpd/ipfw/ipfwrdr.h +++ b/release/src/router/miniupnpd/ipfw/ipfwrdr.h @@ -1,4 +1,4 @@ -/* $Id: ipfwrdr.h,v 1.4 2011/05/26 22:47:59 nanard Exp $ */ +/* $Id: ipfwrdr.h,v 1.5 2011/06/04 15:47:18 nanard Exp $ */ /* * MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ @@ -14,6 +14,7 @@ int add_redirect_rule2( const char * ifname, // src interface (external) + const char * rhost, // remote host (ip) unsigned short eport, // src port (external) const char * iaddr, // dst address (internal) unsigned short iport, // dst port (internal) @@ -23,6 +24,7 @@ int add_redirect_rule2( int add_filter_rule2( const char * ifname, + const char * rhost, const char * iaddr, unsigned short eport, unsigned short iport, diff --git a/release/src/router/miniupnpd/ipfw/testipfwrdr.c b/release/src/router/miniupnpd/ipfw/testipfwrdr.c index ab98592fcd..4eb67e5297 100644 --- a/release/src/router/miniupnpd/ipfw/testipfwrdr.c +++ b/release/src/router/miniupnpd/ipfw/testipfwrdr.c @@ -1,4 +1,4 @@ -/* $Id: testipfwrdr.c,v 1.4 2011/05/28 09:29:08 nanard Exp $ */ +/* $Id: testipfwrdr.c,v 1.6 2011/06/04 15:47:18 nanard Exp $ */ /* * MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ @@ -14,22 +14,66 @@ #include "ipfwrdr.h" // test program for ipfwrdr.c +static const char * ifname = "lo0"; + +static void +list_port_mappings(void) +{ + int i; + unsigned short eport; + char iaddr[16]; + unsigned short iport; + int proto; + char desc[64]; + char rhost[32]; + unsigned int timestamp; + u_int64_t packets, bytes; + + printf("== Port Mapping List ==\n"); + for(i = 0;; i++) { + iaddr[0] = '\0'; + desc[0] = '\0'; + eport = iport = 0; + timestamp = 0; + packets = bytes = 0; + proto = -1; + if(get_redirect_rule_by_index(i, 0/*ifname*/, &eport, iaddr, sizeof(iaddr), + &iport, &proto, desc, sizeof(desc), + rhost, sizeof(rhost), + ×tamp, &packets, &bytes) < 0) + break; + printf("%2d - %5hu=>%15s:%5hu %d '%s' %u %" PRIu64 " %" PRIu64 "\n", + i, eport, iaddr, iport, proto, desc, timestamp, + packets, bytes); + } + printf("== %d Port Mapping%s ==\n", i, (i > 1)?"s":""); +} int main(int argc, char * * argv) { unsigned int timestamp; char desc[64]; char addr[16]; unsigned short iport = 0; + const char * rhost = "8.8.8.8"; desc[0] = '\0'; addr[0] = '\0'; openlog("testipfwrdrd", LOG_CONS | LOG_PERROR, LOG_USER); - init_redirect(); - delete_redirect_rule("lo", 2222, IPPROTO_TCP); - add_redirect_rule2("lo", 2222, "10.1.1.16", 4444, IPPROTO_TCP, "miniupnpd", time(NULL) + 60); - get_redirect_rule("lo", 2222, IPPROTO_TCP, addr, sizeof(addr), &iport, + if(init_redirect() < 0) { + fprintf(stderr, "init_redirect() failed.\n"); + return 1; + } + list_port_mappings(); + delete_redirect_rule(ifname, 2222, IPPROTO_TCP); + add_redirect_rule2(ifname, rhost, 2222, + "10.1.1.16", 4444, IPPROTO_TCP, + "test miniupnpd", time(NULL) + 60); + get_redirect_rule(ifname, 2222, IPPROTO_TCP, addr, sizeof(addr), &iport, desc, sizeof(desc), ×tamp, NULL, NULL); printf("%s:%hu '%s' %u\n", addr, iport, desc, timestamp); + list_port_mappings(); + delete_redirect_rule(ifname, 2222, IPPROTO_TCP); + list_port_mappings(); shutdown_redirect(); return 0; } diff --git a/release/src/router/miniupnpd/natpmp.c b/release/src/router/miniupnpd/natpmp.c index b23a088c34..70636386fc 100644 --- a/release/src/router/miniupnpd/natpmp.c +++ b/release/src/router/miniupnpd/natpmp.c @@ -1,4 +1,4 @@ -/* $Id: natpmp.c,v 1.23 2011/05/27 21:36:22 nanard Exp $ */ +/* $Id: natpmp.c,v 1.24 2011/06/04 08:58:12 nanard Exp $ */ /* MiniUPnP project * (c) 2007-2010 Thomas Bernard * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ @@ -189,7 +189,8 @@ void ProcessIncomingNATPMPPacket(int s) while(get_redirect_rule_by_index(index, 0, &eport2, iaddr2, sizeof(iaddr2), &iport2, &proto2, - desc, sizeof(desc), ×tamp, 0, 0) >= 0) { + desc, sizeof(desc), + 0, 0, ×tamp, 0, 0) >= 0) { syslog(LOG_DEBUG, "%d %d %hu->'%s':%hu '%s'", index, proto2, eport2, iaddr2, iport2, desc); if(0 == strcmp(iaddr2, senderaddrstr) @@ -252,10 +253,11 @@ void ProcessIncomingNATPMPPacket(int s) snprintf(desc, sizeof(desc), "NAT-PMP %u", timestamp); #else timestamp = time(NULL) + lifetime; - snprintf(desc, sizeof(desc), "NAT-PMP"); + snprintf(desc, sizeof(desc), "NAT-PMP %hu %s", + eport, (proto==IPPROTO_TCP)?"tcp":"udp"); #endif /* TODO : check return code */ - if(upnp_redirect_internal(eport, senderaddrstr, + if(upnp_redirect_internal(NULL, eport, senderaddrstr, iport, proto, desc, timestamp) < 0) { syslog(LOG_ERR, "Failed to add NAT-PMP %hu %s->%s:%hu '%s'", diff --git a/release/src/router/miniupnpd/netfilter/iptcrdr.c b/release/src/router/miniupnpd/netfilter/iptcrdr.c index a5cad47c8b..7cbbcf5f8a 100644 --- a/release/src/router/miniupnpd/netfilter/iptcrdr.c +++ b/release/src/router/miniupnpd/netfilter/iptcrdr.c @@ -1,4 +1,4 @@ -/* $Id: iptcrdr.c,v 1.42 2011/05/28 09:05:50 nanard Exp $ */ +/* $Id: iptcrdr.c,v 1.43 2011/06/04 08:57:41 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2011 Thomas Bernard @@ -46,6 +46,16 @@ #include "iptcrdr.h" #include "../upnpglobalvars.h" +/* local functions declarations */ +static int +addnatrule(int proto, unsigned short eport, + const char * iaddr, unsigned short iport, + const char * rhost); + +static int +add_filter_rule(int proto, const char * rhost, + const char * iaddr, unsigned short iport); + /* dummy init and shutdown functions */ int init_redirect(void) { @@ -176,22 +186,24 @@ get_redirect_desc_by_index(int index, unsigned short * eport, int * proto, /* add_redirect_rule2() */ int -add_redirect_rule2(const char * ifname, unsigned short eport, +add_redirect_rule2(const char * ifname, + const char * rhost, unsigned short eport, const char * iaddr, unsigned short iport, int proto, const char * desc, unsigned int timestamp) { - int r = addnatrule(proto, eport, iaddr, iport); + int r = addnatrule(proto, eport, iaddr, iport, rhost); if(r >= 0) add_redirect_desc(eport, proto, desc, timestamp); return r; } int -add_filter_rule2(const char * ifname, const char * iaddr, +add_filter_rule2(const char * ifname, + const char * rhost, const char * iaddr, unsigned short eport, unsigned short iport, int proto, const char * desc) { - return add_filter_rule(proto, iaddr, iport); + return add_filter_rule(proto, rhost, iaddr, iport); } /* get_redirect_rule() @@ -255,13 +267,17 @@ get_redirect_rule(const char * ifname, unsigned short eport, int proto, mr = (const struct ip_nat_multi_range *)&target->data[0]; snprintip(iaddr, iaddrlen, ntohl(mr->range[0].min_ip)); *iport = ntohs(mr->range[0].min.all); - /*if(desc) - strncpy(desc, "miniupnpd", desclen);*/ get_redirect_desc(eport, proto, desc, desclen, timestamp); if(packets) *packets = e->counters.pcnt; if(bytes) *bytes = e->counters.bcnt; +#if 0 + /* rhost */ + if(e->ip.src.s_addr) { + snprintip(rhost, rhostlen, ntohl(e->ip.src.s_addr)); + } +#endif r = 0; break; } @@ -283,6 +299,7 @@ get_redirect_rule_by_index(int index, char * ifname, unsigned short * eport, char * iaddr, int iaddrlen, unsigned short * iport, int * proto, char * desc, int desclen, + char * rhost, int rhostlen, unsigned int * timestamp, u_int64_t * packets, u_int64_t * bytes) { @@ -347,13 +364,19 @@ get_redirect_rule_by_index(int index, mr = (const struct ip_nat_multi_range *)&target->data[0]; snprintip(iaddr, iaddrlen, ntohl(mr->range[0].min_ip)); *iport = ntohs(mr->range[0].min.all); - /*if(desc) - strncpy(desc, "miniupnpd", desclen);*/ get_redirect_desc(*eport, *proto, desc, desclen, timestamp); if(packets) *packets = e->counters.pcnt; if(bytes) *bytes = e->counters.bcnt; + /* rhost */ + if(rhost && rhostlen > 0) { + if(e->ip.src.s_addr) { + snprintip(rhost, rhostlen, ntohl(e->ip.src.s_addr)); + } else { + rhost[0] = '\0'; + } + } r = 0; break; } @@ -678,9 +701,10 @@ iptc_init_verify_and_append(const char * table, /* add nat rule * iptables -t nat -A MINIUPNPD -p proto --dport eport -j DNAT --to iaddr:iport * */ -int +static int addnatrule(int proto, unsigned short eport, - const char * iaddr, unsigned short iport) + const char * iaddr, unsigned short iport, + const char * rhost) { int r = 0; struct ipt_entry * e; @@ -710,6 +734,12 @@ addnatrule(int proto, unsigned short eport, e->next_offset = sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size; + /* remote host */ + if(rhost && (rhost[0] != '\0') && (0 != strcmp(rhost, "*"))) + { + e->ip.src.s_addr = inet_addr(rhost); + e->ip.smsk.s_addr = INADDR_NONE; + } r = iptc_init_verify_and_append("nat", miniupnpd_nat_chain, e, "addnatrule()"); free(target); @@ -733,8 +763,9 @@ get_accept_target(void) /* add_filter_rule() * */ -int -add_filter_rule(int proto, const char * iaddr, unsigned short iport) +static int +add_filter_rule(int proto, const char * rhost, + const char * iaddr, unsigned short iport) { int r = 0; struct ipt_entry * e; @@ -766,6 +797,12 @@ add_filter_rule(int proto, const char * iaddr, unsigned short iport) e->next_offset = sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size; + /* remote host */ + if(rhost && (rhost[0] != '\0') && (0 != strcmp(rhost, "*"))) + { + e->ip.src.s_addr = inet_addr(rhost); + e->ip.smsk.s_addr = INADDR_NONE; + } r = iptc_init_verify_and_append("filter", miniupnpd_forward_chain, e, "add_filter_rule()"); free(target); diff --git a/release/src/router/miniupnpd/netfilter/iptcrdr.h b/release/src/router/miniupnpd/netfilter/iptcrdr.h index 4e9bd0f2cc..2f35c61704 100644 --- a/release/src/router/miniupnpd/netfilter/iptcrdr.h +++ b/release/src/router/miniupnpd/netfilter/iptcrdr.h @@ -1,7 +1,7 @@ -/* $Id: iptcrdr.h,v 1.15 2011/05/26 21:17:15 nanard Exp $ */ +/* $Id: iptcrdr.h,v 1.17 2011/06/04 15:44:58 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006 Thomas Bernard + * (c) 2006-2011 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ @@ -11,12 +11,14 @@ #include "../commonrdr.h" int -add_redirect_rule2(const char * ifname, unsigned short eport, +add_redirect_rule2(const char * ifname, + const char * rhost, unsigned short eport, const char * iaddr, unsigned short iport, int proto, - const char * desc, unsigned int timestamp); + const char * desc, unsigned int timestamp); int -add_filter_rule2(const char * ifname, const char * iaddr, +add_filter_rule2(const char * ifname, + const char * rhost, const char * iaddr, unsigned short eport, unsigned short iport, int proto, const char * desc); @@ -27,12 +29,5 @@ delete_redirect_and_filter_rules(unsigned short eport, int proto); int list_redirect_rule(const char * ifname); -int -addnatrule(int proto, unsigned short eport, - const char * iaddr, unsigned short iport); - -int -add_filter_rule(int proto, const char * iaddr, unsigned short iport); - #endif diff --git a/release/src/router/miniupnpd/pf/obsdrdr.c b/release/src/router/miniupnpd/pf/obsdrdr.c index f3a634711c..0b62f57b19 100644 --- a/release/src/router/miniupnpd/pf/obsdrdr.c +++ b/release/src/router/miniupnpd/pf/obsdrdr.c @@ -1,4 +1,4 @@ -/* $Id: obsdrdr.c,v 1.63 2011/05/27 08:25:23 nanard Exp $ */ +/* $Id: obsdrdr.c,v 1.66 2011/06/17 22:47:12 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2010 Thomas Bernard @@ -180,9 +180,10 @@ error: /* add_redirect_rule2() : * create a rdr rule */ int -add_redirect_rule2(const char * ifname, unsigned short eport, +add_redirect_rule2(const char * ifname, + const char * rhost, unsigned short eport, const char * iaddr, unsigned short iport, int proto, - const char * desc, unsigned int timestamp) + const char * desc, unsigned int timestamp) { int r; struct pfioc_rule pcr; @@ -252,6 +253,11 @@ add_redirect_rule2(const char * ifname, unsigned short eport, if(tag) strlcpy(pcr.rule.tagname, tag, PF_TAG_NAME_SIZE); strlcpy(pcr.rule.label, desc, PF_RULE_LABEL_SIZE); + if(rhost && rhost[0] != '\0' && rhost[0] != '*') + { + inet_pton(AF_INET, rhost, &pcr.rule.src.addr.v.a.addr.v4.s_addr); + pcr.rule.src.addr.v.a.mask.v4.s_addr = htonl(INADDR_NONE); + } #ifndef PF_NEWSTYLE pcr.rule.rpool.proxy_port[0] = iport; pcr.rule.rpool.proxy_port[1] = iport; @@ -315,7 +321,8 @@ add_redirect_rule2(const char * ifname, unsigned short eport, /* thanks to Seth Mos for this function */ int -add_filter_rule2(const char * ifname, const char * iaddr, +add_filter_rule2(const char * ifname, + const char * rhost, const char * iaddr, unsigned short eport, unsigned short iport, int proto, const char * desc) { @@ -378,6 +385,11 @@ add_filter_rule2(const char * ifname, const char * iaddr, if(tag) strlcpy(pcr.rule.tagname, tag, PF_TAG_NAME_SIZE); + if(rhost && rhost[0] != '\0' && rhost[0] != '*') + { + inet_pton(AF_INET, rhost, &pcr.rule.src.addr.v.a.addr.v4.s_addr); + pcr.rule.src.addr.v.a.mask.v4.s_addr = htonl(INADDR_NONE); + } #ifndef PF_NEWSTYLE pcr.rule.rpool.proxy_port[0] = eport; a = calloc(1, sizeof(struct pf_pooladdr)); @@ -636,6 +648,7 @@ get_redirect_rule_by_index(int index, char * ifname, unsigned short * eport, char * iaddr, int iaddrlen, unsigned short * iport, int * proto, char * desc, int desclen, + char * rhost, int rhostlen, unsigned int * timestamp, u_int64_t * packets, u_int64_t * bytes) { @@ -719,6 +732,18 @@ get_redirect_rule_by_index(int index, inet_ntop(AF_INET, &pr.rule.rdr.addr.v.a.addr.v4.s_addr, iaddr, iaddrlen); #endif + if(rhost && rhostlen > 0) + { + if (pr.rule.src.addr.v.a.addr.v4.s_addr == 0) + { + rhost[0] = '\0'; /* empty string */ + } + else + { + inet_ntop(AF_INET, &pr.rule.src.addr.v.a.addr.v4.s_addr, + rhost, rhostlen); + } + } if(timestamp) *timestamp = get_timestamp(*eport, *proto); return 0; @@ -824,8 +849,9 @@ list_rules(void) pr.nr = i; if(ioctl(dev, DIOCGETRULE, &pr) < 0) perror("DIOCGETRULE"); - printf(" %s %d:%d -> %d:%d proto %d keep_state=%d action=%d\n", + printf(" %s %s %d:%d -> %d:%d proto %d keep_state=%d action=%d\n", pr.rule.ifname, + inet_ntop(AF_INET, &pr.rule.src.addr.v.a.addr.v4.s_addr, buf, 32); (int)ntohs(pr.rule.dst.port[0]), (int)ntohs(pr.rule.dst.port[1]), #ifndef PF_NEWSTYLE diff --git a/release/src/router/miniupnpd/pf/obsdrdr.h b/release/src/router/miniupnpd/pf/obsdrdr.h index 145bb98bd4..fa34286601 100644 --- a/release/src/router/miniupnpd/pf/obsdrdr.h +++ b/release/src/router/miniupnpd/pf/obsdrdr.h @@ -1,4 +1,4 @@ -/* $Id: obsdrdr.h,v 1.18 2011/05/26 23:06:39 nanard Exp $ */ +/* $Id: obsdrdr.h,v 1.19 2011/06/04 15:47:18 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006 Thomas Bernard @@ -14,17 +14,19 @@ * proto can take the values IPPROTO_UDP or IPPROTO_TCP */ int -add_redirect_rule2(const char * ifname, unsigned short eport, +add_redirect_rule2(const char * ifname, + const char * rhost, unsigned short eport, const char * iaddr, unsigned short iport, int proto, - const char * desc, unsigned int timestamp); + const char * desc, unsigned int timestamp); /* add_filter_rule2() uses DIOCCHANGERULE ioctl * proto can take the values IPPROTO_UDP or IPPROTO_TCP */ int -add_filter_rule2(const char * ifname, const char * iaddr, +add_filter_rule2(const char * ifname, + const char * rhost, const char * iaddr, unsigned short eport, unsigned short iport, - int proto, const char * desc); + int proto, const char * desc); /* get_redirect_rule() gets internal IP and port from diff --git a/release/src/router/miniupnpd/pf/testobsdrdr.c b/release/src/router/miniupnpd/pf/testobsdrdr.c index ceb50d4cb6..473500b966 100644 --- a/release/src/router/miniupnpd/pf/testobsdrdr.c +++ b/release/src/router/miniupnpd/pf/testobsdrdr.c @@ -1,4 +1,4 @@ -/* $Id: testobsdrdr.c,v 1.21 2011/02/07 12:11:28 nanard Exp $ */ +/* $Id: testobsdrdr.c,v 1.22 2011/06/04 16:45:22 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2011 Thomas Bernard @@ -42,14 +42,18 @@ test_index(void) char ifname[16/*IFNAMSIZ*/]; char iaddr[32]; char desc[64]; + char rhost[32]; unsigned short iport = 0; unsigned short eport = 0; int proto = 0; + unsigned int timestamp; ifname[0] = '\0'; iaddr[0] = '\0'; + rhost[0] = '\0'; if(get_redirect_rule_by_index(0, ifname, &eport, iaddr, sizeof(iaddr), &iport, &proto, desc, sizeof(desc), - 0, 0) < 0) + rhost, sizeof(rhost), + ×tamp, 0, 0) < 0) { printf("get.._by_index : no rule\n"); } @@ -66,7 +70,9 @@ main(int arc, char * * argv) { char buf[32]; char desc[64]; + /*char rhost[32];*/ unsigned short iport; + unsigned int timestamp; u_int64_t packets = 0; u_int64_t bytes = 0; @@ -78,8 +84,8 @@ main(int arc, char * * argv) } //add_redirect_rule("ep0", 12123, "192.168.1.23", 1234); //add_redirect_rule2("ep0", 12155, "192.168.1.155", 1255, IPPROTO_TCP); - //add_redirect_rule2("ep0", 12123, "192.168.1.125", 1234, - // IPPROTO_UDP, "test description"); + add_redirect_rule2("ep0", "8.8.8.8", 12123, "192.168.1.125", 1234, + IPPROTO_UDP, "test description", 0); //add_redirect_rule2("em0", 12123, "127.1.2.3", 1234, // IPPROTO_TCP, "test description tcp"); @@ -88,7 +94,8 @@ main(int arc, char * * argv) if(get_redirect_rule("xl1", 4662, IPPROTO_TCP, - buf, 32, &iport, desc, sizeof(desc), + buf, sizeof(buf), &iport, desc, sizeof(desc), + ×tamp, &packets, &bytes) < 0) printf("get_redirect_rule() failed\n"); else diff --git a/release/src/router/miniupnpd/upnpevents.c b/release/src/router/miniupnpd/upnpevents.c index 6c3a8f9524..e2534df129 100644 --- a/release/src/router/miniupnpd/upnpevents.c +++ b/release/src/router/miniupnpd/upnpevents.c @@ -1,4 +1,4 @@ -/* $Id: upnpevents.c,v 1.14 2011/05/18 22:21:19 nanard Exp $ */ +/* $Id: upnpevents.c,v 1.15 2011/06/04 08:25:27 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2008-2011 Thomas Bernard @@ -476,7 +476,7 @@ void write_events_details(int s) { write(s, "Subscribers :\n", 14); for(sub = subscriberlist.lh_first; sub != NULL; sub = sub->entries.le_next) { n = snprintf(buff, sizeof(buff), " %p timeout=%d seq=%u service=%d\n", - sub, sub->timeout, sub->seq, sub->service); + sub, (int)sub->timeout, sub->seq, sub->service); write(s, buff, n); n = snprintf(buff, sizeof(buff), " notify=%p %s\n", sub->notify, sub->uuid); diff --git a/release/src/router/miniupnpd/upnphttp.c b/release/src/router/miniupnpd/upnphttp.c index 89536acc7f..b4de4f56e8 100644 --- a/release/src/router/miniupnpd/upnphttp.c +++ b/release/src/router/miniupnpd/upnphttp.c @@ -1,4 +1,4 @@ -/* $Id: upnphttp.c,v 1.59 2011/05/20 17:51:23 nanard Exp $ */ +/* $Id: upnphttp.c,v 1.60 2011/06/01 22:35:05 nanard Exp $ */ /* Project : miniupnp * Website : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * Author : Thomas Bernard @@ -344,6 +344,7 @@ with HTTP error 412 Precondition Failed. */ if(renewSubscription(h->req_SID, h->req_SIDLen, h->req_Timeout) < 0) { BuildResp2_upnphttp(h, 412, "Precondition Failed", 0, 0); } else { + h->respflags = FLAG_TIMEOUT; BuildResp_upnphttp(h, 0, 0); } } diff --git a/release/src/router/miniupnpd/upnpredirect.c b/release/src/router/miniupnpd/upnpredirect.c index 4ec2723368..5927675745 100644 --- a/release/src/router/miniupnpd/upnpredirect.c +++ b/release/src/router/miniupnpd/upnpredirect.c @@ -1,4 +1,4 @@ -/* $Id: upnpredirect.c,v 1.56 2011/05/27 08:25:22 nanard Exp $ */ +/* $Id: upnpredirect.c,v 1.59 2011/06/04 08:57:40 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2011 Thomas Bernard @@ -154,6 +154,7 @@ int reload_from_lease_file() char * proto; char * iaddr; char * desc; + char * rhost; unsigned int leaseduration; unsigned int timestamp; time_t current_time; @@ -226,7 +227,8 @@ int reload_from_lease_file() } else { leaseduration = 0; /* default value */ } - r = upnp_redirect(eport, iaddr, iport, proto, desc, leaseduration); + rhost = NULL; + r = upnp_redirect(rhost, eport, iaddr, iport, proto, desc, leaseduration); if(r == -1) { syslog(LOG_ERR, "Failed to redirect %hu -> %s:%hu protocol %s", eport, iaddr, iport, proto); @@ -251,7 +253,7 @@ int reload_from_lease_file() * -3 permission check failed */ int -upnp_redirect(unsigned short eport, +upnp_redirect(const char * rhost, unsigned short eport, const char * iaddr, unsigned short iport, const char * protocol, const char * desc, unsigned int leaseduration) @@ -298,19 +300,19 @@ upnp_redirect(unsigned short eport, timestamp = (leaseduration > 0) ? time(NULL) + leaseduration : 0; syslog(LOG_INFO, "redirecting port %hu to %s:%hu protocol %s for: %s", eport, iaddr, iport, protocol, desc); - return upnp_redirect_internal(eport, iaddr, iport, proto, + return upnp_redirect_internal(rhost, eport, iaddr, iport, proto, desc, timestamp); } int -upnp_redirect_internal(unsigned short eport, +upnp_redirect_internal(const char * rhost, unsigned short eport, const char * iaddr, unsigned short iport, int proto, const char * desc, unsigned int timestamp) { /*syslog(LOG_INFO, "redirecting port %hu to %s:%hu protocol %s for: %s", eport, iaddr, iport, protocol, desc); */ - if(add_redirect_rule2(ext_if_name, eport, iaddr, iport, proto, + if(add_redirect_rule2(ext_if_name, rhost, eport, iaddr, iport, proto, desc, timestamp) < 0) { return -1; } @@ -320,7 +322,7 @@ upnp_redirect_internal(unsigned short eport, #endif /* syslog(LOG_INFO, "creating pass rule to %s:%hu protocol %s for: %s", iaddr, iport, protocol, desc);*/ - if(add_filter_rule2(ext_if_name, iaddr, eport, iport, proto, desc) < 0) { + if(add_filter_rule2(ext_if_name, rhost, iaddr, eport, iport, proto, desc) < 0) { /* clean up the redirect rule */ #if !defined(__linux__) delete_redirect_rule(ext_if_name, eport, proto); @@ -341,6 +343,7 @@ upnp_redirect_internal(unsigned short eport, +/* Firewall independant code which call the FW dependant code. */ int upnp_get_redirection_infos(unsigned short eport, const char * protocol, unsigned short * iport, @@ -371,6 +374,7 @@ upnp_get_redirection_infos_by_index(int index, unsigned short * iport, char * iaddr, int iaddrlen, char * desc, int desclen, + char * rhost, int rhostlen, unsigned int * leaseduration) { /*char ifname[IFNAMSIZ];*/ @@ -380,8 +384,11 @@ upnp_get_redirection_infos_by_index(int index, if(desc && (desclen > 0)) desc[0] = '\0'; + if(rhost && (rhost > 0)) + rhost[0] = '\0'; if(get_redirect_rule_by_index(index, 0/*ifname*/, eport, iaddr, iaddrlen, - iport, &proto, desc, desclen, ×tamp, + iport, &proto, desc, desclen, + rhost, rhostlen, ×tamp, 0, 0) < 0) return -1; else @@ -398,6 +405,7 @@ upnp_get_redirection_infos_by_index(int index, } } +/* called from natpmp.c too */ int _upnp_delete_redir(unsigned short eport, int proto) { @@ -426,19 +434,20 @@ upnp_delete_redirection(unsigned short eport, const char * protocol) } /* upnp_get_portmapping_number_of_entries() - * TODO: improve this code */ + * TODO: improve this code. */ int upnp_get_portmapping_number_of_entries() { int n = 0, r = 0; unsigned short eport, iport; - char protocol[4], iaddr[32], desc[64]; + char protocol[4], iaddr[32], desc[64], rhost[32]; unsigned int leaseduration; do { protocol[0] = '\0'; iaddr[0] = '\0'; desc[0] = '\0'; r = upnp_get_redirection_infos_by_index(n, &eport, protocol, &iport, iaddr, sizeof(iaddr), desc, sizeof(desc), + rhost, sizeof(rhost), &leaseduration); n++; } while(r==0); @@ -467,7 +476,7 @@ get_upnp_rules_state_list(int max_rules_number_target) current_time = time(NULL); nextruletoclean_timestamp = 0; while(get_redirect_rule_by_index(i, /*ifname*/0, &tmp->eport, 0, 0, - &iport, &proto, 0, 0, ×tamp, + &iport, &proto, 0, 0, 0,0, ×tamp, &tmp->packets, &tmp->bytes) >= 0) { tmp->to_remove = 0; @@ -616,14 +625,14 @@ upnp_check_outbound_pinhole(int proto, int * timeout) * -3 inbound pinhole disabled */ int -upnp_add_inboundpinhole(const char * raddr, unsigned short rport, const char * iaddr, unsigned short iport, const char * protocol, const char * leaseTime, int * uid) +upnp_add_inboundpinhole(const char * raddr, + unsigned short rport, + const char * iaddr, + unsigned short iport, + const char * protocol, + const char * leaseTime, + int * uid) { - // Check if there is enough space to create inbound pinhole -/* if(!inboundPinholeSpace) - { - syslog(LOG_INFO, "Not enough space for adding pinhole for inbound traffic [%s]:%hu->[%s]:%hu %s.", raddr, rport, iaddr, iport, protocol); // IPv6 Modification - return -1; - }*/ int r, s, t, lt=0; char iaddr_old[40]="", proto[6]="", idfound[5]="", leaseTmp[12]; // IPv6 Modification snprintf(proto, sizeof(proto), "%.5d", atoi(protocol)); @@ -743,20 +752,23 @@ upnp_add_inboundpinhole_internal(const char * raddr, unsigned short rport, } int -upnp_get_pinhole_info(const char * raddr, unsigned short rport, char * iaddr, unsigned short * iport, char * proto, const char * uid, char * lt) +upnp_get_pinhole_info(const char * raddr, + unsigned short rport, + char * iaddr, + unsigned short * iport, + char * proto, + const char * uid, + char * lt) { -#if 0 - if(!raddr) - return get_rule_from_file(0, 0, iaddr, iport, proto, uid, lt, 0); - else - return get_rule_from_file(raddr, rport, iaddr, iport, proto, uid, lt, 0); -#endif -return 0; + /* TODO : to be done + * Call Firewall specific code to get IPv6 pinhole infos */ + return 0; } int upnp_update_inboundpinhole(const char * uid, const char * leasetime) { + /* TODO : to be implemented */ #if 0 int r, n; syslog(LOG_INFO, "Updating pinhole for inbound traffic with ID: %s", uid); @@ -777,7 +789,10 @@ upnp_update_inboundpinhole(const char * uid, const char * leasetime) int upnp_delete_inboundpinhole(const char * uid) { + /* TODO : to be implemented */ #if 0 + /* this is a alpha implementation calling ip6tables via system(), + * it can be usefull as an example to code the netfilter version */ int r, s, linenum=0; char cmd[256], cmd_raw[256]; syslog(LOG_INFO, "Removing pinhole for inbound traffic with ID: %s", uid); @@ -810,61 +825,6 @@ return -1; #endif } -#if 0 -static int -compare_time(char * traced_time, char * action_time) -{ - char * t, * a; - char t_month[4], a_month[4], t_strdate[3], a_strdate[3], t_strhour[3], a_strhour[3], t_strmin[3], a_strmin[3], t_strsec[3], a_strsec[3]; - int t_date, a_date, t_hour, a_hour, t_min, a_min, t_sec, a_sec; - - t = traced_time; printf("\ttraced_time = %s\n", t); - a = action_time; printf("\taction_time = %s\n", a); - - snprintf(t_month, sizeof(t_month),"%.*s", 3, t); - t += 4; - snprintf(t_strdate, sizeof(t_strdate),"%.*s", 2, t); - t += 3; - snprintf(t_strhour, sizeof(t_strhour),"%.*s", 2, t); - t += 3; - snprintf(t_strmin, sizeof(t_strmin),"%.*s", 2, t); - t += 3; - snprintf(t_strsec, sizeof(t_strsec),"%.*s", 2, t); - - snprintf(a_month, sizeof(a_month),"%.*s", 3, a); - a += 4; - snprintf(a_strdate, sizeof(a_strdate),"%.*s", 2, a); - a += 3; - snprintf(a_strhour, sizeof(a_strhour),"%.*s", 2, a); - a += 3; - snprintf(a_strmin, sizeof(a_strmin),"%.*s", 2, a); - a += 3; - snprintf(a_strsec, sizeof(a_strsec),"%.*s", 2, a); - - printf("\tCompare traced_time = M:%s d:%s h:%s m:%s s:%s\n", t_month, t_strdate, t_strhour, t_strmin, t_strsec); - printf("\t to action_time = M:%s d:%s h:%s m:%s s:%s\n", a_month, a_strdate, a_strhour, a_strmin, a_strsec); - t_date = atoi(t_strdate); - a_date = atoi(a_strdate); - t_hour = atoi(t_strhour); - a_hour = atoi(a_strhour); - t_min = atoi(t_strmin); - a_min = atoi(a_strmin); - t_sec = atoi(t_strsec); - a_sec = atoi(a_strsec); - if((strcmp(t_month, a_month) == 0) && t_date == a_date && t_hour == a_hour) - { - if( (t_min == a_min && (a_sec-10 <= t_sec && t_sec <= a_sec)) - || ((a_min-1 == t_min) && ((60 - t_sec + a_min) <= 10)) ) - return 1; - else - return -1; - - } - else - return -1; -} -#endif - /* * Result: * 1: Found Result @@ -874,8 +834,16 @@ compare_time(char * traced_time, char * action_time) * -7: Result in a chain not a rule */ int -upnp_check_pinhole_working(const char * uid, char * eaddr, char * iaddr, unsigned short * eport, unsigned short * iport, char * protocol, int * rulenum_used) +upnp_check_pinhole_working(const char * uid, + char * eaddr, + char * iaddr, + unsigned short * eport, + unsigned short * iport, + char * protocol, + int * rulenum_used) { + /* TODO : to be implemented */ +#if 0 FILE * fd; time_t expire = time(NULL); char buf[1024], filename[] = "/var/log/kern.log", expire_time[32]=""; @@ -1069,12 +1037,15 @@ upnp_check_pinhole_working(const char * uid, char * eaddr, char * iaddr, unsigne } fclose(fd); return res; - +#else + return -4; +#endif } int upnp_get_pinhole_packets(const char * uid, int * packets) { + /* TODO : to be implemented */ #if 0 int line=0, r; char cmd[256]; @@ -1128,11 +1099,11 @@ upnp_clean_expiredpinhole() void write_ruleset_details(int s) { - char ifname[IFNAMSIZ]; int proto = 0; unsigned short eport, iport; char desc[64]; char iaddr[32]; + char rhost[32]; unsigned int timestamp; u_int64_t packets; u_int64_t bytes; @@ -1140,18 +1111,18 @@ write_ruleset_details(int s) char buffer[256]; int n; - ifname[0] = '\0'; write(s, "Ruleset :\n", 10); - while(get_redirect_rule_by_index(i, ifname, &eport, iaddr, sizeof(iaddr), + while(get_redirect_rule_by_index(i, 0/*ifname*/, &eport, iaddr, sizeof(iaddr), &iport, &proto, desc, sizeof(desc), + rhost, sizeof(rhost), ×tamp, &packets, &bytes) >= 0) { n = snprintf(buffer, sizeof(buffer), - "%2d %s %s %hu->%s:%hu " + "%2d %s %s:%hu->%s:%hu " "'%s' %u %" PRIu64 " %" PRIu64 "\n", /*"'%s' %llu %llu\n",*/ - i, ifname, proto==IPPROTO_TCP?"TCP":"UDP", + i, proto==IPPROTO_TCP?"TCP":"UDP", rhost, eport, iaddr, iport, desc, timestamp, packets, bytes); write(s, buffer, n); i++; diff --git a/release/src/router/miniupnpd/upnpredirect.h b/release/src/router/miniupnpd/upnpredirect.h index f47a35bf0d..cf650ed139 100644 --- a/release/src/router/miniupnpd/upnpredirect.h +++ b/release/src/router/miniupnpd/upnpredirect.h @@ -1,4 +1,4 @@ -/* $Id: upnpredirect.h,v 1.21 2011/05/26 22:28:35 nanard Exp $ */ +/* $Id: upnpredirect.h,v 1.23 2011/06/17 22:46:52 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2011 Thomas Bernard @@ -8,6 +8,9 @@ #ifndef __UPNPREDIRECT_H__ #define __UPNPREDIRECT_H__ +/* for u_int64_t */ +#include + #include "config.h" #ifdef ENABLE_LEASEFILE @@ -23,7 +26,7 @@ int reload_from_lease_file(void); * -3 permission check failed */ int -upnp_redirect(unsigned short eport, +upnp_redirect(const char * rhost, unsigned short eport, const char * iaddr, unsigned short iport, const char * protocol, const char * desc, unsigned int leaseduration); @@ -31,7 +34,7 @@ upnp_redirect(unsigned short eport, /* upnp_redirect_internal() * same as upnp_redirect() without any check */ int -upnp_redirect_internal(unsigned short eport, +upnp_redirect_internal(const char * rhost, unsigned short eport, const char * iaddr, unsigned short iport, int proto, const char * desc, unsigned int timestamp); @@ -54,6 +57,7 @@ upnp_get_redirection_infos_by_index(int index, unsigned short * iport, char * iaddr, int iaddrlen, char * desc, int desclen, + char * rhost, int rhostlen, unsigned int * leaseduration); /* upnp_delete_redirection() diff --git a/release/src/router/miniupnpd/upnpsoap.c b/release/src/router/miniupnpd/upnpsoap.c index dee00954c1..1577542d12 100644 --- a/release/src/router/miniupnpd/upnpsoap.c +++ b/release/src/router/miniupnpd/upnpsoap.c @@ -1,4 +1,4 @@ -/* $Id: upnpsoap.c,v 1.81 2011/05/26 21:17:30 nanard Exp $ */ +/* $Id: upnpsoap.c,v 1.85 2011/06/17 23:24:14 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2011 Thomas Bernard @@ -320,7 +320,10 @@ AddPortMapping(struct upnphttp * h, const char * action) return; } + /* IGD 2 MUST support both wildcard and specific IP address values + * for RemoteHost (only the wildcard value was REQUIRED in release 1.0) */ r_host = GetValueFromNameValueList(&data, "NewRemoteHost"); +#ifndef SUPPORT_REMOTEHOST #ifdef UPNP_STRICT if (r_host && (strlen(r_host) > 0) && (0 != strcmp(r_host, "*"))) { @@ -329,6 +332,7 @@ AddPortMapping(struct upnphttp * h, const char * action) return; } #endif +#endif /* if ip not valid assume hostname and convert */ if (inet_pton(AF_INET, int_ip, &result_ip) <= 0) @@ -383,20 +387,23 @@ AddPortMapping(struct upnphttp * h, const char * action) iport = (unsigned short)atoi(int_port); leaseduration = leaseduration_str ? atoi(leaseduration_str) : 0; - -#if 0 - if(leaseduration) { - /* at the moment, lease duration is always infinite */ - /* TODO : in order to be compliant with IGD v2, lease duration - * support needs to be implemented */ - syslog(LOG_INFO, "NewLeaseDuration=%u not supported, ignored. (ip=%s, desc='%s')", leaseduration, int_ip, desc); - } +#ifdef IGD_V2 + /* PortMappingLeaseDuration can be either a value between 1 and + * 604800 seconds or the zero value (for infinite lease time). + * Note that an infinite lease time can be only set by out-of-band + * mechanisms like WWW-administration, remote management or local + * management. + * If a control point uses the value 0 to indicate an infinite lease + * time mapping, it is REQUIRED that gateway uses the maximum value + * instead (e.g. 604800 seconds) */ + if(leaseduration == 0 || leaseduration > 604800) + leaseduration = 604800; #endif - syslog(LOG_INFO, "%s: ext port %hu to %s:%hu protocol %s for: %s leaseduration=%u", - action, eport, int_ip, iport, protocol, desc, leaseduration); + syslog(LOG_INFO, "%s: ext port %hu to %s:%hu protocol %s for: %s leaseduration=%u rhost=%s", + action, eport, int_ip, iport, protocol, desc, leaseduration, r_host); - r = upnp_redirect(eport, int_ip, iport, protocol, desc, leaseduration); + r = upnp_redirect(r_host, eport, int_ip, iport, protocol, desc, leaseduration); ClearNameValueList(&data); @@ -406,19 +413,20 @@ AddPortMapping(struct upnphttp * h, const char * action) * 715 - Wildcard not permited in SrcAddr * 716 - Wildcard not permited in ExtPort * 718 - ConflictInMappingEntry - * 724 - SamePortValuesRequired + * 724 - SamePortValuesRequired (deprecated in IGD v2) * 725 - OnlyPermanentLeasesSupported The NAT implementation only supports permanent lease times on - port mappings + port mappings (deprecated in IGD v2) * 726 - RemoteHostOnlySupportsWildcard RemoteHost must be a wildcard and cannot be a specific IP - address or DNS name + address or DNS name (deprecated in IGD v2) * 727 - ExternalPortOnlySupportsWildcard ExternalPort must be a wildcard and cannot be a specific port - value + value (deprecated in IGD v2) * 728 - NoPortMapsAvailable There are not enough free prots available to complete the mapping - (added in IGD v2) */ + (added in IGD v2) + * 729 - ConflictWithOtherMechanisms (added in IGD v2) */ switch(r) { case 0: /* success */ @@ -481,6 +489,7 @@ AddAnyPortMapping(struct upnphttp * h, const char * action) SoapError(h, 402, "Invalid Args"); return; } +#ifndef SUPPORT_REMOTEHOST #ifdef UPNP_STRICT if (r_host && (strlen(r_host) > 0) && (0 != strcmp(r_host, "*"))) { @@ -489,6 +498,7 @@ AddAnyPortMapping(struct upnphttp * h, const char * action) return; } #endif +#endif /* if ip not valid assume hostname and convert */ if (inet_pton(AF_INET, int_ip, &result_ip) <= 0) @@ -529,7 +539,7 @@ AddAnyPortMapping(struct upnphttp * h, const char * action) /* TODO : accept a different external port * have some smart strategy to choose the port */ for(;;) { - r = upnp_redirect(eport, int_ip, iport, protocol, desc, leaseduration); + r = upnp_redirect(r_host, eport, int_ip, iport, protocol, desc, leaseduration); if(r==-2 && eport < 65535) { eport++; } else { @@ -593,6 +603,7 @@ GetSpecificPortMappingEntry(struct upnphttp * h, const char * action) SoapError(h, 402, "Invalid Args"); return; } +#ifndef SUPPORT_REMOTEHOST #ifdef UPNP_STRICT if (r_host && (strlen(r_host) > 0) && (0 != strcmp(r_host, "*"))) { @@ -601,9 +612,11 @@ GetSpecificPortMappingEntry(struct upnphttp * h, const char * action) return; } #endif +#endif eport = (unsigned short)atoi(ext_port); + /* add r_host ? */ r = upnp_get_redirection_infos(eport, protocol, &iport, int_ip, sizeof(int_ip), desc, sizeof(desc), @@ -653,6 +666,7 @@ DeletePortMapping(struct upnphttp * h, const char * action) SoapError(h, 402, "Invalid Args"); return; } +#ifndef SUPPORT_REMOTEHOST #ifdef UPNP_STRICT if (r_host && (strlen(r_host) > 0) && (0 != strcmp(r_host, "*"))) { @@ -661,6 +675,7 @@ DeletePortMapping(struct upnphttp * h, const char * action) return; } #endif +#endif eport = (unsigned short)atoi(ext_port); @@ -741,7 +756,7 @@ GetGenericPortMappingEntry(struct upnphttp * h, const char * action) static const char resp[] = "" - "" + "%s" "%u" "%s" "%u" @@ -756,6 +771,7 @@ GetGenericPortMappingEntry(struct upnphttp * h, const char * action) const char * m_index; char protocol[4], iaddr[32]; char desc[64]; + char rhost[40]; unsigned int leaseduration = 0; struct NameValueParserData data; @@ -773,9 +789,11 @@ GetGenericPortMappingEntry(struct upnphttp * h, const char * action) syslog(LOG_INFO, "%s: index=%d", action, index); + rhost[0] = '\0'; r = upnp_get_redirection_infos_by_index(index, &eport, protocol, &iport, iaddr, sizeof(iaddr), desc, sizeof(desc), + rhost, sizeof(rhost), &leaseduration); if(r < 0) @@ -787,7 +805,7 @@ GetGenericPortMappingEntry(struct upnphttp * h, const char * action) int bodylen; char body[2048]; bodylen = snprintf(body, sizeof(body), resp, - action, SERVICE_TYPE_WANIPC, + action, SERVICE_TYPE_WANIPC, rhost, (unsigned int)eport, protocol, (unsigned int)iport, iaddr, desc, leaseduration, action); BuildSendAndCloseSoapResp(h, body, bodylen); @@ -836,6 +854,7 @@ GetListOfPortMappings(struct upnphttp * h, const char * action) unsigned short iport; char int_ip[32]; char desc[64]; + char rhost[64]; unsigned int leaseduration = 0; struct NameValueParserData data; @@ -913,10 +932,12 @@ http://www.upnp.org/schemas/gw/WANIPConnection-v2.xsd"> r = upnp_get_redirection_infos(port_list[i], protocol, &iport, int_ip, sizeof(int_ip), desc, sizeof(desc), &leaseduration); + /* TODO : rhost */ + rhost[0] = '\0'; if(r == 0) { bodylen += snprintf(body+bodylen, bodyalloc-bodylen, entry, - "", port_list[i], protocol, + rhost, port_list[i], protocol, iport, int_ip, desc, leaseduration); number--; } -- 2.11.4.GIT