--- tproxy.c.orig	Mon May  5 23:50:13 1997
+++ tproxy.c	Sat Mar 28 16:16:32 1998
@@ -18,11 +18,27 @@
 #include <syslog.h>
 #include <signal.h>
 #include <pwd.h>
+#ifndef __FreeBSD__
 #include <getopt.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <errno.h>
+
+#ifdef IPFILTER
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <net/if.h>
+#include <netinet/ip_compat.h>
+#include <netinet/ip_fil.h>
+#include <netinet/ip_proxy.h>
+#include <netinet/ip_nat.h>
+#endif
 
 /*
  * Typedefs.
@@ -59,6 +75,13 @@
  */
 static int				fully_transparent = 0;
 
+#ifdef IPFILTER
+/*
+ * /dev/ipnat device node
+ */
+static int				natdev = -1;
+#endif
+
 /*
  * Main loop.
  */
@@ -146,6 +169,17 @@
 		usage(argv[0], "No server port was specified (or it was invalid).");
 	}
 
+#ifdef IPFILTER
+	/*
+	 * Now is a good time to open /dev/ipnat, before giving up an uid's.
+	 */
+	natdev = open(IPL_NAT, O_RDONLY);
+	if (natdev < 0) {
+		perror("open(" IPL_NAT ")");
+		exit(1);
+	}
+#endif
+
 	/*
 	 * See if we should run as a server.
 	 */
@@ -199,7 +233,9 @@
 			 * Start a new session and group.
 			 */
 			setsid();
+#ifndef __FreeBSD__
 			setpgrp();
+#endif
 
 			/*
 			 * Handle the server main loop.
@@ -416,6 +452,7 @@
 	/*
 	 * Set the address to listen to.
 	 */
+	memset(&addr, 0, sizeof(addr));		/* zero sin_len for 4.4BSD */
 	addr.sin_family = AF_INET;
 	addr.sin_port = htons(bind_port);
 	addr.sin_addr.s_addr = bind_ip;
@@ -545,7 +582,19 @@
 	/*
 	 * Ignore dead servers so no zombies should be left hanging.
 	 */
+#if defined(SIGCHLD) && !defined(SIGCLD)
+#define SIGCLD SIGCHLD
+#endif
+#ifdef SA_NOCLDWAIT
+	struct sigaction	sa;
+
+	memset(&sa, 0, sizeof(sa));
+	sa.sa_handler = SIG_IGN;
+	sa.sa_flags = SA_NOCLDWAIT;
+	sigaction(SIGCLD, &sa, NULL);
+#else
 	signal(SIGCLD, SIG_IGN);
+#endif
 
 	for (;;)
 	{
@@ -606,6 +655,9 @@
 	int					max_fd;
 	fd_set				read_fd;
 	int					read_len;
+#ifdef IPFILTER
+	natlookup_t			natlook;
+#endif
 
 	/*
 	 * The first thing we do is get the IP address that the client was
@@ -618,6 +670,35 @@
 		syslog(LOG_ERR, "getsockname(): %m");
 		return;
 	}
+
+#ifdef IPFILTER
+	/*
+	 * However, under IPFILTER, we have to do more work.  The "to_addr"
+	 * above really is the local address.  We need to look the real remote
+	 * address up ourselves.
+	 */
+
+	/*
+	 * Build up the NAT natlookup structure.
+	 */
+	bzero((char *)&natlook, sizeof(natlook));
+	natlook.nl_inip = to_addr.sin_addr;
+	natlook.nl_outip = from_addr->sin_addr;
+	natlook.nl_flags = IPN_TCP;
+	natlook.nl_inport = to_addr.sin_port;
+	natlook.nl_outport = from_addr->sin_port;
+
+	/*
+	 * Open the NAT device and lookup the mapping pair.
+	 */
+	if (ioctl(natdev, SIOCGNATL, &natlook) == -1) {
+		syslog(LOG_ERR, "ioctl(SIOCGNATL): %m");
+		return;
+	}
+
+	to_addr.sin_addr = natlook.nl_realip;
+	to_addr.sin_port = natlook.nl_realport;
+#endif
 
 	/*
 	 * Connect to the proxy server.
