13b9b51feSCy Schubert /* $FreeBSD$ */ 23b9b51feSCy Schubert 33b9b51feSCy Schubert /* 43b9b51feSCy Schubert * Copyright (C) 2012 by Darren Reed. 53b9b51feSCy Schubert * 63b9b51feSCy Schubert * See the IPFILTER.LICENCE file for details on licencing. 73b9b51feSCy Schubert * 83b9b51feSCy Schubert * @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed 93b9b51feSCy Schubert * $FreeBSD$ 103b9b51feSCy Schubert * Id: ip_state.h,v 2.68.2.10 2007/10/16 09:33:24 darrenr Exp $ 113b9b51feSCy Schubert */ 123b9b51feSCy Schubert #ifndef __IP_STATE_H__ 133b9b51feSCy Schubert #define __IP_STATE_H__ 143b9b51feSCy Schubert 153b9b51feSCy Schubert # define SIOCDELST _IOW('r', 61, struct ipfobj) 163b9b51feSCy Schubert 173b9b51feSCy Schubert struct ipscan; 183b9b51feSCy Schubert 193b9b51feSCy Schubert #ifndef IPSTATE_SIZE 203b9b51feSCy Schubert # define IPSTATE_SIZE 5737 213b9b51feSCy Schubert #endif 223b9b51feSCy Schubert #ifndef IPSTATE_MAX 233b9b51feSCy Schubert # define IPSTATE_MAX 4013 /* Maximum number of states held */ 243b9b51feSCy Schubert #endif 253b9b51feSCy Schubert 263b9b51feSCy Schubert #define PAIRS(s1,d1,s2,d2) ((((s1) == (s2)) && ((d1) == (d2))) ||\ 273b9b51feSCy Schubert (((s1) == (d2)) && ((d1) == (s2)))) 283b9b51feSCy Schubert #define IPPAIR(s1,d1,s2,d2) PAIRS((s1).s_addr, (d1).s_addr, \ 293b9b51feSCy Schubert (s2).s_addr, (d2).s_addr) 303b9b51feSCy Schubert 313b9b51feSCy Schubert 323b9b51feSCy Schubert typedef struct ipstate { 333b9b51feSCy Schubert ipfmutex_t is_lock; 343b9b51feSCy Schubert struct ipstate *is_next; 353b9b51feSCy Schubert struct ipstate **is_pnext; 363b9b51feSCy Schubert struct ipstate *is_hnext; 373b9b51feSCy Schubert struct ipstate **is_phnext; 383b9b51feSCy Schubert struct ipstate **is_me; 393b9b51feSCy Schubert void *is_ifp[4]; 403b9b51feSCy Schubert void *is_sync; 413b9b51feSCy Schubert frentry_t *is_rule; 423b9b51feSCy Schubert struct ipftq *is_tqehead[2]; 433b9b51feSCy Schubert struct ipscan *is_isc; 443b9b51feSCy Schubert U_QUAD_T is_pkts[4]; 453b9b51feSCy Schubert U_QUAD_T is_bytes[4]; 463b9b51feSCy Schubert U_QUAD_T is_icmppkts[4]; 473b9b51feSCy Schubert struct ipftqent is_sti; 483b9b51feSCy Schubert u_int is_frage[2]; 493b9b51feSCy Schubert int is_ref; /* reference count */ 503b9b51feSCy Schubert int is_isninc[2]; 513b9b51feSCy Schubert u_short is_sumd[2]; 523b9b51feSCy Schubert i6addr_t is_src; 533b9b51feSCy Schubert i6addr_t is_dst; 543b9b51feSCy Schubert u_int is_pass; 553b9b51feSCy Schubert u_char is_p; /* Protocol */ 563b9b51feSCy Schubert u_char is_v; 573b9b51feSCy Schubert int is_family; 583b9b51feSCy Schubert u_32_t is_hv; 593b9b51feSCy Schubert u_32_t is_tag; 603b9b51feSCy Schubert u_32_t is_opt[2]; /* packet options set */ 613b9b51feSCy Schubert u_32_t is_optmsk[2]; /* " " mask */ 623b9b51feSCy Schubert u_short is_sec; /* security options set */ 633b9b51feSCy Schubert u_short is_secmsk; /* " " mask */ 643b9b51feSCy Schubert u_short is_auth; /* authentication options set */ 653b9b51feSCy Schubert u_short is_authmsk; /* " " mask */ 663b9b51feSCy Schubert union { 673b9b51feSCy Schubert icmpinfo_t is_ics; 683b9b51feSCy Schubert tcpinfo_t is_ts; 693b9b51feSCy Schubert udpinfo_t is_us; 703b9b51feSCy Schubert greinfo_t is_ug; 713b9b51feSCy Schubert } is_ps; 723b9b51feSCy Schubert u_32_t is_flags; 733b9b51feSCy Schubert int is_flx[2][2]; 743b9b51feSCy Schubert u_32_t is_rulen; /* rule number when created */ 753b9b51feSCy Schubert u_32_t is_s0[2]; 763b9b51feSCy Schubert u_short is_smsk[2]; 773b9b51feSCy Schubert frdest_t is_dif; 783b9b51feSCy Schubert frdest_t is_tifs[2]; 793b9b51feSCy Schubert char is_group[FR_GROUPLEN]; 803b9b51feSCy Schubert char is_sbuf[2][16]; 813b9b51feSCy Schubert char is_ifname[4][LIFNAMSIZ]; 823b9b51feSCy Schubert } ipstate_t; 833b9b51feSCy Schubert 843b9b51feSCy Schubert #define is_die is_sti.tqe_die 853b9b51feSCy Schubert #define is_state is_sti.tqe_state 863b9b51feSCy Schubert #define is_touched is_sti.tqe_touched 873b9b51feSCy Schubert #define is_saddr is_src.in4.s_addr 883b9b51feSCy Schubert #define is_daddr is_dst.in4.s_addr 893b9b51feSCy Schubert #define is_icmp is_ps.is_ics 903b9b51feSCy Schubert #define is_type is_icmp.ici_type 913b9b51feSCy Schubert #define is_tcp is_ps.is_ts 923b9b51feSCy Schubert #define is_udp is_ps.is_us 933b9b51feSCy Schubert #define is_send is_tcp.ts_data[0].td_end 943b9b51feSCy Schubert #define is_dend is_tcp.ts_data[1].td_end 953b9b51feSCy Schubert #define is_maxswin is_tcp.ts_data[0].td_maxwin 963b9b51feSCy Schubert #define is_maxdwin is_tcp.ts_data[1].td_maxwin 973b9b51feSCy Schubert #define is_maxsend is_tcp.ts_data[0].td_maxend 983b9b51feSCy Schubert #define is_maxdend is_tcp.ts_data[1].td_maxend 993b9b51feSCy Schubert #define is_swinscale is_tcp.ts_data[0].td_winscale 1003b9b51feSCy Schubert #define is_dwinscale is_tcp.ts_data[1].td_winscale 1013b9b51feSCy Schubert #define is_swinflags is_tcp.ts_data[0].td_winflags 1023b9b51feSCy Schubert #define is_dwinflags is_tcp.ts_data[1].td_winflags 1033b9b51feSCy Schubert #define is_sport is_tcp.ts_sport 1043b9b51feSCy Schubert #define is_dport is_tcp.ts_dport 1053b9b51feSCy Schubert #define is_ifpin is_ifp[0] 1063b9b51feSCy Schubert #define is_ifpout is_ifp[2] 1073b9b51feSCy Schubert #define is_gre is_ps.is_ug 1083b9b51feSCy Schubert #define is_call is_gre.gs_call 1093b9b51feSCy Schubert 1103b9b51feSCy Schubert #define IS_WSPORT SI_W_SPORT /* 0x00100 */ 1113b9b51feSCy Schubert #define IS_WDPORT SI_W_DPORT /* 0x00200 */ 1123b9b51feSCy Schubert #define IS_WSADDR SI_W_SADDR /* 0x00400 */ 1133b9b51feSCy Schubert #define IS_WDADDR SI_W_DADDR /* 0x00800 */ 1143b9b51feSCy Schubert #define IS_NEWFR SI_NEWFR /* 0x01000 */ 1153b9b51feSCy Schubert #define IS_CLONE SI_CLONE /* 0x02000 */ 1163b9b51feSCy Schubert #define IS_CLONED SI_CLONED /* 0x04000 */ 1173b9b51feSCy Schubert #define IS_TCPFSM 0x10000 1183b9b51feSCy Schubert #define IS_STRICT 0x20000 1193b9b51feSCy Schubert #define IS_ISNSYN 0x40000 1203b9b51feSCy Schubert #define IS_ISNACK 0x80000 1213b9b51feSCy Schubert #define IS_STATESYNC 0x100000 1223b9b51feSCy Schubert #define IS_LOOSE 0x200000 1233b9b51feSCy Schubert /* 1243b9b51feSCy Schubert * IS_SC flags are for scan-operations that need to be recognised in state. 1253b9b51feSCy Schubert */ 1263b9b51feSCy Schubert #define IS_SC_CLIENT 0x10000000 1273b9b51feSCy Schubert #define IS_SC_SERVER 0x20000000 1283b9b51feSCy Schubert #define IS_SC_MATCHC 0x40000000 1293b9b51feSCy Schubert #define IS_SC_MATCHS 0x80000000 1303b9b51feSCy Schubert #define IS_SC_MATCHALL (IS_SC_MATCHC|IS_SC_MATCHC) 1313b9b51feSCy Schubert #define IS_SC_ALL (IS_SC_MATCHC|IS_SC_MATCHC|IS_SC_CLIENT|IS_SC_SERVER) 1323b9b51feSCy Schubert 1333b9b51feSCy Schubert /* 1343b9b51feSCy Schubert * Flags that can be passed into ipf_addstate 1353b9b51feSCy Schubert */ 1363b9b51feSCy Schubert #define IS_INHERITED 0x0fffff00 1373b9b51feSCy Schubert 1383b9b51feSCy Schubert #define TH_OPENING (TH_SYN|TH_ACK) 1393b9b51feSCy Schubert /* 1403b9b51feSCy Schubert * is_flags: 1413b9b51feSCy Schubert * Bits 0 - 3 are use as a mask with the current packet's bits to check for 1423b9b51feSCy Schubert * whether it is short, tcp/udp, a fragment or the presence of IP options. 1433b9b51feSCy Schubert * Bits 4 - 7 are set from the initial packet and contain what the packet 1443b9b51feSCy Schubert * anded with bits 0-3 must match. 1453b9b51feSCy Schubert * Bits 8,9 are used to indicate wildcard source/destination port matching. 1463b9b51feSCy Schubert * Bits 10,11 are reserved for other wildcard flag compatibility. 1473b9b51feSCy Schubert * Bits 12,13 are for scaning. 1483b9b51feSCy Schubert */ 1493b9b51feSCy Schubert 1503b9b51feSCy Schubert typedef struct ipstate_save { 1513b9b51feSCy Schubert void *ips_next; 1523b9b51feSCy Schubert struct ipstate ips_is; 1533b9b51feSCy Schubert struct frentry ips_fr; 1543b9b51feSCy Schubert } ipstate_save_t; 1553b9b51feSCy Schubert 1563b9b51feSCy Schubert #define ips_rule ips_is.is_rule 1573b9b51feSCy Schubert 1583b9b51feSCy Schubert 1593b9b51feSCy Schubert typedef struct ipslog { 1603b9b51feSCy Schubert U_QUAD_T isl_pkts[4]; 1613b9b51feSCy Schubert U_QUAD_T isl_bytes[4]; 1623b9b51feSCy Schubert i6addr_t isl_src; 1633b9b51feSCy Schubert i6addr_t isl_dst; 1643b9b51feSCy Schubert u_32_t isl_tag; 1653b9b51feSCy Schubert u_short isl_type; 1663b9b51feSCy Schubert union { 1673b9b51feSCy Schubert u_short isl_filler[2]; 1683b9b51feSCy Schubert u_short isl_ports[2]; 1693b9b51feSCy Schubert u_short isl_icmp; 1703b9b51feSCy Schubert } isl_ps; 1713b9b51feSCy Schubert u_char isl_v; 1723b9b51feSCy Schubert u_char isl_p; 1733b9b51feSCy Schubert u_char isl_flags; 1743b9b51feSCy Schubert u_char isl_state[2]; 1753b9b51feSCy Schubert u_32_t isl_rulen; 1763b9b51feSCy Schubert char isl_group[FR_GROUPLEN]; 1773b9b51feSCy Schubert } ipslog_t; 1783b9b51feSCy Schubert 1793b9b51feSCy Schubert #define isl_sport isl_ps.isl_ports[0] 1803b9b51feSCy Schubert #define isl_dport isl_ps.isl_ports[1] 1813b9b51feSCy Schubert #define isl_itype isl_ps.isl_icmp 1823b9b51feSCy Schubert 1833b9b51feSCy Schubert #define ISL_NEW 0 1843b9b51feSCy Schubert #define ISL_CLONE 1 1853b9b51feSCy Schubert #define ISL_STATECHANGE 2 1863b9b51feSCy Schubert #define ISL_EXPIRE 0xffff 1873b9b51feSCy Schubert #define ISL_FLUSH 0xfffe 1883b9b51feSCy Schubert #define ISL_REMOVE 0xfffd 1893b9b51feSCy Schubert #define ISL_INTERMEDIATE 0xfffc 1903b9b51feSCy Schubert #define ISL_KILLED 0xfffb 1913b9b51feSCy Schubert #define ISL_ORPHAN 0xfffa 1923b9b51feSCy Schubert #define ISL_UNLOAD 0xfff9 1933b9b51feSCy Schubert 1943b9b51feSCy Schubert 1953b9b51feSCy Schubert typedef struct ips_stat { 1963b9b51feSCy Schubert u_int iss_active; 1973b9b51feSCy Schubert u_int iss_active_proto[256]; 1983b9b51feSCy Schubert u_long iss_add_bad; 1993b9b51feSCy Schubert u_long iss_add_dup; 2003b9b51feSCy Schubert u_long iss_add_locked; 2013b9b51feSCy Schubert u_long iss_add_oow; 2023b9b51feSCy Schubert u_long iss_bucket_full; 2033b9b51feSCy Schubert u_long iss_check_bad; 2043b9b51feSCy Schubert u_long iss_check_miss; 2053b9b51feSCy Schubert u_long iss_check_nattag; 2063b9b51feSCy Schubert u_long iss_check_notag; 2073b9b51feSCy Schubert u_long iss_clone_nomem; 2083b9b51feSCy Schubert u_long iss_cloned; 2093b9b51feSCy Schubert u_long iss_expire; 2103b9b51feSCy Schubert u_long iss_fin; 2113b9b51feSCy Schubert u_long iss_flush_all; 2123b9b51feSCy Schubert u_long iss_flush_closing; 2133b9b51feSCy Schubert u_long iss_flush_queue; 2143b9b51feSCy Schubert u_long iss_flush_state; 2153b9b51feSCy Schubert u_long iss_flush_timeout; 2163b9b51feSCy Schubert u_long iss_hits; 2173b9b51feSCy Schubert u_long iss_icmp6_icmperr; 2183b9b51feSCy Schubert u_long iss_icmp6_miss; 2193b9b51feSCy Schubert u_long iss_icmp6_notinfo; 2203b9b51feSCy Schubert u_long iss_icmp6_notquery; 2213b9b51feSCy Schubert u_long iss_icmp_bad; 2223b9b51feSCy Schubert u_long iss_icmp_banned; 2233b9b51feSCy Schubert u_long iss_icmp_headblock; 2243b9b51feSCy Schubert u_long iss_icmp_hits; 2253b9b51feSCy Schubert u_long iss_icmp_icmperr; 2263b9b51feSCy Schubert u_long iss_icmp_miss; 2273b9b51feSCy Schubert u_long iss_icmp_notquery; 2283b9b51feSCy Schubert u_long iss_icmp_short; 2293b9b51feSCy Schubert u_long iss_icmp_toomany; 2303b9b51feSCy Schubert u_int iss_inuse; 2313b9b51feSCy Schubert ipstate_t *iss_list; 2323b9b51feSCy Schubert u_long iss_log_fail; 2333b9b51feSCy Schubert u_long iss_log_ok; 2343b9b51feSCy Schubert u_long iss_lookup_badifp; 2353b9b51feSCy Schubert u_long iss_lookup_badport; 2363b9b51feSCy Schubert u_long iss_lookup_miss; 2373b9b51feSCy Schubert u_long iss_max; 2383b9b51feSCy Schubert u_long iss_max_ref; 2393b9b51feSCy Schubert u_long iss_max_track; 2403b9b51feSCy Schubert u_long iss_miss_mask; 2413b9b51feSCy Schubert u_long iss_nomem; 2423b9b51feSCy Schubert u_long iss_oow; 2433b9b51feSCy Schubert u_long iss_orphan; 2443b9b51feSCy Schubert u_long iss_proto[256]; 2453b9b51feSCy Schubert u_long iss_scan_block; 2463b9b51feSCy Schubert u_long iss_state_max; 2473b9b51feSCy Schubert u_long iss_state_size; 2483b9b51feSCy Schubert u_long iss_states[IPF_TCP_NSTATES]; 2493b9b51feSCy Schubert ipstate_t **iss_table; 2503b9b51feSCy Schubert u_long iss_tcp_closing; 2513b9b51feSCy Schubert u_long iss_tcp_oow; 2523b9b51feSCy Schubert u_long iss_tcp_rstadd; 2533b9b51feSCy Schubert u_long iss_tcp_toosmall; 2543b9b51feSCy Schubert u_long iss_tcp_badopt; 2553b9b51feSCy Schubert u_long iss_tcp_fsm; 2563b9b51feSCy Schubert u_long iss_tcp_strict; 2573b9b51feSCy Schubert ipftq_t *iss_tcptab; 2583b9b51feSCy Schubert u_int iss_ticks; 2593b9b51feSCy Schubert u_long iss_wild; 2603b9b51feSCy Schubert u_long iss_winsack; 2613b9b51feSCy Schubert u_int *iss_bucketlen; 2623b9b51feSCy Schubert } ips_stat_t; 2633b9b51feSCy Schubert 2643b9b51feSCy Schubert 2653b9b51feSCy Schubert typedef struct ipf_state_softc_s { 2663b9b51feSCy Schubert ipfmutex_t ipf_stinsert; 2673b9b51feSCy Schubert int ipf_state_logging; 2683b9b51feSCy Schubert int ipf_state_lock; 2693b9b51feSCy Schubert int ipf_state_doflush; 2703b9b51feSCy Schubert u_int ipf_state_inited; 2713b9b51feSCy Schubert u_int ipf_state_max; 2723b9b51feSCy Schubert u_int ipf_state_maxbucket; 2733b9b51feSCy Schubert u_int ipf_state_size; 2743b9b51feSCy Schubert u_int ipf_state_wm_freq; 2753b9b51feSCy Schubert u_int ipf_state_wm_high; 2763b9b51feSCy Schubert u_int ipf_state_wm_low; 2773b9b51feSCy Schubert u_int ipf_state_wm_last; 2783b9b51feSCy Schubert u_long *ipf_state_seed; 2793b9b51feSCy Schubert ipstate_t *ipf_state_list; 2803b9b51feSCy Schubert ipstate_t **ipf_state_table; 2813b9b51feSCy Schubert ipftuneable_t *ipf_state_tune; 2823b9b51feSCy Schubert ipftq_t *ipf_state_usertq; 2833b9b51feSCy Schubert ipftq_t ipf_state_pending; 2843b9b51feSCy Schubert ipftq_t ipf_state_deletetq; 2853b9b51feSCy Schubert ipftq_t ipf_state_udptq; 2863b9b51feSCy Schubert ipftq_t ipf_state_udpacktq; 2873b9b51feSCy Schubert ipftq_t ipf_state_iptq; 2883b9b51feSCy Schubert ipftq_t ipf_state_icmptq; 2893b9b51feSCy Schubert ipftq_t ipf_state_icmpacktq; 2903b9b51feSCy Schubert ipftq_t ipf_state_tcptq[IPF_TCP_NSTATES]; 2913b9b51feSCy Schubert ips_stat_t ipf_state_stats; 2923b9b51feSCy Schubert } ipf_state_softc_t; 2933b9b51feSCy Schubert 2943b9b51feSCy Schubert 2953b9b51feSCy Schubert #ifndef _KERNEL 2963b9b51feSCy Schubert extern void ipf_state_dump(ipf_main_softc_t *, void *); 2973b9b51feSCy Schubert #endif 2983b9b51feSCy Schubert extern int ipf_tcp_age(struct ipftqent *, struct fr_info *, 2993b9b51feSCy Schubert struct ipftq *, int, int); 3003b9b51feSCy Schubert extern int ipf_tcpinwindow(struct fr_info *, struct tcpdata *, 3013b9b51feSCy Schubert struct tcpdata *, tcphdr_t *, int); 3023b9b51feSCy Schubert 3033b9b51feSCy Schubert extern int ipf_state_add(ipf_main_softc_t *, fr_info_t *, 3043b9b51feSCy Schubert ipstate_t **, u_int); 3053b9b51feSCy Schubert extern frentry_t *ipf_state_check(struct fr_info *, u_32_t *); 3063b9b51feSCy Schubert extern void ipf_state_deref(ipf_main_softc_t *, ipstate_t **); 3073b9b51feSCy Schubert extern void ipf_state_expire(ipf_main_softc_t *); 3083b9b51feSCy Schubert extern int ipf_state_flush(ipf_main_softc_t *, int, int); 3093b9b51feSCy Schubert extern ipstate_t *ipf_state_lookup(fr_info_t *, tcphdr_t *, ipftq_t **); 3103b9b51feSCy Schubert extern int ipf_state_init(void); 3113b9b51feSCy Schubert extern int ipf_state_insert(ipf_main_softc_t *, struct ipstate *, int); 3123b9b51feSCy Schubert extern int ipf_state_ioctl(ipf_main_softc_t *, caddr_t, ioctlcmd_t, int, int, void *); 3133b9b51feSCy Schubert extern void ipf_state_log(ipf_main_softc_t *, struct ipstate *, u_int); 3143b9b51feSCy Schubert extern int ipf_state_matchflush(ipf_main_softc_t *, caddr_t); 3153b9b51feSCy Schubert extern int ipf_state_rehash(ipf_main_softc_t *, ipftuneable_t *, ipftuneval_t *); 3163b9b51feSCy Schubert extern void ipf_state_setqueue(ipf_main_softc_t *, ipstate_t *, int); 3173b9b51feSCy Schubert extern void ipf_state_setpending(ipf_main_softc_t *, ipstate_t *); 3183b9b51feSCy Schubert extern int ipf_state_settimeout(struct ipf_main_softc_s *, ipftuneable_t *, ipftuneval_t *); 3193b9b51feSCy Schubert extern void ipf_state_sync(ipf_main_softc_t *, void *); 3203b9b51feSCy Schubert extern void ipf_state_update(fr_info_t *, ipstate_t *); 3213b9b51feSCy Schubert 3223b9b51feSCy Schubert extern void ipf_sttab_init(ipf_main_softc_t *, struct ipftq *); 3233b9b51feSCy Schubert extern void ipf_sttab_destroy(struct ipftq *); 3243b9b51feSCy Schubert extern void ipf_state_setlock(void *, int); 3253b9b51feSCy Schubert extern int ipf_state_main_load(void); 3263b9b51feSCy Schubert extern int ipf_state_main_unload(void); 3273b9b51feSCy Schubert extern void *ipf_state_soft_create(ipf_main_softc_t *); 3283b9b51feSCy Schubert extern void ipf_state_soft_destroy(ipf_main_softc_t *, void *); 3293b9b51feSCy Schubert extern int ipf_state_soft_init(ipf_main_softc_t *, void *); 3303b9b51feSCy Schubert extern int ipf_state_soft_fini(ipf_main_softc_t *, void *); 3313b9b51feSCy Schubert extern ipftq_t *ipf_state_add_tq(ipf_main_softc_t *, int); 3323b9b51feSCy Schubert 3333b9b51feSCy Schubert #endif /* __IP_STATE_H__ */ 334