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