copy.c revision 8a44513648da0c5f5551f96b329cf56b66f5b303
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
12static void copy_attr_orig_ipv4_src(struct nf_conntrack *dest,
13				    const struct nf_conntrack *orig)
14{
15	dest->head.orig.src.v4 = orig->head.orig.src.v4;
16}
17
18static void copy_attr_orig_ipv4_dst(struct nf_conntrack *dest,
19				    const struct nf_conntrack *orig)
20{
21	dest->head.orig.dst.v4 = orig->head.orig.dst.v4;
22}
23
24static void copy_attr_repl_ipv4_src(struct nf_conntrack *dest,
25				    const struct nf_conntrack *orig)
26{
27	dest->repl.src.v4 = orig->repl.src.v4;
28}
29
30static void copy_attr_repl_ipv4_dst(struct nf_conntrack *dest,
31				    const struct nf_conntrack *orig)
32{
33	dest->repl.dst.v4 = orig->repl.dst.v4;
34}
35
36static void copy_attr_orig_ipv6_src(struct nf_conntrack *dest,
37				    const struct nf_conntrack *orig)
38{
39	memcpy(&dest->head.orig.src,
40	       &orig->head.orig.src,
41	       sizeof(union __nfct_address));
42}
43
44static void copy_attr_orig_ipv6_dst(struct nf_conntrack *dest,
45				    const struct nf_conntrack *orig)
46{
47	memcpy(&dest->head.orig.dst,
48	       &orig->head.orig.dst,
49	       sizeof(union __nfct_address));
50}
51
52static void copy_attr_repl_ipv6_src(struct nf_conntrack *dest,
53				    const struct nf_conntrack *orig)
54{
55	memcpy(&dest->repl.src,
56	       &orig->repl.src,
57	       sizeof(union __nfct_address));
58}
59
60static void copy_attr_repl_ipv6_dst(struct nf_conntrack *dest,
61				    const struct nf_conntrack *orig)
62{
63	memcpy(&dest->repl.dst,
64	       &orig->repl.dst,
65	       sizeof(union __nfct_address));
66}
67
68static void copy_attr_orig_port_src(struct nf_conntrack *dest,
69				    const struct nf_conntrack *orig)
70{
71	dest->head.orig.l4src.all = orig->head.orig.l4src.all;
72}
73
74static void copy_attr_orig_port_dst(struct nf_conntrack *dest,
75				    const struct nf_conntrack *orig)
76{
77	dest->head.orig.l4dst.all = orig->head.orig.l4dst.all;
78}
79
80static void copy_attr_repl_port_src(struct nf_conntrack *dest,
81				    const struct nf_conntrack *orig)
82{
83	dest->repl.l4src.all = orig->repl.l4src.all;
84}
85
86static void copy_attr_repl_port_dst(struct nf_conntrack *dest,
87				    const struct nf_conntrack *orig)
88{
89	dest->repl.l4dst.all = orig->repl.l4dst.all;
90}
91
92static void copy_attr_orig_zone(struct nf_conntrack *dest,
93				const struct nf_conntrack *orig)
94{
95	dest->head.orig.zone = orig->head.orig.zone;
96}
97
98static void copy_attr_repl_zone(struct nf_conntrack *dest,
99				const struct nf_conntrack *orig)
100{
101	dest->repl.zone = orig->repl.zone;
102}
103
104static void copy_attr_icmp_type(struct nf_conntrack *dest,
105				const struct nf_conntrack *orig)
106{
107	dest->head.orig.l4dst.icmp.type =
108		orig->head.orig.l4dst.icmp.type;
109
110}
111
112static void copy_attr_icmp_code(struct nf_conntrack *dest,
113				const struct nf_conntrack *orig)
114{
115	dest->head.orig.l4dst.icmp.code =
116		orig->head.orig.l4dst.icmp.code;
117
118}
119
120static void copy_attr_icmp_id(struct nf_conntrack *dest,
121			      const struct nf_conntrack *orig)
122{
123	dest->head.orig.l4src.icmp.id =
124		orig->head.orig.l4src.icmp.id;
125}
126
127static void copy_attr_orig_l3proto(struct nf_conntrack *dest,
128				   const struct nf_conntrack *orig)
129{
130	dest->head.orig.l3protonum = orig->head.orig.l3protonum;
131}
132
133static void copy_attr_repl_l3proto(struct nf_conntrack *dest,
134				   const struct nf_conntrack *orig)
135{
136	dest->repl.l3protonum = orig->repl.l3protonum;
137}
138
139static void copy_attr_orig_l4proto(struct nf_conntrack *dest,
140				   const struct nf_conntrack *orig)
141{
142	dest->head.orig.protonum = orig->head.orig.protonum;
143}
144
145static void copy_attr_repl_l4proto(struct nf_conntrack *dest,
146				   const struct nf_conntrack *orig)
147{
148	dest->repl.protonum = orig->repl.protonum;
149}
150
151static void copy_attr_master_ipv4_src(struct nf_conntrack *dest,
152				      const struct nf_conntrack *orig)
153{
154	dest->master.src.v4 = orig->master.src.v4;
155}
156
157static void copy_attr_master_ipv4_dst(struct nf_conntrack *dest,
158				      const struct nf_conntrack *orig)
159{
160	dest->master.dst.v4 = orig->master.dst.v4;
161}
162
163static void copy_attr_master_ipv6_src(struct nf_conntrack *dest,
164				      const struct nf_conntrack *orig)
165{
166	memcpy(&dest->master.src, &orig->master.src,
167	       sizeof(union __nfct_address));
168}
169
170static void copy_attr_master_ipv6_dst(struct nf_conntrack *dest,
171				      const struct nf_conntrack *orig)
172{
173	memcpy(&dest->master.dst, &orig->master.dst,
174	       sizeof(union __nfct_address));
175}
176
177static void copy_attr_master_port_src(struct nf_conntrack *dest,
178				      const struct nf_conntrack *orig)
179{
180	dest->master.l4src.all = orig->master.l4src.all;
181}
182
183static void copy_attr_master_port_dst(struct nf_conntrack *dest,
184				      const struct nf_conntrack *orig)
185{
186	dest->master.l4dst.all = orig->master.l4dst.all;
187}
188
189static void copy_attr_master_l3proto(struct nf_conntrack *dest,
190				     const struct nf_conntrack *orig)
191{
192	dest->master.l3protonum = orig->master.l3protonum;
193}
194
195static void copy_attr_master_l4proto(struct nf_conntrack *dest,
196				     const struct nf_conntrack *orig)
197{
198	dest->master.protonum = orig->master.protonum;
199}
200
201static void copy_attr_tcp_state(struct nf_conntrack *dest,
202				const struct nf_conntrack *orig)
203{
204	dest->protoinfo.tcp.state = orig->protoinfo.tcp.state;
205}
206
207static void copy_attr_tcp_flags_orig(struct nf_conntrack *dest,
208				     const struct nf_conntrack *orig)
209{
210	dest->protoinfo.tcp.flags[__DIR_ORIG].value =
211		orig->protoinfo.tcp.flags[__DIR_ORIG].value;
212}
213
214static void copy_attr_tcp_flags_repl(struct nf_conntrack *dest,
215				     const struct nf_conntrack *orig)
216{
217	dest->protoinfo.tcp.flags[__DIR_REPL].value =
218		orig->protoinfo.tcp.flags[__DIR_REPL].value;
219}
220
221static void copy_attr_tcp_mask_orig(struct nf_conntrack *dest,
222				    const struct nf_conntrack *orig)
223{
224	dest->protoinfo.tcp.flags[__DIR_ORIG].mask =
225		orig->protoinfo.tcp.flags[__DIR_ORIG].mask;
226}
227
228static void copy_attr_tcp_mask_repl(struct nf_conntrack *dest,
229				    const struct nf_conntrack *orig)
230{
231	dest->protoinfo.tcp.flags[__DIR_REPL].mask =
232		orig->protoinfo.tcp.flags[__DIR_REPL].mask;
233}
234
235static void copy_attr_tcp_wscale_orig(struct nf_conntrack *dest,
236				      const struct nf_conntrack *orig)
237{
238	dest->protoinfo.tcp.wscale[__DIR_ORIG] =
239		orig->protoinfo.tcp.wscale[__DIR_ORIG];
240}
241
242static void copy_attr_tcp_wscale_repl(struct nf_conntrack *dest,
243				      const struct nf_conntrack *orig)
244{
245	dest->protoinfo.tcp.wscale[__DIR_REPL] =
246		orig->protoinfo.tcp.wscale[__DIR_REPL];
247}
248
249static void copy_attr_sctp_state(struct nf_conntrack *dest,
250				 const struct nf_conntrack *orig)
251{
252	dest->protoinfo.sctp.state = orig->protoinfo.sctp.state;
253}
254
255static void copy_attr_sctp_vtag_orig(struct nf_conntrack *dest,
256				     const struct nf_conntrack *orig)
257{
258	dest->protoinfo.sctp.vtag[__DIR_ORIG] =
259		orig->protoinfo.sctp.vtag[__DIR_ORIG];
260}
261
262static void copy_attr_sctp_vtag_repl(struct nf_conntrack *dest,
263				     const struct nf_conntrack *orig)
264{
265	dest->protoinfo.sctp.vtag[__DIR_REPL] =
266		orig->protoinfo.sctp.vtag[__DIR_REPL];
267}
268
269static void copy_attr_dccp_state(struct nf_conntrack *dest,
270				 const struct nf_conntrack *orig)
271{
272	dest->protoinfo.dccp.state = orig->protoinfo.dccp.state;
273}
274
275static void copy_attr_dccp_role(struct nf_conntrack *dest,
276				const struct nf_conntrack *orig)
277{
278	dest->protoinfo.dccp.role = orig->protoinfo.dccp.role;
279}
280
281static void copy_attr_dccp_handshake_seq(struct nf_conntrack *dest,
282					 const struct nf_conntrack *orig)
283{
284	dest->protoinfo.dccp.handshake_seq = orig->protoinfo.dccp.handshake_seq;
285}
286
287static void copy_attr_snat_ipv4(struct nf_conntrack *dest,
288				const struct nf_conntrack *orig)
289{
290	dest->snat.min_ip.v4 = orig->snat.min_ip.v4;
291}
292
293static void copy_attr_dnat_ipv4(struct nf_conntrack *dest,
294				const struct nf_conntrack *orig)
295{
296	dest->dnat.min_ip.v4 = orig->dnat.min_ip.v4;
297}
298
299static void copy_attr_snat_ipv6(struct nf_conntrack *dest,
300				const struct nf_conntrack *orig)
301{
302	memcpy(&dest->snat.min_ip.v6, &orig->snat.min_ip.v6,
303	       sizeof(struct in6_addr));
304}
305
306static void copy_attr_dnat_ipv6(struct nf_conntrack *dest,
307				const struct nf_conntrack *orig)
308{
309	memcpy(&dest->dnat.min_ip.v6, &orig->dnat.min_ip.v6,
310	       sizeof(struct in6_addr));
311}
312
313static void copy_attr_snat_port(struct nf_conntrack *dest,
314				const struct nf_conntrack *orig)
315{
316	dest->snat.l4min.all = orig->snat.l4min.all;
317}
318
319static void copy_attr_dnat_port(struct nf_conntrack *dest,
320				const struct nf_conntrack *orig)
321{
322	dest->dnat.l4min.all = orig->dnat.l4min.all;
323}
324
325static void copy_attr_timeout(struct nf_conntrack *dest,
326			      const struct nf_conntrack *orig)
327{
328	dest->timeout = orig->timeout;
329}
330
331static void copy_attr_mark(struct nf_conntrack *dest,
332			   const struct nf_conntrack *orig)
333{
334	dest->mark = orig->mark;
335}
336
337static void copy_attr_secmark(struct nf_conntrack *dest,
338			      const struct nf_conntrack *orig)
339{
340	dest->secmark = orig->secmark;
341}
342
343static void copy_attr_orig_counter_packets(struct nf_conntrack *dest,
344					   const struct nf_conntrack *orig)
345{
346	dest->counters[__DIR_ORIG].packets = orig->counters[__DIR_ORIG].packets;
347}
348
349static void copy_attr_repl_counter_packets(struct nf_conntrack *dest,
350					   const struct nf_conntrack *orig)
351{
352	dest->counters[__DIR_REPL].packets = orig->counters[__DIR_REPL].packets;
353}
354
355static void copy_attr_orig_counter_bytes(struct nf_conntrack *dest,
356					 const struct nf_conntrack *orig)
357{
358	dest->counters[__DIR_ORIG].bytes = orig->counters[__DIR_ORIG].bytes;
359}
360
361static void copy_attr_repl_counter_bytes(struct nf_conntrack *dest,
362					 const struct nf_conntrack *orig)
363{
364	dest->counters[__DIR_REPL].bytes = orig->counters[__DIR_REPL].bytes;
365}
366
367static void copy_attr_status(struct nf_conntrack *dest,
368			     const struct nf_conntrack *orig)
369{
370	dest->status = orig->status;
371}
372
373static void copy_attr_use(struct nf_conntrack *dest,
374			  const struct nf_conntrack *orig)
375{
376	dest->use = orig->use;
377}
378
379static void copy_attr_id(struct nf_conntrack *dest,
380			 const struct nf_conntrack *orig)
381{
382	dest->id = orig->id;
383}
384
385static void copy_attr_orig_cor_pos(struct nf_conntrack *dest,
386				   const struct nf_conntrack *orig)
387{
388	dest->natseq[__DIR_ORIG].correction_pos =
389		orig->natseq[__DIR_ORIG].correction_pos;
390}
391
392static void copy_attr_orig_off_bfr(struct nf_conntrack *dest,
393				   const struct nf_conntrack *orig)
394{
395	dest->natseq[__DIR_ORIG].offset_before =
396		orig->natseq[__DIR_ORIG].offset_before;
397}
398
399static void copy_attr_orig_off_aft(struct nf_conntrack *dest,
400				   const struct nf_conntrack *orig)
401{
402	dest->natseq[__DIR_ORIG].offset_after =
403		orig->natseq[__DIR_ORIG].offset_after;
404}
405
406static void copy_attr_repl_cor_pos(struct nf_conntrack *dest,
407				   const struct nf_conntrack *orig)
408{
409	dest->natseq[__DIR_REPL].correction_pos =
410		orig->natseq[__DIR_REPL].correction_pos;
411}
412
413static void copy_attr_repl_off_bfr(struct nf_conntrack *dest,
414				   const struct nf_conntrack *orig)
415{
416	dest->natseq[__DIR_REPL].offset_before =
417		orig->natseq[__DIR_REPL].offset_before;
418}
419
420static void copy_attr_repl_off_aft(struct nf_conntrack *dest,
421				   const struct nf_conntrack *orig)
422{
423	dest->natseq[__DIR_REPL].offset_after =
424		orig->natseq[__DIR_REPL].offset_after;
425}
426
427static void copy_attr_helper_name(struct nf_conntrack *dest,
428				  const struct nf_conntrack *orig)
429{
430	strncpy(dest->helper_name, orig->helper_name, NFCT_HELPER_NAME_MAX);
431	dest->helper_name[NFCT_HELPER_NAME_MAX-1] = '\0';
432}
433
434static void copy_attr_zone(struct nf_conntrack *dest,
435			   const struct nf_conntrack *orig)
436{
437	dest->zone = orig->zone;
438}
439
440static void copy_attr_secctx(struct nf_conntrack *dest,
441			     const struct nf_conntrack *orig)
442{
443	if (dest->secctx) {
444		free(dest->secctx);
445		dest->secctx = NULL;
446	}
447	if (orig->secctx)
448		dest->secctx = strdup(orig->secctx);
449}
450
451static void copy_attr_timestamp_start(struct nf_conntrack *dest,
452				      const struct nf_conntrack *orig)
453{
454	dest->timestamp.start = orig->timestamp.start;
455}
456
457static void copy_attr_timestamp_stop(struct nf_conntrack *dest,
458				     const struct nf_conntrack *orig)
459{
460	dest->timestamp.stop = orig->timestamp.stop;
461}
462
463static void copy_attr_help_info(struct nf_conntrack *dest,
464				const struct nf_conntrack *orig)
465{
466	if (orig->helper_info == NULL)
467		return;
468
469	if (dest->helper_info != NULL)
470		free(dest->helper_info);
471
472	dest->helper_info = calloc(1, orig->helper_info_len);
473	if (dest->helper_info == NULL)
474		return;
475
476	memcpy(dest->helper_info, orig->helper_info, orig->helper_info_len);
477}
478
479static void* do_copy_attr_connlabels(struct nfct_bitmask *dest,
480				     const struct nfct_bitmask *orig)
481{
482	if (orig == NULL)
483		return dest;
484	if (dest)
485		nfct_bitmask_destroy(dest);
486	return nfct_bitmask_clone(orig);
487}
488
489static void copy_attr_connlabels(struct nf_conntrack *dest,
490				 const struct nf_conntrack *orig)
491{
492	dest->connlabels = do_copy_attr_connlabels(dest->connlabels, orig->connlabels);
493}
494
495static void copy_attr_connlabels_mask(struct nf_conntrack *dest,
496				 const struct nf_conntrack *orig)
497{
498	dest->connlabels_mask = do_copy_attr_connlabels(dest->connlabels_mask, orig->connlabels_mask);
499}
500
501const copy_attr copy_attr_array[ATTR_MAX] = {
502	[ATTR_ORIG_IPV4_SRC]		= copy_attr_orig_ipv4_src,
503	[ATTR_ORIG_IPV4_DST] 		= copy_attr_orig_ipv4_dst,
504	[ATTR_REPL_IPV4_SRC]		= copy_attr_repl_ipv4_src,
505	[ATTR_REPL_IPV4_DST]		= copy_attr_repl_ipv4_dst,
506	[ATTR_ORIG_IPV6_SRC]		= copy_attr_orig_ipv6_src,
507	[ATTR_ORIG_IPV6_DST]		= copy_attr_orig_ipv6_dst,
508	[ATTR_REPL_IPV6_SRC]		= copy_attr_repl_ipv6_src,
509	[ATTR_REPL_IPV6_DST]		= copy_attr_repl_ipv6_dst,
510	[ATTR_ORIG_PORT_SRC]		= copy_attr_orig_port_src,
511	[ATTR_ORIG_PORT_DST]		= copy_attr_orig_port_dst,
512	[ATTR_REPL_PORT_SRC]		= copy_attr_repl_port_src,
513	[ATTR_REPL_PORT_DST]		= copy_attr_repl_port_dst,
514	[ATTR_ICMP_TYPE]		= copy_attr_icmp_type,
515	[ATTR_ICMP_CODE]		= copy_attr_icmp_code,
516	[ATTR_ICMP_ID]			= copy_attr_icmp_id,
517	[ATTR_ORIG_L3PROTO]		= copy_attr_orig_l3proto,
518	[ATTR_REPL_L3PROTO]		= copy_attr_repl_l3proto,
519	[ATTR_ORIG_L4PROTO]		= copy_attr_orig_l4proto,
520	[ATTR_REPL_L4PROTO]		= copy_attr_repl_l4proto,
521	[ATTR_TCP_STATE]		= copy_attr_tcp_state,
522	[ATTR_SNAT_IPV4]		= copy_attr_snat_ipv4,
523	[ATTR_DNAT_IPV4]		= copy_attr_dnat_ipv4,
524	[ATTR_SNAT_PORT]		= copy_attr_snat_port,
525	[ATTR_DNAT_PORT]		= copy_attr_dnat_port,
526	[ATTR_TIMEOUT]			= copy_attr_timeout,
527	[ATTR_MARK]			= copy_attr_mark,
528	[ATTR_ORIG_COUNTER_PACKETS] 	= copy_attr_orig_counter_packets,
529	[ATTR_ORIG_COUNTER_BYTES]	= copy_attr_orig_counter_bytes,
530	[ATTR_REPL_COUNTER_PACKETS]	= copy_attr_repl_counter_packets,
531	[ATTR_REPL_COUNTER_BYTES]	= copy_attr_repl_counter_bytes,
532	[ATTR_USE]			= copy_attr_use,
533	[ATTR_ID]			= copy_attr_id,
534	[ATTR_STATUS]			= copy_attr_status,
535	[ATTR_TCP_FLAGS_ORIG]		= copy_attr_tcp_flags_orig,
536	[ATTR_TCP_FLAGS_REPL]		= copy_attr_tcp_flags_repl,
537	[ATTR_TCP_MASK_ORIG]		= copy_attr_tcp_mask_orig,
538	[ATTR_TCP_MASK_REPL]		= copy_attr_tcp_mask_repl,
539	[ATTR_MASTER_IPV4_SRC]		= copy_attr_master_ipv4_src,
540	[ATTR_MASTER_IPV4_DST] 		= copy_attr_master_ipv4_dst,
541	[ATTR_MASTER_IPV6_SRC]		= copy_attr_master_ipv6_src,
542	[ATTR_MASTER_IPV6_DST]		= copy_attr_master_ipv6_dst,
543	[ATTR_MASTER_PORT_SRC]		= copy_attr_master_port_src,
544	[ATTR_MASTER_PORT_DST]		= copy_attr_master_port_dst,
545	[ATTR_MASTER_L3PROTO]		= copy_attr_master_l3proto,
546	[ATTR_MASTER_L4PROTO]		= copy_attr_master_l4proto,
547	[ATTR_SECMARK]			= copy_attr_secmark,
548	[ATTR_ORIG_NAT_SEQ_CORRECTION_POS]	= copy_attr_orig_cor_pos,
549	[ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE]	= copy_attr_orig_off_bfr,
550	[ATTR_ORIG_NAT_SEQ_OFFSET_AFTER]	= copy_attr_orig_off_aft,
551	[ATTR_REPL_NAT_SEQ_CORRECTION_POS]	= copy_attr_repl_cor_pos,
552	[ATTR_REPL_NAT_SEQ_OFFSET_BEFORE]	= copy_attr_repl_off_bfr,
553	[ATTR_REPL_NAT_SEQ_OFFSET_AFTER]	= copy_attr_repl_off_aft,
554	[ATTR_SCTP_STATE]		= copy_attr_sctp_state,
555	[ATTR_SCTP_VTAG_ORIG]		= copy_attr_sctp_vtag_orig,
556	[ATTR_SCTP_VTAG_REPL]		= copy_attr_sctp_vtag_repl,
557	[ATTR_HELPER_NAME]		= copy_attr_helper_name,
558	[ATTR_DCCP_STATE]		= copy_attr_dccp_state,
559	[ATTR_DCCP_ROLE]		= copy_attr_dccp_role,
560	[ATTR_DCCP_HANDSHAKE_SEQ]	= copy_attr_dccp_handshake_seq,
561	[ATTR_TCP_WSCALE_ORIG]		= copy_attr_tcp_wscale_orig,
562	[ATTR_TCP_WSCALE_REPL]		= copy_attr_tcp_wscale_repl,
563	[ATTR_ZONE]			= copy_attr_zone,
564	[ATTR_ORIG_ZONE]		= copy_attr_orig_zone,
565	[ATTR_REPL_ZONE]		= copy_attr_repl_zone,
566	[ATTR_SECCTX]			= copy_attr_secctx,
567	[ATTR_TIMESTAMP_START]		= copy_attr_timestamp_start,
568	[ATTR_TIMESTAMP_STOP]		= copy_attr_timestamp_stop,
569	[ATTR_HELPER_INFO]		= copy_attr_help_info,
570	[ATTR_CONNLABELS]		= copy_attr_connlabels,
571	[ATTR_CONNLABELS_MASK]		= copy_attr_connlabels_mask,
572	[ATTR_SNAT_IPV6]		= copy_attr_snat_ipv6,
573	[ATTR_DNAT_IPV6]		= copy_attr_dnat_ipv6,
574};
575
576/* this is used by nfct_copy() with the NFCT_CP_OVERRIDE flag set. */
577void __copy_fast(struct nf_conntrack *ct1, const struct nf_conntrack *ct2)
578{
579	memcpy(ct1, ct2, sizeof(*ct1));
580	/* malloc'd attributes: don't free, do copy */
581	ct1->secctx = NULL;
582	ct1->helper_info = NULL;
583	ct1->connlabels = NULL;
584	ct1->connlabels_mask = NULL;
585
586	copy_attr_secctx(ct1, ct2);
587	copy_attr_help_info(ct1, ct2);
588	copy_attr_connlabels(ct1, ct2);
589	copy_attr_connlabels_mask(ct1, ct2);
590}
591