/thirdparty/libportfwd/src/portfwd.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 214 lines · 157 code · 38 blank · 19 comment · 23 complexity · 43b221daf240c0d88f2fbab839614bcf MD5 · raw file

  1. /*
  2. * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  3. *
  4. * Tomahawk is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * Tomahawk is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "portfwd/portfwd.h"
  18. #include "miniwget.h"
  19. #include "miniupnpc.h"
  20. #include "upnpcommands.h"
  21. #ifdef WIN32
  22. #include <winsock2.h>
  23. #endif
  24. Portfwd::Portfwd()
  25. : m_urls( 0 )
  26. , m_data( 0 )
  27. {
  28. }
  29. Portfwd::~Portfwd()
  30. {
  31. if ( m_urls )
  32. free( m_urls );
  33. if ( m_data )
  34. free( m_data );
  35. }
  36. bool
  37. Portfwd::init( unsigned int timeout )
  38. {
  39. #ifdef WIN32
  40. WSADATA wsaData;
  41. int nResult = WSAStartup( MAKEWORD( 2, 2 ), &wsaData );
  42. if ( nResult != NO_ERROR )
  43. {
  44. fprintf( stderr, "WSAStartup() failed.\n" );
  45. return -1;
  46. }
  47. #endif
  48. struct UPNPDev* devlist;
  49. struct UPNPDev* dev;
  50. char* descXML;
  51. int descXMLsize = 0;
  52. int error = 0;
  53. printf( "Portfwd::init()\n" );
  54. m_urls = (UPNPUrls*)malloc( sizeof( struct UPNPUrls ) );
  55. m_data = (IGDdatas*)malloc( sizeof( struct IGDdatas ) );
  56. memset( m_urls, 0, sizeof( struct UPNPUrls ) );
  57. memset( m_data, 0, sizeof( struct IGDdatas ) );
  58. devlist = upnpDiscover( timeout, NULL, NULL, 0, 0, &error );
  59. if ( devlist )
  60. {
  61. dev = devlist;
  62. while ( dev )
  63. {
  64. printf( "descurl: %s\n", dev->descURL );
  65. bool blocked = false;
  66. std::list<std::string>::iterator it;
  67. for ( it = m_blockedips.begin(); it != m_blockedips.end(); ++it )
  68. {
  69. printf( "blocked ip: %s\n", it->c_str() );
  70. if ( strstr( dev->descURL, it->c_str() ) )
  71. {
  72. printf( "nope, we blocked this gateway: %s\n", dev->descURL );
  73. blocked = true;
  74. }
  75. }
  76. if ( blocked )
  77. {
  78. dev = dev->pNext;
  79. continue;
  80. }
  81. if ( strstr( dev->descURL, "InternetGatewayDevice" ) )
  82. break;
  83. dev = dev->pNext;
  84. }
  85. if ( !dev )
  86. dev = devlist; /* defaulting to first device */
  87. printf( "UPnP device:\n"
  88. " desc: %s\n st: %s\n",
  89. dev->descURL, dev->st );
  90. descXML = (char*)miniwget( dev->descURL, &descXMLsize );
  91. if ( descXML )
  92. {
  93. parserootdesc( descXML, descXMLsize, m_data );
  94. free( descXML );
  95. descXML = 0;
  96. GetUPNPUrls( m_urls, m_data, dev->descURL );
  97. }
  98. else
  99. {
  100. printf( "couldn't get the UPnP device description XML (descXML is null)" );
  101. freeUPNPDevlist( devlist );
  102. return false;
  103. }
  104. // get lan IP:
  105. char lanaddr[16];
  106. int idg_was_found = UPNP_GetValidIGD( devlist, m_urls, m_data, (char*)&lanaddr, 16 );
  107. if ( !idg_was_found )
  108. {
  109. printf( "NO IGD was found (function UPNP_GetValidIGD())" );
  110. freeUPNPDevlist( devlist );
  111. return false;
  112. }
  113. m_lanip = std::string( lanaddr );
  114. freeUPNPDevlist( devlist );
  115. get_status();
  116. return true;
  117. }
  118. return false;
  119. }
  120. void
  121. Portfwd::get_status()
  122. {
  123. // get connection speed
  124. UPNP_GetLinkLayerMaxBitRates( m_urls->controlURL_CIF, m_data->CIF.servicetype, &m_downbps, &m_upbps );
  125. // get external IP adress
  126. char ip[16];
  127. if ( 0 != UPNP_GetExternalIPAddress( m_urls->controlURL, m_data->first.servicetype, (char*)&ip ) )
  128. {
  129. m_externalip = ""; //failed
  130. }
  131. else
  132. {
  133. m_externalip = std::string( ip );
  134. }
  135. }
  136. bool
  137. Portfwd::add( unsigned short port, unsigned short internal_port )
  138. {
  139. char port_str[16], port_str_internal[16];
  140. int r;
  141. printf( "Portfwd::add (%s, %d)\n", m_lanip.c_str(), port );
  142. if ( m_urls->controlURL[0] == '\0' )
  143. {
  144. printf( "Portfwd - the init was not done!\n" );
  145. return false;
  146. }
  147. sprintf( port_str, "%d", port );
  148. sprintf( port_str_internal, "%d", internal_port );
  149. r = UPNP_AddPortMapping( m_urls->controlURL, m_data->first.servicetype, port_str, port_str_internal, m_lanip.c_str(), "tomahawk", "TCP", NULL, NULL );
  150. if ( r != 0 )
  151. {
  152. printf( "AddPortMapping(%s, %s, %s) failed, code %d\n", port_str, port_str, m_lanip.c_str(), r );
  153. return false;
  154. }
  155. return true;
  156. }
  157. bool
  158. Portfwd::remove( unsigned short port )
  159. {
  160. char port_str[16];
  161. printf( "Portfwd::remove(%d)\n", port );
  162. if ( m_urls->controlURL[0] == '\0' )
  163. {
  164. printf( "Portfwd - the init was not done!\n" );
  165. return false;
  166. }
  167. sprintf( port_str, "%d", port );
  168. int r = UPNP_DeletePortMapping( m_urls->controlURL, m_data->first.servicetype, port_str, "TCP", NULL );
  169. return r == 0;
  170. }
  171. void
  172. Portfwd::addBlockedDevice( const std::string& ip )
  173. {
  174. printf( "adding blocked: %s\n", ip.c_str() );
  175. m_blockedips.push_back( ip );
  176. }