minissdpc.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /* $Id: minissdpc.c,v 1.7 2008/12/18 17:45:48 nanard Exp $ */
  2. /* Project : miniupnp
  3. * Author : Thomas BERNARD
  4. * copyright (c) 2005-2008 Thomas Bernard
  5. * This software is subjet to the conditions detailed in the
  6. * provided LICENCE file. */
  7. /*#include <syslog.h>*/
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #ifdef _MSC_VER
  12. #include <io.h>
  13. typedef intptr_t ssize_t;
  14. #define read _read
  15. #define write _write
  16. #define close _close
  17. #else
  18. #include <unistd.h>
  19. #endif
  20. #include <sys/types.h>
  21. #ifdef WIN32
  22. #include <winsock2.h>
  23. #include <Ws2tcpip.h>
  24. #include <io.h>
  25. #else
  26. #include <sys/socket.h>
  27. #include <sys/un.h>
  28. #endif
  29. #include "minissdpc.h"
  30. #include "miniupnpc.h"
  31. #include "codelength.h"
  32. struct UPNPDev *
  33. getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
  34. {
  35. #ifdef _MSC_VER
  36. /* sockaddr_un not supported on msvc*/
  37. return NULL;
  38. #else
  39. struct UPNPDev * tmp;
  40. struct UPNPDev * devlist = NULL;
  41. unsigned char buffer[2048];
  42. ssize_t n;
  43. unsigned char * p;
  44. unsigned char * url;
  45. unsigned int i;
  46. unsigned int urlsize, stsize, usnsize, l;
  47. int s;
  48. struct sockaddr_un addr;
  49. s = socket(AF_UNIX, SOCK_STREAM, 0);
  50. if(s < 0)
  51. {
  52. /*syslog(LOG_ERR, "socket(unix): %m");*/
  53. perror("socket(unix)");
  54. return NULL;
  55. }
  56. addr.sun_family = AF_UNIX;
  57. strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path));
  58. if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
  59. {
  60. /*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/
  61. close(s);
  62. return NULL;
  63. }
  64. stsize = strlen(devtype);
  65. buffer[0] = 1; /* request type 1 : request devices/services by type */
  66. p = buffer + 1;
  67. l = stsize; CODELENGTH(l, p);
  68. memcpy(p, devtype, stsize);
  69. p += stsize;
  70. if(write(s, buffer, p - buffer) < 0)
  71. {
  72. /*syslog(LOG_ERR, "write(): %m");*/
  73. perror("minissdpc.c: write()");
  74. close(s);
  75. return NULL;
  76. }
  77. n = read(s, buffer, sizeof(buffer));
  78. if(n<=0)
  79. {
  80. perror("minissdpc.c: read()");
  81. close(s);
  82. return NULL;
  83. }
  84. p = buffer + 1;
  85. for(i = 0; i < buffer[0]; i++)
  86. {
  87. if(p+2>=buffer+sizeof(buffer))
  88. break;
  89. DECODELENGTH(urlsize, p);
  90. if(p+urlsize+2>=buffer+sizeof(buffer))
  91. break;
  92. url = p;
  93. p += urlsize;
  94. DECODELENGTH(stsize, p);
  95. if(p+stsize+2>=buffer+sizeof(buffer))
  96. break;
  97. tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
  98. tmp->pNext = devlist;
  99. tmp->descURL = tmp->buffer;
  100. tmp->st = tmp->buffer + 1 + urlsize;
  101. memcpy(tmp->buffer, url, urlsize);
  102. tmp->buffer[urlsize] = '\0';
  103. memcpy(tmp->buffer + urlsize + 1, p, stsize);
  104. p += stsize;
  105. tmp->buffer[urlsize+1+stsize] = '\0';
  106. devlist = tmp;
  107. /* added for compatibility with recent versions of MiniSSDPd
  108. * >= 2007/12/19 */
  109. DECODELENGTH(usnsize, p);
  110. p += usnsize;
  111. if(p>buffer + sizeof(buffer))
  112. break;
  113. }
  114. close(s);
  115. return devlist;
  116. #endif
  117. }