diff options
author | ngie <ngie@FreeBSD.org> | 2015-10-05 03:26:51 +0000 |
---|---|---|
committer | ngie <ngie@FreeBSD.org> | 2015-10-05 03:26:51 +0000 |
commit | e1dd16d965b177f109afb771e59432e36f335d0a (patch) | |
tree | 15db092a5401cf329f1bff9d3bf700d1fde0f121 /contrib/ipfilter/samples | |
parent | 115d008392113efc6f844baa7cc407e9eaae63db (diff) | |
download | FreeBSD-src-e1dd16d965b177f109afb771e59432e36f335d0a.zip FreeBSD-src-e1dd16d965b177f109afb771e59432e36f335d0a.tar.gz |
Revert r288682
I meant to do this on ^/user/ngie/more-tests
Pointyhat to: ngie (use svn info next time...)
Diffstat (limited to 'contrib/ipfilter/samples')
-rw-r--r-- | contrib/ipfilter/samples/Makefile | 24 | ||||
-rw-r--r-- | contrib/ipfilter/samples/ipfilter-pb.gif | bin | 0 -> 795 bytes | |||
-rw-r--r-- | contrib/ipfilter/samples/proxy.c | 317 | ||||
-rw-r--r-- | contrib/ipfilter/samples/relay.c | 196 | ||||
-rw-r--r-- | contrib/ipfilter/samples/userauth.c | 62 |
5 files changed, 599 insertions, 0 deletions
diff --git a/contrib/ipfilter/samples/Makefile b/contrib/ipfilter/samples/Makefile new file mode 100644 index 0000000..47ab4a2 --- /dev/null +++ b/contrib/ipfilter/samples/Makefile @@ -0,0 +1,24 @@ +CC=gcc +all: + @echo "Please do one of the following:" + @echo "make bsd" + @echo "make bsdi" + @echo "make freebsd" + @echo "make freebsd22" + @echo "make netbsd" + @echo "make openbsd" + @echo "make sunos4" + @echo "make sunos5" + +sunos5: + $(CC) -I.. userauth.c -o userauth -lsocket -lnsl + $(CC) -I.. proxy.c -o proxy -lsocket -lnsl + $(CC) -I.. relay.c -o relay -lsocket -lnsl + +freebsd freebsd22 netbsd bsd bsdi sunos4 openbsd: + $(CC) -I.. userauth.c -o userauth + $(CC) -I.. proxy.c -o proxy + $(CC) -I.. relay.c -o relay + +clean: + /bin/rm -f userauth proxy relay diff --git a/contrib/ipfilter/samples/ipfilter-pb.gif b/contrib/ipfilter/samples/ipfilter-pb.gif Binary files differnew file mode 100644 index 0000000..afaefa8 --- /dev/null +++ b/contrib/ipfilter/samples/ipfilter-pb.gif diff --git a/contrib/ipfilter/samples/proxy.c b/contrib/ipfilter/samples/proxy.c new file mode 100644 index 0000000..483c4b5 --- /dev/null +++ b/contrib/ipfilter/samples/proxy.c @@ -0,0 +1,317 @@ +/* $FreeBSD$ */ + +/* + * Sample transparent proxy program. + * + * Sample implementation of a program which intercepts a TCP connectiona and + * just echos all data back to the origin. Written to work via inetd as a + * "nonwait" program running as root; ie. + * tcpmux stream tcp nowait root /usr/local/bin/proxy proxy + * with a NAT rue like this: + * rdr smc0 0/0 port 80 -> 127.0.0.1/32 port 1 + */ +#include <stdio.h> +#include <string.h> +#include <fcntl.h> +#include <syslog.h> +#if !defined(__SVR4) && !defined(__svr4__) +#include <strings.h> +#else +#include <sys/byteorder.h> +#endif +#include <sys/types.h> +#include <sys/time.h> +#include <sys/param.h> +#include <stdlib.h> +#include <unistd.h> +#include <stddef.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#if defined(sun) && (defined(__svr4__) || defined(__SVR4)) +# include <sys/ioccom.h> +# include <sys/sysmacros.h> +#endif +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/tcp.h> +#include <net/if.h> +#include <netdb.h> +#include <arpa/nameser.h> +#include <arpa/inet.h> +#include <resolv.h> +#include <ctype.h> +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_nat.h" +#include "netinet/ip_state.h" +#include "netinet/ip_proxy.h" +#include "netinet/ip_nat.h" +#include "netinet/ipl.h" + + +main(argc, argv) + int argc; + char *argv[]; +{ + struct sockaddr_in sin, sloc, sout; + ipfobj_t obj; + natlookup_t natlook; + char buffer[512]; + int namelen, fd, n; + + /* + * get IP# and port # of the remote end of the connection (at the + * origin). + */ + namelen = sizeof(sin); + if (getpeername(0, (struct sockaddr *)&sin, &namelen) == -1) { + perror("getpeername"); + exit(-1); + } + + /* + * get IP# and port # of the local end of the connection (at the + * man-in-the-middle). + */ + namelen = sizeof(sin); + if (getsockname(0, (struct sockaddr *)&sloc, &namelen) == -1) { + perror("getsockname"); + exit(-1); + } + + bzero((char *)&obj, sizeof(obj)); + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = sizeof(natlook); + obj.ipfo_ptr = &natlook; + obj.ipfo_type = IPFOBJ_NATLOOKUP; + + /* + * Build up the NAT natlookup structure. + */ + bzero((char *)&natlook, sizeof(natlook)); + natlook.nl_outip = sin.sin_addr; + natlook.nl_inip = sloc.sin_addr; + natlook.nl_flags = IPN_TCP; + natlook.nl_outport = sin.sin_port; + natlook.nl_inport = sloc.sin_port; + + /* + * Open the NAT device and lookup the mapping pair. + */ + fd = open(IPNAT_NAME, O_RDONLY); + if (ioctl(fd, SIOCGNATL, &obj) == -1) { + perror("ioctl(SIOCGNATL)"); + exit(-1); + } + +#define DO_NAT_OUT +#ifdef DO_NAT_OUT + if (argc > 1) + do_nat_out(0, 1, fd, &natlook, argv[1]); +#else + + /* + * Log it + */ + syslog(LOG_DAEMON|LOG_INFO, "connect to %s,%d", + inet_ntoa(natlook.nl_realip), ntohs(natlook.nl_realport)); + printf("connect to %s,%d\n", + inet_ntoa(natlook.nl_realip), ntohs(natlook.nl_realport)); + + /* + * Just echo data read in from stdin to stdout + */ + while ((n = read(0, buffer, sizeof(buffer))) > 0) + if (write(1, buffer, n) != n) + break; + close(0); +#endif +} + + +#ifdef DO_NAT_OUT +do_nat_out(in, out, fd, nlp, extif) + int fd; + natlookup_t *nlp; + char *extif; +{ + nat_save_t ns, *nsp = &ns; + struct sockaddr_in usin; + u_32_t sum1, sum2, sumd; + int onoff, ofd, slen; + ipfobj_t obj; + ipnat_t *ipn; + nat_t *nat; + + bzero((char *)&ns, sizeof(ns)); + + nat = &ns.ipn_nat; + nat->nat_p = IPPROTO_TCP; + nat->nat_dir = NAT_OUTBOUND; + if ((extif != NULL) && (*extif != '\0')) { + strncpy(nat->nat_ifnames[0], extif, + sizeof(nat->nat_ifnames[0])); + strncpy(nat->nat_ifnames[1], extif, + sizeof(nat->nat_ifnames[1])); + nat->nat_ifnames[0][sizeof(nat->nat_ifnames[0]) - 1] = '\0'; + nat->nat_ifnames[1][sizeof(nat->nat_ifnames[1]) - 1] = '\0'; + } + + ofd = socket(AF_INET, SOCK_DGRAM, 0); + bzero((char *)&usin, sizeof(usin)); + usin.sin_family = AF_INET; + usin.sin_addr = nlp->nl_realip; + usin.sin_port = nlp->nl_realport; + (void) connect(ofd, (struct sockaddr *)&usin, sizeof(usin)); + slen = sizeof(usin); + (void) getsockname(ofd, (struct sockaddr *)&usin, &slen); + close(ofd); +printf("local IP# to use: %s\n", inet_ntoa(usin.sin_addr)); + + if ((ofd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + perror("socket"); + usin.sin_port = 0; + if (bind(ofd, (struct sockaddr *)&usin, sizeof(usin))) + perror("bind"); + slen = sizeof(usin); + if (getsockname(ofd, (struct sockaddr *)&usin, &slen)) + perror("getsockname"); +printf("local port# to use: %d\n", ntohs(usin.sin_port)); + + nat->nat_inip = usin.sin_addr; + nat->nat_outip = nlp->nl_outip; + nat->nat_oip = nlp->nl_realip; + + sum1 = LONG_SUM(ntohl(usin.sin_addr.s_addr)) + ntohs(usin.sin_port); + sum2 = LONG_SUM(ntohl(nat->nat_outip.s_addr)) + ntohs(nlp->nl_outport); + CALC_SUMD(sum1, sum2, sumd); + nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16); + nat->nat_sumd[1] = nat->nat_sumd[0]; + + sum1 = LONG_SUM(ntohl(usin.sin_addr.s_addr)); + sum2 = LONG_SUM(ntohl(nat->nat_outip.s_addr)); + CALC_SUMD(sum1, sum2, sumd); + nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16); + + nat->nat_inport = usin.sin_port; + nat->nat_outport = nlp->nl_outport; + nat->nat_oport = nlp->nl_realport; + + nat->nat_flags = IPN_TCPUDP; + + bzero((char *)&obj, sizeof(obj)); + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = sizeof(*nsp); + obj.ipfo_ptr = nsp; + obj.ipfo_type = IPFOBJ_NATSAVE; + + onoff = 1; + if (ioctl(fd, SIOCSTLCK, &onoff) == 0) { + if (ioctl(fd, SIOCSTPUT, &obj) != 0) + perror("SIOCSTPUT"); + onoff = 0; + if (ioctl(fd, SIOCSTLCK, &onoff) != 0) + perror("SIOCSTLCK"); + } + + usin.sin_addr = nlp->nl_realip; + usin.sin_port = nlp->nl_realport; +printf("remote end for connection: %s,%d\n", inet_ntoa(usin.sin_addr), +ntohs(usin.sin_port)); +fflush(stdout); + if (connect(ofd, (struct sockaddr *)&usin, sizeof(usin))) + perror("connect"); + + relay(in, out, ofd); +} + + +relay(in, out, net) + int in, out, net; +{ + char netbuf[1024], outbuf[1024]; + char *nwptr, *nrptr, *owptr, *orptr; + size_t nsz, osz; + fd_set rd, wr; + int i, n, maxfd; + + n = 0; + maxfd = in; + if (out > maxfd) + maxfd = out; + if (net > maxfd) + maxfd = net; + + nrptr = netbuf; + nwptr = netbuf; + nsz = sizeof(netbuf); + orptr = outbuf; + owptr = outbuf; + osz = sizeof(outbuf); + + while (n >= 0) { + FD_ZERO(&rd); + FD_ZERO(&wr); + + if (nrptr - netbuf < sizeof(netbuf)) + FD_SET(in, &rd); + if (orptr - outbuf < sizeof(outbuf)) + FD_SET(net, &rd); + + if (nsz < sizeof(netbuf)) + FD_SET(net, &wr); + if (osz < sizeof(outbuf)) + FD_SET(out, &wr); + + n = select(maxfd + 1, &rd, &wr, NULL, NULL); + + if ((n > 0) && FD_ISSET(in, &rd)) { + i = read(in, nrptr, sizeof(netbuf) - (nrptr - netbuf)); + if (i <= 0) + break; + nsz -= i; + nrptr += i; + n--; + } + + if ((n > 0) && FD_ISSET(net, &rd)) { + i = read(net, orptr, sizeof(outbuf) - (orptr - outbuf)); + if (i <= 0) + break; + osz -= i; + orptr += i; + n--; + } + + if ((n > 0) && FD_ISSET(out, &wr)) { + i = write(out, owptr, orptr - owptr); + if (i <= 0) + break; + osz += i; + if (osz == sizeof(outbuf) || owptr == orptr) { + orptr = outbuf; + owptr = outbuf; + } else + owptr += i; + n--; + } + + if ((n > 0) && FD_ISSET(net, &wr)) { + i = write(net, nwptr, nrptr - nwptr); + if (i <= 0) + break; + nsz += i; + if (nsz == sizeof(netbuf) || nwptr == nrptr) { + nrptr = netbuf; + nwptr = netbuf; + } else + nwptr += i; + } + } + + close(net); + close(out); + close(in); +} +#endif diff --git a/contrib/ipfilter/samples/relay.c b/contrib/ipfilter/samples/relay.c new file mode 100644 index 0000000..11b76b0 --- /dev/null +++ b/contrib/ipfilter/samples/relay.c @@ -0,0 +1,196 @@ +/* $FreeBSD$ */ + +/* + * Sample program to be used as a transparent proxy. + * + * Must be executed with permission enough to do an ioctl on /dev/ipl + * or equivalent. This is just a sample and is only alpha quality. + * - Darren Reed (8 April 1996) + */ +#include <unistd.h> +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/syslog.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <netinet/in.h> +#include <net/if.h> +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_nat.h" +#include "netinet/ipl.h" + +#define RELAY_BUFSZ 8192 + +char ibuff[RELAY_BUFSZ]; +char obuff[RELAY_BUFSZ]; + +int relay(ifd, ofd, rfd) + int ifd, ofd, rfd; +{ + fd_set rfds, wfds; + char *irh, *irt, *rrh, *rrt; + char *iwh, *iwt, *rwh, *rwt; + int nfd, n, rw; + + irh = irt = ibuff; + iwh = iwt = obuff; + nfd = ifd; + if (nfd < ofd) + nfd = ofd; + if (nfd < rfd) + nfd = rfd; + + while (1) { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + if (irh > irt) + FD_SET(rfd, &wfds); + if (irh < (ibuff + RELAY_BUFSZ)) + FD_SET(ifd, &rfds); + if (iwh > iwt) + FD_SET(ofd, &wfds); + if (iwh < (obuff + RELAY_BUFSZ)) + FD_SET(rfd, &rfds); + + switch ((n = select(nfd + 1, &rfds, &wfds, NULL, NULL))) + { + case -1 : + case 0 : + return -1; + default : + if (FD_ISSET(ifd, &rfds)) { + rw = read(ifd, irh, ibuff + RELAY_BUFSZ - irh); + if (rw == -1) + return -1; + if (rw == 0) + return 0; + irh += rw; + n--; + } + if (n && FD_ISSET(ofd, &wfds)) { + rw = write(ofd, iwt, iwh - iwt); + if (rw == -1) + return -1; + iwt += rw; + n--; + } + if (n && FD_ISSET(rfd, &rfds)) { + rw = read(rfd, iwh, obuff + RELAY_BUFSZ - iwh); + if (rw == -1) + return -1; + if (rw == 0) + return 0; + iwh += rw; + n--; + } + if (n && FD_ISSET(rfd, &wfds)) { + rw = write(rfd, irt, irh - irt); + if (rw == -1) + return -1; + irt += rw; + n--; + } + if (irh == irt) + irh = irt = ibuff; + if (iwh == iwt) + iwh = iwt = obuff; + } + } +} + +main(argc, argv) + int argc; + char *argv[]; +{ + struct sockaddr_in sin; + ipfobj_t obj; + natlookup_t nl; + natlookup_t *nlp = &nl; + int fd, sl = sizeof(sl), se; + + openlog(argv[0], LOG_PID|LOG_NDELAY, LOG_DAEMON); + if ((fd = open(IPNAT_NAME, O_RDONLY)) == -1) { + se = errno; + perror("open"); + errno = se; + syslog(LOG_ERR, "open: %m\n"); + exit(-1); + } + + bzero(&obj, sizeof(obj)); + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = sizeof(nl); + obj.ipfo_ptr = &nl; + obj.ipfo_type = IPFOBJ_NATLOOKUP; + + bzero(&nl, sizeof(nl)); + nl.nl_flags = IPN_TCP; + + bzero(&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sl = sizeof(sin); + if (getsockname(0, (struct sockaddr *)&sin, &sl) == -1) { + se = errno; + perror("getsockname"); + errno = se; + syslog(LOG_ERR, "getsockname: %m\n"); + exit(-1); + } else { + nl.nl_inip.s_addr = sin.sin_addr.s_addr; + nl.nl_inport = sin.sin_port; + } + + bzero(&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sl = sizeof(sin); + if (getpeername(0, (struct sockaddr *)&sin, &sl) == -1) { + se = errno; + perror("getpeername"); + errno = se; + syslog(LOG_ERR, "getpeername: %m\n"); + exit(-1); + } else { + nl.nl_outip.s_addr = sin.sin_addr.s_addr; + nl.nl_outport = sin.sin_port; + } + + if (ioctl(fd, SIOCGNATL, &obj) == -1) { + se = errno; + perror("ioctl"); + errno = se; + syslog(LOG_ERR, "ioctl: %m\n"); + exit(-1); + } + + sin.sin_port = nl.nl_realport; + sin.sin_addr = nl.nl_realip; + sl = sizeof(sin); + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (connect(fd, (struct sockaddr *)&sin, sl) == -1) { + se = errno; + perror("connect"); + errno = se; + syslog(LOG_ERR, "connect: %m\n"); + exit(-1); + } + + (void) ioctl(fd, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK); + (void) ioctl(0, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK); + (void) ioctl(1, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK); + + syslog(LOG_NOTICE, "connected to %s,%d\n", inet_ntoa(sin.sin_addr), + ntohs(sin.sin_port)); + if (relay(0, 1, fd) == -1) { + se = errno; + perror("relay"); + errno = se; + syslog(LOG_ERR, "relay: %m\n"); + exit(-1); + } + exit(0); +} diff --git a/contrib/ipfilter/samples/userauth.c b/contrib/ipfilter/samples/userauth.c new file mode 100644 index 0000000..620bd72 --- /dev/null +++ b/contrib/ipfilter/samples/userauth.c @@ -0,0 +1,62 @@ +/* $FreeBSD$ */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <stdio.h> +#include <stdlib.h> +#include <netinet/in.h> +#include <net/if.h> +#include "ip_compat.h" +#include "ip_fil.h" +#include "ip_auth.h" + +extern int errno; + +main() +{ + struct frauth fra; + struct frauth *frap = &fra; + fr_info_t *fin = &fra.fra_info; + fr_ip_t *fi = &fin->fin_fi; + char yn[16]; + int fd; + + fd = open(IPL_NAME, O_RDWR); + fra.fra_len = 0; + fra.fra_buf = NULL; + while (ioctl(fd, SIOCAUTHW, &frap) == 0) { + if (fra.fra_info.fin_out) + fra.fra_pass = FR_OUTQUE; + else + fra.fra_pass = FR_INQUE; + + printf("%s ", inet_ntoa(fi->fi_src)); + if (fi->fi_flx & FI_TCPUDP) + printf("port %d ", fin->fin_data[0]); + printf("-> %s ", inet_ntoa(fi->fi_dst)); + if (fi->fi_flx & FI_TCPUDP) + printf("port %d ", fin->fin_data[1]); + printf("\n"); + printf("Allow packet through ? [y/n]"); + fflush(stdout); + if (!fgets(yn, sizeof(yn), stdin)) + break; + fflush(stdin); + if (yn[0] == 'n' || yn[0] == 'N') + fra.fra_pass |= FR_BLOCK; + else if (yn[0] == 'y' || yn[0] == 'Y') { + fra.fra_pass |= FR_PASS; + if (fra.fra_info.fin_fi.fi_flx & FI_TCPUDP) + fra.fra_pass |= FR_KEEPSTATE; + } else + fra.fra_pass |= FR_NOMATCH; + printf("answer = %c (%x), id %d idx %d\n", yn[0], + fra.fra_pass, fra.fra_info.fin_id, fra.fra_index); + if (ioctl(fd, SIOCAUTHR, &frap) != 0) + perror("SIOCAUTHR"); + } + fprintf(stderr, "errno=%d \n", errno); + perror("frauth-SIOCAUTHW"); +} |