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