miniupnpd/minissdp.c: Manage services/devices versions

This commit is contained in:
Thomas Bernard 2012-09-28 11:13:48 +02:00
parent 8b8772eed1
commit e5d7653002
2 changed files with 55 additions and 29 deletions

View File

@ -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 Support for Accept-Language/Content-Language HTTP headers
Content-Type is now text/xml; charset="utf-8" to conform with UDA v1.1 Content-Type is now text/xml; charset="utf-8" to conform with UDA v1.1
Support Expect: 100-continue for POST HTTP requests Support Expect: 100-continue for POST HTTP requests
Manage services/devices versions in minissdp.c
2012/09/20: 2012/09/20:
Cleaning code in ipfw (Jardel Weyrich) Cleaning code in ipfw (Jardel Weyrich)

View File

@ -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 /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2012 Thomas Bernard * (c) 2006-2012 Thomas Bernard
@ -6,6 +6,7 @@
* in the LICENCE file provided within the distribution */ * in the LICENCE file provided within the distribution */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <sys/socket.h> #include <sys/socket.h>
@ -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", {"upnp:rootdevice", 0},
"urn:schemas-upnp-org:device:InternetGatewayDevice:", {"urn:schemas-upnp-org:device:InternetGatewayDevice:", IGD_VER},
"urn:schemas-upnp-org:device:WANConnectionDevice:", {"urn:schemas-upnp-org:device:WANConnectionDevice:", 1},
"urn:schemas-upnp-org:device:WANDevice:", {"urn:schemas-upnp-org:device:WANDevice:", 1},
"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:", {"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:", 1},
"urn:schemas-upnp-org:service:WANIPConnection:", {"urn:schemas-upnp-org:service:WANIPConnection:", WANIPC_VER},
"urn:schemas-upnp-org:service:WANPPPConnection:", {"urn:schemas-upnp-org:service:WANPPPConnection:", 1},
#ifdef ENABLE_L3F_SERVICE #ifdef ENABLE_L3F_SERVICE
"urn:schemas-upnp-org:service:Layer3Forwarding:", {"urn:schemas-upnp-org:service:Layer3Forwarding:", 1},
#endif #endif
#ifdef ENABLE_6FC_SERVICE #ifdef ENABLE_6FC_SERVICE
"url:schemas-upnp-org:service:WANIPv6FirewallControl:", {"url:schemas-upnp-org:service:WANIPv6FirewallControl:", 1},
#endif #endif
0 {0, 0}
}; };
static void 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); 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), l = snprintf(bufr, sizeof(bufr),
"NOTIFY * HTTP/1.1\r\n" "NOTIFY * HTTP/1.1\r\n"
@ -431,8 +443,8 @@ SendSSDPNotifies(int s, const char * host, unsigned short port,
SSDP_PORT, SSDP_PORT,
lifetime, lifetime,
host, port, host, port,
known_service_types[i], (i==0?"":"1"), known_service_types[i].s, (i==0?"":"1"), /* TODO : proper version */
uuidvalue, known_service_types[i], (i==0?"":"1"), uuidvalue, known_service_types[i].s, (i==0?"":"1"),
upnp_bootid, upnp_bootid, upnp_configid ); upnp_bootid, upnp_bootid, upnp_configid );
if(l<0) if(l<0)
{ {
@ -525,6 +537,7 @@ ProcessSSDPData(int s, const char *bufr, int n,
struct lan_addr_s * lan_addr = NULL; struct lan_addr_s * lan_addr = NULL;
const char * st = NULL; const char * st = NULL;
int st_len = 0; int st_len = 0;
int st_ver = 0;
char sender_str[64]; char sender_str[64];
const char * announced_host = NULL; const char * announced_host = NULL;
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
@ -558,7 +571,11 @@ ProcessSSDPData(int s, const char *bufr, int n,
while(st[st_len]!='\r' && st[st_len]!='\n' while(st[st_len]!='\r' && st[st_len]!='\n'
&& (st + st_len < bufr + n)) && (st + st_len < bufr + n))
st_len++; 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;*/ /*j = 0;*/
/*while(bufr[i+j]!='\r') j++;*/ /*while(bufr[i+j]!='\r') j++;*/
/*syslog(LOG_INFO, "%.*s", j, bufr+i);*/ /*syslog(LOG_INFO, "%.*s", j, bufr+i);*/
@ -627,10 +644,15 @@ ProcessSSDPData(int s, const char *bufr, int n,
} }
#endif #endif
/* Responds to request with a device as ST header */ /* 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]); l = (int)strlen(known_service_types[i].s);
if(l<=st_len && (0 == memcmp(st, known_service_types[i], l))) 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"); syslog(LOG_INFO, "Single search found");
SendSSDPAnnounce2(s, sender, 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))) if(st_len==8 && (0 == memcmp(st, "ssdp:all", 8)))
{ {
syslog(LOG_INFO, "ssdp:all found"); 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, 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); announced_host, port);
} }
/* also answer for uuid */
SendSSDPAnnounce2(s, sender, uuidvalue, strlen(uuidvalue), "",
announced_host, port);
} }
/* responds to request by UUID value */ /* responds to request by UUID value */
l = (int)strlen(uuidvalue); l = (int)strlen(uuidvalue);
@ -703,7 +728,7 @@ SendSSDPGoodbye(int * sockets, int n_sockets)
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
ipv6 = j & 1; ipv6 = j & 1;
#endif #endif
for(i=0; known_service_types[i]; i++) for(i=0; known_service_types[i].s; i++)
{ {
l = snprintf(bufr, sizeof(bufr), l = snprintf(bufr, sizeof(bufr),
"NOTIFY * HTTP/1.1\r\n" "NOTIFY * HTTP/1.1\r\n"
@ -718,8 +743,8 @@ SendSSDPGoodbye(int * sockets, int n_sockets)
"\r\n", "\r\n",
ipv6 ? "[" LL_SSDP_MCAST_ADDR "]" : SSDP_MCAST_ADDR, ipv6 ? "[" LL_SSDP_MCAST_ADDR "]" : SSDP_MCAST_ADDR,
SSDP_PORT, SSDP_PORT,
known_service_types[i], (i==0?"":"1"), known_service_types[i].s, (i==0?"":"1"),/* TODO : proper version */
uuidvalue, known_service_types[i], (i==0?"":"1"), uuidvalue, known_service_types[i].s, (i==0?"":"1"),
upnp_bootid, upnp_bootid, upnp_configid); upnp_bootid, upnp_bootid, upnp_configid);
n = sendto(sockets[j], bufr, l, 0, n = sendto(sockets[j], bufr, l, 0,
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
@ -765,20 +790,20 @@ SubmitServicesToMiniSSDPD(const char * host, unsigned short port) {
close(s); close(s);
return -1; 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 */ buffer[0] = 4; /* request type 4 : submit service */
/* 4 strings following : ST (service type), USN, Server, Location */ /* 4 strings following : ST (service type), USN, Server, Location */
p = buffer + 1; p = buffer + 1;
l = (int)strlen(known_service_types[i]); l = (int)strlen(known_service_types[i].s);
if(i > 0) if(i > 0)
l++; l++;
CODELENGTH(l, p); CODELENGTH(l, p);
memcpy(p, known_service_types[i], l); memcpy(p, known_service_types[i].s, l);
if(i > 0) if(i > 0)
p[l-1] = '1'; p[l-1] = '1';
p += l; p += l;
l = snprintf(strbuf, sizeof(strbuf), "%s::%s%s", 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); CODELENGTH(l, p);
memcpy(p, strbuf, l); memcpy(p, strbuf, l);
p += l; p += l;