1 /* $NetBSD: pf.c,v 1.1 2005/04/03 22:15:32 peter Exp $ */
4 * pf.c - NAT lookup code for pf.
6 * This software is in the public domain.
7 * Written by Peter Postma <peter@NetBSD.org>
10 #include <sys/cdefs.h>
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <sys/ioctl.h>
16 #include <sys/fcntl.h>
19 #include <netinet/in.h>
20 #include <net/pfvar.h>
30 pf_natlookup(struct sockaddr_storage
*ss
, struct sockaddr
*nat_addr
,
33 struct pfioc_natlook nl
;
36 (void)memset(&nl
, 0, sizeof(nl
));
38 /* Build the pf natlook structure. */
39 switch (ss
[0].ss_family
) {
41 (void)memcpy(&nl
.daddr
.v4
, &satosin(&ss
[0])->sin_addr
,
42 sizeof(struct in_addr
));
43 (void)memcpy(&nl
.saddr
.v4
, &satosin(&ss
[1])->sin_addr
,
44 sizeof(struct in_addr
));
45 nl
.dport
= satosin(&ss
[0])->sin_port
;
46 nl
.sport
= satosin(&ss
[1])->sin_port
;
48 nl
.proto
= IPPROTO_TCP
;
52 (void)memcpy(&nl
.daddr
.v6
, &satosin6(&ss
[0])->sin6_addr
,
53 sizeof(struct in6_addr
));
54 (void)memcpy(&nl
.saddr
.v6
, &satosin6(&ss
[1])->sin6_addr
,
55 sizeof(struct in6_addr
));
56 nl
.dport
= satosin6(&ss
[0])->sin6_port
;
57 nl
.sport
= satosin6(&ss
[1])->sin6_port
;
59 nl
.proto
= IPPROTO_TCP
;
63 maybe_syslog(LOG_ERR
, "Unsupported protocol for NAT lookup "
64 "(no. %d)", ss
[0].ss_family
);
68 /* Open the /dev/pf device and do the lookup. */
69 if ((dev
= open("/dev/pf", O_RDWR
)) == -1) {
70 maybe_syslog(LOG_ERR
, "Cannot open /dev/pf: %m");
73 if (ioctl(dev
, DIOCNATLOOK
, &nl
) == -1) {
74 maybe_syslog(LOG_ERR
, "NAT lookup failure: %m");
81 * Put the originating address into nat_addr and fill
82 * the port with the ident port, 113.
84 switch (ss
[0].ss_family
) {
86 (void)memcpy(&satosin(nat_addr
)->sin_addr
, &nl
.rsaddr
.v4
,
87 sizeof(struct in_addr
));
88 satosin(nat_addr
)->sin_port
= htons(113);
89 satosin(nat_addr
)->sin_len
= sizeof(struct sockaddr_in
);
90 satosin(nat_addr
)->sin_family
= AF_INET
;
93 (void)memcpy(&satosin6(nat_addr
)->sin6_addr
, &nl
.rsaddr
.v6
,
94 sizeof(struct in6_addr
));
95 satosin6(nat_addr
)->sin6_port
= htons(113);
96 satosin6(nat_addr
)->sin6_len
= sizeof(struct sockaddr_in6
);
97 satosin6(nat_addr
)->sin6_family
= AF_INET6
;
100 /* Put the originating port into nat_lport. */
101 *nat_lport
= nl
.rsport
;