1/* 2 * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org> 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 */ 9 10#include "internal/internal.h" 11#include <linux/icmp.h> 12#include <linux/icmpv6.h> 13 14static const uint8_t invmap_icmp[] = { 15 [ICMP_ECHO] = ICMP_ECHOREPLY + 1, 16 [ICMP_ECHOREPLY] = ICMP_ECHO + 1, 17 [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, 18 [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1, 19 [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1, 20 [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1, 21 [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1, 22 [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1 23}; 24 25#ifndef ICMPV6_NI_QUERY 26#define ICMPV6_NI_QUERY 139 27#endif 28 29#ifndef ICMPV6_NI_REPLY 30#define ICMPV6_NI_REPLY 140 31#endif 32 33static const uint8_t invmap_icmpv6[] = { 34 [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1, 35 [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1, 36 [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1, 37 [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY + 1 38}; 39 40static void set_attr_grp_orig_ipv4(struct nf_conntrack *ct, const void *value) 41{ 42 const struct nfct_attr_grp_ipv4 *this = value; 43 ct->head.orig.src.v4 = this->src; 44 ct->head.orig.dst.v4 = this->dst; 45 ct->head.orig.l3protonum = AF_INET; 46} 47 48static void set_attr_grp_repl_ipv4(struct nf_conntrack *ct, const void *value) 49{ 50 const struct nfct_attr_grp_ipv4 *this = value; 51 ct->repl.src.v4 = this->src; 52 ct->repl.dst.v4 = this->dst; 53 ct->repl.l3protonum = AF_INET; 54} 55 56static void set_attr_grp_orig_ipv6(struct nf_conntrack *ct, const void *value) 57{ 58 const struct nfct_attr_grp_ipv6 *this = value; 59 memcpy(&ct->head.orig.src.v6, this->src, sizeof(uint32_t)*4); 60 memcpy(&ct->head.orig.dst.v6, this->dst, sizeof(uint32_t)*4); 61 ct->head.orig.l3protonum = AF_INET6; 62} 63 64static void set_attr_grp_repl_ipv6(struct nf_conntrack *ct, const void *value) 65{ 66 const struct nfct_attr_grp_ipv6 *this = value; 67 memcpy(&ct->repl.src.v6, this->src, sizeof(uint32_t)*4); 68 memcpy(&ct->repl.dst.v6, this->dst, sizeof(uint32_t)*4); 69 ct->repl.l3protonum = AF_INET6; 70} 71 72static void set_attr_grp_orig_port(struct nf_conntrack *ct, const void *value) 73{ 74 const struct nfct_attr_grp_port *this = value; 75 ct->head.orig.l4src.all = this->sport; 76 ct->head.orig.l4dst.all = this->dport; 77} 78 79static void set_attr_grp_repl_port(struct nf_conntrack *ct, const void *value) 80{ 81 const struct nfct_attr_grp_port *this = value; 82 ct->repl.l4src.all = this->sport; 83 ct->repl.l4dst.all = this->dport; 84} 85 86static void set_attr_grp_icmp(struct nf_conntrack *ct, const void *value) 87{ 88 uint8_t rtype; 89 const struct nfct_attr_grp_icmp *this = value; 90 91 ct->head.orig.l4dst.icmp.type = this->type; 92 93 switch(ct->head.orig.l3protonum) { 94 case AF_INET: 95 rtype = invmap_icmp[this->type]; 96 break; 97 98 case AF_INET6: 99 rtype = invmap_icmpv6[this->type - 128]; 100 break; 101 102 default: 103 rtype = 0; /* not found */ 104 } 105 106 if (rtype) 107 ct->repl.l4dst.icmp.type = rtype - 1; 108 else 109 ct->repl.l4dst.icmp.type = 255; /* -EINVAL */ 110 111 ct->head.orig.l4dst.icmp.code = this->code; 112 ct->repl.l4dst.icmp.code = this->code; 113 114 ct->head.orig.l4src.icmp.id = this->id; 115 ct->repl.l4src.icmp.id = this->id; 116} 117 118static void set_attr_grp_master_ipv4(struct nf_conntrack *ct, const void *value) 119{ 120 const struct nfct_attr_grp_ipv4 *this = value; 121 ct->master.src.v4 = this->src; 122 ct->master.dst.v4 = this->dst; 123 ct->master.l3protonum = AF_INET; 124} 125 126static void set_attr_grp_master_ipv6(struct nf_conntrack *ct, const void *value) 127{ 128 const struct nfct_attr_grp_ipv6 *this = value; 129 memcpy(&ct->master.src.v6, this->src, sizeof(uint32_t)*4); 130 memcpy(&ct->master.dst.v6, this->dst, sizeof(uint32_t)*4); 131 ct->master.l3protonum = AF_INET6; 132} 133 134static void set_attr_grp_master_port(struct nf_conntrack *ct, const void *value) 135{ 136 const struct nfct_attr_grp_port *this = value; 137 ct->master.l4src.all = this->sport; 138 ct->master.l4dst.all = this->dport; 139} 140 141static void set_attr_grp_do_nothing(struct nf_conntrack *ct, const void *value) 142{ 143} 144 145const set_attr_grp set_attr_grp_array[ATTR_GRP_MAX] = { 146 [ATTR_GRP_ORIG_IPV4] = set_attr_grp_orig_ipv4, 147 [ATTR_GRP_REPL_IPV4] = set_attr_grp_repl_ipv4, 148 [ATTR_GRP_ORIG_IPV6] = set_attr_grp_orig_ipv6, 149 [ATTR_GRP_REPL_IPV6] = set_attr_grp_repl_ipv6, 150 [ATTR_GRP_ORIG_PORT] = set_attr_grp_orig_port, 151 [ATTR_GRP_REPL_PORT] = set_attr_grp_repl_port, 152 [ATTR_GRP_ICMP] = set_attr_grp_icmp, 153 [ATTR_GRP_MASTER_IPV4] = set_attr_grp_master_ipv4, 154 [ATTR_GRP_MASTER_IPV6] = set_attr_grp_master_ipv6, 155 [ATTR_GRP_MASTER_PORT] = set_attr_grp_master_port, 156 [ATTR_GRP_ORIG_COUNTERS] = set_attr_grp_do_nothing, 157 [ATTR_GRP_REPL_COUNTERS] = set_attr_grp_do_nothing, 158 [ATTR_GRP_ORIG_ADDR_SRC] = set_attr_grp_do_nothing, 159 [ATTR_GRP_ORIG_ADDR_DST] = set_attr_grp_do_nothing, 160 [ATTR_GRP_REPL_ADDR_SRC] = set_attr_grp_do_nothing, 161 [ATTR_GRP_REPL_ADDR_DST] = set_attr_grp_do_nothing, 162}; 163