From 6c3be39c99240470461af6610a54fbd3157d3e68 Mon Sep 17 00:00:00 2001
From: Ravinder Konka <rkonka@codeaurora.org>
Date: Mon, 23 Mar 2015 22:31:46 +0530
Subject: [PATCH] certification-fixes

Change-Id: I7efdf811a168302d651345695af9c31506c41dcd
---
 getifaddr.c                   |   4 ++--
 minissdp.c                    |   8 ++++----
 config.h                      | 140 ++++++
 getifstats.h                  |   6 +
 linux/getroute.c              |   1 +
 linux/miniupnpd.init.d.script |  15 -
 miniupnpd.c                   |  53 +-
 miniupnpd.conf                |  20 +-
 natpmp.c                      |  17 +-
 pcpserver.c                   |  19 +-
 upnppinhole.c                 | 627 ++++++++++++++++++++++++
 upnpredirect.c                |  81 ++-
 upnpredirect.h                |  17 +-
 upnpsoap.c                    | 140 +++++-
 upnpdescgen.c                 |  27 +++---
 13 files changed, 1079 insertions(+), 63 deletions(-)
 create mode 100755 config.h
 create mode 100755 upnppinhole.c

diff --git a/getifaddr.c b/getifaddr.c
index 6bbbe78..0bdc16a 100644
--- a/getifaddr.c
+++ b/getifaddr.c
@@ -241,8 +241,7 @@ find_ipv6_addr(const char * ifname,
 		if(ife->ifa_addr->sa_family == AF_INET6)
 		{
 			addr = (const struct sockaddr_in6 *)ife->ifa_addr;
-			if(!IN6_IS_ADDR_LOOPBACK(&addr->sin6_addr)
-			   && !IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr))
+			if(IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr))
 			{
 				inet_ntop(ife->ifa_addr->sa_family,
 				          &addr->sin6_addr,
@@ -250,6 +249,7 @@ find_ipv6_addr(const char * ifname,
 				/* add brackets */
 				snprintf(dst, n, "[%s]", buf);
 				r = 1;
+				break;
 			}
 		}
 	}

diff --git a/minissdp.c b/minissdp.c
index 9fff6d9..cc83861 100644
--- a/minissdp.c
+++ b/minissdp.c
@@ -201,7 +201,7 @@ OpenAndConfSSDPNotifySocket(in_addr_t addr)
 	int s;
 	unsigned char loopchar = 0;
 	int bcast = 1;
-	unsigned char ttl = 2; /* UDA v1.1 says :
+	unsigned char ttl = 4; /* UDA v1.1 says :
 		The TTL for the IP packet SHOULD default to 2 and
 		SHOULD be configurable. */
 	/* TODO: Make TTL be configurable */
@@ -485,8 +485,8 @@ static struct {
 {
 	{"upnp:rootdevice", 0, uuidvalue_igd},
 	{"urn:schemas-upnp-org:device:InternetGatewayDevice:", IGD_VER, uuidvalue_igd},
-	{"urn:schemas-upnp-org:device:WANConnectionDevice:", 1, uuidvalue_wcd},
-	{"urn:schemas-upnp-org:device:WANDevice:", 1, uuidvalue_wan},
+	{"urn:schemas-upnp-org:device:WANConnectionDevice:", IGD_VER, uuidvalue_wcd},
+	{"urn:schemas-upnp-org:device:WANDevice:", IGD_VER, uuidvalue_wan},
 	{"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:", 1, uuidvalue_wan},
 	{"urn:schemas-upnp-org:service:WANIPConnection:", WANIPC_VER, uuidvalue_wcd},
 #ifndef UPNP_STRICT
@@ -499,7 +499,7 @@ static struct {
 	{"urn:schemas-upnp-org:service:Layer3Forwarding:", 1, uuidvalue_igd},
 #endif
 #ifdef ENABLE_6FC_SERVICE
-	{"url:schemas-upnp-org:service:WANIPv6FirewallControl:", 1, uuidvalue_wcd},
+	{"urn:schemas-upnp-org:service:WANIPv6FirewallControl:", 1, uuidvalue_wcd},
 #endif
 /* we might want to support urn:schemas-wifialliance-org:device:WFADevice:1
  * urn:schemas-wifialliance-org:device:WFADevice:1
diff --git a/config.h b/config.h
new file mode 100755
index 0000000..25ff292
--- /dev/null
+++ b/config.h
@@ -0,0 +1,142 @@
+/* MiniUPnP Project
+ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
+ * (c) 2006-2014 Thomas Bernard
+ * generated by ./genconfig.sh on Tue Jul 22 16:26:08 PDT 2014
+ * using command line options  */
+#ifndef CONFIG_H_INCLUDED
+#define CONFIG_H_INCLUDED
+
+#include <inttypes.h>
+
+#define MINIUPNPD_VERSION "1.8"
+
+#define UPNP_VERSION	"20140722"
+#define USE_IFACEWATCHER 1
+#define USE_NETFILTER 1
+#define SUPPORT_REMOTEHOST
+
+#define OS_NAME		"Ubuntu"
+#define OS_VERSION	"Ubuntu/lucid"
+#define OS_URL		"http://www.ubuntu.com/"
+
+/* syslog facility to be used by miniupnpd */
+#define LOG_MINIUPNPD		 LOG_DAEMON
+
+/* Uncomment the following line to allow miniupnpd to be
+ * controlled by miniupnpdctl */
+/*#define USE_MINIUPNPDCTL*/
+
+/* Comment the following line to disable NAT-PMP operations */
+#define ENABLE_NATPMP
+
+/* Comment the following line to disable PCP operations */
+#define ENABLE_PCP
+
+#ifdef ENABLE_PCP
+/* Uncomment the following line to enable PCP PEER operation */
+/*#define PCP_PEER*/
+#ifdef PCP_PEER
+/*#define PCP_FLOWP*/
+#endif /*PCP_PEER*/
+/*#define PCP_SADSCP*/
+#endif /*ENABLE_PCP*/
+
+/* Uncomment the following line to enable generation of
+ * filter rules with pf */
+/*#define PF_ENABLE_FILTER_RULES*/
+
+/* Uncomment the following line to enable caching of results of
+ * the getifstats() function */
+/*#define ENABLE_GETIFSTATS_CACHING*/
+/* The cache duration is indicated in seconds */
+#define GETIFSTATS_CACHING_DURATION 2
+
+/* Uncomment the following line to enable multiple external ip support */
+/* note : That is EXPERIMENTAL, do not use that unless you know perfectly what you are doing */
+/* Dynamic external ip adresses are not supported when this option is enabled.
+ * Also note that you would need to configure your .conf file accordingly. */
+/*#define MULTIPLE_EXTERNAL_IP*/
+
+/* Comment the following line to use home made daemonize() func instead
+ * of BSD daemon() */
+#define USE_DAEMON
+
+/* Uncomment the following line to enable lease file support */
+/*#define ENABLE_LEASEFILE*/
+
+/* Uncomment the following line to enable port in use check */
+/*#define CHECK_PORTINUSE*/
+
+/* Define one or none of the two following macros in order to make some
+ * clients happy. It will change the XML Root Description of the IGD.
+ * Enabling the Layer3Forwarding Service seems to be the more compatible
+ * option. */
+/*#define HAS_DUMMY_SERVICE*/
+#define ENABLE_L3F_SERVICE
+
+/* Enable IP v6 support */
+#define ENABLE_IPV6
+
+/* Define V6SOCKETS_ARE_V6ONLY if AF_INET6 sockets are restricted
+ * to IPv6 communications only. */
+#define V6SOCKETS_ARE_V6ONLY
+
+/* Enable the support of IGD v2 specification.
+ * This is not fully tested yet and can cause incompatibilities with some
+ * control points, so enable with care. */
+#define IGD_V2
+
+#ifdef IGD_V2
+/* Enable DeviceProtection service (IGDv2) */
+//#define ENABLE_DP_SERVICE
+/*#define ENABLE_HTTPS*/
+/*#define HTTPS_CERTFILE "/path/to/certificate.pem"*/
+/*#define HTTPS_KEYFILE "/path/to/private.key"*/
+
+/* Enable WANIPv6FirewallControl service (IGDv2). needs IPv6 */
+#ifdef ENABLE_IPV6
+#define ENABLE_6FC_SERVICE
+#endif /* ENABLE_IPV6 */
+#endif /* IGD_V2 */
+
+/* UPnP Events support. Working well enough to be enabled by default.
+ * It can be disabled to save a few bytes. */
+#define ENABLE_EVENTS
+
+/* include interface name in pf and ipf rules */
+#define USE_IFNAME_IN_RULES
+
+/* Experimental NFQUEUE support. */
+/*#define ENABLE_NFQUEUE*/
+
+/* Enable to make MiniUPnPd more strict about UPnP conformance
+ * and the messages it receives from control points */
+#define UPNP_STRICT
+
+/* If SSDP_RESPOND_SAME_VERSION is defined, the M-SEARCH response
+ * include the same device version as was contained in the search
+ * request. It conforms to UPnP DA v1.1 */
+#define SSDP_RESPOND_SAME_VERSION
+
+/* Add the optional Date: header in all HTTP responses */
+#define ENABLE_HTTP_DATE
+
+/* Wait a little before answering M-SEARCH request */
+/*#define DELAY_MSEARCH_RESPONSE*/
+
+/* disable reading and parsing of config file (miniupnpd.conf) */
+/*#define DISABLE_CONFIG_FILE*/
+
+/* Uncomment the following line to configure all manufacturer infos through miniupnpd.conf */
+#define ENABLE_MANUFACTURER_INFO_CONFIGURATION
+
+#if defined(ENABLE_6FC_SERVICE) || (defined(ENABLE_PCP) && defined(ENABLE_IPV6))
+#define ENABLE_UPNPPINHOLE
+#endif
+
+/* Enable QCMAP */
+#define QCMAP
+
+//#define DEBUG
+
+#endif /* CONFIG_H_INCLUDED */
diff --git a/getifstats.h b/getifstats.h
index e14b853..cecaa49 100755
--- a/getifstats.h
+++ b/getifstats.h
@@ -7,12 +7,18 @@
 #ifndef GETIFSTATS_H_INCLUDED
 #define GETIFSTATS_H_INCLUDED
 
+#include "config.h"
+
 struct ifdata {
 	unsigned long opackets;
 	unsigned long ipackets;
 	unsigned long obytes;
 	unsigned long ibytes;
 	unsigned long baudrate;
+#ifdef QCMAP
+	unsigned long upstream_bitrate;
+	unsigned long downstream_bitrate;
+#endif
 };
 
 /* getifstats()
diff --git a/linux/getroute.c b/linux/getroute.c
index e6386d0..6d10bb7 100755
--- a/linux/getroute.c
+++ b/linux/getroute.c
@@ -21,6 +21,7 @@
 #include "../getroute.h"
 #include "../upnputils.h"
 
+
 int
 get_src_for_route_to(const struct sockaddr * dst,
                      void * src, size_t * src_len,
diff --git a/linux/miniupnpd.init.d.script b/linux/miniupnpd.init.d.script
index ee6e47b..b29c249 100755
--- a/linux/miniupnpd.init.d.script
+++ b/linux/miniupnpd.init.d.script
@@ -16,35 +16,20 @@
 set -e

 MINIUPNPD=/usr/sbin/miniupnpd
-ARGS='-f /etc/miniupnpd/miniupnpd.conf'
-
-IPTABLES_CREATE=/etc/miniupnpd/iptables_init.sh
-IPTABLES_REMOVE=/etc/miniupnpd/iptables:removeall.sh
+ARGS='-f /etc/data/miniupnpd/miniupnpd.conf'

 test -f $MINIUPNPD || exit 0
 
-. /lib/lsb/init-functions
-
 case "$1" in
   start)
-	log_daemon_msg "Starting miniupnpd" "miniupnpd"
-	$IPTABLES_CREATE > /dev/null 2>&1
 	start-stop-daemon --start --quiet --pidfile /var/run/miniupnpd.pid --startas $MINIUPNPD -- $ARGS $LSBNAMES
-	log_end_msg $?
 	;;
   stop)
-	log_daemon_msg "Stopping miniupnpd" "miniupnpd"
 	start-stop-daemon --stop --quiet --pidfile /var/run/miniupnpd.pid
-	log_end_msg $?
-	$IPTABLES_REMOVE > /dev/null 2>&1
 	;;
   restart|reload|force-reload)
-	log_daemon_msg "Restarting miniupnpd" "miniupnpd"
 	start-stop-daemon --stop --retry 5 --quiet --pidfile /var/run/miniupnpd.pid
-	$IPTABLES_REMOVE > /dev/null 2>&1
-	$IPTABLES_CREATE > /dev/null 2>&1
 	start-stop-daemon --start --quiet --pidfile /var/run/miniupnpd.pid --startas $MINIUPNPD -- $ARGS $LSBNAMES
-	log_end_msg $?
 	;;
   status)
 	status_of_proc /usr/sbin/miniupnpd miniupnpd

diff --git a/miniupnpd.c b/miniupnpd.c
index f785b01..4875de3 100755
--- a/miniupnpd.c
+++ b/miniupnpd.c
@@ -77,6 +77,16 @@
 #ifdef USE_IFACEWATCHER
 #include "ifacewatcher.h"
 #endif
+#ifdef QCMAP
+#include "netfilter/iptpinhole.c"
+#endif
+
+#ifndef QCMAP
+#if defined(USE_NETFILTER)
+#include "netfilter/iptpinhole.c"
+#endif
+#endif
+
 #ifdef ENABLE_UPNPPINHOLE
 #ifdef USE_NETFILTER
 void init_iptpinhole(void);
@@ -155,15 +165,17 @@ OpenAndConfHTTPSocket(unsigned short * p
 	{
 		syslog(LOG_WARNING, "setsockopt(http, SO_REUSEADDR): %m");
 	}
-#if 0
+
+#ifdef V6SOCKETS_ARE_V6ONLY
 	/* enable this to force IPV6 only for IPV6 socket.
 	 * see http://www.ietf.org/rfc/rfc3493.txt section 5.3 */
-	if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &i, sizeof(i)) < 0)
+        if(ipv6 && setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &i, sizeof(i)) < 0)
 	{
 		syslog(LOG_WARNING, "setsockopt(http, IPV6_V6ONLY): %m");
 	}
 #endif
 
+
 	if(!set_non_blocking(s))
 	{
 		syslog(LOG_WARNING, "set_non_blocking(http): %m");
@@ -1371,7 +1383,11 @@ init(int argc, char * * argv, struct run
 			fprintf(stderr, "Unknown option: %s\n", argv[i]);
 		}
 	}
-	if(!ext_if_name || !lan_addrs.lh_first)
+	if(
+#ifndef QCMAP
+           !ext_if_name ||
+#endif
+           !lan_addrs.lh_first)
 	{
 		/* bad configuration */
 		goto print_usage;
@@ -1457,9 +1473,15 @@ init(int argc, char * * argv, struct run
 	srandom((unsigned int)time(NULL));
 
 	/* initialize redirection engine (and pinholes) */
+#ifndef QCMAP
 	if(init_redirect() < 0)
 	{
 		syslog(LOG_ERR, "Failed to init redirection engine. EXITING");
+#else
+	if(!QCMAPClient())
+	{
+		syslog(LOG_ERR, "Failed to init QCMAP. EXITING");
+#endif
 		return 1;
 	}
 #ifdef ENABLE_UPNPPINHOLE
@@ -1648,7 +1670,11 @@ main(int argc, char * * argv)
 		return 0;
 	}
 
+#ifndef QCMAP
 	syslog(LOG_INFO, "version " MINIUPNPD_VERSION " starting%s%sext if %s BOOTID=%u",
+#else
+	syslog(LOG_INFO, "version " MINIUPNPD_VERSION " starting%s%sext if BOOTID=%u",
+#endif
 #ifdef ENABLE_NATPMP
 #ifdef ENABLE_PCP
 	       GETFLAG(ENABLENATPMPMASK) ? " NAT-PMP/PCP " : " ",
@@ -1658,8 +1684,12 @@ main(int argc, char * * argv)
 #else
 	       " ",
 #endif
-	       GETFLAG(ENABLEUPNPMASK) ? "UPnP-IGD " : "",
-	       ext_if_name, upnp_bootid);
+	       GETFLAG(ENABLEUPNPMASK) ? "UPnP-IGD " : ""
+#ifndef QCMAP
+               ,ext_if_name, upnp_bootid);
+#else
+               ,upnp_bootid);
+#endif
 
 	if(GETFLAG(ENABLEUPNPMASK))
 	{
@@ -2334,6 +2364,7 @@ main(int argc, char * * argv)
 
 shutdown:
 	syslog(LOG_NOTICE, "shutting down MiniUPnPd");
+
 	/* send good-bye */
 	if (GETFLAG(ENABLEUPNPMASK))
 	{
@@ -2349,6 +2380,14 @@ shutdown:
 	/* try to send pending packets */
 	finalize_sendto();
 
+#ifdef QCMAP
+        /* Tear Down QCMap Client */
+	if(!tearDownQCMAPClient())
+	{
+		syslog(LOG_ERR, "Unable to tear down QCMAP Client");
+	}
+#endif
+
 	/* close out open sockets */
 	while(upnphttphead.lh_first != NULL)
 	{
diff --git a/miniupnpd.conf b/miniupnpd.conf
index 90bd5ad..c4bedce 100755
--- a/miniupnpd.conf
+++ b/miniupnpd.conf
@@ -16,7 +16,8 @@
 #  listening_ip=192.168.0.1/24 88.22.44.13
 #listening_ip=192.168.0.1/24
 #listening_ip=10.5.0.0/16
-#listening_ip=eth0
+listening_ip=bridge0
+listening_ip=ppp0
 # CAUTION: mixing up WAN and LAN interfaces may introduce security risks!
 # be sure to assign the correct interfaces to LAN and WAN and consider
 # implementing UPnP permission rules at the bottom of this configuration file
@@ -55,7 +56,7 @@
 # ENABLE_MANUFACTURER_INFO_CONFIGURATION (config.h)
 
 # name of this service, default is "`uname -s` router"
-#friendly_name=MiniUPnPd router
+friendly_name=9x45 MobileAP UPnP
 
 # manufacturer name, default is "`uname -s`"
 #manufacturer_name=Manufacturer corp
@@ -86,7 +87,7 @@ secure_mode=no
 # If set to an empty string, no presentationURL element will appear
 # in the XML description of the device, which prevents MS Windows
 # from displaying an icon in the "Network Connections" panel.
-#presentation_url=http://www.mylan/index.php
+presentation_url=/192.168.225.1:8201
 
 # report system uptime instead of daemon uptime
 system_uptime=yes
@@ -122,7 +123,7 @@ clean_ruleset_interval=600
 #quickrules=no
 
 # uuid : generate your own with "make genuuid"
-uuid=00000000-0000-0000-0000-000000000000
+uuid=1a7872a9-92bc-4661-8a70-69370a908d12
 
 # serial and model number the daemon will report to clients
 # in its XML description
@@ -141,9 +142,9 @@ uuid=00000000-0000-0000-0000-00000000000
 # modify the IP ranges to match their own internal networks, and
 # also consider implementing network-specific restrictions
 # CAUTION: failure to enforce any rules may permit insecure requests to be made!
-allow 1024-65535 192.168.0.0/24 1024-65535
-allow 1024-65535 192.168.1.0/24 1024-65535
-allow 1024-65535 192.168.0.0/23 22
-allow 12345 192.168.7.113/32 54321
-deny 0-65535 0.0.0.0/0 0-65535
+#allow 1024-65535 192.168.0.0/24 0-65535
+#allow 1024-65535 192.168.1.0/24 1024-65535
+#allow 1024-65535 192.168.0.0/23 22
+#allow 12345 192.168.7.113/32 54321
+allow 0-65535 0.0.0.0/0 0-65535
 

diff --git a/natpmp.c b/natpmp.c
index baa0e74..8e7063d 100755
--- a/natpmp.c
+++ b/natpmp.c
@@ -310,6 +310,7 @@ void ProcessIncomingNATPMPPacket(int s,
 			 * (and set eport correctly) */
 			if(lifetime == 0) {
 				/* remove the mapping */
+#ifndef QCMAP
 				/* RFC6886 :
 				 * A client MAY also send an explicit packet to request deletion of a
 				 * mapping that is no longer needed. A client requests explicit
@@ -349,6 +350,7 @@ void ProcessIncomingNATPMPPacket(int s,
 					}
 					index++;
 				}
+#endif
 			} else if(iport==0) {
 				resp[3] = 2;	/* Not Authorized/Refused */
 			} else { /* iport > 0 && lifetime > 0 */
@@ -387,10 +389,14 @@ void ProcessIncomingNATPMPPacket(int s,
 						continue;
 					}
 #endif
+#ifndef QCMAP
 					r = get_redirect_rule(ext_if_name, eport, proto,
 					                      iaddr_old, sizeof(iaddr_old),
 					                      &iport_old, 0, 0, 0, 0,
 					                      &timestamp, 0, 0);
+#else
+					r=0;
+#endif
 					if(r==0) {
 						if(strcmp(senderaddrstr, iaddr_old)==0
 						    && iport==iport_old) {
@@ -419,7 +425,11 @@ void ProcessIncomingNATPMPPacket(int s,
 					         eport, (proto==IPPROTO_TCP)?"tcp":"udp");
 #endif
 					/* TODO : check return code */
-					if(upnp_redirect_internal(NULL, eport, senderaddrstr,
+					if(upnp_redirect_internal(
+#ifndef QCMAP
+                                                                  NULL,
+#endif 
+                                                                  eport, senderaddrstr,
 					                          iport, proto, desc,
 					                          timestamp) < 0) {
 						syslog(LOG_ERR, "Failed to add NAT-PMP %hu %s->%s:%hu '%s'",
diff --git a/pcpserver.c b/pcpserver.c
index 110cccd..a54b6ac 100755
--- a/pcpserver.c
+++ b/pcpserver.c
@@ -962,13 +962,18 @@ static int CreatePCPMap_NAT(pcp_info_t *
 			continue;
 		}
 #endif
+#ifndef QCMAP
 		r = get_redirect_rule(ext_if_name,
 				      pcp_msg_info->ext_port,
 				      pcp_msg_info->protocol,
 				      iaddr_old, sizeof(iaddr_old),
 				      &iport_old, 0, 0, 0, 0,
 				      &timestamp, 0, 0);
-
+#else
+		r = getSpecificEntry( pcp_msg_info->ext_port, pcp_msg_info->protocol,
+	                      iaddr_old, sizeof(iaddr_old), &iport_old,
+	                      0, 0, &timestamp);
+#endif
 		if(r==0) {
 			if((strcmp(pcp_msg_info->mapped_str, iaddr_old)!=0)
 			   || (pcp_msg_info->int_port != iport_old)) {
@@ -995,7 +1000,10 @@ static int CreatePCPMap_NAT(pcp_info_t *
 		}
 	} while (r==0);
 
-	r = upnp_redirect_internal(NULL,
+	r = upnp_redirect_internal(
+#ifndef QCMAP
+				   NULL,
+#endif
 				   pcp_msg_info->ext_port,
 				   pcp_msg_info->mapped_str,
 				   pcp_msg_info->int_port,
@@ -1095,11 +1103,16 @@ static void DeletePCPMap(pcp_info_t *pcp
 	/* iterate through all rules and delete the requested ones */
 	for (index = 0 ;
 	     (!pcp_msg_info->is_fw &&
+#ifndef QCMAP
 	      get_redirect_rule_by_index(index, 0,
 					 &eport2, iaddr2, sizeof(iaddr2),
 					 &iport2, &proto2,
 					 desc, sizeof(desc),
-					 0, 0, &timestamp, 0, 0) >= 0)
+					 0, 0, &timestamp, 0, 0)
+#else
+	     getStaticNatConfigByEntry(index, iaddr2, sizeof(iaddr2), &eport2, &iport2, &proto2)
+#endif
+	     >= 0)
 #ifdef ENABLE_UPNPPINHOLE
 	       ||
 	     (pcp_msg_info->is_fw &&
diff --git a/upnppinhole.c b/upnppinhole.c
new file mode 100755
index 0000000..2c4b661
--- a/upnppinhole.c
+++ b/upnppinhole.c
@@ -13,7 +13,7 @@
 #include <netinet/in.h>
 #include <net/if.h>
 #include <arpa/inet.h>
-
+#include <string.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <unistd.h>
@@ -41,6 +41,15 @@
 #endif
 #if defined(USE_IPFW)
 #endif
+#ifdef QCMAP
+#include "netfilter/iptpinhole.c"
+#endif
+
+#ifndef QCMAP
+#if defined(USE_NETFILTER)
+#include "netfilter/iptpinhole.c"
+#endif
+#endif
 
 #ifdef ENABLE_UPNPPINHOLE
 
@@ -108,7 +117,11 @@ upnp_add_inboundpinhole(const char * rad
 	time_t current;
 	unsigned int timestamp;
 	struct in6_addr address;
-
+#ifdef QCMAP
+	int k;
+	struct in6_addr src_addr,des_addr;
+	int qcmap_handle=0;
+#endif
 	r = inet_pton(AF_INET6, iaddr, &address);
 	if(r <= 0) {
 		syslog(LOG_ERR, "inet_pton(%d, %s, %p) FAILED",
@@ -119,6 +132,9 @@ upnp_add_inboundpinhole(const char * rad
 	timestamp = current + leasetime;
 	r = 0;
 
+	syslog(LOG_INFO, "upnp_add-inbound pinhole from [%s]:%hu to [%s]:%hu with proto %d during %d sec",
+		raddr, rport, iaddr, iport,proto, leasetime);
+
 #if 0
 	if(r == 1 && strcmp(iaddr, iaddr_old)==0 && iport==iport_old)
 	{
@@ -129,15 +145,42 @@ upnp_add_inboundpinhole(const char * rad
 	}
 	else
 #endif
+
+#ifndef QCMAP
 #if defined(USE_PF) || defined(USE_NETFILTER)
 	*uid = add_pinhole (0/*ext_if_name*/, raddr, rport,
-	                    iaddr, iport, proto, desc, timestamp);
+				iaddr, iport, proto, desc, timestamp);
 	return *uid >= 0 ? 1 : -1;
 #else
 	return -42;	/* not implemented */
 #endif
-}
+#else
+//If QCMAP is defined:
+	if(strlen(raddr) > 0)
+	{
+		k= inet_pton(AF_INET6, raddr, &src_addr);
+		if(k <= 0)
+		{
+			syslog(LOG_ERR, "inet_pton(%d, %s, %p) FAILED",
+			AF_INET6, raddr, &src_addr);
+			return -4;
+		}
+	}
+	qcmap_handle= AddFirewallEntryWrapper(iaddr, raddr, rport, iport, proto);
+	*uid = add_to_pinhole_list(&src_addr, rport, &address, iport,proto, desc, timestamp
+#ifdef QCMAP
+							,qcmap_handle
+#endif
+							);
+	if(qcmap_handle == -4)
+	{
+		syslog(LOG_ERR, "ENTRY ALREADY PRESENT. CANNOT ADD DUPLICATE Entry");
+		return 1;
+	}
+	return *uid >= 0 ? 1 : -1;
+#endif
 
+}
 #if 0
 int
 upnp_add_inboundpinhole_internal(const char * raddr, unsigned short rport,
@@ -226,6 +269,7 @@ upnp_get_pinhole_info(unsigned short uid
                       unsigned int * packets)
 {
 	/* Call Firewall specific code to get IPv6 pinhole infos */
+#ifndef QCMAP
 #if defined(USE_PF) || defined(USE_NETFILTER)
 	int r;
 	unsigned int timestamp;
@@ -259,6 +303,52 @@ upnp_get_pinhole_info(unsigned short uid
 	UNUSED(leasetime); UNUSED(packets);
 	return -42;	/* not implemented */
 #endif
+#else
+//If QCMAP is defined
+	int r;
+	char xyz[INET6_ADDRSTRLEN];
+	struct pinhole_t * p= (struct pinhole_t *)malloc(sizeof(struct pinhole_t *));
+	p = get_pinhole(uid);
+	if(!p)
+	return -2;
+	syslog(LOG_INFO, "After get_pinhole puid = %d ,qcmap_handle= %d",p->uid,p->qcmap_handle);
+	unsigned int timestamp;
+	//u_int64_t packets_tmp;
+	/*u_int64_t bytes_tmp;*/
+	r = GetFirewallEntryWrapper(p->qcmap_handle, raddr, rport,
+							iport, proto);
+
+	if(inet_ntop(AF_INET6,(void *)&p->saddr, xyz, INET6_ADDRSTRLEN) == NULL)
+		return -1;
+	if(iaddr)
+	{
+		if(inet_ntop(AF_INET6,(void *)&p->daddr, iaddr, INET6_ADDRSTRLEN) == NULL)
+		return -1;
+	}
+	syslog(LOG_INFO, " internal address  = %s",iaddr);
+
+	if (desc)
+	strncpy(desc, p->desc, desclen);
+	if (leasetime)
+	*leasetime = p->timestamp;
+	if(r >= 0)
+	{
+	if(leasetime)
+	{
+			time_t current_time;
+			current_time = time(NULL);
+			if(p->timestamp > (unsigned int)current_time)
+				*leasetime = timestamp - current_time;
+			else
+ 				*leasetime = 0;
+	}
+	}
+	UNUSED(raddrlen);
+	UNUSED(iaddrlen);
+	UNUSED(packets);
+
+return r;
+#endif
 }
 
 int
@@ -290,6 +380,7 @@ upnp_update_inboundpinhole(unsigned shor
 int
 upnp_delete_inboundpinhole(unsigned short uid)
 {
+#ifndef QCMAP
 #if defined(USE_PF) || defined(USE_NETFILTER)
 	return delete_pinhole(uid);
 #else
@@ -297,6 +388,18 @@ upnp_delete_inboundpinhole(unsigned shor
 
 	return -1;
 #endif
+#else
+//if QCMAP is defined
+struct pinhole_t * p;
+
+p = get_pinhole(uid);
+if(!p)
+  return -2;
+return DeleteFirewallEntryWrapper(p->qcmap_handle);
+LIST_REMOVE(p, entries);
+#endif
+
+
 }
 
 #if 0
diff --git a/upnpredirect.c b/upnpredirect.c
index 28560ab..fc29e92 100755
--- a/upnpredirect.c
+++ b/upnpredirect.c
@@ -43,6 +43,9 @@
 #ifdef ENABLE_LEASEFILE
 #include <sys/stat.h>
 #endif
+#ifdef QCMAP
+#include "netfilter/iptcrdr.c"
+#endif
 
 /* from <inttypes.h> */
 #ifndef PRIu64
@@ -256,7 +259,11 @@ int reload_from_lease_file()
  *          -3 permission check failed
  */
 int
+#ifndef QCMAP
 upnp_redirect(const char * rhost, unsigned short eport,
+#else
+upnp_redirect(/*const char * rhost,*/unsigned short eport,
+#endif
               const char * iaddr, unsigned short iport,
               const char * protocol, const char * desc,
               unsigned int leaseduration)
@@ -279,6 +286,7 @@ upnp_redirect(const char * rhost, unsign
 		                 "%hu->%s:%hu %s", eport, iaddr, iport, protocol);
 		return -3;
 	}
+#ifndef QCMAP
 	r = get_redirect_rule(ext_if_name, eport, proto,
 	                      iaddr_old, sizeof(iaddr_old), &iport_old, 0, 0,
 	                      0, 0,
@@ -302,32 +310,44 @@ upnp_redirect(const char * rhost, unsign
 		return -2;
 #endif /* CHECK_PORTINUSE */
 	} else {
+#endif
 		timestamp = (leaseduration > 0) ? time(NULL) + leaseduration : 0;
 		syslog(LOG_INFO, "redirecting port %hu to %s:%hu protocol %s for: %s",
 			eport, iaddr, iport, protocol, desc);
+#ifdef QCMAP
+	return upnp_redirect_internal(eport, iaddr, iport, proto, desc, timestamp);
+#else
 		return upnp_redirect_internal(rhost, eport, iaddr, iport, proto,
 		                              desc, timestamp);
 	}
+#endif
 
 	return 0;
 }
 
 int
-upnp_redirect_internal(const char * rhost, unsigned short eport,
+upnp_redirect_internal(
+#ifndef QCMAP
+                       const char * rhost,
+#endif
+                       unsigned short eport,
                        const char * iaddr, unsigned short iport,
                        int proto, const char * desc,
                        unsigned int timestamp)
 {
+#ifndef QCMAP
 	/*syslog(LOG_INFO, "redirecting port %hu to %s:%hu protocol %s for: %s",
 		eport, iaddr, iport, protocol, desc);			*/
 	if(add_redirect_rule2(ext_if_name, rhost, eport, iaddr, iport, proto,
 	                      desc, timestamp) < 0) {
 		return -1;
 	}
+#endif
 
 #ifdef ENABLE_LEASEFILE
 	lease_file_add( eport, iaddr, iport, proto, desc, timestamp);
 #endif
+#ifndef QCMAP
 /*	syslog(LOG_INFO, "creating pass rule to %s:%hu protocol %s for: %s",
 		iaddr, iport, protocol, desc);*/
 	if(add_filter_rule2(ext_if_name, rhost, iaddr, eport, iport, proto, desc) < 0) {
@@ -335,8 +355,21 @@ upnp_redirect_internal(const char * rhos
 #if !defined(__linux__)
 		delete_redirect_rule(ext_if_name, eport, proto);
 #endif
+#else
+	struct in_addr address;
+
+	if(inet_aton(iaddr, &address) < 0) {
+		syslog(LOG_ERR, "inet_aton(%s) : %m", iaddr);
+		return -1;
+	}
+        if(addStaticNatEntry_wrapper(address, proto, iport, eport) < 0)
+                return -1;
+	add_redirect_desc(eport, proto, desc, timestamp);
+#endif
+#ifndef QCMAP
 		return -1;
 	}
+#endif
 	if(timestamp > 0) {
 		if(!nextruletoclean_timestamp || (timestamp < nextruletoclean_timestamp))
 			nextruletoclean_timestamp = timestamp;
@@ -368,17 +401,30 @@ upnp_get_redirection_infos(unsigned shor
 		desc[0] = '\0';
 	if(rhost && (rhostlen > 0))
 		rhost[0] = '\0';
+#ifndef QCMAP
 	r = get_redirect_rule(ext_if_name, eport, proto_atoi(protocol),
 	                      iaddr, iaddrlen, iport, desc, desclen,
 	                      rhost, rhostlen, &timestamp,
 	                      0, 0);
 	if(r == 0 &&
 	   timestamp > 0 &&
+#else
+	r = getSpecificEntry( eport, proto_atoi(protocol),
+	                      iaddr, iaddrlen, iport,
+	                      rhost, rhostlen, &timestamp);
+	if (r == 0) {
+		get_redirect_desc(eport, proto_atoi(protocol), desc, desclen, &timestamp);
+
+		if(timestamp > 0 &&
+#endif
 	   timestamp > (unsigned int)(current_time = time(NULL))) {
 		*leaseduration = timestamp - current_time;
 	} else {
 		*leaseduration = 0;
 	}
+#ifdef QCMAP
+        }
+#endif
 	return r;
 }
 
@@ -400,13 +446,20 @@ upnp_get_redirection_infos_by_index(int
 		desc[0] = '\0';
 	if(rhost && (rhostlen > 0))
 		rhost[0] = '\0';
+#ifndef QCMAP
 	if(get_redirect_rule_by_index(index, 0/*ifname*/, eport, iaddr, iaddrlen,
 	                              iport, &proto, desc, desclen,
 	                              rhost, rhostlen, &timestamp,
 	                              0, 0) < 0)
+#else
+	if (getStaticNatConfigByEntry(index, iaddr, iaddrlen, eport, iport, &proto) < 0)
+#endif
 		return -1;
 	else
 	{
+#ifdef QCMAP
+		get_redirect_desc(*eport, proto, desc, desclen, &timestamp);
+#endif
 		current_time = time(NULL);
 		*leaseduration = (timestamp > (unsigned int)current_time)
 		                 ? (timestamp - current_time)
@@ -425,7 +478,11 @@ _upnp_delete_redir(unsigned short eport,
 {
 	int r;
 #if defined(__linux__)
+#ifndef QCMAP
 	r = delete_redirect_and_filter_rules(eport, proto);
+#else
+	r = deleteStaticNatEntry_wrapper( eport, proto);
+#endif
 #elif defined(USE_PF)
 	r = delete_redirect_and_filter_rules(ext_if_name, eport, proto);
 #else
@@ -439,6 +496,10 @@ _upnp_delete_redir(unsigned short eport,
 #ifdef ENABLE_EVENTS
 	upnp_event_var_change_notify(EWanIPC);
 #endif
+#ifdef QCMAP
+	if ( r >= 0 )
+		del_redirect_desc(eport, proto);
+#endif
 	return r;
 }
 
@@ -491,11 +552,18 @@ get_upnp_rules_state_list(int max_rules_
 		return 0;
 	current_time = time(NULL);
 	nextruletoclean_timestamp = 0;
+#ifndef QCMAP
 	while(get_redirect_rule_by_index(i, /*ifname*/0, &tmp->eport, 0, 0,
 	                              &iport, &proto, 0, 0, 0,0, &timestamp,
 								  &tmp->packets, &tmp->bytes) >= 0)
+#else
+	while(getStaticNatConfigByEntry(i, 0, 0, &tmp->eport, &iport, &proto) >= 0)
+#endif
 	{
 		tmp->to:remove = 0;
+#ifdef QCMAP
+		get_redirect_desc(tmp->eport, proto, 0, 0, &timestamp);
+#endif
 		if(timestamp > 0) {
 			/* need to remove this port mapping ? */
 			if(timestamp <= (unsigned int)current_time)
@@ -582,6 +650,7 @@ remove_unused_rules(struct rule_state *
 	while(list)
 	{
 		/* remove the rule if no traffic has used it */
+#ifndef QCMAP
 		if(get_redirect_rule(ifname, list->eport, list->proto,
 	                         0, 0, &iport, 0, 0, 0, 0, &timestamp,
 		                     &packets, &bytes) >= 0)
@@ -592,6 +661,7 @@ remove_unused_rules(struct rule_state *
 				n++;
 			}
 		}
+#endif
 		tmp = list;
 		list = tmp->next;
 		free(tmp);
@@ -604,16 +674,22 @@ remove_unused_rules(struct rule_state *
  * return a list of all "external" ports for which a port
  * mapping exists */
 unsigned short *
-upnp_get_portmappings_in_range(unsigned short startport,
+upnp_get_portmappings_in_range(
+                               unsigned short startport,
                                unsigned short endport,
                                const char * protocol,
-                               unsigned int * number)
+                               unsigned int *number)
 {
+      unsigned int * entries;
 	int proto;
 	proto = proto_atoi(protocol);
 	if(!number)
 		return NULL;
+#ifndef QCMAP
 	return get_portmappings_in_range(startport, endport, proto, number);
+#else
+	return getPortMappingsWrapper(startport,endport,proto, number);
+#endif
 }
 
 /* stuff for miniupnpdctl */
diff --git a/upnpredirect.h b/upnpredirect.h
index b549824..311abba 100755
--- a/upnpredirect.h
+++ b/upnpredirect.h
@@ -26,7 +26,11 @@ int reload_from_lease_file(void);
  *          -3 permission check failed
  */
 int
-upnp_redirect(const char * rhost, unsigned short eport,
+upnp_redirect(
+#ifndef QCMAP
+              const char * rhost,
+#endif
+              unsigned short eport,
               const char * iaddr, unsigned short iport,
               const char * protocol, const char * desc,
               unsigned int leaseduration);
@@ -34,7 +38,11 @@ upnp_redirect(const char * rhost, unsign
 /* upnp_redirect_internal()
  * same as upnp_redirect() without any check */
 int
-upnp_redirect_internal(const char * rhost, unsigned short eport,
+upnp_redirect_internal(
+#ifndef QCMAP
+                       const char * rhost,
+#endif
+                       unsigned short eport,
                        const char * iaddr, unsigned short iport,
                        int proto, const char * desc,
                        unsigned int timestamp);
@@ -103,7 +111,8 @@ remove_unused_rules(struct rule_state *
  * return a list of all "external" ports for which a port
  * mapping exists */
 unsigned short *
-upnp_get_portmappings_in_range(unsigned short startport,
+upnp_get_portmappings_in_range(
+                               unsigned short startport,
                                unsigned short endport,
                                const char * protocol,
                                unsigned int * number);
 
diff --git a/upnpsoap.c b/upnpsoap.c
index e8db166..23cc09a 100755
--- a/upnpsoap.c
+++ b/upnpsoap.c
@@ -65,21 +65,32 @@ BuildSendAndCloseSoapResp(struct upnphtt
 }
 
 static void
-GetConnectionTypeInfo(struct upnphttp * h, const char * action)
+GetConnectionTypeInfo(struct upnphttp * h, const char * action, const char * ns)
 {
+#if 0
 	static const char resp[] =
 		"<u:GetConnectionTypeInfoResponse "
 		"xmlns:u=\"" SERVICE_TYPE_WANIPC "\">"
 		"<NewConnectionType>IP_Routed</NewConnectionType>"
 		"<NewPossibleConnectionTypes>IP_Routed</NewPossibleConnectionTypes>"
 		"</u:GetConnectionTypeInfoResponse>";
-	UNUSED(action);
+#endif
+	static const char resp[] =
+		"<u:%sResponse "
+		"xmlns:u=\"%s\">"
+		"<NewConnectionType>IP_Routed</NewConnectionType>"
+		"<NewPossibleConnectionTypes>IP_Routed</NewPossibleConnectionTypes>"
+		"</u:%sResponse>";
+	char body[512];
+	int bodylen;
 
-	BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1);
+	bodylen = snprintf(body, sizeof(body), resp,
+	         action, ns, action);
+	BuildSendAndCloseSoapResp(h, body, bodylen);
 }
 
 static void
-GetTotalBytesSent(struct upnphttp * h, const char * action)
+GetTotalBytesSent(struct upnphttp * h, const char * action, const char * ns)
 {
 	int r;
 
@@ -92,16 +103,19 @@ GetTotalBytesSent(struct upnphttp * h, c
 	char body[512];
 	int bodylen;
 	struct ifdata data;
-
+#ifndef QCMAP
 	r = getifstats(ext_if_name, &data);
+#else
+	r = getIfaceStats(&data);
+#endif
 	bodylen = snprintf(body, sizeof(body), resp,
-	         action, "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1",
+	         action, ns,
              r<0?0:data.obytes, action);
 	BuildSendAndCloseSoapResp(h, body, bodylen);
 }
 
 static void
-GetTotalBytesReceived(struct upnphttp * h, const char * action)
+GetTotalBytesReceived(struct upnphttp * h, const char * action, const char * ns)
 {
 	int r;
 
@@ -114,16 +128,19 @@ GetTotalBytesReceived(struct upnphttp *
 	char body[512];
 	int bodylen;
 	struct ifdata data;
-
+#ifndef QCMAP
 	r = getifstats(ext_if_name, &data);
+#else
+	r = getIfaceStats(&data);
+#endif
 	bodylen = snprintf(body, sizeof(body), resp,
-	         action, "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1",
+	         action, ns,
 	         r<0?0:data.ibytes, action);
 	BuildSendAndCloseSoapResp(h, body, bodylen);
 }
 
 static void
-GetTotalPacketsSent(struct upnphttp * h, const char * action)
+GetTotalPacketsSent(struct upnphttp * h, const char * action, const char * ns)
 {
 	int r;
 
@@ -136,16 +153,19 @@ GetTotalPacketsSent(struct upnphttp * h,
 	char body[512];
 	int bodylen;
 	struct ifdata data;
-
+#ifndef QCMAP
 	r = getifstats(ext_if_name, &data);
+#else
+	r = getIfaceStats(&data);
+#endif
 	bodylen = snprintf(body, sizeof(body), resp,
-	         action, "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1",
+	         action, ns,/*"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1",*/
 	         r<0?0:data.opackets, action);
 	BuildSendAndCloseSoapResp(h, body, bodylen);
 }
 
 static void
-GetTotalPacketsReceived(struct upnphttp * h, const char * action)
+GetTotalPacketsReceived(struct upnphttp * h, const char * action, const char * ns)
 {
 	int r;
 
@@ -158,16 +178,19 @@ GetTotalPacketsReceived(struct upnphttp
 	char body[512];
 	int bodylen;
 	struct ifdata data;
-
+#ifndef QCMAP
 	r = getifstats(ext_if_name, &data);
+#else
+	r = getIfaceStats(&data);
+#endif
 	bodylen = snprintf(body, sizeof(body), resp,
-	         action, "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1",
+	         action, ns,
 	         r<0?0:data.ipackets, action);
 	BuildSendAndCloseSoapResp(h, body, bodylen);
 }
 
 static void
-GetCommonLinkProperties(struct upnphttp * h, const char * action)
+GetCommonLinkProperties(struct upnphttp * h, const char * action, const char * ns)
 {
 	/* WANAccessType : set depending on the hardware :
 	 * DSL, POTS (plain old Telephone service), Cable, Ethernet */
@@ -188,6 +211,7 @@ GetCommonLinkProperties(struct upnphttp
 	const char * wan_access_type = "Cable"; /* DSL, POTS, Cable, Ethernet */
 	char ext_ip_addr[INET_ADDRSTRLEN];
 
+#ifndef QCMAP
 	if((downstream_bitrate == 0) || (upstream_bitrate == 0))
 	{
 		if(getifstats(ext_if_name, &data) >= 0)
@@ -197,10 +221,23 @@ GetCommonLinkProperties(struct upnphttp
 		}
 	}
 	if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, NULL, NULL) < 0) {
+#else
+	if(getIfaceStats(&data) >= 0)
+	{
+		downstream_bitrate = data.downstream_bitrate;
+		upstream_bitrate = data.upstream_bitrate;
+	}
+	else
+	{
+		downstream_bitrate = 0;
+		upstream_bitrate = 0;
+	}
+	if(getIPAddr(ext_ip_addr, INET_ADDRSTRLEN) < 0) {
+#endif
 		status = "Down";
 	}
 	bodylen = snprintf(body, sizeof(body), resp,
-	    action, "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1",
+	    action, ns,
 	    wan_access_type,
 	    upstream_bitrate, downstream_bitrate,
 	    status, action);
@@ -208,7 +245,7 @@ GetCommonLinkProperties(struct upnphttp
 }
 
 static void
-GetStatusInfo(struct upnphttp * h, const char * action)
+GetStatusInfo(struct upnphttp * h, const char * action, const char * ns)
 {
 	static const char resp[] =
 		"<u:%sResponse "
@@ -225,25 +262,42 @@ GetStatusInfo(struct upnphttp * h, const
 	/* ConnectionStatus possible values :
 	 * Unconfigured, Connecting, Connected, PendingDisconnect,
 	 * Disconnecting, Disconnected */
-
+#ifndef QCMAP
 	status = get_wan_connection_status_str(ext_if_name);
+#else
+	status = getWanStatusStr();
+#endif
 	uptime = (time(NULL) - startup_time);
 	bodylen = snprintf(body, sizeof(body), resp,
-		action, SERVICE_TYPE_WANIPC,
+		action, ns, /*SERVICE_TYPE_WANIPC,*/
 		status, (long)uptime, action);
 	BuildSendAndCloseSoapResp(h, body, bodylen);
 }
 
 static void
-GetNATRSIPStatus(struct upnphttp * h, const char * action)
+GetNATRSIPStatus(struct upnphttp * h, const char * action, const char * ns)
 {
-	static const char resp[] =
-		"<u:GetNATRSIPStatusResponse "
-		"xmlns:u=\"" SERVICE_TYPE_WANIPC "\">"
-		"<NewRSIPAvailable>0</NewRSIPAvailable>"
-		"<NewNATEnabled>1</NewNATEnabled>"
-		"</u:GetNATRSIPStatusResponse>";
-	UNUSED(action);
+	char body[512];
+		int bodylen;
+#if 0
+		static const char resp[] =
+			"<u:GetNATRSIPStatusResponse "
+			"xmlns:u=\"" SERVICE_TYPE_WANIPC "\">"
+			"<NewRSIPAvailable>0</NewRSIPAvailable>"
+			"<NewNATEnabled>1</NewNATEnabled>"
+			"</u:GetNATRSIPStatusResponse>";
+#endif
+		static const char resp[] =
+			"<u:%sResponse "
+			"xmlns:u=\"%s\">"
+			"<NewRSIPAvailable>0</NewRSIPAvailable>"
+			"<NewNATEnabled>1</NewNATEnabled>"
+			"</u:GetNATRSIPStatusResponse>";
+
+		bodylen = snprintf(body, sizeof(body), resp,
+						action, ns, action);
+		BuildSendAndCloseSoapResp(h, body, bodylen);
+
 	/* 2.2.9. RSIPAvailable
 	 * This variable indicates if Realm-specific IP (RSIP) is available
 	 * as a feature on the InternetGatewayDevice. RSIP is being defined
@@ -252,11 +306,11 @@ GetNATRSIPStatus(struct upnphttp * h, co
 	 * applications that otherwise break if NAT is introduced
 	 * (e.g. IPsec-based VPNs).
 	 * A gateway that does not support RSIP should set this variable to 0. */
-	BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1);
+//	BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1);
 }
 
 static void
-GetExternalIPAddress(struct upnphttp * h, const char * action)
+GetExternalIPAddress(struct upnphttp * h, const char * action, const char * ns)
 {
 	static const char resp[] =
 		"<u:%sResponse "
@@ -275,10 +329,16 @@ GetExternalIPAddress(struct upnphttp * h
 	{
 		strncpy(ext_ip_addr, use_ext_ip_addr, INET_ADDRSTRLEN);
 	}
+#ifndef QCMAP
 	else if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, NULL, NULL) < 0)
 	{
 		syslog(LOG_ERR, "Failed to get ip address for interface %s",
 			ext_if_name);
+#else
+	else if(getIPAddr(ext_ip_addr, INET_ADDRSTRLEN) < 0)
+	{
+		syslog(LOG_ERR, "Failed to get ip address for interface");
+#endif
 		strncpy(ext_ip_addr, "0.0.0.0", INET_ADDRSTRLEN);
 	}
 #else
@@ -295,7 +355,7 @@ GetExternalIPAddress(struct upnphttp * h
 	}
 #endif
 	bodylen = snprintf(body, sizeof(body), resp,
-	              action, SERVICE_TYPE_WANIPC,
+	              action, ns, /*SERVICE_TYPE_WANIPC,*/
 				  ext_ip_addr, action);
 	BuildSendAndCloseSoapResp(h, body, bodylen);
 }
@@ -303,7 +363,7 @@ GetExternalIPAddress(struct upnphttp * h
 /* AddPortMapping method of WANIPConnection Service
  * Ignored argument : NewEnabled */
 static void
-AddPortMapping(struct upnphttp * h, const char * action)
+AddPortMapping(struct upnphttp * h, const char * action, const char * ns)
 {
 	int r;
 
@@ -314,7 +374,7 @@ AddPortMapping(struct upnphttp * h, cons
 	struct NameValueParserData data;
 	char * int_ip, * int_port, * ext_port, * protocol, * desc;
 	char * leaseduration_str;
-	unsigned int leaseduration;
+	unsigned int leaseduration,proto;
 	char * r_host;
 	unsigned short iport, eport;
 
@@ -386,14 +446,20 @@ AddPortMapping(struct upnphttp * h, cons
 	protocol = GetValueFromNameValueList(&data, "NewProtocol");
 	desc = GetValueFromNameValueList(&data, "NewPortMappingDescription");
 	leaseduration_str = GetValueFromNameValueList(&data, "NewLeaseDuration");
-
-	if (!int_port || !ext_port || !protocol)
+	if (!int_port || !ext_port || !protocol )
 	{
 		ClearNameValueList(&data);
 		SoapError(h, 402, "Invalid Args");
 		return;
 	}
 
+	if  ((strcmp(protocol, "UDP") != 0) && (strcmp(protocol, "TCP") != 0))
+	{
+		ClearNameValueList(&data);
+		SoapError(h, 601, "Arguments out of range");
+		return;
+	}
+
 	eport = (unsigned short)atoi(ext_port);
 	iport = (unsigned short)atoi(int_port);
 
@@ -423,7 +489,11 @@ AddPortMapping(struct upnphttp * h, cons
 	PortMappingDescription, PortMappingEnabled and PortMappingLeaseDuration are
 	overwritten.
 	*/
-	r = upnp_redirect(r_host, eport, int_ip, iport, protocol, desc, leaseduration);
+	r = upnp_redirect(
+#ifndef QCMAP
+                          r_host,
+#endif
+                          eport, int_ip, iport, protocol, desc, leaseduration);
 
 	ClearNameValueList(&data);
 
@@ -463,7 +533,7 @@ AddPortMapping(struct upnphttp * h, cons
 
 /* AddAnyPortMapping was added in WANIPConnection v2 */
 static void
-AddAnyPortMapping(struct upnphttp * h, const char * action)
+AddAnyPortMapping(struct upnphttp * h, const char * action, const char * ns)
 {
 	int r;
 	static const char resp[] =
@@ -478,7 +548,7 @@ AddAnyPortMapping(struct upnphttp * h, c
 	struct NameValueParserData data;
 	const char * int_ip, * int_port, * ext_port, * protocol, * desc;
 	const char * r_host;
-	unsigned short iport, eport;
+	unsigned short iport, eport,proto;
 	const char * leaseduration_str;
 	unsigned int leaseduration;
 
@@ -499,13 +569,18 @@ AddAnyPortMapping(struct upnphttp * h, c
 	leaseduration = leaseduration_str ? atoi(leaseduration_str) : 0;
 	if(leaseduration == 0)
 		leaseduration = 604800;
-
-	if (!int_ip || !ext_port || !int_port)
+	if (!int_ip || !ext_port || !int_port || !protocol )
 	{
 		ClearNameValueList(&data);
 		SoapError(h, 402, "Invalid Args");
 		return;
 	}
+	if  ((strcmp(protocol, "UDP") != 0) && (strcmp(protocol, "TCP") != 0))
+	{
+		ClearNameValueList(&data);
+		SoapError(h, 601, "Arguments out of range");
+		return;
+	}
 
 	eport = (unsigned short)atoi(ext_port);
 	iport = (unsigned short)atoi(int_port);
@@ -559,7 +634,11 @@ AddAnyPortMapping(struct upnphttp * h, c
 	/* TODO : accept a different external port
 	 * have some smart strategy to choose the port */
 	for(;;) {
-		r = upnp_redirect(r_host, eport, int_ip, iport, protocol, desc, leaseduration);
+	                  r = upnp_redirect(
+#ifndef QCMAP
+                          r_host,
+#endif
+                          eport, int_ip, iport, protocol, desc, leaseduration);
 		if(r==-2 && eport < 65535) {
 			eport++;
 		} else {
@@ -573,7 +652,7 @@ AddAnyPortMapping(struct upnphttp * h, c
 	{
 	case 0:	/* success */
 		bodylen = snprintf(body, sizeof(body), resp,
-		              action, SERVICE_TYPE_WANIPC,
+		              action, ns, /*SERVICE_TYPE_WANIPC,*/
 					  eport, action);
 		BuildSendAndCloseSoapResp(h, body, bodylen);
 		break;
@@ -589,7 +668,7 @@ AddAnyPortMapping(struct upnphttp * h, c
 }
 
 static void
-GetSpecificPortMappingEntry(struct upnphttp * h, const char * action)
+GetSpecificPortMappingEntry(struct upnphttp * h, const char * action, const char * ns)
 {
 	int r;
 
@@ -671,7 +750,7 @@ GetSpecificPortMappingEntry(struct upnph
 }
 
 static void
-DeletePortMapping(struct upnphttp * h, const char * action)
+DeletePortMapping(struct upnphttp * h, const char * action, const char * ns)
 {
 	int r;
 
@@ -704,6 +783,12 @@ DeletePortMapping(struct upnphttp * h, c
 		SoapError(h, 402, "Invalid Args");
 		return;
 	}
+	if  ((strcmp(protocol, "UDP") != 0) && (strcmp(protocol, "TCP") != 0))
+	{
+		ClearNameValueList(&data);
+		SoapError(h, 601, "Arguments out of range");
+		return;
+	}
 #ifndef SUPPORT_REMOTEHOST
 #ifdef UPNP_STRICT
 	if (r_host && (strlen(r_host) > 0) && (0 != strcmp(r_host, "*")))
@@ -765,7 +850,7 @@ DeletePortMapping(struct upnphttp * h, c
 
 /* DeletePortMappingRange was added in IGD spec v2 */
 static void
-DeletePortMappingRange(struct upnphttp * h, const char * action)
+DeletePortMappingRange(struct upnphttp * h, const char * action, const char * ns)
 {
 	int r = -1;
 	static const char resp[] =
@@ -777,6 +862,7 @@ DeletePortMappingRange(struct upnphttp *
 	const char * startport_s, * endport_s;
 	unsigned short startport, endport;
 	/*int manage;*/
+	int proto;
 	unsigned short * port_list;
 	unsigned int i, number = 0;
 	UNUSED(action);
@@ -786,7 +872,7 @@ DeletePortMappingRange(struct upnphttp *
 	endport_s = GetValueFromNameValueList(&data, "NewEndPort");
 	protocol = GetValueFromNameValueList(&data, "NewProtocol");
 	/*manage = atoi(GetValueFromNameValueList(&data, "NewManage"));*/
-	if(startport_s == NULL || endport_s == NULL || protocol == NULL) {
+	if(startport_s == NULL || endport_s == NULL || protocol == NULL ) {
 		SoapError(h, 402, "Invalid Args");
 		ClearNameValueList(&data);
 		return;
@@ -806,10 +892,19 @@ DeletePortMappingRange(struct upnphttp *
 		return;
 	}
 
-	syslog(LOG_INFO, "%s: deleting external ports: %hu-%hu, protocol: %s",
+	if  ((strcmp(protocol, "UDP") != 0) && (strcmp(protocol, "TCP") != 0))
+	{
+		ClearNameValueList(&data);
+		SoapError(h, 601, "Arguments out of range");
+		return;
+	}
+
+	syslog(LOG_INFO, "%s: deleting external ports: %hu-%hu, protocol: %s\n",
 	       action, startport, endport, protocol);
 
-	port_list = upnp_get_portmappings_in_range(startport, endport,
+	port_list = upnp_get_portmappings_in_range(
+
+                                                   startport, endport,
 	                                           protocol, &number);
 	if(number == 0)
 	{
@@ -820,7 +915,7 @@ DeletePortMappingRange(struct upnphttp *
 
 	for(i = 0; i < number; i++)
 	{
-		r = upnp_delete_redirection(port_list[i], protocol);
+	    r = upnp_delete_redirection(port_list[i], protocol);
 		syslog(LOG_INFO, "%s: deleting external port: %hu, protocol: %s: %s",
 		       action, port_list[i], protocol, r < 0 ? "failed" : "ok");
 	}
@@ -831,7 +926,7 @@ DeletePortMappingRange(struct upnphttp *
 }
 
 static void
-GetGenericPortMappingEntry(struct upnphttp * h, const char * action)
+GetGenericPortMappingEntry(struct upnphttp * h, const char * action, const char * ns)
 {
 	int r;
 
@@ -902,7 +997,7 @@ GetGenericPortMappingEntry(struct upnpht
 		int bodylen;
 		char body[2048];
 		bodylen = snprintf(body, sizeof(body), resp,
-			action, SERVICE_TYPE_WANIPC, rhost,
+			action, ns, /*SERVICE_TYPE_WANIPC,*/ rhost,
 			(unsigned int)eport, protocol, (unsigned int)iport, iaddr, desc,
 		    leaseduration, action);
 		BuildSendAndCloseSoapResp(h, body, bodylen);
@@ -913,7 +1008,7 @@ GetGenericPortMappingEntry(struct upnpht
 
 /* GetListOfPortMappings was added in the IGD v2 specification */
 static void
-GetListOfPortMappings(struct upnphttp * h, const char * action)
+GetListOfPortMappings(struct upnphttp * h, const char * action, const char * ns)
 {
 	static const char resp_start[] =
 		"<u:%sResponse "
@@ -960,8 +1055,8 @@ GetListOfPortMappings(struct upnphttp *
 	const char * protocol;
 	/*int manage;*/
 	const char * number_s;
-	int number;
-	unsigned short * port_list;
+	int number,proto;
+	unsigned short *port_list;
 	unsigned int i, list_size = 0;
 
 	ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data);
@@ -981,8 +1076,12 @@ GetListOfPortMappings(struct upnphttp *
 	endport = (unsigned short)atoi(endport_s);
 	/*manage = atoi(manage_s);*/
 	number = atoi(number_s);
+	if(!startport && !endport) {
+		SoapError(h, 402, "Invalid Args");
+		ClearNameValueList(&data);
+		return;
+	}
 	if(number == 0) number = 1000;	/* return up to 1000 mappings by default */
-
 	if(startport > endport)
 	{
 		SoapError(h, 733, "InconsistentParameter");
@@ -1017,7 +1116,7 @@ http://www.upnp.org/schemas/gw/WANIPConn
 		return;
 	}
 	bodylen = snprintf(body, bodyalloc, resp_start,
-	              action, SERVICE_TYPE_WANIPC);
+	              action, ns/*SERVICE_TYPE_WANIPC*/);
 	if(bodylen < 0)
 	{
 		SoapError(h, 501, "ActionFailed");
@@ -1027,10 +1126,11 @@ http://www.upnp.org/schemas/gw/WANIPConn
 	memcpy(body+bodylen, list_start, sizeof(list_start));
 	bodylen += (sizeof(list_start) - 1);
 
-	port_list = upnp_get_portmappings_in_range(startport, endport,
+	port_list = upnp_get_portmappings_in_range(
+                                                   startport, endport,
 	                                           protocol, &list_size);
 	/* loop through port mappings */
-	for(i = 0; number > 0 && i < list_size; i++)
+		for(i = 0; number > 0 && i < list_size; i++)
 	{
 		/* have a margin of 1024 bytes to store the new entry */
 		if((unsigned int)bodylen + 1024 > bodyalloc)
@@ -1091,8 +1191,10 @@ http://www.upnp.org/schemas/gw/WANIPConn
 
 #ifdef ENABLE_L3F_SERVICE
 static void
-SetDefaultConnectionService(struct upnphttp * h, const char * action)
+SetDefaultConnectionService(struct upnphttp * h, const char * action, const char * ns)
 {
+	char body[1024];
+	int bodylen;
 	static const char resp[] =
 		"<u:SetDefaultConnectionServiceResponse "
 		"xmlns:u=\"urn:schemas-upnp-org:service:Layer3Forwarding:1\">"
@@ -1116,6 +1218,9 @@ SetDefaultConnectionService(struct upnph
 #endif
 		{
 			syslog(LOG_INFO, "%s(%s) : Ignored", action, p);
+/*			bodylen = snprintf(body, sizeof(body), resp,
+							action, ns, uuidvalue_wcd, action);
+			BuildSendAndCloseSoapResp(h, body, bodylen);*/
 			BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1);
 		}
 	} else {
@@ -1126,12 +1231,16 @@ SetDefaultConnectionService(struct upnph
 }
 
 static void
-GetDefaultConnectionService(struct upnphttp * h, const char * action)
+GetDefaultConnectionService(struct upnphttp * h, const char * action, const char * ns)
 {
 	static const char resp[] =
 		"<u:%sResponse "
-		"xmlns:u=\"urn:schemas-upnp-org:service:Layer3Forwarding:1\">"
+		"xmlns:u=\"%s\">"
+#ifdef IGD_V2
+		"<NewDefaultConnectionService>%s:WANConnectionDevice:2,"
+#else
 		"<NewDefaultConnectionService>%s:WANConnectionDevice:1,"
+#endif
 		SERVICE_ID_WANIPC "</NewDefaultConnectionService>"
 		"</u:%sResponse>";
 	/* example from UPnP_IGD_Layer3Forwarding 1.0.pdf :
@@ -1139,22 +1248,22 @@ GetDefaultConnectionService(struct upnph
 	 * urn:upnp-org:serviceId:WANPPPConn1 */
 	char body[1024];
 	int bodylen;
-
 	bodylen = snprintf(body, sizeof(body), resp,
-	                   action, uuidvalue_wcd, action);
+	                   action, ns, uuidvalue_wcd, action);
 	BuildSendAndCloseSoapResp(h, body, bodylen);
 }
 #endif
 
 /* Added for compliance with WANIPConnection v2 */
 static void
-SetConnectionType(struct upnphttp * h, const char * action)
+SetConnectionType(struct upnphttp * h, const char * action, const char * ns)
 {
 #ifdef UPNP_STRICT
 	const char * connection_type;
 #endif /* UPNP_STRICT */
 	struct NameValueParserData data;
 	UNUSED(action);
+	UNUSED(ns);
 
 	ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data);
 #ifdef UPNP_STRICT
@@ -1173,18 +1282,92 @@ SetConnectionType(struct upnphttp * h, c
 
 /* Added for compliance with WANIPConnection v2 */
 static void
-RequestConnection(struct upnphttp * h, const char * action)
+RequestConnection(struct upnphttp * h, const char * action, const char * ns)
 {
+
+	char body[512];
+	int bodylen;
+#ifndef QCMAP
 	UNUSED(action);
+	UNUSED(ns);
 	SoapError(h, 606, "Action not authorized");
+#else
+	#if 0
+	static const char resp[] =
+		"<u:RequestConnectionResponse "
+		"xmlns:u=\"" SERVICE_TYPE_WANIPC "\">"
+		"</u:RequestConnectionResponse>";*/
+#endif
+	static const char resp[] =
+			"<u:%sResponse "
+			"xmlns:u=\"%s\">"
+			"</u:%sResponse>";
+
+	if(getWanStatus() == 1)/* Connecting */
+	{
+		SoapError(h, 705, "ConnectionSetupInProgress");
+		return;
+	}
+	if(getWanStatus() == 4)/* Disconnecting */
+	{
+		SoapError(h, 707, "DisconnectInProgress");
+		return;
+	}
+	if(startConnection() < 0) {
+		SoapError(h, 501, "Action Failed");
+		return;
+	}
+	bodylen = snprintf(body, sizeof(body), resp,
+					 action, ns, action);
+	BuildSendAndCloseSoapResp(h, body, bodylen);
+
+	//BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1);
+#endif
 }
 
 /* Added for compliance with WANIPConnection v2 */
 static void
-ForceTermination(struct upnphttp * h, const char * action)
+ForceTermination(struct upnphttp * h, const char * action, const char * ns)
 {
+
+	char body[512];
+	int bodylen;
+#ifndef QCMAP
 	UNUSED(action);
+	UNUSED(ns);
 	SoapError(h, 606, "Action not authorized");
+#else
+	#if 0
+	static const char resp[] =
+		"<u:RequestConnectionResponse "
+		"xmlns:u=\"" SERVICE_TYPE_WANIPC "\">"
+		"</u:RequestConnectionResponse>";*/
+	#endif
+	static const char resp[] =
+			"<u:%sResponse "
+			"xmlns:u=\"%s\">"
+			"</u:%sResponse>";
+
+	if(getWanStatus() == 4)/* Disconnecting */
+	{
+		SoapError(h, 707, "DisconnectInProgress");
+		return;
+	}
+	if(getWanStatus() == 5)/* Disconnected */
+	{
+		SoapError(h, 711, "ConnectionAlreadyTerminated");
+		return;
+	}
+	if(stopConnection() < 0) {
+		SoapError(h, 501, "Action Failed");
+		return;
+	}
+	bodylen = snprintf(body, sizeof(body), resp,
+					action, ns, action);
+	BuildSendAndCloseSoapResp(h, body, bodylen);
+
+//	BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1);
+#endif
 }
 
 /*
@@ -1196,7 +1379,7 @@ QueryStateVariable remains useful as a l
 part of some future versions of UPnP.
 */
 static void
-QueryStateVariable(struct upnphttp * h, const char * action)
+QueryStateVariable(struct upnphttp * h, const char * action, const char * ns)
 {
 	static const char resp[] =
         "<u:%sResponse "
@@ -1223,10 +1406,13 @@ QueryStateVariable(struct upnphttp * h,
 	else if(strcmp(var_name, "ConnectionStatus") == 0)
 	{
 		const char * status;
-
+#ifndef QCMAP
 		status = get_wan_connection_status_str(ext_if_name);
+#else
+		status = getWanStatusStr();
+#endif
 		bodylen = snprintf(body, sizeof(body), resp,
-                           action, "urn:schemas-upnp-org:control-1-0",
+                           action, ns,/*"urn:schemas-upnp-org:control-1-0",*/
 		                   status, action);
 		BuildSendAndCloseSoapResp(h, body, bodylen);
 	}
@@ -1249,7 +1435,7 @@ QueryStateVariable(struct upnphttp * h,
 		snprintf(strn, sizeof(strn), "%i",
 		         upnp_get_portmapping_number_of_entries());
 		bodylen = snprintf(body, sizeof(body), resp,
-                           action, "urn:schemas-upnp-org:control-1-0",
+                           action, ns,/*"urn:schemas-upnp-org:control-1-0",*/
 		                   strn, action);
 		BuildSendAndCloseSoapResp(h, body, bodylen);
 	}
@@ -1268,7 +1454,7 @@ QueryStateVariable(struct upnphttp * h,
 #endif
 /* WANIPv6FirewallControl actions */
 static void
-GetFirewallStatus(struct upnphttp * h, const char * action)
+GetFirewallStatus(struct upnphttp * h, const char * action, const char * ns)
 {
 	static const char resp[] =
 		"<u:%sResponse "
@@ -1279,12 +1465,22 @@ GetFirewallStatus(struct upnphttp * h, c
 
 	char body[512];
 	int bodylen;
-
+	unsigned short upnp_pinhole_allowed,firewall_enabled;
+#ifndef QCMAP
 	bodylen = snprintf(body, sizeof(body), resp,
-		action, "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1",
-	    GETFLAG(IPV6FCFWDISABLEDMASK) ? 0 : 1,
-	    GETFLAG(IPV6FCINBOUNDDISALLOWEDMASK) ? 0 : 1,
-	    action);
+		action, ns, /*"urn:schemas-upnp-org:service:WANIPv6FirewallControl:1",*/
+		GETFLAG(IPV6FCFWDISABLEDMASK) ? 0 : 1,
+		GETFLAG(IPV6FCINBOUNDDISALLOWEDMASK) ? 0 : 1,
+		action);
+#else
+	//If QCMAP is defined
+	GetFirewallStatusWrapper(&firewall_enabled,&upnp_pinhole_allowed);
+	bodylen = snprintf(body, sizeof(body), resp,
+		action, ns,/*"urn:schemas-upnp-org:service:WANIPv6FirewallControl:1",*/
+		firewall_enabled,
+		upnp_pinhole_allowed,
+		action);
+#endif
 	BuildSendAndCloseSoapResp(h, body, bodylen);
 }
 
@@ -1404,12 +1600,14 @@ PinholeVerification(struct upnphttp * h,
 #ifdef DEBUG
 	printf("\tPinholeVerification:\n\t\tCompare sender @: %s\n\t\t  to intClient @: %s\n", senderAddr, int_ip);
 #endif
+    /* Compare only the IID port. */
 	if(strcmp(senderAddr, int_ip) != 0)
-	if(h->clientaddr_v6.s6_addr != result_ip.s6_addr)
+	if(h->clientaddr_v6.s6_addr32[2] != result_ip.s6_addr32[2] ||
+       h->clientaddr_v6.s6_addr32[3] != result_ip.s6_addr32[3])
 	{
 		syslog(LOG_INFO, "Client %s tried to access pinhole for internal %s and is not authorized to do it",
 		       senderAddr, int_ip);
-		SoapError(h, 606, "Action not authorized");
+		SoapError(h, 606, "Action not authorized tried to access pinhole for internal");
 		return 0;
 	}
 
@@ -1418,7 +1616,7 @@ PinholeVerification(struct upnphttp * h,
 	{
 		syslog(LOG_INFO, "Client %s tried to access pinhole with port < 1024 and is not authorized to do it",
 		       senderAddr);
-		SoapError(h, 606, "Action not authorized");
+		SoapError(h, 606, "Action not authorized port < 1024");
 		return 0;
 	}
 	return 1;
@@ -1562,18 +1760,25 @@ AddPinhole(struct upnphttp * h, const ch
 	{
 		case 1:	        /* success */
 			bodylen = snprintf(body, sizeof(body),
-			                   resp, action,
-			                   "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1",
-			                   uid, action);
+							resp, action,
+							"urn:schemas-upnp-org:service:WANIPv6FirewallControl:1",
+							uid, action);
 			BuildSendAndCloseSoapResp(h, body, bodylen);
 			break;
+
 		case -1: 	/* not permitted */
 			SoapError(h, 701, "PinholeSpaceExhausted");
 			break;
+
+		case -4:
+			SoapError(h, 402, "Invalid Args, Already Present");
+			break;
+
 		default:
-			SoapError(h, 501, "ActionFailed");
+			SoapError(h, 501, "ActionFailed- Add Pinhole");
 			break;
 	}
+
 	/* 606 Action not authorized
 	 * 701 PinholeSpaceExhausted
 	 * 702 FirewallDisabled
@@ -1616,7 +1821,7 @@ UpdatePinhole(struct upnphttp * h, const
 		SoapError(h, 402, "Invalid Args");
 		return;
 	}
-
+    syslog(LOG_INFO, " UID: To BE UPDATED %d",uid);
 	/* Check that client is not updating an pinhole
 	 * it doesn't have access to, because of its public access */
 	n = upnp_get_pinhole_info(uid, NULL, 0, NULL,
@@ -1870,6 +2075,7 @@ GetPinholePackets(struct upnphttp * h, c
 		SoapError(h, 402, "Invalid Args");
 		return;
 	}
+    syslog(LOG_INFO, " UID: To BE UPDATED %d",uid);
 
 	/* Check that client is not getting infos of a pinhole
 	 * it doesn't have access to, because of its public access */
@@ -1883,6 +2089,10 @@ GetPinholePackets(struct upnphttp * h, c
 		if(PinholeVerification(h, iaddr, iport)<=0)
 			return ;
 	}
+    else if(n == -2)
+	   SoapError(h, 704, "NoSuchEntry");
+	else
+		SoapError(h, 501, "ActionFailed");
 #if 0
 	else if(r == -4 || r == -1)
 	{
@@ -2011,7 +2221,7 @@ GetAssignedRoles(struct upnphttp * h, co
 static const struct
 {
 	const char * methodName;
-	void (*methodImpl)(struct upnphttp *, const char *);
+	void (*methodImpl)(struct upnphttp *, const char *, const char *);
 }
 soapMethods[] =
 {
@@ -2048,7 +2258,7 @@ soapMethods[] =
 	{ "GetFirewallStatus", GetFirewallStatus},	/* Required */
 	{ "AddPinhole", AddPinhole},				/* Required */
 	{ "UpdatePinhole", UpdatePinhole},			/* Required */
-	{ "GetOutboundPinholeTimeout", GetOutboundPinholeTimeout},	/* Optional */
+	//{ "GetOutboundPinholeTimeout", GetOutboundPinholeTimeout},	/* Optional */
 	{ "DeletePinhole", DeletePinhole},			/* Required */
 	{ "CheckPinholeWorking", CheckPinholeWorking},	/* Optional */
 	{ "GetPinholePackets", GetPinholePackets},	/* Required */
@@ -2068,11 +2278,15 @@ ExecuteSoapAction(struct upnphttp * h, c
 	char * p;
 	char * p2;
 	int i, len, methodlen;
+	char namespace[256];
 
 	/* SoapAction example :
 	 * urn:schemas-upnp-org:service:WANIPConnection:1#GetStatusInfo */
 	p = strchr(action, '#');
 	if(p && (p - action) < n) {
+		for(i = 0; i < ((int)sizeof(namespace) - 1) && (action + i) < p; i++)
+			namespace[i] = action[i];
+		namespace[i] = '\0';
 		p++;
 		p2 = strchr(p, '"');
 		if(p2 && (p2 - action) <= n)
@@ -2088,7 +2302,7 @@ ExecuteSoapAction(struct upnphttp * h, c
 				syslog(LOG_DEBUG, "Remote Call of SoapMethod '%s'",
 				       soapMethods[i].methodName);
 #endif /* DEBUG */
-				soapMethods[i].methodImpl(h, soapMethods[i].methodName);
+				soapMethods[i].methodImpl(h, soapMethods[i].methodName, namespace);
 				return;
 			}
 		}
diff --git a/upnpdescgen.c b/upnpdescgen.c
index 4f45fbf..bf3f384 100755
--- a/upnpdescgen.c
+++ b/upnpdescgen.c
@@ -8,7 +8,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-
+#include <syslog.h>
 #include "config.h"
 #ifdef ENABLE_EVENTS
 #include "getifaddr.h"
@@ -76,16 +76,15 @@ static const char * const upnpallowedvalues[] =
 	"Disconnected",
 	0,
 	"ERROR_NONE",	/* 25 */
-/* Optionals values :
- * ERROR_COMMAND_ABORTED
- * ERROR_NOT_ENABLED_FOR_INTERNET
- * ERROR_USER_DISCONNECT
- * ERROR_ISP_DISCONNECT
- * ERROR_IDLE_DISCONNECT
- * ERROR_FORCED_DISCONNECT
- * ERROR_NO_CARRIER
- * ERROR_IP_CONFIGURATION
- * ERROR_UNKNOWN */
+	"ERROR_COMMAND_ABORTED",
+	"ERROR_NOT_ENABLED_FOR_INTERNET",
+	"ERROR_USER_DISCONNECT",
+	"ERROR_ISP_DISCONNECT",
+	"ERROR_IDLE_DISCONNECT",
+	"ERROR_FORCED_DISCONNECT",
+	"ERROR_NO_CARRIER",
+	"ERROR_IP_CONFIGURATION",
+	"ERROR_UNKNOWN",
 	0,
 	"",		/* 27 */
 	0
@@ -261,7 +260,7 @@ static const struct XMLElt rootDesc[] =
 #ifdef ENABLE_6FC_SERVICE
 /* 58 */
 	{"/serviceType", "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1"},
-	{"/serviceId", "urn:upnp-org:serviceId:WANIPv6FC1"},
+	{"/serviceId", "urn:upnp-org:serviceId:WANIPv6Firewall1"},
 	{"/controlURL", WANIP6FC_CONTROLURL},
 	{"/eventSubURL", WANIP6FC_EVENTURL},
 	{"/SCPDURL", WANIP6FC_PATH},
@@ -655,7 +655,7 @@ static const struct argument GetFirewall
 	{2|0x80, 6}, /* OUT : InboundPinholeAllowed */
 	{0, 0}
 };
-
+#if 0
 static const struct argument GetOutboundPinholeTimeoutArgs[] =
 {
 	{1|0x80|(3<<2), 1}, /* RemoteHost IN A_ARG_TYPE_IPv6Address */
@@ -666,7 +666,7 @@ static const struct argument GetOutbound
 	{2|0x80, 7}, /* OutboundPinholeTimeout OUT A_ARG_TYPE_OutboundPinholeTimeout */
 	{0, 0}
 };
-
+#endif
 static const struct argument AddPinholeArgs[] =
 {
 	{1|0x80|(3<<2), 1}, /* RemoteHost IN A_ARG_TYPE_IPv6Address */
@@ -709,7 +709,7 @@ static const struct argument CheckPinhol
 static const struct action IPv6FCActions[] =
 {
 	{"GetFirewallStatus", GetFirewallStatusArgs}, /* Req */
-	{"GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs}, /* Opt */
+	//{"GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs}, /* Opt */
 	{"AddPinhole", AddPinholeArgs}, /* Req */
 	{"UpdatePinhole", UpdatePinholeArgs}, /* Req */
 	{"DeletePinhole", DeletePinholeArgs}, /* Req */
-- 
1.8.2.1
