/thirdparty/libportfwd/third-party/miniupnpc-1.6/upnpcommands.c

http://github.com/tomahawk-player/tomahawk · C · 1097 lines · 910 code · 86 blank · 101 comment · 133 complexity · 79ca76a1f481acd0070fdfe55c0c4c2c MD5 · raw file

  1. /* $Id: upnpcommands.c,v 1.37 2011/06/04 15:56:23 nanard Exp $ */
  2. /* Project : miniupnp
  3. * Author : Thomas Bernard
  4. * Copyright (c) 2005-2011 Thomas Bernard
  5. * This software is subject to the conditions detailed in the
  6. * LICENCE file provided in this distribution.
  7. * */
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include "upnpcommands.h"
  12. #include "miniupnpc.h"
  13. #include "portlistingparse.h"
  14. static UNSIGNED_INTEGER
  15. my_atoui(const char * s)
  16. {
  17. return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0;
  18. }
  19. /*
  20. * */
  21. LIBSPEC UNSIGNED_INTEGER
  22. UPNP_GetTotalBytesSent(const char * controlURL,
  23. const char * servicetype)
  24. {
  25. struct NameValueParserData pdata;
  26. char * buffer;
  27. int bufsize;
  28. unsigned int r = 0;
  29. char * p;
  30. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  31. "GetTotalBytesSent", 0, &bufsize))) {
  32. return UPNPCOMMAND_HTTP_ERROR;
  33. }
  34. ParseNameValue(buffer, bufsize, &pdata);
  35. /*DisplayNameValueList(buffer, bufsize);*/
  36. free(buffer); buffer = NULL;
  37. p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent");
  38. r = my_atoui(p);
  39. ClearNameValueList(&pdata);
  40. return r;
  41. }
  42. /*
  43. * */
  44. LIBSPEC UNSIGNED_INTEGER
  45. UPNP_GetTotalBytesReceived(const char * controlURL,
  46. const char * servicetype)
  47. {
  48. struct NameValueParserData pdata;
  49. char * buffer;
  50. int bufsize;
  51. unsigned int r = 0;
  52. char * p;
  53. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  54. "GetTotalBytesReceived", 0, &bufsize))) {
  55. return UPNPCOMMAND_HTTP_ERROR;
  56. }
  57. ParseNameValue(buffer, bufsize, &pdata);
  58. /*DisplayNameValueList(buffer, bufsize);*/
  59. free(buffer); buffer = NULL;
  60. p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived");
  61. r = my_atoui(p);
  62. ClearNameValueList(&pdata);
  63. return r;
  64. }
  65. /*
  66. * */
  67. LIBSPEC UNSIGNED_INTEGER
  68. UPNP_GetTotalPacketsSent(const char * controlURL,
  69. const char * servicetype)
  70. {
  71. struct NameValueParserData pdata;
  72. char * buffer;
  73. int bufsize;
  74. unsigned int r = 0;
  75. char * p;
  76. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  77. "GetTotalPacketsSent", 0, &bufsize))) {
  78. return UPNPCOMMAND_HTTP_ERROR;
  79. }
  80. ParseNameValue(buffer, bufsize, &pdata);
  81. /*DisplayNameValueList(buffer, bufsize);*/
  82. free(buffer); buffer = NULL;
  83. p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent");
  84. r = my_atoui(p);
  85. ClearNameValueList(&pdata);
  86. return r;
  87. }
  88. /*
  89. * */
  90. LIBSPEC UNSIGNED_INTEGER
  91. UPNP_GetTotalPacketsReceived(const char * controlURL,
  92. const char * servicetype)
  93. {
  94. struct NameValueParserData pdata;
  95. char * buffer;
  96. int bufsize;
  97. unsigned int r = 0;
  98. char * p;
  99. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  100. "GetTotalPacketsReceived", 0, &bufsize))) {
  101. return UPNPCOMMAND_HTTP_ERROR;
  102. }
  103. ParseNameValue(buffer, bufsize, &pdata);
  104. /*DisplayNameValueList(buffer, bufsize);*/
  105. free(buffer); buffer = NULL;
  106. p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived");
  107. r = my_atoui(p);
  108. ClearNameValueList(&pdata);
  109. return r;
  110. }
  111. /* UPNP_GetStatusInfo() call the corresponding UPNP method
  112. * returns the current status and uptime */
  113. LIBSPEC int
  114. UPNP_GetStatusInfo(const char * controlURL,
  115. const char * servicetype,
  116. char * status,
  117. unsigned int * uptime,
  118. char * lastconnerror)
  119. {
  120. struct NameValueParserData pdata;
  121. char * buffer;
  122. int bufsize;
  123. char * p;
  124. char * up;
  125. char * err;
  126. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  127. if(!status && !uptime)
  128. return UPNPCOMMAND_INVALID_ARGS;
  129. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  130. "GetStatusInfo", 0, &bufsize))) {
  131. return UPNPCOMMAND_HTTP_ERROR;
  132. }
  133. ParseNameValue(buffer, bufsize, &pdata);
  134. /*DisplayNameValueList(buffer, bufsize);*/
  135. free(buffer); buffer = NULL;
  136. up = GetValueFromNameValueList(&pdata, "NewUptime");
  137. p = GetValueFromNameValueList(&pdata, "NewConnectionStatus");
  138. err = GetValueFromNameValueList(&pdata, "NewLastConnectionError");
  139. if(p && up)
  140. ret = UPNPCOMMAND_SUCCESS;
  141. if(status) {
  142. if(p){
  143. strncpy(status, p, 64 );
  144. status[63] = '\0';
  145. }else
  146. status[0]= '\0';
  147. }
  148. if(uptime) {
  149. if(up)
  150. sscanf(up,"%u",uptime);
  151. else
  152. uptime = 0;
  153. }
  154. if(lastconnerror) {
  155. if(err) {
  156. strncpy(lastconnerror, err, 64 );
  157. lastconnerror[63] = '\0';
  158. } else
  159. lastconnerror[0] = '\0';
  160. }
  161. p = GetValueFromNameValueList(&pdata, "errorCode");
  162. if(p) {
  163. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  164. sscanf(p, "%d", &ret);
  165. }
  166. ClearNameValueList(&pdata);
  167. return ret;
  168. }
  169. /* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method
  170. * returns the connection type */
  171. LIBSPEC int
  172. UPNP_GetConnectionTypeInfo(const char * controlURL,
  173. const char * servicetype,
  174. char * connectionType)
  175. {
  176. struct NameValueParserData pdata;
  177. char * buffer;
  178. int bufsize;
  179. char * p;
  180. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  181. if(!connectionType)
  182. return UPNPCOMMAND_INVALID_ARGS;
  183. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  184. "GetConnectionTypeInfo", 0, &bufsize))) {
  185. return UPNPCOMMAND_HTTP_ERROR;
  186. }
  187. ParseNameValue(buffer, bufsize, &pdata);
  188. free(buffer); buffer = NULL;
  189. p = GetValueFromNameValueList(&pdata, "NewConnectionType");
  190. /*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/
  191. /* PossibleConnectionTypes will have several values.... */
  192. if(p) {
  193. strncpy(connectionType, p, 64 );
  194. connectionType[63] = '\0';
  195. ret = UPNPCOMMAND_SUCCESS;
  196. } else
  197. connectionType[0] = '\0';
  198. p = GetValueFromNameValueList(&pdata, "errorCode");
  199. if(p) {
  200. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  201. sscanf(p, "%d", &ret);
  202. }
  203. ClearNameValueList(&pdata);
  204. return ret;
  205. }
  206. /* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method.
  207. * Returns 2 values: Downloadlink bandwidth and Uplink bandwidth.
  208. * One of the values can be null
  209. * Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
  210. * We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
  211. LIBSPEC int
  212. UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
  213. const char * servicetype,
  214. unsigned int * bitrateDown,
  215. unsigned int * bitrateUp)
  216. {
  217. struct NameValueParserData pdata;
  218. char * buffer;
  219. int bufsize;
  220. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  221. char * down;
  222. char * up;
  223. char * p;
  224. if(!bitrateDown && !bitrateUp)
  225. return UPNPCOMMAND_INVALID_ARGS;
  226. /* shouldn't we use GetCommonLinkProperties ? */
  227. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  228. "GetCommonLinkProperties", 0, &bufsize))) {
  229. /*"GetLinkLayerMaxBitRates", 0, &bufsize);*/
  230. return UPNPCOMMAND_HTTP_ERROR;
  231. }
  232. /*DisplayNameValueList(buffer, bufsize);*/
  233. ParseNameValue(buffer, bufsize, &pdata);
  234. free(buffer); buffer = NULL;
  235. /*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/
  236. /*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/
  237. down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate");
  238. up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate");
  239. /*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/
  240. /*GetValueFromNameValueList(&pdata, "NewPhysicalLinkStatus");*/
  241. if(down && up)
  242. ret = UPNPCOMMAND_SUCCESS;
  243. if(bitrateDown) {
  244. if(down)
  245. sscanf(down,"%u",bitrateDown);
  246. else
  247. *bitrateDown = 0;
  248. }
  249. if(bitrateUp) {
  250. if(up)
  251. sscanf(up,"%u",bitrateUp);
  252. else
  253. *bitrateUp = 0;
  254. }
  255. p = GetValueFromNameValueList(&pdata, "errorCode");
  256. if(p) {
  257. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  258. sscanf(p, "%d", &ret);
  259. }
  260. ClearNameValueList(&pdata);
  261. return ret;
  262. }
  263. /* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
  264. * if the third arg is not null the value is copied to it.
  265. * at least 16 bytes must be available
  266. *
  267. * Return values :
  268. * 0 : SUCCESS
  269. * NON ZERO : ERROR Either an UPnP error code or an unknown error.
  270. *
  271. * 402 Invalid Args - See UPnP Device Architecture section on Control.
  272. * 501 Action Failed - See UPnP Device Architecture section on Control.
  273. */
  274. LIBSPEC int
  275. UPNP_GetExternalIPAddress(const char * controlURL,
  276. const char * servicetype,
  277. char * extIpAdd)
  278. {
  279. struct NameValueParserData pdata;
  280. char * buffer;
  281. int bufsize;
  282. char * p;
  283. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  284. if(!extIpAdd || !controlURL || !servicetype)
  285. return UPNPCOMMAND_INVALID_ARGS;
  286. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  287. "GetExternalIPAddress", 0, &bufsize))) {
  288. return UPNPCOMMAND_HTTP_ERROR;
  289. }
  290. /*DisplayNameValueList(buffer, bufsize);*/
  291. ParseNameValue(buffer, bufsize, &pdata);
  292. free(buffer); buffer = NULL;
  293. /*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
  294. p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress");
  295. if(p) {
  296. strncpy(extIpAdd, p, 16 );
  297. extIpAdd[15] = '\0';
  298. ret = UPNPCOMMAND_SUCCESS;
  299. } else
  300. extIpAdd[0] = '\0';
  301. p = GetValueFromNameValueList(&pdata, "errorCode");
  302. if(p) {
  303. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  304. sscanf(p, "%d", &ret);
  305. }
  306. ClearNameValueList(&pdata);
  307. return ret;
  308. }
  309. LIBSPEC int
  310. UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
  311. const char * extPort,
  312. const char * inPort,
  313. const char * inClient,
  314. const char * desc,
  315. const char * proto,
  316. const char * remoteHost,
  317. const char * leaseDuration)
  318. {
  319. struct UPNParg * AddPortMappingArgs;
  320. char * buffer;
  321. int bufsize;
  322. struct NameValueParserData pdata;
  323. const char * resVal;
  324. int ret;
  325. if(!inPort || !inClient || !proto || !extPort)
  326. return UPNPCOMMAND_INVALID_ARGS;
  327. AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
  328. AddPortMappingArgs[0].elt = "NewRemoteHost";
  329. AddPortMappingArgs[0].val = remoteHost;
  330. AddPortMappingArgs[1].elt = "NewExternalPort";
  331. AddPortMappingArgs[1].val = extPort;
  332. AddPortMappingArgs[2].elt = "NewProtocol";
  333. AddPortMappingArgs[2].val = proto;
  334. AddPortMappingArgs[3].elt = "NewInternalPort";
  335. AddPortMappingArgs[3].val = inPort;
  336. AddPortMappingArgs[4].elt = "NewInternalClient";
  337. AddPortMappingArgs[4].val = inClient;
  338. AddPortMappingArgs[5].elt = "NewEnabled";
  339. AddPortMappingArgs[5].val = "1";
  340. AddPortMappingArgs[6].elt = "NewPortMappingDescription";
  341. AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
  342. AddPortMappingArgs[7].elt = "NewLeaseDuration";
  343. AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0";
  344. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  345. "AddPortMapping", AddPortMappingArgs,
  346. &bufsize))) {
  347. free(AddPortMappingArgs);
  348. return UPNPCOMMAND_HTTP_ERROR;
  349. }
  350. /*DisplayNameValueList(buffer, bufsize);*/
  351. /*buffer[bufsize] = '\0';*/
  352. /*puts(buffer);*/
  353. ParseNameValue(buffer, bufsize, &pdata);
  354. free(buffer); buffer = NULL;
  355. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  356. if(resVal) {
  357. /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
  358. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  359. sscanf(resVal, "%d", &ret);
  360. } else {
  361. ret = UPNPCOMMAND_SUCCESS;
  362. }
  363. ClearNameValueList(&pdata);
  364. free(AddPortMappingArgs);
  365. return ret;
  366. }
  367. LIBSPEC int
  368. UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
  369. const char * extPort, const char * proto,
  370. const char * remoteHost)
  371. {
  372. /*struct NameValueParserData pdata;*/
  373. struct UPNParg * DeletePortMappingArgs;
  374. char * buffer;
  375. int bufsize;
  376. struct NameValueParserData pdata;
  377. const char * resVal;
  378. int ret;
  379. if(!extPort || !proto)
  380. return UPNPCOMMAND_INVALID_ARGS;
  381. DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg));
  382. DeletePortMappingArgs[0].elt = "NewRemoteHost";
  383. DeletePortMappingArgs[0].val = remoteHost;
  384. DeletePortMappingArgs[1].elt = "NewExternalPort";
  385. DeletePortMappingArgs[1].val = extPort;
  386. DeletePortMappingArgs[2].elt = "NewProtocol";
  387. DeletePortMappingArgs[2].val = proto;
  388. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  389. "DeletePortMapping",
  390. DeletePortMappingArgs, &bufsize))) {
  391. free(DeletePortMappingArgs);
  392. return UPNPCOMMAND_HTTP_ERROR;
  393. }
  394. /*DisplayNameValueList(buffer, bufsize);*/
  395. ParseNameValue(buffer, bufsize, &pdata);
  396. free(buffer); buffer = NULL;
  397. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  398. if(resVal) {
  399. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  400. sscanf(resVal, "%d", &ret);
  401. } else {
  402. ret = UPNPCOMMAND_SUCCESS;
  403. }
  404. ClearNameValueList(&pdata);
  405. free(DeletePortMappingArgs);
  406. return ret;
  407. }
  408. LIBSPEC int
  409. UPNP_GetGenericPortMappingEntry(const char * controlURL,
  410. const char * servicetype,
  411. const char * index,
  412. char * extPort,
  413. char * intClient,
  414. char * intPort,
  415. char * protocol,
  416. char * desc,
  417. char * enabled,
  418. char * rHost,
  419. char * duration)
  420. {
  421. struct NameValueParserData pdata;
  422. struct UPNParg * GetPortMappingArgs;
  423. char * buffer;
  424. int bufsize;
  425. char * p;
  426. int r = UPNPCOMMAND_UNKNOWN_ERROR;
  427. if(!index)
  428. return UPNPCOMMAND_INVALID_ARGS;
  429. intClient[0] = '\0';
  430. intPort[0] = '\0';
  431. GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
  432. GetPortMappingArgs[0].elt = "NewPortMappingIndex";
  433. GetPortMappingArgs[0].val = index;
  434. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  435. "GetGenericPortMappingEntry",
  436. GetPortMappingArgs, &bufsize))) {
  437. free(GetPortMappingArgs);
  438. return UPNPCOMMAND_HTTP_ERROR;
  439. }
  440. ParseNameValue(buffer, bufsize, &pdata);
  441. free(buffer); buffer = NULL;
  442. p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
  443. if(p && rHost)
  444. {
  445. strncpy(rHost, p, 64);
  446. rHost[63] = '\0';
  447. }
  448. p = GetValueFromNameValueList(&pdata, "NewExternalPort");
  449. if(p && extPort)
  450. {
  451. strncpy(extPort, p, 6);
  452. extPort[5] = '\0';
  453. r = UPNPCOMMAND_SUCCESS;
  454. }
  455. p = GetValueFromNameValueList(&pdata, "NewProtocol");
  456. if(p && protocol)
  457. {
  458. strncpy(protocol, p, 4);
  459. protocol[3] = '\0';
  460. }
  461. p = GetValueFromNameValueList(&pdata, "NewInternalClient");
  462. if(p && intClient)
  463. {
  464. strncpy(intClient, p, 16);
  465. intClient[15] = '\0';
  466. r = 0;
  467. }
  468. p = GetValueFromNameValueList(&pdata, "NewInternalPort");
  469. if(p && intPort)
  470. {
  471. strncpy(intPort, p, 6);
  472. intPort[5] = '\0';
  473. }
  474. p = GetValueFromNameValueList(&pdata, "NewEnabled");
  475. if(p && enabled)
  476. {
  477. strncpy(enabled, p, 4);
  478. enabled[3] = '\0';
  479. }
  480. p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
  481. if(p && desc)
  482. {
  483. strncpy(desc, p, 80);
  484. desc[79] = '\0';
  485. }
  486. p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
  487. if(p && duration)
  488. {
  489. strncpy(duration, p, 16);
  490. duration[15] = '\0';
  491. }
  492. p = GetValueFromNameValueList(&pdata, "errorCode");
  493. if(p) {
  494. r = UPNPCOMMAND_UNKNOWN_ERROR;
  495. sscanf(p, "%d", &r);
  496. }
  497. ClearNameValueList(&pdata);
  498. free(GetPortMappingArgs);
  499. return r;
  500. }
  501. LIBSPEC int
  502. UPNP_GetPortMappingNumberOfEntries(const char * controlURL,
  503. const char * servicetype,
  504. unsigned int * numEntries)
  505. {
  506. struct NameValueParserData pdata;
  507. char * buffer;
  508. int bufsize;
  509. char* p;
  510. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  511. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  512. "GetPortMappingNumberOfEntries", 0,
  513. &bufsize))) {
  514. return UPNPCOMMAND_HTTP_ERROR;
  515. }
  516. #ifdef DEBUG
  517. DisplayNameValueList(buffer, bufsize);
  518. #endif
  519. ParseNameValue(buffer, bufsize, &pdata);
  520. free(buffer); buffer = NULL;
  521. p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
  522. if(numEntries && p) {
  523. *numEntries = 0;
  524. sscanf(p, "%u", numEntries);
  525. ret = UPNPCOMMAND_SUCCESS;
  526. }
  527. p = GetValueFromNameValueList(&pdata, "errorCode");
  528. if(p) {
  529. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  530. sscanf(p, "%d", &ret);
  531. }
  532. ClearNameValueList(&pdata);
  533. return ret;
  534. }
  535. /* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
  536. * the result is returned in the intClient and intPort strings
  537. * please provide 16 and 6 bytes of data */
  538. LIBSPEC int
  539. UPNP_GetSpecificPortMappingEntry(const char * controlURL,
  540. const char * servicetype,
  541. const char * extPort,
  542. const char * proto,
  543. char * intClient,
  544. char * intPort,
  545. char * desc,
  546. char * enabled,
  547. char * leaseDuration)
  548. {
  549. struct NameValueParserData pdata;
  550. struct UPNParg * GetPortMappingArgs;
  551. char * buffer;
  552. int bufsize;
  553. char * p;
  554. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  555. if(!intPort || !intClient || !extPort || !proto)
  556. return UPNPCOMMAND_INVALID_ARGS;
  557. GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
  558. GetPortMappingArgs[0].elt = "NewRemoteHost";
  559. /* TODO : add remote host ? */
  560. GetPortMappingArgs[1].elt = "NewExternalPort";
  561. GetPortMappingArgs[1].val = extPort;
  562. GetPortMappingArgs[2].elt = "NewProtocol";
  563. GetPortMappingArgs[2].val = proto;
  564. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  565. "GetSpecificPortMappingEntry",
  566. GetPortMappingArgs, &bufsize))) {
  567. free(GetPortMappingArgs);
  568. return UPNPCOMMAND_HTTP_ERROR;
  569. }
  570. /*DisplayNameValueList(buffer, bufsize);*/
  571. ParseNameValue(buffer, bufsize, &pdata);
  572. free(buffer); buffer = NULL;
  573. p = GetValueFromNameValueList(&pdata, "NewInternalClient");
  574. if(p) {
  575. strncpy(intClient, p, 16);
  576. intClient[15] = '\0';
  577. ret = UPNPCOMMAND_SUCCESS;
  578. } else
  579. intClient[0] = '\0';
  580. p = GetValueFromNameValueList(&pdata, "NewInternalPort");
  581. if(p) {
  582. strncpy(intPort, p, 6);
  583. intPort[5] = '\0';
  584. } else
  585. intPort[0] = '\0';
  586. p = GetValueFromNameValueList(&pdata, "NewEnabled");
  587. if(p && enabled) {
  588. strncpy(enabled, p, 4);
  589. enabled[3] = '\0';
  590. }
  591. p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
  592. if(p && desc) {
  593. strncpy(desc, p, 80);
  594. desc[79] = '\0';
  595. }
  596. p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
  597. if(p && leaseDuration)
  598. {
  599. strncpy(leaseDuration, p, 16);
  600. leaseDuration[15] = '\0';
  601. }
  602. p = GetValueFromNameValueList(&pdata, "errorCode");
  603. if(p) {
  604. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  605. sscanf(p, "%d", &ret);
  606. }
  607. ClearNameValueList(&pdata);
  608. free(GetPortMappingArgs);
  609. return ret;
  610. }
  611. /* UPNP_GetListOfPortMappings()
  612. *
  613. * Possible UPNP Error codes :
  614. * 606 Action not Authorized
  615. * 730 PortMappingNotFound - no port mapping is found in the specified range.
  616. * 733 InconsistantParameters - NewStartPort and NewEndPort values are not
  617. * consistent.
  618. */
  619. LIBSPEC int
  620. UPNP_GetListOfPortMappings(const char * controlURL,
  621. const char * servicetype,
  622. const char * startPort,
  623. const char * endPort,
  624. const char * protocol,
  625. const char * numberOfPorts,
  626. struct PortMappingParserData * data)
  627. {
  628. struct NameValueParserData pdata;
  629. struct UPNParg * GetListOfPortMappingsArgs;
  630. const char * p;
  631. char * buffer;
  632. int bufsize;
  633. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  634. if(!startPort || !endPort || !protocol)
  635. return UPNPCOMMAND_INVALID_ARGS;
  636. GetListOfPortMappingsArgs = calloc(6, sizeof(struct UPNParg));
  637. GetListOfPortMappingsArgs[0].elt = "NewStartPort";
  638. GetListOfPortMappingsArgs[0].val = startPort;
  639. GetListOfPortMappingsArgs[1].elt = "NewEndPort";
  640. GetListOfPortMappingsArgs[1].val = endPort;
  641. GetListOfPortMappingsArgs[2].elt = "NewProtocol";
  642. GetListOfPortMappingsArgs[2].val = protocol;
  643. GetListOfPortMappingsArgs[3].elt = "NewManage";
  644. GetListOfPortMappingsArgs[3].val = "1";
  645. GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts";
  646. GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000";
  647. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  648. "GetListOfPortMappings",
  649. GetListOfPortMappingsArgs, &bufsize))) {
  650. free(GetListOfPortMappingsArgs);
  651. return UPNPCOMMAND_HTTP_ERROR;
  652. }
  653. free(GetListOfPortMappingsArgs);
  654. /*DisplayNameValueList(buffer, bufsize);*/
  655. ParseNameValue(buffer, bufsize, &pdata);
  656. free(buffer); buffer = NULL;
  657. /*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/
  658. /*if(p) {
  659. printf("NewPortListing : %s\n", p);
  660. }*/
  661. /*printf("NewPortListing(%d chars) : %s\n",
  662. pdata.portListingLength, pdata.portListing);*/
  663. if(pdata.portListing)
  664. {
  665. /*struct PortMapping * pm;
  666. int i = 0;*/
  667. ParsePortListing(pdata.portListing, pdata.portListingLength,
  668. data);
  669. ret = UPNPCOMMAND_SUCCESS;
  670. /*
  671. for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next)
  672. {
  673. printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n",
  674. i, pm->protocol, pm->externalPort, pm->internalClient,
  675. pm->internalPort,
  676. pm->description, pm->remoteHost);
  677. i++;
  678. }
  679. */
  680. /*FreePortListing(&data);*/
  681. }
  682. p = GetValueFromNameValueList(&pdata, "errorCode");
  683. if(p) {
  684. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  685. sscanf(p, "%d", &ret);
  686. }
  687. ClearNameValueList(&pdata);
  688. //printf("%.*s", bufsize, buffer);
  689. return ret;
  690. }
  691. /* IGD:2, functions for service WANIPv6FirewallControl:1 */
  692. LIBSPEC int
  693. UPNP_GetFirewallStatus(const char * controlURL,
  694. const char * servicetype,
  695. int * firewallEnabled,
  696. int * inboundPinholeAllowed)
  697. {
  698. struct NameValueParserData pdata;
  699. char * buffer;
  700. int bufsize;
  701. char * fe, *ipa, *p;
  702. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  703. if(!firewallEnabled && !inboundPinholeAllowed)
  704. return UPNPCOMMAND_INVALID_ARGS;
  705. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  706. "GetFirewallStatus", 0, &bufsize);
  707. if(!buffer) {
  708. return UPNPCOMMAND_HTTP_ERROR;
  709. }
  710. ParseNameValue(buffer, bufsize, &pdata);
  711. free(buffer); buffer = NULL;
  712. fe = GetValueFromNameValueList(&pdata, "FirewallEnabled");
  713. ipa = GetValueFromNameValueList(&pdata, "InboundPinholeAllowed");
  714. if(ipa && fe)
  715. ret = UPNPCOMMAND_SUCCESS;
  716. if(fe)
  717. *firewallEnabled = my_atoui(fe);
  718. /*else
  719. *firewallEnabled = 0;*/
  720. if(ipa)
  721. *inboundPinholeAllowed = my_atoui(ipa);
  722. /*else
  723. *inboundPinholeAllowed = 0;*/
  724. p = GetValueFromNameValueList(&pdata, "errorCode");
  725. if(p)
  726. {
  727. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  728. sscanf(p, "%d", &ret);
  729. }
  730. ClearNameValueList(&pdata);
  731. return ret;
  732. }
  733. LIBSPEC int
  734. UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
  735. const char * remoteHost,
  736. const char * remotePort,
  737. const char * intClient,
  738. const char * intPort,
  739. const char * proto,
  740. int * opTimeout)
  741. {
  742. struct UPNParg * GetOutboundPinholeTimeoutArgs;
  743. char * buffer;
  744. int bufsize;
  745. struct NameValueParserData pdata;
  746. const char * resVal;
  747. char * p;
  748. int ret;
  749. if(!intPort || !intClient || !proto || !remotePort || !remoteHost)
  750. return UPNPCOMMAND_INVALID_ARGS;
  751. GetOutboundPinholeTimeoutArgs = calloc(6, sizeof(struct UPNParg));
  752. GetOutboundPinholeTimeoutArgs[0].elt = "RemoteHost";
  753. GetOutboundPinholeTimeoutArgs[0].val = remoteHost;
  754. GetOutboundPinholeTimeoutArgs[1].elt = "RemotePort";
  755. GetOutboundPinholeTimeoutArgs[1].val = remotePort;
  756. GetOutboundPinholeTimeoutArgs[2].elt = "Protocol";
  757. GetOutboundPinholeTimeoutArgs[2].val = proto;
  758. GetOutboundPinholeTimeoutArgs[3].elt = "InternalPort";
  759. GetOutboundPinholeTimeoutArgs[3].val = intPort;
  760. GetOutboundPinholeTimeoutArgs[4].elt = "InternalClient";
  761. GetOutboundPinholeTimeoutArgs[4].val = intClient;
  762. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  763. "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize);
  764. if(!buffer)
  765. return UPNPCOMMAND_HTTP_ERROR;
  766. ParseNameValue(buffer, bufsize, &pdata);
  767. free(buffer); buffer = NULL;
  768. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  769. if(resVal)
  770. {
  771. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  772. sscanf(resVal, "%d", &ret);
  773. }
  774. else
  775. {
  776. ret = UPNPCOMMAND_SUCCESS;
  777. p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout");
  778. if(p)
  779. *opTimeout = my_atoui(p);
  780. }
  781. ClearNameValueList(&pdata);
  782. free(GetOutboundPinholeTimeoutArgs);
  783. return ret;
  784. }
  785. LIBSPEC int
  786. UPNP_AddPinhole(const char * controlURL, const char * servicetype,
  787. const char * remoteHost,
  788. const char * remotePort,
  789. const char * intClient,
  790. const char * intPort,
  791. const char * proto,
  792. const char * leaseTime,
  793. char * uniqueID)
  794. {
  795. struct UPNParg * AddPinholeArgs;
  796. char * buffer;
  797. int bufsize;
  798. struct NameValueParserData pdata;
  799. const char * resVal;
  800. char * p;
  801. int ret;
  802. if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime)
  803. return UPNPCOMMAND_INVALID_ARGS;
  804. AddPinholeArgs = calloc(7, sizeof(struct UPNParg));
  805. // RemoteHost can be wilcarded
  806. if(strncmp(remoteHost, "empty", 5)==0)
  807. {
  808. AddPinholeArgs[0].elt = "RemoteHost";
  809. AddPinholeArgs[0].val = "";
  810. }
  811. else
  812. {
  813. AddPinholeArgs[0].elt = "RemoteHost";
  814. AddPinholeArgs[0].val = remoteHost;
  815. }
  816. AddPinholeArgs[1].elt = "RemotePort";
  817. AddPinholeArgs[1].val = remotePort;
  818. AddPinholeArgs[2].elt = "Protocol";
  819. AddPinholeArgs[2].val = proto;
  820. AddPinholeArgs[3].elt = "InternalPort";
  821. AddPinholeArgs[3].val = intPort;
  822. if(strncmp(intClient, "empty", 5)==0)
  823. {
  824. AddPinholeArgs[4].elt = "InternalClient";
  825. AddPinholeArgs[4].val = "";
  826. }
  827. else
  828. {
  829. AddPinholeArgs[4].elt = "InternalClient";
  830. AddPinholeArgs[4].val = intClient;
  831. }
  832. AddPinholeArgs[5].elt = "LeaseTime";
  833. AddPinholeArgs[5].val = leaseTime;
  834. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  835. "AddPinhole", AddPinholeArgs, &bufsize);
  836. if(!buffer)
  837. return UPNPCOMMAND_HTTP_ERROR;
  838. ParseNameValue(buffer, bufsize, &pdata);
  839. free(buffer); buffer = NULL;
  840. p = GetValueFromNameValueList(&pdata, "UniqueID");
  841. if(p)
  842. {
  843. strncpy(uniqueID, p, 8);
  844. uniqueID[7] = '\0';
  845. }
  846. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  847. if(resVal)
  848. {
  849. //printf("AddPortMapping errorCode = '%s'\n", resVal);
  850. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  851. sscanf(resVal, "%d", &ret);
  852. }
  853. else
  854. {
  855. ret = UPNPCOMMAND_SUCCESS;
  856. }
  857. ClearNameValueList(&pdata);
  858. free(AddPinholeArgs);
  859. return ret;
  860. }
  861. LIBSPEC int
  862. UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
  863. const char * uniqueID,
  864. const char * leaseTime)
  865. {
  866. struct UPNParg * UpdatePinholeArgs;
  867. char * buffer;
  868. int bufsize;
  869. struct NameValueParserData pdata;
  870. const char * resVal;
  871. int ret;
  872. if(!uniqueID || !leaseTime)
  873. return UPNPCOMMAND_INVALID_ARGS;
  874. UpdatePinholeArgs = calloc(3, sizeof(struct UPNParg));
  875. UpdatePinholeArgs[0].elt = "UniqueID";
  876. UpdatePinholeArgs[0].val = uniqueID;
  877. UpdatePinholeArgs[1].elt = "NewLeaseTime";
  878. UpdatePinholeArgs[1].val = leaseTime;
  879. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  880. "UpdatePinhole", UpdatePinholeArgs, &bufsize);
  881. if(!buffer)
  882. return UPNPCOMMAND_HTTP_ERROR;
  883. ParseNameValue(buffer, bufsize, &pdata);
  884. free(buffer); buffer = NULL;
  885. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  886. if(resVal)
  887. {
  888. /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
  889. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  890. sscanf(resVal, "%d", &ret);
  891. }
  892. else
  893. {
  894. ret = UPNPCOMMAND_SUCCESS;
  895. }
  896. ClearNameValueList(&pdata);
  897. free(UpdatePinholeArgs);
  898. return ret;
  899. }
  900. LIBSPEC int
  901. UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID)
  902. {
  903. /*struct NameValueParserData pdata;*/
  904. struct UPNParg * DeletePinholeArgs;
  905. char * buffer;
  906. int bufsize;
  907. struct NameValueParserData pdata;
  908. const char * resVal;
  909. int ret;
  910. if(!uniqueID)
  911. return UPNPCOMMAND_INVALID_ARGS;
  912. DeletePinholeArgs = calloc(2, sizeof(struct UPNParg));
  913. DeletePinholeArgs[0].elt = "UniqueID";
  914. DeletePinholeArgs[0].val = uniqueID;
  915. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  916. "DeletePinhole", DeletePinholeArgs, &bufsize);
  917. if(!buffer)
  918. return UPNPCOMMAND_HTTP_ERROR;
  919. /*DisplayNameValueList(buffer, bufsize);*/
  920. ParseNameValue(buffer, bufsize, &pdata);
  921. free(buffer); buffer = NULL;
  922. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  923. if(resVal)
  924. {
  925. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  926. sscanf(resVal, "%d", &ret);
  927. }
  928. else
  929. {
  930. ret = UPNPCOMMAND_SUCCESS;
  931. }
  932. ClearNameValueList(&pdata);
  933. free(DeletePinholeArgs);
  934. return ret;
  935. }
  936. LIBSPEC int
  937. UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
  938. const char * uniqueID, int * isWorking)
  939. {
  940. struct NameValueParserData pdata;
  941. struct UPNParg * CheckPinholeWorkingArgs;
  942. char * buffer;
  943. int bufsize;
  944. char * p;
  945. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  946. if(!uniqueID)
  947. return UPNPCOMMAND_INVALID_ARGS;
  948. CheckPinholeWorkingArgs = calloc(4, sizeof(struct UPNParg));
  949. CheckPinholeWorkingArgs[0].elt = "UniqueID";
  950. CheckPinholeWorkingArgs[0].val = uniqueID;
  951. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  952. "CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize);
  953. if(!buffer)
  954. return UPNPCOMMAND_HTTP_ERROR;
  955. ParseNameValue(buffer, bufsize, &pdata);
  956. free(buffer); buffer = NULL;
  957. p = GetValueFromNameValueList(&pdata, "IsWorking");
  958. if(p)
  959. {
  960. *isWorking=my_atoui(p);
  961. ret = UPNPCOMMAND_SUCCESS;
  962. }
  963. else
  964. *isWorking = 0;
  965. p = GetValueFromNameValueList(&pdata, "errorCode");
  966. if(p)
  967. {
  968. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  969. sscanf(p, "%d", &ret);
  970. }
  971. ClearNameValueList(&pdata);
  972. free(CheckPinholeWorkingArgs);
  973. return ret;
  974. }
  975. LIBSPEC int
  976. UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
  977. const char * uniqueID, int * packets)
  978. {
  979. struct NameValueParserData pdata;
  980. struct UPNParg * GetPinholePacketsArgs;
  981. char * buffer;
  982. int bufsize;
  983. char * p;
  984. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  985. if(!uniqueID)
  986. return UPNPCOMMAND_INVALID_ARGS;
  987. GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg));
  988. GetPinholePacketsArgs[0].elt = "UniqueID";
  989. GetPinholePacketsArgs[0].val = uniqueID;
  990. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  991. "GetPinholePackets", GetPinholePacketsArgs, &bufsize);
  992. if(!buffer)
  993. return UPNPCOMMAND_HTTP_ERROR;
  994. ParseNameValue(buffer, bufsize, &pdata);
  995. free(buffer); buffer = NULL;
  996. p = GetValueFromNameValueList(&pdata, "PinholePackets");
  997. if(p)
  998. {
  999. *packets=my_atoui(p);
  1000. ret = UPNPCOMMAND_SUCCESS;
  1001. }
  1002. p = GetValueFromNameValueList(&pdata, "errorCode");
  1003. if(p)
  1004. {
  1005. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  1006. sscanf(p, "%d", &ret);
  1007. }
  1008. ClearNameValueList(&pdata);
  1009. free(GetPinholePacketsArgs);
  1010. return ret;
  1011. }