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;
|