Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #ifndef _IP_CONNTRACK_TUPLE_H |
| 2 | #define _IP_CONNTRACK_TUPLE_H |
| 3 | |
| 4 | /* A `tuple' is a structure containing the information to uniquely |
| 5 | identify a connection. ie. if two packets have the same tuple, they |
| 6 | are in the same connection; if not, they are not. |
| 7 | |
| 8 | We divide the structure along "manipulatable" and |
| 9 | "non-manipulatable" lines, for the benefit of the NAT code. |
| 10 | */ |
| 11 | |
| 12 | /* The protocol-specific manipulable parts of the tuple: always in |
| 13 | network order! */ |
| 14 | union ip_conntrack_manip_proto |
| 15 | { |
| 16 | /* Add other protocols here. */ |
| 17 | u_int16_t all; |
| 18 | |
| 19 | struct { |
| 20 | u_int16_t port; |
| 21 | } tcp; |
| 22 | struct { |
| 23 | u_int16_t port; |
| 24 | } udp; |
| 25 | struct { |
| 26 | u_int16_t id; |
| 27 | } icmp; |
| 28 | struct { |
| 29 | u_int16_t port; |
| 30 | } sctp; |
| 31 | }; |
| 32 | |
| 33 | /* The manipulable part of the tuple. */ |
| 34 | struct ip_conntrack_manip |
| 35 | { |
| 36 | u_int32_t ip; |
| 37 | union ip_conntrack_manip_proto u; |
| 38 | }; |
| 39 | |
| 40 | /* This contains the information to distinguish a connection. */ |
| 41 | struct ip_conntrack_tuple |
| 42 | { |
| 43 | struct ip_conntrack_manip src; |
| 44 | |
| 45 | /* These are the parts of the tuple which are fixed. */ |
| 46 | struct { |
| 47 | u_int32_t ip; |
| 48 | union { |
| 49 | /* Add other protocols here. */ |
| 50 | u_int16_t all; |
| 51 | |
| 52 | struct { |
| 53 | u_int16_t port; |
| 54 | } tcp; |
| 55 | struct { |
| 56 | u_int16_t port; |
| 57 | } udp; |
| 58 | struct { |
| 59 | u_int8_t type, code; |
| 60 | } icmp; |
| 61 | struct { |
| 62 | u_int16_t port; |
| 63 | } sctp; |
| 64 | } u; |
| 65 | |
| 66 | /* The protocol. */ |
| 67 | u_int8_t protonum; |
| 68 | |
| 69 | /* The direction (for tuplehash) */ |
| 70 | u_int8_t dir; |
| 71 | } dst; |
| 72 | }; |
| 73 | |
| 74 | /* This is optimized opposed to a memset of the whole structure. Everything we |
| 75 | * really care about is the source/destination unions */ |
| 76 | #define IP_CT_TUPLE_U_BLANK(tuple) \ |
| 77 | do { \ |
| 78 | (tuple)->src.u.all = 0; \ |
| 79 | (tuple)->dst.u.all = 0; \ |
| 80 | } while (0) |
| 81 | |
| 82 | enum ip_conntrack_dir |
| 83 | { |
| 84 | IP_CT_DIR_ORIGINAL, |
| 85 | IP_CT_DIR_REPLY, |
| 86 | IP_CT_DIR_MAX |
| 87 | }; |
| 88 | |
| 89 | #ifdef __KERNEL__ |
| 90 | |
| 91 | #define DUMP_TUPLE(tp) \ |
| 92 | DEBUGP("tuple %p: %u %u.%u.%u.%u:%hu -> %u.%u.%u.%u:%hu\n", \ |
| 93 | (tp), (tp)->dst.protonum, \ |
| 94 | NIPQUAD((tp)->src.ip), ntohs((tp)->src.u.all), \ |
| 95 | NIPQUAD((tp)->dst.ip), ntohs((tp)->dst.u.all)) |
| 96 | |
| 97 | #define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL) |
| 98 | |
| 99 | /* If we're the first tuple, it's the original dir. */ |
| 100 | #define DIRECTION(h) ((enum ip_conntrack_dir)(h)->tuple.dst.dir) |
| 101 | |
| 102 | /* Connections have two entries in the hash table: one for each way */ |
| 103 | struct ip_conntrack_tuple_hash |
| 104 | { |
| 105 | struct list_head list; |
| 106 | |
| 107 | struct ip_conntrack_tuple tuple; |
| 108 | }; |
| 109 | |
| 110 | #endif /* __KERNEL__ */ |
| 111 | |
| 112 | static inline int ip_ct_tuple_src_equal(const struct ip_conntrack_tuple *t1, |
| 113 | const struct ip_conntrack_tuple *t2) |
| 114 | { |
| 115 | return t1->src.ip == t2->src.ip |
| 116 | && t1->src.u.all == t2->src.u.all; |
| 117 | } |
| 118 | |
| 119 | static inline int ip_ct_tuple_dst_equal(const struct ip_conntrack_tuple *t1, |
| 120 | const struct ip_conntrack_tuple *t2) |
| 121 | { |
| 122 | return t1->dst.ip == t2->dst.ip |
| 123 | && t1->dst.u.all == t2->dst.u.all |
| 124 | && t1->dst.protonum == t2->dst.protonum; |
| 125 | } |
| 126 | |
| 127 | static inline int ip_ct_tuple_equal(const struct ip_conntrack_tuple *t1, |
| 128 | const struct ip_conntrack_tuple *t2) |
| 129 | { |
| 130 | return ip_ct_tuple_src_equal(t1, t2) && ip_ct_tuple_dst_equal(t1, t2); |
| 131 | } |
| 132 | |
| 133 | static inline int ip_ct_tuple_mask_cmp(const struct ip_conntrack_tuple *t, |
| 134 | const struct ip_conntrack_tuple *tuple, |
| 135 | const struct ip_conntrack_tuple *mask) |
| 136 | { |
| 137 | return !(((t->src.ip ^ tuple->src.ip) & mask->src.ip) |
| 138 | || ((t->dst.ip ^ tuple->dst.ip) & mask->dst.ip) |
| 139 | || ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all) |
| 140 | || ((t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all) |
| 141 | || ((t->dst.protonum ^ tuple->dst.protonum) |
| 142 | & mask->dst.protonum)); |
| 143 | } |
| 144 | |
| 145 | #endif /* _IP_CONNTRACK_TUPLE_H */ |