1/* $Id: minissdpc.c,v 1.16 2012/03/05 19:42:46 nanard Exp $ */ 2/* Project : miniupnp 3 * Web : http://miniupnp.free.fr/ 4 * Author : Thomas BERNARD 5 * copyright (c) 2005-2012 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[2048]; 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 buffer[0] = 1; /* request type 1 : request devices/services by type */ 76 p = buffer + 1; 77 l = stsize; CODELENGTH(l, p); 78 if(p + stsize > buffer + sizeof(buffer)) 79 { 80 /* devtype is too long ! */ 81 close(s); 82 return NULL; 83 } 84 memcpy(p, devtype, stsize); 85 p += stsize; 86 if(write(s, buffer, p - buffer) < 0) 87 { 88 /*syslog(LOG_ERR, "write(): %m");*/ 89 perror("minissdpc.c: write()"); 90 close(s); 91 return NULL; 92 } 93 n = read(s, buffer, sizeof(buffer)); 94 if(n<=0) 95 { 96 perror("minissdpc.c: read()"); 97 close(s); 98 return NULL; 99 } 100 p = buffer + 1; 101 for(i = 0; i < buffer[0]; i++) 102 { 103 if(p+2>=buffer+sizeof(buffer)) 104 break; 105 DECODELENGTH(urlsize, p); 106 if(p+urlsize+2>=buffer+sizeof(buffer)) 107 break; 108 url = p; 109 p += urlsize; 110 DECODELENGTH(stsize, p); 111 if(p+stsize+2>=buffer+sizeof(buffer)) 112 break; 113 tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize); 114 tmp->pNext = devlist; 115 tmp->descURL = tmp->buffer; 116 tmp->st = tmp->buffer + 1 + urlsize; 117 memcpy(tmp->buffer, url, urlsize); 118 tmp->buffer[urlsize] = '\0'; 119 memcpy(tmp->buffer + urlsize + 1, p, stsize); 120 p += stsize; 121 tmp->buffer[urlsize+1+stsize] = '\0'; 122 devlist = tmp; 123 /* added for compatibility with recent versions of MiniSSDPd 124 * >= 2007/12/19 */ 125 DECODELENGTH(usnsize, p); 126 p += usnsize; 127 if(p>buffer + sizeof(buffer)) 128 break; 129 } 130 close(s); 131 return devlist; 132} 133 134