13 #include <linux/module.h>
16 #include <linux/udp.h>
17 #include <linux/tcp.h>
31 static unsigned int mangle_packet(
struct sk_buff *
skb,
unsigned int protoff,
33 const char **dptr,
unsigned int *
datalen,
34 unsigned int matchoff,
unsigned int matchlen,
38 struct nf_conn *
ct = nf_ct_get(skb, &ctinfo);
44 baseoff = protoff + th->doff * 4;
45 matchoff += dataoff - baseoff;
48 protoff, matchoff, matchlen,
49 buffer, buflen,
false))
52 baseoff = protoff +
sizeof(
struct udphdr);
53 matchoff += dataoff - baseoff;
56 protoff, matchoff, matchlen,
62 *dptr = skb->
data + dataoff;
63 *datalen += buflen - matchlen;
67 static int sip_sprintf_addr(
const struct nf_conn *ct,
char *buffer,
71 return sprintf(buffer,
"%pI4", &addr->
ip);
80 static int sip_sprintf_addr_port(
const struct nf_conn *ct,
char *buffer,
84 return sprintf(buffer,
"%pI4:%u", &addr->
ip, port);
86 return sprintf(buffer,
"[%pI6c]:%u", &addr->
ip6, port);
89 static int map_addr(
struct sk_buff *skb,
unsigned int protoff,
91 const char **dptr,
unsigned int *datalen,
92 unsigned int matchoff,
unsigned int matchlen,
96 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
103 if (nf_inet_addr_cmp(&ct->
tuplehash[dir].tuple.src.u3, addr) &&
105 newaddr = ct->
tuplehash[!dir].tuple.dst.u3;
106 newport = ct->
tuplehash[!dir].tuple.dst.u.udp.port;
107 }
else if (nf_inet_addr_cmp(&ct->
tuplehash[dir].tuple.dst.u3, addr) &&
109 newaddr = ct->
tuplehash[!dir].tuple.src.u3;
110 newport = ct->
tuplehash[!dir].tuple.src.u.udp.port;
114 if (nf_inet_addr_cmp(&newaddr, addr) && newport ==
port)
117 buflen = sip_sprintf_addr_port(ct, buffer, &newaddr,
ntohs(newport));
118 return mangle_packet(skb, protoff, dataoff, dptr, datalen,
119 matchoff, matchlen, buffer, buflen);
122 static int map_sip_addr(
struct sk_buff *skb,
unsigned int protoff,
123 unsigned int dataoff,
124 const char **dptr,
unsigned int *datalen,
125 enum sip_header_types
type)
128 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
129 unsigned int matchlen, matchoff;
134 &matchoff, &matchlen, &addr, &port) <= 0)
136 return map_addr(skb, protoff, dataoff, dptr, datalen,
137 matchoff, matchlen, &addr, port);
140 static unsigned int nf_nat_sip(
struct sk_buff *skb,
unsigned int protoff,
141 unsigned int dataoff,
142 const char **dptr,
unsigned int *datalen)
145 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
147 unsigned int coff, matchoff, matchlen;
148 enum sip_header_types
hdr;
156 &matchoff, &matchlen,
158 !map_addr(skb, protoff, dataoff, dptr, datalen,
159 matchoff, matchlen, &addr, port))
166 hdr = SIP_HDR_VIA_TCP;
168 hdr = SIP_HDR_VIA_UDP;
172 hdr,
NULL, &matchoff, &matchlen,
174 unsigned int olen, matchend, poff,
plen,
buflen,
n;
180 if (!nf_inet_addr_cmp(&addr,
182 port != ct->
tuplehash[dir].tuple.src.u.udp.port)
185 if (!nf_inet_addr_cmp(&addr,
187 port != ct->
tuplehash[dir].tuple.dst.u.udp.port)
192 if (!map_addr(skb, protoff, dataoff, dptr, datalen,
193 matchoff, matchlen, &addr, port))
196 matchend = matchoff + matchlen + *datalen - olen;
201 "maddr=", &poff, &plen,
203 nf_inet_addr_cmp(&addr, &ct->
tuplehash[dir].tuple.src.u3) &&
204 !nf_inet_addr_cmp(&addr, &ct->
tuplehash[!dir].tuple.dst.u3)) {
205 buflen = sip_sprintf_addr(ct, buffer,
208 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
209 poff, plen, buffer, buflen))
216 "received=", &poff, &plen,
218 nf_inet_addr_cmp(&addr, &ct->
tuplehash[dir].tuple.dst.u3) &&
219 !nf_inet_addr_cmp(&addr, &ct->
tuplehash[!dir].tuple.src.u3)) {
220 buflen = sip_sprintf_addr(ct, buffer,
223 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
224 poff, plen, buffer, buflen))
231 "rport=", &poff, &plen,
237 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
238 poff, plen, buffer, buflen))
248 SIP_HDR_CONTACT, &in_header,
249 &matchoff, &matchlen,
251 if (!map_addr(skb, protoff, dataoff, dptr, datalen,
257 if (!map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_FROM) ||
258 !map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_TO))
264 static void nf_nat_sip_seq_adjust(
struct sk_buff *skb,
unsigned int protoff,
268 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
279 static void nf_nat_sip_expected(
struct nf_conn *ct,
289 range.min_proto =
range.max_proto = exp->saved_proto;
290 range.min_addr =
range.max_addr = exp->saved_addr;
296 &ct->
master->tuplehash[exp->dir].tuple.src.u3)) {
299 = ct->
master->tuplehash[!exp->dir].tuple.dst.u3;
304 static unsigned int nf_nat_sip_expect(
struct sk_buff *skb,
unsigned int protoff,
305 unsigned int dataoff,
306 const char **dptr,
unsigned int *datalen,
308 unsigned int matchoff,
309 unsigned int matchlen)
312 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
320 if (nf_inet_addr_cmp(&ct->
tuplehash[dir].tuple.src.u3,
322 newaddr = exp->
tuple.dst.u3;
324 newaddr = ct->
tuplehash[!dir].tuple.dst.u3;
329 if (exp->
tuple.dst.u.udp.port ==
335 exp->saved_addr = exp->
tuple.dst.u3;
336 exp->
tuple.dst.u3 = newaddr;
337 exp->saved_proto.udp.port = exp->
tuple.dst.u.udp.port;
339 exp->
expectfn = nf_nat_sip_expected;
341 for (; port != 0; port++) {
345 ret = nf_ct_expect_related(exp);
348 else if (ret != -
EBUSY) {
357 if (!nf_inet_addr_cmp(&exp->
tuple.dst.u3, &exp->saved_addr) ||
358 exp->
tuple.dst.u.udp.port != exp->saved_proto.udp.port) {
359 buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, port);
360 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
361 matchoff, matchlen, buffer, buflen))
371 static int mangle_content_len(
struct sk_buff *skb,
unsigned int protoff,
372 unsigned int dataoff,
373 const char **dptr,
unsigned int *datalen)
376 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
377 unsigned int matchoff, matchlen;
378 char buffer[
sizeof(
"65536")];
383 SDP_HDR_VERSION, SDP_HDR_UNSPEC,
384 &matchoff, &matchlen) <= 0)
386 c_len = *datalen - matchoff +
strlen(
"v=");
390 &matchoff, &matchlen) <= 0)
393 buflen =
sprintf(buffer,
"%u", c_len);
394 return mangle_packet(skb, protoff, dataoff, dptr, datalen,
395 matchoff, matchlen, buffer, buflen);
398 static int mangle_sdp_packet(
struct sk_buff *skb,
unsigned int protoff,
399 unsigned int dataoff,
400 const char **dptr,
unsigned int *datalen,
402 enum sdp_header_types type,
403 enum sdp_header_types term,
404 char *buffer,
int buflen)
407 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
408 unsigned int matchlen, matchoff;
411 &matchoff, &matchlen) <= 0)
413 return mangle_packet(skb, protoff, dataoff, dptr, datalen,
414 matchoff, matchlen, buffer, buflen) ? 0 : -
EINVAL;
417 static unsigned int nf_nat_sdp_addr(
struct sk_buff *skb,
unsigned int protoff,
418 unsigned int dataoff,
419 const char **dptr,
unsigned int *datalen,
421 enum sdp_header_types type,
422 enum sdp_header_types term,
426 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
430 buflen = sip_sprintf_addr(ct, buffer, addr,
false);
431 if (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen,
432 sdpoff, type, term, buffer, buflen))
435 return mangle_content_len(skb, protoff, dataoff, dptr, datalen);
438 static unsigned int nf_nat_sdp_port(
struct sk_buff *skb,
unsigned int protoff,
439 unsigned int dataoff,
440 const char **dptr,
unsigned int *datalen,
441 unsigned int matchoff,
442 unsigned int matchlen,
445 char buffer[
sizeof(
"nnnnn")];
448 buflen =
sprintf(buffer,
"%u", port);
449 if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
450 matchoff, matchlen, buffer, buflen))
453 return mangle_content_len(skb, protoff, dataoff, dptr, datalen);
456 static unsigned int nf_nat_sdp_session(
struct sk_buff *skb,
unsigned int protoff,
457 unsigned int dataoff,
458 const char **dptr,
unsigned int *datalen,
463 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
468 buflen = sip_sprintf_addr(ct, buffer, addr,
false);
469 if (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen, sdpoff,
470 SDP_HDR_OWNER, SDP_HDR_MEDIA, buffer, buflen))
473 switch (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen, sdpoff,
474 SDP_HDR_CONNECTION, SDP_HDR_MEDIA,
490 return mangle_content_len(skb, protoff, dataoff, dptr, datalen);
495 static unsigned int nf_nat_sdp_media(
struct sk_buff *skb,
unsigned int protoff,
496 unsigned int dataoff,
497 const char **dptr,
unsigned int *datalen,
500 unsigned int mediaoff,
501 unsigned int medialen,
505 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
510 if (nf_inet_addr_cmp(&ct->
tuplehash[dir].tuple.src.u3,
512 *rtp_addr = rtp_exp->
tuple.dst.u3;
514 *rtp_addr = ct->
tuplehash[!dir].tuple.dst.u3;
516 rtp_exp->saved_addr = rtp_exp->
tuple.dst.u3;
517 rtp_exp->
tuple.dst.u3 = *rtp_addr;
518 rtp_exp->saved_proto.udp.port = rtp_exp->
tuple.dst.u.udp.port;
520 rtp_exp->
expectfn = nf_nat_sip_expected;
522 rtcp_exp->saved_addr = rtcp_exp->
tuple.dst.u3;
523 rtcp_exp->
tuple.dst.u3 = *rtp_addr;
524 rtcp_exp->saved_proto.udp.port = rtcp_exp->
tuple.dst.u.udp.port;
525 rtcp_exp->dir = !dir;
526 rtcp_exp->
expectfn = nf_nat_sip_expected;
529 for (port =
ntohs(rtp_exp->
tuple.dst.u.udp.port);
530 port != 0; port += 2) {
534 ret = nf_ct_expect_related(rtp_exp);
541 rtcp_exp->
tuple.dst.u.udp.port =
htons(port + 1);
542 ret = nf_ct_expect_related(rtcp_exp);
545 else if (ret == -
EBUSY) {
548 }
else if (ret < 0) {
559 if (rtp_exp->
tuple.dst.u.udp.port != rtp_exp->saved_proto.udp.port &&
560 !nf_nat_sdp_port(skb, protoff, dataoff, dptr, datalen,
561 mediaoff, medialen, port))
575 .expectfn = nf_nat_sip_expected,
578 static void __exit nf_nat_sip_fini(
void)
591 static int __init nf_nat_sip_init(
void)