tor-fw-helper-upnp.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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 <string.h>
  6. #include <stdio.h>
  7. #include "tor-fw-helper.h"
  8. #include "tor-fw-helper-upnp.h"
  9. #define UPNP_DISCOVER_TIMEOUT 2000
  10. /* Description of the port mapping in the UPnP table */
  11. #define UPNP_DESC "Tor relay"
  12. #define UPNP_ERR_SUCCESS 0
  13. #define UPNP_ERR_NODEVICESFOUND 1
  14. #define UPNP_ERR_NOIGDFOUND 2
  15. #define UPNP_ERR_ADDPORTMAPPING 3
  16. #define UPNP_ERR_GETPORTMAPPING 4
  17. #define UPNP_ERR_DELPORTMAPPING 5
  18. #define UPNP_ERR_GETEXTERNALIP 6
  19. #define UPNP_ERR_INVAL 7
  20. #define UPNP_ERR_OTHER 8
  21. #define UPNP_SUCCESS 1
  22. int
  23. tor_upnp_init(miniupnpc_state_t *state)
  24. {
  25. struct UPNPDev *devlist;
  26. int r;
  27. memset(&(state->urls), 0, sizeof(struct UPNPUrls));
  28. memset(&(state->data), 0, sizeof(struct IGDdatas));
  29. devlist = upnpDiscover(UPNP_DISCOVER_TIMEOUT, NULL, NULL, 0);
  30. if (NULL == devlist) {
  31. fprintf(stderr, "E: upnpDiscover returned: NULL\n");
  32. return UPNP_ERR_NODEVICESFOUND;
  33. }
  34. r = UPNP_GetValidIGD(devlist, &(state->urls), &(state->data),
  35. state->lanaddr, UPNP_LANADDR_SZ);
  36. fprintf(stdout, "tor-fw-helper: UPnP GetValidIGD returned: %d (%s)\n", r,
  37. r==UPNP_SUCCESS?"SUCCESS":"FAILED");
  38. freeUPNPDevlist(devlist);
  39. if (r != 1 && r != 2)
  40. return UPNP_ERR_NOIGDFOUND;
  41. state->init = 1;
  42. return UPNP_ERR_SUCCESS;
  43. }
  44. int
  45. tor_upnp_cleanup(miniupnpc_state_t *state)
  46. {
  47. if (state->init)
  48. FreeUPNPUrls(&(state->urls));
  49. state->init = 0;
  50. return UPNP_ERR_SUCCESS;
  51. }
  52. int
  53. tor_upnp_fetch_public_ip(miniupnpc_state_t *state)
  54. {
  55. int r;
  56. char externalIPAddress[16];
  57. if (!state->init) {
  58. r = tor_upnp_init(state);
  59. if (r != UPNP_ERR_SUCCESS)
  60. return r;
  61. }
  62. r = UPNP_GetExternalIPAddress(state->urls.controlURL,
  63. state->data.first.servicetype,
  64. externalIPAddress);
  65. if (r != UPNPCOMMAND_SUCCESS)
  66. goto err;
  67. if (externalIPAddress[0]) {
  68. fprintf(stdout, "tor-fw-helper: ExternalIPAddress = %s\n",
  69. externalIPAddress); tor_upnp_cleanup(state);
  70. return UPNP_ERR_SUCCESS;
  71. } else
  72. goto err;
  73. err:
  74. tor_upnp_cleanup(state);
  75. return UPNP_ERR_GETEXTERNALIP;
  76. }
  77. int
  78. tor_upnp_add_tcp_mapping(miniupnpc_state_t *state,
  79. uint16_t internal_port, uint16_t external_port)
  80. {
  81. int r;
  82. char internal_port_str[6];
  83. char external_port_str[6];
  84. if (!state->init) {
  85. r = tor_upnp_init(state);
  86. if (r != UPNP_ERR_SUCCESS)
  87. return r;
  88. }
  89. snprintf(internal_port_str, sizeof(internal_port_str),
  90. "%d", internal_port);
  91. snprintf(external_port_str, sizeof(external_port_str),
  92. "%d", external_port);
  93. r = UPNP_AddPortMapping(state->urls.controlURL,
  94. state->data.first.servicetype,
  95. external_port_str, internal_port_str,
  96. state->lanaddr, UPNP_DESC, "TCP", 0);
  97. if (r != UPNPCOMMAND_SUCCESS)
  98. return UPNP_ERR_ADDPORTMAPPING;
  99. return UPNP_ERR_SUCCESS;
  100. }