Example #1
0
bool NetlibUPnPAddPortMapping(WORD intport, char *proto, WORD *extport, DWORD *extip, bool search)
{
	int res = 0, i = 5;

	if (findUPnPGateway())
	{
		char* szData = (char*)mir_alloc(4096);
		char szExtIP[30];

		*extport = intport - 1;
		*extip = ntohl(locIP.sin_addr.S_un.S_addr);

		WaitForSingleObject(portListMutex, INFINITE);

		do
		{
			++*extport;
			mir_snprintf(szData, 4096, add_port_mapping,
				*extport, proto, intport, inet_ntoa(locIP.sin_addr));
			res = httpTransact(szCtlUrl, szData, 4096, "AddPortMapping", ControlAction);
			txtParseParam(szData, NULL, "<errorCode>", "</errorCode>", szExtIP, sizeof(szExtIP));

		}
		while (search && res == 500 && atol(szExtIP) == 718 && --i);

		mir_free(szData);

		if (res == 200)
		{
			unsigned ip = getExtIP();
			if (ip) *extip = ip; 

			if (numports >= numportsAlloc)
				mir_realloc(portList, sizeof(WORD)*(numportsAlloc += 10));
			portList[numports++] = *extport;
		}

		ReleaseMutex(portListMutex);
	}

	return res == 200;
}
Example #2
0
static void discoverUPnP(void)
{
	char* buf;
	int buflen;
	unsigned i, j, nip = 0;
	unsigned* ips = NULL;

	static const unsigned any = INADDR_ANY;
	static const TIMEVAL tv = { 1, 600000 };

	char szUrl[256] = "";
	char hostname[256];
	PHOSTENT he;
	fd_set readfd;

	SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

	SOCKADDR_IN enetaddr;
	enetaddr.sin_family = AF_INET;
	enetaddr.sin_port = htons(1900);
	enetaddr.sin_addr.s_addr = inet_addr("239.255.255.250");

	gethostname(hostname, sizeof(hostname));
	he = gethostbyname(hostname);

	if (he) {
		while (he->h_addr_list[nip]) ++nip;

		ips = (unsigned*)mir_alloc(nip * sizeof(unsigned));

		for (j = 0; j < nip; j++)
			ips[j] = *(unsigned*)he->h_addr_list[j];
	}

	buf = (char*)mir_alloc(1500);

	for (i = 3; --i && szUrl[0] == 0;) {
		for (j = 0; j < nip; j++) {
			if (ips)
				setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (char *)&ips[j], sizeof(unsigned));

			buflen = mir_snprintf(buf, 1500, search_request_msg, "WANIPConnection:1");
			sendto(sock, buf, buflen, 0, (SOCKADDR*)&enetaddr, sizeof(enetaddr));
			LongLog(buf);

			buflen = mir_snprintf(buf, 1500, search_request_msg, "WANPPPConnection:1");
			sendto(sock, buf, buflen, 0, (SOCKADDR*)&enetaddr, sizeof(enetaddr));
			LongLog(buf);
		}

		if (Miranda_Terminated()) break;

		FD_ZERO(&readfd);
		FD_SET(sock, &readfd);

		while (select(1, &readfd, NULL, NULL, &tv) >= 1) {
			buflen = recv(sock, buf, 1500, 0);
			if (buflen != SOCKET_ERROR) {
				buf[buflen] = 0;
				LongLog(buf);

				if (txtParseParam(buf, NULL, "LOCATION:", "\n", szUrl, sizeof(szUrl)) ||
					txtParseParam(buf, NULL, "Location:", "\n", szUrl, sizeof(szUrl))) {
					char age[30];
					char szHostNew[256], szHostExist[256];

					lrtrim(szUrl);

					parseURL(szUrl, szHostNew, NULL, NULL);
					parseURL(szCtlUrl, szHostExist, NULL, NULL);
					if (mir_strcmp(szHostNew, szHostExist) == 0) {
						gatewayFound = true;
						break;
					}

					txtParseParam(buf, NULL, "ST:", "\n", szDev, sizeof(szDev));
					txtParseParam(buf, "max-age", " = ", "\n", age, sizeof(age));
					expireTime = atoi(lrtrimp(age));
					lrtrim(szDev);

					if (getUPnPURLs(szUrl, sizeof(szUrl))) {
						gatewayFound = getExtIP() != 0;
						if (gatewayFound) break;
					}
				}
			}
			FD_ZERO(&readfd);
			FD_SET(sock, &readfd);
		}
	}

	mir_free(buf);
	mir_free(ips);
	setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (char *)&any, sizeof(unsigned));
	closesocket(sock);
}