From e5d76530027f13ed14de36f8ba1d397a388e2792 Mon Sep 17 00:00:00 2001 From: Thomas Bernard Date: Fri, 28 Sep 2012 11:13:48 +0200 Subject: [PATCH] miniupnpd/minissdp.c: Manage services/devices versions --- miniupnpd/Changelog.txt | 1 + miniupnpd/minissdp.c | 83 +++++++++++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 29 deletions(-) diff --git a/miniupnpd/Changelog.txt b/miniupnpd/Changelog.txt index 28792b9..9835002 100644 --- a/miniupnpd/Changelog.txt +++ b/miniupnpd/Changelog.txt @@ -8,6 +8,7 @@ $Id: Changelog.txt,v 1.309 2012/09/27 16:01:10 nanard Exp $ Support for Accept-Language/Content-Language HTTP headers Content-Type is now text/xml; charset="utf-8" to conform with UDA v1.1 Support Expect: 100-continue for POST HTTP requests + Manage services/devices versions in minissdp.c 2012/09/20: Cleaning code in ipfw (Jardel Weyrich) diff --git a/miniupnpd/minissdp.c b/miniupnpd/minissdp.c index d5e27ee..ca68ebf 100644 --- a/miniupnpd/minissdp.c +++ b/miniupnpd/minissdp.c @@ -1,4 +1,4 @@ -/* $Id: minissdp.c,v 1.40 2012/08/10 12:00:09 nanard Exp $ */ +/* $Id: minissdp.c,v 1.42 2012/09/27 15:35:08 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2012 Thomas Bernard @@ -6,6 +6,7 @@ * in the LICENCE file provided within the distribution */ #include +#include #include #include #include @@ -363,22 +364,33 @@ SendSSDPAnnounce2(int s, const struct sockaddr * addr, } } -static const char * const known_service_types[] = +#ifndef IGD_V2 +#define IGD_VER 1 +#define WANIPC_VER 1 +#else +#define IGD_VER 2 +#define WANIPC_VER 2 +#endif + +static struct { + const char * s; + const int version; +} const known_service_types[] = { - "upnp:rootdevice", - "urn:schemas-upnp-org:device:InternetGatewayDevice:", - "urn:schemas-upnp-org:device:WANConnectionDevice:", - "urn:schemas-upnp-org:device:WANDevice:", - "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:", - "urn:schemas-upnp-org:service:WANIPConnection:", - "urn:schemas-upnp-org:service:WANPPPConnection:", + {"upnp:rootdevice", 0}, + {"urn:schemas-upnp-org:device:InternetGatewayDevice:", IGD_VER}, + {"urn:schemas-upnp-org:device:WANConnectionDevice:", 1}, + {"urn:schemas-upnp-org:device:WANDevice:", 1}, + {"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:", 1}, + {"urn:schemas-upnp-org:service:WANIPConnection:", WANIPC_VER}, + {"urn:schemas-upnp-org:service:WANPPPConnection:", 1}, #ifdef ENABLE_L3F_SERVICE - "urn:schemas-upnp-org:service:Layer3Forwarding:", + {"urn:schemas-upnp-org:service:Layer3Forwarding:", 1}, #endif #ifdef ENABLE_6FC_SERVICE - "url:schemas-upnp-org:service:WANIPv6FirewallControl:", + {"url:schemas-upnp-org:service:WANIPv6FirewallControl:", 1}, #endif - 0 + {0, 0} }; static void @@ -411,7 +423,7 @@ SendSSDPNotifies(int s, const char * host, unsigned short port, p->sin_addr.s_addr = inet_addr(SSDP_MCAST_ADDR); } - while(known_service_types[i]) + while(known_service_types[i].s) { l = snprintf(bufr, sizeof(bufr), "NOTIFY * HTTP/1.1\r\n" @@ -431,8 +443,8 @@ SendSSDPNotifies(int s, const char * host, unsigned short port, SSDP_PORT, lifetime, host, port, - known_service_types[i], (i==0?"":"1"), - uuidvalue, known_service_types[i], (i==0?"":"1"), + known_service_types[i].s, (i==0?"":"1"), /* TODO : proper version */ + uuidvalue, known_service_types[i].s, (i==0?"":"1"), upnp_bootid, upnp_bootid, upnp_configid ); if(l<0) { @@ -525,6 +537,7 @@ ProcessSSDPData(int s, const char *bufr, int n, struct lan_addr_s * lan_addr = NULL; const char * st = NULL; int st_len = 0; + int st_ver = 0; char sender_str[64]; const char * announced_host = NULL; #ifdef ENABLE_IPV6 @@ -558,7 +571,11 @@ ProcessSSDPData(int s, const char *bufr, int n, while(st[st_len]!='\r' && st[st_len]!='\n' && (st + st_len < bufr + n)) st_len++; - /*syslog(LOG_INFO, "ST: %.*s", st_len, st);*/ + l = st_len; + while(l > 0 && st[l-1] != ':') + l--; + st_ver = atoi(st+l); + syslog(LOG_DEBUG, "ST: %.*s (ver=%d)", st_len, st, st_ver); /*j = 0;*/ /*while(bufr[i+j]!='\r') j++;*/ /*syslog(LOG_INFO, "%.*s", j, bufr+i);*/ @@ -627,10 +644,15 @@ ProcessSSDPData(int s, const char *bufr, int n, } #endif /* Responds to request with a device as ST header */ - for(i = 0; known_service_types[i]; i++) + for(i = 0; known_service_types[i].s; i++) { - l = (int)strlen(known_service_types[i]); - if(l<=st_len && (0 == memcmp(st, known_service_types[i], l))) + l = (int)strlen(known_service_types[i].s); + if(l<=st_len && (0 == memcmp(st, known_service_types[i].s, l)) +#ifdef UPNP_STRICT + && (st_ver <= known_service_types[i].version) + /* only answer for service version lower or equal of supported one */ +#endif + ) { syslog(LOG_INFO, "Single search found"); SendSSDPAnnounce2(s, sender, @@ -644,13 +666,16 @@ ProcessSSDPData(int s, const char *bufr, int n, if(st_len==8 && (0 == memcmp(st, "ssdp:all", 8))) { syslog(LOG_INFO, "ssdp:all found"); - for(i=0; known_service_types[i]; i++) + for(i=0; known_service_types[i].s; i++) { - l = (int)strlen(known_service_types[i]); + l = (int)strlen(known_service_types[i].s); SendSSDPAnnounce2(s, sender, - known_service_types[i], l, i==0?"":"1", + known_service_types[i].s, l, i==0?"":"1", /* send proper version */ announced_host, port); } + /* also answer for uuid */ + SendSSDPAnnounce2(s, sender, uuidvalue, strlen(uuidvalue), "", + announced_host, port); } /* responds to request by UUID value */ l = (int)strlen(uuidvalue); @@ -703,7 +728,7 @@ SendSSDPGoodbye(int * sockets, int n_sockets) #ifdef ENABLE_IPV6 ipv6 = j & 1; #endif - for(i=0; known_service_types[i]; i++) + for(i=0; known_service_types[i].s; i++) { l = snprintf(bufr, sizeof(bufr), "NOTIFY * HTTP/1.1\r\n" @@ -718,8 +743,8 @@ SendSSDPGoodbye(int * sockets, int n_sockets) "\r\n", ipv6 ? "[" LL_SSDP_MCAST_ADDR "]" : SSDP_MCAST_ADDR, SSDP_PORT, - known_service_types[i], (i==0?"":"1"), - uuidvalue, known_service_types[i], (i==0?"":"1"), + known_service_types[i].s, (i==0?"":"1"),/* TODO : proper version */ + uuidvalue, known_service_types[i].s, (i==0?"":"1"), upnp_bootid, upnp_bootid, upnp_configid); n = sendto(sockets[j], bufr, l, 0, #ifdef ENABLE_IPV6 @@ -765,20 +790,20 @@ SubmitServicesToMiniSSDPD(const char * host, unsigned short port) { close(s); return -1; } - for(i = 0; known_service_types[i]; i++) { + for(i = 0; known_service_types[i].s; i++) { buffer[0] = 4; /* request type 4 : submit service */ /* 4 strings following : ST (service type), USN, Server, Location */ p = buffer + 1; - l = (int)strlen(known_service_types[i]); + l = (int)strlen(known_service_types[i].s); if(i > 0) l++; CODELENGTH(l, p); - memcpy(p, known_service_types[i], l); + memcpy(p, known_service_types[i].s, l); if(i > 0) p[l-1] = '1'; p += l; l = snprintf(strbuf, sizeof(strbuf), "%s::%s%s", - uuidvalue, known_service_types[i], (i==0)?"":"1"); + uuidvalue, known_service_types[i].s, (i==0)?"":"1"); CODELENGTH(l, p); memcpy(p, strbuf, l); p += l;