From https://github.com/miniupnp/miniupnp/pull/282/files
From c6bf0ba6f33b96386455b410586755367f596b01 Mon Sep 17 00:00:00 2001 From: Nye Liu <[email protected]> Date: Mon, 19 Feb 2018 22:14:05 -0800 Subject: [PATCH] Allow runtime override of igd to v1 for people running binaries with v2 enabled Towards miniupnp/miniupnp#277 --- miniupnpd/miniupnpd.c | 11 +++++++++++ miniupnpd/miniupnpd.conf | 4 ++++ miniupnpd/options.c | 3 +++ miniupnpd/options.h | 3 +++ miniupnpd/testupnpdescgen.c | 5 +++++ miniupnpd/upnpdescgen.c | 39 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 65 insertions(+) diff --git a/miniupnpd/miniupnpd.c b/miniupnpd/miniupnpd.c index 55a3d31..e6a73d4 100644 --- a/miniupnpd/miniupnpd.c +++ b/miniupnpd/miniupnpd.c @@ -1294,6 +1294,17 @@ init(int argc, char * * argv, struct runtime_vars * v) case UPNPMINISSDPDSOCKET: minissdpdsocketpath = ary_options[i].value; break; +#ifdef IGD_V2 + case UPNPFORCEIGDDESCV1: + if (strcmp(ary_options[i].value, "yes")!=0 && + strcmp(ary_options[i].value, "no")!=0 ) { + fprintf(stderr, "force_igd_desc_v1 can only be yes or no\n"); + } + /* ary_options is processed by genRootDesc() to find + this because there is apperently no way to pass + options to the http server */ + break; +#endif default: fprintf(stderr, "Unknown option in file %s\n", optionsfile); diff --git a/miniupnpd/miniupnpd.conf b/miniupnpd/miniupnpd.conf index 338b33d..133566f 100644 --- a/miniupnpd/miniupnpd.conf +++ b/miniupnpd/miniupnpd.conf @@ -129,6 +129,10 @@ uuid=00000000-0000-0000-0000-000000000000 #serial=12345678 #model_number=1 +# If compiled with IGD_V2 defined, force reporting IGDv1 in rootDesc (default +# is no) +#force_igd_desc_v1=no + # UPnP permission rules # (allow|deny) (external port range) IP/mask (internal port range) # A port range is <min port>-<max port> or <port> if there is only diff --git a/miniupnpd/options.c b/miniupnpd/options.c index bdeb244..5062c2c 100644 --- a/miniupnpd/options.c +++ b/miniupnpd/options.c @@ -82,6 +82,9 @@ static const struct { #endif #ifdef ENABLE_LEASEFILE { UPNPLEASEFILE, "lease_file"}, +#endif +#ifdef IGD_V2 + { UPNPFORCEIGDDESCV1, "force_igd_desc_v1"}, #endif { UPNPMINISSDPDSOCKET, "minissdpdsocket"}, { UPNPSECUREMODE, "secure_mode"} diff --git a/miniupnpd/options.h b/miniupnpd/options.h index ae5b884..eb1f866 100644 --- a/miniupnpd/options.h +++ b/miniupnpd/options.h @@ -66,6 +66,9 @@ enum upnpconfigoptions { UPNPLEASEFILE, /* lease_file */ #endif UPNPMINISSDPDSOCKET, /* minissdpdsocket */ +#ifdef IGD_V2 + UPNPFORCEIGDDESCV1, +#endif UPNPENABLE /* enable_upnp */ }; diff --git a/miniupnpd/testupnpdescgen.c b/miniupnpd/testupnpdescgen.c index fdb143a..1ae4bb9 100644 --- a/miniupnpd/testupnpdescgen.c +++ b/miniupnpd/testupnpdescgen.c @@ -44,6 +44,11 @@ const char * ext_if_name = "eth0"; int runtime_flags = 0; +#ifdef IGD_V2 +struct option * ary_options = NULL; +unsigned int num_options = 0; +#endif + int getifaddr(const char * ifname, char * buf, int len, struct in_addr * addr, struct in_addr * mask) { UNUSED(ifname); diff --git a/miniupnpd/upnpdescgen.c b/miniupnpd/upnpdescgen.c index 3322bc0..f74b05e 100644 --- a/miniupnpd/upnpdescgen.c +++ b/miniupnpd/upnpdescgen.c @@ -17,6 +17,7 @@ #endif #include "upnpdescgen.h" #include "miniupnpdpath.h" +#include "options.h" #include "upnpglobalvars.h" #include "upnpdescstrings.h" #include "upnpurns.h" @@ -878,6 +879,31 @@ strcat_int(char * str, int * len, int * tmplen, int i) return str; } +#ifdef IGD_V2 +int force_igd_desc_v1(void) +{ + /* keep a cache so we only do it once */ + static int force=-1; + int i; + + if (force!=-1) return force; + + force=0; + + for(i=0; i<num_options; i++) { + if(ary_options[i].id==UPNPFORCEIGDDESCV1) + { + if (strcmp(ary_options[i].value, "yes")==0) + force=1; + else if (strcmp(ary_options[i].value, "no")==0) + force=0; + } + } + + return force; +} +#endif + /* iterative subroutine using a small stack * This way, the progam stack usage is kept low */ static char * @@ -921,6 +947,19 @@ genXML(char * str, int * len, int * tmplen, } #endif /* RANDOMIZE_URLS */ str = strcat_str(str, len, tmplen, p[i].data); +#ifdef IGD_V2 + if (force_igd_desc_v1()) + { + if ((strcmp(p[i].data, DEVICE_TYPE_IGD) == 0) || + (strcmp(p[i].data, DEVICE_TYPE_WAN) == 0) || + (strcmp(p[i].data, DEVICE_TYPE_WANC) == 0) || + (strcmp(p[i].data, SERVICE_TYPE_WANIPC) == 0) ) + { + int pos = strlen(str)-1; + if (pos>0) str[pos] = '1'; + } + } +#endif str = strcat_char(str, len, tmplen, '<'); str = strcat_str(str, len, tmplen, eltname); str = strcat_char(str, len, tmplen, '>'); -- 2.15.1

