/* * (C) 2012 by Pablo Neira Ayuso * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation (or any later at your option). * * This code has been sponsored by Vyatta Inc. */ #include "include/helper.h" #include "test.h" #include #include #include #include #include #include #include #include int cthelper_expect_init(struct nf_expect *exp, struct nf_conntrack *master, uint32_t class, union nfct_attr_grp_addr *saddr, union nfct_attr_grp_addr *daddr, uint8_t l4proto, uint16_t *sport, uint16_t *dport, uint32_t flags) { struct nf_conntrack *expected, *mask; expected = nfct_new(); if (!expected) return -1; mask = nfct_new(); if (!mask) return -1; if (saddr) { switch(nfct_get_attr_u8(master, ATTR_L3PROTO)) { int i; uint32_t addr[4] = {}; case AF_INET: nfct_set_attr_u8(expected, ATTR_L3PROTO, AF_INET); nfct_set_attr_u32(expected, ATTR_IPV4_SRC, saddr->ip); nfct_set_attr_u8(mask, ATTR_L3PROTO, AF_INET); nfct_set_attr_u32(mask, ATTR_IPV4_SRC, 0xffffffff); break; case AF_INET6: nfct_set_attr_u8(expected, ATTR_L3PROTO, AF_INET6); nfct_set_attr(expected, ATTR_IPV6_SRC, saddr->ip6); for (i=0; i<4; i++) memset(addr, 0xffffffff, sizeof(uint32_t)); nfct_set_attr_u8(mask, ATTR_L3PROTO, AF_INET6); nfct_set_attr(mask, ATTR_IPV6_SRC, addr); break; default: break; } } else { switch(nfct_get_attr_u8(master, ATTR_L3PROTO)) { int i; uint32_t addr[4] = {}; case AF_INET: nfct_set_attr_u8(expected, ATTR_L3PROTO, AF_INET); nfct_set_attr_u32(expected, ATTR_IPV4_SRC, 0x00000000); nfct_set_attr_u8(mask, ATTR_L3PROTO, AF_INET); nfct_set_attr_u32(mask, ATTR_IPV4_SRC, 0x00000000); break; case AF_INET6: for (i=0; i<4; i++) memset(addr, 0x00000000, sizeof(uint32_t)); nfct_set_attr_u8(expected, ATTR_L3PROTO, AF_INET6); nfct_set_attr(expected, ATTR_IPV6_SRC, addr); nfct_set_attr_u8(mask, ATTR_L3PROTO, AF_INET6); nfct_set_attr(mask, ATTR_IPV6_SRC, addr); break; default: break; } } if (sport) { switch(l4proto) { case IPPROTO_TCP: case IPPROTO_UDP: nfct_set_attr_u8(expected, ATTR_L4PROTO, l4proto); nfct_set_attr_u16(expected, ATTR_PORT_SRC, *sport); nfct_set_attr_u8(mask, ATTR_L4PROTO, l4proto); nfct_set_attr_u16(mask, ATTR_PORT_SRC, 0xffff); break; default: break; } } else { switch(l4proto) { case IPPROTO_TCP: case IPPROTO_UDP: nfct_set_attr_u8(expected, ATTR_L4PROTO, l4proto); nfct_set_attr_u16(expected, ATTR_PORT_SRC, 0x0000); nfct_set_attr_u8(mask, ATTR_L4PROTO, l4proto); nfct_set_attr_u16(mask, ATTR_PORT_SRC, 0x0000); break; default: break; } } switch(nfct_get_attr_u8(master, ATTR_L3PROTO)) { uint32_t addr[4] = {}; int i; case AF_INET: nfct_set_attr_u8(expected, ATTR_L3PROTO, AF_INET); nfct_set_attr_u32(expected, ATTR_IPV4_DST, daddr->ip); nfct_set_attr_u32(mask, ATTR_IPV4_DST, 0xffffffff); break; case AF_INET6: nfct_set_attr_u8(expected, ATTR_L3PROTO, AF_INET6); nfct_set_attr(expected, ATTR_IPV6_DST, daddr->ip6); for (i=0; i<4; i++) memset(addr, 0xffffffff, sizeof(uint32_t)); nfct_set_attr(mask, ATTR_IPV6_DST, addr); break; default: break; } switch(l4proto) { case IPPROTO_TCP: case IPPROTO_UDP: nfct_set_attr_u8(expected, ATTR_L4PROTO, l4proto); nfct_set_attr_u16(expected, ATTR_PORT_DST, *dport); nfct_set_attr_u8(mask, ATTR_L4PROTO, l4proto); nfct_set_attr_u16(mask, ATTR_PORT_DST, 0xffff); break; default: break; } nfexp_set_attr(exp, ATTR_EXP_MASTER, master); nfexp_set_attr(exp, ATTR_EXP_EXPECTED, expected); nfexp_set_attr(exp, ATTR_EXP_MASK, mask); nfct_destroy(expected); nfct_destroy(mask); return 0; } int cthelper_add_expect(struct nf_expect *exp) { cthelper_test_stats.ct_expect_created++; return 0; } int cthelper_del_expect(struct nf_expect *exp) { return 0; } int cthelper_upd_expect(struct nf_expect *exp) { return 0; } int cthelper_upd_ct(struct nf_conntrack *ct) { return 0; } void cthelper_get_addr_src(struct nf_conntrack *ct, int dir, union nfct_attr_grp_addr *addr) { switch (dir) { case MYCT_DIR_ORIG: nfct_get_attr_grp(ct, ATTR_GRP_ORIG_ADDR_SRC, addr); break; case MYCT_DIR_REPL: nfct_get_attr_grp(ct, ATTR_GRP_REPL_ADDR_SRC, addr); break; } } void cthelper_get_addr_dst(struct nf_conntrack *ct, int dir, union nfct_attr_grp_addr *addr) { switch (dir) { case MYCT_DIR_ORIG: nfct_get_attr_grp(ct, ATTR_GRP_ORIG_ADDR_DST, addr); break; case MYCT_DIR_REPL: nfct_get_attr_grp(ct, ATTR_GRP_REPL_ADDR_DST, addr); break; } } int cthelper_cmp_addr_src(struct nf_conntrack *ct, int dir, union nfct_attr_grp_addr *addr) { union nfct_attr_grp_addr tmp; switch (dir) { case MYCT_DIR_ORIG: nfct_get_attr_grp(ct, ATTR_GRP_ORIG_ADDR_SRC, &tmp); break; case MYCT_DIR_REPL: nfct_get_attr_grp(ct, ATTR_GRP_REPL_ADDR_SRC, &tmp); break; } return memcmp(addr, &tmp, sizeof(union nfct_attr_grp_addr)) == 0; } int cthelper_cmp_addr_dst(struct nf_conntrack *ct, int dir, union nfct_attr_grp_addr *addr) { union nfct_attr_grp_addr tmp; switch (dir) { case MYCT_DIR_ORIG: nfct_get_attr_grp(ct, ATTR_GRP_ORIG_ADDR_DST, &tmp); break; case MYCT_DIR_REPL: nfct_get_attr_grp(ct, ATTR_GRP_REPL_ADDR_DST, &tmp); break; } return memcmp(addr, &tmp, sizeof(union nfct_attr_grp_addr)) == 0; } void cthelper_get_port_src(struct nf_conntrack *ct, int dir, uint16_t *port) { switch (dir) { case MYCT_DIR_ORIG: *port = nfct_get_attr_u16(ct, ATTR_PORT_SRC); break; case MYCT_DIR_REPL: *port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC); break; } } void cthelper_get_port_dst(struct nf_conntrack *ct, int dir, uint16_t *port) { switch (dir) { case MYCT_DIR_ORIG: *port = nfct_get_attr_u16(ct, ATTR_PORT_DST); break; case MYCT_DIR_REPL: *port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST); break; } } int cthelper_cmp_exp_addr_dst(struct nf_expect *exp, union nfct_attr_grp_addr *addr) { const struct nf_conntrack *tuple = nfexp_get_attr(exp, ATTR_EXP_EXPECTED); union nfct_attr_grp_addr tmp; cthelper_get_addr_dst((struct nf_conntrack *)tuple, MYCT_DIR_ORIG, &tmp); return memcmp(addr, &tmp, sizeof(union nfct_attr_grp_addr)) == 0; } int cthelper_iterate_exp(struct nf_conntrack *ct, int (*cb)(struct nf_expect *exp, void *data), void *data_cb) { return 0; } struct nf_expect *cthelper_find_expect(union nfct_attr_grp_addr *saddr, union nfct_attr_grp_addr *daddr, uint16_t sport, uint16_t dport, uint8_t l3num, uint8_t l4num, uint16_t zone) { return NULL; }