1 /*        $NetBSD: ip_nat.h,v 1.8 2022/05/07 04:38:09 mrg Exp $       */
2 
3 /*
4  * Copyright (C) 2012 by Darren Reed.
5  *
6  * See the IPFILTER.LICENCE file for details on licencing.
7  *
8  * @(#)ip_nat.h     1.5 2/4/96
9  * Id: ip_nat.h,v 1.1.1.2 2012/07/22 13:45:29 darrenr Exp
10  */
11 
12 #ifndef   __IP_NAT_H__
13 #define   __IP_NAT_H__
14 
15 #ifndef   SOLARIS
16 # if (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
17 #  define SOLARIS   1
18 # else
19 #  define SOLARIS   0
20 # endif
21 #endif
22 
23 #if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
24 #define   SIOCADNAT _IOW('r', 60, struct ipfobj)
25 #define   SIOCRMNAT _IOW('r', 61, struct ipfobj)
26 #define   SIOCGNATS _IOWR('r', 62, struct ipfobj)
27 #define   SIOCGNATL _IOWR('r', 63, struct ipfobj)
28 #define   SIOCPURGENAT        _IOWR('r', 100, struct ipfobj)
29 #else
30 #define   SIOCADNAT _IOW(r, 60, struct ipfobj)
31 #define   SIOCRMNAT _IOW(r, 61, struct ipfobj)
32 #define   SIOCGNATS _IOWR(r, 62, struct ipfobj)
33 #define   SIOCGNATL _IOWR(r, 63, struct ipfobj)
34 #define   SIOCPURGENAT        _IOWR(r, 100, struct ipfobj)
35 #endif
36 
37 #undef    LARGE_NAT /* define this if you're setting up a system to NAT
38                                * LARGE numbers of networks/hosts - i.e. in the
39                                * hundreds or thousands.  In such a case, you should
40                                * also change the RDR_SIZE and NAT_SIZE below to more
41                                * appropriate sizes.  The figures below were used for
42                                * a setup with 1000-2000 networks to NAT.
43                                */
44 #ifndef NAT_SIZE
45 # ifdef LARGE_NAT
46 #  define NAT_SIZE  2047
47 # else
48 #  define NAT_SIZE  127
49 # endif
50 #endif
51 #ifndef RDR_SIZE
52 # ifdef LARGE_NAT
53 #  define RDR_SIZE  2047
54 # else
55 #  define RDR_SIZE  127
56 # endif
57 #endif
58 #ifndef HOSTMAP_SIZE
59 # ifdef LARGE_NAT
60 #  define HOSTMAP_SIZE        8191
61 # else
62 #  define HOSTMAP_SIZE        2047
63 # endif
64 #endif
65 #ifndef NAT_TABLE_MAX
66 /*
67  * This is newly introduced and for the sake of "least surprise", the numbers
68  * present aren't what we'd normally use for creating a proper hash table.
69  */
70 # ifdef   LARGE_NAT
71 #  define NAT_TABLE_MAX       180000
72 # else
73 #  define NAT_TABLE_MAX       30000
74 # endif
75 #endif
76 #ifndef NAT_TABLE_SZ
77 # ifdef LARGE_NAT
78 #  define NAT_TABLE_SZ        16383
79 # else
80 #  define NAT_TABLE_SZ        2047
81 # endif
82 #endif
83 #ifndef   APR_LABELLEN
84 #define   APR_LABELLEN        16
85 #endif
86 #define   NAT_HW_CKSUM                  0x80000000
87 #define   NAT_HW_CKSUM_PART   0x40000000
88 
89 #define   DEF_NAT_AGE         1200     /* 10 minutes (600 seconds) */
90 
91 struct ipstate;
92 struct ap_session;
93 
94 /*
95  * This structure is used in the active NAT table and represents an
96  * active NAT session.
97  *
98  * Generally nat_t structures have references from at least two places.
99  * The first place gives them a position in a linked list of NAT sessions
100  * per instace of IPFilter. In this linked list, nat_next always points to
101  * the next entry in the list and nat_pnext points to the pointer that
102  * introduces the structure. That may be either the top of the list pointer
103  * or simply the nat_next of the previous link in the list. The second place
104  * that a nat_t structure is generally referenced from is the NAT hash table.
105  * Two references from this table are required, one for supporting the of
106  * matching packets being transmitted and one for supporting the matching of
107  * packets being received. The hash table is comprised of buckets, each one
108  * having its own chain of nat_t structures. To support these chains,
109  * nat_hnext is used to point to the next member of the chain and nat_phnext
110  * points back to the pointer that is pointing to the nat_t in the chain,
111  * be it the bucket at the top or simply the previous nat_t chain entry.
112  */
113 typedef   struct    nat       {
114           ipfmutex_t          nat_lock;
115           struct    nat       *nat_next;
116           struct    nat       **nat_pnext;
117           struct    nat       *nat_hnext[2];
118           struct    nat       **nat_phnext[2];
119           struct    hostmap   *nat_hm;
120           void                *nat_data;
121           struct    nat       **nat_me;
122           struct    ipstate   *nat_state;
123           struct    ap_session          *nat_aps;           /* proxy session */
124           frentry_t *nat_fr;  /* filter rule ptr if appropriate */
125           struct    ipnat     *nat_ptr; /* pointer back to the rule */
126           void                *nat_ifps[2];
127           void                *nat_sync;
128           ipftqent_t          nat_tqe;
129           int                 nat_mtu[2];
130           u_32_t              nat_flags;
131           u_32_t              nat_sumd[2];        /* ip checksum delta for data segment*/
132           u_32_t              nat_ipsumd;         /* ip checksum delta for ip header */
133           u_32_t              nat_mssclamp;       /* if != zero clamp MSS to this */
134           i6addr_t  nat_odst6;
135           i6addr_t  nat_osrc6;
136           i6addr_t  nat_ndst6;
137           i6addr_t  nat_nsrc6;
138           U_QUAD_T  nat_pkts[2];
139           U_QUAD_T  nat_bytes[2];
140           union     {
141                     udpinfo_t nat_unu;
142                     tcpinfo_t nat_unt;
143                     icmpinfo_t          nat_uni;
144                     greinfo_t nat_ugre;
145           } nat_unold, nat_unnew;
146           int                 nat_use;
147           int                 nat_pr[2];                    /* protocol for NAT */
148           int                 nat_dir;
149           int                 nat_ref;            /* reference count */
150           u_int               nat_hv[2];
151           char                nat_ifnames[2][LIFNAMSIZ];
152           int                 nat_rev;            /* 0 = forward, 1 = reverse */
153           int                 nat_dlocal;
154           int                 nat_v[2];           /* 0 = old, 1 = new */
155           u_int               nat_redir;                    /* copy of in_redir */
156 } nat_t;
157 
158 #define   nat_osrcip          nat_osrc6.in4
159 #define   nat_odstip          nat_odst6.in4
160 #define   nat_nsrcip          nat_nsrc6.in4
161 #define   nat_ndstip          nat_ndst6.in4
162 #define   nat_osrcaddr        nat_osrc6.in4.s_addr
163 #define   nat_odstaddr        nat_odst6.in4.s_addr
164 #define   nat_nsrcaddr        nat_nsrc6.in4.s_addr
165 #define   nat_ndstaddr        nat_ndst6.in4.s_addr
166 #define   nat_age             nat_tqe.tqe_die
167 #define   nat_osport          nat_unold.nat_unt.ts_sport
168 #define   nat_odport          nat_unold.nat_unt.ts_dport
169 #define   nat_nsport          nat_unnew.nat_unt.ts_sport
170 #define   nat_ndport          nat_unnew.nat_unt.ts_dport
171 #define   nat_oicmpid         nat_unold.nat_uni.ici_id
172 #define   nat_nicmpid         nat_unnew.nat_uni.ici_id
173 #define   nat_type  nat_unold.nat_uni.ici_type
174 #define   nat_oseq  nat_unold.nat_uni.ici_seq
175 #define   nat_nseq  nat_unnew.nat_uni.ici_seq
176 #define   nat_tcpstate        nat_tqe.tqe_state
177 #define   nat_die             nat_tqe.tqe_die
178 #define   nat_touched         nat_tqe.tqe_touched
179 
180 /*
181  * Values for nat_dir
182  */
183 #define   NAT_INBOUND         0
184 #define   NAT_OUTBOUND        1
185 #define   NAT_ENCAPIN         2
186 #define   NAT_ENCAPOUT        3
187 #define   NAT_DIVERTIN        4
188 #define   NAT_DIVERTOUT       5
189 
190 /*
191  * Definitions for nat_flags
192  */
193 #define   NAT_TCP             0x0001    /* IPN_TCP */
194 #define   NAT_UDP             0x0002    /* IPN_UDP */
195 #define   NAT_ICMPERR         0x0004    /* IPN_ICMPERR */
196 #define   NAT_ICMPQUERY       0x0008    /* IPN_ICMPQUERY */
197 #define   NAT_SEARCH          0x0010
198 #define   NAT_SLAVE 0x0020    /* Slave connection for a proxy */
199 #define   NAT_NOTRULEPORT     0x0040    /* Don't use the port # in the NAT rule */
200 
201 #define   NAT_TCPUDP          (NAT_TCP|NAT_UDP)
202 #define   NAT_TCPUDPICMP      (NAT_TCP|NAT_UDP|NAT_ICMPERR)
203 #define   NAT_TCPUDPICMPQ     (NAT_TCP|NAT_UDP|NAT_ICMPQUERY)
204 #define   NAT_FROMRULE        (NAT_TCP|NAT_UDP)
205 
206 /* 0x0100 reserved for FI_W_SPORT */
207 /* 0x0200 reserved for FI_W_DPORT */
208 /* 0x0400 reserved for FI_W_SADDR */
209 /* 0x0800 reserved for FI_W_DADDR */
210 /* 0x1000 reserved for FI_W_NEWFR */
211 /* 0x2000 reserved for SI_CLONE */
212 /* 0x4000 reserved for SI_CLONED */
213 /* 0x8000 reserved for SI_IGNOREPKT */
214 
215 #define   NAT_DEBUG 0x800000
216 
217 typedef   struct nat_addr_s {
218           i6addr_t  na_addr[2];
219           i6addr_t  na_nextaddr;
220           int                 na_atype;
221           int                 na_function;
222 } nat_addr_t;
223 
224 #define   na_nextip na_nextaddr.in4.s_addr
225 #define   na_nextip6          na_nextaddr.in6
226 #define   na_num              na_addr[0].iplookupnum
227 #define   na_type             na_addr[0].iplookuptype
228 #define   na_subtype          na_addr[0].iplookupsubtype
229 #define   na_ptr              na_addr[1].iplookupptr
230 #define   na_func             na_addr[1].iplookupfunc
231 
232 
233 /*
234  * This structure represents an actual NAT rule, loaded by ipnat.
235  */
236 typedef   struct    ipnat     {
237           ipfmutex_t          in_lock;
238           struct    ipnat     *in_next;           /* NAT rule list next */
239           struct    ipnat     **in_pnext;                   /* prior rdr next ptr */
240           struct    ipnat     *in_rnext;                    /* rdr rule hash next */
241           struct    ipnat     **in_prnext;                  /* prior rdr next ptr */
242           struct    ipnat     *in_mnext;                    /* map rule hash next */
243           struct    ipnat     **in_pmnext;                  /* prior map next ptr */
244           struct    ipftq     *in_tqehead[2];
245           void                *in_ifps[2];
246           void                *in_apr;
247           char                *in_comment;
248           mb_t                *in_divmp;
249           void                *in_pconf;
250           U_QUAD_T  in_pkts[2];
251           U_QUAD_T  in_bytes[2];
252           u_long              in_space;
253           u_long              in_hits;
254           int                 in_size;
255           int                 in_use;
256           u_int               in_hv[2];
257           int                 in_flineno;                   /* conf. file line number */
258           int                 in_stepnext;
259           int                 in_dlocal;
260           u_short             in_dpnext;
261           u_short             in_spnext;
262           /* From here to the end is covered by IPN_CMPSIZ */
263           u_char              in_v[2];            /* 0 = old, 1 = new */
264           u_32_t              in_flags;
265           u_32_t              in_mssclamp;                  /* if != 0 clamp MSS to this */
266           u_int               in_age[2];
267           int                 in_redir;           /* see below for values */
268           int                 in_pr[2];           /* protocol. */
269           nat_addr_t          in_ndst;
270           nat_addr_t          in_nsrc;
271           nat_addr_t          in_osrc;
272           nat_addr_t          in_odst;
273           frtuc_t             in_tuc;
274           u_short             in_ppip;            /* ports per IP. */
275           u_short             in_ippip;           /* IP #'s per IP# */
276           u_short             in_ndports[2];
277           u_short             in_nsports[2];
278           int                 in_ifnames[2];
279           int                 in_plabel;          /* proxy label. */
280           int                 in_pconfig;         /* proxy label. */
281           ipftag_t  in_tag;
282           int                 in_namelen;
283           char                in_names[1];
284 } ipnat_t;
285 
286 /*
287  *      MAP-IN MAP-OUT RDR-IN RDR-OUT
288  * osrc    X   == src  == src    X
289  * odst    X   == dst  == dst    X
290  * nsrc == dst   X       X    == dst
291  * ndst == src   X       X    == src
292  */
293 #define   in_dpmin  in_ndports[0]       /* Also holds static redir port */
294 #define   in_dpmax  in_ndports[1]
295 #define   in_spmin  in_nsports[0]       /* Also holds static redir port */
296 #define   in_spmax  in_nsports[1]
297 #define   in_ndport in_ndports[0]
298 #define   in_nsport in_nsports[0]
299 #define   in_dipnext          in_ndst.na_nextaddr.in4
300 #define   in_dipnext6         in_ndst.na_nextaddr
301 #define   in_dnip             in_ndst.na_nextaddr.in4.s_addr
302 #define   in_dnip6  in_ndst.na_nextaddr
303 #define   in_sipnext          in_nsrc.na_nextaddr.in4
304 #define   in_snip             in_nsrc.na_nextaddr.in4.s_addr
305 #define   in_snip6  in_nsrc.na_nextaddr
306 #define   in_odstip in_odst.na_addr[0].in4
307 #define   in_odstip6          in_odst.na_addr[0]
308 #define   in_odstaddr         in_odst.na_addr[0].in4.s_addr
309 #define   in_odstmsk          in_odst.na_addr[1].in4.s_addr
310 #define   in_odstmsk6         in_odst.na_addr[1]
311 #define   in_odstatype        in_odst.na_atype
312 #define   in_osrcip in_osrc.na_addr[0].in4
313 #define   in_osrcip6          in_osrc.na_addr[0]
314 #define   in_osrcaddr         in_osrc.na_addr[0].in4.s_addr
315 #define   in_osrcmsk          in_osrc.na_addr[1].in4.s_addr
316 #define   in_osrcmsk6         in_osrc.na_addr[1]
317 #define   in_osrcatype        in_osrc.na_atype
318 #define   in_ndstip in_ndst.na_addr[0].in4
319 #define   in_ndstip6          in_ndst.na_addr[0]
320 #define   in_ndstaddr         in_ndst.na_addr[0].in4.s_addr
321 #define   in_ndstmsk          in_ndst.na_addr[1].in4.s_addr
322 #define   in_ndstmsk6         in_ndst.na_addr[1]
323 #define   in_ndstatype        in_ndst.na_atype
324 #define   in_ndstafunc        in_ndst.na_function
325 #define   in_nsrcip in_nsrc.na_addr[0].in4
326 #define   in_nsrcip6          in_nsrc.na_addr[0]
327 #define   in_nsrcaddr         in_nsrc.na_addr[0].in4.s_addr
328 #define   in_nsrcmsk          in_nsrc.na_addr[1].in4.s_addr
329 #define   in_nsrcmsk6         in_nsrc.na_addr[1]
330 #define   in_nsrcatype        in_nsrc.na_atype
331 #define   in_nsrcafunc        in_nsrc.na_function
332 #define   in_scmp             in_tuc.ftu_scmp
333 #define   in_dcmp             in_tuc.ftu_dcmp
334 #define   in_stop             in_tuc.ftu_stop
335 #define   in_dtop             in_tuc.ftu_dtop
336 #define   in_osport in_tuc.ftu_sport
337 #define   in_odport in_tuc.ftu_dport
338 #define   in_ndstnum          in_ndst.na_addr[0].iplookupnum
339 #define   in_ndsttype         in_ndst.na_addr[0].iplookuptype
340 #define   in_ndstptr          in_ndst.na_addr[1].iplookupptr
341 #define   in_ndstfunc         in_ndst.na_addr[1].iplookupfunc
342 #define   in_nsrcnum          in_nsrc.na_addr[0].iplookupnum
343 #define   in_nsrctype         in_nsrc.na_addr[0].iplookuptype
344 #define   in_nsrcptr          in_nsrc.na_addr[1].iplookupptr
345 #define   in_nsrcfunc         in_nsrc.na_addr[1].iplookupfunc
346 #define   in_odstnum          in_odst.na_addr[0].iplookupnum
347 #define   in_odsttype         in_odst.na_addr[0].iplookuptype
348 #define   in_odstptr          in_odst.na_addr[1].iplookupptr
349 #define   in_odstfunc         in_odst.na_addr[1].iplookupfunc
350 #define   in_osrcnum          in_osrc.na_addr[0].iplookupnum
351 #define   in_osrctype         in_osrc.na_addr[0].iplookuptype
352 #define   in_osrcptr          in_osrc.na_addr[1].iplookupptr
353 #define   in_osrcfunc         in_osrc.na_addr[1].iplookupfunc
354 #define   in_icmpidmin        in_nsports[0]
355 #define   in_icmpidmax        in_nsports[1]
356 
357 /*
358  * Bit definitions for in_flags
359  */
360 #define   IPN_ANY             0x00000
361 #define   IPN_TCP             0x00001
362 #define   IPN_UDP             0x00002
363 #define   IPN_TCPUDP          (IPN_TCP|IPN_UDP)
364 #define   IPN_ICMPERR         0x00004
365 #define   IPN_TCPUDPICMP      (IPN_TCP|IPN_UDP|IPN_ICMPERR)
366 #define   IPN_ICMPQUERY       0x00008
367 #define   IPN_TCPUDPICMPQ     (IPN_TCP|IPN_UDP|IPN_ICMPQUERY)
368 #define   IPN_RF              (IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR)
369 #define   IPN_AUTOPORTMAP     0x00010
370 #define   IPN_FILTER          0x00020
371 #define   IPN_SPLIT 0x00040
372 #define   IPN_ROUNDR          0x00080
373 #define   IPN_SIPRANGE        0x00100
374 #define   IPN_DIPRANGE        0x00200
375 #define   IPN_NOTSRC          0x00400
376 #define   IPN_NOTDST          0x00800
377 #define   IPN_NO              0x01000
378 #define   IPN_DYNSRCIP        0x02000   /* dynamic src IP# */
379 #define   IPN_DYNDSTIP        0x04000   /* dynamic dst IP# */
380 #define   IPN_DELETE          0x08000
381 #define   IPN_STICKY          0x10000
382 #define   IPN_FRAG  0x20000
383 #define   IPN_FIXEDSPORT      0x40000
384 #define   IPN_FIXEDDPORT      0x80000
385 #define   IPN_FINDFORWARD     0x100000
386 #define   IPN_IN              0x200000
387 #define   IPN_SEQUENTIAL      0x400000
388 #define   IPN_PURGE 0x800000
389 #define   IPN_PROXYRULE       0x1000000
390 #define   IPN_USERFLAGS       (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_SIPRANGE|IPN_SPLIT|\
391                                IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST|IPN_NO|\
392                                IPN_FRAG|IPN_STICKY|IPN_FIXEDDPORT|IPN_ICMPQUERY|\
393                                IPN_DIPRANGE|IPN_SEQUENTIAL|IPN_PURGE)
394 
395 /*
396  * Values for in_redir
397  */
398 #define   NAT_MAP             0x01
399 #define   NAT_REDIRECT        0x02
400 #define   NAT_BIMAP (NAT_MAP|NAT_REDIRECT)
401 #define   NAT_MAPBLK          0x04
402 #define   NAT_REWRITE         0x08
403 #define   NAT_ENCAP 0x10
404 #define   NAT_DIVERTUDP       0x20
405 
406 #define   MAPBLK_MINPORT      1024      /* don't use reserved ports for src port */
407 #define   USABLE_PORTS        (65536 - MAPBLK_MINPORT)
408 
409 #define   IPN_CMPSIZ          (sizeof(ipnat_t) - offsetof(ipnat_t, in_v))
410 
411 typedef   struct    natlookup {
412           i6addr_t  nl_inipaddr;
413           i6addr_t  nl_outipaddr;
414           i6addr_t  nl_realipaddr;
415           int                 nl_v;
416           int                 nl_flags;
417           u_short             nl_inport;
418           u_short             nl_outport;
419           u_short             nl_realport;
420 } natlookup_t;
421 
422 #define   nl_inip             nl_inipaddr.in4
423 #define   nl_outip  nl_outipaddr.in4
424 #define   nl_realip nl_realipaddr.in4
425 #define   nl_inip6  nl_inipaddr.in6
426 #define   nl_outip6 nl_outipaddr.in6
427 #define   nl_realip6          nl_realipaddr.in6
428 
429 
430 typedef struct  nat_save    {
431           void      *ipn_next;
432           struct    nat       ipn_nat;
433           struct    ipnat     ipn_ipnat;
434           struct    frentry ipn_fr;
435           int       ipn_dsize;
436           char      ipn_data[4];
437 } nat_save_t;
438 
439 #define   ipn_rule  ipn_nat.nat_fr
440 
441 typedef   struct    natget    {
442           void      *ng_ptr;
443           int       ng_sz;
444 } natget_t;
445 
446 
447 /*
448  * This structure gets used to help NAT sessions keep the same NAT rule (and
449  * thus translation for IP address) when:
450  * (a) round-robin redirects are in use
451  * (b) different IP add
452  */
453 typedef   struct    hostmap   {
454           struct    hostmap   *hm_hnext;
455           struct    hostmap   **hm_phnext;
456           struct    hostmap   *hm_next;
457           struct    hostmap   **hm_pnext;
458           struct    ipnat     *hm_ipnat;
459           i6addr_t  hm_osrcip6;
460           i6addr_t  hm_odstip6;
461           i6addr_t  hm_nsrcip6;
462           i6addr_t  hm_ndstip6;
463           u_32_t              hm_port;
464           int                 hm_ref;
465           int                 hm_hv;
466           int                 hm_v;
467 } hostmap_t;
468 
469 #define   hm_osrcip hm_osrcip6.in4
470 #define   hm_odstip hm_odstip6.in4
471 #define   hm_nsrcip hm_nsrcip6.in4
472 #define   hm_ndstip hm_ndstip6.in4
473 #define   hm_osrc6  hm_osrcip6.in6
474 #define   hm_odst6  hm_odstip6.in6
475 #define   hm_nsrc6  hm_nsrcip6.in6
476 #define   hm_ndst6  hm_ndstip6.in6
477 
478 
479 /*
480  * Structure used to pass information in to nat_newmap and nat_newrdr.
481  */
482 typedef struct      natinfo   {
483           ipnat_t             *nai_np;
484           u_32_t              nai_sum1;
485           u_32_t              nai_sum2;
486           struct    in_addr   nai_ip;             /* In host byte order */
487           u_short             nai_port;
488           u_short             nai_nport;
489           u_short             nai_sport;
490           u_short             nai_dport;
491 } natinfo_t;
492 
493 
494 typedef   struct nat_stat_side {
495           u_int     *ns_bucketlen;
496           nat_t     **ns_table;
497           u_long    ns_added;
498           u_long    ns_appr_fail;
499           u_long    ns_badnat;
500           u_long    ns_badnatnew;
501           u_long    ns_badnextaddr;
502           u_long    ns_bucket_max;
503           u_long    ns_clone_nomem;
504           u_long    ns_decap_bad;
505           u_long    ns_decap_fail;
506           u_long    ns_decap_pullup;
507           u_long    ns_divert_dup;
508           u_long    ns_divert_exist;
509           u_long    ns_drop;
510           u_long    ns_encap_dup;
511           u_long    ns_encap_pullup;
512           u_long    ns_exhausted;
513           u_long    ns_icmp_address;
514           u_long    ns_icmp_basic;
515           u_long    ns_icmp_mbuf;
516           u_long    ns_icmp_notfound;
517           u_long    ns_icmp_rebuild;
518           u_long    ns_icmp_short;
519           u_long    ns_icmp_size;
520           u_long    ns_ifpaddrfail;
521           u_long    ns_ignored;
522           u_long    ns_insert_fail;
523           u_long    ns_inuse;
524           u_long    ns_log;
525           u_long    ns_lookup_miss;
526           u_long    ns_lookup_nowild;
527           u_long    ns_new_ifpaddr;
528           u_long    ns_memfail;
529           u_long    ns_table_max;
530           u_long    ns_translated;
531           u_long    ns_unfinalised;
532           u_long    ns_wrap;
533           u_long    ns_xlate_null;
534           u_long    ns_xlate_exists;
535           u_long    ns_ipf_proxy_fail;
536           u_long    ns_uncreate[2];
537 } nat_stat_side_t;
538 
539 
540 typedef   struct    natstat   {
541           nat_t               *ns_instances;
542           ipnat_t             *ns_list;
543           hostmap_t *ns_maplist;
544           hostmap_t **ns_maptable;
545           u_int               ns_active;
546           u_long              ns_addtrpnt;
547           u_long              ns_divert_build;
548           u_long              ns_expire;
549           u_long              ns_flush_all;
550           u_long              ns_flush_closing;
551           u_long              ns_flush_queue;
552           u_long              ns_flush_state;
553           u_long              ns_flush_timeout;
554           u_long              ns_hm_new;
555           u_long              ns_hm_newfail;
556           u_long              ns_hm_addref;
557           u_long              ns_hm_nullnp;
558           u_long              ns_log_ok;
559           u_long              ns_log_fail;
560           u_int               ns_hostmap_sz;
561           u_int               ns_nattab_sz;
562           u_int               ns_nattab_max;
563           u_int               ns_orphans;
564           u_int               ns_rules;
565           u_int               ns_rules_map;
566           u_int               ns_rules_rdr;
567           u_int               ns_rultab_sz;
568           u_int               ns_rdrtab_sz;
569           u_32_t              ns_ticks;
570           u_int               ns_trpntab_sz;
571           u_int               ns_wilds;
572           u_long              ns_proto[256];
573           nat_stat_side_t     ns_side[2];
574           nat_stat_side_t     ns_side6[2];
575 } natstat_t;
576 
577 typedef   struct    natlog {
578           i6addr_t  nl_osrcip;
579           i6addr_t  nl_odstip;
580           i6addr_t  nl_nsrcip;
581           i6addr_t  nl_ndstip;
582           u_short             nl_osrcport;
583           u_short             nl_odstport;
584           u_short             nl_nsrcport;
585           u_short             nl_ndstport;
586           int                 nl_action;
587           int                 nl_type;
588           int                 nl_rule;
589           U_QUAD_T  nl_pkts[2];
590           U_QUAD_T  nl_bytes[2];
591           u_char              nl_p[2];
592           u_char              nl_v[2];
593           u_char              nl_ifnames[2][LIFNAMSIZ];
594 } natlog_t;
595 
596 
597 #define   NL_NEW              0
598 #define   NL_CLONE  1
599 #define   NL_PURGE  0xfffc
600 #define   NL_DESTROY          0xfffd
601 #define   NL_FLUSH  0xfffe
602 #define   NL_EXPIRE 0xffff
603 
604 #define   NAT_HASH_FN(_k,_l,_m)         (((_k) + ((_k) >> 12) + _l) % (_m))
605 #define   NAT_HASH_FN6(_k,_l,_m)        ((((u_32_t *)(_k))[3] \
606                                          + (((u_32_t *)(_k))[3] >> 12) \
607                                          + (((u_32_t *)(_k))[2]) \
608                                          + (((u_32_t *)(_k))[2] >> 12) \
609                                          + (((u_32_t *)(_k))[1]) \
610                                          + (((u_32_t *)(_k))[1] >> 12) \
611                                          + (((u_32_t *)(_k))[0]) \
612                                          + (((u_32_t *)(_k))[0] >> 12) \
613                                          + _l) % (_m))
614 
615 #define   LONG_SUM(_i)        (((_i) & 0xffff) + ((_i) >> 16))
616 #define   LONG_SUM6(_i)       (LONG_SUM(ntohl(((u_32_t *)(_i))[0])) + \
617                                LONG_SUM(ntohl(((u_32_t *)(_i))[1])) + \
618                                LONG_SUM(ntohl(((u_32_t *)(_i))[2])) + \
619                                LONG_SUM(ntohl(((u_32_t *)(_i))[3])))
620 
621 #define   CALC_SUMD(s1, s2, sd) { \
622                                   (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
623                                   (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
624                                   /* Do it twice */ \
625                                   (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
626                                   (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
627                                   /* Because ~1 == -2, We really need ~1 == -1 */ \
628                                   if ((s1) > (s2)) (s2)--; \
629                                   (sd) = (s2) - (s1); \
630                                   (sd) = ((sd) & 0xffff) + ((sd) >> 16); }
631 
632 #define   NAT_SYSSPACE                  0x80000000
633 #define   NAT_LOCKHELD                  0x40000000
634 
635 /*
636  * This is present in ip_nat.h because it needs to be shared between
637  * ip_nat.c and ip_nat6.c
638  */
639 typedef struct ipf_nat_softc_s {
640           ipfmutex_t          ipf_nat_new;
641           ipfmutex_t          ipf_nat_io;
642           int                 ipf_nat_doflush;
643           int                 ipf_nat_logging;
644           int                 ipf_nat_lock;
645           int                 ipf_nat_inited;
646           int                 ipf_nat_table_wm_high;
647           int                 ipf_nat_table_wm_low;
648           u_int               ipf_nat_table_max;
649           u_int               ipf_nat_table_sz;
650           u_int               ipf_nat_maprules_sz;
651           u_int               ipf_nat_rdrrules_sz;
652           u_int               ipf_nat_hostmap_sz;
653           u_int               ipf_nat_maxbucket;
654           u_int               ipf_nat_last_force_flush;
655           u_int               ipf_nat_defage;
656           u_int               ipf_nat_defipage;
657           u_int               ipf_nat_deficmpage;
658           ipf_v4_masktab_t    ipf_nat_map_mask;
659           ipf_v6_masktab_t    ipf_nat6_map_mask;
660           ipf_v4_masktab_t    ipf_nat_rdr_mask;
661           ipf_v6_masktab_t    ipf_nat6_rdr_mask;
662           nat_t               **ipf_nat_table[2];
663           nat_t               *ipf_nat_instances;
664           ipnat_t             *ipf_nat_list;
665           ipnat_t             **ipf_nat_list_tail;
666           ipnat_t             **ipf_nat_map_rules;
667           ipnat_t             **ipf_nat_rdr_rules;
668           ipftq_t             *ipf_nat_utqe;
669           hostmap_t **ipf_hm_maptable ;
670           hostmap_t *ipf_hm_maplist ;
671           ipftuneable_t       *ipf_nat_tune;
672           ipftq_t             ipf_nat_udptq;
673           ipftq_t             ipf_nat_udpacktq;
674           ipftq_t             ipf_nat_icmptq;
675           ipftq_t             ipf_nat_icmpacktq;
676           ipftq_t             ipf_nat_iptq;
677           ipftq_t             ipf_nat_pending;
678           ipftq_t             ipf_nat_tcptq[IPF_TCP_NSTATES];
679           natstat_t ipf_nat_stats;
680 } ipf_nat_softc_t ;
681 
682 #define   ipf_nat_map_max                         ipf_nat_map_mask.imt4_max
683 #define   ipf_nat_rdr_max                         ipf_nat_rdr_mask.imt4_max
684 #define   ipf_nat6_map_max              ipf_nat6_map_mask.imt6_max
685 #define   ipf_nat6_rdr_max              ipf_nat6_rdr_mask.imt6_max
686 #define   ipf_nat_map_active_masks      ipf_nat_map_mask.imt4_active
687 #define   ipf_nat_rdr_active_masks      ipf_nat_rdr_mask.imt4_active
688 #define   ipf_nat6_map_active_masks     ipf_nat6_map_mask.imt6_active
689 #define   ipf_nat6_rdr_active_masks     ipf_nat6_rdr_mask.imt6_active
690 
691 extern    frentry_t           ipfnatblock;
692 
693 extern    void      ipf_fix_datacksum(u_short *, u_32_t);
694 extern    void      ipf_fix_incksum(int, u_short *, u_32_t, u_32_t);
695 extern    void      ipf_fix_outcksum(int, u_short *, u_32_t, u_32_t);
696 
697 extern    int       ipf_nat_checkin(fr_info_t *, u_32_t *);
698 extern    int       ipf_nat_checkout(fr_info_t *, u_32_t *);
699 extern    void      ipf_nat_delete(ipf_main_softc_t *, struct nat *, int);
700 extern    void      ipf_nat_deref(ipf_main_softc_t *, nat_t **);
701 extern    void      ipf_nat_expire(ipf_main_softc_t *);
702 extern    int       ipf_nat_hashtab_add(ipf_main_softc_t *,
703                                                    ipf_nat_softc_t *, nat_t *);
704 extern    void      ipf_nat_hostmapdel(ipf_main_softc_t *, hostmap_t **);
705 extern    int       ipf_nat_hostmap_rehash(ipf_main_softc_t *,
706                                                       ipftuneable_t *, ipftuneval_t *);
707 extern    nat_t     *ipf_nat_icmperrorlookup(fr_info_t *, int);
708 extern    nat_t     *ipf_nat_icmperror(fr_info_t *, u_int *, int);
709 #if defined(__OpenBSD__)
710 extern    void      ipf_nat_ifdetach(void *);
711 #endif
712 extern    int       ipf_nat_init(void);
713 extern    nat_t     *ipf_nat_inlookup(fr_info_t *, u_int, u_int,
714                                               struct in_addr, struct in_addr);
715 extern    int       ipf_nat_in(fr_info_t *, nat_t *, int, u_32_t);
716 extern    int       ipf_nat_insert(ipf_main_softc_t *, ipf_nat_softc_t *,
717                                             nat_t *);
718 extern    int       ipf_nat_ioctl(ipf_main_softc_t *, void *, ioctlcmd_t,
719                                            int, int, void *);
720 extern    void      ipf_nat_log(ipf_main_softc_t *, ipf_nat_softc_t *,
721                                          struct nat *, u_int);
722 extern    nat_t     *ipf_nat_lookupredir(ipf_main_softc_t *, natlookup_t *);
723 extern    nat_t     *ipf_nat_maplookup(void *, u_int, struct in_addr,
724                                         struct in_addr);
725 extern    nat_t     *ipf_nat_add(fr_info_t *, ipnat_t *, nat_t **,
726                                          u_int, int);
727 extern    int       ipf_nat_out(fr_info_t *, nat_t *, int, u_32_t);
728 extern    nat_t     *ipf_nat_outlookup(fr_info_t *, u_int, u_int,
729                                                struct in_addr, struct in_addr);
730 extern    u_short   *ipf_nat_proto(fr_info_t *, nat_t *, u_int);
731 extern    void      ipf_nat_rule_deref(ipf_main_softc_t *, ipnat_t **);
732 extern    void      ipf_nat_setqueue(ipf_main_softc_t *, ipf_nat_softc_t *,
733                                               nat_t *);
734 extern    void      ipf_nat_setpending(ipf_main_softc_t *, nat_t *);
735 extern    nat_t     *ipf_nat_tnlookup(fr_info_t *, int);
736 extern    void      ipf_nat_update(fr_info_t *, nat_t *);
737 extern    frentry_t *ipf_nat_ipfin(fr_info_t *, u_32_t *);
738 extern    frentry_t *ipf_nat_ipfout(fr_info_t *, u_32_t *);
739 extern    int       ipf_nat_in(fr_info_t *, nat_t *, int, u_32_t);
740 extern    int       ipf_nat_out(fr_info_t *, nat_t *, int, u_32_t);
741 extern    int       ipf_nat_rehash(ipf_main_softc_t *, ipftuneable_t *,
742                                             ipftuneval_t *);
743 extern    int       ipf_nat_rehash_rules(ipf_main_softc_t *, ipftuneable_t *,
744                                                     ipftuneval_t *);
745 extern    int       ipf_nat_settimeout(struct ipf_main_softc_s *,
746                                                   ipftuneable_t *, ipftuneval_t *);
747 extern    void      ipf_nat_sync(ipf_main_softc_t *, void *);
748 
749 extern    nat_t     *ipf_nat_clone(fr_info_t *, nat_t *);
750 extern    void      ipf_nat_delmap(ipf_nat_softc_t *, ipnat_t *);
751 extern    void      ipf_nat_delrdr(ipf_nat_softc_t *, ipnat_t *);
752 extern    int       ipf_nat_wildok(nat_t *, int, int, int, int);
753 extern    void      ipf_nat_setlock(void *, int);
754 extern    void      ipf_nat_load(void);
755 extern    void      *ipf_nat_soft_create(ipf_main_softc_t *);
756 extern    int       ipf_nat_soft_init(ipf_main_softc_t *, void *);
757 extern    void      ipf_nat_soft_destroy(ipf_main_softc_t *, void *);
758 extern    int       ipf_nat_soft_fini(ipf_main_softc_t *, void *);
759 extern    int       ipf_nat_main_load(void);
760 extern    int       ipf_nat_main_unload(void);
761 extern    ipftq_t   *ipf_nat_add_tq(ipf_main_softc_t *, int);
762 extern    void      ipf_nat_uncreate(fr_info_t *);
763 
764 #ifdef USE_INET6
765 extern    nat_t     *ipf_nat6_add(fr_info_t *, ipnat_t *, nat_t **,
766                                            u_int, int);
767 extern    void      ipf_nat6_addrdr(ipf_nat_softc_t *, ipnat_t *);
768 extern    void      ipf_nat6_addmap(ipf_nat_softc_t *, ipnat_t *);
769 extern    int       ipf_nat6_checkout(fr_info_t *, u_32_t *);
770 extern    int       ipf_nat6_checkin(fr_info_t *, u_32_t *);
771 extern    void      ipf_nat6_delmap(ipf_nat_softc_t *, ipnat_t *);
772 extern    void      ipf_nat6_delrdr(ipf_nat_softc_t *, ipnat_t *);
773 extern    int       ipf_nat6_finalise(fr_info_t *, nat_t *);
774 extern    nat_t     *ipf_nat6_icmperror(fr_info_t *, u_int *, int);
775 extern    nat_t     *ipf_nat6_icmperrorlookup(fr_info_t *, int);
776 extern    nat_t     *ipf_nat6_inlookup(fr_info_t *, u_int, u_int,
777                                                   struct in6_addr *, struct in6_addr *);
778 extern    u_32_t    ipf_nat6_ip6subtract(i6addr_t *, i6addr_t *);
779 extern    frentry_t *ipf_nat6_ipfin(fr_info_t *, u_32_t *);
780 extern    frentry_t *ipf_nat6_ipfout(fr_info_t *, u_32_t *);
781 extern    nat_t     *ipf_nat6_lookupredir(ipf_main_softc_t *, natlookup_t *);
782 extern    int       ipf_nat6_newmap(fr_info_t *, nat_t *, natinfo_t *);
783 extern    int       ipf_nat6_newrdr(fr_info_t *, nat_t *, natinfo_t *);
784 extern    nat_t     *ipf_nat6_outlookup(fr_info_t *, u_int, u_int,
785                                                    struct in6_addr *, struct in6_addr *);
786 extern    int       ipf_nat6_newrewrite(fr_info_t *, nat_t *, natinfo_t *);
787 extern    int       ipf_nat6_newdivert(fr_info_t *, nat_t *, natinfo_t *);
788 extern    int       ipf_nat6_ruleaddrinit(ipf_main_softc_t *, ipf_nat_softc_t *, ipnat_t *);
789 
790 #endif
791 
792 
793 #endif /* __IP_NAT_H__ */
794