#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <syslog.h>

#define version "0.50"

void main(int argc, char *argv[])
{
struct sockaddr_in saSRC, saDST, saRCV;
char cBuf[1<<16];
int sSRC, sDST;
struct hostent *ph;
int nLen;
int bDebug = 0;
int on = 1;
pid_t pid;
int nAS;
unsigned long aRCV, aDST;
int i;

char *pszApp = *argv++;

if (argc > 1 && (!strcmp(*argv, "--debug") || !strcmp(*argv, "-d")))
{
bDebug = 1;
argc--;
argv++;
}

printf("UDPProxy v%s - Phil Ten - phil@philten.com\n",version);
if (argc != 4)
{
printf("Usage: %s [--debug] port-in ip-address port-out\n", pszApp);
exit(1);
}

printf("UDP Forward from port %s to %s port %s\n",
argv[0],
argv[1],
argv[2]);

if (bDebug==1)
printf("Debug enabled\n");

ph = gethostbyname(argv[1]);
if (ph == NULL)
{
printf("Invalid address %s\n",argv[1]);
exit(1);
}

saDST.sin_family = AF_INET;
saDST.sin_port = htons(atoi(argv[2]));
saDST.sin_addr.s_addr = *((unsigned long *)ph->h_addr);

saSRC.sin_family = AF_INET;
saSRC.sin_port = htons(atoi(argv[0]));
saSRC.sin_addr.s_addr = 0;

sSRC = socket(AF_INET, SOCK_DGRAM, 0);
sDST = socket(AF_INET, SOCK_DGRAM, 0);

if (bind(sSRC, (struct sockaddr *)&saSRC, sizeof(saSRC)))
{
printf("Unable to bind to socket\n");
exit(1);
}

setsockopt(sDST, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));

aDST = htonl(saDST.sin_addr.s_addr);

while (1)
{
nAS = sizeof(saRCV);

nLen = recvfrom(sSRC, cBuf, sizeof(cBuf), 0, (struct sockaddr *)&saRCV, &nAS);

if (bDebug)
printf("UDP Forward %d.%d.%d.%d->%s:%s (length=%d)\n",
((unsigned char *)&saRCV.sin_addr.s_addr)[0],
((unsigned char *)&saRCV.sin_addr.s_addr)[1],
((unsigned char *)&saRCV.sin_addr.s_addr)[2],
((unsigned char *)&saRCV.sin_addr.s_addr)[3],
argv[1],
argv[2],
nLen);

sendto(sDST, cBuf, nLen, 0, (struct sockaddr *)&saDST, sizeof(saDST));

}
}
