parent
78ab294de9
commit
9e24d3cccb
|
@ -6,3 +6,4 @@ listifaces
|
|||
Makefile.bak
|
||||
validateminissdpd
|
||||
validatecodelength
|
||||
showminissdpdnotif
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
$Id: Changelog.txt,v 1.43 2015/08/06 14:05:49 nanard Exp $
|
||||
|
||||
VERSION 1.5:
|
||||
|
||||
2016/01/13:
|
||||
add "notification" mode (command 5)
|
||||
|
||||
2015/08/06:
|
||||
disable multicast loop
|
||||
add -f command line option to filter for a specific device type
|
||||
|
|
|
@ -31,12 +31,16 @@ ifeq ($(DEB_BUILD_ARCH_OS), kfreebsd)
|
|||
endif
|
||||
|
||||
#EXECUTABLES = minissdpd testminissdpd listifaces
|
||||
EXECUTABLES = minissdpd testminissdpd testcodelength
|
||||
EXECUTABLES = minissdpd testminissdpd testcodelength \
|
||||
showminissdpdnotif
|
||||
MINISSDPDOBJS = minissdpd.o openssdpsocket.o daemonize.o upnputils.o \
|
||||
ifacewatch.o getroute.o getifaddr.o asyncsendto.o
|
||||
TESTMINISSDPDOBJS = testminissdpd.o
|
||||
TESTMINISSDPDOBJS = testminissdpd.o printresponse.o
|
||||
SHOWMINISSDPDNOTIFOBJS = showminissdpdnotif.o printresponse.o
|
||||
|
||||
ALLOBJS = $(MINISSDPDOBJS) $(TESTMINISSDPDOBJS) testcodelength.o
|
||||
ALLOBJS = $(MINISSDPDOBJS) $(TESTMINISSDPDOBJS) \
|
||||
$(SHOWMINISSDPDNOTIFOBJS) \
|
||||
testcodelength.o
|
||||
|
||||
INSTALLPREFIX ?= $(PREFIX)/usr
|
||||
SBININSTALLDIR = $(INSTALLPREFIX)/sbin
|
||||
|
@ -76,6 +80,8 @@ minissdpd: $(MINISSDPDOBJS)
|
|||
|
||||
testminissdpd: $(TESTMINISSDPDOBJS)
|
||||
|
||||
showminissdpdnotif: $(SHOWMINISSDPDNOTIFOBJS)
|
||||
|
||||
testcodelength: testcodelength.o
|
||||
|
||||
listifaces: listifaces.o upnputils.o
|
||||
|
@ -96,4 +102,8 @@ ifacewatch.o: config.h openssdpsocket.h minissdpdtypes.h upnputils.h
|
|||
getroute.o: getroute.h upnputils.h
|
||||
getifaddr.o: config.h getifaddr.h
|
||||
asyncsendto.o: asyncsendto.h upnputils.h
|
||||
testminissdpd.o: codelength.h printresponse.h
|
||||
printresponse.o: codelength.h
|
||||
showminissdpdnotif.o: codelength.h printresponse.h
|
||||
printresponse.o: codelength.h
|
||||
testcodelength.o: codelength.h
|
||||
|
|
|
@ -29,6 +29,7 @@ close unix socket connection.
|
|||
2 - USN (unique id)
|
||||
3 - everything
|
||||
4 - submit service (see below)
|
||||
5 - switch connection to notification mode
|
||||
n bytes : string length : 1 byte if < 128 else the upper bit indicate that
|
||||
one additional byte should be read, etc. (see codelength.h)
|
||||
n bytes = string
|
||||
|
@ -39,8 +40,9 @@ request type 0 (version) :
|
|||
n bytes string length
|
||||
n bytes = version string
|
||||
|
||||
request type 1 / 2 / 3 :
|
||||
1st byte : number of services/devices
|
||||
request type 1 / 2 / 3 / 5 :
|
||||
1st byte : number of services/devices, from 0 to 254.
|
||||
255 is a special value, see below
|
||||
For each service/device :
|
||||
URL :
|
||||
n bytes string length
|
||||
|
@ -52,6 +54,12 @@ USN:
|
|||
n bytes string length
|
||||
n bytes = identifier string
|
||||
|
||||
if the 1st byte is 255, the format is as follows :
|
||||
1st byte = 255
|
||||
2nd byte = notification type (1=NEW, 2=UPDATE, 3=REMOVE)
|
||||
3rd byte = number of services/devices, from 0 to 255.
|
||||
|
||||
|
||||
request type 4 = submit service
|
||||
1st byte = 4
|
||||
(k,n) bytes : length and string "ST" (service type)
|
||||
|
|
|
@ -15,7 +15,7 @@ indique s'il existe un octet suplementaire, etc...
|
|||
n octets = chaine
|
||||
|
||||
format reponse :
|
||||
1 octet : nombre de reponses
|
||||
1 octet : nombre de reponses (de 0 à 254)
|
||||
pour chaque rep :
|
||||
URL :
|
||||
n octets longueur de la chaine
|
||||
|
@ -27,7 +27,16 @@ USN:
|
|||
n octets longueur de la chaine
|
||||
n octets = chaine identifiant
|
||||
|
||||
Type de requete 4 = submit service
|
||||
si le 1er octet est 255, alors le format est le suivant :
|
||||
1 octet : 255
|
||||
1 octet : type de notification
|
||||
1 = NOTIF_NEW, 2 = NOTIF_NEW, 3 = NOTIF_REMOVE
|
||||
1 octet : nombre de reponses (0 à 255)
|
||||
puis comme ci dessus pour chaque réponse
|
||||
|
||||
|
||||
|
||||
* Type de requete 4 = submit service
|
||||
1 octet = 4
|
||||
(k,n) octets : longueur et chaine "ST" (service type)
|
||||
(k,n) octets : longueur et chaine "USN"
|
||||
|
@ -35,3 +44,6 @@ Type de requete 4 = submit service
|
|||
(k,n) octets : longueur et chaine "Location"
|
||||
Pas de reponse
|
||||
|
||||
* Type de requete 5 = mode notification
|
||||
Reste connecté et reçoit au fur et à mesure les nouvelles connections
|
||||
réponses au format normal
|
||||
|
|
|
@ -1 +1 @@
|
|||
1.4
|
||||
1.5
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
/* current request management stucture */
|
||||
struct reqelem {
|
||||
int socket;
|
||||
int is_notify; /* has subscribed to notifications */
|
||||
LIST_ENTRY(reqelem) entries;
|
||||
unsigned char * output_buffer;
|
||||
int output_buffer_offset;
|
||||
|
@ -69,6 +70,16 @@ struct device {
|
|||
char data[];
|
||||
};
|
||||
|
||||
/* Services stored for answering to M-SEARCH */
|
||||
struct service {
|
||||
char * st; /* Service type */
|
||||
char * usn; /* Unique identifier */
|
||||
char * server; /* Server string */
|
||||
char * location; /* URL */
|
||||
LIST_ENTRY(service) entries;
|
||||
};
|
||||
LIST_HEAD(servicehead, service) servicelisthead;
|
||||
|
||||
#define NTS_SSDP_ALIVE 1
|
||||
#define NTS_SSDP_BYEBYE 2
|
||||
#define NTS_SSDP_UPDATE 3
|
||||
|
@ -93,6 +104,16 @@ unsigned int upnp_configid = 1337;
|
|||
/* LAN interfaces/addresses */
|
||||
struct lan_addr_list lan_addrs;
|
||||
|
||||
/* connected clients */
|
||||
LIST_HEAD(reqstructhead, reqelem) reqlisthead;
|
||||
|
||||
/* functions prototypes */
|
||||
|
||||
#define NOTIF_NEW 1
|
||||
#define NOTIF_UPDATE 2
|
||||
#define NOTIF_REMOVE 3
|
||||
static void
|
||||
sendNotifications(int notif_type, const struct device * dev, const struct service * serv);
|
||||
|
||||
/* functions */
|
||||
|
||||
|
@ -296,6 +317,7 @@ updateDevice(const struct header * headers, time_t t)
|
|||
}
|
||||
memcpy(p->data + p->headers[0].l + p->headers[1].l,
|
||||
headers[2].p, headers[2].l);
|
||||
/* TODO : check p->headers[HEADER_LOCATION].l */
|
||||
return 0;
|
||||
}
|
||||
pp = &p->next;
|
||||
|
@ -324,6 +346,7 @@ updateDevice(const struct header * headers, time_t t)
|
|||
pc += headers[i].l;
|
||||
}
|
||||
devlist = p;
|
||||
sendNotifications(NOTIF_NEW, p, NULL);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -346,6 +369,7 @@ removeDevice(const struct header * headers)
|
|||
&& (0==memcmp(p->headers[HEADER_USN].p, headers[HEADER_USN].p, headers[HEADER_USN].l)) )
|
||||
{
|
||||
syslog(LOG_INFO, "remove device : %.*s", headers[HEADER_USN].l, headers[HEADER_USN].p);
|
||||
sendNotifications(NOTIF_REMOVE, p, NULL);
|
||||
*pp = p->next;
|
||||
free(p);
|
||||
return -1;
|
||||
|
@ -357,6 +381,68 @@ removeDevice(const struct header * headers)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* sent notifications to client having subscribed */
|
||||
static void
|
||||
sendNotifications(int notif_type, const struct device * dev, const struct service * serv)
|
||||
{
|
||||
struct reqelem * req;
|
||||
unsigned int m;
|
||||
unsigned char rbuf[RESPONSE_BUFFER_SIZE];
|
||||
unsigned char * rp;
|
||||
|
||||
for(req = reqlisthead.lh_first; req; req = req->entries.le_next) {
|
||||
if(!req->is_notify) continue;
|
||||
rbuf[0] = '\xff'; /* special code for notifications */
|
||||
rbuf[1] = (unsigned char)notif_type;
|
||||
rbuf[2] = 0;
|
||||
rp = rbuf + 3;
|
||||
if(dev) {
|
||||
/* response :
|
||||
* 1 - Location
|
||||
* 2 - NT (device/service type)
|
||||
* 3 - usn */
|
||||
m = dev->headers[HEADER_LOCATION].l;
|
||||
CODELENGTH(m, rp);
|
||||
memcpy(rp, dev->headers[HEADER_LOCATION].p, dev->headers[HEADER_LOCATION].l);
|
||||
rp += dev->headers[HEADER_LOCATION].l;
|
||||
m = dev->headers[HEADER_NT].l;
|
||||
CODELENGTH(m, rp);
|
||||
memcpy(rp, dev->headers[HEADER_NT].p, dev->headers[HEADER_NT].l);
|
||||
rp += dev->headers[HEADER_NT].l;
|
||||
m = dev->headers[HEADER_USN].l;
|
||||
CODELENGTH(m, rp);
|
||||
memcpy(rp, dev->headers[HEADER_USN].p, dev->headers[HEADER_USN].l);
|
||||
rp += dev->headers[HEADER_USN].l;
|
||||
rbuf[2]++;
|
||||
}
|
||||
if(serv) {
|
||||
/* response :
|
||||
* 1 - Location
|
||||
* 2 - NT (device/service type)
|
||||
* 3 - usn */
|
||||
m = strlen(serv->location);
|
||||
CODELENGTH(m, rp);
|
||||
memcpy(rp, serv->location, m);
|
||||
rp += m;
|
||||
m = strlen(serv->st);
|
||||
CODELENGTH(m, rp);
|
||||
memcpy(rp, serv->st, m);
|
||||
rp += m;
|
||||
m = strlen(serv->usn);
|
||||
CODELENGTH(m, rp);
|
||||
memcpy(rp, serv->usn, m);
|
||||
rp += m;
|
||||
rbuf[2]++;
|
||||
}
|
||||
if(rbuf[2] > 0) {
|
||||
if(write_or_buffer(req, rbuf, rp - rbuf) < 0) {
|
||||
syslog(LOG_ERR, "(s=%d) write: %m", req->socket);
|
||||
/*goto error;*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* SendSSDPMSEARCHResponse() :
|
||||
* build and send response to M-SEARCH SSDP packets. */
|
||||
static void
|
||||
|
@ -404,16 +490,6 @@ SendSSDPMSEARCHResponse(int s, const struct sockaddr * sockname,
|
|||
}
|
||||
}
|
||||
|
||||
/* Services stored for answering to M-SEARCH */
|
||||
struct service {
|
||||
char * st; /* Service type */
|
||||
char * usn; /* Unique identifier */
|
||||
char * server; /* Server string */
|
||||
char * location; /* URL */
|
||||
LIST_ENTRY(service) entries;
|
||||
};
|
||||
LIST_HEAD(servicehead, service) servicelisthead;
|
||||
|
||||
/* Process M-SEARCH requests */
|
||||
static void
|
||||
processMSEARCH(int s, const char * st, int st_len,
|
||||
|
@ -775,7 +851,8 @@ void processRequest(struct reqelem * req)
|
|||
l, (unsigned)n);
|
||||
goto error;
|
||||
}
|
||||
if(l == 0 && type != MINISSDPD_SEARCH_ALL && type != MINISSDPD_GET_VERSION) {
|
||||
if(l == 0 && type != MINISSDPD_SEARCH_ALL
|
||||
&& type != MINISSDPD_GET_VERSION && type != MINISSDPD_NOTIF) {
|
||||
syslog(LOG_WARNING, "bad request (length=0, type=%d)", type);
|
||||
goto error;
|
||||
}
|
||||
|
@ -867,7 +944,7 @@ void processRequest(struct reqelem * req)
|
|||
goto error;
|
||||
}
|
||||
break;
|
||||
case 4: /* submit service */
|
||||
case MINISSDPD_SUBMIT: /* submit service */
|
||||
newserv = malloc(sizeof(struct service));
|
||||
if(!newserv) {
|
||||
syslog(LOG_ERR, "cannot allocate memory");
|
||||
|
@ -963,8 +1040,17 @@ void processRequest(struct reqelem * req)
|
|||
}
|
||||
/* Inserting new service */
|
||||
LIST_INSERT_HEAD(&servicelisthead, newserv, entries);
|
||||
sendNotifications(NOTIF_NEW, NULL, newserv);
|
||||
newserv = NULL;
|
||||
break;
|
||||
case MINISSDPD_NOTIF: /* switch socket to notify */
|
||||
rbuf[0] = '\0';
|
||||
if(write_or_buffer(req, rbuf, 1) < 0) {
|
||||
syslog(LOG_ERR, "(s=%d) write: %m", req->socket);
|
||||
goto error;
|
||||
}
|
||||
req->is_notify = 1;
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_WARNING, "Unknown request type %d", type);
|
||||
rbuf[0] = '\0';
|
||||
|
@ -1076,7 +1162,6 @@ int main(int argc, char * * argv)
|
|||
#endif /* ENABLE_IPV6 */
|
||||
int s_unix = -1; /* unix socket communicating with clients */
|
||||
int s_ifacewatch = -1; /* socket to receive Route / network interface config changes */
|
||||
LIST_HEAD(reqstructhead, reqelem) reqlisthead;
|
||||
struct reqelem * req;
|
||||
struct reqelem * reqnext;
|
||||
fd_set readfds;
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/* $Id: $ */
|
||||
/* Project : miniupnp
|
||||
* website : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* Author : Thomas BERNARD
|
||||
* copyright (c) 2005-2016 Thomas Bernard
|
||||
* This software is subjet to the conditions detailed in the
|
||||
* provided LICENCE file. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "codelength.h"
|
||||
|
||||
#define NOTIF_NEW 1
|
||||
#define NOTIF_UPDATE 2
|
||||
#define NOTIF_REMOVE 3
|
||||
|
||||
void printresponse(const unsigned char * resp, int n)
|
||||
{
|
||||
int i, l;
|
||||
int notif_type;
|
||||
unsigned int nresp;
|
||||
const unsigned char * p;
|
||||
|
||||
if(n == 0)
|
||||
return;
|
||||
/* first, hexdump the response : */
|
||||
for(i = 0; i < n; i += 16) {
|
||||
printf("%06x | ", i);
|
||||
for(l = i; l < n && l < (i + 16); l++)
|
||||
printf("%02x ", resp[l]);
|
||||
while(l < (i + 16)) {
|
||||
printf(" ");
|
||||
l++;
|
||||
}
|
||||
printf("| ");
|
||||
for(l = i; l < n && l < (i + 16); l++)
|
||||
putchar((resp[l] >= ' ' && resp[l] < 128) ? resp[l] : '.');
|
||||
putchar('\n');
|
||||
}
|
||||
/* now parse and display all devices of response */
|
||||
nresp = resp[0]; /* 1st byte : number of devices in response */
|
||||
if(nresp == 0xff) {
|
||||
/* notification */
|
||||
notif_type = resp[1];
|
||||
nresp = resp[2];
|
||||
printf("Notification : ");
|
||||
switch(notif_type) {
|
||||
case NOTIF_NEW: printf("new\n"); break;
|
||||
case NOTIF_UPDATE: printf("update\n"); break;
|
||||
case NOTIF_REMOVE: printf("remove\n"); break;
|
||||
default: printf("**UNKNOWN**\n");
|
||||
}
|
||||
p = resp + 3;
|
||||
} else {
|
||||
p = resp + 1;
|
||||
}
|
||||
for(i = 0; i < (int)nresp; i++) {
|
||||
if(p >= resp + n)
|
||||
goto error;
|
||||
/*l = *(p++);*/
|
||||
DECODELENGTH(l, p);
|
||||
if(p + l > resp + n)
|
||||
goto error;
|
||||
printf("%d - %.*s\n", i, l, p); /* URL */
|
||||
p += l;
|
||||
if(p >= resp + n)
|
||||
goto error;
|
||||
/*l = *(p++);*/
|
||||
DECODELENGTH(l, p);
|
||||
if(p + l > resp + n)
|
||||
goto error;
|
||||
printf(" %.*s\n", l, p); /* ST */
|
||||
p += l;
|
||||
if(p >= resp + n)
|
||||
goto error;
|
||||
/*l = *(p++);*/
|
||||
DECODELENGTH(l, p);
|
||||
if(p + l > resp + n)
|
||||
goto error;
|
||||
printf(" %.*s\n", l, p); /* USN */
|
||||
p += l;
|
||||
}
|
||||
return;
|
||||
error:
|
||||
printf("*** WARNING : TRUNCATED RESPONSE ***\n");
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
/* $Id: $ */
|
||||
/* Project : miniupnp
|
||||
* Author : Thomas BERNARD
|
||||
* copyright (c) 2016 Thomas Bernard
|
||||
* This software is subjet to the conditions detailed in the
|
||||
* provided LICENCE file. */
|
||||
#ifndef PRINTRESPONSE_H_INCLUDED
|
||||
#define PRINTRESPONSE_H_INCLUDED
|
||||
|
||||
void printresponse(const unsigned char * resp, int n);
|
||||
|
||||
#endif /* PRINTRESPONSE_H_INCLUDED */
|
|
@ -0,0 +1,77 @@
|
|||
/* $Id: $ */
|
||||
/* MiniUPnP project
|
||||
* (c) 2016 Thomas Bernard
|
||||
* website : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* This software is subject to the conditions detailed
|
||||
* in the LICENCE file provided within the distribution */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "codelength.h"
|
||||
#include "printresponse.h"
|
||||
|
||||
static volatile sig_atomic_t quitting = 0;
|
||||
|
||||
static void sighandler(int sig)
|
||||
{
|
||||
(void)sig;
|
||||
quitting = 1;
|
||||
}
|
||||
|
||||
int main(int argc, char * * argv)
|
||||
{
|
||||
int i;
|
||||
int s;
|
||||
struct sockaddr_un addr;
|
||||
const char * sockpath = "/var/run/minissdpd.sock";
|
||||
unsigned char buffer[4096];
|
||||
ssize_t n;
|
||||
const char command5[] = { 0x05, 0x00 };
|
||||
struct sigaction sa;
|
||||
|
||||
for(i=0; i<argc-1; i++) {
|
||||
if(0==strcmp(argv[i], "-s"))
|
||||
sockpath = argv[++i];
|
||||
}
|
||||
|
||||
/* set signal handlers */
|
||||
memset(&sa, 0, sizeof(struct sigaction));
|
||||
sa.sa_handler = sighandler;
|
||||
if(sigaction(SIGINT, &sa, NULL)) {
|
||||
fprintf(stderr, "Failed to set SIGINT handler.\n");
|
||||
}
|
||||
|
||||
s = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, sockpath, sizeof(addr.sun_path));
|
||||
if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {
|
||||
fprintf(stderr, "connecting to %s : ", addr.sun_path);
|
||||
perror("connect");
|
||||
return 1;
|
||||
}
|
||||
printf("connected to %s\n", addr.sun_path);
|
||||
n = write(s, command5, sizeof(command5)); /* NOTIF command */
|
||||
printf("%d bytes written\n", (int)n);
|
||||
|
||||
while(!quitting) {
|
||||
n = read(s, buffer, sizeof(buffer));
|
||||
if(n < 0) {
|
||||
if(errno == EINTR) continue;
|
||||
perror("read");
|
||||
break;
|
||||
}
|
||||
printf("%d bytes read\n", (int)n);
|
||||
printresponse(buffer, (int)n);
|
||||
}
|
||||
printf("Quit...\n");
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
/* Project : miniupnp
|
||||
* website : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* Author : Thomas BERNARD
|
||||
* copyright (c) 2005-2015 Thomas Bernard
|
||||
* copyright (c) 2005-2016 Thomas Bernard
|
||||
* This software is subjet to the conditions detailed in the
|
||||
* provided LICENCE file. */
|
||||
|
||||
|
@ -14,9 +14,8 @@
|
|||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#define DECODELENGTH(n, p) n = 0; \
|
||||
do { n = (n << 7) | (*p & 0x7f); } \
|
||||
while(*(p++)&0x80);
|
||||
#include "codelength.h"
|
||||
#include "printresponse.h"
|
||||
|
||||
void printversion(const unsigned char * resp, int n)
|
||||
{
|
||||
|
@ -31,61 +30,6 @@ void printversion(const unsigned char * resp, int n)
|
|||
printf("MiniSSDPd version : %.*s\n", l, p);
|
||||
}
|
||||
|
||||
void printresponse(const unsigned char * resp, int n)
|
||||
{
|
||||
int i, l;
|
||||
unsigned int nresp;
|
||||
const unsigned char * p;
|
||||
if(n == 0)
|
||||
return;
|
||||
/* first, hexdump the response : */
|
||||
for(i = 0; i < n; i += 16) {
|
||||
printf("%06x | ", i);
|
||||
for(l = i; l < n && l < (i + 16); l++)
|
||||
printf("%02x ", resp[l]);
|
||||
while(l < (i + 16)) {
|
||||
printf(" ");
|
||||
l++;
|
||||
}
|
||||
printf("| ");
|
||||
for(l = i; l < n && l < (i + 16); l++)
|
||||
putchar((resp[l] >= ' ' && resp[l] < 128) ? resp[l] : '.');
|
||||
putchar('\n');
|
||||
}
|
||||
/* now parse and display all devices of response */
|
||||
nresp = resp[0]; /* 1st byte : number of devices in response */
|
||||
p = resp + 1;
|
||||
for(i = 0; i < (int)nresp; i++) {
|
||||
if(p >= resp + n)
|
||||
goto error;
|
||||
/*l = *(p++);*/
|
||||
DECODELENGTH(l, p);
|
||||
if(p + l > resp + n)
|
||||
goto error;
|
||||
printf("%d - %.*s\n", i, l, p); /* URL */
|
||||
p += l;
|
||||
if(p >= resp + n)
|
||||
goto error;
|
||||
/*l = *(p++);*/
|
||||
DECODELENGTH(l, p);
|
||||
if(p + l > resp + n)
|
||||
goto error;
|
||||
printf(" %.*s\n", l, p); /* ST */
|
||||
p += l;
|
||||
if(p >= resp + n)
|
||||
goto error;
|
||||
/*l = *(p++);*/
|
||||
DECODELENGTH(l, p);
|
||||
if(p + l > resp + n)
|
||||
goto error;
|
||||
printf(" %.*s\n", l, p); /* USN */
|
||||
p += l;
|
||||
}
|
||||
return;
|
||||
error:
|
||||
printf("*** WARNING : TRUNCATED RESPONSE ***\n");
|
||||
}
|
||||
|
||||
#define SENDCOMMAND(command, size) write(s, command, size); \
|
||||
printf("Command written type=%u\n", (unsigned char)command[0]);
|
||||
|
||||
|
@ -110,16 +54,17 @@ int connect_unix_socket(const char * sockpath)
|
|||
int
|
||||
main(int argc, char * * argv)
|
||||
{
|
||||
char command0[] = { 0x00, 0x00 };
|
||||
const char command0[] = { 0x00, 0x00 };
|
||||
char command1[] = "\x01\x00urn:schemas-upnp-org:device:InternetGatewayDevice";
|
||||
char command2[] = "\x02\x00uuid:fc4ec57e-b051-11db-88f8-0060085db3f6::upnp:rootdevice";
|
||||
char command3[] = { 0x03, 0x00 };
|
||||
const char command3[] = { 0x03, 0x00 };
|
||||
/* old versions of minissdpd would reject a command with
|
||||
* a zero length string argument */
|
||||
char command3compat[] = "\x03\x00ssdp:all";
|
||||
char command4[] = "\x04\x00test:test:test";
|
||||
char bad_command[] = { 0xff, 0xff };
|
||||
char overflow[] = { 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
const char bad_command[] = { 0xff, 0xff };
|
||||
const char overflow[] = { 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
const char command5[] = { 0x05, 0x00 };
|
||||
int s;
|
||||
int i;
|
||||
void * tmp;
|
||||
|
@ -226,6 +171,15 @@ main(int argc, char * * argv)
|
|||
n = read(s, buf, sizeof(buf));
|
||||
printf("Response received %d bytes\n", (int)n);
|
||||
printresponse(buf, n);
|
||||
if(n == 0) {
|
||||
close(s);
|
||||
s = connect_unix_socket(sockpath);
|
||||
}
|
||||
|
||||
n = SENDCOMMAND(command5, sizeof(command5));
|
||||
n = read(s, buf, sizeof(buf));
|
||||
printf("Response received %d bytes\n", (int)n);
|
||||
printresponse(buf, n);
|
||||
|
||||
close(s);
|
||||
return 0;
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/sh
|
||||
# $Id: $
|
||||
# (c) 2016 Thomas Bernard
|
||||
|
||||
OS=`uname -s`
|
||||
IF=lo
|
||||
if [ "$OS" = "Darwin" ] ; then
|
||||
IF=lo0
|
||||
fi
|
||||
# if set, 1st argument is network interface
|
||||
if [ -n "$1" ] ; then
|
||||
IF=$1
|
||||
fi
|
||||
SOCKET=`mktemp -t minissdpdsocketXXXXXX`
|
||||
PID="${SOCKET}.pid"
|
||||
./minissdpd -s $SOCKET -p $PID -i $IF || exit 1
|
||||
./showminissdpdnotif -s $SOCKET || exit 2
|
||||
kill `cat $PID`
|
Loading…
Reference in New Issue