Esempio n. 1
0
void
tr_upnpClose (tr_upnp * handle)
{
    assert (!handle->isMapped);
    assert ((handle->state == TR_UPNP_IDLE)
          || (handle->state == TR_UPNP_ERR)
          || (handle->state == TR_UPNP_DISCOVER));

    if (handle->hasDiscovered)
        FreeUPNPUrls (&handle->urls);
    tr_free (handle);
}
Esempio n. 2
0
/** Tear down the UPnP connection stored in <b>backend_state</b>.*/
int
tor_upnp_cleanup(tor_fw_options_t *options, void *backend_state)
{

  miniupnpc_state_t *state = (miniupnpc_state_t *) backend_state;
  assert(options);

  if (state->init)
    FreeUPNPUrls(&(state->urls));
  state->init = 0;

  return UPNP_ERR_SUCCESS;
}
Esempio n. 3
0
static void
clean_upnp_data (VinoUpnp *upnp)
{
  if (upnp->priv->urls)
    {
      FreeUPNPUrls (upnp->priv->urls);
      g_free (upnp->priv->urls);
      upnp->priv->urls = NULL;
    }

  if (upnp->priv->data)
    {
      g_free (upnp->priv->data);
      upnp->priv->data = NULL;
    }
}
Esempio n. 4
0
SWITCH_DECLARE(void) switch_nat_init(switch_memory_pool_t *pool)
{
	/* try free dynamic data structures prior to resetting to 0 */
	FreeUPNPUrls(&nat_globals.urls);
	switch_safe_free(nat_globals.descURL);

	memset(&nat_globals, 0, sizeof(nat_globals));

	if (first_init) {
		memset(&nat_globals_perm, 0, sizeof(nat_globals_perm));
		nat_globals_perm.pool = pool;
	}

	switch_find_local_ip(nat_globals.pvt_addr, sizeof(nat_globals.pvt_addr), NULL, AF_INET);


	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Scanning for NAT\n");

	init_pmp();

	if (!nat_globals.nat_type) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Checking for UPnP\n");
		init_upnp();
	}

	if (nat_globals.nat_type) {
		switch_core_set_variable("nat_public_addr", nat_globals.pub_addr);
		switch_core_set_variable("nat_private_addr", nat_globals.pvt_addr);
		switch_core_set_variable("nat_type", nat_globals.nat_type == SWITCH_NAT_TYPE_PMP ? "pmp" : "upnp");
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "NAT detected type: %s, ExtIP: '%s'\n",
						  nat_globals.nat_type == SWITCH_NAT_TYPE_PMP ? "pmp" : "upnp", nat_globals.pub_addr);

		if (!nat_thread_p) {
			switch_nat_thread_start();
		}
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "No PMP or UPnP NAT devices detected!\n");
	}
	first_init = SWITCH_FALSE;
	initialized = SWITCH_TRUE;
}
Esempio n. 5
0
int test_igd_desc_parse(char * buffer, int len)
{
	struct IGDdatas igd;
	struct xmlparser parser;
	struct UPNPUrls urls;
	memset(&igd, 0, sizeof(struct IGDdatas));
	memset(&parser, 0, sizeof(struct xmlparser));
	parser.xmlstart = buffer;
	parser.xmlsize = len;
	parser.data = &igd;
	parser.starteltfunc = IGDstartelt;
	parser.endeltfunc = IGDendelt;
	parser.datafunc = IGDdata;
	parsexml(&parser);
	printIGD(&igd);
	GetUPNPUrls(&urls, &igd, "http://fake/desc/url/file.xml", 0);
	printf("ipcondescURL='%s'\n", urls.ipcondescURL);
	printf("controlURL='%s'\n", urls.controlURL);
	printf("controlURL_CIF='%s'\n", urls.controlURL_CIF);
	FreeUPNPUrls(&urls);
	return 0;
}
Esempio n. 6
0
void CUPnPImplMiniLib::StartDiscovery(uint16 nTCPPort, uint16 nUDPPort){
	DebugLog(_T("Using MiniUPnPLib based implementation"));
	DebugLog(_T("miniupnpc (c) 2006-2008 Thomas Bernard - http://miniupnp.free.fr/"));
	m_nOldUDPPort = (ArePortsForwarded() == TRIS_TRUE) ? m_nUDPPort : 0;
	m_nUDPPort = nUDPPort;
	m_nOldTCPPort = (ArePortsForwarded() == TRIS_TRUE) ? m_nTCPPort : 0;
	m_nTCPPort = nTCPPort;
	m_bUPnPPortsForwarded = TRIS_UNKNOWN;

	if (m_pURLs != NULL)
		FreeUPNPUrls(m_pURLs);
	delete m_pURLs;
	m_pURLs = NULL;
	delete m_pIGDData;
	m_pIGDData = NULL;

	if (m_bAbortDiscovery)
		return;

	CStartDiscoveryThread* pStartDiscoveryThread = (CStartDiscoveryThread*) AfxBeginThread(RUNTIME_CLASS(CStartDiscoveryThread), THREAD_PRIORITY_NORMAL,0, CREATE_SUSPENDED);
	m_hThreadHandle = pStartDiscoveryThread->m_hThread;
	pStartDiscoveryThread->SetValues(this);
	pStartDiscoveryThread->ResumeThread();
}
Esempio n. 7
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
}
Esempio n. 8
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;
}
Esempio n. 9
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;
}
Esempio n. 10
0
static void I_ShutdownUPnP(void)
{
	FreeUPNPUrls(&urls);
}
Esempio n. 11
0
MiniUPnPInterface::~MiniUPnPInterface() {
	if (p->isValid) {
		FreeUPNPUrls(&p->urls);
	}
	freeUPNPDevlist(p->deviceList);
}
Esempio n. 12
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:)
}
Esempio n. 13
0
/* UPNP_GetValidIGD() :
 * return values :
 *     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 non zero return case, the urls and data structures
 * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
 * free allocated memory.
 */
int
UPNP_GetValidIGD(struct UPNPDev * devlist,
                 struct UPNPUrls * urls,
				 struct IGDdatas * data,
				 char * lanaddr, int lanaddrlen)
{
	char * descXML;
	int descXMLsize = 0;
	struct UPNPDev * dev;
	int ndev = 0;
	int state; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
	if(!devlist)
	{
#ifdef DEBUG
		printf("Empty devlist\n");
#endif
		return 0;
	}
	for(state = 1; state <= 3; state++)
	{
		for(dev = devlist; dev; dev = dev->pNext)
		{
			/* we should choose an internet gateway device.
		 	* with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
			descXML = miniwget_getaddr(dev->descURL, &descXMLsize,
			   	                        lanaddr, lanaddrlen);
			if(descXML)
			{
				ndev++;
				memset(data, 0, sizeof(struct IGDdatas));
				memset(urls, 0, sizeof(struct UPNPUrls));
				parserootdesc(descXML, descXMLsize, data);
				free(descXML);
				descXML = NULL;
				if(0==strcmp(data->servicetype_CIF,
				   "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")
				   || state >= 3 )
				{
				  GetUPNPUrls(urls, data, dev->descURL);

#ifdef DEBUG
				  printf("UPNPIGD_IsConnected(%s) = %d\n",
				     urls->controlURL,
			         UPNPIGD_IsConnected(urls, data));
#endif
				  if((state >= 2) || UPNPIGD_IsConnected(urls, data))
					return state;
				  FreeUPNPUrls(urls);
				}
				memset(data, 0, sizeof(struct IGDdatas));
			}
#ifdef DEBUG
			else
			{
				printf("error getting XML description %s\n", dev->descURL);
			}
#endif
		}
	}
	return 0;
}
Esempio n. 14
0
/* sample upnp client program */
int main(int argc, char ** argv)
{
	char command = 0;
	char ** commandargv = 0;
	int commandargc = 0;
	struct UPNPDev * devlist = 0;
	char lanaddr[64];	/* my ip address on the LAN */
	int i;
	const char * rootdescurl = 0;
	const char * multicastif = 0;
	const char * minissdpdpath = 0;
	int retcode = 0;
	int error = 0;
	int ipv6 = 0;
	const char * description = 0;

#ifdef _WIN32
	WSADATA wsaData;
	int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
	if(nResult != NO_ERROR)
	{
		fprintf(stderr, "WSAStartup() failed.\n");
		return -1;
	}
#endif
    printf("upnpc : miniupnpc library test client. (c) 2005-2014 Thomas Bernard\n");
    printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n"
	       "for more information.\n");
	/* command line processing */
	for(i=1; i<argc; i++)
	{
		if(0 == strcmp(argv[i], "--help") || 0 == strcmp(argv[i], "-h"))
		{
			command = 0;
			break;
		}
		if(argv[i][0] == '-')
		{
			if(argv[i][1] == 'u')
				rootdescurl = argv[++i];
			else if(argv[i][1] == 'm')
				multicastif = argv[++i];
			else if(argv[i][1] == 'p')
				minissdpdpath = argv[++i];
			else if(argv[i][1] == '6')
				ipv6 = 1;
			else if(argv[i][1] == 'e')
				description = argv[++i];
			else
			{
				command = argv[i][1];
				i++;
				commandargv = argv + i;
				commandargc = argc - i;
				break;
			}
		}
		else
		{
			fprintf(stderr, "option '%s' invalid\n", argv[i]);
		}
	}

	if(!command 
	   || (command == 'a' && commandargc<4)
	   || (command == 'd' && argc<2)
	   || (command == 'r' && argc<2)
	   || (command == 'A' && commandargc<6)
	   || (command == 'U' && commandargc<2)
	   || (command == 'D' && commandargc<1))
	{
		fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol [duration]\n\t\tAdd port redirection\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -d external_port protocol <remote host>\n\t\tDelete port redirection\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -s\n\t\tGet Connection status\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -l\n\t\tList redirections\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -L\n\t\tList redirections (using GetListOfPortMappings (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -n ip port external_port protocol [duration]\n\t\tAdd (any) port redirection allowing IGD to use alternative external_port (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -N external_port_start external_port_end protocol [manage]\n\t\tDelete range of port redirections (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -r port1 [external_port1] protocol1 [port2 [external_port2] protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -A remote_ip remote_port internal_ip internal_port protocol lease_time\n\t\tAdd Pinhole (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -U uniqueID new_lease_time\n\t\tUpdate Pinhole (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -C uniqueID\n\t\tCheck if Pinhole is Working (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -K uniqueID\n\t\tGet Number of packets going through the rule (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -D uniqueID\n\t\tDelete Pinhole (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -S\n\t\tGet Firewall status (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -G remote_ip remote_port internal_ip internal_port protocol\n\t\tGet Outbound Pinhole Timeout (for IGD:2 only)\n", argv[0]);
		fprintf(stderr, "       \t%s [options] -P\n\t\tGet Presentation url\n", argv[0]);
		fprintf(stderr, "\nprotocol is UDP or TCP\n");
		fprintf(stderr, "Options:\n");
		fprintf(stderr, "  -e description : set description for port mapping.\n");
		fprintf(stderr, "  -6 : use ip v6 instead of ip v4.\n");
		fprintf(stderr, "  -u url : bypass discovery process by providing the XML root description url.\n");
		fprintf(stderr, "  -m address/interface : provide ip address (ip v4) or interface name (ip v4 or v6) to use for sending SSDP multicast packets.\n");
		fprintf(stderr, "  -p path : use this path for MiniSSDPd socket.\n");
		return 1;
	}

	if( rootdescurl
	  || (devlist = upnpDiscover(2000, multicastif, minissdpdpath,
	                             0/*sameport*/, ipv6, &error)))
	{
		struct UPNPDev * device;
		struct UPNPUrls urls;
		struct IGDdatas data;
		if(devlist)
		{
			printf("List of UPNP devices found on the network :\n");
			for(device = devlist; device; device = device->pNext)
			{
				printf(" desc: %s\n st: %s\n\n",
					   device->descURL, device->st);
			}
		}
		else if(!rootdescurl)
		{
			printf("upnpDiscover() error code=%d\n", error);
		}
		i = 1;
		if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr)))
		  || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))))
		{
			switch(i) {
			case 1:
				printf("Found valid IGD : %s\n", urls.controlURL);
				break;
			case 2:
				printf("Found a (not connected?) IGD : %s\n", urls.controlURL);
				printf("Trying to continue anyway\n");
				break;
			case 3:
				printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
				printf("Trying to continue anyway\n");
				break;
			default:
				printf("Found device (igd ?) : %s\n", urls.controlURL);
				printf("Trying to continue anyway\n");
			}
			printf("Local LAN ip address : %s\n", lanaddr);
			#if 0
			printf("getting \"%s\"\n", urls.ipcondescURL);
			descXML = miniwget(urls.ipcondescURL, &descXMLsize);
			if(descXML)
			{
				/*fwrite(descXML, 1, descXMLsize, stdout);*/
				free(descXML); descXML = NULL;
			}
			#endif

			switch(command)
			{
			case 'l':
				DisplayInfos(&urls, &data);
				ListRedirections(&urls, &data);
				break;
			case 'L':
				NewListRedirections(&urls, &data);
				break;
			case 'a':
				SetRedirectAndTest(&urls, &data,
						   commandargv[0], commandargv[1],
						   commandargv[2], commandargv[3],
						   (commandargc > 4)?commandargv[4]:"0",
						   description, 0);
				break;
			case 'd':
				RemoveRedirect(&urls, &data, commandargv[0], commandargv[1],
				               commandargc > 2 ? commandargv[2] : NULL);
				break;
			case 'n':	/* aNy */
				SetRedirectAndTest(&urls, &data,
						   commandargv[0], commandargv[1],
						   commandargv[2], commandargv[3],
						   (commandargc > 4)?commandargv[4]:"0",
						   description, 1);
				break;
			case 'N':
				if (commandargc < 3)
					fprintf(stderr, "too few arguments\n");

				RemoveRedirectRange(&urls, &data, commandargv[0], commandargv[1], commandargv[2],
						    commandargc > 3 ? commandargv[3] : NULL);
				break;
			case 's':
				GetConnectionStatus(&urls, &data);
				break;
			case 'r':
				i=0;
				while(i<commandargc){
					if(!is_int(commandargv[i+1])){
						/* 2nd parameter not an integer, so format is '<port> <protocol>' */
						/* Note: no 2nd parameter is also not-an-integer, and will lead to a "Wrong arguments" */
						SetRedirectAndTest(&urls, &data,
								   lanaddr, commandargv[i],
								   commandargv[i], commandargv[i+1], "0",
								   description, 0);
						i+=2;	/* 2 parameters parsed */
					} else {
						/* 2nd parameter is an integer, so format is '<port> <external_port> <protocol>' */
						SetRedirectAndTest(&urls, &data,
								   lanaddr, commandargv[i],
								   commandargv[i+1], commandargv[i+2], "0",
								   description, 0);
						i+=3;	/* 3 parameters parsed */
					}
				}
				break;
			case 'A':
				SetPinholeAndTest(&urls, &data,
				                  commandargv[0], commandargv[1],
				                  commandargv[2], commandargv[3],
				                  commandargv[4], commandargv[5]);
				break;
			case 'U':
				GetPinholeAndUpdate(&urls, &data,
				                   commandargv[0], commandargv[1]);
				break;
			case 'C':
				for(i=0; i<commandargc; i++)
				{
					CheckPinhole(&urls, &data, commandargv[i]);
				}
				break;
			case 'K':
				for(i=0; i<commandargc; i++)
				{
					GetPinholePackets(&urls, &data, commandargv[i]);
				}
				break;
			case 'D':
				for(i=0; i<commandargc; i++)
				{
					RemovePinhole(&urls, &data, commandargv[i]);
				}
				break;
			case 'S':
				GetFirewallStatus(&urls, &data);
				break;
			case 'G':
				GetPinholeOutboundTimeout(&urls, &data,
							commandargv[0], commandargv[1],
							commandargv[2], commandargv[3],
							commandargv[4]);
				break;
			case 'P':
				printf("Presentation URL found:\n");
				printf("            %s\n", data.presentationurl);
				break;
			default:
				fprintf(stderr, "Unknown switch -%c\n", command);
				retcode = 1;
			}

			FreeUPNPUrls(&urls);
		}
		else
		{
			fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
			retcode = 1;
		}
		freeUPNPDevlist(devlist); devlist = 0;
	}
	else
	{
		fprintf(stderr, "No IGD UPnP Device found on the network !\n");
		retcode = 1;
	}
#ifdef _WIN32
	nResult = WSACleanup();
	if(nResult != NO_ERROR) {
		fprintf(stderr, "WSACleanup() failed.\n");
	}
#endif /* _WIN32 */
	return retcode;
}
Esempio n. 15
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" );
}
Esempio n. 16
0
SWITCH_DECLARE(void) switch_nat_shutdown(void)
{
	switch_nat_thread_stop();
	FreeUPNPUrls(&nat_globals.urls);
	switch_safe_free(nat_globals.descURL);
}
Esempio n. 17
0
Gateway::~Gateway()
{
	FreeUPNPUrls(&urls);
}
Esempio n. 18
0
File: UPnP.cpp Progetto: l-n-s/i2pd
 void UPnP::Close ()
 {
     freeUPNPDevlist (m_Devlist);
     m_Devlist = 0;
     FreeUPNPUrls (&m_upnpUrls);
 }
 ~MiniUPnPWrapper()
 {
     FreeUPNPUrls(upnpurls);
     delete upnpurls;
     delete igddatas;
 }
Esempio n. 20
0
int xshl5_redirect(unsigned short pri_port, unsigned short ext_port,
                   const char* pri_ip, const char* protocol, int ipv6,
                   const char* interface_or_ipaddr, const char* description,
                   /*out*/char* ext_ipaddr)
{
    int retcode = -1;

    struct UPNPDev * devlist = 0;
    const char * multicastif = interface_or_ipaddr;
    const char * minissdpdpath = 0;
    char lanaddr[64];	/* my ip address on the LAN */

    int error = 0, i = 0;

    char used_protocol[16] = "tcp";
    char used_ipaddr[32] = {0};
    char used_pri_port[8] = {0};
    char used_ext_port[8] = {0};

    // used_pri_port
    sprintf(used_pri_port, "%u", pri_port);
    // used_ext_port
    if(ext_port == 0)
        sprintf(used_ext_port, "%u", pri_port);
    else
        sprintf(used_ext_port, "%u", ext_port);
    // used_protocol
    if(protocol != NULL && (protocol[0]=='u'&&protocol[1]=='d'&&protocol[2]=='p') )
    {
        strncpy(used_protocol, protocol, 3);
    }

    if( (devlist = upnpDiscover(2000, multicastif, minissdpdpath,
                                 0/*sameport*/, ipv6, &error)))
    {
        struct UPNPDev * device;
        struct UPNPUrls urls;
        struct IGDdatas data;
        if(devlist)
        {
            printf("List of UPNP devices found on the network :\n");
            for(device = devlist; device; device = device->pNext)
            {
                printf(" desc: %s\n st: %s\n\n",
                       device->descURL, device->st);
            }
        }
        else
        {
            printf("upnpDiscover() error code=%d\n", error);
        }
        i = 1;
        if( (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))) )
        {
            switch(i) {
            case 1:
                printf("Found valid IGD : %s\n", urls.controlURL);
                break;
            case 2:
                printf("Found a (not connected?) IGD : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
                break;
            case 3:
                printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
                break;
            default:
                printf("Found device (igd ?) : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
            }
            printf("Local LAN ip address : %s\n", lanaddr);

            // used_ipaddr
            if(pri_ip == NULL)
                strcpy(used_ipaddr, lanaddr);
            else
                strcpy(used_ipaddr, pri_ip);

            SetRedirectAndTest(&urls, &data,
                       used_ipaddr, used_pri_port,
                       used_ext_port, used_protocol,
                       "0",
                       description, 0, ext_ipaddr);
            retcode = 0;
/*
            case 'a':
                SetRedirectAndTest(&urls, &data,
                           commandargv[0], commandargv[1],
                           commandargv[2], commandargv[3],
                           (commandargc > 4)?commandargv[4]:"0",
                           description, 0);
                break;
            case 'd':
                for(i=0; i<commandargc; i+=2)
                {
                    RemoveRedirect(&urls, &data, commandargv[i], commandargv[i+1]);
                }
                break;
*/
            FreeUPNPUrls(&urls);
        }
        else
        {
            fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
            retcode = 1;
        }
        freeUPNPDevlist(devlist); devlist = 0;
    }
    else
    {
        fprintf(stderr, "No IGD UPnP Device found on the network !\n");
        retcode = 1;
    }

    return retcode;
}
Esempio n. 21
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;
}
Esempio n. 22
0
int xshl5_redirect_remove(const char* ext_port_and_protocols[], int num,
                    int ipv6, const char* interface_or_ipaddr)
{
    int retcode = -1;

    struct UPNPDev * devlist = 0;
    const char * multicastif = interface_or_ipaddr;
    const char * minissdpdpath = 0;
    char lanaddr[64];	/* my ip address on the LAN */

    int error = 0, i = 0;
    if(num <= 0)
        return retcode;

    if( (devlist = upnpDiscover(2000, multicastif, minissdpdpath,
                                 0/*sameport*/, ipv6, &error)))
    {
        struct UPNPDev * device;
        struct UPNPUrls urls;
        struct IGDdatas data;
        if(devlist)
        {
            printf("List of UPNP devices found on the network :\n");
            for(device = devlist; device; device = device->pNext)
            {
                printf(" desc: %s\n st: %s\n\n",
                       device->descURL, device->st);
            }
        }
        else
        {
            printf("upnpDiscover() error code=%d\n", error);
        }
        i = 1;
        if( (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))) )
        {
            switch(i) {
            case 1:
                printf("Found valid IGD : %s\n", urls.controlURL);
                break;
            case 2:
                printf("Found a (not connected?) IGD : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
                break;
            case 3:
                printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
                break;
            default:
                printf("Found device (igd ?) : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
            }
            printf("Local LAN ip address : %s\n", lanaddr);

            for(i=0; i<num; i+=2)
            {
                if(ext_port_and_protocols[i] == NULL || ext_port_and_protocols[i+1] == NULL)
                {
                    retcode = -2;
                    break;
                }

                RemoveRedirect(&urls, &data, ext_port_and_protocols[i],
                        strcmp(ext_port_and_protocols[i+1], "udp")==0? "udp": "tcp");
            }
            retcode = 0;

            FreeUPNPUrls(&urls);
        }
        else
        {
            fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
            retcode = 1;
        }
        freeUPNPDevlist(devlist); devlist = 0;
    }
    else
    {
        fprintf(stderr, "No IGD UPnP Device found on the network !\n");
        retcode = 1;
    }

    return retcode;
}
Esempio n. 23
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 non zero return case, the urls and data structures
 * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
 * free allocated memory.
 */
LIBSPEC int
UPNP_GetValidIGD(struct UPNPDev * devlist,
                 struct UPNPUrls * urls,
				 struct IGDdatas * data,
				 char * lanaddr, int lanaddrlen)
{
	struct xml_desc {
		char * xml;
		int size;
	} * desc = NULL;
	struct UPNPDev * dev;
	int ndev = 0;
	int i;
	int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
	if(!devlist)
	{
#ifdef DEBUG
		printf("Empty devlist\n");
#endif
		return 0;
	}
	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 */
	}
	for(state = 1; state <= 3; state++)
	{
		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 */
			if(state == 1)
			{
				desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size),
				   	                           lanaddr, lanaddrlen,
				                               dev->scope_id);
#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(0==strcmp(data->CIF.servicetype,
				   "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")
				   || state >= 3 )
				{
				  GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);

#ifdef DEBUG
				  printf("UPNPIGD_IsConnected(%s) = %d\n",
				     urls->controlURL,
			         UPNPIGD_IsConnected(urls, data));
#endif
				  if((state >= 2) || UPNPIGD_IsConnected(urls, data))
					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((state >= 2) || UPNPIGD_IsConnected(urls, data))
					  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;
}
Esempio n. 24
0
/* sample upnp client program */
int main(int argc, char ** argv)
{
    char command = 0;
    char ** commandargv = 0;
    int commandargc = 0;
    struct UPNPDev * devlist = 0;
    char lanaddr[64];	/* my ip address on the LAN */
    int i;
    const char * rootdescurl = 0;
    const char * multicastif = 0;
    const char * minissdpdpath = 0;
    int retcode = 0;

#ifdef WIN32
    WSADATA wsaData;
    int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if(nResult != NO_ERROR)
    {
        fprintf(stderr, "WSAStartup() failed.\n");
        return -1;
    }
#endif
    printf("upnpc : miniupnpc library test client. (c) 2006-2010 Thomas Bernard\n");
    printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n"
           "for more information.\n");
    /* command line processing */
    for(i=1; i<argc; i++)
    {
        if(argv[i][0] == '-')
        {
            if(argv[i][1] == 'u')
                rootdescurl = argv[++i];
            else if(argv[i][1] == 'm')
                multicastif = argv[++i];
            else if(argv[i][1] == 'p')
                minissdpdpath = argv[++i];
            else
            {
                command = argv[i][1];
                i++;
                commandargv = argv + i;
                commandargc = argc - i;
                break;
            }
        }
        else
        {
            fprintf(stderr, "option '%s' invalid\n", argv[i]);
        }
    }

    if(!command || (command == 'a' && commandargc<4)
            || (command == 'd' && argc<2)
            || (command == 'r' && argc<2))
    {
        fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol\n\t\tAdd port redirection\n", argv[0]);
        fprintf(stderr, "       \t%s [options] -d external_port protocol [port2 protocol2] [...]\n\t\tDelete port redirection\n", argv[0]);
        fprintf(stderr, "       \t%s [options] -s\n\t\tGet Connection status\n", argv[0]);
        fprintf(stderr, "       \t%s [options] -l\n\t\tList redirections\n", argv[0]);
        fprintf(stderr, "       \t%s [options] -r port1 protocol1 [port2 protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]);
        fprintf(stderr, "\nprotocol is UDP or TCP\n");
        fprintf(stderr, "Options:\n");
        fprintf(stderr, "  -u url : bypass discovery process by providing the XML root description url.\n");
        fprintf(stderr, "  -m address : provide ip address of the interface to use for sending SSDP multicast packets.\n");
        fprintf(stderr, "  -p path : use this path for MiniSSDPd socket.\n");
        return 1;
    }

    if( rootdescurl
            || (devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0)))
    {
        struct UPNPDev * device;
        struct UPNPUrls urls;
        struct IGDdatas data;
        if(devlist)
        {
            printf("List of UPNP devices found on the network :\n");
            for(device = devlist; device; device = device->pNext)
            {
                printf(" desc: %s\n st: %s\n\n",
                       device->descURL, device->st);
            }
        }
        i = 1;
        if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr)))
                || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))))
        {
            switch(i) {
            case 1:
                printf("Found valid IGD : %s\n", urls.controlURL);
                break;
            case 2:
                printf("Found a (not connected?) IGD : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
                break;
            case 3:
                printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
                break;
            default:
                printf("Found device (igd ?) : %s\n", urls.controlURL);
                printf("Trying to continue anyway\n");
            }
            printf("Local LAN ip address : %s\n", lanaddr);
#if 0
            printf("getting \"%s\"\n", urls.ipcondescURL);
            descXML = miniwget(urls.ipcondescURL, &descXMLsize);
            if(descXML)
            {
                /*fwrite(descXML, 1, descXMLsize, stdout);*/
                free(descXML);
                descXML = NULL;
            }
#endif

            switch(command)
            {
            case 'l':
                DisplayInfos(&urls, &data);
                ListRedirections(&urls, &data);
                break;
            case 'a':
                SetRedirectAndTest(&urls, &data,
                                   commandargv[0], commandargv[1],
                                   commandargv[2], commandargv[3]);
                break;
            case 'd':
                for(i=0; i<commandargc; i+=2)
                {
                    RemoveRedirect(&urls, &data, commandargv[i], commandargv[i+1]);
                }
                break;
            case 's':
                GetConnectionStatus(&urls, &data);
                break;
            case 'r':
                for(i=0; i<commandargc; i+=2)
                {
                    /*printf("port %s protocol %s\n", argv[i], argv[i+1]);*/
                    SetRedirectAndTest(&urls, &data,
                                       lanaddr, commandargv[i],
                                       commandargv[i], commandargv[i+1]);
                }
                break;
            default:
                fprintf(stderr, "Unknown switch -%c\n", command);
                retcode = 1;
            }

            FreeUPNPUrls(&urls);
        }
        else
        {
            fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
            retcode = 1;
        }
        freeUPNPDevlist(devlist);
        devlist = 0;
    }
    else
    {
        fprintf(stderr, "No IGD UPnP Device found on the network !\n");
        retcode = 1;
    }
    return retcode;
}