Udppipe.c is a udp redirector, similar to TCP's datapipe.c. It can be used to play OICQ behind firewall.
7ce4b808c6d3393759594ce8fde16570/*---------------------------------------------------------------
Author: HJY
Func: To provide a udp data pipe from LAN to the internet bypassing the
annoying firewall.(udp port redirect).
It can be used to play OICQ behind firewall.
Email: hujiaying@263.net
Note: Want to use the tcp data pipe(tcp port redirect)?Refer to datapipe.c
---------------------------------------------------------------*/
#include <sys/socket.h>
#include <linux/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#define max(a,b) (((a)>(b))?(a):(b))
typedef void Sigfunc (int);
int sd1,sd2;
void dispose(int signo);
int Socket(int family, int type, int protocol);
void Bind(int fd, const struct sockaddr *sa, socklen_t salen);
void fillsock(struct sockaddr_in *addr,char *ip,char *port);
char *Sock_ntop(struct sockaddr *cliaddr,int len);
Sigfunc *Signal(int signo, Sigfunc *func);
int Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout);
ssize_t Recvfrom(int fd, void *ptr, size_t nbytes, int flags,
struct sockaddr *sa, socklen_t *salenptr);
void Sendto(int fd, const void *ptr, size_t nbytes, int flags,
const struct sockaddr *sa, socklen_t salen);
u_int32_t domain2ip_n(const char *domain);
int service2port(const char *service);
main(int argc,char **argv)
{
char msg_detail[4096];
char msg[4096];
int maxfd1,len,n;
struct sockaddr_in addr1,addr2;
struct sockaddr cliaddr;
fd_set fdsr,fdse;
if(argc!=4)
{
printf("Usage: %s localport remoteport remotehost\n",argv[0]);
return;
}
sd1=Socket(AF_INET,SOCK_DGRAM,0);
fillsock(&addr1,INADDR_ANY,argv[1]);
Bind(sd1,(struct sockaddr *)&addr1,sizeof(addr1));
fillsock(&addr2,argv[3],argv[2]);
sd2=Socket(AF_INET,SOCK_DGRAM,0);
Signal(SIGINT,dispose);
for(;;)
{
FD_ZERO(&fdsr);
FD_ZERO(&fdse);
FD_SET(sd1,&fdsr);
FD_SET(sd2,&fdsr);
FD_SET(sd1,&fdse);
FD_SET(sd2,&fdse);
maxfd1=max(sd1,sd2)+1;
Select(maxfd1,&fdsr,NULL,&fdse,NULL);
if(FD_ISSET(sd1,&fdsr)||FD_ISSET(sd1,&fdse))
{
len=sizeof(cliaddr);
memset(msg,0,sizeof(msg));
n=Recvfrom(sd1,msg,4096,0,&cliaddr,&len);
printf("from client[%s]\n",
Sock_ntop(&cliaddr,sizeof(cliaddr)));
memset(msg_detail,0,sizeof(msg_detail));
sprintf(msg_detail,"->[%s]\n",msg);
Sendto(sd2,msg,n,0,(struct sockaddr *)&addr2,
sizeof(addr2));
}
else if(FD_ISSET(sd2,&fdsr)||FD_ISSET(sd2,&fdse))
{
printf("from server\n");
len=sizeof(addr2);
memset(msg,0,sizeof(msg));
n=Recvfrom(sd2,msg,4096,0,NULL,NULL);
memset(msg_detail,0,sizeof(msg_detail));
sprintf(msg_detail,"<-[%s]\n",msg);
Sendto(sd1,msg,n,0,&cliaddr,sizeof(cliaddr));
}
}
}
void dispose(int signo)
{
close(sd1);
close(sd2);
}
int Socket(int family, int type, int protocol)
{
int n;
if ( (n = socket(family, type, protocol)) < 0)
{
printf("socket error");
exit(0);
}
return(n);
}
void Bind(int fd, const struct sockaddr *sa, socklen_t salen)
{
if (bind(fd, sa, salen) < 0)
{
printf("bind error");
exit(0);
}
}
void fillsock(struct sockaddr_in *addr,char *ip,char *port)
{
u_int32_t ip_n;
int port_no;
addr->sin_family=AF_INET;
bzero(addr,sizeof(addr));
if(ip==NULL||(!strcmp(ip,"0")))
addr->sin_addr.s_addr=htonl(INADDR_ANY);
else
{
if(inet_pton(AF_INET,ip,&addr->sin_addr)==0)
{
ip_n=domain2ip_n(ip);
memcpy(&addr->sin_addr.s_addr,&ip_n,4);
}
}
if(isdigit(port[0]))
port_no=atoi(port);
else
port_no=service2port(port);
addr->sin_port=htons(port_no);
}
char *Sock_ntop(struct sockaddr *cliaddr,int len)//sockaddr->ip:port
{
struct sockaddr_in cli;
char ip[100];
int port;
static char str[4096];
memcpy(&cli,cliaddr,sizeof(cli));
inet_ntop(AF_INET,&cli.sin_addr,ip,sizeof(ip));
port=ntohs(cli.sin_port);
snprintf(str,sizeof(str),"%s:%d",ip,port);
return str;
}
Sigfunc *
Signal(int signo, Sigfunc *func) /* for our signal() function */
{
Sigfunc *sigfunc;
if ( (sigfunc = signal(signo, func)) == SIG_ERR)
{
printf("signal error");
exit(0);
}
return(sigfunc);
}
int
Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout)
{
int n;
if ( (n = select(nfds, readfds, writefds, exceptfds, timeout)) < 0)
{
printf("select error");
exit(0);
}
return(n); /* can return 0 on timeout */
}
ssize_t
Recvfrom(int fd, void *ptr, size_t nbytes, int flags,
struct sockaddr *sa, socklen_t *salenptr)
{
ssize_t n;
if ( (n = recvfrom(fd, ptr, nbytes, flags, sa, salenptr)) < 0)
{
printf("recvfrom error");
exit(0);
}
return(n);
}
void
Sendto(int fd, const void *ptr, size_t nbytes, int flags,
const struct sockaddr *sa, socklen_t salen)
{
if (sendto(fd, ptr, nbytes, flags, sa, salen) != nbytes)
{
printf("sendto error");
exit(0);
}
}
u_int32_t domain2ip_n(const char *domain) //return network order(binary)
{
static u_int32_t ip_n;
struct hostent *ht;
if((ht=gethostbyname(domain))==NULL)
{
printf("gethostbyname() error for host:%s:%s",domain,
hstrerror(h_errno));
exit(0);
}
memcpy(&ip_n,ht->h_addr,4);
return ip_n;
}
int service2port(const char *service)
{
static int port;
struct servent *sv;
if((port=atoi(service))==0)
{
if((sv=getservbyname(service,NULL))==NULL)
{
printf("getservbyname() error for %s\n",port);
exit(0);
}
port=ntohs(sv->s_port);
}
return port;
}
Comments
No comments yet, be the first!