diff -urN xchat-2.6.6/configure xchat-2.6.6upnp/configure
--- xchat-2.6.6/configure	2006-07-18 04:51:55.000000000 +0200
+++ xchat-2.6.6upnp/configure	2011-08-11 16:41:08.000000000 +0200
@@ -26516,6 +26516,8 @@
   rm -f conf.gtktest
 
 
+LIBS="$LIBS -lminiupnpc"
+
 if test "$havegtk" = no; then
 	gtkfe=no
 	echo
diff -urN xchat-2.6.6/configure.in xchat-2.6.6upnp/configure.in
--- xchat-2.6.6/configure.in	2006-07-18 04:51:09.000000000 +0200
+++ xchat-2.6.6upnp/configure.in	2006-10-22 19:47:34.000000000 +0200
@@ -142,6 +142,8 @@
 [  --enable-spell=type     enable spelling type: none static libsexy gtkspell],
 		  spell=$enableval, spell=libsexy)
 
+LIBS="$LIBS -lminiupnpc"
+
 dnl *********************************************************************
 dnl ** GLIB *************************************************************
 dnl *********************************************************************
Les fichiers binaires xchat-2.6.6/po/de.gmo et xchat-2.6.6upnp/po/de.gmo sont différents.
Les fichiers binaires xchat-2.6.6/po/el.gmo et xchat-2.6.6upnp/po/el.gmo sont différents.
Les fichiers binaires xchat-2.6.6/po/es.gmo et xchat-2.6.6upnp/po/es.gmo sont différents.
Les fichiers binaires xchat-2.6.6/po/fi.gmo et xchat-2.6.6upnp/po/fi.gmo sont différents.
Les fichiers binaires xchat-2.6.6/po/fr.gmo et xchat-2.6.6upnp/po/fr.gmo sont différents.
Les fichiers binaires xchat-2.6.6/po/gl.gmo et xchat-2.6.6upnp/po/gl.gmo sont différents.
Les fichiers binaires xchat-2.6.6/po/hu.gmo et xchat-2.6.6upnp/po/hu.gmo sont différents.
Les fichiers binaires xchat-2.6.6/po/ja.gmo et xchat-2.6.6upnp/po/ja.gmo sont différents.
Les fichiers binaires xchat-2.6.6/po/ko.gmo et xchat-2.6.6upnp/po/ko.gmo sont différents.
Les fichiers binaires xchat-2.6.6/po/nl.gmo et xchat-2.6.6upnp/po/nl.gmo sont différents.
Les fichiers binaires xchat-2.6.6/po/pa.gmo et xchat-2.6.6upnp/po/pa.gmo sont différents.
Les fichiers binaires xchat-2.6.6/po/sq.gmo et xchat-2.6.6upnp/po/sq.gmo sont différents.
Les fichiers binaires xchat-2.6.6/po/sr.gmo et xchat-2.6.6upnp/po/sr.gmo sont différents.
diff -urN xchat-2.6.6/po/stamp-po xchat-2.6.6upnp/po/stamp-po
--- xchat-2.6.6/po/stamp-po	1970-01-01 01:00:00.000000000 +0100
+++ xchat-2.6.6upnp/po/stamp-po	2006-10-22 20:07:18.000000000 +0200
@@ -0,0 +1 @@
+timestamp
Les fichiers binaires xchat-2.6.6/po/sv.gmo et xchat-2.6.6upnp/po/sv.gmo sont différents.
Les fichiers binaires xchat-2.6.6/po/vi.gmo et xchat-2.6.6upnp/po/vi.gmo sont différents.
Les fichiers binaires xchat-2.6.6/po/zh_TW.gmo et xchat-2.6.6upnp/po/zh_TW.gmo sont différents.
diff -urN xchat-2.6.6/src/common/dcc.c xchat-2.6.6upnp/src/common/dcc.c
--- xchat-2.6.6/src/common/dcc.c	2006-07-10 10:00:37.000000000 +0200
+++ xchat-2.6.6upnp/src/common/dcc.c	2006-10-27 23:56:12.000000000 +0200
@@ -55,6 +55,8 @@
 #include "url.h"
 #include "xchatc.h"
 
+#include "upnp.h"
+
 #ifdef USE_DCC64
 #define BIG_STR_TO_INT(x) strtoull(x,NULL,10)
 #else
@@ -352,6 +354,11 @@
 static void
 dcc_close (struct DCC *dcc, int dccstat, int destroy)
 {
+	if (dcc->port > 0)	// && dcc->pasvid ??
+	{
+		upnp_rem_redir (dcc->port);
+	}
+
 	if (dcc->wiotag)
 	{
 		fe_input_remove (dcc->wiotag);
@@ -1680,6 +1687,8 @@
 
 	SAddr.sin_family = AF_INET;
 
+	/*printf("prefs.local_ip=%08x\n", prefs.local_ip);*/
+	/*printf("SAddr.sin_addr.s_addr=%s => ip interne\n", inet_ntoa(SAddr.sin_addr));*/
 	/*if local_ip is specified use that*/
 	if (prefs.local_ip != 0xffffffff)
 	{
@@ -1726,6 +1735,7 @@
 	getsockname (dcc->sok, (struct sockaddr *) &SAddr, &len);
 
 	dcc->port = ntohs (SAddr.sin_port);
+	/*printf("dcc port = %d\n", dcc->port);*/
 
 	/*if we have a dcc_ip, we use that, so the remote client can connect*/
 	/*else we try to take an address from dcc_ip_str*/
@@ -1738,12 +1748,17 @@
 
 	dcc->addr = ntohl (dcc->addr);
 
+	/*printf("dcc_get_my_address=%s = ext ip\n", net_ip(dcc->addr));*/
+
 	set_nonblocking (dcc->sok);
 	listen (dcc->sok, 1);
 	set_blocking (dcc->sok);
 
 	dcc->iotag = fe_input_add (dcc->sok, FIA_READ|FIA_EX, dcc_accept, dcc);
 
+/* redirect port dcc->port => dcc->addr:dcc->port */
+	upnp_add_redir (inet_ntoa(SAddr.sin_addr), dcc->port);
+
 	return TRUE;
 }
 
diff -urN xchat-2.6.6/src/common/Makefile.am xchat-2.6.6upnp/src/common/Makefile.am
--- xchat-2.6.6/src/common/Makefile.am	2006-04-16 09:29:32.000000000 +0200
+++ xchat-2.6.6upnp/src/common/Makefile.am	2006-10-21 02:24:40.000000000 +0200
@@ -37,7 +37,8 @@
 	util.h \
 	xchat.h \
 	xchatc.h \
-	xchat-plugin.h
+	xchat-plugin.h \
+	upnp.h
 
 if USE_OPENSSL
 ssl_c = ssl.c
@@ -46,7 +47,8 @@
 libxchatcommon_a_SOURCES = cfgfiles.c ctcp.c dcc.c history.c ignore.c \
 	inbound.c modes.c msproxy.c network.c notify.c outbound.c \
 	plugin.c plugin-timer.c proto-irc.c server.c servlist.c $(ssl_c) \
-	text.c tree.c url.c userlist.c util.c xchat.c
+	text.c tree.c url.c userlist.c util.c xchat.c \
+	upnp.c
 
 textevents: make-te
 	./make-te < textevents.in > textevents.h 2> textenums.h
diff -urN xchat-2.6.6/src/common/Makefile.in xchat-2.6.6upnp/src/common/Makefile.in
--- xchat-2.6.6/src/common/Makefile.in	2006-07-18 04:51:53.000000000 +0200
+++ xchat-2.6.6upnp/src/common/Makefile.in	2006-10-22 20:10:23.000000000 +0200
@@ -52,7 +52,8 @@
 am__libxchatcommon_a_SOURCES_DIST = cfgfiles.c ctcp.c dcc.c history.c \
 	ignore.c inbound.c modes.c msproxy.c network.c notify.c \
 	outbound.c plugin.c plugin-timer.c proto-irc.c server.c \
-	servlist.c ssl.c text.c tree.c url.c userlist.c util.c xchat.c
+	servlist.c ssl.c text.c tree.c url.c userlist.c util.c xchat.c \
+	upnp.c
 @USE_OPENSSL_TRUE@am__objects_1 = ssl.$(OBJEXT)
 am_libxchatcommon_a_OBJECTS = cfgfiles.$(OBJEXT) ctcp.$(OBJEXT) \
 	dcc.$(OBJEXT) history.$(OBJEXT) ignore.$(OBJEXT) \
@@ -61,7 +62,7 @@
 	plugin.$(OBJEXT) plugin-timer.$(OBJEXT) proto-irc.$(OBJEXT) \
 	server.$(OBJEXT) servlist.$(OBJEXT) $(am__objects_1) \
 	text.$(OBJEXT) tree.$(OBJEXT) url.$(OBJEXT) userlist.$(OBJEXT) \
-	util.$(OBJEXT) xchat.$(OBJEXT)
+	util.$(OBJEXT) xchat.$(OBJEXT) upnp.$(OBJEXT)
 libxchatcommon_a_OBJECTS = $(am_libxchatcommon_a_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -302,13 +303,15 @@
 	util.h \
 	xchat.h \
 	xchatc.h \
-	xchat-plugin.h
+	xchat-plugin.h \
+	upnp.h
 
 @USE_OPENSSL_TRUE@ssl_c = ssl.c
 libxchatcommon_a_SOURCES = cfgfiles.c ctcp.c dcc.c history.c ignore.c \
 	inbound.c modes.c msproxy.c network.c notify.c outbound.c \
 	plugin.c plugin-timer.c proto-irc.c server.c servlist.c $(ssl_c) \
-	text.c tree.c url.c userlist.c util.c xchat.c
+	text.c tree.c url.c userlist.c util.c xchat.c \
+	upnp.c
 
 all: all-am
 
@@ -380,6 +383,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/userlist.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xchat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upnp.Po@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`; \
diff -urN xchat-2.6.6/src/common/upnp.c xchat-2.6.6upnp/src/common/upnp.c
--- xchat-2.6.6/src/common/upnp.c	1970-01-01 01:00:00.000000000 +0100
+++ xchat-2.6.6upnp/src/common/upnp.c	2011-08-11 16:25:09.000000000 +0200
@@ -0,0 +1,89 @@
+/* upnp.c */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "xchat.h"
+#include "network.h"
+#include "upnp.h"
+
+#include <miniupnpc/miniwget.h>
+#include <miniupnpc/miniupnpc.h>
+#include <miniupnpc/upnpcommands.h>
+
+static struct UPNPUrls urls;
+static struct IGDdatas data;
+
+void init_upnp (void)
+{
+	struct UPNPDev * devlist;
+	struct UPNPDev * dev;
+	char * descXML;
+	int descXMLsize = 0;
+	int upnperror = 0;
+	printf("TB : init_upnp()\n");
+	memset(&urls, 0, sizeof(struct UPNPUrls));
+	memset(&data, 0, sizeof(struct IGDdatas));
+	devlist = upnpDiscover(2000, NULL/*multicast interface*/, NULL/*minissdpd socket path*/, 0/*sameport*/, 0/*ipv6*/, &upnperror);
+	if (devlist)
+	{
+		dev = devlist;
+		while (dev)
+		{
+			if (strstr (dev->st, "InternetGatewayDevice"))
+				break;
+			dev = dev->pNext;
+		}
+		if (!dev)
+			dev = devlist; /* defaulting to first device */
+
+		printf("UPnP device :\n"
+		       " desc: %s\n st: %s\n",
+			   dev->descURL, dev->st);
+
+		descXML = miniwget(dev->descURL, &descXMLsize);
+		if (descXML)
+		{
+			parserootdesc (descXML, descXMLsize, &data);
+			free (descXML); descXML = 0;
+			GetUPNPUrls (&urls, &data, dev->descURL);
+		}
+		freeUPNPDevlist(devlist);
+	}
+	else
+	{
+		/* error ! */
+	}
+}
+
+void upnp_add_redir (const char * addr, int port)
+{
+	char port_str[16];
+	int r;
+	printf("TB : upnp_add_redir (%s, %d)\n", addr, port);
+	if(urls.controlURL[0] == '\0')
+	{
+		printf("TB : the init was not done !\n");
+		return;
+	}
+	sprintf(port_str, "%d", port);
+	r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
+	                        port_str, port_str, addr, "xchat", "TCP", NULL, NULL);
+	if(r==0)
+		printf("AddPortMapping(%s, %s, %s) failed\n", port_str, port_str, addr);
+}
+
+void upnp_rem_redir (int port)
+{
+	char port_str[16];
+	int t;
+	printf("TB : upnp_rem_redir (%d)\n", port);
+	if(urls.controlURL[0] == '\0')
+	{
+		printf("TB : the init was not done !\n");
+		return;
+	}
+	sprintf(port_str, "%d", port);
+	UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port_str, "TCP", NULL);
+}
+
diff -urN xchat-2.6.6/src/common/upnp.h xchat-2.6.6upnp/src/common/upnp.h
--- xchat-2.6.6/src/common/upnp.h	1970-01-01 01:00:00.000000000 +0100
+++ xchat-2.6.6upnp/src/common/upnp.h	2006-10-21 03:09:18.000000000 +0200
@@ -0,0 +1,11 @@
+/* upnp.h */
+
+#ifndef XCHAT_UPNP_H
+#define XCHAT_UPNP_H
+
+void init_upnp (void);
+void upnp_add_redir (const char * addr, int port);
+void upnp_rem_redir (int port);
+
+#endif
+
diff -urN xchat-2.6.6/src/common/xchat.c xchat-2.6.6upnp/src/common/xchat.c
--- xchat-2.6.6/src/common/xchat.c	2006-05-27 17:06:26.000000000 +0200
+++ xchat-2.6.6upnp/src/common/xchat.c	2006-10-21 02:12:43.000000000 +0200
@@ -48,6 +48,8 @@
 #include "url.h"
 #include "xchatc.h"
 
+#include "upnp.h"
+
 #ifdef USE_OPENSSL
 #include <openssl/ssl.h>		  /* SSL_() */
 #include "ssl.h"
@@ -721,6 +723,7 @@
 	sound_load ();
 	notify_load ();
 	ignore_load ();
+	init_upnp ();
 
 	snprintf (buf, sizeof (buf),
 		"NAME %s\n"						"CMD query %%s\n\n"\
