aboutsummaryrefslogtreecommitdiffstats
path: root/ftp/frox/files/patch-src-bsd.c
blob: ca2735065b4f28b9fe3001de93c8e11d99dbb442 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
--- src/bsd.c.orig  Fri Feb  4 20:54:55 2005
+++ src/bsd.c   Wed Jul 25 01:25:16 2007
@@ -30,6 +30,16 @@
 #error --enable-transparent-data not supported under BSD
 #endif
 
+#ifdef PF
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <net/pfvar.h>
+
+static int natfd;
+#endif
+
+
 #ifdef IPFILTER
 #include <fcntl.h>
 #include <sys/ioctl.h>
@@ -51,6 +61,11 @@
    if(natfd < 0)
        write_log(ERROR, "Unable to initialise IPFilter");
 #endif
+#ifdef PF
+       natfd = open("/dev/pf", O_RDWR);
+       if (natfd == -1)
+               write_log(ERROR, "Unable to initialise PF");
+#endif
    return 0;
 }
 
@@ -61,6 +76,11 @@
 int get_orig_dest(int fd, struct sockaddr_in *addr)
 {
    socklen_t len;
+#ifdef PF
+    struct pfioc_natlook nl;
+    struct sockaddr_in from;
+    int r2;
+#endif
 #ifdef IPFILTER
    struct natlookup nat;
    struct sockaddr_in from;
@@ -99,6 +119,31 @@
        addr->sin_family = AF_INET;
        return r2;
    }
+#endif
+#ifdef PF
+       getpeername(fd, (struct sockaddr *) &from, &len);
+       memset(&nl, 0, sizeof(struct pfioc_natlook));
+       memcpy( &nl.daddr.v4, &to.sin_addr.s_addr, sizeof( nl.saddr.v4 ));
+       memcpy( &nl.saddr.v4, &from.sin_addr.s_addr, sizeof( nl.daddr.v4 ));
+       nl.dport = to.sin_port;
+       nl.sport = from.sin_port;
+       nl.af = AF_INET;
+       nl.proto = IPPROTO_TCP;
+       nl.direction = PF_INOUT;
+
+       if ( natfd > 0 ){
+           if (ioctl(natfd, DIOCNATLOOK, &nl)==-1){
+               write_log(ERROR, "Failed to lookup address");
+           }
+           else {
+               memset(addr, sizeof(*addr), 0);
+               memcpy(&addr->sin_addr.s_addr, &nl.rdaddr.v4.s_addr, sizeof(struct sockaddr_in));
+               addr->sin_len = sizeof(struct sockaddr_in);
+               addr->sin_port = nl.rdport;
+               addr->sin_family = AF_INET;
+               return r2;
+          }
+      }
 #endif
    memcpy(addr, &to, len);
    return r1;