//Netfilter caching system //Ganhawk //Inculde file with functions as Macros that will be preprocessed into the code //#define DEBUG #define DEBUG_NFCACHE #ifndef __NB_INCLUDE__ #define __NB_INCLUDE__ #endif #define NFC_PRESENT_IN_CACHE 0x1000000 #define NFC_PRESENT_IN_CACHE_REJECT 0x2000000 // Cache limit is the number of packets to store in cache #define NFC_CACHE_LIMIT 500 //Struct for storing data in binary srch tree struct NFC_tree{ unsigned int nfcache; //IP Header __u8 tos; __u16 tot_len; __u16 id; __u16 frag_off; __u8 ttl; __u8 protocol; __u16 check; __u32 saddr; __u32 daddr; //TCP Header __u16 source_PT; __u16 dest_PT; // __u32 seq; // __u32 ack_seq; #if defined(__LITTLE_ENDIAN_BITFIELD) __u16 res1:4, doff:4, fin:1, syn:1, rst:1, psh:1, ack:1, urg:1, ece:1, cwr:1; #elif defined(__BIG_ENDIAN_BITFIELD) __u16 doff:4, res1:4, cwr:1, ece:1, urg:1, ack:1, psh:1, rst:1, syn:1, fin:1; #else #error "Adjust your defines" #endif // __u16 window; // __u16 check; // __u16 urg_ptr; //struct net_device *dev; //struct net_device *rx_dev; __u8 verdict; //Accepted or Rejected ? unsigned long dev_addr; unsigned long rx_dev_addr; // tree *left; // tree *right; struct NFC_tree *next; //store in this linked list streams from same machine struct NFC_tree *next_delete; //Fast delete linked list chain struct avl_node treenode; //Thanks Kevin O'Conoor for code released uder GPL in 1999. }; //Genral Functions #define NULL_CHECK(ptr) \ if ((ptr) == NULL) return -EINVAL //Caching Functions #define NFCACHE_PRINT(__nfcache)({ \ if ((__nfcache) & NFC_IP_SRC) printk(" NFC_IP_SRC "); \ if ((__nfcache) & NFC_IP_IF_IN) printk(" NFC_IP_IF_IN "); \ if ((__nfcache) & NFC_IP_SRC_PT) printk(" NFC_IP_SRC_PT "); \ if ((__nfcache) & NFC_IP_DST_PT) printk(" NFC_IP_DST_PT "); \ if ((__nfcache) & NFC_IP_DST) printk(" NFC_IP_DST "); \ if ((__nfcache) & NFC_IP_TOS) printk(" NFC_IP_TOS "); \ if ((__nfcache) & NFC_IP_PROTO) printk(" NFC_IP_PROTO "); \ if ((__nfcache) & NFC_IP_OPTIONS) printk(" NFC_IP_OPTIONS "); \ if ((__nfcache) & NFC_IP_FRAG) printk(" NFC_IP_FRAG "); \ if ((__nfcache) & NFC_IP_TCPFLAGS) printk(" NFC_IP_TCPFLAGS "); \ if ((__nfcache) & NFC_IP_IF_OUT) printk(" NFC_IP_IF_OUT "); \ if ((__nfcache) & NFC_IP_PROTO_UNKNOWN) printk(" NFC_IP_PROTO_UNKNOWN ");\ if ((__nfcache) & NFC_UNKNOWN) printk(" NFC_UNKNOWN "); \ if ((__nfcache) & NFC_ALTERED) printk(" NFC_ALTERED "); \ }) //Check if the packet can be cached //FIXME: set 1 for NFC_UNKNOWN also. Currently set 0 to counter bug in ip_conntrack #define NFCACHE_CANNOTCACHE(__nfcache)({ \ int __ans=0; \ if ((__nfcache) & NFC_UNKNOWN) __ans=0; \ if ((__nfcache) & NFC_ALTERED) __ans=1; \ if ((__nfcache) & NFC_IP_PROTO_UNKNOWN) __ans=1; \ __ans;}) /*FIXME*******Unused in SKB_COMPARE******************* add these lines as we go along. This section indicates the cacing system is not yet complete. if ((__nfcache) & NFC_IP_IF_IN) if ( (__tree_ptr)->saddr != (__skb_ptr)->nh.iph->saddr ) break; \ if ((__nfcache) & NFC_IP_TOS) if ( (__tree_ptr)->tos != (__skb_ptr)->nh.iph->tos ) break; \ if ((__nfcache) & NFC_IP_OPTIONS) if ( (__tree_ptr)->saddr != (__skb_ptr)->nh.iph->saddr ) break; \ if ((__nfcache) & NFC_IP_FRAG) if ( (__tree_ptr)->saddr != (__skb_ptr)->nh.iph->saddr ) break; \ if ((__nfcache) & NFC_IP_IF_OUT) if ( (__tree_ptr)->saddr != (__skb_ptr)->nh.iph->saddr ) break;\ **************************************************/ #define SKB_COMPARE(__skb_ptr, __tree_ptr)({ \ int __nfcache = (__tree_ptr)->nfcache; \ int __ret = 0; \ struct tcphdr *__tcphdr_ptr; \ __tcphdr_ptr = ((__skb_ptr)->data + ( (__skb_ptr)->nh.iph->ihl * 4)); \ while(1){ \ if ((__nfcache) & NFC_IP_SRC) if ( (__tree_ptr)->saddr != (__skb_ptr)->nh.iph->saddr ) break; \ if ((__nfcache) & NFC_IP_DST) if ( (__tree_ptr)->daddr != (__skb_ptr)->nh.iph->daddr ) break; \ if ((__nfcache) & NFC_IP_PROTO) if ( (__tree_ptr)->protocol != (__skb_ptr)->nh.iph->protocol ) break;\ if ((__nfcache) & NFC_IP_SRC_PT) if ( (__tree_ptr)->source_PT != (__tcphdr_ptr)->source ) break; \ if ((__nfcache) & NFC_IP_DST_PT) if ( (__tree_ptr)->dest_PT != (__tcphdr_ptr)->dest ) break; \ if ((__nfcache) & NFC_IP_TCPFLAGS) { \ if ( (__tree_ptr)->res1 != (__tcphdr_ptr)->res1 ) break; \ if ( (__tree_ptr)->doff != (__tcphdr_ptr)->doff ) break; \ if ( (__tree_ptr)->fin != (__tcphdr_ptr)->fin ) break; \ if ( (__tree_ptr)->syn != (__tcphdr_ptr)->syn ) break; \ if ( (__tree_ptr)->rst != (__tcphdr_ptr)->rst ) break; \ if ( (__tree_ptr)->psh != (__tcphdr_ptr)->psh ) break; \ if ( (__tree_ptr)->ack != (__tcphdr_ptr)->ack ) break; \ if ( (__tree_ptr)->urg != (__tcphdr_ptr)->urg ) break; \ if ( (__tree_ptr)->ece != (__tcphdr_ptr)->ece ) break; \ if ( (__tree_ptr)->cwr != (__tcphdr_ptr)->cwr ) break; \ } \ __ret=1; break; \ } \ __ret;}) //Function Suite for AVL Tree manipulation. Derrived from Kevin Coonor's #define avl_entry(ptr, type, member) \ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) #define AVL_FIND(__Tree,__Compare) ({ \ struct avl_node *AVLNode=(__Tree); \ \ while (AVLNode) { \ int __compval = (__Compare); \ \ if (__compval < 0) { \ AVLNode = AVLNode->left; \ } else if (__compval > 0) { \ AVLNode = AVLNode->right; \ } else { \ break; \ } \ } \ AVLNode;}) #define AVL_FINDWITHSTACK(__TreeP,__Stack,__Count,__Compare) ({ \ struct avl_node **__tree = (__TreeP); \ struct avl_node *AVLNode = *__tree; \ struct avl_node ***__stack = (__Stack); \ int __found=0; \ \ *__stack++ = __tree; \ __Count = 1; \ while (AVLNode) { \ int __compval = (__Compare); \ \ if (__compval < 0) { \ (__Count)++; \ *__stack++ = &AVLNode->left; \ AVLNode = AVLNode->left; \ } else if (__compval > 0) { \ (__Count)++; \ *__stack++ = &AVLNode->right; \ AVLNode = AVLNode->right; \ } else { \ __found = 1; \ break; \ } \ } \ AVLNode;}) #define AVL_REMOVE(__TreeP,__Compare) ({ \ struct avl_node **__stk[AVL_MAXHEIGHT]; \ int __cnt, __ret; \ \ if (! AVL_FINDWITHSTACK((__TreeP),__stk,__cnt,(__Compare))) { \ __ret = 0; \ } else { \ __avl_remove(__stk, __cnt); \ __ret = 1; \ } \ __ret;}) #define AVL_INSERT(__TreeP,__Node,__Compare) ({ \ struct avl_node **__stk[AVL_MAXHEIGHT]; \ int __cnt, __ret; \ struct NFC_tree *__linked; \ struct avl_node *__ans; \ __ans = AVL_FINDWITHSTACK((__TreeP),__stk,__cnt,(__Compare)); \ if ( (__ans) ) { \ __ret = 0; \ __linked = avl_entry((__ans), struct NFC_tree, treenode); \ while(__linked->next) \ __linked = __linked->next; \ __linked->next = (__Node); \ } else { \ __avl_insert((&(__Node)->treenode), __stk, __cnt); \ __ret = 1; \ } \ __ret;})