upnpcommands.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237
  1. /* $Id: upnpcommands.c,v 1.47 2016/03/07 12:26:48 nanard Exp $ */
  2. /* Project : miniupnp
  3. * Author : Thomas Bernard
  4. * Copyright (c) 2005-2015 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. MINIUPNP_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. MINIUPNP_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. MINIUPNP_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. MINIUPNP_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. MINIUPNP_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. MINIUPNP_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. MINIUPNP_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. MINIUPNP_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. MINIUPNP_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. if(AddPortMappingArgs == NULL)
  329. return UPNPCOMMAND_MEM_ALLOC_ERROR;
  330. AddPortMappingArgs[0].elt = "NewRemoteHost";
  331. AddPortMappingArgs[0].val = remoteHost;
  332. AddPortMappingArgs[1].elt = "NewExternalPort";
  333. AddPortMappingArgs[1].val = extPort;
  334. AddPortMappingArgs[2].elt = "NewProtocol";
  335. AddPortMappingArgs[2].val = proto;
  336. AddPortMappingArgs[3].elt = "NewInternalPort";
  337. AddPortMappingArgs[3].val = inPort;
  338. AddPortMappingArgs[4].elt = "NewInternalClient";
  339. AddPortMappingArgs[4].val = inClient;
  340. AddPortMappingArgs[5].elt = "NewEnabled";
  341. AddPortMappingArgs[5].val = "1";
  342. AddPortMappingArgs[6].elt = "NewPortMappingDescription";
  343. AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
  344. AddPortMappingArgs[7].elt = "NewLeaseDuration";
  345. AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0";
  346. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  347. "AddPortMapping", AddPortMappingArgs,
  348. &bufsize))) {
  349. free(AddPortMappingArgs);
  350. return UPNPCOMMAND_HTTP_ERROR;
  351. }
  352. /*DisplayNameValueList(buffer, bufsize);*/
  353. /*buffer[bufsize] = '\0';*/
  354. /*puts(buffer);*/
  355. ParseNameValue(buffer, bufsize, &pdata);
  356. free(buffer); buffer = NULL;
  357. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  358. if(resVal) {
  359. /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
  360. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  361. sscanf(resVal, "%d", &ret);
  362. } else {
  363. ret = UPNPCOMMAND_SUCCESS;
  364. }
  365. ClearNameValueList(&pdata);
  366. free(AddPortMappingArgs);
  367. return ret;
  368. }
  369. MINIUPNP_LIBSPEC int
  370. UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype,
  371. const char * extPort,
  372. const char * inPort,
  373. const char * inClient,
  374. const char * desc,
  375. const char * proto,
  376. const char * remoteHost,
  377. const char * leaseDuration,
  378. char * reservedPort)
  379. {
  380. struct UPNParg * AddPortMappingArgs;
  381. char * buffer;
  382. int bufsize;
  383. struct NameValueParserData pdata;
  384. const char * resVal;
  385. int ret;
  386. if(!inPort || !inClient || !proto || !extPort)
  387. return UPNPCOMMAND_INVALID_ARGS;
  388. AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
  389. if(AddPortMappingArgs == NULL)
  390. return UPNPCOMMAND_MEM_ALLOC_ERROR;
  391. AddPortMappingArgs[0].elt = "NewRemoteHost";
  392. AddPortMappingArgs[0].val = remoteHost;
  393. AddPortMappingArgs[1].elt = "NewExternalPort";
  394. AddPortMappingArgs[1].val = extPort;
  395. AddPortMappingArgs[2].elt = "NewProtocol";
  396. AddPortMappingArgs[2].val = proto;
  397. AddPortMappingArgs[3].elt = "NewInternalPort";
  398. AddPortMappingArgs[3].val = inPort;
  399. AddPortMappingArgs[4].elt = "NewInternalClient";
  400. AddPortMappingArgs[4].val = inClient;
  401. AddPortMappingArgs[5].elt = "NewEnabled";
  402. AddPortMappingArgs[5].val = "1";
  403. AddPortMappingArgs[6].elt = "NewPortMappingDescription";
  404. AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
  405. AddPortMappingArgs[7].elt = "NewLeaseDuration";
  406. AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0";
  407. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  408. "AddAnyPortMapping", AddPortMappingArgs,
  409. &bufsize))) {
  410. free(AddPortMappingArgs);
  411. return UPNPCOMMAND_HTTP_ERROR;
  412. }
  413. ParseNameValue(buffer, bufsize, &pdata);
  414. free(buffer); buffer = NULL;
  415. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  416. if(resVal) {
  417. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  418. sscanf(resVal, "%d", &ret);
  419. } else {
  420. char *p;
  421. p = GetValueFromNameValueList(&pdata, "NewReservedPort");
  422. if(p) {
  423. strncpy(reservedPort, p, 6);
  424. reservedPort[5] = '\0';
  425. ret = UPNPCOMMAND_SUCCESS;
  426. } else {
  427. ret = UPNPCOMMAND_INVALID_RESPONSE;
  428. }
  429. }
  430. ClearNameValueList(&pdata);
  431. free(AddPortMappingArgs);
  432. return ret;
  433. }
  434. MINIUPNP_LIBSPEC int
  435. UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
  436. const char * extPort, const char * proto,
  437. const char * remoteHost)
  438. {
  439. /*struct NameValueParserData pdata;*/
  440. struct UPNParg * DeletePortMappingArgs;
  441. char * buffer;
  442. int bufsize;
  443. struct NameValueParserData pdata;
  444. const char * resVal;
  445. int ret;
  446. if(!extPort || !proto)
  447. return UPNPCOMMAND_INVALID_ARGS;
  448. DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg));
  449. if(DeletePortMappingArgs == NULL)
  450. return UPNPCOMMAND_MEM_ALLOC_ERROR;
  451. DeletePortMappingArgs[0].elt = "NewRemoteHost";
  452. DeletePortMappingArgs[0].val = remoteHost;
  453. DeletePortMappingArgs[1].elt = "NewExternalPort";
  454. DeletePortMappingArgs[1].val = extPort;
  455. DeletePortMappingArgs[2].elt = "NewProtocol";
  456. DeletePortMappingArgs[2].val = proto;
  457. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  458. "DeletePortMapping",
  459. DeletePortMappingArgs, &bufsize))) {
  460. free(DeletePortMappingArgs);
  461. return UPNPCOMMAND_HTTP_ERROR;
  462. }
  463. /*DisplayNameValueList(buffer, bufsize);*/
  464. ParseNameValue(buffer, bufsize, &pdata);
  465. free(buffer); buffer = NULL;
  466. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  467. if(resVal) {
  468. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  469. sscanf(resVal, "%d", &ret);
  470. } else {
  471. ret = UPNPCOMMAND_SUCCESS;
  472. }
  473. ClearNameValueList(&pdata);
  474. free(DeletePortMappingArgs);
  475. return ret;
  476. }
  477. MINIUPNP_LIBSPEC int
  478. UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype,
  479. const char * extPortStart, const char * extPortEnd,
  480. const char * proto,
  481. const char * manage)
  482. {
  483. struct UPNParg * DeletePortMappingArgs;
  484. char * buffer;
  485. int bufsize;
  486. struct NameValueParserData pdata;
  487. const char * resVal;
  488. int ret;
  489. if(!extPortStart || !extPortEnd || !proto || !manage)
  490. return UPNPCOMMAND_INVALID_ARGS;
  491. DeletePortMappingArgs = calloc(5, sizeof(struct UPNParg));
  492. if(DeletePortMappingArgs == NULL)
  493. return UPNPCOMMAND_MEM_ALLOC_ERROR;
  494. DeletePortMappingArgs[0].elt = "NewStartPort";
  495. DeletePortMappingArgs[0].val = extPortStart;
  496. DeletePortMappingArgs[1].elt = "NewEndPort";
  497. DeletePortMappingArgs[1].val = extPortEnd;
  498. DeletePortMappingArgs[2].elt = "NewProtocol";
  499. DeletePortMappingArgs[2].val = proto;
  500. DeletePortMappingArgs[3].elt = "NewManage";
  501. DeletePortMappingArgs[3].val = manage;
  502. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  503. "DeletePortMappingRange",
  504. DeletePortMappingArgs, &bufsize))) {
  505. free(DeletePortMappingArgs);
  506. return UPNPCOMMAND_HTTP_ERROR;
  507. }
  508. ParseNameValue(buffer, bufsize, &pdata);
  509. free(buffer); buffer = NULL;
  510. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  511. if(resVal) {
  512. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  513. sscanf(resVal, "%d", &ret);
  514. } else {
  515. ret = UPNPCOMMAND_SUCCESS;
  516. }
  517. ClearNameValueList(&pdata);
  518. free(DeletePortMappingArgs);
  519. return ret;
  520. }
  521. MINIUPNP_LIBSPEC int
  522. UPNP_GetGenericPortMappingEntry(const char * controlURL,
  523. const char * servicetype,
  524. const char * index,
  525. char * extPort,
  526. char * intClient,
  527. char * intPort,
  528. char * protocol,
  529. char * desc,
  530. char * enabled,
  531. char * rHost,
  532. char * duration)
  533. {
  534. struct NameValueParserData pdata;
  535. struct UPNParg * GetPortMappingArgs;
  536. char * buffer;
  537. int bufsize;
  538. char * p;
  539. int r = UPNPCOMMAND_UNKNOWN_ERROR;
  540. if(!index)
  541. return UPNPCOMMAND_INVALID_ARGS;
  542. intClient[0] = '\0';
  543. intPort[0] = '\0';
  544. GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
  545. if(GetPortMappingArgs == NULL)
  546. return UPNPCOMMAND_MEM_ALLOC_ERROR;
  547. GetPortMappingArgs[0].elt = "NewPortMappingIndex";
  548. GetPortMappingArgs[0].val = index;
  549. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  550. "GetGenericPortMappingEntry",
  551. GetPortMappingArgs, &bufsize))) {
  552. free(GetPortMappingArgs);
  553. return UPNPCOMMAND_HTTP_ERROR;
  554. }
  555. ParseNameValue(buffer, bufsize, &pdata);
  556. free(buffer); buffer = NULL;
  557. p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
  558. if(p && rHost)
  559. {
  560. strncpy(rHost, p, 64);
  561. rHost[63] = '\0';
  562. }
  563. p = GetValueFromNameValueList(&pdata, "NewExternalPort");
  564. if(p && extPort)
  565. {
  566. strncpy(extPort, p, 6);
  567. extPort[5] = '\0';
  568. r = UPNPCOMMAND_SUCCESS;
  569. }
  570. p = GetValueFromNameValueList(&pdata, "NewProtocol");
  571. if(p && protocol)
  572. {
  573. strncpy(protocol, p, 4);
  574. protocol[3] = '\0';
  575. }
  576. p = GetValueFromNameValueList(&pdata, "NewInternalClient");
  577. if(p)
  578. {
  579. strncpy(intClient, p, 16);
  580. intClient[15] = '\0';
  581. r = 0;
  582. }
  583. p = GetValueFromNameValueList(&pdata, "NewInternalPort");
  584. if(p)
  585. {
  586. strncpy(intPort, p, 6);
  587. intPort[5] = '\0';
  588. }
  589. p = GetValueFromNameValueList(&pdata, "NewEnabled");
  590. if(p && enabled)
  591. {
  592. strncpy(enabled, p, 4);
  593. enabled[3] = '\0';
  594. }
  595. p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
  596. if(p && desc)
  597. {
  598. strncpy(desc, p, 80);
  599. desc[79] = '\0';
  600. }
  601. p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
  602. if(p && duration)
  603. {
  604. strncpy(duration, p, 16);
  605. duration[15] = '\0';
  606. }
  607. p = GetValueFromNameValueList(&pdata, "errorCode");
  608. if(p) {
  609. r = UPNPCOMMAND_UNKNOWN_ERROR;
  610. sscanf(p, "%d", &r);
  611. }
  612. ClearNameValueList(&pdata);
  613. free(GetPortMappingArgs);
  614. return r;
  615. }
  616. MINIUPNP_LIBSPEC int
  617. UPNP_GetPortMappingNumberOfEntries(const char * controlURL,
  618. const char * servicetype,
  619. unsigned int * numEntries)
  620. {
  621. struct NameValueParserData pdata;
  622. char * buffer;
  623. int bufsize;
  624. char* p;
  625. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  626. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  627. "GetPortMappingNumberOfEntries", 0,
  628. &bufsize))) {
  629. return UPNPCOMMAND_HTTP_ERROR;
  630. }
  631. #ifdef DEBUG
  632. DisplayNameValueList(buffer, bufsize);
  633. #endif
  634. ParseNameValue(buffer, bufsize, &pdata);
  635. free(buffer); buffer = NULL;
  636. p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
  637. if(numEntries && p) {
  638. *numEntries = 0;
  639. sscanf(p, "%u", numEntries);
  640. ret = UPNPCOMMAND_SUCCESS;
  641. }
  642. p = GetValueFromNameValueList(&pdata, "errorCode");
  643. if(p) {
  644. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  645. sscanf(p, "%d", &ret);
  646. }
  647. ClearNameValueList(&pdata);
  648. return ret;
  649. }
  650. /* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
  651. * the result is returned in the intClient and intPort strings
  652. * please provide 16 and 6 bytes of data */
  653. MINIUPNP_LIBSPEC int
  654. UPNP_GetSpecificPortMappingEntry(const char * controlURL,
  655. const char * servicetype,
  656. const char * extPort,
  657. const char * proto,
  658. const char * remoteHost,
  659. char * intClient,
  660. char * intPort,
  661. char * desc,
  662. char * enabled,
  663. char * leaseDuration)
  664. {
  665. struct NameValueParserData pdata;
  666. struct UPNParg * GetPortMappingArgs;
  667. char * buffer;
  668. int bufsize;
  669. char * p;
  670. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  671. if(!intPort || !intClient || !extPort || !proto)
  672. return UPNPCOMMAND_INVALID_ARGS;
  673. GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
  674. if(GetPortMappingArgs == NULL)
  675. return UPNPCOMMAND_MEM_ALLOC_ERROR;
  676. GetPortMappingArgs[0].elt = "NewRemoteHost";
  677. GetPortMappingArgs[0].val = remoteHost;
  678. GetPortMappingArgs[1].elt = "NewExternalPort";
  679. GetPortMappingArgs[1].val = extPort;
  680. GetPortMappingArgs[2].elt = "NewProtocol";
  681. GetPortMappingArgs[2].val = proto;
  682. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  683. "GetSpecificPortMappingEntry",
  684. GetPortMappingArgs, &bufsize))) {
  685. free(GetPortMappingArgs);
  686. return UPNPCOMMAND_HTTP_ERROR;
  687. }
  688. /*DisplayNameValueList(buffer, bufsize);*/
  689. ParseNameValue(buffer, bufsize, &pdata);
  690. free(buffer); buffer = NULL;
  691. p = GetValueFromNameValueList(&pdata, "NewInternalClient");
  692. if(p) {
  693. strncpy(intClient, p, 16);
  694. intClient[15] = '\0';
  695. ret = UPNPCOMMAND_SUCCESS;
  696. } else
  697. intClient[0] = '\0';
  698. p = GetValueFromNameValueList(&pdata, "NewInternalPort");
  699. if(p) {
  700. strncpy(intPort, p, 6);
  701. intPort[5] = '\0';
  702. } else
  703. intPort[0] = '\0';
  704. p = GetValueFromNameValueList(&pdata, "NewEnabled");
  705. if(p && enabled) {
  706. strncpy(enabled, p, 4);
  707. enabled[3] = '\0';
  708. }
  709. p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
  710. if(p && desc) {
  711. strncpy(desc, p, 80);
  712. desc[79] = '\0';
  713. }
  714. p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
  715. if(p && leaseDuration)
  716. {
  717. strncpy(leaseDuration, p, 16);
  718. leaseDuration[15] = '\0';
  719. }
  720. p = GetValueFromNameValueList(&pdata, "errorCode");
  721. if(p) {
  722. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  723. sscanf(p, "%d", &ret);
  724. }
  725. ClearNameValueList(&pdata);
  726. free(GetPortMappingArgs);
  727. return ret;
  728. }
  729. /* UPNP_GetListOfPortMappings()
  730. *
  731. * Possible UPNP Error codes :
  732. * 606 Action not Authorized
  733. * 730 PortMappingNotFound - no port mapping is found in the specified range.
  734. * 733 InconsistantParameters - NewStartPort and NewEndPort values are not
  735. * consistent.
  736. */
  737. MINIUPNP_LIBSPEC int
  738. UPNP_GetListOfPortMappings(const char * controlURL,
  739. const char * servicetype,
  740. const char * startPort,
  741. const char * endPort,
  742. const char * protocol,
  743. const char * numberOfPorts,
  744. struct PortMappingParserData * data)
  745. {
  746. struct NameValueParserData pdata;
  747. struct UPNParg * GetListOfPortMappingsArgs;
  748. const char * p;
  749. char * buffer;
  750. int bufsize;
  751. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  752. if(!startPort || !endPort || !protocol)
  753. return UPNPCOMMAND_INVALID_ARGS;
  754. GetListOfPortMappingsArgs = calloc(6, sizeof(struct UPNParg));
  755. if(GetListOfPortMappingsArgs == NULL)
  756. return UPNPCOMMAND_MEM_ALLOC_ERROR;
  757. GetListOfPortMappingsArgs[0].elt = "NewStartPort";
  758. GetListOfPortMappingsArgs[0].val = startPort;
  759. GetListOfPortMappingsArgs[1].elt = "NewEndPort";
  760. GetListOfPortMappingsArgs[1].val = endPort;
  761. GetListOfPortMappingsArgs[2].elt = "NewProtocol";
  762. GetListOfPortMappingsArgs[2].val = protocol;
  763. GetListOfPortMappingsArgs[3].elt = "NewManage";
  764. GetListOfPortMappingsArgs[3].val = "1";
  765. GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts";
  766. GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000";
  767. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  768. "GetListOfPortMappings",
  769. GetListOfPortMappingsArgs, &bufsize))) {
  770. free(GetListOfPortMappingsArgs);
  771. return UPNPCOMMAND_HTTP_ERROR;
  772. }
  773. free(GetListOfPortMappingsArgs);
  774. /*DisplayNameValueList(buffer, bufsize);*/
  775. ParseNameValue(buffer, bufsize, &pdata);
  776. free(buffer); buffer = NULL;
  777. /*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/
  778. /*if(p) {
  779. printf("NewPortListing : %s\n", p);
  780. }*/
  781. /*printf("NewPortListing(%d chars) : %s\n",
  782. pdata.portListingLength, pdata.portListing);*/
  783. if(pdata.portListing)
  784. {
  785. /*struct PortMapping * pm;
  786. int i = 0;*/
  787. ParsePortListing(pdata.portListing, pdata.portListingLength,
  788. data);
  789. ret = UPNPCOMMAND_SUCCESS;
  790. /*
  791. for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next)
  792. {
  793. printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n",
  794. i, pm->protocol, pm->externalPort, pm->internalClient,
  795. pm->internalPort,
  796. pm->description, pm->remoteHost);
  797. i++;
  798. }
  799. */
  800. /*FreePortListing(&data);*/
  801. }
  802. p = GetValueFromNameValueList(&pdata, "errorCode");
  803. if(p) {
  804. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  805. sscanf(p, "%d", &ret);
  806. }
  807. ClearNameValueList(&pdata);
  808. /*printf("%.*s", bufsize, buffer);*/
  809. return ret;
  810. }
  811. /* IGD:2, functions for service WANIPv6FirewallControl:1 */
  812. MINIUPNP_LIBSPEC int
  813. UPNP_GetFirewallStatus(const char * controlURL,
  814. const char * servicetype,
  815. int * firewallEnabled,
  816. int * inboundPinholeAllowed)
  817. {
  818. struct NameValueParserData pdata;
  819. char * buffer;
  820. int bufsize;
  821. char * fe, *ipa, *p;
  822. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  823. if(!firewallEnabled || !inboundPinholeAllowed)
  824. return UPNPCOMMAND_INVALID_ARGS;
  825. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  826. "GetFirewallStatus", 0, &bufsize);
  827. if(!buffer) {
  828. return UPNPCOMMAND_HTTP_ERROR;
  829. }
  830. ParseNameValue(buffer, bufsize, &pdata);
  831. free(buffer); buffer = NULL;
  832. fe = GetValueFromNameValueList(&pdata, "FirewallEnabled");
  833. ipa = GetValueFromNameValueList(&pdata, "InboundPinholeAllowed");
  834. if(ipa && fe)
  835. ret = UPNPCOMMAND_SUCCESS;
  836. if(fe)
  837. *firewallEnabled = my_atoui(fe);
  838. /*else
  839. *firewallEnabled = 0;*/
  840. if(ipa)
  841. *inboundPinholeAllowed = my_atoui(ipa);
  842. /*else
  843. *inboundPinholeAllowed = 0;*/
  844. p = GetValueFromNameValueList(&pdata, "errorCode");
  845. if(p)
  846. {
  847. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  848. sscanf(p, "%d", &ret);
  849. }
  850. ClearNameValueList(&pdata);
  851. return ret;
  852. }
  853. MINIUPNP_LIBSPEC int
  854. UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
  855. const char * remoteHost,
  856. const char * remotePort,
  857. const char * intClient,
  858. const char * intPort,
  859. const char * proto,
  860. int * opTimeout)
  861. {
  862. struct UPNParg * GetOutboundPinholeTimeoutArgs;
  863. char * buffer;
  864. int bufsize;
  865. struct NameValueParserData pdata;
  866. const char * resVal;
  867. char * p;
  868. int ret;
  869. if(!intPort || !intClient || !proto || !remotePort || !remoteHost)
  870. return UPNPCOMMAND_INVALID_ARGS;
  871. GetOutboundPinholeTimeoutArgs = calloc(6, sizeof(struct UPNParg));
  872. if(GetOutboundPinholeTimeoutArgs == NULL)
  873. return UPNPCOMMAND_MEM_ALLOC_ERROR;
  874. GetOutboundPinholeTimeoutArgs[0].elt = "RemoteHost";
  875. GetOutboundPinholeTimeoutArgs[0].val = remoteHost;
  876. GetOutboundPinholeTimeoutArgs[1].elt = "RemotePort";
  877. GetOutboundPinholeTimeoutArgs[1].val = remotePort;
  878. GetOutboundPinholeTimeoutArgs[2].elt = "Protocol";
  879. GetOutboundPinholeTimeoutArgs[2].val = proto;
  880. GetOutboundPinholeTimeoutArgs[3].elt = "InternalPort";
  881. GetOutboundPinholeTimeoutArgs[3].val = intPort;
  882. GetOutboundPinholeTimeoutArgs[4].elt = "InternalClient";
  883. GetOutboundPinholeTimeoutArgs[4].val = intClient;
  884. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  885. "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize);
  886. if(!buffer)
  887. return UPNPCOMMAND_HTTP_ERROR;
  888. ParseNameValue(buffer, bufsize, &pdata);
  889. free(buffer); buffer = NULL;
  890. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  891. if(resVal)
  892. {
  893. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  894. sscanf(resVal, "%d", &ret);
  895. }
  896. else
  897. {
  898. ret = UPNPCOMMAND_SUCCESS;
  899. p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout");
  900. if(p)
  901. *opTimeout = my_atoui(p);
  902. }
  903. ClearNameValueList(&pdata);
  904. free(GetOutboundPinholeTimeoutArgs);
  905. return ret;
  906. }
  907. MINIUPNP_LIBSPEC int
  908. UPNP_AddPinhole(const char * controlURL, const char * servicetype,
  909. const char * remoteHost,
  910. const char * remotePort,
  911. const char * intClient,
  912. const char * intPort,
  913. const char * proto,
  914. const char * leaseTime,
  915. char * uniqueID)
  916. {
  917. struct UPNParg * AddPinholeArgs;
  918. char * buffer;
  919. int bufsize;
  920. struct NameValueParserData pdata;
  921. const char * resVal;
  922. char * p;
  923. int ret;
  924. if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime)
  925. return UPNPCOMMAND_INVALID_ARGS;
  926. AddPinholeArgs = calloc(7, sizeof(struct UPNParg));
  927. if(AddPinholeArgs == NULL)
  928. return UPNPCOMMAND_MEM_ALLOC_ERROR;
  929. /* RemoteHost can be wilcarded */
  930. if(strncmp(remoteHost, "empty", 5)==0)
  931. {
  932. AddPinholeArgs[0].elt = "RemoteHost";
  933. AddPinholeArgs[0].val = "";
  934. }
  935. else
  936. {
  937. AddPinholeArgs[0].elt = "RemoteHost";
  938. AddPinholeArgs[0].val = remoteHost;
  939. }
  940. AddPinholeArgs[1].elt = "RemotePort";
  941. AddPinholeArgs[1].val = remotePort;
  942. AddPinholeArgs[2].elt = "Protocol";
  943. AddPinholeArgs[2].val = proto;
  944. AddPinholeArgs[3].elt = "InternalPort";
  945. AddPinholeArgs[3].val = intPort;
  946. if(strncmp(intClient, "empty", 5)==0)
  947. {
  948. AddPinholeArgs[4].elt = "InternalClient";
  949. AddPinholeArgs[4].val = "";
  950. }
  951. else
  952. {
  953. AddPinholeArgs[4].elt = "InternalClient";
  954. AddPinholeArgs[4].val = intClient;
  955. }
  956. AddPinholeArgs[5].elt = "LeaseTime";
  957. AddPinholeArgs[5].val = leaseTime;
  958. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  959. "AddPinhole", AddPinholeArgs, &bufsize);
  960. if(!buffer)
  961. return UPNPCOMMAND_HTTP_ERROR;
  962. ParseNameValue(buffer, bufsize, &pdata);
  963. free(buffer); buffer = NULL;
  964. p = GetValueFromNameValueList(&pdata, "UniqueID");
  965. if(p)
  966. {
  967. strncpy(uniqueID, p, 8);
  968. uniqueID[7] = '\0';
  969. }
  970. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  971. if(resVal)
  972. {
  973. /*printf("AddPortMapping errorCode = '%s'\n", resVal);*/
  974. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  975. sscanf(resVal, "%d", &ret);
  976. }
  977. else
  978. {
  979. ret = UPNPCOMMAND_SUCCESS;
  980. }
  981. ClearNameValueList(&pdata);
  982. free(AddPinholeArgs);
  983. return ret;
  984. }
  985. MINIUPNP_LIBSPEC int
  986. UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
  987. const char * uniqueID,
  988. const char * leaseTime)
  989. {
  990. struct UPNParg * UpdatePinholeArgs;
  991. char * buffer;
  992. int bufsize;
  993. struct NameValueParserData pdata;
  994. const char * resVal;
  995. int ret;
  996. if(!uniqueID || !leaseTime)
  997. return UPNPCOMMAND_INVALID_ARGS;
  998. UpdatePinholeArgs = calloc(3, sizeof(struct UPNParg));
  999. if(UpdatePinholeArgs == NULL)
  1000. return UPNPCOMMAND_MEM_ALLOC_ERROR;
  1001. UpdatePinholeArgs[0].elt = "UniqueID";
  1002. UpdatePinholeArgs[0].val = uniqueID;
  1003. UpdatePinholeArgs[1].elt = "NewLeaseTime";
  1004. UpdatePinholeArgs[1].val = leaseTime;
  1005. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  1006. "UpdatePinhole", UpdatePinholeArgs, &bufsize);
  1007. if(!buffer)
  1008. return UPNPCOMMAND_HTTP_ERROR;
  1009. ParseNameValue(buffer, bufsize, &pdata);
  1010. free(buffer); buffer = NULL;
  1011. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  1012. if(resVal)
  1013. {
  1014. /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
  1015. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  1016. sscanf(resVal, "%d", &ret);
  1017. }
  1018. else
  1019. {
  1020. ret = UPNPCOMMAND_SUCCESS;
  1021. }
  1022. ClearNameValueList(&pdata);
  1023. free(UpdatePinholeArgs);
  1024. return ret;
  1025. }
  1026. MINIUPNP_LIBSPEC int
  1027. UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID)
  1028. {
  1029. /*struct NameValueParserData pdata;*/
  1030. struct UPNParg * DeletePinholeArgs;
  1031. char * buffer;
  1032. int bufsize;
  1033. struct NameValueParserData pdata;
  1034. const char * resVal;
  1035. int ret;
  1036. if(!uniqueID)
  1037. return UPNPCOMMAND_INVALID_ARGS;
  1038. DeletePinholeArgs = calloc(2, sizeof(struct UPNParg));
  1039. if(DeletePinholeArgs == NULL)
  1040. return UPNPCOMMAND_MEM_ALLOC_ERROR;
  1041. DeletePinholeArgs[0].elt = "UniqueID";
  1042. DeletePinholeArgs[0].val = uniqueID;
  1043. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  1044. "DeletePinhole", DeletePinholeArgs, &bufsize);
  1045. if(!buffer)
  1046. return UPNPCOMMAND_HTTP_ERROR;
  1047. /*DisplayNameValueList(buffer, bufsize);*/
  1048. ParseNameValue(buffer, bufsize, &pdata);
  1049. free(buffer); buffer = NULL;
  1050. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  1051. if(resVal)
  1052. {
  1053. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  1054. sscanf(resVal, "%d", &ret);
  1055. }
  1056. else
  1057. {
  1058. ret = UPNPCOMMAND_SUCCESS;
  1059. }
  1060. ClearNameValueList(&pdata);
  1061. free(DeletePinholeArgs);
  1062. return ret;
  1063. }
  1064. MINIUPNP_LIBSPEC int
  1065. UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
  1066. const char * uniqueID, int * isWorking)
  1067. {
  1068. struct NameValueParserData pdata;
  1069. struct UPNParg * CheckPinholeWorkingArgs;
  1070. char * buffer;
  1071. int bufsize;
  1072. char * p;
  1073. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  1074. if(!uniqueID)
  1075. return UPNPCOMMAND_INVALID_ARGS;
  1076. CheckPinholeWorkingArgs = calloc(4, sizeof(struct UPNParg));
  1077. if(CheckPinholeWorkingArgs == NULL)
  1078. return UPNPCOMMAND_MEM_ALLOC_ERROR;
  1079. CheckPinholeWorkingArgs[0].elt = "UniqueID";
  1080. CheckPinholeWorkingArgs[0].val = uniqueID;
  1081. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  1082. "CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize);
  1083. if(!buffer)
  1084. return UPNPCOMMAND_HTTP_ERROR;
  1085. ParseNameValue(buffer, bufsize, &pdata);
  1086. free(buffer); buffer = NULL;
  1087. p = GetValueFromNameValueList(&pdata, "IsWorking");
  1088. if(p)
  1089. {
  1090. *isWorking=my_atoui(p);
  1091. ret = UPNPCOMMAND_SUCCESS;
  1092. }
  1093. else
  1094. *isWorking = 0;
  1095. p = GetValueFromNameValueList(&pdata, "errorCode");
  1096. if(p)
  1097. {
  1098. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  1099. sscanf(p, "%d", &ret);
  1100. }
  1101. ClearNameValueList(&pdata);
  1102. free(CheckPinholeWorkingArgs);
  1103. return ret;
  1104. }
  1105. MINIUPNP_LIBSPEC int
  1106. UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
  1107. const char * uniqueID, int * packets)
  1108. {
  1109. struct NameValueParserData pdata;
  1110. struct UPNParg * GetPinholePacketsArgs;
  1111. char * buffer;
  1112. int bufsize;
  1113. char * p;
  1114. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  1115. if(!uniqueID)
  1116. return UPNPCOMMAND_INVALID_ARGS;
  1117. GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg));
  1118. if(GetPinholePacketsArgs == NULL)
  1119. return UPNPCOMMAND_MEM_ALLOC_ERROR;
  1120. GetPinholePacketsArgs[0].elt = "UniqueID";
  1121. GetPinholePacketsArgs[0].val = uniqueID;
  1122. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  1123. "GetPinholePackets", GetPinholePacketsArgs, &bufsize);
  1124. if(!buffer)
  1125. return UPNPCOMMAND_HTTP_ERROR;
  1126. ParseNameValue(buffer, bufsize, &pdata);
  1127. free(buffer); buffer = NULL;
  1128. p = GetValueFromNameValueList(&pdata, "PinholePackets");
  1129. if(p)
  1130. {
  1131. *packets=my_atoui(p);
  1132. ret = UPNPCOMMAND_SUCCESS;
  1133. }
  1134. p = GetValueFromNameValueList(&pdata, "errorCode");
  1135. if(p)
  1136. {
  1137. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  1138. sscanf(p, "%d", &ret);
  1139. }
  1140. ClearNameValueList(&pdata);
  1141. free(GetPinholePacketsArgs);
  1142. return ret;
  1143. }