18a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/* 28a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org> 38a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 48a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This program is free software; you can redistribute it and/or modify it 58a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * under the terms of the GNU General Public License as published by 68a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * the Free Software Foundation; either version 2 of the License, or 78a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * (at your option) any later version. 88a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */ 98a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include "internal/internal.h" 118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include <linux/icmp.h> 128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include <linux/icmpv6.h> 138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 148a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic const uint8_t invmap_icmp[] = { 158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ICMP_ECHO] = ICMP_ECHOREPLY + 1, 168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ICMP_ECHOREPLY] = ICMP_ECHO + 1, 178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, 188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1, 198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1, 208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1, 218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1, 228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1 238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}; 248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#ifndef ICMPV6_NI_QUERY 268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#define ICMPV6_NI_QUERY 139 278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#endif 288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#ifndef ICMPV6_NI_REPLY 308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#define ICMPV6_NI_REPLY 140 318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#endif 328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 338a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic const uint8_t invmap_icmpv6[] = { 348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1, 358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1, 368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1, 378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY + 1 388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}; 398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 408a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic void set_attr_grp_orig_ipv4(struct nf_conntrack *ct, const void *value) 418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar const struct nfct_attr_grp_ipv4 *this = value; 438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->head.orig.src.v4 = this->src; 448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->head.orig.dst.v4 = this->dst; 458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->head.orig.l3protonum = AF_INET; 468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 488a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic void set_attr_grp_repl_ipv4(struct nf_conntrack *ct, const void *value) 498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar const struct nfct_attr_grp_ipv4 *this = value; 518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->repl.src.v4 = this->src; 528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->repl.dst.v4 = this->dst; 538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->repl.l3protonum = AF_INET; 548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 568a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic void set_attr_grp_orig_ipv6(struct nf_conntrack *ct, const void *value) 578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar const struct nfct_attr_grp_ipv6 *this = value; 598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar memcpy(&ct->head.orig.src.v6, this->src, sizeof(uint32_t)*4); 608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar memcpy(&ct->head.orig.dst.v6, this->dst, sizeof(uint32_t)*4); 618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->head.orig.l3protonum = AF_INET6; 628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 648a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic void set_attr_grp_repl_ipv6(struct nf_conntrack *ct, const void *value) 658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar const struct nfct_attr_grp_ipv6 *this = value; 678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar memcpy(&ct->repl.src.v6, this->src, sizeof(uint32_t)*4); 688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar memcpy(&ct->repl.dst.v6, this->dst, sizeof(uint32_t)*4); 698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->repl.l3protonum = AF_INET6; 708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 728a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic void set_attr_grp_orig_port(struct nf_conntrack *ct, const void *value) 738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar const struct nfct_attr_grp_port *this = value; 758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->head.orig.l4src.all = this->sport; 768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->head.orig.l4dst.all = this->dport; 778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 798a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic void set_attr_grp_repl_port(struct nf_conntrack *ct, const void *value) 808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar const struct nfct_attr_grp_port *this = value; 828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->repl.l4src.all = this->sport; 838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->repl.l4dst.all = this->dport; 848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 868a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic void set_attr_grp_icmp(struct nf_conntrack *ct, const void *value) 878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar uint8_t rtype; 898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar const struct nfct_attr_grp_icmp *this = value; 908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->head.orig.l4dst.icmp.type = this->type; 928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar switch(ct->head.orig.l3protonum) { 948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar case AF_INET: 958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar rtype = invmap_icmp[this->type]; 968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar break; 978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar case AF_INET6: 998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar rtype = invmap_icmpv6[this->type - 128]; 1008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar break; 1018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 1028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar default: 1038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar rtype = 0; /* not found */ 1048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar } 1058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 1068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar if (rtype) 1078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->repl.l4dst.icmp.type = rtype - 1; 1088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar else 1098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->repl.l4dst.icmp.type = 255; /* -EINVAL */ 1108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 1118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->head.orig.l4dst.icmp.code = this->code; 1128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->repl.l4dst.icmp.code = this->code; 1138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 1148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->head.orig.l4src.icmp.id = this->id; 1158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->repl.l4src.icmp.id = this->id; 1168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 1178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 1188a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic void set_attr_grp_master_ipv4(struct nf_conntrack *ct, const void *value) 1198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 1208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar const struct nfct_attr_grp_ipv4 *this = value; 1218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->master.src.v4 = this->src; 1228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->master.dst.v4 = this->dst; 1238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->master.l3protonum = AF_INET; 1248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 1258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 1268a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic void set_attr_grp_master_ipv6(struct nf_conntrack *ct, const void *value) 1278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 1288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar const struct nfct_attr_grp_ipv6 *this = value; 1298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar memcpy(&ct->master.src.v6, this->src, sizeof(uint32_t)*4); 1308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar memcpy(&ct->master.dst.v6, this->dst, sizeof(uint32_t)*4); 1318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->master.l3protonum = AF_INET6; 1328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 1338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 1348a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic void set_attr_grp_master_port(struct nf_conntrack *ct, const void *value) 1358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 1368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar const struct nfct_attr_grp_port *this = value; 1378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->master.l4src.all = this->sport; 1388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar ct->master.l4dst.all = this->dport; 1398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 1408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 1418a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic void set_attr_grp_do_nothing(struct nf_conntrack *ct, const void *value) 1428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 1438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 1448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 1458a44513648da0c5f5551f96b329cf56b66f5b303pkanwarconst set_attr_grp set_attr_grp_array[ATTR_GRP_MAX] = { 1468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_ORIG_IPV4] = set_attr_grp_orig_ipv4, 1478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_REPL_IPV4] = set_attr_grp_repl_ipv4, 1488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_ORIG_IPV6] = set_attr_grp_orig_ipv6, 1498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_REPL_IPV6] = set_attr_grp_repl_ipv6, 1508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_ORIG_PORT] = set_attr_grp_orig_port, 1518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_REPL_PORT] = set_attr_grp_repl_port, 1528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_ICMP] = set_attr_grp_icmp, 1538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_MASTER_IPV4] = set_attr_grp_master_ipv4, 1548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_MASTER_IPV6] = set_attr_grp_master_ipv6, 1558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_MASTER_PORT] = set_attr_grp_master_port, 1568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_ORIG_COUNTERS] = set_attr_grp_do_nothing, 1578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_REPL_COUNTERS] = set_attr_grp_do_nothing, 1588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_ORIG_ADDR_SRC] = set_attr_grp_do_nothing, 1598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_ORIG_ADDR_DST] = set_attr_grp_do_nothing, 1608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_REPL_ADDR_SRC] = set_attr_grp_do_nothing, 1618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar [ATTR_GRP_REPL_ADDR_DST] = set_attr_grp_do_nothing, 1628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}; 163