1/* 2 * Definitions and Declarations for tuple. 3 * 4 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> 5 * - generalize L3 protocol dependent part. 6 * 7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_tuple.h 8 */ 9 10#ifndef _NF_CONNTRACK_TUPLE_H 11#define _NF_CONNTRACK_TUPLE_H 12 13#include <linux/netfilter/nf_conntrack_tuple_common.h> 14 15/* A `tuple' is a structure containing the information to uniquely 16 identify a connection. ie. if two packets have the same tuple, they 17 are in the same connection; if not, they are not. 18 19 We divide the structure along "manipulatable" and 20 "non-manipulatable" lines, for the benefit of the NAT code. 21*/ 22 23#define NF_CT_TUPLE_L3SIZE 4 24 25/* The l3 protocol-specific manipulable parts of the tuple: always in 26 network order! */ 27union nf_conntrack_address { 28 u_int32_t all[NF_CT_TUPLE_L3SIZE]; 29 __be32 ip; 30 __be32 ip6[4]; 31}; 32 33/* The protocol-specific manipulable parts of the tuple: always in 34 network order! */ 35union nf_conntrack_man_proto 36{ 37 /* Add other protocols here. */ 38 u_int16_t all; 39 40 struct { 41 __be16 port; 42 } tcp; 43 struct { 44 __be16 port; 45 } udp; 46 struct { 47 __be16 id; 48 } icmp; 49 struct { 50 __be16 port; 51 } sctp; 52 struct { 53 __be16 key; /* GRE key is 32bit, PPtP only uses 16bit */ 54 } gre; 55}; 56 57/* The manipulable part of the tuple. */ 58struct nf_conntrack_man 59{ 60 union nf_conntrack_address u3; 61 union nf_conntrack_man_proto u; 62 /* Layer 3 protocol */ 63 u_int16_t l3num; 64}; 65 66/* This contains the information to distinguish a connection. */ 67struct nf_conntrack_tuple 68{ 69 struct nf_conntrack_man src; 70 71 /* These are the parts of the tuple which are fixed. */ 72 struct { 73 union nf_conntrack_address u3; 74 union { 75 /* Add other protocols here. */ 76 u_int16_t all; 77 78 struct { 79 __be16 port; 80 } tcp; 81 struct { 82 __be16 port; 83 } udp; 84 struct { 85 u_int8_t type, code; 86 } icmp; 87 struct { 88 __be16 port; 89 } sctp; 90 struct { 91 __be16 key; 92 } gre; 93 } u; 94 95 /* The protocol. */ 96 u_int8_t protonum; 97 98 /* The direction (for tuplehash) */ 99 u_int8_t dir; 100 } dst; 101}; 102 103/* This is optimized opposed to a memset of the whole structure. Everything we 104 * really care about is the source/destination unions */ 105#define NF_CT_TUPLE_U_BLANK(tuple) \ 106 do { \ 107 (tuple)->src.u.all = 0; \ 108 (tuple)->dst.u.all = 0; \ 109 memset(&(tuple)->src.u3, 0, sizeof((tuple)->src.u3)); \ 110 memset(&(tuple)->dst.u3, 0, sizeof((tuple)->dst.u3)); \ 111 } while (0) 112 113#ifdef __KERNEL__ 114 115#define NF_CT_DUMP_TUPLE(tp) \ 116DEBUGP("tuple %p: %u %u " NIP6_FMT " %hu -> " NIP6_FMT " %hu\n", \ 117 (tp), (tp)->src.l3num, (tp)->dst.protonum, \ 118 NIP6(*(struct in6_addr *)(tp)->src.u3.all), ntohs((tp)->src.u.all), \ 119 NIP6(*(struct in6_addr *)(tp)->dst.u3.all), ntohs((tp)->dst.u.all)) 120 121/* If we're the first tuple, it's the original dir. */ 122#define NF_CT_DIRECTION(h) \ 123 ((enum ip_conntrack_dir)(h)->tuple.dst.dir) 124 125/* Connections have two entries in the hash table: one for each way */ 126struct nf_conntrack_tuple_hash 127{ 128 struct list_head list; 129 130 struct nf_conntrack_tuple tuple; 131}; 132 133#endif /* __KERNEL__ */ 134 135static inline int nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1, 136 const struct nf_conntrack_tuple *t2) 137{ 138 return (t1->src.u3.all[0] == t2->src.u3.all[0] && 139 t1->src.u3.all[1] == t2->src.u3.all[1] && 140 t1->src.u3.all[2] == t2->src.u3.all[2] && 141 t1->src.u3.all[3] == t2->src.u3.all[3] && 142 t1->src.u.all == t2->src.u.all && 143 t1->src.l3num == t2->src.l3num && 144 t1->dst.protonum == t2->dst.protonum); 145} 146 147static inline int nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1, 148 const struct nf_conntrack_tuple *t2) 149{ 150 return (t1->dst.u3.all[0] == t2->dst.u3.all[0] && 151 t1->dst.u3.all[1] == t2->dst.u3.all[1] && 152 t1->dst.u3.all[2] == t2->dst.u3.all[2] && 153 t1->dst.u3.all[3] == t2->dst.u3.all[3] && 154 t1->dst.u.all == t2->dst.u.all && 155 t1->src.l3num == t2->src.l3num && 156 t1->dst.protonum == t2->dst.protonum); 157} 158 159static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1, 160 const struct nf_conntrack_tuple *t2) 161{ 162 return nf_ct_tuple_src_equal(t1, t2) && nf_ct_tuple_dst_equal(t1, t2); 163} 164 165static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t, 166 const struct nf_conntrack_tuple *tuple, 167 const struct nf_conntrack_tuple *mask) 168{ 169 int count = 0; 170 171 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){ 172 if ((t->src.u3.all[count] ^ tuple->src.u3.all[count]) & 173 mask->src.u3.all[count]) 174 return 0; 175 } 176 177 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){ 178 if ((t->dst.u3.all[count] ^ tuple->dst.u3.all[count]) & 179 mask->dst.u3.all[count]) 180 return 0; 181 } 182 183 if ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all || 184 (t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all || 185 (t->src.l3num ^ tuple->src.l3num) & mask->src.l3num || 186 (t->dst.protonum ^ tuple->dst.protonum) & mask->dst.protonum) 187 return 0; 188 189 return 1; 190} 191 192#endif /* _NF_CONNTRACK_TUPLE_H */ 193