--- linux-igd-1.0+cvs20070630.orig/debian/compat +++ linux-igd-1.0+cvs20070630/debian/compat @@ -0,0 +1 @@ +7 --- linux-igd-1.0+cvs20070630.orig/debian/linux-igd.init +++ linux-igd-1.0+cvs20070630/debian/linux-igd.init @@ -0,0 +1,108 @@ +#! /bin/sh +### BEGIN INIT INFO +# Provides: linux-igd +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: UPnP Internet Gateway Device +# Description: Daemon that emulates Microsoft's Internet Connection Service (ICS) +# and implements the UPnP Internet Gateway Device specification (IGD). +### END INIT INFO + +PATH=/sbin:/bin:/usr/sbin:/usr/bin +DAEMON=/usr/sbin/upnpd +NAME=linux-igd +PIDFILE=/var/run/$NAME.pid +DESC="Linux IGD Daemon" + +test -x $DAEMON || exit 0 + +# Include upnpd defaults if available +if [ -f /etc/default/$NAME ] ; then + . /etc/default/$NAME +fi + +# Check if defaults configured (don't fail on first installation). +if [ -z "$EXTIFACE" -a -z "$INTIFACE" ] ; then + echo "/etc/default/$NAME not configured: $NAME not running" >&2 + exit 0 +fi + +# Verify options +if [ -z "$EXTIFACE" ] ; then + echo "External interface not specified in /etc/default/$NAME" >&2 + exit 1 +fi +if [ -z "$INTIFACE" ] ; then + echo "Internal interface not specified in /etc/default/$NAME" >&2 + exit 1 +fi + +if [ "$CHROOT_DIR" ]; then + RUN_OPTS="$RUN_OPTS --chroot $CHROOT_DIR" +fi + +if [ "$UPNPD_USER" ]; then + RUN_OPTS="$RUN_OPTS --chuid $UPNPD_USER" +fi +if [ "$UPNPD_GROUP" ]; then + RUN_OPTS="$RUN_OPTS --group $UPNPD_GROUP" +fi + +set -e + +start () { + # Don't abort if we merely failed to setup routing, maybe something + # else is handling it after all. + # In any case, "RT_NETLINK answers: File exists" is a poor diagnostic. + [ "$ALLOW_MULTICAST" != "yes" ] || ip route add 224.0.0.0/4 dev $INTIFACE >/dev/null 2>&1 || true + start-stop-daemon --start --quiet --oknodo $RUN_OPTS \ + --exec $DAEMON -- "$EXTIFACE" "$INTIFACE" \ + && pidof `basename $DAEMON` > $PIDFILE +} + +stop () { + start-stop-daemon --stop --quiet --pidfile $PIDFILE --retry 30 --oknodo $RUN_OPTS \ + --exec $DAEMON + # Don't abort if we merely failed to delete routing, maybe we're + # restarting when it's not setup yet anyway. + # Also suppress "RT_NETLINK answers: No such process" message + [ "$ALLOW_MULTICAST" != "yes" ] || ip route del 224.0.0.0/4 dev $INTIFACE >/dev/null 2>&1 || true +} + +signal () { + start-stop-daemon --stop --quiet --pidfile $PIDFILE --signal "$1" $RUN_OPTS \ + --exec $DAEMON +} + + +case "$1" in + start) + echo -n "Starting $DESC: " + start + echo "$NAME." + ;; + stop) + echo -n "Stopping $DESC: " + stop + echo "$NAME." + ;; + reset) + echo "Resetting $DESC port mappings." + signal USR1 + ;; + restart|force-reload) + echo -n "Restarting $DESC: " + stop + sleep 1 + start + echo "$NAME." + ;; + *) + echo "Usage: $0 {start|stop|restart|reset|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 --- linux-igd-1.0+cvs20070630.orig/debian/README.Debian +++ linux-igd-1.0+cvs20070630/debian/README.Debian @@ -0,0 +1,101 @@ +linux-igd for Debian +-------------------- + +You have to edit /etc/default/linux-igd and specify your external and +internal interface names, otherwise the daemon will not be started. + +System Preparation before starting +---------------------------------- + +1. In order for device discovery to function properly, you must add a +multicast route to the internal interface like so: + + # ip route add 224.0.0.0/4 dev eth0 # (or whatever your internal + interface name is - here + eth0) + +If you set ALLOW_MULTICAST=yes in /etc/default/linux-igd, the Debian +package will attempt to do this for you on daemon startup. + +This is optional and defaults to "no", for two reasons: it might +conflict with an existing multicast routing setup, if you are using +multicast for other purposes such as Zeroconf/Avahi or media streaming, +and also the route if made this way does not persist across ifdown/ifup. + +A better approach for "the Debian way" would be to edit +/etc/network/interfaces and make it add the route each time your internal +interface is brought up, like the following example: + + iface eth0 inet + address + netmask + network + broadcast + up ip route add 224.0.0.0/4 dev eth0 # add a line similar to this + + +2. If your internal interface is firewalled, then allow multicast packets, eg: + + # iptables -t filter -I INPUT 1 -s 224.0.0.0/4 -j ACCEPT + # iptables -t filter -I INPUT 1 -d 224.0.0.0/4 -j ACCEPT + +The Debian package does not do this, it politely considers that it cannot +take responsibility for configuring your firewall. + +If you are using Shorewall then, assuming your local trusted zone is named +'loc', the appropriate rules would be + + ACCEPT loc $FW:224.0.0.0/4 all + ACCEPT $FW:224.0.0.0/4 loc all + +See http://www.shorewall.net/UPnP.html for further information on using +linux-igd with Shorewall. + +3. Also, if you'd like to see debug information, and please do, as it helps us +resolve your conflicts, perform the following steps: + +A. Add the following lines to bottom of your /etc/syslog.conf file + + # UPnP IGD messages + local6.!=debug /var/log/messages + local6.* /var/log/upnpd + +This will send all non-debug output to /var/log/messages, and all output including +debug output to /var/log/upnpd. Modify as you like. + +B. invoke-rc.d sysklogd restart + +(or if you have a different syslog daemon installed, restart that in the +way that it prefers). + + +Daemon Startup +-------------- + +Configure the daemon in /etc/upnpd.conf and /etc/default/linux-igd. + +Now you should be ready to run the daemon. Start it with the following +command line: + + invoke-rc.d linux-igd start + +Where the daemon isn't starting correctly, or exiting soon after with an +error, you can run it in the foreground with 'upnpd -f ', +preventing it daemonizing into the background; error messages will be sent +to stderr also - this is good for testing, but don't forget to have the +multicast route setup for it to accept multicast requests. + +To check and see if everything starts up ok, in /var/log/debug you should see +a few debug messages followed by Advertisements Sent, and possibly some +GetNATRSIPStatus and other messages. + +Another way to check this is to look in your Windows XP or later client +under Network Conections. Provided that you have installed the Internet +Gateway Client software on Windows, you should see an icon for Internet +Connection set to enabled in there. If for some reason you don't, +first try restarting the linux-igd daemon, which will cause it to send +out its advertisements again. + + +-- +Installation note Debianised 2008-04-05 by Nick Leverton --- linux-igd-1.0+cvs20070630.orig/debian/docs +++ linux-igd-1.0+cvs20070630/debian/docs @@ -0,0 +1,6 @@ +TODO +debian/README.Debian +debian/SECURITY.Debian +debian/THANKS +debian/TODO.Debian +debian/jailer.conf.sample --- linux-igd-1.0+cvs20070630.orig/debian/watch +++ linux-igd-1.0+cvs20070630/debian/watch @@ -0,0 +1,4 @@ +# Site Directory Pattern Version Script +version=3 +http://sf.net/linux-igd/linuxigd-(.*)\.(?:tar.bz2|tar.gz|tar|tgz) + --- linux-igd-1.0+cvs20070630.orig/debian/jailer.conf.sample +++ linux-igd-1.0+cvs20070630/debian/jailer.conf.sample @@ -0,0 +1,11 @@ +# Sample jailer.conf fragment - 'apt-get install jailer' and read the docs + + +Root: /var/chroot/upnpd +Debs: linux-igd +Conf: /etc/upnp* /etc/linuxigd/* +Junk: /bin/* /usr/bin/* /sbin/* /usr/sbin/* +Extra: /usr/sbin/upnpd /sbin/iptables /dev/null /dev/log /etc/hosts /etc/localtime /etc/resolv.conf /etc/nsswitch.conf +# Don't forget to add "-a /var/chroot/upnpd/dev/log" to the SYSLOGD startup options in /etc/default/syslogd + + --- linux-igd-1.0+cvs20070630.orig/debian/copyright +++ linux-igd-1.0+cvs20070630/debian/copyright @@ -0,0 +1,33 @@ +This package was debianized by José Fonseca on +Sun, 5 Mar 2006 13:51:39 +0000. + +It was downloaded from http://linux-igd.sourceforge.net/ + +It is now maintained by Nick Leverton . +with thanks to Jochen Friedrich for help and contributions. + +Daniel Blueman clarified the licensing in email as follows: + "Yes, linuxigd was understood to be under the GPLv2 license, so I + clearly need to fix it to ensure there is no doubt." + +Copyright 2002,2003 Glover George and contributors. +Copyright 2006-2008 Daniel J Blueman and contributors. + +License: + + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +On Debian systems, the complete text of the GNU General Public License +version 2 can be found in `/usr/share/common-licenses/GPL-2'. + --- linux-igd-1.0+cvs20070630.orig/debian/upnpd.conf.5 +++ linux-igd-1.0+cvs20070630/debian/upnpd.conf.5 @@ -0,0 +1,164 @@ +.TH upnpd.conf 5 "May 4, 2008" + +.SH NAME +upnpd.conf \- upnpd(8) configuration file + +.SH SYNOPSIS +upnpd.conf + +.SH DESCRIPTION + +upnpd.conf contains the configuration details to do with run\-time of +\fIupnpd(8)\fR. Configuration items related to starting the daemon such as +interface names are defined, for Debian, in +\fI/etc/default/linux\-igd\fR. + +.SH OPTIONS + +.TP +.B iptables_location +The full path and name of the iptables executable, +(enclosed in quotes). + +Example: \fBiptables_location = "/sbin/iptables"\fR + +.TP +.B debug_mode +Daemon debug level. Messages are logged via syslog to debug. + + 0 \- no debug messages + 1 \- log errors + 2 \- log errors and basic info + 3 \- log errors and verbose info + default = 0 + +Example: \fBdebug_mode = 2\fR + +.TP +.B create_forward_rules +Should the daemon create rules in the forward chain, or not. +This is necessary if your firewall has a drop or reject +policy in your forward chain. + + allowed values: yes,no + default = no + +Example: \fBcreate_forward_rules = yes\fR + +.TP +.B forward_rules_append +Should the daemon insert or append rules in the forward chain. +Normally you will want to insert rules at the beginning of the +forward chain, so that they apply before any drop or reject rules +later in the chain. +This option only applies if "create_forward_rules = yes". + +As an experiment, this setting now also affects the PREROUTING chain +in the same way. If this causes you problems please let me (Debian +maintainer) know through the BTS. + +Tip: If you need to insert rules somewhere in the middle of the PREROUTING +or FORWARD chains, instead of first or last, then you should create a +new empty chain, e.g forwardUPnP, and set forward_chain_name to that +chain. Then insert a rule to jump to forwardUPnP in the appropriate place +in the PREROUTING or FORWARD chain. (The value of forward_rules_append +probably won't matter much in that case.) + + allowed values: yes,no + default = no + +Example: \fBforward_rules_append = no\fR + +.TP +.B forward_chain_name +The name of the chain to put the forward rules in. +This option only applies if "create_forward_rules = yes". + + allowed values: a\-z, A\-Z, _, \- + default = FORWARD + +Example: \fBforward_chain_name = FORWARD\fR + +.TP +.B prerouting_chain_name +The name of the chain to put prerouting rules in. + + allowed values: a\-z, A\-Z, _, \- + default = PREROUTING + +Example: \fBprerouting_chain_name = PREROUTING\fR + +.TP +.B upstream_bitrate +The internet line upstream bit rate reported from +the daemon. Value in bits per second. + + default = 0 + +Example: \fBupstream_bitrate = 512000\fR + +.TP +.B downstream_bitrate +The internet line downstream bit rate reported from +the daemon. Value in bits per second. + + default = 0 + +Example: \fBdownstream_bitrate = 512000\fR + +.TP +.B duration +The default duration of port mappings, used when the client +doesn't specify a duration. +Can have the following values: + + 0 \- no default duration specified + seconds | HH:MM \- duration from the time of addition + @seconds | @HH:MM \- expire mapping at the specified time of day + default = 0 + +Example: \fBduration = 86400 # One day\fR + +.TP +.B xml_document_path +The path to the xml documents. +Do not include the trailing "/". + + default = /etc/linuxigd + +Example: \fBxml_document_path = /etc/linuxigd\fR + +.TP +.B description_document_name +The name of the igd device xml description document, underneath +.BR xml_document_path . + + default = gatedesc.xml + +Example: \fBdescription_document_name = gatedesc.xml\fR + +.TP +.B listenport +The UPnP port to listen on. + + default = 0 (first free UPnP port, starting with 49152). + +Example: \fBlistenport = 0\fR + +.TP +.B paranoid +Paranoid forwarding setting. +Can have the following values: + + 0 - allow internal hosts to forward to any other (internal) host. + 1- only allow internal hosts to forward to themselves. + default = 0 + +Example: \fBparanoid = 1\fR + +.SH SEE ALSO +upnpd(8) + +.SH AUTHOR +This manual page was written by Nick Leverton for +the Debian GNU/Linux system (but may be used by others). --- linux-igd-1.0+cvs20070630.orig/debian/control +++ linux-igd-1.0+cvs20070630/debian/control @@ -0,0 +1,17 @@ +Source: linux-igd +Section: net +Priority: optional +Homepage: http://linux-igd.sourceforge.net/ +Maintainer: Nick Leverton +Build-Depends: debhelper (>= 7.0.50), quilt (>= 0.46-8~), iptables-dev, pkg-config, + libupnp4-dev (>= 1.8.0~svn20100507-1.1) +Standards-Version: 3.9.3 + +Package: linux-igd +Architecture: any +Depends: iptables, lsb-base, libupnp4 (>= 1.8.0~svn20100316), ${shlibs:Depends}, ${misc:Depends} +Description: Linux UPnP Internet Gateway Device + This is a daemon which emulates Microsoft's Internet Connection Service (ICS). + It implements the UPnP Internet Gateway Device specification (IGD) and allows + UPnP aware clients, such as MSN Messenger or games consoles, to work + properly from behind a NAT firewall. --- linux-igd-1.0+cvs20070630.orig/debian/NEWS +++ linux-igd-1.0+cvs20070630/debian/NEWS @@ -0,0 +1,46 @@ +linux-igd (1.0+cvs20070630-3) unstable; urgency=low + + Please note that the forward_rules_append option now determines whether + entries will be inserted or appended to PREROUTING as well as to the + FORWARD chain. See man upnpd.conf for more on this option. + + -- Nick Leverton Mon, 17 May 2010 11:43:21 +0100 + +linux-igd (1.0+cvs20070630-1) unstable; urgency=low + + For compatibility with upstream, the INT_IFACE and EXT_IFACE + variables have been renamed to INTIFACE and EXTIFACE. This affects + /etc/default/linux-igd and /etc/init.d/linux-igd (formerly + named /etc/default/upnpd and /etc/init.d/upnpd). + + PLEASE REMEMBER, YOU NEED TO UPDATE THESE VARIABLES IN + /etc/default/linux-igd OR THE DAEMON WILL NOT START. + + The linux-igd project has renamed the insert_forward_rules option to + create_forward_rules to better reflect what it actually does, i.e. add + forwarding rules to the forward chain. + + Also added the forward_rules_append to do what people thought + insert_forward_rules did, i.e. control whether the rules are appended + (to end) or inserted (at the beginning) in the forward chain. The + option description also includes a tip about what to do if neither + insert or append is what you need. + + See /usr/share/doc/linux-igd/CHANGES.gz . + + SECURITY NOTE + ------------- + + This SOFTWARE IS A BETA RELEASE AND NO CLAIMS ARE MADE TO ITS SECURITY + OR ITS FUNCTIONALITY. + + Be aware that, even if this software and the upnp libraries all prove + to be bug free and completely secure, the Microsoft Internet Gateway + Device is designed to allow any computer that has access to the daemon + to open up any ports on your firewall and give incoming port forwarding + to any other port on any internal computer. + + See /usr/share/doc/linux-igd/SECURITY.Debian + + -- Nick Leverton Tue, 17 Jun 2008 12:51:29 +0100 + --- linux-igd-1.0+cvs20070630.orig/debian/linux-igd.default +++ linux-igd-1.0+cvs20070630/debian/linux-igd.default @@ -0,0 +1,34 @@ +# Defaults for linux-igd initscript +# sourced by /etc/init.d/linux-igd +# installed at /etc/default/linux-igd by the maintainer scripts + +# Options for upnpd + +# External interface name. If undefined then upnpd will not be started. +#EXTIFACE=ppp0 + +# Internal interface name. If undefined then upnpd will not be started. +#INTIFACE=eth0 + +# Options for initscript + +# Setup multicast route ? +# "yes" = add/del route to 224.0.0.0 through internal interface when starting/stopping daemon, +# "no" or unset = leave as-is, I will configure multicast routing by another method. +#ALLOW_MULTICAST=yes + +# Options for start-stop-daemon + +# User or user:group to run upnpd as, if not root. This user will need +# suitable capabilities (I believe this is CAP_NET_ADMIN; untested). +# If undefined then upnpd will run as root. +#UPNPD_USER=$NAME:$NAME + +# Supplementary group to run as (beyond those normally defined for +# UPNPD_USER). If undefined then upnpd will run with the groups defined +# for the user, or if UPNPD_USER is also undefined then as gid=root. +#UPNPD_GROUP=$NAME + +# Chroot directory (you need to maintain the chroot yourself with a program +# like 'jailer'). If undefined then upnpd will not be chrooted before starting. +#CHROOT_DIR=/var/chroot/$NAME --- linux-igd-1.0+cvs20070630.orig/debian/changelog +++ linux-igd-1.0+cvs20070630/debian/changelog @@ -0,0 +1,90 @@ +linux-igd (1.0+cvs20070630-4) unstable; urgency=low + + * Apply patch 16 from Rob Lesley to fix use-after-free (Closes: #499827) + * Apply hardening in line with Wheezy release goal, as we are a daemon + and handle unsanitised input from the net. Update *FLAGS in line + with this to be supplied by dh_buildflags. + * Update Policy to 3.9.3 (no change to package). + + -- Nick Leverton Sat, 07 Jul 2012 21:54:47 +0100 + +linux-igd (1.0+cvs20070630-3) unstable; urgency=low + + * Use debhelper 7 and dh; update patch 02-makefile to support DESTDIR. + Really compile with -O0 when "DEB_BUILD_OPTIONS=noopt" is specified. + * Reformat patches for source 3.0 (Closes: #538576) and update to DEP-3. + * Create a pidfile in initscript (Closes: #527144) + * Update for Policy 3.8.1 to 3.8.4: + Add --oknodo to start calls in case daemon was already running (3.8.1) + * Update to current netfilter, thanks to OpenWRT for patches 001/2/3/4 + * Use standard include files for string.h etc (patch 07). + * Update to use xtables functions when available (patch 08). + * Update upnp.8 man page with current options (patch 09). + * Update to current libupnp 1.8.x API instead of 1.6.x (patch 10). + * Fix potential sprintf overrun just in case (patch 11). + * Add upnp_log_filename and upnp_log_level options to enable the libupnp + debug file, and use that file for our own debug logging (patch 13). + * Some extra debugging, using the new libupnp debug file (patch 12, 14). + * Use forward_rules_append option to append to PREROUTING also (patch + 15, Closes: #507313). + + -- Nick Leverton Mon, 17 May 2010 11:43:21 +0100 + +linux-igd (1.0+cvs20070630-2) unstable; urgency=high + + * Don't sprintf from struct in_addr when 'paranoid' is enabled (Closes: + #489565, "paranoid" option can result in segfaults). + + -- Nick Leverton Mon, 07 Jul 2008 23:02:42 +0100 + +linux-igd (1.0+cvs20070630-1) unstable; urgency=low + + * New maintainer (Closes: #411875) + * New upstream CVS (Closes: #436919, #436365), including important + option name changes: + - Renamed the insert_forward_rules option to create_forward_rules to + better reflect what it actually does. + - Added the forward_rules_append to do what people thought + insert_forward_rules did. + See /usr/share/doc/linux-igd/CHANGES.gz for further details. + * For compatibility with upstream, the INT_IFACE and EXT_IFACE + initscript variables have been renamed to INTIFACE and EXTIFACE. + * Rename initscript and defaults from /etc/{init.d,default}/upnpd to + /etc/*/linux-igd so that they match our package name. + * Change initscript to do nothing until /etc/default/linux-igd is + configured (Closes: #423189, #399960). + * Add --oknodo to all "start-stop-daemon --stop" calls in initscript + in case daemon wasn't running anyway (Closes: #415981). + * Configurable CHROOT and USER/GROUP for daemon. + * Add SECURITY note and sample conf for jailer chroot. + * Add ALLOW_MULTICAST option for multicast routing setup (compatible + with upstream). + * Abstract the patch for #397572 from .diff.gz into separate quilt patch + 01-debian-my_parse_port.diff + * New patch 02-makefile.diff for fixes to makefile + * Patch 03-debian-bindtodevice.diff Closes: #441082 (linux-igd does not + restrict itself to the internal interface) (with further fix from Eric + Valette). + * Honour CFLAGS in compilation (thanks Gianluigi Tiesi + http://debian.cli.unipi.it/debian/pool/sherpya/l/linux-igd/ ). + * Update watchfile as per Jochen Friedrich's suggestion. + * Add paranoid flag to validate port forwarding requests. + * Remove bashisms from initscript, make it dash-compatible. + + -- Nick Leverton Fri, 04 Jul 2008 22:21:20 +0100 + +linux-igd (0.cvs20060201-1.1) unstable; urgency=medium + + * Non-maintainer upload. + * Rename parse_port and service_to_port to my_parse_port and + my_service_to_port respectively, as they crash with functions already + defined in /usr/include/iptables.h; fixes FTBFS. (Closes: #397572) + + -- Steinar H. Gunderson Wed, 15 Nov 2006 14:04:32 +0100 + +linux-igd (0.cvs20060201-1) unstable; urgency=low + + * Initial release (Closes: #328986) + + -- José Fonseca Sun, 5 Mar 2006 13:51:39 +0000 + --- linux-igd-1.0+cvs20070630.orig/debian/rules +++ linux-igd-1.0+cvs20070630/debian/rules @@ -0,0 +1,21 @@ +#!/usr/bin/make -f + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +export DEB_BUILD_MAINT_OPTIONS = hardening=+all +export DEB_CFLAGS_MAINT_APPEND = -DDEBUG + +CPPFLAGS_DEF += `dpkg-buildflags --get CPPFLAGS` +CFLAGS_DEF += `dpkg-buildflags --get CFLAGS` +LDFLAGS_DEF += `dpkg-buildflags --get LDFLAGS` + +%: + dh --with quilt $@ + +override_dh_auto_build: + ## iptc was removed as a public interface in iptables 1.4.0. We will need + ## to re-work it all for netfilter+xtables and, in due course, for IPV6. + # dh_auto_build -- HAVE_LIBIPTC=1 HAVE_XTABLES=1 HAVE_IPTABLES_143=1 + dh_auto_build -- CFLAGS="$(CPPFLAGS_DEF) $(CFLAGS_DEF)" LDFLAGS="$(LDFLAGS_DEF)" + --- linux-igd-1.0+cvs20070630.orig/debian/TODO.Debian +++ linux-igd-1.0+cvs20070630/debian/TODO.Debian @@ -0,0 +1,21 @@ +DEBIAN TODO 2010-03-01 + +* Linux-igd Shorewall integration: think about route/iptables fragments + to run on shorewall reload/restart so that it keeps our changes. + Should we do a store, or add a hook, or just forget about it and let + the client repeat its forwardings ? + +* Linux-igd Shorewall integration: we could perhaps add further chains: + + 1. to setup outward NAT/forwarding as well as incoming, so that that + doesn't have to be the default policy. + + 2. to restrict a subscription connection to the host that actually + subscribed, so that we don't have to have all of 49152 to 65535 open + Note the current Shorewall assumes hosts will only subscribe on + port 49152 which limits it to single-host, single-subscription. + +* Re-work HAVE_LIBIPTC code to work with the xfilter public interface + to netfilter, instead of using fields which don't exist any more from + iptable's private headers - should make us kernel version independent. + --- linux-igd-1.0+cvs20070630.orig/debian/manpages +++ linux-igd-1.0+cvs20070630/debian/manpages @@ -0,0 +1,2 @@ +upnpd.8 +debian/upnpd.conf.5 --- linux-igd-1.0+cvs20070630.orig/debian/THANKS +++ linux-igd-1.0+cvs20070630/debian/THANKS @@ -0,0 +1,21 @@ +REMINDERS and THANK YOUS +------------------------ + +Truth is I can't remember everyone to thank, but I especially want to thank +both Henri Manson and Anders Betner for their development and testing work. +Also Eric Wirt, for helping us test, and providing the winning comments for +switching to C, alongside many others contributing patches and help. + +This is a work in progress. This code is simply released now for others to +help us debug some problems we are having. Please, help us out by checking +the forums, answering problems, and giving any advice and suggestions you can +to the open source community. + +Thanks a lot to the users, and to the over 10,000 downloads, and countless +CVS checkouts. If it weren't for the interest in the program, we wouldn't be +touching it (ok maybe i would, when i got bored or something) :-) + +Cheers all + +Dime + --- linux-igd-1.0+cvs20070630.orig/debian/README.source +++ linux-igd-1.0+cvs20070630/debian/README.source @@ -0,0 +1,5 @@ +This package uses quilt to manage all modifications to the upstream +source. Changes are stored in the source package as diffs in +debian/patches and applied during the build. + +See /usr/share/doc/quilt/README.source for a detailed explanation. --- linux-igd-1.0+cvs20070630.orig/debian/SECURITY.Debian +++ linux-igd-1.0+cvs20070630/debian/SECURITY.Debian @@ -0,0 +1,37 @@ + SECURITY NOTE + ------------- + + This SOFTWARE IS A BETA RELEASE AND NO CLAIMS ARE MADE TO ITS SECURITY + OR ITS FUNCTIONALITY. + + See http://linux-igd.sourceforge.net/documentation.php . + + Be aware that, even if this software and the upnp libraries all prove + to be bug free and completely secure, the Microsoft Internet Gateway + Device is designed to allow any computer that has access to the daemon + to open up any ports on your firewall and give incoming port forwarding + to any other port on any internal computer (possibly also external, + I haven't tested that). + + This means that a PC or game console which you want to allow to + forward ports to itself can also open and redirect any ports to any + other machine. + + You can restrict the ranges of access by limiting access to your + configured IGD uPnP chains through further iptables rules or chains, + but you cannot make linux-igd secure because IGD is insecure by design. + It may in future be possible to restrict use of linux-igd but this + has not yet been done. I am sure contributions will be welcome. + + Also, some uPnP features may allow computers to execute programs + on the uPnP gateway, so you should think about running upnpd in a + chroot containing no other binaries. I do not know whether this was + uPnP's intention but it seems to be a risk with some implementations. + Using a chroot is doubly important since linux-igd by default runs as + root in order to manipulate netfilter iptables. + + The 'jailer' package is one of several simple ways of setting up chroots + with Debian, and a conffile fragment is included to help with this. + + -- Nick Leverton Tue, 17 Jun 2008 12:51:29 +0100 + --- linux-igd-1.0+cvs20070630.orig/debian/dirs +++ linux-igd-1.0+cvs20070630/debian/dirs @@ -0,0 +1 @@ +usr/sbin --- linux-igd-1.0+cvs20070630.orig/debian/patches/02-makefile.diff +++ linux-igd-1.0+cvs20070630/debian/patches/02-makefile.diff @@ -0,0 +1,137 @@ +Description: Fix include files and include paths +Author: Nick Leverton + +Index: linux-igd-1.0+cvs20070630-3~/Makefile +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/Makefile 2010-05-17 15:06:32.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/Makefile 2010-05-17 15:06:35.000000000 +0100 +@@ -1,18 +1,32 @@ +-PREFIX=/usr +-LIBUPNP_PREFIX=/usr ++PREFIX ?= /usr + #LIBIPTC_PREFIX=/usr + +-CC=gcc +-INCLUDES= -I$(LIBUPNP_PREFIX)/include -I../include +-LIBS= -lpthread -lupnp -lixml -lthreadutil -L$(LIBUPNP_PREFIX)/lib -L../libs +-FILES= main.o gatedevice.o pmlist.o util.o config.o ++# libupnp version for use with pkgconfig ++LIBUPNP=libupnp ++ ++CC ?= gcc ++CFLAGS ?= -Wall -g -O2 + +-CFLAGS += -Wall -g -O2 ++INCLUDES += $(shell pkg-config --cflags $(LIBUPNP)) ++LIBS += $(shell pkg-config --libs $(LIBUPNP)) ++FILES= main.o gatedevice.o pmlist.o util.o config.o + + ifdef HAVE_LIBIPTC + ifdef LIBIPTC_PREFIX +-LIBS += -L$(LIBIPTC_PREFIX)/lib +-INCLUDES += -I$(LIBIPTC_PREFIX)/include ++INCLUDES += $(shell pkg-config --cflags libiptc) ++LIBS += $(shell pkg-config --libs libiptc) ++endif ++ ++# iptables 1.4.3 moves some functions from ip_ namespace to nf_ ++ifdef HAVE_IPTABLES_143 ++INCLUDES += -DIPTABLES_143 ++endif ++ ++# xtables now makes available some formerly private iptables bits ++ifdef HAVE_XTABLES ++INCLUDES += -DHAVE_XTABLES ++INCLUDES += $(shell pkg-config --cflags xtables) ++LIBS += $(shell pkg-config --libs xtables) + endif + + LIBS += -liptc +@@ -23,7 +37,7 @@ + all: upnpd + + upnpd: $(FILES) +- $(CC) $(CFLAGS) $(FILES) $(LIBS) -o $@ ++ $(CC) $(LDFLAGS) $(FILES) $(LIBS) -o $@ + @echo "make $@ finished on `date`" + + %.o: %.c +@@ -33,11 +47,11 @@ + rm -f *.o upnpd + + install: upnpd +- install -d /etc/linuxigd +- install etc/gatedesc.xml /etc/linuxigd +- install etc/gateconnSCPD.xml /etc/linuxigd +- install etc/gateicfgSCPD.xml /etc/linuxigd +- install etc/dummy.xml /etc/linuxigd +- install upnpd $(PREFIX)/sbin +- install upnpd.8 $(PREFIX)/share/man/man8 +- if [ ! -f /etc/upnpd.conf ]; then install etc/upnpd.conf /etc; fi ++ install -d $(DESTDIR)/etc/linuxigd ++ install -m0644 -p etc/gatedesc.xml $(DESTDIR)/etc/linuxigd ++ install -m0644 -p etc/gateconnSCPD.xml $(DESTDIR)/etc/linuxigd ++ install -m0644 -p etc/gateicfgSCPD.xml $(DESTDIR)/etc/linuxigd ++ install -m0644 -p etc/dummy.xml $(DESTDIR)/etc/linuxigd ++ install -D upnpd $(DESTDIR)$(PREFIX)/sbin/upnpd ++ install -D -m0644 -p upnpd.8 $(DESTDIR)$(PREFIX)/share/man/man8/upnpd.8 ++ if [ ! -f $(DESTDIR)/etc/upnpd.conf ]; then install -p -m0644 etc/upnpd.conf $(DESTDIR)/etc; fi +Index: linux-igd-1.0+cvs20070630-3~/gatedevice.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/gatedevice.c 2010-05-17 15:06:32.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/gatedevice.c 2010-05-17 15:06:51.000000000 +0100 +@@ -1,11 +1,11 @@ + #include + #include +-#include + #include + #include +-#include +-#include +-#include ++#include ++#include ++#include ++#include + #include "globals.h" + #include "gatedevice.h" + #include "pmlist.h" +Index: linux-igd-1.0+cvs20070630-3~/gatedevice.h +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/gatedevice.h 2010-05-17 15:06:32.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/gatedevice.h 2010-05-17 15:06:48.000000000 +0100 +@@ -1,7 +1,7 @@ + #ifndef _GATEDEVICE_H_ + #define _GATEDEVICE_H_ 1 + +-#include ++#include + + /* interface statistics */ + typedef enum { +Index: linux-igd-1.0+cvs20070630-3~/main.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/main.c 2010-05-17 15:06:32.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/main.c 2010-05-17 15:06:51.000000000 +0100 +@@ -9,7 +9,7 @@ + #include + #include + #include +-#include ++#include + #include "globals.h" + #include "config.h" + #include "gatedevice.h" +Index: linux-igd-1.0+cvs20070630-3~/pmlist.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/pmlist.c 2010-05-17 15:06:32.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/pmlist.c 2010-05-17 15:06:51.000000000 +0100 +@@ -1,7 +1,7 @@ + #include + #include + #include +-#include ++#include + #include "globals.h" + #include "config.h" + #include "pmlist.h" --- linux-igd-1.0+cvs20070630.orig/debian/patches/13-upnp-debug.patch +++ linux-igd-1.0+cvs20070630/debian/patches/13-upnp-debug.patch @@ -0,0 +1,181 @@ +Description: Add upnp_log_filename option for libupnp debug, + and use that file for our own debug log. +Author: Nick Leverton + +Index: linux-igd-1.0+cvs20070630-3~/config.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/config.c 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/config.c 2010-05-17 15:06:36.000000000 +0100 +@@ -63,6 +63,8 @@ + regex_t re_xml_path; + regex_t re_listenport; + regex_t re_paranoid; ++ regex_t re_upnp_log_filename; ++ regex_t re_upnp_log_level; + + // Make sure all vars are 0 or \0 terminated + vars->debug = 0; +@@ -78,6 +80,8 @@ + strcpy(vars->xmlPath,""); + vars->listenport = 0; + vars->paranoid = 0; ++ strcpy(vars->upnp_log_filename,""); ++ vars->upnp_log_level = UPNP_INFO; + + // Regexp to match a comment line + regcomp(&re_comment,"^[[:blank:]]*#",0); +@@ -97,6 +101,8 @@ + regcomp(&re_xml_path,"xml_document_path[[:blank:]]*=[[:blank:]]*([[:alpha:]_/.]{1,50})",REG_EXTENDED); + regcomp(&re_listenport,"listenport[[:blank:]]*=[[:blank:]]*([[:digit:]]+)",REG_EXTENDED); + regcomp(&re_paranoid,"paranoid[[:blank:]]*=[[:blank:]]*([[:digit:]]+)",REG_EXTENDED); ++ regcomp(&re_upnp_log_filename,"upnp_log_filename[[:blank:]]*=[[:blank:]]*\"([^\"]+)\"",REG_EXTENDED); ++ regcomp(&re_upnp_log_level,"upnp_log_level[[:blank:]]*=[[:blank:]]*(UPNP_CRITICAL|UPNP_PACKET|UPNP_INFO|UPNP_ALL)",REG_EXTENDED); + + if ((conf_file=fopen(CONF_FILE,"r")) != NULL) + { +@@ -174,6 +180,23 @@ + getConfigOptionArgument(tmp,sizeof(tmp),line,submatch); + vars->paranoid = atoi(tmp); + } ++ else if (regexec(&re_upnp_log_filename,line,NMATCH,submatch,0) == 0) ++ { ++ getConfigOptionArgument(vars->upnp_log_filename, PATH_LEN, line, submatch); ++ } ++ else if (regexec(&re_upnp_log_level,line,NMATCH,submatch,0) == 0) ++ { ++ char tmp[15]; ++ getConfigOptionArgument(tmp,sizeof(tmp),line,submatch); ++ if( 0 == strcmp(tmp, "UPNP_ALL") ) ++ vars->upnp_log_level = UPNP_ALL; ++ else if( 0 == strcmp(tmp, "UPNP_INFO") ) ++ vars->upnp_log_level = UPNP_INFO; ++ else if( 0 == strcmp(tmp, "UPNP_PACKET") ) ++ vars->upnp_log_level = UPNP_PACKET; ++ else if( 0 == strcmp(tmp, "UPNP_CRITICAL") ) ++ vars->upnp_log_level = UPNP_CRITICAL; ++ } + else + { + // We end up here if ther is an unknown config directive +@@ -198,6 +221,8 @@ + regfree(&re_xml_path); + regfree(&re_listenport); + regfree(&re_paranoid); ++ regfree(&re_upnp_log_filename); ++ regfree(&re_upnp_log_level); + // Set default values for options not found in config file + if (strnlen(vars->forwardChainName, CHAIN_NAME_LEN) == 0) + { +Index: linux-igd-1.0+cvs20070630-3~/etc/upnpd.conf +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/etc/upnpd.conf 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/etc/upnpd.conf 2010-05-17 15:06:46.000000000 +0100 +@@ -101,3 +101,14 @@ + # 1, only allow internal hosts to forward to themselves. + # default = 0 + paranoid = 0 ++ ++# libupnp debug log file name ++# Note, if this file is enabled then linux-igd debug entries will also be ++# written to it as well as to syslog (see debug_mode, above) ++upnp_log_filename = ""; ++# libupnp debug logging level ++# UPNP_CRITICAL ++# UPNP_PACKET ++# UPNP_INFO ++# UPNP_ALL ++upnp_log_level = UPNP_CRITICAL +Index: linux-igd-1.0+cvs20070630-3~/globals.h +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/globals.h 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/globals.h 2010-05-17 15:06:36.000000000 +0100 +@@ -3,6 +3,9 @@ + + #include + ++#include ++#include ++ + #define CHAIN_NAME_LEN 32 + #define BITRATE_LEN 32 + #define PATH_LEN 64 +@@ -37,6 +40,8 @@ + char descDocName[PATH_LEN]; + char xmlPath[PATH_LEN]; + int listenport; //The port to listen on ++ char upnp_log_filename[PATH_LEN]; // The file for libupnp debug logging ++ Upnp_LogLevel upnp_log_level; + }; + + typedef struct GLOBALS* globals_p; +Index: linux-igd-1.0+cvs20070630-3~/main.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/main.c 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/main.c 2010-05-17 15:06:36.000000000 +0100 +@@ -16,6 +16,9 @@ + #include "util.h" + #include "pmlist.h" + ++#define DEBUG ++#include ++ + // Global variables + globals g_vars; + +@@ -112,6 +115,10 @@ + + openlog("upnpd", LOG_CONS | LOG_NDELAY | LOG_PID | (foreground ? LOG_PERROR : 0), LOG_LOCAL6); + ++ // Set up libupnp debug logging ++ UpnpSetLogFileNames(NULL, g_vars.upnp_log_filename); ++ UpnpSetLogLevel(g_vars.upnp_log_level); ++ + // Initialize UPnP SDK on the internal Interface + trace(3, "Initializing UPnP SDK ... "); + if ( (ret = UpnpInit(intIpAddress,g_vars.listenport) ) != UPNP_E_SUCCESS) +@@ -132,7 +139,7 @@ + UpnpFinish(); + exit(1); + } +- trace(2, "Succesfully set the Web Server Root Directory."); ++ trace(2, "Successfully set the Web Server Root Directory."); + + //initialize the timer thread for expiration of mappings + if (ExpirationTimerThreadInit()!=0) { +Index: linux-igd-1.0+cvs20070630-3~/util.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/util.c 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/util.c 2010-05-17 15:06:36.000000000 +0100 +@@ -12,6 +12,8 @@ + #include "globals.h" + + #include ++#define DEBUG ++#include + + static int get_sockfd(void) + { +@@ -63,13 +65,21 @@ + va_start(ap, format); + + if( -1 == asprintf(&thr_format, "0x%lx %s", (unsigned long int)ithread_self(), format) ) +- thr_format = format; ++ thr_format = (char *)format; + + if (g_vars.debug >= debuglevel) { ++ FILE * upnp_fd = UpnpGetDebugFile(UPNP_ALL, 0); + vsyslog(LOG_DEBUG, thr_format, ap); ++ va_end(ap); ++ va_start(ap, format); ++ if( NULL != upnp_fd ) ++ { ++ vfprintf(upnp_fd, thr_format, ap); ++ fprintf(upnp_fd, "\n"); ++ } + } + +- if( thr_format != format ) ++ if( thr_format != (char *)format ) + free(thr_format); + + va_end(ap); --- linux-igd-1.0+cvs20070630.orig/debian/patches/08-fix-have-iptc.patch +++ linux-igd-1.0+cvs20070630/debian/patches/08-fix-have-iptc.patch @@ -0,0 +1,56 @@ +Description: Update IPTC to use xtables instead of netfilter +Author: Nick Leverton + +Index: linux-igd-1.0+cvs20070630-3~/iptc.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/iptc.c 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/iptc.c 2010-05-17 15:06:35.000000000 +0100 +@@ -4,9 +4,10 @@ + #include + #include + #include +-#include ++#include + #include + #include ++// # include "nf_nat.h" + #ifdef IPTABLES_143 + # include + # define ip_nat_multi_range nf_nat_multi_range_compat +@@ -353,14 +354,17 @@ + static u_int16_t + igd_parse_port(const char *port) + { ++#ifdef HAVE_XTABLES ++ return xtables_parse_port(port,""); ++#else + unsigned int portnum; +- + if ((portnum = igd_service_to_port(port)) != -1) { + return (u_int16_t)portnum; + } + else { + return atoi(port); + } ++#endif + } + + static void +@@ -381,6 +385,8 @@ + } + free(buffer); + } ++ ++#ifndef HAVE_XTABLES + static int + igd_service_to_port(const char *name) + { +@@ -391,7 +397,7 @@ + + return -1; + } +- ++#endif + + + /* Copied and modified from libipt_DNAT.c */ --- linux-igd-1.0+cvs20070630.orig/debian/patches/05-debian-upnpd.conf.diff +++ linux-igd-1.0+cvs20070630/debian/patches/05-debian-upnpd.conf.diff @@ -0,0 +1,23 @@ +Description: Update upnpd.conf comment for /etc/default instead of sysconfig + +Index: linux-igd-1.0+cvs20070630-3~/etc/upnpd.conf +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/etc/upnpd.conf 2010-05-17 15:06:32.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/etc/upnpd.conf 2010-05-17 15:06:51.000000000 +0100 +@@ -1,5 +1,5 @@ + # To change the interfaces used edit: +-# /etc/sysconfig/upnpd ++# /etc/default/linux-igd + + # + # The full path and name of the iptables executable, +@@ -76,7 +76,8 @@ + # seconds | HH:MM - duration from the time of addition + # @seconds | @HH:MM - expire mapping at the specified time of day + # default = 0 +-duration = 86400 # One day ++#duration = 86400 # One day from time of addition ++duration = 0 + + # The name of the igd device xml description document + # default = gatedesc.xml --- linux-igd-1.0+cvs20070630.orig/debian/patches/11-ipv6.patch +++ linux-igd-1.0+cvs20070630/debian/patches/11-ipv6.patch @@ -0,0 +1,136 @@ +Description: First attempt to update for IPV6 from libupnp4 (needs testing) +Author: Nick Leverton + +Index: linux-igd-1.0+cvs20070630/main.c +=================================================================== +--- linux-igd-1.0+cvs20070630.orig/main.c 2010-03-08 14:03:40.000000000 +0000 ++++ linux-igd-1.0+cvs20070630/main.c 2010-03-08 14:03:40.000000000 +0000 +@@ -21,8 +21,7 @@ + + int main (int argc, char** argv) + { +- char descDocUrl[7+15+1+5+1+sizeof(g_vars.descDocName)+1]; // http://ipaddr:port/docName +- char intIpAddress[16]; // Server internal ip address ++ char *descDocUrl; // http://ipaddr:port/docName + sigset_t sigsToCatch; + int ret, signum, arg = 1, foreground = 0; + +@@ -45,12 +44,6 @@ + strncpy(g_vars.extInterfaceName, argv[arg++], IFNAMSIZ); + strncpy(g_vars.intInterfaceName, argv[arg++], IFNAMSIZ); + +- // Get the internal ip address to start the daemon on +- if (GetIpAddressStr(intIpAddress, g_vars.intInterfaceName) == 0) { +- fprintf(stderr, "Invalid internal interface name '%s'\n", g_vars.intInterfaceName); +- exit(EXIT_FAILURE); +- } +- + if (!foreground) { + struct rlimit resourceLimit = { 0, 0 }; + pid_t pid, sid; +@@ -114,9 +107,10 @@ + + // Initialize UPnP SDK on the internal Interface + trace(3, "Initializing UPnP SDK ... "); +- if ( (ret = UpnpInit(intIpAddress,g_vars.listenport) ) != UPNP_E_SUCCESS) ++ if ( (ret = UpnpInit2(g_vars.intInterfaceName, g_vars.listenport) ) != UPNP_E_SUCCESS) + { +- syslog (LOG_ERR, "Error Initializing UPnP SDK on IP %s port %d",intIpAddress,g_vars.listenport); ++ syslog (LOG_ERR, "Error Initializing UPnP SDK on interface %s port %d", ++ g_vars.intInterfaceName, g_vars.listenport); + syslog (LOG_ERR, " UpnpInit returned %d", ret); + UpnpFinish(); + exit(1); +@@ -142,7 +136,7 @@ + } + + // Form the Description Doc URL to pass to RegisterRootDevice +- sprintf(descDocUrl, "http://%s:%d/%s", UpnpGetServerIpAddress(), ++ asprintf(descDocUrl, "http://%s:%d/%s", UpnpGetServerIpAddress(), + UpnpGetServerPort(), g_vars.descDocName); + + // Register our IGD as a valid UPnP Root device +@@ -199,6 +193,7 @@ + + UpnpUnRegisterRootDevice(deviceHandle); + UpnpFinish(); ++ free(descDocUrl); + + // Exit normally + return (0); +Index: linux-igd-1.0+cvs20070630/util.c +=================================================================== +--- linux-igd-1.0+cvs20070630.orig/util.c 2010-03-08 14:02:39.000000000 +0000 ++++ linux-igd-1.0+cvs20070630/util.c 2010-03-08 14:03:40.000000000 +0000 +@@ -1,57 +1,8 @@ +-#include +-#include + #include + #include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "globals.h" +- + +-static int get_sockfd(void) +-{ +- static int sockfd = -1; +- +- if (sockfd == -1) +- { +- if ((sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) +- { +- perror("user: socket creating failed"); +- return (-1); +- } +- } +- return sockfd; +-} +- +-int GetIpAddressStr(char *address, char *ifname) +-{ +- struct ifreq ifr; +- struct sockaddr_in *saddr; +- int fd; +- int succeeded = 0; ++#include "globals.h" + +- fd = get_sockfd(); +- if (fd >= 0 ) +- { +- strncpy(ifr.ifr_name, ifname, IFNAMSIZ); +- ifr.ifr_addr.sa_family = AF_INET; +- if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) +- { +- saddr = (struct sockaddr_in *)&ifr.ifr_addr; +- strcpy(address,inet_ntoa(saddr->sin_addr)); +- succeeded = 1; +- } +- else +- { +- syslog(LOG_ERR, "Failure obtaining ip address of interface %s", ifname); +- succeeded = 0; +- } +- } +- return succeeded; +-} + + void trace(int debuglevel, const char *format, ...) + { +Index: linux-igd-1.0+cvs20070630/util.h +=================================================================== +--- linux-igd-1.0+cvs20070630.orig/util.h 2010-03-08 14:03:58.000000000 +0000 ++++ linux-igd-1.0+cvs20070630/util.h 2010-03-08 14:04:12.000000000 +0000 +@@ -1,8 +1,6 @@ + #ifndef _UTIL_H_ + #define _UTIL_H_ + +-int get_sockfd(void); +-int GetIpAddressStr(char *address, char *ifname); + void trace(int debuglevel, const char *format, ...); + + #endif //_UTIL_H_ --- linux-igd-1.0+cvs20070630.orig/debian/patches/07-fix-includes.patch +++ linux-igd-1.0+cvs20070630/debian/patches/07-fix-includes.patch @@ -0,0 +1,28 @@ +Description: Fix include files for standard functions +Author: Nick Leverton + +Index: linux-igd-1.0+cvs20070630-3~/main.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/main.c 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/main.c 2010-05-17 15:06:47.000000000 +0100 +@@ -3,8 +3,8 @@ + #include + #include + #include ++#include + #include +-#include + #include + #include + #include +Index: linux-igd-1.0+cvs20070630-3~/pmlist.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/pmlist.c 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/pmlist.c 2010-05-17 15:06:46.000000000 +0100 +@@ -1,4 +1,6 @@ + #include ++#include ++#include + #include + #include + #include --- linux-igd-1.0+cvs20070630.orig/debian/patches/16-nullify-event-mapping-to-prevent-writing-over-free-d.patch +++ linux-igd-1.0+cvs20070630/debian/patches/16-nullify-event-mapping-to-prevent-writing-over-free-d.patch @@ -0,0 +1,24 @@ +Description: Nullify event->mapping to prevent writing over free'd memory +Author: Rob Leslie +Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=499827 +Bug: https://sourceforge.net/tracker/index.php?func=detail&aid=3541140&group_id=52728&atid=467821 +Forwarded: yes + +Without this patch, free_expiration_event() will write to memory +free()'d by pmlist_Delete(). +--- + gatedevice.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +Index: linux-igd-1.0+cvs20070630/gatedevice.c +=================================================================== +--- linux-igd-1.0+cvs20070630.orig/gatedevice.c 2012-07-07 17:58:53.000000000 +0100 ++++ linux-igd-1.0+cvs20070630/gatedevice.c 2012-07-07 17:58:54.000000000 +0100 +@@ -805,6 +805,7 @@ + //will not call CancelMappingExpiration + event->mapping->expirationEventId = -1; + pmlist_Delete(event->mapping); ++ event->mapping = NULL; + + snprintf(num, sizeof(num), "%d", pmlist_Size()); + UpnpAddToPropertySet(&propSet, "PortMappingNumberOfEntries", num); --- linux-igd-1.0+cvs20070630.orig/debian/patches/09-update-manpage.patch +++ linux-igd-1.0+cvs20070630/debian/patches/09-update-manpage.patch @@ -0,0 +1,98 @@ +Description: Update upnp.8 man page with current options +Author: Nick Leverton + +Index: linux-igd-1.0+cvs20070630-3~/upnpd.8 +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/upnpd.8 2010-05-17 15:06:31.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/upnpd.8 2010-05-17 15:06:35.000000000 +0100 +@@ -1,9 +1,11 @@ + .\" Hey, EMACS: -*- nroff -*- ++ ++.TH UPNPD 8 "March 21, 2010" + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH UPNPD 8 "March 5, 2006" + .\" Please adjust this date whenever revising the manpage. ++ + .\" + .\" Some roff macros, for reference: + .\" .nh disable hyphenation +@@ -15,31 +17,71 @@ + .\" .br insert line break + .\" .sp insert n+1 empty lines + .\" for manpage-specific macros, see man(7) ++ + .SH NAME + upnpd \- Linux UPnP Internet Gateway Device daemon. ++ + .SH SYNOPSIS ++ + .B upnpd +-.RI +-.RI ++.RB [ -f ] ++.I ++.I ++ + .SH DESCRIPTION ++ + This manual page documents briefly the + .B upnpd + command. ++ + .PP +-.\" TeX users may be more comfortable with the \fB\fP and +-.\" \fI\fP escape sequences to invode bold face and italics, +-.\" respectively. +-\fBupnpd\fP is a daemon that daemon that emulates Microsoft's Internet Connection Service (ICS). It implements the UPnP Internet Gateway Device specification (IGD) and allows UPnP aware clients, such as MSN Messenger to work properly from behind a NAT firewall. ++.B upnpd ++is a daemon that emulates Microsoft's Internet Connection Service (ICS). It implements the UPnP Internet Gateway Device specification (IGD) and allows UPnP aware clients, such as MSN Messenger to work properly from behind a NAT firewall. ++ + .SH OPTIONS ++ + A summary of options is included below. ++ ++.TP ++.B -f ++Stay in foreground, don't daemonise. ++ + .TP + .B ext_ifname + External interface name. ++ + .TP + .B int_ifname + Internal interface name. ++ ++.PP ++Further configuration is performed by ++.B upnpd.conf(5). ++ ++.SH SIGNALS ++ ++.TP ++SIGUSR1 ++Delete all port mappings ++ ++.TP ++SIGINT, SIGTERM ++Shut down the server. ++ ++.PP ++The result of sending any other signals to the server is undefined. ++ ++.SH FILES ++.TP ++.I /etc/upnpd.conf ++ ++.SH SEE ALSO ++.B upnpd.conf(5) ++ + .SH AUTHOR ++ + upnpd was written by Glover George and others. ++ + .PP + This manual page was written by Jos\['e] Fonseca , + for the Debian project (but may be used by others). --- linux-igd-1.0+cvs20070630.orig/debian/patches/002-netfilter_nat_headers.patch +++ linux-igd-1.0+cvs20070630/debian/patches/002-netfilter_nat_headers.patch @@ -0,0 +1,20 @@ +Description: Update IPTC NAT for kernel iptables to netfilter changes +Origin: https://dev.openwrt.org/changeset/7964 + +Index: linux-igd-1.0+cvs20070630-3~/iptc.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/iptc.c 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/iptc.c 2010-05-17 15:06:50.000000000 +0100 +@@ -6,7 +6,12 @@ + #include + #include + #include ++#include ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++#include ++#else + #include ++#endif + #include /* inet_addr */ + #include "globals.h" + #include "util.h" --- linux-igd-1.0+cvs20070630.orig/debian/patches/10-libupnp4.diff +++ linux-igd-1.0+cvs20070630/debian/patches/10-libupnp4.diff @@ -0,0 +1,800 @@ +Description: Update API to libupnp 1.8.0 (libupnp4). +Author: Nick Leverton + +Index: linux-igd-1.0+cvs20070630-3~/gatedevice.h +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/gatedevice.h 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/gatedevice.h 2010-05-17 15:06:35.000000000 +0100 +@@ -42,23 +42,23 @@ + // WanIPConnection Actions + int EventHandler(Upnp_EventType EventType, void *Event, void *Cookie); + int StateTableInit(char *descDocUrl); +-int HandleSubscriptionRequest(struct Upnp_Subscription_Request *sr_event); +-int HandleGetVarRequest(struct Upnp_State_Var_Request *gv_event); +-int HandleActionRequest(struct Upnp_Action_Request *ca_event); ++int HandleSubscriptionRequest(UpnpSubscriptionRequest *sr_event); ++int HandleGetVarRequest(UpnpStateVarRequest *gv_event); ++int HandleActionRequest(UpnpActionRequest *ca_event); + +-int GetConnectionTypeInfo(struct Upnp_Action_Request *ca_event); +-int GetNATRSIPStatus(struct Upnp_Action_Request *ca_event); +-int SetConnectionType(struct Upnp_Action_Request *ca_event); +-int RequestConnection(struct Upnp_Action_Request *ca_event); +-int GetTotal(struct Upnp_Action_Request *ca_event, stats_t stat); +-int GetCommonLinkProperties(struct Upnp_Action_Request *ca_event); +-int InvalidAction(struct Upnp_Action_Request *ca_event); +-int GetStatusInfo(struct Upnp_Action_Request *ca_event); +-int AddPortMapping(struct Upnp_Action_Request *ca_event); +-int GetGenericPortMappingEntry(struct Upnp_Action_Request *ca_event); +-int GetSpecificPortMappingEntry(struct Upnp_Action_Request *ca_event); +-int GetExternalIPAddress(struct Upnp_Action_Request *ca_event); +-int DeletePortMapping(struct Upnp_Action_Request *ca_event); ++int GetConnectionTypeInfo(UpnpActionRequest *ca_event); ++int GetNATRSIPStatus(UpnpActionRequest *ca_event); ++int SetConnectionType(UpnpActionRequest *ca_event); ++int RequestConnection(UpnpActionRequest *ca_event); ++int GetTotal(UpnpActionRequest *ca_event, stats_t stat); ++int GetCommonLinkProperties(UpnpActionRequest *ca_event); ++int InvalidAction(UpnpActionRequest *ca_event); ++int GetStatusInfo(UpnpActionRequest *ca_event); ++int AddPortMapping(UpnpActionRequest *ca_event); ++int GetGenericPortMappingEntry(UpnpActionRequest *ca_event); ++int GetSpecificPortMappingEntry(UpnpActionRequest *ca_event); ++int GetExternalIPAddress(UpnpActionRequest *ca_event); ++int DeletePortMapping(UpnpActionRequest *ca_event); + + // Definitions for mapping expiration timer thread + #define THREAD_IDLE_TIME 5000 +@@ -68,7 +68,7 @@ + + int ExpirationTimerThreadInit(void); + int ExpirationTimerThreadShutdown(void); +-int ScheduleMappingExpiration(struct portMap *mapping, char *DevUDN, char *ServiceID); ++int ScheduleMappingExpiration(struct portMap *mapping, const char *DevUDN, const char *ServiceID); + int CancelMappingExpiration(int eventId); + void DeleteAllPortMappings(void); + +Index: linux-igd-1.0+cvs20070630-3~/gatedevice.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/gatedevice.c 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/gatedevice.c 2010-05-17 15:06:48.000000000 +0100 +@@ -1,4 +1,4 @@ +-#include ++# include + #include + #include + #include +@@ -27,14 +27,14 @@ + switch (EventType) + { + case UPNP_EVENT_SUBSCRIPTION_REQUEST: +- HandleSubscriptionRequest((struct Upnp_Subscription_Request *) Event); ++ HandleSubscriptionRequest((UpnpSubscriptionRequest *) Event); + break; + // -- Deprecated -- + case UPNP_CONTROL_GET_VAR_REQUEST: +- HandleGetVarRequest((struct Upnp_State_Var_Request *) Event); ++ HandleGetVarRequest((UpnpStateVarRequest *) Event); + break; + case UPNP_CONTROL_ACTION_REQUEST: +- HandleActionRequest((struct Upnp_Action_Request *) Event); ++ HandleActionRequest((UpnpActionRequest *) Event); + break; + default: + trace(1, "Error in EventHandler: Unknown event type %d", +@@ -69,25 +69,25 @@ + } + + // Handles subscription request for state variable notifications +-int HandleSubscriptionRequest(struct Upnp_Subscription_Request *sr_event) ++int HandleSubscriptionRequest(UpnpSubscriptionRequest *sr_event) + { + IXML_Document *propSet = NULL; + + ithread_mutex_lock(&DevMutex); + +- if (strcmp(sr_event->UDN, gateUDN) == 0) ++ if (strcmp(UpnpSubscriptionRequest_get_UDN_cstr(sr_event), gateUDN) == 0) + { + // WAN Common Interface Config Device Notifications +- if (strcmp(sr_event->ServiceId, "urn:upnp-org:serviceId:WANCommonIFC1") == 0) ++ if (strcmp(UpnpSubscriptionRequest_get_ServiceId_cstr(sr_event), "urn:upnp-org:serviceId:WANCommonIFC1") == 0) + { + trace(3, "Recieved request to subscribe to WANCommonIFC1"); + UpnpAddToPropertySet(&propSet, "PhysicalLinkStatus", "Up"); +- UpnpAcceptSubscriptionExt(deviceHandle, sr_event->UDN, sr_event->ServiceId, +- propSet, sr_event->Sid); ++ UpnpAcceptSubscriptionExt(deviceHandle, UpnpSubscriptionRequest_get_UDN_cstr(sr_event), UpnpSubscriptionRequest_get_ServiceId_cstr(sr_event), ++ propSet, UpnpSubscriptionRequest_get_SID_cstr(sr_event)); + ixmlDocument_free(propSet); + } + // WAN IP Connection Device Notifications +- else if (strcmp(sr_event->ServiceId, "urn:upnp-org:serviceId:WANIPConn1") == 0) ++ else if (strcmp(UpnpSubscriptionRequest_get_ServiceId_cstr(sr_event), "urn:upnp-org:serviceId:WANIPConn1") == 0) + { + GetIpAddressStr(ExternalIPAddress, g_vars.extInterfaceName); + trace(3, "Received request to subscribe to WANIPConn1"); +@@ -95,8 +95,8 @@ + UpnpAddToPropertySet(&propSet, "ConnectionStatus","Connected"); + UpnpAddToPropertySet(&propSet, "ExternalIPAddress", ExternalIPAddress); + UpnpAddToPropertySet(&propSet, "PortMappingNumberOfEntries","0"); +- UpnpAcceptSubscriptionExt(deviceHandle, sr_event->UDN, sr_event->ServiceId, +- propSet, sr_event->Sid); ++ UpnpAcceptSubscriptionExt(deviceHandle, UpnpSubscriptionRequest_get_UDN_cstr(sr_event), UpnpSubscriptionRequest_get_ServiceId_cstr(sr_event), ++ propSet, UpnpSubscriptionRequest_get_SID_cstr(sr_event)); + ixmlDocument_free(propSet); + } + } +@@ -104,7 +104,7 @@ + return(1); + } + +-int HandleGetVarRequest(struct Upnp_State_Var_Request *gv_request) ++int HandleGetVarRequest(UpnpStateVarRequest *gv_request) + { + // GET VAR REQUEST DEPRECATED FROM UPnP SPECIFICATIONS + // Report this in debug and ignore requests. If anyone experiences problems +@@ -113,74 +113,74 @@ + return 1; + } + +-int HandleActionRequest(struct Upnp_Action_Request *ca_event) ++int HandleActionRequest(UpnpActionRequest *ca_event) + { + int result = 0; + + ithread_mutex_lock(&DevMutex); + +- if (strcmp(ca_event->DevUDN, gateUDN) == 0) ++ if (strcmp(UpnpActionRequest_get_DevUDN_cstr(ca_event), gateUDN) == 0) + { + // Common debugging info, hopefully gets removed soon. +- trace(3, "ActionName = %s", ca_event->ActionName); ++ trace(3, "ActionName = %s", UpnpActionRequest_get_ActionName_cstr(ca_event)); + +- if (strcmp(ca_event->ServiceID, "urn:upnp-org:serviceId:WANIPConn1") == 0) ++ if (strcmp(UpnpActionRequest_get_ServiceID_cstr(ca_event), "urn:upnp-org:serviceId:WANIPConn1") == 0) + { +- if (strcmp(ca_event->ActionName,"GetConnectionTypeInfo") == 0) ++ if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"GetConnectionTypeInfo") == 0) + result = GetConnectionTypeInfo(ca_event); +- else if (strcmp(ca_event->ActionName,"GetNATRSIPStatus") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"GetNATRSIPStatus") == 0) + result = GetNATRSIPStatus(ca_event); +- else if (strcmp(ca_event->ActionName,"SetConnectionType") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"SetConnectionType") == 0) + result = SetConnectionType(ca_event); +- else if (strcmp(ca_event->ActionName,"RequestConnection") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"RequestConnection") == 0) + result = RequestConnection(ca_event); +- else if (strcmp(ca_event->ActionName,"AddPortMapping") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"AddPortMapping") == 0) + result = AddPortMapping(ca_event); +- else if (strcmp(ca_event->ActionName,"GetGenericPortMappingEntry") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"GetGenericPortMappingEntry") == 0) + result = GetGenericPortMappingEntry(ca_event); +- else if (strcmp(ca_event->ActionName,"GetSpecificPortMappingEntry") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"GetSpecificPortMappingEntry") == 0) + result = GetSpecificPortMappingEntry(ca_event); +- else if (strcmp(ca_event->ActionName,"GetExternalIPAddress") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"GetExternalIPAddress") == 0) + result = GetExternalIPAddress(ca_event); +- else if (strcmp(ca_event->ActionName,"DeletePortMapping") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"DeletePortMapping") == 0) + result = DeletePortMapping(ca_event); +- else if (strcmp(ca_event->ActionName,"GetStatusInfo") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"GetStatusInfo") == 0) + result = GetStatusInfo(ca_event); + + // Intentionally Non-Implemented Functions -- To be added later +- /*else if (strcmp(ca_event->ActionName,"RequestTermination") == 0) ++ /*else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"RequestTermination") == 0) + result = RequestTermination(ca_event); +- else if (strcmp(ca_event->ActionName,"ForceTermination") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"ForceTermination") == 0) + result = ForceTermination(ca_event); +- else if (strcmp(ca_event->ActionName,"SetAutoDisconnectTime") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"SetAutoDisconnectTime") == 0) + result = SetAutoDisconnectTime(ca_event); +- else if (strcmp(ca_event->ActionName,"SetIdleDisconnectTime") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"SetIdleDisconnectTime") == 0) + result = SetIdleDisconnectTime(ca_event); +- else if (strcmp(ca_event->ActionName,"SetWarnDisconnectDelay") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"SetWarnDisconnectDelay") == 0) + result = SetWarnDisconnectDelay(ca_event); +- else if (strcmp(ca_event->ActionName,"GetAutoDisconnectTime") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"GetAutoDisconnectTime") == 0) + result = GetAutoDisconnectTime(ca_event); +- else if (strcmp(ca_event->ActionName,"GetIdleDisconnectTime") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"GetIdleDisconnectTime") == 0) + result = GetIdleDisconnectTime(ca_event); +- else if (strcmp(ca_event->ActionName,"GetWarnDisconnectDelay") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"GetWarnDisconnectDelay") == 0) + result = GetWarnDisconnectDelay(ca_event);*/ + else result = InvalidAction(ca_event); + } +- else if (strcmp(ca_event->ServiceID,"urn:upnp-org:serviceId:WANCommonIFC1") == 0) ++ else if (strcmp(UpnpActionRequest_get_ServiceID_cstr(ca_event),"urn:upnp-org:serviceId:WANCommonIFC1") == 0) + { +- if (strcmp(ca_event->ActionName,"GetTotalBytesSent") == 0) ++ if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"GetTotalBytesSent") == 0) + result = GetTotal(ca_event, STATS_TX_BYTES); +- else if (strcmp(ca_event->ActionName,"GetTotalBytesReceived") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"GetTotalBytesReceived") == 0) + result = GetTotal(ca_event, STATS_RX_BYTES); +- else if (strcmp(ca_event->ActionName,"GetTotalPacketsSent") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"GetTotalPacketsSent") == 0) + result = GetTotal(ca_event, STATS_TX_PACKETS); +- else if (strcmp(ca_event->ActionName,"GetTotalPacketsReceived") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"GetTotalPacketsReceived") == 0) + result = GetTotal(ca_event, STATS_RX_PACKETS); +- else if (strcmp(ca_event->ActionName,"GetCommonLinkProperties") == 0) ++ else if (strcmp(UpnpActionRequest_get_ActionName_cstr(ca_event),"GetCommonLinkProperties") == 0) + result = GetCommonLinkProperties(ca_event); + else + { +- trace(1, "Invalid Action Request : %s",ca_event->ActionName); ++ trace(1, "Invalid Action Request : %s",UpnpActionRequest_get_ActionName_cstr(ca_event)); + result = InvalidAction(ca_event); + } + } +@@ -192,17 +192,17 @@ + } + + // Default Action when we receive unknown Action Requests +-int InvalidAction(struct Upnp_Action_Request *ca_event) ++int InvalidAction(UpnpActionRequest *ca_event) + { +- ca_event->ErrCode = 401; +- strcpy(ca_event->ErrStr, "Invalid Action"); +- ca_event->ActionResult = NULL; +- return (ca_event->ErrCode); ++ UpnpActionRequest_set_ErrCode(ca_event, 401); ++ UpnpActionRequest_strcpy_ErrStr(ca_event, "Invalid Action"); ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); ++ return (UpnpActionRequest_get_ErrCode(ca_event)); + } + + // As IP_Routed is the only relevant Connection Type for Linux-IGD + // we respond with IP_Routed as both current type and only type +-int GetConnectionTypeInfo (struct Upnp_Action_Request *ca_event) ++int GetConnectionTypeInfo (UpnpActionRequest *ca_event) + { + char resultStr[RESULT_LEN]; + IXML_Document *result; +@@ -216,22 +216,22 @@ + // Create a IXML_Document from resultStr and return with ca_event + if ((result = ixmlParseBuffer(resultStr)) != NULL) + { +- ca_event->ActionResult = result; +- ca_event->ErrCode = UPNP_E_SUCCESS; ++ UpnpActionRequest_set_ActionResult(ca_event, result); ++ UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); + } + else + { + trace(1, "Error parsing Response to GetConnectionTypeinfo: %s", resultStr); +- ca_event->ActionResult = NULL; +- ca_event->ErrCode = 402; ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); ++ UpnpActionRequest_set_ErrCode(ca_event, 402); + } + +- return(ca_event->ErrCode); ++ return(UpnpActionRequest_get_ErrCode(ca_event)); + } + + // Linux-IGD does not support RSIP. However NAT is of course + // so respond with NewNATEnabled = 1 +-int GetNATRSIPStatus(struct Upnp_Action_Request *ca_event) ++int GetNATRSIPStatus(UpnpActionRequest *ca_event) + { + char resultStr[RESULT_LEN]; + IXML_Document *result; +@@ -244,29 +244,29 @@ + // Create a IXML_Document from resultStr and return with ca_event + if ((result = ixmlParseBuffer(resultStr)) != NULL) + { +- ca_event->ActionResult = result; +- ca_event->ErrCode = UPNP_E_SUCCESS; ++ UpnpActionRequest_set_ActionResult(ca_event, result); ++ UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); + } + else + { + trace(1, "Error parsing Response to GetNATRSIPStatus: %s", resultStr); +- ca_event->ActionResult = NULL; +- ca_event->ErrCode = 402; ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); ++ UpnpActionRequest_set_ErrCode(ca_event, 402); + } + +- return(ca_event->ErrCode); ++ return(UpnpActionRequest_get_ErrCode(ca_event)); + } + + + // Connection Type is a Read Only Variable as linux-igd is only + // a device that supports a NATing IP router (not an Ethernet + // bridge). Possible other uses may be explored. +-int SetConnectionType(struct Upnp_Action_Request *ca_event) ++int SetConnectionType(UpnpActionRequest *ca_event) + { + // Ignore requests +- ca_event->ActionResult = NULL; +- ca_event->ErrCode = UPNP_E_SUCCESS; +- return ca_event->ErrCode; ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); ++ UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); ++ return UpnpActionRequest_get_ErrCode(ca_event); + } + + // This function should set the state variable ConnectionStatus to +@@ -274,7 +274,7 @@ + // asynchronously to actually change the status to connected. However, here we + // assume that the external WAN device is configured and connected + // outside of linux igd. +-int RequestConnection(struct Upnp_Action_Request *ca_event) ++int RequestConnection(UpnpActionRequest *ca_event) + { + + IXML_Document *propSet = NULL; +@@ -288,19 +288,19 @@ + UpnpAddToPropertySet(&propSet, "ConnectionStatus", ConnectionStatus); + + // Send off notifications of state change +- UpnpNotifyExt(deviceHandle, ca_event->DevUDN, ca_event->ServiceID, propSet); ++ UpnpNotifyExt(deviceHandle, UpnpActionRequest_get_DevUDN_cstr(ca_event), UpnpActionRequest_get_ServiceID_cstr(ca_event), propSet); + +- ca_event->ErrCode = UPNP_E_SUCCESS; +- return ca_event->ErrCode; ++ UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); ++ return UpnpActionRequest_get_ErrCode(ca_event); + } + + +-int GetCommonLinkProperties(struct Upnp_Action_Request *ca_event) ++int GetCommonLinkProperties(UpnpActionRequest *ca_event) + { + char resultStr[RESULT_LEN]; + IXML_Document *result; + +- ca_event->ErrCode = UPNP_E_SUCCESS; ++ UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); + snprintf(resultStr, RESULT_LEN, + "\n" + "Cable\n" +@@ -312,21 +312,21 @@ + // Create a IXML_Document from resultStr and return with ca_event + if ((result = ixmlParseBuffer(resultStr)) != NULL) + { +- ca_event->ActionResult = result; +- ca_event->ErrCode = UPNP_E_SUCCESS; ++ UpnpActionRequest_set_ActionResult(ca_event, result); ++ UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); + } + else + { + trace(1, "Error parsing Response to GetCommonLinkProperties: %s", resultStr); +- ca_event->ActionResult = NULL; +- ca_event->ErrCode = 402; ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); ++ UpnpActionRequest_set_ErrCode(ca_event, 402); + } + +- return(ca_event->ErrCode); ++ return(UpnpActionRequest_get_ErrCode(ca_event)); + } + + /* get specified statistic from /proc/net/dev */ +-int GetTotal(struct Upnp_Action_Request *ca_event, stats_t stat) ++int GetTotal(UpnpActionRequest *ca_event, stats_t stat) + { + char dev[IFNAMSIZ], resultStr[RESULT_LEN]; + const char *methods[STATS_LIMIT] = +@@ -362,21 +362,21 @@ + // Create a IXML_Document from resultStr and return with ca_event + if ((result = ixmlParseBuffer(resultStr)) != NULL) + { +- ca_event->ActionResult = result; +- ca_event->ErrCode = UPNP_E_SUCCESS; ++ UpnpActionRequest_set_ActionResult(ca_event, result); ++ UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); + } + else + { + trace(1, "Error parsing response to GetTotal: %s", resultStr); +- ca_event->ActionResult = NULL; +- ca_event->ErrCode = 402; ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); ++ UpnpActionRequest_set_ErrCode(ca_event, 402); + } + +- return (ca_event->ErrCode); ++ return (UpnpActionRequest_get_ErrCode(ca_event)); + } + + // Returns connection status related information to the control points +-int GetStatusInfo(struct Upnp_Action_Request *ca_event) ++int GetStatusInfo(UpnpActionRequest *ca_event) + { + long int uptime; + char resultStr[RESULT_LEN]; +@@ -395,21 +395,21 @@ + // Create a IXML_Document from resultStr and return with ca_event + if ((result = ixmlParseBuffer(resultStr)) != NULL) + { +- ca_event->ActionResult = result; +- ca_event->ErrCode = UPNP_E_SUCCESS; ++ UpnpActionRequest_set_ActionResult(ca_event, result); ++ UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); + } + else + { + trace(1, "Error parsing Response to GetStatusInfo: %s", resultStr); +- ca_event->ActionResult = NULL; +- ca_event->ErrCode = 402; ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); ++ UpnpActionRequest_set_ErrCode(ca_event, 402); + } + +- return(ca_event->ErrCode); ++ return(UpnpActionRequest_get_ErrCode(ca_event)); + } + + // Add New Port Map to the IGD +-int AddPortMapping(struct Upnp_Action_Request *ca_event) ++int AddPortMapping(UpnpActionRequest *ca_event) + { + char *remote_host=NULL; + char *ext_port=NULL; +@@ -426,27 +426,30 @@ + int action_succeeded = 0; + char resultStr[RESULT_LEN]; + +- if ( (ext_port = GetFirstDocumentItem(ca_event->ActionRequest, "NewExternalPort") ) +- && (proto = GetFirstDocumentItem(ca_event->ActionRequest, "NewProtocol") ) +- && (int_port = GetFirstDocumentItem(ca_event->ActionRequest, "NewInternalPort") ) +- && (int_ip = GetFirstDocumentItem(ca_event->ActionRequest, "NewInternalClient") ) +- && (int_duration = GetFirstDocumentItem(ca_event->ActionRequest, "NewLeaseDuration") ) +- && (bool_enabled = GetFirstDocumentItem(ca_event->ActionRequest, "NewEnabled") ) +- && (desc = GetFirstDocumentItem(ca_event->ActionRequest, "NewPortMappingDescription") )) +- { +- struct in_addr agent_ip; +- if ( g_vars.paranoid && +- ! ( 1 == inet_aton(int_ip, &agent_ip) && +- 0 == memcmp(&agent_ip, &(ca_event->CtrlPtIPAddr), sizeof(agent_ip)) ) ) ++ if ( (ext_port = GetFirstDocumentItem(UpnpActionRequest_get_ActionRequest(ca_event), "NewExternalPort") ) ++ && (proto = GetFirstDocumentItem(UpnpActionRequest_get_ActionRequest(ca_event), "NewProtocol") ) ++ && (int_port = GetFirstDocumentItem(UpnpActionRequest_get_ActionRequest(ca_event), "NewInternalPort") ) ++ && (int_ip = GetFirstDocumentItem(UpnpActionRequest_get_ActionRequest(ca_event), "NewInternalClient") ) ++ && (int_duration = GetFirstDocumentItem(UpnpActionRequest_get_ActionRequest(ca_event), "NewLeaseDuration") ) ++ && (bool_enabled = GetFirstDocumentItem(UpnpActionRequest_get_ActionRequest(ca_event), "NewEnabled") ) ++ && (desc = GetFirstDocumentItem(UpnpActionRequest_get_ActionRequest(ca_event), "NewPortMappingDescription") )) ++ { ++ char cp_addr[INET6_ADDRSTRLEN] = {0}; ++ const struct sockaddr *cp_sockaddr = UpnpActionRequest_get_CtrlPtIPAddr(ca_event); ++ ++ inet_ntop( cp_sockaddr->sa_family, cp_sockaddr->sa_data, cp_addr, sizeof(cp_addr) ); ++ if ( g_vars.paranoid ++ && ! strcmp( int_ip, cp_addr ) ) + { +- trace(3, "Paranoid setting but control point IP %s doesn't match forwarding destination IP %s", inet_ntoa(ca_event->CtrlPtIPAddr), int_ip); +- ca_event->ErrCode = 600; +- strcpy(ca_event->ErrStr, "Security policy violation"); +- ca_event->ActionResult = NULL; ++ trace(1, "Paranoid setting but control point IP %s doesn't match forwarding destination IP %s", ++ cp_addr, int_ip); ++ UpnpActionRequest_set_ErrCode(ca_event, 600); ++ UpnpActionRequest_strcpy_ErrStr(ca_event, "Security policy violation"); ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); + } + else + { +- remote_host = GetFirstDocumentItem(ca_event->ActionRequest, "NewRemoteHost"); ++ remote_host = GetFirstDocumentItem(UpnpActionRequest_get_ActionRequest(ca_event), "NewRemoteHost"); + // If port map with the same External Port, Protocol, and Internal Client exists + // then, as per spec, we overwrite it (for simplicity, we delete and re-add at end of list) + // Note: This may cause problems with GetGernericPortMappingEntry if a CP expects the overwritten +@@ -461,14 +464,14 @@ + result = pmlist_PushBack(new); + if (result==1) + { +- ScheduleMappingExpiration(new,ca_event->DevUDN,ca_event->ServiceID); ++ ScheduleMappingExpiration(new,UpnpActionRequest_get_DevUDN_cstr(ca_event),UpnpActionRequest_get_ServiceID_cstr(ca_event)); + sprintf(num, "%d", pmlist_Size()); + trace(3, "PortMappingNumberOfEntries: %d", pmlist_Size()); + UpnpAddToPropertySet(&propSet, "PortMappingNumberOfEntries", num); +- UpnpNotifyExt(deviceHandle, ca_event->DevUDN, ca_event->ServiceID, propSet); ++ UpnpNotifyExt(deviceHandle, UpnpActionRequest_get_DevUDN_cstr(ca_event), UpnpActionRequest_get_ServiceID_cstr(ca_event), propSet); + ixmlDocument_free(propSet); + trace(2, "AddPortMap: DevUDN: %s ServiceID: %s RemoteHost: %s Prot: %s ExtPort: %s Int: %s.%s", +- ca_event->DevUDN,ca_event->ServiceID,remote_host, proto, ext_port, int_ip, int_port); ++ UpnpActionRequest_get_DevUDN_cstr(ca_event),UpnpActionRequest_get_ServiceID_cstr(ca_event),remote_host, proto, ext_port, int_ip, int_port); + action_succeeded = 1; + } + else +@@ -477,9 +480,9 @@ + { + trace(1,"Failure in GateDeviceAddPortMapping: RemoteHost: %s Prot:%s ExtPort: %s Int: %s.%s\n", + remote_host, proto, ext_port, int_ip, int_port); +- ca_event->ErrCode = 718; +- strcpy(ca_event->ErrStr, "ConflictInMappingEntry"); +- ca_event->ActionResult = NULL; ++ UpnpActionRequest_set_ErrCode(ca_event, 718); ++ UpnpActionRequest_strcpy_ErrStr(ca_event, "ConflictInMappingEntry"); ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); + } + } + } +@@ -489,17 +492,17 @@ + trace(1, "Failiure in GateDeviceAddPortMapping: Invalid Arguments!"); + trace(1, " ExtPort: %s Proto: %s IntPort: %s IntIP: %s Dur: %s Ena: %s Desc: %s", + ext_port, proto, int_port, int_ip, int_duration, bool_enabled, desc); +- ca_event->ErrCode = 402; +- strcpy(ca_event->ErrStr, "Invalid Args"); +- ca_event->ActionResult = NULL; ++ UpnpActionRequest_set_ErrCode(ca_event, 402); ++ UpnpActionRequest_strcpy_ErrStr(ca_event, "Invalid Args"); ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); + } + + if (action_succeeded) + { +- ca_event->ErrCode = UPNP_E_SUCCESS; ++ UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); + snprintf(resultStr, RESULT_LEN, "\n%s\n", +- ca_event->ActionName, "urn:schemas-upnp-org:service:WANIPConnection:1", "", ca_event->ActionName); +- ca_event->ActionResult = ixmlParseBuffer(resultStr); ++ UpnpActionRequest_get_ActionName_cstr(ca_event), "urn:schemas-upnp-org:service:WANIPConnection:1", "", UpnpActionRequest_get_ActionName_cstr(ca_event)); ++ UpnpActionRequest_set_ActionResult(ca_event, ixmlParseBuffer(resultStr)); + } + + if (ext_port) free(ext_port); +@@ -510,10 +513,10 @@ + if (desc) free(desc); + if (remote_host) free(remote_host); + +- return(ca_event->ErrCode); ++ return(UpnpActionRequest_get_ErrCode(ca_event)); + } + +-int GetGenericPortMappingEntry(struct Upnp_Action_Request *ca_event) ++int GetGenericPortMappingEntry(UpnpActionRequest *ca_event) + { + char *mapindex = NULL; + struct portMap *temp; +@@ -521,7 +524,7 @@ + char resultStr[RESULT_LEN]; + int action_succeeded = 0; + +- if ((mapindex = GetFirstDocumentItem(ca_event->ActionRequest, "NewPortMappingIndex"))) ++ if ((mapindex = GetFirstDocumentItem(UpnpActionRequest_get_ActionRequest(ca_event), "NewPortMappingIndex"))) + { + temp = pmlist_FindByIndex(atoi(mapindex)); + if (temp) +@@ -531,31 +534,31 @@ + } + if (action_succeeded) + { +- ca_event->ErrCode = UPNP_E_SUCCESS; +- snprintf(resultStr, RESULT_LEN, "\n%s\n", ca_event->ActionName, +- "urn:schemas-upnp-org:service:WANIPConnection:1",result_param, ca_event->ActionName); +- ca_event->ActionResult = ixmlParseBuffer(resultStr); ++ UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); ++ snprintf(resultStr, RESULT_LEN, "\n%s\n", UpnpActionRequest_get_ActionName_cstr(ca_event), ++ "urn:schemas-upnp-org:service:WANIPConnection:1",result_param, UpnpActionRequest_get_ActionName_cstr(ca_event)); ++ UpnpActionRequest_set_ActionResult(ca_event, ixmlParseBuffer(resultStr)); + } + else + { +- ca_event->ErrCode = 713; +- strcpy(ca_event->ErrStr, "SpecifiedArrayIndexInvalid"); +- ca_event->ActionResult = NULL; ++ UpnpActionRequest_set_ErrCode(ca_event, 713); ++ UpnpActionRequest_strcpy_ErrStr(ca_event, "SpecifiedArrayIndexInvalid"); ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); + } + + } + else + { + trace(1, "Failure in GateDeviceGetGenericPortMappingEntry: Invalid Args"); +- ca_event->ErrCode = 402; +- strcpy(ca_event->ErrStr, "Invalid Args"); +- ca_event->ActionResult = NULL; ++ UpnpActionRequest_set_ErrCode(ca_event, 402); ++ UpnpActionRequest_strcpy_ErrStr(ca_event, "Invalid Args"); ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); + } + if (mapindex) free (mapindex); +- return (ca_event->ErrCode); ++ return (UpnpActionRequest_get_ErrCode(ca_event)); + + } +-int GetSpecificPortMappingEntry(struct Upnp_Action_Request *ca_event) ++int GetSpecificPortMappingEntry(UpnpActionRequest *ca_event) + { + char *ext_port=NULL; + char *proto=NULL; +@@ -564,8 +567,8 @@ + int action_succeeded = 0; + struct portMap *temp; + +- if ((ext_port = GetFirstDocumentItem(ca_event->ActionRequest, "NewExternalPort")) +- && (proto = GetFirstDocumentItem(ca_event->ActionRequest,"NewProtocol"))) ++ if ((ext_port = GetFirstDocumentItem(UpnpActionRequest_get_ActionRequest(ca_event), "NewExternalPort")) ++ && (proto = GetFirstDocumentItem(UpnpActionRequest_get_ActionRequest(ca_event),"NewProtocol"))) + { + if ((strcmp(proto, "TCP") == 0) || (strcmp(proto, "UDP") == 0)) + { +@@ -582,45 +585,45 @@ + } + if (action_succeeded) + { +- ca_event->ErrCode = UPNP_E_SUCCESS; +- snprintf(resultStr, RESULT_LEN, "\n%s\n", ca_event->ActionName, +- "urn:schemas-upnp-org:service:WANIPConnection:1",result_param, ca_event->ActionName); +- ca_event->ActionResult = ixmlParseBuffer(resultStr); ++ UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); ++ snprintf(resultStr, RESULT_LEN, "\n%s\n", UpnpActionRequest_get_ActionName_cstr(ca_event), ++ "urn:schemas-upnp-org:service:WANIPConnection:1",result_param, UpnpActionRequest_get_ActionName_cstr(ca_event)); ++ UpnpActionRequest_set_ActionResult(ca_event, ixmlParseBuffer(resultStr)); + } + else + { + trace(2, "GateDeviceGetSpecificPortMappingEntry: PortMapping Doesn't Exist..."); +- ca_event->ErrCode = 714; +- strcpy(ca_event->ErrStr, "NoSuchEntryInArray"); +- ca_event->ActionResult = NULL; ++ UpnpActionRequest_set_ErrCode(ca_event, 714); ++ UpnpActionRequest_strcpy_ErrStr(ca_event, "NoSuchEntryInArray"); ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); + } + } + else + { + trace(1, "Failure in GateDeviceGetSpecificPortMappingEntry: Invalid NewProtocol=%s\n",proto); +- ca_event->ErrCode = 402; +- strcpy(ca_event->ErrStr, "Invalid Args"); +- ca_event->ActionResult = NULL; ++ UpnpActionRequest_set_ErrCode(ca_event, 402); ++ UpnpActionRequest_strcpy_ErrStr(ca_event, "Invalid Args"); ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); + } + } + else + { + trace(1, "Failure in GateDeviceGetSpecificPortMappingEntry: Invalid Args"); +- ca_event->ErrCode = 402; +- strcpy(ca_event->ErrStr, "Invalid Args"); +- ca_event->ActionResult = NULL; ++ UpnpActionRequest_set_ErrCode(ca_event, 402); ++ UpnpActionRequest_strcpy_ErrStr(ca_event, "Invalid Args"); ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); + } + +- return (ca_event->ErrCode); ++ return (UpnpActionRequest_get_ErrCode(ca_event)); + + + } +-int GetExternalIPAddress(struct Upnp_Action_Request *ca_event) ++int GetExternalIPAddress(UpnpActionRequest *ca_event) + { + char resultStr[RESULT_LEN]; + IXML_Document *result = NULL; + +- ca_event->ErrCode = UPNP_E_SUCCESS; ++ UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); + GetIpAddressStr(ExternalIPAddress, g_vars.extInterfaceName); + snprintf(resultStr, RESULT_LEN, "\n" + "%s\n" +@@ -629,20 +632,20 @@ + // Create a IXML_Document from resultStr and return with ca_event + if ((result = ixmlParseBuffer(resultStr)) != NULL) + { +- ca_event->ActionResult = result; +- ca_event->ErrCode = UPNP_E_SUCCESS; ++ UpnpActionRequest_set_ActionResult(ca_event, result); ++ UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); + } + else + { + trace(1, "Error parsing Response to ExternalIPAddress: %s", resultStr); +- ca_event->ActionResult = NULL; +- ca_event->ErrCode = 402; ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); ++ UpnpActionRequest_set_ErrCode(ca_event, 402); + } + +- return(ca_event->ErrCode); ++ return(UpnpActionRequest_get_ErrCode(ca_event)); + } + +-int DeletePortMapping(struct Upnp_Action_Request *ca_event) ++int DeletePortMapping(UpnpActionRequest *ca_event) + { + char *ext_port=NULL; + char *proto=NULL; +@@ -653,8 +656,8 @@ + int action_succeeded = 0; + struct portMap *temp; + +- if (((ext_port = GetFirstDocumentItem(ca_event->ActionRequest, "NewExternalPort")) && +- (proto = GetFirstDocumentItem(ca_event->ActionRequest, "NewProtocol")))) ++ if (((ext_port = GetFirstDocumentItem(UpnpActionRequest_get_ActionRequest(ca_event), "NewExternalPort")) && ++ (proto = GetFirstDocumentItem(UpnpActionRequest_get_ActionRequest(ca_event), "NewProtocol")))) + { + + if ((strcmp(proto, "TCP") == 0) || (strcmp(proto, "UDP") == 0)) +@@ -667,46 +670,46 @@ + trace(2, "DeletePortMap: Proto:%s Port:%s\n",proto, ext_port); + sprintf(num,"%d",pmlist_Size()); + UpnpAddToPropertySet(&propSet,"PortMappingNumberOfEntries", num); +- UpnpNotifyExt(deviceHandle, ca_event->DevUDN,ca_event->ServiceID,propSet); ++ UpnpNotifyExt(deviceHandle, UpnpActionRequest_get_DevUDN_cstr(ca_event),UpnpActionRequest_get_ServiceID_cstr(ca_event),propSet); + ixmlDocument_free(propSet); + action_succeeded = 1; + } + else + { + trace(1, "Failure in GateDeviceDeletePortMapping: DeletePortMap: Proto:%s Port:%s\n",proto, ext_port); +- ca_event->ErrCode = 714; +- strcpy(ca_event->ErrStr, "NoSuchEntryInArray"); +- ca_event->ActionResult = NULL; ++ UpnpActionRequest_set_ErrCode(ca_event, 714); ++ UpnpActionRequest_strcpy_ErrStr(ca_event, "NoSuchEntryInArray"); ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); + } + } + else + { + trace(1, "Failure in GateDeviceDeletePortMapping: Invalid NewProtocol=%s\n",proto); +- ca_event->ErrCode = 402; +- strcpy(ca_event->ErrStr, "Invalid Args"); +- ca_event->ActionResult = NULL; ++ UpnpActionRequest_set_ErrCode(ca_event, 402); ++ UpnpActionRequest_strcpy_ErrStr(ca_event, "Invalid Args"); ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); + } + } + else + { + trace(1, "Failiure in GateDeviceDeletePortMapping: Invalid Arguments!"); +- ca_event->ErrCode = 402; +- strcpy(ca_event->ErrStr, "Invalid Args"); +- ca_event->ActionResult = NULL; ++ UpnpActionRequest_set_ErrCode(ca_event, 402); ++ UpnpActionRequest_strcpy_ErrStr(ca_event, "Invalid Args"); ++ UpnpActionRequest_set_ActionResult(ca_event, NULL); + } + + if (action_succeeded) + { +- ca_event->ErrCode = UPNP_E_SUCCESS; ++ UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); + snprintf(resultStr, RESULT_LEN, "\n%s\n", +- ca_event->ActionName, "urn:schemas-upnp-org:service:WANIPConnection:1", "", ca_event->ActionName); +- ca_event->ActionResult = ixmlParseBuffer(resultStr); ++ UpnpActionRequest_get_ActionName_cstr(ca_event), "urn:schemas-upnp-org:service:WANIPConnection:1", "", UpnpActionRequest_get_ActionName_cstr(ca_event)); ++ UpnpActionRequest_set_ActionResult(ca_event, ixmlParseBuffer(resultStr)); + } + + if (ext_port) free(ext_port); + if (proto) free(proto); + +- return(ca_event->ErrCode); ++ return(UpnpActionRequest_get_ErrCode(ca_event)); + } + + // From sampleutil.c included with libupnp +@@ -800,7 +803,7 @@ + ithread_mutex_unlock(&DevMutex); + } + +-int ScheduleMappingExpiration(struct portMap *mapping, char *DevUDN, char *ServiceID) ++int ScheduleMappingExpiration(struct portMap *mapping, const char *DevUDN, const char *ServiceID) + { + int retVal = 0; + ThreadPoolJob job; --- linux-igd-1.0+cvs20070630.orig/debian/patches/11-fix-sprintf.patch +++ linux-igd-1.0+cvs20070630/debian/patches/11-fix-sprintf.patch @@ -0,0 +1,34 @@ +Description: Add a couple of sprintf buffer overrun preventions +Author: Nick Leverton + +Index: linux-igd-1.0+cvs20070630-3~/gatedevice.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/gatedevice.c 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/gatedevice.c 2010-05-17 15:06:47.000000000 +0100 +@@ -465,7 +465,7 @@ + if (result==1) + { + ScheduleMappingExpiration(new,UpnpActionRequest_get_DevUDN_cstr(ca_event),UpnpActionRequest_get_ServiceID_cstr(ca_event)); +- sprintf(num, "%d", pmlist_Size()); ++ snprintf(num, sizeof(num), "%d", pmlist_Size()); + trace(3, "PortMappingNumberOfEntries: %d", pmlist_Size()); + UpnpAddToPropertySet(&propSet, "PortMappingNumberOfEntries", num); + UpnpNotifyExt(deviceHandle, UpnpActionRequest_get_DevUDN_cstr(ca_event), UpnpActionRequest_get_ServiceID_cstr(ca_event), propSet); +@@ -668,7 +668,7 @@ + if (result==1) + { + trace(2, "DeletePortMap: Proto:%s Port:%s\n",proto, ext_port); +- sprintf(num,"%d",pmlist_Size()); ++ snprintf(num,sizeof(num), "%d",pmlist_Size()); + UpnpAddToPropertySet(&propSet,"PortMappingNumberOfEntries", num); + UpnpNotifyExt(deviceHandle, UpnpActionRequest_get_DevUDN_cstr(ca_event),UpnpActionRequest_get_ServiceID_cstr(ca_event),propSet); + ixmlDocument_free(propSet); +@@ -791,7 +791,7 @@ + event->mapping->expirationEventId = -1; + pmlist_Delete(event->mapping); + +- sprintf(num, "%d", pmlist_Size()); ++ snprintf(num, sizeof(num), "%d", pmlist_Size()); + UpnpAddToPropertySet(&propSet, "PortMappingNumberOfEntries", num); + UpnpNotifyExt(deviceHandle, event->DevUDN, event->ServiceID, propSet); + ixmlDocument_free(propSet); --- linux-igd-1.0+cvs20070630.orig/debian/patches/06-paranoid-port-forwarding.patch +++ linux-igd-1.0+cvs20070630/debian/patches/06-paranoid-port-forwarding.patch @@ -0,0 +1,184 @@ +Description: Add paranoid option for port forwarding +Author: Nick Leverton + +Index: linux-igd-1.0+cvs20070630-3~/config.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/config.c 2010-05-17 15:06:32.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/config.c 2010-05-17 15:06:47.000000000 +0100 +@@ -62,6 +62,7 @@ + regex_t re_desc_doc; + regex_t re_xml_path; + regex_t re_listenport; ++ regex_t re_paranoid; + + // Make sure all vars are 0 or \0 terminated + vars->debug = 0; +@@ -76,6 +77,7 @@ + strcpy(vars->descDocName,""); + strcpy(vars->xmlPath,""); + vars->listenport = 0; ++ vars->paranoid = 0; + + // Regexp to match a comment line + regcomp(&re_comment,"^[[:blank:]]*#",0); +@@ -94,6 +96,7 @@ + regcomp(&re_desc_doc,"description_document_name[[:blank:]]*=[[:blank:]]*([[:alpha:].]{1,20})",REG_EXTENDED); + regcomp(&re_xml_path,"xml_document_path[[:blank:]]*=[[:blank:]]*([[:alpha:]_/.]{1,50})",REG_EXTENDED); + regcomp(&re_listenport,"listenport[[:blank:]]*=[[:blank:]]*([[:digit:]]+)",REG_EXTENDED); ++ regcomp(&re_paranoid,"paranoid[[:blank:]]*=[[:blank:]]*([[:digit:]]+)",REG_EXTENDED); + + if ((conf_file=fopen(CONF_FILE,"r")) != NULL) + { +@@ -165,6 +168,12 @@ + getConfigOptionArgument(tmp,sizeof(tmp),line,submatch); + vars->listenport = atoi(tmp); + } ++ else if (regexec(&re_paranoid,line,NMATCH,submatch,0) == 0) ++ { ++ char tmp[2]; ++ getConfigOptionArgument(tmp,sizeof(tmp),line,submatch); ++ vars->paranoid = atoi(tmp); ++ } + else + { + // We end up here if ther is an unknown config directive +@@ -188,6 +197,7 @@ + regfree(&re_desc_doc); + regfree(&re_xml_path); + regfree(&re_listenport); ++ regfree(&re_paranoid); + // Set default values for options not found in config file + if (strnlen(vars->forwardChainName, CHAIN_NAME_LEN) == 0) + { +Index: linux-igd-1.0+cvs20070630-3~/gatedevice.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/gatedevice.c 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/gatedevice.c 2010-05-17 15:06:48.000000000 +0100 +@@ -1,7 +1,9 @@ + #include ++#include + #include + #include + #include ++#include + #include + #include + #include +@@ -432,42 +434,55 @@ + && (bool_enabled = GetFirstDocumentItem(ca_event->ActionRequest, "NewEnabled") ) + && (desc = GetFirstDocumentItem(ca_event->ActionRequest, "NewPortMappingDescription") )) + { +- remote_host = GetFirstDocumentItem(ca_event->ActionRequest, "NewRemoteHost"); +- // If port map with the same External Port, Protocol, and Internal Client exists +- // then, as per spec, we overwrite it (for simplicity, we delete and re-add at end of list) +- // Note: This may cause problems with GetGernericPortMappingEntry if a CP expects the overwritten +- // to be in the same place. +- if ((ret = pmlist_Find(ext_port, proto, int_ip)) != NULL) +- { +- trace(3, "Found port map to already exist. Replacing"); +- pmlist_Delete(ret); +- } +- +- new = pmlist_NewNode(atoi(bool_enabled), atol(int_duration), "", ext_port, int_port, proto, int_ip, desc); +- result = pmlist_PushBack(new); +- if (result==1) +- { +- ScheduleMappingExpiration(new,ca_event->DevUDN,ca_event->ServiceID); +- sprintf(num, "%d", pmlist_Size()); +- trace(3, "PortMappingNumberOfEntries: %d", pmlist_Size()); +- UpnpAddToPropertySet(&propSet, "PortMappingNumberOfEntries", num); +- UpnpNotifyExt(deviceHandle, ca_event->DevUDN, ca_event->ServiceID, propSet); +- ixmlDocument_free(propSet); +- trace(2, "AddPortMap: DevUDN: %s ServiceID: %s RemoteHost: %s Prot: %s ExtPort: %s Int: %s.%s", +- ca_event->DevUDN,ca_event->ServiceID,remote_host, proto, ext_port, int_ip, int_port); +- action_succeeded = 1; +- } +- else +- { +- if (result==718) +- { +- trace(1,"Failure in GateDeviceAddPortMapping: RemoteHost: %s Prot:%s ExtPort: %s Int: %s.%s\n", +- remote_host, proto, ext_port, int_ip, int_port); +- ca_event->ErrCode = 718; +- strcpy(ca_event->ErrStr, "ConflictInMappingEntry"); +- ca_event->ActionResult = NULL; +- } +- } ++ struct in_addr agent_ip; ++ if ( g_vars.paranoid && ++ ! ( 1 == inet_aton(int_ip, &agent_ip) && ++ 0 == memcmp(&agent_ip, &(ca_event->CtrlPtIPAddr), sizeof(agent_ip)) ) ) ++ { ++ trace(3, "Paranoid setting but control point IP %s doesn't match forwarding destination IP %s", inet_ntoa(ca_event->CtrlPtIPAddr), int_ip); ++ ca_event->ErrCode = 600; ++ strcpy(ca_event->ErrStr, "Security policy violation"); ++ ca_event->ActionResult = NULL; ++ } ++ else ++ { ++ remote_host = GetFirstDocumentItem(ca_event->ActionRequest, "NewRemoteHost"); ++ // If port map with the same External Port, Protocol, and Internal Client exists ++ // then, as per spec, we overwrite it (for simplicity, we delete and re-add at end of list) ++ // Note: This may cause problems with GetGernericPortMappingEntry if a CP expects the overwritten ++ // to be in the same place. ++ if ((ret = pmlist_Find(ext_port, proto, int_ip)) != NULL) ++ { ++ trace(3, "Found port map to already exist. Replacing"); ++ pmlist_Delete(ret); ++ } ++ ++ new = pmlist_NewNode(atoi(bool_enabled), atol(int_duration), "", ext_port, int_port, proto, int_ip, desc); ++ result = pmlist_PushBack(new); ++ if (result==1) ++ { ++ ScheduleMappingExpiration(new,ca_event->DevUDN,ca_event->ServiceID); ++ sprintf(num, "%d", pmlist_Size()); ++ trace(3, "PortMappingNumberOfEntries: %d", pmlist_Size()); ++ UpnpAddToPropertySet(&propSet, "PortMappingNumberOfEntries", num); ++ UpnpNotifyExt(deviceHandle, ca_event->DevUDN, ca_event->ServiceID, propSet); ++ ixmlDocument_free(propSet); ++ trace(2, "AddPortMap: DevUDN: %s ServiceID: %s RemoteHost: %s Prot: %s ExtPort: %s Int: %s.%s", ++ ca_event->DevUDN,ca_event->ServiceID,remote_host, proto, ext_port, int_ip, int_port); ++ action_succeeded = 1; ++ } ++ else ++ { ++ if (result==718) ++ { ++ trace(1,"Failure in GateDeviceAddPortMapping: RemoteHost: %s Prot:%s ExtPort: %s Int: %s.%s\n", ++ remote_host, proto, ext_port, int_ip, int_port); ++ ca_event->ErrCode = 718; ++ strcpy(ca_event->ErrStr, "ConflictInMappingEntry"); ++ ca_event->ActionResult = NULL; ++ } ++ } ++ } + } + else + { +Index: linux-igd-1.0+cvs20070630-3~/globals.h +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/globals.h 2010-05-17 15:06:32.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/globals.h 2010-05-17 15:06:47.000000000 +0100 +@@ -33,6 +33,7 @@ + long int duration; // 0 - no duration + // >0 - duration in seconds + // <0 - expiration time ++ int paranoid; // 0 - liberal, 1 - paranoid checks on gateway requests + char descDocName[PATH_LEN]; + char xmlPath[PATH_LEN]; + int listenport; //The port to listen on +Index: linux-igd-1.0+cvs20070630-3~/etc/upnpd.conf +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/etc/upnpd.conf 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/etc/upnpd.conf 2010-05-17 15:06:47.000000000 +0100 +@@ -95,3 +95,9 @@ + # The UPnP port to listen on. + # default = 0 (first free UPnP port, starting with 49152) + listenport = 0 ++ ++# paranoid forwarding option ++# 0, allow all forwarding ++# 1, only allow internal hosts to forward to themselves. ++# default = 0 ++paranoid = 0 --- linux-igd-1.0+cvs20070630.orig/debian/patches/15-prerouting-rules-append.patch +++ linux-igd-1.0+cvs20070630/debian/patches/15-prerouting-rules-append.patch @@ -0,0 +1,58 @@ +Description: Append or insert to PREROUTING chain depending on forward_rules_append +Author: Daniel Tryba +Bug-Debian: http://bugs.debian.org/507313 + +Index: linux-igd-1.0+cvs20070630-3~/etc/upnpd.conf +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/etc/upnpd.conf 2010-05-17 15:06:36.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/etc/upnpd.conf 2010-05-17 15:06:36.000000000 +0100 +@@ -30,14 +30,18 @@ + # forward chain, so that they apply before any drop or reject rules + # later in the chain. + # This option only applies if "create_forward_rules = yes". +-# +-# Tip: If you need to insert rules somewhere in the middle of the +-# FORWARD chain, instead of first or last, then you should create a ++# ++# As an experiment, this setting now also affects the PREROUTING chain ++# in the same way. If this causes you problems please let me (Debian ++# maintainer) know through the BTS. ++# ++# Tip: If you need to insert rules somewhere in the middle of the PREROUTING ++# or FORWARD chains, instead of first or last, then you should create a + # new empty chain, e.g forwardUPnP, and set forward_chain_name to that +-# chain. Then insert a rule to jump to forwardUPnP in the appropriate +-# place in the FORWARD chain. (The value of forward_rules_append ++# chain. Then insert a rule to jump to forwardUPnP in the appropriate place ++# in the PREROUTING or FORWARD chain. (The value of forward_rules_append + # probably won't matter much in that case.) +-# ++# + # allowed values: yes,no + # default = no + forward_rules_append = no +Index: linux-igd-1.0+cvs20070630-3~/pmlist.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/pmlist.c 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/pmlist.c 2010-05-17 15:06:36.000000000 +0100 +@@ -273,10 +273,17 @@ + } + + { +- char *args[] = {g_vars.iptables, "-t", "nat", "-A", g_vars.preroutingChainName, "-i", g_vars.extInterfaceName, "-p", protocol, "--dport", externalPort, "-j", "DNAT", "--to", dest, NULL}; ++ char *args[] = {g_vars.iptables, "-t", "nat", ++ g_vars.forwardRulesAppend ? "-A" : "-I", ++ g_vars.preroutingChainName, "-i", g_vars.extInterfaceName, ++ "-p", protocol, "--dport", externalPort, ++ "-j", "DNAT", "--to", dest, NULL}; + +- trace(3, "%s -t nat -A %s -i %s -p %s --dport %s -j DNAT --to %s", +- g_vars.iptables, g_vars.preroutingChainName, g_vars.extInterfaceName, protocol, externalPort, dest); ++ trace(3, "%s -t nat %s %s -i %s -p %s --dport %s -j DNAT --to %s", ++ g_vars.iptables, g_vars.forwardRulesAppend ? "-A" : "-I", ++ g_vars.preroutingChainName, g_vars.extInterfaceName, ++ protocol, externalPort, ++ dest); + if (!fork()) { + int rc = execv(g_vars.iptables, args); + exit(rc); --- linux-igd-1.0+cvs20070630.orig/debian/patches/001a-more-statics.patch +++ linux-igd-1.0+cvs20070630/debian/patches/001a-more-statics.patch @@ -0,0 +1,209 @@ +Description: Add statics and consts in IPTC, and rename remaining private + functions with igd_ prefix to align things with patch 001-iptables_defs. +Author: Nick Leverton + +Index: linux-igd-1.0+cvs20070630-3~/iptc.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/iptc.c 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/iptc.c 2010-05-17 15:06:49.000000000 +0100 +@@ -31,18 +31,18 @@ + struct ip_nat_multi_range mr; + }; + +-struct ipt_entry_match *get_tcp_match(const char *sports, const char *dports, unsigned int *nfcache); +-struct ipt_entry_match *get_udp_match(const char *sports, const char *dports, unsigned int *nfcache); +-struct ipt_entry_target *get_dnat_target(const char *input, unsigned int *nfcache); ++static struct ipt_entry_match *igd_get_tcp_match(const char *sports, const char *dports, unsigned int *nfcache); ++static struct ipt_entry_match *igd_get_udp_match(const char *sports, const char *dports, unsigned int *nfcache); ++static struct ipt_entry_target *igd_get_dnat_target(const char *input, unsigned int *nfcache); + + static u_int16_t igd_parse_port(const char *port); +-void parse_ports(const char *portstring, u_int16_t *ports); ++static void igd_parse_ports(const char *portstring, u_int16_t *ports); + static int igd_service_to_port(const char *name); + +-static void parse_range(const char *input, struct ip_nat_range *range); +-static struct ipt_natinfo *append_range(struct ipt_natinfo *info, const struct ip_nat_range *range); ++static void igd_parse_range(const char *input, struct ip_nat_range *range); ++static struct ipt_natinfo *igd_append_range(struct ipt_natinfo *info, const struct ip_nat_range *range); + +-static int matchcmp(const struct ipt_entry_match *match, const char *srcports, const char *destports); ++static int igd_matchcmp(const struct ipt_entry_match *match, const char *srcports, const char *destports); + + void iptc_add_rule(const char *table, + const char *chain, +@@ -81,11 +81,11 @@ + + if (strcmp(protocol, "TCP") == 0) { + chain_entry->ip.proto = IPPROTO_TCP; +- entry_match = get_tcp_match(srcports, destports, &chain_entry->nfcache); ++ entry_match = igd_get_tcp_match(srcports, destports, &chain_entry->nfcache); + } + else if (strcmp(protocol, "UDP") == 0) { + chain_entry->ip.proto = IPPROTO_UDP; +- entry_match = get_udp_match(srcports, destports, &chain_entry->nfcache); ++ entry_match = igd_get_udp_match(srcports, destports, &chain_entry->nfcache); + } + else { + trace(1, "Unsupported protocol: %s", protocol); +@@ -105,7 +105,7 @@ + strncpy(entry_target->u.user.name, target, IPT_FUNCTION_MAXNAMELEN); + } + else if (strcmp(target, "DNAT") == 0) { +- entry_target = get_dnat_target(dnat_to, &chain_entry->nfcache); ++ entry_target = igd_get_dnat_target(dnat_to, &chain_entry->nfcache); + } + + if (entry_match) +@@ -197,7 +197,7 @@ + if (outiface && strcmp(e->ip.outiface, outiface) != 0) continue; + if (protocol && strcmp(protocol, "TCP") == 0 && e->ip.proto != IPPROTO_TCP) continue; + if (protocol && strcmp(protocol, "UDP") == 0 && e->ip.proto != IPPROTO_UDP) continue; +- if ((srcports || destports) && IPT_MATCH_ITERATE(e, matchcmp, srcports, destports) == 0) continue; ++ if ((srcports || destports) && IPT_MATCH_ITERATE(e, igd_matchcmp, srcports, destports) == 0) continue; + if (target && strcmp(target, iptc_get_target(e, handle)) != 0) continue; + if (dnat_to && strcmp(target, "DNAT") == 0) { + struct ipt_entry_target *t; +@@ -209,7 +209,7 @@ + + if (mr->rangesize != 1) continue; /* we have only single dnat_to target now */ + r = mr->range; +- parse_range(dnat_to, &range); ++ igd_parse_range(dnat_to, &range); + if (r->flags == range.flags + && r->min_ip == range.min_ip + && r->max_ip == range.max_ip +@@ -236,18 +236,19 @@ + trace(3, "deleted rule from block successfully"); + } + +-static int matchcmp(const struct ipt_entry_match *match, const char *srcports, const char *destports) { ++static int ++igd_matchcmp(const struct ipt_entry_match *match, const char *srcports, const char *destports) { + u_int16_t temp[2]; + + if (strcmp(match->u.user.name, "tcp") == 0) { + struct ipt_tcp *tcpinfo = (struct ipt_tcp *)match->data; + + if (srcports) { +- parse_ports(srcports, temp); ++ igd_parse_ports(srcports, temp); + if (temp[0] != tcpinfo->spts[0] || temp[1] != tcpinfo->spts[1]) return 0; + } + if (destports) { +- parse_ports(destports, temp); ++ igd_parse_ports(destports, temp); + if (temp[0] != tcpinfo->dpts[0] || temp[1] != tcpinfo->dpts[1]) return 0; + } + return 1; +@@ -256,11 +257,11 @@ + struct ipt_udp *udpinfo = (struct ipt_udp *)match->data; + + if (srcports) { +- parse_ports(srcports, temp); ++ igd_parse_ports(srcports, temp); + if (temp[0] != udpinfo->spts[0] || temp[1] != udpinfo->spts[1]) return 0; + } + if (destports) { +- parse_ports(destports, temp); ++ igd_parse_ports(destports, temp); + if (temp[0] != udpinfo->dpts[0] || temp[1] != udpinfo->dpts[1]) return 0; + } + return 1; +@@ -270,8 +271,8 @@ + + /* These functions are used to create structs */ + +-struct ipt_entry_match * +-get_tcp_match(const char *sports, const char *dports, unsigned int *nfcache) { ++static struct ipt_entry_match * ++igd_get_tcp_match(const char *sports, const char *dports, unsigned int *nfcache) { + struct ipt_entry_match *match; + struct ipt_tcp *tcpinfo; + size_t size; +@@ -286,18 +287,18 @@ + + if (sports) { + *nfcache |= NFC_IP_SRC_PT; +- parse_ports(sports, tcpinfo->spts); ++ igd_parse_ports(sports, tcpinfo->spts); + } + if (dports) { + *nfcache |= NFC_IP_DST_PT; +- parse_ports(dports, tcpinfo->dpts); ++ igd_parse_ports(dports, tcpinfo->dpts); + } + + return match; + } + +-struct ipt_entry_match * +-get_udp_match(const char *sports, const char *dports, unsigned int *nfcache) { ++static struct ipt_entry_match * ++igd_get_udp_match(const char *sports, const char *dports, unsigned int *nfcache) { + struct ipt_entry_match *match; + struct ipt_udp *udpinfo; + size_t size; +@@ -312,18 +313,18 @@ + + if (sports) { + *nfcache |= NFC_IP_SRC_PT; +- parse_ports(sports, udpinfo->spts); ++ igd_parse_ports(sports, udpinfo->spts); + } + if (dports) { + *nfcache |= NFC_IP_DST_PT; +- parse_ports(dports, udpinfo->dpts); ++ igd_parse_ports(dports, udpinfo->dpts); + } + + return match; + } + +-struct ipt_entry_target * +-get_dnat_target(const char *input, unsigned int *nfcache) { ++static struct ipt_entry_target * ++igd_get_dnat_target(const char *input, unsigned int *nfcache) { + struct ipt_entry_target *target; + struct ipt_natinfo *info; + struct ip_nat_range range; +@@ -341,8 +342,8 @@ + strncpy(target->u.user.name, "DNAT", IPT_FUNCTION_MAXNAMELEN); + + info = (void *)target; +- parse_range(buffer, &range); +- target = &(append_range(info, &range)->t); ++ igd_parse_range(buffer, &range); ++ target = &(igd_append_range(info, &range)->t); + free(buffer); + + return target; +@@ -362,8 +363,8 @@ + } + } + +-void +-parse_ports(const char *portstring, u_int16_t *ports) ++static void ++igd_parse_ports(const char *portstring, u_int16_t *ports) + { + char *buffer; + char *cp; +@@ -396,7 +397,7 @@ + /* Copied and modified from libipt_DNAT.c */ + + static void +-parse_range(const char *input, struct ip_nat_range *range) { ++igd_parse_range(const char *input, struct ip_nat_range *range) { + char *colon, *dash, *buffer; + in_addr_t ip; + +@@ -452,7 +453,7 @@ + + + static struct ipt_natinfo * +-append_range(struct ipt_natinfo *info, const struct ip_nat_range *range) { ++igd_append_range(struct ipt_natinfo *info, const struct ip_nat_range *range) { + unsigned int size; + + /* One ip_nat_range already included in ip_nat_multi_range */ --- linux-igd-1.0+cvs20070630.orig/debian/patches/04-upstream-multiple-wan-interfaces.diff +++ linux-igd-1.0+cvs20070630/debian/patches/04-upstream-multiple-wan-interfaces.diff @@ -0,0 +1,411 @@ +Description: Allow multiple WAN interfaces (untested) +Origin: upstream + +diff -ruN linuxigd-cvs/arcoscom_extra.c linuxigd-cvs.3/arcoscom_extra.c +--- linuxigd-cvs/arcoscom_extra.c 1970-01-01 03:00:00.000000000 +0300 ++++ linuxigd-cvs.3/arcoscom_extra.c 2008-01-03 19:11:02.000000000 +0300 +@@ -0,0 +1,133 @@ ++#include ++#include ++#include ++#include ++ ++#include "globals.h" ++#include "util.h" ++ ++void initGlobals( globals_p ioGlobales ) { ++ memset( ( void * ) ioGlobales, sizeof( struct GLOBALS ), 0 ); ++} ++ ++int parseCommandLine(int argc, char ** argv, globals_p ioGlobales ) { ++ int ret = 0; ++ register int argc_count; ++ int parameters_without_switches = 0; ++ int lan_switch_found = 0; ++ int wan_switch_found = 0; ++ ++ for( argc_count = 1; argc_count < argc && !ret; ++argc_count ) { ++ if( !strcmp( argv[ argc_count ], "-f" ) ) { // foreground parameter ++ lan_switch_found = 0; ++ wan_switch_found = 0; ++ parameters_without_switches = 0; ++ ioGlobales->foreground = 1; ++ } ++ else if( !strcmp( argv[ argc_count ], "-L" ) ) { // LAN interfaces parameter ++ lan_switch_found = 1; ++ wan_switch_found = 0; ++ parameters_without_switches = 0; ++ } ++ else if( !strcmp( argv[ argc_count ], "-W" ) ) { // WAN interfaces parameter ++ lan_switch_found = 0; ++ wan_switch_found = 1; ++ parameters_without_switches = 0; ++ } ++ else { ++ if( wan_switch_found ) { // It's a WAN interface name ++ if( 0 == ioGlobales->extCount ) { ++ strncpy( ioGlobales->extInterfaceName, argv[ argc_count ], IFNAMSIZ ); ++ } ++ if( ioGlobales->extCount < MAX_WAN_IFACES ) { ++ strncpy( ioGlobales->extInterfaces[ ioGlobales->extCount ], argv[ argc_count ], IFNAMSIZ ); ++ ioGlobales->extCount++; ++ } ++ } ++ else if( lan_switch_found ) { // It's a LAN interface name ++ if( 0 == ioGlobales->intCount ) { ++ strncpy( ioGlobales->intInterfaceName, argv[ argc_count ], IFNAMSIZ ); ++ // Get the internal ip address to start the daemon on ++ if( 0 == GetIpAddressStr(ioGlobales->intIpAddress, ioGlobales->intInterfaceName) ) { ++ fprintf(stderr, "Invalid internal interface name '%s'\n", ioGlobales->intInterfaceName); ++ ret = EXIT_FAILURE; ++ } ++ } ++ if( ioGlobales->intCount < MAX_WAN_IFACES ) { ++ strncpy( ioGlobales->intInterfaces[ ioGlobales->intCount ], argv[ argc_count ], IFNAMSIZ ); ++ // Get the internal ip address to start the daemon on ++ if( 0 == GetIpAddressStr( ++ ioGlobales->intIpAddresses[ ioGlobales->intCount ], ++ ioGlobales->intInterfaces[ ioGlobales->intCount ] ++ ) ++ ) { ++ fprintf(stderr, "Invalid internal interface name '%s'\n", ioGlobales->intInterfaceName); ++ ret = EXIT_FAILURE; ++ } ++ ioGlobales->intCount++; ++ } ++ } ++ else { ++ switch( parameters_without_switches ) { ++ case 0: // Obsolete WAN interface ++ if( 0 == ioGlobales->extCount ) { ++ strncpy( ioGlobales->extInterfaceName, argv[ argc_count ], IFNAMSIZ ); ++ } ++ if( ioGlobales->extCount < MAX_WAN_IFACES ) { ++ strncpy( ioGlobales->extInterfaces[ ioGlobales->extCount ], argv[ argc_count ], IFNAMSIZ ); ++ ioGlobales->extCount++; ++ } ++ break; ++ case 1: // Obsolete LAN interface ++ if( 0 == ioGlobales->intCount ) { ++ strncpy( ioGlobales->intInterfaceName, argv[ argc_count ], IFNAMSIZ ); ++ // Get the internal ip address to start the daemon on ++ if( 0 == GetIpAddressStr(ioGlobales->intIpAddress, ioGlobales->intInterfaceName) ) { ++ fprintf(stderr, "Invalid internal interface name '%s'\n", ioGlobales->intInterfaceName); ++ ret = EXIT_FAILURE; ++ } ++ } ++ if( ioGlobales->intCount < MAX_LAN_IFACES ) { ++ strncpy( ioGlobales->intInterfaces[ ioGlobales->intCount ], argv[ argc_count ], IFNAMSIZ ); ++ // Get the internal ip address to start the daemon on ++ if( 0 == GetIpAddressStr( ++ ioGlobales->intIpAddresses[ ioGlobales->intCount ], ++ ioGlobales->intInterfaces[ ioGlobales->intCount ] ++ ) ++ ) { ++ fprintf(stderr, "Invalid internal interface name '%s'\n", ioGlobales->intInterfaceName); ++ ret = EXIT_FAILURE; ++ } ++ ioGlobales->intCount++; ++ } ++ break; ++ default: ++ ret = 1; ++ break; ++ } ++ } ++ parameters_without_switches++; ++ } ++ } ++ ++ if( !ioGlobales->intCount || !ioGlobales->extCount ) { ++ fprintf(stderr, "Parameters error found.\n", ioGlobales->intInterfaceName); ++ ret = 1; ++ } ++ ++ return ret; ++} ++ ++void printUsage( void ) { ++ printf( ++ "SINGLE WAN INTERFACE USAGE:\n" ++ " upnpd [-f] \n" ++ "MULTIPLE WAN INTERFACE USAGE (subject to change):\n" ++ " upnpd [-f] -W -L \n" ++ "\n" ++ " -f\tdon't daemonize\n" ++ "Examples:\n" ++ " upnpd ppp0 eth0\n" ++ " upnpd -W ppp0 ppp1 -L eth0\n" ++ ); ++} +--- linuxigd-cvs/arcoscom_extra.h 1970-01-01 03:00:00.000000000 +0300 ++++ linuxigd-cvs.3/arcoscom_extra.h 2008-01-03 19:11:02.000000000 +0300 +@@ -0,0 +1,10 @@ ++#ifndef _ARCOSCOM_EXTRA_H_ ++#define _ARCOSCOM_EXTRA_H_ ++ ++#include "globals.h" ++ ++void initGlobals( globals_p ioGlobales ); ++int parseCommandLine(int argc, char ** argv, globals_p ioGlobales ); ++void printUsage( void ); ++ ++#endif // _ARCOSCOM_EXTRA_H_ +--- linuxigd-cvs/CHANGES 2008-01-03 18:40:37.000000000 +0300 ++++ linuxigd-cvs.3/CHANGES 2008-01-03 19:11:02.000000000 +0300 +@@ -1,3 +1,10 @@ ++2007-10-23 Samuel Díaz García ++ * Multiple WAN interfaces: First attempt. ++ ++ * Prepared code for multiple LAN interfaces. ++ ++ * Changed command line arguments (with backward compatibility). ++ + 2007-06-30 Magnus Hyllander + * Added the listenport option, which lets you select which UPnP port + to listen to. The port number is passed to UpnpInit when +--- linuxigd-cvs/etc/upnpd.rc 2006-08-16 03:34:56.000000000 +0400 ++++ linuxigd-cvs.3/etc/upnpd.rc 2008-01-03 19:11:02.000000000 +0300 +@@ -34,7 +34,7 @@ + if [ ! -f /var/lock/subsys/upnpd ]; then + echo -n $"Starting $prog: " + [ "$ALLOW_MULTICAST" != "no" ] && route add -net 239.0.0.0 netmask 255.0.0.0 $INTIFACE +- daemon "$UPNPD" $EXTIFACE $INTIFACE ++ daemon "$UPNPD" -W $EXTIFACE -L $INTIFACE + RETVAL=$? + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/upnpd + echo +--- linuxigd-cvs/globals.h 2008-01-03 18:40:40.000000000 +0300 ++++ linuxigd-cvs.3/globals.h 2008-01-03 19:11:02.000000000 +0300 +@@ -6,17 +6,23 @@ + #define CHAIN_NAME_LEN 32 + #define BITRATE_LEN 32 + #define PATH_LEN 64 +-#define RESULT_LEN 512 ++#define RESULT_LEN 1024 + #define NUM_LEN 32 ++#define MAX_IFACES 8 ++#define MAX_LAN_IFACES MAX_IFACES ++#define MAX_WAN_IFACES MAX_IFACES + + #ifndef min + #define min(a,b) ((a) < (b) ? (a) : (b)) + #endif + ++typedef char T_INTERFACENAME[ IFNAMSIZ ]; // Interface name type. ++ + struct GLOBALS { +- char extInterfaceName[IFNAMSIZ]; // The name of the external interface, picked up from the ++ T_INTERFACENAME extInterfaceName; // The name of the external interface, picked up from the + // command line +- char intInterfaceName[IFNAMSIZ]; // The name of the internal interface, picked from command line ++ T_INTERFACENAME intInterfaceName; // The name of the internal interface, picked from command line ++ char intIpAddress[16]; // Server internal ip address + + // All vars below are read from /etc/upnpd.conf in main.c + int debug; // 1 - print debug messages to syslog +@@ -36,6 +42,15 @@ + char descDocName[PATH_LEN]; + char xmlPath[PATH_LEN]; + int listenport; //The port to listen on ++ ++// Now we can use lists for external and/or internal interfaces with diferent params ++ T_INTERFACENAME extInterfaces[ MAX_WAN_IFACES ]; // Pointer to external interfaces names array. ++ int extCount; // Number of external interfaces. Must be <= MAX_WAN_IFACES ++ T_INTERFACENAME intInterfaces[ MAX_LAN_IFACES ]; // Pointer to internal interfaces names array. ++ char intIpAddresses[ MAX_LAN_IFACES ][ 16 ]; // Server internal ip address ++ int intCount; // Number of internal interfaces. Must be <= MAX_LAN_IFACES ++ ++ int foreground; + }; + + typedef struct GLOBALS* globals_p; +--- linuxigd-cvs/main.c 2008-01-03 18:40:41.000000000 +0300 ++++ linuxigd-cvs.3/main.c 2008-01-03 19:11:02.000000000 +0300 +@@ -15,6 +15,7 @@ + #include "gatedevice.h" + #include "util.h" + #include "pmlist.h" ++#include "arcoscom_extra.h" + + // Global variables + globals g_vars; +@@ -22,36 +23,19 @@ + int main (int argc, char** argv) + { + char descDocUrl[7+15+1+5+1+sizeof(g_vars.descDocName)+1]; // http://ipaddr:port/docName +- char intIpAddress[16]; // Server internal ip address + sigset_t sigsToCatch; + int ret, signum, arg = 1, foreground = 0; ++ ++ initGlobals( &g_vars ); + +- if (argc < 3 || argc > 4) { +- printf("Usage: upnpd [-f] \n"); +- printf(" -f\tdon't daemonize\n"); +- printf("Example: upnpd ppp0 eth0\n"); +- exit(0); +- } ++ if( parseCommandLine( argc, argv, &g_vars ) ) { ++ printUsage(); ++ exit( 0 ); ++ } + + parseConfigFile(&g_vars); + +- // check for '-f' option +- if (strcmp(argv[arg], "-f") == 0) { +- foreground = 1; +- arg++; +- } +- +- // Save interface names for later use +- strncpy(g_vars.extInterfaceName, argv[arg++], IFNAMSIZ); +- strncpy(g_vars.intInterfaceName, argv[arg++], IFNAMSIZ); +- +- // Get the internal ip address to start the daemon on +- if (GetIpAddressStr(intIpAddress, g_vars.intInterfaceName) == 0) { +- fprintf(stderr, "Invalid internal interface name '%s'\n", g_vars.intInterfaceName); +- exit(EXIT_FAILURE); +- } +- +- if (!foreground) { ++ if (!g_vars.foreground) { + struct rlimit resourceLimit = { 0, 0 }; + pid_t pid, sid; + unsigned int i; +@@ -114,9 +98,9 @@ + + // Initialize UPnP SDK on the internal Interface + trace(3, "Initializing UPnP SDK ... "); +- if ( (ret = UpnpInit(intIpAddress,g_vars.listenport) ) != UPNP_E_SUCCESS) ++ if ( (ret = UpnpInit(g_vars.intIpAddress,g_vars.listenport) ) != UPNP_E_SUCCESS) + { +- syslog (LOG_ERR, "Error Initializing UPnP SDK on IP %s port %d",intIpAddress,g_vars.listenport); ++ syslog (LOG_ERR, "Error Initializing UPnP SDK on IP %s port %d",g_vars.intIpAddress,g_vars.listenport); + syslog (LOG_ERR, " UpnpInit returned %d", ret); + UpnpFinish(); + exit(1); +--- linuxigd-cvs/Makefile 2008-01-03 18:40:38.000000000 +0300 ++++ linuxigd-cvs.3/Makefile 2008-01-03 19:11:02.000000000 +0300 +@@ -6,7 +6,7 @@ + CC=gcc + INCLUDES= + LIBS= -lpthread -lupnp -lixml -lthreadutil +-FILES= main.o gatedevice.o pmlist.o util.o config.o ++FILES= arcoscom_extra.o main.o gatedevice.o pmlist.o util.o config.o + + CFLAGS += -Wall -g -O2 + +--- linuxigd-cvs/pmlist.c 2008-01-03 18:40:41.000000000 +0300 ++++ linuxigd-cvs.3/pmlist.c 2008-01-03 19:12:12.000000000 +0300 +@@ -233,9 +233,12 @@ + { + if (enabled) + { ++ register int external_iface_count; ++ + char dest[DEST_LEN]; + snprintf(dest, DEST_LEN, "%s:%s", internalClient, internalPort); + ++ for( external_iface_count = 0; external_iface_count < g_vars.extCount; ++external_iface_count ) { + #if HAVE_LIBIPTC + char *buffer = malloc(strlen(internalClient) + strlen(internalPort) + 2); + if (buffer == NULL) { +@@ -251,17 +254,17 @@ + iptc_add_rule("filter", g_vars.forwardChainName, protocol, NULL, NULL, NULL, internalClient, NULL, internalPort, "ACCEPT", NULL, g_vars.forwardRulesAppend ? TRUE : FALSE); + } + trace(3, "iptc_add_rule %s %s %s %s %s %s %s %s", +- "nat", g_vars.preroutingChainName, protocol, g_vars.extInterfaceName, externalPort, "DNAT", dest, "APPEND"); +- iptc_add_rule("nat", g_vars.preroutingChainName, protocol, g_vars.extInterfaceName, NULL, NULL, NULL, NULL, externalPort, "DNAT", dest, TRUE); ++ "nat", g_vars.preroutingChainName, protocol, g_vars.extInterfaces[ external_iface_count ], externalPort, "DNAT", dest, "APPEND"); ++ iptc_add_rule("nat", g_vars.preroutingChainName, protocol, g_vars.extInterfaces[ external_iface_count ], NULL, NULL, NULL, NULL, externalPort, "DNAT", dest, TRUE); + #else + int status; + + if (g_vars.createForwardRules) + { +- char *args[] = {g_vars.iptables, g_vars.forwardRulesAppend ? "-A" : "-I", g_vars.forwardChainName, "-p", protocol, "-d", internalClient, "--dport", internalPort, "-j", "ACCEPT", NULL}; ++ char *args[] = {g_vars.iptables, g_vars.forwardRulesAppend ? "-A" : "-I", g_vars.forwardChainName, "-i", g_vars.extInterfaces[ external_iface_count ], "-p", protocol, "-d", internalClient, "--dport", internalPort, "-j", "ACCEPT", NULL}; + +- trace(3, "%s %s %s -p %s -d %s --dport %s -j ACCEPT", +- g_vars.iptables,g_vars.forwardRulesAppend ? "-A" : "-I",g_vars.forwardChainName, protocol, internalClient, internalPort); ++ trace(3, "%s %s %s -i %s -p %s -d %s --dport %s -j ACCEPT", ++ g_vars.iptables,g_vars.forwardRulesAppend ? "-A" : "-I",g_vars.forwardChainName, g_vars.extInterfaces[ external_iface_count ], protocol, internalClient, internalPort); + if (!fork()) { + int rc = execv(g_vars.iptables, args); + exit(rc); +@@ -271,10 +274,10 @@ + } + + { +- char *args[] = {g_vars.iptables, "-t", "nat", "-A", g_vars.preroutingChainName, "-i", g_vars.extInterfaceName, "-p", protocol, "--dport", externalPort, "-j", "DNAT", "--to", dest, NULL}; ++ char *args[] = {g_vars.iptables, "-t", "nat", "-A", g_vars.preroutingChainName, "-i", g_vars.extInterfaces[ external_iface_count ], "-p", protocol, "--dport", externalPort, "-j", "DNAT", "--to", dest, NULL}; + + trace(3, "%s -t nat -A %s -i %s -p %s --dport %s -j DNAT --to %s", +- g_vars.iptables, g_vars.preroutingChainName, g_vars.extInterfaceName, protocol, externalPort, dest); ++ g_vars.iptables, g_vars.preroutingChainName, g_vars.extInterfaces[ external_iface_count ], protocol, externalPort, dest); + if (!fork()) { + int rc = execv(g_vars.iptables, args); + exit(rc); +@@ -283,6 +286,7 @@ + } + } + #endif ++ } // for + } + return 1; + } +@@ -291,13 +295,15 @@ + { + if (enabled) + { ++ register int external_iface_count; + char dest[DEST_LEN]; + snprintf(dest, DEST_LEN, "%s:%s", internalClient, internalPort); + ++ for( external_iface_count = 0; external_iface_count < g_vars.extCount; ++external_iface_count ) { + #if HAVE_LIBIPTC + trace(3, "iptc_delete_rule %s %s %s %s %s %s %s", +- "nat", g_vars.preroutingChainName, protocol, g_vars.extInterfaceName, externalPort, "DNAT", dest); +- iptc_delete_rule("nat", g_vars.preroutingChainName, protocol, g_vars.extInterfaceName, NULL, NULL, NULL, NULL, externalPort, "DNAT", dest); ++ "nat", g_vars.preroutingChainName, protocol, g_vars.extInterfaces[ external_iface_count ], externalPort, "DNAT", dest); ++ iptc_delete_rule("nat", g_vars.preroutingChainName, protocol, g_vars.extInterfaces[ external_iface_count ], NULL, NULL, NULL, NULL, externalPort, "DNAT", dest); + if (g_vars.createForwardRules) + { + trace(3, "iptc_delete_rule %s %s %s %s %s %s", +@@ -308,10 +314,10 @@ + int status; + + { +- char *args[] = {g_vars.iptables, "-t", "nat", "-D", g_vars.preroutingChainName, "-i", g_vars.extInterfaceName, "-p", protocol, "--dport", externalPort, "-j", "DNAT", "--to", dest, NULL}; ++ char *args[] = {g_vars.iptables, "-t", "nat", "-D", g_vars.preroutingChainName, "-i", g_vars.extInterfaces[ external_iface_count ], "-p", protocol, "--dport", externalPort, "-j", "DNAT", "--to", dest, NULL}; + + trace(3, "%s -t nat -D %s -i %s -p %s --dport %s -j DNAT --to %s", +- g_vars.iptables, g_vars.preroutingChainName, g_vars.extInterfaceName, protocol, externalPort, dest); ++ g_vars.iptables, g_vars.preroutingChainName, g_vars.extInterfaces[ external_iface_count ], protocol, externalPort, dest); + + if (!fork()) { + int rc = execv(g_vars.iptables, args); +@@ -323,10 +329,10 @@ + + if (g_vars.createForwardRules) + { +- char *args[] = {g_vars.iptables, "-D", g_vars.forwardChainName, "-p", protocol, "-d", internalClient, "--dport", internalPort, "-j", "ACCEPT", NULL}; ++ char *args[] = {g_vars.iptables, "-D", g_vars.forwardChainName, "-i", g_vars.extInterfaces[ external_iface_count ], "-p", protocol, "-d", internalClient, "--dport", internalPort, "-j", "ACCEPT", NULL}; + +- trace(3, "%s -D %s -p %s -d %s --dport %s -j ACCEPT", +- g_vars.iptables, g_vars.forwardChainName, protocol, internalClient, internalPort); ++ trace(3, "%s -D %s -i %s -p %s -d %s --dport %s -j ACCEPT", ++ g_vars.iptables, g_vars.forwardChainName, g_vars.extInterfaces[ external_iface_count ], protocol, internalClient, internalPort); + if (!fork()) { + int rc = execv(g_vars.iptables, args); + exit(rc); +@@ -335,6 +341,7 @@ + } + } + #endif ++ } // for + } + return 1; + } --- linux-igd-1.0+cvs20070630.orig/debian/patches/001-iptables_defs.patch +++ linux-igd-1.0+cvs20070630/debian/patches/001-iptables_defs.patch @@ -0,0 +1,78 @@ +Description: Rename parse_ports and serve_to_port to avoid standard functions + Replaces original Debian my_parse_ports patch in interests of standardisation. +Origin: https://dev.openwrt.org/changeset/7446 + +Index: linux-igd-1.0+cvs20070630-3~/iptc.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/iptc.c 2010-05-17 15:06:31.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/iptc.c 2010-05-17 15:06:50.000000000 +0100 +@@ -22,9 +22,9 @@ + struct ipt_entry_match *get_udp_match(const char *sports, const char *dports, unsigned int *nfcache); + struct ipt_entry_target *get_dnat_target(const char *input, unsigned int *nfcache); + +-static u_int16_t parse_port(const char *port); +-static void parse_ports(const char *portstring, u_int16_t *ports); +-static int service_to_port(const char *name); ++static u_int16_t igd_parse_port(const char *port); ++void parse_ports(const char *portstring, u_int16_t *ports); ++static int igd_service_to_port(const char *name); + + static void parse_range(const char *input, struct ip_nat_range *range); + static struct ipt_natinfo *append_range(struct ipt_natinfo *info, const struct ip_nat_range *range); +@@ -336,13 +336,12 @@ + } + + /* Copied and modified from libipt_tcp.c and libipt_udp.c */ +- + static u_int16_t +-parse_port(const char *port) ++igd_parse_port(const char *port) + { + unsigned int portnum; + +- if ((portnum = service_to_port(port)) != -1) { ++ if ((portnum = igd_service_to_port(port)) != -1) { + return (u_int16_t)portnum; + } + else { +@@ -350,7 +349,7 @@ + } + } + +-static void ++void + parse_ports(const char *portstring, u_int16_t *ports) + { + char *buffer; +@@ -358,19 +357,18 @@ + + buffer = strdup(portstring); + if ((cp = strchr(buffer, ':')) == NULL) +- ports[0] = ports[1] = parse_port(buffer); ++ ports[0] = ports[1] = igd_parse_port(buffer); + else { + *cp = '\0'; + cp++; + +- ports[0] = buffer[0] ? parse_port(buffer) : 0; +- ports[1] = cp[0] ? parse_port(cp) : 0xFFFF; ++ ports[0] = buffer[0] ? igd_parse_port(buffer) : 0; ++ ports[1] = cp[0] ? igd_parse_port(cp) : 0xFFFF; + } + free(buffer); + } +- + static int +-service_to_port(const char *name) ++igd_service_to_port(const char *name) + { + struct servent *service; + +@@ -382,7 +380,6 @@ + + + +- + /* Copied and modified from libipt_DNAT.c */ + + static void --- linux-igd-1.0+cvs20070630.orig/debian/patches/14-igd-debug.patch +++ linux-igd-1.0+cvs20070630/debian/patches/14-igd-debug.patch @@ -0,0 +1,90 @@ +Description: Add some extra debugs for pesky SID/subscription problems +Author: Nick Leverton + +Index: linux-igd-1.0+cvs20070630-3~/gatedevice.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/gatedevice.c 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/gatedevice.c 2010-05-17 15:06:36.000000000 +0100 +@@ -75,12 +75,14 @@ + + ithread_mutex_lock(&DevMutex); + ++ trace(3, "HandleSubscriptionRequest enter for UDN %s, expected UDN %s", ++ UpnpSubscriptionRequest_get_UDN_cstr(sr_event), gateUDN); + if (strcmp(UpnpSubscriptionRequest_get_UDN_cstr(sr_event), gateUDN) == 0) + { + // WAN Common Interface Config Device Notifications + if (strcmp(UpnpSubscriptionRequest_get_ServiceId_cstr(sr_event), "urn:upnp-org:serviceId:WANCommonIFC1") == 0) + { +- trace(3, "Recieved request to subscribe to WANCommonIFC1"); ++ trace(3, "Received request to subscribe to WANCommonIFC1"); + UpnpAddToPropertySet(&propSet, "PhysicalLinkStatus", "Up"); + UpnpAcceptSubscriptionExt(deviceHandle, UpnpSubscriptionRequest_get_UDN_cstr(sr_event), UpnpSubscriptionRequest_get_ServiceId_cstr(sr_event), + propSet, UpnpSubscriptionRequest_get_SID_cstr(sr_event)); +@@ -98,9 +100,13 @@ + UpnpAcceptSubscriptionExt(deviceHandle, UpnpSubscriptionRequest_get_UDN_cstr(sr_event), UpnpSubscriptionRequest_get_ServiceId_cstr(sr_event), + propSet, UpnpSubscriptionRequest_get_SID_cstr(sr_event)); + ixmlDocument_free(propSet); ++ } else { ++ trace(3, "HandleSubscriptionRequest unknown ServiceID %s", ++ UpnpSubscriptionRequest_get_ServiceId_cstr(sr_event)); + } + } + ithread_mutex_unlock(&DevMutex); ++ trace(3, "HandleSubscriptionRequest exit, result=%d", 1); + return(1); + } + +@@ -119,10 +125,13 @@ + + ithread_mutex_lock(&DevMutex); + ++ trace(3, "HandleActionRequest enter for UDN %s, expected UDN %s", ++ UpnpActionRequest_get_DevUDN_cstr(ca_event), gateUDN); + if (strcmp(UpnpActionRequest_get_DevUDN_cstr(ca_event), gateUDN) == 0) + { + // Common debugging info, hopefully gets removed soon. +- trace(3, "ActionName = %s", UpnpActionRequest_get_ActionName_cstr(ca_event)); ++ trace(3, "ActionName = %s, ServiceID = %s", UpnpActionRequest_get_ActionName_cstr(ca_event), ++ UpnpActionRequest_get_ServiceID_cstr(ca_event)); + + if (strcmp(UpnpActionRequest_get_ServiceID_cstr(ca_event), "urn:upnp-org:serviceId:WANIPConn1") == 0) + { +@@ -180,20 +189,26 @@ + result = GetCommonLinkProperties(ca_event); + else + { +- trace(1, "Invalid Action Request : %s",UpnpActionRequest_get_ActionName_cstr(ca_event)); + result = InvalidAction(ca_event); + } +- } ++ } else { ++ trace(3, "HandleActionRequest unknown ServiceID %s", ++ UpnpActionRequest_get_ServiceID_cstr(ca_event)); ++ } ++ } else { ++ trace(3, "HandleActionRequest UDN doesn't match"); + } + + ithread_mutex_unlock(&DevMutex); + ++ trace(3, "HandleActionRequest exit, result=%d", result); + return (result); + } + + // Default Action when we receive unknown Action Requests + int InvalidAction(UpnpActionRequest *ca_event) + { ++ trace(1, "Invalid Action Request : %s", UpnpActionRequest_get_ActionName_cstr(ca_event)); + UpnpActionRequest_set_ErrCode(ca_event, 401); + UpnpActionRequest_strcpy_ErrStr(ca_event, "Invalid Action"); + UpnpActionRequest_set_ActionResult(ca_event, NULL); +@@ -282,7 +297,7 @@ + //Immediatley Set connectionstatus to connected, and lastconnectionerror to none. + strcpy(ConnectionStatus,"Connected"); + strcpy(LastConnectionError, "ERROR_NONE"); +- trace(2, "RequestConnection recieved ... Setting Status to %s.", ConnectionStatus); ++ trace(2, "RequestConnection received ... Setting Status to %s.", ConnectionStatus); + + // Build DOM Document with state variable connectionstatus and event it + UpnpAddToPropertySet(&propSet, "ConnectionStatus", ConnectionStatus); --- linux-igd-1.0+cvs20070630.orig/debian/patches/12-thread-debug.patch +++ linux-igd-1.0+cvs20070630/debian/patches/12-thread-debug.patch @@ -0,0 +1,46 @@ +Description: Add thread ID to debug messages to aid debugging +Author: Nick Leverton + +Index: linux-igd-1.0+cvs20070630-3~/util.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/util.c 2010-05-17 15:06:30.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/util.c 2010-05-17 15:06:47.000000000 +0100 +@@ -1,6 +1,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -10,6 +11,7 @@ + #include + #include "globals.h" + ++#include + + static int get_sockfd(void) + { +@@ -56,9 +58,19 @@ + void trace(int debuglevel, const char *format, ...) + { + va_list ap; +- va_start(ap,format); +- if (g_vars.debug>=debuglevel) { +- vsyslog(LOG_DEBUG,format,ap); ++ char *thr_format; ++ ++ va_start(ap, format); ++ ++ if( -1 == asprintf(&thr_format, "0x%lx %s", (unsigned long int)ithread_self(), format) ) ++ thr_format = format; ++ ++ if (g_vars.debug >= debuglevel) { ++ vsyslog(LOG_DEBUG, thr_format, ap); + } ++ ++ if( thr_format != format ) ++ free(thr_format); ++ + va_end(ap); + } --- linux-igd-1.0+cvs20070630.orig/debian/patches/03-gatedesc-version.patch +++ linux-igd-1.0+cvs20070630/debian/patches/03-gatedesc-version.patch @@ -0,0 +1,19 @@ +Description: Update linux-igd version number in gatedesc +Author: Nick Leverton + +Index: linux-igd-1.0+cvs20070630-3~/etc/gatedesc.xml +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/etc/gatedesc.xml 2010-05-17 15:06:32.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/etc/gatedesc.xml 2010-05-17 15:06:35.000000000 +0100 +@@ -59,9 +59,9 @@ + http://linux-igd.sourceforge.net + WanConnectionDevice on Linux IGD + Linux IGD +- 0.95 ++ 1.00 + http://linux-igd.sourceforge.net +- 0.95 ++ 1.00 + uuid:75802409-bccb-40e7-8e6c-fa095ecce13e + Linux IGD + --- linux-igd-1.0+cvs20070630.orig/debian/patches/004-iptables-1.4.3.2-compat.patch +++ linux-igd-1.0+cvs20070630/debian/patches/004-iptables-1.4.3.2-compat.patch @@ -0,0 +1,105 @@ +Description: Update IPTC multiport for kernel iptables to netfilter changes +Origin: https://dev.openwrt.org/changeset/15622 + +Index: linux-igd-1.0+cvs20070630-3~/iptc.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/iptc.c 2010-05-17 15:06:35.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/iptc.c 2010-05-17 15:06:49.000000000 +0100 +@@ -7,16 +7,24 @@ + #include + #include + #include +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +-#include ++#ifdef IPTABLES_143 ++# include ++# define ip_nat_multi_range nf_nat_multi_range_compat ++# define ip_nat_range nf_nat_range + #else +-#include ++# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++# include ++# else ++# include ++# endif + #endif + #include /* inet_addr */ + #include "globals.h" + #include "util.h" + #include "iptc.h" + ++#define IPTC_HANDLE struct iptc_handle * ++ + struct ipt_natinfo + { + struct ipt_entry_target t; +@@ -49,7 +57,7 @@ + const char *dnat_to, + const int append) + { +- iptc_handle_t handle; ++ IPTC_HANDLE handle; + struct ipt_entry *chain_entry; + struct ipt_entry_match *entry_match = NULL; + struct ipt_entry_target *entry_target = NULL; +@@ -126,15 +134,15 @@ + return; + } + if (append) +- result = iptc_append_entry(labelit, chain_entry, &handle); ++ result = iptc_append_entry(labelit, chain_entry, handle); + else +- result = iptc_insert_entry(labelit, chain_entry, 0, &handle); ++ result = iptc_insert_entry(labelit, chain_entry, 0, handle); + + if (!result) { + trace(1, "libiptc error: Can't add, %s", iptc_strerror(errno)); + return; + } +- result = iptc_commit(&handle); ++ result = iptc_commit(handle); + if (!result) { + trace(1, "libiptc error: Commit error, %s", iptc_strerror(errno)); + return; +@@ -159,7 +167,7 @@ + const char *target, + const char *dnat_to) + { +- iptc_handle_t handle; ++ IPTC_HANDLE handle; + const struct ipt_entry *e; + ipt_chainlabel labelit; + int i, result; +@@ -182,7 +190,7 @@ + } + + /* check through rules to find match */ +- for (e = iptc_first_rule(chain, &handle), i=0; e; e = iptc_next_rule(e, &handle), i++) { ++ for (e = iptc_first_rule(chain, handle), i=0; e; e = iptc_next_rule(e, handle), i++) { + if (s_src != INADDR_NONE && e->ip.src.s_addr != s_src) continue; + if (s_dest != INADDR_NONE && e->ip.dst.s_addr != s_dest) continue; + if (iniface && strcmp(e->ip.iniface, iniface) != 0) continue; +@@ -190,7 +198,7 @@ + if (protocol && strcmp(protocol, "TCP") == 0 && e->ip.proto != IPPROTO_TCP) continue; + if (protocol && strcmp(protocol, "UDP") == 0 && e->ip.proto != IPPROTO_UDP) continue; + if ((srcports || destports) && IPT_MATCH_ITERATE(e, matchcmp, srcports, destports) == 0) continue; +- if (target && strcmp(target, iptc_get_target(e, &handle)) != 0) continue; ++ if (target && strcmp(target, iptc_get_target(e, handle)) != 0) continue; + if (dnat_to && strcmp(target, "DNAT") == 0) { + struct ipt_entry_target *t; + struct ip_nat_multi_range *mr; +@@ -214,12 +222,12 @@ + break; + } + if (!e) return; +- result = iptc_delete_num_entry(chain, i, &handle); ++ result = iptc_delete_num_entry(chain, i, handle); + if (!result) { + trace(1, "libiptc error: Delete error, %s", iptc_strerror(errno)); + return; + } +- result = iptc_commit(&handle); ++ result = iptc_commit(handle); + if (!result) { + trace(1, "libiptc error: Commit error, %s", iptc_strerror(errno)); + return; --- linux-igd-1.0+cvs20070630.orig/debian/patches/16-debug-spelling.patch +++ linux-igd-1.0+cvs20070630/debian/patches/16-debug-spelling.patch @@ -0,0 +1,38 @@ +Description: Fix a couple of trivial spelling errors in debug, to shut lintian up +Author: nick@leverton.org + +Index: linux-igd-1.0+cvs20070630-3~/gatedevice.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/gatedevice.c 2010-05-14 11:00:27.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/gatedevice.c 2010-05-14 11:01:28.000000000 +0100 +@@ -82,7 +82,7 @@ + // WAN Common Interface Config Device Notifications + if (strcmp(UpnpSubscriptionRequest_get_ServiceId_cstr(sr_event), "urn:upnp-org:serviceId:WANCommonIFC1") == 0) + { +- trace(3, "Recieved request to subscribe to WANCommonIFC1"); ++ trace(3, "Received request to subscribe to WANCommonIFC1"); + UpnpAddToPropertySet(&propSet, "PhysicalLinkStatus", "Up"); + UpnpAcceptSubscriptionExt(deviceHandle, UpnpSubscriptionRequest_get_UDN_cstr(sr_event), UpnpSubscriptionRequest_get_ServiceId_cstr(sr_event), + propSet, UpnpSubscriptionRequest_get_SID_cstr(sr_event)); +@@ -297,7 +297,7 @@ + //Immediatley Set connectionstatus to connected, and lastconnectionerror to none. + strcpy(ConnectionStatus,"Connected"); + strcpy(LastConnectionError, "ERROR_NONE"); +- trace(2, "RequestConnection recieved ... Setting Status to %s.", ConnectionStatus); ++ trace(2, "RequestConnection received ... Setting Status to %s.", ConnectionStatus); + + // Build DOM Document with state variable connectionstatus and event it + UpnpAddToPropertySet(&propSet, "ConnectionStatus", ConnectionStatus); +Index: linux-igd-1.0+cvs20070630-3~/main.c +=================================================================== +--- linux-igd-1.0+cvs20070630-3~.orig/main.c 2010-05-14 11:00:27.000000000 +0100 ++++ linux-igd-1.0+cvs20070630-3~/main.c 2010-05-14 11:01:28.000000000 +0100 +@@ -139,7 +139,7 @@ + UpnpFinish(); + exit(1); + } +- trace(2, "Succesfully set the Web Server Root Directory."); ++ trace(2, "Successfully set the Web Server Root Directory."); + + //initialize the timer thread for expiration of mappings + if (ExpirationTimerThreadInit()!=0) { --- linux-igd-1.0+cvs20070630.orig/debian/patches/series +++ linux-igd-1.0+cvs20070630/debian/patches/series @@ -0,0 +1,22 @@ +# 01-debian-my_parse_port.diff +02-makefile.diff +# include patch04 for reference, not compiled in as not yet reviewed for stability. +# 04-upstream-multiple-wan-interfaces.diff +03-gatedesc-version.patch +05-debian-upnpd.conf.diff +06-paranoid-port-forwarding.patch +07-fix-includes.patch +001-iptables_defs.patch +002-netfilter_nat_headers.patch +004-iptables-1.4.3.2-compat.patch +001a-more-statics.patch +08-fix-have-iptc.patch +09-update-manpage.patch +10-libupnp4.diff +# 11-ipv6.patch +11-fix-sprintf.patch +12-thread-debug.patch +13-upnp-debug.patch +14-igd-debug.patch +15-prerouting-rules-append.patch +16-nullify-event-mapping-to-prevent-writing-over-free-d.patch --- linux-igd-1.0+cvs20070630.orig/debian/source/format +++ linux-igd-1.0+cvs20070630/debian/source/format @@ -0,0 +1 @@ +1.0