aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/nf_nat_sip.c101
-rw-r--r--net/netfilter/nf_conntrack_sip.c82
2 files changed, 95 insertions, 88 deletions
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index 07d61a57613c..2454ea5abb79 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -29,7 +29,7 @@ MODULE_DESCRIPTION("SIP NAT helper");
29MODULE_ALIAS("ip_nat_sip"); 29MODULE_ALIAS("ip_nat_sip");
30 30
31 31
32static unsigned int mangle_packet(struct sk_buff *skb, 32static unsigned int mangle_packet(struct sk_buff *skb, unsigned int dataoff,
33 const char **dptr, unsigned int *datalen, 33 const char **dptr, unsigned int *datalen,
34 unsigned int matchoff, unsigned int matchlen, 34 unsigned int matchoff, unsigned int matchlen,
35 const char *buffer, unsigned int buflen) 35 const char *buffer, unsigned int buflen)
@@ -42,12 +42,12 @@ static unsigned int mangle_packet(struct sk_buff *skb,
42 return 0; 42 return 0;
43 43
44 /* Reload data pointer and adjust datalen value */ 44 /* Reload data pointer and adjust datalen value */
45 *dptr = skb->data + ip_hdrlen(skb) + sizeof(struct udphdr); 45 *dptr = skb->data + dataoff;
46 *datalen += buflen - matchlen; 46 *datalen += buflen - matchlen;
47 return 1; 47 return 1;
48} 48}
49 49
50static int map_addr(struct sk_buff *skb, 50static int map_addr(struct sk_buff *skb, unsigned int dataoff,
51 const char **dptr, unsigned int *datalen, 51 const char **dptr, unsigned int *datalen,
52 unsigned int matchoff, unsigned int matchlen, 52 unsigned int matchoff, unsigned int matchlen,
53 union nf_inet_addr *addr, __be16 port) 53 union nf_inet_addr *addr, __be16 port)
@@ -76,11 +76,11 @@ static int map_addr(struct sk_buff *skb,
76 76
77 buflen = sprintf(buffer, "%pI4:%u", &newaddr, ntohs(newport)); 77 buflen = sprintf(buffer, "%pI4:%u", &newaddr, ntohs(newport));
78 78
79 return mangle_packet(skb, dptr, datalen, matchoff, matchlen, 79 return mangle_packet(skb, dataoff, dptr, datalen, matchoff, matchlen,
80 buffer, buflen); 80 buffer, buflen);
81} 81}
82 82
83static int map_sip_addr(struct sk_buff *skb, 83static int map_sip_addr(struct sk_buff *skb, unsigned int dataoff,
84 const char **dptr, unsigned int *datalen, 84 const char **dptr, unsigned int *datalen,
85 enum sip_header_types type) 85 enum sip_header_types type)
86{ 86{
@@ -93,16 +93,17 @@ static int map_sip_addr(struct sk_buff *skb,
93 if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, type, NULL, 93 if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, type, NULL,
94 &matchoff, &matchlen, &addr, &port) <= 0) 94 &matchoff, &matchlen, &addr, &port) <= 0)
95 return 1; 95 return 1;
96 return map_addr(skb, dptr, datalen, matchoff, matchlen, &addr, port); 96 return map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen,
97 &addr, port);
97} 98}
98 99
99static unsigned int ip_nat_sip(struct sk_buff *skb, 100static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,
100 const char **dptr, unsigned int *datalen) 101 const char **dptr, unsigned int *datalen)
101{ 102{
102 enum ip_conntrack_info ctinfo; 103 enum ip_conntrack_info ctinfo;
103 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 104 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
104 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 105 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
105 unsigned int dataoff, matchoff, matchlen; 106 unsigned int coff, matchoff, matchlen;
106 union nf_inet_addr addr; 107 union nf_inet_addr addr;
107 __be16 port; 108 __be16 port;
108 int request, in_header; 109 int request, in_header;
@@ -112,7 +113,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb,
112 if (ct_sip_parse_request(ct, *dptr, *datalen, 113 if (ct_sip_parse_request(ct, *dptr, *datalen,
113 &matchoff, &matchlen, 114 &matchoff, &matchlen,
114 &addr, &port) > 0 && 115 &addr, &port) > 0 &&
115 !map_addr(skb, dptr, datalen, matchoff, matchlen, 116 !map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen,
116 &addr, port)) 117 &addr, port))
117 return NF_DROP; 118 return NF_DROP;
118 request = 1; 119 request = 1;
@@ -138,7 +139,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb,
138 goto next; 139 goto next;
139 } 140 }
140 141
141 if (!map_addr(skb, dptr, datalen, matchoff, matchlen, 142 if (!map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen,
142 &addr, port)) 143 &addr, port))
143 return NF_DROP; 144 return NF_DROP;
144 145
@@ -153,8 +154,8 @@ static unsigned int ip_nat_sip(struct sk_buff *skb,
153 addr.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) { 154 addr.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) {
154 buflen = sprintf(buffer, "%pI4", 155 buflen = sprintf(buffer, "%pI4",
155 &ct->tuplehash[!dir].tuple.dst.u3.ip); 156 &ct->tuplehash[!dir].tuple.dst.u3.ip);
156 if (!mangle_packet(skb, dptr, datalen, poff, plen, 157 if (!mangle_packet(skb, dataoff, dptr, datalen,
157 buffer, buflen)) 158 poff, plen, buffer, buflen))
158 return NF_DROP; 159 return NF_DROP;
159 } 160 }
160 161
@@ -167,8 +168,8 @@ static unsigned int ip_nat_sip(struct sk_buff *skb,
167 addr.ip != ct->tuplehash[!dir].tuple.src.u3.ip) { 168 addr.ip != ct->tuplehash[!dir].tuple.src.u3.ip) {
168 buflen = sprintf(buffer, "%pI4", 169 buflen = sprintf(buffer, "%pI4",
169 &ct->tuplehash[!dir].tuple.src.u3.ip); 170 &ct->tuplehash[!dir].tuple.src.u3.ip);
170 if (!mangle_packet(skb, dptr, datalen, poff, plen, 171 if (!mangle_packet(skb, dataoff, dptr, datalen,
171 buffer, buflen)) 172 poff, plen, buffer, buflen))
172 return NF_DROP; 173 return NF_DROP;
173 } 174 }
174 175
@@ -181,27 +182,27 @@ static unsigned int ip_nat_sip(struct sk_buff *skb,
181 htons(n) != ct->tuplehash[!dir].tuple.src.u.udp.port) { 182 htons(n) != ct->tuplehash[!dir].tuple.src.u.udp.port) {
182 __be16 p = ct->tuplehash[!dir].tuple.src.u.udp.port; 183 __be16 p = ct->tuplehash[!dir].tuple.src.u.udp.port;
183 buflen = sprintf(buffer, "%u", ntohs(p)); 184 buflen = sprintf(buffer, "%u", ntohs(p));
184 if (!mangle_packet(skb, dptr, datalen, poff, plen, 185 if (!mangle_packet(skb, dataoff, dptr, datalen,
185 buffer, buflen)) 186 poff, plen, buffer, buflen))
186 return NF_DROP; 187 return NF_DROP;
187 } 188 }
188 } 189 }
189 190
190next: 191next:
191 /* Translate Contact headers */ 192 /* Translate Contact headers */
192 dataoff = 0; 193 coff = 0;
193 in_header = 0; 194 in_header = 0;
194 while (ct_sip_parse_header_uri(ct, *dptr, &dataoff, *datalen, 195 while (ct_sip_parse_header_uri(ct, *dptr, &coff, *datalen,
195 SIP_HDR_CONTACT, &in_header, 196 SIP_HDR_CONTACT, &in_header,
196 &matchoff, &matchlen, 197 &matchoff, &matchlen,
197 &addr, &port) > 0) { 198 &addr, &port) > 0) {
198 if (!map_addr(skb, dptr, datalen, matchoff, matchlen, 199 if (!map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen,
199 &addr, port)) 200 &addr, port))
200 return NF_DROP; 201 return NF_DROP;
201 } 202 }
202 203
203 if (!map_sip_addr(skb, dptr, datalen, SIP_HDR_FROM) || 204 if (!map_sip_addr(skb, dataoff, dptr, datalen, SIP_HDR_FROM) ||
204 !map_sip_addr(skb, dptr, datalen, SIP_HDR_TO)) 205 !map_sip_addr(skb, dataoff, dptr, datalen, SIP_HDR_TO))
205 return NF_DROP; 206 return NF_DROP;
206 return NF_ACCEPT; 207 return NF_ACCEPT;
207} 208}
@@ -232,7 +233,7 @@ static void ip_nat_sip_expected(struct nf_conn *ct,
232 } 233 }
233} 234}
234 235
235static unsigned int ip_nat_sip_expect(struct sk_buff *skb, 236static unsigned int ip_nat_sip_expect(struct sk_buff *skb, unsigned int dataoff,
236 const char **dptr, unsigned int *datalen, 237 const char **dptr, unsigned int *datalen,
237 struct nf_conntrack_expect *exp, 238 struct nf_conntrack_expect *exp,
238 unsigned int matchoff, 239 unsigned int matchoff,
@@ -279,8 +280,8 @@ static unsigned int ip_nat_sip_expect(struct sk_buff *skb,
279 if (exp->tuple.dst.u3.ip != exp->saved_ip || 280 if (exp->tuple.dst.u3.ip != exp->saved_ip ||
280 exp->tuple.dst.u.udp.port != exp->saved_proto.udp.port) { 281 exp->tuple.dst.u.udp.port != exp->saved_proto.udp.port) {
281 buflen = sprintf(buffer, "%pI4:%u", &newip, port); 282 buflen = sprintf(buffer, "%pI4:%u", &newip, port);
282 if (!mangle_packet(skb, dptr, datalen, matchoff, matchlen, 283 if (!mangle_packet(skb, dataoff, dptr, datalen,
283 buffer, buflen)) 284 matchoff, matchlen, buffer, buflen))
284 goto err; 285 goto err;
285 } 286 }
286 return NF_ACCEPT; 287 return NF_ACCEPT;
@@ -290,7 +291,7 @@ err:
290 return NF_DROP; 291 return NF_DROP;
291} 292}
292 293
293static int mangle_content_len(struct sk_buff *skb, 294static int mangle_content_len(struct sk_buff *skb, unsigned int dataoff,
294 const char **dptr, unsigned int *datalen) 295 const char **dptr, unsigned int *datalen)
295{ 296{
296 enum ip_conntrack_info ctinfo; 297 enum ip_conntrack_info ctinfo;
@@ -312,12 +313,13 @@ static int mangle_content_len(struct sk_buff *skb,
312 return 0; 313 return 0;
313 314
314 buflen = sprintf(buffer, "%u", c_len); 315 buflen = sprintf(buffer, "%u", c_len);
315 return mangle_packet(skb, dptr, datalen, matchoff, matchlen, 316 return mangle_packet(skb, dataoff, dptr, datalen, matchoff, matchlen,
316 buffer, buflen); 317 buffer, buflen);
317} 318}
318 319
319static int mangle_sdp_packet(struct sk_buff *skb, const char **dptr, 320static int mangle_sdp_packet(struct sk_buff *skb, unsigned int dataoff,
320 unsigned int dataoff, unsigned int *datalen, 321 const char **dptr, unsigned int *datalen,
322 unsigned int sdpoff,
321 enum sdp_header_types type, 323 enum sdp_header_types type,
322 enum sdp_header_types term, 324 enum sdp_header_types term,
323 char *buffer, int buflen) 325 char *buffer, int buflen)
@@ -326,16 +328,16 @@ static int mangle_sdp_packet(struct sk_buff *skb, const char **dptr,
326 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 328 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
327 unsigned int matchlen, matchoff; 329 unsigned int matchlen, matchoff;
328 330
329 if (ct_sip_get_sdp_header(ct, *dptr, dataoff, *datalen, type, term, 331 if (ct_sip_get_sdp_header(ct, *dptr, sdpoff, *datalen, type, term,
330 &matchoff, &matchlen) <= 0) 332 &matchoff, &matchlen) <= 0)
331 return -ENOENT; 333 return -ENOENT;
332 return mangle_packet(skb, dptr, datalen, matchoff, matchlen, 334 return mangle_packet(skb, dataoff, dptr, datalen, matchoff, matchlen,
333 buffer, buflen) ? 0 : -EINVAL; 335 buffer, buflen) ? 0 : -EINVAL;
334} 336}
335 337
336static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr, 338static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, unsigned int dataoff,
337 unsigned int dataoff, 339 const char **dptr, unsigned int *datalen,
338 unsigned int *datalen, 340 unsigned int sdpoff,
339 enum sdp_header_types type, 341 enum sdp_header_types type,
340 enum sdp_header_types term, 342 enum sdp_header_types term,
341 const union nf_inet_addr *addr) 343 const union nf_inet_addr *addr)
@@ -344,16 +346,15 @@ static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr,
344 unsigned int buflen; 346 unsigned int buflen;
345 347
346 buflen = sprintf(buffer, "%pI4", &addr->ip); 348 buflen = sprintf(buffer, "%pI4", &addr->ip);
347 if (mangle_sdp_packet(skb, dptr, dataoff, datalen, type, term, 349 if (mangle_sdp_packet(skb, dataoff, dptr, datalen, sdpoff, type, term,
348 buffer, buflen)) 350 buffer, buflen))
349 return 0; 351 return 0;
350 352
351 return mangle_content_len(skb, dptr, datalen); 353 return mangle_content_len(skb, dataoff, dptr, datalen);
352} 354}
353 355
354static unsigned int ip_nat_sdp_port(struct sk_buff *skb, 356static unsigned int ip_nat_sdp_port(struct sk_buff *skb, unsigned int dataoff,
355 const char **dptr, 357 const char **dptr, unsigned int *datalen,
356 unsigned int *datalen,
357 unsigned int matchoff, 358 unsigned int matchoff,
358 unsigned int matchlen, 359 unsigned int matchlen,
359 u_int16_t port) 360 u_int16_t port)
@@ -362,16 +363,16 @@ static unsigned int ip_nat_sdp_port(struct sk_buff *skb,
362 unsigned int buflen; 363 unsigned int buflen;
363 364
364 buflen = sprintf(buffer, "%u", port); 365 buflen = sprintf(buffer, "%u", port);
365 if (!mangle_packet(skb, dptr, datalen, matchoff, matchlen, 366 if (!mangle_packet(skb, dataoff, dptr, datalen, matchoff, matchlen,
366 buffer, buflen)) 367 buffer, buflen))
367 return 0; 368 return 0;
368 369
369 return mangle_content_len(skb, dptr, datalen); 370 return mangle_content_len(skb, dataoff, dptr, datalen);
370} 371}
371 372
372static unsigned int ip_nat_sdp_session(struct sk_buff *skb, const char **dptr, 373static unsigned int ip_nat_sdp_session(struct sk_buff *skb, unsigned int dataoff,
373 unsigned int dataoff, 374 const char **dptr, unsigned int *datalen,
374 unsigned int *datalen, 375 unsigned int sdpoff,
375 const union nf_inet_addr *addr) 376 const union nf_inet_addr *addr)
376{ 377{
377 char buffer[sizeof("nnn.nnn.nnn.nnn")]; 378 char buffer[sizeof("nnn.nnn.nnn.nnn")];
@@ -379,12 +380,12 @@ static unsigned int ip_nat_sdp_session(struct sk_buff *skb, const char **dptr,
379 380
380 /* Mangle session description owner and contact addresses */ 381 /* Mangle session description owner and contact addresses */
381 buflen = sprintf(buffer, "%pI4", &addr->ip); 382 buflen = sprintf(buffer, "%pI4", &addr->ip);
382 if (mangle_sdp_packet(skb, dptr, dataoff, datalen, 383 if (mangle_sdp_packet(skb, dataoff, dptr, datalen, sdpoff,
383 SDP_HDR_OWNER_IP4, SDP_HDR_MEDIA, 384 SDP_HDR_OWNER_IP4, SDP_HDR_MEDIA,
384 buffer, buflen)) 385 buffer, buflen))
385 return 0; 386 return 0;
386 387
387 switch (mangle_sdp_packet(skb, dptr, dataoff, datalen, 388 switch (mangle_sdp_packet(skb, dataoff, dptr, datalen, sdpoff,
388 SDP_HDR_CONNECTION_IP4, SDP_HDR_MEDIA, 389 SDP_HDR_CONNECTION_IP4, SDP_HDR_MEDIA,
389 buffer, buflen)) { 390 buffer, buflen)) {
390 case 0: 391 case 0:
@@ -401,14 +402,13 @@ static unsigned int ip_nat_sdp_session(struct sk_buff *skb, const char **dptr,
401 return 0; 402 return 0;
402 } 403 }
403 404
404 return mangle_content_len(skb, dptr, datalen); 405 return mangle_content_len(skb, dataoff, dptr, datalen);
405} 406}
406 407
407/* So, this packet has hit the connection tracking matching code. 408/* So, this packet has hit the connection tracking matching code.
408 Mangle it, and change the expectation to match the new version. */ 409 Mangle it, and change the expectation to match the new version. */
409static unsigned int ip_nat_sdp_media(struct sk_buff *skb, 410static unsigned int ip_nat_sdp_media(struct sk_buff *skb, unsigned int dataoff,
410 const char **dptr, 411 const char **dptr, unsigned int *datalen,
411 unsigned int *datalen,
412 struct nf_conntrack_expect *rtp_exp, 412 struct nf_conntrack_expect *rtp_exp,
413 struct nf_conntrack_expect *rtcp_exp, 413 struct nf_conntrack_expect *rtcp_exp,
414 unsigned int mediaoff, 414 unsigned int mediaoff,
@@ -456,7 +456,8 @@ static unsigned int ip_nat_sdp_media(struct sk_buff *skb,
456 456
457 /* Update media port. */ 457 /* Update media port. */
458 if (rtp_exp->tuple.dst.u.udp.port != rtp_exp->saved_proto.udp.port && 458 if (rtp_exp->tuple.dst.u.udp.port != rtp_exp->saved_proto.udp.port &&
459 !ip_nat_sdp_port(skb, dptr, datalen, mediaoff, medialen, port)) 459 !ip_nat_sdp_port(skb, dataoff, dptr, datalen,
460 mediaoff, medialen, port))
460 goto err2; 461 goto err2;
461 462
462 return NF_ACCEPT; 463 return NF_ACCEPT;
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 0ca2f2b5c2fa..0ec37d6a2df7 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -50,12 +50,13 @@ module_param(sip_direct_media, int, 0600);
50MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling " 50MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling "
51 "endpoints only (default 1)"); 51 "endpoints only (default 1)");
52 52
53unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, 53unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, unsigned int dataoff,
54 const char **dptr, 54 const char **dptr,
55 unsigned int *datalen) __read_mostly; 55 unsigned int *datalen) __read_mostly;
56EXPORT_SYMBOL_GPL(nf_nat_sip_hook); 56EXPORT_SYMBOL_GPL(nf_nat_sip_hook);
57 57
58unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb, 58unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb,
59 unsigned int dataoff,
59 const char **dptr, 60 const char **dptr,
60 unsigned int *datalen, 61 unsigned int *datalen,
61 struct nf_conntrack_expect *exp, 62 struct nf_conntrack_expect *exp,
@@ -63,17 +64,17 @@ unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb,
63 unsigned int matchlen) __read_mostly; 64 unsigned int matchlen) __read_mostly;
64EXPORT_SYMBOL_GPL(nf_nat_sip_expect_hook); 65EXPORT_SYMBOL_GPL(nf_nat_sip_expect_hook);
65 66
66unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb, 67unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb, unsigned int dataoff,
67 const char **dptr, 68 const char **dptr,
68 unsigned int dataoff,
69 unsigned int *datalen, 69 unsigned int *datalen,
70 unsigned int sdpoff,
70 enum sdp_header_types type, 71 enum sdp_header_types type,
71 enum sdp_header_types term, 72 enum sdp_header_types term,
72 const union nf_inet_addr *addr) 73 const union nf_inet_addr *addr)
73 __read_mostly; 74 __read_mostly;
74EXPORT_SYMBOL_GPL(nf_nat_sdp_addr_hook); 75EXPORT_SYMBOL_GPL(nf_nat_sdp_addr_hook);
75 76
76unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb, 77unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb, unsigned int dataoff,
77 const char **dptr, 78 const char **dptr,
78 unsigned int *datalen, 79 unsigned int *datalen,
79 unsigned int matchoff, 80 unsigned int matchoff,
@@ -82,14 +83,15 @@ unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb,
82EXPORT_SYMBOL_GPL(nf_nat_sdp_port_hook); 83EXPORT_SYMBOL_GPL(nf_nat_sdp_port_hook);
83 84
84unsigned int (*nf_nat_sdp_session_hook)(struct sk_buff *skb, 85unsigned int (*nf_nat_sdp_session_hook)(struct sk_buff *skb,
85 const char **dptr,
86 unsigned int dataoff, 86 unsigned int dataoff,
87 const char **dptr,
87 unsigned int *datalen, 88 unsigned int *datalen,
89 unsigned int sdpoff,
88 const union nf_inet_addr *addr) 90 const union nf_inet_addr *addr)
89 __read_mostly; 91 __read_mostly;
90EXPORT_SYMBOL_GPL(nf_nat_sdp_session_hook); 92EXPORT_SYMBOL_GPL(nf_nat_sdp_session_hook);
91 93
92unsigned int (*nf_nat_sdp_media_hook)(struct sk_buff *skb, 94unsigned int (*nf_nat_sdp_media_hook)(struct sk_buff *skb, unsigned int dataoff,
93 const char **dptr, 95 const char **dptr,
94 unsigned int *datalen, 96 unsigned int *datalen,
95 struct nf_conntrack_expect *rtp_exp, 97 struct nf_conntrack_expect *rtp_exp,
@@ -729,7 +731,7 @@ static void flush_expectations(struct nf_conn *ct, bool media)
729 spin_unlock_bh(&nf_conntrack_lock); 731 spin_unlock_bh(&nf_conntrack_lock);
730} 732}
731 733
732static int set_expected_rtp_rtcp(struct sk_buff *skb, 734static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int dataoff,
733 const char **dptr, unsigned int *datalen, 735 const char **dptr, unsigned int *datalen,
734 union nf_inet_addr *daddr, __be16 port, 736 union nf_inet_addr *daddr, __be16 port,
735 enum sip_expectation_classes class, 737 enum sip_expectation_classes class,
@@ -806,7 +808,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
806 if (direct_rtp) { 808 if (direct_rtp) {
807 nf_nat_sdp_port = rcu_dereference(nf_nat_sdp_port_hook); 809 nf_nat_sdp_port = rcu_dereference(nf_nat_sdp_port_hook);
808 if (nf_nat_sdp_port && 810 if (nf_nat_sdp_port &&
809 !nf_nat_sdp_port(skb, dptr, datalen, 811 !nf_nat_sdp_port(skb, dataoff, dptr, datalen,
810 mediaoff, medialen, ntohs(rtp_port))) 812 mediaoff, medialen, ntohs(rtp_port)))
811 goto err1; 813 goto err1;
812 } 814 }
@@ -828,7 +830,8 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
828 830
829 nf_nat_sdp_media = rcu_dereference(nf_nat_sdp_media_hook); 831 nf_nat_sdp_media = rcu_dereference(nf_nat_sdp_media_hook);
830 if (nf_nat_sdp_media && ct->status & IPS_NAT_MASK && !direct_rtp) 832 if (nf_nat_sdp_media && ct->status & IPS_NAT_MASK && !direct_rtp)
831 ret = nf_nat_sdp_media(skb, dptr, datalen, rtp_exp, rtcp_exp, 833 ret = nf_nat_sdp_media(skb, dataoff, dptr, datalen,
834 rtp_exp, rtcp_exp,
832 mediaoff, medialen, daddr); 835 mediaoff, medialen, daddr);
833 else { 836 else {
834 if (nf_ct_expect_related(rtp_exp) == 0) { 837 if (nf_ct_expect_related(rtp_exp) == 0) {
@@ -867,7 +870,7 @@ static const struct sdp_media_type *sdp_media_type(const char *dptr,
867 return NULL; 870 return NULL;
868} 871}
869 872
870static int process_sdp(struct sk_buff *skb, 873static int process_sdp(struct sk_buff *skb, unsigned int dataoff,
871 const char **dptr, unsigned int *datalen, 874 const char **dptr, unsigned int *datalen,
872 unsigned int cseq) 875 unsigned int cseq)
873{ 876{
@@ -942,7 +945,7 @@ static int process_sdp(struct sk_buff *skb,
942 else 945 else
943 return NF_DROP; 946 return NF_DROP;
944 947
945 ret = set_expected_rtp_rtcp(skb, dptr, datalen, 948 ret = set_expected_rtp_rtcp(skb, dataoff, dptr, datalen,
946 &rtp_addr, htons(port), t->class, 949 &rtp_addr, htons(port), t->class,
947 mediaoff, medialen); 950 mediaoff, medialen);
948 if (ret != NF_ACCEPT) 951 if (ret != NF_ACCEPT)
@@ -950,8 +953,9 @@ static int process_sdp(struct sk_buff *skb,
950 953
951 /* Update media connection address if present */ 954 /* Update media connection address if present */
952 if (maddr_len && nf_nat_sdp_addr && ct->status & IPS_NAT_MASK) { 955 if (maddr_len && nf_nat_sdp_addr && ct->status & IPS_NAT_MASK) {
953 ret = nf_nat_sdp_addr(skb, dptr, mediaoff, datalen, 956 ret = nf_nat_sdp_addr(skb, dataoff, dptr, datalen,
954 c_hdr, SDP_HDR_MEDIA, &rtp_addr); 957 mediaoff, c_hdr, SDP_HDR_MEDIA,
958 &rtp_addr);
955 if (ret != NF_ACCEPT) 959 if (ret != NF_ACCEPT)
956 return ret; 960 return ret;
957 } 961 }
@@ -961,14 +965,15 @@ static int process_sdp(struct sk_buff *skb,
961 /* Update session connection and owner addresses */ 965 /* Update session connection and owner addresses */
962 nf_nat_sdp_session = rcu_dereference(nf_nat_sdp_session_hook); 966 nf_nat_sdp_session = rcu_dereference(nf_nat_sdp_session_hook);
963 if (nf_nat_sdp_session && ct->status & IPS_NAT_MASK) 967 if (nf_nat_sdp_session && ct->status & IPS_NAT_MASK)
964 ret = nf_nat_sdp_session(skb, dptr, sdpoff, datalen, &rtp_addr); 968 ret = nf_nat_sdp_session(skb, dataoff, dptr, datalen, sdpoff,
969 &rtp_addr);
965 970
966 if (ret == NF_ACCEPT && i > 0) 971 if (ret == NF_ACCEPT && i > 0)
967 help->help.ct_sip_info.invite_cseq = cseq; 972 help->help.ct_sip_info.invite_cseq = cseq;
968 973
969 return ret; 974 return ret;
970} 975}
971static int process_invite_response(struct sk_buff *skb, 976static int process_invite_response(struct sk_buff *skb, unsigned int dataoff,
972 const char **dptr, unsigned int *datalen, 977 const char **dptr, unsigned int *datalen,
973 unsigned int cseq, unsigned int code) 978 unsigned int cseq, unsigned int code)
974{ 979{
@@ -978,13 +983,13 @@ static int process_invite_response(struct sk_buff *skb,
978 983
979 if ((code >= 100 && code <= 199) || 984 if ((code >= 100 && code <= 199) ||
980 (code >= 200 && code <= 299)) 985 (code >= 200 && code <= 299))
981 return process_sdp(skb, dptr, datalen, cseq); 986 return process_sdp(skb, dataoff, dptr, datalen, cseq);
982 else if (help->help.ct_sip_info.invite_cseq == cseq) 987 else if (help->help.ct_sip_info.invite_cseq == cseq)
983 flush_expectations(ct, true); 988 flush_expectations(ct, true);
984 return NF_ACCEPT; 989 return NF_ACCEPT;
985} 990}
986 991
987static int process_update_response(struct sk_buff *skb, 992static int process_update_response(struct sk_buff *skb, unsigned int dataoff,
988 const char **dptr, unsigned int *datalen, 993 const char **dptr, unsigned int *datalen,
989 unsigned int cseq, unsigned int code) 994 unsigned int cseq, unsigned int code)
990{ 995{
@@ -994,13 +999,13 @@ static int process_update_response(struct sk_buff *skb,
994 999
995 if ((code >= 100 && code <= 199) || 1000 if ((code >= 100 && code <= 199) ||
996 (code >= 200 && code <= 299)) 1001 (code >= 200 && code <= 299))
997 return process_sdp(skb, dptr, datalen, cseq); 1002 return process_sdp(skb, dataoff, dptr, datalen, cseq);
998 else if (help->help.ct_sip_info.invite_cseq == cseq) 1003 else if (help->help.ct_sip_info.invite_cseq == cseq)
999 flush_expectations(ct, true); 1004 flush_expectations(ct, true);
1000 return NF_ACCEPT; 1005 return NF_ACCEPT;
1001} 1006}
1002 1007
1003static int process_prack_response(struct sk_buff *skb, 1008static int process_prack_response(struct sk_buff *skb, unsigned int dataoff,
1004 const char **dptr, unsigned int *datalen, 1009 const char **dptr, unsigned int *datalen,
1005 unsigned int cseq, unsigned int code) 1010 unsigned int cseq, unsigned int code)
1006{ 1011{
@@ -1010,13 +1015,13 @@ static int process_prack_response(struct sk_buff *skb,
1010 1015
1011 if ((code >= 100 && code <= 199) || 1016 if ((code >= 100 && code <= 199) ||
1012 (code >= 200 && code <= 299)) 1017 (code >= 200 && code <= 299))
1013 return process_sdp(skb, dptr, datalen, cseq); 1018 return process_sdp(skb, dataoff, dptr, datalen, cseq);
1014 else if (help->help.ct_sip_info.invite_cseq == cseq) 1019 else if (help->help.ct_sip_info.invite_cseq == cseq)
1015 flush_expectations(ct, true); 1020 flush_expectations(ct, true);
1016 return NF_ACCEPT; 1021 return NF_ACCEPT;
1017} 1022}
1018 1023
1019static int process_bye_request(struct sk_buff *skb, 1024static int process_bye_request(struct sk_buff *skb, unsigned int dataoff,
1020 const char **dptr, unsigned int *datalen, 1025 const char **dptr, unsigned int *datalen,
1021 unsigned int cseq) 1026 unsigned int cseq)
1022{ 1027{
@@ -1031,7 +1036,7 @@ static int process_bye_request(struct sk_buff *skb,
1031 * signalling connections. The expectation is marked inactive and is activated 1036 * signalling connections. The expectation is marked inactive and is activated
1032 * when receiving a response indicating success from the registrar. 1037 * when receiving a response indicating success from the registrar.
1033 */ 1038 */
1034static int process_register_request(struct sk_buff *skb, 1039static int process_register_request(struct sk_buff *skb, unsigned int dataoff,
1035 const char **dptr, unsigned int *datalen, 1040 const char **dptr, unsigned int *datalen,
1036 unsigned int cseq) 1041 unsigned int cseq)
1037{ 1042{
@@ -1101,7 +1106,7 @@ static int process_register_request(struct sk_buff *skb,
1101 1106
1102 nf_nat_sip_expect = rcu_dereference(nf_nat_sip_expect_hook); 1107 nf_nat_sip_expect = rcu_dereference(nf_nat_sip_expect_hook);
1103 if (nf_nat_sip_expect && ct->status & IPS_NAT_MASK) 1108 if (nf_nat_sip_expect && ct->status & IPS_NAT_MASK)
1104 ret = nf_nat_sip_expect(skb, dptr, datalen, exp, 1109 ret = nf_nat_sip_expect(skb, dataoff, dptr, datalen, exp,
1105 matchoff, matchlen); 1110 matchoff, matchlen);
1106 else { 1111 else {
1107 if (nf_ct_expect_related(exp) != 0) 1112 if (nf_ct_expect_related(exp) != 0)
@@ -1117,7 +1122,7 @@ store_cseq:
1117 return ret; 1122 return ret;
1118} 1123}
1119 1124
1120static int process_register_response(struct sk_buff *skb, 1125static int process_register_response(struct sk_buff *skb, unsigned int dataoff,
1121 const char **dptr, unsigned int *datalen, 1126 const char **dptr, unsigned int *datalen,
1122 unsigned int cseq, unsigned int code) 1127 unsigned int cseq, unsigned int code)
1123{ 1128{
@@ -1127,7 +1132,7 @@ static int process_register_response(struct sk_buff *skb,
1127 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 1132 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
1128 union nf_inet_addr addr; 1133 union nf_inet_addr addr;
1129 __be16 port; 1134 __be16 port;
1130 unsigned int matchoff, matchlen, dataoff = 0; 1135 unsigned int matchoff, matchlen, coff = 0;
1131 unsigned int expires = 0; 1136 unsigned int expires = 0;
1132 int in_contact = 0, ret; 1137 int in_contact = 0, ret;
1133 1138
@@ -1154,7 +1159,7 @@ static int process_register_response(struct sk_buff *skb,
1154 while (1) { 1159 while (1) {
1155 unsigned int c_expires = expires; 1160 unsigned int c_expires = expires;
1156 1161
1157 ret = ct_sip_parse_header_uri(ct, *dptr, &dataoff, *datalen, 1162 ret = ct_sip_parse_header_uri(ct, *dptr, &coff, *datalen,
1158 SIP_HDR_CONTACT, &in_contact, 1163 SIP_HDR_CONTACT, &in_contact,
1159 &matchoff, &matchlen, 1164 &matchoff, &matchlen,
1160 &addr, &port); 1165 &addr, &port);
@@ -1193,13 +1198,13 @@ static const struct sip_handler sip_handlers[] = {
1193 SIP_HANDLER("REGISTER", process_register_request, process_register_response), 1198 SIP_HANDLER("REGISTER", process_register_request, process_register_response),
1194}; 1199};
1195 1200
1196static int process_sip_response(struct sk_buff *skb, 1201static int process_sip_response(struct sk_buff *skb, unsigned int dataoff,
1197 const char **dptr, unsigned int *datalen) 1202 const char **dptr, unsigned int *datalen)
1198{ 1203{
1199 enum ip_conntrack_info ctinfo; 1204 enum ip_conntrack_info ctinfo;
1200 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1205 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1201 unsigned int matchoff, matchlen; 1206 unsigned int matchoff, matchlen, matchend;
1202 unsigned int code, cseq, dataoff, i; 1207 unsigned int code, cseq, i;
1203 1208
1204 if (*datalen < strlen("SIP/2.0 200")) 1209 if (*datalen < strlen("SIP/2.0 200"))
1205 return NF_ACCEPT; 1210 return NF_ACCEPT;
@@ -1213,7 +1218,7 @@ static int process_sip_response(struct sk_buff *skb,
1213 cseq = simple_strtoul(*dptr + matchoff, NULL, 10); 1218 cseq = simple_strtoul(*dptr + matchoff, NULL, 10);
1214 if (!cseq) 1219 if (!cseq)
1215 return NF_DROP; 1220 return NF_DROP;
1216 dataoff = matchoff + matchlen + 1; 1221 matchend = matchoff + matchlen + 1;
1217 1222
1218 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) { 1223 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
1219 const struct sip_handler *handler; 1224 const struct sip_handler *handler;
@@ -1221,15 +1226,16 @@ static int process_sip_response(struct sk_buff *skb,
1221 handler = &sip_handlers[i]; 1226 handler = &sip_handlers[i];
1222 if (handler->response == NULL) 1227 if (handler->response == NULL)
1223 continue; 1228 continue;
1224 if (*datalen < dataoff + handler->len || 1229 if (*datalen < matchend + handler->len ||
1225 strnicmp(*dptr + dataoff, handler->method, handler->len)) 1230 strnicmp(*dptr + matchend, handler->method, handler->len))
1226 continue; 1231 continue;
1227 return handler->response(skb, dptr, datalen, cseq, code); 1232 return handler->response(skb, dataoff, dptr, datalen,
1233 cseq, code);
1228 } 1234 }
1229 return NF_ACCEPT; 1235 return NF_ACCEPT;
1230} 1236}
1231 1237
1232static int process_sip_request(struct sk_buff *skb, 1238static int process_sip_request(struct sk_buff *skb, unsigned int dataoff,
1233 const char **dptr, unsigned int *datalen) 1239 const char **dptr, unsigned int *datalen)
1234{ 1240{
1235 enum ip_conntrack_info ctinfo; 1241 enum ip_conntrack_info ctinfo;
@@ -1254,7 +1260,7 @@ static int process_sip_request(struct sk_buff *skb,
1254 if (!cseq) 1260 if (!cseq)
1255 return NF_DROP; 1261 return NF_DROP;
1256 1262
1257 return handler->request(skb, dptr, datalen, cseq); 1263 return handler->request(skb, dataoff, dptr, datalen, cseq);
1258 } 1264 }
1259 return NF_ACCEPT; 1265 return NF_ACCEPT;
1260} 1266}
@@ -1288,13 +1294,13 @@ static int sip_help(struct sk_buff *skb,
1288 return NF_ACCEPT; 1294 return NF_ACCEPT;
1289 1295
1290 if (strnicmp(dptr, "SIP/2.0 ", strlen("SIP/2.0 ")) != 0) 1296 if (strnicmp(dptr, "SIP/2.0 ", strlen("SIP/2.0 ")) != 0)
1291 ret = process_sip_request(skb, &dptr, &datalen); 1297 ret = process_sip_request(skb, dataoff, &dptr, &datalen);
1292 else 1298 else
1293 ret = process_sip_response(skb, &dptr, &datalen); 1299 ret = process_sip_response(skb, dataoff, &dptr, &datalen);
1294 1300
1295 if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) { 1301 if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) {
1296 nf_nat_sip = rcu_dereference(nf_nat_sip_hook); 1302 nf_nat_sip = rcu_dereference(nf_nat_sip_hook);
1297 if (nf_nat_sip && !nf_nat_sip(skb, &dptr, &datalen)) 1303 if (nf_nat_sip && !nf_nat_sip(skb, dataoff, &dptr, &datalen))
1298 ret = NF_DROP; 1304 ret = NF_DROP;
1299 } 1305 }
1300 1306