⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpproxy.c

📁 tcp protocol proxy,it is userful!
💻 C
📖 第 1 页 / 共 2 页
字号:
						continue;					syslog(LOG_NOTICE, "accept error: %m");					exit (-1);					}						if ((pid = fork()) < 0) {					syslog(LOG_NOTICE, "can't fork process: %m");					exit (-1);					}				else if (pid == 0) {					dup2(connect, 0);					dup2(connect, 1);					dup2(connect, 2);					close (connect);					close (bindport[i].sock);							return (0);					}				close (connect);				}			}		}	syslog(LOG_NOTICE, "server broke while loop -- terminating");	exit (-1);	return (0);}int proxy_request(config_t *x, int cfd){	int	sfd, rc, bytes;	unsigned long started, now;	char	buffer[4096];	struct timeval tov;	fd_set	connection, available;	FILE	*fp;	fp = NULL;	if (*x->writefile != 0) {		char	filename[200];		snprintf (filename, sizeof(filename) - 2, "%s.%d.log", x->writefile, getpid());		if ((fp = fopen(filename, "a")) == NULL)			syslog(LOG_NOTICE, "can't open writefile: %s\n", filename);		}	time((time_t *) &started); 	cfd = cfd;	sfd = fileno(ip_open(x->u.server.name, x->u.server.port));	if (sfd < 0) {		char	*error;		error = get_error(ip_lib_error);		syslog(LOG_NOTICE, "connection error: client= %s, server= %s:%u, error= %s\n",			x->client, x->u.server.name, x->u.server.port, error);		exit (-1);		}		syslog(LOG_NOTICE, "connect: client= %s, server= %s:%u, timeout= %d",		x->client, x->u.server.name, x->u.server.port, x->timeout);	FD_ZERO(&connection);	FD_SET(cfd, &connection);	FD_SET(sfd, &connection);	while (1) {		memmove(&available, &connection, sizeof(fd_set));		tov.tv_sec  = x->timeout;		tov.tv_usec = 0;		rc = select(sfd + 1, &available, (fd_set *) NULL, (fd_set *) NULL, &tov);		if (rc < 0) {			syslog(LOG_NOTICE, "select() error: %m\n");			break;			}		else if (rc == 0) {			syslog(LOG_NOTICE, "connection timed out: client= %s, server= %s:%u",				x->client, x->u.server.name, x->u.server.port);			break;			}		if (FD_ISSET(cfd, &available)) {			if ((bytes = read(0, buffer, sizeof(buffer))) <= 0)				shutdown(sfd, 1);			else if (write(sfd, buffer, bytes) != bytes)				break;			if (fp != NULL) {				buffer[bytes] = 0;				fprintf (fp, "--- CLIENT [%d]:\n", getpid());				fprintf (fp, "%s\n", buffer);				fprintf (fp, "\n");				}			x->bytes_send = x->bytes_send + bytes;			}					if (FD_ISSET(sfd, &available)) {			if ((bytes = read(sfd, buffer, sizeof(buffer))) <= 0)				break;			else if (write(1, buffer, bytes) != bytes)				break;			if (fp != NULL) {				buffer[bytes] = 0;				fprintf (fp, "--- SERVER [%d]:\n", getpid());				fprintf (fp, "%s\n", buffer);				fprintf (fp, "\n");				}			x->bytes_received = x->bytes_received + bytes;			}		}	time((time_t *) &now); 	syslog(LOG_NOTICE, "disconnect: client= %s, server= %s:%u, received= %ld, send= %ld, duration= %ld",		x->client, x->u.server.name, x->u.server.port,		x->bytes_received, x->bytes_send,		now - started);			return (0);}unsigned get_interface_info(int pfd, char *ip, int max){	int	size;	unsigned int port;	struct sockaddr_in saddr;	size = sizeof(saddr);	if (getsockname(pfd, (struct sockaddr *) &saddr, &size) < 0) {		syslog(LOG_NOTICE, "can't get interface info: %m");		exit (-1);		}	copy_string(ip, (char *) inet_ntoa(saddr.sin_addr), max);	port = ntohs(saddr.sin_port);	return (port);}int get_client_info(config_t *x, int pfd){	int	size;	struct sockaddr_in saddr;	struct in_addr *addr;	struct hostent *hostp = NULL;	*x->client = 0;	size = sizeof(saddr);	if (getpeername(pfd, (struct sockaddr *) &saddr, &size) < 0) {		return (-1);		}					copy_string(x->client_ip, (char *) inet_ntoa(saddr.sin_addr), sizeof(x->client_ip));	addr = &saddr.sin_addr,	hostp = gethostbyaddr((char *) addr,			sizeof (saddr.sin_addr.s_addr), AF_INET);	if (hostp == NULL) {		strcpy(x->client, x->client_ip);		return (0);		}	strcpy(x->client, hostp->h_name);	strlwr(x->client);	return (0);}int open_errorlog(char *filename){	int	fno;	if (use_errorlog == 0)		return (0);	if ((fno = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0664)) >= 0)		dup2(fno, 2);	else 		fprintf (stderr, "%s: can't open %s, using stderr\n", program, filename);	return (0);}void missing_arg(int c, char *string){	fprintf (stderr, "%s: missing arg: -%c, %s\n", program, c, string);	exit (-1);}int main(int argc, char *argv[], char *envp[]){	int	c, i, k, bound;	unsigned int port;	char	*p, option[80], interface[300];	config_t *x;		if ((p = strrchr(argv[0], '/')) == NULL)		program = argv[0];	else {		copy_string(progname, &p[1], sizeof(progname));		program = progname;		}	x = allocate(sizeof(config_t));	x->timeout = 60;	strcpy(x->varname, "PROXY_");	bindport = allocate(sizeof(port_t) * MAX_PORT);	openlog(program, LOG_PID, LOG_MAIL);	bound = 0;	k = 1;	while (k < argc  &&  argv[k][0] == '-'  &&  argv[k][1] != 0) {		copy_string(option, argv[k++], sizeof(option));		for (i=1; (c = option[i]) != 0; i++) {			if (c == 'd')				debug = 1;			else if (c == 'a') {				if (k >= argc)					missing_arg(c, "access control program");				copy_string(x->acp, argv[k++], sizeof(x->acp));				}			else if (c == 'b') {				char	addr[300];								if (k >= argc)					missing_arg(c, "bind address and port");				copy_string(addr, argv[k++], sizeof(addr));				if ((p = strchr(addr, ':')) == NULL)					x->port = getportnum(addr);				else {					*p++ = 0;					x->port = getportnum(p);					copy_string(x->interface, addr, sizeof(x->interface));					}				bound = 1;				standalone = 1;				}			else if (c == 'e') {				if (use_errorlog != 0) {					if (k >= argc)						missing_arg(c, "logfile name");					copy_string(errorlog, argv[k++], sizeof(errorlog));					}									use_errorlog = 1;				}			else if (c == 'f'  ||  c == 'c') {				if (k >= argc)					missing_arg(c, "configuration file");				copy_string(configfile, argv[k++], sizeof(configfile));				}			else if (c == 'l') {				if (k >= argc)					missing_arg(c, "logname");				copy_string(logname, argv[k++], sizeof(logname));				}			else if (c == 'p') {				if (*pidfile == 0)					strcpy(pidfile, PIDFILE);				else {					if (k >= argc)						missing_arg(c, "pidfile");					copy_string(pidfile, argv[k++], sizeof(pidfile));					}				}			else if (c == 's')				standalone = 1;			else if (c == 't') {				if (k >= argc)					missing_arg(c, "timeout");				x->timeout = atoi(argv[k++]);				if (x->timeout < 1)					x->timeout = 60;				}			else if (c == 'v') {				if (k >= argc)					missing_arg(c, "varname prefix");				copy_string(x->varname, argv[k++], sizeof(x->varname));				}			else if (c == 'w') {				if (k >= argc)					missing_arg(c, "write file");				copy_string(x->writefile, argv[k++], sizeof(x->writefile));				}			else if (c == 'y')				x->cleanenv = 1;			else if (c == 'z') {				if (listports == 0)					listports = 1;				else					listports = 2;				}			else {				fprintf (stderr, "%s: unknown option: -%c\n", program, c);				exit (-1);				}			}		}	if (*configfile != 0)		read_configuration(configfile, x); 	else if (bound == 0  &&  k >= argc) {		copy_string(configfile, "/etc/tcpproxy.conf", sizeof(configfile));		standalone = 1;		read_configuration(configfile, x);		}	else if (listports == 1)		/* ist ok, ein Serverprogramm wird nicht benoetigt */ ;	else if (k >= argc) {		fprintf (stderr, "%s: missing server\n", program);		exit (1);		}	else {		if (*argv[k] == '/'  ||  *argv[k] == '.') {			x->proxytype = PROXY_PROGRAM;			i = 0;			while (k < argc)				x->u.program.argv[i++] = argv[k++];			x->u.program.argv[i] = NULL;			}		else {			x->proxytype = PROXY_SERVER;			copy_string(x->u.server.name, argv[k++], sizeof(x->u.server.name));			x->u.server.port = get_port(x->u.server.name, 0);			if (k < argc) {				fprintf (stderr, "%s: extra arguments after server\n", program);				exit (1);				}			}		}		if (*logname != 0) {		copy_string(progname, logname, sizeof(progname));		closelog();		openlog(logname, LOG_PID, LOG_MAIL);		}	if (first == NULL) {		x = new_configuration(x);		bindport[binds].port  = x->port;		bindport[binds].count = 1;		binds++;		}	if (listports == 1) {		for (i=0; i<binds; i++) {			if (bindport[i].port != 0)				printf ("%u\n", bindport[i].port);			}					exit (0);		}	else if (listports == 2) {		config_t *y;		y = first;		while (y != NULL) {			printf ("%s %u", y->interface, y->port);			if (y->proxytype == PROXY_PROGRAM) {				int	i;				printf ("  exec:");				for (i=0; y->u.program.argv[i] != NULL; i++)					printf (" %s", y->u.program.argv[i]);				}			else {				printf ("  proxy:");				printf (" %s %u", y->u.server.name, y->u.server.port);				}			printf ("\n");			y = y->next;			}		exit (0);		}	if (standalone != 0) {		int	i;		char	*ip;				for (i=0; i<binds; i++) {			if (bindport[i].port == 0)				continue;	/* Mogelt sich irgendwie in die Port-Liste -- 20AUG99wzk */							ip = bindport[i].ip;			if (strcmp(ip, "*") == 0  ||  bindport[i].count > 1)				ip = "0.0.0.0";							bindport[i].sock = bind_to_port(strcmp(ip, "0.0.0.0") == 0? "": ip, bindport[i].port);			syslog(LOG_NOTICE, "bound to %s:%u",				ip, bindport[i].port);			}					signal(SIGCHLD, SIG_IGN);		standalone = 1;		}	/*	 * Prozess in den Hintergrund legen.	 */	if (debug == 0) {		if (standalone != 0) {			int	pid;					if ((pid = fork()) < 0) {				fprintf (stderr, "%s: can't fork into background\n", program);				exit (-1);				}			else if (pid > 0)				exit (0);			syslog(LOG_NOTICE, "ready");			}				open_errorlog(errorlog);		}	/*	 * pidfile schreiben	 */	if (*pidfile != 0) {		FILE	*fp;		if ((fp = fopen(pidfile, "w")) == NULL) {			fprintf (stderr, "%s: can't write pidfile: %s\n", program, pidfile);			exit (1);			}		fprintf (fp, "%d\n", getpid());		fclose (fp);		}			/*	 * user id aendern	 */	if (getuid() != 0  &&  geteuid() != 0)		/* nichts */ ;	else if (setgid(gid) != 0  ||  setuid(uid) != 0) {		fprintf (stderr, "%s: can't change uid/gid to %d/%d\n", program, uid, gid);		exit (1);		}	/*	 * Server ist einsatzbereit	 */	 	if (standalone != 0)		multiaccept_loop(first);	signal(SIGCHLD, SIG_DFL);	/*	 * An dieser Stelle liegt auf stdin/stdout eine TCP/IP-Verbindung	 * vor.  Im standalone-Modus bleibt der Master-Server immer in der	 * multiaccept-loop.	 *	 * Wir fragen zunaechst die Interface-Daten ab.	 */	port = get_interface_info(0, interface, sizeof(interface));	syslog(LOG_NOTICE, "connected via %s:%u", interface, port);	/*	 * Konfiguration zum Interface suchen, ggf. die Verbindung	 * terminieren.	 */	x = find_configuration(interface, port);	if (x == NULL  &&  (x = find_configuration(interface, 0)) == NULL) {		syslog(LOG_NOTICE, "no configuration found for interface %s:%u", interface, port);		exit (-1);		}	/*	 * Ok, es existiert eine Konfiguration.  Wir uebernehmen die	 * Interface-Daten.	 */	copy_string(x->incoming.ip, interface, sizeof(x->incoming.ip));	x->incoming.port = port;	get_client_info(x, 0);	if (*x->client == 0) {		syslog(LOG_NOTICE, "can't get client info");		exit (-1);		}	/*	 * access control Programm ausfuehren	 */	if (*x->acp != 0) {		int	rc;		rc = run_acp(x);		if (rc != 0)			exit (0);		}	/*	 * Server oder Proxy starten	 */	if (x->proxytype == PROXY_PROGRAM) {		syslog(LOG_NOTICE, "starting %s, client= %s", x->u.program.argv[0], x->client);				if (x->cleanenv != 0)			cleanenv(x, envp);		set_variables(x);		execvp(x->u.program.argv[0], x->u.program.argv);				syslog(LOG_NOTICE, "can't execute %s: %m", x->u.program.argv[0]);		exit (1);		}	else {		/*		 * proxytype ist entweder PROXY_SERVER oder PROXY_DEFAULT.		 */		if (x->u.server.port == 0)			x->u.server.port = x->incoming.port;		if (x->u.server.port == 0) {			syslog(LOG_NOTICE, "no destination port for interface %s:%u", interface, port);			exit (-1);			}		proxy_request(x, 0);		close(0);		}	exit (0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -