Пример #1
0
/** Fetch our likely public IP from our upstream UPnP IGD enabled NAT device.
 * Use the connection context stored in <b>backend_state</b>. */
int
tor_upnp_fetch_public_ip(tor_fw_options_t *options, void *backend_state)
{
  miniupnpc_state_t *state = (miniupnpc_state_t *) backend_state;
  int r;
  char externalIPAddress[16];

  if (!state->init) {
    r = tor_upnp_init(options, state);
    if (r != UPNP_ERR_SUCCESS)
      return r;
  }

  r = UPNP_GetExternalIPAddress(state->urls.controlURL,
                                state->data.first.servicetype,
                                externalIPAddress);

  if (r != UPNPCOMMAND_SUCCESS)
    goto err;

  if (externalIPAddress[0]) {
    fprintf(stderr, "tor-fw-helper: ExternalIPAddress = %s\n",
            externalIPAddress); tor_upnp_cleanup(options, state);
    options->public_ip_status = 1;
    return UPNP_ERR_SUCCESS;
  } else {
    goto err;
  }

 err:
  tor_upnp_cleanup(options, state);
  return UPNP_ERR_GETEXTERNALIP;
}
Пример #2
0
string UPNPCheckDlg::MiniUPnPc_getExternalIP(string& url, string&  service)
{
	char buf[16] = { 0 };
	if (UPNP_GetExternalIPAddress(url.c_str(), service.c_str(), buf) == UPNPCOMMAND_SUCCESS)
		return buf;
	return Util::emptyString;
}
Пример #3
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);
	}
}
Пример #4
0
static PyObject *
UPnP_externalipaddress(UPnPObject *self)
{
	char externalIPAddress[16];
	externalIPAddress[0] = '\0';
	UPNP_GetExternalIPAddress(self->urls.controlURL,
	                          self->data.servicetype,
							  externalIPAddress);
	return Py_BuildValue("s", externalIPAddress);
}
Пример #5
0
bool Gateway::_getExternalIPAddress()
{
	if (UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, tmp) != 0) {
		return false;
	}

	externalIPAddress = CString(tmp);

	return true;
}
Пример #6
0
static void DisplayInfos(struct UPNPUrls * urls,
                         struct IGDdatas * data)
{
	char externalIPAddress[40];
	char connectionType[64];
	char status[64];
	char lastconnerr[64];
	unsigned int uptime = 0;
	unsigned int brUp, brDown;
	time_t timenow, timestarted;
	int r;
	if(UPNP_GetConnectionTypeInfo(urls->controlURL,
	                              data->first.servicetype,
	                              connectionType) != UPNPCOMMAND_SUCCESS)
		printf("GetConnectionTypeInfo failed.\n");
	else
		printf("Connection Type : %s\n", connectionType);
	if(UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
	                      status, &uptime, lastconnerr) != UPNPCOMMAND_SUCCESS)
		printf("GetStatusInfo failed.\n");
	else
		printf("Status : %s, uptime=%us, LastConnectionError : %s\n",
		       status, uptime, lastconnerr);
	if(uptime > 0) {
		timenow = time(NULL);
		timestarted = timenow - uptime;
		printf("  Time started : %s", ctime(&timestarted));
	}
	if(UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype,
	                                &brDown, &brUp) != UPNPCOMMAND_SUCCESS) {
		printf("GetLinkLayerMaxBitRates failed.\n");
	} else {
		printf("MaxBitRateDown : %u bps", brDown);
		if(brDown >= 1000000) {
			printf(" (%u.%u Mbps)", brDown / 1000000, (brDown / 100000) % 10);
		} else if(brDown >= 1000) {
			printf(" (%u Kbps)", brDown / 1000);
		}
		printf("   MaxBitRateUp %u bps", brUp);
		if(brUp >= 1000000) {
			printf(" (%u.%u Mbps)", brUp / 1000000, (brUp / 100000) % 10);
		} else if(brUp >= 1000) {
			printf(" (%u Kbps)", brUp / 1000);
		}
		printf("\n");
	}
	r = UPNP_GetExternalIPAddress(urls->controlURL,
	                          data->first.servicetype,
							  externalIPAddress);
	if(r != UPNPCOMMAND_SUCCESS) {
		printf("GetExternalIPAddress failed. (errorcode=%d)\n", r);
	} else {
		printf("ExternalIPAddress = %s\n", externalIPAddress);
	}
}
Пример #7
0
boost::optional<HostAddress> MiniUPnPInterface::getPublicIP() {
	if (!p->isValid) {
		return boost::optional<HostAddress>();
	}
	char externalIPAddress[40];
	int ret = UPNP_GetExternalIPAddress(p->urls.controlURL, p->data.first.servicetype, externalIPAddress);
	if (ret != UPNPCOMMAND_SUCCESS) {
		return boost::optional<HostAddress>();
	}
	else {
		return HostAddress(std::string(externalIPAddress));
	}
}
Пример #8
0
static switch_status_t get_upnp_pubaddr(char *pub_addr)
{
	if (UPNP_GetExternalIPAddress(nat_globals.urls.controlURL, nat_globals.data.servicetype, pub_addr) == UPNPCOMMAND_SUCCESS) {
		if (!strcmp(pub_addr, "0.0.0.0") || zstr_buf(pub_addr)) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
							  "uPNP Device (url: %s) returned an invalid external address of '%s'.  Disabling uPNP\n", nat_globals.urls.controlURL,
							  pub_addr);
			return SWITCH_STATUS_GENERR;
		}
	} else {
		return SWITCH_STATUS_GENERR;
	}
	return SWITCH_STATUS_SUCCESS;
}
Пример #9
0
static PyObject *
UPnP_externalipaddress(UPnPObject *self)
{
	char externalIPAddress[16];
	int r;
	externalIPAddress[0] = '\0';
	r = UPNP_GetExternalIPAddress(self->urls.controlURL,
	                              self->data.servicetype,
	                              externalIPAddress);
	if(r==UPNPCOMMAND_SUCCESS) {
		return Py_BuildValue("s", externalIPAddress);
	} else {
		/* TODO: have our own exception type ! */
		PyErr_SetString(PyExc_Exception, strupnperror(r));
		return NULL;
	}
}
Пример #10
0
    void UPnP::Discover ()
    {
        int nerror = 0;
#if MINIUPNPC_API_VERSION >= 14
        m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, 2, &nerror);
#else
        m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror);
#endif
		{
			// notify satrting thread			
			std::unique_lock<std::mutex> l(m_StartedMutex);
			m_Started.notify_all ();
		}	
		
        int r;
        r = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr));
        if (r == 1)
        {
            r = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress);
            if(r != UPNPCOMMAND_SUCCESS)
            {
                LogPrint (eLogError, "UPnP: UPNP_GetExternalIPAddress() returned ", r);
                return;
            }
            else
            {
                if (!m_externalIPAddress[0])
                {
                    LogPrint (eLogError, "UPnP: GetExternalIPAddress() failed.");
                    return;
                }
            }
        }
		else
		{
			 LogPrint (eLogError, "UPnP: GetValidIGD() failed.");
             return;
		}

		// UPnP discovered	
		LogPrint (eLogDebug, "UPnP: ExternalIPAddress is ", m_externalIPAddress);
        i2p::context.UpdateAddress (boost::asio::ip::address::from_string (m_externalIPAddress));
		// port mapping
		PortMapping ();
    }
Пример #11
0
void
Portfwd::get_status()
{
    // get connection speed
    UPNP_GetLinkLayerMaxBitRates(
        urls->controlURL_CIF, data->servicetype_CIF, &m_downbps, &m_upbps);

    // get external IP adress
    char ip[16];
    if( 0 != UPNP_GetExternalIPAddress( urls->controlURL, 
                                        data->servicetype, 
                                        (char*)&ip ) )
    {
        m_externalip = ""; //failed
    }else{
        m_externalip = std::string(ip);
    }
}
Пример #12
0
gchar *
vino_upnp_get_external_ip (VinoUpnp *upnp)
{
  gchar ip[16];

  g_return_val_if_fail (VINO_IS_UPNP (upnp), NULL);

  if (!update_upnp_status (upnp))
    return NULL;

  UPNP_GetExternalIPAddress (upnp->priv->urls->controlURL,
			     upnp->priv->data->servicetype,
			     ip);
  if (ip[0])
    if (strcmp (ip, "0.0.0.0") == 0)
      return NULL;
    else
      return g_strdup (ip);
  else
    return NULL;
}
Пример #13
0
static void DisplayInfos(struct UPNPUrls * urls,
                         struct IGDdatas * data)
{
    char externalIPAddress[16];
    char connectionType[64];
    char status[64];
    char lastconnerr[64];
    unsigned int uptime;
    unsigned int brUp, brDown;
    time_t timenow, timestarted;
    int r;
    UPNP_GetConnectionTypeInfo(urls->controlURL,
                               data->first.servicetype,
                               connectionType);
    if(connectionType[0])
        printf("Connection Type : %s\n", connectionType);
    else
        printf("GetConnectionTypeInfo failed.\n");
    UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
                       status, &uptime, lastconnerr);
    printf("Status : %s, uptime=%us, LastConnectionError : %s\n",
           status, uptime, lastconnerr);
    timenow = time(NULL);
    timestarted = timenow - uptime;
    printf("  Time started : %s", ctime(&timestarted));
    UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype,
                                 &brDown, &brUp);
    printf("MaxBitRateDown : %u bps   MaxBitRateUp %u bps\n", brDown, brUp);
    r = UPNP_GetExternalIPAddress(urls->controlURL,
                                  data->first.servicetype,
                                  externalIPAddress);
    if(r != UPNPCOMMAND_SUCCESS)
        printf("GetExternalIPAddress() returned %d\n", r);
    if(externalIPAddress[0])
        printf("ExternalIPAddress = %s\n", externalIPAddress);
    else
        printf("GetExternalIPAddress failed.\n");
}
Пример #14
0
/* UPNP_GetValidIGD() :
 * return values :
 *    -1 = Internal error
 *     0 = NO IGD found
 *     1 = A valid connected IGD has been found
 *     2 = A valid IGD has been found but it reported as
 *         not connected
 *     3 = an UPnP device has been found but was not recognized as an IGD
 *
 * In any positive non zero return case, the urls and data structures
 * passed as parameters are set. Don't forget to call FreeUPNPUrls(urls) to
 * free allocated memory.
 */
MINIUPNP_LIBSPEC int
UPNP_GetValidIGD(struct UPNPDev * devlist,
                 struct UPNPUrls * urls,
				 struct IGDdatas * data,
				 char * lanaddr, int lanaddrlen)
{
	struct xml_desc {
		char * xml;
		int size;
		int is_igd;
	} * desc = NULL;
	struct UPNPDev * dev;
	int ndev = 0;
	int i;
	int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
	char extIpAddr[16];
	char myLanAddr[40];
	int status_code = -1;

	if(!devlist)
	{
#ifdef DEBUG
		printf("Empty devlist\n");
#endif
		return 0;
	}
	/* counting total number of devices in the list */
	for(dev = devlist; dev; dev = dev->pNext)
		ndev++;
	/* ndev is always > 0 */
	desc = calloc(ndev, sizeof(struct xml_desc));
	if(!desc)
		return -1; /* memory allocation error */
	/* Step 1 : downloading descriptions and testing type */
	for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
	{
		/* we should choose an internet gateway device.
		 * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
		desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size),
		                               myLanAddr, sizeof(myLanAddr),
		                               dev->scope_id, &status_code);
#ifdef DEBUG
		if(!desc[i].xml)
		{
			printf("error getting XML description %s\n", dev->descURL);
		}
#endif
		if(desc[i].xml)
		{
			memset(data, 0, sizeof(struct IGDdatas));
			memset(urls, 0, sizeof(struct UPNPUrls));
			parserootdesc(desc[i].xml, desc[i].size, data);
			if(COMPARE(data->CIF.servicetype,
			           "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:"))
			{
				desc[i].is_igd = 1;
				if(lanaddr)
					strncpy(lanaddr, myLanAddr, lanaddrlen);
			}
		}
	}
	/* iterate the list to find a device depending on state */
	for(state = 1; state <= 3; state++)
	{
		for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
		{
			if(desc[i].xml)
			{
				memset(data, 0, sizeof(struct IGDdatas));
				memset(urls, 0, sizeof(struct UPNPUrls));
				parserootdesc(desc[i].xml, desc[i].size, data);
				if(desc[i].is_igd || state >= 3 )
				{
				  int is_connected;

				  GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);

				  /* in state 2 and 3 we don't test if device is connected ! */
				  if(state >= 2)
				    goto free_and_return;
				  is_connected = UPNPIGD_IsConnected(urls, data);
#ifdef DEBUG
				  printf("UPNPIGD_IsConnected(%s) = %d\n",
				     urls->controlURL, is_connected);
#endif
				  /* checks that status is connected AND there is a external IP address assigned */
				  if(is_connected &&
				     (UPNP_GetExternalIPAddress(urls->controlURL,  data->first.servicetype, extIpAddr) == 0)) {
					if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0')
					   && (0 != strcmp(extIpAddr, "0.0.0.0")))
					  goto free_and_return;
				  }
				  FreeUPNPUrls(urls);
				  if(data->second.servicetype[0] != '\0') {
#ifdef DEBUG
				    printf("We tried %s, now we try %s !\n",
				           data->first.servicetype, data->second.servicetype);
#endif
				    /* swaping WANPPPConnection and WANIPConnection ! */
				    memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service));
				    memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
				    memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service));
				    GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
				    is_connected = UPNPIGD_IsConnected(urls, data);
#ifdef DEBUG
				    printf("UPNPIGD_IsConnected(%s) = %d\n",
				       urls->controlURL, is_connected);
#endif
				    if(is_connected &&
				       (UPNP_GetExternalIPAddress(urls->controlURL,  data->first.servicetype, extIpAddr) == 0)) {
					  if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0')
					     && (0 != strcmp(extIpAddr, "0.0.0.0")))
					    goto free_and_return;
				    }
				    FreeUPNPUrls(urls);
				  }
				}
				memset(data, 0, sizeof(struct IGDdatas));
			}
		}
	}
	state = 0;
free_and_return:
	for(i = 0; i < ndev; i++)
		free(desc[i].xml);
	free(desc);
	return state;
}
Пример #15
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:)
}
Пример #16
0
	void threadMain()
		throw()
	{
		char lanaddr[4096];
		char externalip[4096]; // no range checking? so make these buffers larger than any UDP packet a uPnP server could send us as a precaution :P
		char inport[16];
		char outport[16];
		struct UPNPUrls urls;
		struct IGDdatas data;

#ifdef ZT_UPNP_TRACE
		fprintf(stderr,"UPNPClient: started for UDP port %d"ZT_EOL_S,localPort);
#endif

		unsigned int tryPortStart = 0;
		Utils::getSecureRandom(&tryPortStart,sizeof(tryPortStart));
		tryPortStart = (tryPortStart % (65535 - 1025)) + 1025;

		while (run) {
			{
				int upnpError = 0;
				UPNPDev *devlist = upnpDiscover(2000,(const char *)0,(const char *)0,0,0,0,&upnpError);
				if (devlist) {
#ifdef ZT_UPNP_TRACE
					{
						UPNPDev *dev = devlist;
						while (dev) {
							fprintf(stderr,"UPNPClient: found device at URL '%s': %s"ZT_EOL_S,dev->descURL,dev->st);
							dev = dev->pNext;
						}
					}
#endif

					memset(lanaddr,0,sizeof(lanaddr));
					memset(externalip,0,sizeof(externalip));
					memset(&urls,0,sizeof(urls));
					memset(&data,0,sizeof(data));
					Utils::snprintf(inport,sizeof(inport),"%d",localPort);

					if ((UPNP_GetValidIGD(devlist,&urls,&data,lanaddr,sizeof(lanaddr)))&&(lanaddr[0])) {
#ifdef ZT_UPNP_TRACE
						fprintf(stderr,"UPNPClient: my LAN IP address: %s"ZT_EOL_S,lanaddr);
#endif
						if ((UPNP_GetExternalIPAddress(urls.controlURL,data.first.servicetype,externalip) == UPNPCOMMAND_SUCCESS)&&(externalip[0])) {
#ifdef ZT_UPNP_TRACE
							fprintf(stderr,"UPNPClient: my external IP address: %s"ZT_EOL_S,externalip);
#endif

							for(int tries=0;tries<64;++tries) {
								int tryPort = (int)tryPortStart + tries;
								if (tryPort >= 65535)
									tryPort = (tryPort - 65535) + 1025;
								Utils::snprintf(outport,sizeof(outport),"%u",tryPort);

								int mapResult = 0;
								if ((mapResult = UPNP_AddPortMapping(urls.controlURL,data.first.servicetype,outport,inport,lanaddr,"ZeroTier","UDP",(const char *)0,"0")) == UPNPCOMMAND_SUCCESS) {
	#ifdef ZT_UPNP_TRACE
									fprintf(stderr,"UPNPClient: reserved external port: %s"ZT_EOL_S,outport);
	#endif
									{
										Mutex::Lock sl(surface_l);
										surface.clear();
										InetAddress tmp(externalip);
										tmp.setPort(tryPort);
										surface.push_back(tmp);
									}
									break;
								} else {
	#ifdef ZT_UPNP_TRACE
									fprintf(stderr,"UPNPClient: UPNP_AddAnyPortMapping(%s) failed: %d"ZT_EOL_S,outport,mapResult);
	#endif
									Thread::sleep(1000);
								}
							}
						} else {
#ifdef ZT_UPNP_TRACE
							fprintf(stderr,"UPNPClient: UPNP_GetExternalIPAddress failed"ZT_EOL_S);
#endif
						}
					} else {
#ifdef ZT_UPNP_TRACE
						fprintf(stderr,"UPNPClient: UPNP_GetValidIGD failed"ZT_EOL_S);
#endif
					}

					freeUPNPDevlist(devlist);
				} else {
#ifdef ZT_UPNP_TRACE
					fprintf(stderr,"UPNPClient: upnpDiscover error code: %d"ZT_EOL_S,upnpError);
#endif
				}
			}

#ifdef ZT_UPNP_TRACE
			fprintf(stderr,"UPNPClient: rescanning in %d ms"ZT_EOL_S,ZT_UPNP_CLIENT_REFRESH_DELAY);
#endif
			Thread::sleep(ZT_UPNP_CLIENT_REFRESH_DELAY);
		}
		delete this;
	}
Пример #17
0
void upnp_service::map_port( uint16_t local_port )
{
  std::string port = fc::variant(local_port).as_string();

  my->map_port_complete = my->upnp_thread.async( [=]() {
      const char * multicastif = 0;
      const char * minissdpdpath = 0;
      struct UPNPDev * devlist = 0;
      char lanaddr[64];
      
      /* miniupnpc 1.6 */
      int error = 0;
      devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);

      struct UPNPUrls urls;
      memset( &urls, 0, sizeof(urls) );
      struct IGDdatas data;
      memset( &data, 0, sizeof(data) );
      int r;
      
      r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));

      bool port_mapping_added = false;
      bool port_mapping_added_successfully = false;

       if (r == 1)
       {
           if (true) //  TODO  config this ?  fDiscover) 
           {
               char externalIPAddress[40];
               r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
               if(r != UPNPCOMMAND_SUCCESS)
                   wlog("UPnP: GetExternalIPAddress() returned ${code}", ("code", r));
               else
               {
                   if(externalIPAddress[0])
                   {
                       ulog("UPnP: ExternalIPAddress = ${address}", ("address", externalIPAddress));
                       my->external_ip = fc::ip::address( std::string(externalIPAddress) );
                       // AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
                   }
                   else
                       wlog("UPnP: GetExternalIPAddress failed.");
               }
           }
       
           std::string strDesc = "BitShares 0.0"; // TODO  + FormatFullVersion();
       
     //      try 
           {
               while(!my->done)  // TODO provide way to exit cleanly
               {
                   /* miniupnpc 1.6 */
                   r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
                                       port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
       
                   port_mapping_added = true;
                   if(r!=UPNPCOMMAND_SUCCESS)
                       wlog("AddPortMapping(${port}, ${port}, ${addr}) failed with code ${code} (${string})",
                            ("port", port)("addr", lanaddr)("code", r)("string", strupnperror(r)));
                   else
                   {
                       if (!port_mapping_added_successfully)
                         ulog("UPnP Port Mapping successful");
                       port_mapping_added_successfully = true;

                       my->mapped_port = local_port;
                   }
       
                   fc::usleep( fc::seconds(60*20) ); // Refresh every 20 minutes
               }
           }
     //      catch (boost::thread_interrupted)
           {
               if( port_mapping_added )
               {
                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
                 ilog("UPNP_DeletePortMapping() returned : ${r}", ("r",r));
                 freeUPNPDevlist(devlist); devlist = 0;
                 FreeUPNPUrls(&urls);
               }
      //         throw;
           }
       } else {
           //printf("No valid UPnP IGDs found\n");
           wlog("No valid UPnP IGDs found");
           freeUPNPDevlist(devlist); devlist = 0;
           if (r != 0)
           {
               FreeUPNPUrls(&urls);
           }
       }
  }, "upnp::map_port" );
}
string Mapper_MiniUPnPc::getExternalIP() {
	char buf[16] = { 0 };
	if(UPNP_GetExternalIPAddress(url.c_str(), service.c_str(), buf) == UPNPCOMMAND_SUCCESS)
		return buf;
	return Util::emptyString;
}
Пример #19
0
void init_upnp (void)
{
	struct UPNPDev * devlist;
	struct UPNPDev * dev;
	char * descXML;
	int descXMLsize = 0;
    int res = 0;

    char IPAddress[40];
    int r;

    if (!sv_upnp)
        return;

	memset(&urls, 0, sizeof(struct UPNPUrls));
	memset(&data, 0, sizeof(struct IGDdatas));

	Printf(PRINT_HIGH, "UPnP: Discovering router (max 1 unit supported)\n");

	devlist = upnpDiscover(sv_upnp_discovertimeout.asInt(), NULL, NULL, 0, 0, &res);

	if (!devlist || res != UPNPDISCOVER_SUCCESS)
    {
		Printf(PRINT_HIGH, "UPnP: Router not found or timed out, error %d\n",
            res);

        is_upnp_ok = false;

        return;
    }

    dev = devlist;

    while (dev)
    {
        if (strstr (dev->st, "InternetGatewayDevice"))
            break;
        dev = dev->pNext;
    }

    if (!dev)
        dev = devlist; /* defaulting to first device */

    //Printf(PRINT_HIGH, "UPnP device :\n"
      //      " desc: %s\n st: %s\n",
        //    dev->descURL, dev->st);

    descXML = (char *)miniwget(dev->descURL, &descXMLsize, 0);

    if (descXML)
    {
        parserootdesc (descXML, descXMLsize, &data);
        free (descXML);
        descXML = NULL;
        GetUPNPUrls (&urls, &data, dev->descURL, 0);
    }

    freeUPNPDevlist(devlist);

    r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype,
            IPAddress);

    if (r != 0)
    {
        Printf(PRINT_HIGH,
            "UPnP: Router found but unable to get external IP address\n");

        is_upnp_ok = false;
    }
    else
    {
        Printf(PRINT_HIGH, "UPnP: Router found, external IP address is: %s\n",
            IPAddress);

        // Store ip address just in case admin wants it
        sv_upnp_externalip.ForceSet(IPAddress);

        is_upnp_ok = true;
    }
}
Пример #20
0
/* UPNP_GetValidIGDe) :
 * return values :
 *    -1 = Internal error
 *     0 = NO IGD found
 *     1 = A valid connected IGD has been found
 *     2 = A valid IGD has been found but it reported as
 *         not connected
 *     3 = an UPnP device has been found but was not recognized as an IGD
 *
 * In any positive non zero return case, the urls and data structures
 * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
 * free allocated memory.
 */
MINIUPNP_LIBSPEC int
UPNP_GetValidIGD(struct UPNPDev * devlist,
                 struct UPNPUrls * urls,
                 struct IGDdatas * data,
                 char * lanaddr, int lanaddrlen)
{
    struct xml_desc {
        char * xml;
        int size;
        int is_igd;
    } * desc = NULL;
    struct UPNPDev * dev;
    int ndev = 0;
    int i;
    int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
    int n_igd = 0;
    char extIpAddr[16];
    struct UPNPDevInfo IGDInfo;
    char *dut_lanaddr;
    char IGDDescURL[256];

    if(!devlist)
    {
#ifdef DEBUG
        printf("Empty devlist\n");
#endif
        return 0;
    }
    /* counting total number of devices in the list */
    for(dev = devlist; dev; dev = dev->pNext)
        ndev++;
    if(ndev > 0)
    {
        desc = calloc(ndev, sizeof(struct xml_desc));
        if(!desc)
            return -1; /* memory allocation error */
    }

    dut_lanaddr = get_lan_ipaddr();

    /* Step 1 : downloading descriptions and testing type */
    for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
    {
        memset(&IGDInfo, 0, sizeof(struct UPNPDevInfo));
        /* we should choose an internet gateway device.
         * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
        strcpy(IGDDescURL, dev->descURL);
        desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size),
                                       lanaddr, lanaddrlen,
                                       dev->scope_id, &IGDInfo, dut_lanaddr);

#ifdef DEBUG
        if(!desc[i].xml)
        {
            printf("error getting XML description %s\n", dev->descURL);
        }
#endif
        if(desc[i].xml)
        {
            memset(data, 0, sizeof(struct IGDdatas));
            memset(urls, 0, sizeof(struct UPNPUrls));
            /* parserootdesc(desc[i].xml, desc[i].size, data); */

#ifdef DEBUG
            FILE *xml_fd;
            xml_fd = fopen("/tmp/upnpc_xml.log", "w");
            fprintf(xml_fd, "============= XML ==============\n");
            fprintf(xml_fd, "%s\n", desc[i].xml);
            parsedescxml(desc[i].xml, &IGDInfo.friendlyName, &IGDInfo.iconUrl);
            fprintf(xml_fd, "    HostName: %s\n", IGDInfo.hostname);
            fprintf(xml_fd, "    type:     %s\n", IGDInfo.type);
            fprintf(xml_fd, "    F Name:   %s\n", IGDInfo.friendlyName);
            fprintf(xml_fd, "    Icon URL: %s\n", IGDInfo.iconUrl);
            fprintf(xml_fd, "================================\n\n");
            syslog(LOG_NOTICE, "parse icon url: %s", IGDInfo.iconUrl);
#endif

            strcpy(dev->DevInfo.hostname, IGDInfo.hostname);
            strcpy(dev->DevInfo.type, IGDInfo.type);
            strcpy(dev->DevInfo.friendlyName, IGDInfo.friendlyName);
            strcpy(dev->DevInfo.iconUrl, IGDInfo.iconUrl);

#ifdef RTCONFIG_JFFS2USERICON
            if(strcmp(IGDInfo.iconUrl, "") != NULL) {
                char realIconUrl[158], iconFile[32], iconBuf[512];
                char *ico_head, *ico_end;
                char *icon, *p, *q;
                int  iconSize, i = 0, iconCheck = 0;
                FILE *ico_fd;

                memset(realIconUrl, 0, 158);
                if(strstr(IGDInfo.iconUrl, "http://")) {
                    strcpy(realIconUrl, IGDInfo.iconUrl);
                }
                else {
                    q = IGDDescURL;
                    while(q = strchr(q, '/')) {
                        i++;
                        if(i == 3) {
                            p = IGDDescURL;
                            i = 0;
                            while ( p < q ) {
                                realIconUrl[i++] = *p++;
                            }
                            strcat(realIconUrl, IGDInfo.iconUrl);
#ifdef DEBUG
                            printf("\n*** Real URL=%s=\n\n", realIconUrl);
#endif
                            break;
                        }
                        q++;
                    }
                }
get_icon:
#ifdef DEBUG
                syslog(LOG_NOTICE, "Real icon url: %s", realIconUrl);
                fprintf(xml_fd, "Real icon url: %s\n", realIconUrl);
#endif
                sprintf(iconFile, "/tmp/upnpicon/%s.ico", IGDInfo.hostname);

                icon = miniwget_getaddr(realIconUrl, &iconSize,
                                        lanaddr, lanaddrlen,
                                        0, &IGDInfo, dut_lanaddr);

                if( iconSize > 512 ) {
                    ico_fd = fopen(iconFile, "w");
                    if(ico_fd) {
                        fwrite(icon, sizeof(char), iconSize, ico_fd);
                        fclose(ico_fd);
                    }
                }
                else if(iconSize > 0) {
                    ico_head = strstr(icon, "<a href=");
                    if(ico_head) {
                        ico_head = ico_head+9;
                        ico_end = strstr(icon, "\">");
                        if(ico_end) {
                            *ico_end = '\0';
                            strcpy(realIconUrl, ico_head);
                            goto get_icon;
                        }
                    }
                }
            }
#endif

            if(COMPARE(data->CIF.servicetype,
                       "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:"))
            {
                desc[i].is_igd = 1;
                n_igd++;
            }
#ifdef DEBUG
            fclose(xml_fd);
#endif
        }
        else
            memset(dev->DevInfo.hostname, 0, 65);
    }

    /* iterate the list to find a device depending on state */
    for(state = 1; state <= 3; state++)
        /*if(0)*/
    {
        for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
        {
            if(desc[i].xml)
            {
                memset(data, 0, sizeof(struct IGDdatas));
                memset(urls, 0, sizeof(struct UPNPUrls));
                parserootdesc(desc[i].xml, desc[i].size, data);
                if(desc[i].is_igd || state >= 3 )
                {
                    GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);

                    /* in state 2 and 3 we dont test if device is connected ! */
                    if(state >= 2)
                        goto free_and_return;
#ifdef DEBUG
                    printf("UPNPIGD_IsConnected(%s) = %d\n",
                           urls->controlURL,
                           UPNPIGD_IsConnected(urls, data));
#endif
                    /* checks that status is connected AND there is a external IP address assigned */
                    if(UPNPIGD_IsConnected(urls, data)
                            && (UPNP_GetExternalIPAddress(urls->controlURL,  data->first.servicetype, extIpAddr) == 0))
                        goto free_and_return;
                    FreeUPNPUrls(urls);
                    if(data->second.servicetype[0] != '\0') {
#ifdef DEBUG
                        printf("We tried %s, now we try %s !\n",
                               data->first.servicetype, data->second.servicetype);
#endif
                        /* swaping WANPPPConnection and WANIPConnection ! */
                        memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service));
                        memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
                        memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service));
                        GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
#ifdef DEBUG
                        printf("UPNPIGD_IsConnected(%s) = %d\n",
                               urls->controlURL,
                               UPNPIGD_IsConnected(urls, data));
#endif
                        if(UPNPIGD_IsConnected(urls, data)
                                && (UPNP_GetExternalIPAddress(urls->controlURL,  data->first.servicetype, extIpAddr) == 0))
                            goto free_and_return;
                        FreeUPNPUrls(urls);
                    }
                }
                memset(data, 0, sizeof(struct IGDdatas));
            }
        }
    }
    state = 0;
free_and_return:
    if(desc) {
        for(i = 0; i < ndev; i++) {
            if(desc[i].xml) {
                free(desc[i].xml);
            }
        }
        free(desc);
    }
    return state;
}
Пример #21
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;
}
Пример #22
0
static bool natt_open_port(struct natt_status *status,
      struct sockaddr *addr, socklen_t addrlen, enum socket_protocol proto)
{
#ifndef HAVE_SOCKET_LEGACY
#if HAVE_MINIUPNPC
   int r;
   char host[PATH_MAX_LENGTH], ext_host[PATH_MAX_LENGTH],
        port_str[6], ext_port_str[6];
   struct addrinfo hints         = {0};
   const char *proto_str         = NULL;
   struct addrinfo *ext_addrinfo = NULL;

   /* if NAT traversal is uninitialized or unavailable, oh well */
   if (!urls.controlURL || !urls.controlURL[0])
      return false;

   /* figure out the internal info */
   if (getnameinfo(addr, addrlen, host, PATH_MAX_LENGTH,
            port_str, 6, NI_NUMERICHOST|NI_NUMERICSERV) != 0)
      return false;

   proto_str = (proto == SOCKET_PROTOCOL_UDP) ? "UDP" : "TCP";

   /* add the port mapping */
   r = UPNP_AddAnyPortMapping(urls.controlURL,
         data.first.servicetype, port_str,
         port_str, host, "retroarch",
         proto_str, NULL, "3600", ext_port_str);

   if (r != 0)
   {
      /* try the older AddPortMapping */
      memcpy(ext_port_str, port_str, 6);
      r = UPNP_AddPortMapping(urls.controlURL,
            data.first.servicetype, port_str,
            port_str, host, "retroarch",
            proto_str, NULL, "3600");
   }
   if (r != 0)
      return false;

   /* get the external IP */
   r = UPNP_GetExternalIPAddress(urls.controlURL,
         data.first.servicetype, ext_host);
   if (r != 0)
      return false;

   /* update the status */
   if (getaddrinfo_retro(ext_host,
            ext_port_str, &hints, &ext_addrinfo) != 0)
      return false;

   if (ext_addrinfo->ai_family == AF_INET &&
       ext_addrinfo->ai_addrlen >= sizeof(struct sockaddr_in))
   {
      status->have_inet4     = true;
      status->ext_inet4_addr = *((struct sockaddr_in *)
            ext_addrinfo->ai_addr);
   }
#if defined(AF_INET6) && !defined(HAVE_SOCKET_LEGACY)
   else if (ext_addrinfo->ai_family == AF_INET6 &&
            ext_addrinfo->ai_addrlen >= sizeof(struct sockaddr_in6))
   {
      status->have_inet6     = true;
      status->ext_inet6_addr = *((struct sockaddr_in6 *)
            ext_addrinfo->ai_addr);
   }
#endif
   else
   {
      freeaddrinfo_retro(ext_addrinfo);
      return false;
   }

   freeaddrinfo_retro(ext_addrinfo);
   return true;

#else
   return false;
#endif
#else
   return false;
#endif
}
Пример #23
0
bool UPnP::start()
{
    int error = 0;

    UPNPDev *devlist = ::upnpDiscover(2000, NULL, NULL, FALSE, FALSE, &error);
    UPNPDev *devlistBegin = devlist;

    // get interface list
    /*foreach(interface, interfaces) {
        newdevlist = ::upnpDiscover(2000, interface, NULL, FALSE, FALSE, &error);

        // go to end of list and append
    }*/

    while (devlist)
    {
        UPNPUrls urls;
        IGDdatas data;
        char lanaddr[64];
        UPnPHash resultHash;

        int code = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));

        if (code > 0)   // TODO maybe distinguish between the return codes (1,2,3) to add information what happend to the result
        {
            resultHash.insert(LanIpAddress, QLatin1String(lanaddr));

            char externalIP[40];

            if (UPNPCOMMAND_SUCCESS == UPNP_GetExternalIPAddress(urls.controlURL,
                                                                 data.first.servicetype,
                                                                 externalIP))
            {
                resultHash.insert(ExternalIpAddress, QLatin1String(externalIP));
            }

            char connectionType[64];

            if (UPNPCOMMAND_SUCCESS == UPNP_GetConnectionTypeInfo(urls.controlURL,
                                                                  data.first.servicetype,
                                                                  connectionType))
            {
                resultHash.insert(ConnectionType, QLatin1String(connectionType));
            }

            quint32 uplink, downlink;

            if (UPNPCOMMAND_SUCCESS == UPNP_GetLinkLayerMaxBitRates(urls.controlURL_CIF,
                                                                    data.CIF.servicetype,
                                                                    &downlink, &uplink))
            {
                resultHash.insert(LinkLayerMaxDownload, downlink);
                resultHash.insert(LinkLayerMaxUpload, uplink);
            }

            quint32 bytesSent, bytesReceived, packetsSent, packetsReceived;

            bytesSent = UPNP_GetTotalBytesSent(urls.controlURL_CIF,
                                               data.CIF.servicetype);

            if ((unsigned int)UPNPCOMMAND_HTTP_ERROR != bytesSent)
            {
                resultHash.insert(TotalBytesSent, bytesSent);
            }

            bytesReceived = UPNP_GetTotalBytesReceived(urls.controlURL_CIF,
                                                       data.CIF.servicetype);

            if ((unsigned int)UPNPCOMMAND_HTTP_ERROR != bytesReceived)
            {
                resultHash.insert(TotalBytesReceived, bytesReceived);
            }

            packetsSent = UPNP_GetTotalPacketsSent(urls.controlURL_CIF,
                                                   data.CIF.servicetype);

            if ((unsigned int)UPNPCOMMAND_HTTP_ERROR != packetsSent)
            {
                resultHash.insert(TotalPacketsSent, packetsSent);
            }


            packetsReceived = UPNP_GetTotalPacketsReceived(urls.controlURL_CIF,
                                                           data.CIF.servicetype);

            if ((unsigned int)UPNPCOMMAND_HTTP_ERROR != packetsReceived)
            {
                resultHash.insert(TotalPacketsReceived, packetsReceived);
            }


            char status[100];
            unsigned int uptime = 0;
            char lastConnectionError[128];

            if (UPNPCOMMAND_SUCCESS == UPNP_GetStatusInfo(urls.controlURL,
                                                          data.first.servicetype,
                                                          status,
                                                          &uptime,
                                                          lastConnectionError))
            {
                resultHash.insert(Status, status);
                resultHash.insert(Uptime, uptime);
                resultHash.insert(LastConnectionError, lastConnectionError);
            }

            quint32 num;

            if (UPNPCOMMAND_SUCCESS == UPNP_GetPortMappingNumberOfEntries(urls.controlURL,
                                                                          data.first.servicetype,
                                                                          &num))
            {
                resultHash.insert(NumberOfPortMappings, num);
            }

            // TODO GetListOfPortMappings do we need this?

            int firewallEnabled, inboundPinholeAllowed;

            if (UPNPCOMMAND_SUCCESS == UPNP_GetFirewallStatus(urls.controlURL,
                                                              data.first.servicetype,
                                                              &firewallEnabled,
                                                              &inboundPinholeAllowed))
            {
                resultHash.insert(FirewallEnabled, firewallEnabled);
                resultHash.insert(InboundPinholeAllowed, inboundPinholeAllowed);
            }

            int bufferSize = 0;

            if (char *buffer = (char *)miniwget(urls.rootdescURL, &bufferSize, 0))
            {
                NameValueParserData pdata;
                ParseNameValue(buffer, bufferSize, &pdata);
                free(buffer);
                buffer = NULL;

                QStringList modelName = GetValuesFromNameValueList(&pdata, "modelName");

                if (!modelName.isEmpty())
                {
                    resultHash.insert(ModelName, modelName.last());
                }

                QStringList manufacturer = GetValuesFromNameValueList(&pdata, "manufacturer");

                if (!manufacturer.isEmpty())
                {
                    resultHash.insert(Manufacturer, manufacturer.last());
                }

                QStringList friendlyName = GetValuesFromNameValueList(&pdata, "friendlyName");

                if (!friendlyName.isEmpty())
                {
                    resultHash.insert(FriendlyName, friendlyName.last());
                }

                ClearNameValueList(&pdata);
            }
        }

        FreeUPNPUrls(&urls);

        results.append(resultHash);
        devlist = devlist->pNext;
    }

    freeUPNPDevlist(devlistBegin);

    emit finished();
    return true; // TODO return false if something went wrong or if there are no results
}