minissdpc.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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, plen;
  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. plen = strlen(socketpath);
  58. if (plen + 1 > sizeof(addr.sun_path)) {
  59. plen = sizeof(addr.sun_path) - 1;
  60. }
  61. memset(addr.sun_path, 0, sizeof(addr.sun_path));
  62. memcpy(addr.sun_path, socketpath, plen);
  63. if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
  64. {
  65. /*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/
  66. close(s);
  67. return NULL;
  68. }
  69. stsize = strlen(devtype);
  70. buffer[0] = 1; /* request type 1 : request devices/services by type */
  71. p = buffer + 1;
  72. l = stsize; CODELENGTH(l, p);
  73. memcpy(p, devtype, stsize);
  74. p += stsize;
  75. if(write(s, buffer, p - buffer) < 0)
  76. {
  77. /*syslog(LOG_ERR, "write(): %m");*/
  78. perror("minissdpc.c: write()");
  79. close(s);
  80. return NULL;
  81. }
  82. n = read(s, buffer, sizeof(buffer));
  83. if(n<=0)
  84. {
  85. perror("minissdpc.c: read()");
  86. close(s);
  87. return NULL;
  88. }
  89. p = buffer + 1;
  90. for(i = 0; i < buffer[0]; i++)
  91. {
  92. if(p+2>=buffer+sizeof(buffer))
  93. break;
  94. DECODELENGTH(urlsize, p);
  95. if(p+urlsize+2>=buffer+sizeof(buffer))
  96. break;
  97. url = p;
  98. p += urlsize;
  99. DECODELENGTH(stsize, p);
  100. if(p+stsize+2>=buffer+sizeof(buffer))
  101. break;
  102. tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
  103. tmp->pNext = devlist;
  104. tmp->descURL = tmp->buffer;
  105. tmp->st = tmp->buffer + 1 + urlsize;
  106. memcpy(tmp->buffer, url, urlsize);
  107. tmp->buffer[urlsize] = '\0';
  108. memcpy(tmp->buffer + urlsize + 1, p, stsize);
  109. p += stsize;
  110. tmp->buffer[urlsize+1+stsize] = '\0';
  111. devlist = tmp;
  112. /* added for compatibility with recent versions of MiniSSDPd
  113. * >= 2007/12/19 */
  114. DECODELENGTH(usnsize, p);
  115. p += usnsize;
  116. if(p>buffer + sizeof(buffer))
  117. break;
  118. }
  119. close(s);
  120. return devlist;
  121. #endif
  122. }