Blame view

net/netfilter/nf_nat_proto_dccp.c 2.92 KB
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
1
2
3
  /*
   * DCCP NAT protocol helper
   *
c7232c997   Patrick McHardy   netfilter: add pr...
4
   * Copyright (c) 2005, 2006, 2008 Patrick McHardy <kaber@trash.net>
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
5
6
7
8
9
10
11
12
13
14
15
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   *
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/skbuff.h>
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
16
17
18
19
  #include <linux/dccp.h>
  
  #include <net/netfilter/nf_conntrack.h>
  #include <net/netfilter/nf_nat.h>
c7232c997   Patrick McHardy   netfilter: add pr...
20
21
  #include <net/netfilter/nf_nat_l3proto.h>
  #include <net/netfilter/nf_nat_l4proto.h>
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
22
23
  
  static u_int16_t dccp_port_rover;
f43dc98b3   Changli Gao   netfilter: nf_nat...
24
  static void
c7232c997   Patrick McHardy   netfilter: add pr...
25
26
27
  dccp_unique_tuple(const struct nf_nat_l3proto *l3proto,
  		  struct nf_conntrack_tuple *tuple,
  		  const struct nf_nat_range *range,
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
28
29
30
  		  enum nf_nat_manip_type maniptype,
  		  const struct nf_conn *ct)
  {
c7232c997   Patrick McHardy   netfilter: add pr...
31
32
  	nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct,
  				    &dccp_port_rover);
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
33
  }
f2ea825f4   Jan Engelhardt   [NETFILTER]: nf_n...
34
  static bool
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
35
  dccp_manip_pkt(struct sk_buff *skb,
c7232c997   Patrick McHardy   netfilter: add pr...
36
37
  	       const struct nf_nat_l3proto *l3proto,
  	       unsigned int iphdroff, unsigned int hdroff,
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
38
39
40
  	       const struct nf_conntrack_tuple *tuple,
  	       enum nf_nat_manip_type maniptype)
  {
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
41
  	struct dccp_hdr *hdr;
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
42
43
44
45
46
47
48
  	__be16 *portptr, oldport, newport;
  	int hdrsize = 8; /* DCCP connection tracking guarantees this much */
  
  	if (skb->len >= hdroff + sizeof(struct dccp_hdr))
  		hdrsize = sizeof(struct dccp_hdr);
  
  	if (!skb_make_writable(skb, hdroff + hdrsize))
f2ea825f4   Jan Engelhardt   [NETFILTER]: nf_n...
49
  		return false;
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
50

4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
51
  	hdr = (struct dccp_hdr *)(skb->data + hdroff);
cbc9f2f4f   Patrick McHardy   netfilter: nf_nat...
52
  	if (maniptype == NF_NAT_MANIP_SRC) {
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
53
54
55
  		newport = tuple->src.u.dccp.port;
  		portptr = &hdr->dccph_sport;
  	} else {
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
56
57
58
59
60
61
62
63
  		newport = tuple->dst.u.dccp.port;
  		portptr = &hdr->dccph_dport;
  	}
  
  	oldport = *portptr;
  	*portptr = newport;
  
  	if (hdrsize < sizeof(*hdr))
f2ea825f4   Jan Engelhardt   [NETFILTER]: nf_n...
64
  		return true;
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
65

c7232c997   Patrick McHardy   netfilter: add pr...
66
67
  	l3proto->csum_update(skb, iphdroff, &hdr->dccph_checksum,
  			     tuple, maniptype);
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
68
  	inet_proto_csum_replace2(&hdr->dccph_checksum, skb, oldport, newport,
4b048d6d9   Tom Herbert   net: Change pseud...
69
  				 false);
f2ea825f4   Jan Engelhardt   [NETFILTER]: nf_n...
70
  	return true;
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
71
  }
c7232c997   Patrick McHardy   netfilter: add pr...
72
73
  static const struct nf_nat_l4proto nf_nat_l4proto_dccp = {
  	.l4proto		= IPPROTO_DCCP,
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
74
  	.manip_pkt		= dccp_manip_pkt,
c7232c997   Patrick McHardy   netfilter: add pr...
75
  	.in_range		= nf_nat_l4proto_in_range,
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
76
  	.unique_tuple		= dccp_unique_tuple,
24de3d377   Duan Jiong   netfilter: use IS...
77
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
c7232c997   Patrick McHardy   netfilter: add pr...
78
  	.nlattr_to_range	= nf_nat_l4proto_nlattr_to_range,
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
79
80
81
82
83
  #endif
  };
  
  static int __init nf_nat_proto_dccp_init(void)
  {
c7232c997   Patrick McHardy   netfilter: add pr...
84
85
86
87
88
89
90
91
92
93
94
95
96
97
  	int err;
  
  	err = nf_nat_l4proto_register(NFPROTO_IPV4, &nf_nat_l4proto_dccp);
  	if (err < 0)
  		goto err1;
  	err = nf_nat_l4proto_register(NFPROTO_IPV6, &nf_nat_l4proto_dccp);
  	if (err < 0)
  		goto err2;
  	return 0;
  
  err2:
  	nf_nat_l4proto_unregister(NFPROTO_IPV4, &nf_nat_l4proto_dccp);
  err1:
  	return err;
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
98
99
100
101
  }
  
  static void __exit nf_nat_proto_dccp_fini(void)
  {
c7232c997   Patrick McHardy   netfilter: add pr...
102
103
  	nf_nat_l4proto_unregister(NFPROTO_IPV6, &nf_nat_l4proto_dccp);
  	nf_nat_l4proto_unregister(NFPROTO_IPV4, &nf_nat_l4proto_dccp);
4910a0879   Patrick McHardy   [NETFILTER]: nf_n...
104
105
106
107
108
109
110
111
  }
  
  module_init(nf_nat_proto_dccp_init);
  module_exit(nf_nat_proto_dccp_fini);
  
  MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
  MODULE_DESCRIPTION("DCCP NAT protocol helper");
  MODULE_LICENSE("GPL");