Ejemplo n.º 1
0
static int
tr_upnpGetSpecificPortMappingEntry (tr_upnp * handle, const char * proto)
{
    int err;
    char intClient[16];
    char intPort[16];
    char portStr[16];

    *intClient = '\0';
    *intPort = '\0';

    tr_snprintf (portStr, sizeof(portStr), "%d", (int)handle->port);

#if (MINIUPNPC_API_VERSION >= 10) /* adds remoteHost arg */

    err = UPNP_GetSpecificPortMappingEntry (handle->urls.controlURL,
                                            handle->data.first.servicetype,
                                            portStr,
                                            proto,
                                            NULL /*remoteHost*/,
                                            intClient,
                                            intPort,
                                            NULL /*desc*/,
                                            NULL /*enabled*/,
                                            NULL /*duration*/);

#elif (MINIUPNPC_API_VERSION >= 8) /* adds desc, enabled and leaseDuration args */

    err = UPNP_GetSpecificPortMappingEntry (handle->urls.controlURL,
                                            handle->data.first.servicetype,
                                            portStr,
                                            proto,
                                            intClient,
                                            intPort,
                                            NULL /*desc*/,
                                            NULL /*enabled*/,
                                            NULL /*duration*/);

#else

    err = UPNP_GetSpecificPortMappingEntry (handle->urls.controlURL,
                                            handle->data.first.servicetype,
                                            portStr,
                                            proto,
                                            intClient,
                                            intPort);

#endif

    return err;
}
Ejemplo n.º 2
0
bool CUPnPImplMiniLib::CStartDiscoveryThread::OpenPort(uint16 nPort, bool bTCP, char* pachLANIP){
	const char achTCP[] = "TCP";
	const char achUDP[] = "UDP";
	const char achDescTCP[] = "eMule_TCP";
	const char achDescUDP[] = "eMule_UDP";
	char achPort[10];
	sprintf(achPort, "%u", nPort);
	
	if (m_pOwner->m_bAbortDiscovery)
		return false;

	int nResult;
	if (bTCP)
		nResult = UPNP_AddPortMapping(m_pOwner->m_pURLs->controlURL, m_pOwner->m_pIGDData->servicetype
		, achPort, achPort, pachLANIP, achDescTCP, achTCP);
	else
		nResult = UPNP_AddPortMapping(m_pOwner->m_pURLs->controlURL, m_pOwner->m_pIGDData->servicetype
		, achPort, achPort, pachLANIP, achDescUDP, achUDP);

	if (nResult != UPNPCOMMAND_SUCCESS){
		DebugLog(_T("Adding PortMapping failed, Error Code %u"), nResult);
		return false;
	}

	if (m_pOwner->m_bAbortDiscovery)
		return false;

	// make sure it really worked
	char achOutIP[20];
	achOutIP[0] = 0;
	if (bTCP)
		nResult = UPNP_GetSpecificPortMappingEntry(m_pOwner->m_pURLs->controlURL, m_pOwner->m_pIGDData->servicetype
		, achPort, achTCP, achOutIP, achPort);
	else
		nResult = UPNP_GetSpecificPortMappingEntry(m_pOwner->m_pURLs->controlURL, m_pOwner->m_pIGDData->servicetype
		, achPort, achUDP, achOutIP, achPort);

	if (nResult == UPNPCOMMAND_SUCCESS && achOutIP[0] != 0){
		DebugLog(_T("Sucessfully added mapping for port %u (%s) on local IP %S"), nPort, bTCP ? _T("TCP") : _T("UDP"), achOutIP);
		return true;
	}
	else {
		DebugLogWarning(_T("Failed to verfiy mapping for port %u (%s) on local IP %S - considering as failed"), nPort, bTCP ? _T("TCP") : _T("UDP"), achOutIP);
		// maybe counting this as error is a bit harsh as this may lead to false negatives, however if we would risk false postives
		// this would mean that the fallback implementations are not tried because eMule thinks it worked out fine
		return false;
	}
}
Ejemplo n.º 3
0
/* GetSpecificPortMapping(ePort, proto) 
 * proto = 'UDP' or 'TCP' */
static PyObject *
UPnP_getspecificportmapping(UPnPObject *self, PyObject *args)
{
	char extPort[6];
	unsigned short ePort;
	const char * proto;
	char intClient[16];
	char intPort[6];
	unsigned short iPort;
	if(!PyArg_ParseTuple(args, "Hs", &ePort, &proto))
		return NULL;
	sprintf(extPort, "%hu", ePort);
	UPNP_GetSpecificPortMappingEntry(self->urls.controlURL,
	                                 self->data.servicetype,
									 extPort, proto,
									 intClient, intPort);
	if(intClient[0])
	{
		iPort = (unsigned short)atoi(intPort);
		return Py_BuildValue("(s,H)", intClient, iPort);
	}
	else
	{
		Py_RETURN_NONE;
	}
}
Ejemplo n.º 4
0
int GetPortMapping(unsigned int extPort, const char* protocol)
{
    char myextPort[6] = {0};  //IN
    sprintf(myextPort, "%d", extPort);
    printf("***%s, %s***\n", myextPort, protocol);

    char intClient[16]     = {0};  //OUT
    char intPort[6]        = {0};  //OUT
    char desc[80]          = {0};  //OUT
    char enabled[4]        = {0};  //OUT
    char leaseDuration[16] = {0};  //OUT

    int result = UPNP_GetSpecificPortMappingEntry(g_urls->controlURL, g_data->first.servicetype, 
                                                  myextPort, protocol, NULL, 
                                                  intClient, intPort, desc, enabled, leaseDuration);
    if(0 == result)
    {
        printf("extPort:%s, intPort:%s, %s, %s\n", myextPort, intPort, intClient, protocol);
        printf("%s, %s, duration:%s\n", desc, enabled ? "enabled" : "disabled", leaseDuration);
    }
    else
    {
        printf("get port mapping[%s, %s] failed: %d\n", myextPort, protocol, result);
    }

    return 0;
}
Ejemplo n.º 5
0
int upnpGetSpecificPortMappingEntry( struct upnp_handle_t *handle, const char *proto, unsigned short port ) {
	char extPort[6];
	char intClient[16];
	char intPort[6];

	snprintf( extPort, sizeof(extPort), "%hu", port );

	*intClient = '\0';
	*intPort = '\0';

#if (MINIUPNPC_API_VERSION <= 5)
	return UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, extPort, proto, intClient, intPort );
#elif (MINIUPNPC_API_VERSION <= 9)
	return UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, extPort, proto, intClient, intPort, NULL, NULL, NULL );
#else
	return UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, extPort, proto, NULL, intClient, intPort, NULL, NULL, NULL );
#endif
}
Ejemplo n.º 6
0
/* Test function
 * 1 - get connection type
 * 2 - get extenal ip address
 * 3 - Add port mapping
 * 4 - get this port mapping from the IGD */
static void SetRedirectAndTest(struct UPNPUrls * urls,
                               struct IGDdatas * data,
							   const char * iaddr,
							   const char * iport,
							   const char * eport,
                               const char * proto,
                               const char * leaseDuration,
                               const char * description)
{
	char externalIPAddress[40];
	char intClient[40];
	char intPort[6];
	char duration[16];
	int r;

	if(!iaddr || !iport || !eport || !proto)
	{
		fprintf(stderr, "Wrong arguments\n");
		return;
	}
	proto = protofix(proto);
	if(!proto)
	{
		fprintf(stderr, "invalid protocol\n");
		return;
	}

	UPNP_GetExternalIPAddress(urls->controlURL,
	                          data->first.servicetype,
							  externalIPAddress);
	if(externalIPAddress[0])
		printf("ExternalIPAddress = %s\n", externalIPAddress);
	else
		printf("GetExternalIPAddress failed.\n");

	r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype,
	                        eport, iport, iaddr, description,
	                        proto, 0, leaseDuration);
	if(r!=UPNPCOMMAND_SUCCESS)
		printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
		       eport, iport, iaddr, r, strupnperror(r));

	r = UPNP_GetSpecificPortMappingEntry(urls->controlURL,
	                                 data->first.servicetype,
    	                             eport, proto, NULL/*remoteHost*/,
									 intClient, intPort, NULL/*desc*/,
	                                 NULL/*enabled*/, duration);
	if(r!=UPNPCOMMAND_SUCCESS)
		printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n",
		       r, strupnperror(r));

	if(intClient[0]) {
		printf("InternalIP:Port = %s:%s\n", intClient, intPort);
		printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n",
		       externalIPAddress, eport, proto, intClient, intPort, duration);
	}
}
Ejemplo n.º 7
0
static int
tr_upnpGetSpecificPortMappingEntry (tr_upnp * handle, const char * proto)
{
    int err;
    char intClient[16];
    char intPort[16];
    char portStr[16];

    *intClient = '\0';
    *intPort = '\0';

    tr_snprintf (portStr, sizeof (portStr), "%d", (int)handle->port);

#if defined (HAVE_MINIUPNP_16)
    err = UPNP_GetSpecificPortMappingEntry (handle->urls.controlURL, handle->data.first.servicetype, portStr, proto, intClient, intPort, NULL, NULL, NULL);
#elif defined (HAVE_MINIUPNP_15)
    err = UPNP_GetSpecificPortMappingEntry (handle->urls.controlURL, handle->data.first.servicetype, portStr, proto, intClient, intPort);
#else
    err = UPNPCOMMAND_UNKNOWN_ERROR;
#endif

    return err;
}
Ejemplo n.º 8
0
/* GetSpecificPortMapping(ePort, proto, remoteHost='')
 * proto = 'UDP' or 'TCP' */
static PyObject *
UPnP_getspecificportmapping(UPnPObject *self, PyObject *args)
{
	char extPort[6];
	unsigned short ePort;
	const char * proto;
	const char * remoteHost = "";
	char intClient[40];
	char intPort[6];
	unsigned short iPort;
	char desc[80];
	char enabled[4];
	char leaseDuration[16];
	if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost))
		return NULL;
	extPort[0] = '\0'; intClient[0] = '\0'; intPort[0] = '\0';
	desc[0] = '\0'; enabled[0] = '\0'; leaseDuration[0] = '\0';
Py_BEGIN_ALLOW_THREADS
	sprintf(extPort, "%hu", ePort);
	UPNP_GetSpecificPortMappingEntry(self->urls.controlURL,
	                                 self->data.first.servicetype,
									 extPort, proto, remoteHost,
									 intClient, intPort,
	                                 desc, enabled, leaseDuration);
Py_END_ALLOW_THREADS
	if(intClient[0])
	{
		iPort = (unsigned short)atoi(intPort);
		return Py_BuildValue("(s,H,s,O,i)",
		                     intClient, iPort, desc,
		                     PyBool_FromLong(atoi(enabled)),
		                     atoi(leaseDuration));
	}
	else
	{
		Py_RETURN_NONE;
	}
}
Ejemplo n.º 9
0
int
tr_upnpPulse( tr_upnp * handle,
              int       port,
              int       isEnabled,
              int       doPortCheck )
{
    int ret;

    if( isEnabled && ( handle->state == TR_UPNP_DISCOVER ) )
    {
        struct UPNPDev * devlist;
        errno = 0;
        devlist = upnpDiscover( 2000, NULL, NULL, 0 );
        if( devlist == NULL )
        {
            tr_ndbg(
                 getKey( ), "upnpDiscover failed (errno %d - %s)", errno,
                tr_strerror( errno ) );
        }
        errno = 0;
        if( UPNP_GetValidIGD( devlist, &handle->urls, &handle->data,
                             handle->lanaddr, sizeof( handle->lanaddr ) ) == UPNP_IGD_VALID_CONNECTED )
        {
            tr_ninf( getKey( ), _(
                         "Found Internet Gateway Device \"%s\"" ),
                     handle->urls.controlURL );
            tr_ninf( getKey( ), _(
                         "Local Address is \"%s\"" ), handle->lanaddr );
            handle->state = TR_UPNP_IDLE;
            handle->hasDiscovered = 1;
        }
        else
        {
            handle->state = TR_UPNP_ERR;
            tr_ndbg(
                 getKey( ), "UPNP_GetValidIGD failed (errno %d - %s)",
                errno,
                tr_strerror( errno ) );
            tr_ndbg(
                getKey( ),
                "If your router supports UPnP, please make sure UPnP is enabled!" );
        }
        freeUPNPDevlist( devlist );
    }

    if( handle->state == TR_UPNP_IDLE )
    {
        if( handle->isMapped && ( !isEnabled || ( handle->port != port ) ) )
            handle->state = TR_UPNP_UNMAP;
    }

    if( isEnabled && handle->isMapped && doPortCheck )
    {
        char portStr[8];
        char intPort[8];
        char intClient[16];

        tr_snprintf( portStr, sizeof( portStr ), "%d", handle->port );
        if( UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, 
            portStr, "TCP", intClient, intPort ) != UPNPCOMMAND_SUCCESS  ||
            UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, 
            portStr, "UDP", intClient, intPort ) != UPNPCOMMAND_SUCCESS )
        {
            tr_ninf( getKey( ), _( "Port %d isn't forwarded" ), handle->port );
            handle->isMapped = FALSE;
        }
    }

    if( handle->state == TR_UPNP_UNMAP )
    {
        char portStr[16];
        tr_snprintf( portStr, sizeof( portStr ), "%d", handle->port );
        UPNP_DeletePortMapping( handle->urls.controlURL,
                                handle->data.first.servicetype,
                                portStr, "TCP", NULL );
        UPNP_DeletePortMapping( handle->urls.controlURL,
                                handle->data.first.servicetype,
                                portStr, "UDP", NULL );
        tr_ninf( getKey( ),
                 _(
                     "Stopping port forwarding through \"%s\", service \"%s\"" ),
                 handle->urls.controlURL, handle->data.first.servicetype );
        handle->isMapped = 0;
        handle->state = TR_UPNP_IDLE;
        handle->port = -1;
    }

    if( handle->state == TR_UPNP_IDLE )
    {
        if( isEnabled && !handle->isMapped )
            handle->state = TR_UPNP_MAP;
    }

    if( handle->state == TR_UPNP_MAP )
    {
        int  err_tcp = -1;
        int  err_udp = -1;
        errno = 0;

        if( !handle->urls.controlURL || !handle->data.first.servicetype )
            handle->isMapped = 0;
        else
        {
            char portStr[16];
            char desc[64];
            const int prev_errno = errno;
            tr_snprintf( portStr, sizeof( portStr ), "%d", port );
            tr_snprintf( desc, sizeof( desc ), "%s at %d", TR_NAME, port );

            errno = 0;
            err_tcp = UPNP_AddPortMapping( handle->urls.controlURL,
                                       handle->data.first.servicetype,
                                       portStr, portStr, handle->lanaddr,
                                       desc, "TCP", NULL );
            if( err_tcp )
                tr_ndbg( getKey( ), "TCP Port forwarding failed with error %d (errno %d - %s)",
                         err_tcp, errno, tr_strerror( errno ) );

            errno = 0;
            err_udp = UPNP_AddPortMapping( handle->urls.controlURL,
                                       handle->data.first.servicetype,
                                       portStr, portStr, handle->lanaddr,
                                       desc, "UDP", NULL );
            if( err_udp )
                tr_ndbg( getKey( ), "UDP Port forwarding failed with error %d (errno %d - %s)",
                         err_udp, errno, tr_strerror( errno ) );

            errno = prev_errno;
            handle->isMapped = !err_tcp | !err_udp;
        }
        tr_ninf( getKey( ),
                 _( "Port forwarding through \"%s\", service \"%s\". (local address: %s:%d)" ),
                 handle->urls.controlURL, handle->data.first.servicetype,
                 handle->lanaddr, port );
        if( handle->isMapped )
        {
            tr_ninf( getKey( ), "%s", _( "Port forwarding successful!" ) );
            handle->port = port;
            handle->state = TR_UPNP_IDLE;
        }
        else
        {
            tr_ndbg( getKey( ), "If your router supports UPnP, please make sure UPnP is enabled!" );
            handle->port = -1;
            handle->state = TR_UPNP_ERR;
        }
    }

    switch( handle->state )
    {
        case TR_UPNP_DISCOVER:
            ret = TR_PORT_UNMAPPED; break;

        case TR_UPNP_MAP:
            ret = TR_PORT_MAPPING; break;

        case TR_UPNP_UNMAP:
            ret = TR_PORT_UNMAPPING; break;

        case TR_UPNP_IDLE:
            ret = handle->isMapped ? TR_PORT_MAPPED
                  : TR_PORT_UNMAPPED; break;

        default:
            ret = TR_PORT_ERROR; break;
    }

    return ret;
}
Ejemplo n.º 10
0
int
vino_upnp_add_port (VinoUpnp *upnp, int port)
{
  char *ext_port, *int_port, *desc;
  int   err, local_port;
  char  int_client_tmp[16], int_port_tmp[6];

  g_return_val_if_fail (VINO_IS_UPNP (upnp), -1);

  if (!update_upnp_status (upnp))
    return -1;

  vino_upnp_remove_port (upnp);

  local_port = port;
  do
    {
      ext_port = g_strdup_printf ("%d", local_port);
      dprintf (UPNP, "UPnP: Trying to forward port %d...: ", local_port);
      UPNP_GetSpecificPortMappingEntry (upnp->priv->urls->controlURL,
					upnp->priv->data->servicetype,
					ext_port,
					"TCP",
					int_client_tmp,
					int_port_tmp);
      if ( (strcmp (int_client_tmp, upnp->priv->lanaddr) == 0) && (strcmp (int_port_tmp, ext_port) == 0) )
	{
	  dprintf (UPNP, "UPnP: Found a previous redirect\n");
	  break;
	}
      else if (int_client_tmp[0])
	{
	  dprintf (UPNP, "Failed, this port is already forwarded to %s:%s\n", int_client_tmp, int_port_tmp);
	  g_free (ext_port);
	}
      else
	{
	  dprintf (UPNP, "OK, this port is free on the router\n");
	  break;
	}

      local_port++;
    } while (local_port < INT_MAX);

  if (local_port == INT_MAX)
    {
      dprintf (UPNP, "UPnP: Not forwarding any port, tried so much\n");
      return -1;
    }

  int_port = g_strdup_printf ("%d", port);
  desc = g_strdup_printf ("VNC: %s@%s",
			  g_get_user_name (),
			  g_get_host_name ());  

  err = UPNP_AddPortMapping (upnp->priv->urls->controlURL,
			     upnp->priv->data->servicetype,
			     ext_port,
			     int_port,
			     upnp->priv->lanaddr,
			     desc,
			     "TCP");
  if (err == 0)
    {
      upnp->priv->port = local_port;
      upnp->priv->internal_port = port;
      dprintf (UPNP, "UPnP: Successfuly forwarded port %d\n", local_port);
    }
  else
    dprintf (UPNP, "Failed to forward port %d, with status %d\n", local_port, err);

  g_free (ext_port);
  g_free (int_port);
  g_free (desc);

  return upnp->priv->port;
}
Ejemplo n.º 11
0
void* CNetServerWorker::SetupUPnP(void*)
{
	// Values we want to set.
	char psPort[6];
	sprintf_s(psPort, ARRAY_SIZE(psPort), "%d", PS_DEFAULT_PORT);
	const char* leaseDuration = "0"; // Indefinite/permanent lease duration.
	const char* description = "0AD Multiplayer";
	const char* protocall = "UDP";
	char internalIPAddress[64];
	char externalIPAddress[40];
	// Variables to hold the values that actually get set.
	char intClient[40];
	char intPort[6];
	char duration[16];
	// Intermediate variables.
	struct UPNPUrls urls;
	struct IGDdatas data;
	struct UPNPDev* devlist = NULL;

	// Cached root descriptor URL.
	std::string rootDescURL;
	CFG_GET_VAL("network.upnprootdescurl", rootDescURL);
	if (!rootDescURL.empty())
		LOGMESSAGE("Net server: attempting to use cached root descriptor URL: %s", rootDescURL.c_str());

	int ret = 0;
	bool allocatedUrls = false;

	// Try a cached URL first
	if (!rootDescURL.empty() && UPNP_GetIGDFromUrl(rootDescURL.c_str(), &urls, &data, internalIPAddress, sizeof(internalIPAddress)))
	{
		LOGMESSAGE("Net server: using cached IGD = %s", urls.controlURL);
		ret = 1;
	}
	// No cached URL, or it did not respond. Try getting a valid UPnP device for 10 seconds.
	else if ((devlist = upnpDiscover(10000, 0, 0, 0, 0, 0)) != NULL)
	{
		ret = UPNP_GetValidIGD(devlist, &urls, &data, internalIPAddress, sizeof(internalIPAddress));
		allocatedUrls = ret != 0; // urls is allocated on non-zero return values
	}
	else
	{
		LOGMESSAGE("Net server: upnpDiscover failed and no working cached URL.");
		return NULL;
	}

	switch (ret)
	{
	case 0:
		LOGMESSAGE("Net server: No IGD found");
		break;
	case 1:
		LOGMESSAGE("Net server: found valid IGD = %s", urls.controlURL);
		break;
	case 2:
		LOGMESSAGE("Net server: found a valid, not connected IGD = %s, will try to continue anyway", urls.controlURL);
		break;
	case 3:
		LOGMESSAGE("Net server: found a UPnP device unrecognized as IGD = %s, will try to continue anyway", urls.controlURL);
		break;
	default:
		debug_warn(L"Unrecognized return value from UPNP_GetValidIGD");
	}

	// Try getting our external/internet facing IP. TODO: Display this on the game-setup page for conviniance.
	ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
	if (ret != UPNPCOMMAND_SUCCESS)
	{
		LOGMESSAGE("Net server: GetExternalIPAddress failed with code %d (%s)", ret, strupnperror(ret));
		return NULL;
	}
	LOGMESSAGE("Net server: ExternalIPAddress = %s", externalIPAddress);

	// Try to setup port forwarding.
	ret = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, psPort, psPort,
							internalIPAddress, description, protocall, 0, leaseDuration);
	if (ret != UPNPCOMMAND_SUCCESS)
	{
		LOGMESSAGE("Net server: AddPortMapping(%s, %s, %s) failed with code %d (%s)",
			   psPort, psPort, internalIPAddress, ret, strupnperror(ret));
		return NULL;
	}

	// Check that the port was actually forwarded.
	ret = UPNP_GetSpecificPortMappingEntry(urls.controlURL,
									 data.first.servicetype,
									 psPort, protocall,
#if defined(MINIUPNPC_API_VERSION) && MINIUPNPC_API_VERSION >= 10
									 NULL/*remoteHost*/,
#endif
									 intClient, intPort, NULL/*desc*/,
									 NULL/*enabled*/, duration);

	if (ret != UPNPCOMMAND_SUCCESS)
	{
		LOGMESSAGE("Net server: GetSpecificPortMappingEntry() failed with code %d (%s)", ret, strupnperror(ret));
		return NULL;
	}

	LOGMESSAGE("Net server: External %s:%s %s is redirected to internal %s:%s (duration=%s)",
				   externalIPAddress, psPort, protocall, intClient, intPort, duration);

	// Cache root descriptor URL to try to avoid discovery next time.
	g_ConfigDB.SetValueString(CFG_USER, "network.upnprootdescurl", urls.controlURL);
	g_ConfigDB.WriteFile(CFG_USER);
	LOGMESSAGE("Net server: cached UPnP root descriptor URL as %s", urls.controlURL);

	// Make sure everything is properly freed.
	if (allocatedUrls)
		FreeUPNPUrls(&urls);
    
	freeUPNPDevlist(devlist);

	return NULL;
}
Ejemplo n.º 12
0
int upnpPulse(upnp * handle, int port, int proto, char isEnabled, int doPortCheck, const char* name)
{
    if(isEnabled && (handle->state == UPNP_DISCOVER))
    {
        struct UPNPDev * devlist;
        devlist = upnpDiscover(200, NULL, NULL, 0);
        if(UPNP_GetValidIGD(devlist, &handle->urls, &handle->data,
                             handle->lanaddr, sizeof(handle->lanaddr )) == UPNP_IGD_VALID_CONNECTED)
        {
			//qDebug() << QString("Found Internet Gateway Device \"%1\"").arg(QString(handle->urls.controlURL));
			//qDebug() << QString("Local Address is \"%1\"").arg(QString(handle->lanaddr));

            handle->state = UPNP_IDLE;
            handle->hasDiscovered = 1;
        }
        else
        {
            handle->state = UPNP_ERR;
			//qDebug() << QString("UPNP_GetValidIGD failed");
        }
        freeUPNPDevlist(devlist);
    }

    if(handle->state == UPNP_IDLE)
    {
        if(handle->isMapped && (!isEnabled || handle->port != port))
            handle->state = UPNP_UNMAP;
    }

	char* protoStr = "";
	switch(proto)
	{
	case PORT_TCP: protoStr = "TCP"; break;
	case PORT_UDP: protoStr = "UDP"; break;
	}

    if(isEnabled && handle->isMapped && doPortCheck)
    {
        char portStr[8];
        char intPort[8];
        char intClient[16];

        snprintf(portStr, sizeof(portStr), "%d", handle->port);
        if(UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, portStr, protoStr, intClient, intPort ) != UPNPCOMMAND_SUCCESS)
        {
			//qDebug() << QString("Port %1 isn't forwarded").arg(handle->port);
            handle->isMapped = 0;
        }
    }

    if( handle->state == UPNP_UNMAP )
    {
        char portStr[16];
        snprintf(portStr, sizeof(portStr), "%d", handle->port);
        UPNP_DeletePortMapping(handle->urls.controlURL, handle->data.first.servicetype, portStr, protoStr, NULL);

		//qDebug() << QString("Stopping port forwarding through \"%1\", service \"%1\"").arg(QString(handle->urls.controlURL)).arg(QString(handle->data.first.servicetype));

        handle->isMapped = 0;
        handle->state = UPNP_IDLE;
        handle->port = -1;
    }

    if(handle->state == UPNP_IDLE)
    {
        if(isEnabled && !handle->isMapped)
            handle->state = UPNP_MAP;
    }

    if(handle->state == UPNP_MAP)
    {
        int  err = -1;

        if(!handle->urls.controlURL || !handle->data.first.servicetype)
            handle->isMapped = 0;
        else
        {
            char portStr[16];
            char desc[64];
            snprintf(portStr, sizeof(portStr), "%d", port);
            snprintf(desc, sizeof(desc), "%s at %d", name, port);

            err = UPNP_AddPortMapping(handle->urls.controlURL, handle->data.first.servicetype, portStr, portStr, handle->lanaddr, desc, protoStr, NULL);
			//if(err)
			//	qDebug() << QString("%1 Port forwarding failed with error %2").arg(QString(protoStr)).arg(err);
            
            handle->isMapped = !err;
        }
		//qDebug() << QString("Port forwarding through \"%1\", service \"%2\". (local address: %3:%4)")
		//		.arg(QString(handle->urls.controlURL)).arg(QString(handle->data.first.servicetype)).arg(QString(handle->lanaddr)).arg(port);

        if(handle->isMapped)
        {
			//qDebug() << QString("Port forwarding successful!");
            handle->port = port;
            handle->state = UPNP_IDLE;
        }
        else
        {
			//qDebug() << QString("If your router supports UPnP, please make sure UPnP is enabled!");
            handle->port = -1;
            handle->state = UPNP_ERR;
        }
    }

    switch( handle->state )
    {
    case UPNP_DISCOVER:	return PORT_UNMAPPED;
	case UPNP_MAP:		return PORT_MAPPING;
	case UPNP_UNMAP:	return PORT_UNMAPPING;
	case UPNP_IDLE:		return handle->isMapped ? PORT_MAPPED : PORT_UNMAPPED;
	default:			return PORT_ERROR;
    }
}
Ejemplo n.º 13
0
static int
upnpPulse( ml_upnpmp_t * map )
{
    int ret;

    if( map->enabled && ( map->upnpState == ML_UPNP_DISCOVER ) )
    {
        struct UPNPDev * devlist;
        errno = 0;
        devlist = upnpDiscover( 2000, NULL, NULL, 0, 0, 0 );
        if( devlist == NULL )
        {
            dbg_printf( "upnpDiscover failed (errno %d - %s)\n", errno,  str_errno( errno ) );
        }
        errno = 0;
        if( UPNP_IGD_VALID_CONNECTED == UPNP_GetValidIGD( devlist, &map->upnpUrls, &map->upnpData,
        		map->lanaddr, sizeof( map->lanaddr ) ) )
        {
            dbg_printf( "Found Internet Gateway Device \"%s\" \n", map->upnpUrls.controlURL );
            dbg_printf( "Local Address is \"%s\" \n", map->lanaddr );
            map->upnpState = ML_UPNP_IDLE;
            map->upnpDiscovered = 1;
        }
        else
        {
            map->upnpState = ML_UPNP_ERR;
            dbg_printf( "UPNP_GetValidIGD failed (errno %d - %s)\n", errno, str_errno( errno ) );
            dbg_printf( "If your router supports UPnP, please make sure UPnP is enabled!\n" );
        }
        freeUPNPDevlist( devlist );
    }

    if( map->upnpState == ML_UPNP_IDLE )
    {
        if( map->upnpMapped && ( !map->enabled ) )
        	map->upnpState = ML_UPNP_UNMAP;
    }

    if( map->enabled && map->upnpMapped && map->doPortCheck )
    {
        char portStr[8];
        char intPort[8];
        char intClient[16];
        char type[8];
        int i;

        snprintf( portStr, sizeof( portStr ), "%d", map->extPort );
        snprintf( type, sizeof( type ), "%s", ( map->isTcp ? "TCP" : "UDP" ) );
        i = UPNP_GetSpecificPortMappingEntry( map->upnpUrls.controlURL,
                                              map->upnpData.first.servicetype, portStr,
                                              type,
#if MINIUPNPC_API_VERSION >= 10
                                              NULL, /* remoteHost */
#endif
                                              intClient, intPort, NULL, NULL, NULL );
        if( i != UPNPCOMMAND_SUCCESS )
        {
            dbg_printf( "Port %d isn't forwarded\n", map->extPort );
            map->upnpMapped = 0;
        }
        map->doPortCheck = 0;
    }

    if( map->upnpState == ML_UPNP_UNMAP )
    {
        char portStr[16];
        char type[8];
        snprintf( portStr, sizeof( portStr ), "%d", map->extPort );
        snprintf( type, sizeof( type ), "%s", ( map->isTcp ? "TCP" : "UDP" ) );
        UPNP_DeletePortMapping( map->upnpUrls.controlURL,
                                map->upnpData.first.servicetype,
                                portStr, type, NULL );
        dbg_printf( "Stopping port forwarding through \"%s\", service \"%s\"\n", map->upnpUrls.controlURL, map->upnpData.first.servicetype );
        map->upnpMapped = 0;
        map->upnpState = ML_UPNP_IDLE;
        map->extPort = 0;
    }

    if( map->upnpState == ML_UPNP_IDLE )
    {
        if( map->enabled && !map->upnpMapped )
            map->upnpState = ML_UPNP_MAP;
    }

    if( map->upnpState == ML_UPNP_MAP )
    {
        int  err = -1;
        errno = 0;

        if( !map->upnpUrls.controlURL || !map->upnpData.first.servicetype )
            map->upnpMapped = 0;
        else
        {
            char intPortStr[16];
            char extPortStr[16];
            char desc[64];
            char type[8];
            snprintf( intPortStr, sizeof( intPortStr ), "%d", map->intPort );
            snprintf( extPortStr, sizeof( extPortStr ), "%d", map->extPort );
            snprintf( desc, sizeof( desc ), "%s", map->notes );
            snprintf( type, sizeof( type ), "%s", ( map->isTcp ? "TCP" : "UDP" ) );
            err = UPNP_AddPortMapping( map->upnpUrls.controlURL,
                                       map->upnpData.first.servicetype,
                                       extPortStr, intPortStr, map->lanaddr,
                                       desc, type, NULL, "0" );
            map->upnpMapped = !err;
        }
        dbg_printf( "Port forwarding through \"%s\", service \"%s\". (local address[%s:%d])\n", map->upnpUrls.controlURL, map->upnpData.first.servicetype, map->lanaddr, map->intPort );
        if( map->upnpMapped )
        {
            dbg_printf( "Port forwarding successful!\n" );
            //handle->port = port;
            map->upnpState = ML_UPNP_IDLE;
        }
        else
        {
            dbg_printf( "Port forwarding failed with error %d (errno %d - %s)\n", err, errno, str_errno( errno ) );
            dbg_printf( "If your router supports UPnP, please make sure UPnP is enabled!\n" );
            //handle->port = -1;
            map->upnpState = ML_UPNP_ERR;
        }
    }

    switch( map->upnpState )
    {
        case ML_UPNP_DISCOVER:
            ret = ML_PORT_UNMAPPED; break;

        case ML_UPNP_MAP:
            ret = ML_PORT_MAPPING; break;

        case ML_UPNP_UNMAP:
            ret = ML_PORT_UNMAPPING; break;

        case ML_UPNP_IDLE:
            ret = map->upnpMapped ? ML_PORT_MAPPED
                  : ML_PORT_UNMAPPED; break;

        default:
            ret = ML_PORT_ERROR; break;
    }

    return ret;
}
Ejemplo n.º 14
0
// redirect port on external upnp enabled router to port on *this* host
int upnpredirect(const char* eport, const char* iport, const char* proto, const char* description)
{
    
    //  Discovery parameters
    struct UPNPDev * devlist = 0;
    struct UPNPUrls urls;
    struct IGDdatas data;
    int i;
    char lanaddr[64];	// my ip address on the LAN
    const char* leaseDuration="0";
    
    //  Redirect & test parameters
    char intClient[40];
    char intPort[6];
    char externalIPAddress[40];
    char duration[16];
    int error=0;
    
    //  Find UPNP devices on the network
    if ((devlist=upnpDiscover(2000, 0, 0,0, 0, &error))) {
        struct UPNPDev * device = 0;
        printf("UPNP INIALISED: List of UPNP devices found on the network.\n");
        for(device = devlist; device; device = device->pNext) {
            printf("UPNP INFO: dev [%s] \n\t st [%s]\n",
                   device->descURL, device->st);
        }
    } else {
        printf("UPNP ERROR: no device found - MANUAL PORTMAP REQUIRED\n");
        return 0;
    }
    
    //  Output whether we found a good one or not.
    if((error = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)))) {
        switch(error) {
            case 1:
                printf("UPNP OK: Found valid IGD : %s\n", urls.controlURL);
                break;
            case 2:
                printf("UPNP WARN: Found a (not connected?) IGD : %s\n", urls.controlURL);
                break;
            case 3:
                printf("UPNP WARN: UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
                break;
            default:
                printf("UPNP WARN: Found device (igd ?) : %s\n", urls.controlURL);
        }
        printf("UPNP OK: Local LAN ip address : %s\n", lanaddr);
    } else {
        printf("UPNP ERROR: no device found - MANUAL PORTMAP REQUIRED\n");
        return 0;
    }
    
    //  Get the external IP address (just because we can really...)
    if(UPNP_GetExternalIPAddress(urls.controlURL,
                                 data.first.servicetype,
                                 externalIPAddress)!=UPNPCOMMAND_SUCCESS)
        printf("UPNP WARN: GetExternalIPAddress failed.\n");
    else
        printf("UPNP OK: ExternalIPAddress = %s\n", externalIPAddress);
    
    //  Check for existing supernet mapping - from this host and another host
    //  In theory I can adapt this so multiple nodes can exist on same lan and choose a different portmap
    //  for each one :)
    //  At the moment just delete a conflicting portmap and override with the one requested.
    i=0;
    error=0;
    do {
        char index[6];
        char extPort[6];
        char desc[80];
        char enabled[6];
        char rHost[64];
        char protocol[4];
        
        snprintf(index, 6, "%d", i++);
        
        if(!(error=UPNP_GetGenericPortMappingEntry(urls.controlURL,
                                                   data.first.servicetype,
                                                   index,
                                                   extPort, intClient, intPort,
                                                   protocol, desc, enabled,
                                                   rHost, duration))) {
            // printf("%2d %s %5s->%s:%-5s '%s' '%s' %s\n",i, protocol, extPort, intClient, intPort,desc, rHost, duration);
            
            // check for an existing supernet mapping on this host
            if(!strcmp(lanaddr, intClient)) { // same host
                if(!strcmp(protocol,proto)) { //same protocol
                    if(!strcmp(intPort,iport)) { // same port
                        printf("UPNP WARN: existing mapping found (%s:%s)\n",lanaddr,iport);
                        if(!strcmp(extPort,eport)) {
                            printf("UPNP OK: exact mapping already in place (%s:%s->%s)\n", lanaddr, iport, eport);
                            FreeUPNPUrls(&urls);
                            freeUPNPDevlist(devlist);
                            return 1;
                            
                        } else { // delete old mapping
                            printf("UPNP WARN: deleting existing mapping (%s:%s->%s)\n",lanaddr, iport, extPort);
                            if(UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, extPort, proto, rHost))
                                printf("UPNP WARN: error deleting old mapping (%s:%s->%s) continuing\n", lanaddr, iport, extPort);
                            else printf("UPNP OK: old mapping deleted (%s:%s->%s)\n",lanaddr, iport, extPort);
                        }
                    }
                }
            } else { // ipaddr different - check to see if requested port is already mapped
                if(!strcmp(protocol,proto)) {
                    if(!strcmp(extPort,eport)) {
                        printf("UPNP WARN: EXT port conflict mapped to another ip (%s-> %s vs %s)\n", extPort, lanaddr, intClient);
                        if(UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, extPort, proto, rHost))
                            printf("UPNP WARN: error deleting conflict mapping (%s:%s) continuing\n", intClient, extPort);
                        else printf("UPNP OK: conflict mapping deleted (%s:%s)\n",intClient, extPort);
                    }
                }
            }
        } else
            printf("UPNP OK: GetGenericPortMappingEntry() End-of-List (%d entries) \n", i);
    } while(error==0);
    
    //  Set the requested port mapping
    if((i=UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
                              eport, iport, lanaddr, description,
                              proto, 0, leaseDuration))!=UPNPCOMMAND_SUCCESS) {
        printf("UPNP ERROR: AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
               eport, iport, lanaddr, i, strupnperror(i));
        
        FreeUPNPUrls(&urls);
        freeUPNPDevlist(devlist);
        return 0; //error - adding the port map primary failure
    }
    
    if((i=UPNP_GetSpecificPortMappingEntry(urls.controlURL,
                                           data.first.servicetype,
                                           eport, proto, NULL/*remoteHost*/,
                                           intClient, intPort, NULL/*desc*/,
                                           NULL/*enabled*/, duration))!=UPNPCOMMAND_SUCCESS) {
        printf("UPNP ERROR: GetSpecificPortMappingEntry(%s, %s, %s) failed with code %d (%s)\n", eport, iport, lanaddr,
               i, strupnperror(i));
        FreeUPNPUrls(&urls);
        freeUPNPDevlist(devlist);
        return 0; //error - port map wasnt returned by query so likely failed.
    }
    else printf("UPNP OK: EXT (%s:%s) %s redirected to INT (%s:%s) (duration=%s)\n",externalIPAddress, eport, proto, intClient, intPort, duration);
    FreeUPNPUrls(&urls);
    freeUPNPDevlist(devlist);
    return 1; //ok - we are mapped:)
}