Skip to content

Commit

Permalink
add NAT-PMP port mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
anzz1 committed Sep 29, 2023
1 parent a0112a9 commit 2b02828
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
2 changes: 1 addition & 1 deletion dllmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ typedef HINTERNET (__stdcall *InternetOpenUrlA_fn)(HINTERNET hInternet, LPCSTR l
InternetOpenUrlA_fn oInternetOpenUrlA = 0;

unsigned long __stdcall portMapThread(void* param) {
UPNP_AddPortMapping((unsigned short)param, (unsigned long)param >> 16);
AddPortMapping((unsigned short)param, (unsigned long)param >> 16);
return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions include/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
#include <winsock2.h>
#include <ws2tcpip.h>
#include <wininet.h>
#include <iphlpapi.h>
#include <shellapi.h>

#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "iphlpapi.lib")

#if defined(_MSC_VER) && _MSC_VER < 1800
#pragma comment(linker, "/IGNORE:4104")
Expand Down
63 changes: 62 additions & 1 deletion include/picoupnp.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ int GetURLParts(char* url, char* host, char* port, char* path)
}

WSADATA wsaData;
int WSAInit()
int WSAInit(void)
{
SOCKET sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sd == INVALID_SOCKET) {
Expand Down Expand Up @@ -375,6 +375,61 @@ int GetLocalIP(char* ip)
return 1;
}

unsigned long GetDefaultGatewayIP(void)
{
MIB_IPFORWARDROW ip_forward;
memset(&ip_forward, 0, sizeof(ip_forward));
if(!GetBestRoute(0, 0, &ip_forward)) return ip_forward.dwForwardNextHop;
return 0;
}

#define NATPMP_PORT 5351
#define NATPMP_MAP_UDP 1
#define NATPMP_MAP_TCP 2

struct natpmp_request {
unsigned char version;
unsigned char opcode;
unsigned short reserved;
unsigned short internal_port;
unsigned short external_port;
unsigned long lifetime;
};

void NATPMP_AddPortMapping(unsigned short port, int protocol)
{
SOCKET sd;
unsigned long gatewayip, addrlen;
struct natpmp_request req;
struct sockaddr_in server;

gatewayip = GetDefaultGatewayIP();
if (!gatewayip) return;

req.version = 0;
req.reserved = 0;
req.opcode = (protocol == IPPROTO_UDP ? NATPMP_MAP_UDP : NATPMP_MAP_TCP);
req.internal_port = htons(port);
req.external_port = req.internal_port;
req.lifetime = htonl(604800);

sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sd == INVALID_SOCKET) return;

setsockopt(sd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&dwTimeout, sizeof(dwTimeout));
setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&dwTimeout, sizeof(dwTimeout));
setsockopt(sd, SOL_TCP, TCP_USER_TIMEOUT, (const char *)&dwTimeout, sizeof(dwTimeout));

memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(NATPMP_PORT);
server.sin_addr.s_addr = gatewayip;
addrlen = sizeof(struct sockaddr);

sendto(sd, (const char*)&req, sizeof(struct natpmp_request), 0, (struct sockaddr*)&server, addrlen);
closesocket(sd);
}

int UPNP_AddPortMapping(unsigned short port, int protocol)
{
char xml[768], localip[16], url[256], host[256], hport[6], cport[6];
Expand Down Expand Up @@ -421,4 +476,10 @@ int UPNP_AddPortMapping(unsigned short port, int protocol)
return i;
}

void AddPortMapping(unsigned short port, int protocol)
{
NATPMP_AddPortMapping(port, protocol);
UPNP_AddPortMapping(port, protocol);
}

#endif // __PICOUPNP_H

0 comments on commit 2b02828

Please sign in to comment.