IPNAT(4)
π¦ ipnat β NAT kernel interface, bestie π¦
Welcome to IPNAT(4) from the Kernel Interfaces Manual β this is the page for ipnat, and itβs all about the kernel interface for Network Address Translation. Slay. π
β¨ NAME β¨
ipnat β Network Address Translation kernel interface π
πΈ SYNOPSIS πΈ
Include these exactly, or the compiler simply will not vibe with you:
#include <netinet/ip_compat.h>
#include <netinet/ip_fil.h>
#include <netinet/ip_proxy.h>
#include <netinet/ip_nat.h>
π IOCTLS π
To add and delete rules to the NAT list, there are two 'basic' ioctls provided for use. They go like this:
ioctl(fd, SIOCADNAT, struct ipnat **)
ioctl(fd, SIOCRMNAT, struct ipnat **)
ioctl(fd, SIOCGNATS, struct natstat **)
ioctl(fd, SIOCGNATL, struct natlookup **)
Unlike ipf(4), the kernel NAT interface supports only a single list. An inactive list that can be swapped to is not currently supported, bestie. π
These ioctls are implemented as routing ioctls, so the same rules for the various routing ioctls and the file descriptor apply. Main-character rule: the fd must be that of the device associated with the module β i.e., /dev/ipl. π«Ά
The structure used with the NAT interface is this one right here:
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
Recognised values for in_redir:
#define NAT_MAP 0
#define NAT_REDIRECT 1
NAT statistics β the kernel keeps statistics on the number of packets mapped, going in and out; the number of times a new entry is added and deleted (through expiration) to the NAT table; and the current usage level of the NAT table. π
There are pointers to the NAT table inside the kernel, as well as to the top of the internal NAT lists constructed with the SIOCADNAT ioctls. The table itself is a hash table of size NAT_SIZE (default size is 367). π§
To retrieve the statistics, the SIOCGNATS ioctl must be used, with the appropriate structure passed by reference, as follows:
ioctl(fd, SIOCGNATS, struct natstat *)
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 π
It would be nice if there were more flexibility when adding and deleting filter rules. Thatβs the whole bug note β manifesting flexibility fr fr. π
π FILES π
/dev/ipnat
π SEE ALSO π
okay thatβs the tea β β source/version vibes: Kernel Interfaces Manual; page: IPNAT(4); date: none listed on this one. byeee, stay slay π β¨
π¦ where this page comes from
- freebsd 15.1: base 15.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms