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