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