1/* $Id: minissdpc.c,v 1.18 2014/11/17 09:41:32 nanard Exp $ */ 2/* Project : miniupnp 3 * Web : http://miniupnp.free.fr/ 4 * Author : Thomas BERNARD 5 * copyright (c) 2005-2014 Thomas Bernard 6 * This software is subjet to the conditions detailed in the 7 * provided LICENCE file. */ 8/*#include <syslog.h>*/ 9#include <stdio.h> 10#include <string.h> 11#include <stdlib.h> 12#include <unistd.h> 13#include <sys/types.h> 14#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__) 15#ifdef _WIN32 16#include <winsock2.h> 17#include <ws2tcpip.h> 18#include <io.h> 19#include <winsock.h> 20#include <stdint.h> 21#endif 22#if defined(__amigaos__) || defined(__amigaos4__) 23#include <sys/socket.h> 24#endif 25#if defined(__amigaos__) 26#define uint16_t unsigned short 27#endif 28/* Hack */ 29#define UNIX_PATH_LEN 108 30struct sockaddr_un { 31 uint16_t sun_family; 32 char sun_path[UNIX_PATH_LEN]; 33}; 34#else 35#include <sys/socket.h> 36#include <sys/un.h> 37#endif 38 39#include "minissdpc.h" 40#include "miniupnpc.h" 41 42#include "codelength.h" 43 44struct UPNPDev * 45getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath) 46{ 47 struct UPNPDev * tmp; 48 struct UPNPDev * devlist = NULL; 49 unsigned char buffer[4*1024]; /* is that enough ? */ 50 ssize_t n; 51 unsigned char * p; 52 unsigned char * url; 53 unsigned int i; 54 unsigned int urlsize, stsize, usnsize, l; 55 int s; 56 struct sockaddr_un addr; 57 58 s = socket(AF_UNIX, SOCK_STREAM, 0); 59 if(s < 0) 60 { 61 /*syslog(LOG_ERR, "socket(unix): %m");*/ 62 perror("socket(unix)"); 63 return NULL; 64 } 65 addr.sun_family = AF_UNIX; 66 strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path)); 67 /* TODO : check if we need to handle the EINTR */ 68 if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) 69 { 70 /*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/ 71 close(s); 72 return NULL; 73 } 74 stsize = strlen(devtype); 75 if(stsize == 8 && 0 == memcmp(devtype, "ssdp:all", 8)) 76 { 77 buffer[0] = 3; /* request type 3 : everything */ 78 } 79 else 80 { 81 buffer[0] = 1; /* request type 1 : request devices/services by type */ 82 } 83 p = buffer + 1; 84 l = stsize; CODELENGTH(l, p); 85 if(p + stsize > buffer + sizeof(buffer)) 86 { 87 /* devtype is too long ! */ 88 close(s); 89 return NULL; 90 } 91 memcpy(p, devtype, stsize); 92 p += stsize; 93 if(write(s, buffer, p - buffer) < 0) 94 { 95 /*syslog(LOG_ERR, "write(): %m");*/ 96 perror("minissdpc.c: write()"); 97 close(s); 98 return NULL; 99 } 100 n = read(s, buffer, sizeof(buffer)); 101 if(n<=0) 102 { 103 perror("minissdpc.c: read()"); 104 close(s); 105 return NULL; 106 } 107 p = buffer + 1; 108 for(i = 0; i < buffer[0]; i++) 109 { 110 if(p+2>=buffer+sizeof(buffer)) 111 break; 112 DECODELENGTH(urlsize, p); 113 if(p+urlsize+2>=buffer+sizeof(buffer)) 114 break; 115 url = p; 116 p += urlsize; 117 DECODELENGTH(stsize, p); 118 if(p+stsize+2>=buffer+sizeof(buffer)) 119 break; 120 tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize); 121 tmp->pNext = devlist; 122 tmp->descURL = tmp->buffer; 123 tmp->st = tmp->buffer + 1 + urlsize; 124 memcpy(tmp->buffer, url, urlsize); 125 tmp->buffer[urlsize] = '\0'; 126 memcpy(tmp->buffer + urlsize + 1, p, stsize); 127 p += stsize; 128 tmp->buffer[urlsize+1+stsize] = '\0'; 129 devlist = tmp; 130 /* added for compatibility with recent versions of MiniSSDPd 131 * >= 2007/12/19 */ 132 DECODELENGTH(usnsize, p); 133 p += usnsize; 134 if(p>buffer + sizeof(buffer)) 135 break; 136 } 137 close(s); 138 return devlist; 139} 140 141