/* * (C) 2006-2008 by Pablo Neira Ayuso * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. */ #include "internal/internal.h" #include #include static const u_int8_t invmap_icmp[] = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1, [ICMP_ECHOREPLY] = ICMP_ECHO + 1, [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1, [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1, [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1, [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1, [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1 }; #ifndef ICMPV6_NI_QUERY #define ICMPV6_NI_QUERY 139 #endif #ifndef ICMPV6_NI_REPLY #define ICMPV6_NI_REPLY 140 #endif static u_int8_t invmap_icmpv6[] = { [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1, [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1, [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1, [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY + 1 }; static void set_attr_orig_ipv4_src(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_ORIG].src.v4 = *((u_int32_t *) value); } static void set_attr_orig_ipv4_dst(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_ORIG].dst.v4 = *((u_int32_t *) value); } static void set_attr_repl_ipv4_src(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_REPL].src.v4 = *((u_int32_t *) value); } static void set_attr_repl_ipv4_dst(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_REPL].dst.v4 = *((u_int32_t *) value); } static void set_attr_orig_ipv6_src(struct nf_conntrack *ct, const void *value) { memcpy(&ct->tuple[__DIR_ORIG].src.v6, value, sizeof(u_int32_t)*4); } static void set_attr_orig_ipv6_dst(struct nf_conntrack *ct, const void *value) { memcpy(&ct->tuple[__DIR_ORIG].dst.v6, value, sizeof(u_int32_t)*4); } static void set_attr_repl_ipv6_src(struct nf_conntrack *ct, const void *value) { memcpy(&ct->tuple[__DIR_REPL].src.v6, value, sizeof(u_int32_t)*4); } static void set_attr_repl_ipv6_dst(struct nf_conntrack *ct, const void *value) { memcpy(&ct->tuple[__DIR_REPL].dst.v6, value, sizeof(u_int32_t)*4); } static void set_attr_orig_port_src(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_ORIG].l4src.all = *((u_int16_t *) value); } static void set_attr_orig_port_dst(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_ORIG].l4dst.all = *((u_int16_t *) value); } static void set_attr_repl_port_src(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_REPL].l4src.all = *((u_int16_t *) value); } static void set_attr_repl_port_dst(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_REPL].l4dst.all = *((u_int16_t *) value); } static void set_attr_icmp_type(struct nf_conntrack *ct, const void *value) { u_int8_t rtype; ct->tuple[__DIR_ORIG].l4dst.icmp.type = *((u_int8_t *) value); switch(ct->tuple[__DIR_ORIG].l3protonum) { case AF_INET: rtype = invmap_icmp[*((u_int8_t *) value)]; break; case AF_INET6: rtype = invmap_icmpv6[*((u_int8_t *) value) - 128]; break; default: rtype = 0; /* not found */ } if (rtype) ct->tuple[__DIR_REPL].l4dst.icmp.type = rtype - 1; else ct->tuple[__DIR_REPL].l4dst.icmp.type = 255; /* will fail with -EINVAL */ } static void set_attr_icmp_code(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_ORIG].l4dst.icmp.code = *((u_int8_t *) value); ct->tuple[__DIR_REPL].l4dst.icmp.code = *((u_int8_t *) value); } static void set_attr_icmp_id(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_ORIG].l4src.icmp.id = *((u_int16_t *) value); ct->tuple[__DIR_REPL].l4src.icmp.id = *((u_int16_t *) value); } static void set_attr_orig_l3proto(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_ORIG].l3protonum = *((u_int8_t *) value); } static void set_attr_repl_l3proto(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_REPL].l3protonum = *((u_int8_t *) value); } static void set_attr_orig_l4proto(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_ORIG].protonum = *((u_int8_t *) value); } static void set_attr_repl_l4proto(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_REPL].protonum = *((u_int8_t *) value); } static void set_attr_tcp_state(struct nf_conntrack *ct, const void *value) { ct->protoinfo.tcp.state = *((u_int8_t *) value); } static void set_attr_tcp_flags_orig(struct nf_conntrack *ct, const void *value) { ct->protoinfo.tcp.flags[__DIR_ORIG].value = *((u_int8_t *) value); } static void set_attr_tcp_mask_orig(struct nf_conntrack *ct, const void *value) { ct->protoinfo.tcp.flags[__DIR_ORIG].mask = *((u_int8_t *) value); } static void set_attr_tcp_flags_repl(struct nf_conntrack *ct, const void *value) { ct->protoinfo.tcp.flags[__DIR_REPL].value = *((u_int8_t *) value); } static void set_attr_tcp_mask_repl(struct nf_conntrack *ct, const void *value) { ct->protoinfo.tcp.flags[__DIR_REPL].mask = *((u_int8_t *) value); } static void set_attr_sctp_state(struct nf_conntrack *ct, const void *value) { ct->protoinfo.sctp.state = *((u_int8_t *) value); } static void set_attr_sctp_vtag_orig(struct nf_conntrack *ct, const void *value) { ct->protoinfo.sctp.vtag[__DIR_ORIG] = *((u_int32_t *) value); } static void set_attr_sctp_vtag_repl(struct nf_conntrack *ct, const void *value) { ct->protoinfo.sctp.vtag[__DIR_REPL] = *((u_int32_t *) value); } static void set_attr_snat_ipv4(struct nf_conntrack *ct, const void *value) { ct->snat.min_ip = ct->snat.max_ip = *((u_int32_t *) value); } static void set_attr_dnat_ipv4(struct nf_conntrack *ct, const void *value) { ct->dnat.min_ip = ct->snat.max_ip = *((u_int32_t *) value); } static void set_attr_snat_port(struct nf_conntrack *ct, const void *value) { ct->snat.l4min.all = ct->snat.l4max.all = *((u_int16_t *) value); } static void set_attr_dnat_port(struct nf_conntrack *ct, const void *value) { ct->dnat.l4min.all = ct->dnat.l4max.all = *((u_int16_t *) value); } static void set_attr_timeout(struct nf_conntrack *ct, const void *value) { ct->timeout = *((u_int32_t *) value); } static void set_attr_mark(struct nf_conntrack *ct, const void *value) { ct->mark = *((u_int32_t *) value); } static void set_attr_secmark(struct nf_conntrack *ct, const void *value) { ct->secmark = *((u_int32_t *) value); } static void set_attr_status(struct nf_conntrack *ct, const void *value) { ct->status = *((u_int32_t *) value); } static void set_attr_id(struct nf_conntrack *ct, const void *value) { ct->id = *((u_int32_t *) value); } static void set_attr_master_ipv4_src(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_MASTER].src.v4 = *((u_int32_t *) value); } static void set_attr_master_ipv4_dst(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_MASTER].dst.v4 = *((u_int32_t *) value); } static void set_attr_master_ipv6_src(struct nf_conntrack *ct, const void *value) { memcpy(&ct->tuple[__DIR_MASTER].dst.v6, value, sizeof(u_int32_t)*4); } static void set_attr_master_ipv6_dst(struct nf_conntrack *ct, const void *value) { memcpy(&ct->tuple[__DIR_MASTER].src.v6, value, sizeof(u_int32_t)*4); } static void set_attr_master_port_src(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_MASTER].l4src.all = *((u_int16_t *) value); } static void set_attr_master_port_dst(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_MASTER].l4dst.all = *((u_int16_t *) value); } static void set_attr_master_l3proto(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_MASTER].l3protonum = *((u_int8_t *) value); } static void set_attr_master_l4proto(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_MASTER].protonum = *((u_int8_t *) value); } static void set_attr_orig_cor_pos(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_ORIG].natseq.correction_pos = *((u_int32_t *) value); } static void set_attr_orig_off_bfr(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_ORIG].natseq.offset_before = *((u_int32_t *) value); } static void set_attr_orig_off_aft(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_ORIG].natseq.offset_after = *((u_int32_t *) value); } static void set_attr_repl_cor_pos(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_REPL].natseq.correction_pos = *((u_int32_t *) value); } static void set_attr_repl_off_bfr(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_REPL].natseq.offset_before = *((u_int32_t *) value); } static void set_attr_repl_off_aft(struct nf_conntrack *ct, const void *value) { ct->tuple[__DIR_REPL].natseq.offset_after = *((u_int32_t *) value); } static void set_attr_helper_name(struct nf_conntrack *ct, const void *value) { strncpy(ct->helper_name, value, __NFCT_HELPER_NAMELEN); ct->helper_name[__NFCT_HELPER_NAMELEN-1] = '\0'; } static void set_attr_dccp_state(struct nf_conntrack *ct, const void *value) { ct->protoinfo.dccp.state = *((u_int8_t *) value); } static void set_attr_dccp_role(struct nf_conntrack *ct, const void *value) { ct->protoinfo.dccp.role = *((u_int8_t *) value); } static void set_attr_dccp_handshake_seq(struct nf_conntrack *ct, const void *value) { ct->protoinfo.dccp.handshake_seq = *((u_int64_t *) value); } static void set_attr_do_nothing(struct nf_conntrack *ct, const void *value) {} set_attr set_attr_array[ATTR_MAX] = { [ATTR_ORIG_IPV4_SRC] = set_attr_orig_ipv4_src, [ATTR_ORIG_IPV4_DST] = set_attr_orig_ipv4_dst, [ATTR_REPL_IPV4_SRC] = set_attr_repl_ipv4_src, [ATTR_REPL_IPV4_DST] = set_attr_repl_ipv4_dst, [ATTR_ORIG_IPV6_SRC] = set_attr_orig_ipv6_src, [ATTR_ORIG_IPV6_DST] = set_attr_orig_ipv6_dst, [ATTR_REPL_IPV6_SRC] = set_attr_repl_ipv6_src, [ATTR_REPL_IPV6_DST] = set_attr_repl_ipv6_dst, [ATTR_ORIG_PORT_SRC] = set_attr_orig_port_src, [ATTR_ORIG_PORT_DST] = set_attr_orig_port_dst, [ATTR_REPL_PORT_SRC] = set_attr_repl_port_src, [ATTR_REPL_PORT_DST] = set_attr_repl_port_dst, [ATTR_ICMP_TYPE] = set_attr_icmp_type, [ATTR_ICMP_CODE] = set_attr_icmp_code, [ATTR_ICMP_ID] = set_attr_icmp_id, [ATTR_ORIG_L3PROTO] = set_attr_orig_l3proto, [ATTR_REPL_L3PROTO] = set_attr_repl_l3proto, [ATTR_ORIG_L4PROTO] = set_attr_orig_l4proto, [ATTR_REPL_L4PROTO] = set_attr_repl_l4proto, [ATTR_TCP_STATE] = set_attr_tcp_state, [ATTR_SNAT_IPV4] = set_attr_snat_ipv4, [ATTR_DNAT_IPV4] = set_attr_dnat_ipv4, [ATTR_SNAT_PORT] = set_attr_snat_port, [ATTR_DNAT_PORT] = set_attr_dnat_port, [ATTR_TIMEOUT] = set_attr_timeout, [ATTR_MARK] = set_attr_mark, [ATTR_ORIG_COUNTER_PACKETS] = set_attr_do_nothing, [ATTR_REPL_COUNTER_PACKETS] = set_attr_do_nothing, [ATTR_ORIG_COUNTER_BYTES] = set_attr_do_nothing, [ATTR_REPL_COUNTER_BYTES] = set_attr_do_nothing, [ATTR_USE] = set_attr_do_nothing, [ATTR_ID] = set_attr_id, [ATTR_STATUS] = set_attr_status, [ATTR_TCP_FLAGS_ORIG] = set_attr_tcp_flags_orig, [ATTR_TCP_FLAGS_REPL] = set_attr_tcp_flags_repl, [ATTR_TCP_MASK_ORIG] = set_attr_tcp_mask_orig, [ATTR_TCP_MASK_REPL] = set_attr_tcp_mask_repl, [ATTR_MASTER_IPV4_SRC] = set_attr_master_ipv4_src, [ATTR_MASTER_IPV4_DST] = set_attr_master_ipv4_dst, [ATTR_MASTER_IPV6_SRC] = set_attr_master_ipv6_src, [ATTR_MASTER_IPV6_DST] = set_attr_master_ipv6_dst, [ATTR_MASTER_PORT_SRC] = set_attr_master_port_src, [ATTR_MASTER_PORT_DST] = set_attr_master_port_dst, [ATTR_MASTER_L3PROTO] = set_attr_master_l3proto, [ATTR_MASTER_L4PROTO] = set_attr_master_l4proto, [ATTR_SECMARK] = set_attr_secmark, [ATTR_ORIG_NAT_SEQ_CORRECTION_POS] = set_attr_orig_cor_pos, [ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE] = set_attr_orig_off_aft, [ATTR_ORIG_NAT_SEQ_OFFSET_AFTER] = set_attr_orig_off_bfr, [ATTR_REPL_NAT_SEQ_CORRECTION_POS] = set_attr_repl_cor_pos, [ATTR_REPL_NAT_SEQ_OFFSET_BEFORE] = set_attr_repl_off_aft, [ATTR_REPL_NAT_SEQ_OFFSET_AFTER] = set_attr_repl_off_bfr, [ATTR_SCTP_STATE] = set_attr_sctp_state, [ATTR_SCTP_VTAG_ORIG] = set_attr_sctp_vtag_orig, [ATTR_SCTP_VTAG_REPL] = set_attr_sctp_vtag_repl, [ATTR_HELPER_NAME] = set_attr_helper_name, [ATTR_DCCP_STATE] = set_attr_dccp_state, [ATTR_DCCP_ROLE] = set_attr_dccp_role, [ATTR_DCCP_HANDSHAKE_SEQ] = set_attr_dccp_handshake_seq, };