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"); 568