upnpcommands.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239
  1. #define _CRT_SECURE_NO_WARNINGS
  2. /* $Id: upnpcommands.c,v 1.46 2015/07/15 12:19:00 nanard Exp $ */
  3. /* Project : miniupnp
  4. * Author : Thomas Bernard
  5. * Copyright (c) 2005-2015 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. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  348. "AddPortMapping", AddPortMappingArgs,
  349. &bufsize))) {
  350. free(AddPortMappingArgs);
  351. return UPNPCOMMAND_HTTP_ERROR;
  352. }
  353. /*DisplayNameValueList(buffer, bufsize);*/
  354. /*buffer[bufsize] = '\0';*/
  355. /*puts(buffer);*/
  356. ParseNameValue(buffer, bufsize, &pdata);
  357. free(buffer); buffer = NULL;
  358. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  359. if(resVal) {
  360. /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
  361. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  362. sscanf(resVal, "%d", &ret);
  363. } else {
  364. ret = UPNPCOMMAND_SUCCESS;
  365. }
  366. ClearNameValueList(&pdata);
  367. free(AddPortMappingArgs);
  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. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  409. "AddAnyPortMapping", AddPortMappingArgs,
  410. &bufsize))) {
  411. free(AddPortMappingArgs);
  412. return UPNPCOMMAND_HTTP_ERROR;
  413. }
  414. ParseNameValue(buffer, bufsize, &pdata);
  415. free(buffer); buffer = NULL;
  416. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  417. if(resVal) {
  418. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  419. sscanf(resVal, "%d", &ret);
  420. } else {
  421. char *p;
  422. p = GetValueFromNameValueList(&pdata, "NewReservedPort");
  423. if(p) {
  424. strncpy(reservedPort, p, 6);
  425. reservedPort[5] = '\0';
  426. ret = UPNPCOMMAND_SUCCESS;
  427. } else {
  428. ret = UPNPCOMMAND_INVALID_RESPONSE;
  429. }
  430. }
  431. ClearNameValueList(&pdata);
  432. free(AddPortMappingArgs);
  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. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  459. "DeletePortMapping",
  460. DeletePortMappingArgs, &bufsize))) {
  461. free(DeletePortMappingArgs);
  462. return UPNPCOMMAND_HTTP_ERROR;
  463. }
  464. /*DisplayNameValueList(buffer, bufsize);*/
  465. ParseNameValue(buffer, bufsize, &pdata);
  466. free(buffer); buffer = NULL;
  467. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  468. if(resVal) {
  469. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  470. sscanf(resVal, "%d", &ret);
  471. } else {
  472. ret = UPNPCOMMAND_SUCCESS;
  473. }
  474. ClearNameValueList(&pdata);
  475. free(DeletePortMappingArgs);
  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. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  504. "DeletePortMappingRange",
  505. DeletePortMappingArgs, &bufsize))) {
  506. free(DeletePortMappingArgs);
  507. return UPNPCOMMAND_HTTP_ERROR;
  508. }
  509. ParseNameValue(buffer, bufsize, &pdata);
  510. free(buffer); buffer = NULL;
  511. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  512. if(resVal) {
  513. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  514. sscanf(resVal, "%d", &ret);
  515. } else {
  516. ret = UPNPCOMMAND_SUCCESS;
  517. }
  518. ClearNameValueList(&pdata);
  519. free(DeletePortMappingArgs);
  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. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  551. "GetGenericPortMappingEntry",
  552. GetPortMappingArgs, &bufsize))) {
  553. free(GetPortMappingArgs);
  554. return UPNPCOMMAND_HTTP_ERROR;
  555. }
  556. ParseNameValue(buffer, bufsize, &pdata);
  557. free(buffer); buffer = NULL;
  558. p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
  559. if(p && rHost)
  560. {
  561. strncpy(rHost, p, 64);
  562. rHost[63] = '\0';
  563. }
  564. p = GetValueFromNameValueList(&pdata, "NewExternalPort");
  565. if(p && extPort)
  566. {
  567. strncpy(extPort, p, 6);
  568. extPort[5] = '\0';
  569. r = UPNPCOMMAND_SUCCESS;
  570. }
  571. p = GetValueFromNameValueList(&pdata, "NewProtocol");
  572. if(p && protocol)
  573. {
  574. strncpy(protocol, p, 4);
  575. protocol[3] = '\0';
  576. }
  577. p = GetValueFromNameValueList(&pdata, "NewInternalClient");
  578. if(p && intClient)
  579. {
  580. strncpy(intClient, p, 16);
  581. intClient[15] = '\0';
  582. r = 0;
  583. }
  584. p = GetValueFromNameValueList(&pdata, "NewInternalPort");
  585. if(p && intPort)
  586. {
  587. strncpy(intPort, p, 6);
  588. intPort[5] = '\0';
  589. }
  590. p = GetValueFromNameValueList(&pdata, "NewEnabled");
  591. if(p && enabled)
  592. {
  593. strncpy(enabled, p, 4);
  594. enabled[3] = '\0';
  595. }
  596. p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
  597. if(p && desc)
  598. {
  599. strncpy(desc, p, 80);
  600. desc[79] = '\0';
  601. }
  602. p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
  603. if(p && duration)
  604. {
  605. strncpy(duration, p, 16);
  606. duration[15] = '\0';
  607. }
  608. p = GetValueFromNameValueList(&pdata, "errorCode");
  609. if(p) {
  610. r = UPNPCOMMAND_UNKNOWN_ERROR;
  611. sscanf(p, "%d", &r);
  612. }
  613. ClearNameValueList(&pdata);
  614. free(GetPortMappingArgs);
  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. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  684. "GetSpecificPortMappingEntry",
  685. GetPortMappingArgs, &bufsize))) {
  686. free(GetPortMappingArgs);
  687. return UPNPCOMMAND_HTTP_ERROR;
  688. }
  689. /*DisplayNameValueList(buffer, bufsize);*/
  690. ParseNameValue(buffer, bufsize, &pdata);
  691. free(buffer); buffer = NULL;
  692. p = GetValueFromNameValueList(&pdata, "NewInternalClient");
  693. if(p) {
  694. strncpy(intClient, p, 16);
  695. intClient[15] = '\0';
  696. ret = UPNPCOMMAND_SUCCESS;
  697. } else
  698. intClient[0] = '\0';
  699. p = GetValueFromNameValueList(&pdata, "NewInternalPort");
  700. if(p) {
  701. strncpy(intPort, p, 6);
  702. intPort[5] = '\0';
  703. } else
  704. intPort[0] = '\0';
  705. p = GetValueFromNameValueList(&pdata, "NewEnabled");
  706. if(p && enabled) {
  707. strncpy(enabled, p, 4);
  708. enabled[3] = '\0';
  709. }
  710. p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
  711. if(p && desc) {
  712. strncpy(desc, p, 80);
  713. desc[79] = '\0';
  714. }
  715. p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
  716. if(p && leaseDuration)
  717. {
  718. strncpy(leaseDuration, p, 16);
  719. leaseDuration[15] = '\0';
  720. }
  721. p = GetValueFromNameValueList(&pdata, "errorCode");
  722. if(p) {
  723. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  724. sscanf(p, "%d", &ret);
  725. }
  726. ClearNameValueList(&pdata);
  727. free(GetPortMappingArgs);
  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. if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  769. "GetListOfPortMappings",
  770. GetListOfPortMappingsArgs, &bufsize))) {
  771. free(GetListOfPortMappingsArgs);
  772. return UPNPCOMMAND_HTTP_ERROR;
  773. }
  774. free(GetListOfPortMappingsArgs);
  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. if(!buffer)
  888. return UPNPCOMMAND_HTTP_ERROR;
  889. ParseNameValue(buffer, bufsize, &pdata);
  890. free(buffer); buffer = NULL;
  891. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  892. if(resVal)
  893. {
  894. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  895. sscanf(resVal, "%d", &ret);
  896. }
  897. else
  898. {
  899. ret = UPNPCOMMAND_SUCCESS;
  900. p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout");
  901. if(p)
  902. *opTimeout = my_atoui(p);
  903. }
  904. ClearNameValueList(&pdata);
  905. free(GetOutboundPinholeTimeoutArgs);
  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. if(!buffer)
  962. return UPNPCOMMAND_HTTP_ERROR;
  963. ParseNameValue(buffer, bufsize, &pdata);
  964. free(buffer); buffer = NULL;
  965. p = GetValueFromNameValueList(&pdata, "UniqueID");
  966. if(p)
  967. {
  968. strncpy(uniqueID, p, 8);
  969. uniqueID[7] = '\0';
  970. }
  971. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  972. if(resVal)
  973. {
  974. /*printf("AddPortMapping errorCode = '%s'\n", resVal);*/
  975. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  976. sscanf(resVal, "%d", &ret);
  977. }
  978. else
  979. {
  980. ret = UPNPCOMMAND_SUCCESS;
  981. }
  982. ClearNameValueList(&pdata);
  983. free(AddPinholeArgs);
  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. if(!buffer)
  1009. return UPNPCOMMAND_HTTP_ERROR;
  1010. ParseNameValue(buffer, bufsize, &pdata);
  1011. free(buffer); buffer = NULL;
  1012. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  1013. if(resVal)
  1014. {
  1015. /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
  1016. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  1017. sscanf(resVal, "%d", &ret);
  1018. }
  1019. else
  1020. {
  1021. ret = UPNPCOMMAND_SUCCESS;
  1022. }
  1023. ClearNameValueList(&pdata);
  1024. free(UpdatePinholeArgs);
  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. if(!buffer)
  1047. return UPNPCOMMAND_HTTP_ERROR;
  1048. /*DisplayNameValueList(buffer, bufsize);*/
  1049. ParseNameValue(buffer, bufsize, &pdata);
  1050. free(buffer); buffer = NULL;
  1051. resVal = GetValueFromNameValueList(&pdata, "errorCode");
  1052. if(resVal)
  1053. {
  1054. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  1055. sscanf(resVal, "%d", &ret);
  1056. }
  1057. else
  1058. {
  1059. ret = UPNPCOMMAND_SUCCESS;
  1060. }
  1061. ClearNameValueList(&pdata);
  1062. free(DeletePinholeArgs);
  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. if(!buffer)
  1085. return UPNPCOMMAND_HTTP_ERROR;
  1086. ParseNameValue(buffer, bufsize, &pdata);
  1087. free(buffer); buffer = NULL;
  1088. p = GetValueFromNameValueList(&pdata, "IsWorking");
  1089. if(p)
  1090. {
  1091. *isWorking=my_atoui(p);
  1092. ret = UPNPCOMMAND_SUCCESS;
  1093. }
  1094. else
  1095. *isWorking = 0;
  1096. p = GetValueFromNameValueList(&pdata, "errorCode");
  1097. if(p)
  1098. {
  1099. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  1100. sscanf(p, "%d", &ret);
  1101. }
  1102. ClearNameValueList(&pdata);
  1103. free(CheckPinholeWorkingArgs);
  1104. return ret;
  1105. }
  1106. MINIUPNP_LIBSPEC int
  1107. UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
  1108. const char * uniqueID, int * packets)
  1109. {
  1110. struct NameValueParserData pdata;
  1111. struct UPNParg * GetPinholePacketsArgs;
  1112. char * buffer;
  1113. int bufsize;
  1114. char * p;
  1115. int ret = UPNPCOMMAND_UNKNOWN_ERROR;
  1116. if(!uniqueID)
  1117. return UPNPCOMMAND_INVALID_ARGS;
  1118. GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg));
  1119. if(GetPinholePacketsArgs == NULL)
  1120. return UPNPCOMMAND_MEM_ALLOC_ERROR;
  1121. GetPinholePacketsArgs[0].elt = "UniqueID";
  1122. GetPinholePacketsArgs[0].val = uniqueID;
  1123. buffer = simpleUPnPcommand(-1, controlURL, servicetype,
  1124. "GetPinholePackets", GetPinholePacketsArgs, &bufsize);
  1125. if(!buffer)
  1126. return UPNPCOMMAND_HTTP_ERROR;
  1127. ParseNameValue(buffer, bufsize, &pdata);
  1128. free(buffer); buffer = NULL;
  1129. p = GetValueFromNameValueList(&pdata, "PinholePackets");
  1130. if(p)
  1131. {
  1132. *packets=my_atoui(p);
  1133. ret = UPNPCOMMAND_SUCCESS;
  1134. }
  1135. p = GetValueFromNameValueList(&pdata, "errorCode");
  1136. if(p)
  1137. {
  1138. ret = UPNPCOMMAND_UNKNOWN_ERROR;
  1139. sscanf(p, "%d", &ret);
  1140. }
  1141. ClearNameValueList(&pdata);
  1142. free(GetPinholePacketsArgs);
  1143. return ret;
  1144. }