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