1 /* $FreeBSD: stable/9/sys/contrib/ipfilter/netinet/ip_nat.h 180778 2008-07-24 12:35:05Z darrenr $ */ 2 3 /* 4 * Copyright (C) 1995-2001, 2003 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 * $FreeBSD: stable/9/sys/contrib/ipfilter/netinet/ip_nat.h 180778 2008-07-24 12:35:05Z darrenr $ 10 * Id: ip_nat.h,v 2.90.2.20 2007/09/25 08:27:32 darrenr Exp $ 11 */ 12 13 #ifndef __IP_NAT_H__ 14 #define __IP_NAT_H__ 15 16 #ifndef SOLARIS 17 #define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) 18 #endif 19 20 #if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51) 21 #define SIOCADNAT _IOW('r', 60, struct ipfobj) 22 #define SIOCRMNAT _IOW('r', 61, struct ipfobj) 23 #define SIOCGNATS _IOWR('r', 62, struct ipfobj) 24 #define SIOCGNATL _IOWR('r', 63, struct ipfobj) 25 #else 26 #define SIOCADNAT _IOW(r, 60, struct ipfobj) 27 #define SIOCRMNAT _IOW(r, 61, struct ipfobj) 28 #define SIOCGNATS _IOWR(r, 62, struct ipfobj) 29 #define SIOCGNATL _IOWR(r, 63, struct ipfobj) 30 #endif 31 32 #undef LARGE_NAT /* define this if you're setting up a system to NAT 33 * LARGE numbers of networks/hosts - i.e. in the 34 * hundreds or thousands. In such a case, you should 35 * also change the RDR_SIZE and NAT_SIZE below to more 36 * appropriate sizes. The figures below were used for 37 * a setup with 1000-2000 networks to NAT. 38 */ 39 #ifndef NAT_SIZE 40 # ifdef LARGE_NAT 41 # define NAT_SIZE 2047 42 # else 43 # define NAT_SIZE 127 44 # endif 45 #endif 46 #ifndef RDR_SIZE 47 # ifdef LARGE_NAT 48 # define RDR_SIZE 2047 49 # else 50 # define RDR_SIZE 127 51 # endif 52 #endif 53 #ifndef HOSTMAP_SIZE 54 # ifdef LARGE_NAT 55 # define HOSTMAP_SIZE 8191 56 # else 57 # define HOSTMAP_SIZE 2047 58 # endif 59 #endif 60 #ifndef NAT_TABLE_MAX 61 /* 62 * This is newly introduced and for the sake of "least surprise", the numbers 63 * present aren't what we'd normally use for creating a proper hash table. 64 */ 65 # ifdef LARGE_NAT 66 # define NAT_TABLE_MAX 180000 67 # else 68 # define NAT_TABLE_MAX 30000 69 # endif 70 #endif 71 #ifndef NAT_TABLE_SZ 72 # ifdef LARGE_NAT 73 # define NAT_TABLE_SZ 16383 74 # else 75 # define NAT_TABLE_SZ 2047 76 # endif 77 #endif 78 #ifndef APR_LABELLEN 79 #define APR_LABELLEN 16 80 #endif 81 #define NAT_HW_CKSUM 0x80000000 82 83 #define DEF_NAT_AGE 1200 /* 10 minutes (600 seconds) */ 84 85 struct ipstate; 86 struct ap_session; 87 88 typedef struct nat { 89 ipfmutex_t nat_lock; 90 struct nat *nat_next; 91 struct nat **nat_pnext; 92 struct nat *nat_hnext[2]; 93 struct nat **nat_phnext[2]; 94 struct hostmap *nat_hm; 95 void *nat_data; 96 struct nat **nat_me; 97 struct ipstate *nat_state; 98 struct ap_session *nat_aps; /* proxy session */ 99 frentry_t *nat_fr; /* filter rule ptr if appropriate */ 100 struct ipnat *nat_ptr; /* pointer back to the rule */ 101 void *nat_ifps[2]; 102 void *nat_sync; 103 ipftqent_t nat_tqe; 104 u_32_t nat_flags; 105 u_32_t nat_sumd[2]; /* ip checksum delta for data segment*/ 106 u_32_t nat_ipsumd; /* ip checksum delta for ip header */ 107 u_32_t nat_mssclamp; /* if != zero clamp MSS to this */ 108 i6addr_t nat_inip6; 109 i6addr_t nat_outip6; 110 i6addr_t nat_oip6; /* other ip */ 111 U_QUAD_T nat_pkts[2]; 112 U_QUAD_T nat_bytes[2]; 113 union { 114 udpinfo_t nat_unu; 115 tcpinfo_t nat_unt; 116 icmpinfo_t nat_uni; 117 greinfo_t nat_ugre; 118 } nat_un; 119 u_short nat_oport; /* other port */ 120 u_short nat_use; 121 u_char nat_p; /* protocol for NAT */ 122 int nat_dir; 123 int nat_ref; /* reference count */ 124 int nat_hv[2]; 125 char nat_ifnames[2][LIFNAMSIZ]; 126 int nat_rev; /* 0 = forward, 1 = reverse */ 127 int nat_redir; /* copy of in_redir */ 128 u_32_t nat_seqnext[2]; 129 } nat_t; 130 131 #define nat_inip nat_inip6.in4 132 #define nat_outip nat_outip6.in4 133 #define nat_oip nat_oip6.in4 134 #define nat_age nat_tqe.tqe_die 135 #define nat_inport nat_un.nat_unt.ts_sport 136 #define nat_outport nat_un.nat_unt.ts_dport 137 #define nat_type nat_un.nat_uni.ici_type 138 #define nat_seq nat_un.nat_uni.ici_seq 139 #define nat_id nat_un.nat_uni.ici_id 140 #define nat_tcpstate nat_tqe.tqe_state 141 #define nat_die nat_tqe.tqe_die 142 #define nat_touched nat_tqe.tqe_touched 143 144 /* 145 * Values for nat_dir 146 */ 147 #define NAT_INBOUND 0 148 #define NAT_OUTBOUND 1 149 150 /* 151 * Definitions for nat_flags 152 */ 153 #define NAT_TCP 0x0001 /* IPN_TCP */ 154 #define NAT_UDP 0x0002 /* IPN_UDP */ 155 #define NAT_ICMPERR 0x0004 /* IPN_ICMPERR */ 156 #define NAT_ICMPQUERY 0x0008 /* IPN_ICMPQUERY */ 157 #define NAT_SEARCH 0x0010 158 #define NAT_SLAVE 0x0020 /* Slave connection for a proxy */ 159 #define NAT_NOTRULEPORT 0x0040 /* Don't use the port # in the NAT rule */ 160 161 #define NAT_TCPUDP (NAT_TCP|NAT_UDP) 162 #define NAT_TCPUDPICMP (NAT_TCP|NAT_UDP|NAT_ICMPERR) 163 #define NAT_TCPUDPICMPQ (NAT_TCP|NAT_UDP|NAT_ICMPQUERY) 164 #define NAT_FROMRULE (NAT_TCP|NAT_UDP) 165 166 /* 0x0100 reserved for FI_W_SPORT */ 167 /* 0x0200 reserved for FI_W_DPORT */ 168 /* 0x0400 reserved for FI_W_SADDR */ 169 /* 0x0800 reserved for FI_W_DADDR */ 170 /* 0x1000 reserved for FI_W_NEWFR */ 171 /* 0x2000 reserved for SI_CLONE */ 172 /* 0x4000 reserved for SI_CLONED */ 173 /* 0x8000 reserved for SI_IGNOREPKT */ 174 175 #define NAT_DEBUG 0x800000 176 177 typedef struct ipnat { 178 ipfmutex_t in_lock; 179 struct ipnat *in_next; /* NAT rule list next */ 180 struct ipnat *in_rnext; /* rdr rule hash next */ 181 struct ipnat **in_prnext; /* prior rdr next ptr */ 182 struct ipnat *in_mnext; /* map rule hash next */ 183 struct ipnat **in_pmnext; /* prior map next ptr */ 184 struct ipftq *in_tqehead[2]; 185 void *in_ifps[2]; 186 void *in_apr; 187 char *in_comment; 188 i6addr_t in_next6; 189 u_long in_space; 190 u_long in_hits; 191 u_int in_use; 192 u_int in_hv; 193 int in_flineno; /* conf. file line number */ 194 u_short in_pnext; 195 u_char in_v; 196 u_char in_xxx; 197 /* From here to the end is covered by IPN_CMPSIZ */ 198 u_32_t in_flags; 199 u_32_t in_mssclamp; /* if != 0 clamp MSS to this */ 200 u_int in_age[2]; 201 int in_redir; /* see below for values */ 202 int in_p; /* protocol. */ 203 i6addr_t in_in[2]; 204 i6addr_t in_out[2]; 205 i6addr_t in_src[2]; 206 frtuc_t in_tuc; 207 u_short in_port[2]; 208 u_short in_ppip; /* ports per IP. */ 209 u_short in_ippip; /* IP #'s per IP# */ 210 char in_ifnames[2][LIFNAMSIZ]; 211 char in_plabel[APR_LABELLEN]; /* proxy label. */ 212 ipftag_t in_tag; 213 } ipnat_t; 214 215 #define in_pmin in_port[0] /* Also holds static redir port */ 216 #define in_pmax in_port[1] 217 #define in_nextip in_next6.in4 218 #define in_nip in_next6.in4.s_addr 219 #define in_inip in_in[0].in4.s_addr 220 #define in_inmsk in_in[1].in4.s_addr 221 #define in_outip in_out[0].in4.s_addr 222 #define in_outmsk in_out[1].in4.s_addr 223 #define in_srcip in_src[0].in4.s_addr 224 #define in_srcmsk in_src[1].in4.s_addr 225 #define in_scmp in_tuc.ftu_scmp 226 #define in_dcmp in_tuc.ftu_dcmp 227 #define in_stop in_tuc.ftu_stop 228 #define in_dtop in_tuc.ftu_dtop 229 #define in_sport in_tuc.ftu_sport 230 #define in_dport in_tuc.ftu_dport 231 232 /* 233 * Bit definitions for in_flags 234 */ 235 #define IPN_ANY 0x00000 236 #define IPN_TCP 0x00001 237 #define IPN_UDP 0x00002 238 #define IPN_TCPUDP (IPN_TCP|IPN_UDP) 239 #define IPN_ICMPERR 0x00004 240 #define IPN_TCPUDPICMP (IPN_TCP|IPN_UDP|IPN_ICMPERR) 241 #define IPN_ICMPQUERY 0x00008 242 #define IPN_TCPUDPICMPQ (IPN_TCP|IPN_UDP|IPN_ICMPQUERY) 243 #define IPN_RF (IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR) 244 #define IPN_AUTOPORTMAP 0x00010 245 #define IPN_IPRANGE 0x00020 246 #define IPN_FILTER 0x00040 247 #define IPN_SPLIT 0x00080 248 #define IPN_ROUNDR 0x00100 249 #define IPN_NOTSRC 0x04000 250 #define IPN_NOTDST 0x08000 251 #define IPN_DYNSRCIP 0x10000 /* dynamic src IP# */ 252 #define IPN_DYNDSTIP 0x20000 /* dynamic dst IP# */ 253 #define IPN_DELETE 0x40000 254 #define IPN_STICKY 0x80000 255 #define IPN_FRAG 0x100000 256 #define IPN_FIXEDDPORT 0x200000 257 #define IPN_FINDFORWARD 0x400000 258 #define IPN_IN 0x800000 259 #define IPN_SEQUENTIAL 0x1000000 260 #define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\ 261 IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST|\ 262 IPN_FRAG|IPN_STICKY|IPN_FIXEDDPORT|IPN_ICMPQUERY|\ 263 IPN_SEQUENTIAL) 264 265 /* 266 * Values for in_redir 267 */ 268 #define NAT_MAP 0x01 269 #define NAT_REDIRECT 0x02 270 #define NAT_BIMAP (NAT_MAP|NAT_REDIRECT) 271 #define NAT_MAPBLK 0x04 272 273 #define MAPBLK_MINPORT 1024 /* don't use reserved ports for src port */ 274 #define USABLE_PORTS (65536 - MAPBLK_MINPORT) 275 276 #define IPN_CMPSIZ (sizeof(ipnat_t) - offsetof(ipnat_t, in_flags)) 277 278 typedef struct natlookup { 279 struct in_addr nl_inip; 280 struct in_addr nl_outip; 281 struct in_addr nl_realip; 282 int nl_flags; 283 u_short nl_inport; 284 u_short nl_outport; 285 u_short nl_realport; 286 } natlookup_t; 287 288 289 typedef struct nat_save { 290 void *ipn_next; 291 struct nat ipn_nat; 292 struct ipnat ipn_ipnat; 293 struct frentry ipn_fr; 294 int ipn_dsize; 295 char ipn_data[4]; 296 } nat_save_t; 297 298 #define ipn_rule ipn_nat.nat_fr 299 300 typedef struct natget { 301 void *ng_ptr; 302 int ng_sz; 303 } natget_t; 304 305 306 /* 307 * This structure gets used to help NAT sessions keep the same NAT rule (and 308 * thus translation for IP address) when: 309 * (a) round-robin redirects are in use 310 * (b) different IP add 311 */ 312 typedef struct hostmap { 313 struct hostmap *hm_hnext; 314 struct hostmap **hm_phnext; 315 struct hostmap *hm_next; 316 struct hostmap **hm_pnext; 317 struct ipnat *hm_ipnat; 318 struct in_addr hm_srcip; 319 struct in_addr hm_dstip; 320 struct in_addr hm_mapip; 321 u_32_t hm_port; 322 int hm_ref; 323 } hostmap_t; 324 325 326 /* 327 * Structure used to pass information in to nat_newmap and nat_newrdr. 328 */ 329 typedef struct natinfo { 330 ipnat_t *nai_np; 331 u_32_t nai_sum1; 332 u_32_t nai_sum2; 333 u_32_t nai_nflags; 334 u_32_t nai_flags; 335 struct in_addr nai_ip; 336 u_short nai_port; 337 u_short nai_nport; 338 u_short nai_sport; 339 u_short nai_dport; 340 } natinfo_t; 341 342 343 typedef struct natstat { 344 u_long ns_mapped[2]; 345 u_long ns_rules; 346 u_long ns_added; 347 u_long ns_expire; 348 u_long ns_inuse; 349 u_long ns_logged; 350 u_long ns_logfail; 351 u_long ns_memfail; 352 u_long ns_badnat; 353 u_long ns_addtrpnt; 354 nat_t **ns_table[2]; 355 hostmap_t **ns_maptable; 356 ipnat_t *ns_list; 357 void *ns_apslist; 358 u_int ns_wilds; 359 u_int ns_nattab_sz; 360 u_int ns_nattab_max; 361 u_int ns_rultab_sz; 362 u_int ns_rdrtab_sz; 363 u_int ns_trpntab_sz; 364 u_int ns_hostmap_sz; 365 nat_t *ns_instances; 366 hostmap_t *ns_maplist; 367 u_long *ns_bucketlen[2]; 368 u_long ns_ticks; 369 u_int ns_orphans; 370 } natstat_t; 371 372 typedef struct natlog { 373 struct in_addr nl_origip; 374 struct in_addr nl_outip; 375 struct in_addr nl_inip; 376 u_short nl_origport; 377 u_short nl_outport; 378 u_short nl_inport; 379 u_short nl_type; 380 int nl_rule; 381 U_QUAD_T nl_pkts[2]; 382 U_QUAD_T nl_bytes[2]; 383 u_char nl_p; 384 } natlog_t; 385 386 387 #define NL_NEWMAP NAT_MAP 388 #define NL_NEWRDR NAT_REDIRECT 389 #define NL_NEWBIMAP NAT_BIMAP 390 #define NL_NEWBLOCK NAT_MAPBLK 391 #define NL_DESTROY 0xfffc 392 #define NL_CLONE 0xfffd 393 #define NL_FLUSH 0xfffe 394 #define NL_EXPIRE 0xffff 395 396 #define NAT_HASH_FN(k,l,m) (((k) + ((k) >> 12) + l) % (m)) 397 398 #define LONG_SUM(in) (((in) & 0xffff) + ((in) >> 16)) 399 400 #define CALC_SUMD(s1, s2, sd) { \ 401 (s1) = ((s1) & 0xffff) + ((s1) >> 16); \ 402 (s2) = ((s2) & 0xffff) + ((s2) >> 16); \ 403 /* Do it twice */ \ 404 (s1) = ((s1) & 0xffff) + ((s1) >> 16); \ 405 (s2) = ((s2) & 0xffff) + ((s2) >> 16); \ 406 /* Because ~1 == -2, We really need ~1 == -1 */ \ 407 if ((s1) > (s2)) (s2)--; \ 408 (sd) = (s2) - (s1); \ 409 (sd) = ((sd) & 0xffff) + ((sd) >> 16); } 410 411 #define NAT_SYSSPACE 0x80000000 412 #define NAT_LOCKHELD 0x40000000 413 414 415 extern u_int ipf_nattable_sz; 416 extern u_int ipf_nattable_max; 417 extern u_int ipf_natrules_sz; 418 extern u_int ipf_rdrrules_sz; 419 extern u_int ipf_hostmap_sz; 420 extern u_int fr_nat_maxbucket; 421 extern u_int fr_nat_maxbucket_reset; 422 extern int fr_nat_lock; 423 extern int fr_nat_doflush; 424 extern void fr_natsync __P((void *)); 425 extern u_long fr_defnatage; 426 extern u_long fr_defnaticmpage; 427 extern u_long fr_defnatipage; 428 /* nat_table[0] -> hashed list sorted by inside (ip, port) */ 429 /* nat_table[1] -> hashed list sorted by outside (ip, port) */ 430 extern nat_t **nat_table[2]; 431 extern nat_t *nat_instances; 432 extern ipnat_t *nat_list; 433 extern ipnat_t **nat_rules; 434 extern ipnat_t **rdr_rules; 435 extern ipftq_t *nat_utqe; 436 extern natstat_t nat_stats; 437 438 #if defined(__OpenBSD__) 439 extern void nat_ifdetach __P((void *)); 440 #endif 441 extern int fr_nat_ioctl __P((caddr_t, ioctlcmd_t, int, int, void *)); 442 extern int fr_natinit __P((void)); 443 extern nat_t *nat_new __P((fr_info_t *, ipnat_t *, nat_t **, u_int, int)); 444 extern nat_t *nat_outlookup __P((fr_info_t *, u_int, u_int, struct in_addr, 445 struct in_addr)); 446 extern void fix_datacksum __P((u_short *, u_32_t)); 447 extern nat_t *nat_inlookup __P((fr_info_t *, u_int, u_int, struct in_addr, 448 struct in_addr)); 449 extern nat_t *nat_tnlookup __P((fr_info_t *, int)); 450 extern nat_t *nat_maplookup __P((void *, u_int, struct in_addr, 451 struct in_addr)); 452 extern nat_t *nat_lookupredir __P((natlookup_t *)); 453 extern nat_t *nat_icmperrorlookup __P((fr_info_t *, int)); 454 extern nat_t *nat_icmperror __P((fr_info_t *, u_int *, int)); 455 extern void nat_delete __P((struct nat *, int)); 456 extern int nat_insert __P((nat_t *, int)); 457 458 extern int fr_checknatout __P((fr_info_t *, u_32_t *)); 459 extern int fr_natout __P((fr_info_t *, nat_t *, int, u_32_t)); 460 extern int fr_checknatin __P((fr_info_t *, u_32_t *)); 461 extern int fr_natin __P((fr_info_t *, nat_t *, int, u_32_t)); 462 extern void fr_natunload __P((void)); 463 extern void fr_natexpire __P((void)); 464 extern void nat_log __P((struct nat *, u_int)); 465 extern void fix_incksum __P((fr_info_t *, u_short *, u_32_t)); 466 extern void fix_outcksum __P((fr_info_t *, u_short *, u_32_t)); 467 extern void fr_ipnatderef __P((ipnat_t **)); 468 extern void fr_natderef __P((nat_t **)); 469 extern u_short *nat_proto __P((fr_info_t *, nat_t *, u_int)); 470 extern void nat_update __P((fr_info_t *, nat_t *, ipnat_t *)); 471 extern void fr_setnatqueue __P((nat_t *, int)); 472 extern void fr_hostmapdel __P((hostmap_t **)); 473 474 #endif /* __IP_NAT_H__ */ 475