upnpcommands.c 35 KB

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