Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added more functions #23

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/ssdp.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@
# define LOCATION_PORT 8080
#endif
#define LOCATION_DESC "/description.xml"
#define LOCATION_ICON "/icon.png"

#define MIME_XML "text/xml"
#define MIME_PNG "image/png"

#define SSDP_ST_ALL "ssdp:all"

Expand Down Expand Up @@ -108,10 +112,12 @@ extern int log_level;
extern int log_opts;
extern char uuid[42];
extern char url[128];
extern char deviceType[64];
extern char fname[128];
extern char model[128];
extern char modelNumber[128];
extern char serialNumber[128];
extern char iconFile[256];
extern char mfrurl[128];
extern char mfrnm[128];
extern int ttl;
Expand Down
40 changes: 26 additions & 14 deletions src/ssdpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ int ttl = MC_TTL_DEFAULT;
char *cachefn = NULL;
char *ver = NULL;
char *os = NULL;
char deviceType[64] = "Basic";
char fname[128];
char model[128];
char modelNumber[128];
char serialNumber[128];
char iconFile[256];
#ifdef MANUFACTURER_URL
char mfrurl[128] = MANUFACTURER_URL;
#else
Expand Down Expand Up @@ -561,28 +563,31 @@ static void signal_init(void)

static int usage(int code)
{
printf("Usage: %s [-hnsvw] [-c FILE] [-D MODEL] [-N MODELN] [-S SERIAL] [-d URL] [-i SEC] [-l LEVEL] [-m NAME] [-M URL]\n"
printf("Usage: %s [-hnsvw] [-c FILE] [-D MODEL] [-N MODELN] [-S SERIAL] [-d URL] [-i SEC] [-I ICON] [-T DTYPE] [-l LEVEL] [-m NAME] [-M URL]\n"
" [-p URL] [-P FILE] [-r SEC] [-R NUM] [-t TTL] [-u UUID]\n"
" [IFACE [IFACE ...]]\n"
"\n"
" -c FILE Path to alternate ssdpd.cache to store and/or read the UUID\n"
" -d URL Override UPnP description.xml URL in announcements. The '%%s' in\n"
" the URL is replaced with the IP, e.g. https://%%s:1901/main.xml\n"
" SSDP Params:\n"
" -T DTYPE Override deviceType in the default description.xml\n"
" -D MODEL Override modelName in the default description.xml\n"
" -N MODELN Override modelNumber in the default description.xml\n"
" -S SERIAL Override serialNumber in the default description.xml\n"
" -f FNAME Override friendlyName in the default description.xml\n"
" -h This help text\n"
" -i SEC SSDP notify interval (30-900), default %d sec\n"
" -l LVL Set log level: none, err, notice (default), info, debug\n"
" -m NAME Override manufacturer in the default description.xml\n"
" -m NAME Override manufacturer in the default description.xml\n"
" -M URL Override manufacturerURL in the default description.xml\n"
" -I ICON Icon file (only png file, required 128x128px)\n"
" -p URL Override presentationURL (WebUI) in the default description.xml\n"
" The '%%s' is replaced with the IP address. Default: http://%%s/\n"
" -c FILE Path to alternate ssdpd.cache to store and/or read the UUID\n"
" -d URL Override UPnP description.xml URL in announcements. The '%%s' in\n"
" the URL is replaced with the IP, e.g. https://%%s:1901/main.xml\n"
" -h This help text\n"
" -i SEC SSDP notify interval (30-900), default %d sec\n"
" -l LVL Set log level: none, err, notice (default), info, debug\n"
" -n Run in foreground, do not daemonize by default\n"
" -r SEC Interface refresh interval (5-1800), default %d sec\n"
" -R NUM Initial retries, using 10 sec refresh interval, default 3 times\n"
" Note: unused on systems with netlink interface monitoring.\n"
" -p URL Override presentationURL (WebUI) in the default description.xml\n"
" The '%%s' is replaced with the IP address. Default: http://%%s/\n"
" -P FILE Override PID file location, absolute path required\n"
" -s Use syslog, default unless running in foreground, -n\n"
" -t TTL TTL for multicast frames, default 2, according to the UDA\n"
Expand Down Expand Up @@ -614,7 +619,7 @@ int main(int argc, char *argv[])
int nlmon = 0;
int c;

while ((c = getopt(argc, argv, "c:d:D:f:hi:l:m:M:np:P:r:R:st:u:vwN:S:")) != EOF) {
while ((c = getopt(argc, argv, "c:d:D:f:hi:l:m:M:np:P:r:R:st:u:vwN:S:I:T:")) != EOF) {
switch (c) {
case 'c':
cachefn = strdup(optarg);
Expand All @@ -627,13 +632,20 @@ int main(int argc, char *argv[])
case 'D':
strlcpy(model, optarg, sizeof(model));
break;


case 'T':
strlcpy(deviceType, optarg, sizeof(deviceType));
break;
case 'N':
strlcpy(modelNumber, optarg, sizeof(model));
strlcpy(modelNumber, optarg, sizeof(modelNumber));
break;

case 'S':
strlcpy(serialNumber, optarg, sizeof(model));
strlcpy(serialNumber, optarg, sizeof(serialNumber));
break;

case 'I':
strlcpy(iconFile, optarg, sizeof(iconFile));
break;

case 'f':
Expand Down
94 changes: 70 additions & 24 deletions src/web.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,31 +46,24 @@ const char *xml =
" <minor>0</minor>\r\n"
" </specVersion>\r\n"
" <device>\r\n"
" <deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>\r\n"
" <deviceType>urn:schemas-upnp-org:device:%s:1</deviceType>\r\n"
" <friendlyName>%s</friendlyName>\r\n"
" <manufacturer>%s</manufacturer>\r\n%s"
" <modelName>%s</modelName>\r\n"
" <modelNumber>%s</modelNumber>\r\n"
" <serialNumber>%s</serialNumber>"
" <UDN>%s</UDN>\r\n"
" <presentationURL>%s</presentationURL>\r\n"
" <iconList>"
" <icon>"
" <mimetype>image/png</mimetype>"
" <height>120</height>"
" <width>120</width>"
" <depth>24</depth>"
" <url>icon.png</url>"
" </icon>"
" </iconList>"
" </device>\r\n"
//"<iconList>"
//"<icon>"
//"<mimetype>image/png</mimetype>"
//"<height>48</height>"
//"<width>48</width>"
//"<depth>24</depth>"
//"<url>icon48.png</url>"
//"</icon>"
//"<icon>"
//"<mimetype>image/png</mimetype>"
//"<height>120</height>"
//"<width>120</width>"
//"<depth>24</depth>"
//"<url>icon120.png</url>"
//"</icon>"
//"</iconList>"
"</root>\r\n"
"\r\n";

Expand Down Expand Up @@ -142,6 +135,12 @@ static int validate_http(int sd, char *http)
return 0;
}

static int errorNotFound(int sd){
if (write(sd, "HTTP/1.1 404 Not Found\r\n", 24) < 0)
logit(LOG_WARNING, "Failed returning status 404 to client: %s", strerror(errno));
return -1;
}

static int respond(int sd, struct sockaddr_in *sin)
{
struct pollfd pfd = {
Expand All @@ -151,7 +150,7 @@ static int respond(int sd, struct sockaddr_in *sin)
const char *head = "HTTP/1.1 200 OK\r\n"
"Date: %s\r\n"
"Server: ssdp-responder/%s\r\n"
"Content-Type: text/xml\r\n"
"Content-Type: %s\r\n"
"Connection: close\r\n"
"\r\n";
char manufacturer_url[192] = "";
Expand Down Expand Up @@ -187,28 +186,75 @@ static int respond(int sd, struct sockaddr_in *sin)
if (validate_http(sd, reqline[2]))
return -1;

snprintf(mesg, sizeof(mesg), head, compose_time(), VERSION);
snprintf(mesg, sizeof(mesg), head, compose_time(), VERSION, MIME_XML);
if (send(sd, mesg, strlen(mesg), 0) < 0)
return -1;
} else if (strncmp(reqline[0], "GET", 4) == 0) {
if (validate_http(sd, reqline[2]))
return -1;

/* XXX: Add support for icon as well */
if (!reqline[1] || !strstr(reqline[1], LOCATION_DESC)) {
if (write(sd, "HTTP/1.1 404 Not Found\r\n", 24) < 0)
logit(LOG_WARNING, "Failed returning status 404 to client: %s", strerror(errno));
return -1;
if (!reqline[1] || (!strstr(reqline[1], LOCATION_DESC) && !strstr(reqline[1], LOCATION_ICON))) {
return errorNotFound(sd);
}

if(strstr(reqline[1], LOCATION_ICON)){
if(!strlen(iconFile)){
return errorNotFound(sd);
}

FILE *fp = fopen(iconFile, "r"); //open file
if(fp)
{
logit(LOG_DEBUG, "Sending Icon reply ...");
//Calculate file size
int64_t _file_size = 0;
fseek(fp, 0, SEEK_END);
_file_size = ftello(fp);

//malloc buffer for image
uint8_t *buffer = (uint8_t*)malloc(_file_size + 1);
if(buffer == NULL){
logit(LOG_WARNING, "Failed malloc()");
return errorNotFound(sd);
}
fseek(fp, 0, SEEK_SET); //move to start file

//Read image file in buffer
if(!fread(buffer, _file_size, 1, fp)){
logit(LOG_DEBUG, "Error reading image file");
return errorNotFound(sd);
}

snprintf(mesg, sizeof(mesg), head, compose_time(), VERSION, MIME_PNG); //Generate head string
//Send HTTP Headers
if (send(sd, mesg, strlen(mesg), 0) < 0) {
logit(LOG_WARNING, "Failed sending file to client: %s", strerror(errno));
}
//Send Image buffer
if (send(sd, buffer, _file_size, 0) < 0) {
logit(LOG_WARNING, "Failed sending file to client: %s", strerror(errno));
}
fclose(fp); //Close file
free(buffer); //Free buffer
}
else{
logit(LOG_DEBUG, "Icon file not found ...");
return errorNotFound(sd);
}
return 0;
}

if(!strlen(fname))
gethostname(fname, sizeof(fname));
if (mfrurl[0])
snprintf(manufacturer_url, sizeof(manufacturer_url),
" <manufacturerURL>%s</manufacturerURL>\r\n", mfrurl);

logit(LOG_DEBUG, "Sending XML reply ...");
rc = snprintf(mesg, sizeof(mesg), head, compose_time(), VERSION);
rc = snprintf(mesg, sizeof(mesg), head, compose_time(), VERSION, MIME_XML);
snprintf(&mesg[rc], sizeof(mesg) - rc, xml,
deviceType,
fname,
mfrnm,
manufacturer_url,
Expand Down
Loading