proxy.c revision 31183
1/* 2 * Sample transparent proxy program. 3 * 4 * Sample implementation of a program which intercepts a TCP connectiona and 5 * just echos all data back to the origin. Written to work via inetd as a 6 * "nonwait" program running as root; ie. 7 * tcpmux stream tcp nowait root /usr/local/bin/proxy proxy 8 * with a NAT rue like this: 9 * rdr smc0 0/0 port 80 -> 127.0.0.1/32 port 1 10 */ 11#include <stdio.h> 12#include <string.h> 13#include <fcntl.h> 14#include <syslog.h> 15#if !defined(__SVR4) && !defined(__svr4__) 16#include <strings.h> 17#else 18#include <sys/byteorder.h> 19#endif 20#include <sys/types.h> 21#include <sys/time.h> 22#include <sys/param.h> 23#include <stdlib.h> 24#include <unistd.h> 25#include <stddef.h> 26#include <sys/socket.h> 27#include <sys/ioctl.h> 28#if defined(sun) && (defined(__svr4__) || defined(__SVR4)) 29# include <sys/ioccom.h> 30# include <sys/sysmacros.h> 31#endif 32#include <netinet/in.h> 33#include <netinet/in_systm.h> 34#include <netinet/ip.h> 35#include <netinet/tcp.h> 36#include <net/if.h> 37#include <netdb.h> 38#include <arpa/nameser.h> 39#include <arpa/inet.h> 40#include <resolv.h> 41#include <ctype.h> 42#include "netinet/ip_compat.h" 43#include "netinet/ip_fil.h" 44#include "netinet/ip_proxy.h" 45#include "netinet/ip_nat.h" 46 47 48main(argc, argv) 49int argc; 50char *argv[]; 51{ 52 struct sockaddr_in sin, sloc, sout; 53 natlookup_t natlook; 54 char buffer[512]; 55 int namelen, fd, n; 56 57 /* 58 * get IP# and port # of the remote end of the connection (at the 59 * origin). 60 */ 61 namelen = sizeof(sin); 62 if (getpeername(0, (struct sockaddr *)&sin, &namelen) == -1) { 63 perror("getpeername"); 64 exit(-1); 65 } 66 67 /* 68 * get IP# and port # of the local end of the connection (at the 69 * man-in-the-middle). 70 */ 71 namelen = sizeof(sin); 72 if (getsockname(0, (struct sockaddr *)&sloc, &namelen) == -1) { 73 perror("getsockname"); 74 exit(-1); 75 } 76 77 /* 78 * Build up the NAT natlookup structure. 79 */ 80 bzero((char *)&natlook, sizeof(natlook)); 81 natlook.nl_outip = sin.sin_addr; 82 natlook.nl_inip = sloc.sin_addr; 83 natlook.nl_flags = IPN_TCP; 84 natlook.nl_outport = sin.sin_port; 85 natlook.nl_inport = sloc.sin_port; 86 87 /* 88 * Open the NAT device and lookup the mapping pair. 89 */ 90 fd = open(IPL_NAT, O_RDONLY); 91 if (ioctl(fd, SIOCGNATL, &natlook) == -1) { 92 perror("ioctl"); 93 exit(-1); 94 } 95 close(fd); 96 /* 97 * Log it 98 */ 99 syslog(LOG_DAEMON|LOG_INFO, "connect to %s,%d", 100 inet_ntoa(natlook.nl_realip), natlook.nl_realport); 101 printf("connect to %s,%d\n", 102 inet_ntoa(natlook.nl_realip), ntohs(natlook.nl_realport)); 103 104 /* 105 * Just echo data read in from stdin to stdout 106 */ 107 while ((n = read(0, buffer, sizeof(buffer))) > 0) 108 if (write(1, buffer, n) != n) 109 break; 110 close(0); 111} 112