• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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 
set_attr_grp_orig_ipv4(struct nf_conntrack * ct,const void * value)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 
set_attr_grp_repl_ipv4(struct nf_conntrack * ct,const void * value)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 
set_attr_grp_orig_ipv6(struct nf_conntrack * ct,const void * value)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 
set_attr_grp_repl_ipv6(struct nf_conntrack * ct,const void * value)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 
set_attr_grp_orig_port(struct nf_conntrack * ct,const void * value)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 
set_attr_grp_repl_port(struct nf_conntrack * ct,const void * value)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 
set_attr_grp_icmp(struct nf_conntrack * ct,const void * value)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 
set_attr_grp_master_ipv4(struct nf_conntrack * ct,const void * value)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 
set_attr_grp_master_ipv6(struct nf_conntrack * ct,const void * value)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 
set_attr_grp_master_port(struct nf_conntrack * ct,const void * value)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 
set_attr_grp_do_nothing(struct nf_conntrack * ct,const void * value)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