Home | History | Annotate | Download | only in netfilter_ipv4
      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! */
     17 union 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. */
     40 struct 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. */
     47 struct 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)						\
     95 DEBUGP("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 */
    104 struct ip_conntrack_tuple_hash
    105 {
    106 	struct list_head list;
    107 
    108 	struct ip_conntrack_tuple tuple;
    109 };
    110 
    111 #endif /* __KERNEL__ */
    112 
    113 static 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 
    120 static 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 
    128 static 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 
    134 static 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