proxy.c revision 31183
131183Speter/*
231183Speter * Sample transparent proxy program.
331183Speter *
431183Speter * Sample implementation of a program which intercepts a TCP connectiona and
531183Speter * just echos all data back to the origin.  Written to work via inetd as a
631183Speter * "nonwait" program running as root; ie.
731183Speter * tcpmux          stream  tcp     nowait root /usr/local/bin/proxy proxy
831183Speter * with a NAT rue like this:
931183Speter * rdr smc0 0/0 port 80 -> 127.0.0.1/32 port 1
1031183Speter */
1131183Speter#include <stdio.h>
1231183Speter#include <string.h>
1331183Speter#include <fcntl.h>
1431183Speter#include <syslog.h>
1531183Speter#if !defined(__SVR4) && !defined(__svr4__)
1631183Speter#include <strings.h>
1731183Speter#else
1831183Speter#include <sys/byteorder.h>
1931183Speter#endif
2031183Speter#include <sys/types.h>
2131183Speter#include <sys/time.h>
2231183Speter#include <sys/param.h>
2331183Speter#include <stdlib.h>
2431183Speter#include <unistd.h>
2531183Speter#include <stddef.h>
2631183Speter#include <sys/socket.h>
2731183Speter#include <sys/ioctl.h>
2831183Speter#if defined(sun) && (defined(__svr4__) || defined(__SVR4))
2931183Speter# include <sys/ioccom.h>
3031183Speter# include <sys/sysmacros.h>
3131183Speter#endif
3231183Speter#include <netinet/in.h>
3331183Speter#include <netinet/in_systm.h>
3431183Speter#include <netinet/ip.h>
3531183Speter#include <netinet/tcp.h>
3631183Speter#include <net/if.h>
3731183Speter#include <netdb.h>
3831183Speter#include <arpa/nameser.h>
3931183Speter#include <arpa/inet.h>
4031183Speter#include <resolv.h>
4131183Speter#include <ctype.h>
4231183Speter#include "netinet/ip_compat.h"
4331183Speter#include "netinet/ip_fil.h"
4431183Speter#include "netinet/ip_proxy.h"
4531183Speter#include "netinet/ip_nat.h"
4631183Speter
4731183Speter
4831183Spetermain(argc, argv)
4931183Speterint argc;
5031183Speterchar *argv[];
5131183Speter{
5231183Speter	struct	sockaddr_in	sin, sloc, sout;
5331183Speter	natlookup_t	natlook;
5431183Speter	char	buffer[512];
5531183Speter	int	namelen, fd, n;
5631183Speter
5731183Speter	/*
5831183Speter	 * get IP# and port # of the remote end of the connection (at the
5931183Speter	 * origin).
6031183Speter	 */
6131183Speter	namelen = sizeof(sin);
6231183Speter	if (getpeername(0, (struct sockaddr *)&sin, &namelen) == -1) {
6331183Speter		perror("getpeername");
6431183Speter		exit(-1);
6531183Speter	}
6631183Speter
6731183Speter	/*
6831183Speter	 * get IP# and port # of the local end of the connection (at the
6931183Speter	 * man-in-the-middle).
7031183Speter	 */
7131183Speter	namelen = sizeof(sin);
7231183Speter	if (getsockname(0, (struct sockaddr *)&sloc, &namelen) == -1) {
7331183Speter		perror("getsockname");
7431183Speter		exit(-1);
7531183Speter	}
7631183Speter
7731183Speter	/*
7831183Speter	 * Build up the NAT natlookup structure.
7931183Speter	 */
8031183Speter	bzero((char *)&natlook, sizeof(natlook));
8131183Speter	natlook.nl_outip = sin.sin_addr;
8231183Speter	natlook.nl_inip = sloc.sin_addr;
8331183Speter	natlook.nl_flags = IPN_TCP;
8431183Speter	natlook.nl_outport = sin.sin_port;
8531183Speter	natlook.nl_inport = sloc.sin_port;
8631183Speter
8731183Speter	/*
8831183Speter	 * Open the NAT device and lookup the mapping pair.
8931183Speter	 */
9031183Speter	fd = open(IPL_NAT, O_RDONLY);
9131183Speter	if (ioctl(fd, SIOCGNATL, &natlook) == -1) {
9231183Speter		perror("ioctl");
9331183Speter		exit(-1);
9431183Speter	}
9531183Speter	close(fd);
9631183Speter	/*
9731183Speter	 * Log it
9831183Speter	 */
9931183Speter	syslog(LOG_DAEMON|LOG_INFO, "connect to %s,%d",
10031183Speter		inet_ntoa(natlook.nl_realip), natlook.nl_realport);
10131183Speter	printf("connect to %s,%d\n",
10231183Speter		inet_ntoa(natlook.nl_realip), ntohs(natlook.nl_realport));
10331183Speter
10431183Speter	/*
10531183Speter	 * Just echo data read in from stdin to stdout
10631183Speter	 */
10731183Speter	while ((n = read(0, buffer, sizeof(buffer))) > 0)
10831183Speter		if (write(1, buffer, n) != n)
10931183Speter			break;
11031183Speter	close(0);
11131183Speter}
112