IPNAT(4)
β¨ IPNAT(4) β the ipnat manual page, bestie edition β¨
okay so you opened the manual for ipnat β aka the Network Address Translation kernel interface β from the Kernel Interfaces Manual section 4. sit down, grab a strawberry π, and let's get into it, because this one is genuinely iconic.
πΈ NAME πΈ
ipnat β Network Address Translation kernel interface. that's the whole name. short, sweet, does exactly what it says π
π¦ SYNOPSIS π¦
so before you can do literally anything, you gotta include these. all four. no skipping:
#include <netinet/ip_compat.h>
#include <netinet/ip_fil.h>
#include <netinet/ip_proxy.h>
#include <netinet/ip_nat.h>
it's giving "i need my whole friend group with me" energy π«Ά
π IOCTLS π
to add and delete rules from the NAT list, there are two 'basic' ioctls you get to use. and they get called like this:
ioctl(fd, SIOCADNAT, struct ipnat **)
ioctl(fd, SIOCRMNAT, struct ipnat **)
ioctl(fd, SIOCGNATS, struct natstat **)
ioctl(fd, SIOCGNATL, struct natlookup **)
now, heads up: unlike ipf(4), the kernel NAT interface supports only a single list. there is not an inactive list that you can swap to. not currently supported, bestie, so don't go looking for one π
these ioctls are implemented as being routing ioctls, which means the same rules that apply to the various routing ioctls also apply to the file descriptor. the big one: the fd must be that of the device associated with the module, i.e. /dev/ipl. that part matters, fr fr.
π the structure π
here's the structure the NAT interface uses, described below, verbatim, don't touch anything:
typedef struct ipnat {
struct ipnat *in_next;
void *in_ifp;
u_short in_flags;
u_short in_pnext;
u_short in_port[2];
struct in_addr in_in[2];
struct in_addr in_out[2];
struct in_addr in_nextip;
int in_space;
int in_redir; /* 0 if it's a mapping, 1 if it's a hard redir */
char in_ifname[IFNAMSIZ];
} ipnat_t;
#define in_pmin in_port[0] /* Also holds static redir port */
#define in_pmax in_port[1]
#define in_nip in_nextip.s_addr
#define in_inip in_in[0].s_addr
#define in_inmsk in_in[1].s_addr
#define in_outip in_out[0].s_addr
#define in_outmsk in_out[1].s_addr
and the recognised values for in_redir are:
#define NAT_MAP 0
#define NAT_REDIRECT 1
not me reading that comment inin_redirlike0= it's a mapping,1= it's a hard redir. that's it, that's the tea β
π NAT statistics π
so the kernel keeps stats for you. what's being counted?
- the number of packets mapped, going in and out
- the number of times a new entry gets added and deleted (through expiration) to the NAT table
- the current usage level of the NAT table
you also get pointers to the NAT table inside the kernel, plus pointers to the top of the internal NAT lists constructed with the SIOCADNAT ioctls. and the table itself? it's a hash table of size NAT_SIZE β default size is 367 β
to retrieve the statistics, you must use the SIOCGNATS ioctl, with the appropriate structure passed by reference, like so:
ioctl(fd, SIOCGNATS, struct natstat *)
and here's that structure, again, exact, no edits:
typedef struct natstat {
u_long ns_mapped[2];
u_long ns_added;
u_long ns_expire;
u_long ns_inuse;
nat_t ***ns_table;
ipnat_t *ns_list;
} natstat_t;
π BUGS π
okay the actual bug note, and it's a whole mood: it would be nice if there were more flexibility when adding and deleting filter rules. that's the entire bug report. relatable, honestly. π
π FILES π
/dev/ipnat
that's the one. go say hi to it.
π SEE ALSO π
go read these next, bestie, they're the rest of the lore:
and that's the page!! π it came from the IPNAT(4) manual β Kernel Interfaces Manual, section 4, page IPNAT(4) β so if you cite it, that's the whole flex. now go configure something responsibly, mwah πβ¨π
π¦ where this page comes from
- debian bookworm: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- debian trixie: freebsd-manpages 12.2-2 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu jammy: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu noble: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu questing: freebsd-manpages 12.2-2
- ubuntu resolute: freebsd-manpages 12.2-2build1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu stonking: freebsd-manpages 12.2-2build1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms