1 // SPDX-License-Identifier: GPL-2.0-only 2 /* SIP extension for NAT alteration. 3 * 4 * (C) 2005 by Christian Hentschel <chentschel@arnet.com.ar> 5 * based on RR's ip_nat_ftp.c and other modules. 6 * (C) 2007 United Security Providers 7 * (C) 2007, 2008, 2011, 2012 Patrick McHardy <kaber@trash.net> 8 */ 9 10 #include <linux/module.h> 11 #include <linux/skbuff.h> 12 #include <linux/inet.h> 13 #include <linux/udp.h> 14 #include <linux/tcp.h> 15 16 #include <net/netfilter/nf_nat.h> 17 #include <net/netfilter/nf_nat_helper.h> 18 #include <net/netfilter/nf_conntrack_core.h> 19 #include <net/netfilter/nf_conntrack_helper.h> 20 #include <net/netfilter/nf_conntrack_expect.h> 21 #include <net/netfilter/nf_conntrack_seqadj.h> 22 #include <linux/netfilter/nf_conntrack_sip.h> 23 24 #define NAT_HELPER_NAME "sip" 25 26 MODULE_LICENSE("GPL"); 27 MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>"); 28 MODULE_DESCRIPTION("SIP NAT helper"); 29 MODULE_ALIAS_NF_NAT_HELPER(NAT_HELPER_NAME); 30 31 static struct nf_conntrack_nat_helper nat_helper_sip = 32 NF_CT_NAT_HELPER_INIT(NAT_HELPER_NAME); 33 34 static unsigned int mangle_packet(struct sk_buff *skb, unsigned int protoff, 35 unsigned int dataoff, 36 const char **dptr, unsigned int *datalen, 37 unsigned int matchoff, unsigned int matchlen, 38 const char *buffer, unsigned int buflen) 39 { 40 enum ip_conntrack_info ctinfo; 41 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 42 struct tcphdr *th; 43 unsigned int baseoff; 44 45 if (nf_ct_protonum(ct) == IPPROTO_TCP) { 46 th = (struct tcphdr *)(skb->data + protoff); 47 baseoff = protoff + th->doff * 4; 48 matchoff += dataoff - baseoff; 49 50 if (!__nf_nat_mangle_tcp_packet(skb, ct, ctinfo, 51 protoff, matchoff, matchlen, 52 buffer, buflen, false)) 53 return 0; 54 } else { 55 baseoff = protoff + sizeof(struct udphdr); 56 matchoff += dataoff - baseoff; 57 58 if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo, 59 protoff, matchoff, matchlen, 60 buffer, buflen)) 61 return 0; 62 } 63 64 /* Reload data pointer and adjust datalen value */ 65 *dptr = skb->data + dataoff; 66 *datalen += buflen - matchlen; 67 return 1; 68 } 69 70 static int sip_sprintf_addr(const struct nf_conn *ct, char *buffer, 71 const union nf_inet_addr *addr, bool delim) 72 { 73 if (nf_ct_l3num(ct) == NFPROTO_IPV4) 74 return sprintf(buffer, "%pI4", &addr->ip); 75 else { 76 if (delim) 77 return sprintf(buffer, "[%pI6c]", &addr->ip6); 78 else 79 return sprintf(buffer, "%pI6c", &addr->ip6); 80 } 81 } 82 83 static int sip_sprintf_addr_port(const struct nf_conn *ct, char *buffer, 84 const union nf_inet_addr *addr, u16 port) 85 { 86 if (nf_ct_l3num(ct) == NFPROTO_IPV4) 87 return sprintf(buffer, "%pI4:%u", &addr->ip, port); 88 else 89 return sprintf(buffer, "[%pI6c]:%u", &addr->ip6, port); 90 } 91 92 static int map_addr(struct sk_buff *skb, unsigned int protoff, 93 unsigned int dataoff, 94 const char **dptr, unsigned int *datalen, 95 unsigned int matchoff, unsigned int matchlen, 96 union nf_inet_addr *addr, __be16 port) 97 { 98 enum ip_conntrack_info ctinfo; 99 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 100 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 101 struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); 102 char buffer[INET6_ADDRSTRLEN + sizeof("[]:nnnnn")]; 103 unsigned int buflen; 104 union nf_inet_addr newaddr; 105 __be16 newport; 106 107 if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, addr) && 108 ct->tuplehash[dir].tuple.src.u.udp.port == port) { 109 newaddr = ct->tuplehash[!dir].tuple.dst.u3; 110 newport = ct->tuplehash[!dir].tuple.dst.u.udp.port; 111 } else if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3, addr) && 112 ct->tuplehash[dir].tuple.dst.u.udp.port == port) { 113 newaddr = ct->tuplehash[!dir].tuple.src.u3; 114 newport = ct_sip_info->forced_dport ? : 115 ct->tuplehash[!dir].tuple.src.u.udp.port; 116 } else 117 return 1; 118 119 if (nf_inet_addr_cmp(&newaddr, addr) && newport == port) 120 return 1; 121 122 buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, ntohs(newport)); 123 return mangle_packet(skb, protoff, dataoff, dptr, datalen, 124 matchoff, matchlen, buffer, buflen); 125 } 126 127 static int map_sip_addr(struct sk_buff *skb, unsigned int protoff, 128 unsigned int dataoff, 129 const char **dptr, unsigned int *datalen, 130 enum sip_header_types type) 131 { 132 enum ip_conntrack_info ctinfo; 133 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 134 unsigned int matchlen, matchoff; 135 union nf_inet_addr addr; 136 __be16 port; 137 138 if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, type, NULL, 139 &matchoff, &matchlen, &addr, &port) <= 0) 140 return 1; 141 return map_addr(skb, protoff, dataoff, dptr, datalen, 142 matchoff, matchlen, &addr, port); 143 } 144 145 static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff, 146 unsigned int dataoff, 147 const char **dptr, unsigned int *datalen) 148 { 149 enum ip_conntrack_info ctinfo; 150 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 151 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 152 struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); 153 unsigned int coff, matchoff, matchlen; 154 enum sip_header_types hdr; 155 union nf_inet_addr addr; 156 __be16 port; 157 int request, in_header; 158 159 /* Basic rules: requests and responses. */ 160 if (strncasecmp(*dptr, "SIP/2.0", strlen("SIP/2.0")) != 0) { 161 if (ct_sip_parse_request(ct, *dptr, *datalen, 162 &matchoff, &matchlen, 163 &addr, &port) > 0 && 164 !map_addr(skb, protoff, dataoff, dptr, datalen, 165 matchoff, matchlen, &addr, port)) { 166 nf_ct_helper_log(skb, ct, "cannot mangle SIP message"); 167 return NF_DROP; 168 } 169 request = 1; 170 } else 171 request = 0; 172 173 if (nf_ct_protonum(ct) == IPPROTO_TCP) 174 hdr = SIP_HDR_VIA_TCP; 175 else 176 hdr = SIP_HDR_VIA_UDP; 177 178 /* Translate topmost Via header and parameters */ 179 if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, 180 hdr, NULL, &matchoff, &matchlen, 181 &addr, &port) > 0) { 182 unsigned int olen, matchend, poff, plen, buflen, n; 183 char buffer[INET6_ADDRSTRLEN + sizeof("[]:nnnnn")]; 184 185 /* We're only interested in headers related to this 186 * connection */ 187 if (request) { 188 if (!nf_inet_addr_cmp(&addr, 189 &ct->tuplehash[dir].tuple.src.u3) || 190 port != ct->tuplehash[dir].tuple.src.u.udp.port) 191 goto next; 192 } else { 193 if (!nf_inet_addr_cmp(&addr, 194 &ct->tuplehash[dir].tuple.dst.u3) || 195 port != ct->tuplehash[dir].tuple.dst.u.udp.port) 196 goto next; 197 } 198 199 olen = *datalen; 200 if (!map_addr(skb, protoff, dataoff, dptr, datalen, 201 matchoff, matchlen, &addr, port)) { 202 nf_ct_helper_log(skb, ct, "cannot mangle Via header"); 203 return NF_DROP; 204 } 205 206 matchend = matchoff + matchlen + *datalen - olen; 207 208 /* The maddr= parameter (RFC 2361) specifies where to send 209 * the reply. */ 210 if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen, 211 "maddr=", &poff, &plen, 212 &addr, true) > 0 && 213 nf_inet_addr_cmp(&addr, &ct->tuplehash[dir].tuple.src.u3) && 214 !nf_inet_addr_cmp(&addr, &ct->tuplehash[!dir].tuple.dst.u3)) { 215 buflen = sip_sprintf_addr(ct, buffer, 216 &ct->tuplehash[!dir].tuple.dst.u3, 217 true); 218 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, 219 poff, plen, buffer, buflen)) { 220 nf_ct_helper_log(skb, ct, "cannot mangle maddr"); 221 return NF_DROP; 222 } 223 } 224 225 /* The received= parameter (RFC 2361) contains the address 226 * from which the server received the request. */ 227 if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen, 228 "received=", &poff, &plen, 229 &addr, false) > 0 && 230 nf_inet_addr_cmp(&addr, &ct->tuplehash[dir].tuple.dst.u3) && 231 !nf_inet_addr_cmp(&addr, &ct->tuplehash[!dir].tuple.src.u3)) { 232 buflen = sip_sprintf_addr(ct, buffer, 233 &ct->tuplehash[!dir].tuple.src.u3, 234 false); 235 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, 236 poff, plen, buffer, buflen)) { 237 nf_ct_helper_log(skb, ct, "cannot mangle received"); 238 return NF_DROP; 239 } 240 } 241 242 /* The rport= parameter (RFC 3581) contains the port number 243 * from which the server received the request. */ 244 if (ct_sip_parse_numerical_param(ct, *dptr, matchend, *datalen, 245 "rport=", &poff, &plen, 246 &n) > 0 && 247 htons(n) == ct->tuplehash[dir].tuple.dst.u.udp.port && 248 htons(n) != ct->tuplehash[!dir].tuple.src.u.udp.port) { 249 __be16 p = ct->tuplehash[!dir].tuple.src.u.udp.port; 250 buflen = sprintf(buffer, "%u", ntohs(p)); 251 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, 252 poff, plen, buffer, buflen)) { 253 nf_ct_helper_log(skb, ct, "cannot mangle rport"); 254 return NF_DROP; 255 } 256 } 257 } 258 259 next: 260 /* Translate Contact headers */ 261 coff = 0; 262 in_header = 0; 263 while (ct_sip_parse_header_uri(ct, *dptr, &coff, *datalen, 264 SIP_HDR_CONTACT, &in_header, 265 &matchoff, &matchlen, 266 &addr, &port) > 0) { 267 if (!map_addr(skb, protoff, dataoff, dptr, datalen, 268 matchoff, matchlen, 269 &addr, port)) { 270 nf_ct_helper_log(skb, ct, "cannot mangle contact"); 271 return NF_DROP; 272 } 273 } 274 275 if (!map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_FROM) || 276 !map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_TO)) { 277 nf_ct_helper_log(skb, ct, "cannot mangle SIP from/to"); 278 return NF_DROP; 279 } 280 281 /* Mangle destination port for Cisco phones, then fix up checksums */ 282 if (dir == IP_CT_DIR_REPLY && ct_sip_info->forced_dport) { 283 struct udphdr *uh; 284 285 if (skb_ensure_writable(skb, skb->len)) { 286 nf_ct_helper_log(skb, ct, "cannot mangle packet"); 287 return NF_DROP; 288 } 289 290 uh = (void *)skb->data + protoff; 291 uh->dest = ct_sip_info->forced_dport; 292 293 if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo, protoff, 294 0, 0, NULL, 0)) { 295 nf_ct_helper_log(skb, ct, "cannot mangle packet"); 296 return NF_DROP; 297 } 298 } 299 300 return NF_ACCEPT; 301 } 302 303 static void nf_nat_sip_seq_adjust(struct sk_buff *skb, unsigned int protoff, 304 s16 off) 305 { 306 enum ip_conntrack_info ctinfo; 307 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 308 const struct tcphdr *th; 309 310 if (nf_ct_protonum(ct) != IPPROTO_TCP || off == 0) 311 return; 312 313 th = (struct tcphdr *)(skb->data + protoff); 314 nf_ct_seqadj_set(ct, ctinfo, th->seq, off); 315 } 316 317 /* Handles expected signalling connections and media streams */ 318 static void nf_nat_sip_expected(struct nf_conn *ct, 319 struct nf_conntrack_expect *exp) 320 { 321 struct nf_conn_help *help = nfct_help(ct->master); 322 struct nf_conntrack_expect *pair_exp; 323 int range_set_for_snat = 0; 324 struct nf_nat_range2 range; 325 326 /* This must be a fresh one. */ 327 BUG_ON(ct->status & IPS_NAT_DONE_MASK); 328 329 /* For DST manip, map port here to where it's expected. */ 330 range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED); 331 range.min_proto = range.max_proto = exp->saved_proto; 332 range.min_addr = range.max_addr = exp->saved_addr; 333 nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST); 334 335 /* Do media streams SRC manip according with the parameters 336 * found in the paired expectation. 337 */ 338 if (exp->class != SIP_EXPECT_SIGNALLING) { 339 spin_lock_bh(&nf_conntrack_expect_lock); 340 hlist_for_each_entry(pair_exp, &help->expectations, lnode) { 341 if (pair_exp->tuple.src.l3num == nf_ct_l3num(ct) && 342 pair_exp->tuple.dst.protonum == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum && 343 nf_inet_addr_cmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, &pair_exp->saved_addr) && 344 ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.all == pair_exp->saved_proto.all) { 345 range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED); 346 range.min_proto.all = range.max_proto.all = pair_exp->tuple.dst.u.all; 347 range.min_addr = range.max_addr = pair_exp->tuple.dst.u3; 348 range_set_for_snat = 1; 349 break; 350 } 351 } 352 spin_unlock_bh(&nf_conntrack_expect_lock); 353 } 354 355 /* When no paired expectation has been found, change src to 356 * where master sends to, but only if the connection actually came 357 * from the same source. 358 */ 359 if (!range_set_for_snat && 360 nf_inet_addr_cmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, 361 &ct->master->tuplehash[exp->dir].tuple.src.u3)) { 362 range.flags = NF_NAT_RANGE_MAP_IPS; 363 range.min_addr = range.max_addr 364 = ct->master->tuplehash[!exp->dir].tuple.dst.u3; 365 range_set_for_snat = 1; 366 } 367 368 /* Perform SRC manip. */ 369 if (range_set_for_snat) 370 nf_nat_setup_info(ct, &range, NF_NAT_MANIP_SRC); 371 } 372 373 static unsigned int nf_nat_sip_expect(struct sk_buff *skb, unsigned int protoff, 374 unsigned int dataoff, 375 const char **dptr, unsigned int *datalen, 376 struct nf_conntrack_expect *exp, 377 unsigned int matchoff, 378 unsigned int matchlen) 379 { 380 enum ip_conntrack_info ctinfo; 381 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 382 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 383 struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); 384 union nf_inet_addr newaddr; 385 u_int16_t port; 386 __be16 srcport; 387 char buffer[INET6_ADDRSTRLEN + sizeof("[]:nnnnn")]; 388 unsigned int buflen; 389 390 /* Connection will come from reply */ 391 if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, 392 &ct->tuplehash[!dir].tuple.dst.u3)) 393 newaddr = exp->tuple.dst.u3; 394 else 395 newaddr = ct->tuplehash[!dir].tuple.dst.u3; 396 397 /* If the signalling port matches the connection's source port in the 398 * original direction, try to use the destination port in the opposite 399 * direction. */ 400 srcport = ct_sip_info->forced_dport ? : 401 ct->tuplehash[dir].tuple.src.u.udp.port; 402 if (exp->tuple.dst.u.udp.port == srcport) 403 port = ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port); 404 else 405 port = ntohs(exp->tuple.dst.u.udp.port); 406 407 exp->saved_addr = exp->tuple.dst.u3; 408 exp->tuple.dst.u3 = newaddr; 409 exp->saved_proto.udp.port = exp->tuple.dst.u.udp.port; 410 exp->dir = !dir; 411 exp->expectfn = nf_nat_sip_expected; 412 413 port = nf_nat_exp_find_port(exp, port); 414 if (port == 0) { 415 nf_ct_helper_log(skb, ct, "all ports in use for SIP"); 416 return NF_DROP; 417 } 418 419 if (!nf_inet_addr_cmp(&exp->tuple.dst.u3, &exp->saved_addr) || 420 exp->tuple.dst.u.udp.port != exp->saved_proto.udp.port) { 421 buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, port); 422 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, 423 matchoff, matchlen, buffer, buflen)) { 424 nf_ct_helper_log(skb, ct, "cannot mangle packet"); 425 goto err; 426 } 427 } 428 return NF_ACCEPT; 429 430 err: 431 nf_ct_unexpect_related(exp); 432 return NF_DROP; 433 } 434 435 static int mangle_content_len(struct sk_buff *skb, unsigned int protoff, 436 unsigned int dataoff, 437 const char **dptr, unsigned int *datalen) 438 { 439 enum ip_conntrack_info ctinfo; 440 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 441 unsigned int matchoff, matchlen; 442 char buffer[sizeof("65536")]; 443 int buflen, c_len; 444 445 /* Get actual SDP length */ 446 if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen, 447 SDP_HDR_VERSION, SDP_HDR_UNSPEC, 448 &matchoff, &matchlen) <= 0) 449 return 0; 450 c_len = *datalen - matchoff + strlen("v="); 451 452 /* Now, update SDP length */ 453 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CONTENT_LENGTH, 454 &matchoff, &matchlen) <= 0) 455 return 0; 456 457 buflen = sprintf(buffer, "%u", c_len); 458 return mangle_packet(skb, protoff, dataoff, dptr, datalen, 459 matchoff, matchlen, buffer, buflen); 460 } 461 462 static int mangle_sdp_packet(struct sk_buff *skb, unsigned int protoff, 463 unsigned int dataoff, 464 const char **dptr, unsigned int *datalen, 465 unsigned int sdpoff, 466 enum sdp_header_types type, 467 enum sdp_header_types term, 468 char *buffer, int buflen) 469 { 470 enum ip_conntrack_info ctinfo; 471 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 472 unsigned int matchlen, matchoff; 473 474 if (ct_sip_get_sdp_header(ct, *dptr, sdpoff, *datalen, type, term, 475 &matchoff, &matchlen) <= 0) 476 return -ENOENT; 477 return mangle_packet(skb, protoff, dataoff, dptr, datalen, 478 matchoff, matchlen, buffer, buflen) ? 0 : -EINVAL; 479 } 480 481 static unsigned int nf_nat_sdp_addr(struct sk_buff *skb, unsigned int protoff, 482 unsigned int dataoff, 483 const char **dptr, unsigned int *datalen, 484 unsigned int sdpoff, 485 enum sdp_header_types type, 486 enum sdp_header_types term, 487 const union nf_inet_addr *addr) 488 { 489 enum ip_conntrack_info ctinfo; 490 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 491 char buffer[INET6_ADDRSTRLEN]; 492 unsigned int buflen; 493 494 buflen = sip_sprintf_addr(ct, buffer, addr, false); 495 if (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen, 496 sdpoff, type, term, buffer, buflen)) 497 return 0; 498 499 return mangle_content_len(skb, protoff, dataoff, dptr, datalen); 500 } 501 502 static unsigned int nf_nat_sdp_port(struct sk_buff *skb, unsigned int protoff, 503 unsigned int dataoff, 504 const char **dptr, unsigned int *datalen, 505 unsigned int matchoff, 506 unsigned int matchlen, 507 u_int16_t port) 508 { 509 char buffer[sizeof("nnnnn")]; 510 unsigned int buflen; 511 512 buflen = sprintf(buffer, "%u", port); 513 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, 514 matchoff, matchlen, buffer, buflen)) 515 return 0; 516 517 return mangle_content_len(skb, protoff, dataoff, dptr, datalen); 518 } 519 520 static unsigned int nf_nat_sdp_session(struct sk_buff *skb, unsigned int protoff, 521 unsigned int dataoff, 522 const char **dptr, unsigned int *datalen, 523 unsigned int sdpoff, 524 const union nf_inet_addr *addr) 525 { 526 enum ip_conntrack_info ctinfo; 527 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 528 char buffer[INET6_ADDRSTRLEN]; 529 unsigned int buflen; 530 531 /* Mangle session description owner and contact addresses */ 532 buflen = sip_sprintf_addr(ct, buffer, addr, false); 533 if (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen, sdpoff, 534 SDP_HDR_OWNER, SDP_HDR_MEDIA, buffer, buflen)) 535 return 0; 536 537 switch (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen, sdpoff, 538 SDP_HDR_CONNECTION, SDP_HDR_MEDIA, 539 buffer, buflen)) { 540 case 0: 541 /* 542 * RFC 2327: 543 * 544 * Session description 545 * 546 * c=* (connection information - not required if included in all media) 547 */ 548 case -ENOENT: 549 break; 550 default: 551 return 0; 552 } 553 554 return mangle_content_len(skb, protoff, dataoff, dptr, datalen); 555 } 556 557 /* So, this packet has hit the connection tracking matching code. 558 Mangle it, and change the expectation to match the new version. */ 559 static unsigned int nf_nat_sdp_media(struct sk_buff *skb, unsigned int protoff, 560 unsigned int dataoff, 561 const char **dptr, unsigned int *datalen, 562 struct nf_conntrack_expect *rtp_exp, 563 struct nf_conntrack_expect *rtcp_exp, 564 unsigned int mediaoff, 565 unsigned int medialen, 566 union nf_inet_addr *rtp_addr) 567 { 568 enum ip_conntrack_info ctinfo; 569 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 570 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 571 u_int16_t port; 572 573 /* Connection will come from reply */ 574 if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, 575 &ct->tuplehash[!dir].tuple.dst.u3)) 576 *rtp_addr = rtp_exp->tuple.dst.u3; 577 else 578 *rtp_addr = ct->tuplehash[!dir].tuple.dst.u3; 579 580 rtp_exp->saved_addr = rtp_exp->tuple.dst.u3; 581 rtp_exp->tuple.dst.u3 = *rtp_addr; 582 rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port; 583 rtp_exp->dir = !dir; 584 rtp_exp->expectfn = nf_nat_sip_expected; 585 586 rtcp_exp->saved_addr = rtcp_exp->tuple.dst.u3; 587 rtcp_exp->tuple.dst.u3 = *rtp_addr; 588 rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port; 589 rtcp_exp->dir = !dir; 590 rtcp_exp->expectfn = nf_nat_sip_expected; 591 592 /* Try to get same pair of ports: if not, try to change them. */ 593 for (port = ntohs(rtp_exp->tuple.dst.u.udp.port); 594 port != 0; port += 2) { 595 int ret; 596 597 rtp_exp->tuple.dst.u.udp.port = htons(port); 598 ret = nf_ct_expect_related(rtp_exp, 599 NF_CT_EXP_F_SKIP_MASTER); 600 if (ret == -EBUSY) 601 continue; 602 else if (ret < 0) { 603 port = 0; 604 break; 605 } 606 rtcp_exp->tuple.dst.u.udp.port = htons(port + 1); 607 ret = nf_ct_expect_related(rtcp_exp, 608 NF_CT_EXP_F_SKIP_MASTER); 609 if (ret == 0) 610 break; 611 else if (ret == -EBUSY) { 612 nf_ct_unexpect_related(rtp_exp); 613 continue; 614 } else if (ret < 0) { 615 nf_ct_unexpect_related(rtp_exp); 616 port = 0; 617 break; 618 } 619 } 620 621 if (port == 0) { 622 nf_ct_helper_log(skb, ct, "all ports in use for SDP media"); 623 goto err1; 624 } 625 626 /* Update media port. */ 627 if (rtp_exp->tuple.dst.u.udp.port != rtp_exp->saved_proto.udp.port && 628 !nf_nat_sdp_port(skb, protoff, dataoff, dptr, datalen, 629 mediaoff, medialen, port)) { 630 nf_ct_helper_log(skb, ct, "cannot mangle SDP message"); 631 goto err2; 632 } 633 634 return NF_ACCEPT; 635 636 err2: 637 nf_ct_unexpect_related(rtp_exp); 638 nf_ct_unexpect_related(rtcp_exp); 639 err1: 640 return NF_DROP; 641 } 642 643 static struct nf_ct_helper_expectfn sip_nat = { 644 .name = "sip", 645 .expectfn = nf_nat_sip_expected, 646 }; 647 648 static void __exit nf_nat_sip_fini(void) 649 { 650 nf_nat_helper_unregister(&nat_helper_sip); 651 RCU_INIT_POINTER(nf_nat_sip_hooks, NULL); 652 nf_ct_helper_expectfn_unregister(&sip_nat); 653 synchronize_rcu(); 654 } 655 656 static const struct nf_nat_sip_hooks sip_hooks = { 657 .msg = nf_nat_sip, 658 .seq_adjust = nf_nat_sip_seq_adjust, 659 .expect = nf_nat_sip_expect, 660 .sdp_addr = nf_nat_sdp_addr, 661 .sdp_port = nf_nat_sdp_port, 662 .sdp_session = nf_nat_sdp_session, 663 .sdp_media = nf_nat_sdp_media, 664 }; 665 666 static int __init nf_nat_sip_init(void) 667 { 668 BUG_ON(nf_nat_sip_hooks != NULL); 669 nf_nat_helper_register(&nat_helper_sip); 670 RCU_INIT_POINTER(nf_nat_sip_hooks, &sip_hooks); 671 nf_ct_helper_expectfn_register(&sip_nat); 672 return 0; 673 } 674 675 module_init(nf_nat_sip_init); 676 module_exit(nf_nat_sip_fini); 677