00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #include "../comp_defs.h"
00063 #include <stdlib.h>
00064 #include <string.h>
00065 #include "../dprint.h"
00066 #include "../ut.h"
00067 #include "../mem/mem.h"
00068 #include "../ip_addr.h"
00069 #include "parse_via.h"
00070 #include "parse_def.h"
00071 #include "msg_parser.h"
00072
00073
00074
00076 enum {
00077 F_HOST, P_HOST,
00078 L_PORT, F_PORT, P_PORT,
00079 L_PARAM, F_PARAM, P_PARAM,
00080 L_VIA, F_VIA,
00081 F_COMMENT, P_COMMENT,
00082 F_IP6HOST, P_IP6HOST,
00083 F_CRLF,
00084 F_LF,
00085 F_CR,
00086 END_OF_HEADER
00087 };
00088
00089
00091 enum {
00092 F_SIP = 100,
00093 SIP1, SIP2, FIN_SIP,
00094 L_VER, F_VER,
00095 VER1, VER2, FIN_VER,
00096 UDP1, UDP2, FIN_UDP,
00097 TCP_TLS1, TCP2, FIN_TCP,
00098 TLS2, FIN_TLS,
00099 SCTP1, SCTP2, SCTP3, FIN_SCTP,
00100 OTHER_PROTO,
00101 L_PROTO, F_PROTO
00102 };
00103
00104
00108 enum {
00109 L_VALUE = 200, F_VALUE, P_VALUE, P_STRING,
00110 HIDDEN1, HIDDEN2, HIDDEN3, HIDDEN4, HIDDEN5,
00111 TTL1, TTL2,
00112 BRANCH1, BRANCH2, BRANCH3, BRANCH4, BRANCH5,
00113 MADDR1, MADDR2, MADDR3, MADDR4,
00114 RECEIVED1, RECEIVED2, RECEIVED3, RECEIVED4, RECEIVED5, RECEIVED6,
00115 RECEIVED7,
00116 RPORT1, RPORT2, RPORT3,
00117 ALIAS1, ALIAS2, ALIAS3, ALIAS4,
00118 #ifdef USE_COMP
00119 COMP1, COMP2, COMP3,
00120
00121 L_COMP_VALUE, F_COMP_VALUE,
00122 V_COMP_S, V_SIGCOMP_I, V_SIGCOMP_G, V_SIGCOMP_C, V_SIGCOMP_O, V_SIGCOMP_M,
00123 FIN_V_SIGCOMP_P,
00124 V_SERGZ_E, V_SERGZ_R, V_SERGZ_G, FIN_V_SERGZ_Z,
00125 #endif
00126
00127 FIN_HIDDEN = 230, FIN_TTL, FIN_BRANCH,
00128 FIN_MADDR, FIN_RECEIVED, FIN_RPORT, FIN_I, FIN_ALIAS
00129 #ifdef USE_COMP
00130 , FIN_COMP
00131 #endif
00132
00133
00134 };
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 static char* parse_via_param(char* p, char* end,
00145 unsigned char* pstate,
00146 unsigned char* psaved_state,
00147 struct via_param* param,
00148 struct via_body* vb)
00149 {
00150 char* tmp;
00151 register unsigned char state;
00152 unsigned char saved_state;
00153
00154 #define value_case(c, C, oldstate, newstate, start_of_value) \
00155 case (c): \
00156 case (C): \
00157 switch(state){ \
00158 case (oldstate): \
00159 state=(newstate); \
00160 if ((start_of_value)) param->value.s=tmp; \
00161 break; \
00162 default_value_cases \
00163 } \
00164 break
00165
00166 #define value_case_double(c, C, oldstate1, newstate1, oldstate2, newstate2) \
00167 case (c): \
00168 case (C): \
00169 switch(state){ \
00170 case (oldstate1): \
00171 state=(newstate1); \
00172 break; \
00173 case (oldstate2): \
00174 state=(newstate2); \
00175 break; \
00176 default_value_cases \
00177 } \
00178 break
00179
00180 #define default_value_cases \
00181 case F_VALUE: \
00182 state=P_VALUE; \
00183 param->value.s=tmp; \
00184 break; \
00185 case P_VALUE: \
00186 case P_STRING: \
00187 break; \
00188 case F_LF: \
00189 case F_CR: \
00190 case F_CRLF: \
00191 state=END_OF_HEADER; \
00192 goto end_via; \
00193 default: \
00194 switch(state){ \
00195 case F_COMP_VALUE: \
00196 comp_unexpected_char; \
00197 state=P_VALUE; \
00198 param->value.s=tmp; \
00199 break; \
00200 comp_states_cases \
00201 comp_fin_states_cases \
00202 comp_unexpected_char; \
00203 state=P_VALUE; \
00204 break; \
00205 default: \
00206 LOG(L_ERR, "ERROR: parse_via_param: invalid " \
00207 "char <%c> in state %d\n", *tmp, state); \
00208 goto error; \
00209 }
00210
00211 #define comp_states_cases \
00212 case V_COMP_S: \
00213 case V_SIGCOMP_I: \
00214 case V_SIGCOMP_G: \
00215 case V_SIGCOMP_C: \
00216 case V_SIGCOMP_O: \
00217 case V_SIGCOMP_M: \
00218 case V_SERGZ_E: \
00219 case V_SERGZ_R: \
00220 case V_SERGZ_G:
00221
00222 #define comp_fin_states_cases \
00223 case FIN_V_SIGCOMP_P: \
00224 case FIN_V_SERGZ_Z:
00225
00226
00227
00228 #define comp_unexpected_char \
00229 LOG(L_ERR, "parse_via_param: bad/unrecognized" \
00230 " comp method\n"); \
00231 vb->comp_no=0
00232
00233
00234
00235 state=*pstate;
00236 saved_state=*psaved_state;
00237 param->type=PARAM_ERROR;
00238
00239 for (tmp=p;tmp<end;tmp++){
00240 switch(*tmp){
00241 case ' ':
00242 case '\t':
00243 switch(state){
00244 case FIN_HIDDEN:
00245 case FIN_ALIAS:
00246 param->type=state;
00247 param->name.len=tmp-param->name.s;
00248 state=L_PARAM;
00249 goto endofparam;
00250 case FIN_BRANCH:
00251 case FIN_TTL:
00252 case FIN_MADDR:
00253 case FIN_RECEIVED:
00254 case FIN_RPORT:
00255 case FIN_I:
00256 param->type=state;
00257 param->name.len=tmp-param->name.s;
00258 state=L_VALUE;
00259 goto find_value;
00260 #ifdef USE_COMP
00261 case FIN_COMP:
00262 param->type=state;
00263 param->name.len=tmp-param->name.s;
00264 state=L_COMP_VALUE;
00265 goto find_value;
00266 #endif
00267 case F_PARAM:
00268 break;
00269 case F_LF:
00270 case F_CR:
00271 case F_CRLF:
00272 state=saved_state;
00273 break;
00274 case GEN_PARAM:
00275 default:
00276 param->type=GEN_PARAM;
00277 param->name.len=tmp-param->name.s;
00278 state=L_VALUE;
00279 goto find_value;
00280 }
00281 break;
00282
00283 case '\n':
00284 switch(state){
00285 case FIN_HIDDEN:
00286 case FIN_ALIAS:
00287 param->type=state;
00288 param->name.len=tmp-param->name.s;
00289 param->size=tmp-param->start;
00290 saved_state=L_PARAM;
00291 state=F_LF;
00292 goto endofparam;
00293 case FIN_BRANCH:
00294 case FIN_TTL:
00295 case FIN_MADDR:
00296 case FIN_RECEIVED:
00297 case FIN_I:
00298 case FIN_RPORT:
00299 param->type=state;
00300 param->name.len=tmp-param->name.s;
00301 param->size=tmp-param->start;
00302 saved_state=L_VALUE;
00303 state=F_LF;
00304 goto find_value;
00305 #ifdef USE_COMP
00306 case FIN_COMP:
00307 param->type=state;
00308 param->name.len=tmp-param->name.s;
00309 param->size=tmp-param->start;
00310 saved_state=L_COMP_VALUE;
00311 state=F_LF;
00312 goto find_value;
00313 #endif
00314 case F_PARAM:
00315 saved_state=state;
00316 state=F_LF;
00317 break;
00318 case F_LF:
00319 case F_CRLF:
00320 state=END_OF_HEADER;
00321 goto end_via;
00322 case F_CR:
00323 state=F_CRLF;
00324 break;
00325 case GEN_PARAM:
00326 default:
00327 param->type=GEN_PARAM;
00328 saved_state=L_VALUE;
00329 param->name.len=tmp-param->name.s;
00330 param->size=tmp-param->start;
00331 state=F_LF;
00332 goto find_value;
00333 }
00334 break;
00335 case '\r':
00336 switch(state){
00337 case FIN_HIDDEN:
00338 case FIN_ALIAS:
00339 param->type=state;
00340 param->name.len=tmp-param->name.s;
00341 param->size=tmp-param->start;
00342 saved_state=L_PARAM;
00343 state=F_CR;
00344 goto endofparam;
00345 case FIN_BRANCH:
00346 case FIN_TTL:
00347 case FIN_MADDR:
00348 case FIN_RECEIVED:
00349 case FIN_I:
00350 case FIN_RPORT:
00351 param->type=state;
00352 param->name.len=tmp-param->name.s;
00353 param->size=tmp-param->start;
00354 saved_state=L_VALUE;
00355 state=F_CR;
00356 goto find_value;
00357 #ifdef USE_COMP
00358 case FIN_COMP:
00359 param->type=state;
00360 param->name.len=tmp-param->name.s;
00361 param->size=tmp-param->start;
00362 saved_state=L_COMP_VALUE;
00363 state=F_LF;
00364 goto find_value;
00365 #endif
00366 case F_PARAM:
00367 saved_state=state;
00368 state=F_CR;
00369 break;
00370 case F_CR:
00371 case F_CRLF:
00372 state=END_OF_HEADER;
00373 goto end_via;
00374 case GEN_PARAM:
00375 default:
00376 param->type=GEN_PARAM;
00377 param->name.len=tmp-param->name.s;
00378 param->size=tmp-param->start;
00379 saved_state=L_VALUE;
00380 state=F_CR;
00381 goto find_value;
00382 }
00383 break;
00384
00385 case '=':
00386 switch(state){
00387 case FIN_BRANCH:
00388 case FIN_TTL:
00389 case FIN_MADDR:
00390 case FIN_RECEIVED:
00391 case FIN_RPORT:
00392 case FIN_I:
00393 param->type=state;
00394 param->name.len=tmp-param->name.s;
00395 state=F_VALUE;
00396 goto find_value;
00397 #ifdef USE_COMP
00398 case FIN_COMP:
00399 param->type=state;
00400 param->name.len=tmp-param->name.s;
00401 state=F_COMP_VALUE;
00402 goto find_value;
00403 #endif
00404 case F_PARAM:
00405 case FIN_HIDDEN:
00406 case FIN_ALIAS:
00407 LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
00408 " state %d\n", *tmp, state);
00409 goto error;
00410 case F_CR:
00411 case F_LF:
00412 case F_CRLF:
00413 state=END_OF_HEADER;
00414 goto end_via;
00415 case GEN_PARAM:
00416 default:
00417 param->type=GEN_PARAM;
00418 param->name.len=tmp-param->name.s;
00419 state=F_VALUE;
00420 goto find_value;
00421 }
00422 break;
00423 case ';':
00424 switch(state){
00425 case FIN_HIDDEN:
00426 case FIN_RPORT:
00427 case FIN_ALIAS:
00428 param->type=state;
00429 param->name.len=tmp-param->name.s;
00430 state=F_PARAM;
00431 goto endofparam;
00432 case FIN_BRANCH:
00433 case FIN_MADDR:
00434 case FIN_TTL:
00435 case FIN_RECEIVED:
00436 case FIN_I:
00437 #ifdef USE_COMP
00438 case FIN_COMP:
00439 #endif
00440 LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
00441 " state %d\n", *tmp, state);
00442 goto error;
00443 case F_CR:
00444 case F_LF:
00445 case F_CRLF:
00446 state=END_OF_HEADER;
00447 goto end_via;
00448 case GEN_PARAM:
00449 default:
00450 param->type=GEN_PARAM;
00451 param->name.len=tmp-param->name.s;
00452 state=F_PARAM;
00453 goto endofparam;
00454 }
00455 break;
00456 case ',':
00457 switch(state){
00458 case FIN_HIDDEN:
00459 case FIN_RPORT:
00460 case FIN_ALIAS:
00461 param->type=state;
00462 param->name.len=tmp-param->name.s;
00463 state=F_VIA;
00464 goto endofvalue;
00465 case FIN_BRANCH:
00466 case FIN_MADDR:
00467 case FIN_TTL:
00468 case FIN_RECEIVED:
00469 case FIN_I:
00470 #ifdef USE_COMP
00471 case FIN_COMP:
00472 #endif
00473 LOG(L_ERR, "ERROR: parse_via_param: new via found"
00474 "(',') when '=' expected (state %d=)\n",
00475 state);
00476 goto error;
00477 case F_CR:
00478 case F_LF:
00479 case F_CRLF:
00480 state=END_OF_HEADER;
00481 goto end_via;
00482 case GEN_PARAM:
00483 default:
00484 param->type=GEN_PARAM;
00485 param->name.len=tmp-param->name.s;
00486 state=F_VIA;
00487 goto endofvalue;
00488 }
00489 break;
00490
00491
00492 case 'h':
00493 case 'H':
00494 switch(state){
00495 case F_PARAM:
00496 state=HIDDEN1;
00497 param->name.s=tmp;
00498 break;
00499 case BRANCH5:
00500 state=FIN_BRANCH;
00501 break;
00502 case GEN_PARAM:
00503 break;
00504 case F_CR:
00505 case F_LF:
00506 case F_CRLF:
00507 state=END_OF_HEADER;
00508 goto end_via;
00509 default:
00510 state=GEN_PARAM;
00511 }
00512 break;
00513 case 'i':
00514 case 'I':
00515 switch(state){
00516 case F_PARAM:
00517 state=FIN_I;
00518 param->name.s=tmp;
00519 break;
00520 case HIDDEN1:
00521 state=HIDDEN2;
00522 break;
00523 case RECEIVED4:
00524 state=RECEIVED5;
00525 break;
00526 case ALIAS2:
00527 state=ALIAS3;
00528 break;
00529 case GEN_PARAM:
00530 break;
00531 case F_CR:
00532 case F_LF:
00533 case F_CRLF:
00534 state=END_OF_HEADER;
00535 goto end_via;
00536 default:
00537 state=GEN_PARAM;
00538 }
00539 break;
00540 case 'd':
00541 case 'D':
00542 switch(state){
00543 case F_PARAM:
00544 state=GEN_PARAM;
00545 param->name.s=tmp;
00546 break;
00547 case HIDDEN2:
00548 state=HIDDEN3;
00549 break;
00550 case HIDDEN3:
00551 state=HIDDEN4;
00552 break;
00553 case MADDR2:
00554 state=MADDR3;
00555 break;
00556 case MADDR3:
00557 state=MADDR4;
00558 break;
00559 case RECEIVED7:
00560 state=FIN_RECEIVED;
00561 break;
00562 case GEN_PARAM:
00563 break;
00564 case F_CR:
00565 case F_LF:
00566 case F_CRLF:
00567 state=END_OF_HEADER;
00568 goto end_via;
00569 default:
00570 state=GEN_PARAM;
00571 }
00572 break;
00573 case 'e':
00574 case 'E':
00575 switch(state){
00576 case F_PARAM:
00577 state=GEN_PARAM;
00578 param->name.s=tmp;
00579 break;
00580 case HIDDEN4:
00581 state=HIDDEN5;
00582 break;
00583 case RECEIVED1:
00584 state=RECEIVED2;
00585 break;
00586 case RECEIVED3:
00587 state=RECEIVED4;
00588 break;
00589 case RECEIVED6:
00590 state=RECEIVED7;
00591 break;
00592 case GEN_PARAM:
00593 break;
00594 case F_CR:
00595 case F_LF:
00596 case F_CRLF:
00597 state=END_OF_HEADER;
00598 goto end_via;
00599 default:
00600 state=GEN_PARAM;
00601 }
00602 break;
00603 case 'n':
00604 case 'N':
00605 switch(state){
00606 case F_PARAM:
00607 state=GEN_PARAM;
00608 param->name.s=tmp;
00609 break;
00610 case HIDDEN5:
00611 state=FIN_HIDDEN;
00612 break;
00613 case BRANCH3:
00614 state=BRANCH4;
00615 break;
00616 case GEN_PARAM:
00617 break;
00618 case F_CR:
00619 case F_LF:
00620 case F_CRLF:
00621 state=END_OF_HEADER;
00622 goto end_via;
00623 default:
00624 state=GEN_PARAM;
00625 }
00626 break;
00627 case 't':
00628 case 'T':
00629 switch(state){
00630 case F_PARAM:
00631 state=TTL1;
00632 param->name.s=tmp;
00633 break;
00634 case TTL1:
00635 state=TTL2;
00636 break;
00637 case RPORT3:
00638 state=FIN_RPORT;
00639 break;
00640 case GEN_PARAM:
00641 break;
00642 case F_CR:
00643 case F_LF:
00644 case F_CRLF:
00645 state=END_OF_HEADER;
00646 goto end_via;
00647 default:
00648 state=GEN_PARAM;
00649 }
00650 break;
00651 case 'l':
00652 case 'L':
00653 switch(state){
00654 case F_PARAM:
00655 state=GEN_PARAM;
00656 param->name.s=tmp;
00657 break;
00658 case TTL2:
00659 state=FIN_TTL;
00660 break;
00661 case ALIAS1:
00662 state=ALIAS2;
00663 break;
00664 case GEN_PARAM:
00665 break;
00666 case F_CR:
00667 case F_LF:
00668 case F_CRLF:
00669 state=END_OF_HEADER;
00670 goto end_via;
00671 default:
00672 state=GEN_PARAM;
00673 }
00674 break;
00675 case 'm':
00676 case 'M':
00677 switch(state){
00678 case F_PARAM:
00679 state=MADDR1;
00680 param->name.s=tmp;
00681 break;
00682 #ifdef USE_COMP
00683 case COMP2:
00684 state=COMP3;
00685 break;
00686 #endif
00687 case GEN_PARAM:
00688 break;
00689 case F_CR:
00690 case F_LF:
00691 case F_CRLF:
00692 state=END_OF_HEADER;
00693 goto end_via;
00694 default:
00695 state=GEN_PARAM;
00696 }
00697 break;
00698 case 'a':
00699 case 'A':
00700 switch(state){
00701 case F_PARAM:
00702 state=ALIAS1;
00703 param->name.s=tmp;
00704 break;
00705 case MADDR1:
00706 state=MADDR2;
00707 break;
00708 case BRANCH2:
00709 state=BRANCH3;
00710 break;
00711 case ALIAS3:
00712 state=ALIAS4;
00713 break;
00714 case GEN_PARAM:
00715 break;
00716 case F_CR:
00717 case F_LF:
00718 case F_CRLF:
00719 state=END_OF_HEADER;
00720 goto end_via;
00721 default:
00722 state=GEN_PARAM;
00723 }
00724 break;
00725 case 'r':
00726 case 'R':
00727 switch(state){
00728 case MADDR4:
00729 state=FIN_MADDR;
00730 break;
00731 case F_PARAM:
00732 state=RECEIVED1;
00733 param->name.s=tmp;
00734 break;
00735 case BRANCH1:
00736 state=BRANCH2;
00737 break;
00738 case RPORT2:
00739 state=RPORT3;
00740 break;
00741 case GEN_PARAM:
00742 break;
00743 case F_CR:
00744 case F_LF:
00745 case F_CRLF:
00746 state=END_OF_HEADER;
00747 goto end_via;
00748 default:
00749 state=GEN_PARAM;
00750 }
00751 break;
00752 case 'c':
00753 case 'C':
00754 switch(state){
00755 case F_PARAM:
00756 #ifdef USE_COMP
00757 state=COMP1;
00758 #else
00759 state=GEN_PARAM;
00760 #endif
00761 param->name.s=tmp;
00762 break;
00763 case RECEIVED2:
00764 state=RECEIVED3;
00765 break;
00766 case BRANCH4:
00767 state=BRANCH5;
00768 break;
00769 case GEN_PARAM:
00770 break;
00771 case F_CR:
00772 case F_LF:
00773 case F_CRLF:
00774 state=END_OF_HEADER;
00775 goto end_via;
00776 default:
00777 state=GEN_PARAM;
00778 }
00779 break;
00780 case 'v':
00781 case 'V':
00782 switch(state){
00783 case F_PARAM:
00784 state=GEN_PARAM;
00785 param->name.s=tmp;
00786 break;
00787 case RECEIVED5:
00788 state=RECEIVED6;
00789 break;
00790 case GEN_PARAM:
00791 break;
00792 case F_CR:
00793 case F_LF:
00794 case F_CRLF:
00795 state=END_OF_HEADER;
00796 goto end_via;
00797 default:
00798 state=GEN_PARAM;
00799 }
00800 break;
00801 case 'b':
00802 case 'B':
00803 switch(state){
00804 case F_PARAM:
00805 state=BRANCH1;
00806 param->name.s=tmp;
00807 break;
00808 case GEN_PARAM:
00809 break;
00810 case F_CR:
00811 case F_LF:
00812 case F_CRLF:
00813 state=END_OF_HEADER;
00814 goto end_via;
00815 default:
00816 state=GEN_PARAM;
00817 }
00818 break;
00819 case 'p':
00820 case 'P':
00821 switch(state){
00822 case F_PARAM:
00823 state=GEN_PARAM;
00824 param->name.s=tmp;
00825 break;
00826 case RECEIVED1:
00827 state=RPORT1;
00828 break;
00829 #ifdef USE_COMP
00830 case COMP3:
00831 state=FIN_COMP;
00832 break;
00833 #endif
00834 case F_CR:
00835 case F_LF:
00836 case F_CRLF:
00837 state=END_OF_HEADER;
00838 goto end_via;
00839 default:
00840 state=GEN_PARAM;
00841 }
00842 break;
00843 case 'o':
00844 case 'O':
00845 switch(state){
00846 case F_PARAM:
00847 state=GEN_PARAM;
00848 param->name.s=tmp;
00849 break;
00850 case RPORT1:
00851 state=RPORT2;
00852 break;
00853 #ifdef USE_COMP
00854 case COMP1:
00855 state=COMP2;
00856 break;
00857 #endif
00858 case F_CR:
00859 case F_LF:
00860 case F_CRLF:
00861 state=END_OF_HEADER;
00862 goto end_via;
00863 default:
00864 state=GEN_PARAM;
00865 }
00866 break;
00867 case 's':
00868 case 'S':
00869 switch(state){
00870 case F_PARAM:
00871 state=GEN_PARAM;
00872 param->name.s=tmp;
00873 break;
00874 case ALIAS4:
00875 state=FIN_ALIAS;
00876 break;
00877 case F_CR:
00878 case F_LF:
00879 case F_CRLF:
00880 state=END_OF_HEADER;
00881 goto end_via;
00882 default:
00883 state=GEN_PARAM;
00884 }
00885 break;
00886 default:
00887 switch(state){
00888 case F_PARAM:
00889 state=GEN_PARAM;
00890 param->name.s=tmp;
00891 break;
00892 case GEN_PARAM:
00893 break;
00894 case F_CR:
00895 case F_LF:
00896 case F_CRLF:
00897 state=END_OF_HEADER;
00898 goto end_via;
00899 default:
00900 state=GEN_PARAM;
00901 }
00902 }
00903 }
00904
00905
00906 saved_state=state;
00907 state=END_OF_HEADER;
00908 goto error;
00909
00910 find_value:
00911 tmp++;
00912 for(;*tmp;tmp++){
00913 switch(*tmp){
00914 case ' ':
00915 case '\t':
00916 switch(state){
00917 case L_VALUE:
00918 case F_VALUE:
00919 break;
00920 case P_VALUE:
00921 state=L_PARAM;
00922 param->value.len=tmp-param->value.s;
00923 goto endofvalue;
00924 #ifdef USE_COMP
00925 case L_COMP_VALUE:
00926 case F_COMP_VALUE:
00927 break;
00928 case FIN_V_SIGCOMP_P:
00929 state=L_PARAM;
00930 param->value.len=tmp-param->value.s;
00931 vb->comp_no=COMP_SIGCOMP;
00932 goto endofvalue;
00933 case FIN_V_SERGZ_Z:
00934 state=L_PARAM;
00935 param->value.len=tmp-param->value.s;
00936 vb->comp_no=COMP_SIGCOMP;
00937 goto endofvalue;
00938 comp_states_cases
00939 state=L_PARAM;
00940 param->value.len=tmp-param->value.s;
00941 comp_unexpected_char;
00942 goto endofvalue;
00943 #endif
00944 case P_STRING:
00945 break;
00946 case F_CR:
00947 case F_LF:
00948 case F_CRLF:
00949 state=saved_state;
00950 break;
00951 default:
00952 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
00953 " in state %d\n", *tmp, state);
00954 goto error;
00955 }
00956 break;
00957 case '\n':
00958 switch(state){
00959 case L_VALUE:
00960 case F_VALUE:
00961 #ifdef USE_COMP
00962 case L_COMP_VALUE:
00963 case F_COMP_VALUE:
00964 #endif
00965 case P_STRING:
00966 saved_state=state;
00967 param->size=tmp-param->start;
00968 state=F_LF;
00969 break;
00970 case P_VALUE:
00971 saved_state=L_PARAM;
00972 state=F_LF;
00973 param->value.len=tmp-param->value.s;
00974 goto endofvalue;
00975 #ifdef USE_COMP
00976 case FIN_V_SIGCOMP_P:
00977 saved_state=L_PARAM;
00978 state=F_LF;
00979 param->value.len=tmp-param->value.s;
00980 vb->comp_no=COMP_SIGCOMP;
00981 goto endofvalue;
00982 case FIN_V_SERGZ_Z:
00983 saved_state=L_PARAM;
00984 state=F_LF;
00985 param->value.len=tmp-param->value.s;
00986 vb->comp_no=COMP_SIGCOMP;
00987 goto endofvalue;
00988 comp_states_cases
00989 saved_state=L_PARAM;
00990 state=F_LF;
00991 param->value.len=tmp-param->value.s;
00992 comp_unexpected_char;
00993 goto endofvalue;
00994 #endif
00995 case F_LF:
00996 case F_CRLF:
00997 state=END_OF_HEADER;
00998 goto end_via;
00999 case F_CR:
01000 state=F_CRLF;
01001 break;
01002 default:
01003 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
01004 " in state %d\n", *tmp, state);
01005 goto error;
01006 }
01007 break;
01008 case '\r':
01009 switch(state){
01010 case L_VALUE:
01011 case F_VALUE:
01012 #ifdef USE_COMP
01013 case L_COMP_VALUE:
01014 case F_COMP_VALUE:
01015 #endif
01016 case P_STRING:
01017 saved_state=state;
01018 param->size=tmp-param->start;
01019 state=F_CR;
01020 break;
01021 case P_VALUE:
01022 param->value.len=tmp-param->value.s;
01023 saved_state=L_PARAM;
01024 state=F_CR;
01025 goto endofvalue;
01026 #ifdef USE_COMP
01027 case FIN_V_SIGCOMP_P:
01028 saved_state=L_PARAM;
01029 state=F_CR;
01030 param->value.len=tmp-param->value.s;
01031 vb->comp_no=COMP_SIGCOMP;
01032 goto endofvalue;
01033 case FIN_V_SERGZ_Z:
01034 saved_state=L_PARAM;
01035 state=F_CR;
01036 param->value.len=tmp-param->value.s;
01037 vb->comp_no=COMP_SIGCOMP;
01038 goto endofvalue;
01039 comp_states_cases
01040 saved_state=L_PARAM;
01041 state=F_CR;
01042 param->value.len=tmp-param->value.s;
01043 comp_unexpected_char;
01044 goto endofvalue;
01045 #endif
01046 case F_LF:
01047 case F_CR:
01048 case F_CRLF:
01049 state=END_OF_HEADER;
01050 goto end_via;
01051 default:
01052 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
01053 " in state %d\n", *tmp, state);
01054 goto error;
01055 }
01056 break;
01057
01058 case '=':
01059 switch(state){
01060 case L_VALUE:
01061 state=F_VALUE;
01062 break;
01063 #ifdef USE_COMP
01064 case L_COMP_VALUE:
01065 state=F_COMP_VALUE;
01066 break;
01067
01068
01069 #endif
01070 case P_STRING:
01071 break;
01072 case F_LF:
01073 case F_CR:
01074 case F_CRLF:
01075 state=END_OF_HEADER;
01076 goto end_via;
01077 default:
01078 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
01079 " in state %d\n", *tmp, state);
01080 goto error;
01081 }
01082 break;
01083 case ';':
01084 switch(state){
01085 case P_VALUE:
01086 param->value.len=tmp-param->value.s;
01087 state=F_PARAM;
01088 goto endofvalue;
01089 case F_VALUE:
01090 param->value.len=0;
01091 state=F_PARAM;
01092 goto endofvalue;
01093 case P_STRING:
01094 break;
01095 case F_LF:
01096 case F_CR:
01097 case F_CRLF:
01098 state=END_OF_HEADER;
01099 goto end_via;
01100 #ifdef USE_COMP
01101 case L_COMP_VALUE:
01102 comp_unexpected_char;
01103
01104 state=F_PARAM;
01105 param->value.len=0;
01106 param->value.s=0;
01107 goto endofvalue;
01108 case F_COMP_VALUE:
01109 comp_unexpected_char;
01110 param->value.len=0;
01111 state=F_PARAM;
01112 goto endofvalue;
01113 comp_states_cases
01114 comp_unexpected_char;
01115 param->value.len=tmp-param->value.s;
01116 state=F_PARAM;
01117 goto endofvalue;
01118 case FIN_V_SIGCOMP_P:
01119 vb->comp_no=COMP_SIGCOMP;
01120 param->value.len=tmp-param->value.s;
01121 state=F_PARAM;
01122 goto endofvalue;
01123 case FIN_V_SERGZ_Z:
01124 vb->comp_no=COMP_SIGCOMP;
01125 param->value.len=tmp-param->value.s;
01126 state=F_PARAM;
01127 goto endofvalue;
01128 #endif
01129 case L_VALUE:
01130 if (param->type==FIN_RPORT){
01131 param->value.len=0;
01132 param->value.s=0;
01133 state=F_PARAM;
01134 goto endofvalue;
01135 };
01136
01137 default:
01138 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
01139 " in state %d\n", *tmp, state);
01140 goto error;
01141 }
01142 break;
01143 case ',':
01144 switch(state){
01145 case P_VALUE:
01146 param->value.len=tmp-param->value.s;
01147 state=F_VIA;
01148 goto endofvalue;
01149 case P_STRING:
01150 case F_LF:
01151 case F_CR:
01152 case F_CRLF:
01153 state=END_OF_HEADER;
01154 goto end_via;
01155 #ifdef USE_COMP
01156 case L_COMP_VALUE:
01157 comp_unexpected_char;
01158
01159 state=F_VIA;
01160 param->value.len=0;
01161 param->value.s=0;
01162 goto endofvalue;
01163 case F_COMP_VALUE:
01164 comp_unexpected_char;
01165 param->value.len=0;
01166 state=F_VIA;
01167 goto endofvalue;
01168 comp_states_cases
01169 comp_unexpected_char;
01170 param->value.len=tmp-param->value.s;
01171 state=F_VIA;
01172 goto endofvalue;
01173 case FIN_V_SIGCOMP_P:
01174 vb->comp_no=COMP_SIGCOMP;
01175 param->value.len=tmp-param->value.s;
01176 state=F_VIA;
01177 goto endofvalue;
01178 case FIN_V_SERGZ_Z:
01179 vb->comp_no=COMP_SIGCOMP;
01180 param->value.len=tmp-param->value.s;
01181 state=F_VIA;
01182 goto endofvalue;
01183 #endif
01184 case L_VALUE:
01185 if (param->type==FIN_RPORT){
01186 param->value.len=0;
01187 param->value.s=0;
01188 state=F_VIA;
01189 goto endofvalue;
01190 };
01191
01192 default:
01193 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
01194 " in state %d\n", *tmp, state);
01195 goto error;
01196 }
01197 break;
01198 case '"':
01199 switch(state){
01200 case F_VALUE:
01201 state=P_STRING;
01202 param->value.s=tmp+1;
01203 break;
01204 case P_STRING:
01205 state=L_PARAM;
01206 param->value.len=tmp-param->value.s;
01207 goto endofvalue;
01208 case F_LF:
01209 case F_CR:
01210 case F_CRLF:
01211 state=END_OF_HEADER;
01212 goto end_via;
01213 default:
01214 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
01215 " in state %d\n", *tmp, state);
01216 goto error;
01217 }
01218 break;
01219 #ifdef USE_COMP
01220 value_case('s', 'S', F_COMP_VALUE, V_COMP_S, 1);
01221 value_case('i', 'I', V_COMP_S, V_SIGCOMP_I, 0);
01222 value_case_double('g', 'G', V_SIGCOMP_I, V_SIGCOMP_G,
01223 V_SERGZ_R, V_SERGZ_G);
01224 value_case('c', 'C', V_SIGCOMP_G, V_SIGCOMP_C, 0);
01225 value_case('o', 'O', V_SIGCOMP_C, V_SIGCOMP_O, 0);
01226 value_case('m', 'M', V_SIGCOMP_O, V_SIGCOMP_M, 0);
01227 value_case('p', 'P', V_SIGCOMP_M, FIN_V_SIGCOMP_P, 0);
01228
01229 value_case('e', 'E', V_COMP_S, V_SERGZ_E, 0);
01230 value_case('r', 'R', V_SERGZ_E, V_SERGZ_R, 0);
01231 value_case('z', 'Z', V_SERGZ_G, FIN_V_SERGZ_Z, 0);
01232 #endif
01233
01234 default:
01235 switch(state){
01236 case F_VALUE:
01237 state=P_VALUE;
01238 param->value.s=tmp;
01239 break;
01240 case P_VALUE:
01241 case P_STRING:
01242 break;
01243 case F_LF:
01244 case F_CR:
01245 case F_CRLF:
01246 state=END_OF_HEADER;
01247 goto end_via;
01248 default:
01249 #ifdef USE_COMP
01250 switch(state){
01251 case F_COMP_VALUE:
01252 comp_unexpected_char;
01253 state=P_VALUE;
01254 param->value.s=tmp;
01255 break;
01256 comp_states_cases
01257 comp_fin_states_cases
01258 comp_unexpected_char;
01259 state=P_VALUE;
01260 break;
01261 default:
01262 LOG(L_ERR, "ERROR: parse_via_param: invalid "
01263 "char <%c> in state %d\n", *tmp, state);
01264 goto error;
01265 }
01266 #else
01267 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
01268 " in state %d\n", *tmp, state);
01269 goto error;
01270 #endif
01271 }
01272 }
01273 }
01274
01275
01276 saved_state=state;
01277 state=END_OF_HEADER;
01278 goto error;
01279
01280 endofparam:
01281 endofvalue:
01282 param->size=tmp-param->start;
01283 normal_exit:
01284 *pstate=state;
01285 *psaved_state=saved_state;
01286 DBG("Found param type %d, <%.*s> = <%.*s>; state=%d\n", param->type,
01287 param->name.len, ZSW(param->name.s),
01288 (param->value.len?param->value.len:3),
01289 (param->value.len?param->value.s:"n/a"), state);
01290 return tmp;
01291
01292 end_via:
01293
01294
01295
01296
01297 if ((param->type==GEN_PARAM)||(param->type==PARAM_RPORT)){
01298 saved_state=L_PARAM;
01299
01300
01301 goto normal_exit;
01302 }
01303 *pstate=state;
01304 *psaved_state=saved_state;
01305 DBG("Error on param type %d, <%.*s>, state=%d, saved_state=%d\n",
01306 param->type, param->name.len, ZSW(param->name.s), state, saved_state);
01307
01308 error:
01309 LOG(L_ERR, "error: parse_via_param\n");
01310 param->type=PARAM_ERROR;
01311 *pstate=PARAM_ERROR;
01312 *psaved_state=state;
01313 return tmp;
01314 }
01315
01316
01317
01318
01319
01320
01321
01322
01323 char* parse_via(char* buffer, char* end, struct via_body *vbody)
01324 {
01325 char* tmp;
01326 char* param_start;
01327 unsigned char state;
01328 unsigned char saved_state;
01329 int c_nest;
01330 int err;
01331 struct via_body* vb;
01332 struct via_param* param;
01333
01334 vb=vbody;
01335
01336 parse_again:
01337 vb->error=PARSE_ERROR;
01338
01339 state=F_SIP;
01340 saved_state=F_SIP;
01341 param_start=0;
01342 for(tmp=buffer;tmp<end;tmp++){
01343 switch(*tmp){
01344 case ' ':
01345 case'\t':
01346 switch(state){
01347 case L_VER:
01348 case L_PROTO:
01349 case F_SIP:
01350 case F_VER:
01351 case F_PROTO:
01352 break;
01353 case FIN_UDP:
01354 vb->transport.len=tmp-vb->transport.s;
01355 vb->proto=PROTO_UDP;
01356 state=F_HOST;
01357 goto main_via;
01358 case FIN_TCP:
01359
01360 vb->transport.len=tmp-vb->transport.s;
01361 vb->proto=PROTO_TCP;
01362 state=F_HOST;
01363 goto main_via;
01364 case FIN_TLS:
01365
01366 vb->transport.len=tmp-vb->transport.s;
01367 vb->proto=PROTO_TLS;
01368 state=F_HOST;
01369 goto main_via;
01370 case FIN_SCTP:
01371
01372 vb->transport.len=tmp-vb->transport.s;
01373 vb->proto=PROTO_SCTP;
01374 state=F_HOST;
01375 goto main_via;
01376 case OTHER_PROTO:
01377
01378 vb->transport.len=tmp-vb->transport.s;
01379 vb->proto=PROTO_OTHER;
01380 state=F_HOST;
01381 goto main_via;
01382 case UDP1:
01383 case UDP2:
01384 case TCP_TLS1:
01385 case TCP2:
01386 case TLS2:
01387 case SCTP1:
01388 case SCTP2:
01389 case SCTP3:
01390
01391 vb->transport.len=tmp-vb->transport.s;
01392 vb->proto=PROTO_OTHER;
01393 state=F_HOST;
01394 goto main_via;
01395 case FIN_SIP:
01396 vb->name.len=tmp-vb->name.s;
01397 state=L_VER;
01398 break;
01399 case FIN_VER:
01400 vb->version.len=tmp-vb->version.s;
01401 state=L_PROTO;
01402 break;
01403 case F_LF:
01404 case F_CRLF:
01405 case F_CR:
01406 state=saved_state;
01407 break;
01408 default:
01409 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01410 " state %d\n", *tmp, state);
01411 goto error;
01412 }
01413 break;
01414 case '\n':
01415 switch(state){
01416 case L_VER:
01417 case F_SIP:
01418 case F_VER:
01419 case F_PROTO:
01420 case L_PROTO:
01421 saved_state=state;
01422 state=F_LF;
01423 break;
01424 case FIN_UDP:
01425 vb->transport.len=tmp-vb->transport.s;
01426 vb->proto=PROTO_UDP;
01427 state=F_LF;
01428 saved_state=F_HOST;
01429 goto main_via;
01430 case FIN_TCP:
01431 vb->transport.len=tmp-vb->transport.s;
01432 vb->proto=PROTO_TCP;
01433 state=F_LF;
01434 saved_state=F_HOST;
01435 goto main_via;
01436 case FIN_TLS:
01437 vb->transport.len=tmp-vb->transport.s;
01438 vb->proto=PROTO_TLS;
01439 state=F_LF;
01440 saved_state=F_HOST;
01441 goto main_via;
01442 case FIN_SCTP:
01443
01444 vb->transport.len=tmp-vb->transport.s;
01445 vb->proto=PROTO_SCTP;
01446 state=F_LF;
01447 saved_state=F_HOST;
01448 goto main_via;
01449 case OTHER_PROTO:
01450
01451 vb->transport.len=tmp-vb->transport.s;
01452 vb->proto=PROTO_OTHER;
01453 state=F_LF;
01454 saved_state=F_HOST;
01455 goto main_via;
01456 case UDP1:
01457 case UDP2:
01458 case TCP_TLS1:
01459 case TCP2:
01460 case TLS2:
01461 case SCTP1:
01462 case SCTP2:
01463 case SCTP3:
01464
01465 vb->transport.len=tmp-vb->transport.s;
01466 vb->proto=PROTO_OTHER;
01467 state=F_LF;
01468 saved_state=F_HOST;
01469 goto main_via;
01470 case FIN_SIP:
01471 vb->name.len=tmp-vb->name.s;
01472 state=F_LF;
01473 saved_state=L_VER;
01474 break;
01475 case FIN_VER:
01476 vb->version.len=tmp-vb->version.s;
01477 state=F_LF;
01478 saved_state=L_PROTO;
01479 break;
01480 case F_CR:
01481 state=F_CRLF;
01482 break;
01483 case F_LF:
01484 case F_CRLF:
01485 state=saved_state;
01486 goto endofheader;
01487 default:
01488 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01489 " state %d\n", *tmp, state);
01490 goto error;
01491 }
01492 break;
01493 case '\r':
01494 switch(state){
01495 case L_VER:
01496 case F_SIP:
01497 case F_VER:
01498 case F_PROTO:
01499 case L_PROTO:
01500 saved_state=state;
01501 state=F_CR;
01502 break;
01503 case FIN_UDP:
01504 vb->transport.len=tmp-vb->transport.s;
01505 vb->proto=PROTO_UDP;
01506 state=F_CR;
01507 saved_state=F_HOST;
01508 goto main_via;
01509 case FIN_TCP:
01510 vb->transport.len=tmp-vb->transport.s;
01511 vb->proto=PROTO_TCP;
01512 state=F_CR;
01513 saved_state=F_HOST;
01514 goto main_via;
01515 case FIN_TLS:
01516 vb->transport.len=tmp-vb->transport.s;
01517 vb->proto=PROTO_TLS;
01518 state=F_CR;
01519 saved_state=F_HOST;
01520 goto main_via;
01521 case FIN_SCTP:
01522 vb->transport.len=tmp-vb->transport.s;
01523 vb->proto=PROTO_SCTP;
01524 state=F_CR;
01525 saved_state=F_HOST;
01526 goto main_via;
01527 case OTHER_PROTO:
01528 vb->transport.len=tmp-vb->transport.s;
01529 vb->proto=PROTO_OTHER;
01530 state=F_CR;
01531 saved_state=F_HOST;
01532 goto main_via;
01533 case UDP1:
01534 case UDP2:
01535 case TCP_TLS1:
01536 case TCP2:
01537 case TLS2:
01538 case SCTP1:
01539 case SCTP2:
01540 case SCTP3:
01541
01542 vb->transport.len=tmp-vb->transport.s;
01543 vb->proto=PROTO_OTHER;
01544 state=F_CR;
01545 saved_state=F_HOST;
01546 goto main_via;
01547 case FIN_SIP:
01548 vb->name.len=tmp-vb->name.s;
01549 state=F_CR;
01550 saved_state=L_VER;
01551 break;
01552 case FIN_VER:
01553 vb->version.len=tmp-vb->version.s;
01554 state=F_CR;
01555 saved_state=L_PROTO;
01556 break;
01557 case F_LF:
01558 case F_CR:
01559 case F_CRLF:
01560 state=saved_state;
01561 goto endofheader;
01562 default:
01563 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01564 " state %d\n", *tmp, state);
01565 goto error;
01566 }
01567 break;
01568
01569 case '/':
01570 switch(state){
01571 case FIN_SIP:
01572 vb->name.len=tmp-vb->name.s;
01573 state=F_VER;
01574 break;
01575 case FIN_VER:
01576 vb->version.len=tmp-vb->version.s;
01577 state=F_PROTO;
01578 break;
01579 case L_VER:
01580 state=F_VER;
01581 break;
01582 case L_PROTO:
01583 state=F_PROTO;
01584 break;
01585 default:
01586 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01587 " state %d\n", *tmp, state);
01588 goto error;
01589 }
01590 break;
01591
01592 case 'S':
01593 case 's':
01594 switch(state){
01595 case F_SIP:
01596 state=SIP1;
01597 vb->name.s=tmp;
01598 break;
01599 case TLS2:
01600 state=FIN_TLS;
01601 break;
01602 case F_PROTO:
01603 state=SCTP1;
01604 vb->transport.s=tmp;
01605 break;
01606 case OTHER_PROTO:
01607 break;
01608 case UDP1:
01609 case UDP2:
01610 case FIN_UDP:
01611 case TCP_TLS1:
01612 case TCP2:
01613 case FIN_TCP:
01614 case FIN_TLS:
01615 case SCTP1:
01616 case SCTP2:
01617 case SCTP3:
01618 case FIN_SCTP:
01619 state=OTHER_PROTO;
01620 break;
01621 default:
01622 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01623 " state %d\n", *tmp, state);
01624 goto error;
01625 }
01626 break;
01627 case 'I':
01628 case 'i':
01629 switch(state){
01630 case SIP1:
01631 state=SIP2;
01632 break;
01633 case OTHER_PROTO:
01634 break;
01635 case UDP1:
01636 case UDP2:
01637 case FIN_UDP:
01638 case TCP_TLS1:
01639 case TCP2:
01640 case FIN_TCP:
01641 case TLS2:
01642 case FIN_TLS:
01643 case SCTP1:
01644 case SCTP2:
01645 case SCTP3:
01646 case FIN_SCTP:
01647 state=OTHER_PROTO;
01648 break;
01649 default:
01650 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01651 " state %d\n", *tmp, state);
01652 goto error;
01653 }
01654 break;
01655 case 'p':
01656 case 'P':
01657 switch(state){
01658 case SIP2:
01659 state=FIN_SIP;
01660 break;
01661
01662 case UDP2:
01663 state=FIN_UDP;
01664 break;
01665 case TCP2:
01666 state=FIN_TCP;
01667 break;
01668 case SCTP3:
01669 state=FIN_SCTP;
01670 break;
01671 case OTHER_PROTO:
01672 break;
01673 case UDP1:
01674 case FIN_UDP:
01675 case TCP_TLS1:
01676 case FIN_TCP:
01677 case TLS2:
01678 case FIN_TLS:
01679 case SCTP1:
01680 case SCTP2:
01681 case FIN_SCTP:
01682 state=OTHER_PROTO;
01683 break;
01684 default:
01685 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01686 " state %d\n", *tmp, state);
01687 goto error;
01688 }
01689 break;
01690 case 'U':
01691 case 'u':
01692 switch(state){
01693 case F_PROTO:
01694 state=UDP1;
01695 vb->transport.s=tmp;
01696 break;
01697 case OTHER_PROTO:
01698 break;
01699 case UDP1:
01700 case UDP2:
01701 case FIN_UDP:
01702 case TCP_TLS1:
01703 case TCP2:
01704 case FIN_TCP:
01705 case TLS2:
01706 case FIN_TLS:
01707 case SCTP1:
01708 case SCTP2:
01709 case SCTP3:
01710 case FIN_SCTP:
01711 state=OTHER_PROTO;
01712 break;
01713 default:
01714 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01715 " state %d\n", *tmp, state);
01716 goto error;
01717 }
01718 break;
01719 case 'D':
01720 case 'd':
01721 switch(state){
01722 case UDP1:
01723 state=UDP2;
01724 break;
01725 case OTHER_PROTO:
01726 break;
01727 case UDP2:
01728 case FIN_UDP:
01729 case TCP_TLS1:
01730 case TCP2:
01731 case FIN_TCP:
01732 case TLS2:
01733 case FIN_TLS:
01734 case SCTP1:
01735 case SCTP2:
01736 case SCTP3:
01737 case FIN_SCTP:
01738 state=OTHER_PROTO;
01739 break;
01740 default:
01741 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01742 " state %d\n", *tmp, state);
01743 goto error;
01744 }
01745 break;
01746 case 'T':
01747 case 't':
01748 switch(state){
01749 case F_PROTO:
01750 state=TCP_TLS1;
01751 vb->transport.s=tmp;
01752 break;
01753 case SCTP2:
01754 state=SCTP3;
01755 break;
01756 case OTHER_PROTO:
01757 break;
01758 case UDP1:
01759 case UDP2:
01760 case FIN_UDP:
01761 case TCP_TLS1:
01762 case TCP2:
01763 case FIN_TCP:
01764 case TLS2:
01765 case FIN_TLS:
01766 case SCTP1:
01767 case SCTP3:
01768 case FIN_SCTP:
01769 state=OTHER_PROTO;
01770 break;
01771 default:
01772 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01773 " state %d\n", *tmp, state);
01774 goto error;
01775 }
01776 break;
01777 case 'C':
01778 case 'c':
01779 switch(state){
01780 case TCP_TLS1:
01781 state=TCP2;
01782 break;
01783 case SCTP1:
01784 state=SCTP2;
01785 break;
01786 case OTHER_PROTO:
01787 break;
01788 case UDP1:
01789 case UDP2:
01790 case FIN_UDP:
01791 case TCP2:
01792 case FIN_TCP:
01793 case TLS2:
01794 case FIN_TLS:
01795 case SCTP2:
01796 case SCTP3:
01797 case FIN_SCTP:
01798 state=OTHER_PROTO;
01799 break;
01800 default:
01801 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01802 " state %d\n", *tmp, state);
01803 goto error;
01804 }
01805 break;
01806 case 'L':
01807 case 'l':
01808 switch(state){
01809 case TCP_TLS1:
01810 state=TLS2;
01811 break;
01812 case OTHER_PROTO:
01813 break;
01814 case UDP1:
01815 case UDP2:
01816 case FIN_UDP:
01817 case TCP2:
01818 case FIN_TCP:
01819 case TLS2:
01820 case FIN_TLS:
01821 case SCTP1:
01822 case SCTP2:
01823 case SCTP3:
01824 case FIN_SCTP:
01825 state=OTHER_PROTO;
01826 break;
01827 default:
01828 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01829 " state %d\n", *tmp, state);
01830 goto error;
01831 }
01832 break;
01833
01834 case '2':
01835 switch(state){
01836 case F_VER:
01837 state=VER1;
01838 vb->version.s=tmp;
01839 break;
01840 case OTHER_PROTO:
01841 break;
01842 case UDP1:
01843 case UDP2:
01844 case FIN_UDP:
01845 case TCP_TLS1:
01846 case TCP2:
01847 case FIN_TCP:
01848 case TLS2:
01849 case FIN_TLS:
01850 case SCTP1:
01851 case SCTP2:
01852 case SCTP3:
01853 case FIN_SCTP:
01854 state=OTHER_PROTO;
01855 break;
01856 default:
01857 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01858 " state %d\n", *tmp, state);
01859 goto error;
01860 }
01861 break;
01862 case '.':
01863 switch(state){
01864 case VER1:
01865 state=VER2;
01866 break;
01867 case OTHER_PROTO:
01868 break;
01869 case UDP1:
01870 case UDP2:
01871 case FIN_UDP:
01872 case TCP_TLS1:
01873 case TCP2:
01874 case FIN_TCP:
01875 case TLS2:
01876 case FIN_TLS:
01877 case SCTP1:
01878 case SCTP2:
01879 case SCTP3:
01880 case FIN_SCTP:
01881 state=OTHER_PROTO;
01882 break;
01883 default:
01884 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01885 " state %d\n", *tmp, state);
01886 goto error;
01887 }
01888 break;
01889 case '0':
01890 switch(state){
01891 case VER2:
01892 state=FIN_VER;
01893 break;
01894 case OTHER_PROTO:
01895 break;
01896 case UDP1:
01897 case UDP2:
01898 case FIN_UDP:
01899 case TCP_TLS1:
01900 case TCP2:
01901 case FIN_TCP:
01902 case TLS2:
01903 case FIN_TLS:
01904 case SCTP1:
01905 case SCTP2:
01906 case SCTP3:
01907 case FIN_SCTP:
01908 state=OTHER_PROTO;
01909 break;
01910 default:
01911 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01912 " state %d\n", *tmp, state);
01913 goto error;
01914 }
01915 break;
01916 default:
01917 switch(state){
01918 case F_PROTO:
01919 state=OTHER_PROTO;
01920 vb->transport.s=tmp;
01921 break;
01922 case OTHER_PROTO:
01923 break;
01924 case UDP1:
01925 case UDP2:
01926 case FIN_UDP:
01927 case TCP_TLS1:
01928 case TCP2:
01929 case FIN_TCP:
01930 case TLS2:
01931 case FIN_TLS:
01932 case SCTP1:
01933 case SCTP2:
01934 case SCTP3:
01935 case FIN_SCTP:
01936 state=OTHER_PROTO;
01937 break;
01938 default:
01939 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01940 " state %d\n", *tmp, state);
01941 goto error;
01942 }
01943 break;
01944 }
01945 }
01946
01947
01948 LOG(L_ERR, "ERROR: parse_via: bad via: end of packet on state=%d\n",
01949 state);
01950 goto error;
01951
01952 main_via:
01953
01954 tmp++;
01955 c_nest=0;
01956 ;
01957 for(;*tmp;tmp++){
01958 switch(*tmp){
01959 case ' ':
01960 case '\t':
01961 switch(state){
01962 case F_HOST:
01963 break;
01964 case P_HOST:
01965
01966 vb->host.len=tmp-vb->host.s;
01967 state=L_PORT;
01968 break;
01969 case L_PORT:
01970 case F_PORT:
01971 break;
01972 case P_PORT:
01973
01974 vb->port_str.len=tmp-vb->port_str.s;
01975 state=L_PARAM;
01976 break;
01977 case L_PARAM:
01978 case F_PARAM:
01979 break;
01980 case P_PARAM:
01981
01982 state=L_PARAM;
01983 break;
01984 case L_VIA:
01985 case F_VIA:
01986 break;
01987 case F_COMMENT:
01988 case P_COMMENT:
01989 break;
01990 case F_IP6HOST:
01991 case P_IP6HOST:
01992 LOG(L_ERR, "ERROR:parse_via: bad ipv6 reference\n");
01993 goto error;
01994 case F_CRLF:
01995 case F_LF:
01996 case F_CR:
01997
01998 state=saved_state;
01999 break;
02000 default:
02001 LOG(L_CRIT,"BUG: parse_via"
02002 " on <%c>, state=%d\n",*tmp, state);
02003 goto error;
02004 }
02005 break;
02006 case '\n':
02007 switch(state){
02008 case F_HOST:
02009 case L_PORT:
02010 case F_PORT:
02011 case L_PARAM:
02012 case F_PARAM:
02013 case F_VIA:
02014 case L_VIA:
02015 case F_COMMENT:
02016 case P_COMMENT:
02017 case F_IP6HOST:
02018 case P_IP6HOST:
02019 saved_state=state;
02020 state=F_LF;
02021 break;
02022 case P_HOST:
02023
02024 vb->host.len=tmp-vb->host.s;
02025 saved_state=L_PORT;
02026 state=F_LF;
02027 break;
02028 case P_PORT:
02029
02030 vb->port_str.len=tmp-vb->port_str.s;
02031 saved_state=L_PARAM;
02032 state=F_LF;
02033 break;
02034 case P_PARAM:
02035
02036 saved_state=L_PARAM;
02037 state=F_LF;
02038 break;
02039 case F_CR:
02040 state=F_CRLF;
02041 break;
02042 case F_CRLF:
02043 case F_LF:
02044 state=saved_state;
02045 goto endofheader;
02046 default:
02047 LOG(L_CRIT,"BUG: parse_via"
02048 " on <%c>\n",*tmp);
02049 goto error;
02050 }
02051 break;
02052 case '\r':
02053 switch(state){
02054 case F_HOST:
02055 case L_PORT:
02056 case F_PORT:
02057 case L_PARAM:
02058 case F_PARAM:
02059 case F_VIA:
02060 case L_VIA:
02061 case F_COMMENT:
02062 case P_COMMENT:
02063 case F_IP6HOST:
02064 case P_IP6HOST:
02065 saved_state=state;
02066 state=F_CR;
02067 break;
02068 case P_HOST:
02069
02070 vb->host.len=tmp-vb->host.s;
02071 saved_state=L_PORT;
02072 state=F_CR;
02073 break;
02074 case P_PORT:
02075
02076 vb->port_str.len=tmp-vb->port_str.s;
02077 saved_state=L_PARAM;
02078 state=F_CR;
02079 break;
02080 case P_PARAM:
02081
02082 saved_state=L_PARAM;
02083 state=F_CR;
02084 break;
02085 case F_CRLF:
02086 case F_CR:
02087 case F_LF:
02088 state=saved_state;
02089 goto endofheader;
02090 default:
02091 LOG(L_CRIT,"BUG: parse_via"
02092 " on <%c>\n",*tmp);
02093 goto error;
02094 }
02095 break;
02096
02097 case ':':
02098 switch(state){
02099 case F_HOST:
02100 case F_IP6HOST:
02101 state=P_IP6HOST;
02102 break;
02103 case P_IP6HOST:
02104 break;
02105 case P_HOST:
02106
02107 vb->host.len=tmp-vb->host.s;
02108 state=F_PORT;
02109 break;
02110 case L_PORT:
02111 state=F_PORT;
02112 break;
02113 case P_PORT:
02114 LOG(L_ERR, "ERROR:parse_via:"
02115 " bad port\n");
02116 goto error;
02117 case L_PARAM:
02118 case F_PARAM:
02119 case F_PORT:
02120 case P_PARAM:
02121 LOG(L_ERR, "ERROR:parse_via:"
02122 " bad char <%c> in state %d\n",
02123 *tmp,state);
02124 goto error;
02125 case L_VIA:
02126 case F_VIA:
02127 LOG(L_ERR, "ERROR:parse_via:"
02128 " bad char in compact via\n");
02129 goto error;
02130 case F_CRLF:
02131 case F_LF:
02132 case F_CR:
02133
02134 goto endofheader;
02135 case F_COMMENT:
02136 vb->comment.s=tmp;
02137 state=P_COMMENT;
02138 break;
02139 case P_COMMENT:
02140 break;
02141 default:
02142 LOG(L_CRIT,"BUG: parse_via"
02143 " on <%c> state %d\n",
02144 *tmp, state);
02145 goto error;
02146 }
02147 break;
02148 case ';':
02149 switch(state){
02150 case F_HOST:
02151 case F_IP6HOST:
02152 LOG(L_ERR,"ERROR:parse_via:"
02153 " no host found\n");
02154 goto error;
02155 case P_IP6HOST:
02156 LOG(L_ERR, "ERROR:parse_via: bad ipv6 reference\n");
02157 goto error;
02158 case P_HOST:
02159 vb->host.len=tmp-vb->host.s;
02160 state=F_PARAM;
02161 param_start=tmp+1;
02162 break;
02163 case P_PORT:
02164
02165 vb->port_str.len=tmp-vb->port_str.s;
02166 case L_PORT:
02167 case L_PARAM:
02168 state=F_PARAM;
02169 param_start=tmp+1;
02170 break;
02171 case F_PORT:
02172 LOG(L_ERR, "ERROR:parse_via:"
02173 " bad char <%c> in state %d\n",
02174 *tmp,state);
02175 goto error;
02176 case F_PARAM:
02177 LOG(L_ERR, "ERROR:parse_via:"
02178 " null param?\n");
02179 goto error;
02180 case P_PARAM:
02181
02182 state=F_PARAM;
02183 param_start=tmp+1;
02184 break;
02185 case L_VIA:
02186 case F_VIA:
02187 LOG(L_ERR, "ERROR:parse_via:"
02188 " bad char <%c> in next via\n",
02189 *tmp);
02190 goto error;
02191 case F_CRLF:
02192 case F_LF:
02193 case F_CR:
02194
02195 goto endofheader;
02196 case F_COMMENT:
02197 vb->comment.s=tmp;
02198 state=P_COMMENT;
02199 break;
02200 case P_COMMENT:
02201 break;
02202
02203 default:
02204 LOG(L_CRIT,"BUG: parse_via"
02205 " on <%c> state %d\n",
02206 *tmp, state);
02207 goto error;
02208 }
02209 break;
02210 case ',':
02211 switch(state){
02212 case F_HOST:
02213 case F_IP6HOST:
02214 LOG(L_ERR,"ERROR:parse_via:"
02215 " no host found\n");
02216 goto error;
02217 case P_IP6HOST:
02218 LOG(L_ERR, "ERROR:parse_via: bad ipv6 reference\n");
02219 goto error;
02220 case P_HOST:
02221
02222 vb->host.len=tmp-vb->host.s;
02223 state=F_VIA;
02224 break;
02225 case P_PORT:
02226
02227 vb->port_str.len=tmp-vb->port_str.s;
02228 state=F_VIA;
02229 break;
02230 case L_PORT:
02231 case L_PARAM:
02232 case P_PARAM:
02233 case L_VIA:
02234 state=F_VIA;
02235 break;
02236 case F_PORT:
02237 case F_PARAM:
02238 LOG(L_ERR, "ERROR:parse_via:"
02239 " invalid char <%c> in state"
02240 " %d\n", *tmp,state);
02241 goto error;
02242 case F_VIA:
02243
02244 break;
02245 case F_CRLF:
02246 case F_LF:
02247 case F_CR:
02248
02249 goto endofheader;
02250 case F_COMMENT:
02251 vb->comment.s=tmp;
02252 state=P_COMMENT;
02253 break;
02254 case P_COMMENT:
02255 break;
02256 default:
02257 LOG(L_CRIT,"BUG: parse_via"
02258 " on <%c> state %d\n",
02259 *tmp, state);
02260 goto error;
02261 }
02262 break;
02263 case '(':
02264 switch(state){
02265 case F_HOST:
02266 case F_PORT:
02267 case F_PARAM:
02268 case F_VIA:
02269 case F_IP6HOST:
02270 case P_IP6HOST:
02271 LOG(L_ERR,"ERROR:parse_via"
02272 " on <%c> state %d\n",
02273 *tmp, state);
02274 goto error;
02275 case P_HOST:
02276
02277 vb->host.len=tmp-vb->host.s;
02278 state=F_COMMENT;
02279 c_nest++;
02280 break;
02281 case P_PORT:
02282
02283 vb->port_str.len=tmp-vb->port_str.s;
02284 state=F_COMMENT;
02285 c_nest++;
02286 break;
02287 case P_PARAM:
02288
02289 vb->params.len=tmp-vb->params.s;
02290 state=F_COMMENT;
02291 c_nest++;
02292 break;
02293 case L_PORT:
02294 case L_PARAM:
02295 case L_VIA:
02296 state=F_COMMENT;
02297 vb->params.len=tmp-vb->params.s;
02298 c_nest++;
02299 break;
02300 case P_COMMENT:
02301 case F_COMMENT:
02302 c_nest++;
02303 break;
02304 case F_CRLF:
02305 case F_LF:
02306 case F_CR:
02307
02308 goto endofheader;
02309 default:
02310 LOG(L_CRIT,"BUG: parse_via"
02311 " on <%c> state %d\n",
02312 *tmp, state);
02313 goto error;
02314 }
02315 break;
02316 case ')':
02317 switch(state){
02318 case F_COMMENT:
02319 case P_COMMENT:
02320 if (c_nest){
02321 c_nest--;
02322 if(c_nest==0){
02323 state=L_VIA;
02324 vb->comment.len=tmp-vb->comment.s;
02325 break;
02326 }
02327 }else{
02328 LOG(L_ERR,"ERROR:"
02329 "parse_via: "
02330 "missing '(' - "
02331 "nesting = %d\n",
02332 c_nest);
02333 goto error;
02334 }
02335 break;
02336 case F_HOST:
02337 case F_PORT:
02338 case F_PARAM:
02339 case F_VIA:
02340 case P_HOST:
02341 case P_PORT:
02342 case P_PARAM:
02343 case L_PORT:
02344 case L_PARAM:
02345 case L_VIA:
02346 case F_IP6HOST:
02347 case P_IP6HOST:
02348 LOG(L_ERR,"ERROR:parse_via"
02349 " on <%c> state %d\n",
02350 *tmp, state);
02351 goto error;
02352 case F_CRLF:
02353 case F_LF:
02354 case F_CR:
02355
02356 goto endofheader;
02357 default:
02358 LOG(L_CRIT,"BUG: parse_via"
02359 " on <%c> state %d\n",
02360 *tmp, state);
02361 goto error;
02362 }
02363 break;
02364 case '[':
02365 switch(state){
02366 case F_HOST:
02367 vb->host.s=tmp;
02368 state=F_IP6HOST;
02369 break;
02370 case F_COMMENT:
02371 vb->comment.s=tmp;
02372 state=P_COMMENT;
02373 break;
02374 case P_COMMENT:
02375 break;
02376 case F_CRLF:
02377 case F_LF:
02378 case F_CR:
02379
02380 goto endofheader;
02381 default:
02382 LOG(L_ERR,"ERROR:parse_via"
02383 " on <%c> state %d\n",
02384 *tmp, state);
02385 goto error;
02386 }
02387 break;
02388 case ']':
02389 switch(state){
02390 case P_IP6HOST:
02391
02392 vb->host.len=(tmp-vb->host.s)+1;
02393 state=L_PORT;
02394 break;
02395 case F_CRLF:
02396 case F_LF:
02397 case F_CR:
02398
02399 goto endofheader;
02400 case F_COMMENT:
02401 vb->comment.s=tmp;
02402 state=P_COMMENT;
02403 break;
02404 case P_COMMENT:
02405 break;
02406 default:
02407 LOG(L_ERR,"ERROR:parse_via"
02408 " on <%c> state %d\n",
02409 *tmp, state);
02410 goto error;
02411 }
02412 break;
02413
02414 default:
02415 switch(state){
02416 case F_HOST:
02417 state=P_HOST;
02418 vb->host.s=tmp;
02419 break;
02420 case P_HOST:
02421 break;
02422 case F_PORT:
02423 state=P_PORT;
02424 vb->port_str.s=tmp;
02425 break;
02426 case P_PORT:
02427
02428 break;
02429 case F_PARAM:
02430 ;
02431 if(vb->params.s==0) vb->params.s=param_start;
02432 param=pkg_malloc(sizeof(struct via_param));
02433 if (param==0){
02434 LOG(L_ERR, "ERROR:parse_via: mem. allocation"
02435 " error\n");
02436 goto error;
02437 }
02438 memset(param,0, sizeof(struct via_param));
02439 param->start=param_start;
02440 tmp=parse_via_param(tmp, end, &state, &saved_state,
02441 param, vb);
02442
02443 switch(state){
02444 case F_PARAM:
02445 param_start=tmp+1;
02446 case L_PARAM:
02447 case F_LF:
02448 case F_CR:
02449 break;
02450 case F_VIA:
02451 vb->params.len=param->start+param->size
02452 -vb->params.s;
02453 break;
02454 case END_OF_HEADER:
02455 vb->params.len=param->start+param->size
02456 -vb->params.s;
02457 break;
02458 case PARAM_ERROR:
02459 pkg_free(param);
02460 goto error;
02461 default:
02462 pkg_free(param);
02463 LOG(L_ERR, "ERROR: parse_via after"
02464 " parse_via_param: invalid"
02465 " char <%c> on state %d\n",
02466 *tmp, state);
02467 goto error;
02468 }
02469
02470 if (vb->last_param) vb->last_param->next=param;
02471 else vb->param_lst=param;
02472 vb->last_param=param;
02473
02474 switch(param->type){
02475 case PARAM_BRANCH:
02476 vb->branch=param;
02477 break;
02478 case PARAM_RECEIVED:
02479 vb->received=param;
02480 break;
02481 case PARAM_RPORT:
02482 vb->rport=param;
02483 break;
02484 case PARAM_I:
02485 vb->i=param;
02486 break;
02487 case PARAM_ALIAS:
02488 vb->alias=param;
02489 break;
02490 #ifdef USE_COMP
02491 case PARAM_COMP:
02492 vb->comp=param;
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510 break;
02511 #endif
02512 }
02513
02514 if (state==END_OF_HEADER){
02515 state=saved_state;
02516 goto endofheader;
02517 }
02518 break;
02519 case P_PARAM:
02520 break;
02521 case F_VIA:
02522
02523 goto nextvia;
02524 case L_PORT:
02525 case L_PARAM:
02526 case L_VIA:
02527 LOG(L_ERR,"ERROR:parse_via"
02528 " on <%c> state %d (default)\n",
02529 *tmp, state);
02530 goto error;
02531 case F_COMMENT:
02532 state=P_COMMENT;
02533 vb->comment.s=tmp;
02534 break;
02535 case P_COMMENT:
02536 break;
02537 case F_IP6HOST:
02538 state=P_IP6HOST;
02539 break;
02540 case P_IP6HOST:
02541 break;
02542 case F_CRLF:
02543 case F_LF:
02544 case F_CR:
02545
02546 goto endofheader;
02547 default:
02548 LOG(L_ERR, "BUG:parse_via:"
02549 " invalid char <%c>"
02550 " in state %d\n",
02551 *tmp, state);
02552 goto error;
02553 }
02554
02555
02556 }
02557 }
02558
02559 DBG("end of packet reached, state=%d\n", state);
02560 goto endofpacket;
02561
02562 endofheader:
02563 state=saved_state;
02564 DBG("end of header reached, state=%d\n", state);
02565 endofpacket:
02566
02567 switch(state){
02568 case P_HOST:
02569 case L_PORT:
02570 case P_PORT:
02571 case L_PARAM:
02572 case P_PARAM:
02573 case P_VALUE:
02574 case GEN_PARAM:
02575 case FIN_HIDDEN:
02576 case L_VIA:
02577 break;
02578 default:
02579 LOG(L_ERR, "ERROR: parse_via: invalid via - end of header in"
02580 " state %d\n", state);
02581 goto error;
02582 }
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595 vb->error=PARSE_OK;
02596 vb->bsize=tmp-buffer;
02597 if (vb->port_str.s){
02598 vb->port=str2s(vb->port_str.s, vb->port_str.len, &err);
02599 if (err){
02600 LOG(L_ERR, "ERROR: parse_via: invalid port number <%.*s>\n",
02601 vb->port_str.len, ZSW(vb->port_str.s));
02602 goto error;
02603 }
02604 }
02605 return tmp;
02606 nextvia:
02607 DBG("parse_via: next_via\n");
02608 vb->error=PARSE_OK;
02609 vb->bsize=tmp-buffer;
02610 if (vb->port_str.s){
02611 vb->port=str2s(vb->port_str.s, vb->port_str.len, &err);
02612 if (err){
02613 LOG(L_ERR, "ERROR: parse_via: invalid port number <%.*s>\n",
02614 vb->port_str.len, ZSW(vb->port_str.s));
02615 goto error;
02616 }
02617 }
02618 vb->next=pkg_malloc(sizeof(struct via_body));
02619 if (vb->next==0){
02620 LOG(L_ERR, "ERROR: parse_via: out of memory\n");
02621 goto error;
02622 }
02623 vb=vb->next;
02624 memset(vb, 0, sizeof(struct via_body));
02625 buffer=tmp;
02626 goto parse_again;
02627
02628 error:
02629 if (end>buffer){
02630 LOG(L_ERR, "ERROR: parse_via on: <%.*s>\n", (int)(end-buffer), ZSW(buffer));
02631 }
02632 if ((tmp>buffer)&&(tmp<end)){
02633 LOG(L_ERR, "ERROR: parse_via parse error, parsed so far:<%.*s>\n",
02634 (int)(tmp-buffer), ZSW(buffer) );
02635 }else{
02636 LOG(L_ERR, "ERROR: parse_via: via parse error\n");
02637 }
02638 vb->error=PARSE_ERROR;
02639 vbody->error=PARSE_ERROR;
02640
02641 return tmp;
02642 }
02643
02644
02645 static inline void free_via_param_list(struct via_param* vp)
02646 {
02647 struct via_param* foo;
02648 while(vp){
02649 foo=vp;
02650 vp=vp->next;
02651 pkg_free(foo);
02652 }
02653 }
02654
02655
02656 void free_via_list(struct via_body* vb)
02657 {
02658 struct via_body* foo;
02659 while(vb){
02660 foo=vb;
02661 vb=vb->next;
02662 if (foo->param_lst) free_via_param_list(foo->param_lst);
02663 pkg_free(foo);
02664 }
02665 }
02666
02667 int parse_via_header( struct sip_msg *msg, int n, struct via_body** q)
02668 {
02669 struct hdr_field *p;
02670 struct via_body *pp = NULL;
02671 int i;
02672
02673 switch (n) {
02674 case 1:
02675 case 2:
02676 if (!msg->h_via1 && (parse_headers(msg,HDR_VIA_F,0)==-1 || !msg->h_via1)) {
02677 DBG("bad msg or missing VIA1 header \n");
02678 return -1;
02679 }
02680 pp = msg->h_via1->parsed;
02681 if (n==1) break;
02682 pp = pp->next;
02683 if (pp) break;
02684
02685 if (!msg->h_via2 && (parse_headers(msg,HDR_VIA2_F,0)==-1 || !msg->h_via2)) {
02686 DBG("bad msg or missing VIA2 header \n");
02687 return -1;
02688 }
02689 pp = msg->h_via2->parsed;
02690 break;
02691 default:
02692 if (!msg->eoh && (parse_headers(msg,HDR_EOH_F,0)==-1 || !msg->eoh)) {
02693 ERR("bad msg while parsing to EOH \n");
02694 return -1;
02695 }
02696 p = msg->h_via1;
02697 i = n;
02698 while (i && p) {
02699 if (p->type == HDR_VIA_T) {
02700 i--;
02701 pp = p->parsed;
02702 while (i && (pp->next)) {
02703 i--;
02704 pp = pp->next;
02705 }
02706 }
02707 p = p->next;
02708 }
02709 if (i > 0) {
02710 DBG("missing VIA[%d] header\n", n);
02711 return -1;
02712 }
02713 }
02714 if (pp) {
02715 *q = pp;
02716 return 0;
02717 } else
02718 return -1;
02719 }
02720