upnpcommands.c 35 KB

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