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
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)

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
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.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",
"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;