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