tor-fw-helper-natpmp.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /* Copyright (c) 2010, Jacob Appelbaum, Steven J. Murdoch.
  2. * Copyright (c) 2010, The Tor Project, Inc. */
  3. /* See LICENSE for licensing information */
  4. #include <stdint.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <errno.h>
  8. #include <arpa/inet.h>
  9. #include "tor-fw-helper.h"
  10. #include "tor-fw-helper-natpmp.h"
  11. int
  12. tor_natpmp_add_tcp_mapping(tor_fw_options_t *tor_fw_options)
  13. {
  14. int r = 0;
  15. int x = 0;
  16. int sav_errno;
  17. int protocol = NATPMP_PROTOCOL_TCP;
  18. int lease = NATPMP_DEFAULT_LEASE;
  19. natpmp_t natpmp;
  20. natpmpresp_t response;
  21. fd_set fds;
  22. struct timeval timeout;
  23. if (tor_fw_options->verbose)
  24. fprintf(stdout, "V: natpmp init...\n");
  25. initnatpmp(&natpmp);
  26. if (tor_fw_options->verbose)
  27. fprintf(stdout, "V: sending natpmp portmapping request...\n");
  28. r = sendnewportmappingrequest(&natpmp, protocol,
  29. tor_fw_options->internal_port,
  30. tor_fw_options->external_port,
  31. lease);
  32. fprintf(stdout, "tor-fw-helper: NAT-PMP sendnewportmappingrequest returned"
  33. " %d (%s)\n", r, r==12?"SUCCESS":"FAILED");
  34. do {
  35. FD_ZERO(&fds);
  36. FD_SET(natpmp.s, &fds);
  37. getnatpmprequesttimeout(&natpmp, &timeout);
  38. select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
  39. if (tor_fw_options->verbose)
  40. fprintf(stdout, "V: attempting to readnatpmpreponseorretry...\n");
  41. r = readnatpmpresponseorretry(&natpmp, &response);
  42. sav_errno = errno;
  43. if (r<0 && r!=NATPMP_TRYAGAIN)
  44. {
  45. fprintf(stderr, "E: readnatpmpresponseorretry failed %d\n", r);
  46. fprintf(stderr, "E: errno=%d '%s'\n", sav_errno,
  47. strerror(sav_errno));
  48. }
  49. } while ( r == NATPMP_TRYAGAIN );
  50. if (r == NATPMP_SUCCESS) {
  51. fprintf(stdout, "tor-fw-helper: NAT-PMP mapped public port %hu to"
  52. " localport %hu liftime %u\n",
  53. response.pnu.newportmapping.mappedpublicport,
  54. response.pnu.newportmapping.privateport,
  55. response.pnu.newportmapping.lifetime);
  56. }
  57. x = closenatpmp(&natpmp);
  58. if (tor_fw_options->verbose)
  59. fprintf(stdout, "V: closing natpmp socket: %d\n", x);
  60. return r;
  61. }
  62. int
  63. tor_natpmp_fetch_public_ip(tor_fw_options_t *tor_fw_options)
  64. {
  65. int r = 0;
  66. int x = 0;
  67. int sav_errno;
  68. natpmp_t natpmp;
  69. natpmpresp_t response;
  70. struct timeval timeout;
  71. fd_set fds;
  72. r = initnatpmp(&natpmp);
  73. if (tor_fw_options->verbose)
  74. fprintf(stdout, "V: NAT-PMP init: %d\n", r);
  75. r = sendpublicaddressrequest(&natpmp);
  76. fprintf(stdout, "tor-fw-helper: NAT-PMP sendpublicaddressrequest returned"
  77. " %d (%s)\n", r, r==2?"SUCCESS":"FAILED");
  78. do {
  79. FD_ZERO(&fds);
  80. FD_SET(natpmp.s, &fds);
  81. getnatpmprequesttimeout(&natpmp, &timeout);
  82. select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
  83. if (tor_fw_options->verbose)
  84. fprintf(stdout, "V: NAT-PMP attempting to read reponse...\n");
  85. r = readnatpmpresponseorretry(&natpmp, &response);
  86. sav_errno = errno;
  87. if (tor_fw_options->verbose)
  88. fprintf(stdout, "V: NAT-PMP readnatpmpresponseorretry returned"
  89. " %d\n", r);
  90. if ( r < 0 && r != NATPMP_TRYAGAIN)
  91. {
  92. fprintf(stderr, "E: NAT-PMP readnatpmpresponseorretry failed %d\n",
  93. r);
  94. fprintf(stderr, "E: NAT-PMP errno=%d '%s'\n", sav_errno,
  95. strerror(sav_errno));
  96. }
  97. } while ( r == NATPMP_TRYAGAIN );
  98. if (r != 0)
  99. {
  100. fprintf(stderr, "E: NAT-PMP It appears that something went wrong:"
  101. " %d\n", r);
  102. return r;
  103. }
  104. fprintf(stdout, "tor-fw-helper: ExternalIPAddress = %s\n",
  105. inet_ntoa(response.pnu.publicaddress.addr));
  106. x = closenatpmp(&natpmp);
  107. if (tor_fw_options->verbose)
  108. {
  109. fprintf(stdout, "V: result = %u\n", r);
  110. fprintf(stdout, "V: type = %u\n", response.type);
  111. fprintf(stdout, "V: resultcode = %u\n", response.resultcode);
  112. fprintf(stdout, "V: epoch = %u\n", response.epoch);
  113. fprintf(stdout, "V: closing natpmp result: %d\n", r);
  114. }
  115. return r;
  116. }