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

http://github.com/tomahawk-player/tomahawk · C · 683 lines · 600 code · 35 blank · 48 comment · 118 complexity · 5a94258bafe92c5f9cc253dc07dd184d MD5 · raw file

  1. /* $Id: upnpc.c,v 1.88 2011/06/17 23:31:01 nanard Exp $ */
  2. /* Project : miniupnp
  3. * Author : Thomas Bernard
  4. * Copyright (c) 2005-2011 Thomas Bernard
  5. * This software is subject to the conditions detailed in the
  6. * LICENCE file provided in this distribution. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <time.h>
  11. #ifdef WIN32
  12. #include <winsock2.h>
  13. #define snprintf _snprintf
  14. #endif
  15. #include "miniwget.h"
  16. #include "miniupnpc.h"
  17. #include "upnpcommands.h"
  18. #include "upnperrors.h"
  19. /* protofix() checks if protocol is "UDP" or "TCP"
  20. * returns NULL if not */
  21. const char * protofix(const char * proto)
  22. {
  23. static const char proto_tcp[4] = { 'T', 'C', 'P', 0};
  24. static const char proto_udp[4] = { 'U', 'D', 'P', 0};
  25. int i, b;
  26. for(i=0, b=1; i<4; i++)
  27. b = b && ( (proto[i] == proto_tcp[i])
  28. || (proto[i] == (proto_tcp[i] | 32)) );
  29. if(b)
  30. return proto_tcp;
  31. for(i=0, b=1; i<4; i++)
  32. b = b && ( (proto[i] == proto_udp[i])
  33. || (proto[i] == (proto_udp[i] | 32)) );
  34. if(b)
  35. return proto_udp;
  36. return 0;
  37. }
  38. static void DisplayInfos(struct UPNPUrls * urls,
  39. struct IGDdatas * data)
  40. {
  41. char externalIPAddress[40];
  42. char connectionType[64];
  43. char status[64];
  44. char lastconnerr[64];
  45. unsigned int uptime;
  46. unsigned int brUp, brDown;
  47. time_t timenow, timestarted;
  48. int r;
  49. UPNP_GetConnectionTypeInfo(urls->controlURL,
  50. data->first.servicetype,
  51. connectionType);
  52. if(connectionType[0])
  53. printf("Connection Type : %s\n", connectionType);
  54. else
  55. printf("GetConnectionTypeInfo failed.\n");
  56. UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
  57. status, &uptime, lastconnerr);
  58. printf("Status : %s, uptime=%us, LastConnectionError : %s\n",
  59. status, uptime, lastconnerr);
  60. timenow = time(NULL);
  61. timestarted = timenow - uptime;
  62. printf(" Time started : %s", ctime(&timestarted));
  63. UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype,
  64. &brDown, &brUp);
  65. printf("MaxBitRateDown : %u bps", brDown);
  66. if(brDown >= 1000000) {
  67. printf(" (%u.%u Mbps)", brDown / 1000000, (brDown / 100000) % 10);
  68. } else if(brDown >= 1000) {
  69. printf(" (%u Kbps)", brDown / 1000);
  70. }
  71. printf(" MaxBitRateUp %u bps", brUp);
  72. if(brUp >= 1000000) {
  73. printf(" (%u.%u Mbps)", brUp / 1000000, (brUp / 100000) % 10);
  74. } else if(brUp >= 1000) {
  75. printf(" (%u Kbps)", brUp / 1000);
  76. }
  77. printf("\n");
  78. r = UPNP_GetExternalIPAddress(urls->controlURL,
  79. data->first.servicetype,
  80. externalIPAddress);
  81. if(r != UPNPCOMMAND_SUCCESS)
  82. printf("GetExternalIPAddress() returned %d\n", r);
  83. if(externalIPAddress[0])
  84. printf("ExternalIPAddress = %s\n", externalIPAddress);
  85. else
  86. printf("GetExternalIPAddress failed.\n");
  87. }
  88. static void GetConnectionStatus(struct UPNPUrls * urls,
  89. struct IGDdatas * data)
  90. {
  91. unsigned int bytessent, bytesreceived, packetsreceived, packetssent;
  92. DisplayInfos(urls, data);
  93. bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype);
  94. bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype);
  95. packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype);
  96. packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype);
  97. printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived);
  98. printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived);
  99. }
  100. static void ListRedirections(struct UPNPUrls * urls,
  101. struct IGDdatas * data)
  102. {
  103. int r;
  104. int i = 0;
  105. char index[6];
  106. char intClient[40];
  107. char intPort[6];
  108. char extPort[6];
  109. char protocol[4];
  110. char desc[80];
  111. char enabled[6];
  112. char rHost[64];
  113. char duration[16];
  114. /*unsigned int num=0;
  115. UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num);
  116. printf("PortMappingNumberOfEntries : %u\n", num);*/
  117. do {
  118. snprintf(index, 6, "%d", i);
  119. rHost[0] = '\0'; enabled[0] = '\0';
  120. duration[0] = '\0'; desc[0] = '\0';
  121. extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0';
  122. r = UPNP_GetGenericPortMappingEntry(urls->controlURL,
  123. data->first.servicetype,
  124. index,
  125. extPort, intClient, intPort,
  126. protocol, desc, enabled,
  127. rHost, duration);
  128. if(r==0)
  129. /*
  130. printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n"
  131. " desc='%s' rHost='%s'\n",
  132. i, protocol, extPort, intClient, intPort,
  133. enabled, duration,
  134. desc, rHost);
  135. */
  136. printf("%2d %s %5s->%s:%-5s '%s' '%s' %s\n",
  137. i, protocol, extPort, intClient, intPort,
  138. desc, rHost, duration);
  139. else
  140. printf("GetGenericPortMappingEntry() returned %d (%s)\n",
  141. r, strupnperror(r));
  142. i++;
  143. } while(r==0);
  144. }
  145. static void NewListRedirections(struct UPNPUrls * urls,
  146. struct IGDdatas * data)
  147. {
  148. int r;
  149. int i = 0;
  150. struct PortMappingParserData pdata;
  151. struct PortMapping * pm;
  152. memset(&pdata, 0, sizeof(struct PortMappingParserData));
  153. r = UPNP_GetListOfPortMappings(urls->controlURL,
  154. data->first.servicetype,
  155. "0",
  156. "65535",
  157. "TCP",
  158. "1000",
  159. &pdata);
  160. if(r == UPNPCOMMAND_SUCCESS)
  161. {
  162. for(pm = pdata.head.lh_first; pm != NULL; pm = pm->entries.le_next)
  163. {
  164. printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n",
  165. i, pm->protocol, pm->externalPort, pm->internalClient,
  166. pm->internalPort,
  167. pm->description, pm->remoteHost,
  168. (unsigned)pm->leaseTime);
  169. i++;
  170. }
  171. FreePortListing(&pdata);
  172. }
  173. else
  174. {
  175. printf("GetListOfPortMappings() returned %d (%s)\n",
  176. r, strupnperror(r));
  177. }
  178. r = UPNP_GetListOfPortMappings(urls->controlURL,
  179. data->first.servicetype,
  180. "0",
  181. "65535",
  182. "UDP",
  183. "1000",
  184. &pdata);
  185. if(r == UPNPCOMMAND_SUCCESS)
  186. {
  187. for(pm = pdata.head.lh_first; pm != NULL; pm = pm->entries.le_next)
  188. {
  189. printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n",
  190. i, pm->protocol, pm->externalPort, pm->internalClient,
  191. pm->internalPort,
  192. pm->description, pm->remoteHost,
  193. (unsigned)pm->leaseTime);
  194. i++;
  195. }
  196. FreePortListing(&pdata);
  197. }
  198. else
  199. {
  200. printf("GetListOfPortMappings() returned %d (%s)\n",
  201. r, strupnperror(r));
  202. }
  203. }
  204. /* Test function
  205. * 1 - get connection type
  206. * 2 - get extenal ip address
  207. * 3 - Add port mapping
  208. * 4 - get this port mapping from the IGD */
  209. static void SetRedirectAndTest(struct UPNPUrls * urls,
  210. struct IGDdatas * data,
  211. const char * iaddr,
  212. const char * iport,
  213. const char * eport,
  214. const char * proto,
  215. const char * leaseDuration)
  216. {
  217. char externalIPAddress[40];
  218. char intClient[40];
  219. char intPort[6];
  220. char duration[16];
  221. int r;
  222. if(!iaddr || !iport || !eport || !proto)
  223. {
  224. fprintf(stderr, "Wrong arguments\n");
  225. return;
  226. }
  227. proto = protofix(proto);
  228. if(!proto)
  229. {
  230. fprintf(stderr, "invalid protocol\n");
  231. return;
  232. }
  233. UPNP_GetExternalIPAddress(urls->controlURL,
  234. data->first.servicetype,
  235. externalIPAddress);
  236. if(externalIPAddress[0])
  237. printf("ExternalIPAddress = %s\n", externalIPAddress);
  238. else
  239. printf("GetExternalIPAddress failed.\n");
  240. r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype,
  241. eport, iport, iaddr, 0, proto, 0, leaseDuration);
  242. if(r!=UPNPCOMMAND_SUCCESS)
  243. printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
  244. eport, iport, iaddr, r, strupnperror(r));
  245. r = UPNP_GetSpecificPortMappingEntry(urls->controlURL,
  246. data->first.servicetype,
  247. eport, proto,
  248. intClient, intPort, NULL/*desc*/,
  249. NULL/*enabled*/, duration);
  250. if(r!=UPNPCOMMAND_SUCCESS)
  251. printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n",
  252. r, strupnperror(r));
  253. if(intClient[0]) {
  254. printf("InternalIP:Port = %s:%s\n", intClient, intPort);
  255. printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n",
  256. externalIPAddress, eport, proto, intClient, intPort, duration);
  257. }
  258. }
  259. static void
  260. RemoveRedirect(struct UPNPUrls * urls,
  261. struct IGDdatas * data,
  262. const char * eport,
  263. const char * proto)
  264. {
  265. int r;
  266. if(!proto || !eport)
  267. {
  268. fprintf(stderr, "invalid arguments\n");
  269. return;
  270. }
  271. proto = protofix(proto);
  272. if(!proto)
  273. {
  274. fprintf(stderr, "protocol invalid\n");
  275. return;
  276. }
  277. r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, 0);
  278. printf("UPNP_DeletePortMapping() returned : %d\n", r);
  279. }
  280. /* IGD:2, functions for service WANIPv6FirewallControl:1 */
  281. static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data)
  282. {
  283. unsigned int bytessent, bytesreceived, packetsreceived, packetssent;
  284. int firewallEnabled = 0, inboundPinholeAllowed = 0;
  285. UPNP_GetFirewallStatus(urls->controlURL_6FC, data->IPv6FC.servicetype, &firewallEnabled, &inboundPinholeAllowed);
  286. printf("FirewallEnabled: %d & Inbound Pinhole Allowed: %d\n", firewallEnabled, inboundPinholeAllowed);
  287. printf("GetFirewallStatus:\n Firewall Enabled: %s\n Inbound Pinhole Allowed: %s\n", (firewallEnabled)? "Yes":"No", (inboundPinholeAllowed)? "Yes":"No");
  288. bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype);
  289. bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype);
  290. packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype);
  291. packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype);
  292. printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived);
  293. printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived);
  294. }
  295. /* Test function
  296. * 1 - Add pinhole
  297. * 2 - Check if pinhole is working from the IGD side */
  298. static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data,
  299. const char * remoteaddr, const char * eport,
  300. const char * intaddr, const char * iport,
  301. const char * proto, const char * lease_time)
  302. {
  303. char uniqueID[8];
  304. //int isWorking = 0;
  305. int r;
  306. if(!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time)
  307. {
  308. fprintf(stderr, "Wrong arguments\n");
  309. return;
  310. }
  311. /*proto = protofix(proto);
  312. if(!proto)
  313. {
  314. fprintf(stderr, "invalid protocol\n");
  315. return;
  316. }*/
  317. r = UPNP_AddPinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, lease_time, uniqueID);
  318. if(r!=UPNPCOMMAND_SUCCESS)
  319. printf("AddPinhole([%s]:%s -> [%s]:%s) failed with code %d (%s)\n",
  320. intaddr, iport, remoteaddr, eport, r, strupnperror(r));
  321. else
  322. {
  323. printf("AddPinhole: ([%s]:%s -> [%s]:%s) / Pinhole ID = %s\n", intaddr, iport, remoteaddr, eport, uniqueID);
  324. /*r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->servicetype_6FC, uniqueID, &isWorking);
  325. if(r!=UPNPCOMMAND_SUCCESS)
  326. printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r));
  327. printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");*/
  328. }
  329. }
  330. /* Test function
  331. * 1 - Check if pinhole is working from the IGD side
  332. * 2 - Update pinhole */
  333. static void GetPinholeAndUpdate(struct UPNPUrls * urls, struct IGDdatas * data,
  334. const char * uniqueID, const char * lease_time)
  335. {
  336. int isWorking = 0;
  337. int r;
  338. if(!uniqueID || !lease_time)
  339. {
  340. fprintf(stderr, "Wrong arguments\n");
  341. return;
  342. }
  343. r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking);
  344. printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");
  345. if(r!=UPNPCOMMAND_SUCCESS)
  346. printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r));
  347. if(isWorking || r==709)
  348. {
  349. r = UPNP_UpdatePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, lease_time);
  350. printf("UpdatePinhole: Pinhole ID = %s with Lease Time: %s\n", uniqueID, lease_time);
  351. if(r!=UPNPCOMMAND_SUCCESS)
  352. printf("UpdatePinhole: ID (%s) failed with code %d (%s)\n", uniqueID, r, strupnperror(r));
  353. }
  354. }
  355. /* Test function
  356. * Get pinhole timeout
  357. */
  358. static void GetPinholeOutboundTimeout(struct UPNPUrls * urls, struct IGDdatas * data,
  359. const char * remoteaddr, const char * eport,
  360. const char * intaddr, const char * iport,
  361. const char * proto)
  362. {
  363. int timeout = 0;
  364. int r;
  365. if(!intaddr || !remoteaddr || !iport || !eport || !proto)
  366. {
  367. fprintf(stderr, "Wrong arguments\n");
  368. return;
  369. }
  370. r = UPNP_GetOutboundPinholeTimeout(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, &timeout);
  371. if(r!=UPNPCOMMAND_SUCCESS)
  372. printf("GetOutboundPinholeTimeout([%s]:%s -> [%s]:%s) failed with code %d (%s)\n",
  373. intaddr, iport, remoteaddr, eport, r, strupnperror(r));
  374. else
  375. printf("GetOutboundPinholeTimeout: ([%s]:%s -> [%s]:%s) / Timeout = %d\n", intaddr, iport, remoteaddr, eport, timeout);
  376. }
  377. static void
  378. GetPinholePackets(struct UPNPUrls * urls,
  379. struct IGDdatas * data, const char * uniqueID)
  380. {
  381. int r, pinholePackets = 0;
  382. if(!uniqueID)
  383. {
  384. fprintf(stderr, "invalid arguments\n");
  385. return;
  386. }
  387. r = UPNP_GetPinholePackets(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &pinholePackets);
  388. if(r!=UPNPCOMMAND_SUCCESS)
  389. printf("GetPinholePackets() failed with code %d (%s)\n", r, strupnperror(r));
  390. else
  391. printf("GetPinholePackets: Pinhole ID = %s / PinholePackets = %d\n", uniqueID, pinholePackets);
  392. }
  393. static void
  394. CheckPinhole(struct UPNPUrls * urls,
  395. struct IGDdatas * data, const char * uniqueID)
  396. {
  397. int r, isWorking = 0;
  398. if(!uniqueID)
  399. {
  400. fprintf(stderr, "invalid arguments\n");
  401. return;
  402. }
  403. r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking);
  404. if(r!=UPNPCOMMAND_SUCCESS)
  405. printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r));
  406. else
  407. printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");
  408. }
  409. static void
  410. RemovePinhole(struct UPNPUrls * urls,
  411. struct IGDdatas * data, const char * uniqueID)
  412. {
  413. int r;
  414. if(!uniqueID)
  415. {
  416. fprintf(stderr, "invalid arguments\n");
  417. return;
  418. }
  419. r = UPNP_DeletePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID);
  420. printf("UPNP_DeletePinhole() returned : %d\n", r);
  421. }
  422. /* sample upnp client program */
  423. int main(int argc, char ** argv)
  424. {
  425. char command = 0;
  426. char ** commandargv = 0;
  427. int commandargc = 0;
  428. struct UPNPDev * devlist = 0;
  429. char lanaddr[64]; /* my ip address on the LAN */
  430. int i;
  431. const char * rootdescurl = 0;
  432. const char * multicastif = 0;
  433. const char * minissdpdpath = 0;
  434. int retcode = 0;
  435. int error = 0;
  436. int ipv6 = 0;
  437. #ifdef WIN32
  438. WSADATA wsaData;
  439. int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
  440. if(nResult != NO_ERROR)
  441. {
  442. fprintf(stderr, "WSAStartup() failed.\n");
  443. return -1;
  444. }
  445. #endif
  446. printf("upnpc : miniupnpc library test client. (c) 2006-2011 Thomas Bernard\n");
  447. printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n"
  448. "for more information.\n");
  449. /* command line processing */
  450. for(i=1; i<argc; i++)
  451. {
  452. if(argv[i][0] == '-')
  453. {
  454. if(argv[i][1] == 'u')
  455. rootdescurl = argv[++i];
  456. else if(argv[i][1] == 'm')
  457. multicastif = argv[++i];
  458. else if(argv[i][1] == 'p')
  459. minissdpdpath = argv[++i];
  460. else if(argv[i][1] == '6')
  461. ipv6 = 1;
  462. else
  463. {
  464. command = argv[i][1];
  465. i++;
  466. commandargv = argv + i;
  467. commandargc = argc - i;
  468. break;
  469. }
  470. }
  471. else
  472. {
  473. fprintf(stderr, "option '%s' invalid\n", argv[i]);
  474. }
  475. }
  476. if(!command || (command == 'a' && commandargc<4)
  477. || (command == 'd' && argc<2)
  478. || (command == 'r' && argc<2)
  479. || (command == 'A' && commandargc<6)
  480. || (command == 'U' && commandargc<2)
  481. || (command == 'D' && commandargc<1))
  482. {
  483. fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol [duration]\n\t\tAdd port redirection\n", argv[0]);
  484. fprintf(stderr, " \t%s [options] -d external_port protocol [port2 protocol2] [...]\n\t\tDelete port redirection\n", argv[0]);
  485. fprintf(stderr, " \t%s [options] -s\n\t\tGet Connection status\n", argv[0]);
  486. fprintf(stderr, " \t%s [options] -l\n\t\tList redirections\n", argv[0]);
  487. fprintf(stderr, " \t%s [options] -L\n\t\tList redirections (using GetListOfPortMappings, IGD v2)\n", argv[0]);
  488. fprintf(stderr, " \t%s [options] -r port1 protocol1 [port2 protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]);
  489. fprintf(stderr, " \t%s [options] -A remote_ip remote_port internal_ip internal_port protocol lease_time\n\t\tAdd Pinhole (for IGD:2 only)\n", argv[0]);
  490. fprintf(stderr, " \t%s [options] -U uniqueID new_lease_time\n\t\tUpdate Pinhole (for IGD:2 only)\n", argv[0]);
  491. fprintf(stderr, " \t%s [options] -C uniqueID\n\t\tCheck if Pinhole is Working (for IGD:2 only)\n", argv[0]);
  492. fprintf(stderr, " \t%s [options] -K uniqueID\n\t\tGet Number of packets going through the rule (for IGD:2 only)\n", argv[0]);
  493. fprintf(stderr, " \t%s [options] -D uniqueID\n\t\tDelete Pinhole (for IGD:2 only)\n", argv[0]);
  494. fprintf(stderr, " \t%s [options] -S\n\t\tGet Firewall status (for IGD:2 only)\n", argv[0]);
  495. fprintf(stderr, " \t%s [options] -G remote_ip remote_port internal_ip internal_port protocol\n\t\tGet Outbound Pinhole Timeout (for IGD:2 only)\n", argv[0]);
  496. fprintf(stderr, " \t%s [options] -P\n\t\tGet Presentation url\n", argv[0]);
  497. fprintf(stderr, "\nprotocol is UDP or TCP\n");
  498. fprintf(stderr, "Options:\n");
  499. fprintf(stderr, " -6 : use ip v6 instead of ip v4.\n");
  500. fprintf(stderr, " -u url : bypass discovery process by providing the XML root description url.\n");
  501. fprintf(stderr, " -m address/interface : provide ip address (ip v4) or interface name (ip v6) to use for sending SSDP multicast packets.\n");
  502. fprintf(stderr, " -p path : use this path for MiniSSDPd socket.\n");
  503. return 1;
  504. }
  505. if( rootdescurl
  506. || (devlist = upnpDiscover(2000, multicastif, minissdpdpath,
  507. 0/*sameport*/, ipv6, &error)))
  508. {
  509. struct UPNPDev * device;
  510. struct UPNPUrls urls;
  511. struct IGDdatas data;
  512. if(devlist)
  513. {
  514. printf("List of UPNP devices found on the network :\n");
  515. for(device = devlist; device; device = device->pNext)
  516. {
  517. printf(" desc: %s\n st: %s\n\n",
  518. device->descURL, device->st);
  519. }
  520. }
  521. else
  522. {
  523. printf("upnpDiscover() error code=%d\n", error);
  524. }
  525. i = 1;
  526. if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr)))
  527. || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))))
  528. {
  529. switch(i) {
  530. case 1:
  531. printf("Found valid IGD : %s\n", urls.controlURL);
  532. break;
  533. case 2:
  534. printf("Found a (not connected?) IGD : %s\n", urls.controlURL);
  535. printf("Trying to continue anyway\n");
  536. break;
  537. case 3:
  538. printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
  539. printf("Trying to continue anyway\n");
  540. break;
  541. default:
  542. printf("Found device (igd ?) : %s\n", urls.controlURL);
  543. printf("Trying to continue anyway\n");
  544. }
  545. printf("Local LAN ip address : %s\n", lanaddr);
  546. #if 0
  547. printf("getting \"%s\"\n", urls.ipcondescURL);
  548. descXML = miniwget(urls.ipcondescURL, &descXMLsize);
  549. if(descXML)
  550. {
  551. /*fwrite(descXML, 1, descXMLsize, stdout);*/
  552. free(descXML); descXML = NULL;
  553. }
  554. #endif
  555. switch(command)
  556. {
  557. case 'l':
  558. DisplayInfos(&urls, &data);
  559. ListRedirections(&urls, &data);
  560. break;
  561. case 'L':
  562. NewListRedirections(&urls, &data);
  563. break;
  564. case 'a':
  565. SetRedirectAndTest(&urls, &data,
  566. commandargv[0], commandargv[1],
  567. commandargv[2], commandargv[3],
  568. (commandargc > 4)?commandargv[4]:"0");
  569. break;
  570. case 'd':
  571. for(i=0; i<commandargc; i+=2)
  572. {
  573. RemoveRedirect(&urls, &data, commandargv[i], commandargv[i+1]);
  574. }
  575. break;
  576. case 's':
  577. GetConnectionStatus(&urls, &data);
  578. break;
  579. case 'r':
  580. for(i=0; i<commandargc; i+=2)
  581. {
  582. /*printf("port %s protocol %s\n", argv[i], argv[i+1]);*/
  583. SetRedirectAndTest(&urls, &data,
  584. lanaddr, commandargv[i],
  585. commandargv[i], commandargv[i+1], "0");
  586. }
  587. break;
  588. case 'A':
  589. SetPinholeAndTest(&urls, &data,
  590. commandargv[0], commandargv[1],
  591. commandargv[2], commandargv[3],
  592. commandargv[4], commandargv[5]);
  593. break;
  594. case 'U':
  595. GetPinholeAndUpdate(&urls, &data,
  596. commandargv[0], commandargv[1]);
  597. break;
  598. case 'C':
  599. for(i=0; i<commandargc; i++)
  600. {
  601. CheckPinhole(&urls, &data, commandargv[i]);
  602. }
  603. break;
  604. case 'K':
  605. for(i=0; i<commandargc; i++)
  606. {
  607. GetPinholePackets(&urls, &data, commandargv[i]);
  608. }
  609. break;
  610. case 'D':
  611. for(i=0; i<commandargc; i++)
  612. {
  613. RemovePinhole(&urls, &data, commandargv[i]);
  614. }
  615. break;
  616. case 'S':
  617. GetFirewallStatus(&urls, &data);
  618. break;
  619. case 'G':
  620. GetPinholeOutboundTimeout(&urls, &data,
  621. commandargv[0], commandargv[1],
  622. commandargv[2], commandargv[3],
  623. commandargv[4]);
  624. break;
  625. case 'P':
  626. printf("Presentation URL found:\n");
  627. printf(" %s\n", data.presentationurl);
  628. break;
  629. default:
  630. fprintf(stderr, "Unknown switch -%c\n", command);
  631. retcode = 1;
  632. }
  633. FreeUPNPUrls(&urls);
  634. }
  635. else
  636. {
  637. fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
  638. retcode = 1;
  639. }
  640. freeUPNPDevlist(devlist); devlist = 0;
  641. }
  642. else
  643. {
  644. fprintf(stderr, "No IGD UPnP Device found on the network !\n");
  645. retcode = 1;
  646. }
  647. return retcode;
  648. }