1 /*
2  * Copyright (C) 2001-2003 FhG Fokus
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * Kamailio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  * Kamailio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21 
22 /** @file
23  * @brief Parser :: Parse URI's
24  *
25  * @ingroup parser
26  */
27 
28 
29 #include <stdint.h>
30 
31 #include "../globals.h"
32 #include "parse_uri.h"
33 #include <string.h>
34 #include "../dprint.h"
35 #include "../ut.h"   /* q_memchr */
36 #include "../error.h"
37 #include "../core_stats.h"
38 
39 static char _sr_uri_empty_buf[2] = {0};
40 static str _sr_uri_empty = { _sr_uri_empty_buf, 0 };
41 
42 /* extra chars that should be allowed in URI host */
43 char *_sr_uri_host_extra_chars = "";
44 
uri_host_char_allowed(char c)45 int uri_host_char_allowed(char c)
46 {
47 	int i = 0;
48 
49 	if(_sr_uri_host_extra_chars==NULL || _sr_uri_host_extra_chars[0]=='\0') {
50 		return 0;
51 	}
52 	while(_sr_uri_host_extra_chars[i]!='\0') {
53 		if(_sr_uri_host_extra_chars[i]==c) {
54 			return 1;
55 		}
56 		i++;
57 	}
58 	return 0;
59 }
60 
61 /* buf= pointer to begining of uri (sip:x@foo.bar:5060;a=b?h=i)
62  * len= len of uri
63  * returns: fills uri & returns <0 on error or 0 if ok
64  */
parse_uri(char * buf,int len,struct sip_uri * uri)65 int parse_uri(char* buf, int len, struct sip_uri* uri)
66 {
67 	enum states  {	URI_INIT, URI_USER, URI_PASSWORD, URI_PASSWORD_ALPHA,
68 					URI_HOST, URI_HOST_P,
69 					URI_HOST6_P, URI_HOST6_END, URI_PORT,
70 					URI_PARAM, URI_PARAM_P, URI_VAL_P, URI_HEADERS,
71 					/* param states */
72 					/* transport */
73 					PT_T, PT_R, PT_A, PT_N, PT_S, PT_P, PT_O, PT_R2, PT_T2,
74 					PT_eq,
75 					/* ttl */
76 					PTTL_T2, PTTL_L, PTTL_eq,
77 					/* user */
78 					PU_U, PU_S, PU_E, PU_R, PU_eq,
79 					/* method */
80 					PM_M, PM_E, PM_T, PM_H, PM_O, PM_D, PM_eq,
81 					/* maddr */
82 					PMA_A, PMA_D, PMA_D2, PMA_R, PMA_eq,
83 					/* lr */
84 					PLR_L, PLR_R_FIN, PLR_eq,
85 					/* r2 */
86 					PR2_R, PR2_2_FIN, PR2_eq,
87 					/* gr */
88 					PGR_G, PGR_R_FIN, PGR_eq,
89 #ifdef USE_COMP
90 					/* comp */
91 					PCOMP_C, PCOMP_O, PCOMP_M, PCOMP_P, PCOMP_eq,
92 
93 					/* comp values */
94 					/* sigcomp */
95 					VCOMP_S, VCOMP_SIGC_I, VCOMP_SIGC_G,
96 					VCOMP_SIGC_C, VCOMP_SIGC_O,  VCOMP_SIGC_M,
97 					VCOMP_SIGC_P_FIN,
98 					/* sergz */
99 							VCOMP_SGZ_E, VCOMP_SGZ_R, VCOMP_SGZ_G,
100 							VCOMP_SGZ_Z_FIN,
101 #endif
102 
103 					/* transport values */
104 					/* udp */
105 					VU_U, VU_D, VU_P_FIN,
106 					/* tcp */
107 					VT_T, VT_C, VT_P_FIN,
108 					/* tls */
109 					VTLS_L, VTLS_S_FIN,
110 					/* sctp */
111 					VS_S, VS_C, VS_T, VS_P_FIN,
112 					/* ws */
113 					VW_W, VW_S_FIN
114 	};
115 	register enum states state;
116 	char* s;
117 	char* b; /* param start */
118 	char *v; /* value start */
119 	str* param; /* current param */
120 	str* param_val; /* current param val */
121 	str user;
122 	str password;
123 	int port_no;
124 	register char* p;
125 	char* end;
126 	char* pass;
127 	int found_user;
128 	int error_headers;
129 	uint32_t scheme;
130 	uri_type backup_urit;
131 	uri_flags backup_urif;
132 
133 #ifdef USE_COMP
134 	str comp_str; /* not returned for now */
135 	str comp_val; /* not returned for now */
136 #endif
137 
138 #define SIP_SCH		0x3a706973
139 #define SIPS_SCH	0x73706973
140 #define TEL_SCH		0x3a6c6574
141 #define URN_SCH		0x3a6e7275
142 
143 #define case_port( ch, var) \
144 	case ch: \
145 			(var)=(var)*10+ch-'0'; \
146 			if((var) > MAX_PORT_VAL) { \
147 				goto error_bad_port; \
148 			}\
149 			break
150 
151 #define still_at_user  \
152 						if (found_user==0){ \
153 							user.s=uri->host.s; \
154 							if (pass){\
155 								user.len=pass-user.s; \
156 								password.s=pass+1; \
157 								password.len=p-password.s; \
158 							}else{ \
159 								user.len=p-user.s; \
160 							}\
161 							/* save the uri type/scheme */ \
162 							backup_urit=uri->type; \
163 							backup_urif=uri->flags; \
164 							/* everything else is 0 */ \
165 							memset(uri, 0, sizeof(struct sip_uri)); \
166 							/* restore the scheme & flags, copy user & pass */ \
167 							uri->type=backup_urit; \
168 							uri->flags=backup_urif; \
169 							uri->user=user; \
170 							if (pass)	uri->passwd=password;  \
171 							s=p+1; \
172 							found_user=1;\
173 							error_headers=0; \
174 							state=URI_HOST; \
175 						}else goto error_bad_char
176 
177 #define check_host_end \
178 					case ':': \
179 						/* found the host */ \
180 						uri->host.s=s; \
181 						uri->host.len=p-s; \
182 						state=URI_PORT; \
183 						s=p+1; \
184 						break; \
185 					case ';': \
186 						uri->host.s=s; \
187 						uri->host.len=p-s; \
188 						state=URI_PARAM; \
189 						s=p+1; \
190 						break; \
191 					case '?': \
192 						uri->host.s=s; \
193 						uri->host.len=p-s; \
194 						state=URI_HEADERS; \
195 						s=p+1; \
196 						break; \
197 					case '&': \
198 					case '@': \
199 						goto error_bad_char
200 
201 
202 #define param_set(t_start, v_start) \
203 					param->s=(t_start);\
204 					param->len=(p-(t_start));\
205 					param_val->s=(v_start); \
206 					param_val->len=(p-(v_start))
207 
208 #define semicolon_case \
209 					case';': \
210 						if (pass){ \
211 							found_user=1;/* no user, pass cannot contain ';'*/ \
212 							pass=0; \
213 						} \
214 						state=URI_PARAM   /* new param */
215 
216 #define question_case \
217 					case '?': \
218 						uri->params.s=s; \
219 						uri->params.len=p-s; \
220 						state=URI_HEADERS; \
221 						s=p+1; \
222 						if (pass){ \
223 							found_user=1;/* no user, pass cannot contain '?'*/ \
224 							pass=0; \
225 						}
226 
227 #define colon_case \
228 					case ':': \
229 						if (found_user==0){ \
230 							/*might be pass but only if user not found yet*/ \
231 							if (pass){ \
232 								found_user=1; /* no user */ \
233 								pass=0; \
234 							}else{ \
235 								pass=p; \
236 							} \
237 						} \
238 						state=URI_PARAM_P /* generic param */
239 
240 #define param_common_cases \
241 					case '@': \
242 						/* ughhh, this is still the user */ \
243 						still_at_user; \
244 						break; \
245 					semicolon_case; \
246 						break; \
247 					question_case; \
248 						break; \
249 					colon_case; \
250 						break
251 
252 #define value_common_cases \
253 					case '@': \
254 						/* ughhh, this is still the user */ \
255 						still_at_user; \
256 						break; \
257 					semicolon_case; \
258 						param_set(b, v); \
259 						break; \
260 					question_case; \
261 						param_set(b, v); \
262 						break; \
263 					colon_case; \
264 						state=URI_VAL_P; \
265 						break
266 
267 #define param_switch(old_state, c1, c2, new_state) \
268 			case old_state: \
269 				switch(*p){ \
270 					case c1: \
271 					case c2: \
272 						state=(new_state); \
273 						break; \
274 					param_common_cases; \
275 					default: \
276 						state=URI_PARAM_P; \
277 				} \
278 				break
279 #define param_switch1(old_state, c1, new_state) \
280 			case old_state: \
281 				switch(*p){ \
282 					case c1: \
283 						state=(new_state); \
284 						break; \
285 					param_common_cases; \
286 					default: \
287 						state=URI_PARAM_P; \
288 				} \
289 				break
290 #define param_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
291 			case old_state : \
292 				switch(*p){ \
293 					case c1: \
294 					case c2: \
295 						state=(new_state_c); \
296 						break; \
297 					case d1: \
298 					case d2: \
299 						state=(new_state_d); \
300 						break; \
301 					param_common_cases; \
302 					default: \
303 						state=URI_PARAM_P; \
304 				} \
305 				break
306 #define value_switch(old_state, c1, c2, new_state) \
307 			case old_state: \
308 				switch(*p){ \
309 					case c1: \
310 					case c2: \
311 						state=(new_state); \
312 						break; \
313 					value_common_cases; \
314 					default: \
315 						state=URI_VAL_P; \
316 				} \
317 				break
318 #define value_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
319 			case old_state: \
320 				switch(*p){ \
321 					case c1: \
322 					case c2: \
323 						state=(new_state_c); \
324 						break; \
325 					case d1: \
326 					case d2: \
327 						state=(new_state_d); \
328 						break; \
329 					value_common_cases; \
330 					default: \
331 						state=URI_VAL_P; \
332 				} \
333 				break
334 
335 #define transport_fin(c_state, proto_no) \
336 			case c_state: \
337 				switch(*p){ \
338 					case '@': \
339 						still_at_user; \
340 						break; \
341 					semicolon_case; \
342 						param_set(b, v); \
343 						uri->proto=(proto_no); \
344 						break; \
345 					question_case; \
346 						param_set(b, v); \
347 						uri->proto=(proto_no); \
348 						break; \
349 					colon_case;  \
350 					default: \
351 						state=URI_VAL_P; \
352 						break; \
353 				} \
354 				break
355 
356 
357 #ifdef USE_COMP
358 #define comp_fin(c_state, comp_no) \
359 			case c_state: \
360 				switch(*p){ \
361 					case '@': \
362 						still_at_user; \
363 						break; \
364 					semicolon_case; \
365 						/* param_set(b, v); */ \
366 						uri->comp=(comp_no); \
367 						break; \
368 					question_case; \
369 						/* param_set(b, v) */; \
370 						uri->comp=(comp_no); \
371 						break; \
372 					colon_case;  \
373 					default: \
374 						state=URI_VAL_P; \
375 						break; \
376 				} \
377 				break
378 
379 #endif
380 
381 	/* init */
382 	end=buf+len;
383 	p=buf+4;
384 	found_user=0;
385 	error_headers=0;
386 	b=v=0;
387 	param=param_val=0;
388 	pass=0;
389 	password.s=0; /* fixes gcc 4.0 warning */
390 	password.len=0;
391 	port_no=0;
392 	state=URI_INIT;
393 	memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure*/
394 	/*look for sip:, sips:, tel: or urn:*/
395 	if (len<5) goto error_too_short;
396 	scheme=((uint32_t)buf[0]) + (((uint32_t)buf[1])<<8)
397 				+ (((uint32_t)buf[2])<<16) + (((uint32_t)buf[3])<<24);
398 	scheme|=0x20202020;
399 	if (scheme==SIP_SCH){
400 		uri->type=SIP_URI_T;
401 	}else if(scheme==SIPS_SCH){
402 		if(buf[4]==':'){ p++; uri->type=SIPS_URI_T;}
403 		else goto error_bad_uri;
404 	}else if (scheme==TEL_SCH){
405 		uri->type=TEL_URI_T;
406 	}else if (scheme==URN_SCH){
407 		uri->type=URN_URI_T;
408 	}else goto error_bad_uri;
409 
410 	s=p;
411 	for(;p<end; p++){
412 		switch((unsigned char)state){
413 			case URI_INIT:
414 				switch(*p){
415 					case '[':
416 						/* uri =  [ipv6address]... */
417 						state=URI_HOST6_P;
418 						s=p;
419 						break;
420 					case ']':
421 						/* invalid, no uri can start with ']' */
422 					case ':':
423 						/* the same as above for ':' */
424 						goto error_bad_char;
425 					case '@': /* error no user part, or
426 								* be forgiving and accept it ? */
427 					default:
428 						state=URI_USER;
429 				}
430 				break;
431 			case URI_USER:
432 				switch(*p){
433 					case '@':
434 						/* found the user*/
435 						uri->user.s=s;
436 						uri->user.len=p-s;
437 						state=URI_HOST;
438 						found_user=1;
439 						s=p+1; /* skip '@' */
440 						break;
441 					case ':':
442 						/* found the user, or the host? */
443 						uri->user.s=s;
444 						uri->user.len=p-s;
445 						state=URI_PASSWORD;
446 						s=p+1; /* skip ':' */
447 						break;
448 					case ';':
449 						/* this could be still the user or
450 						 * params?*/
451 						uri->host.s=s;
452 						uri->host.len=p-s;
453 						state=URI_PARAM;
454 						s=p+1;
455 						break;
456 					case '?': /* still user or headers? */
457 						uri->host.s=s;
458 						uri->host.len=p-s;
459 						state=URI_HEADERS;
460 						s=p+1;
461 						break;
462 						/* almost anything permitted in the user part */
463 					case '.':
464 					case '-':
465 					case '(':
466 					case ')':
467 						/* tel uri visual separators, set flag meaning, that
468 						 * user should be normalized before usage
469 						 */
470 						uri->flags|=URI_USER_NORMALIZE;
471 						break;
472 					case '[':
473 					case ']': /* the user part cannot contain "[]" */
474 						goto error_bad_char;
475 				}
476 				break;
477 			case URI_PASSWORD: /* this can also be the port (missing user)*/
478 				switch(*p){
479 					case '@':
480 						/* found the password*/
481 						uri->passwd.s=s;
482 						uri->passwd.len=p-s;
483 						port_no=0;
484 						state=URI_HOST;
485 						found_user=1;
486 						s=p+1; /* skip '@' */
487 						break;
488 					case ';':
489 						/* upps this is the port */
490 						uri->port.s=s;
491 						uri->port.len=p-s;
492 						uri->port_no=port_no;
493 						/* user contains in fact the host */
494 						uri->host.s=uri->user.s;
495 						uri->host.len=uri->user.len;
496 						uri->user.s=0;
497 						uri->user.len=0;
498 						state=URI_PARAM;
499 						found_user=1; /*  there is no user part */
500 						s=p+1;
501 						break;
502 					case '?':
503 						/* upps this is the port */
504 						uri->port.s=s;
505 						uri->port.len=p-s;
506 						uri->port_no=port_no;
507 						/* user contains in fact the host */
508 						uri->host.s=uri->user.s;
509 						uri->host.len=uri->user.len;
510 						uri->user.s=0;
511 						uri->user.len=0;
512 						state=URI_HEADERS;
513 						found_user=1; /*  there is no user part */
514 						s=p+1;
515 						break;
516 					case_port('0', port_no);
517 					case_port('1', port_no);
518 					case_port('2', port_no);
519 					case_port('3', port_no);
520 					case_port('4', port_no);
521 					case_port('5', port_no);
522 					case_port('6', port_no);
523 					case_port('7', port_no);
524 					case_port('8', port_no);
525 					case_port('9', port_no);
526 					case '[':
527 					case ']':
528 					case ':':
529 						goto error_bad_char;
530 					default:
531 						/* it can't be the port, non number found */
532 						port_no=0;
533 						state=URI_PASSWORD_ALPHA;
534 				}
535 				break;
536 			case URI_PASSWORD_ALPHA:
537 				switch(*p){
538 					case '@':
539 						/* found the password*/
540 						uri->passwd.s=s;
541 						uri->passwd.len=p-s;
542 						state=URI_HOST;
543 						found_user=1;
544 						s=p+1; /* skip '@' */
545 						break;
546 					case ';': /* contains non-numbers => cannot be port no*/
547 					case '?':
548 						goto error_bad_port;
549 					case '[':
550 					case ']':
551 					case ':':
552 						goto error_bad_char;
553 				}
554 				break;
555 			case URI_HOST:
556 				if(*p == '[') {
557 					state = URI_HOST6_P;
558 				} else {
559 					if(isalnum(*p)) {
560 						state = URI_HOST_P;
561 					} else {
562 						goto error_bad_host;
563 					}
564 				}
565 				break;
566 			case URI_HOST_P:
567 				switch(*p) {
568 					check_host_end;
569 					default:
570 						if(!isalnum(*p) && (*p != '.') && (*p != '-')
571 								&& !uri_host_char_allowed(*p)) {
572 							goto error_bad_host;
573 						}
574 				}
575 				break;
576 			case URI_HOST6_END:
577 				switch(*p){
578 					check_host_end;
579 					default: /*no chars allowed after [ipv6] */
580 						goto error_bad_host;
581 				}
582 				break;
583 			case URI_HOST6_P:
584 				switch(*p){
585 					case ']':
586 						state=URI_HOST6_END;
587 						break;
588 					case '[':
589 					case '&':
590 					case '@':
591 					case ';':
592 					case '?':
593 						goto error_bad_host;
594 				}
595 				break;
596 			case URI_PORT:
597 				switch(*p){
598 					case ';':
599 						uri->port.s=s;
600 						uri->port.len=p-s;
601 						uri->port_no=port_no;
602 						state=URI_PARAM;
603 						s=p+1;
604 						break;
605 					case '?':
606 						uri->port.s=s;
607 						uri->port.len=p-s;
608 						uri->port_no=port_no;
609 						state=URI_HEADERS;
610 						s=p+1;
611 						break;
612 					case_port('0', port_no);
613 					case_port('1', port_no);
614 					case_port('2', port_no);
615 					case_port('3', port_no);
616 					case_port('4', port_no);
617 					case_port('5', port_no);
618 					case_port('6', port_no);
619 					case_port('7', port_no);
620 					case_port('8', port_no);
621 					case_port('9', port_no);
622 					case '&':
623 					case '@':
624 					case ':':
625 					default:
626 						goto error_bad_port;
627 				}
628 				break;
629 			case URI_PARAM: /* beginning of a new param */
630 				switch(*p){
631 					param_common_cases;
632 					/* recognized params */
633 					case 't':
634 					case 'T':
635 						b=p;
636 						state=PT_T;
637 						break;
638 					case 'u':
639 					case 'U':
640 						b=p;
641 						state=PU_U;
642 						break;
643 					case 'm':
644 					case 'M':
645 						b=p;
646 						state=PM_M;
647 						break;
648 					case 'l':
649 					case 'L':
650 						b=p;
651 						state=PLR_L;
652 						break;
653 					case 'r':
654 					case 'R':
655 						b=p;
656 						state=PR2_R;
657 						break;
658 					case 'g':
659 					case 'G':
660 						b=p;
661 						state=PGR_G;
662 						break;
663 #ifdef USE_COMP
664 					case 'c':
665 					case 'C':
666 						b=p;
667 						state=PCOMP_C;
668 						break;
669 #endif
670 					default:
671 						state=URI_PARAM_P;
672 				}
673 				break;
674 			case URI_PARAM_P: /* ignore current param */
675 				/* supported params:
676 				 *  maddr, transport, ttl, lr, user, method, r2  */
677 				switch(*p){
678 					param_common_cases;
679 				};
680 				break;
681 			/* ugly but fast param names parsing */
682 			/*transport */
683 			param_switch_big(PT_T,  'r', 'R', 't', 'T', PT_R, PTTL_T2);
684 			param_switch(PT_R,  'a', 'A', PT_A);
685 			param_switch(PT_A,  'n', 'N', PT_N);
686 			param_switch(PT_N,  's', 'S', PT_S);
687 			param_switch(PT_S,  'p', 'P', PT_P);
688 			param_switch(PT_P,  'o', 'O', PT_O);
689 			param_switch(PT_O,  'r', 'R', PT_R2);
690 			param_switch(PT_R2, 't', 'T', PT_T2);
691 			param_switch1(PT_T2, '=',  PT_eq);
692 			/* value parsing */
693 			case PT_eq:
694 				param=&uri->transport;
695 				param_val=&uri->transport_val;
696 				switch (*p){
697 					param_common_cases;
698 					case 'u':
699 					case 'U':
700 						v=p;
701 						state=VU_U;
702 						break;
703 					case 't':
704 					case 'T':
705 						v=p;
706 						state=VT_T;
707 						break;
708 					case 's':
709 					case 'S':
710 						v=p;
711 						state=VS_S;
712 						break;
713 					case 'w':
714 					case 'W':
715 						v=p;
716 						state=VW_W;
717 						break;
718 					default:
719 						v=p;
720 						state=URI_VAL_P;
721 				}
722 				break;
723 				/* generic value */
724 			case URI_VAL_P:
725 				switch(*p){
726 					value_common_cases;
727 				}
728 				break;
729 			/* udp */
730 			value_switch(VU_U,  'd', 'D', VU_D);
731 			value_switch(VU_D,  'p', 'P', VU_P_FIN);
732 			transport_fin(VU_P_FIN, PROTO_UDP);
733 			/* tcp */
734 			value_switch_big(VT_T,  'c', 'C', 'l', 'L', VT_C, VTLS_L);
735 			value_switch(VT_C,  'p', 'P', VT_P_FIN);
736 			transport_fin(VT_P_FIN, PROTO_TCP);
737 			/* tls */
738 			value_switch(VTLS_L, 's', 'S', VTLS_S_FIN);
739 			transport_fin(VTLS_S_FIN, PROTO_TLS);
740 			/* sctp */
741 			value_switch(VS_S, 'c', 'C', VS_C);
742 			value_switch(VS_C, 't', 'T', VS_T);
743 			value_switch(VS_T, 'p', 'P', VS_P_FIN);
744 			transport_fin(VS_P_FIN, PROTO_SCTP);
745 			/* ws */
746 			value_switch(VW_W, 's', 'S', VW_S_FIN);
747 			transport_fin(VW_S_FIN, PROTO_WS);
748 
749 			/* ttl */
750 			param_switch(PTTL_T2,  'l', 'L', PTTL_L);
751 			param_switch1(PTTL_L,  '=', PTTL_eq);
752 			case PTTL_eq:
753 				param=&uri->ttl;
754 				param_val=&uri->ttl_val;
755 				switch(*p){
756 					param_common_cases;
757 					default:
758 						v=p;
759 						state=URI_VAL_P;
760 				}
761 				break;
762 
763 			/* user param */
764 			param_switch(PU_U, 's', 'S', PU_S);
765 			param_switch(PU_S, 'e', 'E', PU_E);
766 			param_switch(PU_E, 'r', 'R', PU_R);
767 			param_switch1(PU_R, '=', PU_eq);
768 			case PU_eq:
769 				param=&uri->user_param;
770 				param_val=&uri->user_param_val;
771 				switch(*p){
772 					param_common_cases;
773 					default:
774 						v=p;
775 						state=URI_VAL_P;
776 				}
777 				break;
778 
779 			/* method*/
780 			param_switch_big(PM_M, 'e', 'E', 'a', 'A', PM_E, PMA_A);
781 			param_switch(PM_E, 't', 'T', PM_T);
782 			param_switch(PM_T, 'h', 'H', PM_H);
783 			param_switch(PM_H, 'o', 'O', PM_O);
784 			param_switch(PM_O, 'd', 'D', PM_D);
785 			param_switch1(PM_D, '=', PM_eq);
786 			case PM_eq:
787 				param=&uri->method;
788 				param_val=&uri->method_val;
789 				switch(*p){
790 					param_common_cases;
791 					default:
792 						v=p;
793 						state=URI_VAL_P;
794 				}
795 				break;
796 
797 			/*maddr*/
798 			param_switch(PMA_A,  'd', 'D', PMA_D);
799 			param_switch(PMA_D,  'd', 'D', PMA_D2);
800 			param_switch(PMA_D2, 'r', 'R', PMA_R);
801 			param_switch1(PMA_R, '=', PMA_eq);
802 			case PMA_eq:
803 				param=&uri->maddr;
804 				param_val=&uri->maddr_val;
805 				switch(*p){
806 					param_common_cases;
807 					default:
808 						v=p;
809 						state=URI_VAL_P;
810 				}
811 				break;
812 
813 			/* lr */
814 			param_switch(PLR_L,  'r', 'R', PLR_R_FIN);
815 			case PLR_R_FIN:
816 				switch(*p){
817 					case '@':
818 						still_at_user;
819 						break;
820 					case '=':
821 						state=PLR_eq;
822 						break;
823 					semicolon_case;
824 						uri->lr.s=b;
825 						uri->lr.len=(p-b);
826 						break;
827 					question_case;
828 						uri->lr.s=b;
829 						uri->lr.len=(p-b);
830 						break;
831 					colon_case;
832 						break;
833 					default:
834 						state=URI_PARAM_P;
835 				}
836 				break;
837 				/* handle lr=something case */
838 			case PLR_eq:
839 				param=&uri->lr;
840 				param_val=&uri->lr_val;
841 				switch(*p){
842 					param_common_cases;
843 					default:
844 						v=p;
845 						state=URI_VAL_P;
846 				}
847 				break;
848 			/* r2 */
849 			param_switch1(PR2_R,  '2', PR2_2_FIN);
850 			case PR2_2_FIN:
851 				switch(*p){
852 					case '@':
853 						still_at_user;
854 						break;
855 					case '=':
856 						state=PR2_eq;
857 						break;
858 					semicolon_case;
859 						uri->r2.s=b;
860 						uri->r2.len=(p-b);
861 						break;
862 					question_case;
863 						uri->r2.s=b;
864 						uri->r2.len=(p-b);
865 						break;
866 					colon_case;
867 						break;
868 					default:
869 						state=URI_PARAM_P;
870 				}
871 				break;
872 				/* handle lr=something case */
873 			case PR2_eq:
874 				param=&uri->r2;
875 				param_val=&uri->r2_val;
876 				switch(*p){
877 					param_common_cases;
878 					default:
879 						v=p;
880 						state=URI_VAL_P;
881 				}
882 				break;
883 			/* gr */
884 			param_switch(PGR_G,  'r', 'R', PGR_R_FIN);
885 			case PGR_R_FIN:
886 				switch(*p){
887 					case '@':
888 						still_at_user;
889 						break;
890 					case '=':
891 						state=PGR_eq;
892 						break;
893 					semicolon_case;
894 						uri->gr.s=b;
895 						uri->gr.len=(p-b);
896 						break;
897 					question_case;
898 						uri->gr.s=b;
899 						uri->gr.len=(p-b);
900 						break;
901 					colon_case;
902 						break;
903 					default:
904 						state=URI_PARAM_P;
905 				}
906 				break;
907 				/* handle gr=something case */
908 			case PGR_eq:
909 				param=&uri->gr;
910 				param_val=&uri->gr_val;
911 				switch(*p){
912 					param_common_cases;
913 					default:
914 						v=p;
915 						state=URI_VAL_P;
916 				}
917 				break;
918 
919 #ifdef USE_COMP
920 			param_switch(PCOMP_C,  'o', 'O' , PCOMP_O);
921 			param_switch(PCOMP_O,  'm', 'M' , PCOMP_M);
922 			param_switch(PCOMP_M,  'p', 'P' , PCOMP_P);
923 			param_switch1(PCOMP_P,  '=', PCOMP_eq);
924 			/* value */
925 			case PCOMP_eq:
926 				param=&comp_str;
927 				param_val=&comp_val;
928 				switch (*p){
929 					param_common_cases;
930 					case 's':
931 					case 'S':
932 						v=p;
933 						state=VCOMP_S;
934 						break;
935 					default:
936 						v=p;
937 						state=URI_VAL_P;
938 				}
939 				break;
940 			/* sigcomp*/
941 			value_switch_big(VCOMP_S, 'i', 'I', 'e', 'E',
942 									VCOMP_SIGC_I, VCOMP_SGZ_E);
943 			value_switch(VCOMP_SIGC_I, 'g', 'G', VCOMP_SIGC_G);
944 			value_switch(VCOMP_SIGC_G, 'c', 'C', VCOMP_SIGC_C);
945 			value_switch(VCOMP_SIGC_C, 'o', 'O', VCOMP_SIGC_O);
946 			value_switch(VCOMP_SIGC_O, 'm', 'M', VCOMP_SIGC_M);
947 			value_switch(VCOMP_SIGC_M, 'p', 'P', VCOMP_SIGC_P_FIN);
948 			comp_fin(VCOMP_SIGC_P_FIN, COMP_SIGCOMP);
949 
950 			/* sergz*/
951 			value_switch(VCOMP_SGZ_E, 'r', 'R', VCOMP_SGZ_R);
952 			value_switch(VCOMP_SGZ_R, 'g', 'G', VCOMP_SGZ_G);
953 			value_switch(VCOMP_SGZ_G, 'z', 'Z', VCOMP_SGZ_Z_FIN);
954 			comp_fin(VCOMP_SGZ_Z_FIN, COMP_SERGZ);
955 #endif
956 
957 
958 			case URI_HEADERS:
959 				/* for now nobody needs them so we completely ignore the
960 				 * headers (they are not allowed in request uri) --andrei */
961 				switch(*p){
962 					case '@':
963 						/* yak, we are still at user */
964 						still_at_user;
965 						break;
966 					case ';':
967 						/* we might be still parsing user, try it */
968 						if (found_user) goto error_bad_char;
969 						error_headers=1; /* if this is not the user
970 											we have an error */
971 						/* if pass is set => it cannot be user:pass
972 						 * => error (';') is illegal in a header */
973 						if (pass) goto error_headers;
974 						break;
975 					case ':':
976 						if (found_user==0){
977 							/*might be pass but only if user not found yet*/
978 							if (pass){
979 								found_user=1; /* no user */
980 								pass=0;
981 							}else{
982 								pass=p;
983 							}
984 						}
985 						break;
986 					case '?':
987 						if (pass){
988 							found_user=1; /* no user, pass cannot contain '?'*/
989 							pass=0;
990 						}
991 						break;
992 				}
993 				break;
994 			default:
995 				goto error_bug;
996 		}
997 	}
998 	/*end of uri */
999 	switch (state){
1000 		case URI_INIT: /* error empty uri */
1001 			goto error_too_short;
1002 		case URI_USER:
1003 			/* this is the host, it can't be the user */
1004 			if (found_user) goto error_bad_uri;
1005 			uri->host.s=s;
1006 			uri->host.len=p-s;
1007 			state=URI_HOST;
1008 			break;
1009 		case URI_PASSWORD:
1010 			/* this is the port, it can't be the passwd */
1011 			if (found_user) goto error_bad_port;
1012 			uri->port.s=s;
1013 			uri->port.len=p-s;
1014 			uri->port_no=port_no;
1015 			uri->host=uri->user;
1016 			uri->user.s=0;
1017 			uri->user.len=0;
1018 			break;
1019 		case URI_PASSWORD_ALPHA:
1020 			/* it might be an urn, check scheme and set host */
1021 			if (scheme==URN_SCH){
1022 				uri->host.s=s;
1023 				uri->host.len=p-s;
1024 				LM_DBG("parsed urn scheme with host: %.*s\n",
1025 						uri->host.len, uri->host.s);
1026 			/* this is the port, it can't be the passwd */
1027 			}else goto error_bad_port;
1028 			break;
1029 		case URI_HOST_P:
1030 		case URI_HOST6_END:
1031 			uri->host.s=s;
1032 			uri->host.len=p-s;
1033 			break;
1034 		case URI_HOST: /* error: null host */
1035 		case URI_HOST6_P: /* error: unterminated ipv6 reference*/
1036 			goto error_bad_host;
1037 		case URI_PORT:
1038 			uri->port.s=s;
1039 			uri->port.len=p-s;
1040 			uri->port_no=port_no;
1041 			break;
1042 		case URI_PARAM:
1043 		case URI_PARAM_P:
1044 		/* intermediate param states */
1045 		case PT_T: /* transport */
1046 		case PT_R:
1047 		case PT_A:
1048 		case PT_N:
1049 		case PT_S:
1050 		case PT_P:
1051 		case PT_O:
1052 		case PT_R2:
1053 		case PT_T2:
1054 		case PT_eq: /* ignore empty transport params */
1055 		case PTTL_T2: /* ttl */
1056 		case PTTL_L:
1057 		case PTTL_eq:
1058 		case PU_U:  /* user */
1059 		case PU_S:
1060 		case PU_E:
1061 		case PU_R:
1062 		case PU_eq:
1063 		case PM_M: /* method */
1064 		case PM_E:
1065 		case PM_T:
1066 		case PM_H:
1067 		case PM_O:
1068 		case PM_D:
1069 		case PM_eq:
1070 		case PLR_L: /* lr */
1071 		case PR2_R: /* r2 */
1072 		case PGR_G: /* gr */
1073 #ifdef USE_COMP
1074 		case PCOMP_C:
1075 		case PCOMP_O:
1076 		case PCOMP_M:
1077 		case PCOMP_P:
1078 		case PCOMP_eq:
1079 #endif
1080 			uri->params.s=s;
1081 			uri->params.len=p-s;
1082 			break;
1083 		/* fin param states */
1084 		case PLR_R_FIN:
1085 		case PLR_eq:
1086 			uri->params.s=s;
1087 			uri->params.len=p-s;
1088 			uri->lr.s=b;
1089 			uri->lr.len=p-b;
1090 			break;
1091 		case PR2_2_FIN:
1092 		case PR2_eq:
1093 			uri->params.s=s;
1094 			uri->params.len=p-s;
1095 			uri->r2.s=b;
1096 			uri->r2.len=p-b;
1097 			break;
1098 		case PGR_R_FIN:
1099 		case PGR_eq:
1100 			uri->params.s=s;
1101 			uri->params.len=p-s;
1102 			uri->gr.s=b;
1103 			uri->gr.len=p-b;
1104 			break;
1105 		case URI_VAL_P:
1106 		/* intermediate value states */
1107 		case VU_U:
1108 		case VU_D:
1109 		case VT_T:
1110 		case VT_C:
1111 		case VTLS_L:
1112 		case VS_S:
1113 		case VS_C:
1114 		case VS_T:
1115 		case VW_W:
1116 			uri->params.s=s;
1117 			uri->params.len=p-s;
1118 			param_set(b, v);
1119 			break;
1120 #ifdef USE_COMP
1121 		case VCOMP_S:
1122 		case VCOMP_SIGC_I:
1123 		case VCOMP_SIGC_G:
1124 		case VCOMP_SIGC_C:
1125 		case VCOMP_SIGC_O:
1126 		case VCOMP_SIGC_M:
1127 		case VCOMP_SGZ_E:
1128 		case VCOMP_SGZ_R:
1129 		case VCOMP_SGZ_G:
1130 			/* unrecognized comp method, assume none */
1131 			uri->params.s=s;
1132 			uri->params.len=p-s;
1133 			/* uri->comp=COMP_NONE ; */
1134 			break;
1135 #endif
1136 		/* fin value states */
1137 		case VU_P_FIN:
1138 			uri->params.s=s;
1139 			uri->params.len=p-s;
1140 			param_set(b, v);
1141 			uri->proto=PROTO_UDP;
1142 			break;
1143 		case VT_P_FIN:
1144 			uri->params.s=s;
1145 			uri->params.len=p-s;
1146 			param_set(b, v);
1147 			uri->proto=PROTO_TCP;
1148 			break;
1149 		case VTLS_S_FIN:
1150 			uri->params.s=s;
1151 			uri->params.len=p-s;
1152 			param_set(b, v);
1153 			uri->proto=PROTO_TLS;
1154 			break;
1155 		case VS_P_FIN:
1156 			uri->params.s=s;
1157 			uri->params.len=p-s;
1158 			param_set(b, v);
1159 			uri->proto=PROTO_SCTP;
1160 			break;
1161 		case VW_S_FIN:
1162 			uri->params.s=s;
1163 			uri->params.len=p-s;
1164 			param_set(b, v);
1165 			uri->proto=PROTO_WS;
1166 			break;
1167 #ifdef USE_COMP
1168 		case VCOMP_SIGC_P_FIN:
1169 			uri->params.s=s;
1170 			uri->params.len=p-s;
1171 			/* param_set(b, v); */
1172 			uri->comp=COMP_SIGCOMP;
1173 			break;
1174 		case VCOMP_SGZ_Z_FIN:
1175 			uri->params.s=s;
1176 			uri->params.len=p-s;
1177 			/* param_set(b, v); */
1178 			uri->comp=COMP_SERGZ;
1179 			break;
1180 #endif
1181 		/* headers */
1182 		case URI_HEADERS:
1183 			uri->headers.s=s;
1184 			uri->headers.len=p-s;
1185 			if (error_headers) goto error_headers;
1186 			break;
1187 		default:
1188 			goto error_bug;
1189 	}
1190 	switch(uri->type){
1191 		case SIPS_URI_T:
1192 		case SIP_URI_T:
1193 			/* save the original sip: URI parameters in sip_params */
1194 			uri->sip_params=uri->params;
1195 			if ((phone2tel) &&
1196 					(uri->user_param_val.len == 5) &&
1197 					(strncmp(uri->user_param_val.s, "phone", 5) == 0)
1198 				) {
1199 				uri->type = TEL_URI_T;
1200 				uri->flags |= URI_SIP_USER_PHONE;
1201 				/* move params from user into uri->params */
1202 				p=q_memchr(uri->user.s, ';', uri->user.len);
1203 				if (p){
1204 					/* NOTE:
1205 					 * specialized uri params (user, maddr, etc.) still hold
1206 					 * the values from the sip-uri envelope
1207 					 * while uri->params point to the params in the embedded tel uri
1208 					 */
1209 					uri->params.s=p+1;
1210 					uri->params.len=uri->user.s+uri->user.len-uri->params.s;
1211 					uri->user.len=p-uri->user.s;
1212 				} else {
1213 					uri->params.s=0;
1214 					uri->params.len=0;
1215 				}
1216 			} else {
1217 				uri->flags&=~URI_USER_NORMALIZE;
1218 			}
1219 			break;
1220 		case TEL_URI_T:
1221 		case TELS_URI_T:
1222 			/* fix tel uris, move the number in uri and empty the host */
1223 			uri->user=uri->host;
1224 			uri->host=_sr_uri_empty;
1225 			break;
1226 		/* urn: do nothing */
1227 		case URN_URI_T:
1228 			break;
1229 		case ERROR_URI_T:
1230 			LM_ERR("parse uri unexpected error (BUG?)\n");
1231 			goto error_bad_uri;
1232 			break; /* do nothing, avoids a compilation warning */
1233 	}
1234 
1235 	if(uri->port.len>5)
1236 		goto error_invalid_port;
1237 
1238 #ifdef EXTRA_DEBUG
1239 	/* do stuff */
1240 	LM_DBG("parsed uri:\n type=%d user=<%.*s>(%d)\n passwd=<%.*s>(%d)\n"
1241 			" host=<%.*s>(%d)\n port=<%.*s>(%d): %d\n params=<%.*s>(%d)\n"
1242 			" headers=<%.*s>(%d)\n",
1243 			uri->type,
1244 			uri->user.len, ZSW(uri->user.s), uri->user.len,
1245 			uri->passwd.len, ZSW(uri->passwd.s), uri->passwd.len,
1246 			uri->host.len, ZSW(uri->host.s), uri->host.len,
1247 			uri->port.len, ZSW(uri->port.s), uri->port.len, uri->port_no,
1248 			uri->params.len, ZSW(uri->params.s), uri->params.len,
1249 			uri->headers.len, ZSW(uri->headers.s), uri->headers.len
1250 		);
1251 	LM_DBG(" uri flags : ");
1252 		if (uri->flags & URI_USER_NORMALIZE) LM_DBG("user_need_norm ");
1253 		if (uri->flags & URI_SIP_USER_PHONE) LM_DBG("sip_user_phone ");
1254 	LM_DBG("   value=%d\n",uri->flags);
1255 	LM_DBG(" uri params:\n   transport=<%.*s>, val=<%.*s>, proto=%d\n",
1256 			uri->transport.len, ZSW(uri->transport.s), uri->transport_val.len,
1257 			ZSW(uri->transport_val.s), uri->proto);
1258 	LM_DBG("   user-param=<%.*s>, val=<%.*s>\n",
1259 			uri->user_param.len, ZSW(uri->user_param.s),
1260 			uri->user_param_val.len, ZSW(uri->user_param_val.s));
1261 	LM_DBG("   method=<%.*s>, val=<%.*s>\n",
1262 			uri->method.len, ZSW(uri->method.s),
1263 			uri->method_val.len, ZSW(uri->method_val.s));
1264 	LM_DBG("   ttl=<%.*s>, val=<%.*s>\n",
1265 			uri->ttl.len, ZSW(uri->ttl.s),
1266 			uri->ttl_val.len, ZSW(uri->ttl_val.s));
1267 	LM_DBG("   maddr=<%.*s>, val=<%.*s>\n",
1268 			uri->maddr.len, ZSW(uri->maddr.s),
1269 			uri->maddr_val.len, ZSW(uri->maddr_val.s));
1270 	LM_DBG("   lr=<%.*s>\n", uri->lr.len, ZSW(uri->lr.s));
1271 	LM_DBG("   r2=<%.*s>\n", uri->r2.len, ZSW(uri->r2.s));
1272 #ifdef USE_COMP
1273 	LM_DBG("   comp=%d\n", uri->comp);
1274 #endif
1275 
1276 #endif
1277 	return 0;
1278 
1279 error_too_short:
1280 	LM_DBG("uri too short: <%.*s> (%d)\n",
1281 		len, ZSW(buf), len);
1282 	goto error_exit;
1283 error_bad_char:
1284 	LM_DBG("bad char '%c' in state %d"
1285 		" parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1286 		*p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
1287 		len, ZSW(buf), len);
1288 	goto error_exit;
1289 error_bad_host:
1290 	LM_DBG("bad host in uri (error at char %c in"
1291 		" state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
1292 		*p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
1293 		len, ZSW(buf), len);
1294 	goto error_exit;
1295 error_bad_port:
1296 	LM_DBG("bad port in uri (error at char %c in"
1297 		" state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
1298 		*p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
1299 		len, ZSW(buf), len);
1300 	goto error_exit;
1301 error_invalid_port:
1302 	LM_DBG("bad port in uri: [%.*s] in <%.*s>\n",
1303 			uri->port.len, uri->port.s, len, ZSW(buf));
1304 	goto error_exit;
1305 error_bad_uri:
1306 	LM_DBG("bad uri,  state %d parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1307 		state, (int)(p-buf), ZSW(buf), (int)(p-buf), len,
1308 		ZSW(buf), len);
1309 	goto error_exit;
1310 error_headers:
1311 	LM_DBG("bad uri headers: <%.*s>(%d) / <%.*s>(%d)\n",
1312 		uri->headers.len, ZSW(uri->headers.s), uri->headers.len,
1313 		len, ZSW(buf), len);
1314 	goto error_exit;
1315 error_bug:
1316 	LM_CRIT("BUG: bad  state %d parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1317 			state, (int)(p-buf), ZSW(buf), (int)(p-buf), len, ZSW(buf), len);
1318 error_exit:
1319 	ser_error=E_BAD_URI;
1320 	uri->type=ERROR_URI_T;
1321 	STATS_BAD_URI();
1322 	return E_BAD_URI;
1323 }
1324 
1325 
_parse_ruri(str * uri,int * status,struct sip_uri * parsed_uri)1326 static inline int _parse_ruri(str *uri,
1327 	int *status, struct sip_uri *parsed_uri)
1328 {
1329 	if (*status) return 1;
1330 
1331 	if (parse_uri(uri->s, uri->len, parsed_uri)<0) {
1332 		LM_ERR("bad uri <%.*s>\n", uri->len, ZSW(uri->s));
1333 		*status=0;
1334 		return -1;
1335 	}
1336 	*status=1;
1337 	return 1;
1338 }
1339 
parse_sip_msg_uri(struct sip_msg * msg)1340 int parse_sip_msg_uri(struct sip_msg* msg)
1341 {
1342 	char* tmp;
1343 	int tmp_len;
1344 	if (msg->parsed_uri_ok) return 1;
1345 
1346 	if (msg->new_uri.s){
1347 		tmp=msg->new_uri.s;
1348 		tmp_len=msg->new_uri.len;
1349 	}else{
1350 		tmp=msg->first_line.u.request.uri.s;
1351 		tmp_len=msg->first_line.u.request.uri.len;
1352 	}
1353 	if (parse_uri(tmp, tmp_len, &msg->parsed_uri)<0){
1354 		LM_DBG("bad uri <%.*s>\n", tmp_len, tmp);
1355 		msg->parsed_uri_ok=0;
1356 		return -1;
1357 	}
1358 	msg->parsed_uri_ok=1;
1359 	return 1;
1360 }
1361 
parse_orig_ruri(struct sip_msg * msg)1362 int parse_orig_ruri(struct sip_msg* msg)
1363 {
1364 	int ret;
1365 
1366 	ret=_parse_ruri(&REQ_LINE(msg).uri,
1367 		&msg->parsed_orig_ruri_ok, &msg->parsed_orig_ruri);
1368 	if (ret<0) LM_ERR("parse orig ruri failed\n");
1369 	return ret;
1370 }
1371 
normalize_tel_user(char * res,str * src)1372 int normalize_tel_user(char* res, str* src)
1373 {
1374 	int i, l;
1375 	l=0;
1376 	for (i=0; i<src->len; i++) {
1377 		switch (src->s[i]) {
1378 			case '-':
1379 			case '.':
1380 			case '(':
1381 			case ')':
1382 				break;
1383 			default:
1384 				res[l++]=src->s[i];
1385 		}
1386 	}
1387 	return l;
1388 }
1389 
1390 
1391 str	s_sip  = STR_STATIC_INIT("sip");
1392 str	s_sips = STR_STATIC_INIT("sips");
1393 str	s_tel  = STR_STATIC_INIT("tel");
1394 str	s_tels = STR_STATIC_INIT("tels");
1395 str	s_urn  = STR_STATIC_INIT("urn");
1396 static str	s_null = STR_STATIC_INIT("");
1397 
uri_type_to_str(uri_type type,str * s)1398 void uri_type_to_str(uri_type type, str *s) {
1399 	switch (type) {
1400 	case SIP_URI_T:
1401 		*s = s_sip;
1402 		break;
1403 	case SIPS_URI_T:
1404 		*s = s_sips;
1405 		break;
1406 	case TEL_URI_T:
1407 		*s = s_tel;
1408 		break;
1409 	case TELS_URI_T:
1410 		*s = s_tels;
1411 		break;
1412 	case URN_URI_T:
1413 		*s = s_urn;
1414 		break;
1415 	default:
1416 		*s = s_null;
1417 	}
1418 }
1419 
1420 static str	s_udp  = STR_STATIC_INIT("udp");
1421 static str	s_tcp  = STR_STATIC_INIT("tcp");
1422 static str	s_tls  = STR_STATIC_INIT("tls");
1423 static str	s_sctp = STR_STATIC_INIT("sctp");
1424 static str	s_ws   = STR_STATIC_INIT("ws");
1425 
proto_type_to_str(unsigned short type,str * s)1426 void proto_type_to_str(unsigned short type, str *s) {
1427 	switch (type) {
1428 	case PROTO_UDP:
1429 		*s = s_udp;
1430 		break;
1431 	case PROTO_TCP:
1432 		*s = s_tcp;
1433 		break;
1434 	case PROTO_TLS:
1435 		*s = s_tls;
1436 		break;
1437 	case PROTO_SCTP:
1438 		*s = s_sctp;
1439 		break;
1440 	case PROTO_WS:
1441 	case PROTO_WSS:
1442 		*s = s_ws;
1443 		break;
1444 	default:
1445 		*s = s_null;
1446 	}
1447 }
1448