1#ifndef _NETWORK_H_ 2#define _NETWORK_H_ 3 4#include <stdint.h> 5#include <sys/types.h> 6 7#define CONNTRACKD_PROTOCOL_VERSION 1 8 9struct nf_conntrack; 10struct nf_expect; 11 12struct nethdr { 13#if __BYTE_ORDER == __LITTLE_ENDIAN 14 uint8_t type:4, 15 version:4; 16#elif __BYTE_ORDER == __BIG_ENDIAN 17 uint8_t version:4, 18 type:4; 19#else 20#error "Unknown system endianess!" 21#endif 22 uint8_t flags; 23 uint16_t len; 24 uint32_t seq; 25}; 26#define NETHDR_SIZ nethdr_align(sizeof(struct nethdr)) 27 28enum nethdr_type { 29 NET_T_STATE_CT_NEW = 0, 30 NET_T_STATE_CT_UPD, 31 NET_T_STATE_CT_DEL, 32 NET_T_STATE_EXP_NEW = 3, 33 NET_T_STATE_EXP_UPD, 34 NET_T_STATE_EXP_DEL, 35 NET_T_STATE_MAX = NET_T_STATE_EXP_DEL, 36 NET_T_CTL = 10, 37}; 38 39int nethdr_align(int len); 40int nethdr_size(int len); 41void nethdr_set(struct nethdr *net, int type); 42void nethdr_set_ack(struct nethdr *net); 43void nethdr_set_ctl(struct nethdr *net); 44 45struct cache_object; 46int object_status_to_network_type(struct cache_object *obj); 47 48#define NETHDR_DATA(x) \ 49 (struct netattr *)(((char *)x) + NETHDR_SIZ) 50#define NETHDR_TAIL(x) \ 51 (struct netattr *)(((char *)x) + x->len) 52 53struct nethdr_ack { 54#if __BYTE_ORDER == __LITTLE_ENDIAN 55 uint8_t type:4, 56 version:4; 57#elif __BYTE_ORDER == __BIG_ENDIAN 58 uint8_t version:4, 59 type:4; 60#else 61#error "Unknown system endianess!" 62#endif 63 uint8_t flags; 64 uint16_t len; 65 uint32_t seq; 66 uint32_t from; 67 uint32_t to; 68}; 69#define NETHDR_ACK_SIZ nethdr_align(sizeof(struct nethdr_ack)) 70 71enum { 72 NET_F_UNUSED = (1 << 0), 73 NET_F_RESYNC = (1 << 1), 74 NET_F_NACK = (1 << 2), 75 NET_F_ACK = (1 << 3), 76 NET_F_ALIVE = (1 << 4), 77 NET_F_HELLO = (1 << 5), 78 NET_F_HELLO_BACK= (1 << 6), 79}; 80 81enum { 82 MSG_DATA, 83 MSG_CTL, 84 MSG_DROP, 85 MSG_BAD, 86}; 87 88#define BUILD_NETMSG_FROM_CT(ct, query) \ 89({ \ 90 static char __net[4096]; \ 91 struct nethdr *__hdr = (struct nethdr *) __net; \ 92 memset(__hdr, 0, NETHDR_SIZ); \ 93 nethdr_set(__hdr, query); \ 94 ct2msg(ct, __hdr); \ 95 HDR_HOST2NETWORK(__hdr); \ 96 __hdr; \ 97}) 98 99#define BUILD_NETMSG_FROM_EXP(exp, query) \ 100({ \ 101 static char __net[4096]; \ 102 struct nethdr *__hdr = (struct nethdr *) __net; \ 103 memset(__hdr, 0, NETHDR_SIZ); \ 104 nethdr_set(__hdr, query); \ 105 exp2msg(exp, __hdr); \ 106 HDR_HOST2NETWORK(__hdr); \ 107 __hdr; \ 108}) 109 110struct mcast_sock_multi; 111 112enum { 113 SEQ_UNKNOWN, 114 SEQ_UNSET, 115 SEQ_IN_SYNC, 116 SEQ_AFTER, 117 SEQ_BEFORE, 118}; 119 120int nethdr_track_seq(uint32_t seq, uint32_t *exp_seq); 121void nethdr_track_update_seq(uint32_t seq); 122int nethdr_track_is_seq_set(void); 123 124struct mcast_conf; 125 126#define IS_DATA(x) (x->type <= NET_T_STATE_MAX && \ 127 (x->flags & ~(NET_F_HELLO | NET_F_HELLO_BACK)) == 0) 128#define IS_ACK(x) (x->type == NET_T_CTL && x->flags & NET_F_ACK) 129#define IS_NACK(x) (x->type == NET_T_CTL && x->flags & NET_F_NACK) 130#define IS_RESYNC(x) (x->type == NET_T_CTL && x->flags & NET_F_RESYNC) 131#define IS_ALIVE(x) (x->type == NET_T_CTL && x->flags & NET_F_ALIVE) 132#define IS_HELLO(x) (x->flags & NET_F_HELLO) 133#define IS_HELLO_BACK(x)(x->flags & NET_F_HELLO_BACK) 134 135#define HDR_NETWORK2HOST(x) \ 136({ \ 137 x->len = ntohs(x->len); \ 138 x->seq = ntohl(x->seq); \ 139 if (IS_ACK(x) || IS_NACK(x) || IS_RESYNC(x)) { \ 140 struct nethdr_ack *__ack = (struct nethdr_ack *) x; \ 141 __ack->from = ntohl(__ack->from); \ 142 __ack->to = ntohl(__ack->to); \ 143 } \ 144}) 145 146#define HDR_HOST2NETWORK(x) \ 147({ \ 148 if (IS_ACK(x) || IS_NACK(x) || IS_RESYNC(x)) { \ 149 struct nethdr_ack *__ack = (struct nethdr_ack *) x; \ 150 __ack->from = htonl(__ack->from); \ 151 __ack->to = htonl(__ack->to); \ 152 } \ 153 x->len = htons(x->len); \ 154 x->seq = htonl(x->seq); \ 155}) 156 157/* extracted from net/tcp.h */ 158 159/* 160 * The next routines deal with comparing 32 bit unsigned ints 161 * and worry about wraparound (automatic with unsigned arithmetic). 162 */ 163 164static inline int before(uint32_t seq1, uint32_t seq2) 165{ 166 return (int32_t)(seq1-seq2) < 0; 167} 168#define after(seq2, seq1) before(seq1, seq2) 169 170/* is s2<=s1<=s3 ? */ 171static inline int between(uint32_t seq1, uint32_t seq2, uint32_t seq3) 172{ 173 return seq3 - seq2 >= seq1 - seq2; 174} 175 176#define PLD_NETWORK2HOST(x) \ 177({ \ 178 x->len = ntohs(x->len); \ 179 x->query = ntohs(x->query); \ 180}) 181 182#define PLD_HOST2NETWORK(x) \ 183({ \ 184 x->len = htons(x->len); \ 185 x->query = htons(x->query); \ 186}) 187 188struct netattr { 189 uint16_t nta_len; 190 uint16_t nta_attr; 191}; 192 193#define ATTR_NETWORK2HOST(x) \ 194({ \ 195 x->nta_len = ntohs(x->nta_len); \ 196 x->nta_attr = ntohs(x->nta_attr); \ 197}) 198 199#define NTA_SIZE(len) NTA_ALIGN(sizeof(struct netattr)) + len 200 201#define NTA_DATA(x) \ 202 (void *)(((char *)x) + NTA_ALIGN(sizeof(struct netattr))) 203 204#define NTA_NEXT(x, len) \ 205( \ 206 len -= NTA_ALIGN(x->nta_len), \ 207 (struct netattr *)(((char *)x) + NTA_ALIGN(x->nta_len)) \ 208) 209 210#define NTA_ALIGNTO 4 211#define NTA_ALIGN(len) (((len) + NTA_ALIGNTO - 1) & ~(NTA_ALIGNTO - 1)) 212#define NTA_LENGTH(len) (NTA_ALIGN(sizeof(struct netattr)) + (len)) 213 214enum nta_attr { 215 NTA_IPV4 = 0, /* struct nfct_attr_grp_ipv4 */ 216 NTA_IPV6, /* struct nfct_attr_grp_ipv6 */ 217 NTA_L4PROTO, /* uint8_t */ 218 NTA_PORT, /* struct nfct_attr_grp_port */ 219 NTA_TCP_STATE = 4, /* uint8_t */ 220 NTA_STATUS, /* uint32_t */ 221 NTA_TIMEOUT, /* uint32_t */ 222 NTA_MARK, /* uint32_t */ 223 NTA_MASTER_IPV4 = 8, /* struct nfct_attr_grp_ipv4 */ 224 NTA_MASTER_IPV6, /* struct nfct_attr_grp_ipv6 */ 225 NTA_MASTER_L4PROTO, /* uint8_t */ 226 NTA_MASTER_PORT, /* struct nfct_attr_grp_port */ 227 NTA_SNAT_IPV4 = 12, /* uint32_t */ 228 NTA_DNAT_IPV4, /* uint32_t */ 229 NTA_SPAT_PORT, /* uint16_t */ 230 NTA_DPAT_PORT, /* uint16_t */ 231 NTA_NAT_SEQ_ADJ = 16, /* struct nta_attr_natseqadj */ 232 NTA_SCTP_STATE, /* uint8_t */ 233 NTA_SCTP_VTAG_ORIG, /* uint32_t */ 234 NTA_SCTP_VTAG_REPL, /* uint32_t */ 235 NTA_DCCP_STATE = 20, /* uint8_t */ 236 NTA_DCCP_ROLE, /* uint8_t */ 237 NTA_ICMP_TYPE, /* uint8_t */ 238 NTA_ICMP_CODE, /* uint8_t */ 239 NTA_ICMP_ID, /* uint16_t */ 240 NTA_TCP_WSCALE_ORIG, /* uint8_t */ 241 NTA_TCP_WSCALE_REPL, /* uint8_t */ 242 NTA_HELPER_NAME, /* string (variable length) */ 243 NTA_MAX 244}; 245 246struct nta_attr_natseqadj { 247 uint32_t orig_seq_correction_pos; 248 uint32_t orig_seq_offset_before; 249 uint32_t orig_seq_offset_after; 250 uint32_t repl_seq_correction_pos; 251 uint32_t repl_seq_offset_before; 252 uint32_t repl_seq_offset_after; 253}; 254 255void ct2msg(const struct nf_conntrack *ct, struct nethdr *n); 256int msg2ct(struct nf_conntrack *ct, struct nethdr *n, size_t remain); 257 258enum nta_exp_attr { 259 NTA_EXP_MASTER_IPV4 = 0, /* struct nfct_attr_grp_ipv4 */ 260 NTA_EXP_MASTER_IPV6, /* struct nfct_attr_grp_ipv6 */ 261 NTA_EXP_MASTER_L4PROTO, /* uint8_t */ 262 NTA_EXP_MASTER_PORT, /* struct nfct_attr_grp_port */ 263 NTA_EXP_EXPECT_IPV4 = 4, /* struct nfct_attr_grp_ipv4 */ 264 NTA_EXP_EXPECT_IPV6, /* struct nfct_attr_grp_ipv6 */ 265 NTA_EXP_EXPECT_L4PROTO, /* uint8_t */ 266 NTA_EXP_EXPECT_PORT, /* struct nfct_attr_grp_port */ 267 NTA_EXP_MASK_IPV4 = 8, /* struct nfct_attr_grp_ipv4 */ 268 NTA_EXP_MASK_IPV6, /* struct nfct_attr_grp_ipv6 */ 269 NTA_EXP_MASK_L4PROTO, /* uint8_t */ 270 NTA_EXP_MASK_PORT, /* struct nfct_attr_grp_port */ 271 NTA_EXP_TIMEOUT, /* uint32_t */ 272 NTA_EXP_FLAGS, /* uint32_t */ 273 NTA_EXP_CLASS, /* uint32_t */ 274 NTA_EXP_NAT_IPV4, /* struct nfct_attr_grp_ipv4 */ 275 NTA_EXP_NAT_PORT, /* struct nfct_attr_grp_port */ 276 NTA_EXP_NAT_L4PROTO, /* uint8_t */ 277 NTA_EXP_NAT_DIR, /* uint32_t */ 278 NTA_EXP_HELPER_NAME, /* string (variable length) */ 279 NTA_EXP_FN, /* string (variable length) */ 280 NTA_EXP_MAX 281}; 282 283void exp2msg(const struct nf_expect *exp, struct nethdr *n); 284int msg2exp(struct nf_expect *exp, struct nethdr *n, size_t remain); 285 286#endif 287