2 * DCCP NAT protocol helper
4 * Copyright (c) 2005, 2006, 2008 Patrick McHardy <kaber@trash.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
12 #include <linux/kernel.h>
13 #include <linux/skbuff.h>
14 #include <linux/dccp.h>
16 #include <net/netfilter/nf_conntrack.h>
17 #include <net/netfilter/nf_nat.h>
18 #include <net/netfilter/nf_nat_l3proto.h>
19 #include <net/netfilter/nf_nat_l4proto.h>
21 static u_int16_t dccp_port_rover
;
24 dccp_unique_tuple(const struct nf_nat_l3proto
*l3proto
,
25 struct nf_conntrack_tuple
*tuple
,
26 const struct nf_nat_range
*range
,
27 enum nf_nat_manip_type maniptype
,
28 const struct nf_conn
*ct
)
30 nf_nat_l4proto_unique_tuple(l3proto
, tuple
, range
, maniptype
, ct
,
35 dccp_manip_pkt(struct sk_buff
*skb
,
36 const struct nf_nat_l3proto
*l3proto
,
37 unsigned int iphdroff
, unsigned int hdroff
,
38 const struct nf_conntrack_tuple
*tuple
,
39 enum nf_nat_manip_type maniptype
)
42 __be16
*portptr
, oldport
, newport
;
43 int hdrsize
= 8; /* DCCP connection tracking guarantees this much */
45 if (skb
->len
>= hdroff
+ sizeof(struct dccp_hdr
))
46 hdrsize
= sizeof(struct dccp_hdr
);
48 if (!skb_make_writable(skb
, hdroff
+ hdrsize
))
51 hdr
= (struct dccp_hdr
*)(skb
->data
+ hdroff
);
53 if (maniptype
== NF_NAT_MANIP_SRC
) {
54 newport
= tuple
->src
.u
.dccp
.port
;
55 portptr
= &hdr
->dccph_sport
;
57 newport
= tuple
->dst
.u
.dccp
.port
;
58 portptr
= &hdr
->dccph_dport
;
64 if (hdrsize
< sizeof(*hdr
))
67 l3proto
->csum_update(skb
, iphdroff
, &hdr
->dccph_checksum
,
69 inet_proto_csum_replace2(&hdr
->dccph_checksum
, skb
, oldport
, newport
,
74 const struct nf_nat_l4proto nf_nat_l4proto_dccp
= {
75 .l4proto
= IPPROTO_DCCP
,
76 .manip_pkt
= dccp_manip_pkt
,
77 .in_range
= nf_nat_l4proto_in_range
,
78 .unique_tuple
= dccp_unique_tuple
,
79 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
80 .nlattr_to_range
= nf_nat_l4proto_nlattr_to_range
,