arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / net / ipv4 / netfilter / nf_nat_h323.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * H.323 extension for NAT alteration.
4  *
5  * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
6  * Copyright (c) 2006-2012 Patrick McHardy <kaber@trash.net>
7  *
8  * Based on the 'brute force' H.323 NAT module by
9  * Jozsef Kadlecsik <kadlec@netfilter.org>
10  */
11
12 #include <linux/module.h>
13 #include <linux/tcp.h>
14 #include <net/tcp.h>
15
16 #include <net/netfilter/nf_nat.h>
17 #include <net/netfilter/nf_nat_helper.h>
18 #include <net/netfilter/nf_conntrack_helper.h>
19 #include <net/netfilter/nf_conntrack_expect.h>
20 #include <linux/netfilter/nf_conntrack_h323.h>
21
22 /****************************************************************************/
23 static int set_addr(struct sk_buff *skb, unsigned int protoff,
24                     unsigned char **data, int dataoff,
25                     unsigned int addroff, __be32 ip, __be16 port)
26 {
27         enum ip_conntrack_info ctinfo;
28         struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
29         struct {
30                 __be32 ip;
31                 __be16 port;
32         } __attribute__ ((__packed__)) buf;
33         const struct tcphdr *th;
34         struct tcphdr _tcph;
35
36         buf.ip = ip;
37         buf.port = port;
38         addroff += dataoff;
39
40         if (ip_hdr(skb)->protocol == IPPROTO_TCP) {
41                 if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
42                                               protoff, addroff, sizeof(buf),
43                                               (char *) &buf, sizeof(buf))) {
44                         net_notice_ratelimited("nf_nat_h323: nf_nat_mangle_tcp_packet error\n");
45                         return -1;
46                 }
47
48                 /* Relocate data pointer */
49                 th = skb_header_pointer(skb, ip_hdrlen(skb),
50                                         sizeof(_tcph), &_tcph);
51                 if (th == NULL)
52                         return -1;
53                 *data = skb->data + ip_hdrlen(skb) + th->doff * 4 + dataoff;
54         } else {
55                 if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo,
56                                               protoff, addroff, sizeof(buf),
57                                               (char *) &buf, sizeof(buf))) {
58                         net_notice_ratelimited("nf_nat_h323: nf_nat_mangle_udp_packet error\n");
59                         return -1;
60                 }
61                 /* nf_nat_mangle_udp_packet uses skb_ensure_writable() to copy
62                  * or pull everything in a linear buffer, so we can safely
63                  * use the skb pointers now */
64                 *data = skb->data + ip_hdrlen(skb) + sizeof(struct udphdr);
65         }
66
67         return 0;
68 }
69
70 /****************************************************************************/
71 static int set_h225_addr(struct sk_buff *skb, unsigned int protoff,
72                          unsigned char **data, int dataoff,
73                          TransportAddress *taddr,
74                          union nf_inet_addr *addr, __be16 port)
75 {
76         return set_addr(skb, protoff, data, dataoff, taddr->ipAddress.ip,
77                         addr->ip, port);
78 }
79
80 /****************************************************************************/
81 static int set_h245_addr(struct sk_buff *skb, unsigned protoff,
82                          unsigned char **data, int dataoff,
83                          H245_TransportAddress *taddr,
84                          union nf_inet_addr *addr, __be16 port)
85 {
86         return set_addr(skb, protoff, data, dataoff,
87                         taddr->unicastAddress.iPAddress.network,
88                         addr->ip, port);
89 }
90
91 /****************************************************************************/
92 static int set_sig_addr(struct sk_buff *skb, struct nf_conn *ct,
93                         enum ip_conntrack_info ctinfo,
94                         unsigned int protoff, unsigned char **data,
95                         TransportAddress *taddr, int count)
96 {
97         const struct nf_ct_h323_master *info = nfct_help_data(ct);
98         int dir = CTINFO2DIR(ctinfo);
99         int i;
100         __be16 port;
101         union nf_inet_addr addr;
102
103         for (i = 0; i < count; i++) {
104                 if (get_h225_addr(ct, *data, &taddr[i], &addr, &port)) {
105                         if (addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
106                             port == info->sig_port[dir]) {
107                                 /* GW->GK */
108
109                                 /* Fix for Gnomemeeting */
110                                 if (i > 0 &&
111                                     get_h225_addr(ct, *data, &taddr[0],
112                                                   &addr, &port) &&
113                                     (ntohl(addr.ip) & 0xff000000) == 0x7f000000)
114                                         i = 0;
115
116                                 pr_debug("nf_nat_ras: set signal address %pI4:%hu->%pI4:%hu\n",
117                                          &addr.ip, port,
118                                          &ct->tuplehash[!dir].tuple.dst.u3.ip,
119                                          info->sig_port[!dir]);
120                                 return set_h225_addr(skb, protoff, data, 0,
121                                                      &taddr[i],
122                                                      &ct->tuplehash[!dir].
123                                                      tuple.dst.u3,
124                                                      info->sig_port[!dir]);
125                         } else if (addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip &&
126                                    port == info->sig_port[dir]) {
127                                 /* GK->GW */
128                                 pr_debug("nf_nat_ras: set signal address %pI4:%hu->%pI4:%hu\n",
129                                          &addr.ip, port,
130                                          &ct->tuplehash[!dir].tuple.src.u3.ip,
131                                          info->sig_port[!dir]);
132                                 return set_h225_addr(skb, protoff, data, 0,
133                                                      &taddr[i],
134                                                      &ct->tuplehash[!dir].
135                                                      tuple.src.u3,
136                                                      info->sig_port[!dir]);
137                         }
138                 }
139         }
140
141         return 0;
142 }
143
144 /****************************************************************************/
145 static int set_ras_addr(struct sk_buff *skb, struct nf_conn *ct,
146                         enum ip_conntrack_info ctinfo,
147                         unsigned int protoff, unsigned char **data,
148                         TransportAddress *taddr, int count)
149 {
150         int dir = CTINFO2DIR(ctinfo);
151         int i;
152         __be16 port;
153         union nf_inet_addr addr;
154
155         for (i = 0; i < count; i++) {
156                 if (get_h225_addr(ct, *data, &taddr[i], &addr, &port) &&
157                     addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
158                     port == ct->tuplehash[dir].tuple.src.u.udp.port) {
159                         pr_debug("nf_nat_ras: set rasAddress %pI4:%hu->%pI4:%hu\n",
160                                  &addr.ip, ntohs(port),
161                                  &ct->tuplehash[!dir].tuple.dst.u3.ip,
162                                  ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port));
163                         return set_h225_addr(skb, protoff, data, 0, &taddr[i],
164                                              &ct->tuplehash[!dir].tuple.dst.u3,
165                                              ct->tuplehash[!dir].tuple.
166                                                                 dst.u.udp.port);
167                 }
168         }
169
170         return 0;
171 }
172
173 /****************************************************************************/
174 static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
175                         enum ip_conntrack_info ctinfo,
176                         unsigned int protoff, unsigned char **data, int dataoff,
177                         H245_TransportAddress *taddr,
178                         __be16 port, __be16 rtp_port,
179                         struct nf_conntrack_expect *rtp_exp,
180                         struct nf_conntrack_expect *rtcp_exp)
181 {
182         struct nf_ct_h323_master *info = nfct_help_data(ct);
183         int dir = CTINFO2DIR(ctinfo);
184         int i;
185         u_int16_t nated_port;
186
187         /* Set expectations for NAT */
188         rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port;
189         rtp_exp->expectfn = nf_nat_follow_master;
190         rtp_exp->dir = !dir;
191         rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port;
192         rtcp_exp->expectfn = nf_nat_follow_master;
193         rtcp_exp->dir = !dir;
194
195         /* Lookup existing expects */
196         for (i = 0; i < H323_RTP_CHANNEL_MAX; i++) {
197                 if (info->rtp_port[i][dir] == rtp_port) {
198                         /* Expected */
199
200                         /* Use allocated ports first. This will refresh
201                          * the expects */
202                         rtp_exp->tuple.dst.u.udp.port = info->rtp_port[i][dir];
203                         rtcp_exp->tuple.dst.u.udp.port =
204                             htons(ntohs(info->rtp_port[i][dir]) + 1);
205                         break;
206                 } else if (info->rtp_port[i][dir] == 0) {
207                         /* Not expected */
208                         break;
209                 }
210         }
211
212         /* Run out of expectations */
213         if (i >= H323_RTP_CHANNEL_MAX) {
214                 net_notice_ratelimited("nf_nat_h323: out of expectations\n");
215                 return 0;
216         }
217
218         /* Try to get a pair of ports. */
219         for (nated_port = ntohs(rtp_exp->tuple.dst.u.udp.port);
220              nated_port != 0; nated_port += 2) {
221                 int ret;
222
223                 rtp_exp->tuple.dst.u.udp.port = htons(nated_port);
224                 ret = nf_ct_expect_related(rtp_exp, 0);
225                 if (ret == 0) {
226                         rtcp_exp->tuple.dst.u.udp.port =
227                             htons(nated_port + 1);
228                         ret = nf_ct_expect_related(rtcp_exp, 0);
229                         if (ret == 0)
230                                 break;
231                         else if (ret == -EBUSY) {
232                                 nf_ct_unexpect_related(rtp_exp);
233                                 continue;
234                         } else if (ret < 0) {
235                                 nf_ct_unexpect_related(rtp_exp);
236                                 nated_port = 0;
237                                 break;
238                         }
239                 } else if (ret != -EBUSY) {
240                         nated_port = 0;
241                         break;
242                 }
243         }
244
245         if (nated_port == 0) {  /* No port available */
246                 net_notice_ratelimited("nf_nat_h323: out of RTP ports\n");
247                 return 0;
248         }
249
250         /* Modify signal */
251         if (set_h245_addr(skb, protoff, data, dataoff, taddr,
252                           &ct->tuplehash[!dir].tuple.dst.u3,
253                           htons((port & htons(1)) ? nated_port + 1 :
254                                                     nated_port))) {
255                 nf_ct_unexpect_related(rtp_exp);
256                 nf_ct_unexpect_related(rtcp_exp);
257                 return -1;
258         }
259
260         /* Save ports */
261         info->rtp_port[i][dir] = rtp_port;
262         info->rtp_port[i][!dir] = htons(nated_port);
263
264         /* Success */
265         pr_debug("nf_nat_h323: expect RTP %pI4:%hu->%pI4:%hu\n",
266                  &rtp_exp->tuple.src.u3.ip,
267                  ntohs(rtp_exp->tuple.src.u.udp.port),
268                  &rtp_exp->tuple.dst.u3.ip,
269                  ntohs(rtp_exp->tuple.dst.u.udp.port));
270         pr_debug("nf_nat_h323: expect RTCP %pI4:%hu->%pI4:%hu\n",
271                  &rtcp_exp->tuple.src.u3.ip,
272                  ntohs(rtcp_exp->tuple.src.u.udp.port),
273                  &rtcp_exp->tuple.dst.u3.ip,
274                  ntohs(rtcp_exp->tuple.dst.u.udp.port));
275
276         return 0;
277 }
278
279 /****************************************************************************/
280 static int nat_t120(struct sk_buff *skb, struct nf_conn *ct,
281                     enum ip_conntrack_info ctinfo,
282                     unsigned int protoff, unsigned char **data, int dataoff,
283                     H245_TransportAddress *taddr, __be16 port,
284                     struct nf_conntrack_expect *exp)
285 {
286         int dir = CTINFO2DIR(ctinfo);
287         u_int16_t nated_port = ntohs(port);
288
289         /* Set expectations for NAT */
290         exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
291         exp->expectfn = nf_nat_follow_master;
292         exp->dir = !dir;
293
294         nated_port = nf_nat_exp_find_port(exp, nated_port);
295         if (nated_port == 0) {  /* No port available */
296                 net_notice_ratelimited("nf_nat_h323: out of TCP ports\n");
297                 return 0;
298         }
299
300         /* Modify signal */
301         if (set_h245_addr(skb, protoff, data, dataoff, taddr,
302                           &ct->tuplehash[!dir].tuple.dst.u3,
303                           htons(nated_port)) < 0) {
304                 nf_ct_unexpect_related(exp);
305                 return -1;
306         }
307
308         pr_debug("nf_nat_h323: expect T.120 %pI4:%hu->%pI4:%hu\n",
309                  &exp->tuple.src.u3.ip,
310                  ntohs(exp->tuple.src.u.tcp.port),
311                  &exp->tuple.dst.u3.ip,
312                  ntohs(exp->tuple.dst.u.tcp.port));
313
314         return 0;
315 }
316
317 /****************************************************************************/
318 static int nat_h245(struct sk_buff *skb, struct nf_conn *ct,
319                     enum ip_conntrack_info ctinfo,
320                     unsigned int protoff, unsigned char **data, int dataoff,
321                     TransportAddress *taddr, __be16 port,
322                     struct nf_conntrack_expect *exp)
323 {
324         struct nf_ct_h323_master *info = nfct_help_data(ct);
325         int dir = CTINFO2DIR(ctinfo);
326         u_int16_t nated_port = ntohs(port);
327
328         /* Set expectations for NAT */
329         exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
330         exp->expectfn = nf_nat_follow_master;
331         exp->dir = !dir;
332
333         /* Check existing expects */
334         if (info->sig_port[dir] == port)
335                 nated_port = ntohs(info->sig_port[!dir]);
336
337         nated_port = nf_nat_exp_find_port(exp, nated_port);
338         if (nated_port == 0) {  /* No port available */
339                 net_notice_ratelimited("nf_nat_q931: out of TCP ports\n");
340                 return 0;
341         }
342
343         /* Modify signal */
344         if (set_h225_addr(skb, protoff, data, dataoff, taddr,
345                           &ct->tuplehash[!dir].tuple.dst.u3,
346                           htons(nated_port))) {
347                 nf_ct_unexpect_related(exp);
348                 return -1;
349         }
350
351         /* Save ports */
352         info->sig_port[dir] = port;
353         info->sig_port[!dir] = htons(nated_port);
354
355         pr_debug("nf_nat_q931: expect H.245 %pI4:%hu->%pI4:%hu\n",
356                  &exp->tuple.src.u3.ip,
357                  ntohs(exp->tuple.src.u.tcp.port),
358                  &exp->tuple.dst.u3.ip,
359                  ntohs(exp->tuple.dst.u.tcp.port));
360
361         return 0;
362 }
363
364 /****************************************************************************
365  * This conntrack expect function replaces nf_conntrack_q931_expect()
366  * which was set by nf_conntrack_h323.c.
367  ****************************************************************************/
368 static void ip_nat_q931_expect(struct nf_conn *new,
369                                struct nf_conntrack_expect *this)
370 {
371         struct nf_nat_range2 range;
372
373         if (this->tuple.src.u3.ip != 0) {       /* Only accept calls from GK */
374                 nf_nat_follow_master(new, this);
375                 return;
376         }
377
378         /* This must be a fresh one. */
379         BUG_ON(new->status & IPS_NAT_DONE_MASK);
380
381         /* Change src to where master sends to */
382         range.flags = NF_NAT_RANGE_MAP_IPS;
383         range.min_addr = range.max_addr =
384             new->tuplehash[!this->dir].tuple.src.u3;
385         nf_nat_setup_info(new, &range, NF_NAT_MANIP_SRC);
386
387         /* For DST manip, map port here to where it's expected. */
388         range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED);
389         range.min_proto = range.max_proto = this->saved_proto;
390         range.min_addr = range.max_addr =
391             new->master->tuplehash[!this->dir].tuple.src.u3;
392         nf_nat_setup_info(new, &range, NF_NAT_MANIP_DST);
393 }
394
395 /****************************************************************************/
396 static int nat_q931(struct sk_buff *skb, struct nf_conn *ct,
397                     enum ip_conntrack_info ctinfo,
398                     unsigned int protoff, unsigned char **data,
399                     TransportAddress *taddr, int idx,
400                     __be16 port, struct nf_conntrack_expect *exp)
401 {
402         struct nf_ct_h323_master *info = nfct_help_data(ct);
403         int dir = CTINFO2DIR(ctinfo);
404         u_int16_t nated_port = ntohs(port);
405         union nf_inet_addr addr;
406
407         /* Set expectations for NAT */
408         exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
409         exp->expectfn = ip_nat_q931_expect;
410         exp->dir = !dir;
411
412         /* Check existing expects */
413         if (info->sig_port[dir] == port)
414                 nated_port = ntohs(info->sig_port[!dir]);
415
416         nated_port = nf_nat_exp_find_port(exp, nated_port);
417         if (nated_port == 0) {  /* No port available */
418                 net_notice_ratelimited("nf_nat_ras: out of TCP ports\n");
419                 return 0;
420         }
421
422         /* Modify signal */
423         if (set_h225_addr(skb, protoff, data, 0, &taddr[idx],
424                           &ct->tuplehash[!dir].tuple.dst.u3,
425                           htons(nated_port))) {
426                 nf_ct_unexpect_related(exp);
427                 return -1;
428         }
429
430         /* Save ports */
431         info->sig_port[dir] = port;
432         info->sig_port[!dir] = htons(nated_port);
433
434         /* Fix for Gnomemeeting */
435         if (idx > 0 &&
436             get_h225_addr(ct, *data, &taddr[0], &addr, &port) &&
437             (ntohl(addr.ip) & 0xff000000) == 0x7f000000) {
438                 if (set_h225_addr(skb, protoff, data, 0, &taddr[0],
439                                   &ct->tuplehash[!dir].tuple.dst.u3,
440                                   info->sig_port[!dir])) {
441                         nf_ct_unexpect_related(exp);
442                         return -1;
443                 }
444         }
445
446         /* Success */
447         pr_debug("nf_nat_ras: expect Q.931 %pI4:%hu->%pI4:%hu\n",
448                  &exp->tuple.src.u3.ip,
449                  ntohs(exp->tuple.src.u.tcp.port),
450                  &exp->tuple.dst.u3.ip,
451                  ntohs(exp->tuple.dst.u.tcp.port));
452
453         return 0;
454 }
455
456 /****************************************************************************/
457 static void ip_nat_callforwarding_expect(struct nf_conn *new,
458                                          struct nf_conntrack_expect *this)
459 {
460         struct nf_nat_range2 range;
461
462         /* This must be a fresh one. */
463         BUG_ON(new->status & IPS_NAT_DONE_MASK);
464
465         /* Change src to where master sends to */
466         range.flags = NF_NAT_RANGE_MAP_IPS;
467         range.min_addr = range.max_addr =
468             new->tuplehash[!this->dir].tuple.src.u3;
469         nf_nat_setup_info(new, &range, NF_NAT_MANIP_SRC);
470
471         /* For DST manip, map port here to where it's expected. */
472         range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED);
473         range.min_proto = range.max_proto = this->saved_proto;
474         range.min_addr = range.max_addr = this->saved_addr;
475         nf_nat_setup_info(new, &range, NF_NAT_MANIP_DST);
476 }
477
478 /****************************************************************************/
479 static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct,
480                               enum ip_conntrack_info ctinfo,
481                               unsigned int protoff,
482                               unsigned char **data, int dataoff,
483                               TransportAddress *taddr, __be16 port,
484                               struct nf_conntrack_expect *exp)
485 {
486         int dir = CTINFO2DIR(ctinfo);
487         u_int16_t nated_port;
488
489         /* Set expectations for NAT */
490         exp->saved_addr = exp->tuple.dst.u3;
491         exp->tuple.dst.u3.ip = ct->tuplehash[!dir].tuple.dst.u3.ip;
492         exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
493         exp->expectfn = ip_nat_callforwarding_expect;
494         exp->dir = !dir;
495
496         nated_port = nf_nat_exp_find_port(exp, ntohs(port));
497         if (nated_port == 0) {  /* No port available */
498                 net_notice_ratelimited("nf_nat_q931: out of TCP ports\n");
499                 return 0;
500         }
501
502         /* Modify signal */
503         if (set_h225_addr(skb, protoff, data, dataoff, taddr,
504                           &ct->tuplehash[!dir].tuple.dst.u3,
505                           htons(nated_port))) {
506                 nf_ct_unexpect_related(exp);
507                 return -1;
508         }
509
510         /* Success */
511         pr_debug("nf_nat_q931: expect Call Forwarding %pI4:%hu->%pI4:%hu\n",
512                  &exp->tuple.src.u3.ip,
513                  ntohs(exp->tuple.src.u.tcp.port),
514                  &exp->tuple.dst.u3.ip,
515                  ntohs(exp->tuple.dst.u.tcp.port));
516
517         return 0;
518 }
519
520 static struct nf_ct_helper_expectfn q931_nat = {
521         .name           = "Q.931",
522         .expectfn       = ip_nat_q931_expect,
523 };
524
525 static struct nf_ct_helper_expectfn callforwarding_nat = {
526         .name           = "callforwarding",
527         .expectfn       = ip_nat_callforwarding_expect,
528 };
529
530 static const struct nfct_h323_nat_hooks nathooks = {
531         .set_h245_addr = set_h245_addr,
532         .set_h225_addr = set_h225_addr,
533         .set_sig_addr = set_sig_addr,
534         .set_ras_addr = set_ras_addr,
535         .nat_rtp_rtcp = nat_rtp_rtcp,
536         .nat_t120 = nat_t120,
537         .nat_h245 = nat_h245,
538         .nat_callforwarding = nat_callforwarding,
539         .nat_q931 = nat_q931,
540 };
541
542 /****************************************************************************/
543 static int __init nf_nat_h323_init(void)
544 {
545         RCU_INIT_POINTER(nfct_h323_nat_hook, &nathooks);
546         nf_ct_helper_expectfn_register(&q931_nat);
547         nf_ct_helper_expectfn_register(&callforwarding_nat);
548         return 0;
549 }
550
551 /****************************************************************************/
552 static void __exit nf_nat_h323_fini(void)
553 {
554         RCU_INIT_POINTER(nfct_h323_nat_hook, NULL);
555         nf_ct_helper_expectfn_unregister(&q931_nat);
556         nf_ct_helper_expectfn_unregister(&callforwarding_nat);
557         synchronize_rcu();
558 }
559
560 /****************************************************************************/
561 module_init(nf_nat_h323_init);
562 module_exit(nf_nat_h323_fini);
563
564 MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>");
565 MODULE_DESCRIPTION("H.323 NAT helper");
566 MODULE_LICENSE("GPL");
567 MODULE_ALIAS_NF_NAT_HELPER("h323");