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/x_tables.h> 14#include <linux/netfilter/nf_conntrack_tuple_common.h> 15#include <linux/list_nulls.h> 16 17/* A `tuple' is a structure containing the information to uniquely 18 identify a connection. ie. if two packets have the same tuple, they 19 are in the same connection; if not, they are not. 20 21 We divide the structure along "manipulatable" and 22 "non-manipulatable" lines, for the benefit of the NAT code. 23*/ 24 25#define NF_CT_TUPLE_L3SIZE ARRAY_SIZE(((union nf_inet_addr *)NULL)->all) 26 27/* The protocol-specific manipulable parts of the tuple: always in 28 network order! */ 29union nf_conntrack_man_proto { 30 /* Add other protocols here. */ 31 __be16 all; 32 33 struct { 34 __be16 port; 35 } tcp; 36 struct { 37 __be16 port; 38 } udp; 39 struct { 40 __be16 id; 41 } icmp; 42 struct { 43 __be16 port; 44 } dccp; 45 struct { 46 __be16 port; 47 } sctp; 48 struct { 49 __be16 key; /* GRE key is 32bit, PPtP only uses 16bit */ 50 } gre; 51}; 52 53/* The manipulable part of the tuple. */ 54struct nf_conntrack_man { 55 union nf_inet_addr u3; 56 union nf_conntrack_man_proto u; 57 /* Layer 3 protocol */ 58 u_int16_t l3num; 59}; 60 61/* This contains the information to distinguish a connection. */ 62struct nf_conntrack_tuple { 63 struct nf_conntrack_man src; 64 65 /* These are the parts of the tuple which are fixed. */ 66 struct { 67 union nf_inet_addr u3; 68 union { 69 /* Add other protocols here. */ 70 __be16 all; 71 72 struct { 73 __be16 port; 74 } tcp; 75 struct { 76 __be16 port; 77 } udp; 78 struct { 79 u_int8_t type, code; 80 } icmp; 81 struct { 82 __be16 port; 83 } dccp; 84 struct { 85 __be16 port; 86 } sctp; 87 struct { 88 __be16 key; 89 } gre; 90 } u; 91 92 /* The protocol. */ 93 u_int8_t protonum; 94 95 /* The direction (for tuplehash) */ 96 u_int8_t dir; 97 } dst; 98}; 99 100struct nf_conntrack_tuple_mask { 101 struct { 102 union nf_inet_addr u3; 103 union nf_conntrack_man_proto u; 104 } src; 105}; 106 107#ifdef __KERNEL__ 108 109static inline void nf_ct_dump_tuple_ip(const struct nf_conntrack_tuple *t) 110{ 111#ifdef DEBUG 112 printk("tuple %p: %u %pI4:%hu -> %pI4:%hu\n", 113 t, t->dst.protonum, 114 &t->src.u3.ip, ntohs(t->src.u.all), 115 &t->dst.u3.ip, ntohs(t->dst.u.all)); 116#endif 117} 118 119static inline void nf_ct_dump_tuple_ipv6(const struct nf_conntrack_tuple *t) 120{ 121#ifdef DEBUG 122 printk("tuple %p: %u %pI6 %hu -> %pI6 %hu\n", 123 t, t->dst.protonum, 124 t->src.u3.all, ntohs(t->src.u.all), 125 t->dst.u3.all, ntohs(t->dst.u.all)); 126#endif 127} 128 129static inline void nf_ct_dump_tuple(const struct nf_conntrack_tuple *t) 130{ 131 switch (t->src.l3num) { 132 case AF_INET: 133 nf_ct_dump_tuple_ip(t); 134 break; 135 case AF_INET6: 136 nf_ct_dump_tuple_ipv6(t); 137 break; 138 } 139} 140 141/* If we're the first tuple, it's the original dir. */ 142#define NF_CT_DIRECTION(h) \ 143 ((enum ip_conntrack_dir)(h)->tuple.dst.dir) 144 145/* Connections have two entries in the hash table: one for each way */ 146struct nf_conntrack_tuple_hash { 147 struct hlist_nulls_node hnnode; 148 struct nf_conntrack_tuple tuple; 149}; 150 151#endif /* __KERNEL__ */ 152 153static inline int __nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1, 154 const struct nf_conntrack_tuple *t2) 155{ 156 return (nf_inet_addr_cmp(&t1->src.u3, &t2->src.u3) && 157 t1->src.u.all == t2->src.u.all && 158 t1->src.l3num == t2->src.l3num); 159} 160 161static inline int __nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1, 162 const struct nf_conntrack_tuple *t2) 163{ 164 return (nf_inet_addr_cmp(&t1->dst.u3, &t2->dst.u3) && 165 t1->dst.u.all == t2->dst.u.all && 166 t1->dst.protonum == t2->dst.protonum); 167} 168 169static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1, 170 const struct nf_conntrack_tuple *t2) 171{ 172 return __nf_ct_tuple_src_equal(t1, t2) && 173 __nf_ct_tuple_dst_equal(t1, t2); 174} 175 176static inline int 177nf_ct_tuple_mask_equal(const struct nf_conntrack_tuple_mask *m1, 178 const struct nf_conntrack_tuple_mask *m2) 179{ 180 return (nf_inet_addr_cmp(&m1->src.u3, &m2->src.u3) && 181 m1->src.u.all == m2->src.u.all); 182} 183 184static inline int 185nf_ct_tuple_src_mask_cmp(const struct nf_conntrack_tuple *t1, 186 const struct nf_conntrack_tuple *t2, 187 const struct nf_conntrack_tuple_mask *mask) 188{ 189 int count; 190 191 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++) { 192 if ((t1->src.u3.all[count] ^ t2->src.u3.all[count]) & 193 mask->src.u3.all[count]) 194 return 0; 195 } 196 197 if ((t1->src.u.all ^ t2->src.u.all) & mask->src.u.all) 198 return 0; 199 200 if (t1->src.l3num != t2->src.l3num || 201 t1->dst.protonum != t2->dst.protonum) 202 return 0; 203 204 return 1; 205} 206 207static inline int 208nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t, 209 const struct nf_conntrack_tuple *tuple, 210 const struct nf_conntrack_tuple_mask *mask) 211{ 212 return nf_ct_tuple_src_mask_cmp(t, tuple, mask) && 213 __nf_ct_tuple_dst_equal(t, tuple); 214} 215 216#endif /* _NF_CONNTRACK_TUPLE_H */ 217