Commit 7874896a26624214bd7c05eeba7c8ab01548b1b5

Authored by Simon Horman
Committed by David S. Miller
1 parent d485d500cf

netfilter: nf_ct_sip: default to NF_ACCEPT in sip_help_tcp()

I initially noticed this because of the compiler warning below, but it
does seem to be a valid concern in the case where ct_sip_get_header()
returns 0 in the first iteration of the while loop.

net/netfilter/nf_conntrack_sip.c: In function 'sip_help_tcp':
net/netfilter/nf_conntrack_sip.c:1379: warning: 'ret' may be used uninitialized in this function

Signed-off-by: Simon Horman <horms@verge.net.au>
[Patrick: changed NF_DROP to NF_ACCEPT]
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 1 additions and 1 deletions Inline Diff

net/netfilter/nf_conntrack_sip.c
1 /* SIP extension for IP connection tracking. 1 /* SIP extension for IP connection tracking.
2 * 2 *
3 * (C) 2005 by Christian Hentschel <chentschel@arnet.com.ar> 3 * (C) 2005 by Christian Hentschel <chentschel@arnet.com.ar>
4 * based on RR's ip_conntrack_ftp.c and other modules. 4 * based on RR's ip_conntrack_ftp.c and other modules.
5 * (C) 2007 United Security Providers 5 * (C) 2007 United Security Providers
6 * (C) 2007, 2008 Patrick McHardy <kaber@trash.net> 6 * (C) 2007, 2008 Patrick McHardy <kaber@trash.net>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13 #include <linux/module.h> 13 #include <linux/module.h>
14 #include <linux/ctype.h> 14 #include <linux/ctype.h>
15 #include <linux/skbuff.h> 15 #include <linux/skbuff.h>
16 #include <linux/inet.h> 16 #include <linux/inet.h>
17 #include <linux/in.h> 17 #include <linux/in.h>
18 #include <linux/udp.h> 18 #include <linux/udp.h>
19 #include <linux/tcp.h> 19 #include <linux/tcp.h>
20 #include <linux/netfilter.h> 20 #include <linux/netfilter.h>
21 21
22 #include <net/netfilter/nf_conntrack.h> 22 #include <net/netfilter/nf_conntrack.h>
23 #include <net/netfilter/nf_conntrack_core.h> 23 #include <net/netfilter/nf_conntrack_core.h>
24 #include <net/netfilter/nf_conntrack_expect.h> 24 #include <net/netfilter/nf_conntrack_expect.h>
25 #include <net/netfilter/nf_conntrack_helper.h> 25 #include <net/netfilter/nf_conntrack_helper.h>
26 #include <net/netfilter/nf_conntrack_zones.h> 26 #include <net/netfilter/nf_conntrack_zones.h>
27 #include <linux/netfilter/nf_conntrack_sip.h> 27 #include <linux/netfilter/nf_conntrack_sip.h>
28 28
29 MODULE_LICENSE("GPL"); 29 MODULE_LICENSE("GPL");
30 MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>"); 30 MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
31 MODULE_DESCRIPTION("SIP connection tracking helper"); 31 MODULE_DESCRIPTION("SIP connection tracking helper");
32 MODULE_ALIAS("ip_conntrack_sip"); 32 MODULE_ALIAS("ip_conntrack_sip");
33 MODULE_ALIAS_NFCT_HELPER("sip"); 33 MODULE_ALIAS_NFCT_HELPER("sip");
34 34
35 #define MAX_PORTS 8 35 #define MAX_PORTS 8
36 static unsigned short ports[MAX_PORTS]; 36 static unsigned short ports[MAX_PORTS];
37 static unsigned int ports_c; 37 static unsigned int ports_c;
38 module_param_array(ports, ushort, &ports_c, 0400); 38 module_param_array(ports, ushort, &ports_c, 0400);
39 MODULE_PARM_DESC(ports, "port numbers of SIP servers"); 39 MODULE_PARM_DESC(ports, "port numbers of SIP servers");
40 40
41 static unsigned int sip_timeout __read_mostly = SIP_TIMEOUT; 41 static unsigned int sip_timeout __read_mostly = SIP_TIMEOUT;
42 module_param(sip_timeout, uint, 0600); 42 module_param(sip_timeout, uint, 0600);
43 MODULE_PARM_DESC(sip_timeout, "timeout for the master SIP session"); 43 MODULE_PARM_DESC(sip_timeout, "timeout for the master SIP session");
44 44
45 static int sip_direct_signalling __read_mostly = 1; 45 static int sip_direct_signalling __read_mostly = 1;
46 module_param(sip_direct_signalling, int, 0600); 46 module_param(sip_direct_signalling, int, 0600);
47 MODULE_PARM_DESC(sip_direct_signalling, "expect incoming calls from registrar " 47 MODULE_PARM_DESC(sip_direct_signalling, "expect incoming calls from registrar "
48 "only (default 1)"); 48 "only (default 1)");
49 49
50 static int sip_direct_media __read_mostly = 1; 50 static int sip_direct_media __read_mostly = 1;
51 module_param(sip_direct_media, int, 0600); 51 module_param(sip_direct_media, int, 0600);
52 MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling " 52 MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling "
53 "endpoints only (default 1)"); 53 "endpoints only (default 1)");
54 54
55 unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, unsigned int dataoff, 55 unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, unsigned int dataoff,
56 const char **dptr, 56 const char **dptr,
57 unsigned int *datalen) __read_mostly; 57 unsigned int *datalen) __read_mostly;
58 EXPORT_SYMBOL_GPL(nf_nat_sip_hook); 58 EXPORT_SYMBOL_GPL(nf_nat_sip_hook);
59 59
60 void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb, s16 off) __read_mostly; 60 void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb, s16 off) __read_mostly;
61 EXPORT_SYMBOL_GPL(nf_nat_sip_seq_adjust_hook); 61 EXPORT_SYMBOL_GPL(nf_nat_sip_seq_adjust_hook);
62 62
63 unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb, 63 unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb,
64 unsigned int dataoff, 64 unsigned int dataoff,
65 const char **dptr, 65 const char **dptr,
66 unsigned int *datalen, 66 unsigned int *datalen,
67 struct nf_conntrack_expect *exp, 67 struct nf_conntrack_expect *exp,
68 unsigned int matchoff, 68 unsigned int matchoff,
69 unsigned int matchlen) __read_mostly; 69 unsigned int matchlen) __read_mostly;
70 EXPORT_SYMBOL_GPL(nf_nat_sip_expect_hook); 70 EXPORT_SYMBOL_GPL(nf_nat_sip_expect_hook);
71 71
72 unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb, unsigned int dataoff, 72 unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb, unsigned int dataoff,
73 const char **dptr, 73 const char **dptr,
74 unsigned int *datalen, 74 unsigned int *datalen,
75 unsigned int sdpoff, 75 unsigned int sdpoff,
76 enum sdp_header_types type, 76 enum sdp_header_types type,
77 enum sdp_header_types term, 77 enum sdp_header_types term,
78 const union nf_inet_addr *addr) 78 const union nf_inet_addr *addr)
79 __read_mostly; 79 __read_mostly;
80 EXPORT_SYMBOL_GPL(nf_nat_sdp_addr_hook); 80 EXPORT_SYMBOL_GPL(nf_nat_sdp_addr_hook);
81 81
82 unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb, unsigned int dataoff, 82 unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb, unsigned int dataoff,
83 const char **dptr, 83 const char **dptr,
84 unsigned int *datalen, 84 unsigned int *datalen,
85 unsigned int matchoff, 85 unsigned int matchoff,
86 unsigned int matchlen, 86 unsigned int matchlen,
87 u_int16_t port) __read_mostly; 87 u_int16_t port) __read_mostly;
88 EXPORT_SYMBOL_GPL(nf_nat_sdp_port_hook); 88 EXPORT_SYMBOL_GPL(nf_nat_sdp_port_hook);
89 89
90 unsigned int (*nf_nat_sdp_session_hook)(struct sk_buff *skb, 90 unsigned int (*nf_nat_sdp_session_hook)(struct sk_buff *skb,
91 unsigned int dataoff, 91 unsigned int dataoff,
92 const char **dptr, 92 const char **dptr,
93 unsigned int *datalen, 93 unsigned int *datalen,
94 unsigned int sdpoff, 94 unsigned int sdpoff,
95 const union nf_inet_addr *addr) 95 const union nf_inet_addr *addr)
96 __read_mostly; 96 __read_mostly;
97 EXPORT_SYMBOL_GPL(nf_nat_sdp_session_hook); 97 EXPORT_SYMBOL_GPL(nf_nat_sdp_session_hook);
98 98
99 unsigned int (*nf_nat_sdp_media_hook)(struct sk_buff *skb, unsigned int dataoff, 99 unsigned int (*nf_nat_sdp_media_hook)(struct sk_buff *skb, unsigned int dataoff,
100 const char **dptr, 100 const char **dptr,
101 unsigned int *datalen, 101 unsigned int *datalen,
102 struct nf_conntrack_expect *rtp_exp, 102 struct nf_conntrack_expect *rtp_exp,
103 struct nf_conntrack_expect *rtcp_exp, 103 struct nf_conntrack_expect *rtcp_exp,
104 unsigned int mediaoff, 104 unsigned int mediaoff,
105 unsigned int medialen, 105 unsigned int medialen,
106 union nf_inet_addr *rtp_addr) 106 union nf_inet_addr *rtp_addr)
107 __read_mostly; 107 __read_mostly;
108 EXPORT_SYMBOL_GPL(nf_nat_sdp_media_hook); 108 EXPORT_SYMBOL_GPL(nf_nat_sdp_media_hook);
109 109
110 static int string_len(const struct nf_conn *ct, const char *dptr, 110 static int string_len(const struct nf_conn *ct, const char *dptr,
111 const char *limit, int *shift) 111 const char *limit, int *shift)
112 { 112 {
113 int len = 0; 113 int len = 0;
114 114
115 while (dptr < limit && isalpha(*dptr)) { 115 while (dptr < limit && isalpha(*dptr)) {
116 dptr++; 116 dptr++;
117 len++; 117 len++;
118 } 118 }
119 return len; 119 return len;
120 } 120 }
121 121
122 static int digits_len(const struct nf_conn *ct, const char *dptr, 122 static int digits_len(const struct nf_conn *ct, const char *dptr,
123 const char *limit, int *shift) 123 const char *limit, int *shift)
124 { 124 {
125 int len = 0; 125 int len = 0;
126 while (dptr < limit && isdigit(*dptr)) { 126 while (dptr < limit && isdigit(*dptr)) {
127 dptr++; 127 dptr++;
128 len++; 128 len++;
129 } 129 }
130 return len; 130 return len;
131 } 131 }
132 132
133 /* get media type + port length */ 133 /* get media type + port length */
134 static int media_len(const struct nf_conn *ct, const char *dptr, 134 static int media_len(const struct nf_conn *ct, const char *dptr,
135 const char *limit, int *shift) 135 const char *limit, int *shift)
136 { 136 {
137 int len = string_len(ct, dptr, limit, shift); 137 int len = string_len(ct, dptr, limit, shift);
138 138
139 dptr += len; 139 dptr += len;
140 if (dptr >= limit || *dptr != ' ') 140 if (dptr >= limit || *dptr != ' ')
141 return 0; 141 return 0;
142 len++; 142 len++;
143 dptr++; 143 dptr++;
144 144
145 return len + digits_len(ct, dptr, limit, shift); 145 return len + digits_len(ct, dptr, limit, shift);
146 } 146 }
147 147
148 static int parse_addr(const struct nf_conn *ct, const char *cp, 148 static int parse_addr(const struct nf_conn *ct, const char *cp,
149 const char **endp, union nf_inet_addr *addr, 149 const char **endp, union nf_inet_addr *addr,
150 const char *limit) 150 const char *limit)
151 { 151 {
152 const char *end; 152 const char *end;
153 int ret = 0; 153 int ret = 0;
154 154
155 memset(addr, 0, sizeof(*addr)); 155 memset(addr, 0, sizeof(*addr));
156 switch (nf_ct_l3num(ct)) { 156 switch (nf_ct_l3num(ct)) {
157 case AF_INET: 157 case AF_INET:
158 ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end); 158 ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end);
159 break; 159 break;
160 case AF_INET6: 160 case AF_INET6:
161 ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end); 161 ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end);
162 break; 162 break;
163 default: 163 default:
164 BUG(); 164 BUG();
165 } 165 }
166 166
167 if (ret == 0 || end == cp) 167 if (ret == 0 || end == cp)
168 return 0; 168 return 0;
169 if (endp) 169 if (endp)
170 *endp = end; 170 *endp = end;
171 return 1; 171 return 1;
172 } 172 }
173 173
174 /* skip ip address. returns its length. */ 174 /* skip ip address. returns its length. */
175 static int epaddr_len(const struct nf_conn *ct, const char *dptr, 175 static int epaddr_len(const struct nf_conn *ct, const char *dptr,
176 const char *limit, int *shift) 176 const char *limit, int *shift)
177 { 177 {
178 union nf_inet_addr addr; 178 union nf_inet_addr addr;
179 const char *aux = dptr; 179 const char *aux = dptr;
180 180
181 if (!parse_addr(ct, dptr, &dptr, &addr, limit)) { 181 if (!parse_addr(ct, dptr, &dptr, &addr, limit)) {
182 pr_debug("ip: %s parse failed.!\n", dptr); 182 pr_debug("ip: %s parse failed.!\n", dptr);
183 return 0; 183 return 0;
184 } 184 }
185 185
186 /* Port number */ 186 /* Port number */
187 if (*dptr == ':') { 187 if (*dptr == ':') {
188 dptr++; 188 dptr++;
189 dptr += digits_len(ct, dptr, limit, shift); 189 dptr += digits_len(ct, dptr, limit, shift);
190 } 190 }
191 return dptr - aux; 191 return dptr - aux;
192 } 192 }
193 193
194 /* get address length, skiping user info. */ 194 /* get address length, skiping user info. */
195 static int skp_epaddr_len(const struct nf_conn *ct, const char *dptr, 195 static int skp_epaddr_len(const struct nf_conn *ct, const char *dptr,
196 const char *limit, int *shift) 196 const char *limit, int *shift)
197 { 197 {
198 const char *start = dptr; 198 const char *start = dptr;
199 int s = *shift; 199 int s = *shift;
200 200
201 /* Search for @, but stop at the end of the line. 201 /* Search for @, but stop at the end of the line.
202 * We are inside a sip: URI, so we don't need to worry about 202 * We are inside a sip: URI, so we don't need to worry about
203 * continuation lines. */ 203 * continuation lines. */
204 while (dptr < limit && 204 while (dptr < limit &&
205 *dptr != '@' && *dptr != '\r' && *dptr != '\n') { 205 *dptr != '@' && *dptr != '\r' && *dptr != '\n') {
206 (*shift)++; 206 (*shift)++;
207 dptr++; 207 dptr++;
208 } 208 }
209 209
210 if (dptr < limit && *dptr == '@') { 210 if (dptr < limit && *dptr == '@') {
211 dptr++; 211 dptr++;
212 (*shift)++; 212 (*shift)++;
213 } else { 213 } else {
214 dptr = start; 214 dptr = start;
215 *shift = s; 215 *shift = s;
216 } 216 }
217 217
218 return epaddr_len(ct, dptr, limit, shift); 218 return epaddr_len(ct, dptr, limit, shift);
219 } 219 }
220 220
221 /* Parse a SIP request line of the form: 221 /* Parse a SIP request line of the form:
222 * 222 *
223 * Request-Line = Method SP Request-URI SP SIP-Version CRLF 223 * Request-Line = Method SP Request-URI SP SIP-Version CRLF
224 * 224 *
225 * and return the offset and length of the address contained in the Request-URI. 225 * and return the offset and length of the address contained in the Request-URI.
226 */ 226 */
227 int ct_sip_parse_request(const struct nf_conn *ct, 227 int ct_sip_parse_request(const struct nf_conn *ct,
228 const char *dptr, unsigned int datalen, 228 const char *dptr, unsigned int datalen,
229 unsigned int *matchoff, unsigned int *matchlen, 229 unsigned int *matchoff, unsigned int *matchlen,
230 union nf_inet_addr *addr, __be16 *port) 230 union nf_inet_addr *addr, __be16 *port)
231 { 231 {
232 const char *start = dptr, *limit = dptr + datalen, *end; 232 const char *start = dptr, *limit = dptr + datalen, *end;
233 unsigned int mlen; 233 unsigned int mlen;
234 unsigned int p; 234 unsigned int p;
235 int shift = 0; 235 int shift = 0;
236 236
237 /* Skip method and following whitespace */ 237 /* Skip method and following whitespace */
238 mlen = string_len(ct, dptr, limit, NULL); 238 mlen = string_len(ct, dptr, limit, NULL);
239 if (!mlen) 239 if (!mlen)
240 return 0; 240 return 0;
241 dptr += mlen; 241 dptr += mlen;
242 if (++dptr >= limit) 242 if (++dptr >= limit)
243 return 0; 243 return 0;
244 244
245 /* Find SIP URI */ 245 /* Find SIP URI */
246 for (; dptr < limit - strlen("sip:"); dptr++) { 246 for (; dptr < limit - strlen("sip:"); dptr++) {
247 if (*dptr == '\r' || *dptr == '\n') 247 if (*dptr == '\r' || *dptr == '\n')
248 return -1; 248 return -1;
249 if (strnicmp(dptr, "sip:", strlen("sip:")) == 0) { 249 if (strnicmp(dptr, "sip:", strlen("sip:")) == 0) {
250 dptr += strlen("sip:"); 250 dptr += strlen("sip:");
251 break; 251 break;
252 } 252 }
253 } 253 }
254 if (!skp_epaddr_len(ct, dptr, limit, &shift)) 254 if (!skp_epaddr_len(ct, dptr, limit, &shift))
255 return 0; 255 return 0;
256 dptr += shift; 256 dptr += shift;
257 257
258 if (!parse_addr(ct, dptr, &end, addr, limit)) 258 if (!parse_addr(ct, dptr, &end, addr, limit))
259 return -1; 259 return -1;
260 if (end < limit && *end == ':') { 260 if (end < limit && *end == ':') {
261 end++; 261 end++;
262 p = simple_strtoul(end, (char **)&end, 10); 262 p = simple_strtoul(end, (char **)&end, 10);
263 if (p < 1024 || p > 65535) 263 if (p < 1024 || p > 65535)
264 return -1; 264 return -1;
265 *port = htons(p); 265 *port = htons(p);
266 } else 266 } else
267 *port = htons(SIP_PORT); 267 *port = htons(SIP_PORT);
268 268
269 if (end == dptr) 269 if (end == dptr)
270 return 0; 270 return 0;
271 *matchoff = dptr - start; 271 *matchoff = dptr - start;
272 *matchlen = end - dptr; 272 *matchlen = end - dptr;
273 return 1; 273 return 1;
274 } 274 }
275 EXPORT_SYMBOL_GPL(ct_sip_parse_request); 275 EXPORT_SYMBOL_GPL(ct_sip_parse_request);
276 276
277 /* SIP header parsing: SIP headers are located at the beginning of a line, but 277 /* SIP header parsing: SIP headers are located at the beginning of a line, but
278 * may span several lines, in which case the continuation lines begin with a 278 * may span several lines, in which case the continuation lines begin with a
279 * whitespace character. RFC 2543 allows lines to be terminated with CR, LF or 279 * whitespace character. RFC 2543 allows lines to be terminated with CR, LF or
280 * CRLF, RFC 3261 allows only CRLF, we support both. 280 * CRLF, RFC 3261 allows only CRLF, we support both.
281 * 281 *
282 * Headers are followed by (optionally) whitespace, a colon, again (optionally) 282 * Headers are followed by (optionally) whitespace, a colon, again (optionally)
283 * whitespace and the values. Whitespace in this context means any amount of 283 * whitespace and the values. Whitespace in this context means any amount of
284 * tabs, spaces and continuation lines, which are treated as a single whitespace 284 * tabs, spaces and continuation lines, which are treated as a single whitespace
285 * character. 285 * character.
286 * 286 *
287 * Some headers may appear multiple times. A comma separated list of values is 287 * Some headers may appear multiple times. A comma separated list of values is
288 * equivalent to multiple headers. 288 * equivalent to multiple headers.
289 */ 289 */
290 static const struct sip_header ct_sip_hdrs[] = { 290 static const struct sip_header ct_sip_hdrs[] = {
291 [SIP_HDR_CSEQ] = SIP_HDR("CSeq", NULL, NULL, digits_len), 291 [SIP_HDR_CSEQ] = SIP_HDR("CSeq", NULL, NULL, digits_len),
292 [SIP_HDR_FROM] = SIP_HDR("From", "f", "sip:", skp_epaddr_len), 292 [SIP_HDR_FROM] = SIP_HDR("From", "f", "sip:", skp_epaddr_len),
293 [SIP_HDR_TO] = SIP_HDR("To", "t", "sip:", skp_epaddr_len), 293 [SIP_HDR_TO] = SIP_HDR("To", "t", "sip:", skp_epaddr_len),
294 [SIP_HDR_CONTACT] = SIP_HDR("Contact", "m", "sip:", skp_epaddr_len), 294 [SIP_HDR_CONTACT] = SIP_HDR("Contact", "m", "sip:", skp_epaddr_len),
295 [SIP_HDR_VIA_UDP] = SIP_HDR("Via", "v", "UDP ", epaddr_len), 295 [SIP_HDR_VIA_UDP] = SIP_HDR("Via", "v", "UDP ", epaddr_len),
296 [SIP_HDR_VIA_TCP] = SIP_HDR("Via", "v", "TCP ", epaddr_len), 296 [SIP_HDR_VIA_TCP] = SIP_HDR("Via", "v", "TCP ", epaddr_len),
297 [SIP_HDR_EXPIRES] = SIP_HDR("Expires", NULL, NULL, digits_len), 297 [SIP_HDR_EXPIRES] = SIP_HDR("Expires", NULL, NULL, digits_len),
298 [SIP_HDR_CONTENT_LENGTH] = SIP_HDR("Content-Length", "l", NULL, digits_len), 298 [SIP_HDR_CONTENT_LENGTH] = SIP_HDR("Content-Length", "l", NULL, digits_len),
299 }; 299 };
300 300
301 static const char *sip_follow_continuation(const char *dptr, const char *limit) 301 static const char *sip_follow_continuation(const char *dptr, const char *limit)
302 { 302 {
303 /* Walk past newline */ 303 /* Walk past newline */
304 if (++dptr >= limit) 304 if (++dptr >= limit)
305 return NULL; 305 return NULL;
306 306
307 /* Skip '\n' in CR LF */ 307 /* Skip '\n' in CR LF */
308 if (*(dptr - 1) == '\r' && *dptr == '\n') { 308 if (*(dptr - 1) == '\r' && *dptr == '\n') {
309 if (++dptr >= limit) 309 if (++dptr >= limit)
310 return NULL; 310 return NULL;
311 } 311 }
312 312
313 /* Continuation line? */ 313 /* Continuation line? */
314 if (*dptr != ' ' && *dptr != '\t') 314 if (*dptr != ' ' && *dptr != '\t')
315 return NULL; 315 return NULL;
316 316
317 /* skip leading whitespace */ 317 /* skip leading whitespace */
318 for (; dptr < limit; dptr++) { 318 for (; dptr < limit; dptr++) {
319 if (*dptr != ' ' && *dptr != '\t') 319 if (*dptr != ' ' && *dptr != '\t')
320 break; 320 break;
321 } 321 }
322 return dptr; 322 return dptr;
323 } 323 }
324 324
325 static const char *sip_skip_whitespace(const char *dptr, const char *limit) 325 static const char *sip_skip_whitespace(const char *dptr, const char *limit)
326 { 326 {
327 for (; dptr < limit; dptr++) { 327 for (; dptr < limit; dptr++) {
328 if (*dptr == ' ') 328 if (*dptr == ' ')
329 continue; 329 continue;
330 if (*dptr != '\r' && *dptr != '\n') 330 if (*dptr != '\r' && *dptr != '\n')
331 break; 331 break;
332 dptr = sip_follow_continuation(dptr, limit); 332 dptr = sip_follow_continuation(dptr, limit);
333 if (dptr == NULL) 333 if (dptr == NULL)
334 return NULL; 334 return NULL;
335 } 335 }
336 return dptr; 336 return dptr;
337 } 337 }
338 338
339 /* Search within a SIP header value, dealing with continuation lines */ 339 /* Search within a SIP header value, dealing with continuation lines */
340 static const char *ct_sip_header_search(const char *dptr, const char *limit, 340 static const char *ct_sip_header_search(const char *dptr, const char *limit,
341 const char *needle, unsigned int len) 341 const char *needle, unsigned int len)
342 { 342 {
343 for (limit -= len; dptr < limit; dptr++) { 343 for (limit -= len; dptr < limit; dptr++) {
344 if (*dptr == '\r' || *dptr == '\n') { 344 if (*dptr == '\r' || *dptr == '\n') {
345 dptr = sip_follow_continuation(dptr, limit); 345 dptr = sip_follow_continuation(dptr, limit);
346 if (dptr == NULL) 346 if (dptr == NULL)
347 break; 347 break;
348 continue; 348 continue;
349 } 349 }
350 350
351 if (strnicmp(dptr, needle, len) == 0) 351 if (strnicmp(dptr, needle, len) == 0)
352 return dptr; 352 return dptr;
353 } 353 }
354 return NULL; 354 return NULL;
355 } 355 }
356 356
357 int ct_sip_get_header(const struct nf_conn *ct, const char *dptr, 357 int ct_sip_get_header(const struct nf_conn *ct, const char *dptr,
358 unsigned int dataoff, unsigned int datalen, 358 unsigned int dataoff, unsigned int datalen,
359 enum sip_header_types type, 359 enum sip_header_types type,
360 unsigned int *matchoff, unsigned int *matchlen) 360 unsigned int *matchoff, unsigned int *matchlen)
361 { 361 {
362 const struct sip_header *hdr = &ct_sip_hdrs[type]; 362 const struct sip_header *hdr = &ct_sip_hdrs[type];
363 const char *start = dptr, *limit = dptr + datalen; 363 const char *start = dptr, *limit = dptr + datalen;
364 int shift = 0; 364 int shift = 0;
365 365
366 for (dptr += dataoff; dptr < limit; dptr++) { 366 for (dptr += dataoff; dptr < limit; dptr++) {
367 /* Find beginning of line */ 367 /* Find beginning of line */
368 if (*dptr != '\r' && *dptr != '\n') 368 if (*dptr != '\r' && *dptr != '\n')
369 continue; 369 continue;
370 if (++dptr >= limit) 370 if (++dptr >= limit)
371 break; 371 break;
372 if (*(dptr - 1) == '\r' && *dptr == '\n') { 372 if (*(dptr - 1) == '\r' && *dptr == '\n') {
373 if (++dptr >= limit) 373 if (++dptr >= limit)
374 break; 374 break;
375 } 375 }
376 376
377 /* Skip continuation lines */ 377 /* Skip continuation lines */
378 if (*dptr == ' ' || *dptr == '\t') 378 if (*dptr == ' ' || *dptr == '\t')
379 continue; 379 continue;
380 380
381 /* Find header. Compact headers must be followed by a 381 /* Find header. Compact headers must be followed by a
382 * non-alphabetic character to avoid mismatches. */ 382 * non-alphabetic character to avoid mismatches. */
383 if (limit - dptr >= hdr->len && 383 if (limit - dptr >= hdr->len &&
384 strnicmp(dptr, hdr->name, hdr->len) == 0) 384 strnicmp(dptr, hdr->name, hdr->len) == 0)
385 dptr += hdr->len; 385 dptr += hdr->len;
386 else if (hdr->cname && limit - dptr >= hdr->clen + 1 && 386 else if (hdr->cname && limit - dptr >= hdr->clen + 1 &&
387 strnicmp(dptr, hdr->cname, hdr->clen) == 0 && 387 strnicmp(dptr, hdr->cname, hdr->clen) == 0 &&
388 !isalpha(*(dptr + hdr->clen))) 388 !isalpha(*(dptr + hdr->clen)))
389 dptr += hdr->clen; 389 dptr += hdr->clen;
390 else 390 else
391 continue; 391 continue;
392 392
393 /* Find and skip colon */ 393 /* Find and skip colon */
394 dptr = sip_skip_whitespace(dptr, limit); 394 dptr = sip_skip_whitespace(dptr, limit);
395 if (dptr == NULL) 395 if (dptr == NULL)
396 break; 396 break;
397 if (*dptr != ':' || ++dptr >= limit) 397 if (*dptr != ':' || ++dptr >= limit)
398 break; 398 break;
399 399
400 /* Skip whitespace after colon */ 400 /* Skip whitespace after colon */
401 dptr = sip_skip_whitespace(dptr, limit); 401 dptr = sip_skip_whitespace(dptr, limit);
402 if (dptr == NULL) 402 if (dptr == NULL)
403 break; 403 break;
404 404
405 *matchoff = dptr - start; 405 *matchoff = dptr - start;
406 if (hdr->search) { 406 if (hdr->search) {
407 dptr = ct_sip_header_search(dptr, limit, hdr->search, 407 dptr = ct_sip_header_search(dptr, limit, hdr->search,
408 hdr->slen); 408 hdr->slen);
409 if (!dptr) 409 if (!dptr)
410 return -1; 410 return -1;
411 dptr += hdr->slen; 411 dptr += hdr->slen;
412 } 412 }
413 413
414 *matchlen = hdr->match_len(ct, dptr, limit, &shift); 414 *matchlen = hdr->match_len(ct, dptr, limit, &shift);
415 if (!*matchlen) 415 if (!*matchlen)
416 return -1; 416 return -1;
417 *matchoff = dptr - start + shift; 417 *matchoff = dptr - start + shift;
418 return 1; 418 return 1;
419 } 419 }
420 return 0; 420 return 0;
421 } 421 }
422 EXPORT_SYMBOL_GPL(ct_sip_get_header); 422 EXPORT_SYMBOL_GPL(ct_sip_get_header);
423 423
424 /* Get next header field in a list of comma separated values */ 424 /* Get next header field in a list of comma separated values */
425 static int ct_sip_next_header(const struct nf_conn *ct, const char *dptr, 425 static int ct_sip_next_header(const struct nf_conn *ct, const char *dptr,
426 unsigned int dataoff, unsigned int datalen, 426 unsigned int dataoff, unsigned int datalen,
427 enum sip_header_types type, 427 enum sip_header_types type,
428 unsigned int *matchoff, unsigned int *matchlen) 428 unsigned int *matchoff, unsigned int *matchlen)
429 { 429 {
430 const struct sip_header *hdr = &ct_sip_hdrs[type]; 430 const struct sip_header *hdr = &ct_sip_hdrs[type];
431 const char *start = dptr, *limit = dptr + datalen; 431 const char *start = dptr, *limit = dptr + datalen;
432 int shift = 0; 432 int shift = 0;
433 433
434 dptr += dataoff; 434 dptr += dataoff;
435 435
436 dptr = ct_sip_header_search(dptr, limit, ",", strlen(",")); 436 dptr = ct_sip_header_search(dptr, limit, ",", strlen(","));
437 if (!dptr) 437 if (!dptr)
438 return 0; 438 return 0;
439 439
440 dptr = ct_sip_header_search(dptr, limit, hdr->search, hdr->slen); 440 dptr = ct_sip_header_search(dptr, limit, hdr->search, hdr->slen);
441 if (!dptr) 441 if (!dptr)
442 return 0; 442 return 0;
443 dptr += hdr->slen; 443 dptr += hdr->slen;
444 444
445 *matchoff = dptr - start; 445 *matchoff = dptr - start;
446 *matchlen = hdr->match_len(ct, dptr, limit, &shift); 446 *matchlen = hdr->match_len(ct, dptr, limit, &shift);
447 if (!*matchlen) 447 if (!*matchlen)
448 return -1; 448 return -1;
449 *matchoff += shift; 449 *matchoff += shift;
450 return 1; 450 return 1;
451 } 451 }
452 452
453 /* Walk through headers until a parsable one is found or no header of the 453 /* Walk through headers until a parsable one is found or no header of the
454 * given type is left. */ 454 * given type is left. */
455 static int ct_sip_walk_headers(const struct nf_conn *ct, const char *dptr, 455 static int ct_sip_walk_headers(const struct nf_conn *ct, const char *dptr,
456 unsigned int dataoff, unsigned int datalen, 456 unsigned int dataoff, unsigned int datalen,
457 enum sip_header_types type, int *in_header, 457 enum sip_header_types type, int *in_header,
458 unsigned int *matchoff, unsigned int *matchlen) 458 unsigned int *matchoff, unsigned int *matchlen)
459 { 459 {
460 int ret; 460 int ret;
461 461
462 if (in_header && *in_header) { 462 if (in_header && *in_header) {
463 while (1) { 463 while (1) {
464 ret = ct_sip_next_header(ct, dptr, dataoff, datalen, 464 ret = ct_sip_next_header(ct, dptr, dataoff, datalen,
465 type, matchoff, matchlen); 465 type, matchoff, matchlen);
466 if (ret > 0) 466 if (ret > 0)
467 return ret; 467 return ret;
468 if (ret == 0) 468 if (ret == 0)
469 break; 469 break;
470 dataoff += *matchoff; 470 dataoff += *matchoff;
471 } 471 }
472 *in_header = 0; 472 *in_header = 0;
473 } 473 }
474 474
475 while (1) { 475 while (1) {
476 ret = ct_sip_get_header(ct, dptr, dataoff, datalen, 476 ret = ct_sip_get_header(ct, dptr, dataoff, datalen,
477 type, matchoff, matchlen); 477 type, matchoff, matchlen);
478 if (ret > 0) 478 if (ret > 0)
479 break; 479 break;
480 if (ret == 0) 480 if (ret == 0)
481 return ret; 481 return ret;
482 dataoff += *matchoff; 482 dataoff += *matchoff;
483 } 483 }
484 484
485 if (in_header) 485 if (in_header)
486 *in_header = 1; 486 *in_header = 1;
487 return 1; 487 return 1;
488 } 488 }
489 489
490 /* Locate a SIP header, parse the URI and return the offset and length of 490 /* Locate a SIP header, parse the URI and return the offset and length of
491 * the address as well as the address and port themselves. A stream of 491 * the address as well as the address and port themselves. A stream of
492 * headers can be parsed by handing in a non-NULL datalen and in_header 492 * headers can be parsed by handing in a non-NULL datalen and in_header
493 * pointer. 493 * pointer.
494 */ 494 */
495 int ct_sip_parse_header_uri(const struct nf_conn *ct, const char *dptr, 495 int ct_sip_parse_header_uri(const struct nf_conn *ct, const char *dptr,
496 unsigned int *dataoff, unsigned int datalen, 496 unsigned int *dataoff, unsigned int datalen,
497 enum sip_header_types type, int *in_header, 497 enum sip_header_types type, int *in_header,
498 unsigned int *matchoff, unsigned int *matchlen, 498 unsigned int *matchoff, unsigned int *matchlen,
499 union nf_inet_addr *addr, __be16 *port) 499 union nf_inet_addr *addr, __be16 *port)
500 { 500 {
501 const char *c, *limit = dptr + datalen; 501 const char *c, *limit = dptr + datalen;
502 unsigned int p; 502 unsigned int p;
503 int ret; 503 int ret;
504 504
505 ret = ct_sip_walk_headers(ct, dptr, dataoff ? *dataoff : 0, datalen, 505 ret = ct_sip_walk_headers(ct, dptr, dataoff ? *dataoff : 0, datalen,
506 type, in_header, matchoff, matchlen); 506 type, in_header, matchoff, matchlen);
507 WARN_ON(ret < 0); 507 WARN_ON(ret < 0);
508 if (ret == 0) 508 if (ret == 0)
509 return ret; 509 return ret;
510 510
511 if (!parse_addr(ct, dptr + *matchoff, &c, addr, limit)) 511 if (!parse_addr(ct, dptr + *matchoff, &c, addr, limit))
512 return -1; 512 return -1;
513 if (*c == ':') { 513 if (*c == ':') {
514 c++; 514 c++;
515 p = simple_strtoul(c, (char **)&c, 10); 515 p = simple_strtoul(c, (char **)&c, 10);
516 if (p < 1024 || p > 65535) 516 if (p < 1024 || p > 65535)
517 return -1; 517 return -1;
518 *port = htons(p); 518 *port = htons(p);
519 } else 519 } else
520 *port = htons(SIP_PORT); 520 *port = htons(SIP_PORT);
521 521
522 if (dataoff) 522 if (dataoff)
523 *dataoff = c - dptr; 523 *dataoff = c - dptr;
524 return 1; 524 return 1;
525 } 525 }
526 EXPORT_SYMBOL_GPL(ct_sip_parse_header_uri); 526 EXPORT_SYMBOL_GPL(ct_sip_parse_header_uri);
527 527
528 static int ct_sip_parse_param(const struct nf_conn *ct, const char *dptr, 528 static int ct_sip_parse_param(const struct nf_conn *ct, const char *dptr,
529 unsigned int dataoff, unsigned int datalen, 529 unsigned int dataoff, unsigned int datalen,
530 const char *name, 530 const char *name,
531 unsigned int *matchoff, unsigned int *matchlen) 531 unsigned int *matchoff, unsigned int *matchlen)
532 { 532 {
533 const char *limit = dptr + datalen; 533 const char *limit = dptr + datalen;
534 const char *start; 534 const char *start;
535 const char *end; 535 const char *end;
536 536
537 limit = ct_sip_header_search(dptr + dataoff, limit, ",", strlen(",")); 537 limit = ct_sip_header_search(dptr + dataoff, limit, ",", strlen(","));
538 if (!limit) 538 if (!limit)
539 limit = dptr + datalen; 539 limit = dptr + datalen;
540 540
541 start = ct_sip_header_search(dptr + dataoff, limit, name, strlen(name)); 541 start = ct_sip_header_search(dptr + dataoff, limit, name, strlen(name));
542 if (!start) 542 if (!start)
543 return 0; 543 return 0;
544 start += strlen(name); 544 start += strlen(name);
545 545
546 end = ct_sip_header_search(start, limit, ";", strlen(";")); 546 end = ct_sip_header_search(start, limit, ";", strlen(";"));
547 if (!end) 547 if (!end)
548 end = limit; 548 end = limit;
549 549
550 *matchoff = start - dptr; 550 *matchoff = start - dptr;
551 *matchlen = end - start; 551 *matchlen = end - start;
552 return 1; 552 return 1;
553 } 553 }
554 554
555 /* Parse address from header parameter and return address, offset and length */ 555 /* Parse address from header parameter and return address, offset and length */
556 int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr, 556 int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr,
557 unsigned int dataoff, unsigned int datalen, 557 unsigned int dataoff, unsigned int datalen,
558 const char *name, 558 const char *name,
559 unsigned int *matchoff, unsigned int *matchlen, 559 unsigned int *matchoff, unsigned int *matchlen,
560 union nf_inet_addr *addr) 560 union nf_inet_addr *addr)
561 { 561 {
562 const char *limit = dptr + datalen; 562 const char *limit = dptr + datalen;
563 const char *start, *end; 563 const char *start, *end;
564 564
565 limit = ct_sip_header_search(dptr + dataoff, limit, ",", strlen(",")); 565 limit = ct_sip_header_search(dptr + dataoff, limit, ",", strlen(","));
566 if (!limit) 566 if (!limit)
567 limit = dptr + datalen; 567 limit = dptr + datalen;
568 568
569 start = ct_sip_header_search(dptr + dataoff, limit, name, strlen(name)); 569 start = ct_sip_header_search(dptr + dataoff, limit, name, strlen(name));
570 if (!start) 570 if (!start)
571 return 0; 571 return 0;
572 572
573 start += strlen(name); 573 start += strlen(name);
574 if (!parse_addr(ct, start, &end, addr, limit)) 574 if (!parse_addr(ct, start, &end, addr, limit))
575 return 0; 575 return 0;
576 *matchoff = start - dptr; 576 *matchoff = start - dptr;
577 *matchlen = end - start; 577 *matchlen = end - start;
578 return 1; 578 return 1;
579 } 579 }
580 EXPORT_SYMBOL_GPL(ct_sip_parse_address_param); 580 EXPORT_SYMBOL_GPL(ct_sip_parse_address_param);
581 581
582 /* Parse numerical header parameter and return value, offset and length */ 582 /* Parse numerical header parameter and return value, offset and length */
583 int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr, 583 int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr,
584 unsigned int dataoff, unsigned int datalen, 584 unsigned int dataoff, unsigned int datalen,
585 const char *name, 585 const char *name,
586 unsigned int *matchoff, unsigned int *matchlen, 586 unsigned int *matchoff, unsigned int *matchlen,
587 unsigned int *val) 587 unsigned int *val)
588 { 588 {
589 const char *limit = dptr + datalen; 589 const char *limit = dptr + datalen;
590 const char *start; 590 const char *start;
591 char *end; 591 char *end;
592 592
593 limit = ct_sip_header_search(dptr + dataoff, limit, ",", strlen(",")); 593 limit = ct_sip_header_search(dptr + dataoff, limit, ",", strlen(","));
594 if (!limit) 594 if (!limit)
595 limit = dptr + datalen; 595 limit = dptr + datalen;
596 596
597 start = ct_sip_header_search(dptr + dataoff, limit, name, strlen(name)); 597 start = ct_sip_header_search(dptr + dataoff, limit, name, strlen(name));
598 if (!start) 598 if (!start)
599 return 0; 599 return 0;
600 600
601 start += strlen(name); 601 start += strlen(name);
602 *val = simple_strtoul(start, &end, 0); 602 *val = simple_strtoul(start, &end, 0);
603 if (start == end) 603 if (start == end)
604 return 0; 604 return 0;
605 if (matchoff && matchlen) { 605 if (matchoff && matchlen) {
606 *matchoff = start - dptr; 606 *matchoff = start - dptr;
607 *matchlen = end - start; 607 *matchlen = end - start;
608 } 608 }
609 return 1; 609 return 1;
610 } 610 }
611 EXPORT_SYMBOL_GPL(ct_sip_parse_numerical_param); 611 EXPORT_SYMBOL_GPL(ct_sip_parse_numerical_param);
612 612
613 static int ct_sip_parse_transport(struct nf_conn *ct, const char *dptr, 613 static int ct_sip_parse_transport(struct nf_conn *ct, const char *dptr,
614 unsigned int dataoff, unsigned int datalen, 614 unsigned int dataoff, unsigned int datalen,
615 u8 *proto) 615 u8 *proto)
616 { 616 {
617 unsigned int matchoff, matchlen; 617 unsigned int matchoff, matchlen;
618 618
619 if (ct_sip_parse_param(ct, dptr, dataoff, datalen, "transport=", 619 if (ct_sip_parse_param(ct, dptr, dataoff, datalen, "transport=",
620 &matchoff, &matchlen)) { 620 &matchoff, &matchlen)) {
621 if (!strnicmp(dptr + matchoff, "TCP", strlen("TCP"))) 621 if (!strnicmp(dptr + matchoff, "TCP", strlen("TCP")))
622 *proto = IPPROTO_TCP; 622 *proto = IPPROTO_TCP;
623 else if (!strnicmp(dptr + matchoff, "UDP", strlen("UDP"))) 623 else if (!strnicmp(dptr + matchoff, "UDP", strlen("UDP")))
624 *proto = IPPROTO_UDP; 624 *proto = IPPROTO_UDP;
625 else 625 else
626 return 0; 626 return 0;
627 627
628 if (*proto != nf_ct_protonum(ct)) 628 if (*proto != nf_ct_protonum(ct))
629 return 0; 629 return 0;
630 } else 630 } else
631 *proto = nf_ct_protonum(ct); 631 *proto = nf_ct_protonum(ct);
632 632
633 return 1; 633 return 1;
634 } 634 }
635 635
636 /* SDP header parsing: a SDP session description contains an ordered set of 636 /* SDP header parsing: a SDP session description contains an ordered set of
637 * headers, starting with a section containing general session parameters, 637 * headers, starting with a section containing general session parameters,
638 * optionally followed by multiple media descriptions. 638 * optionally followed by multiple media descriptions.
639 * 639 *
640 * SDP headers always start at the beginning of a line. According to RFC 2327: 640 * SDP headers always start at the beginning of a line. According to RFC 2327:
641 * "The sequence CRLF (0x0d0a) is used to end a record, although parsers should 641 * "The sequence CRLF (0x0d0a) is used to end a record, although parsers should
642 * be tolerant and also accept records terminated with a single newline 642 * be tolerant and also accept records terminated with a single newline
643 * character". We handle both cases. 643 * character". We handle both cases.
644 */ 644 */
645 static const struct sip_header ct_sdp_hdrs[] = { 645 static const struct sip_header ct_sdp_hdrs[] = {
646 [SDP_HDR_VERSION] = SDP_HDR("v=", NULL, digits_len), 646 [SDP_HDR_VERSION] = SDP_HDR("v=", NULL, digits_len),
647 [SDP_HDR_OWNER_IP4] = SDP_HDR("o=", "IN IP4 ", epaddr_len), 647 [SDP_HDR_OWNER_IP4] = SDP_HDR("o=", "IN IP4 ", epaddr_len),
648 [SDP_HDR_CONNECTION_IP4] = SDP_HDR("c=", "IN IP4 ", epaddr_len), 648 [SDP_HDR_CONNECTION_IP4] = SDP_HDR("c=", "IN IP4 ", epaddr_len),
649 [SDP_HDR_OWNER_IP6] = SDP_HDR("o=", "IN IP6 ", epaddr_len), 649 [SDP_HDR_OWNER_IP6] = SDP_HDR("o=", "IN IP6 ", epaddr_len),
650 [SDP_HDR_CONNECTION_IP6] = SDP_HDR("c=", "IN IP6 ", epaddr_len), 650 [SDP_HDR_CONNECTION_IP6] = SDP_HDR("c=", "IN IP6 ", epaddr_len),
651 [SDP_HDR_MEDIA] = SDP_HDR("m=", NULL, media_len), 651 [SDP_HDR_MEDIA] = SDP_HDR("m=", NULL, media_len),
652 }; 652 };
653 653
654 /* Linear string search within SDP header values */ 654 /* Linear string search within SDP header values */
655 static const char *ct_sdp_header_search(const char *dptr, const char *limit, 655 static const char *ct_sdp_header_search(const char *dptr, const char *limit,
656 const char *needle, unsigned int len) 656 const char *needle, unsigned int len)
657 { 657 {
658 for (limit -= len; dptr < limit; dptr++) { 658 for (limit -= len; dptr < limit; dptr++) {
659 if (*dptr == '\r' || *dptr == '\n') 659 if (*dptr == '\r' || *dptr == '\n')
660 break; 660 break;
661 if (strncmp(dptr, needle, len) == 0) 661 if (strncmp(dptr, needle, len) == 0)
662 return dptr; 662 return dptr;
663 } 663 }
664 return NULL; 664 return NULL;
665 } 665 }
666 666
667 /* Locate a SDP header (optionally a substring within the header value), 667 /* Locate a SDP header (optionally a substring within the header value),
668 * optionally stopping at the first occurence of the term header, parse 668 * optionally stopping at the first occurence of the term header, parse
669 * it and return the offset and length of the data we're interested in. 669 * it and return the offset and length of the data we're interested in.
670 */ 670 */
671 int ct_sip_get_sdp_header(const struct nf_conn *ct, const char *dptr, 671 int ct_sip_get_sdp_header(const struct nf_conn *ct, const char *dptr,
672 unsigned int dataoff, unsigned int datalen, 672 unsigned int dataoff, unsigned int datalen,
673 enum sdp_header_types type, 673 enum sdp_header_types type,
674 enum sdp_header_types term, 674 enum sdp_header_types term,
675 unsigned int *matchoff, unsigned int *matchlen) 675 unsigned int *matchoff, unsigned int *matchlen)
676 { 676 {
677 const struct sip_header *hdr = &ct_sdp_hdrs[type]; 677 const struct sip_header *hdr = &ct_sdp_hdrs[type];
678 const struct sip_header *thdr = &ct_sdp_hdrs[term]; 678 const struct sip_header *thdr = &ct_sdp_hdrs[term];
679 const char *start = dptr, *limit = dptr + datalen; 679 const char *start = dptr, *limit = dptr + datalen;
680 int shift = 0; 680 int shift = 0;
681 681
682 for (dptr += dataoff; dptr < limit; dptr++) { 682 for (dptr += dataoff; dptr < limit; dptr++) {
683 /* Find beginning of line */ 683 /* Find beginning of line */
684 if (*dptr != '\r' && *dptr != '\n') 684 if (*dptr != '\r' && *dptr != '\n')
685 continue; 685 continue;
686 if (++dptr >= limit) 686 if (++dptr >= limit)
687 break; 687 break;
688 if (*(dptr - 1) == '\r' && *dptr == '\n') { 688 if (*(dptr - 1) == '\r' && *dptr == '\n') {
689 if (++dptr >= limit) 689 if (++dptr >= limit)
690 break; 690 break;
691 } 691 }
692 692
693 if (term != SDP_HDR_UNSPEC && 693 if (term != SDP_HDR_UNSPEC &&
694 limit - dptr >= thdr->len && 694 limit - dptr >= thdr->len &&
695 strnicmp(dptr, thdr->name, thdr->len) == 0) 695 strnicmp(dptr, thdr->name, thdr->len) == 0)
696 break; 696 break;
697 else if (limit - dptr >= hdr->len && 697 else if (limit - dptr >= hdr->len &&
698 strnicmp(dptr, hdr->name, hdr->len) == 0) 698 strnicmp(dptr, hdr->name, hdr->len) == 0)
699 dptr += hdr->len; 699 dptr += hdr->len;
700 else 700 else
701 continue; 701 continue;
702 702
703 *matchoff = dptr - start; 703 *matchoff = dptr - start;
704 if (hdr->search) { 704 if (hdr->search) {
705 dptr = ct_sdp_header_search(dptr, limit, hdr->search, 705 dptr = ct_sdp_header_search(dptr, limit, hdr->search,
706 hdr->slen); 706 hdr->slen);
707 if (!dptr) 707 if (!dptr)
708 return -1; 708 return -1;
709 dptr += hdr->slen; 709 dptr += hdr->slen;
710 } 710 }
711 711
712 *matchlen = hdr->match_len(ct, dptr, limit, &shift); 712 *matchlen = hdr->match_len(ct, dptr, limit, &shift);
713 if (!*matchlen) 713 if (!*matchlen)
714 return -1; 714 return -1;
715 *matchoff = dptr - start + shift; 715 *matchoff = dptr - start + shift;
716 return 1; 716 return 1;
717 } 717 }
718 return 0; 718 return 0;
719 } 719 }
720 EXPORT_SYMBOL_GPL(ct_sip_get_sdp_header); 720 EXPORT_SYMBOL_GPL(ct_sip_get_sdp_header);
721 721
722 static int ct_sip_parse_sdp_addr(const struct nf_conn *ct, const char *dptr, 722 static int ct_sip_parse_sdp_addr(const struct nf_conn *ct, const char *dptr,
723 unsigned int dataoff, unsigned int datalen, 723 unsigned int dataoff, unsigned int datalen,
724 enum sdp_header_types type, 724 enum sdp_header_types type,
725 enum sdp_header_types term, 725 enum sdp_header_types term,
726 unsigned int *matchoff, unsigned int *matchlen, 726 unsigned int *matchoff, unsigned int *matchlen,
727 union nf_inet_addr *addr) 727 union nf_inet_addr *addr)
728 { 728 {
729 int ret; 729 int ret;
730 730
731 ret = ct_sip_get_sdp_header(ct, dptr, dataoff, datalen, type, term, 731 ret = ct_sip_get_sdp_header(ct, dptr, dataoff, datalen, type, term,
732 matchoff, matchlen); 732 matchoff, matchlen);
733 if (ret <= 0) 733 if (ret <= 0)
734 return ret; 734 return ret;
735 735
736 if (!parse_addr(ct, dptr + *matchoff, NULL, addr, 736 if (!parse_addr(ct, dptr + *matchoff, NULL, addr,
737 dptr + *matchoff + *matchlen)) 737 dptr + *matchoff + *matchlen))
738 return -1; 738 return -1;
739 return 1; 739 return 1;
740 } 740 }
741 741
742 static int refresh_signalling_expectation(struct nf_conn *ct, 742 static int refresh_signalling_expectation(struct nf_conn *ct,
743 union nf_inet_addr *addr, 743 union nf_inet_addr *addr,
744 u8 proto, __be16 port, 744 u8 proto, __be16 port,
745 unsigned int expires) 745 unsigned int expires)
746 { 746 {
747 struct nf_conn_help *help = nfct_help(ct); 747 struct nf_conn_help *help = nfct_help(ct);
748 struct nf_conntrack_expect *exp; 748 struct nf_conntrack_expect *exp;
749 struct hlist_node *n, *next; 749 struct hlist_node *n, *next;
750 int found = 0; 750 int found = 0;
751 751
752 spin_lock_bh(&nf_conntrack_lock); 752 spin_lock_bh(&nf_conntrack_lock);
753 hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) { 753 hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) {
754 if (exp->class != SIP_EXPECT_SIGNALLING || 754 if (exp->class != SIP_EXPECT_SIGNALLING ||
755 !nf_inet_addr_cmp(&exp->tuple.dst.u3, addr) || 755 !nf_inet_addr_cmp(&exp->tuple.dst.u3, addr) ||
756 exp->tuple.dst.protonum != proto || 756 exp->tuple.dst.protonum != proto ||
757 exp->tuple.dst.u.udp.port != port) 757 exp->tuple.dst.u.udp.port != port)
758 continue; 758 continue;
759 if (!del_timer(&exp->timeout)) 759 if (!del_timer(&exp->timeout))
760 continue; 760 continue;
761 exp->flags &= ~NF_CT_EXPECT_INACTIVE; 761 exp->flags &= ~NF_CT_EXPECT_INACTIVE;
762 exp->timeout.expires = jiffies + expires * HZ; 762 exp->timeout.expires = jiffies + expires * HZ;
763 add_timer(&exp->timeout); 763 add_timer(&exp->timeout);
764 found = 1; 764 found = 1;
765 break; 765 break;
766 } 766 }
767 spin_unlock_bh(&nf_conntrack_lock); 767 spin_unlock_bh(&nf_conntrack_lock);
768 return found; 768 return found;
769 } 769 }
770 770
771 static void flush_expectations(struct nf_conn *ct, bool media) 771 static void flush_expectations(struct nf_conn *ct, bool media)
772 { 772 {
773 struct nf_conn_help *help = nfct_help(ct); 773 struct nf_conn_help *help = nfct_help(ct);
774 struct nf_conntrack_expect *exp; 774 struct nf_conntrack_expect *exp;
775 struct hlist_node *n, *next; 775 struct hlist_node *n, *next;
776 776
777 spin_lock_bh(&nf_conntrack_lock); 777 spin_lock_bh(&nf_conntrack_lock);
778 hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) { 778 hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) {
779 if ((exp->class != SIP_EXPECT_SIGNALLING) ^ media) 779 if ((exp->class != SIP_EXPECT_SIGNALLING) ^ media)
780 continue; 780 continue;
781 if (!del_timer(&exp->timeout)) 781 if (!del_timer(&exp->timeout))
782 continue; 782 continue;
783 nf_ct_unlink_expect(exp); 783 nf_ct_unlink_expect(exp);
784 nf_ct_expect_put(exp); 784 nf_ct_expect_put(exp);
785 if (!media) 785 if (!media)
786 break; 786 break;
787 } 787 }
788 spin_unlock_bh(&nf_conntrack_lock); 788 spin_unlock_bh(&nf_conntrack_lock);
789 } 789 }
790 790
791 static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int dataoff, 791 static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int dataoff,
792 const char **dptr, unsigned int *datalen, 792 const char **dptr, unsigned int *datalen,
793 union nf_inet_addr *daddr, __be16 port, 793 union nf_inet_addr *daddr, __be16 port,
794 enum sip_expectation_classes class, 794 enum sip_expectation_classes class,
795 unsigned int mediaoff, unsigned int medialen) 795 unsigned int mediaoff, unsigned int medialen)
796 { 796 {
797 struct nf_conntrack_expect *exp, *rtp_exp, *rtcp_exp; 797 struct nf_conntrack_expect *exp, *rtp_exp, *rtcp_exp;
798 enum ip_conntrack_info ctinfo; 798 enum ip_conntrack_info ctinfo;
799 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 799 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
800 struct net *net = nf_ct_net(ct); 800 struct net *net = nf_ct_net(ct);
801 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 801 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
802 union nf_inet_addr *saddr; 802 union nf_inet_addr *saddr;
803 struct nf_conntrack_tuple tuple; 803 struct nf_conntrack_tuple tuple;
804 int direct_rtp = 0, skip_expect = 0, ret = NF_DROP; 804 int direct_rtp = 0, skip_expect = 0, ret = NF_DROP;
805 u_int16_t base_port; 805 u_int16_t base_port;
806 __be16 rtp_port, rtcp_port; 806 __be16 rtp_port, rtcp_port;
807 typeof(nf_nat_sdp_port_hook) nf_nat_sdp_port; 807 typeof(nf_nat_sdp_port_hook) nf_nat_sdp_port;
808 typeof(nf_nat_sdp_media_hook) nf_nat_sdp_media; 808 typeof(nf_nat_sdp_media_hook) nf_nat_sdp_media;
809 809
810 saddr = NULL; 810 saddr = NULL;
811 if (sip_direct_media) { 811 if (sip_direct_media) {
812 if (!nf_inet_addr_cmp(daddr, &ct->tuplehash[dir].tuple.src.u3)) 812 if (!nf_inet_addr_cmp(daddr, &ct->tuplehash[dir].tuple.src.u3))
813 return NF_ACCEPT; 813 return NF_ACCEPT;
814 saddr = &ct->tuplehash[!dir].tuple.src.u3; 814 saddr = &ct->tuplehash[!dir].tuple.src.u3;
815 } 815 }
816 816
817 /* We need to check whether the registration exists before attempting 817 /* We need to check whether the registration exists before attempting
818 * to register it since we can see the same media description multiple 818 * to register it since we can see the same media description multiple
819 * times on different connections in case multiple endpoints receive 819 * times on different connections in case multiple endpoints receive
820 * the same call. 820 * the same call.
821 * 821 *
822 * RTP optimization: if we find a matching media channel expectation 822 * RTP optimization: if we find a matching media channel expectation
823 * and both the expectation and this connection are SNATed, we assume 823 * and both the expectation and this connection are SNATed, we assume
824 * both sides can reach each other directly and use the final 824 * both sides can reach each other directly and use the final
825 * destination address from the expectation. We still need to keep 825 * destination address from the expectation. We still need to keep
826 * the NATed expectations for media that might arrive from the 826 * the NATed expectations for media that might arrive from the
827 * outside, and additionally need to expect the direct RTP stream 827 * outside, and additionally need to expect the direct RTP stream
828 * in case it passes through us even without NAT. 828 * in case it passes through us even without NAT.
829 */ 829 */
830 memset(&tuple, 0, sizeof(tuple)); 830 memset(&tuple, 0, sizeof(tuple));
831 if (saddr) 831 if (saddr)
832 tuple.src.u3 = *saddr; 832 tuple.src.u3 = *saddr;
833 tuple.src.l3num = nf_ct_l3num(ct); 833 tuple.src.l3num = nf_ct_l3num(ct);
834 tuple.dst.protonum = IPPROTO_UDP; 834 tuple.dst.protonum = IPPROTO_UDP;
835 tuple.dst.u3 = *daddr; 835 tuple.dst.u3 = *daddr;
836 tuple.dst.u.udp.port = port; 836 tuple.dst.u.udp.port = port;
837 837
838 rcu_read_lock(); 838 rcu_read_lock();
839 do { 839 do {
840 exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); 840 exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
841 841
842 if (!exp || exp->master == ct || 842 if (!exp || exp->master == ct ||
843 nfct_help(exp->master)->helper != nfct_help(ct)->helper || 843 nfct_help(exp->master)->helper != nfct_help(ct)->helper ||
844 exp->class != class) 844 exp->class != class)
845 break; 845 break;
846 #ifdef CONFIG_NF_NAT_NEEDED 846 #ifdef CONFIG_NF_NAT_NEEDED
847 if (exp->tuple.src.l3num == AF_INET && !direct_rtp && 847 if (exp->tuple.src.l3num == AF_INET && !direct_rtp &&
848 (exp->saved_ip != exp->tuple.dst.u3.ip || 848 (exp->saved_ip != exp->tuple.dst.u3.ip ||
849 exp->saved_proto.udp.port != exp->tuple.dst.u.udp.port) && 849 exp->saved_proto.udp.port != exp->tuple.dst.u.udp.port) &&
850 ct->status & IPS_NAT_MASK) { 850 ct->status & IPS_NAT_MASK) {
851 daddr->ip = exp->saved_ip; 851 daddr->ip = exp->saved_ip;
852 tuple.dst.u3.ip = exp->saved_ip; 852 tuple.dst.u3.ip = exp->saved_ip;
853 tuple.dst.u.udp.port = exp->saved_proto.udp.port; 853 tuple.dst.u.udp.port = exp->saved_proto.udp.port;
854 direct_rtp = 1; 854 direct_rtp = 1;
855 } else 855 } else
856 #endif 856 #endif
857 skip_expect = 1; 857 skip_expect = 1;
858 } while (!skip_expect); 858 } while (!skip_expect);
859 rcu_read_unlock(); 859 rcu_read_unlock();
860 860
861 base_port = ntohs(tuple.dst.u.udp.port) & ~1; 861 base_port = ntohs(tuple.dst.u.udp.port) & ~1;
862 rtp_port = htons(base_port); 862 rtp_port = htons(base_port);
863 rtcp_port = htons(base_port + 1); 863 rtcp_port = htons(base_port + 1);
864 864
865 if (direct_rtp) { 865 if (direct_rtp) {
866 nf_nat_sdp_port = rcu_dereference(nf_nat_sdp_port_hook); 866 nf_nat_sdp_port = rcu_dereference(nf_nat_sdp_port_hook);
867 if (nf_nat_sdp_port && 867 if (nf_nat_sdp_port &&
868 !nf_nat_sdp_port(skb, dataoff, dptr, datalen, 868 !nf_nat_sdp_port(skb, dataoff, dptr, datalen,
869 mediaoff, medialen, ntohs(rtp_port))) 869 mediaoff, medialen, ntohs(rtp_port)))
870 goto err1; 870 goto err1;
871 } 871 }
872 872
873 if (skip_expect) 873 if (skip_expect)
874 return NF_ACCEPT; 874 return NF_ACCEPT;
875 875
876 rtp_exp = nf_ct_expect_alloc(ct); 876 rtp_exp = nf_ct_expect_alloc(ct);
877 if (rtp_exp == NULL) 877 if (rtp_exp == NULL)
878 goto err1; 878 goto err1;
879 nf_ct_expect_init(rtp_exp, class, nf_ct_l3num(ct), saddr, daddr, 879 nf_ct_expect_init(rtp_exp, class, nf_ct_l3num(ct), saddr, daddr,
880 IPPROTO_UDP, NULL, &rtp_port); 880 IPPROTO_UDP, NULL, &rtp_port);
881 881
882 rtcp_exp = nf_ct_expect_alloc(ct); 882 rtcp_exp = nf_ct_expect_alloc(ct);
883 if (rtcp_exp == NULL) 883 if (rtcp_exp == NULL)
884 goto err2; 884 goto err2;
885 nf_ct_expect_init(rtcp_exp, class, nf_ct_l3num(ct), saddr, daddr, 885 nf_ct_expect_init(rtcp_exp, class, nf_ct_l3num(ct), saddr, daddr,
886 IPPROTO_UDP, NULL, &rtcp_port); 886 IPPROTO_UDP, NULL, &rtcp_port);
887 887
888 nf_nat_sdp_media = rcu_dereference(nf_nat_sdp_media_hook); 888 nf_nat_sdp_media = rcu_dereference(nf_nat_sdp_media_hook);
889 if (nf_nat_sdp_media && ct->status & IPS_NAT_MASK && !direct_rtp) 889 if (nf_nat_sdp_media && ct->status & IPS_NAT_MASK && !direct_rtp)
890 ret = nf_nat_sdp_media(skb, dataoff, dptr, datalen, 890 ret = nf_nat_sdp_media(skb, dataoff, dptr, datalen,
891 rtp_exp, rtcp_exp, 891 rtp_exp, rtcp_exp,
892 mediaoff, medialen, daddr); 892 mediaoff, medialen, daddr);
893 else { 893 else {
894 if (nf_ct_expect_related(rtp_exp) == 0) { 894 if (nf_ct_expect_related(rtp_exp) == 0) {
895 if (nf_ct_expect_related(rtcp_exp) != 0) 895 if (nf_ct_expect_related(rtcp_exp) != 0)
896 nf_ct_unexpect_related(rtp_exp); 896 nf_ct_unexpect_related(rtp_exp);
897 else 897 else
898 ret = NF_ACCEPT; 898 ret = NF_ACCEPT;
899 } 899 }
900 } 900 }
901 nf_ct_expect_put(rtcp_exp); 901 nf_ct_expect_put(rtcp_exp);
902 err2: 902 err2:
903 nf_ct_expect_put(rtp_exp); 903 nf_ct_expect_put(rtp_exp);
904 err1: 904 err1:
905 return ret; 905 return ret;
906 } 906 }
907 907
908 static const struct sdp_media_type sdp_media_types[] = { 908 static const struct sdp_media_type sdp_media_types[] = {
909 SDP_MEDIA_TYPE("audio ", SIP_EXPECT_AUDIO), 909 SDP_MEDIA_TYPE("audio ", SIP_EXPECT_AUDIO),
910 SDP_MEDIA_TYPE("video ", SIP_EXPECT_VIDEO), 910 SDP_MEDIA_TYPE("video ", SIP_EXPECT_VIDEO),
911 SDP_MEDIA_TYPE("image ", SIP_EXPECT_IMAGE), 911 SDP_MEDIA_TYPE("image ", SIP_EXPECT_IMAGE),
912 }; 912 };
913 913
914 static const struct sdp_media_type *sdp_media_type(const char *dptr, 914 static const struct sdp_media_type *sdp_media_type(const char *dptr,
915 unsigned int matchoff, 915 unsigned int matchoff,
916 unsigned int matchlen) 916 unsigned int matchlen)
917 { 917 {
918 const struct sdp_media_type *t; 918 const struct sdp_media_type *t;
919 unsigned int i; 919 unsigned int i;
920 920
921 for (i = 0; i < ARRAY_SIZE(sdp_media_types); i++) { 921 for (i = 0; i < ARRAY_SIZE(sdp_media_types); i++) {
922 t = &sdp_media_types[i]; 922 t = &sdp_media_types[i];
923 if (matchlen < t->len || 923 if (matchlen < t->len ||
924 strncmp(dptr + matchoff, t->name, t->len)) 924 strncmp(dptr + matchoff, t->name, t->len))
925 continue; 925 continue;
926 return t; 926 return t;
927 } 927 }
928 return NULL; 928 return NULL;
929 } 929 }
930 930
931 static int process_sdp(struct sk_buff *skb, unsigned int dataoff, 931 static int process_sdp(struct sk_buff *skb, unsigned int dataoff,
932 const char **dptr, unsigned int *datalen, 932 const char **dptr, unsigned int *datalen,
933 unsigned int cseq) 933 unsigned int cseq)
934 { 934 {
935 enum ip_conntrack_info ctinfo; 935 enum ip_conntrack_info ctinfo;
936 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 936 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
937 unsigned int matchoff, matchlen; 937 unsigned int matchoff, matchlen;
938 unsigned int mediaoff, medialen; 938 unsigned int mediaoff, medialen;
939 unsigned int sdpoff; 939 unsigned int sdpoff;
940 unsigned int caddr_len, maddr_len; 940 unsigned int caddr_len, maddr_len;
941 unsigned int i; 941 unsigned int i;
942 union nf_inet_addr caddr, maddr, rtp_addr; 942 union nf_inet_addr caddr, maddr, rtp_addr;
943 unsigned int port; 943 unsigned int port;
944 enum sdp_header_types c_hdr; 944 enum sdp_header_types c_hdr;
945 const struct sdp_media_type *t; 945 const struct sdp_media_type *t;
946 int ret = NF_ACCEPT; 946 int ret = NF_ACCEPT;
947 typeof(nf_nat_sdp_addr_hook) nf_nat_sdp_addr; 947 typeof(nf_nat_sdp_addr_hook) nf_nat_sdp_addr;
948 typeof(nf_nat_sdp_session_hook) nf_nat_sdp_session; 948 typeof(nf_nat_sdp_session_hook) nf_nat_sdp_session;
949 949
950 nf_nat_sdp_addr = rcu_dereference(nf_nat_sdp_addr_hook); 950 nf_nat_sdp_addr = rcu_dereference(nf_nat_sdp_addr_hook);
951 c_hdr = nf_ct_l3num(ct) == AF_INET ? SDP_HDR_CONNECTION_IP4 : 951 c_hdr = nf_ct_l3num(ct) == AF_INET ? SDP_HDR_CONNECTION_IP4 :
952 SDP_HDR_CONNECTION_IP6; 952 SDP_HDR_CONNECTION_IP6;
953 953
954 /* Find beginning of session description */ 954 /* Find beginning of session description */
955 if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen, 955 if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen,
956 SDP_HDR_VERSION, SDP_HDR_UNSPEC, 956 SDP_HDR_VERSION, SDP_HDR_UNSPEC,
957 &matchoff, &matchlen) <= 0) 957 &matchoff, &matchlen) <= 0)
958 return NF_ACCEPT; 958 return NF_ACCEPT;
959 sdpoff = matchoff; 959 sdpoff = matchoff;
960 960
961 /* The connection information is contained in the session description 961 /* The connection information is contained in the session description
962 * and/or once per media description. The first media description marks 962 * and/or once per media description. The first media description marks
963 * the end of the session description. */ 963 * the end of the session description. */
964 caddr_len = 0; 964 caddr_len = 0;
965 if (ct_sip_parse_sdp_addr(ct, *dptr, sdpoff, *datalen, 965 if (ct_sip_parse_sdp_addr(ct, *dptr, sdpoff, *datalen,
966 c_hdr, SDP_HDR_MEDIA, 966 c_hdr, SDP_HDR_MEDIA,
967 &matchoff, &matchlen, &caddr) > 0) 967 &matchoff, &matchlen, &caddr) > 0)
968 caddr_len = matchlen; 968 caddr_len = matchlen;
969 969
970 mediaoff = sdpoff; 970 mediaoff = sdpoff;
971 for (i = 0; i < ARRAY_SIZE(sdp_media_types); ) { 971 for (i = 0; i < ARRAY_SIZE(sdp_media_types); ) {
972 if (ct_sip_get_sdp_header(ct, *dptr, mediaoff, *datalen, 972 if (ct_sip_get_sdp_header(ct, *dptr, mediaoff, *datalen,
973 SDP_HDR_MEDIA, SDP_HDR_UNSPEC, 973 SDP_HDR_MEDIA, SDP_HDR_UNSPEC,
974 &mediaoff, &medialen) <= 0) 974 &mediaoff, &medialen) <= 0)
975 break; 975 break;
976 976
977 /* Get media type and port number. A media port value of zero 977 /* Get media type and port number. A media port value of zero
978 * indicates an inactive stream. */ 978 * indicates an inactive stream. */
979 t = sdp_media_type(*dptr, mediaoff, medialen); 979 t = sdp_media_type(*dptr, mediaoff, medialen);
980 if (!t) { 980 if (!t) {
981 mediaoff += medialen; 981 mediaoff += medialen;
982 continue; 982 continue;
983 } 983 }
984 mediaoff += t->len; 984 mediaoff += t->len;
985 medialen -= t->len; 985 medialen -= t->len;
986 986
987 port = simple_strtoul(*dptr + mediaoff, NULL, 10); 987 port = simple_strtoul(*dptr + mediaoff, NULL, 10);
988 if (port == 0) 988 if (port == 0)
989 continue; 989 continue;
990 if (port < 1024 || port > 65535) 990 if (port < 1024 || port > 65535)
991 return NF_DROP; 991 return NF_DROP;
992 992
993 /* The media description overrides the session description. */ 993 /* The media description overrides the session description. */
994 maddr_len = 0; 994 maddr_len = 0;
995 if (ct_sip_parse_sdp_addr(ct, *dptr, mediaoff, *datalen, 995 if (ct_sip_parse_sdp_addr(ct, *dptr, mediaoff, *datalen,
996 c_hdr, SDP_HDR_MEDIA, 996 c_hdr, SDP_HDR_MEDIA,
997 &matchoff, &matchlen, &maddr) > 0) { 997 &matchoff, &matchlen, &maddr) > 0) {
998 maddr_len = matchlen; 998 maddr_len = matchlen;
999 memcpy(&rtp_addr, &maddr, sizeof(rtp_addr)); 999 memcpy(&rtp_addr, &maddr, sizeof(rtp_addr));
1000 } else if (caddr_len) 1000 } else if (caddr_len)
1001 memcpy(&rtp_addr, &caddr, sizeof(rtp_addr)); 1001 memcpy(&rtp_addr, &caddr, sizeof(rtp_addr));
1002 else 1002 else
1003 return NF_DROP; 1003 return NF_DROP;
1004 1004
1005 ret = set_expected_rtp_rtcp(skb, dataoff, dptr, datalen, 1005 ret = set_expected_rtp_rtcp(skb, dataoff, dptr, datalen,
1006 &rtp_addr, htons(port), t->class, 1006 &rtp_addr, htons(port), t->class,
1007 mediaoff, medialen); 1007 mediaoff, medialen);
1008 if (ret != NF_ACCEPT) 1008 if (ret != NF_ACCEPT)
1009 return ret; 1009 return ret;
1010 1010
1011 /* Update media connection address if present */ 1011 /* Update media connection address if present */
1012 if (maddr_len && nf_nat_sdp_addr && ct->status & IPS_NAT_MASK) { 1012 if (maddr_len && nf_nat_sdp_addr && ct->status & IPS_NAT_MASK) {
1013 ret = nf_nat_sdp_addr(skb, dataoff, dptr, datalen, 1013 ret = nf_nat_sdp_addr(skb, dataoff, dptr, datalen,
1014 mediaoff, c_hdr, SDP_HDR_MEDIA, 1014 mediaoff, c_hdr, SDP_HDR_MEDIA,
1015 &rtp_addr); 1015 &rtp_addr);
1016 if (ret != NF_ACCEPT) 1016 if (ret != NF_ACCEPT)
1017 return ret; 1017 return ret;
1018 } 1018 }
1019 i++; 1019 i++;
1020 } 1020 }
1021 1021
1022 /* Update session connection and owner addresses */ 1022 /* Update session connection and owner addresses */
1023 nf_nat_sdp_session = rcu_dereference(nf_nat_sdp_session_hook); 1023 nf_nat_sdp_session = rcu_dereference(nf_nat_sdp_session_hook);
1024 if (nf_nat_sdp_session && ct->status & IPS_NAT_MASK) 1024 if (nf_nat_sdp_session && ct->status & IPS_NAT_MASK)
1025 ret = nf_nat_sdp_session(skb, dataoff, dptr, datalen, sdpoff, 1025 ret = nf_nat_sdp_session(skb, dataoff, dptr, datalen, sdpoff,
1026 &rtp_addr); 1026 &rtp_addr);
1027 1027
1028 return ret; 1028 return ret;
1029 } 1029 }
1030 static int process_invite_response(struct sk_buff *skb, unsigned int dataoff, 1030 static int process_invite_response(struct sk_buff *skb, unsigned int dataoff,
1031 const char **dptr, unsigned int *datalen, 1031 const char **dptr, unsigned int *datalen,
1032 unsigned int cseq, unsigned int code) 1032 unsigned int cseq, unsigned int code)
1033 { 1033 {
1034 enum ip_conntrack_info ctinfo; 1034 enum ip_conntrack_info ctinfo;
1035 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1035 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1036 struct nf_conn_help *help = nfct_help(ct); 1036 struct nf_conn_help *help = nfct_help(ct);
1037 1037
1038 if ((code >= 100 && code <= 199) || 1038 if ((code >= 100 && code <= 199) ||
1039 (code >= 200 && code <= 299)) 1039 (code >= 200 && code <= 299))
1040 return process_sdp(skb, dataoff, dptr, datalen, cseq); 1040 return process_sdp(skb, dataoff, dptr, datalen, cseq);
1041 else if (help->help.ct_sip_info.invite_cseq == cseq) 1041 else if (help->help.ct_sip_info.invite_cseq == cseq)
1042 flush_expectations(ct, true); 1042 flush_expectations(ct, true);
1043 return NF_ACCEPT; 1043 return NF_ACCEPT;
1044 } 1044 }
1045 1045
1046 static int process_update_response(struct sk_buff *skb, unsigned int dataoff, 1046 static int process_update_response(struct sk_buff *skb, unsigned int dataoff,
1047 const char **dptr, unsigned int *datalen, 1047 const char **dptr, unsigned int *datalen,
1048 unsigned int cseq, unsigned int code) 1048 unsigned int cseq, unsigned int code)
1049 { 1049 {
1050 enum ip_conntrack_info ctinfo; 1050 enum ip_conntrack_info ctinfo;
1051 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1051 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1052 struct nf_conn_help *help = nfct_help(ct); 1052 struct nf_conn_help *help = nfct_help(ct);
1053 1053
1054 if ((code >= 100 && code <= 199) || 1054 if ((code >= 100 && code <= 199) ||
1055 (code >= 200 && code <= 299)) 1055 (code >= 200 && code <= 299))
1056 return process_sdp(skb, dataoff, dptr, datalen, cseq); 1056 return process_sdp(skb, dataoff, dptr, datalen, cseq);
1057 else if (help->help.ct_sip_info.invite_cseq == cseq) 1057 else if (help->help.ct_sip_info.invite_cseq == cseq)
1058 flush_expectations(ct, true); 1058 flush_expectations(ct, true);
1059 return NF_ACCEPT; 1059 return NF_ACCEPT;
1060 } 1060 }
1061 1061
1062 static int process_prack_response(struct sk_buff *skb, unsigned int dataoff, 1062 static int process_prack_response(struct sk_buff *skb, unsigned int dataoff,
1063 const char **dptr, unsigned int *datalen, 1063 const char **dptr, unsigned int *datalen,
1064 unsigned int cseq, unsigned int code) 1064 unsigned int cseq, unsigned int code)
1065 { 1065 {
1066 enum ip_conntrack_info ctinfo; 1066 enum ip_conntrack_info ctinfo;
1067 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1067 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1068 struct nf_conn_help *help = nfct_help(ct); 1068 struct nf_conn_help *help = nfct_help(ct);
1069 1069
1070 if ((code >= 100 && code <= 199) || 1070 if ((code >= 100 && code <= 199) ||
1071 (code >= 200 && code <= 299)) 1071 (code >= 200 && code <= 299))
1072 return process_sdp(skb, dataoff, dptr, datalen, cseq); 1072 return process_sdp(skb, dataoff, dptr, datalen, cseq);
1073 else if (help->help.ct_sip_info.invite_cseq == cseq) 1073 else if (help->help.ct_sip_info.invite_cseq == cseq)
1074 flush_expectations(ct, true); 1074 flush_expectations(ct, true);
1075 return NF_ACCEPT; 1075 return NF_ACCEPT;
1076 } 1076 }
1077 1077
1078 static int process_invite_request(struct sk_buff *skb, unsigned int dataoff, 1078 static int process_invite_request(struct sk_buff *skb, unsigned int dataoff,
1079 const char **dptr, unsigned int *datalen, 1079 const char **dptr, unsigned int *datalen,
1080 unsigned int cseq) 1080 unsigned int cseq)
1081 { 1081 {
1082 enum ip_conntrack_info ctinfo; 1082 enum ip_conntrack_info ctinfo;
1083 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1083 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1084 struct nf_conn_help *help = nfct_help(ct); 1084 struct nf_conn_help *help = nfct_help(ct);
1085 unsigned int ret; 1085 unsigned int ret;
1086 1086
1087 flush_expectations(ct, true); 1087 flush_expectations(ct, true);
1088 ret = process_sdp(skb, dataoff, dptr, datalen, cseq); 1088 ret = process_sdp(skb, dataoff, dptr, datalen, cseq);
1089 if (ret == NF_ACCEPT) 1089 if (ret == NF_ACCEPT)
1090 help->help.ct_sip_info.invite_cseq = cseq; 1090 help->help.ct_sip_info.invite_cseq = cseq;
1091 return ret; 1091 return ret;
1092 } 1092 }
1093 1093
1094 static int process_bye_request(struct sk_buff *skb, unsigned int dataoff, 1094 static int process_bye_request(struct sk_buff *skb, unsigned int dataoff,
1095 const char **dptr, unsigned int *datalen, 1095 const char **dptr, unsigned int *datalen,
1096 unsigned int cseq) 1096 unsigned int cseq)
1097 { 1097 {
1098 enum ip_conntrack_info ctinfo; 1098 enum ip_conntrack_info ctinfo;
1099 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1099 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1100 1100
1101 flush_expectations(ct, true); 1101 flush_expectations(ct, true);
1102 return NF_ACCEPT; 1102 return NF_ACCEPT;
1103 } 1103 }
1104 1104
1105 /* Parse a REGISTER request and create a permanent expectation for incoming 1105 /* Parse a REGISTER request and create a permanent expectation for incoming
1106 * signalling connections. The expectation is marked inactive and is activated 1106 * signalling connections. The expectation is marked inactive and is activated
1107 * when receiving a response indicating success from the registrar. 1107 * when receiving a response indicating success from the registrar.
1108 */ 1108 */
1109 static int process_register_request(struct sk_buff *skb, unsigned int dataoff, 1109 static int process_register_request(struct sk_buff *skb, unsigned int dataoff,
1110 const char **dptr, unsigned int *datalen, 1110 const char **dptr, unsigned int *datalen,
1111 unsigned int cseq) 1111 unsigned int cseq)
1112 { 1112 {
1113 enum ip_conntrack_info ctinfo; 1113 enum ip_conntrack_info ctinfo;
1114 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1114 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1115 struct nf_conn_help *help = nfct_help(ct); 1115 struct nf_conn_help *help = nfct_help(ct);
1116 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 1116 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
1117 unsigned int matchoff, matchlen; 1117 unsigned int matchoff, matchlen;
1118 struct nf_conntrack_expect *exp; 1118 struct nf_conntrack_expect *exp;
1119 union nf_inet_addr *saddr, daddr; 1119 union nf_inet_addr *saddr, daddr;
1120 __be16 port; 1120 __be16 port;
1121 u8 proto; 1121 u8 proto;
1122 unsigned int expires = 0; 1122 unsigned int expires = 0;
1123 int ret; 1123 int ret;
1124 typeof(nf_nat_sip_expect_hook) nf_nat_sip_expect; 1124 typeof(nf_nat_sip_expect_hook) nf_nat_sip_expect;
1125 1125
1126 /* Expected connections can not register again. */ 1126 /* Expected connections can not register again. */
1127 if (ct->status & IPS_EXPECTED) 1127 if (ct->status & IPS_EXPECTED)
1128 return NF_ACCEPT; 1128 return NF_ACCEPT;
1129 1129
1130 /* We must check the expiration time: a value of zero signals the 1130 /* We must check the expiration time: a value of zero signals the
1131 * registrar to release the binding. We'll remove our expectation 1131 * registrar to release the binding. We'll remove our expectation
1132 * when receiving the new bindings in the response, but we don't 1132 * when receiving the new bindings in the response, but we don't
1133 * want to create new ones. 1133 * want to create new ones.
1134 * 1134 *
1135 * The expiration time may be contained in Expires: header, the 1135 * The expiration time may be contained in Expires: header, the
1136 * Contact: header parameters or the URI parameters. 1136 * Contact: header parameters or the URI parameters.
1137 */ 1137 */
1138 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_EXPIRES, 1138 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_EXPIRES,
1139 &matchoff, &matchlen) > 0) 1139 &matchoff, &matchlen) > 0)
1140 expires = simple_strtoul(*dptr + matchoff, NULL, 10); 1140 expires = simple_strtoul(*dptr + matchoff, NULL, 10);
1141 1141
1142 ret = ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, 1142 ret = ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen,
1143 SIP_HDR_CONTACT, NULL, 1143 SIP_HDR_CONTACT, NULL,
1144 &matchoff, &matchlen, &daddr, &port); 1144 &matchoff, &matchlen, &daddr, &port);
1145 if (ret < 0) 1145 if (ret < 0)
1146 return NF_DROP; 1146 return NF_DROP;
1147 else if (ret == 0) 1147 else if (ret == 0)
1148 return NF_ACCEPT; 1148 return NF_ACCEPT;
1149 1149
1150 /* We don't support third-party registrations */ 1150 /* We don't support third-party registrations */
1151 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, &daddr)) 1151 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, &daddr))
1152 return NF_ACCEPT; 1152 return NF_ACCEPT;
1153 1153
1154 if (ct_sip_parse_transport(ct, *dptr, matchoff + matchlen, *datalen, 1154 if (ct_sip_parse_transport(ct, *dptr, matchoff + matchlen, *datalen,
1155 &proto) == 0) 1155 &proto) == 0)
1156 return NF_ACCEPT; 1156 return NF_ACCEPT;
1157 1157
1158 if (ct_sip_parse_numerical_param(ct, *dptr, 1158 if (ct_sip_parse_numerical_param(ct, *dptr,
1159 matchoff + matchlen, *datalen, 1159 matchoff + matchlen, *datalen,
1160 "expires=", NULL, NULL, &expires) < 0) 1160 "expires=", NULL, NULL, &expires) < 0)
1161 return NF_DROP; 1161 return NF_DROP;
1162 1162
1163 if (expires == 0) { 1163 if (expires == 0) {
1164 ret = NF_ACCEPT; 1164 ret = NF_ACCEPT;
1165 goto store_cseq; 1165 goto store_cseq;
1166 } 1166 }
1167 1167
1168 exp = nf_ct_expect_alloc(ct); 1168 exp = nf_ct_expect_alloc(ct);
1169 if (!exp) 1169 if (!exp)
1170 return NF_DROP; 1170 return NF_DROP;
1171 1171
1172 saddr = NULL; 1172 saddr = NULL;
1173 if (sip_direct_signalling) 1173 if (sip_direct_signalling)
1174 saddr = &ct->tuplehash[!dir].tuple.src.u3; 1174 saddr = &ct->tuplehash[!dir].tuple.src.u3;
1175 1175
1176 nf_ct_expect_init(exp, SIP_EXPECT_SIGNALLING, nf_ct_l3num(ct), 1176 nf_ct_expect_init(exp, SIP_EXPECT_SIGNALLING, nf_ct_l3num(ct),
1177 saddr, &daddr, proto, NULL, &port); 1177 saddr, &daddr, proto, NULL, &port);
1178 exp->timeout.expires = sip_timeout * HZ; 1178 exp->timeout.expires = sip_timeout * HZ;
1179 exp->helper = nfct_help(ct)->helper; 1179 exp->helper = nfct_help(ct)->helper;
1180 exp->flags = NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE; 1180 exp->flags = NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE;
1181 1181
1182 nf_nat_sip_expect = rcu_dereference(nf_nat_sip_expect_hook); 1182 nf_nat_sip_expect = rcu_dereference(nf_nat_sip_expect_hook);
1183 if (nf_nat_sip_expect && ct->status & IPS_NAT_MASK) 1183 if (nf_nat_sip_expect && ct->status & IPS_NAT_MASK)
1184 ret = nf_nat_sip_expect(skb, dataoff, dptr, datalen, exp, 1184 ret = nf_nat_sip_expect(skb, dataoff, dptr, datalen, exp,
1185 matchoff, matchlen); 1185 matchoff, matchlen);
1186 else { 1186 else {
1187 if (nf_ct_expect_related(exp) != 0) 1187 if (nf_ct_expect_related(exp) != 0)
1188 ret = NF_DROP; 1188 ret = NF_DROP;
1189 else 1189 else
1190 ret = NF_ACCEPT; 1190 ret = NF_ACCEPT;
1191 } 1191 }
1192 nf_ct_expect_put(exp); 1192 nf_ct_expect_put(exp);
1193 1193
1194 store_cseq: 1194 store_cseq:
1195 if (ret == NF_ACCEPT) 1195 if (ret == NF_ACCEPT)
1196 help->help.ct_sip_info.register_cseq = cseq; 1196 help->help.ct_sip_info.register_cseq = cseq;
1197 return ret; 1197 return ret;
1198 } 1198 }
1199 1199
1200 static int process_register_response(struct sk_buff *skb, unsigned int dataoff, 1200 static int process_register_response(struct sk_buff *skb, unsigned int dataoff,
1201 const char **dptr, unsigned int *datalen, 1201 const char **dptr, unsigned int *datalen,
1202 unsigned int cseq, unsigned int code) 1202 unsigned int cseq, unsigned int code)
1203 { 1203 {
1204 enum ip_conntrack_info ctinfo; 1204 enum ip_conntrack_info ctinfo;
1205 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1205 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1206 struct nf_conn_help *help = nfct_help(ct); 1206 struct nf_conn_help *help = nfct_help(ct);
1207 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 1207 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
1208 union nf_inet_addr addr; 1208 union nf_inet_addr addr;
1209 __be16 port; 1209 __be16 port;
1210 u8 proto; 1210 u8 proto;
1211 unsigned int matchoff, matchlen, coff = 0; 1211 unsigned int matchoff, matchlen, coff = 0;
1212 unsigned int expires = 0; 1212 unsigned int expires = 0;
1213 int in_contact = 0, ret; 1213 int in_contact = 0, ret;
1214 1214
1215 /* According to RFC 3261, "UAs MUST NOT send a new registration until 1215 /* According to RFC 3261, "UAs MUST NOT send a new registration until
1216 * they have received a final response from the registrar for the 1216 * they have received a final response from the registrar for the
1217 * previous one or the previous REGISTER request has timed out". 1217 * previous one or the previous REGISTER request has timed out".
1218 * 1218 *
1219 * However, some servers fail to detect retransmissions and send late 1219 * However, some servers fail to detect retransmissions and send late
1220 * responses, so we store the sequence number of the last valid 1220 * responses, so we store the sequence number of the last valid
1221 * request and compare it here. 1221 * request and compare it here.
1222 */ 1222 */
1223 if (help->help.ct_sip_info.register_cseq != cseq) 1223 if (help->help.ct_sip_info.register_cseq != cseq)
1224 return NF_ACCEPT; 1224 return NF_ACCEPT;
1225 1225
1226 if (code >= 100 && code <= 199) 1226 if (code >= 100 && code <= 199)
1227 return NF_ACCEPT; 1227 return NF_ACCEPT;
1228 if (code < 200 || code > 299) 1228 if (code < 200 || code > 299)
1229 goto flush; 1229 goto flush;
1230 1230
1231 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_EXPIRES, 1231 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_EXPIRES,
1232 &matchoff, &matchlen) > 0) 1232 &matchoff, &matchlen) > 0)
1233 expires = simple_strtoul(*dptr + matchoff, NULL, 10); 1233 expires = simple_strtoul(*dptr + matchoff, NULL, 10);
1234 1234
1235 while (1) { 1235 while (1) {
1236 unsigned int c_expires = expires; 1236 unsigned int c_expires = expires;
1237 1237
1238 ret = ct_sip_parse_header_uri(ct, *dptr, &coff, *datalen, 1238 ret = ct_sip_parse_header_uri(ct, *dptr, &coff, *datalen,
1239 SIP_HDR_CONTACT, &in_contact, 1239 SIP_HDR_CONTACT, &in_contact,
1240 &matchoff, &matchlen, 1240 &matchoff, &matchlen,
1241 &addr, &port); 1241 &addr, &port);
1242 if (ret < 0) 1242 if (ret < 0)
1243 return NF_DROP; 1243 return NF_DROP;
1244 else if (ret == 0) 1244 else if (ret == 0)
1245 break; 1245 break;
1246 1246
1247 /* We don't support third-party registrations */ 1247 /* We don't support third-party registrations */
1248 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3, &addr)) 1248 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3, &addr))
1249 continue; 1249 continue;
1250 1250
1251 if (ct_sip_parse_transport(ct, *dptr, matchoff + matchlen, 1251 if (ct_sip_parse_transport(ct, *dptr, matchoff + matchlen,
1252 *datalen, &proto) == 0) 1252 *datalen, &proto) == 0)
1253 continue; 1253 continue;
1254 1254
1255 ret = ct_sip_parse_numerical_param(ct, *dptr, 1255 ret = ct_sip_parse_numerical_param(ct, *dptr,
1256 matchoff + matchlen, 1256 matchoff + matchlen,
1257 *datalen, "expires=", 1257 *datalen, "expires=",
1258 NULL, NULL, &c_expires); 1258 NULL, NULL, &c_expires);
1259 if (ret < 0) 1259 if (ret < 0)
1260 return NF_DROP; 1260 return NF_DROP;
1261 if (c_expires == 0) 1261 if (c_expires == 0)
1262 break; 1262 break;
1263 if (refresh_signalling_expectation(ct, &addr, proto, port, 1263 if (refresh_signalling_expectation(ct, &addr, proto, port,
1264 c_expires)) 1264 c_expires))
1265 return NF_ACCEPT; 1265 return NF_ACCEPT;
1266 } 1266 }
1267 1267
1268 flush: 1268 flush:
1269 flush_expectations(ct, false); 1269 flush_expectations(ct, false);
1270 return NF_ACCEPT; 1270 return NF_ACCEPT;
1271 } 1271 }
1272 1272
1273 static const struct sip_handler sip_handlers[] = { 1273 static const struct sip_handler sip_handlers[] = {
1274 SIP_HANDLER("INVITE", process_invite_request, process_invite_response), 1274 SIP_HANDLER("INVITE", process_invite_request, process_invite_response),
1275 SIP_HANDLER("UPDATE", process_sdp, process_update_response), 1275 SIP_HANDLER("UPDATE", process_sdp, process_update_response),
1276 SIP_HANDLER("ACK", process_sdp, NULL), 1276 SIP_HANDLER("ACK", process_sdp, NULL),
1277 SIP_HANDLER("PRACK", process_sdp, process_prack_response), 1277 SIP_HANDLER("PRACK", process_sdp, process_prack_response),
1278 SIP_HANDLER("BYE", process_bye_request, NULL), 1278 SIP_HANDLER("BYE", process_bye_request, NULL),
1279 SIP_HANDLER("REGISTER", process_register_request, process_register_response), 1279 SIP_HANDLER("REGISTER", process_register_request, process_register_response),
1280 }; 1280 };
1281 1281
1282 static int process_sip_response(struct sk_buff *skb, unsigned int dataoff, 1282 static int process_sip_response(struct sk_buff *skb, unsigned int dataoff,
1283 const char **dptr, unsigned int *datalen) 1283 const char **dptr, unsigned int *datalen)
1284 { 1284 {
1285 enum ip_conntrack_info ctinfo; 1285 enum ip_conntrack_info ctinfo;
1286 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1286 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1287 unsigned int matchoff, matchlen, matchend; 1287 unsigned int matchoff, matchlen, matchend;
1288 unsigned int code, cseq, i; 1288 unsigned int code, cseq, i;
1289 1289
1290 if (*datalen < strlen("SIP/2.0 200")) 1290 if (*datalen < strlen("SIP/2.0 200"))
1291 return NF_ACCEPT; 1291 return NF_ACCEPT;
1292 code = simple_strtoul(*dptr + strlen("SIP/2.0 "), NULL, 10); 1292 code = simple_strtoul(*dptr + strlen("SIP/2.0 "), NULL, 10);
1293 if (!code) 1293 if (!code)
1294 return NF_DROP; 1294 return NF_DROP;
1295 1295
1296 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CSEQ, 1296 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CSEQ,
1297 &matchoff, &matchlen) <= 0) 1297 &matchoff, &matchlen) <= 0)
1298 return NF_DROP; 1298 return NF_DROP;
1299 cseq = simple_strtoul(*dptr + matchoff, NULL, 10); 1299 cseq = simple_strtoul(*dptr + matchoff, NULL, 10);
1300 if (!cseq) 1300 if (!cseq)
1301 return NF_DROP; 1301 return NF_DROP;
1302 matchend = matchoff + matchlen + 1; 1302 matchend = matchoff + matchlen + 1;
1303 1303
1304 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) { 1304 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
1305 const struct sip_handler *handler; 1305 const struct sip_handler *handler;
1306 1306
1307 handler = &sip_handlers[i]; 1307 handler = &sip_handlers[i];
1308 if (handler->response == NULL) 1308 if (handler->response == NULL)
1309 continue; 1309 continue;
1310 if (*datalen < matchend + handler->len || 1310 if (*datalen < matchend + handler->len ||
1311 strnicmp(*dptr + matchend, handler->method, handler->len)) 1311 strnicmp(*dptr + matchend, handler->method, handler->len))
1312 continue; 1312 continue;
1313 return handler->response(skb, dataoff, dptr, datalen, 1313 return handler->response(skb, dataoff, dptr, datalen,
1314 cseq, code); 1314 cseq, code);
1315 } 1315 }
1316 return NF_ACCEPT; 1316 return NF_ACCEPT;
1317 } 1317 }
1318 1318
1319 static int process_sip_request(struct sk_buff *skb, unsigned int dataoff, 1319 static int process_sip_request(struct sk_buff *skb, unsigned int dataoff,
1320 const char **dptr, unsigned int *datalen) 1320 const char **dptr, unsigned int *datalen)
1321 { 1321 {
1322 enum ip_conntrack_info ctinfo; 1322 enum ip_conntrack_info ctinfo;
1323 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1323 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1324 unsigned int matchoff, matchlen; 1324 unsigned int matchoff, matchlen;
1325 unsigned int cseq, i; 1325 unsigned int cseq, i;
1326 1326
1327 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) { 1327 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
1328 const struct sip_handler *handler; 1328 const struct sip_handler *handler;
1329 1329
1330 handler = &sip_handlers[i]; 1330 handler = &sip_handlers[i];
1331 if (handler->request == NULL) 1331 if (handler->request == NULL)
1332 continue; 1332 continue;
1333 if (*datalen < handler->len || 1333 if (*datalen < handler->len ||
1334 strnicmp(*dptr, handler->method, handler->len)) 1334 strnicmp(*dptr, handler->method, handler->len))
1335 continue; 1335 continue;
1336 1336
1337 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CSEQ, 1337 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CSEQ,
1338 &matchoff, &matchlen) <= 0) 1338 &matchoff, &matchlen) <= 0)
1339 return NF_DROP; 1339 return NF_DROP;
1340 cseq = simple_strtoul(*dptr + matchoff, NULL, 10); 1340 cseq = simple_strtoul(*dptr + matchoff, NULL, 10);
1341 if (!cseq) 1341 if (!cseq)
1342 return NF_DROP; 1342 return NF_DROP;
1343 1343
1344 return handler->request(skb, dataoff, dptr, datalen, cseq); 1344 return handler->request(skb, dataoff, dptr, datalen, cseq);
1345 } 1345 }
1346 return NF_ACCEPT; 1346 return NF_ACCEPT;
1347 } 1347 }
1348 1348
1349 static int process_sip_msg(struct sk_buff *skb, struct nf_conn *ct, 1349 static int process_sip_msg(struct sk_buff *skb, struct nf_conn *ct,
1350 unsigned int dataoff, const char **dptr, 1350 unsigned int dataoff, const char **dptr,
1351 unsigned int *datalen) 1351 unsigned int *datalen)
1352 { 1352 {
1353 typeof(nf_nat_sip_hook) nf_nat_sip; 1353 typeof(nf_nat_sip_hook) nf_nat_sip;
1354 int ret; 1354 int ret;
1355 1355
1356 if (strnicmp(*dptr, "SIP/2.0 ", strlen("SIP/2.0 ")) != 0) 1356 if (strnicmp(*dptr, "SIP/2.0 ", strlen("SIP/2.0 ")) != 0)
1357 ret = process_sip_request(skb, dataoff, dptr, datalen); 1357 ret = process_sip_request(skb, dataoff, dptr, datalen);
1358 else 1358 else
1359 ret = process_sip_response(skb, dataoff, dptr, datalen); 1359 ret = process_sip_response(skb, dataoff, dptr, datalen);
1360 1360
1361 if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) { 1361 if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) {
1362 nf_nat_sip = rcu_dereference(nf_nat_sip_hook); 1362 nf_nat_sip = rcu_dereference(nf_nat_sip_hook);
1363 if (nf_nat_sip && !nf_nat_sip(skb, dataoff, dptr, datalen)) 1363 if (nf_nat_sip && !nf_nat_sip(skb, dataoff, dptr, datalen))
1364 ret = NF_DROP; 1364 ret = NF_DROP;
1365 } 1365 }
1366 1366
1367 return ret; 1367 return ret;
1368 } 1368 }
1369 1369
1370 static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, 1370 static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
1371 struct nf_conn *ct, enum ip_conntrack_info ctinfo) 1371 struct nf_conn *ct, enum ip_conntrack_info ctinfo)
1372 { 1372 {
1373 struct tcphdr *th, _tcph; 1373 struct tcphdr *th, _tcph;
1374 unsigned int dataoff, datalen; 1374 unsigned int dataoff, datalen;
1375 unsigned int matchoff, matchlen, clen; 1375 unsigned int matchoff, matchlen, clen;
1376 unsigned int msglen, origlen; 1376 unsigned int msglen, origlen;
1377 const char *dptr, *end; 1377 const char *dptr, *end;
1378 s16 diff, tdiff = 0; 1378 s16 diff, tdiff = 0;
1379 int ret; 1379 int ret = NF_ACCEPT;
1380 typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust; 1380 typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust;
1381 1381
1382 if (ctinfo != IP_CT_ESTABLISHED && 1382 if (ctinfo != IP_CT_ESTABLISHED &&
1383 ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) 1383 ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY)
1384 return NF_ACCEPT; 1384 return NF_ACCEPT;
1385 1385
1386 /* No Data ? */ 1386 /* No Data ? */
1387 th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); 1387 th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
1388 if (th == NULL) 1388 if (th == NULL)
1389 return NF_ACCEPT; 1389 return NF_ACCEPT;
1390 dataoff = protoff + th->doff * 4; 1390 dataoff = protoff + th->doff * 4;
1391 if (dataoff >= skb->len) 1391 if (dataoff >= skb->len)
1392 return NF_ACCEPT; 1392 return NF_ACCEPT;
1393 1393
1394 nf_ct_refresh(ct, skb, sip_timeout * HZ); 1394 nf_ct_refresh(ct, skb, sip_timeout * HZ);
1395 1395
1396 if (unlikely(skb_linearize(skb))) 1396 if (unlikely(skb_linearize(skb)))
1397 return NF_DROP; 1397 return NF_DROP;
1398 1398
1399 dptr = skb->data + dataoff; 1399 dptr = skb->data + dataoff;
1400 datalen = skb->len - dataoff; 1400 datalen = skb->len - dataoff;
1401 if (datalen < strlen("SIP/2.0 200")) 1401 if (datalen < strlen("SIP/2.0 200"))
1402 return NF_ACCEPT; 1402 return NF_ACCEPT;
1403 1403
1404 while (1) { 1404 while (1) {
1405 if (ct_sip_get_header(ct, dptr, 0, datalen, 1405 if (ct_sip_get_header(ct, dptr, 0, datalen,
1406 SIP_HDR_CONTENT_LENGTH, 1406 SIP_HDR_CONTENT_LENGTH,
1407 &matchoff, &matchlen) <= 0) 1407 &matchoff, &matchlen) <= 0)
1408 break; 1408 break;
1409 1409
1410 clen = simple_strtoul(dptr + matchoff, (char **)&end, 10); 1410 clen = simple_strtoul(dptr + matchoff, (char **)&end, 10);
1411 if (dptr + matchoff == end) 1411 if (dptr + matchoff == end)
1412 break; 1412 break;
1413 1413
1414 if (end + strlen("\r\n\r\n") > dptr + datalen) 1414 if (end + strlen("\r\n\r\n") > dptr + datalen)
1415 break; 1415 break;
1416 if (end[0] != '\r' || end[1] != '\n' || 1416 if (end[0] != '\r' || end[1] != '\n' ||
1417 end[2] != '\r' || end[3] != '\n') 1417 end[2] != '\r' || end[3] != '\n')
1418 break; 1418 break;
1419 end += strlen("\r\n\r\n") + clen; 1419 end += strlen("\r\n\r\n") + clen;
1420 1420
1421 msglen = origlen = end - dptr; 1421 msglen = origlen = end - dptr;
1422 1422
1423 ret = process_sip_msg(skb, ct, dataoff, &dptr, &msglen); 1423 ret = process_sip_msg(skb, ct, dataoff, &dptr, &msglen);
1424 if (ret != NF_ACCEPT) 1424 if (ret != NF_ACCEPT)
1425 break; 1425 break;
1426 diff = msglen - origlen; 1426 diff = msglen - origlen;
1427 tdiff += diff; 1427 tdiff += diff;
1428 1428
1429 dataoff += msglen; 1429 dataoff += msglen;
1430 dptr += msglen; 1430 dptr += msglen;
1431 datalen = datalen + diff - msglen; 1431 datalen = datalen + diff - msglen;
1432 } 1432 }
1433 1433
1434 if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) { 1434 if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) {
1435 nf_nat_sip_seq_adjust = rcu_dereference(nf_nat_sip_seq_adjust_hook); 1435 nf_nat_sip_seq_adjust = rcu_dereference(nf_nat_sip_seq_adjust_hook);
1436 if (nf_nat_sip_seq_adjust) 1436 if (nf_nat_sip_seq_adjust)
1437 nf_nat_sip_seq_adjust(skb, tdiff); 1437 nf_nat_sip_seq_adjust(skb, tdiff);
1438 } 1438 }
1439 1439
1440 return ret; 1440 return ret;
1441 } 1441 }
1442 1442
1443 static int sip_help_udp(struct sk_buff *skb, unsigned int protoff, 1443 static int sip_help_udp(struct sk_buff *skb, unsigned int protoff,
1444 struct nf_conn *ct, enum ip_conntrack_info ctinfo) 1444 struct nf_conn *ct, enum ip_conntrack_info ctinfo)
1445 { 1445 {
1446 unsigned int dataoff, datalen; 1446 unsigned int dataoff, datalen;
1447 const char *dptr; 1447 const char *dptr;
1448 1448
1449 /* No Data ? */ 1449 /* No Data ? */
1450 dataoff = protoff + sizeof(struct udphdr); 1450 dataoff = protoff + sizeof(struct udphdr);
1451 if (dataoff >= skb->len) 1451 if (dataoff >= skb->len)
1452 return NF_ACCEPT; 1452 return NF_ACCEPT;
1453 1453
1454 nf_ct_refresh(ct, skb, sip_timeout * HZ); 1454 nf_ct_refresh(ct, skb, sip_timeout * HZ);
1455 1455
1456 if (unlikely(skb_linearize(skb))) 1456 if (unlikely(skb_linearize(skb)))
1457 return NF_DROP; 1457 return NF_DROP;
1458 1458
1459 dptr = skb->data + dataoff; 1459 dptr = skb->data + dataoff;
1460 datalen = skb->len - dataoff; 1460 datalen = skb->len - dataoff;
1461 if (datalen < strlen("SIP/2.0 200")) 1461 if (datalen < strlen("SIP/2.0 200"))
1462 return NF_ACCEPT; 1462 return NF_ACCEPT;
1463 1463
1464 return process_sip_msg(skb, ct, dataoff, &dptr, &datalen); 1464 return process_sip_msg(skb, ct, dataoff, &dptr, &datalen);
1465 } 1465 }
1466 1466
1467 static struct nf_conntrack_helper sip[MAX_PORTS][4] __read_mostly; 1467 static struct nf_conntrack_helper sip[MAX_PORTS][4] __read_mostly;
1468 static char sip_names[MAX_PORTS][4][sizeof("sip-65535")] __read_mostly; 1468 static char sip_names[MAX_PORTS][4][sizeof("sip-65535")] __read_mostly;
1469 1469
1470 static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1] = { 1470 static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1] = {
1471 [SIP_EXPECT_SIGNALLING] = { 1471 [SIP_EXPECT_SIGNALLING] = {
1472 .name = "signalling", 1472 .name = "signalling",
1473 .max_expected = 1, 1473 .max_expected = 1,
1474 .timeout = 3 * 60, 1474 .timeout = 3 * 60,
1475 }, 1475 },
1476 [SIP_EXPECT_AUDIO] = { 1476 [SIP_EXPECT_AUDIO] = {
1477 .name = "audio", 1477 .name = "audio",
1478 .max_expected = 2 * IP_CT_DIR_MAX, 1478 .max_expected = 2 * IP_CT_DIR_MAX,
1479 .timeout = 3 * 60, 1479 .timeout = 3 * 60,
1480 }, 1480 },
1481 [SIP_EXPECT_VIDEO] = { 1481 [SIP_EXPECT_VIDEO] = {
1482 .name = "video", 1482 .name = "video",
1483 .max_expected = 2 * IP_CT_DIR_MAX, 1483 .max_expected = 2 * IP_CT_DIR_MAX,
1484 .timeout = 3 * 60, 1484 .timeout = 3 * 60,
1485 }, 1485 },
1486 [SIP_EXPECT_IMAGE] = { 1486 [SIP_EXPECT_IMAGE] = {
1487 .name = "image", 1487 .name = "image",
1488 .max_expected = IP_CT_DIR_MAX, 1488 .max_expected = IP_CT_DIR_MAX,
1489 .timeout = 3 * 60, 1489 .timeout = 3 * 60,
1490 }, 1490 },
1491 }; 1491 };
1492 1492
1493 static void nf_conntrack_sip_fini(void) 1493 static void nf_conntrack_sip_fini(void)
1494 { 1494 {
1495 int i, j; 1495 int i, j;
1496 1496
1497 for (i = 0; i < ports_c; i++) { 1497 for (i = 0; i < ports_c; i++) {
1498 for (j = 0; j < ARRAY_SIZE(sip[i]); j++) { 1498 for (j = 0; j < ARRAY_SIZE(sip[i]); j++) {
1499 if (sip[i][j].me == NULL) 1499 if (sip[i][j].me == NULL)
1500 continue; 1500 continue;
1501 nf_conntrack_helper_unregister(&sip[i][j]); 1501 nf_conntrack_helper_unregister(&sip[i][j]);
1502 } 1502 }
1503 } 1503 }
1504 } 1504 }
1505 1505
1506 static int __init nf_conntrack_sip_init(void) 1506 static int __init nf_conntrack_sip_init(void)
1507 { 1507 {
1508 int i, j, ret; 1508 int i, j, ret;
1509 char *tmpname; 1509 char *tmpname;
1510 1510
1511 if (ports_c == 0) 1511 if (ports_c == 0)
1512 ports[ports_c++] = SIP_PORT; 1512 ports[ports_c++] = SIP_PORT;
1513 1513
1514 for (i = 0; i < ports_c; i++) { 1514 for (i = 0; i < ports_c; i++) {
1515 memset(&sip[i], 0, sizeof(sip[i])); 1515 memset(&sip[i], 0, sizeof(sip[i]));
1516 1516
1517 sip[i][0].tuple.src.l3num = AF_INET; 1517 sip[i][0].tuple.src.l3num = AF_INET;
1518 sip[i][0].tuple.dst.protonum = IPPROTO_UDP; 1518 sip[i][0].tuple.dst.protonum = IPPROTO_UDP;
1519 sip[i][0].help = sip_help_udp; 1519 sip[i][0].help = sip_help_udp;
1520 sip[i][1].tuple.src.l3num = AF_INET; 1520 sip[i][1].tuple.src.l3num = AF_INET;
1521 sip[i][1].tuple.dst.protonum = IPPROTO_TCP; 1521 sip[i][1].tuple.dst.protonum = IPPROTO_TCP;
1522 sip[i][1].help = sip_help_tcp; 1522 sip[i][1].help = sip_help_tcp;
1523 1523
1524 sip[i][2].tuple.src.l3num = AF_INET6; 1524 sip[i][2].tuple.src.l3num = AF_INET6;
1525 sip[i][2].tuple.dst.protonum = IPPROTO_UDP; 1525 sip[i][2].tuple.dst.protonum = IPPROTO_UDP;
1526 sip[i][2].help = sip_help_udp; 1526 sip[i][2].help = sip_help_udp;
1527 sip[i][3].tuple.src.l3num = AF_INET6; 1527 sip[i][3].tuple.src.l3num = AF_INET6;
1528 sip[i][3].tuple.dst.protonum = IPPROTO_TCP; 1528 sip[i][3].tuple.dst.protonum = IPPROTO_TCP;
1529 sip[i][3].help = sip_help_tcp; 1529 sip[i][3].help = sip_help_tcp;
1530 1530
1531 for (j = 0; j < ARRAY_SIZE(sip[i]); j++) { 1531 for (j = 0; j < ARRAY_SIZE(sip[i]); j++) {
1532 sip[i][j].tuple.src.u.udp.port = htons(ports[i]); 1532 sip[i][j].tuple.src.u.udp.port = htons(ports[i]);
1533 sip[i][j].expect_policy = sip_exp_policy; 1533 sip[i][j].expect_policy = sip_exp_policy;
1534 sip[i][j].expect_class_max = SIP_EXPECT_MAX; 1534 sip[i][j].expect_class_max = SIP_EXPECT_MAX;
1535 sip[i][j].me = THIS_MODULE; 1535 sip[i][j].me = THIS_MODULE;
1536 1536
1537 tmpname = &sip_names[i][j][0]; 1537 tmpname = &sip_names[i][j][0];
1538 if (ports[i] == SIP_PORT) 1538 if (ports[i] == SIP_PORT)
1539 sprintf(tmpname, "sip"); 1539 sprintf(tmpname, "sip");
1540 else 1540 else
1541 sprintf(tmpname, "sip-%u", i); 1541 sprintf(tmpname, "sip-%u", i);
1542 sip[i][j].name = tmpname; 1542 sip[i][j].name = tmpname;
1543 1543
1544 pr_debug("port #%u: %u\n", i, ports[i]); 1544 pr_debug("port #%u: %u\n", i, ports[i]);
1545 1545
1546 ret = nf_conntrack_helper_register(&sip[i][j]); 1546 ret = nf_conntrack_helper_register(&sip[i][j]);
1547 if (ret) { 1547 if (ret) {
1548 printk(KERN_ERR "nf_ct_sip: failed to register" 1548 printk(KERN_ERR "nf_ct_sip: failed to register"
1549 " helper for pf: %u port: %u\n", 1549 " helper for pf: %u port: %u\n",
1550 sip[i][j].tuple.src.l3num, ports[i]); 1550 sip[i][j].tuple.src.l3num, ports[i]);
1551 nf_conntrack_sip_fini(); 1551 nf_conntrack_sip_fini();
1552 return ret; 1552 return ret;
1553 } 1553 }
1554 } 1554 }
1555 } 1555 }
1556 return 0; 1556 return 0;
1557 } 1557 }
1558 1558
1559 module_init(nf_conntrack_sip_init); 1559 module_init(nf_conntrack_sip_init);
1560 module_exit(nf_conntrack_sip_fini); 1560 module_exit(nf_conntrack_sip_fini);
1561 1561