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