📄 proxy.c
字号:
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include <termio.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/file.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <netdb.h>
#define TCP_PROTO "tcp"
int proxy_port;
struct sockaddr_in hostaddr;
extern int errno;
extern char *sys_errlist[];
void parse_args (int argc, char **argv);
void daemonize (int servfd);
void do_proxy (int usersockfd);
void reap_status (void);
typedef void Signal(int);
main (argc,argv)
int argc;
char **argv;
{
int clilen;
int childpid;
int sockfd, newsockfd;
//struct sockaddr_in servaddr, cliaddr;
struct sockaddr_in servaddr, cliaddr;
parse_args(argc,argv);
bzero((char *) &servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = proxy_port;
if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
printf("failed to create server socket\r\n");
exit(1);
}
if(bind(sockfd,(struct sockaddr_in *) &servaddr,sizeof(servaddr)) < 0)
{
printf("faild to bind server socket to specified port\r\n");
exit(1);
}
listen(sockfd,5);
daemonize(sockfd);
while (1)
{
clilen = sizeof(cliaddr);
newsockfd = accept(sockfd, (struct sockaddr_in *) &cliaddr, &clilen);
if (newsockfd < 0 && errno == EINTR)
continue;
else if (newsockfd < 0)
printf("failed to accept connection");
if ((childpid = fork()) == 0)
{
close(sockfd);
do_proxy(newsockfd);
exit(0);
}
close(newsockfd);
}
}
void parse_args (argc,argv)
int argc;
char **argv;
{
int i;
struct hostent *hostp;
struct servent *servp;
unsigned long inaddr;
struct {
char proxy_port [16];
char isolated_host [64];
char service_name [32];
} pargs;
if (argc < 4) {
printf("usage: %s <proxy-port> <host> <service-name|port-number>\r\n", argv[0]);
exit(1);
}
strcpy(pargs.proxy_port,argv[1]);
strcpy(pargs.isolated_host,argv[2]);
strcpy(pargs.service_name,argv[3]);
for (i = 0; i < strlen(pargs.proxy_port); i++)
if (!isdigit(*(pargs.proxy_port + i)))
break;
if (i == strlen(pargs.proxy_port))
proxy_port = htons(atoi(pargs.proxy_port));
else {
printf("%s: invalid proxy port\r\n",pargs.proxy_port);
exit(0);
}
bzero(&hostaddr,sizeof(hostaddr));
hostaddr.sin_family = AF_INET;
if ((inaddr = inet_addr(pargs.isolated_host)) != INADDR_NONE)
bcopy(&inaddr,&hostaddr.sin_addr,sizeof(inaddr));
else if ((hostp = gethostbyname(pargs.isolated_host)) != NULL)
bcopy(hostp->h_addr,&hostaddr.sin_addr,hostp->h_length);
else {
printf("%s: unknown host\r\n",pargs.isolated_host);
exit(1);
}
if((servp=getservbyname(pargs.service_name,TCP_PROTO))!=NULL)
hostaddr.sin_port = servp->s_port;
else if (atoi(pargs.service_name) > 0)
hostaddr.sin_port = htons(atoi(pargs.service_name));
else {
printf("%s: invalid/unknown service name or port number\r\n", pargs.service_name);
exit(1);
}
}
void daemonize (servfd)
int servfd;
{
int childpid, fd, fdtablesize;
signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
signal(SIGTSTP,SIG_IGN);
if ((childpid = fork()) < 0) {
printf("failed to fork first child\r\n");
exit(1);
}
else if (childpid > 0)
exit(0); /* terminate parent, continue in child */
if (setpgrp(0,getpid())<0) {
printf("failed to become process group leader\r\n",stderr);
exit(1);
}
/*
if ((fd = open("/dev/tty",O_RDWR)) >= 0) {
ioctl(fd,TIOCNOTTY,NULL);
close(fd);
}
*/
for (fd = 0, fdtablesize = getdtablesize(); fd < fdtablesize; fd++)
if (fd != servfd)
close(fd);
chdir("/");
umask(0);
//signal(SIGCLD,(func *)reap_status);
signal(SIGCLD,SIG_IGN);
}
/*
void reap_status()
{
int pid;
union wait status;
while ((pid = wait3(&status,WNOHANG,NULL)) > 0);
}
*/
void do_proxy (usersockfd)
int usersockfd;
{
int isosockfd;
fd_set rdfdset;
int connstat;
int iolen;
char buf[2048];
if ((isosockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
printf("failed to create socket to host");
connstat = connect(isosockfd,(struct sockaddr *) &hostaddr, sizeof(hostaddr));
switch (connstat) {
case 0:
break;
case ETIMEDOUT:
case ECONNREFUSED:
case ENETUNREACH:
strcpy(buf,sys_errlist[errno]);
strcat(buf,"\r\n");
write(usersockfd,buf,strlen(buf));
close(usersockfd);
exit(1);
break;
default:
printf("failed to connect to host");
}
while (1) {
FD_ZERO(&rdfdset);
FD_SET(usersockfd,&rdfdset);
FD_SET(isosockfd,&rdfdset);
if (select(FD_SETSIZE,&rdfdset,NULL,NULL,NULL) < 0)
printf("select failed");
if (FD_ISSET(usersockfd,&rdfdset)) {
if ((iolen = read(usersockfd,buf,sizeof(buf))) <= 0)
break;
write(isosockfd,buf,iolen);
}
if (FD_ISSET(isosockfd,&rdfdset)) {
if((iolen = read(isosockfd,buf,sizeof(buf))) <= 0)
break; /* zero length means the host disconnected */
write(usersockfd,buf,iolen);
}
}
close(isosockfd);
close(usersockfd);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -