| 1 | /* $NetBSD: ip_nat.h,v 1.7 2015/08/07 17:31:12 prlw1 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 *; |
| 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 | #ifdef USE_INET6 |
| 575 | nat_stat_side_t ns_side6[2]; |
| 576 | #endif |
| 577 | } natstat_t; |
| 578 | |
| 579 | typedef struct natlog { |
| 580 | i6addr_t nl_osrcip; |
| 581 | i6addr_t nl_odstip; |
| 582 | i6addr_t nl_nsrcip; |
| 583 | i6addr_t nl_ndstip; |
| 584 | u_short nl_osrcport; |
| 585 | u_short nl_odstport; |
| 586 | u_short nl_nsrcport; |
| 587 | u_short nl_ndstport; |
| 588 | int nl_action; |
| 589 | int nl_type; |
| 590 | int nl_rule; |
| 591 | U_QUAD_T nl_pkts[2]; |
| 592 | U_QUAD_T nl_bytes[2]; |
| 593 | u_char nl_p[2]; |
| 594 | u_char nl_v[2]; |
| 595 | u_char nl_ifnames[2][LIFNAMSIZ]; |
| 596 | } natlog_t; |
| 597 | |
| 598 | |
| 599 | #define NL_NEW 0 |
| 600 | #define NL_CLONE 1 |
| 601 | #define NL_PURGE 0xfffc |
| 602 | #define NL_DESTROY 0xfffd |
| 603 | #define NL_FLUSH 0xfffe |
| 604 | #define NL_EXPIRE 0xffff |
| 605 | |
| 606 | #define NAT_HASH_FN(_k,_l,_m) (((_k) + ((_k) >> 12) + _l) % (_m)) |
| 607 | #define NAT_HASH_FN6(_k,_l,_m) ((((u_32_t *)(_k))[3] \ |
| 608 | + (((u_32_t *)(_k))[3] >> 12) \ |
| 609 | + (((u_32_t *)(_k))[2]) \ |
| 610 | + (((u_32_t *)(_k))[2] >> 12) \ |
| 611 | + (((u_32_t *)(_k))[1]) \ |
| 612 | + (((u_32_t *)(_k))[1] >> 12) \ |
| 613 | + (((u_32_t *)(_k))[0]) \ |
| 614 | + (((u_32_t *)(_k))[0] >> 12) \ |
| 615 | + _l) % (_m)) |
| 616 | |
| 617 | #define LONG_SUM(_i) (((_i) & 0xffff) + ((_i) >> 16)) |
| 618 | #define LONG_SUM6(_i) (LONG_SUM(ntohl(((u_32_t *)(_i))[0])) + \ |
| 619 | LONG_SUM(ntohl(((u_32_t *)(_i))[1])) + \ |
| 620 | LONG_SUM(ntohl(((u_32_t *)(_i))[2])) + \ |
| 621 | LONG_SUM(ntohl(((u_32_t *)(_i))[3]))) |
| 622 | |
| 623 | #define CALC_SUMD(s1, s2, sd) { \ |
| 624 | (s1) = ((s1) & 0xffff) + ((s1) >> 16); \ |
| 625 | (s2) = ((s2) & 0xffff) + ((s2) >> 16); \ |
| 626 | /* Do it twice */ \ |
| 627 | (s1) = ((s1) & 0xffff) + ((s1) >> 16); \ |
| 628 | (s2) = ((s2) & 0xffff) + ((s2) >> 16); \ |
| 629 | /* Because ~1 == -2, We really need ~1 == -1 */ \ |
| 630 | if ((s1) > (s2)) (s2)--; \ |
| 631 | (sd) = (s2) - (s1); \ |
| 632 | (sd) = ((sd) & 0xffff) + ((sd) >> 16); } |
| 633 | |
| 634 | #define NAT_SYSSPACE 0x80000000 |
| 635 | #define NAT_LOCKHELD 0x40000000 |
| 636 | |
| 637 | /* |
| 638 | * This is present in ip_nat.h because it needs to be shared between |
| 639 | * ip_nat.c and ip_nat6.c |
| 640 | */ |
| 641 | typedef struct ipf_nat_softc_s { |
| 642 | ipfmutex_t ipf_nat_new; |
| 643 | ipfmutex_t ipf_nat_io; |
| 644 | int ipf_nat_doflush; |
| 645 | int ipf_nat_logging; |
| 646 | int ipf_nat_lock; |
| 647 | int ipf_nat_inited; |
| 648 | int ipf_nat_table_wm_high; |
| 649 | int ipf_nat_table_wm_low; |
| 650 | u_int ipf_nat_table_max; |
| 651 | u_int ipf_nat_table_sz; |
| 652 | u_int ipf_nat_maprules_sz; |
| 653 | u_int ipf_nat_rdrrules_sz; |
| 654 | u_int ipf_nat_hostmap_sz; |
| 655 | u_int ipf_nat_maxbucket; |
| 656 | u_int ipf_nat_last_force_flush; |
| 657 | u_int ipf_nat_defage; |
| 658 | u_int ipf_nat_defipage; |
| 659 | u_int ipf_nat_deficmpage; |
| 660 | ipf_v4_masktab_t ipf_nat_map_mask; |
| 661 | ipf_v6_masktab_t ipf_nat6_map_mask; |
| 662 | ipf_v4_masktab_t ipf_nat_rdr_mask; |
| 663 | ipf_v6_masktab_t ipf_nat6_rdr_mask; |
| 664 | nat_t **ipf_nat_table[2]; |
| 665 | nat_t *ipf_nat_instances; |
| 666 | ipnat_t *ipf_nat_list; |
| 667 | ipnat_t **ipf_nat_list_tail; |
| 668 | ipnat_t **ipf_nat_map_rules; |
| 669 | ipnat_t **ipf_nat_rdr_rules; |
| 670 | ipftq_t *ipf_nat_utqe; |
| 671 | hostmap_t **ipf_hm_maptable ; |
| 672 | hostmap_t *ipf_hm_maplist ; |
| 673 | ipftuneable_t *ipf_nat_tune; |
| 674 | ipftq_t ipf_nat_udptq; |
| 675 | ipftq_t ipf_nat_udpacktq; |
| 676 | ipftq_t ipf_nat_icmptq; |
| 677 | ipftq_t ipf_nat_icmpacktq; |
| 678 | ipftq_t ipf_nat_iptq; |
| 679 | ipftq_t ipf_nat_pending; |
| 680 | ipftq_t ipf_nat_tcptq[IPF_TCP_NSTATES]; |
| 681 | natstat_t ipf_nat_stats; |
| 682 | } ipf_nat_softc_t ; |
| 683 | |
| 684 | #define ipf_nat_map_max ipf_nat_map_mask.imt4_max |
| 685 | #define ipf_nat_rdr_max ipf_nat_rdr_mask.imt4_max |
| 686 | #define ipf_nat6_map_max ipf_nat6_map_mask.imt6_max |
| 687 | #define ipf_nat6_rdr_max ipf_nat6_rdr_mask.imt6_max |
| 688 | #define ipf_nat_map_active_masks ipf_nat_map_mask.imt4_active |
| 689 | #define ipf_nat_rdr_active_masks ipf_nat_rdr_mask.imt4_active |
| 690 | #define ipf_nat6_map_active_masks ipf_nat6_map_mask.imt6_active |
| 691 | #define ipf_nat6_rdr_active_masks ipf_nat6_rdr_mask.imt6_active |
| 692 | |
| 693 | extern frentry_t ipfnatblock; |
| 694 | |
| 695 | extern void ipf_fix_datacksum(u_short *, u_32_t); |
| 696 | extern void ipf_fix_incksum(int, u_short *, u_32_t, u_32_t); |
| 697 | extern void ipf_fix_outcksum(int, u_short *, u_32_t, u_32_t); |
| 698 | |
| 699 | extern int ipf_nat_checkin(fr_info_t *, u_32_t *); |
| 700 | extern int ipf_nat_checkout(fr_info_t *, u_32_t *); |
| 701 | extern void ipf_nat_delete(ipf_main_softc_t *, struct nat *, int); |
| 702 | extern void ipf_nat_deref(ipf_main_softc_t *, nat_t **); |
| 703 | extern void ipf_nat_expire(ipf_main_softc_t *); |
| 704 | extern int ipf_nat_hashtab_add(ipf_main_softc_t *, |
| 705 | ipf_nat_softc_t *, nat_t *); |
| 706 | extern void ipf_nat_hostmapdel(ipf_main_softc_t *, hostmap_t **); |
| 707 | extern int ipf_nat_hostmap_rehash(ipf_main_softc_t *, |
| 708 | ipftuneable_t *, ipftuneval_t *); |
| 709 | extern nat_t *ipf_nat_icmperrorlookup(fr_info_t *, int); |
| 710 | extern nat_t *ipf_nat_icmperror(fr_info_t *, u_int *, int); |
| 711 | #if defined(__OpenBSD__) |
| 712 | extern void ipf_nat_ifdetach(void *); |
| 713 | #endif |
| 714 | extern int ipf_nat_init(void); |
| 715 | extern nat_t *ipf_nat_inlookup(fr_info_t *, u_int, u_int, |
| 716 | struct in_addr, struct in_addr); |
| 717 | extern int ipf_nat_in(fr_info_t *, nat_t *, int, u_32_t); |
| 718 | extern int ipf_nat_insert(ipf_main_softc_t *, ipf_nat_softc_t *, |
| 719 | nat_t *); |
| 720 | extern int ipf_nat_ioctl(ipf_main_softc_t *, void *, ioctlcmd_t, |
| 721 | int, int, void *); |
| 722 | extern void ipf_nat_log(ipf_main_softc_t *, ipf_nat_softc_t *, |
| 723 | struct nat *, u_int); |
| 724 | extern nat_t *ipf_nat_lookupredir(ipf_main_softc_t *, natlookup_t *); |
| 725 | extern nat_t *ipf_nat_maplookup(void *, u_int, struct in_addr, |
| 726 | struct in_addr); |
| 727 | extern nat_t *ipf_nat_add(fr_info_t *, ipnat_t *, nat_t **, |
| 728 | u_int, int); |
| 729 | extern int ipf_nat_out(fr_info_t *, nat_t *, int, u_32_t); |
| 730 | extern nat_t *ipf_nat_outlookup(fr_info_t *, u_int, u_int, |
| 731 | struct in_addr, struct in_addr); |
| 732 | extern u_short *ipf_nat_proto(fr_info_t *, nat_t *, u_int); |
| 733 | extern void ipf_nat_rule_deref(ipf_main_softc_t *, ipnat_t **); |
| 734 | extern void ipf_nat_setqueue(ipf_main_softc_t *, ipf_nat_softc_t *, |
| 735 | nat_t *); |
| 736 | extern void ipf_nat_setpending(ipf_main_softc_t *, nat_t *); |
| 737 | extern nat_t *ipf_nat_tnlookup(fr_info_t *, int); |
| 738 | extern void ipf_nat_update(fr_info_t *, nat_t *); |
| 739 | extern frentry_t *ipf_nat_ipfin(fr_info_t *, u_32_t *); |
| 740 | extern frentry_t *ipf_nat_ipfout(fr_info_t *, u_32_t *); |
| 741 | extern int ipf_nat_in(fr_info_t *, nat_t *, int, u_32_t); |
| 742 | extern int ipf_nat_out(fr_info_t *, nat_t *, int, u_32_t); |
| 743 | extern int ipf_nat_rehash(ipf_main_softc_t *, ipftuneable_t *, |
| 744 | ipftuneval_t *); |
| 745 | extern int ipf_nat_rehash_rules(ipf_main_softc_t *, ipftuneable_t *, |
| 746 | ipftuneval_t *); |
| 747 | extern int ipf_nat_settimeout(struct ipf_main_softc_s *, |
| 748 | ipftuneable_t *, ipftuneval_t *); |
| 749 | extern void ipf_nat_sync(ipf_main_softc_t *, void *); |
| 750 | |
| 751 | extern nat_t *ipf_nat_clone(fr_info_t *, nat_t *); |
| 752 | extern void ipf_nat_delmap(ipf_nat_softc_t *, ipnat_t *); |
| 753 | extern void ipf_nat_delrdr(ipf_nat_softc_t *, ipnat_t *); |
| 754 | extern int ipf_nat_wildok(nat_t *, int, int, int, int); |
| 755 | extern void ipf_nat_setlock(void *, int); |
| 756 | extern void ipf_nat_load(void); |
| 757 | extern void *ipf_nat_soft_create(ipf_main_softc_t *); |
| 758 | extern int ipf_nat_soft_init(ipf_main_softc_t *, void *); |
| 759 | extern void ipf_nat_soft_destroy(ipf_main_softc_t *, void *); |
| 760 | extern int ipf_nat_soft_fini(ipf_main_softc_t *, void *); |
| 761 | extern int ipf_nat_main_load(void); |
| 762 | extern int ipf_nat_main_unload(void); |
| 763 | extern ipftq_t *ipf_nat_add_tq(ipf_main_softc_t *, int); |
| 764 | extern void ipf_nat_uncreate(fr_info_t *); |
| 765 | |
| 766 | #ifdef USE_INET6 |
| 767 | extern nat_t *ipf_nat6_add(fr_info_t *, ipnat_t *, nat_t **, |
| 768 | u_int, int); |
| 769 | extern void ipf_nat6_addrdr(ipf_nat_softc_t *, ipnat_t *); |
| 770 | extern void ipf_nat6_addmap(ipf_nat_softc_t *, ipnat_t *); |
| 771 | extern int ipf_nat6_checkout(fr_info_t *, u_32_t *); |
| 772 | extern int ipf_nat6_checkin(fr_info_t *, u_32_t *); |
| 773 | extern void ipf_nat6_delmap(ipf_nat_softc_t *, ipnat_t *); |
| 774 | extern void ipf_nat6_delrdr(ipf_nat_softc_t *, ipnat_t *); |
| 775 | extern int ipf_nat6_finalise(fr_info_t *, nat_t *); |
| 776 | extern nat_t *ipf_nat6_icmperror(fr_info_t *, u_int *, int); |
| 777 | extern nat_t *ipf_nat6_icmperrorlookup(fr_info_t *, int); |
| 778 | extern nat_t *ipf_nat6_inlookup(fr_info_t *, u_int, u_int, |
| 779 | struct in6_addr *, struct in6_addr *); |
| 780 | extern u_32_t ipf_nat6_ip6subtract(i6addr_t *, i6addr_t *); |
| 781 | extern frentry_t *ipf_nat6_ipfin(fr_info_t *, u_32_t *); |
| 782 | extern frentry_t *ipf_nat6_ipfout(fr_info_t *, u_32_t *); |
| 783 | extern nat_t *ipf_nat6_lookupredir(ipf_main_softc_t *, natlookup_t *); |
| 784 | extern int ipf_nat6_newmap(fr_info_t *, nat_t *, natinfo_t *); |
| 785 | extern int ipf_nat6_newrdr(fr_info_t *, nat_t *, natinfo_t *); |
| 786 | extern nat_t *ipf_nat6_outlookup(fr_info_t *, u_int, u_int, |
| 787 | struct in6_addr *, struct in6_addr *); |
| 788 | extern int ipf_nat6_newrewrite(fr_info_t *, nat_t *, natinfo_t *); |
| 789 | extern int ipf_nat6_newdivert(fr_info_t *, nat_t *, natinfo_t *); |
| 790 | extern int ipf_nat6_ruleaddrinit(ipf_main_softc_t *, ipf_nat_softc_t *, ipnat_t *); |
| 791 | |
| 792 | #endif |
| 793 | |
| 794 | |
| 795 | #endif /* __IP_NAT_H__ */ |
| 796 | |