| #ifndef _NETWORK_H_ |
| #define _NETWORK_H_ |
| |
| #include <stdint.h> |
| #include <sys/types.h> |
| |
| #define CONNTRACKD_PROTOCOL_VERSION 1 |
| |
| struct nf_conntrack; |
| struct nf_expect; |
| |
| struct nethdr { |
| #if __BYTE_ORDER == __LITTLE_ENDIAN |
| uint8_t type:4, |
| version:4; |
| #elif __BYTE_ORDER == __BIG_ENDIAN |
| uint8_t version:4, |
| type:4; |
| #else |
| #error "Unknown system endianess!" |
| #endif |
| uint8_t flags; |
| uint16_t len; |
| uint32_t seq; |
| }; |
| #define NETHDR_SIZ nethdr_align(sizeof(struct nethdr)) |
| |
| enum nethdr_type { |
| NET_T_STATE_CT_NEW = 0, |
| NET_T_STATE_CT_UPD, |
| NET_T_STATE_CT_DEL, |
| NET_T_STATE_EXP_NEW = 3, |
| NET_T_STATE_EXP_UPD, |
| NET_T_STATE_EXP_DEL, |
| NET_T_STATE_MAX = NET_T_STATE_EXP_DEL, |
| NET_T_CTL = 10, |
| }; |
| |
| int nethdr_align(int len); |
| int nethdr_size(int len); |
| void nethdr_set(struct nethdr *net, int type); |
| void nethdr_set_ack(struct nethdr *net); |
| void nethdr_set_ctl(struct nethdr *net); |
| |
| struct cache_object; |
| int object_status_to_network_type(struct cache_object *obj); |
| |
| #define NETHDR_DATA(x) \ |
| (struct netattr *)(((char *)x) + NETHDR_SIZ) |
| #define NETHDR_TAIL(x) \ |
| (struct netattr *)(((char *)x) + x->len) |
| |
| struct nethdr_ack { |
| #if __BYTE_ORDER == __LITTLE_ENDIAN |
| uint8_t type:4, |
| version:4; |
| #elif __BYTE_ORDER == __BIG_ENDIAN |
| uint8_t version:4, |
| type:4; |
| #else |
| #error "Unknown system endianess!" |
| #endif |
| uint8_t flags; |
| uint16_t len; |
| uint32_t seq; |
| uint32_t from; |
| uint32_t to; |
| }; |
| #define NETHDR_ACK_SIZ nethdr_align(sizeof(struct nethdr_ack)) |
| |
| enum { |
| NET_F_UNUSED = (1 << 0), |
| NET_F_RESYNC = (1 << 1), |
| NET_F_NACK = (1 << 2), |
| NET_F_ACK = (1 << 3), |
| NET_F_ALIVE = (1 << 4), |
| NET_F_HELLO = (1 << 5), |
| NET_F_HELLO_BACK= (1 << 6), |
| }; |
| |
| enum { |
| MSG_DATA, |
| MSG_CTL, |
| MSG_DROP, |
| MSG_BAD, |
| }; |
| |
| #define BUILD_NETMSG_FROM_CT(ct, query) \ |
| ({ \ |
| static char __net[4096]; \ |
| struct nethdr *__hdr = (struct nethdr *) __net; \ |
| memset(__hdr, 0, NETHDR_SIZ); \ |
| nethdr_set(__hdr, query); \ |
| ct2msg(ct, __hdr); \ |
| HDR_HOST2NETWORK(__hdr); \ |
| __hdr; \ |
| }) |
| |
| #define BUILD_NETMSG_FROM_EXP(exp, query) \ |
| ({ \ |
| static char __net[4096]; \ |
| struct nethdr *__hdr = (struct nethdr *) __net; \ |
| memset(__hdr, 0, NETHDR_SIZ); \ |
| nethdr_set(__hdr, query); \ |
| exp2msg(exp, __hdr); \ |
| HDR_HOST2NETWORK(__hdr); \ |
| __hdr; \ |
| }) |
| |
| struct mcast_sock_multi; |
| |
| enum { |
| SEQ_UNKNOWN, |
| SEQ_UNSET, |
| SEQ_IN_SYNC, |
| SEQ_AFTER, |
| SEQ_BEFORE, |
| }; |
| |
| int nethdr_track_seq(uint32_t seq, uint32_t *exp_seq); |
| void nethdr_track_update_seq(uint32_t seq); |
| int nethdr_track_is_seq_set(void); |
| |
| struct mcast_conf; |
| |
| #define IS_DATA(x) (x->type <= NET_T_STATE_MAX && \ |
| (x->flags & ~(NET_F_HELLO | NET_F_HELLO_BACK)) == 0) |
| #define IS_ACK(x) (x->type == NET_T_CTL && x->flags & NET_F_ACK) |
| #define IS_NACK(x) (x->type == NET_T_CTL && x->flags & NET_F_NACK) |
| #define IS_RESYNC(x) (x->type == NET_T_CTL && x->flags & NET_F_RESYNC) |
| #define IS_ALIVE(x) (x->type == NET_T_CTL && x->flags & NET_F_ALIVE) |
| #define IS_HELLO(x) (x->flags & NET_F_HELLO) |
| #define IS_HELLO_BACK(x)(x->flags & NET_F_HELLO_BACK) |
| |
| #define HDR_NETWORK2HOST(x) \ |
| ({ \ |
| x->len = ntohs(x->len); \ |
| x->seq = ntohl(x->seq); \ |
| if (IS_ACK(x) || IS_NACK(x) || IS_RESYNC(x)) { \ |
| struct nethdr_ack *__ack = (struct nethdr_ack *) x; \ |
| __ack->from = ntohl(__ack->from); \ |
| __ack->to = ntohl(__ack->to); \ |
| } \ |
| }) |
| |
| #define HDR_HOST2NETWORK(x) \ |
| ({ \ |
| if (IS_ACK(x) || IS_NACK(x) || IS_RESYNC(x)) { \ |
| struct nethdr_ack *__ack = (struct nethdr_ack *) x; \ |
| __ack->from = htonl(__ack->from); \ |
| __ack->to = htonl(__ack->to); \ |
| } \ |
| x->len = htons(x->len); \ |
| x->seq = htonl(x->seq); \ |
| }) |
| |
| /* extracted from net/tcp.h */ |
| |
| /* |
| * The next routines deal with comparing 32 bit unsigned ints |
| * and worry about wraparound (automatic with unsigned arithmetic). |
| */ |
| |
| static inline int before(uint32_t seq1, uint32_t seq2) |
| { |
| return (int32_t)(seq1-seq2) < 0; |
| } |
| #define after(seq2, seq1) before(seq1, seq2) |
| |
| /* is s2<=s1<=s3 ? */ |
| static inline int between(uint32_t seq1, uint32_t seq2, uint32_t seq3) |
| { |
| return seq3 - seq2 >= seq1 - seq2; |
| } |
| |
| struct netattr { |
| uint16_t nta_len; |
| uint16_t nta_attr; |
| }; |
| |
| #define ATTR_NETWORK2HOST(x) \ |
| ({ \ |
| x->nta_len = ntohs(x->nta_len); \ |
| x->nta_attr = ntohs(x->nta_attr); \ |
| }) |
| |
| #define NTA_SIZE(len) NTA_ALIGN(sizeof(struct netattr)) + len |
| |
| #define NTA_DATA(x) \ |
| (void *)(((char *)x) + NTA_ALIGN(sizeof(struct netattr))) |
| |
| #define NTA_NEXT(x, len) \ |
| ( \ |
| len -= NTA_ALIGN(x->nta_len), \ |
| (struct netattr *)(((char *)x) + NTA_ALIGN(x->nta_len)) \ |
| ) |
| |
| #define NTA_ALIGNTO 4 |
| #define NTA_ALIGN(len) (((len) + NTA_ALIGNTO - 1) & ~(NTA_ALIGNTO - 1)) |
| #define NTA_LENGTH(len) (NTA_ALIGN(sizeof(struct netattr)) + (len)) |
| |
| enum nta_attr { |
| NTA_IPV4 = 0, /* struct nfct_attr_grp_ipv4 */ |
| NTA_IPV6, /* struct nfct_attr_grp_ipv6 */ |
| NTA_L4PROTO, /* uint8_t */ |
| NTA_PORT, /* struct nfct_attr_grp_port */ |
| NTA_TCP_STATE = 4, /* uint8_t */ |
| NTA_STATUS, /* uint32_t */ |
| NTA_TIMEOUT, /* uint32_t */ |
| NTA_MARK, /* uint32_t */ |
| NTA_MASTER_IPV4 = 8, /* struct nfct_attr_grp_ipv4 */ |
| NTA_MASTER_IPV6, /* struct nfct_attr_grp_ipv6 */ |
| NTA_MASTER_L4PROTO, /* uint8_t */ |
| NTA_MASTER_PORT, /* struct nfct_attr_grp_port */ |
| NTA_SNAT_IPV4 = 12, /* uint32_t */ |
| NTA_DNAT_IPV4, /* uint32_t */ |
| NTA_SPAT_PORT, /* uint16_t */ |
| NTA_DPAT_PORT, /* uint16_t */ |
| NTA_NAT_SEQ_ADJ = 16, /* struct nta_attr_natseqadj */ |
| NTA_SCTP_STATE, /* uint8_t */ |
| NTA_SCTP_VTAG_ORIG, /* uint32_t */ |
| NTA_SCTP_VTAG_REPL, /* uint32_t */ |
| NTA_DCCP_STATE = 20, /* uint8_t */ |
| NTA_DCCP_ROLE, /* uint8_t */ |
| NTA_ICMP_TYPE, /* uint8_t */ |
| NTA_ICMP_CODE, /* uint8_t */ |
| NTA_ICMP_ID, /* uint16_t */ |
| NTA_TCP_WSCALE_ORIG, /* uint8_t */ |
| NTA_TCP_WSCALE_REPL, /* uint8_t */ |
| NTA_HELPER_NAME, /* string (variable length) */ |
| NTA_LABELS, /* array of uint32_t (variable length) */ |
| NTA_SNAT_IPV6, /* uint32_t * 4 */ |
| NTA_DNAT_IPV6, /* uint32_t * 4 */ |
| NTA_MAX |
| }; |
| |
| /* allow to serialize/replicate up to 4k labels per flow */ |
| #define NTA_LABELS_MAX_SIZE (4096/sizeof(uint32_t)) |
| |
| struct nta_attr_natseqadj { |
| uint32_t orig_seq_correction_pos; |
| uint32_t orig_seq_offset_before; |
| uint32_t orig_seq_offset_after; |
| uint32_t repl_seq_correction_pos; |
| uint32_t repl_seq_offset_before; |
| uint32_t repl_seq_offset_after; |
| }; |
| |
| void ct2msg(const struct nf_conntrack *ct, struct nethdr *n); |
| int msg2ct(struct nf_conntrack *ct, struct nethdr *n, size_t remain); |
| |
| enum nta_exp_attr { |
| NTA_EXP_MASTER_IPV4 = 0, /* struct nfct_attr_grp_ipv4 */ |
| NTA_EXP_MASTER_IPV6, /* struct nfct_attr_grp_ipv6 */ |
| NTA_EXP_MASTER_L4PROTO, /* uint8_t */ |
| NTA_EXP_MASTER_PORT, /* struct nfct_attr_grp_port */ |
| NTA_EXP_EXPECT_IPV4 = 4, /* struct nfct_attr_grp_ipv4 */ |
| NTA_EXP_EXPECT_IPV6, /* struct nfct_attr_grp_ipv6 */ |
| NTA_EXP_EXPECT_L4PROTO, /* uint8_t */ |
| NTA_EXP_EXPECT_PORT, /* struct nfct_attr_grp_port */ |
| NTA_EXP_MASK_IPV4 = 8, /* struct nfct_attr_grp_ipv4 */ |
| NTA_EXP_MASK_IPV6, /* struct nfct_attr_grp_ipv6 */ |
| NTA_EXP_MASK_L4PROTO, /* uint8_t */ |
| NTA_EXP_MASK_PORT, /* struct nfct_attr_grp_port */ |
| NTA_EXP_TIMEOUT, /* uint32_t */ |
| NTA_EXP_FLAGS, /* uint32_t */ |
| NTA_EXP_CLASS, /* uint32_t */ |
| NTA_EXP_NAT_IPV4, /* struct nfct_attr_grp_ipv4 */ |
| NTA_EXP_NAT_PORT, /* struct nfct_attr_grp_port */ |
| NTA_EXP_NAT_L4PROTO, /* uint8_t */ |
| NTA_EXP_NAT_DIR, /* uint32_t */ |
| NTA_EXP_HELPER_NAME, /* string (variable length) */ |
| NTA_EXP_FN, /* string (variable length) */ |
| NTA_EXP_MAX |
| }; |
| |
| void exp2msg(const struct nf_expect *exp, struct nethdr *n); |
| int msg2exp(struct nf_expect *exp, struct nethdr *n, size_t remain); |
| |
| #endif |