From b3dd278c95a4b344d551664f37a0689754e53652 Mon Sep 17 00:00:00 2001 From: Shibby Date: Thu, 18 Feb 2016 14:12:43 +0100 Subject: [PATCH] miniupnpd 1.9 (20160113) --- release/src/router/httpd/tomato.c | 2 +- release/src/router/miniupnpd/Changelog.txt | 39 +- release/src/router/miniupnpd/Makefile | 25 +- release/src/router/miniupnpd/Makefile.linux | 123 ++++- release/src/router/miniupnpd/asyncsendto.c | 4 +- release/src/router/miniupnpd/bsd/getroute.c | 72 ++- release/src/router/miniupnpd/codelength.h | 31 +- release/src/router/miniupnpd/genconfig.sh | 84 +++- release/src/router/miniupnpd/getifaddr.c | 3 +- release/src/router/miniupnpd/ipf/ipfrdr.c | 16 +- release/src/router/miniupnpd/ipfw/ipfwaux.h | 4 +- release/src/router/miniupnpd/ipfw/ipfwrdr.c | 21 +- release/src/router/miniupnpd/linux/getifstats.c | 2 +- release/src/router/miniupnpd/linux/getroute.c | 3 - release/src/router/miniupnpd/macros.h | 37 +- release/src/router/miniupnpd/minissdp.c | 92 ++-- release/src/router/miniupnpd/miniupnpd.c | 188 +++++--- release/src/router/miniupnpd/miniupnpd.conf | 3 +- release/src/router/miniupnpd/natpmp.c | 35 +- release/src/router/miniupnpd/netfilter/Makefile | 27 +- .../miniupnpd/netfilter/ip6tables_display.sh | 0 .../router/miniupnpd/netfilter/ip6tables_flush.sh | 0 .../router/miniupnpd/netfilter/ip6tables_init.sh | 0 .../netfilter/ip6tables_init_and_clean.sh | 0 .../miniupnpd/netfilter/ip6tables_removeall.sh | 0 .../src/router/miniupnpd/netfilter/iptpinhole.c | 5 +- .../netfilter_nft/scripts/nft_delete_chain.sh | 0 .../miniupnpd/netfilter_nft/scripts/nft_flush.sh | 0 .../miniupnpd/netfilter_nft/scripts/nft_init.sh | 0 .../netfilter_nft/scripts/nft_removeall.sh | 0 release/src/router/miniupnpd/pcp_msg_struct.h | 59 ++- release/src/router/miniupnpd/pcplearndscp.c | 4 +- release/src/router/miniupnpd/pcpserver.c | 495 ++++++++++----------- release/src/router/miniupnpd/portinuse.c | 6 +- release/src/router/miniupnpd/testgetroute.c | 11 +- release/src/router/miniupnpd/testssdppktgen.c | 100 +++++ release/src/router/miniupnpd/testupnppermissions.c | 12 +- release/src/router/miniupnpd/upnpdescgen.c | 94 +++- release/src/router/miniupnpd/upnpdescstrings.h | 6 +- release/src/router/miniupnpd/upnpevents.c | 14 +- release/src/router/miniupnpd/upnpevents.h | 8 +- release/src/router/miniupnpd/upnphttp.c | 27 +- release/src/router/miniupnpd/upnphttp.h | 14 +- release/src/router/miniupnpd/upnpreplyparse.c | 19 +- release/src/router/miniupnpd/upnpsoap.c | 265 +++++++---- release/src/router/nvram/defaults.c | 2 +- release/src/router/rc/dhcp.c | 2 +- release/src/router/rc/wan.c | 4 +- release/src/router/www/basic-ipv6.asp | 25 +- .../arch/arm/boot/compressed/mpcore_cache.S | 118 +++++ 50 files changed, 1425 insertions(+), 676 deletions(-) mode change 100644 => 100755 release/src/router/miniupnpd/netfilter/ip6tables_display.sh mode change 100644 => 100755 release/src/router/miniupnpd/netfilter/ip6tables_flush.sh mode change 100644 => 100755 release/src/router/miniupnpd/netfilter/ip6tables_init.sh mode change 100644 => 100755 release/src/router/miniupnpd/netfilter/ip6tables_init_and_clean.sh mode change 100644 => 100755 release/src/router/miniupnpd/netfilter/ip6tables_removeall.sh mode change 100644 => 100755 release/src/router/miniupnpd/netfilter_nft/scripts/nft_delete_chain.sh mode change 100644 => 100755 release/src/router/miniupnpd/netfilter_nft/scripts/nft_flush.sh mode change 100644 => 100755 release/src/router/miniupnpd/netfilter_nft/scripts/nft_init.sh mode change 100644 => 100755 release/src/router/miniupnpd/netfilter_nft/scripts/nft_removeall.sh create mode 100644 release/src/router/miniupnpd/testssdppktgen.c create mode 100644 release/src/src/linux/linux-2.6.36/arch/arm/boot/compressed/mpcore_cache.S diff --git a/release/src/router/httpd/tomato.c b/release/src/router/httpd/tomato.c index f6a8746d7c..843556eb91 100644 --- a/release/src/router/httpd/tomato.c +++ b/release/src/router/httpd/tomato.c @@ -719,7 +719,7 @@ static const nvset_t nvset_list[] = { { "ipv6_6rd_borderrelay", V_IP }, { "ipv6_6rd_ipv4masklen", V_RANGE(0, 32) }, { "ipv6_vlan", V_RANGE(0, 7) }, // Enable IPv6 on 1=LAN1 2=LAN2 4=LAN3 - { "ipv6_isp_opt", V_01 }, // wan.c add eval option for dhcpd + { "ipv6_pdonly", V_01 }, // Request DHCPv6 Prefix Delegation Only #endif // basic-wfilter diff --git a/release/src/router/miniupnpd/Changelog.txt b/release/src/router/miniupnpd/Changelog.txt index c5340d0851..f6d76048a9 100644 --- a/release/src/router/miniupnpd/Changelog.txt +++ b/release/src/router/miniupnpd/Changelog.txt @@ -1,4 +1,41 @@ -$Id: Changelog.txt,v 1.399 2015/04/30 09:05:07 nanard Exp $ +$Id: Changelog.txt,v 1.415 2015/12/16 10:21:48 nanard Exp $ + +2015/12/16: + improve syslog message for incoming HTTP requests + +2015/12/13: + --disable-pppconn to disable WanPPPConnection + more fixes in DeviceProtection service + +2015/12/12: + add commandline option to genconfig.sh to set UPnP (UDA) version + advertise correct service and device versions when IGDv2 is enabled + fix action arguments for DeviceProtection service + fix event subscription renewal (include SID in response) + +2015/11/16: + Fix bsd/getroute.c get_src_for_route_to() when args are NULL + +2015/11/02: + use LOG_INFO instead of LOG_ERR for PCP PEER and MAP success + +2015/10/30: + fix : properly call find_ipv6_addr() with the 1st LAN interface + use name server from query in SOAP responses (continued) + +2015/10/24: + move SSDP_PACKET_MAX_LEN definition to config.h. also set default to 1024. + +2015/09/22: + cleanup UPNP_VERSION macro / add UPNP_VERSION_MAJOR, UPNP_VERSION_MINOR + Dont use packed structs anymore to read/write PCP messages + +2015/09/15: + use name server from query in SOAP responses + +2015/08/25: + better bind socket to right interface(s), + using struct ip_mreqn, SO_BINDTODEVICE 2015/04/30: Adding linux/nftables support diff --git a/release/src/router/miniupnpd/Makefile b/release/src/router/miniupnpd/Makefile index a141f59b5e..7d63d4152f 100644 --- a/release/src/router/miniupnpd/Makefile +++ b/release/src/router/miniupnpd/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.85 2014/06/27 13:01:30 nanard Exp $ +# $Id: Makefile,v 1.87 2015/11/05 11:16:13 nanard Exp $ # MiniUPnP project # http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ # Author: Thomas Bernard @@ -143,7 +143,7 @@ TESTPORTINUSEOBJS = testportinuse.o portinuse.o getifaddr.o EXECUTABLES = miniupnpd testupnpdescgen testgetifstats \ testupnppermissions miniupnpdctl \ testgetifaddr testgetroute testasyncsendto \ - testportinuse + testportinuse testssdppktgen .if $(OSNAME) == "Darwin" LIBS = @@ -172,6 +172,7 @@ clean: miniupnpdctl.o testgetifaddr.o testgetroute.o testasyncsendto.o \ testportinuse.o \ $(PFOBJS) $(IPFOBJS) $(IPFWOBJS) + $(RM) validateupnppermissions validategetifaddr validatessdppktgen install: miniupnpd genuuid $(STRIP) miniupnpd @@ -193,15 +194,33 @@ UUID != if which uuidgen 2>&1 > /dev/null; then \ else echo "00000000-0000-0000-0000-000000000000"; \ fi +# bash or ksh +SH != which bash || which ksh + genuuid: $(MV) miniupnpd.conf miniupnpd.conf.before sed -e "s/^uuid=[-0-9a-fA-F]*/uuid=$(UUID)/" miniupnpd.conf.before > miniupnpd.conf $(RM) miniupnpd.conf.before +check: validateupnppermissions validategetifaddr validatessdppktgen + +validateupnppermissions: testupnppermissions testupnppermissions.sh + $(SH) ./testupnppermissions.sh + touch $@ + +validategetifaddr: testgetifaddr testgetifaddr.sh + ./testgetifaddr.sh + touch $@ + +validatessdppktgen: testssdppktgen + ./testssdppktgen + touch $@ + depend: config.h mkdep $(ALLOBJS:.o=.c) testupnpdescgen.c testgetifstats.c \ testupnppermissions.c miniupnpdctl.c testgetifaddr.c \ - testgetroute.c testportinuse.c testasyncsendto.c + testgetroute.c testportinuse.c testasyncsendto.c \ + testssdppktgen.c miniupnpd: config.h $(ALLOBJS) $(CC) $(CFLAGS) -o $@ $(ALLOBJS) $(LIBS) diff --git a/release/src/router/miniupnpd/Makefile.linux b/release/src/router/miniupnpd/Makefile.linux index 061c23e868..fc0fd9a8bc 100644 --- a/release/src/router/miniupnpd/Makefile.linux +++ b/release/src/router/miniupnpd/Makefile.linux @@ -1,4 +1,4 @@ -# $Id: Makefile.linux,v 1.90 2015/04/26 14:43:28 nanard Exp $ +# $Id: Makefile.linux,v 1.91 2015/10/26 16:53:25 nanard Exp $ # MiniUPnP project # (c) 2006-2015 Thomas Bernard # http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ @@ -28,7 +28,6 @@ CFLAGS += -fno-common CPPFLAGS += -D_GNU_SOURCE CFLAGS += -Wall CFLAGS += -Wextra -Wstrict-prototypes -Wdeclaration-after-statement -CFLAGS += $(EXTRACFLAGS) #CFLAGS += -Wno-missing-field-initializers #CFLAGS += -ansi # iptables headers does use typeof which is a gcc extension CC ?= gcc @@ -56,38 +55,106 @@ NETFILTEROBJS = netfilter/iptcrdr.o netfilter/iptpinhole.o netfilter/nfct_get.o ALLOBJS = $(BASEOBJS) $(LNXOBJS) $(NETFILTEROBJS) +PCFILE_FOUND := $(shell $(PKG_CONFIG) --exists libiptc; echo $$?) + +ifeq (${PCFILE_FOUND},0) + +IPTABLESVERSION := $(shell $(PKG_CONFIG) --modversion libiptc) +IPTABLESVERSION1 := $(shell echo $(IPTABLESVERSION) | cut -d. -f1 ) +IPTABLESVERSION2 := $(shell echo $(IPTABLESVERSION) | cut -d. -f2 ) +IPTABLESVERSION3 := $(shell echo $(IPTABLESVERSION) | cut -d. -f3 ) +# test if iptables version >= 1.4.3 +TEST := $(shell [ \( \( $(IPTABLESVERSION1) -ge 1 \) -a \( $(IPTABLESVERSION2) -ge 4 \) \) -a \( $(IPTABLESVERSION3) -ge 3 \) ] && echo 1 ) +ifeq ($(TEST), 1) +CPPFLAGS += -DIPTABLES_143 +endif + +CFLAGS += $(shell $(PKG_CONFIG) --cflags libiptc) +LDLIBS += $(shell $(PKG_CONFIG) --static --libs-only-l libiptc) +LDFLAGS += $(shell $(PKG_CONFIG) --libs-only-L libiptc) +LDFLAGS += $(shell $(PKG_CONFIG) --libs-only-other libiptc) +else + +ifeq "$(wildcard /etc/gentoo-release )" "" +LDLIBS ?= -liptc +else # gentoo +# the following is better, at least on gentoo with iptables 1.4.6 +# see http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1618 +# and http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=2183 +LDLIBS ?= -lip4tc +CPPFLAGS := -DIPTABLES_143 $(CPPFLAGS) +endif + +ARCH ?= $(shell uname -m | grep -q "x86_64" && echo 64) ifdef IPTABLESPATH -CFLAGS := $(CFLAGS) -I$(IPTABLESPATH)/include/ +CPPFLAGS := $(CPPFLAGS) -I$(IPTABLESPATH)/include/ LDFLAGS := $(LDFLAFGS) -L$(IPTABLESPATH)/libiptc/ - # get iptables version and set IPTABLES_143 macro if needed +ifeq ($(TARGET_OPENWRT),) IPTABLESVERSION := $(shell grep "\#define VERSION" $(IPTABLESPATH)/config.h | tr -d \" |cut -d" " -f3 ) IPTABLESVERSION1 := $(shell echo $(IPTABLESVERSION) | cut -d. -f1 ) IPTABLESVERSION2 := $(shell echo $(IPTABLESVERSION) | cut -d. -f2 ) IPTABLESVERSION3 := $(shell echo $(IPTABLESVERSION) | cut -d. -f3 ) - # test if iptables version >= 1.4.3 TEST := $(shell [ \( \( $(IPTABLESVERSION1) -ge 1 \) -a \( $(IPTABLESVERSION2) -ge 4 \) \) -a \( $(IPTABLESVERSION3) -ge 3 \) ] && echo 1 ) ifeq ($(TEST), 1) -CPPFLAGS := $(CFLAGS) -DIPTABLES_143 +CPPFLAGS := $(CPPFLAGS) -DIPTABLES_143 # the following sucks, but works LDLIBS = $(IPTABLESPATH)/libiptc/.libs/libip4tc.o -else # ifeq ($(TEST), 1) +#LDLIBS = $(IPTABLESPATH)/libiptc/.libs/libiptc.a +else # ifeq ($(TEST), 1) LDLIBS = $(IPTABLESPATH)/libiptc/libiptc.a -endif # ifeq ($(TEST), 1) -else #ifdef IPTABLESPATH +endif # ifeq ($(TEST), 1) +else # ($(TARGET_OPENWRT),) +# openWRT : +# check for system-wide iptables files. Test if iptables version >= 1.4.3 +# the following test has to be verified : +TEST := $(shell test -f /usr/include/iptables/internal.h && grep -q "\#define IPTABLES_VERSION" /usr/include/iptables/internal.h && echo 1) +ifeq ($(TEST), 1) +CPPFLAGS := $(CPPFLAGS) -DIPTABLES_143 +LDLIBS = -liptc +endif # ($(TEST), 1) +TEST_LIB := $(shell test -f /usr/lib$(ARCH)/libiptc.a && echo 1) +ifeq ($(TEST_LIB), 1) +LDLIBS = -liptc /usr/lib$(ARCH)/libiptc.a +endif # ($(TEST_LIB), 1) +endif # ($(TARGET_OPENWRT),) +else # ifdef IPTABLESPATH +# IPTABLESPATH not defined +# the following test has to be verified : +TEST := $(shell test -f /usr/include/xtables.h && grep -q "XTABLES_VERSION_CODE" /usr/include/xtables.h && echo 1) +ifeq ($(TEST), 1) +CPPFLAGS := $(CPPFLAGS) -DIPTABLES_143 +LDLIBS = -liptc +TESTIP4TC := $(shell test -f /lib/libip4tc.so && echo 1) +ifeq ($(TESTIP4TC), 1) +LDLIBS := $(LDLIBS) -lip4tc +endif # ($(TESTIP4TC), 1) +TESTIP6TC := $(shell test -f /lib/libip6tc.so && echo 1) +ifeq ($(TESTIP6TC), 1) +LDLIBS := $(LDLIBS) -lip6tc +endif # ($(TESTIP6TC), 1) +endif # ($(TEST), 1) +endif # ifdef IPTABLESPATH +endif # ifdef PCFILE_FOUND -CPPFLAGS += -I../iptables/include -LDFLAGS = -L../iptables -liptc +#LDLIBS += -lnfnetlink -endif #ifdef IPTABLESPATH +TEST := $(shell $(PKG_CONFIG) --atleast-version=1.0.2 libnetfilter_conntrack && $(PKG_CONFIG) --atleast-version=1.0.3 libmnl && echo 1) +ifeq ($(TEST),1) +CPPFLAGS += -DUSE_NFCT +LDLIBS += $(shell $(PKG_CONFIG) --static --libs-only-l libmnl) +LDLIBS += $(shell $(PKG_CONFIG) --static --libs-only-l libnetfilter_conntrack) +endif # ($(TEST),1) + +LDLIBS += $(shell $(PKG_CONFIG) --static --libs-only-l libssl) TESTUPNPDESCGENOBJS = testupnpdescgen.o upnpdescgen.o -EXECUTABLES = miniupnpd -#EXECUTABLES = miniupnpd testupnpdescgen testgetifstats \ -# testupnppermissions miniupnpdctl testgetifaddr \ -# testgetroute testasyncsendto testportinuse +EXECUTABLES = miniupnpd testupnpdescgen testgetifstats \ + testupnppermissions miniupnpdctl testgetifaddr \ + testgetroute testasyncsendto testportinuse \ + testssdppktgen .PHONY: all clean install depend genuuid @@ -101,6 +168,7 @@ clean: $(RM) testgetroute.o testasyncsendto.o $(RM) testportinuse.o $(RM) miniupnpdctl.o + $(RM) validateupnppermissions validategetifaddr validatessdppktgen install: miniupnpd miniupnpd.8 miniupnpd.conf genuuid \ netfilter/iptables_init.sh netfilter/iptables_removeall.sh \ @@ -131,6 +199,20 @@ else sed -i -e "s/^uuid=[-0-9a-f]*/uuid=`($(STAGING_DIR_HOST)/bin/genuuid||$(STAGING_DIR_HOST)/bin/uuidgen||$(STAGING_DIR_HOST)/bin/uuid) 2>/dev/null`/" miniupnpd.conf endif +check: validateupnppermissions validategetifaddr validatessdppktgen + +validateupnppermissions: testupnppermissions testupnppermissions.sh + ./testupnppermissions.sh + touch $@ + +validategetifaddr: testgetifaddr testgetifaddr.sh + ./testgetifaddr.sh + touch $@ + +validatessdppktgen: testssdppktgen + ./testssdppktgen + touch $@ + miniupnpd: $(BASEOBJS) $(LNXOBJS) $(NETFILTEROBJS) testupnpdescgen: $(TESTUPNPDESCGENOBJS) @@ -143,6 +225,8 @@ testgetifaddr: testgetifaddr.o getifaddr.o testgetroute: testgetroute.o linux/getroute.o upnputils.o +testssdppktgen: testssdppktgen.o + testasyncsendto: testasyncsendto.o asyncsendto.o upnputils.o \ linux/getroute.o @@ -159,7 +243,7 @@ depend: config.h $(ALLOBJS:.o=.c) $(TESTUPNPDESCGENOBJS:.o=.c) \ testgetifstats.c testupnppermissions.c testgetifaddr.c \ testgetroute.c testasyncsendto.c testportinuse.c \ - miniupnpdctl.c 2>/dev/null + miniupnpdctl.c testssdppktgen.c 2>/dev/null # DO NOT DELETE @@ -228,11 +312,12 @@ testupnpdescgen.o: getifaddr.h upnpdescgen.o: config.h getifaddr.h upnpredirect.h upnpdescgen.h upnpdescgen.o: miniupnpdpath.h upnpglobalvars.h upnppermissions.h upnpdescgen.o: miniupnpdtypes.h upnpdescstrings.h upnpurns.h getconnstatus.h -testgetifstats.o: config.h getifstats.h +testgetifstats.o: getifstats.h testupnppermissions.o: upnppermissions.h config.h -testgetifaddr.o: getifaddr.h +testgetifaddr.o: config.h getifaddr.h testgetroute.o: getroute.h upnputils.h upnpglobalvars.h upnppermissions.h testgetroute.o: config.h miniupnpdtypes.h testasyncsendto.o: miniupnpdtypes.h config.h upnputils.h asyncsendto.h testportinuse.o: macros.h config.h portinuse.h miniupnpdctl.o: macros.h +testssdppktgen.o: macros.h config.h miniupnpdpath.h upnphttp.h diff --git a/release/src/router/miniupnpd/asyncsendto.c b/release/src/router/miniupnpd/asyncsendto.c index 218d3f2328..bd21e93919 100644 --- a/release/src/router/miniupnpd/asyncsendto.c +++ b/release/src/router/miniupnpd/asyncsendto.c @@ -1,4 +1,4 @@ -/* $Id: asyncsendto.c,v 1.6 2014/05/19 14:26:56 nanard Exp $ */ +/* $Id: asyncsendto.c,v 1.7 2015/09/03 18:19:20 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2014 Thomas Bernard @@ -11,10 +11,12 @@ #include #include #include +#include #include #include #include #include +#include #include "asyncsendto.h" #include "upnputils.h" diff --git a/release/src/router/miniupnpd/bsd/getroute.c b/release/src/router/miniupnpd/bsd/getroute.c index e9eda1d584..0663575596 100644 --- a/release/src/router/miniupnpd/bsd/getroute.c +++ b/release/src/router/miniupnpd/bsd/getroute.c @@ -1,7 +1,7 @@ -/* $Id: getroute.c,v 1.4 2014/03/31 12:27:14 nanard Exp $ */ +/* $Id: getroute.c,v 1.12 2015/11/19 11:46:30 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2013 Thomas Bernard + * (c) 2006-2015 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ @@ -20,6 +20,9 @@ #include "../config.h" #include "../upnputils.h" +#ifndef SA_SIZE +#define SA_SIZE(sa) (SA_LEN(sa)) +#endif /* SA_SIZE */ int get_src_for_route_to(const struct sockaddr * dst, @@ -39,12 +42,18 @@ get_src_for_route_to(const struct sockaddr * dst, if(dst == NULL) return -1; -#ifdef __APPLE__ - if(dst->sa_family == AF_INET6) { - syslog(LOG_ERR, "Sorry, get_src_for_route_to() is known to fail with IPV6 on OS X..."); - return -1; + if(dst->sa_len > 0) { + l = dst->sa_len; + } else { + if(dst->sa_family == AF_INET) + l = sizeof(struct sockaddr_in); + else if(dst->sa_family == AF_INET6) + l = sizeof(struct sockaddr_in6); + else { + syslog(LOG_ERR, "unknown address family %d", dst->sa_family); + return -1; + } } -#endif s = socket(PF_ROUTE, SOCK_RAW, dst->sa_family); if(s < 0) { syslog(LOG_ERR, "socket(PF_ROUTE) failed : %m"); @@ -55,9 +64,10 @@ get_src_for_route_to(const struct sockaddr * dst, rtm.rtm_flags = RTF_UP; rtm.rtm_version = RTM_VERSION; rtm.rtm_seq = 1; - rtm.rtm_addrs = RTA_DST; /* destination address */ - memcpy(m_rtmsg.m_space, dst, sizeof(struct sockaddr)); - rtm.rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr); + rtm.rtm_addrs = RTA_DST | RTA_IFA | RTA_IFP; /* pass destination address, request source address & interface */ + memcpy(m_rtmsg.m_space, dst, l); + ((struct sockaddr *)m_rtmsg.m_space)->sa_len = l; + rtm.rtm_msglen = sizeof(struct rt_msghdr) + l; if(write(s, &m_rtmsg, rtm.rtm_msglen) < 0) { syslog(LOG_ERR, "write: %m"); close(s); @@ -71,21 +81,28 @@ get_src_for_route_to(const struct sockaddr * dst, close(s); return -1; } - syslog(LOG_DEBUG, "read l=%d seq=%d pid=%d", - l, rtm.rtm_seq, rtm.rtm_pid); + syslog(LOG_DEBUG, "read l=%d seq=%d pid=%d sizeof(struct rt_msghdr)=%d", + l, rtm.rtm_seq, rtm.rtm_pid, (int)sizeof(struct rt_msghdr)); } while(l > 0 && (rtm.rtm_pid != getpid() || rtm.rtm_seq != 1)); close(s); + if(l <= 0) { + syslog(LOG_WARNING, "no matching ROUTE response message"); + return -1; + } p = m_rtmsg.m_space; if(rtm.rtm_addrs) { for(i=1; i<0x8000; i <<= 1) { if(i & rtm.rtm_addrs) { char tmp[256] = { 0 }; + if(p >= (char *)&m_rtmsg + l) { + syslog(LOG_ERR, "error parsing ROUTE response message"); + break; + } sa = (struct sockaddr *)p; sockaddr_to_string(sa, tmp, sizeof(tmp)); syslog(LOG_DEBUG, "type=%d sa_len=%d sa_family=%d %s", - i, SA_LEN(sa), sa->sa_family, tmp); - if((i == RTA_DST || i == RTA_GATEWAY) && - (src_len && src)) { + i, sa->sa_len, sa->sa_family, tmp); + if(i == RTA_IFA) { size_t len = 0; void * paddr = NULL; if(sa->sa_family == AF_INET) { @@ -96,24 +113,33 @@ get_src_for_route_to(const struct sockaddr * dst, len = sizeof(struct in6_addr); } if(paddr) { - if(*src_len < len) { - syslog(LOG_WARNING, "cannot copy src. %u<%u", - (unsigned)*src_len, (unsigned)len); - return -1; + if(src && src_len) { + if(*src_len < len) { + syslog(LOG_WARNING, "cannot copy src. %u<%u", + (unsigned)*src_len, (unsigned)len); + return -1; + } + memcpy(src, paddr, len); + *src_len = len; } - memcpy(src, paddr, len); - *src_len = len; found = 1; } } #ifdef AF_LINK - if(sa->sa_family == AF_LINK) { + else if((i == RTA_IFP) && (sa->sa_family == AF_LINK)) { struct sockaddr_dl * sdl = (struct sockaddr_dl *)sa; if(index) *index = sdl->sdl_index; } #endif - p += SA_LEN(sa); + /* at least 4 bytes per address are reserved, + * that is true with OpenBSD 4.3. + * The test is only useful when SA_SIZE() is not properly + * defined, as it should be always >= sizeof(long) */ + if(SA_SIZE(sa) > 0) + p += SA_SIZE(sa); + else + p += sizeof(long); } } } diff --git a/release/src/router/miniupnpd/codelength.h b/release/src/router/miniupnpd/codelength.h index d342bd1419..f5f8e30f9a 100644 --- a/release/src/router/miniupnpd/codelength.h +++ b/release/src/router/miniupnpd/codelength.h @@ -1,7 +1,7 @@ -/* $Id: codelength.h,v 1.4 2012/09/27 15:40:29 nanard Exp $ */ +/* $Id: codelength.h,v 1.5 2015/07/09 12:40:18 nanard Exp $ */ /* Project : miniupnp * Author : Thomas BERNARD - * copyright (c) 2005-2011 Thomas Bernard + * copyright (c) 2005-2015 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENCE file. */ #ifndef CODELENGTH_H_INCLUDED @@ -10,10 +10,30 @@ /* Encode length by using 7bit per Byte : * Most significant bit of each byte specifies that the * following byte is part of the code */ + +/* n : unsigned + * p : unsigned char * + */ #define DECODELENGTH(n, p) n = 0; \ do { n = (n << 7) | (*p & 0x7f); } \ while((*(p++)&0x80) && (n<(1<<25))); +/* n : unsigned + * READ : function/macro to read one byte (unsigned char) + */ +#define DECODELENGTH_READ(n, READ) \ + n = 0; \ + do { \ + unsigned char c; \ + READ(c); \ + n = (n << 7) | (c & 0x07f); \ + if(!(c&0x80)) break; \ + } while(n<(1<<25)); + +/* n : unsigned + * p : unsigned char * + * p_limit : unsigned char * + */ #define DECODELENGTH_CHECKLIMIT(n, p, p_limit) \ n = 0; \ do { \ @@ -21,11 +41,14 @@ n = (n << 7) | (*(p) & 0x7f); \ } while((*((p)++)&0x80) && (n<(1<<25))); + +/* n : unsigned + * p : unsigned char * + */ #define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \ if(n>=2097152) *(p++) = (n >> 21) | 0x80; \ if(n>=16384) *(p++) = (n >> 14) | 0x80; \ if(n>=128) *(p++) = (n >> 7) | 0x80; \ *(p++) = n & 0x7f; -#endif - +#endif /* CODELENGTH_H_INCLUDED */ diff --git a/release/src/router/miniupnpd/genconfig.sh b/release/src/router/miniupnpd/genconfig.sh index f3d0ed2380..2c0f82f778 100755 --- a/release/src/router/miniupnpd/genconfig.sh +++ b/release/src/router/miniupnpd/genconfig.sh @@ -1,11 +1,16 @@ #! /bin/sh -# $Id: genconfig.sh,v 1.78 2014/12/10 09:34:42 nanard Exp $ +# $Id: genconfig.sh,v 1.87 2016/01/01 11:16:29 nanard Exp $ # miniupnp daemon # http://miniupnp.free.fr or http://miniupnp.tuxfamily.org/ -# (c) 2006-2014 Thomas Bernard +# (c) 2006-2015 Thomas Bernard # This software is subject to the conditions detailed in the # LICENCE file provided within the distribution +# default to UPnP Device Architecture (UDA) v1.1 +# some control points do not like UDA v2.0 +UPNP_VERSION_MAJOR=1 +UPNP_VERSION_MINOR=1 + for argv; do case "$argv" in --ipv6) IPV6=1 ;; @@ -15,6 +20,16 @@ case "$argv" in --vendorcfg) VENDORCFG=1 ;; --pcp-peer) PCP_PEER=1 ;; --portinuse) PORTINUSE=1 ;; + --uda-version=*) + UPNP_VERSION=$(echo $argv | cut -d= -f2) + UPNP_VERSION_MAJOR=$(echo $UPNP_VERSION | cut -s -d. -f1) + UPNP_VERSION_MINOR=$(echo $UPNP_VERSION | cut -s -d. -f2) + echo "Setting UPnP version major=$UPNP_VERSION_MAJOR minor=$UPNP_VERSION_MINOR" + if [ -z "$UPNP_VERSION_MAJOR" ] || [ -z "$UPNP_VERSION_MINOR" ] ; then + echo "UPnP Version invalid in option $argv" + exit 1 + fi ;; + --disable-pppconn) DISABLEPPPCONN=1 ;; --help|-h) echo "Usage : $0 [options]" echo " --ipv6 enable IPv6" @@ -24,6 +39,8 @@ case "$argv" in echo " --vendorcfg enable configuration of manufacturer info" echo " --pcp-peer enable PCP PEER operation" echo " --portinuse enable port in use check" + echo " --uda-version=x.x set advertised UPnP version (default to ${UPNP_VERSION_MAJOR}.${UPNP_VERSION_MINOR})" + echo " --disable-pppconn disable WANPPPConnection" exit 1 ;; *) @@ -36,13 +53,11 @@ done RM="rm -f" MV="mv" -CONFIGFILE="config.h.tmp" +CONFIGFILE=`mktemp tmp.config.h.XXXXXXXXXX` CONFIGFILE_FINAL="config.h" CONFIGMACRO="CONFIG_H_INCLUDED" -# version reported in XML descriptions -#UPNP_VERSION=20070827 -UPNP_VERSION=`date +"%Y%m%d"` +MINIUPNPD_DATE=`date +"%Y%m%d"` # Facility to syslog LOG_MINIUPNPD="LOG_DAEMON" @@ -79,15 +94,17 @@ fi # Tomato USB special case if [ -f ../shared/tomato_version ]; then OS_NAME=Tomato - OS_VERSION="Tomato $(cat ../shared/tomato_version)" + TOMATO_VER=`cat ../shared/tomato_version | cut -d' ' -f2,3` + OS_VERSION="Tomato $TOMATO_VER" fi ${RM} ${CONFIGFILE} echo "/* MiniUPnP Project" >> ${CONFIGFILE} echo " * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/" >> ${CONFIGFILE} -echo " * (c) 2006-2014 Thomas Bernard" >> ${CONFIGFILE} +echo " * (c) 2006-2015 Thomas Bernard" >> ${CONFIGFILE} echo " * generated by $0 on `date`" >> ${CONFIGFILE} +echo " * `uname -a`" >> ${CONFIGFILE} echo " * using command line options $* */" >> ${CONFIGFILE} echo "#ifndef $CONFIGMACRO" >> ${CONFIGFILE} echo "#define $CONFIGMACRO" >> ${CONFIGFILE} @@ -95,8 +112,26 @@ echo "" >> ${CONFIGFILE} echo "#include " >> ${CONFIGFILE} echo "" >> ${CONFIGFILE} echo "#define MINIUPNPD_VERSION \"`cat VERSION`\"" >> ${CONFIGFILE} +echo "#define MINIUPNPD_DATE \"$MINIUPNPD_DATE\"" >> ${CONFIGFILE} +echo "" >> ${CONFIGFILE} + +cat >> ${CONFIGFILE} <> ${CONFIGFILE} +cat >> ${CONFIGFILE} <> ${CONFIGFILE} -echo "#define UPNP_VERSION \"$UPNP_VERSION\"" >> ${CONFIGFILE} # OS Specific stuff case $OS_NAME in @@ -130,6 +165,7 @@ case $OS_NAME in if [ $VER -ge 700049 ]; then echo "#define PFRULE_INOUT_COUNTS" >> ${CONFIGFILE} fi + HAVE_IP_MREQN=1 # new way to see which one to use PF or IPF. # see http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=957 if [ -f /etc/rc.subr ] && [ -f /etc/rc.conf ] ; then @@ -218,6 +254,10 @@ case $OS_NAME in KERNVERC=`echo $OS_VERSION | awk -F. '{print $3}'` KERNVERD=`echo $OS_VERSION | awk -F. '{print $4}'` #echo "$KERNVERA.$KERNVERB.$KERNVERC.$KERNVERD" + # from the 2.4 version, struct ip_mreqn instead of struct ip_mreq + if [ \( $KERNVERA -ge 3 \) -o \( $KERNVERA -eq 2 -a $KERNVERB -ge 4 \) ]; then + HAVE_IP_MREQN=1 + fi # Debian GNU/Linux special case if [ -f /etc/debian_version ]; then OS_NAME=Debian @@ -266,6 +306,10 @@ case $OS_NAME in OS_NAME=UPnP OS_URL=http://tomatousb.org/ echo "" >> ${CONFIGFILE} + echo "#ifndef TOMATO" >> ${CONFIGFILE} + echo "#define TOMATO" >> ${CONFIGFILE} + echo "#endif" >> ${CONFIGFILE} + echo "" >> ${CONFIGFILE} echo "#ifdef LINUX26" >> ${CONFIGFILE} echo "#define USE_IFACEWATCHER 1" >> ${CONFIGFILE} echo "#endif" >> ${CONFIGFILE} @@ -413,6 +457,15 @@ echo "/*#define HAS_DUMMY_SERVICE*/" >> ${CONFIGFILE} echo "#define ENABLE_L3F_SERVICE" >> ${CONFIGFILE} echo "" >> ${CONFIGFILE} +echo "/* define ADVERTISE_WANPPPCONN to allow buggy Control Point to use" >> ${CONFIGFILE} +echo " * WANPPPConnection instead of WANIPConnection. */" >> ${CONFIGFILE} +if [ -n "$STRICT" ] || [ -n "$DISABLEPPPCONN" ] ; then + echo "/*#define ADVERTISE_WANPPPCONN*/" >> ${CONFIGFILE} +else + echo "#define ADVERTISE_WANPPPCONN" >> ${CONFIGFILE} +fi +echo "" >> ${CONFIGFILE} + echo "/* Enable IP v6 support */" >> ${CONFIGFILE} if [ -n "$IPV6" ]; then echo "#define ENABLE_IPV6" >> ${CONFIGFILE} @@ -430,6 +483,11 @@ else fi echo "" >> ${CONFIGFILE} +if [ -n "$HAVE_IP_MREQN" ]; then + echo "#define HAVE_IP_MREQN" >> ${CONFIGFILE} + echo "" >> ${CONFIGFILE} +fi + echo "/* Enable the support of IGD v2 specification." >> ${CONFIGFILE} echo " * This is not fully tested yet and can cause incompatibilities with some" >> ${CONFIGFILE} echo " * control points, so enable with care. */" >> ${CONFIGFILE} @@ -521,6 +579,14 @@ cat >> ${CONFIGFILE} <> ${CONFIGFILE} <> ${CONFIGFILE} diff --git a/release/src/router/miniupnpd/getifaddr.c b/release/src/router/miniupnpd/getifaddr.c index 6bbbe78d83..3febe64b83 100644 --- a/release/src/router/miniupnpd/getifaddr.c +++ b/release/src/router/miniupnpd/getifaddr.c @@ -1,4 +1,4 @@ -/* $Id: getifaddr.c,v 1.23 2014/05/06 14:40:53 nanard Exp $ */ +/* $Id: getifaddr.c,v 1.24 2015/07/09 12:27:26 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2014 Thomas Bernard @@ -47,6 +47,7 @@ getifaddr(const char * ifname, char * buf, int len, return -1; } strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ-1] = '\0'; if(ioctl(s, SIOCGIFFLAGS, &ifr, &ifrlen) < 0) { syslog(LOG_DEBUG, "ioctl(s, SIOCGIFFLAGS, ...): %m"); diff --git a/release/src/router/miniupnpd/ipf/ipfrdr.c b/release/src/router/miniupnpd/ipf/ipfrdr.c index 6d21ad1711..5a2dc02c6d 100644 --- a/release/src/router/miniupnpd/ipf/ipfrdr.c +++ b/release/src/router/miniupnpd/ipf/ipfrdr.c @@ -1,4 +1,4 @@ -/* $Id: ipfrdr.c,v 1.16 2013/05/20 00:07:47 nanard Exp $ */ +/* $Id: ipfrdr.c,v 1.17 2016/01/13 15:51:07 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2007 Darren Reed @@ -723,7 +723,7 @@ unsigned short * get_portmappings_in_range(unsigned short startport, unsigned short endport, int proto, unsigned int * number) { - unsigned short * array; + unsigned short *array, *array2; unsigned int capacity; unsigned short eport; ipfgeniter_t iter; @@ -742,7 +742,7 @@ get_portmappings_in_range(unsigned short startport, unsigned short endport, syslog(LOG_ERR, "get_portmappings_in_range() : calloc error"); return NULL; } - + memset(&obj, 0, sizeof(obj)); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_ptr = &iter; @@ -761,10 +761,10 @@ get_portmappings_in_range(unsigned short startport, unsigned short endport, "get_portmappings_in_range"); break; } - + if (strcmp(ipn.in_tag.ipt_tag, group_name) != 0) continue; - + #if IPFILTER_VERSION >= 5000000 eport = ntohs(ipn.in_dpmin); if( (eport == ntohs(ipn.in_dpmax)) @@ -781,13 +781,15 @@ get_portmappings_in_range(unsigned short startport, unsigned short endport, { /* need to increase the capacity of the array */ capacity += 128; - array = realloc(array, sizeof(unsigned short)*capacity); - if(!array) + array2 = realloc(array, sizeof(unsigned short)*capacity); + if(!array2) { syslog(LOG_ERR, "get_portmappings_in_range() : realloc(%lu) error", sizeof(unsigned short)*capacity); *number = 0; + free(array); return NULL; } + array = array2; } array[*number] = eport; (*number)++; diff --git a/release/src/router/miniupnpd/ipfw/ipfwaux.h b/release/src/router/miniupnpd/ipfw/ipfwaux.h index 1cb17e17f5..44d4046041 100644 --- a/release/src/router/miniupnpd/ipfw/ipfwaux.h +++ b/release/src/router/miniupnpd/ipfw/ipfwaux.h @@ -1,4 +1,4 @@ -/* $Id: ipfwaux.h,v 1.5 2012/09/20 12:46:01 nanard Exp $ */ +/* $Id: ipfwaux.h,v 1.6 2015/09/04 14:20:58 nanard Exp $ */ /* * MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ @@ -10,6 +10,8 @@ #define IPFWAUX_H #include +#include +#include #include #include diff --git a/release/src/router/miniupnpd/ipfw/ipfwrdr.c b/release/src/router/miniupnpd/ipfw/ipfwrdr.c index 5b54f904be..c83810f492 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.13 2012/03/05 20:36:19 nanard Exp $ */ +/* $Id: ipfwrdr.c,v 1.15 2016/01/13 15:51:06 nanard Exp $ */ /* * MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ @@ -9,6 +9,7 @@ */ #include "../config.h" +#include "../macros.h" #include #include @@ -327,6 +328,13 @@ int add_filter_rule2( int proto, const char * desc) { + UNUSED(ifname); + UNUSED(rhost); + UNUSED(iaddr); + UNUSED(eport); + UNUSED(iport); + UNUSED(proto); + UNUSED(desc); return 0; /* nothing to do, always success */ } @@ -335,6 +343,9 @@ int delete_filter_rule( unsigned short eport, int proto) { + UNUSED(ifname); + UNUSED(eport); + UNUSED(proto); return 0; /* nothing to do, always success */ } @@ -419,7 +430,7 @@ get_portmappings_in_range(unsigned short startport, int proto, unsigned int * number) { - unsigned short * array = NULL; + unsigned short *array = NULL, *array2 = NULL; unsigned int capacity = 128; int i, count_rules, total_rules = 0; struct ip_fw * rules = NULL; @@ -448,12 +459,14 @@ get_portmappings_in_range(unsigned short startport, && eport <= endport) { if(*number >= capacity) { capacity += 128; - array = realloc(array, sizeof(unsigned short)*capacity); - if(!array) { + array2 = realloc(array, sizeof(unsigned short)*capacity); + if(!array2) { syslog(LOG_ERR, "get_portmappings_in_range() : realloc(%lu) error", sizeof(unsigned short)*capacity); *number = 0; + free(array); goto error; } + array = array2; } array[*number] = eport; (*number)++; diff --git a/release/src/router/miniupnpd/linux/getifstats.c b/release/src/router/miniupnpd/linux/getifstats.c index 3feabdd0a9..fc35ba654e 100644 --- a/release/src/router/miniupnpd/linux/getifstats.c +++ b/release/src/router/miniupnpd/linux/getifstats.c @@ -1,4 +1,4 @@ -/* $Id: getifstats.c,v 1.12 2013/04/29 10:18:20 nanard Exp $ */ +/* $Id: getifstats.c,v 1.13 2015/06/09 15:33:24 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2013 Thomas Bernard diff --git a/release/src/router/miniupnpd/linux/getroute.c b/release/src/router/miniupnpd/linux/getroute.c index 4daddf57e7..1b29804e04 100644 --- a/release/src/router/miniupnpd/linux/getroute.c +++ b/release/src/router/miniupnpd/linux/getroute.c @@ -5,8 +5,6 @@ * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ -#ifdef UPNP_STRICT - #include #include #include @@ -197,4 +195,3 @@ error: return -1; } -#endif /* UPNP_STRICT */ diff --git a/release/src/router/miniupnpd/macros.h b/release/src/router/miniupnpd/macros.h index ab83aec831..7b7e31c5c0 100644 --- a/release/src/router/miniupnpd/macros.h +++ b/release/src/router/miniupnpd/macros.h @@ -1,7 +1,7 @@ -/* $Id: macros.h,v 1.2 2012/09/27 16:00:10 nanard Exp $ */ +/* $Id: macros.h,v 1.3 2015/09/22 10:10:54 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2012 Thomas Bernard + * (c) 2012-2015 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ @@ -10,5 +10,36 @@ #define UNUSED(arg) (void)(arg) -#endif +#include +#define INLINE static inline +/* theses macros are designed to read/write unsigned short/long int + * from an unsigned char array in network order (big endian). + * Avoid pointer casting, so avoid accessing unaligned memory, which + * can crash with some cpu's */ +INLINE uint32_t readnu32(const uint8_t * p) +{ + return (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]); +} +#define READNU32(p) readnu32(p) +INLINE uint16_t readnu16(const uint8_t * p) +{ + return (p[0] << 8 | p[1]); +} +#define READNU16(p) readnu16(p) +INLINE void writenu32(uint8_t * p, uint32_t n) +{ + p[0] = (n & 0xff000000) >> 24; + p[1] = (n & 0xff0000) >> 16; + p[2] = (n & 0xff00) >> 8; + p[3] = n & 0xff; +} +#define WRITENU32(p, n) writenu32(p, n) +INLINE void writenu16(uint8_t * p, uint16_t n) +{ + p[0] = (n & 0xff00) >> 8; + p[1] = n & 0xff; +} +#define WRITENU16(p, n) writenu16(p, n) + +#endif /* MACROS_H_INCLUDED */ diff --git a/release/src/router/miniupnpd/minissdp.c b/release/src/router/miniupnpd/minissdp.c index 92f7b75270..e9d8371a12 100644 --- a/release/src/router/miniupnpd/minissdp.c +++ b/release/src/router/miniupnpd/minissdp.c @@ -1,4 +1,4 @@ -/* $Id: minissdp.c,v 1.74 2015/04/30 08:59:51 nanard Exp $ */ +/* $Id: minissdp.c,v 1.83 2015/12/15 11:08:24 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2015 Thomas Bernard @@ -35,29 +35,43 @@ #define SL_SSDP_MCAST_ADDR "FF05::C" #define GL_SSDP_MCAST_ADDR "FF0E::C" -/* maximum lenght of SSDP packets we are generating - * (reception is done in a 1500byte buffer) */ -#ifdef ENABLE_HTTPS -#define SSDP_PACKET_MAX_LEN 768 -#else -#define SSDP_PACKET_MAX_LEN 512 -#endif - /* AddMulticastMembership() - * param s socket - * param ifaddr ip v4 address + * param s socket + * param lan_addr lan address */ static int -AddMulticastMembership(int s, in_addr_t ifaddr) +AddMulticastMembership(int s, struct lan_addr_s * lan_addr) { +#ifndef HAVE_IP_MREQN + /* The ip_mreqn structure appeared in Linux 2.4. */ struct ip_mreq imr; /* Ip multicast membership */ +#else /* HAVE_IP_MREQN */ + struct ip_mreqn imr; /* Ip multicast membership */ +#endif /* HAVE_IP_MREQN */ /* setting up imr structure */ imr.imr_multiaddr.s_addr = inet_addr(SSDP_MCAST_ADDR); /*imr.imr_interface.s_addr = htonl(INADDR_ANY);*/ - imr.imr_interface.s_addr = ifaddr; /*inet_addr(ifaddr);*/ +#ifndef HAVE_IP_MREQN + imr.imr_interface.s_addr = lan_addr->addr.s_addr; +#else /* HAVE_IP_MREQN */ + imr.imr_address.s_addr = lan_addr->addr.s_addr; +#ifndef MULTIPLE_EXTERNAL_IP +#ifdef ENABLE_IPV6 + imr.imr_ifindex = lan_addr->index; +#else /* ENABLE_IPV6 */ + imr.imr_ifindex = if_nametoindex(lan_addr->ifname); +#endif /* ENABLE_IPV6 */ +#else /* MULTIPLE_EXTERNAL_IP */ + imr.imr_ifindex = 0; +#endif /* MULTIPLE_EXTERNAL_IP */ +#endif /* HAVE_IP_MREQN */ +#ifndef HAVE_IP_MREQN if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&imr, sizeof(struct ip_mreq)) < 0) +#else /* HAVE_IP_MREQN */ + if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&imr, sizeof(struct ip_mreqn)) < 0) +#endif /* HAVE_IP_MREQN */ { syslog(LOG_ERR, "setsockopt(udp, IP_ADD_MEMBERSHIP): %m"); return -1; @@ -155,6 +169,20 @@ OpenAndConfSSDPReceiveSocket(int ipv6) "OpenAndConfSSDPReceiveSocket"); } +#if defined(SO_BINDTODEVICE) && !defined(MULTIPLE_EXTERNAL_IP) + /* One and only one LAN interface */ + if(lan_addrs.lh_first != NULL && lan_addrs.lh_first->list.le_next == NULL + && strlen(lan_addrs.lh_first->ifname) > 0) + { + if(setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, + lan_addrs.lh_first->ifname, + strlen(lan_addrs.lh_first->ifname)) < 0) + syslog(LOG_WARNING, "%s: setsockopt(udp%s, SO_BINDTODEVICE, %s): %m", + "OpenAndConfSSDPReceiveSocket", ipv6 ? "6" : "", + lan_addrs.lh_first->ifname); + } +#endif /* defined(SO_BINDTODEVICE) && !defined(MULTIPLE_EXTERNAL_IP) */ + if(bind(s, (struct sockaddr *)&sockname, sockname_len) < 0) { syslog(LOG_ERR, "%s: bind(udp%s): %m", @@ -181,11 +209,11 @@ OpenAndConfSSDPReceiveSocket(int ipv6) { for(lan_addr = lan_addrs.lh_first; lan_addr != NULL; lan_addr = lan_addr->list.le_next) { - if(AddMulticastMembership(s, lan_addr->addr.s_addr) < 0) + if(AddMulticastMembership(s, lan_addr) < 0) { syslog(LOG_WARNING, "Failed to add multicast membership for interface %s", - lan_addr->str ? lan_addr->str : "NULL"); + strlen(lan_addr->str) ? lan_addr->str : "NULL"); } } } @@ -469,14 +497,6 @@ SendSSDPResponse(int s, const struct sockaddr * addr, } } -#ifndef IGD_V2 -#define IGD_VER 1 -#define WANIPC_VER 1 -#else -#define IGD_VER 2 -#define WANIPC_VER 2 -#endif - static struct { const char * s; const int version; @@ -484,23 +504,32 @@ static struct { } const known_service_types[] = { {"upnp:rootdevice", 0, uuidvalue_igd}, - {"urn:schemas-upnp-org:device:InternetGatewayDevice:", IGD_VER, uuidvalue_igd}, +#ifdef IGD_V2 + {"urn:schemas-upnp-org:device:InternetGatewayDevice:", 2, uuidvalue_igd}, + {"urn:schemas-upnp-org:device:WANConnectionDevice:", 2, uuidvalue_wcd}, + {"urn:schemas-upnp-org:device:WANDevice:", 2, uuidvalue_wan}, + {"urn:schemas-upnp-org:service:WANIPConnection:", 2, uuidvalue_wcd}, + {"urn:schemas-upnp-org:service:DeviceProtection:", 1, uuidvalue_igd}, +#ifdef ENABLE_6FC_SERVICE + {"urn:schemas-upnp-org:service:WANIPv6FirewallControl:", 1, uuidvalue_wcd}, +#endif +#else /* IGD_V2 */ + /* IGD v1 */ + {"urn:schemas-upnp-org:device:InternetGatewayDevice:", 1, uuidvalue_igd}, {"urn:schemas-upnp-org:device:WANConnectionDevice:", 1, uuidvalue_wcd}, {"urn:schemas-upnp-org:device:WANDevice:", 1, uuidvalue_wan}, + {"urn:schemas-upnp-org:service:WANIPConnection:", 1, uuidvalue_wcd}, +#endif /* IGD_V2 */ {"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:", 1, uuidvalue_wan}, - {"urn:schemas-upnp-org:service:WANIPConnection:", WANIPC_VER, uuidvalue_wcd}, -#ifndef UPNP_STRICT +#ifdef ADVERTISE_WANPPPCONN /* We use WAN IP Connection, not PPP connection, * but buggy control points may try to use WanPPPConnection * anyway */ {"urn:schemas-upnp-org:service:WANPPPConnection:", 1, uuidvalue_wcd}, -#endif +#endif /* ADVERTISE_WANPPPCONN */ #ifdef ENABLE_L3F_SERVICE {"urn:schemas-upnp-org:service:Layer3Forwarding:", 1, uuidvalue_igd}, -#endif -#ifdef ENABLE_6FC_SERVICE - {"url:schemas-upnp-org:service:WANIPv6FirewallControl:", 1, uuidvalue_wcd}, -#endif +#endif /* ENABLE_L3F_SERVICE */ /* we might want to support urn:schemas-wifialliance-org:device:WFADevice:1 * urn:schemas-wifialliance-org:device:WFADevice:1 * in the future */ @@ -1237,6 +1266,7 @@ SubmitServicesToMiniSSDPD(const char * host, unsigned short port) { } addr.sun_family = AF_UNIX; strncpy(addr.sun_path, minissdpdsocketpath, sizeof(addr.sun_path)); + addr.sun_path[sizeof(addr.sun_path) - 1] = '\0'; if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) { syslog(LOG_ERR, "connect(\"%s\"): %m", minissdpdsocketpath); close(s); diff --git a/release/src/router/miniupnpd/miniupnpd.c b/release/src/router/miniupnpd/miniupnpd.c index 6517a304a1..45e88fc853 100644 --- a/release/src/router/miniupnpd/miniupnpd.c +++ b/release/src/router/miniupnpd/miniupnpd.c @@ -1,4 +1,4 @@ -/* $Id: miniupnpd.c,v 1.207 2015/03/07 15:53:50 nanard Exp $ */ +/* $Id: miniupnpd.c,v 1.214 2016/01/01 11:15:56 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2015 Thomas Bernard @@ -49,7 +49,9 @@ #include #endif +#ifdef TOMATO #include +#endif /* TOMATO */ #include "macros.h" #include "upnpglobalvars.h" #include "upnphttp.h" @@ -93,7 +95,7 @@ struct ctlelem { int socket; LIST_ENTRY(ctlelem) entries; }; -#endif +#endif /* USE_MINIUPNPDCTL */ #ifdef ENABLE_NFQUEUE /* globals */ @@ -104,22 +106,25 @@ static struct sockaddr_in ssdp; static int nfqueue_cb( struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data) ; int identify_ip_protocol (char *payload); int get_udp_dst_port (char *payload); -#endif +#endif /* ENABLE_NFQUEUE */ /* variables used by signals */ static volatile sig_atomic_t quitting = 0; volatile sig_atomic_t should_send_public_address_change_notif = 0; - +#ifdef TOMATO #if 1 -static volatile int gotusr2 = 0; +/* Tomato specific code */ +static volatile sig_atomic_t gotusr2 = 0; -static void sigusr2(int sig) +static void +sigusr2(int sig) { gotusr2 = 1; } -static void tomato_save(const char *fname) +static void +tomato_save(const char *fname) { unsigned short eport; unsigned short iport; @@ -133,12 +138,15 @@ static void tomato_save(const char *fname) FILE *f; int t; char tmp[128]; - + strcpy(tmp, "/etc/upnp/saveXXXXXX"); - if ((t = mkstemp(tmp)) != -1) { - if ((f = fdopen(t, "w")) != NULL) { + if ((t = mkstemp(tmp)) != -1) + { + if ((f = fdopen(t, "w")) != NULL) + { n = 0; - while (upnp_get_redirection_infos_by_index(n, &eport, proto, &iport, iaddr, sizeof(iaddr), desc, sizeof(desc), rhost, sizeof(rhost), &leaseduration) == 0) { + while (upnp_get_redirection_infos_by_index(n, &eport, proto, &iport, iaddr, sizeof(iaddr), desc, sizeof(desc), rhost, sizeof(rhost), &leaseduration) == 0) + { timestamp = (leaseduration > 0) ? time(NULL) + leaseduration : 0; fprintf(f, "%s %u %s %u [%s] %u\n", proto, eport, iaddr, iport, desc, timestamp); ++n; @@ -146,14 +154,16 @@ static void tomato_save(const char *fname) fclose(f); rename(tmp, fname); } - else { + else + { close(t); } unlink(tmp); } } -static void tomato_load(void) +static void +tomato_load(void) { FILE *f; char s[256]; @@ -167,18 +177,24 @@ static void tomato_load(void) char *rhost; char *a, *b; - if ((f = fopen("/etc/upnp/data", "r")) != NULL) { + if ((f = fopen("/etc/upnp/data", "r")) != NULL) + { current_time = time(NULL); s[sizeof(s) - 1] = 0; while (fgets(s, sizeof(s) - 1, f)) { - if (sscanf(s, "%3s %hu %31s %hu [%*s] %u", proto, &eport, iaddr, &iport, ×tamp) >= 4) { - if (((a = strchr(s, '[')) != NULL) && ((b = strrchr(a, ']')) != NULL)) { - if (timestamp > 0) { + if (sscanf(s, "%3s %hu %31s %hu [%*s] %u", proto, &eport, iaddr, &iport, ×tamp) >= 4) + { + if (((a = strchr(s, '[')) != NULL) && ((b = strrchr(a, ']')) != NULL)) + { + if (timestamp > 0) + { if (timestamp > current_time) leaseduration = current_time - timestamp; else continue; - } else { + } + else + { leaseduration = 0; /* default value */ } *b = 0; @@ -193,11 +209,12 @@ static void tomato_load(void) #if 0 ScanNATPMPforExpiration(); #endif -#endif +#endif /* ENABLE_NATPMP */ unlink("/etc/upnp/load"); } -static void tomato_delete(void) +static void +tomato_delete(void) { FILE *f; char s[128]; @@ -210,20 +227,27 @@ static void tomato_delete(void) char rhost[32]; int n; - if ((f = fopen("/etc/upnp/delete", "r")) != NULL) { + if ((f = fopen("/etc/upnp/delete", "r")) != NULL) + { s[sizeof(s) - 1] = 0; - while (fgets(s, sizeof(s) - 1, f)) { - if (sscanf(s, "%3s %hu", proto, &eport) == 2) { - if (proto[0] == '*') { + while (fgets(s, sizeof(s) - 1, f)) + { + if (sscanf(s, "%3s %hu", proto, &eport) == 2) + { + if (proto[0] == '*') + { n = upnp_get_portmapping_number_of_entries(); - while (--n >= 0) { - if (upnp_get_redirection_infos_by_index(n, &eport, proto, &iport, iaddr, sizeof(iaddr), desc, sizeof(desc), rhost, sizeof(rhost), &leaseduration) == 0) { + while (--n >= 0) + { + if (upnp_get_redirection_infos_by_index(n, &eport, proto, &iport, iaddr, sizeof(iaddr), desc, sizeof(desc), rhost, sizeof(rhost), &leaseduration) == 0) + { upnp_delete_redirection(eport, proto); } } break; } - else { + else + { upnp_delete_redirection(eport, proto); } } @@ -233,30 +257,35 @@ static void tomato_delete(void) } } -static void tomato_helper(void) +static void +tomato_helper(void) { struct stat st; - if (stat("/etc/upnp/delete", &st) == 0) { + if (stat("/etc/upnp/delete", &st) == 0) + { tomato_delete(); } - if (stat("/etc/upnp/load", &st) == 0) { + if (stat("/etc/upnp/load", &st) == 0) + { tomato_load(); } - if (stat("/etc/upnp/save", &st) == 0) { + if (stat("/etc/upnp/save", &st) == 0) + { tomato_save("/etc/upnp/data"); unlink("/etc/upnp/save"); } - if (stat("/etc/upnp/info", &st) == 0) { + if (stat("/etc/upnp/info", &st) == 0) + { tomato_save("/etc/upnp/data.info"); unlink("/etc/upnp/info"); } } -#endif /* 1 (tomato) */ - +#endif /* 1 (tomato) */ +#endif /* TOMATO */ /* OpenAndConfHTTPSocket() : * setup the socket used to handle incoming HTTP connections. */ @@ -341,6 +370,19 @@ OpenAndConfHTTPSocket(unsigned short * port) listenname_len = sizeof(struct sockaddr_in); #endif +#if defined(SO_BINDTODEVICE) && !defined(MULTIPLE_EXTERNAL_IP) + /* One and only one LAN interface */ + if(lan_addrs.lh_first != NULL && lan_addrs.lh_first->list.le_next == NULL + && strlen(lan_addrs.lh_first->ifname) > 0) + { + if(setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, + lan_addrs.lh_first->ifname, + strlen(lan_addrs.lh_first->ifname)) < 0) + syslog(LOG_WARNING, "setsockopt(http, SO_BINDTODEVICE, %s): %m", + lan_addrs.lh_first->ifname); + } +#endif /* defined(SO_BINDTODEVICE) && !defined(MULTIPLE_EXTERNAL_IP) */ + #ifdef ENABLE_IPV6 if(bind(s, ipv6 ? (struct sockaddr *)&listenname6 : (struct sockaddr *)&listenname4, @@ -412,7 +454,9 @@ ProcessIncomingHTTP(int shttpl, const char * protocol) char addr_str[64]; sockaddr_to_string((struct sockaddr *)&clientname, addr_str, sizeof(addr_str)); - syslog(LOG_INFO, "%s connection from %s", protocol, addr_str); +#ifdef DEBUG + syslog(LOG_DEBUG, "%s connection from %s", protocol, addr_str); +#endif /* DEBUG */ if(get_lan_for_peer((struct sockaddr *)&clientname) == NULL) { /* The peer is not a LAN ! */ @@ -453,6 +497,7 @@ ProcessIncomingHTTP(int shttpl, const char * protocol) #else tmp->clientaddr = clientname.sin_addr; #endif + memcpy(tmp->clientaddr_str, addr_str, sizeof(tmp->clientaddr_str)); return tmp; } else @@ -1140,7 +1185,7 @@ init(int argc, char * * argv, struct runtime_vars * v) strncpy(model_url, ary_options[i].value, MODEL_URL_MAX_LEN); model_url[MODEL_URL_MAX_LEN-1] = '\0'; break; -#endif +#endif /* ENABLE_MANUFACTURER_INFO_CONFIGURATION */ #ifdef USE_NETFILTER case UPNPFORWARDCHAIN: miniupnpd_forward_chain = ary_options[i].value; @@ -1148,7 +1193,7 @@ init(int argc, char * * argv, struct runtime_vars * v) case UPNPNATCHAIN: miniupnpd_nat_chain = ary_options[i].value; break; -#endif +#endif /* USE_NETFILTER */ case UPNPNOTIFY_INTERVAL: v->notify_interval = atoi(ary_options[i].value); break; @@ -1161,7 +1206,7 @@ init(int argc, char * * argv, struct runtime_vars * v) if(strcmp(ary_options[i].value, "yes") == 0) SETFLAG(LOGPACKETSMASK); /*logpackets = 1;*/ break; -#endif +#endif /* defined(USE_PF) || defined(USE_IPF) */ case UPNPUUID: strncpy(uuidvalue_igd+5, ary_options[i].value, strlen(uuidvalue_igd+5) + 1); @@ -1191,7 +1236,7 @@ init(int argc, char * * argv, struct runtime_vars * v) case UPNPTAG: tag = ary_options[i].value; break; -#endif +#endif /* USE_PF */ #ifdef ENABLE_NATPMP case UPNPENABLENATPMP: if(strcmp(ary_options[i].value, "yes") == 0) @@ -1201,7 +1246,7 @@ init(int argc, char * * argv, struct runtime_vars * v) SETFLAG(ENABLENATPMPMASK); /*enablenatpmp = atoi(ary_options[i].value);*/ break; -#endif +#endif /* ENABLE_NATPMP */ #ifdef ENABLE_PCP case UPNPPCPMINLIFETIME: min_lifetime = atoi(ary_options[i].value); @@ -1219,13 +1264,13 @@ init(int argc, char * * argv, struct runtime_vars * v) if(strcmp(ary_options[i].value, "yes") == 0) SETFLAG(PCP_ALLOWTHIRDPARTYMASK); break; -#endif +#endif /* ENABLE_PCP */ #ifdef PF_ENABLE_FILTER_RULES case UPNPQUICKRULES: if(strcmp(ary_options[i].value, "no") == 0) SETFLAG(PFNOQUICKRULESMASK); break; -#endif +#endif /* PF_ENABLE_FILTER_RULES */ case UPNPENABLE: if(strcmp(ary_options[i].value, "yes") != 0) CLEARFLAG(ENABLEUPNPMASK); @@ -1238,7 +1283,7 @@ init(int argc, char * * argv, struct runtime_vars * v) case UPNPLEASEFILE: lease_file = ary_options[i].value; break; -#endif +#endif /* ENABLE_LEASEFILE */ case UPNPMINISSDPDSOCKET: minissdpdsocketpath = ary_options[i].value; break; @@ -1254,7 +1299,7 @@ init(int argc, char * * argv, struct runtime_vars * v) fprintf(stderr, "Check your configuration file.\n"); return 1; } -#endif +#endif /* ENABLE_PCP */ } #endif /* DISABLE_CONFIG_FILE */ @@ -1306,7 +1351,7 @@ init(int argc, char * * argv, struct runtime_vars * v) fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]); friendly_name[FRIENDLY_NAME_MAX_LEN-1] = '\0'; break; -#endif +#endif /* ENABLE_MANUFACTURER_INFO_CONFIGURATION */ case 's': if(i+1 < argc) strncpy(serialnumber, argv[++i], SERIALNUMBER_MAX_LEN); @@ -1326,7 +1371,7 @@ init(int argc, char * * argv, struct runtime_vars * v) /*enablenatpmp = 1;*/ SETFLAG(ENABLENATPMPMASK); break; -#endif +#endif /* ENABLE_NATPMP */ case 'U': /*sysuptime = 1;*/ SETFLAG(SYSUPTIMEMASK); @@ -1339,7 +1384,7 @@ init(int argc, char * * argv, struct runtime_vars * v) /*logpackets = 1;*/ SETFLAG(LOGPACKETSMASK); break; -#endif +#endif /* defined(USE_PF) || defined(USE_IPF) */ case 'S': SETFLAG(SECUREMODEMASK); break; @@ -1362,7 +1407,7 @@ init(int argc, char * * argv, struct runtime_vars * v) else fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]); break; -#endif +#endif /* USE_PF */ case 'p': if(i+1 < argc) v->port = atoi(argv[++i]); @@ -1376,7 +1421,7 @@ init(int argc, char * * argv, struct runtime_vars * v) else fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]); break; -#endif +#endif /* ENABLE_HTTPS */ #ifdef ENABLE_NFQUEUE case 'Q': if(i+1 0) { + if(find_ipv6_addr(lan_addrs.lh_first ? lan_addrs.lh_first->ifname : NULL, + ipv6_addr_for_http_with_brackets, sizeof(ipv6_addr_for_http_with_brackets)) > 0) { syslog(LOG_NOTICE, "HTTP IPv6 address given to control points : %s", ipv6_addr_for_http_with_brackets); } else { @@ -1967,7 +2019,9 @@ main(int argc, char * * argv) } #endif - tomato_helper(); // zzz +#ifdef TOMATO + tomato_helper(); +#endif /* main loop */ while(!quitting) @@ -2223,11 +2277,14 @@ main(int argc, char * * argv) if(select(max_fd+1, &readset, &writeset, 0, &timeout) < 0) { if(quitting) goto shutdown; - if (gotusr2) { // zzz +#ifdef TOMATO + if (gotusr2) + { gotusr2 = 0; tomato_helper(); continue; } +#endif /* TOMATO */ if(errno == EINTR) continue; /* interrupted by a signal, start again */ syslog(LOG_ERR, "select(all): %m"); syslog(LOG_ERR, "Failed to select open sockets. EXITING"); @@ -2513,8 +2570,9 @@ shutdown: /* try to send pending packets */ finalize_sendto(); - tomato_save("/etc/upnp/data"); // zzz - +#ifdef TOMATO + tomato_save("/etc/upnp/data"); +#endif /* TOMATO */ /* close out open sockets */ while(upnphttphead.lh_first != NULL) { diff --git a/release/src/router/miniupnpd/miniupnpd.conf b/release/src/router/miniupnpd/miniupnpd.conf index 36040f4127..75e911f4c8 100644 --- a/release/src/router/miniupnpd/miniupnpd.conf +++ b/release/src/router/miniupnpd/miniupnpd.conf @@ -6,7 +6,8 @@ #ext_ip= # LAN network interfaces IPs / networks -# There can be multiple listening IPs for SSDP traffic +# There can be multiple listening IPs for SSDP traffic, in that case +# use multiple 'listening_ip=...' lines, one for each network interface. # It can be IP address or network interface name (ie. "eth0") # It is mandatory to use the network interface name in order to enable IPv6 # HTTP is available on all interfaces. diff --git a/release/src/router/miniupnpd/natpmp.c b/release/src/router/miniupnpd/natpmp.c index 455748e43d..8a6ab4370c 100644 --- a/release/src/router/miniupnpd/natpmp.c +++ b/release/src/router/miniupnpd/natpmp.c @@ -1,4 +1,4 @@ -/* $Id: natpmp.c,v 1.51 2015/02/08 09:18:15 nanard Exp $ */ +/* $Id: natpmp.c,v 1.53 2015/09/22 10:10:54 nanard Exp $ */ /* MiniUPnP project * (c) 2007-2015 Thomas Bernard * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ @@ -29,36 +29,6 @@ #ifdef ENABLE_NATPMP -#define INLINE static inline -/* theses macros are designed to read/write unsigned short/long int - * from an unsigned char array in network order (big endian). - * Avoid pointer casting, so avoid accessing unaligned memory, which - * can crash with some cpu's */ -INLINE uint32_t readnu32(const uint8_t * p) -{ - return (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]); -} -#define READNU32(p) readnu32(p) -INLINE uint16_t readnu16(const uint8_t * p) -{ - return (p[0] << 8 | p[1]); -} -#define READNU16(p) readnu16(p) -INLINE void writenu32(uint8_t * p, uint32_t n) -{ - p[0] = (n & 0xff000000) >> 24; - p[1] = (n & 0xff0000) >> 16; - p[2] = (n & 0xff00) >> 8; - p[3] = n & 0xff; -} -#define WRITENU32(p, n) writenu32(p, n) -INLINE void writenu16(uint8_t * p, uint16_t n) -{ - p[0] = (n & 0xff00) >> 8; - p[1] = n & 0xff; -} -#define WRITENU16(p, n) writenu16(p, n) - int OpenAndConfNATPMPSocket(in_addr_t addr) { int snatpmp; @@ -513,5 +483,4 @@ void SendNATPMPPublicAddressChangeNotification(int * sockets, int n_sockets) } } -#endif - +#endif /* ENABLE_NATPMP */ diff --git a/release/src/router/miniupnpd/netfilter/Makefile b/release/src/router/miniupnpd/netfilter/Makefile index 8a16f4af1c..b6af301c89 100644 --- a/release/src/router/miniupnpd/netfilter/Makefile +++ b/release/src/router/miniupnpd/netfilter/Makefile @@ -1,5 +1,5 @@ -# $Id: Makefile,v 1.6 2012/04/26 13:50:48 nanard Exp $ -CFLAGS?=-Wall -g -D_GNU_SOURCE -DDEBUG -Wstrict-prototypes -Wdeclaration-after-statement -ansi +# $Id: Makefile,v 1.7 2013/12/13 13:10:48 nanard Exp $ +CFLAGS?=-Wall -g -D_GNU_SOURCE -DDEBUG -Wstrict-prototypes -Wdeclaration-after-statement CC = gcc #LIBS = -liptc @@ -38,15 +38,32 @@ endif endif endif -all: iptcrdr.o testiptcrdr iptpinhole.o testiptpinhole +LIBS += /lib/libip4tc.so /lib/libip6tc.so + +all: iptcrdr.o testiptcrdr iptpinhole.o \ + testiptcrdr_peer testiptcrdr_dscp test_nfct_get +# testiptpinhole clean: - $(RM) *.o testiptcrdr testiptpinhole + $(RM) *.o testiptcrdr testiptpinhole testiptcrdr_peer test_nfct_get \ + testiptcrdr_dscp + +testiptcrdr: testiptcrdr.o upnpglobalvars.o $(LIBS) -testiptcrdr: testiptcrdr.o iptcrdr.o upnpglobalvars.o $(LIBS) +testiptcrdr_peer: testiptcrdr_peer.o upnpglobalvars.o $(LIBS) + +testiptcrdr_dscp: testiptcrdr_dscp.o upnpglobalvars.o $(LIBS) testiptpinhole: testiptpinhole.o iptpinhole.o upnpglobalvars.o $(LIBS) +test_nfct_get: test_nfct_get.o test_nfct_get.o -lmnl -lnetfilter_conntrack + +test_nfct_get.o: test_nfct_get.c + +testiptcrdr_peer.o: testiptcrdr_peer.c + +testiptcrdr_dscp.o: testiptcrdr_dscp.c + iptcrdr.o: iptcrdr.c iptcrdr.h iptpinhole.o: iptpinhole.c iptpinhole.h diff --git a/release/src/router/miniupnpd/netfilter/ip6tables_display.sh b/release/src/router/miniupnpd/netfilter/ip6tables_display.sh old mode 100644 new mode 100755 diff --git a/release/src/router/miniupnpd/netfilter/ip6tables_flush.sh b/release/src/router/miniupnpd/netfilter/ip6tables_flush.sh old mode 100644 new mode 100755 diff --git a/release/src/router/miniupnpd/netfilter/ip6tables_init.sh b/release/src/router/miniupnpd/netfilter/ip6tables_init.sh old mode 100644 new mode 100755 diff --git a/release/src/router/miniupnpd/netfilter/ip6tables_init_and_clean.sh b/release/src/router/miniupnpd/netfilter/ip6tables_init_and_clean.sh old mode 100644 new mode 100755 diff --git a/release/src/router/miniupnpd/netfilter/ip6tables_removeall.sh b/release/src/router/miniupnpd/netfilter/ip6tables_removeall.sh old mode 100644 new mode 100755 diff --git a/release/src/router/miniupnpd/netfilter/iptpinhole.c b/release/src/router/miniupnpd/netfilter/iptpinhole.c index 978e4c0ca0..2c474c8b06 100644 --- a/release/src/router/miniupnpd/netfilter/iptpinhole.c +++ b/release/src/router/miniupnpd/netfilter/iptpinhole.c @@ -1,4 +1,4 @@ -/* $Id: iptpinhole.c,v 1.14 2015/02/10 15:01:03 nanard Exp $ */ +/* $Id: iptpinhole.c,v 1.15 2016/01/13 15:54:42 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2012-2015 Thomas Bernard @@ -297,7 +297,7 @@ delete_pinhole(unsigned short uid) info = (const struct ip6t_tcp *)&match->data; if((info->spts[0] == p->sport) && (info->dpts[0] == p->dport)) { if(!ip6tc_delete_num_entry(miniupnpd_v6_filter_chain, index, h)) { - syslog(LOG_ERR, "ip6tc_delete_num_entry(%s,%d,...): %s", + syslog(LOG_ERR, "ip6tc_delete_num_entry(%s,%u,...): %s", miniupnpd_v6_filter_chain, index, ip6tc_strerror(errno)); goto error; } @@ -315,6 +315,7 @@ delete_pinhole(unsigned short uid) } ip6tc_free(h); syslog(LOG_WARNING, "delete_pinhole() rule with PID=%hu not found", uid); + LIST_REMOVE(p, entries); return -2; /* not found */ error: ip6tc_free(h); diff --git a/release/src/router/miniupnpd/netfilter_nft/scripts/nft_delete_chain.sh b/release/src/router/miniupnpd/netfilter_nft/scripts/nft_delete_chain.sh old mode 100644 new mode 100755 diff --git a/release/src/router/miniupnpd/netfilter_nft/scripts/nft_flush.sh b/release/src/router/miniupnpd/netfilter_nft/scripts/nft_flush.sh old mode 100644 new mode 100755 diff --git a/release/src/router/miniupnpd/netfilter_nft/scripts/nft_init.sh b/release/src/router/miniupnpd/netfilter_nft/scripts/nft_init.sh old mode 100644 new mode 100755 diff --git a/release/src/router/miniupnpd/netfilter_nft/scripts/nft_removeall.sh b/release/src/router/miniupnpd/netfilter_nft/scripts/nft_removeall.sh old mode 100644 new mode 100755 diff --git a/release/src/router/miniupnpd/pcp_msg_struct.h b/release/src/router/miniupnpd/pcp_msg_struct.h index 2e795e8b02..c6d98ebf9a 100644 --- a/release/src/router/miniupnpd/pcp_msg_struct.h +++ b/release/src/router/miniupnpd/pcp_msg_struct.h @@ -1,4 +1,4 @@ -/* $Id: pcp_msg_struct.h,v 1.5 2014/09/06 08:15:37 nanard Exp $ */ +/* $Id: pcp_msg_struct.h,v 1.6 2015/09/22 10:10:54 nanard Exp $ */ /* MiniUPnP project * Website : http://miniupnp.free.fr/ * Author : Peter Tatrai @@ -29,6 +29,8 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef PCP_MSG_STRUCT_H_INCLUDED +#define PCP_MSG_STRUCT_H_INCLUDED #define PCP_OPCODE_ANNOUNCE 0 #define PCP_OPCODE_MAP 1 @@ -135,14 +137,8 @@ typedef enum pcp_options { } pcp_options_t; -#ifdef _WIN32 -#pragma warning (push) -#pragma warning (disable:4200) -#endif /* _WIN32 */ - -#pragma pack(push, 1) - /* PCP common request header*/ +#if 0 typedef struct pcp_request { uint8_t ver; uint8_t r_opcode; @@ -152,8 +148,11 @@ typedef struct pcp_request { by the ipv4 mapped ipv6 */ uint8_t next_data[0]; } pcp_request_t; +#endif +#define PCP_COMMON_REQUEST_SIZE (24) /* PCP common response header*/ +#if 0 typedef struct pcp_response { uint8_t ver; uint8_t r_opcode; /* R indicates Request (0) or Response (1) @@ -166,16 +165,22 @@ typedef struct pcp_response { uint32_t reserved1[3];/* For requests that were successfully parsed this must be sent as 0 */ uint8_t next_data[0]; } pcp_response_t; +#endif +#define PCP_COMMON_RESPONSE_SIZE (24) +#if 0 typedef struct pcp_options_hdr { uint8_t code; /* Most significant bit indicates if this option is mandatory (0) or optional (1) */ uint8_t reserved; /* MUST be set to 0 on transmission and MUST be ignored on reception */ uint16_t len; /* indicates the length of the enclosed data in octets (see RFC) */ uint8_t next_data[0]; /* */ } pcp_options_hdr_t; +#endif +#define PCP_OPTION_HDR_SIZE (4) /* same for both request and response */ +#if 0 typedef struct pcp_map_v2 { uint32_t nonce[3]; uint8_t protocol; /* 6 = TCP, 17 = UDP, 0 = 'all protocols' */ @@ -186,7 +191,10 @@ typedef struct pcp_map_v2 { * ipv4 will be represented by the ipv4 mapped ipv6 */ uint8_t next_data[0]; } pcp_map_v2_t; +#endif +#define PCP_MAP_V2_SIZE (36) +#if 0 /* same for both request and response */ typedef struct pcp_map_v1 { uint8_t protocol; @@ -197,8 +205,11 @@ typedef struct pcp_map_v1 { by the ipv4 mapped ipv6 */ uint8_t next_data[0]; } pcp_map_v1_t; +#endif +#define PCP_MAP_V1_SIZE (24) /* same for both request and response */ +#if 0 typedef struct pcp_peer_v1 { uint8_t protocol; uint8_t reserved[3]; @@ -211,8 +222,11 @@ typedef struct pcp_peer_v1 { struct in6_addr peer_ip; uint8_t next_data[0]; } pcp_peer_v1_t; +#endif +#define PCP_PEER_V1_SIZE (44) /* same for both request and response */ +#if 0 typedef struct pcp_peer_v2 { uint32_t nonce[3]; uint8_t protocol; @@ -226,30 +240,41 @@ typedef struct pcp_peer_v2 { struct in6_addr peer_ip; uint8_t next_data[0]; } pcp_peer_v2_t; +#endif +#define PCP_PEER_V2_SIZE (56) #ifdef PCP_SADSCP +#if 0 typedef struct pcp_sadscp_req { uint32_t nonce[3]; uint8_t tolerance_fields; uint8_t app_name_length; char app_name[0]; } pcp_sadscp_req_t; +#endif +#define PCP_SADSCP_REQ_SIZE (14) +#if 0 typedef struct pcp_sadscp_resp { uint32_t nonce[3]; -#define PCP_SADSCP_MASK ((1<<6)-1) uint8_t a_r_dscp_value; uint8_t reserved[3]; } pcp_sadscp_resp_t; #endif +#define PCP_SADSCP_MASK ((1<<6)-1) +#endif /* PCP_SADSCP */ +#if 0 typedef struct pcp_prefer_fail_option { uint8_t option; uint8_t reserved; uint16_t len; uint8_t next_data[0]; } pcp_prefer_fail_option_t; +#endif +#define PCP_PREFER_FAIL_OPTION_SIZE (4) +#if 0 typedef struct pcp_3rd_party_option{ uint8_t option; uint8_t reserved; @@ -257,22 +282,28 @@ typedef struct pcp_3rd_party_option{ struct in6_addr ip; uint8_t next_data[0]; } pcp_3rd_party_option_t; +#endif +#define PCP_3RD_PARTY_OPTION_SIZE (20) #ifdef PCP_FLOWP +#if 0 typedef struct pcp_flow_priority_option{ uint8_t option; uint8_t reserved; uint16_t len; uint8_t dscp_up; uint8_t dscp_down; -#define PCP_DSCP_MASK ((1<<6)-1) uint8_t reserved2; /* most significant bit is used for response */ uint8_t response_bit; uint8_t next_data[0]; } pcp_flow_priority_option_t; #endif +#define PCP_DSCP_MASK ((1<<6)-1) +#define PCP_FLOW_PRIORITY_OPTION_SIZE (8) +#endif +#if 0 typedef struct pcp_filter_option { uint8_t option; uint8_t reserved1; @@ -282,9 +313,7 @@ typedef struct pcp_filter_option { uint16_t peer_port; struct in6_addr peer_ip; }pcp_filter_option_t; +#endif +#define PCP_FILTER_OPTION_SIZE (24) -#pragma pack(pop) - -#ifdef _WIN32 -#pragma warning (pop) -#endif /* _WIN32 */ +#endif /* PCP_MSG_STRUCT_H_INCLUDED */ diff --git a/release/src/router/miniupnpd/pcplearndscp.c b/release/src/router/miniupnpd/pcplearndscp.c index 9ab31ceb6d..c1b3e22e57 100644 --- a/release/src/router/miniupnpd/pcplearndscp.c +++ b/release/src/router/miniupnpd/pcplearndscp.c @@ -1,4 +1,4 @@ -/* $Id: pcplearndscp.c,v 1.1 2013/12/13 13:23:01 nanard Exp $ */ +/* $Id: pcplearndscp.c,v 1.2 2016/01/13 16:02:08 nanard Exp $ */ /* MiniUPnP project * Website : http://miniupnp.free.fr/ * Author : Miroslav Bagljas @@ -228,7 +228,7 @@ read_learn_dscp_line(struct dscp_values *dscpvalues, char *p) dscpvalues->dscp_value = 38; break; default: - fprintf(stderr, "Unknown AF value %u \n", af_value); + fprintf(stderr, "Unknown AF value %d \n", af_value); goto exit_err_and_cleanup; } } diff --git a/release/src/router/miniupnpd/pcpserver.c b/release/src/router/miniupnpd/pcpserver.c index 110cccdf4f..5408158684 100644 --- a/release/src/router/miniupnpd/pcpserver.c +++ b/release/src/router/miniupnpd/pcpserver.c @@ -1,4 +1,4 @@ -/* $Id: pcpserver.c,v 1.38 2014/10/27 16:35:13 nanard Exp $ */ +/* $Id: pcpserver.c,v 1.43 2016/01/13 15:48:13 nanard Exp $ */ /* MiniUPnP project * Website : http://miniupnp.free.fr/ * Author : Peter Tatrai @@ -153,6 +153,36 @@ typedef struct pcp_info { char desc[64]; } pcp_info_t; +/* getPCPOpCodeStr() + * return a string representation of the PCP OpCode + * can be used for debug output */ +static const char * getPCPOpCodeStr(uint8_t opcode) +{ + switch(opcode) { + case PCP_OPCODE_ANNOUNCE: + return "ANNOUNCE"; + case PCP_OPCODE_MAP: + return "MAP"; + case PCP_OPCODE_PEER: + return "PEER"; +#ifdef PCP_SADSCP + case PCP_OPCODE_SADSCP: + return "SADSCP"; +#endif /* PCP_SADSCP */ + default: + return "UNKNOWN"; + } +} + +/* useful to copy ext_ip only if needed, as request and response + * buffers are same */ +static void copyIPv6IfDifferent(void * dest, const void * src) +{ + if(dest != src) { + memcpy(dest, src, sizeof(struct in6_addr)); + } +} + #ifdef PCP_SADSCP int get_dscp_value(pcp_info_t *pcp_msg_info) { @@ -207,16 +237,16 @@ int get_dscp_value(pcp_info_t *pcp_msg_info) { * result code is assigned to pcp_msg_info->result_code to indicate * what kind of error occurred */ -static int parseCommonRequestHeader(const pcp_request_t *common_req, pcp_info_t *pcp_msg_info) +static int parseCommonRequestHeader(const uint8_t *common_req, pcp_info_t *pcp_msg_info) { - pcp_msg_info->version = common_req->ver ; - pcp_msg_info->opcode = common_req->r_opcode & 0x7f; - pcp_msg_info->lifetime = ntohl(common_req->req_lifetime); - pcp_msg_info->int_ip = &common_req->ip; - pcp_msg_info->mapped_ip = &common_req->ip; + pcp_msg_info->version = common_req[0] ; + pcp_msg_info->opcode = common_req[1] & 0x7f; + pcp_msg_info->lifetime = READNU32(common_req + 4); + pcp_msg_info->int_ip = (struct in6_addr *)(common_req + 8); + pcp_msg_info->mapped_ip = (struct in6_addr *)(common_req + 8); - if ( (common_req->ver > this_server_info.server_version) ) { + if ( (pcp_msg_info->version > this_server_info.server_version) ) { pcp_msg_info->result_code = PCP_ERR_UNSUPP_VERSION; return 1; } @@ -233,102 +263,87 @@ static int parseCommonRequestHeader(const pcp_request_t *common_req, pcp_info_t } #ifdef DEBUG -static void printMAPOpcodeVersion1(const pcp_map_v1_t *map_buf) +static void printMAPOpcodeVersion1(const uint8_t *buf) { char map_addr[INET6_ADDRSTRLEN]; syslog(LOG_DEBUG, "PCP MAP: v1 Opcode specific information. \n"); - syslog(LOG_DEBUG, "MAP protocol: \t\t %d\n",map_buf->protocol ); - syslog(LOG_DEBUG, "MAP int port: \t\t %d\n", ntohs(map_buf->int_port) ); - syslog(LOG_DEBUG, "MAP ext port: \t\t %d\n", ntohs(map_buf->ext_port) ); + syslog(LOG_DEBUG, "MAP protocol: \t\t %d\n", (int)buf[0] ); + syslog(LOG_DEBUG, "MAP int port: \t\t %d\n", (int)READNU16(buf+4)); + syslog(LOG_DEBUG, "MAP ext port: \t\t %d\n", (int)READNU16(buf+6)); syslog(LOG_DEBUG, "MAP Ext IP: \t\t %s\n", inet_ntop(AF_INET6, - &map_buf->ext_ip, map_addr, INET6_ADDRSTRLEN)); + buf+8, map_addr, INET6_ADDRSTRLEN)); } -static void printMAPOpcodeVersion2(const pcp_map_v2_t *map_buf) +static void printMAPOpcodeVersion2(const uint8_t *buf) { char map_addr[INET6_ADDRSTRLEN]; syslog(LOG_DEBUG, "PCP MAP: v2 Opcode specific information."); syslog(LOG_DEBUG, "MAP nonce: \t%08x%08x%08x", - map_buf->nonce[0], map_buf->nonce[1], map_buf->nonce[2]); - syslog(LOG_DEBUG, "MAP protocol:\t%d", map_buf->protocol); - syslog(LOG_DEBUG, "MAP int port:\t%d", ntohs(map_buf->int_port)); - syslog(LOG_DEBUG, "MAP ext port:\t%d", ntohs(map_buf->ext_port)); + READNU32(buf), READNU32(buf+4), READNU32(buf+8)); + syslog(LOG_DEBUG, "MAP protocol:\t%d", (int)buf[12]); + syslog(LOG_DEBUG, "MAP int port:\t%d", (int)READNU16(buf+16)); + syslog(LOG_DEBUG, "MAP ext port:\t%d", (int)READNU16(buf+18)); syslog(LOG_DEBUG, "MAP Ext IP: \t%s", inet_ntop(AF_INET6, - &map_buf->ext_ip, map_addr, INET6_ADDRSTRLEN)); + buf+20, map_addr, INET6_ADDRSTRLEN)); } #endif /* DEBUG */ -static int parsePCPMAP_version1(const pcp_map_v1_t *map_v1, +static void parsePCPMAP_version1(const uint8_t *map_v1, pcp_info_t *pcp_msg_info) { pcp_msg_info->is_map_op = 1; - pcp_msg_info->protocol = map_v1->protocol; - pcp_msg_info->int_port = ntohs(map_v1->int_port); - pcp_msg_info->ext_port = ntohs(map_v1->ext_port); + pcp_msg_info->protocol = map_v1[0]; + pcp_msg_info->int_port = READNU16(map_v1 + 4); + pcp_msg_info->ext_port = READNU16(map_v1 + 6); - pcp_msg_info->ext_ip = &(map_v1->ext_ip); - - if (pcp_msg_info->protocol == 0 && pcp_msg_info->int_port !=0 ){ - syslog(LOG_ERR, "PCP MAP: Protocol was ZERO, but internal port has non-ZERO value."); - pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST; - return 1; - } - return 0; + pcp_msg_info->ext_ip = (struct in6_addr *)(map_v1 + 8); } -static int parsePCPMAP_version2(const pcp_map_v2_t *map_v2, +static void parsePCPMAP_version2(const uint8_t *map_v2, pcp_info_t *pcp_msg_info) { pcp_msg_info->is_map_op = 1; - memcpy(pcp_msg_info->nonce, map_v2->nonce, 12); - pcp_msg_info->protocol = map_v2->protocol; - pcp_msg_info->int_port = ntohs(map_v2->int_port); - pcp_msg_info->ext_port = ntohs(map_v2->ext_port); - - pcp_msg_info->ext_ip = &(map_v2->ext_ip); + memcpy(pcp_msg_info->nonce, map_v2, 12); + pcp_msg_info->protocol = map_v2[12]; + pcp_msg_info->int_port = READNU16(map_v2 + 16); + pcp_msg_info->ext_port = READNU16(map_v2 + 18); - if (pcp_msg_info->protocol == 0 && pcp_msg_info->int_port !=0 ) { - syslog(LOG_ERR, "PCP MAP: Protocol was ZERO, but internal port has non-ZERO value."); - pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST; - return PCP_ERR_MALFORMED_REQUEST; - } - - return 0; + pcp_msg_info->ext_ip = (struct in6_addr *)(map_v2 + 20); } #ifdef PCP_PEER #ifdef DEBUG -static void printPEEROpcodeVersion1(pcp_peer_v1_t *peer_buf) +static void printPEEROpcodeVersion1(const uint8_t *buf) { char ext_addr[INET6_ADDRSTRLEN]; char peer_addr[INET6_ADDRSTRLEN]; syslog(LOG_DEBUG, "PCP PEER: v1 Opcode specific information. \n"); - syslog(LOG_DEBUG, "Protocol: \t\t %d\n",peer_buf->protocol ); - syslog(LOG_DEBUG, "Internal port: \t\t %d\n", ntohs(peer_buf->int_port) ); - syslog(LOG_DEBUG, "External IP: \t\t %s\n", inet_ntop(AF_INET6, &peer_buf->ext_ip, + syslog(LOG_DEBUG, "Protocol: \t\t %d\n", (int)buf[0]); + syslog(LOG_DEBUG, "Internal port: \t\t %d\n", READNU16(buf + 4)); + syslog(LOG_DEBUG, "External IP: \t\t %s\n", inet_ntop(AF_INET6, buf + 8, ext_addr,INET6_ADDRSTRLEN)); - syslog(LOG_DEBUG, "External port port: \t\t %d\n", ntohs(peer_buf->ext_port) ); - syslog(LOG_DEBUG, "PEER IP: \t\t %s\n", inet_ntop(AF_INET6, &peer_buf->peer_ip, + syslog(LOG_DEBUG, "External port port: \t\t %d\n", READNU16(buf + 6)); + syslog(LOG_DEBUG, "PEER IP: \t\t %s\n", inet_ntop(AF_INET6, buf + 28, peer_addr,INET6_ADDRSTRLEN)); - syslog(LOG_DEBUG, "PEER port port: \t\t %d\n", ntohs(peer_buf->peer_port) ); + syslog(LOG_DEBUG, "PEER port port: \t\t %d\n", READNU16(buf + 24)); } -static void printPEEROpcodeVersion2(pcp_peer_v2_t *peer_buf) +static void printPEEROpcodeVersion2(const uint8_t *buf) { char ext_addr[INET6_ADDRSTRLEN]; char peer_addr[INET6_ADDRSTRLEN]; syslog(LOG_DEBUG, "PCP PEER: v2 Opcode specific information."); syslog(LOG_DEBUG, "nonce: \t%08x%08x%08x", - peer_buf->nonce[0], peer_buf->nonce[1], peer_buf->nonce[2]); - syslog(LOG_DEBUG, "Protocol: \t%d",peer_buf->protocol ); - syslog(LOG_DEBUG, "Internal port:\t%d", ntohs(peer_buf->int_port) ); - syslog(LOG_DEBUG, "External IP: \t%s", inet_ntop(AF_INET6, &peer_buf->ext_ip, - ext_addr,INET6_ADDRSTRLEN)); - syslog(LOG_DEBUG, "External port:\t%d", ntohs(peer_buf->ext_port) ); - syslog(LOG_DEBUG, "PEER IP: \t%s", inet_ntop(AF_INET6, &peer_buf->peer_ip, - peer_addr,INET6_ADDRSTRLEN)); - syslog(LOG_DEBUG, "PEER port: \t%d", ntohs(peer_buf->peer_port) ); + READNU32(buf), READNU32(buf+4), READNU32(buf+8)); + syslog(LOG_DEBUG, "Protocol: \t%d", buf[12]); + syslog(LOG_DEBUG, "Internal port:\t%d", READNU16(buf + 16)); + syslog(LOG_DEBUG, "External IP: \t%s", inet_ntop(AF_INET6, buf + 20, + ext_addr, INET6_ADDRSTRLEN)); + syslog(LOG_DEBUG, "External port:\t%d", READNU16(buf + 18)); + syslog(LOG_DEBUG, "PEER IP: \t%s", inet_ntop(AF_INET6, buf + 40, + peer_addr, INET6_ADDRSTRLEN)); + syslog(LOG_DEBUG, "PEER port: \t%d", READNU16(buf + 36)); } #endif /* DEBUG */ @@ -336,158 +351,122 @@ static void printPEEROpcodeVersion2(pcp_peer_v2_t *peer_buf) * Function extracting information from peer_buf to pcp_msg_info * @return : when no problem occurred 0 is returned, 1 otherwise */ -static int parsePCPPEER_version1(pcp_peer_v1_t *peer_buf, \ +static void parsePCPPEER_version1(const uint8_t *buf, pcp_info_t *pcp_msg_info) { pcp_msg_info->is_peer_op = 1; - pcp_msg_info->protocol = peer_buf->protocol; - pcp_msg_info->int_port = ntohs(peer_buf->int_port); - pcp_msg_info->ext_port = ntohs(peer_buf->ext_port); - pcp_msg_info->peer_port = ntohs(peer_buf->peer_port); - - pcp_msg_info->ext_ip = &peer_buf->ext_ip; - pcp_msg_info->peer_ip = &peer_buf->peer_ip; + pcp_msg_info->protocol = buf[0]; + pcp_msg_info->int_port = READNU16(buf + 4); + pcp_msg_info->ext_port = READNU16(buf + 6); + pcp_msg_info->peer_port = READNU16(buf + 24); - if (pcp_msg_info->protocol == 0 && pcp_msg_info->int_port !=0 ){ - syslog(LOG_ERR, "PCP PEER: protocol was ZERO, but internal port has non-ZERO value."); - pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST; - return 1; - } - return 0; + pcp_msg_info->ext_ip = (struct in6_addr *)(buf + 8); + pcp_msg_info->peer_ip = (struct in6_addr *)(buf + 28); } /* * Function extracting information from peer_buf to pcp_msg_info * @return : when no problem occurred 0 is returned, 1 otherwise */ -static int parsePCPPEER_version2(pcp_peer_v2_t *peer_buf, \ - pcp_info_t *pcp_msg_info) +static void parsePCPPEER_version2(const uint8_t *buf, pcp_info_t *pcp_msg_info) { pcp_msg_info->is_peer_op = 1; - memcpy(pcp_msg_info->nonce, peer_buf->nonce, 12); - pcp_msg_info->protocol = peer_buf->protocol; - pcp_msg_info->int_port = ntohs(peer_buf->int_port); - pcp_msg_info->ext_port = ntohs(peer_buf->ext_port); - pcp_msg_info->peer_port = ntohs(peer_buf->peer_port); - - pcp_msg_info->ext_ip = &peer_buf->ext_ip; - pcp_msg_info->peer_ip = &peer_buf->peer_ip; - - if (pcp_msg_info->protocol == 0 && pcp_msg_info->int_port !=0 ){ - syslog(LOG_ERR, "PCP PEER: protocol was ZERO, but internal port has non-ZERO value."); - pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST; - return 1; - } - return 0; + memcpy(pcp_msg_info->nonce, buf, 12); + pcp_msg_info->protocol = buf[12]; + pcp_msg_info->int_port = READNU16(buf + 16); + pcp_msg_info->ext_port = READNU16(buf + 18); + pcp_msg_info->peer_port = READNU16(buf + 36); + + pcp_msg_info->ext_ip = (struct in6_addr *)(buf + 20); + pcp_msg_info->peer_ip = (struct in6_addr *)(buf + 40); } #endif /* PCP_PEER */ #ifdef PCP_SADSCP #ifdef DEBUG -static void printSADSCPOpcode(pcp_sadscp_req_t *sadscp) { +static void printSADSCPOpcode(const uint8_t *buf) +{ unsigned char sadscp_tol; - sadscp_tol = sadscp->tolerance_fields; + sadscp_tol = buf[12]; /* tolerance_fields */ syslog(LOG_DEBUG, "PCP SADSCP: Opcode specific information.\n"); - syslog(LOG_DEBUG, "Delay tolerance %d \n", (sadscp_tol>>6)&3 ); + syslog(LOG_DEBUG, "Delay tolerance %d \n", (sadscp_tol>>6)&3); syslog(LOG_DEBUG, "Loss tolerance %d \n", (sadscp_tol>>4)&3); syslog(LOG_DEBUG, "Jitter tolerance %d \n", (sadscp_tol>>2)&3); syslog(LOG_DEBUG, "RRR %d \n", sadscp_tol&3); - syslog(LOG_DEBUG, "AppName Length %d \n", sadscp->app_name_length); - if (sadscp->app_name) { - syslog(LOG_DEBUG, "Application name %.*s \n", sadscp->app_name_length, - sadscp->app_name); - } + syslog(LOG_DEBUG, "AppName Length %d \n", buf[13]); + syslog(LOG_DEBUG, "Application name %.*s \n", buf[13], buf + 14); } #endif //DEBUG -static int parseSADSCP(pcp_sadscp_req_t *sadscp, pcp_info_t *pcp_msg_info) { - - pcp_msg_info->delay_tolerance = (sadscp->tolerance_fields>>6)&3; - pcp_msg_info->loss_tolerance = (sadscp->tolerance_fields>>4)&3; - pcp_msg_info->jitter_tolerance = (sadscp->tolerance_fields>>2)&3; +static int parseSADSCP(const uint8_t *buf, pcp_info_t *pcp_msg_info) +{ + pcp_msg_info->delay_tolerance = (buf[12]>>6)&3; + pcp_msg_info->loss_tolerance = (buf[12]>>4)&3; + pcp_msg_info->jitter_tolerance = (buf[12]>>2)&3; - if (pcp_msg_info->delay_tolerance == 3 ) { - pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST; - return 1; - } - if ( pcp_msg_info->loss_tolerance == 3 ) { - pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST; - return 1; - } - if ( pcp_msg_info->jitter_tolerance == 3 ) { + if (pcp_msg_info->delay_tolerance == 3 || + pcp_msg_info->loss_tolerance == 3 || + pcp_msg_info->jitter_tolerance == 3 ) { pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST; return 1; } - pcp_msg_info->app_name = sadscp->app_name; - pcp_msg_info->app_name_len = sadscp->app_name_length; + pcp_msg_info->app_name = (const char *)(buf + 14); + pcp_msg_info->app_name_len = buf[13]; return 0; } -#endif +#endif /* PCP_SADSCP */ -static int parsePCPOption(void* pcp_buf, int remain, pcp_info_t *pcp_msg_info) + +static int parsePCPOption(uint8_t* pcp_buf, int remain, pcp_info_t *pcp_msg_info) { #ifdef DEBUG char third_addr[INET6_ADDRSTRLEN]; -#endif +#endif /* DEBUG */ unsigned short option_length; - pcp_3rd_party_option_t* opt_3rd; -#ifdef PCP_FLOWP - pcp_flow_priority_option_t* opt_flp; -#endif - pcp_filter_option_t* opt_filter; - pcp_prefer_fail_option_t* opt_prefail; - pcp_options_hdr_t* opt_hdr; - - opt_hdr = (pcp_options_hdr_t*)pcp_buf; - /* Do centralized option sanity checks here. */ - if (remain < (int)sizeof(*opt_hdr)) { + if (remain < (int)PCP_OPTION_HDR_SIZE) { pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION; return 0; } - option_length = ntohs(opt_hdr->len) + 4; + option_length = READNU16(pcp_buf + 2) + 4; /* len */ if (remain < option_length) { pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION; return 0; } - switch (opt_hdr->code) { + switch (pcp_buf[0]) { /* code */ case PCP_OPTION_3RD_PARTY: - opt_3rd = (pcp_3rd_party_option_t*)pcp_buf; - if ( option_length != sizeof(*opt_3rd) ) { + if (option_length != PCP_3RD_PARTY_OPTION_SIZE) { pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION; return 0; } #ifdef DEBUG - syslog(LOG_DEBUG, "PCP OPTION: \t Third party \n"); + syslog(LOG_DEBUG, "PCP OPTION: \t Third party\n"); syslog(LOG_DEBUG, "Third PARTY IP: \t %s\n", inet_ntop(AF_INET6, - &(opt_3rd->ip), third_addr, INET6_ADDRSTRLEN)); + pcp_buf + 4, third_addr, INET6_ADDRSTRLEN)); #endif if (pcp_msg_info->thirdp_ip ) { syslog(LOG_ERR, "PCP: THIRD PARTY OPTION was already present. \n"); pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION; return 0; - } - else { - pcp_msg_info->thirdp_ip = &opt_3rd->ip; - pcp_msg_info->mapped_ip = &opt_3rd->ip; + } else { + pcp_msg_info->thirdp_ip = (struct in6_addr *)(pcp_buf + 4); + pcp_msg_info->mapped_ip = (struct in6_addr *)(pcp_buf + 4); } break; case PCP_OPTION_PREF_FAIL: - opt_prefail = (pcp_prefer_fail_option_t*)pcp_buf; - - if ( option_length != sizeof(*opt_prefail) ) { + if (option_length != PCP_PREFER_FAIL_OPTION_SIZE) { pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION; return 0; } @@ -499,19 +478,16 @@ static int parsePCPOption(void* pcp_buf, int remain, pcp_info_t *pcp_msg_info) pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST; } if (pcp_msg_info->pfailure_present != 0 ) { - syslog(LOG_DEBUG, "PCP: PREFER FAILURE OPTION was already present. \n"); + syslog(LOG_DEBUG, "PCP: PREFER FAILURE OPTION was already present.\n"); pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION; - } - else { + } else { pcp_msg_info->pfailure_present = 1; } break; case PCP_OPTION_FILTER: /* TODO fully implement filter */ - opt_filter = (pcp_filter_option_t*)pcp_buf; - - if ( option_length != sizeof(*opt_filter) ) { + if (option_length != PCP_FILTER_OPTION_SIZE) { pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION; return 0; } @@ -531,28 +507,26 @@ static int parsePCPOption(void* pcp_buf, int remain, pcp_info_t *pcp_msg_info) #ifdef DEBUG syslog(LOG_DEBUG, "PCP OPTION: \t Flow priority\n"); #endif - opt_flp = (pcp_flow_priority_option_t*)pcp_buf; - - if ( option_length != sizeof (*flp) ) { - syslog(LOG_ERR, "PCP: Error processing DSCP. sizeof %d and remaining %d . flow len %d \n", - (int)sizeof(pcp_flow_priority_option_t), remain, opt_flp->len); + if (option_length != PCP_FLOW_PRIORITY_OPTION_SIZE) { + syslog(LOG_ERR, "PCP: Error processing DSCP. sizeof %d and remaining %d. flow len %d \n", + PCP_FLOW_PRIORITY_OPTION_SIZE, remain, READNU16(pcp_buf + 2)); pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION; return 0; } #ifdef DEBUG - syslog(LOG_DEBUG, "DSCP UP: \t %d \n", opt_flp->dscp_up); - syslog(LOG_DEBUG, "DSCP DOWN: \t %d \n", opt_flp->dscp_down); + syslog(LOG_DEBUG, "DSCP UP: \t %d\n", pcp_buf[4]); + syslog(LOG_DEBUG, "DSCP DOWN: \t %d\n", pcp_buf[5]); #endif - pcp_msg_info->dscp_up = opt_flp->dscp_up; - pcp_msg_info->dscp_down = opt_flp->dscp_down; + pcp_msg_info->dscp_up = pcp_buf[4]; + pcp_msg_info->dscp_down = pcp_buf[5]; pcp_msg_info->flowp_present = 1; break; #endif default: - if (opt_hdr->code < 128) { - syslog(LOG_ERR, "PCP: Unrecognized mandatory PCP OPTION: %d \n", opt_hdr->code); + if (pcp_buf[0] < 128) { + syslog(LOG_ERR, "PCP: Unrecognized mandatory PCP OPTION: %d \n", (int)pcp_buf[0]); /* Mandatory to understand */ pcp_msg_info->result_code = PCP_ERR_UNSUPP_OPTION; remain = 0; @@ -576,6 +550,9 @@ static void parsePCPOptions(void* pcp_buf, int remain, pcp_info_t *pcp_msg_info) remain -= option_length; pcp_buf += option_length; } + if (remain > 0) { + syslog(LOG_WARNING, "%s: remain=%d", "parsePCPOptions", remain); + } } @@ -770,7 +747,7 @@ static int CreatePCPPeer_NAT(pcp_info_t *pcp_msg_info) pcp_msg_info->peer_port, pcp_msg_info->desc); pcp_msg_info->result_code = PCP_ERR_NO_RESOURCES; - return; + return PCP_ERR_NO_RESOURCES; } } #endif @@ -822,7 +799,8 @@ static void CreatePCPPeer(pcp_info_t *pcp_msg_info) } /* TODO: add upnp function for PI */ pcp_msg_info->result_code = r; - syslog(LOG_ERR, "PCP PEER: %s peer mapping %s %s:%hu(%hu)->%s:%hu '%s'", + syslog(r == PCP_SUCCESS ? LOG_INFO : LOG_ERR, + "PCP PEER: %s peer mapping %s %s:%hu(%hu)->%s:%hu '%s'", r == PCP_SUCCESS ? "added" : "failed to add", (pcp_msg_info->protocol==IPPROTO_TCP)?"TCP":"UDP", pcp_msg_info->mapped_str, @@ -876,7 +854,7 @@ static void DeletePCPPeer(pcp_info_t *pcp_msg_info) rhost2, sizeof(rhost2), &rport2, iaddr2, sizeof(iaddr2), &iport2, &proto2, desc, sizeof(desc), - ×tamp, NULL) > 0) + ×tamp, NULL) >= 0) #endif /* 0 */ ; index++) @@ -967,7 +945,7 @@ static int CreatePCPMap_NAT(pcp_info_t *pcp_msg_info) pcp_msg_info->protocol, iaddr_old, sizeof(iaddr_old), &iport_old, 0, 0, 0, 0, - ×tamp, 0, 0); + NULL/*×tamp*/, 0, 0); if(r==0) { if((strcmp(pcp_msg_info->mapped_str, iaddr_old)!=0) @@ -1066,7 +1044,8 @@ static void CreatePCPMap(pcp_info_t *pcp_msg_info) else r = CreatePCPMap_NAT(pcp_msg_info); pcp_msg_info->result_code = r; - syslog(LOG_ERR, "PCP MAP: %s mapping %s %hu->%s:%hu '%s'", + syslog(r == PCP_SUCCESS ? LOG_INFO : LOG_ERR, + "PCP MAP: %s mapping %s %hu->%s:%hu '%s'", r == PCP_SUCCESS ? "added" : "failed to add", (pcp_msg_info->protocol==IPPROTO_TCP)?"TCP":"UDP", pcp_msg_info->ext_port, @@ -1084,7 +1063,7 @@ static void DeletePCPMap(pcp_info_t *pcp_msg_info) /* remove all the mappings for this client */ int index; unsigned short eport2, iport2; - char iaddr2[16]; + char iaddr2[INET6_ADDRSTRLEN]; int proto2; char desc[64]; unsigned int timestamp; @@ -1108,15 +1087,20 @@ static void DeletePCPMap(pcp_info_t *pcp_msg_info) NULL, 0, NULL, iaddr2, sizeof(iaddr2), &iport2, &proto2, desc, sizeof(desc), - ×tamp, NULL) > 0) + ×tamp, NULL) >= 0) #endif /* ENABLE_UPNPPINHOLE */ ; index++) if(0 == strcmp(iaddr2, pcp_msg_info->mapped_str) && (proto2==proto) - && 0 == strcmp(desc, pcp_msg_info->desc) && ((iport2==iport) || (iport==0))) { - if (!pcp_msg_info->is_fw) { + if(0 != strcmp(desc, pcp_msg_info->desc)) { + /* nonce does not match */ + pcp_msg_info->result_code = PCP_ERR_NOT_AUTHORIZED; + syslog(LOG_ERR, "Unauthorized to remove PCP mapping internal port %hu, protocol %s", + iport, (pcp_msg_info->protocol == IPPROTO_TCP)?"TCP":"UDP"); + return; + } else if (!pcp_msg_info->is_fw) { r = _upnp_delete_redir(eport2, proto2); } else { #ifdef ENABLE_UPNPPINHOLE @@ -1175,6 +1159,8 @@ static int ValidatePCPMsg(pcp_info_t *pcp_msg_info) /* protocol zero means 'all protocols' : internal port MUST be zero */ if (pcp_msg_info->protocol == 0 && pcp_msg_info->int_port != 0) { + syslog(LOG_ERR, "PCP %s: Protocol was ZERO, but internal port " + "has non-ZERO value.", getPCPOpCodeStr(pcp_msg_info->opcode)); pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST; return 0; } @@ -1203,7 +1189,7 @@ static int ValidatePCPMsg(pcp_info_t *pcp_msg_info) case PCP_OPCODE_PEER: snprintf(pcp_msg_info->desc, sizeof(pcp_msg_info->desc), "PCP %s %08x%08x%08x", - pcp_msg_info->opcode == PCP_OPCODE_MAP ? "MAP":"PEER", + getPCPOpCodeStr(pcp_msg_info->opcode), pcp_msg_info->nonce[0], pcp_msg_info->nonce[1], pcp_msg_info->nonce[2]); break; @@ -1219,17 +1205,8 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info) { int remainingSize; - const pcp_map_v1_t* map_v1; - const pcp_map_v2_t* map_v2; -#ifdef PCP_PEER - pcp_peer_v1_t* peer_v1; - pcp_peer_v2_t* peer_v2; -#endif - -#ifdef PCP_SADSCP - pcp_sadscp_req_t* sadscp; -#endif - /* start with PCP_SUCCESS as result code, if everything is OK value will be unchanged */ + /* start with PCP_SUCCESS as result code, + * if everything is OK value will be unchanged */ pcp_msg_info->result_code = PCP_SUCCESS; remainingSize = req_size; @@ -1253,33 +1230,30 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info) } /* first parse request header */ - if (parseCommonRequestHeader((pcp_request_t*)req, pcp_msg_info) ) { + if (parseCommonRequestHeader(req, pcp_msg_info) ) { return 1; } - remainingSize -= sizeof(pcp_request_t); - req += sizeof(pcp_request_t); + remainingSize -= PCP_COMMON_REQUEST_SIZE; + req += PCP_COMMON_REQUEST_SIZE; if (pcp_msg_info->version == 1) { /* legacy PCP version 1 support */ switch (pcp_msg_info->opcode) { case PCP_OPCODE_MAP: - remainingSize -= sizeof(pcp_map_v1_t); + remainingSize -= PCP_MAP_V1_SIZE; if (remainingSize < 0) { pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST; return pcp_msg_info->result_code; } - map_v1 = (pcp_map_v1_t*)req; #ifdef DEBUG - printMAPOpcodeVersion1(map_v1); + printMAPOpcodeVersion1(req); #endif /* DEBUG */ - if ( parsePCPMAP_version1(map_v1, pcp_msg_info) ) { - return pcp_msg_info->result_code; - } + parsePCPMAP_version1(req, pcp_msg_info); - req += sizeof(pcp_map_v1_t); + req += PCP_MAP_V1_SIZE; parsePCPOptions(req, remainingSize, pcp_msg_info); if (ValidatePCPMsg(pcp_msg_info)) { @@ -1290,29 +1264,25 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info) } } else { syslog(LOG_ERR, "PCP: Invalid PCP v1 MAP message."); + return pcp_msg_info->result_code; } - - break; #ifdef PCP_PEER case PCP_OPCODE_PEER: - remainingSize -= sizeof(pcp_peer_v1_t); + remainingSize -= PCP_PEER_V1_SIZE; if (remainingSize < 0) { pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST; return pcp_msg_info->result_code; } - peer_v1 = (pcp_peer_v1_t*)req; #ifdef DEBUG - printPEEROpcodeVersion1(peer_v1); + printPEEROpcodeVersion1(req); #endif /* DEBUG */ - if ( parsePCPPEER_version1(peer_v1, pcp_msg_info) ) { - return pcp_msg_info->result_code; - } + parsePCPPEER_version1(req, pcp_msg_info); - req += sizeof(pcp_peer_v1_t); + req += PCP_PEER_V1_SIZE; parsePCPOptions(req, remainingSize, pcp_msg_info); @@ -1324,6 +1294,7 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info) } } else { syslog(LOG_ERR, "PCP: Invalid PCP v1 PEER message."); + return pcp_msg_info->result_code; } @@ -1344,22 +1315,17 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info) break; case PCP_OPCODE_MAP: - remainingSize -= sizeof(pcp_map_v2_t); + remainingSize -= PCP_MAP_V2_SIZE; if (remainingSize < 0) { pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST; return pcp_msg_info->result_code; } - map_v2 = (pcp_map_v2_t*)req; - #ifdef DEBUG - printMAPOpcodeVersion2(map_v2); + printMAPOpcodeVersion2(req); #endif /* DEBUG */ - - if (parsePCPMAP_version2(map_v2, pcp_msg_info) ) { - return pcp_msg_info->result_code; - } - req += sizeof(pcp_map_v2_t); + parsePCPMAP_version2(req, pcp_msg_info); + req += PCP_MAP_V2_SIZE; parsePCPOptions(req, remainingSize, pcp_msg_info); @@ -1371,6 +1337,7 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info) } } else { syslog(LOG_ERR, "PCP: Invalid PCP v2 MAP message."); + return pcp_msg_info->result_code; } @@ -1379,18 +1346,17 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info) #ifdef PCP_PEER case PCP_OPCODE_PEER: - remainingSize -= sizeof(pcp_peer_v2_t); + remainingSize -= PCP_PEER_V2_SIZE; if (remainingSize < 0) { pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST; return pcp_msg_info->result_code; } - peer_v2 = (pcp_peer_v2_t*)req; #ifdef DEBUG - printPEEROpcodeVersion2(peer_v2); + printPEEROpcodeVersion2(req); #endif /* DEBUG */ - parsePCPPEER_version2(peer_v2, pcp_msg_info); - req += sizeof(pcp_peer_v2_t); + parsePCPPEER_version2(req, pcp_msg_info); + req += PCP_PEER_V2_SIZE; if (pcp_msg_info->result_code != 0) { return pcp_msg_info->result_code; @@ -1413,25 +1379,27 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info) #ifdef PCP_SADSCP case PCP_OPCODE_SADSCP: - remainingSize -= sizeof(pcp_sadscp_req_t); + remainingSize -= PCP_SADSCP_REQ_SIZE; if (remainingSize < 0) { pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST; return pcp_msg_info->result_code; } - sadscp = (pcp_sadscp_req_t*)req; - req += sizeof(pcp_sadscp_req_t); - - if (sadscp->app_name_length > remainingSize) { + remainingSize -= ((uint8_t *)req)[13]; /* app_name_length */ + if (remainingSize < 0) { pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION; + return pcp_msg_info->result_code; } #ifdef DEBUG - printSADSCPOpcode(sadscp); + printSADSCPOpcode(req); #endif - if (parseSADSCP(sadscp, pcp_msg_info)) { + parseSADSCP(req, pcp_msg_info); + req += PCP_SADSCP_REQ_SIZE; + if (pcp_msg_info->result_code != 0) { return pcp_msg_info->result_code; } + req += pcp_msg_info->app_name_len; get_dscp_value(pcp_msg_info); @@ -1452,22 +1420,18 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info) static void createPCPResponse(unsigned char *response, pcp_info_t *pcp_msg_info) { - pcp_response_t *resp = (pcp_response_t*)response; - - resp->reserved = 0; - resp->reserved1[0]=0; - resp->reserved1[1]=0; - resp->reserved1[2]=0; + response[2] = 0; /* reserved */ + memset(response + 12, 0, 12); /* reserved */ if (pcp_msg_info->result_code == PCP_ERR_UNSUPP_VERSION ) { /* highest supported version */ - resp->ver = this_server_info.server_version; + response[0] = this_server_info.server_version; } else { - resp->ver = pcp_msg_info->version; + response[0] = pcp_msg_info->version; } - resp->r_opcode |= 0x80; - resp->result_code = pcp_msg_info->result_code; - resp->epochtime = htonl(time(NULL) - startup_time); + response[1] |= 0x80; /* r_opcode */ + response[3] = pcp_msg_info->result_code; + WRITENU32(response + 8, time(NULL) - startup_time); /* epochtime */ switch (pcp_msg_info->result_code) { /*long lifetime errors*/ case PCP_ERR_UNSUPP_VERSION: @@ -1480,61 +1444,60 @@ static void createPCPResponse(unsigned char *response, pcp_info_t *pcp_msg_info) case PCP_ERR_ADDRESS_MISMATCH: case PCP_ERR_CANNOT_PROVIDE_EXTERNAL: case PCP_ERR_EXCESSIVE_REMOTE_PEERS: - resp->lifetime = 0; + WRITENU32(response + 4, 0); /* lifetime */ break; case PCP_ERR_NETWORK_FAILURE: case PCP_ERR_NO_RESOURCES: case PCP_ERR_USER_EX_QUOTA: - resp->lifetime = htonl(30); + WRITENU32(response + 4, 30); /* lifetime */ break; case PCP_SUCCESS: default: - resp->lifetime = htonl(pcp_msg_info->lifetime); + WRITENU32(response + 4, pcp_msg_info->lifetime); /* lifetime */ break; } - if (resp->r_opcode == 0x81) { /* MAP response */ - if (resp->ver == 1 ) { - pcp_map_v1_t *mapr = (pcp_map_v1_t *)resp->next_data; - mapr->ext_ip = *pcp_msg_info->ext_ip; - mapr->ext_port = htons(pcp_msg_info->ext_port); - mapr->int_port = htons(pcp_msg_info->int_port); + if (response[1] == 0x81) { /* MAP response */ + if (response[0] == 1) { /* version */ + WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 4, pcp_msg_info->int_port); + WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 6, pcp_msg_info->ext_port); + copyIPv6IfDifferent(response + PCP_COMMON_RESPONSE_SIZE + 8, + pcp_msg_info->ext_ip); } - else if (resp->ver == 2 ) { - pcp_map_v2_t *mapr = (pcp_map_v2_t *)resp->next_data; - mapr->ext_ip = *pcp_msg_info->ext_ip; - mapr->ext_port = htons(pcp_msg_info->ext_port); - mapr->int_port = htons(pcp_msg_info->int_port); + else if (response[0] == 2) { + WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 16, pcp_msg_info->int_port); + WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 18, pcp_msg_info->ext_port); + copyIPv6IfDifferent(response + PCP_COMMON_RESPONSE_SIZE + 20, + pcp_msg_info->ext_ip); } } #ifdef PCP_PEER - else if (resp->r_opcode == 0x82) { /* PEER response */ - if (resp->ver == 1 ){ - pcp_peer_v1_t* peer_resp = (pcp_peer_v1_t*)resp->next_data; - peer_resp->ext_port = htons(pcp_msg_info->ext_port); - peer_resp->int_port = htons(pcp_msg_info->int_port); - peer_resp->peer_port = htons(pcp_msg_info->peer_port); - peer_resp->ext_ip = *pcp_msg_info->ext_ip; + else if (response[1] == 0x82) { /* PEER response */ + if (response[0] == 1) { + WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 4, pcp_msg_info->int_port); + WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 6, pcp_msg_info->ext_port); + WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 24, pcp_msg_info->peer_port); + copyIPv6IfDifferent(response + PCP_COMMON_RESPONSE_SIZE + 8, + pcp_msg_info->ext_ip); } - else if (resp->ver == 2 ){ - pcp_peer_v2_t* peer_resp = (pcp_peer_v2_t*)resp->next_data; - peer_resp->ext_port = htons(pcp_msg_info->ext_port); - peer_resp->int_port = htons(pcp_msg_info->int_port); - peer_resp->peer_port = htons(pcp_msg_info->peer_port); - peer_resp->ext_ip = *pcp_msg_info->ext_ip; + else if (response[0] == 2) { + WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 16, pcp_msg_info->int_port); + WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 18, pcp_msg_info->ext_port); + WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 36, pcp_msg_info->peer_port); + copyIPv6IfDifferent(response + PCP_COMMON_RESPONSE_SIZE + 20, + pcp_msg_info->ext_ip); } } #endif /* PCP_PEER */ #ifdef PCP_SADSCP - else if (resp->r_opcode == 0x83) { /*SADSCP response*/ - pcp_sadscp_resp_t *sadscp_resp = (pcp_sadscp_resp_t*)resp->next_data; - sadscp_resp->a_r_dscp_value = pcp_msg_info->matched_name<<7; - sadscp_resp->a_r_dscp_value &= ~(1<<6); - sadscp_resp->a_r_dscp_value |= (pcp_msg_info->sadscp_dscp & PCP_SADSCP_MASK); - memset(sadscp_resp->reserved, 0, sizeof(sadscp_resp->reserved)); + else if (response[1] == 0x83) { /*SADSCP response*/ + response[PCP_COMMON_RESPONSE_SIZE + 12] + = ((pcp_msg_info->matched_name<<7) & ~(1<<6)) | + (pcp_msg_info->sadscp_dscp & PCP_SADSCP_MASK); + memset(response + PCP_COMMON_RESPONSE_SIZE + 13, 0, 3); } #endif /* PCP_SADSCP */ } diff --git a/release/src/router/miniupnpd/portinuse.c b/release/src/router/miniupnpd/portinuse.c index b48061c20e..7b145a10e7 100644 --- a/release/src/router/miniupnpd/portinuse.c +++ b/release/src/router/miniupnpd/portinuse.c @@ -1,4 +1,4 @@ -/* $Id: portinuse.c,v 1.4 2014/04/20 16:46:42 nanard Exp $ */ +/* $Id: portinuse.c,v 1.5 2016/01/13 16:02:08 nanard Exp $ */ /* MiniUPnP project * (c) 2007-2014 Thomas Bernard * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ @@ -79,7 +79,7 @@ port_in_use(const char *if_name, ip_addr_str[0] = '\0'; } - syslog(LOG_DEBUG, "Check protocol %s for port %d on ext_if %s %s, %08X", + syslog(LOG_DEBUG, "Check protocol %s for port %u on ext_if %s %s, %08X", (proto==IPPROTO_TCP)?"tcp":"udp", eport, if_name, ip_addr_str, (unsigned)ip_addr.s_addr); @@ -101,7 +101,7 @@ port_in_use(const char *if_name, /* TODO add IPV6 support if enabled * Presently assumes IPV4 */ #ifdef DEBUG - syslog(LOG_DEBUG, "port_in_use check port %d and address %s", tmp_port, eaddr); + syslog(LOG_DEBUG, "port_in_use check port %u and address %s", tmp_port, eaddr); #endif if (tmp_port == eport) { char tmp_addr[4]; diff --git a/release/src/router/miniupnpd/testgetroute.c b/release/src/router/miniupnpd/testgetroute.c index 1afab64916..b8571d872d 100644 --- a/release/src/router/miniupnpd/testgetroute.c +++ b/release/src/router/miniupnpd/testgetroute.c @@ -1,7 +1,7 @@ -/* $Id: testgetroute.c,v 1.5 2013/02/06 12:07:36 nanard Exp $ */ +/* $Id: testgetroute.c,v 1.6 2015/11/16 19:20:21 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2013 Thomas Bernard + * (c) 2006-2015 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ @@ -75,6 +75,13 @@ main(int argc, char ** argv) } if (dst) { + syslog(LOG_DEBUG, "calling get_src_for_route_to(%p, NULL, NULL, %p)", + dst, &index); + r = get_src_for_route_to (dst, NULL, NULL, &index); + syslog(LOG_DEBUG, "get_src_for_route_to() returned %d", r); + if(r >= 0) { + syslog(LOG_DEBUG, "index=%d", index); + } syslog(LOG_DEBUG, "calling get_src_for_route_to(%p, %p, %p(%u), %p)", dst, src, &src_len, (unsigned)src_len, &index); r = get_src_for_route_to (dst, src, &src_len, &index); diff --git a/release/src/router/miniupnpd/testssdppktgen.c b/release/src/router/miniupnpd/testssdppktgen.c new file mode 100644 index 0000000000..7f62daba40 --- /dev/null +++ b/release/src/router/miniupnpd/testssdppktgen.c @@ -0,0 +1,100 @@ +/* $Id: testssdppktgen.c,v 1.1 2015/10/26 16:54:31 nanard Exp $ */ +#include +#include +#include + +#include "config.h" +#include "miniupnpdpath.h" +#include "upnphttp.h" +#include "macros.h" + +#define SSDP_PORT 1900 + +char uuidvalue_igd[] = "uuid:12345678-0000-0000-0000-000000abcd01"; +unsigned upnp_bootid; +unsigned upnp_configid; + +static int +MakeSSDPPacket(const char * dest_str, + const char * host, unsigned short http_port, +#ifdef ENABLE_HTTPS + unsigned short https_port, +#endif + const char * nt, const char * suffix, + const char * usn1, const char * usn2, const char * usn3, + unsigned int lifetime) +{ + char bufr[SSDP_PACKET_MAX_LEN]; + int l; + + l = snprintf(bufr, sizeof(bufr), + "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%d\r\n" + "CACHE-CONTROL: max-age=%u\r\n" + "LOCATION: http://%s:%u" ROOTDESC_PATH "\r\n" +#ifdef ENABLE_HTTPS + "SECURELOCATION.UPNP.ORG: https://%s:%u" ROOTDESC_PATH "\r\n" +#endif + "SERVER: " MINIUPNPD_SERVER_STRING "\r\n" + "NT: %s%s\r\n" + "USN: %s%s%s%s\r\n" + "NTS: ssdp:alive\r\n" + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" /* UDA v1.1 */ + "01-NLS: %u\r\n" /* same as BOOTID field. UDA v1.1 */ + "BOOTID.UPNP.ORG: %u\r\n" /* UDA v1.1 */ + "CONFIGID.UPNP.ORG: %u\r\n" /* UDA v1.1 */ + "\r\n", + dest_str, SSDP_PORT, /* HOST: */ + lifetime, /* CACHE-CONTROL: */ + host, (unsigned int)http_port, /* LOCATION: */ +#ifdef ENABLE_HTTPS + host, (unsigned int)https_port, /* SECURE-LOCATION: */ +#endif + nt, suffix, /* NT: */ + usn1, usn2, usn3, suffix, /* USN: */ + upnp_bootid, /* 01-NLS: */ + upnp_bootid, /* BOOTID.UPNP.ORG: */ + upnp_configid ); /* CONFIGID.UPNP.ORG: */ + if(l<0) { + syslog(LOG_ERR, "%s: snprintf error", "MakeSSDPPacket()"); + return -1; + } else if((unsigned int)l >= sizeof(bufr)) { + syslog(LOG_WARNING, "%s: truncated output (%u>=%u)", + "MakeSSDPPacket()", (unsigned)l, (unsigned)sizeof(bufr)); + l = sizeof(bufr) - 1; + return -1; + } + return 0; +} + + +int main(int argc, char * * argv) +{ + int r; + UNUSED(argc); UNUSED(argv); + + openlog("testssdppktgen", LOG_CONS|LOG_PERROR, LOG_USER); + upnp_bootid = (unsigned)time(NULL); + upnp_configid = 1234567890; + r = MakeSSDPPacket("123.456.789.123", "222.222.222.222", 12345, +#ifdef ENABLE_HTTPS + 54321, +#endif /* ENABLE_HTTPS */ + "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:", "1", + uuidvalue_igd, "", "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:", + 1234567890); + if(r < 0) return 1; +#ifdef ENABLE_IPV6 + r = MakeSSDPPacket("[1234:5678:abcd:ef00:1234:5678:abcd:ef00]", + "[1000:2000:3000:4000:5000:6000:7000:8000]", 12345, +#ifdef ENABLE_HTTPS + 54321, +#endif /* ENABLE_HTTPS */ + "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:", "1", + uuidvalue_igd, "", "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:", + 1234567890); + if(r < 0) return 1; +#endif /* ENABLE_IPV6 */ + return 0; +} + diff --git a/release/src/router/miniupnpd/testupnppermissions.c b/release/src/router/miniupnpd/testupnppermissions.c index a044e812c1..2ab8802353 100644 --- a/release/src/router/miniupnpd/testupnppermissions.c +++ b/release/src/router/miniupnpd/testupnppermissions.c @@ -1,5 +1,5 @@ -/* $Id: testupnppermissions.c,v 1.3 2009/09/14 15:24:46 nanard Exp $ */ -/* (c) 2007-2009 Thomas Bernard +/* $Id: testupnppermissions.c,v 1.4 2015/10/26 16:53:26 nanard Exp $ */ +/* (c) 2007-2015 Thomas Bernard * MiniUPnP Project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ */ @@ -35,7 +35,7 @@ print_upnpperm(const struct upnpperm * p) int main(int argc, char * * argv) { - int i, r; + int i, r, ret; struct upnpperm p; if(argc < 2) { fprintf(stderr, "Usage: %s \"permission line\" [...]\n", argv[0]); @@ -43,8 +43,7 @@ int main(int argc, char * * argv) return 1; } openlog("testupnppermissions", LOG_PERROR, LOG_USER); -/* for(i=0; i'); str = strcat_str(str, len, &tmplen, - "10"); + "" UPNP_VERSION_MAJOR_STR "" + "" UPNP_VERSION_MINOR_STR ""); i = 0; str = strcat_str(str, len, &tmplen, ""); @@ -1167,6 +1208,13 @@ genEventVars(int * len, const struct serviceDesc * s) switch(v->ieventvalue) { case 0: break; +#ifdef ENABLE_DP_SERVICE + case SETUPREADY_MAGICALVALUE: + /* always ready for setup */ + snprintf(tmp, sizeof(tmp), "%d", 1); + str = strcat_str(str, len, &tmplen, tmp); + break; +#endif case CONNECTIONSTATUS_MAGICALVALUE: /* or get_wan_connection_status_str(ext_if_name) */ str = strcat_str(str, len, &tmplen, diff --git a/release/src/router/miniupnpd/upnpdescstrings.h b/release/src/router/miniupnpd/upnpdescstrings.h index cc24a5a170..e817362c38 100644 --- a/release/src/router/miniupnpd/upnpdescstrings.h +++ b/release/src/router/miniupnpd/upnpdescstrings.h @@ -1,4 +1,4 @@ -/* $Id: upnpdescstrings.h,v 1.9 2013/12/13 12:50:54 nanard Exp $ */ +/* $Id: upnpdescstrings.h,v 1.10 2015/09/22 10:07:13 nanard Exp $ */ /* miniupnp project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2013 Thomas Bernard @@ -22,7 +22,7 @@ #define WANDEV_MANUFACTURERURL "http://miniupnp.free.fr/" #define WANDEV_MODELNAME "WAN Device" #define WANDEV_MODELDESCRIPTION "WAN Device" -#define WANDEV_MODELNUMBER UPNP_VERSION +#define WANDEV_MODELNUMBER MINIUPNPD_DATE #define WANDEV_MODELURL "http://miniupnp.free.fr/" #define WANDEV_UPC "000000000000" /* UPC is 12 digit (barcode) */ @@ -32,7 +32,7 @@ #define WANCDEV_MANUFACTURERURL WANDEV_MANUFACTURERURL #define WANCDEV_MODELNAME "MiniUPnPd" #define WANCDEV_MODELDESCRIPTION "MiniUPnP daemon" -#define WANCDEV_MODELNUMBER UPNP_VERSION +#define WANCDEV_MODELNUMBER MINIUPNPD_DATE #define WANCDEV_MODELURL "http://miniupnp.free.fr/" #define WANCDEV_UPC "000000000000" /* UPC is 12 digit (barcode) */ diff --git a/release/src/router/miniupnpd/upnpevents.c b/release/src/router/miniupnpd/upnpevents.c index 628aff8940..569eb60d85 100644 --- a/release/src/router/miniupnpd/upnpevents.c +++ b/release/src/router/miniupnpd/upnpevents.c @@ -1,7 +1,7 @@ -/* $Id: upnpevents.c,v 1.30 2014/03/14 22:26:07 nanard Exp $ */ +/* $Id: upnpevents.c,v 1.32 2015/12/15 11:11:12 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2008-2014 Thomas Bernard + * (c) 2008-2015 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ @@ -112,7 +112,7 @@ newSubscriber(const char * eventurl, const char * callback, int callbacklen) /* TODO: improve that */ strncpy(tmp->uuid, uuidvalue_igd, sizeof(tmp->uuid)); tmp->uuid[sizeof(tmp->uuid)-1] = '\0'; - snprintf(tmp->uuid+37, 5, "%04lx", random() & 0xffff); + snprintf(tmp->uuid+sizeof(tmp->uuid)-5, 5, "%04lx", random() & 0xffff); return tmp; } @@ -143,8 +143,8 @@ upnpevents_addSubscriber(const char * eventurl, } /* renew a subscription (update the timeout) */ -int -renewSubscription(const char * sid, int sidlen, int timeout) +const char * +upnpevents_renewSubscription(const char * sid, int sidlen, int timeout) { struct subscriber * sub; for(sub = subscriberlist.lh_first; sub != NULL; sub = sub->entries.le_next) { @@ -155,10 +155,10 @@ renewSubscription(const char * sid, int sidlen, int timeout) continue; #endif sub->timeout = (timeout ? time(NULL) + timeout : 0); - return 0; + return sub->uuid; } } - return -1; + return NULL; } int diff --git a/release/src/router/miniupnpd/upnpevents.h b/release/src/router/miniupnpd/upnpevents.h index 27c20699b8..04d6105eb6 100644 --- a/release/src/router/miniupnpd/upnpevents.h +++ b/release/src/router/miniupnpd/upnpevents.h @@ -1,7 +1,7 @@ -/* $Id: upnpevents.h,v 1.10 2012/09/27 16:00:10 nanard Exp $ */ +/* $Id: upnpevents.h,v 1.11 2015/12/12 09:36:22 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2008-2011 Thomas Bernard + * (c) 2008-2015 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ @@ -36,8 +36,8 @@ upnpevents_addSubscriber(const char * eventurl, int upnpevents_removeSubscriber(const char * sid, int sidlen); -int -renewSubscription(const char * sid, int sidlen, int timeout); +const char * +upnpevents_renewSubscription(const char * sid, int sidlen, int timeout); void upnpevents_selectfds(fd_set *readset, fd_set *writeset, int * max_fd); void upnpevents_processfds(fd_set *readset, fd_set *writeset); diff --git a/release/src/router/miniupnpd/upnphttp.c b/release/src/router/miniupnpd/upnphttp.c index 958b404bab..42f6e4083c 100644 --- a/release/src/router/miniupnpd/upnphttp.c +++ b/release/src/router/miniupnpd/upnphttp.c @@ -1,8 +1,9 @@ -/* $Id: upnphttp.c,v 1.99 2014/12/09 17:25:30 nanard Exp $ */ +/* $Id: upnphttp.c,v 1.103 2015/12/16 10:21:49 nanard Exp $ */ +/* vim: tabstop=4 shiftwidth=4 noexpandtab */ /* Project : miniupnp * Website : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * Author : Thomas Bernard - * Copyright (c) 2005-2014 Thomas Bernard + * Copyright (c) 2005-2015 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file included in this distribution. * */ @@ -60,7 +61,7 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) int init_ssl(void) { - SSL_METHOD *method; + const SSL_METHOD *method; SSL_library_init(); SSL_load_error_strings(); method = TLSv1_server_method(); @@ -665,11 +666,13 @@ with HTTP error 412 Precondition Failed. */ BuildResp2_upnphttp(h, 400, "Incompatible header fields", 0, 0); } else #endif - if(renewSubscription(h->req_buf + h->req_SIDOff, h->req_SIDLen, - h->req_Timeout) < 0) { + sid = upnpevents_renewSubscription(h->req_buf + h->req_SIDOff, + h->req_SIDLen, h->req_Timeout); + if(!sid) { BuildResp2_upnphttp(h, 412, "Precondition Failed", 0, 0); } else { - h->respflags = FLAG_TIMEOUT; + h->respflags = FLAG_TIMEOUT | FLAG_SID; + h->res_SID = sid; BuildResp_upnphttp(h, 0, 0); } } @@ -734,6 +737,7 @@ ProcessHttpQuery_upnphttp(struct upnphttp * h) char * HttpVer; char * p; int i; + p = h->req_buf; if(!p) return; @@ -754,8 +758,8 @@ ProcessHttpQuery_upnphttp(struct upnphttp * h) for(i = 0; i<15 && *p != '\r'; i++) HttpVer[i] = *(p++); HttpVer[i] = '\0'; - syslog(LOG_INFO, "HTTP REQUEST : %s %s (%s)", - HttpCommand, HttpUrl, HttpVer); + syslog(LOG_INFO, "HTTP REQUEST from %s : %s %s (%s)", + h->clientaddr_str, HttpCommand, HttpUrl, HttpVer); ParseHttpHeaders(h); if(h->req_HostOff > 0 && h->req_HostLen > 0) { syslog(LOG_DEBUG, "Host: %.*s", h->req_HostLen, h->req_buf + h->req_HostOff); @@ -858,6 +862,7 @@ Process_upnphttp(struct upnphttp * h) char * h_tmp; char buf[2048]; int n; + if(!h) return; switch(h->state) @@ -900,8 +905,7 @@ Process_upnphttp(struct upnphttp * h) } else if(n==0) { - syslog(LOG_WARNING, "HTTP Connection from %s closed unexpectedly", - inet_ntoa(h->clientaddr)); //!!TB - added client address + syslog(LOG_WARNING, "HTTP Connection from %s closed unexpectedly", inet_ntoa(h->clientaddr)); h->state = EToDelete; } else @@ -971,8 +975,7 @@ Process_upnphttp(struct upnphttp * h) } else if(n==0) { - syslog(LOG_WARNING, "HTTP Connection from %s closed unexpectedly", - inet_ntoa(h->clientaddr)); //!!TB - added client address + syslog(LOG_WARNING, "HTTP Connection from %s closed unexpectedly", inet_ntoa(h->clientaddr)); h->state = EToDelete; } else diff --git a/release/src/router/miniupnpd/upnphttp.h b/release/src/router/miniupnpd/upnphttp.h index a060211520..bf48b47b49 100644 --- a/release/src/router/miniupnpd/upnphttp.h +++ b/release/src/router/miniupnpd/upnphttp.h @@ -1,7 +1,8 @@ -/* $Id: upnphttp.h,v 1.40 2014/12/09 16:41:21 nanard Exp $ */ +/* $Id: upnphttp.h,v 1.42 2015/12/16 10:21:49 nanard Exp $ */ +/* vim: tabstop=4 shiftwidth=4 noexpandtab */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2014 Thomas Bernard + * (c) 2006-2015 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ @@ -17,13 +18,7 @@ #include #endif /* ENABLE_HTTPS */ -#if 0 -/* according to "UPnP Device Architecture 1.0" */ -#define UPNP_VERSION_STRING "UPnP/1.0" -#else -/* according to "UPnP Device Architecture 1.1" */ -#define UPNP_VERSION_STRING "UPnP/1.1" -#endif +#define UPNP_VERSION_STRING "UPnP/" UPNP_VERSION_MAJOR_STR "." UPNP_VERSION_MINOR_STR /* server: HTTP header returned in all HTTP responses : */ #define MINIUPNPD_SERVER_STRING OS_VERSION " " UPNP_VERSION_STRING " MiniUPnPd/" MINIUPNPD_VERSION @@ -61,6 +56,7 @@ struct upnphttp { #ifdef ENABLE_HTTPS SSL * ssl; #endif /* ENABLE_HTTPS */ + char clientaddr_str[64]; /* used for syslog() output */ enum httpStates state; char HttpVer[16]; /* request */ diff --git a/release/src/router/miniupnpd/upnpreplyparse.c b/release/src/router/miniupnpd/upnpreplyparse.c index 8daa6a052b..5de5796a39 100644 --- a/release/src/router/miniupnpd/upnpreplyparse.c +++ b/release/src/router/miniupnpd/upnpreplyparse.c @@ -1,7 +1,7 @@ -/* $Id: upnpreplyparse.c,v 1.18 2014/11/05 05:36:08 nanard Exp $ */ +/* $Id: upnpreplyparse.c,v 1.19 2015/07/15 10:29:11 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2014 Thomas Bernard + * (c) 2006-2015 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ @@ -40,6 +40,15 @@ NameValueParserEndElt(void * d, const char * name, int l) /* standard case. Limited to n chars strings */ l = data->cdatalen; nv = malloc(sizeof(struct NameValue)); + if(nv == NULL) + { + /* malloc error */ +#ifdef DEBUG + fprintf(stderr, "%s: error allocating memory", + "NameValueParserEndElt"); +#endif /* DEBUG */ + return; + } if(l>=(int)sizeof(nv->value)) l = sizeof(nv->value) - 1; strncpy(nv->name, data->curelt, 64); @@ -72,6 +81,10 @@ NameValueParserGetData(void * d, const char * datas, int l) if(!data->portListing) { /* malloc error */ +#ifdef DEBUG + fprintf(stderr, "%s: error allocating memory", + "NameValueParserGetData"); +#endif /* DEBUG */ return; } memcpy(data->portListing, datas, l); @@ -180,5 +193,5 @@ DisplayNameValueList(char * buffer, int bufsize) } ClearNameValueList(&pdata); } -#endif +#endif /* DEBUG */ diff --git a/release/src/router/miniupnpd/upnpsoap.c b/release/src/router/miniupnpd/upnpsoap.c index 7d126a1dfa..1eb64e6779 100644 --- a/release/src/router/miniupnpd/upnpsoap.c +++ b/release/src/router/miniupnpd/upnpsoap.c @@ -1,4 +1,4 @@ -/* $Id: upnpsoap.c,v 1.136 2015/03/07 15:52:30 nanard Exp $ */ +/* $Id: upnpsoap.c,v 1.142 2015/12/15 11:12:37 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2015 Thomas Bernard @@ -65,21 +65,32 @@ BuildSendAndCloseSoapResp(struct upnphttp * h, } static void -GetConnectionTypeInfo(struct upnphttp * h, const char * action) +GetConnectionTypeInfo(struct upnphttp * h, const char * action, const char * ns) { +#if 0 static const char resp[] = "" "IP_Routed" "IP_Routed" ""; - UNUSED(action); +#endif + static const char resp[] = + "" + "IP_Routed" + "IP_Routed" + ""; + char body[512]; + int bodylen; - BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1); + bodylen = snprintf(body, sizeof(body), resp, + action, ns, action); + BuildSendAndCloseSoapResp(h, body, bodylen); } static void -GetTotalBytesSent(struct upnphttp * h, const char * action) +GetTotalBytesSent(struct upnphttp * h, const char * action, const char * ns) { int r; @@ -95,13 +106,13 @@ GetTotalBytesSent(struct upnphttp * h, const char * action) r = getifstats(ext_if_name, &data); bodylen = snprintf(body, sizeof(body), resp, - action, "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1", + action, ns, /* was "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */ r<0?0:data.obytes, action); BuildSendAndCloseSoapResp(h, body, bodylen); } static void -GetTotalBytesReceived(struct upnphttp * h, const char * action) +GetTotalBytesReceived(struct upnphttp * h, const char * action, const char * ns) { int r; @@ -117,13 +128,13 @@ GetTotalBytesReceived(struct upnphttp * h, const char * action) r = getifstats(ext_if_name, &data); bodylen = snprintf(body, sizeof(body), resp, - action, "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1", + action, ns, /* was "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */ r<0?0:data.ibytes, action); BuildSendAndCloseSoapResp(h, body, bodylen); } static void -GetTotalPacketsSent(struct upnphttp * h, const char * action) +GetTotalPacketsSent(struct upnphttp * h, const char * action, const char * ns) { int r; @@ -139,13 +150,13 @@ GetTotalPacketsSent(struct upnphttp * h, const char * action) r = getifstats(ext_if_name, &data); bodylen = snprintf(body, sizeof(body), resp, - action, "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1", + action, ns,/*"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1",*/ r<0?0:data.opackets, action); BuildSendAndCloseSoapResp(h, body, bodylen); } static void -GetTotalPacketsReceived(struct upnphttp * h, const char * action) +GetTotalPacketsReceived(struct upnphttp * h, const char * action, const char * ns) { int r; @@ -161,13 +172,13 @@ GetTotalPacketsReceived(struct upnphttp * h, const char * action) r = getifstats(ext_if_name, &data); bodylen = snprintf(body, sizeof(body), resp, - action, "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1", + action, ns, /* was "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */ r<0?0:data.ipackets, action); BuildSendAndCloseSoapResp(h, body, bodylen); } static void -GetCommonLinkProperties(struct upnphttp * h, const char * action) +GetCommonLinkProperties(struct upnphttp * h, const char * action, const char * ns) { /* WANAccessType : set depending on the hardware : * DSL, POTS (plain old Telephone service), Cable, Ethernet */ @@ -200,7 +211,7 @@ GetCommonLinkProperties(struct upnphttp * h, const char * action) status = "Down"; } bodylen = snprintf(body, sizeof(body), resp, - action, "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1", + action, ns, /* was "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */ wan_access_type, upstream_bitrate, downstream_bitrate, status, action); @@ -208,7 +219,7 @@ GetCommonLinkProperties(struct upnphttp * h, const char * action) } static void -GetStatusInfo(struct upnphttp * h, const char * action) +GetStatusInfo(struct upnphttp * h, const char * action, const char * ns) { static const char resp[] = "" @@ -244,6 +256,15 @@ GetNATRSIPStatus(struct upnphttp * h, const char * action) "1" ""; UNUSED(action); +#endif + static const char resp[] = + "" + "0" + "1" + ""; + char body[512]; + int bodylen; /* 2.2.9. RSIPAvailable * This variable indicates if Realm-specific IP (RSIP) is available * as a feature on the InternetGatewayDevice. RSIP is being defined @@ -252,11 +273,14 @@ GetNATRSIPStatus(struct upnphttp * h, const char * action) * applications that otherwise break if NAT is introduced * (e.g. IPsec-based VPNs). * A gateway that does not support RSIP should set this variable to 0. */ - BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1); + bodylen = snprintf(body, sizeof(body), resp, + action, ns, /*SERVICE_TYPE_WANIPC,*/ + action); + BuildSendAndCloseSoapResp(h, body, bodylen); } static void -GetExternalIPAddress(struct upnphttp * h, const char * action) +GetExternalIPAddress(struct upnphttp * h, const char * action, const char * ns) { static const char resp[] = ""; + "xmlns:u=\"" SERVICE_TYPE_WANIPC "\"/>";*/ + static const char resp[] = + ""; + char body[512]; + int bodylen; struct NameValueParserData data; char * int_ip, * int_port, * ext_port, * protocol, * desc; char * leaseduration_str; @@ -450,7 +480,9 @@ AddPortMapping(struct upnphttp * h, const char * action) switch(r) { case 0: /* success */ - BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1); + bodylen = snprintf(body, sizeof(body), resp, + action, ns/*SERVICE_TYPE_WANIPC*/); + BuildSendAndCloseSoapResp(h, body, bodylen); break; case -2: /* already redirected */ case -3: /* not permitted */ @@ -463,7 +495,7 @@ AddPortMapping(struct upnphttp * h, const char * action) /* AddAnyPortMapping was added in WANIPConnection v2 */ static void -AddAnyPortMapping(struct upnphttp * h, const char * action) +AddAnyPortMapping(struct upnphttp * h, const char * action, const char * ns) { int r; static const char resp[] = @@ -573,7 +605,7 @@ AddAnyPortMapping(struct upnphttp * h, const char * action) { case 0: /* success */ bodylen = snprintf(body, sizeof(body), resp, - action, SERVICE_TYPE_WANIPC, + action, ns, /*SERVICE_TYPE_WANIPC,*/ eport, action); BuildSendAndCloseSoapResp(h, body, bodylen); break; @@ -589,7 +621,7 @@ AddAnyPortMapping(struct upnphttp * h, const char * action) } static void -GetSpecificPortMappingEntry(struct upnphttp * h, const char * action) +GetSpecificPortMappingEntry(struct upnphttp * h, const char * action, const char * ns) { int r; @@ -661,7 +693,7 @@ GetSpecificPortMappingEntry(struct upnphttp * h, const char * action) r_host ? r_host : "NULL", ext_port, protocol, int_ip, (unsigned int)iport, desc); bodylen = snprintf(body, sizeof(body), resp, - action, SERVICE_TYPE_WANIPC, + action, ns/*SERVICE_TYPE_WANIPC*/, (unsigned int)iport, int_ip, desc, leaseduration, action); BuildSendAndCloseSoapResp(h, body, bodylen); @@ -671,15 +703,21 @@ GetSpecificPortMappingEntry(struct upnphttp * h, const char * action) } static void -DeletePortMapping(struct upnphttp * h, const char * action) +DeletePortMapping(struct upnphttp * h, const char * action, const char * ns) { int r; - static const char resp[] = + /*static const char resp[] = "" - ""; + "";*/ + static const char resp[] = + "" + ""; + char body[512]; + int bodylen; struct NameValueParserData data; const char * ext_port, * protocol; unsigned short eport; @@ -757,7 +795,9 @@ DeletePortMapping(struct upnphttp * h, const char * action) } else { - BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1); + bodylen = snprintf(body, sizeof(body), resp, + action, ns, action); + BuildSendAndCloseSoapResp(h, body, bodylen); } ClearNameValueList(&data); @@ -765,13 +805,19 @@ DeletePortMapping(struct upnphttp * h, const char * action) /* DeletePortMappingRange was added in IGD spec v2 */ static void -DeletePortMappingRange(struct upnphttp * h, const char * action) +DeletePortMappingRange(struct upnphttp * h, const char * action, const char * ns) { int r = -1; - static const char resp[] = + /*static const char resp[] = "" - ""; + "";*/ + static const char resp[] = + "" + ""; + char body[512]; + int bodylen; struct NameValueParserData data; const char * protocol; const char * startport_s, * endport_s; @@ -779,7 +825,6 @@ DeletePortMappingRange(struct upnphttp * h, const char * action) /*int manage;*/ unsigned short * port_list; unsigned int i, number = 0; - UNUSED(action); ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data); startport_s = GetValueFromNameValueList(&data, "NewStartPort"); @@ -815,6 +860,7 @@ DeletePortMappingRange(struct upnphttp * h, const char * action) { SoapError(h, 730, "PortMappingNotFound"); ClearNameValueList(&data); + free(port_list); return; } @@ -825,13 +871,15 @@ DeletePortMappingRange(struct upnphttp * h, const char * action) action, port_list[i], protocol, r < 0 ? "failed" : "ok"); } free(port_list); - BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1); + bodylen = snprintf(body, sizeof(body), resp, + action, ns, action); + BuildSendAndCloseSoapResp(h, body, bodylen); ClearNameValueList(&data); } static void -GetGenericPortMappingEntry(struct upnphttp * h, const char * action) +GetGenericPortMappingEntry(struct upnphttp * h, const char * action, const char * ns) { int r; @@ -902,7 +950,7 @@ GetGenericPortMappingEntry(struct upnphttp * h, const char * action) int bodylen; char body[2048]; bodylen = snprintf(body, sizeof(body), resp, - action, SERVICE_TYPE_WANIPC, rhost, + action, ns, /*SERVICE_TYPE_WANIPC,*/ rhost, (unsigned int)eport, protocol, (unsigned int)iport, iaddr, desc, leaseduration, action); BuildSendAndCloseSoapResp(h, body, bodylen); @@ -913,7 +961,7 @@ GetGenericPortMappingEntry(struct upnphttp * h, const char * action) /* GetListOfPortMappings was added in the IGD v2 specification */ static void -GetListOfPortMappings(struct upnphttp * h, const char * action) +GetListOfPortMappings(struct upnphttp * h, const char * action, const char * ns) { static const char resp_start[] = " return; } bodylen = snprintf(body, bodyalloc, resp_start, - action, SERVICE_TYPE_WANIPC); + action, ns/*SERVICE_TYPE_WANIPC*/); if(bodylen < 0) { SoapError(h, 501, "ActionFailed"); @@ -1091,12 +1139,18 @@ http://www.upnp.org/schemas/gw/WANIPConnection-v2.xsd"> #ifdef ENABLE_L3F_SERVICE static void -SetDefaultConnectionService(struct upnphttp * h, const char * action) +SetDefaultConnectionService(struct upnphttp * h, const char * action, const char * ns) { - static const char resp[] = + /*static const char resp[] = "" - ""; + "";*/ + static const char resp[] = + "" + ""; + char body[512]; + int bodylen; struct NameValueParserData data; char * p; ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data); @@ -1116,7 +1170,9 @@ SetDefaultConnectionService(struct upnphttp * h, const char * action) #endif { syslog(LOG_INFO, "%s(%s) : Ignored", action, p); - BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1); + bodylen = snprintf(body, sizeof(body), resp, + action, ns, action); + BuildSendAndCloseSoapResp(h, body, bodylen); } } else { /* missing argument */ @@ -1126,12 +1182,16 @@ SetDefaultConnectionService(struct upnphttp * h, const char * action) } static void -GetDefaultConnectionService(struct upnphttp * h, const char * action) +GetDefaultConnectionService(struct upnphttp * h, const char * action, const char * ns) { static const char resp[] = "" + "xmlns:u=\"%s\">" +#ifdef IGD_V2 + "%s:WANConnectionDevice:2," +#else "%s:WANConnectionDevice:1," +#endif SERVICE_ID_WANIPC "" ""; /* example from UPnP_IGD_Layer3Forwarding 1.0.pdf : @@ -1140,21 +1200,23 @@ GetDefaultConnectionService(struct upnphttp * h, const char * action) char body[1024]; int bodylen; + /* namespace : urn:schemas-upnp-org:service:Layer3Forwarding:1 */ bodylen = snprintf(body, sizeof(body), resp, - action, uuidvalue_wcd, action); + action, ns, uuidvalue_wcd, action); BuildSendAndCloseSoapResp(h, body, bodylen); } #endif /* Added for compliance with WANIPConnection v2 */ static void -SetConnectionType(struct upnphttp * h, const char * action) +SetConnectionType(struct upnphttp * h, const char * action, const char * ns) { #ifdef UPNP_STRICT const char * connection_type; #endif /* UPNP_STRICT */ struct NameValueParserData data; UNUSED(action); + UNUSED(ns); ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data); #ifdef UPNP_STRICT @@ -1173,17 +1235,19 @@ SetConnectionType(struct upnphttp * h, const char * action) /* Added for compliance with WANIPConnection v2 */ static void -RequestConnection(struct upnphttp * h, const char * action) +RequestConnection(struct upnphttp * h, const char * action, const char * ns) { UNUSED(action); + UNUSED(ns); SoapError(h, 606, "Action not authorized"); } /* Added for compliance with WANIPConnection v2 */ static void -ForceTermination(struct upnphttp * h, const char * action) +ForceTermination(struct upnphttp * h, const char * action, const char * ns) { UNUSED(action); + UNUSED(ns); SoapError(h, 606, "Action not authorized"); } @@ -1196,7 +1260,7 @@ QueryStateVariable remains useful as a limited test tool but may not be part of some future versions of UPnP. */ static void -QueryStateVariable(struct upnphttp * h, const char * action) +QueryStateVariable(struct upnphttp * h, const char * action, const char * ns) { static const char resp[] = "" ""; +#endif + static const char resp[] = + "" + ""; + char body[512]; + int bodylen; struct NameValueParserData data; const char * uid_str, * leaseTime; char iaddr[INET6_ADDRSTRLEN]; @@ -1648,12 +1720,15 @@ UpdatePinhole(struct upnphttp * h, const char * action) SoapError(h, 704, "NoSuchEntry"); else if(n < 0) SoapError(h, 501, "ActionFailed"); - else - BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1); + else { + bodylen = snprintf(body, sizeof(body), resp, + action, ns, action); + BuildSendAndCloseSoapResp(h, body, bodylen); + } } static void -GetOutboundPinholeTimeout(struct upnphttp * h, const char * action) +GetOutboundPinholeTimeout(struct upnphttp * h, const char * action, const char * ns) { int r; @@ -1667,7 +1742,8 @@ GetOutboundPinholeTimeout(struct upnphttp * h, const char * action) int bodylen; struct NameValueParserData data; char * int_ip, * int_port, * rem_host, * rem_port, * protocol; - int opt=0, proto=0; + int opt=0; + /*int proto=0;*/ unsigned short iport, rport; if (GETFLAG(IPV6FCFWDISABLEDMASK)) @@ -1685,7 +1761,7 @@ GetOutboundPinholeTimeout(struct upnphttp * h, const char * action) rport = (unsigned short)atoi(rem_port); iport = (unsigned short)atoi(int_port); - proto = atoi(protocol); + /*proto = atoi(protocol);*/ syslog(LOG_INFO, "%s: retrieving timeout for outbound pinhole from [%s]:%hu to [%s]:%hu protocol %s", action, int_ip, iport,rem_host, rport, protocol); @@ -1696,7 +1772,7 @@ GetOutboundPinholeTimeout(struct upnphttp * h, const char * action) { case 1: /* success */ bodylen = snprintf(body, sizeof(body), resp, - action, "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1", + action, ns/*"urn:schemas-upnp-org:service:WANIPv6FirewallControl:1"*/, opt, action); BuildSendAndCloseSoapResp(h, body, bodylen); break; @@ -1710,14 +1786,21 @@ GetOutboundPinholeTimeout(struct upnphttp * h, const char * action) } static void -DeletePinhole(struct upnphttp * h, const char * action) +DeletePinhole(struct upnphttp * h, const char * action, const char * ns) { int n; - +#if 0 static const char resp[] = "" ""; +#endif + static const char resp[] = + "" + ""; + char body[512]; + int bodylen; struct NameValueParserData data; const char * uid_str; @@ -1774,11 +1857,13 @@ DeletePinhole(struct upnphttp * h, const char * action) } syslog(LOG_INFO, "%s: (inbound) pinhole with ID %d successfully removed", action, uid); - BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1); + bodylen = snprintf(body, sizeof(body), resp, + action, ns, action); + BuildSendAndCloseSoapResp(h, body, bodylen); } static void -CheckPinholeWorking(struct upnphttp * h, const char * action) +CheckPinholeWorking(struct upnphttp * h, const char * action, const char * ns) { static const char resp[] = "" - "%s" + "%s" ""; char body[1024]; int bodylen; @@ -1914,8 +1999,8 @@ SendSetupMessage(struct upnphttp * h, const char * action) const char * OutMessage = ""; /* base64 */ ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data); - ProtocolType = GetValueFromNameValueList(&data, "NewProtocolType"); /* string */ - InMessage = GetValueFromNameValueList(&data, "NewInMessage"); /* base64 */ + ProtocolType = GetValueFromNameValueList(&data, "ProtocolType"); /* string */ + InMessage = GetValueFromNameValueList(&data, "InMessage"); /* base64 */ if(ProtocolType == NULL || InMessage == NULL) { @@ -1933,19 +2018,19 @@ SendSetupMessage(struct upnphttp * h, const char * action) /* TODO : put here code for WPS */ bodylen = snprintf(body, sizeof(body), resp, - action, "urn:schemas-upnp-org:service:DeviceProtection:1", + action, ns/*"urn:schemas-upnp-org:service:DeviceProtection:1"*/, OutMessage, action); BuildSendAndCloseSoapResp(h, body, bodylen); ClearNameValueList(&data); } static void -GetSupportedProtocols(struct upnphttp * h, const char * action) +GetSupportedProtocols(struct upnphttp * h, const char * action, const char * ns) { static const char resp[] = "" - "%s" + "" ""; char body[1024]; int bodylen; @@ -1960,18 +2045,18 @@ GetSupportedProtocols(struct upnphttp * h, const char * action) ""; bodylen = snprintf(body, sizeof(body), resp, - action, "urn:schemas-upnp-org:service:DeviceProtection:1", + action, ns/*"urn:schemas-upnp-org:service:DeviceProtection:1"*/, ProtocolList, action); BuildSendAndCloseSoapResp(h, body, bodylen); } static void -GetAssignedRoles(struct upnphttp * h, const char * action) +GetAssignedRoles(struct upnphttp * h, const char * action, const char * ns) { static const char resp[] = "" - "%s" + "%s" ""; char body[1024]; int bodylen; @@ -1990,7 +2075,7 @@ GetAssignedRoles(struct upnphttp * h, const char * action) #endif bodylen = snprintf(body, sizeof(body), resp, - action, "urn:schemas-upnp-org:service:DeviceProtection:1", + action, ns/*"urn:schemas-upnp-org:service:DeviceProtection:1"*/, RoleList, action); BuildSendAndCloseSoapResp(h, body, bodylen); } @@ -2011,7 +2096,7 @@ GetAssignedRoles(struct upnphttp * h, const char * action) static const struct { const char * methodName; - void (*methodImpl)(struct upnphttp *, const char *); + void (*methodImpl)(struct upnphttp *, const char *, const char *); } soapMethods[] = { @@ -2068,11 +2153,15 @@ ExecuteSoapAction(struct upnphttp * h, const char * action, int n) char * p; char * p2; int i, len, methodlen; + char namespace[256]; /* SoapAction example : * urn:schemas-upnp-org:service:WANIPConnection:1#GetStatusInfo */ p = strchr(action, '#'); if(p && (p - action) < n) { + for(i = 0; i < ((int)sizeof(namespace) - 1) && (action + i) < p; i++) + namespace[i] = action[i]; + namespace[i] = '\0'; p++; p2 = strchr(p, '"'); if(p2 && (p2 - action) <= n) @@ -2085,14 +2174,14 @@ ExecuteSoapAction(struct upnphttp * h, const char * action, int n) len = strlen(soapMethods[i].methodName); if((len == methodlen) && memcmp(p, soapMethods[i].methodName, len) == 0) { #ifdef DEBUG - syslog(LOG_DEBUG, "Remote Call of SoapMethod '%s'", - soapMethods[i].methodName); + syslog(LOG_DEBUG, "Remote Call of SoapMethod '%s' %s", + soapMethods[i].methodName, namespace); #endif /* DEBUG */ - soapMethods[i].methodImpl(h, soapMethods[i].methodName); + soapMethods[i].methodImpl(h, soapMethods[i].methodName, namespace); return; } } - syslog(LOG_NOTICE, "SoapMethod: Unknown: %.*s", methodlen, p); + syslog(LOG_NOTICE, "SoapMethod: Unknown: %.*s %s", methodlen, p, namespace); } else { syslog(LOG_NOTICE, "cannot parse SoapAction"); } diff --git a/release/src/router/nvram/defaults.c b/release/src/router/nvram/defaults.c index 8519c6e659..8ecf02f197 100644 --- a/release/src/router/nvram/defaults.c +++ b/release/src/router/nvram/defaults.c @@ -200,7 +200,7 @@ const defaults_t defaults[] = { { "ipv6_6rd_borderrelay", "68.113.165.1" }, // 6RD border relay address { "ipv6_6rd_ipv4masklen", "0" }, // 6RD IPv4 mask length (0-30) checkme { "ipv6_vlan", "0" }, // Enable IPv6 on 1=LAN1 2=LAN2 4=LAN3 - { "ipv6_isp_opt", "0" }, // wan.c add eval option for dhcpd + { "ipv6_pdonly", "0" }, // Request DHCPv6 Prefix Delegation Only #endif // Wireless parameters diff --git a/release/src/router/rc/dhcp.c b/release/src/router/rc/dhcp.c index 60781a10f2..888b88bd33 100644 --- a/release/src/router/rc/dhcp.c +++ b/release/src/router/rc/dhcp.c @@ -501,7 +501,7 @@ void start_dhcp6c(void) if ((f = fopen("/etc/dhcp6c.conf", "w"))) { fprintf(f, "interface %s {\n", wan6face); - if (nvram_match("ipv6_service", "native-pd")) { + if (nvram_get_int("ipv6_pdonly") == 0) { fprintf(f, " send ia-na 0;\n"); }; diff --git a/release/src/router/rc/wan.c b/release/src/router/rc/wan.c index 0593fe9624..b4394d2d68 100644 --- a/release/src/router/rc/wan.c +++ b/release/src/router/rc/wan.c @@ -867,8 +867,8 @@ void start_wan6_done(const char *wan_ifname) eval("ip", "route", "add", "::/0", "dev", (char *)wan_ifname, "metric", "2048"); break; case IPV6_NATIVE_DHCP: - if (nvram_get_int("ipv6_isp_opt") == 1) { - eval("ip", "route", "add", "::/0", "dev", (char *)wan_ifname, "metric", "2048"); //not needed? - workaround for misconfigured ISPs? + if (nvram_get_int("ipv6_pdonly") == 1) { + eval("ip", "route", "add", "::/0", "dev", (char *)wan_ifname); } stop_dhcp6c(); start_dhcp6c(); diff --git a/release/src/router/www/basic-ipv6.asp b/release/src/router/www/basic-ipv6.asp index d2b779324d..b9a4cc43ac 100644 --- a/release/src/router/www/basic-ipv6.asp +++ b/release/src/router/www/basic-ipv6.asp @@ -21,7 +21,7 @@