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
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <stdio.h>
00045
00046
00047 enum{ F_HOST, P_HOST,
00048 L_PORT, F_PORT, P_PORT,
00049 L_PARAM, F_PARAM, P_PARAM,
00050 L_VIA, F_VIA,
00051 F_COMMENT, P_COMMENT,
00052 F_IP6HOST, P_IP6HOST,
00053 F_CRLF,
00054 F_LF,
00055 F_CR,
00056 END_OF_HEADER
00057 };
00058
00059
00060 enum{ F_SIP=100,
00061 SIP1, SIP2, FIN_SIP,
00062 L_VER, F_VER,
00063 VER1, VER2, FIN_VER,
00064 L_PROTO, F_PROTO, P_PROTO
00065 };
00066
00067
00068 enum{ L_VALUE=200, F_VALUE, P_VALUE, P_STRING,
00069 HIDDEN1, HIDDEN2, HIDDEN3, HIDDEN4, HIDDEN5,
00070 TTL1, TTL2,
00071 BRANCH1, BRANCH2, BRANCH3, BRANCH4, BRANCH5,
00072 MADDR1, MADDR2, MADDR3, MADDR4,
00073 RECEIVED1, RECEIVED2, RECEIVED3, RECEIVED4, RECEIVED5, RECEIVED6,
00074 RECEIVED7,
00075
00076 FIN_HIDDEN, FIN_TTL, FIN_BRANCH, FIN_MADDR, FIN_RECEIVED,
00077 GEN_PARAM
00078 };
00079
00080 #define LOG(lev, fmt, args...) fprintf(stderr, fmt, ## args)
00081
00082
00083
00084
00085
00086
00087 __inline char* parse_via_param(char* p, int* pstate, int* psaved_state)
00088 {
00089 char* tmp;
00090 register int state;
00091 int saved_state;
00092 int param_type;
00093 char* param_name;
00094 char* param_value;
00095
00096 state=*pstate;
00097 saved_state=*psaved_state;
00098 param_name=param_value=0;
00099 param_type=0;
00100
00101 for (tmp=p;*tmp;tmp++){
00102 switch(*tmp){
00103 case ' ':
00104 case '\t':
00105 switch(state){
00106 case FIN_HIDDEN:
00107 *tmp=0;
00108 param_type=state;
00109 state=L_PARAM;
00110 goto endofparam;
00111 case FIN_BRANCH:
00112 case FIN_TTL:
00113 case FIN_MADDR:
00114 case FIN_RECEIVED:
00115 *tmp=0;
00116 param_type=state;
00117 state=L_VALUE;
00118 goto find_value;
00119 case F_PARAM:
00120 break;
00121 case F_LF:
00122 case F_CR:
00123 case F_CRLF:
00124 state=saved_state;
00125 break;
00126 case GEN_PARAM:
00127 default:
00128 *tmp=0;
00129 param_type=GEN_PARAM;
00130 state=L_VALUE;
00131 goto find_value;
00132 }
00133 break;
00134
00135 case '\n':
00136 switch(state){
00137 case FIN_HIDDEN:
00138 *tmp=0;
00139 param_type=state;
00140 saved_state=L_PARAM;
00141 state=F_LF;
00142 goto endofparam;
00143 case FIN_BRANCH:
00144 case FIN_TTL:
00145 case FIN_MADDR:
00146 case FIN_RECEIVED:
00147 *tmp=0;
00148 param_type=state;
00149 saved_state=L_VALUE;
00150 state=F_LF;
00151 goto find_value;
00152 case F_PARAM:
00153 saved_state=state;
00154 state=F_LF;
00155 break;
00156 case F_LF:
00157 case F_CRLF:
00158 state=END_OF_HEADER;
00159 goto end;
00160 case F_CR:
00161 state=F_CRLF;
00162 break;
00163 case GEN_PARAM:
00164 default:
00165 *tmp=0;
00166 param_type=GEN_PARAM;
00167 saved_state=L_VALUE;
00168 state=F_LF;
00169 goto find_value;
00170 }
00171 break;
00172 case '\r':
00173 switch(state){
00174 case FIN_HIDDEN:
00175 *tmp=0;
00176 param_type=state;
00177 saved_state=L_PARAM;
00178 state=F_CR;
00179 goto endofparam;
00180 case FIN_BRANCH:
00181 case FIN_TTL:
00182 case FIN_MADDR:
00183 case FIN_RECEIVED:
00184 *tmp=0;
00185 param_type=state;
00186 saved_state=L_VALUE;
00187 state=F_CR;
00188 goto find_value;
00189 case F_PARAM:
00190 saved_state=state;
00191 state=F_CR;
00192 break;
00193 case F_CR:
00194 case F_CRLF:
00195 state=END_OF_HEADER;
00196 goto end;
00197 case GEN_PARAM:
00198 default:
00199 *tmp=0;
00200 param_type=GEN_PARAM;
00201 saved_state=L_VALUE;
00202 state=F_CR;
00203 goto find_value;
00204 }
00205 break;
00206
00207 case '=':
00208 switch(state){
00209 case FIN_BRANCH:
00210 case FIN_TTL:
00211 case FIN_MADDR:
00212 case FIN_RECEIVED:
00213 *tmp=0;
00214 param_type=state;
00215 state=F_VALUE;
00216 goto find_value;
00217 case F_PARAM:
00218 case FIN_HIDDEN:
00219 LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
00220 " state %d\n");
00221 goto error;
00222 case F_CR:
00223 case F_LF:
00224 case F_CRLF:
00225 state=END_OF_HEADER;
00226 goto end;
00227 case GEN_PARAM:
00228 default:
00229 *tmp=0;
00230 param_type=GEN_PARAM;
00231 state=F_VALUE;
00232 goto find_value;
00233 }
00234 break;
00235 case ';':
00236 switch(state){
00237 case FIN_HIDDEN:
00238 *tmp=0;
00239 param_type=state;
00240 state=F_PARAM;
00241 goto endofparam;
00242 case FIN_BRANCH:
00243 case FIN_MADDR:
00244 case FIN_TTL:
00245 case FIN_RECEIVED:
00246 LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
00247 " state %d\n");
00248 goto error;
00249 case F_CR:
00250 case F_LF:
00251 case F_CRLF:
00252 state=END_OF_HEADER;
00253 goto end;
00254 case GEN_PARAM:
00255 default:
00256 *tmp=0;
00257 param_type=GEN_PARAM;
00258 state=F_PARAM;
00259 goto endofparam;
00260 }
00261 break;
00262
00263
00264 case 'h':
00265 case 'H':
00266 switch(state){
00267 case F_PARAM:
00268 state=HIDDEN1;
00269 param_name=tmp;
00270 break;
00271 case GEN_PARAM:
00272 break;
00273 case F_CR:
00274 case F_LF:
00275 case F_CRLF:
00276 state=END_OF_HEADER;
00277 goto end;
00278 default:
00279 state=GEN_PARAM;
00280 }
00281 break;
00282 case 'i':
00283 case 'I':
00284 switch(state){
00285 case HIDDEN1:
00286 state=HIDDEN2;
00287 break;
00288 case RECEIVED4:
00289 state=RECEIVED5;
00290 break;
00291 case GEN_PARAM:
00292 break;
00293 case F_CR:
00294 case F_LF:
00295 case F_CRLF:
00296 state=END_OF_HEADER;
00297 goto end;
00298 default:
00299 state=GEN_PARAM;
00300 }
00301 break;
00302 case 'd':
00303 case 'D':
00304 switch(state){
00305 case HIDDEN2:
00306 state=HIDDEN3;
00307 break;
00308 case HIDDEN3:
00309 state=HIDDEN4;
00310 break;
00311 case MADDR2:
00312 state=MADDR3;
00313 break;
00314 case MADDR3:
00315 state=MADDR4;
00316 break;
00317 case RECEIVED7:
00318 state=FIN_RECEIVED;
00319 break;
00320 case GEN_PARAM:
00321 break;
00322 case F_CR:
00323 case F_LF:
00324 case F_CRLF:
00325 state=END_OF_HEADER;
00326 goto end;
00327 default:
00328 state=GEN_PARAM;
00329 }
00330 break;
00331 case 'e':
00332 case 'E':
00333 switch(state){
00334 case HIDDEN4:
00335 state=HIDDEN5;
00336 break;
00337 case RECEIVED1:
00338 state=RECEIVED2;
00339 break;
00340 case RECEIVED3:
00341 state=RECEIVED4;
00342 break;
00343 case RECEIVED6:
00344 state=RECEIVED7;
00345 break;
00346 case GEN_PARAM:
00347 break;
00348 case F_CR:
00349 case F_LF:
00350 case F_CRLF:
00351 state=END_OF_HEADER;
00352 goto end;
00353 default:
00354 state=GEN_PARAM;
00355 }
00356 break;
00357 case 'n':
00358 case 'N':
00359 switch(state){
00360 case HIDDEN5:
00361 state=FIN_HIDDEN;
00362 break;
00363 case BRANCH3:
00364 state=BRANCH4;
00365 break;
00366 case GEN_PARAM:
00367 break;
00368 case F_CR:
00369 case F_LF:
00370 case F_CRLF:
00371 state=END_OF_HEADER;
00372 goto end;
00373 default:
00374 state=GEN_PARAM;
00375 }
00376 break;
00377 case 't':
00378 case 'T':
00379 switch(state){
00380 case F_PARAM:
00381 state=TTL1;
00382 param_name=tmp;
00383 break;
00384 case TTL1:
00385 state=TTL2;
00386 break;
00387 case GEN_PARAM:
00388 break;
00389 case F_CR:
00390 case F_LF:
00391 case F_CRLF:
00392 state=END_OF_HEADER;
00393 goto end;
00394 default:
00395 state=GEN_PARAM;
00396 }
00397 break;
00398 case 'l':
00399 case 'L':
00400 switch(state){
00401 case TTL2:
00402 state=FIN_TTL;
00403 break;
00404 case GEN_PARAM:
00405 break;
00406 case F_CR:
00407 case F_LF:
00408 case F_CRLF:
00409 state=END_OF_HEADER;
00410 goto end;
00411 default:
00412 state=GEN_PARAM;
00413 }
00414 break;
00415 case 'm':
00416 case 'M':
00417 switch(state){
00418 case F_PARAM:
00419 state=MADDR1;
00420 param_name=tmp;
00421 break;
00422 case GEN_PARAM:
00423 break;
00424 case F_CR:
00425 case F_LF:
00426 case F_CRLF:
00427 state=END_OF_HEADER;
00428 goto end;
00429 default:
00430 state=GEN_PARAM;
00431 }
00432 break;
00433 case 'a':
00434 case 'A':
00435 switch(state){
00436 case MADDR1:
00437 state=MADDR2;
00438 break;
00439 case BRANCH2:
00440 state=BRANCH3;
00441 break;
00442 case GEN_PARAM:
00443 break;
00444 case F_CR:
00445 case F_LF:
00446 case F_CRLF:
00447 state=END_OF_HEADER;
00448 goto end;
00449 default:
00450 state=GEN_PARAM;
00451 }
00452 break;
00453 case 'r':
00454 case 'R':
00455 switch(state){
00456 case MADDR4:
00457 state=FIN_MADDR;
00458 break;
00459 case F_PARAM:
00460 state=RECEIVED1;
00461 param_name=tmp;
00462 break;
00463 case BRANCH1:
00464 state=BRANCH2;
00465 break;
00466 case GEN_PARAM:
00467 break;
00468 case F_CR:
00469 case F_LF:
00470 case F_CRLF:
00471 state=END_OF_HEADER;
00472 goto end;
00473 default:
00474 state=GEN_PARAM;
00475 }
00476 break;
00477 case 'c':
00478 case 'C':
00479 switch(state){
00480 case RECEIVED2:
00481 state=RECEIVED3;
00482 break;
00483 case BRANCH4:
00484 state=BRANCH5;
00485 break;
00486 case GEN_PARAM:
00487 break;
00488 case F_CR:
00489 case F_LF:
00490 case F_CRLF:
00491 state=END_OF_HEADER;
00492 goto end;
00493 default:
00494 state=GEN_PARAM;
00495 }
00496 break;
00497 case 'v':
00498 case 'V':
00499 switch(state){
00500 case RECEIVED5:
00501 state=RECEIVED6;
00502 break;
00503 case GEN_PARAM:
00504 break;
00505 case F_CR:
00506 case F_LF:
00507 case F_CRLF:
00508 state=END_OF_HEADER;
00509 goto end;
00510 default:
00511 state=GEN_PARAM;
00512 }
00513 break;
00514 case 'b':
00515 case 'B':
00516 switch(state){
00517 case F_PARAM:
00518 state=BRANCH1;
00519 param_name=tmp;
00520 break;
00521 case GEN_PARAM:
00522 break;
00523 case F_CR:
00524 case F_LF:
00525 case F_CRLF:
00526 state=END_OF_HEADER;
00527 goto end;
00528 default:
00529 state=GEN_PARAM;
00530 }
00531 break;
00532
00533 default:
00534 switch(state){
00535 case F_PARAM:
00536 state=GEN_PARAM;
00537 param_name=tmp;
00538 break;
00539 case GEN_PARAM:
00540 break;
00541 case F_CR:
00542 case F_LF:
00543 case F_CRLF:
00544 state=END_OF_HEADER;
00545 goto end;
00546 default:
00547 state=GEN_PARAM;
00548 }
00549 }
00550 }
00551
00552
00553 saved_state=state;
00554 param_type=state;
00555 state=END_OF_HEADER;
00556 goto end;
00557
00558 find_value:
00559 tmp++;
00560 for(tmp;*tmp;tmp++){
00561 switch(*tmp){
00562 case ' ':
00563 case '\t':
00564 switch(state){
00565 case L_VALUE:
00566 case F_VALUE:
00567 break;
00568 case P_VALUE:
00569 *tmp=0;
00570 state=L_PARAM;
00571 goto endofvalue;
00572 case P_STRING:
00573 break;
00574 case F_CR:
00575 case F_LF:
00576 case F_CRLF:
00577 state=saved_state;
00578 break;
00579 default:
00580 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
00581 " in state %d\n", state);
00582 goto error;
00583 }
00584 break;
00585 case '\n':
00586 switch(state){
00587 case L_VALUE:
00588 case F_VALUE:
00589 case P_STRING:
00590 saved_state=state;
00591 state=F_LF;
00592 break;
00593 case P_VALUE:
00594 *tmp=0;
00595 saved_state=L_PARAM;
00596 state=F_LF;
00597 goto endofvalue;
00598 case F_LF:
00599 case F_CRLF:
00600 state=END_OF_HEADER;
00601 goto end;
00602 case F_CR:
00603 state=F_CRLF;
00604 break;
00605 default:
00606 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
00607 " in state %d\n", state);
00608 goto error;
00609 }
00610 break;
00611 case '\r':
00612 switch(state){
00613 case L_VALUE:
00614 case F_VALUE:
00615 case P_STRING:
00616 saved_state=state;
00617 state=F_CR;
00618 break;
00619 case P_VALUE:
00620 *tmp=0;
00621 saved_state=L_PARAM;
00622 state=F_CR;
00623 goto endofvalue;
00624 case F_LF:
00625 case F_CR:
00626 case F_CRLF:
00627 state=END_OF_HEADER;
00628 goto end;
00629 default:
00630 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
00631 " in state %d\n", state);
00632 goto error;
00633 }
00634 break;
00635
00636 case '=':
00637 switch(state){
00638 case L_VALUE:
00639 state=F_VALUE;
00640 break;
00641 case P_STRING:
00642 break;
00643 case F_LF:
00644 case F_CR:
00645 case F_CRLF:
00646 state=END_OF_HEADER;
00647 goto end;
00648 default:
00649 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
00650 " in state %d\n", state);
00651 goto error;
00652 }
00653 break;
00654 case ';':
00655 switch(state){
00656 case P_VALUE:
00657 *tmp=0;
00658 state=F_PARAM;
00659 goto endofvalue;
00660 case P_STRING:
00661 break;
00662 case F_LF:
00663 case F_CR:
00664 case F_CRLF:
00665 state=END_OF_HEADER;
00666 goto end;
00667 default:
00668 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
00669 " in state %d\n", state);
00670 goto error;
00671 }
00672 break;
00673
00674 case '"':
00675 switch(state){
00676 case F_VALUE:
00677 state=P_STRING;
00678 param_value=tmp+1;
00679 break;
00680 case P_STRING:
00681 *tmp=0;
00682 state=L_PARAM;
00683 goto endofvalue;
00684 case F_LF:
00685 case F_CR:
00686 case F_CRLF:
00687 state=END_OF_HEADER;
00688 goto end;
00689 default:
00690 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
00691 " in state %d\n", state);
00692 goto error;
00693 }
00694 break;
00695 default:
00696 switch(state){
00697 case F_VALUE:
00698 state=P_VALUE;
00699 param_value=tmp;
00700 break;
00701 case P_VALUE:
00702 case P_STRING:
00703 break;
00704 case F_LF:
00705 case F_CR:
00706 case F_CRLF:
00707 state=END_OF_HEADER;
00708 goto end;
00709 default:
00710 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
00711 " in state %d\n", state);
00712 goto error;
00713 }
00714 }
00715 }
00716
00717
00718 if ((state==L_VALUE)&&(param_type==GEN_PARAM)) state=L_PARAM;
00719 saved_state=state;
00720 state=END_OF_HEADER;
00721 goto end;
00722
00723 endofparam:
00724 endofvalue:
00725 printf("end, tmp=%x, <%c>\n", tmp, *tmp);
00726
00727 end:
00728 *pstate=state;
00729 *psaved_state=saved_state;
00730 printf("Found param type %d, <%s> = <%s>\n", param_type, param_name,
00731 param_value);
00732 return tmp;
00733
00734 error:
00735 fprintf(stderr,"error: via_parse_param\n");
00736 *pstate=state;
00737 *psaved_state=saved_state;
00738 return tmp;
00739 }
00740
00741
00742
00743
00744
00745
00746 int main(int argc, char** argv)
00747 {
00748
00749 char* tmp;
00750 int state;
00751 int saved_state;
00752 int c_nest;
00753 int i;
00754 int port;
00755 char* host;
00756 char* port_str;
00757 char* param;
00758 char* comment;
00759 char* next_via;
00760 char *proto;
00761
00762 host=port_str=param=comment=next_via=proto=0;
00763
00764 printf(" %s (%d)\n", argv[0], argc);
00765 if (argc<2){
00766 fprintf(stderr, " no parameters\n");
00767 exit(-1);
00768 }
00769
00770
00771 state=F_SIP;
00772 for(tmp=argv[1];*tmp;tmp++){
00773 switch(*tmp){
00774 case ' ':
00775 case'\t':
00776 switch(state){
00777 case L_VER:
00778 case L_PROTO:
00779 case F_SIP:
00780 case F_VER:
00781 case F_PROTO:
00782 break;
00783 case P_PROTO:
00784 *tmp=0;
00785 state=F_HOST;
00786 goto main_via;
00787 case FIN_SIP:
00788 *tmp=0;
00789 state=L_VER;
00790 break;
00791 case FIN_VER:
00792 *tmp=0;
00793 state=L_PROTO;
00794 break;
00795 case F_LF:
00796 case F_CRLF:
00797 case F_CR:
00798 state=saved_state;
00799 break;
00800 default:
00801 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
00802 " state %d\n", *tmp, state);
00803 goto error;
00804 }
00805 break;
00806 case '\n':
00807 switch(state){
00808 case L_VER:
00809 case F_SIP:
00810 case F_VER:
00811 case F_PROTO:
00812 case L_PROTO:
00813 saved_state=state;
00814 state=F_LF;
00815 break;
00816 case P_PROTO:
00817 *tmp=0;
00818 state=F_LF;
00819 saved_state=F_HOST;
00820 goto main_via;
00821 case FIN_SIP:
00822 *tmp=0;
00823 state=F_LF;
00824 saved_state=L_VER;
00825 break;
00826 case FIN_VER:
00827 *tmp=0;
00828 state=F_LF;
00829 saved_state=L_PROTO;
00830 break;
00831 case F_CR:
00832 state=F_CRLF;
00833 break;
00834 case F_LF:
00835 case F_CRLF:
00836 state=saved_state;
00837 goto endofheader;
00838 default:
00839 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
00840 " state %d\n", *tmp, state);
00841 goto error;
00842 }
00843 break;
00844 case '\r':
00845 switch(state){
00846 case L_VER:
00847 case F_SIP:
00848 case F_VER:
00849 case F_PROTO:
00850 case L_PROTO:
00851 saved_state=state;
00852 state=F_CR;
00853 break;
00854 case P_PROTO:
00855 *tmp=0;
00856 state=F_CR;
00857 saved_state=F_HOST;
00858 goto main_via;
00859 case FIN_SIP:
00860 *tmp=0;
00861 state=F_CR;
00862 saved_state=L_VER;
00863 break;
00864 case FIN_VER:
00865 *tmp=0;
00866 state=F_CR;
00867 saved_state=L_PROTO;
00868 break;
00869 case F_LF:
00870 case F_CR:
00871 case F_CRLF:
00872 state=saved_state;
00873 goto endofheader;
00874 default:
00875 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
00876 " state %d\n", *tmp, state);
00877 goto error;
00878 }
00879 break;
00880
00881 case '/':
00882 switch(state){
00883 case FIN_SIP:
00884 *tmp=0;
00885 state=F_VER;
00886 break;
00887 case FIN_VER:
00888 *tmp=0;
00889 state=F_PROTO;
00890 break;
00891 case L_VER:
00892 state=F_VER;
00893 break;
00894 case L_PROTO:
00895 state=F_PROTO;
00896 break;
00897 default:
00898 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
00899 " state %d\n", *tmp, state);
00900 goto error;
00901 }
00902 break;
00903
00904 case 'S':
00905 case 's':
00906 switch(state){
00907 case F_SIP:
00908 state=SIP1;
00909 break;
00910
00911 case F_PROTO:
00912 proto=tmp;
00913 state=P_PROTO;
00914 break;
00915 case P_PROTO:
00916 break;
00917 default:
00918 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
00919 " state %d\n", *tmp, state);
00920 goto error;
00921 }
00922 break;
00923 case 'I':
00924 case 'i':
00925 switch(state){
00926 case SIP1:
00927 state=SIP2;
00928 break;
00929
00930 case F_PROTO:
00931 proto=tmp;
00932 state=P_PROTO;
00933 break;
00934 case P_PROTO:
00935 break;
00936 default:
00937 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
00938 " state %d\n", *tmp, state);
00939 goto error;
00940 }
00941 break;
00942 case 'p':
00943 case 'P':
00944 switch(state){
00945 case SIP2:
00946 state=FIN_SIP;
00947 break;
00948
00949 case F_PROTO:
00950 proto=tmp;
00951 state=P_PROTO;
00952 break;
00953 case P_PROTO:
00954 break;
00955 default:
00956 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
00957 " state %d\n", *tmp, state);
00958 goto error;
00959 }
00960 break;
00961
00962 case '2':
00963 switch(state){
00964 case F_VER:
00965 state=VER1;
00966 break;
00967
00968 case F_PROTO:
00969 proto=tmp;
00970 state=P_PROTO;
00971 break;
00972 case P_PROTO:
00973 break;
00974 default:
00975 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
00976 " state %d\n", *tmp, state);
00977 goto error;
00978 }
00979 break;
00980 case '.':
00981 switch(state){
00982 case VER1:
00983 state=VER2;
00984 break;
00985
00986 case F_PROTO:
00987 proto=tmp;
00988 state=P_PROTO;
00989 break;
00990 case P_PROTO:
00991 break;
00992 default:
00993 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
00994 " state %d\n", *tmp, state);
00995 goto error;
00996 }
00997 break;
00998 case '0':
00999 switch(state){
01000 case VER2:
01001 state=FIN_VER;
01002 break;
01003
01004 case F_PROTO:
01005 proto=tmp;
01006 state=P_PROTO;
01007 break;
01008 case P_PROTO:
01009 break;
01010 default:
01011 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01012 " state %d\n", *tmp, state);
01013 goto error;
01014 }
01015 break;
01016
01017 default:
01018 switch(state){
01019 case F_PROTO:
01020 proto=tmp;
01021 state=P_PROTO;
01022 break;
01023 case P_PROTO:
01024 break;
01025 default:
01026 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
01027 " state %d\n", *tmp, state);
01028 goto error;
01029 }
01030 break;
01031 }
01032 }
01033
01034
01035 LOG(L_ERR, "ERROR: parse_via: bad via: end of packet on state=%d\n",
01036 state);
01037 goto error;
01038
01039 main_via:
01040
01041 tmp++;
01042 c_nest=0;
01043 ;
01044 for(;*tmp;tmp++){
01045 switch(*tmp){
01046 case ' ':
01047 case '\t':
01048 switch(state){
01049 case F_HOST:
01050 break;
01051 case P_HOST:
01052 *tmp=0;
01053 state=L_PORT;
01054 break;
01055 case L_PORT:
01056 case F_PORT:
01057 break;
01058 case P_PORT:
01059 *tmp=0;
01060 state=L_PARAM;
01061 break;
01062 case L_PARAM:
01063 case F_PARAM:
01064 break;
01065 case P_PARAM:
01066
01067 state=L_PARAM;
01068 break;
01069 case L_VIA:
01070 case F_VIA:
01071 break;
01072 case F_COMMENT:
01073 case P_COMMENT:
01074 break;
01075 case F_IP6HOST:
01076 break;
01077 case P_IP6HOST:
01078 *tmp=0;
01079 state=L_PORT;
01080 break;
01081 case F_CRLF:
01082 case F_LF:
01083 case F_CR:
01084
01085 state=saved_state;
01086 break;
01087 default:
01088 LOG(L_CRIT,"BUG: parse_via"
01089 " on <%c>, state=%d\n",*tmp, state);
01090 goto error;
01091 }
01092 break;
01093 case '\n':
01094 switch(state){
01095 case F_HOST:
01096 case L_PORT:
01097 case F_PORT:
01098 case L_PARAM:
01099 case F_PARAM:
01100 case F_VIA:
01101 case L_VIA:
01102 case F_COMMENT:
01103 case P_COMMENT:
01104 case F_IP6HOST:
01105 case P_IP6HOST:
01106 saved_state=state;
01107 state=F_LF;
01108 break;
01109 case P_HOST:
01110 *tmp=0;
01111 saved_state=L_PORT;
01112 state=F_LF;
01113 break;
01114 case P_PORT:
01115 *tmp=0;
01116 saved_state=L_PARAM;
01117 state=F_LF;
01118 break;
01119 case P_PARAM:
01120
01121 saved_state=L_PARAM;
01122 state=F_LF;
01123 break;
01124 case F_CR:
01125 state=F_CRLF;
01126 break;
01127 case F_CRLF:
01128 case F_LF:
01129 state=saved_state;
01130 goto endofheader;
01131 default:
01132 LOG(L_CRIT,"BUG: parse_via"
01133 " on <%c>\n",*tmp);
01134 goto error;
01135 }
01136 break;
01137 case '\r':
01138 switch(state){
01139 case F_HOST:
01140 case L_PORT:
01141 case F_PORT:
01142 case L_PARAM:
01143 case F_PARAM:
01144 case F_VIA:
01145 case L_VIA:
01146 case F_COMMENT:
01147 case P_COMMENT:
01148 case F_IP6HOST:
01149 case P_IP6HOST:
01150 saved_state=state;
01151 state=F_CR;
01152 break;
01153 case P_HOST:
01154 *tmp=0;
01155 saved_state=L_PORT;
01156 state=F_CR;
01157 break;
01158 case P_PORT:
01159 *tmp=0;
01160 saved_state=L_PARAM;
01161 state=F_CR;
01162 break;
01163 case P_PARAM:
01164
01165 saved_state=L_PARAM;
01166 state=F_CR;
01167 break;
01168 case F_CRLF:
01169 case F_CR:
01170 case F_LF:
01171 state=saved_state;
01172 goto endofheader;
01173 default:
01174 LOG(L_CRIT,"BUG: parse_via"
01175 " on <%c>\n",*tmp);
01176 goto error;
01177 }
01178 break;
01179
01180 case ':':
01181 switch(state){
01182 case F_HOST:
01183 case F_IP6HOST:
01184 LOG(L_ERR,"ERROR:parse_via:"
01185 " no host found\n");
01186 goto error;
01187 case P_IP6HOST:
01188 LOG(L_ERR, "ERROR:parse_via: bad ipv6 reference\n");
01189 goto error;
01190 case P_HOST:
01191 *tmp=0;
01192 state=F_PORT;
01193 break;
01194 case L_PORT:
01195 state=F_PORT;
01196 break;
01197 case P_PORT:
01198 LOG(L_ERR, "ERROR:parse_via:"
01199 " bad port\n");
01200 goto error;
01201 case L_PARAM:
01202 case F_PARAM:
01203 case P_PARAM:
01204 LOG(L_ERR, "ERROR:parse_via:"
01205 " bad char <%c> in state %d\n",
01206 *tmp,state);
01207 goto error;
01208 case L_VIA:
01209 case F_VIA:
01210 LOG(L_ERR, "ERROR:parse_via:"
01211 " bad char in compact via\n");
01212 goto error;
01213 case F_CRLF:
01214 case F_LF:
01215 case F_CR:
01216
01217 goto endofheader;
01218 case F_COMMENT:
01219 comment=tmp;
01220 state=P_COMMENT;
01221 break;
01222 case P_COMMENT:
01223 break;
01224 default:
01225 LOG(L_CRIT,"BUG: parse_via"
01226 " on <%c> state %d\n",
01227 *tmp, state);
01228 goto error;
01229 }
01230 break;
01231 case ';':
01232 switch(state){
01233 case F_HOST:
01234 case F_IP6HOST:
01235 LOG(L_ERR,"ERROR:parse_via:"
01236 " no host found\n");
01237 goto error;
01238 case P_IP6HOST:
01239 LOG(L_ERR, "ERROR:parse_via: bad ipv6 reference\n");
01240 goto error;
01241 case P_HOST:
01242 case P_PORT:
01243 *tmp=0;
01244 case L_PORT:
01245 case L_PARAM:
01246 state=F_PARAM;
01247 break;
01248 case F_PORT:
01249 LOG(L_ERR, "ERROR:parse_via:"
01250 " bad char <%c> in state %d\n",
01251 *tmp,state);
01252 goto error;
01253 case F_PARAM:
01254 LOG(L_ERR, "ERROR:parse_via:"
01255 " null param?\n");
01256 goto error;
01257 case P_PARAM:
01258
01259 state=F_PARAM;
01260 break;
01261 case L_VIA:
01262 case F_VIA:
01263 LOG(L_ERR, "ERROR:parse_via:"
01264 " bad char <%c> in next via\n",
01265 *tmp);
01266 goto error;
01267 case F_CRLF:
01268 case F_LF:
01269 case F_CR:
01270
01271 goto endofheader;
01272 case F_COMMENT:
01273 comment=tmp;
01274 state=P_COMMENT;
01275 break;
01276 case P_COMMENT:
01277 break;
01278
01279 default:
01280 LOG(L_CRIT,"BUG: parse_via"
01281 " on <%c> state %d\n",
01282 *tmp, state);
01283 goto error;
01284 }
01285 break;
01286 case ',':
01287 switch(state){
01288 case F_HOST:
01289 case F_IP6HOST:
01290 LOG(L_ERR,"ERROR:parse_via:"
01291 " no host found\n");
01292 goto error;
01293 case P_IP6HOST:
01294 LOG(L_ERR, "ERROR:parse_via: bad ipv6 reference\n");
01295 goto error;
01296 case P_HOST:
01297 case P_PORT:
01298 *tmp=0;
01299 case L_PORT:
01300 case L_PARAM:
01301 case P_PARAM:
01302 case L_VIA:
01303 state=F_VIA;
01304 break;
01305 case F_PORT:
01306 case F_PARAM:
01307 LOG(L_ERR, "ERROR:parse_via:"
01308 " invalid char <%c> in state"
01309 " %d\n", *tmp,state);
01310 goto error;
01311 case F_VIA:
01312
01313 break;
01314 case F_CRLF:
01315 case F_LF:
01316 case F_CR:
01317
01318 goto endofheader;
01319 case F_COMMENT:
01320 comment=tmp;
01321 state=P_COMMENT;
01322 break;
01323 case P_COMMENT:
01324 break;
01325 default:
01326 LOG(L_CRIT,"BUG: parse_via"
01327 " on <%c> state %d\n",
01328 *tmp, state);
01329 goto error;
01330 }
01331 break;
01332 case '(':
01333 switch(state){
01334 case F_HOST:
01335 case F_PORT:
01336 case F_PARAM:
01337 case F_VIA:
01338 case F_IP6HOST:
01339 case P_IP6HOST:
01340 LOG(_ERR,"ERROR:parse_via"
01341 " on <%c> state %d\n",
01342 *tmp, state);
01343 goto error;
01344 case P_HOST:
01345 case P_PORT:
01346 case P_PARAM:
01347 *tmp=0;
01348 case L_PORT:
01349 case L_PARAM:
01350 case L_VIA:
01351 state=F_COMMENT;
01352 c_nest++;
01353 printf("found '(', state=%d, c_nest=%d\n",
01354 state, c_nest);
01355 *tmp=0;
01356 break;
01357 case P_COMMENT:
01358 case F_COMMENT:
01359 c_nest++;
01360 break;
01361 case F_CRLF:
01362 case F_LF:
01363 case F_CR:
01364
01365 goto endofheader;
01366 default:
01367 LOG(L_CRIT,"BUG: parse_via"
01368 " on <%c> state %d\n",
01369 *tmp, state);
01370 goto error;
01371 }
01372 break;
01373 case ')':
01374 switch(state){
01375 case F_COMMENT:
01376 case P_COMMENT:
01377 if (c_nest){
01378 c_nest--;
01379 if(c_nest==0){
01380 state=L_VIA;
01381 *tmp=0;
01382 printf("out of comment\n");
01383 break;
01384 }
01385 }else{
01386 LOG(L_ERR,"ERROR:"
01387 "parse_via: "
01388 "missing '(' - "
01389 "nesting = %d\n",
01390 c_nest);
01391 goto error;
01392 }
01393 break;
01394 case F_HOST:
01395 case F_PORT:
01396 case F_PARAM:
01397 case F_VIA:
01398 case P_HOST:
01399 case P_PORT:
01400 case P_PARAM:
01401 case L_PORT:
01402 case L_PARAM:
01403 case L_VIA:
01404 case F_IP6HOST:
01405 case P_IP6HOST:
01406 LOG(L_ERR,"ERROR:parse_via"
01407 " on <%c> state %d\n",
01408 *tmp, state);
01409 goto error;
01410 case F_CRLF:
01411 case F_LF:
01412 case F_CR:
01413
01414 goto endofheader;
01415 default:
01416 LOG(L_CRIT,"BUG: parse_via"
01417 " on <%c> state %d\n",
01418 *tmp, state);
01419 goto error;
01420 }
01421 break;
01422 case '[':
01423 switch(state){
01424 case F_HOST:
01425 state=F_IP6HOST;
01426 break;
01427 case F_COMMENT:
01428 comment=tmp;
01429 state=P_COMMENT;
01430 break;
01431 case P_COMMENT:
01432 break;
01433 case F_CRLF:
01434 case F_LF:
01435 case F_CR:
01436
01437 goto endofheader;
01438 default:
01439 LOG(L_ERR,"ERROR:parse_via"
01440 " on <%c> state %d\n",
01441 *tmp, state);
01442 goto error;
01443 }
01444 break;
01445 case ']':
01446 switch(state){
01447 case P_IP6HOST:
01448 *tmp=0;
01449 state=L_PORT;
01450 break;
01451 case F_CRLF:
01452 case F_LF:
01453 case F_CR:
01454
01455 goto endofheader;
01456 case F_COMMENT:
01457 comment=tmp;
01458 state=P_COMMENT;
01459 break;
01460 case P_COMMENT:
01461 break;
01462 default:
01463 LOG(L_ERR,"ERROR:parse_via"
01464 " on <%c> state %d\n",
01465 *tmp, state);
01466 goto error;
01467 }
01468 break;
01469
01470 default:
01471 switch(state){
01472 case F_HOST:
01473 state=P_HOST;
01474 host=tmp;
01475 break;
01476 case P_HOST:
01477 break;
01478 case F_PORT:
01479 state=P_PORT;
01480 port_str=tmp;
01481 break;
01482 case P_PORT:
01483
01484 break;
01485 case F_PARAM:
01486 ;
01487 param=tmp;
01488 tmp=parse_via_param(tmp, &state, &saved_state);
01489 switch(state){
01490 case L_PARAM:
01491 case F_PARAM:
01492 case F_LF:
01493 case F_CR:
01494 break;
01495 case END_OF_HEADER:
01496 state=saved_state;
01497 goto endofheader;
01498 default:
01499 LOG(L_ERR, "ERROR: parse_via after"
01500 " parse_via_param: invalid"
01501 " char <%c> on state %d\n",
01502 *tmp, state);
01503 goto error;
01504 }
01505 break;
01506 case P_PARAM:
01507 break;
01508 case F_VIA:
01509 next_via=tmp;
01510 printf("found new via on <%c>\n", *tmp);
01511 goto nextvia;
01512 case L_PORT:
01513 case L_PARAM:
01514 case L_VIA:
01515 LOG(L_ERR,"ERROR:parse_via"
01516 " on <%c> state %d (default)\n",
01517 *tmp, state);
01518 goto error;
01519 case F_COMMENT:
01520 printf("starting comment parsing on %c \n",*tmp);
01521 state=P_COMMENT;
01522 comment=tmp;
01523 break;
01524 case P_COMMENT:
01525 break;
01526 case F_IP6HOST:
01527 state=P_IP6HOST;
01528 host=tmp;
01529 break;
01530 case P_IP6HOST:
01531 break;
01532 case F_CRLF:
01533 case F_LF:
01534 case F_CR:
01535
01536 goto endofheader;
01537 default:
01538 LOG(L_ERR, "BUG:parse_via:"
01539 " invalid char <%c>"
01540 " in state %d\n",
01541 *tmp, state);
01542 goto error;
01543 }
01544
01545
01546 }
01547 }
01548
01549 printf("end of packet reached, state=%d\n", state);
01550 goto endofpacket;
01551
01552 endofheader:
01553 state=saved_state;
01554 printf("end of header reached, state=%d\n", state);
01555 endofpacket:
01556
01557 switch(state){
01558 case P_HOST:
01559 case L_PORT:
01560 case P_PORT:
01561 case L_PARAM:
01562 case P_PARAM:
01563 case P_VALUE:
01564 case GEN_PARAM:
01565 case FIN_HIDDEN:
01566 case L_VIA:
01567 break;
01568 default:
01569 LOG(L_ERR, "ERROR: parse_via: invalid via - end of header in"
01570 " state %d\n", state);
01571 goto error;
01572 }
01573
01574 nextvia:
01575 if (proto) printf("<SIP/2.0/%s>\n", proto);
01576 if (host) printf("host= <%s>\n", host);
01577 if (port_str) printf("port= <%s>\n", port_str);
01578 if (param) printf("params= <%s>\n", param);
01579 if (comment) printf("comment= <%s>\n", comment);
01580 if(next_via) printf("next_via= <%s>\n", next_via);
01581 printf("rest=<%s>\n", tmp);
01582
01583 exit(0);
01584
01585 error:
01586 fprintf(stderr, "via parse error\n");
01587 exit(-1);
01588 }
01589