1 /*
2  * via parsing automaton
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * This file is part of Kamailio, a free SIP server.
7  *
8  * Kamailio is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * Kamailio is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22 
23 /** @file
24  * @brief Parser :: Via parsing automation
25  *
26  * @ingroup parser
27  */
28 
29 #include "../comp_defs.h"
30 #include <stdlib.h>
31 #include <string.h>
32 #include "../dprint.h"
33 #include "../ut.h"
34 #include "../mem/mem.h"
35 #include "../ip_addr.h"
36 #include "parse_via.h"
37 #include "parse_def.h"
38 #include "msg_parser.h"
39 
40 
41 /** \brief main via states (uri:port ...) */
42 enum
43 {
44 	F_HOST,
45 	P_HOST,
46 	L_PORT,
47 	F_PORT,
48 	P_PORT,
49 	L_PARAM,
50 	F_PARAM,
51 	P_PARAM,
52 	L_VIA,
53 	F_VIA,
54 	F_COMMENT,
55 	P_COMMENT,
56 	F_IP6HOST,
57 	P_IP6HOST,
58 	F_CRLF,
59 	F_LF,
60 	F_CR,
61 	END_OF_HEADER
62 };
63 
64 
65 /** \brief first via part state */
66 enum
67 {
68 	F_SIP = 100,
69 	SIP1,
70 	SIP2,
71 	FIN_SIP,
72 	L_VER,
73 	F_VER,
74 	VER1,
75 	VER2,
76 	FIN_VER,
77 	UDP1,
78 	UDP2,
79 	FIN_UDP,
80 	TCP_TLS1,
81 	TCP2,
82 	FIN_TCP,
83 	TLS2,
84 	FIN_TLS,
85 	SCTP1,
86 	SCTP2,
87 	SCTP3,
88 	FIN_SCTP,
89 	WS_WSS1,
90 	WS_WSS2,
91 	FIN_WSS,
92 	OTHER_PROTO,
93 	L_PROTO,
94 	F_PROTO
95 };
96 
97 
98 /** \brief param related states
99  * WARNING: keep in sync with parse_via.h, PARAM_HIDDEN, ...
100  */
101 enum
102 {
103 	L_VALUE = 200,
104 	F_VALUE,
105 	P_VALUE,
106 	P_STRING,
107 	HIDDEN1,
108 	HIDDEN2,
109 	HIDDEN3,
110 	HIDDEN4,
111 	HIDDEN5,
112 	TTL1,
113 	TTL2,
114 	BRANCH1,
115 	BRANCH2,
116 	BRANCH3,
117 	BRANCH4,
118 	BRANCH5,
119 	MADDR1,
120 	MADDR2,
121 	MADDR3,
122 	MADDR4,
123 	RECEIVED1,
124 	RECEIVED2,
125 	RECEIVED3,
126 	RECEIVED4,
127 	RECEIVED5,
128 	RECEIVED6,
129 	RECEIVED7,
130 	RPORT1,
131 	RPORT2,
132 	RPORT3,
133 	ALIAS1,
134 	ALIAS2,
135 	ALIAS3,
136 	ALIAS4,
137 #ifdef USE_COMP
138 	COMP1,
139 	COMP2,
140 	COMP3,
141 	/* values */
142 	L_COMP_VALUE,
143 	F_COMP_VALUE,
144 	V_COMP_S,
145 	V_SIGCOMP_I,
146 	V_SIGCOMP_G,
147 	V_SIGCOMP_C,
148 	V_SIGCOMP_O,
149 	V_SIGCOMP_M,
150 	FIN_V_SIGCOMP_P,
151 	V_SERGZ_E,
152 	V_SERGZ_R,
153 	V_SERGZ_G,
154 	FIN_V_SERGZ_Z,
155 #endif
156 	/* fin states (227-...)*/
157 	FIN_HIDDEN = 230,
158 	FIN_TTL,
159 	FIN_BRANCH,
160 	FIN_MADDR,
161 	FIN_RECEIVED,
162 	FIN_RPORT,
163 	FIN_I,
164 	FIN_ALIAS
165 #ifdef USE_COMP
166 	,
167 	FIN_COMP
168 #endif
169 	/*GEN_PARAM,
170 	PARAM_ERROR*/ /* declared in msg_parser.h*/
171 };
172 
173 
174 /* entry state must be F_PARAM, or saved_state=F_PARAM and
175  * state=F_{LF,CR,CRLF}!
176  * output state = L_PARAM or F_PARAM or END_OF_HEADER
177  * (and saved_state= last state); everything else => error
178  * WARNING: param->start must be filled before, it's used in param->size
179  * computation.
180  */
parse_via_param(char * const p,const char * const end,unsigned char * const pstate,unsigned char * const psaved_state,struct via_param * const param,const struct via_body * vb)181 static /*inline*/ char *parse_via_param(char *const p, const char *const end,
182 		unsigned char *const pstate, unsigned char *const psaved_state,
183 		struct via_param *const param, const struct via_body *vb)
184 {
185 	char *tmp;
186 	register unsigned char state;
187 	unsigned char saved_state;
188 
189 #define value_case(c, C, oldstate, newstate, start_of_value) \
190 	case(c):                                                 \
191 	case(C):                                                 \
192 		switch(state) {                                      \
193 			case(oldstate):                                  \
194 				state = (newstate);                          \
195 				if((start_of_value))                         \
196 					param->value.s = tmp;                    \
197 				break;                                       \
198 				default_value_cases                          \
199 		}                                                    \
200 		break
201 
202 #define value_case_double(c, C, oldstate1, newstate1, oldstate2, newstate2) \
203 	case(c):                                                                \
204 	case(C):                                                                \
205 		switch(state) {                                                     \
206 			case(oldstate1):                                                \
207 				state = (newstate1);                                        \
208 				break;                                                      \
209 			case(oldstate2):                                                \
210 				state = (newstate2);                                        \
211 				break;                                                      \
212 				default_value_cases                                         \
213 		}                                                                   \
214 		break
215 
216 #define default_value_cases                                                   \
217 	case F_VALUE:                                                             \
218 		state = P_VALUE;                                                      \
219 		param->value.s = tmp;                                                 \
220 		break;                                                                \
221 	case P_VALUE:                                                             \
222 	case P_STRING:                                                            \
223 		break;                                                                \
224 	case F_LF:                                                                \
225 	case F_CR:                                                                \
226 	case F_CRLF:                                                              \
227 		state = END_OF_HEADER;                                                \
228 		goto end_via;                                                         \
229 	default:                                                                  \
230 		switch(state) {                                                       \
231 			case F_COMP_VALUE:                                                \
232 				comp_unexpected_char;                                         \
233 				state = P_VALUE;                                              \
234 				param->value.s = tmp;                                         \
235 				break;                                                        \
236 				comp_states_cases comp_fin_states_cases comp_unexpected_char; \
237 				state = P_VALUE;                                              \
238 				break;                                                        \
239 			default:                                                          \
240 				LM_ERR("invalid "                                             \
241 						"char <%c> in state %d\n",                            \
242 						*tmp, state);                                         \
243 				goto error;                                                   \
244 		}
245 
246 #define comp_states_cases \
247 	case V_COMP_S:        \
248 	case V_SIGCOMP_I:     \
249 	case V_SIGCOMP_G:     \
250 	case V_SIGCOMP_C:     \
251 	case V_SIGCOMP_O:     \
252 	case V_SIGCOMP_M:     \
253 	case V_SERGZ_E:       \
254 	case V_SERGZ_R:       \
255 	case V_SERGZ_G:
256 
257 #define comp_fin_states_cases \
258 	case FIN_V_SIGCOMP_P:     \
259 	case FIN_V_SERGZ_Z:
260 
261 
262 /* if unrecognized/bad comp, don't return error, just ignore comp */
263 #define comp_unexpected_char                  \
264 	LM_ERR("bad/unrecognized comp method\n"); \
265 	vb->comp_no = 0
266 
267 
268 	state = *pstate;
269 	saved_state = *psaved_state;
270 	param->type = PARAM_ERROR;
271 
272 	for(tmp = p; tmp < end; tmp++) {
273 		switch(*tmp) {
274 			case ' ':
275 			case '\t':
276 				switch(state) {
277 					case FIN_HIDDEN:
278 					case FIN_ALIAS:
279 						param->type = state;
280 						param->name.len = tmp - param->name.s;
281 						state = L_PARAM;
282 						goto endofparam;
283 					case FIN_BRANCH:
284 					case FIN_TTL:
285 					case FIN_MADDR:
286 					case FIN_RECEIVED:
287 					case FIN_RPORT:
288 					case FIN_I:
289 						param->type = state;
290 						param->name.len = tmp - param->name.s;
291 						state = L_VALUE;
292 						goto find_value;
293 #ifdef USE_COMP
294 					case FIN_COMP:
295 						param->type = state;
296 						param->name.len = tmp - param->name.s;
297 						state = L_COMP_VALUE;
298 						goto find_value;
299 #endif
300 					case F_PARAM:
301 						break;
302 					case F_LF:
303 					case F_CR:
304 					case F_CRLF:
305 						state = saved_state;
306 						break;
307 					case GEN_PARAM:
308 					default:
309 						param->type = GEN_PARAM;
310 						param->name.len = tmp - param->name.s;
311 						state = L_VALUE;
312 						goto find_value;
313 				}
314 				break;
315 			/* \n and \r*/
316 			case '\n':
317 				switch(state) {
318 					case FIN_HIDDEN:
319 					case FIN_ALIAS:
320 						param->type = state;
321 						param->name.len = tmp - param->name.s;
322 						param->size = tmp - param->start;
323 						saved_state = L_PARAM;
324 						state = F_LF;
325 						goto endofparam;
326 					case FIN_BRANCH:
327 					case FIN_TTL:
328 					case FIN_MADDR:
329 					case FIN_RECEIVED:
330 					case FIN_I:
331 					case FIN_RPORT:
332 						param->type = state;
333 						param->name.len = tmp - param->name.s;
334 						param->size = tmp - param->start;
335 						saved_state = L_VALUE;
336 						state = F_LF;
337 						goto find_value;
338 #ifdef USE_COMP
339 					case FIN_COMP:
340 						param->type = state;
341 						param->name.len = tmp - param->name.s;
342 						param->size = tmp - param->start;
343 						saved_state = L_COMP_VALUE;
344 						state = F_LF;
345 						goto find_value;
346 #endif
347 					case F_PARAM:
348 						saved_state = state;
349 						state = F_LF;
350 						break;
351 					case F_LF:
352 					case F_CRLF:
353 						state = END_OF_HEADER;
354 						goto end_via;
355 					case F_CR:
356 						state = F_CRLF;
357 						break;
358 					case GEN_PARAM:
359 					default:
360 						param->type = GEN_PARAM;
361 						saved_state = L_VALUE;
362 						param->name.len = tmp - param->name.s;
363 						param->size = tmp - param->start;
364 						state = F_LF;
365 						goto find_value;
366 				}
367 				break;
368 			case '\r':
369 				switch(state) {
370 					case FIN_HIDDEN:
371 					case FIN_ALIAS:
372 						param->type = state;
373 						param->name.len = tmp - param->name.s;
374 						param->size = tmp - param->start;
375 						saved_state = L_PARAM;
376 						state = F_CR;
377 						goto endofparam;
378 					case FIN_BRANCH:
379 					case FIN_TTL:
380 					case FIN_MADDR:
381 					case FIN_RECEIVED:
382 					case FIN_I:
383 					case FIN_RPORT:
384 						param->type = state;
385 						param->name.len = tmp - param->name.s;
386 						param->size = tmp - param->start;
387 						saved_state = L_VALUE;
388 						state = F_CR;
389 						goto find_value;
390 #ifdef USE_COMP
391 					case FIN_COMP:
392 						param->type = state;
393 						param->name.len = tmp - param->name.s;
394 						param->size = tmp - param->start;
395 						saved_state = L_COMP_VALUE;
396 						state = F_LF;
397 						goto find_value;
398 #endif
399 					case F_PARAM:
400 						saved_state = state;
401 						state = F_CR;
402 						break;
403 					case F_CR:
404 					case F_CRLF:
405 						state = END_OF_HEADER;
406 						goto end_via;
407 					case GEN_PARAM:
408 					default:
409 						param->type = GEN_PARAM;
410 						param->name.len = tmp - param->name.s;
411 						param->size = tmp - param->start;
412 						saved_state = L_VALUE;
413 						state = F_CR;
414 						goto find_value;
415 				}
416 				break;
417 
418 			case '=':
419 				switch(state) {
420 					case FIN_BRANCH:
421 					case FIN_TTL:
422 					case FIN_MADDR:
423 					case FIN_RECEIVED:
424 					case FIN_RPORT:
425 					case FIN_I:
426 						param->type = state;
427 						param->name.len = tmp - param->name.s;
428 						state = F_VALUE;
429 						goto find_value;
430 #ifdef USE_COMP
431 					case FIN_COMP:
432 						param->type = state;
433 						param->name.len = tmp - param->name.s;
434 						state = F_COMP_VALUE;
435 						goto find_value;
436 #endif
437 					case F_PARAM:
438 					case FIN_HIDDEN:
439 					case FIN_ALIAS:
440 						LM_ERR("invalid char <%c> in state %d\n", *tmp, state);
441 						goto error;
442 					case F_CR:
443 					case F_LF:
444 					case F_CRLF:
445 						state = END_OF_HEADER;
446 						goto end_via;
447 					case GEN_PARAM:
448 					default:
449 						param->type = GEN_PARAM;
450 						param->name.len = tmp - param->name.s;
451 						state = F_VALUE;
452 						goto find_value;
453 				}
454 				break;
455 			case ';':
456 				switch(state) {
457 					case FIN_HIDDEN:
458 					case FIN_RPORT: /* rport can appear w/o a value */
459 					case FIN_ALIAS:
460 						param->type = state;
461 						param->name.len = tmp - param->name.s;
462 						state = F_PARAM;
463 						goto endofparam;
464 					case FIN_BRANCH:
465 					case FIN_MADDR:
466 					case FIN_TTL:
467 					case FIN_RECEIVED:
468 					case FIN_I:
469 #ifdef USE_COMP
470 					case FIN_COMP:
471 #endif
472 						LM_ERR("invalid char <%c> in state %d\n", *tmp, state);
473 						goto error;
474 					case F_CR:
475 					case F_LF:
476 					case F_CRLF:
477 						state = END_OF_HEADER;
478 						goto end_via;
479 					case GEN_PARAM:
480 					default:
481 						param->type = GEN_PARAM;
482 						param->name.len = tmp - param->name.s;
483 						state = F_PARAM;
484 						goto endofparam;
485 				}
486 				break;
487 			case ',':
488 				switch(state) {
489 					case FIN_HIDDEN:
490 					case FIN_RPORT:
491 					case FIN_ALIAS:
492 						param->type = state;
493 						param->name.len = tmp - param->name.s;
494 						state = F_VIA;
495 						goto endofvalue;
496 					case FIN_BRANCH:
497 					case FIN_MADDR:
498 					case FIN_TTL:
499 					case FIN_RECEIVED:
500 					case FIN_I:
501 #ifdef USE_COMP
502 					case FIN_COMP:
503 #endif
504 						LM_ERR("new via found"
505 								"(',') when '=' expected (state %d=)\n",
506 								state);
507 						goto error; /* or we could ignore this bad param*/
508 					case F_CR:
509 					case F_LF:
510 					case F_CRLF:
511 						state = END_OF_HEADER;
512 						goto end_via;
513 					case GEN_PARAM:
514 					default:
515 						param->type = GEN_PARAM;
516 						param->name.len = tmp - param->name.s;
517 						state = F_VIA;
518 						goto endofvalue;
519 				}
520 				break;
521 
522 			/* param names */
523 			case 'h':
524 			case 'H':
525 				switch(state) {
526 					case F_PARAM:
527 						state = HIDDEN1;
528 						param->name.s = tmp;
529 						break;
530 					case BRANCH5:
531 						state = FIN_BRANCH;
532 						break;
533 					case GEN_PARAM:
534 						break;
535 					case F_CR:
536 					case F_LF:
537 					case F_CRLF:
538 						state = END_OF_HEADER;
539 						goto end_via;
540 					default:
541 						state = GEN_PARAM;
542 				}
543 				break;
544 			case 'i':
545 			case 'I':
546 				switch(state) {
547 					case F_PARAM:
548 						state = FIN_I;
549 						param->name.s = tmp;
550 						break;
551 					case HIDDEN1:
552 						state = HIDDEN2;
553 						break;
554 					case RECEIVED4:
555 						state = RECEIVED5;
556 						break;
557 					case ALIAS2:
558 						state = ALIAS3;
559 						break;
560 					case GEN_PARAM:
561 						break;
562 					case F_CR:
563 					case F_LF:
564 					case F_CRLF:
565 						state = END_OF_HEADER;
566 						goto end_via;
567 					default:
568 						state = GEN_PARAM;
569 				}
570 				break;
571 			case 'd':
572 			case 'D':
573 				switch(state) {
574 					case F_PARAM:
575 						state = GEN_PARAM;
576 						param->name.s = tmp;
577 						break;
578 					case HIDDEN2:
579 						state = HIDDEN3;
580 						break;
581 					case HIDDEN3:
582 						state = HIDDEN4;
583 						break;
584 					case MADDR2:
585 						state = MADDR3;
586 						break;
587 					case MADDR3:
588 						state = MADDR4;
589 						break;
590 					case RECEIVED7:
591 						state = FIN_RECEIVED;
592 						break;
593 					case GEN_PARAM:
594 						break;
595 					case F_CR:
596 					case F_LF:
597 					case F_CRLF:
598 						state = END_OF_HEADER;
599 						goto end_via;
600 					default:
601 						state = GEN_PARAM;
602 				}
603 				break;
604 			case 'e':
605 			case 'E':
606 				switch(state) {
607 					case F_PARAM:
608 						state = GEN_PARAM;
609 						param->name.s = tmp;
610 						break;
611 					case HIDDEN4:
612 						state = HIDDEN5;
613 						break;
614 					case RECEIVED1:
615 						state = RECEIVED2;
616 						break;
617 					case RECEIVED3:
618 						state = RECEIVED4;
619 						break;
620 					case RECEIVED6:
621 						state = RECEIVED7;
622 						break;
623 					case GEN_PARAM:
624 						break;
625 					case F_CR:
626 					case F_LF:
627 					case F_CRLF:
628 						state = END_OF_HEADER;
629 						goto end_via;
630 					default:
631 						state = GEN_PARAM;
632 				}
633 				break;
634 			case 'n':
635 			case 'N':
636 				switch(state) {
637 					case F_PARAM:
638 						state = GEN_PARAM;
639 						param->name.s = tmp;
640 						break;
641 					case HIDDEN5:
642 						state = FIN_HIDDEN;
643 						break;
644 					case BRANCH3:
645 						state = BRANCH4;
646 						break;
647 					case GEN_PARAM:
648 						break;
649 					case F_CR:
650 					case F_LF:
651 					case F_CRLF:
652 						state = END_OF_HEADER;
653 						goto end_via;
654 					default:
655 						state = GEN_PARAM;
656 				}
657 				break;
658 			case 't':
659 			case 'T':
660 				switch(state) {
661 					case F_PARAM:
662 						state = TTL1;
663 						param->name.s = tmp;
664 						break;
665 					case TTL1:
666 						state = TTL2;
667 						break;
668 					case RPORT3:
669 						state = FIN_RPORT;
670 						break;
671 					case GEN_PARAM:
672 						break;
673 					case F_CR:
674 					case F_LF:
675 					case F_CRLF:
676 						state = END_OF_HEADER;
677 						goto end_via;
678 					default:
679 						state = GEN_PARAM;
680 				}
681 				break;
682 			case 'l':
683 			case 'L':
684 				switch(state) {
685 					case F_PARAM:
686 						state = GEN_PARAM;
687 						param->name.s = tmp;
688 						break;
689 					case TTL2:
690 						state = FIN_TTL;
691 						break;
692 					case ALIAS1:
693 						state = ALIAS2;
694 						break;
695 					case GEN_PARAM:
696 						break;
697 					case F_CR:
698 					case F_LF:
699 					case F_CRLF:
700 						state = END_OF_HEADER;
701 						goto end_via;
702 					default:
703 						state = GEN_PARAM;
704 				}
705 				break;
706 			case 'm':
707 			case 'M':
708 				switch(state) {
709 					case F_PARAM:
710 						state = MADDR1;
711 						param->name.s = tmp;
712 						break;
713 #ifdef USE_COMP
714 					case COMP2:
715 						state = COMP3;
716 						break;
717 #endif
718 					case GEN_PARAM:
719 						break;
720 					case F_CR:
721 					case F_LF:
722 					case F_CRLF:
723 						state = END_OF_HEADER;
724 						goto end_via;
725 					default:
726 						state = GEN_PARAM;
727 				}
728 				break;
729 			case 'a':
730 			case 'A':
731 				switch(state) {
732 					case F_PARAM:
733 						state = ALIAS1;
734 						param->name.s = tmp;
735 						break;
736 					case MADDR1:
737 						state = MADDR2;
738 						break;
739 					case BRANCH2:
740 						state = BRANCH3;
741 						break;
742 					case ALIAS3:
743 						state = ALIAS4;
744 						break;
745 					case GEN_PARAM:
746 						break;
747 					case F_CR:
748 					case F_LF:
749 					case F_CRLF:
750 						state = END_OF_HEADER;
751 						goto end_via;
752 					default:
753 						state = GEN_PARAM;
754 				}
755 				break;
756 			case 'r':
757 			case 'R':
758 				switch(state) {
759 					case MADDR4:
760 						state = FIN_MADDR;
761 						break;
762 					case F_PARAM:
763 						state = RECEIVED1;
764 						param->name.s = tmp;
765 						break;
766 					case BRANCH1:
767 						state = BRANCH2;
768 						break;
769 					case RPORT2:
770 						state = RPORT3;
771 						break;
772 					case GEN_PARAM:
773 						break;
774 					case F_CR:
775 					case F_LF:
776 					case F_CRLF:
777 						state = END_OF_HEADER;
778 						goto end_via;
779 					default:
780 						state = GEN_PARAM;
781 				}
782 				break;
783 			case 'c':
784 			case 'C':
785 				switch(state) {
786 					case F_PARAM:
787 #ifdef USE_COMP
788 						state = COMP1;
789 #else
790 						state = GEN_PARAM;
791 #endif
792 						param->name.s = tmp;
793 						break;
794 					case RECEIVED2:
795 						state = RECEIVED3;
796 						break;
797 					case BRANCH4:
798 						state = BRANCH5;
799 						break;
800 					case GEN_PARAM:
801 						break;
802 					case F_CR:
803 					case F_LF:
804 					case F_CRLF:
805 						state = END_OF_HEADER;
806 						goto end_via;
807 					default:
808 						state = GEN_PARAM;
809 				}
810 				break;
811 			case 'v':
812 			case 'V':
813 				switch(state) {
814 					case F_PARAM:
815 						state = GEN_PARAM;
816 						param->name.s = tmp;
817 						break;
818 					case RECEIVED5:
819 						state = RECEIVED6;
820 						break;
821 					case GEN_PARAM:
822 						break;
823 					case F_CR:
824 					case F_LF:
825 					case F_CRLF:
826 						state = END_OF_HEADER;
827 						goto end_via;
828 					default:
829 						state = GEN_PARAM;
830 				}
831 				break;
832 			case 'b':
833 			case 'B':
834 				switch(state) {
835 					case F_PARAM:
836 						state = BRANCH1;
837 						param->name.s = tmp;
838 						break;
839 					case GEN_PARAM:
840 						break;
841 					case F_CR:
842 					case F_LF:
843 					case F_CRLF:
844 						state = END_OF_HEADER;
845 						goto end_via;
846 					default:
847 						state = GEN_PARAM;
848 				}
849 				break;
850 			case 'p':
851 			case 'P':
852 				switch(state) {
853 					case F_PARAM:
854 						state = GEN_PARAM;
855 						param->name.s = tmp;
856 						break;
857 					case RECEIVED1:
858 						state = RPORT1;
859 						break;
860 #ifdef USE_COMP
861 					case COMP3:
862 						state = FIN_COMP;
863 						break;
864 #endif
865 					case F_CR:
866 					case F_LF:
867 					case F_CRLF:
868 						state = END_OF_HEADER;
869 						goto end_via;
870 					default:
871 						state = GEN_PARAM;
872 				}
873 				break;
874 			case 'o':
875 			case 'O':
876 				switch(state) {
877 					case F_PARAM:
878 						state = GEN_PARAM;
879 						param->name.s = tmp;
880 						break;
881 					case RPORT1:
882 						state = RPORT2;
883 						break;
884 #ifdef USE_COMP
885 					case COMP1:
886 						state = COMP2;
887 						break;
888 #endif
889 					case F_CR:
890 					case F_LF:
891 					case F_CRLF:
892 						state = END_OF_HEADER;
893 						goto end_via;
894 					default:
895 						state = GEN_PARAM;
896 				}
897 				break;
898 			case 's':
899 			case 'S':
900 				switch(state) {
901 					case F_PARAM:
902 						state = GEN_PARAM;
903 						param->name.s = tmp;
904 						break;
905 					case ALIAS4:
906 						state = FIN_ALIAS;
907 						break;
908 					case F_CR:
909 					case F_LF:
910 					case F_CRLF:
911 						state = END_OF_HEADER;
912 						goto end_via;
913 					default:
914 						state = GEN_PARAM;
915 				}
916 				break;
917 			default:
918 				switch(state) {
919 					case F_PARAM:
920 						state = GEN_PARAM;
921 						param->name.s = tmp;
922 						break;
923 					case GEN_PARAM:
924 						break;
925 					case F_CR:
926 					case F_LF:
927 					case F_CRLF:
928 						state = END_OF_HEADER;
929 						goto end_via;
930 					default:
931 						state = GEN_PARAM;
932 				}
933 		}
934 	} /* for tmp*/
935 
936 	/* end of packet? => error, no cr/lf,',' found!!!*/
937 	saved_state = state;
938 	state = END_OF_HEADER;
939 	goto error;
940 
941 find_value:
942 	tmp++;
943 	for(; *tmp; tmp++) {
944 		switch(*tmp) {
945 			case ' ':
946 			case '\t':
947 				switch(state) {
948 					case L_VALUE:
949 					case F_VALUE: /*eat space*/
950 						break;
951 					case P_VALUE:
952 						state = L_PARAM;
953 						param->value.len = tmp - param->value.s;
954 						goto endofvalue;
955 #ifdef USE_COMP
956 					case L_COMP_VALUE:
957 					case F_COMP_VALUE:
958 						break; /* eat space */
959 					case FIN_V_SIGCOMP_P:
960 						state = L_PARAM;
961 						param->value.len = tmp - param->value.s;
962 						vb->comp_no = COMP_SIGCOMP;
963 						goto endofvalue;
964 					case FIN_V_SERGZ_Z:
965 						state = L_PARAM;
966 						param->value.len = tmp - param->value.s;
967 						vb->comp_no = COMP_SIGCOMP;
968 						goto endofvalue;
969 						comp_states_cases state = L_PARAM;
970 						param->value.len = tmp - param->value.s;
971 						comp_unexpected_char;
972 						goto endofvalue;
973 #endif
974 					case P_STRING:
975 						break;
976 					case F_CR:
977 					case F_LF:
978 					case F_CRLF:
979 						state = saved_state;
980 						break;
981 					default:
982 						LM_ERR("invalid char <%c> in state %d\n", *tmp, state);
983 						goto error;
984 				}
985 				break;
986 			case '\n':
987 				switch(state) {
988 					case L_VALUE:
989 					case F_VALUE: /*eat space*/
990 #ifdef USE_COMP
991 					case L_COMP_VALUE:
992 					case F_COMP_VALUE:
993 #endif
994 					case P_STRING:
995 						saved_state = state;
996 						param->size = tmp - param->start;
997 						state = F_LF;
998 						break;
999 					case P_VALUE:
1000 						saved_state = L_PARAM;
1001 						state = F_LF;
1002 						param->value.len = tmp - param->value.s;
1003 						goto endofvalue;
1004 #ifdef USE_COMP
1005 					case FIN_V_SIGCOMP_P:
1006 						saved_state = L_PARAM;
1007 						state = F_LF;
1008 						param->value.len = tmp - param->value.s;
1009 						vb->comp_no = COMP_SIGCOMP;
1010 						goto endofvalue;
1011 					case FIN_V_SERGZ_Z:
1012 						saved_state = L_PARAM;
1013 						state = F_LF;
1014 						param->value.len = tmp - param->value.s;
1015 						vb->comp_no = COMP_SIGCOMP;
1016 						goto endofvalue;
1017 						comp_states_cases saved_state = L_PARAM;
1018 						state = F_LF;
1019 						param->value.len = tmp - param->value.s;
1020 						comp_unexpected_char;
1021 						goto endofvalue;
1022 #endif
1023 					case F_LF:
1024 					case F_CRLF:
1025 						state = END_OF_HEADER;
1026 						goto end_via;
1027 					case F_CR:
1028 						state = F_CRLF;
1029 						break;
1030 					default:
1031 						LM_ERR("invalid char <%c> in state %d\n", *tmp, state);
1032 						goto error;
1033 				}
1034 				break;
1035 			case '\r':
1036 				switch(state) {
1037 					case L_VALUE:
1038 					case F_VALUE: /*eat space*/
1039 #ifdef USE_COMP
1040 					case L_COMP_VALUE:
1041 					case F_COMP_VALUE:
1042 #endif
1043 					case P_STRING:
1044 						saved_state = state;
1045 						param->size = tmp - param->start;
1046 						state = F_CR;
1047 						break;
1048 					case P_VALUE:
1049 						param->value.len = tmp - param->value.s;
1050 						saved_state = L_PARAM;
1051 						state = F_CR;
1052 						goto endofvalue;
1053 #ifdef USE_COMP
1054 					case FIN_V_SIGCOMP_P:
1055 						saved_state = L_PARAM;
1056 						state = F_CR;
1057 						param->value.len = tmp - param->value.s;
1058 						vb->comp_no = COMP_SIGCOMP;
1059 						goto endofvalue;
1060 					case FIN_V_SERGZ_Z:
1061 						saved_state = L_PARAM;
1062 						state = F_CR;
1063 						param->value.len = tmp - param->value.s;
1064 						vb->comp_no = COMP_SIGCOMP;
1065 						goto endofvalue;
1066 						comp_states_cases saved_state = L_PARAM;
1067 						state = F_CR;
1068 						param->value.len = tmp - param->value.s;
1069 						comp_unexpected_char;
1070 						goto endofvalue;
1071 #endif
1072 					case F_LF:
1073 					case F_CR:
1074 					case F_CRLF:
1075 						state = END_OF_HEADER;
1076 						goto end_via;
1077 					default:
1078 						LM_ERR("invalid char <%c> in state %d\n", *tmp, state);
1079 						goto error;
1080 				}
1081 				break;
1082 
1083 			case '=':
1084 				switch(state) {
1085 					case L_VALUE:
1086 						state = F_VALUE;
1087 						break;
1088 #ifdef USE_COMP
1089 					case L_COMP_VALUE:
1090 						state = F_COMP_VALUE;
1091 						break;
1092 /* '=' in any other COMP value state is an error,
1093 					 * and it will be catched by the default branch */
1094 #endif
1095 					case P_STRING:
1096 						break;
1097 					case F_LF:
1098 					case F_CR:
1099 					case F_CRLF:
1100 						state = END_OF_HEADER;
1101 						goto end_via;
1102 					default:
1103 						LM_ERR("invalid char <%c> in state %d\n", *tmp, state);
1104 						goto error;
1105 				}
1106 				break;
1107 			case ';':
1108 				switch(state) {
1109 					case P_VALUE:
1110 						param->value.len = tmp - param->value.s;
1111 						state = F_PARAM;
1112 						goto endofvalue;
1113 					case F_VALUE:
1114 						param->value.len = 0;
1115 						state = F_PARAM;
1116 						goto endofvalue;
1117 					case P_STRING:
1118 						break; /* what to do? */
1119 					case F_LF:
1120 					case F_CR:
1121 					case F_CRLF:
1122 						state = END_OF_HEADER;
1123 						goto end_via;
1124 #ifdef USE_COMP
1125 					case L_COMP_VALUE:
1126 						comp_unexpected_char;
1127 						/* we want to contine with no comp */
1128 						state = F_PARAM;
1129 						param->value.len = 0;
1130 						param->value.s = 0;
1131 						goto endofvalue;
1132 					case F_COMP_VALUE:
1133 						comp_unexpected_char;
1134 						param->value.len = 0;
1135 						state = F_PARAM;
1136 						goto endofvalue;
1137 						comp_states_cases comp_unexpected_char;
1138 						param->value.len = tmp - param->value.s;
1139 						state = F_PARAM;
1140 						goto endofvalue;
1141 					case FIN_V_SIGCOMP_P:
1142 						vb->comp_no = COMP_SIGCOMP;
1143 						param->value.len = tmp - param->value.s;
1144 						state = F_PARAM;
1145 						goto endofvalue;
1146 					case FIN_V_SERGZ_Z:
1147 						vb->comp_no = COMP_SIGCOMP;
1148 						param->value.len = tmp - param->value.s;
1149 						state = F_PARAM;
1150 						goto endofvalue;
1151 #endif
1152 					case L_VALUE:
1153 						param->value.len = 0;
1154 						param->value.s = 0; /* null value */
1155 						state = F_PARAM;
1156 						goto endofvalue;
1157 					default:
1158 						LM_ERR("invalid char <%c> in state %d\n", *tmp, state);
1159 						goto error;
1160 				}
1161 				break;
1162 			case ',':
1163 				switch(state) {
1164 					case P_VALUE:
1165 						param->value.len = tmp - param->value.s;
1166 						state = F_VIA;
1167 						goto endofvalue;
1168 					case P_STRING:
1169 					case F_LF:
1170 					case F_CR:
1171 					case F_CRLF:
1172 						state = END_OF_HEADER;
1173 						goto end_via;
1174 #ifdef USE_COMP
1175 					case L_COMP_VALUE:
1176 						comp_unexpected_char;
1177 						/* we want to contine with no comp */
1178 						state = F_VIA;
1179 						param->value.len = 0;
1180 						param->value.s = 0;
1181 						goto endofvalue;
1182 					case F_COMP_VALUE:
1183 						comp_unexpected_char;
1184 						param->value.len = 0;
1185 						state = F_VIA;
1186 						goto endofvalue;
1187 						comp_states_cases comp_unexpected_char;
1188 						param->value.len = tmp - param->value.s;
1189 						state = F_VIA;
1190 						goto endofvalue;
1191 					case FIN_V_SIGCOMP_P:
1192 						vb->comp_no = COMP_SIGCOMP;
1193 						param->value.len = tmp - param->value.s;
1194 						state = F_VIA;
1195 						goto endofvalue;
1196 					case FIN_V_SERGZ_Z:
1197 						vb->comp_no = COMP_SIGCOMP;
1198 						param->value.len = tmp - param->value.s;
1199 						state = F_VIA;
1200 						goto endofvalue;
1201 #endif
1202 					case L_VALUE:
1203 						if(param->type == FIN_RPORT) {
1204 							param->value.len = 0;
1205 							param->value.s = 0; /* null value */
1206 							state = F_VIA;
1207 							goto endofvalue;
1208 						};
1209 					/* no break */
1210 					default:
1211 						LM_ERR("invalid char <%c> in state %d\n", *tmp, state);
1212 						goto error;
1213 				}
1214 				break; /* what to do? */
1215 			case '"':
1216 				switch(state) {
1217 					case F_VALUE:
1218 						state = P_STRING;
1219 						param->value.s = tmp + 1;
1220 						break;
1221 					case P_STRING:
1222 						state = L_PARAM;
1223 						param->value.len = tmp - param->value.s;
1224 						goto endofvalue;
1225 					case F_LF:
1226 					case F_CR:
1227 					case F_CRLF:
1228 						state = END_OF_HEADER;
1229 						goto end_via;
1230 					default:
1231 						LM_ERR("invalid char <%c> in state %d\n", *tmp, state);
1232 						goto error;
1233 				}
1234 				break;
1235 #ifdef USE_COMP
1236 				value_case('s', 'S', F_COMP_VALUE, V_COMP_S, 1);
1237 				value_case('i', 'I', V_COMP_S, V_SIGCOMP_I, 0);
1238 				value_case_double('g', 'G', V_SIGCOMP_I, V_SIGCOMP_G, V_SERGZ_R,
1239 						V_SERGZ_G);
1240 				value_case('c', 'C', V_SIGCOMP_G, V_SIGCOMP_C, 0);
1241 				value_case('o', 'O', V_SIGCOMP_C, V_SIGCOMP_O, 0);
1242 				value_case('m', 'M', V_SIGCOMP_O, V_SIGCOMP_M, 0);
1243 				value_case('p', 'P', V_SIGCOMP_M, FIN_V_SIGCOMP_P, 0);
1244 
1245 				value_case('e', 'E', V_COMP_S, V_SERGZ_E, 0);
1246 				value_case('r', 'R', V_SERGZ_E, V_SERGZ_R, 0);
1247 				value_case('z', 'Z', V_SERGZ_G, FIN_V_SERGZ_Z, 0);
1248 #endif /* USE_COMP */
1249 
1250 			default:
1251 				switch(state) {
1252 					case F_VALUE:
1253 						state = P_VALUE;
1254 						param->value.s = tmp;
1255 						break;
1256 					case P_VALUE:
1257 					case P_STRING:
1258 						break;
1259 					case F_LF:
1260 					case F_CR:
1261 					case F_CRLF:
1262 						state = END_OF_HEADER;
1263 						goto end_via;
1264 					default:
1265 #ifdef USE_COMP
1266 						switch(state) {
1267 							case F_COMP_VALUE:
1268 								comp_unexpected_char;
1269 								state = P_VALUE;
1270 								param->value.s = tmp;
1271 								break;
1272 								comp_states_cases comp_fin_states_cases
1273 										comp_unexpected_char;
1274 								state = P_VALUE;
1275 								break;
1276 							default:
1277 								LM_ERR("invalid char <%c> in state %d\n", *tmp,
1278 										state);
1279 								goto error;
1280 						}
1281 #else
1282 						LM_ERR("invalid char <%c> in state %d\n", *tmp, state);
1283 						goto error;
1284 #endif /* USE_COMP */
1285 				}
1286 		}
1287 	} /* for2 tmp*/
1288 
1289 	/* end of buff and no CR/LF =>error*/
1290 	saved_state = state;
1291 	state = END_OF_HEADER;
1292 	goto error;
1293 
1294 endofparam:
1295 endofvalue:
1296 	param->size = tmp - param->start;
1297 normal_exit:
1298 	*pstate = state;
1299 	*psaved_state = saved_state;
1300 	DBG("Found param type %d, <%.*s> = <%.*s>; state=%d\n", param->type,
1301 			param->name.len, ZSW(param->name.s),
1302 			(param->value.len ? param->value.len : 3),
1303 			(param->value.len ? param->value.s : "n/a"), state);
1304 	return tmp;
1305 
1306 end_via:
1307 	/* if we are here we found an "unexpected" end of via
1308 	 * (cr/lf). This is valid only if the param type is GEN_PARAM or
1309 	 *  RPORT (the only ones which can miss the value; HIDDEN is a
1310 	 *  special case )*/
1311 	if((param->type == GEN_PARAM) || (param->type == PARAM_RPORT)) {
1312 		saved_state = L_PARAM; /* change the saved_state, we have an unknown
1313 								* param. w/o a value */
1314 		/* param->size should be computed before */
1315 		goto normal_exit;
1316 	}
1317 	*pstate = state;
1318 	*psaved_state = saved_state;
1319 	DBG("Error on  param type %d, <%.*s>, state=%d, saved_state=%d\n",
1320 			param->type, param->name.len, ZSW(param->name.s), state,
1321 			saved_state);
1322 
1323 error:
1324 	LM_ERR("failure parsing via param\n");
1325 	param->type = PARAM_ERROR;
1326 	*pstate = PARAM_ERROR;
1327 	*psaved_state = state;
1328 	return tmp;
1329 }
1330 
1331 
1332 /*
1333  * call it with a vb initialized to 0
1334  * returns: pointer after the parsed parts and sets vb->error
1335  * WARNING: don't forget to cleanup on error with free_via_list(vb)!
1336  */
parse_via(char * buffer,const char * const end,struct via_body * const vbody)1337 char *parse_via(
1338 		char *buffer, const char *const end, struct via_body *const vbody)
1339 {
1340 	char *tmp;
1341 	char *param_start;
1342 	unsigned char state;
1343 	unsigned char saved_state;
1344 	int c_nest;
1345 	int err;
1346 	struct via_body *vb;
1347 	struct via_param *param;
1348 
1349 	vb = vbody; /* keep orignal vbody value, needed to set the error member
1350 				* in case of multiple via bodies in the same header */
1351 parse_again:
1352 	vb->error = PARSE_ERROR;
1353 	/* parse start of via ( SIP/2.0/UDP    )*/
1354 	state = F_SIP;
1355 	saved_state = F_SIP; /* fixes gcc 4.0 warning */
1356 	param_start = 0;
1357 	for(tmp = buffer; tmp < end; tmp++) {
1358 		switch(*tmp) {
1359 			case ' ':
1360 			case '\t':
1361 				switch(state) {
1362 					case L_VER: /* eat space */
1363 					case L_PROTO:
1364 					case F_SIP:
1365 					case F_VER:
1366 					case F_PROTO:
1367 						break;
1368 					case FIN_UDP:
1369 						vb->transport.len = tmp - vb->transport.s;
1370 						vb->proto = PROTO_UDP;
1371 						state = F_HOST; /* start looking for host*/
1372 						goto main_via;
1373 					case FIN_TCP:
1374 						/* finished proto parsing */
1375 						vb->transport.len = tmp - vb->transport.s;
1376 						vb->proto = PROTO_TCP;
1377 						state = F_HOST; /* start looking for host*/
1378 						goto main_via;
1379 					case FIN_TLS:
1380 						/* finished proto parsing */
1381 						vb->transport.len = tmp - vb->transport.s;
1382 						vb->proto = PROTO_TLS;
1383 						state = F_HOST; /* start looking for host*/
1384 						goto main_via;
1385 					case FIN_SCTP:
1386 						/* finished proto parsing */
1387 						vb->transport.len = tmp - vb->transport.s;
1388 						vb->proto = PROTO_SCTP;
1389 						state = F_HOST; /* start looking for host*/
1390 						goto main_via;
1391 					case WS_WSS2:
1392 						/* finished proto parsing */
1393 						vb->transport.len = tmp - vb->transport.s;
1394 						vb->proto = PROTO_WS;
1395 						state = F_HOST; /* start looking for host*/
1396 						goto main_via;
1397 					case FIN_WSS:
1398 						/* finished proto parsing */
1399 						vb->transport.len = tmp - vb->transport.s;
1400 						vb->proto = PROTO_WSS;
1401 						state = F_HOST; /* start looking for host*/
1402 						goto main_via;
1403 					case OTHER_PROTO:
1404 						/* finished proto parsing */
1405 						vb->transport.len = tmp - vb->transport.s;
1406 						vb->proto = PROTO_OTHER;
1407 						state = F_HOST; /* start looking for host*/
1408 						goto main_via;
1409 					case UDP1:
1410 					case UDP2:
1411 					case TCP_TLS1:
1412 					case TCP2:
1413 					case TLS2:
1414 					case SCTP1:
1415 					case SCTP2:
1416 					case SCTP3:
1417 					case WS_WSS1:
1418 						/* finished proto parsing */
1419 						vb->transport.len = tmp - vb->transport.s;
1420 						vb->proto = PROTO_OTHER;
1421 						state = F_HOST; /* start looking for host*/
1422 						goto main_via;
1423 					case FIN_SIP:
1424 						vb->name.len = tmp - vb->name.s;
1425 						state = L_VER;
1426 						break;
1427 					case FIN_VER:
1428 						vb->version.len = tmp - vb->version.s;
1429 						state = L_PROTO;
1430 						break;
1431 					case F_LF:
1432 					case F_CRLF:
1433 					case F_CR: /* header continues on this line */
1434 						state = saved_state;
1435 						break;
1436 					default:
1437 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1438 						goto error;
1439 				}
1440 				break;
1441 			case '\n':
1442 				switch(state) {
1443 					case L_VER:
1444 					case F_SIP:
1445 					case F_VER:
1446 					case F_PROTO:
1447 					case L_PROTO:
1448 						saved_state = state;
1449 						state = F_LF;
1450 						break;
1451 					case FIN_UDP:
1452 						vb->transport.len = tmp - vb->transport.s;
1453 						vb->proto = PROTO_UDP;
1454 						state = F_LF;
1455 						saved_state = F_HOST; /* start looking for host*/
1456 						goto main_via;
1457 					case FIN_TCP:
1458 						vb->transport.len = tmp - vb->transport.s;
1459 						vb->proto = PROTO_TCP;
1460 						state = F_LF;
1461 						saved_state = F_HOST; /* start looking for host*/
1462 						goto main_via;
1463 					case FIN_TLS:
1464 						vb->transport.len = tmp - vb->transport.s;
1465 						vb->proto = PROTO_TLS;
1466 						state = F_LF;
1467 						saved_state = F_HOST; /* start looking for host*/
1468 						goto main_via;
1469 					case FIN_SCTP:
1470 						/* finished proto parsing */
1471 						vb->transport.len = tmp - vb->transport.s;
1472 						vb->proto = PROTO_SCTP;
1473 						state = F_LF;
1474 						saved_state = F_HOST; /* start looking for host*/
1475 						goto main_via;
1476 					case WS_WSS2:
1477 						/* finished proto parsing */
1478 						vb->transport.len = tmp - vb->transport.s;
1479 						vb->proto = PROTO_WS;
1480 						state = F_LF;
1481 						saved_state = F_HOST; /* start looking for host*/
1482 						goto main_via;
1483 					case FIN_WSS:
1484 						/* finished proto parsing */
1485 						vb->transport.len = tmp - vb->transport.s;
1486 						vb->proto = PROTO_WSS;
1487 						state = F_LF;
1488 						saved_state = F_HOST; /* start looking for host*/
1489 						goto main_via;
1490 					case OTHER_PROTO:
1491 						/* finished proto parsing */
1492 						vb->transport.len = tmp - vb->transport.s;
1493 						vb->proto = PROTO_OTHER;
1494 						state = F_LF;
1495 						saved_state = F_HOST; /* start looking for host*/
1496 						goto main_via;
1497 					case UDP1:
1498 					case UDP2:
1499 					case TCP_TLS1:
1500 					case TCP2:
1501 					case TLS2:
1502 					case SCTP1:
1503 					case SCTP2:
1504 					case SCTP3:
1505 					case WS_WSS1:
1506 						/* finished proto parsing */
1507 						vb->transport.len = tmp - vb->transport.s;
1508 						vb->proto = PROTO_OTHER;
1509 						state = F_LF;
1510 						saved_state = F_HOST; /* start looking for host*/
1511 						goto main_via;
1512 					case FIN_SIP:
1513 						vb->name.len = tmp - vb->name.s;
1514 						state = F_LF;
1515 						saved_state = L_VER;
1516 						break;
1517 					case FIN_VER:
1518 						vb->version.len = tmp - vb->version.s;
1519 						state = F_LF;
1520 						saved_state = L_PROTO;
1521 						break;
1522 					case F_CR:
1523 						state = F_CRLF;
1524 						break;
1525 					case F_LF:
1526 					case F_CRLF:
1527 						state = saved_state;
1528 						goto endofheader;
1529 					default:
1530 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1531 						goto error;
1532 				}
1533 				break;
1534 			case '\r':
1535 				switch(state) {
1536 					case L_VER:
1537 					case F_SIP:
1538 					case F_VER:
1539 					case F_PROTO:
1540 					case L_PROTO:
1541 						saved_state = state;
1542 						state = F_CR;
1543 						break;
1544 					case FIN_UDP:
1545 						vb->transport.len = tmp - vb->transport.s;
1546 						vb->proto = PROTO_UDP;
1547 						state = F_CR;
1548 						saved_state = F_HOST;
1549 						goto main_via;
1550 					case FIN_TCP:
1551 						vb->transport.len = tmp - vb->transport.s;
1552 						vb->proto = PROTO_TCP;
1553 						state = F_CR;
1554 						saved_state = F_HOST;
1555 						goto main_via;
1556 					case FIN_TLS:
1557 						vb->transport.len = tmp - vb->transport.s;
1558 						vb->proto = PROTO_TLS;
1559 						state = F_CR;
1560 						saved_state = F_HOST;
1561 						goto main_via;
1562 					case FIN_SCTP:
1563 						vb->transport.len = tmp - vb->transport.s;
1564 						vb->proto = PROTO_SCTP;
1565 						state = F_CR;
1566 						saved_state = F_HOST;
1567 						goto main_via;
1568 					case WS_WSS2:
1569 						vb->transport.len = tmp - vb->transport.s;
1570 						vb->proto = PROTO_WS;
1571 						state = F_CR;
1572 						saved_state = F_HOST;
1573 						goto main_via;
1574 					case FIN_WSS:
1575 						vb->transport.len = tmp - vb->transport.s;
1576 						vb->proto = PROTO_WSS;
1577 						state = F_CR;
1578 						saved_state = F_HOST;
1579 						goto main_via;
1580 					case OTHER_PROTO:
1581 						vb->transport.len = tmp - vb->transport.s;
1582 						vb->proto = PROTO_OTHER;
1583 						state = F_CR;
1584 						saved_state = F_HOST;
1585 						goto main_via;
1586 					case UDP1:
1587 					case UDP2:
1588 					case TCP_TLS1:
1589 					case TCP2:
1590 					case TLS2:
1591 					case SCTP1:
1592 					case SCTP2:
1593 					case SCTP3:
1594 					case WS_WSS1:
1595 						/* finished proto parsing */
1596 						vb->transport.len = tmp - vb->transport.s;
1597 						vb->proto = PROTO_OTHER;
1598 						state = F_CR;
1599 						saved_state = F_HOST;
1600 						goto main_via;
1601 					case FIN_SIP:
1602 						vb->name.len = tmp - vb->name.s;
1603 						state = F_CR;
1604 						saved_state = L_VER;
1605 						break;
1606 					case FIN_VER:
1607 						vb->version.len = tmp - vb->version.s;
1608 						state = F_CR;
1609 						saved_state = L_PROTO;
1610 						break;
1611 					case F_LF: /*end of line ?next header?*/
1612 					case F_CR:
1613 					case F_CRLF:
1614 						state = saved_state;
1615 						goto endofheader;
1616 					default:
1617 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1618 						goto error;
1619 				}
1620 				break;
1621 
1622 			case '/':
1623 				switch(state) {
1624 					case FIN_SIP:
1625 						vb->name.len = tmp - vb->name.s;
1626 						state = F_VER;
1627 						break;
1628 					case FIN_VER:
1629 						vb->version.len = tmp - vb->version.s;
1630 						state = F_PROTO;
1631 						break;
1632 					case L_VER:
1633 						state = F_VER;
1634 						break;
1635 					case L_PROTO:
1636 						state = F_PROTO;
1637 						break;
1638 					default:
1639 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1640 						goto error;
1641 				}
1642 				break;
1643 			/* match SIP*/
1644 			case 'S':
1645 			case 's':
1646 				switch(state) {
1647 					case F_SIP:
1648 						state = SIP1;
1649 						vb->name.s = tmp;
1650 						break;
1651 					case TLS2:
1652 						state = FIN_TLS;
1653 						break;
1654 					case WS_WSS1:
1655 						state = WS_WSS2;
1656 						break;
1657 					case WS_WSS2:
1658 						state = FIN_WSS;
1659 						break;
1660 					case F_PROTO:
1661 						state = SCTP1;
1662 						vb->transport.s = tmp;
1663 						break;
1664 					case OTHER_PROTO:
1665 						break;
1666 					case UDP1:
1667 					case UDP2:
1668 					case FIN_UDP:
1669 					case TCP_TLS1:
1670 					case TCP2:
1671 					case FIN_TCP:
1672 					case FIN_TLS:
1673 					case SCTP1:
1674 					case SCTP2:
1675 					case SCTP3:
1676 					case FIN_WSS:
1677 					case FIN_SCTP:
1678 						state = OTHER_PROTO;
1679 						break;
1680 					default:
1681 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1682 						goto error;
1683 				}
1684 				break;
1685 			case 'I':
1686 			case 'i':
1687 				switch(state) {
1688 					case SIP1:
1689 						state = SIP2;
1690 						break;
1691 					case OTHER_PROTO:
1692 						break;
1693 					case UDP1:
1694 					case UDP2:
1695 					case FIN_UDP:
1696 					case TCP_TLS1:
1697 					case TCP2:
1698 					case FIN_TCP:
1699 					case TLS2:
1700 					case FIN_TLS:
1701 					case SCTP1:
1702 					case SCTP2:
1703 					case SCTP3:
1704 					case FIN_SCTP:
1705 					case WS_WSS1:
1706 					case WS_WSS2:
1707 					case FIN_WSS:
1708 						state = OTHER_PROTO;
1709 						break;
1710 					default:
1711 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1712 						goto error;
1713 				}
1714 				break;
1715 			case 'p':
1716 			case 'P':
1717 				switch(state) {
1718 					case SIP2:
1719 						state = FIN_SIP;
1720 						break;
1721 					/* allow p in PROTO */
1722 					case UDP2:
1723 						state = FIN_UDP;
1724 						break;
1725 					case TCP2:
1726 						state = FIN_TCP;
1727 						break;
1728 					case SCTP3:
1729 						state = FIN_SCTP;
1730 						break;
1731 					case OTHER_PROTO:
1732 						break;
1733 					case UDP1:
1734 					case FIN_UDP:
1735 					case TCP_TLS1:
1736 					case FIN_TCP:
1737 					case TLS2:
1738 					case FIN_TLS:
1739 					case SCTP1:
1740 					case SCTP2:
1741 					case FIN_SCTP:
1742 					case WS_WSS1:
1743 					case WS_WSS2:
1744 					case FIN_WSS:
1745 						state = OTHER_PROTO;
1746 						break;
1747 					default:
1748 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1749 						goto error;
1750 				}
1751 				break;
1752 			case 'U':
1753 			case 'u':
1754 				switch(state) {
1755 					case F_PROTO:
1756 						state = UDP1;
1757 						vb->transport.s = tmp;
1758 						break;
1759 					case OTHER_PROTO:
1760 						break;
1761 					case UDP1:
1762 					case UDP2:
1763 					case FIN_UDP:
1764 					case TCP_TLS1:
1765 					case TCP2:
1766 					case FIN_TCP:
1767 					case TLS2:
1768 					case FIN_TLS:
1769 					case SCTP1:
1770 					case SCTP2:
1771 					case SCTP3:
1772 					case FIN_SCTP:
1773 					case WS_WSS1:
1774 					case WS_WSS2:
1775 					case FIN_WSS:
1776 						state = OTHER_PROTO;
1777 						break;
1778 					default:
1779 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1780 						goto error;
1781 				}
1782 				break;
1783 			case 'D':
1784 			case 'd':
1785 				switch(state) {
1786 					case UDP1:
1787 						state = UDP2;
1788 						break;
1789 					case OTHER_PROTO:
1790 						break;
1791 					case UDP2:
1792 					case FIN_UDP:
1793 					case TCP_TLS1:
1794 					case TCP2:
1795 					case FIN_TCP:
1796 					case TLS2:
1797 					case FIN_TLS:
1798 					case SCTP1:
1799 					case SCTP2:
1800 					case SCTP3:
1801 					case FIN_SCTP:
1802 					case WS_WSS1:
1803 					case WS_WSS2:
1804 					case FIN_WSS:
1805 						state = OTHER_PROTO;
1806 						break;
1807 					default:
1808 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1809 						goto error;
1810 				}
1811 				break;
1812 			case 'T':
1813 			case 't':
1814 				switch(state) {
1815 					case F_PROTO:
1816 						state = TCP_TLS1;
1817 						vb->transport.s = tmp;
1818 						break;
1819 					case SCTP2:
1820 						state = SCTP3;
1821 						break;
1822 					case OTHER_PROTO:
1823 						break;
1824 					case UDP1:
1825 					case UDP2:
1826 					case FIN_UDP:
1827 					case TCP_TLS1:
1828 					case TCP2:
1829 					case FIN_TCP:
1830 					case TLS2:
1831 					case FIN_TLS:
1832 					case SCTP1:
1833 					case SCTP3:
1834 					case FIN_SCTP:
1835 					case WS_WSS1:
1836 					case WS_WSS2:
1837 					case FIN_WSS:
1838 						state = OTHER_PROTO;
1839 						break;
1840 					default:
1841 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1842 						goto error;
1843 				}
1844 				break;
1845 			case 'C':
1846 			case 'c':
1847 				switch(state) {
1848 					case TCP_TLS1:
1849 						state = TCP2;
1850 						break;
1851 					case SCTP1:
1852 						state = SCTP2;
1853 						break;
1854 					case OTHER_PROTO:
1855 						break;
1856 					case UDP1:
1857 					case UDP2:
1858 					case FIN_UDP:
1859 					case TCP2:
1860 					case FIN_TCP:
1861 					case TLS2:
1862 					case FIN_TLS:
1863 					case SCTP2:
1864 					case SCTP3:
1865 					case FIN_SCTP:
1866 					case WS_WSS1:
1867 					case WS_WSS2:
1868 					case FIN_WSS:
1869 						state = OTHER_PROTO;
1870 						break;
1871 					default:
1872 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1873 						goto error;
1874 				}
1875 				break;
1876 			case 'L':
1877 			case 'l':
1878 				switch(state) {
1879 					case TCP_TLS1:
1880 						state = TLS2;
1881 						break;
1882 					case OTHER_PROTO:
1883 						break;
1884 					case UDP1:
1885 					case UDP2:
1886 					case FIN_UDP:
1887 					case TCP2:
1888 					case FIN_TCP:
1889 					case TLS2:
1890 					case FIN_TLS:
1891 					case SCTP1:
1892 					case SCTP2:
1893 					case SCTP3:
1894 					case FIN_SCTP:
1895 					case WS_WSS1:
1896 					case WS_WSS2:
1897 					case FIN_WSS:
1898 						state = OTHER_PROTO;
1899 						break;
1900 					default:
1901 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1902 						goto error;
1903 				}
1904 				break;
1905 			case 'W':
1906 			case 'w':
1907 				switch(state) {
1908 					case F_PROTO:
1909 						state = WS_WSS1;
1910 						vb->transport.s = tmp;
1911 						break;
1912 					case OTHER_PROTO:
1913 						break;
1914 					case UDP1:
1915 					case UDP2:
1916 					case FIN_UDP:
1917 					case TCP_TLS1:
1918 					case TCP2:
1919 					case FIN_TCP:
1920 					case TLS2:
1921 					case FIN_TLS:
1922 					case SCTP1:
1923 					case SCTP2:
1924 					case SCTP3:
1925 					case FIN_SCTP:
1926 					case WS_WSS1:
1927 					case WS_WSS2:
1928 					case FIN_WSS:
1929 						state = OTHER_PROTO;
1930 						break;
1931 					default:
1932 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1933 						goto error;
1934 				}
1935 				break;
1936 			/*match 2.0*/
1937 			case '2':
1938 				switch(state) {
1939 					case F_VER:
1940 						state = VER1;
1941 						vb->version.s = tmp;
1942 						break;
1943 					case OTHER_PROTO:
1944 						break;
1945 					case UDP1:
1946 					case UDP2:
1947 					case FIN_UDP:
1948 					case TCP_TLS1:
1949 					case TCP2:
1950 					case FIN_TCP:
1951 					case TLS2:
1952 					case FIN_TLS:
1953 					case SCTP1:
1954 					case SCTP2:
1955 					case SCTP3:
1956 					case FIN_SCTP:
1957 					case WS_WSS1:
1958 					case WS_WSS2:
1959 					case FIN_WSS:
1960 						state = OTHER_PROTO;
1961 						break;
1962 					default:
1963 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1964 						goto error;
1965 				}
1966 				break;
1967 			case '.':
1968 				switch(state) {
1969 					case VER1:
1970 						state = VER2;
1971 						break;
1972 					case OTHER_PROTO:
1973 						break;
1974 					case UDP1:
1975 					case UDP2:
1976 					case FIN_UDP:
1977 					case TCP_TLS1:
1978 					case TCP2:
1979 					case FIN_TCP:
1980 					case TLS2:
1981 					case FIN_TLS:
1982 					case SCTP1:
1983 					case SCTP2:
1984 					case SCTP3:
1985 					case FIN_SCTP:
1986 					case WS_WSS1:
1987 					case WS_WSS2:
1988 					case FIN_WSS:
1989 						state = OTHER_PROTO;
1990 						break;
1991 					default:
1992 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
1993 						goto error;
1994 				}
1995 				break;
1996 			case '0':
1997 				switch(state) {
1998 					case VER2:
1999 						state = FIN_VER;
2000 						break;
2001 					case OTHER_PROTO:
2002 						break;
2003 					case UDP1:
2004 					case UDP2:
2005 					case FIN_UDP:
2006 					case TCP_TLS1:
2007 					case TCP2:
2008 					case FIN_TCP:
2009 					case TLS2:
2010 					case FIN_TLS:
2011 					case SCTP1:
2012 					case SCTP2:
2013 					case SCTP3:
2014 					case FIN_SCTP:
2015 					case WS_WSS1:
2016 					case WS_WSS2:
2017 					case FIN_WSS:
2018 						state = OTHER_PROTO;
2019 						break;
2020 					default:
2021 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
2022 						goto error;
2023 				}
2024 				break;
2025 			default:
2026 				switch(state) {
2027 					case F_PROTO:
2028 						state = OTHER_PROTO;
2029 						vb->transport.s = tmp;
2030 						break;
2031 					case OTHER_PROTO:
2032 						break;
2033 					case UDP1:
2034 					case UDP2:
2035 					case FIN_UDP:
2036 					case TCP_TLS1:
2037 					case TCP2:
2038 					case FIN_TCP:
2039 					case TLS2:
2040 					case FIN_TLS:
2041 					case SCTP1:
2042 					case SCTP2:
2043 					case SCTP3:
2044 					case FIN_SCTP:
2045 					case WS_WSS1:
2046 					case WS_WSS2:
2047 					case FIN_WSS:
2048 						state = OTHER_PROTO;
2049 						break;
2050 					default:
2051 						LM_ERR("bad char <%c> on state %d\n", *tmp, state);
2052 						goto error;
2053 				}
2054 				break;
2055 		}
2056 	} /* for tmp*/
2057 
2058 	/* we should not be here! if everything is ok > main_via*/
2059 	LM_ERR("bad via: end of packet on state=%d\n", state);
2060 	goto error;
2061 
2062 main_via:
2063 	/* inc tmp to point to the next char*/
2064 	tmp++;
2065 	c_nest = 0;
2066 	/*state should always be F_HOST here*/;
2067 	for(; *tmp; tmp++) {
2068 		switch(*tmp) {
2069 			case ' ':
2070 			case '\t':
2071 				switch(state) {
2072 					case F_HOST: /*eat the spaces*/
2073 						break;
2074 					case P_HOST:
2075 						/*mark end of host*/
2076 						if(vb->host.s) vb->host.len = tmp - vb->host.s;
2077 						state = L_PORT;
2078 						break;
2079 					case L_PORT: /*eat the spaces*/
2080 					case F_PORT:
2081 						break;
2082 					case P_PORT:
2083 						/*end of port */
2084 						if(vb->port_str.s) vb->port_str.len = tmp - vb->port_str.s;
2085 						state = L_PARAM;
2086 						break;
2087 					case L_PARAM: /* eat the space */
2088 					case F_PARAM:
2089 						break;
2090 					case P_PARAM:
2091 						/*	*tmp=0;*/ /*!?end of param*/
2092 						state = L_PARAM;
2093 						break;
2094 					case L_VIA:
2095 					case F_VIA: /* eat the space */
2096 						break;
2097 					case F_COMMENT:
2098 					case P_COMMENT:
2099 						break;
2100 					case F_IP6HOST: /*no spaces allowed*/
2101 					case P_IP6HOST:
2102 						LM_ERR("bad ipv6 reference\n");
2103 						goto error;
2104 					case F_CRLF:
2105 					case F_LF:
2106 					case F_CR:
2107 						/*previous=crlf and now =' '*/
2108 						state = saved_state;
2109 						break;
2110 					default:
2111 						LM_CRIT("BUG: parsing via on <%c>, state=%d\n", *tmp,
2112 								state);
2113 						goto error;
2114 				}
2115 				break;
2116 			case '\n':
2117 				switch(state) {
2118 					case F_HOST: /*eat the spaces*/
2119 					case L_PORT: /*eat the spaces*/
2120 					case F_PORT:
2121 					case L_PARAM: /* eat the space */
2122 					case F_PARAM:
2123 					case F_VIA: /* eat the space */
2124 					case L_VIA:
2125 					case F_COMMENT:
2126 					case P_COMMENT:
2127 					case F_IP6HOST:
2128 					case P_IP6HOST:
2129 						saved_state = state;
2130 						state = F_LF;
2131 						break;
2132 					case P_HOST:
2133 						/*mark end of host*/
2134 						if(vb->host.s) vb->host.len = tmp - vb->host.s;
2135 						saved_state = L_PORT;
2136 						state = F_LF;
2137 						break;
2138 					case P_PORT:
2139 						/*end of port */
2140 						if(vb->port_str.s) vb->port_str.len = tmp - vb->port_str.s;
2141 						saved_state = L_PARAM;
2142 						state = F_LF;
2143 						break;
2144 					case P_PARAM:
2145 						/*	*tmp=0;*/ /*!?end of param*/
2146 						saved_state = L_PARAM;
2147 						state = F_LF;
2148 						break;
2149 					case F_CR:
2150 						state = F_CRLF;
2151 						break;
2152 					case F_CRLF:
2153 					case F_LF:
2154 						state = saved_state;
2155 						goto endofheader;
2156 					default:
2157 						LM_CRIT("BUG: parsing via on <%c>\n", *tmp);
2158 						goto error;
2159 				}
2160 				break;
2161 			case '\r':
2162 				switch(state) {
2163 					case F_HOST: /*eat the spaces*/
2164 					case L_PORT: /*eat the spaces*/
2165 					case F_PORT:
2166 					case L_PARAM: /* eat the space */
2167 					case F_PARAM:
2168 					case F_VIA: /* eat the space */
2169 					case L_VIA:
2170 					case F_COMMENT:
2171 					case P_COMMENT:
2172 					case F_IP6HOST:
2173 					case P_IP6HOST:
2174 						saved_state = state;
2175 						state = F_CR;
2176 						break;
2177 					case P_HOST:
2178 						/*mark end of host*/
2179 						if(vb->host.s) vb->host.len = tmp - vb->host.s;
2180 						saved_state = L_PORT;
2181 						state = F_CR;
2182 						break;
2183 					case P_PORT:
2184 						/*end of port */
2185 						if(vb->port_str.s) vb->port_str.len = tmp - vb->port_str.s;
2186 						saved_state = L_PARAM;
2187 						state = F_CR;
2188 						break;
2189 					case P_PARAM:
2190 						/*	*tmp=0;*/ /*!?end of param*/
2191 						saved_state = L_PARAM;
2192 						state = F_CR;
2193 						break;
2194 					case F_CRLF:
2195 					case F_CR:
2196 					case F_LF:
2197 						state = saved_state;
2198 						goto endofheader;
2199 					default:
2200 						LM_CRIT("BUG: parsing via on <%c>\n", *tmp);
2201 						goto error;
2202 				}
2203 				break;
2204 
2205 			case ':':
2206 				switch(state) {
2207 					case F_HOST:
2208 					case F_IP6HOST:
2209 						state = P_IP6HOST;
2210 						break;
2211 					case P_IP6HOST:
2212 						break;
2213 					case P_HOST:
2214 						/*mark  end of host*/
2215 						if(vb->host.s) vb->host.len = tmp - vb->host.s;
2216 						state = F_PORT;
2217 						break;
2218 					case L_PORT:
2219 						state = F_PORT;
2220 						break;
2221 					case P_PORT:
2222 						LM_ERR("bad port\n");
2223 						goto error;
2224 					case L_PARAM:
2225 					case F_PARAM:
2226 					case F_PORT:
2227 					case P_PARAM:
2228 						LM_ERR("bad char <%c> in state %d\n", *tmp, state);
2229 						goto error;
2230 					case L_VIA:
2231 					case F_VIA:
2232 						LM_ERR("bad char in compact via\n");
2233 						goto error;
2234 					case F_CRLF:
2235 					case F_LF:
2236 					case F_CR:
2237 						/*previous=crlf and now !=' '*/
2238 						goto endofheader;
2239 					case F_COMMENT: /*everything is allowed in a comment*/
2240 						vb->comment.s = tmp;
2241 						state = P_COMMENT;
2242 						break;
2243 					case P_COMMENT: /*everything is allowed in a comment*/
2244 						break;
2245 					default:
2246 						LM_CRIT("on <%c> state %d\n", *tmp, state);
2247 						goto error;
2248 				}
2249 				break;
2250 			case ';':
2251 				switch(state) {
2252 					case F_HOST:
2253 					case F_IP6HOST:
2254 						LM_ERR("no host found\n");
2255 						goto error;
2256 					case P_IP6HOST:
2257 						LM_ERR("bad ipv6 reference\n");
2258 						goto error;
2259 					case P_HOST:
2260 						if(vb->host.s) vb->host.len = tmp - vb->host.s;
2261 						state = F_PARAM;
2262 						param_start = tmp + 1;
2263 						break;
2264 					case P_PORT:
2265 						/*mark the end*/
2266 						if(vb->port_str.s) vb->port_str.len = tmp - vb->port_str.s;
2267 					case L_PORT:
2268 					case L_PARAM:
2269 						state = F_PARAM;
2270 						param_start = tmp + 1;
2271 						break;
2272 					case F_PORT:
2273 						LM_ERR("bad char <%c> in state %d\n", *tmp, state);
2274 						goto error;
2275 					case F_PARAM:
2276 						LM_ERR("null param?\n");
2277 						goto error;
2278 					case P_PARAM:
2279 						/*hmm next, param?*/
2280 						state = F_PARAM;
2281 						param_start = tmp + 1;
2282 						break;
2283 					case L_VIA:
2284 					case F_VIA:
2285 						LM_ERR("bad char <%c> in next via\n", *tmp);
2286 						goto error;
2287 					case F_CRLF:
2288 					case F_LF:
2289 					case F_CR:
2290 						/*previous=crlf and now !=' '*/
2291 						goto endofheader;
2292 					case F_COMMENT: /*everything is allowed in a comment*/
2293 						vb->comment.s = tmp;
2294 						state = P_COMMENT;
2295 						break;
2296 					case P_COMMENT: /*everything is allowed in a comment*/
2297 						break;
2298 
2299 					default:
2300 						LM_CRIT("BUG: parsing via on <%c> state %d\n", *tmp,
2301 								state);
2302 						goto error;
2303 				}
2304 				break;
2305 			case ',':
2306 				switch(state) {
2307 					case F_HOST:
2308 					case F_IP6HOST:
2309 						LM_ERR("no host found\n");
2310 						goto error;
2311 					case P_IP6HOST:
2312 						LM_ERR("bad ipv6 reference\n");
2313 						goto error;
2314 					case P_HOST:
2315 						/*mark the end*/
2316 						if(vb->host.s) vb->host.len = tmp - vb->host.s;
2317 						state = F_VIA;
2318 						break;
2319 					case P_PORT:
2320 						/*mark the end*/
2321 						if(vb->port_str.s) vb->port_str.len = tmp - vb->port_str.s;
2322 						state = F_VIA;
2323 						break;
2324 					case L_PORT:
2325 					case L_PARAM:
2326 					case P_PARAM:
2327 					case L_VIA:
2328 						state = F_VIA;
2329 						break;
2330 					case F_PORT:
2331 					case F_PARAM:
2332 						LM_ERR("invalid char <%c> in state %d\n", *tmp, state);
2333 						goto error;
2334 					case F_VIA:
2335 						/* do  nothing,  eat ","*/
2336 						break;
2337 					case F_CRLF:
2338 					case F_LF:
2339 					case F_CR:
2340 						/*previous=crlf and now !=' '*/
2341 						goto endofheader;
2342 					case F_COMMENT: /*everything is allowed in a comment*/
2343 						vb->comment.s = tmp;
2344 						state = P_COMMENT;
2345 						break;
2346 					case P_COMMENT: /*everything is allowed in a comment*/
2347 						break;
2348 					default:
2349 						LM_CRIT("BUG: parsing via on <%c> state %d\n", *tmp,
2350 								state);
2351 						goto error;
2352 				}
2353 				break;
2354 			case '(':
2355 				switch(state) {
2356 					case F_HOST:
2357 					case F_PORT:
2358 					case F_PARAM:
2359 					case F_VIA:
2360 					case F_IP6HOST:
2361 					case P_IP6HOST: /*must be terminated in ']'*/
2362 						LM_ERR("parsing via on <%c> state %d\n", *tmp, state);
2363 						goto error;
2364 					case P_HOST:
2365 						/*mark the end*/
2366 						if(vb->host.s) vb->host.len = tmp - vb->host.s;
2367 						state = F_COMMENT;
2368 						c_nest++;
2369 						break;
2370 					case P_PORT:
2371 						/*mark the end*/
2372 						if(vb->port_str.s) vb->port_str.len = tmp - vb->port_str.s;
2373 						state = F_COMMENT;
2374 						c_nest++;
2375 						break;
2376 					case P_PARAM:
2377 						/*mark the end*/
2378 						vb->params.len = tmp - vb->params.s;
2379 						state = F_COMMENT;
2380 						c_nest++;
2381 						break;
2382 					case L_PORT:
2383 					case L_PARAM:
2384 					case L_VIA:
2385 						state = F_COMMENT;
2386 						vb->params.len = tmp - vb->params.s;
2387 						c_nest++;
2388 						break;
2389 					case P_COMMENT:
2390 					case F_COMMENT:
2391 						c_nest++;
2392 						break;
2393 					case F_CRLF:
2394 					case F_LF:
2395 					case F_CR:
2396 						/*previous=crlf and now !=' '*/
2397 						goto endofheader;
2398 					default:
2399 						LM_CRIT("BUG: parsing via on <%c> state %d\n", *tmp,
2400 								state);
2401 						goto error;
2402 				}
2403 				break;
2404 			case ')':
2405 				switch(state) {
2406 					case F_COMMENT:
2407 					case P_COMMENT:
2408 						if(c_nest) {
2409 							c_nest--;
2410 							if(c_nest == 0) {
2411 								state = L_VIA;
2412 								vb->comment.len = tmp - vb->comment.s;
2413 								break;
2414 							}
2415 						} else {
2416 							LM_ERR("parsing via: missing '(' - nesting = %d\n",
2417 									c_nest);
2418 							goto error;
2419 						}
2420 						break;
2421 					case F_HOST:
2422 					case F_PORT:
2423 					case F_PARAM:
2424 					case F_VIA:
2425 					case P_HOST:
2426 					case P_PORT:
2427 					case P_PARAM:
2428 					case L_PORT:
2429 					case L_PARAM:
2430 					case L_VIA:
2431 					case F_IP6HOST:
2432 					case P_IP6HOST:
2433 						LM_ERR("parsing via on <%c> state %d\n", *tmp, state);
2434 						goto error;
2435 					case F_CRLF:
2436 					case F_LF:
2437 					case F_CR:
2438 						/*previous=crlf and now !=' '*/
2439 						goto endofheader;
2440 					default:
2441 						LM_CRIT("BUG: parsing via on <%c> state %d\n", *tmp,
2442 								state);
2443 						goto error;
2444 				}
2445 				break;
2446 			case '[':
2447 				switch(state) {
2448 					case F_HOST:
2449 						vb->host.s = tmp; /* mark start here (include [])*/
2450 						state = F_IP6HOST;
2451 						break;
2452 					case F_COMMENT: /*everything is allowed in a comment*/
2453 						vb->comment.s = tmp;
2454 						state = P_COMMENT;
2455 						break;
2456 					case P_COMMENT:
2457 						break;
2458 					case F_CRLF:
2459 					case F_LF:
2460 					case F_CR:
2461 						/*previous=crlf and now !=' '*/
2462 						goto endofheader;
2463 					default:
2464 						LM_ERR("parsing via on <%c> state %d\n", *tmp, state);
2465 						goto error;
2466 				}
2467 				break;
2468 			case ']':
2469 				switch(state) {
2470 					case P_IP6HOST:
2471 						/*mark the end*/
2472 						if(vb->host.s) vb->host.len = (tmp - vb->host.s) + 1; /* include "]" */
2473 						state = L_PORT;
2474 						break;
2475 					case F_CRLF:
2476 					case F_LF:
2477 					case F_CR:
2478 						/*previous=crlf and now !=' '*/
2479 						goto endofheader;
2480 					case F_COMMENT: /*everything is allowed in a comment*/
2481 						vb->comment.s = tmp;
2482 						state = P_COMMENT;
2483 						break;
2484 					case P_COMMENT:
2485 						break;
2486 					default:
2487 						LM_ERR("parsing via on <%c> state %d\n", *tmp, state);
2488 						goto error;
2489 				}
2490 				break;
2491 
2492 			default:
2493 				switch(state) {
2494 					case F_HOST:
2495 						state = P_HOST;
2496 						vb->host.s = tmp;
2497 						break;
2498 					case P_HOST:
2499 						break;
2500 					case F_PORT:
2501 						state = P_PORT;
2502 						vb->port_str.s = tmp;
2503 						break;
2504 					case P_PORT:
2505 						/*check if number?*/
2506 						break;
2507 					case F_PARAM:
2508 							/*state=P_PARAM*/;
2509 						if(vb->params.s == 0)
2510 							vb->params.s = param_start;
2511 						param = pkg_malloc(sizeof(struct via_param));
2512 						if(param == 0) {
2513 							PKG_MEM_ERROR;
2514 							goto error;
2515 						}
2516 						memset(param, 0, sizeof(struct via_param));
2517 						param->start = param_start;
2518 						tmp = parse_via_param(
2519 								tmp, end, &state, &saved_state, param, vb);
2520 
2521 						switch(state) {
2522 							case F_PARAM:
2523 								param_start = tmp + 1;
2524 							case L_PARAM:
2525 							case F_LF:
2526 							case F_CR:
2527 								break;
2528 							case F_VIA:
2529 								vb->params.len = param->start + param->size
2530 													- vb->params.s;
2531 								break;
2532 							case END_OF_HEADER:
2533 								vb->params.len = param->start + param->size
2534 													- vb->params.s;
2535 								break;
2536 							case PARAM_ERROR:
2537 								pkg_free(param);
2538 								goto error;
2539 							default:
2540 								pkg_free(param);
2541 								LM_ERR("parsing via after parse_via_param:"
2542 										" invalid char <%c> on state %d\n",
2543 										*tmp, state);
2544 								goto error;
2545 						}
2546 						/*add param to the list*/
2547 						if(vb->last_param)
2548 							vb->last_param->next = param;
2549 						else
2550 							vb->param_lst = param;
2551 						vb->last_param = param;
2552 						/* update param. shortcuts */
2553 						switch(param->type) {
2554 							case PARAM_BRANCH:
2555 								vb->branch = param;
2556 								break;
2557 							case PARAM_RECEIVED:
2558 								vb->received = param;
2559 								break;
2560 							case PARAM_RPORT:
2561 								vb->rport = param;
2562 								break;
2563 							case PARAM_I:
2564 								vb->i = param;
2565 								break;
2566 							case PARAM_ALIAS:
2567 								vb->alias = param;
2568 								break;
2569 #ifdef USE_COMP
2570 							case PARAM_COMP:
2571 								vb->comp = param;
2572 								/*  moved comp value parsing in via_param */
2573 								/*
2574 								if  ((param->value.len==SIGCOMP_NAME_LEN) &&
2575 									(strncasecmp(param->value.s, SIGCOMP_NAME,
2576 												SIGCOMP_NAME_LEN)==0)){
2577 									vb->comp_no=COMP_SIGCOMP;
2578 								}else if ((param->value.len==SERGZ_NAME_LEN) &&
2579 										(strncasecmp(param->value.s,
2580 													SERGZ_NAME,
2581 													SERGZ_NAME_LEN)==0)){
2582 									vb->comp_no=COMP_SERGZ;
2583 								}else{
2584 									LM_ERR("unrecognized"
2585 										" compression method in comp=%.*s\n",
2586 										param->value.len, param->value.s);
2587 								}
2588 								*/
2589 								break;
2590 #endif
2591 						}
2592 
2593 						if(state == END_OF_HEADER) {
2594 							state = saved_state;
2595 							goto endofheader;
2596 						}
2597 						break;
2598 					case P_PARAM:
2599 						break;
2600 					case F_VIA:
2601 						/*vb->next=tmp;*/ /*???*/
2602 						goto nextvia;
2603 					case L_PORT:
2604 					case L_PARAM:
2605 					case L_VIA:
2606 						LM_ERR("parsing via on <%c> state %d (default)\n", *tmp,
2607 								state);
2608 						goto error;
2609 					case F_COMMENT:
2610 						state = P_COMMENT;
2611 						vb->comment.s = tmp;
2612 						break;
2613 					case P_COMMENT:
2614 						break;
2615 					case F_IP6HOST:
2616 						state = P_IP6HOST;
2617 						break;
2618 					case P_IP6HOST:
2619 						break;
2620 					case F_CRLF:
2621 					case F_LF:
2622 					case F_CR:
2623 						/*previous=crlf and now !=' '*/
2624 						goto endofheader;
2625 					default:
2626 						LM_ERR("BUG: parsing via - invalid char <%c>"
2627 								" in state %d\n",
2628 								*tmp, state);
2629 						goto error;
2630 				}
2631 		}
2632 	}
2633 
2634 	DBG("end of packet reached, state=%d\n", state);
2635 	goto endofpacket; /*end of packet, probably should be goto error*/
2636 
2637 endofheader:
2638 	state = saved_state;
2639 	DBG("end of header reached, state=%d\n", state);
2640 endofpacket:
2641 	/* check if error*/
2642 	switch(state) {
2643 		case P_HOST:
2644 		case L_PORT:
2645 		case P_PORT:
2646 		case L_PARAM:
2647 		case P_PARAM:
2648 		case P_VALUE:
2649 		case GEN_PARAM:
2650 		case FIN_HIDDEN:
2651 		case L_VIA:
2652 			break;
2653 		default:
2654 			LM_ERR("invalid via - end of header in state %d\n", state);
2655 			goto error;
2656 	}
2657 
2658 
2659 	/*
2660 	if (proto) printf("<SIP/2.0/%s>\n", proto);
2661 	if (host) printf("host= <%s>\n", host);
2662 	if (port_str) printf("port= <%s>\n", port_str);
2663 	if (param) printf("params= <%s>\n", param);
2664 	if (comment) printf("comment= <%s>\n", comment);
2665 	if(next_via) printf("next_via= <%s>\n", next_via);
2666 	*/
2667 	/*DBG("parse_via: rest=<%s>\n", tmp);*/
2668 
2669 	vb->error = PARSE_OK;
2670 	vb->bsize = tmp - buffer;
2671 	if(vb->port_str.s) {
2672 		vb->port = str2s(vb->port_str.s, vb->port_str.len, &err);
2673 		if(err) {
2674 			LM_ERR("invalid port number <%.*s>\n", vb->port_str.len,
2675 					ZSW(vb->port_str.s));
2676 			goto error;
2677 		}
2678 	}
2679 	return tmp;
2680 nextvia:
2681 	DBG("parsing via: next via\n");
2682 	vb->error = PARSE_OK;
2683 	vb->bsize = tmp - buffer;
2684 	if(vb->port_str.s) {
2685 		vb->port = str2s(vb->port_str.s, vb->port_str.len, &err);
2686 		if(err) {
2687 			LM_ERR("invalid port number <%.*s>\n", vb->port_str.len,
2688 					ZSW(vb->port_str.s));
2689 			goto error;
2690 		}
2691 	}
2692 	vb->next = pkg_malloc(sizeof(struct via_body));
2693 	if(vb->next == 0) {
2694 		PKG_MEM_ERROR;
2695 		goto error;
2696 	}
2697 	vb = vb->next;
2698 	memset(vb, 0, sizeof(struct via_body));
2699 	buffer = tmp;
2700 	goto parse_again;
2701 
2702 error:
2703 	if(end > buffer) {
2704 		LM_ERR("parsing via on: <%.*s>\n", (int)(end - buffer), ZSW(buffer));
2705 	}
2706 	if((tmp > buffer) && (tmp < end)) {
2707 		LM_ERR("parse error, parsed so far:<%.*s>\n", (int)(tmp - buffer),
2708 				ZSW(buffer));
2709 	} else {
2710 		LM_ERR("via parse error\n");
2711 	}
2712 	vb->error = PARSE_ERROR;
2713 	vbody->error = PARSE_ERROR; /* make sure the first via body is marked
2714 								 * as bad also */
2715 	return tmp;
2716 }
2717 
2718 
free_via_param_list(struct via_param * vp)2719 static inline void free_via_param_list(struct via_param *vp)
2720 {
2721 	struct via_param *foo;
2722 	while(vp) {
2723 		foo = vp;
2724 		vp = vp->next;
2725 		pkg_free(foo);
2726 	}
2727 }
2728 
2729 
free_via_list(struct via_body * vb)2730 void free_via_list(struct via_body *vb)
2731 {
2732 	struct via_body *foo;
2733 	while(vb) {
2734 		foo = vb;
2735 		vb = vb->next;
2736 		if(foo->param_lst)
2737 			free_via_param_list(foo->param_lst);
2738 		pkg_free(foo);
2739 	}
2740 }
2741 
parse_via_header(struct sip_msg * msg,int n,struct via_body ** q)2742 int parse_via_header(struct sip_msg *msg, int n, struct via_body **q)
2743 {
2744 	struct hdr_field *p;
2745 	struct via_body *pp = NULL;
2746 	int i;
2747 
2748 	switch(n) {
2749 		case 1:
2750 		case 2:
2751 			if(!msg->h_via1 && (parse_headers(msg, HDR_VIA_F, 0) == -1
2752 									|| !msg->h_via1)) {
2753 				DBG("bad msg or missing VIA1 header \n");
2754 				return -1;
2755 			}
2756 			pp = msg->h_via1->parsed;
2757 			if(n == 1)
2758 				break;
2759 			pp = pp->next;
2760 			if(pp)
2761 				break;
2762 
2763 			if(!msg->h_via2 && (parse_headers(msg, HDR_VIA2_F, 0) == -1
2764 									|| !msg->h_via2)) {
2765 				DBG("bad msg or missing VIA2 header \n");
2766 				return -1;
2767 			}
2768 			pp = msg->h_via2->parsed;
2769 			break;
2770 		default:
2771 			if(!msg->eoh
2772 					&& (parse_headers(msg, HDR_EOH_F, 0) == -1 || !msg->eoh)) {
2773 				ERR("bad msg while parsing to EOH \n");
2774 				return -1;
2775 			}
2776 			p = msg->h_via1;
2777 			i = n;
2778 			while(i && p) {
2779 				if(p->type == HDR_VIA_T) {
2780 					i--;
2781 					pp = p->parsed;
2782 					while(i && (pp->next)) {
2783 						i--;
2784 						pp = pp->next;
2785 					}
2786 				}
2787 				p = p->next;
2788 			}
2789 			if(i > 0) {
2790 				DBG("missing VIA[%d] header\n", n);
2791 				return -1;
2792 			}
2793 	}
2794 	if(pp) {
2795 		*q = pp;
2796 		return 0;
2797 	} else
2798 		return -1;
2799 }
2800