Home | History | Annotate | Download | only in conntrack
      1 /*
      2  * (C) 2005-2011 by Pablo Neira Ayuso <pablo (at) 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 
     14 static 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 
     33 static 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 
     40 static 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 
     48 static 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 
     56 static 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 
     64 static 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 
     72 static 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 
     79 static 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 
     86 static 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 
    118 static 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 
    126 static 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 
    134 static 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 
    141 static void set_attr_grp_do_nothing(struct nf_conntrack *ct, const void *value)
    142 {
    143 }
    144 
    145 const 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