$OpenBSD$
--- common/smtppass.c.orig	Tue May 27 14:46:35 2008
+++ common/smtppass.c	Fri Dec 17 13:10:44 2010
@@ -64,6 +64,14 @@
 #include <linux/netfilter_ipv4.h>
 #endif
 
+#ifdef USE_PF_NATLOOKUP
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <net/pfvar.h>
+#endif /* USE_PF_NATLOOKUP */
+
 #include "compat.h"
 #include "sock_any.h"
 #include "stringx.h"
@@ -737,7 +745,12 @@
     struct sockaddr_any* outaddr;
     char buf[MAXPATHLEN];
     const char* outname;
-    
+
+#ifdef USE_PF_NATLOOKUP
+	struct pfioc_natlook nl;
+	int dev;
+#endif /* USE_PF_NATLOOKUP */
+   
     ASSERT(client != -1);
 
     /* Setup the incoming connection. This also fills in peeraddr for us */
@@ -753,7 +766,7 @@
     {
         memset(&addr, 0, sizeof(addr));
         SANY_LEN(addr) = sizeof(addr);
-        
+
 #ifdef LINUX_TRANSPARENT_PROXY
         if(getsockopt(ctx->client.fd, SOL_IP, SO_ORIGINAL_DST, &SANY_ADDR(addr), &SANY_LEN(addr)) == -1)
 #else        
@@ -763,7 +776,41 @@
             sp_message(ctx, LOG_ERR, "couldn't get source address for transparent proxying");
             return -1;
         }
-        
+
+#ifdef USE_PF_NATLOOKUP
+	dev = open("/dev/pf", O_RDWR);
+	if (dev == -1) {
+		sp_message(ctx, LOG_ERR, "open(\"/dev/pf\") failed");
+		return -1;
+	}
+
+	memset(&nl, 0, sizeof(struct pfioc_natlook));
+
+	memcpy(&nl.saddr.v4.s_addr, &(peeraddr.s.in.sin_addr), sizeof(struct in_addr));
+	nl.sport = peeraddr.s.in.sin_port;
+
+	memcpy(&nl.daddr.v4.s_addr, &(addr.s.in.sin_addr), sizeof(struct in_addr));
+	nl.dport = addr.s.in.sin_port;
+
+	nl.af = AF_INET;
+	nl.proto = IPPROTO_TCP;
+
+	if (ioctl(dev, DIOCNATLOOK, &nl)) {
+		sp_message(ctx, LOG_ERR, "DIOCNATLOOK");
+		return -1;
+	}
+	
+	if (close(dev) != 0) {
+		sp_message(ctx, LOG_ERR, "close(\"/dev/pf\") failed");
+		return -1;
+	}
+
+	memcpy(&(addr.s.in.sin_addr), &nl.rdaddr.v4.s_addr,
+		sizeof(struct in_addr));
+	addr.s.in.sin_port = nl.rdport;
+	addr.s.in.sin_family = AF_INET;
+#endif /* USE_PF_NATLOOKUP */
+
         /* Check address types */
         if(sock_any_cmp(&addr, &peeraddr, SANY_OPT_NOPORT) == 0)
         {
@@ -1101,7 +1148,7 @@
                     /* Make note of the sender for later */
                     ctx->sender = (char*)reallocf(ctx->sender, strlen(t) + 1);
                     if(ctx->sender)
-                        strcpy(ctx->sender, t);
+                        strlcpy(ctx->sender, t, sizeof(ctx->sender));
                 }
                 
                 /* RCPT TO (that the server accepted) */
@@ -1117,11 +1164,11 @@
                     {
                         /* Recipients are separated by lines */
                         if(r != 0)
-                            strcat(ctx->recipients, "\n");
+                            strlcat(ctx->recipients, "\n", 1);
                         else
                             ctx->recipients[0] = 0;
                             
-                        strcat(ctx->recipients, t);
+                        strlcat(ctx->recipients, t, sizeof(ctx->recipients));
                     }
                 }
                             
@@ -1136,14 +1183,14 @@
                     {
                         ctx->xforwardaddr = (char*)reallocf(ctx->xforwardaddr, strlen(t) + 1);
                         if(ctx->xforwardaddr)
-                            strcpy(ctx->xforwardaddr, t);
+                            strlcpy(ctx->xforwardaddr, t, sizeof(ctx->xforwardaddr));
                     }
                     
                     if((t = parse_xforward (C_LINE + KL(XFORWARD_CMD), "HELO"))) 
                     {
                         ctx->xforwardhelo = (char*)reallocf(ctx->xforwardhelo, strlen(t) + 1);
                         if(ctx->xforwardhelo)
-                            strcpy(ctx->xforwardhelo, t);
+                            strlcpy(ctx->xforwardhelo, t, sizeof(ctx->xforwardhelo));
                     }
                     
                 }
