via_parse.c

00001 
00002 /* test program -> via parse */
00003 /*
00004  *
00005  * Copyright (C) 2001-2003 FhG Fokus
00006  *
00007  * This file is part of ser, a free SIP server.
00008  *
00009  * ser is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version
00013  *
00014  * For a license to use the ser software under conditions
00015  * other than those described here, or to purchase support for this
00016  * software, please contact iptel.org by e-mail at the following addresses:
00017  *    info@iptel.org
00018  *
00019  * ser is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  * GNU General Public License for more details.
00023  *
00024  * You should have received a copy of the GNU General Public License 
00025  * along with this program; if not, write to the Free Software 
00026  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00027  */
00028 
00029 
00030 
00031 /* parsing:           compact form:
00032  */
00033 
00034 /* 
00035  * still TODO/test:
00036  *  - parse next via
00037  *  - return a list of header structs
00038  *  - '[' ']' ipv6 parsing!
00039  *  - return list of params
00040  *  - test ^\s...'
00041  *  - add support for parsing via front (SIP/2.0/UDP)
00042  */
00043 
00044 #include <stdio.h>
00045 
00046 /* main via states (uri:port ...) */
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 /* first via part state */
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 /* param related states */
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                 /* fin states (227-...)*/
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 /* entry state must be F_PARAM, or saved_state=F_PARAM and 
00084  * state=F_{LF,CR,CRLF}!
00085  * output state = L_PARAM or F_PARAM or END_OF_HEADER 
00086  * (and saved_state= last state); everything else => error */
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                         /* \n and \r*/
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                                 /* param names */
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         }/* for tmp*/
00551 
00552 /* end of packet?*/
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: /*eat space*/
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: /*eat space*/
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: /*eat space*/
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; /* what to do? */
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         } /* for2 tmp*/
00716 
00717         /* if generic_param => it can have no value */
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         //tmp++;
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; /* in fact transport*/
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         /* parse start of via ( SIP/2.0/UDP    )*/
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: /* eat space */
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;  /* finished proto parsing */
00785                                                 state=F_HOST; /* start looking for 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: /* header continues on this line */
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; /* start looking for 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: /*end of line ?next header?*/
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                                 /* match SIP*/
00904                         case 'S':
00905                         case 's':
00906                                 switch(state){
00907                                         case F_SIP:
00908                                                 state=SIP1;
00909                                                 break;
00910                                         /* allow S in PROTO */
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                                         /* allow i in PROTO */
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                                         /* allow p in PROTO */
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                         /*match 2.0*/
00962                         case '2':
00963                                 switch(state){
00964                                         case F_VER:
00965                                                 state=VER1;
00966                                                 break;
00967                                         /* allow 2 in PROTO*/
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                                         /* allow . in PROTO */
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                                         /* allow 0 in PROTO*/
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         } /* for tmp*/
01033 
01034 /* we should not be here! if everything is ok > main_via*/
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 /* inc tmp to point to the next char*/
01041         tmp++;
01042         c_nest=0;
01043         /*state should always be F_HOST here*/;
01044         for(;*tmp;tmp++){
01045                 switch(*tmp){
01046                         case ' ':
01047                         case '\t':
01048                                 switch(state){
01049                                         case F_HOST:/*eat the spaces*/
01050                                                 break;
01051                                         case P_HOST:
01052                                                  *tmp=0;/*mark end of host*/
01053                                                  state=L_PORT;
01054                                                  break;
01055                                         case L_PORT: /*eat the spaces*/
01056                                         case F_PORT:
01057                                                 break;
01058                                         case P_PORT:
01059                                                 *tmp=0; /*end of port */
01060                                                 state=L_PARAM;
01061                                                 break;
01062                                         case L_PARAM: /* eat the space */
01063                                         case F_PARAM:
01064                                                 break;
01065                                         case P_PARAM:
01066                                         /*      *tmp=0;*/ 
01067                                                 state=L_PARAM;
01068                                                 break;
01069                                         case L_VIA:
01070                                         case F_VIA: /* eat the space */
01071                                                 break;
01072                                         case F_COMMENT:
01073                                         case P_COMMENT:
01074                                                 break;
01075                                         case F_IP6HOST: /*eat the spaces*/
01076                                                 break;
01077                                         case P_IP6HOST:
01078                                                 *tmp=0; /*mark end of host*/
01079                                                 state=L_PORT; 
01080                                                 break;
01081                                         case F_CRLF:
01082                                         case F_LF:
01083                                         case F_CR:
01084                                                 /*previous=crlf and now =' '*/
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:/*eat the spaces*/
01096                                         case L_PORT: /*eat the spaces*/
01097                                         case F_PORT:
01098                                         case L_PARAM: /* eat the space */
01099                                         case F_PARAM:
01100                                         case F_VIA: /* eat the space */
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;/*mark end of host*/
01111                                                  saved_state=L_PORT;
01112                                                  state=F_LF;
01113                                                  break;
01114                                         case P_PORT:
01115                                                 *tmp=0; /*end of port */
01116                                                 saved_state=L_PARAM;
01117                                                 state=F_LF;
01118                                                 break;
01119                                         case P_PARAM:
01120                                         /*      *tmp=0;*/ 
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:/*eat the spaces*/
01140                                         case L_PORT: /*eat the spaces*/
01141                                         case F_PORT:
01142                                         case L_PARAM: /* eat the space */
01143                                         case F_PARAM:
01144                                         case F_VIA: /* eat the space */
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;/*mark end of host*/
01155                                                  saved_state=L_PORT;
01156                                                  state=F_CR;
01157                                                  break;
01158                                         case P_PORT:
01159                                                 *tmp=0; /*end of port */
01160                                                 saved_state=L_PARAM;
01161                                                 state=F_CR;
01162                                                 break;
01163                                         case P_PARAM:
01164                                         /*      *tmp=0;*/ 
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; /*mark  end of host*/
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                                                 /*previous=crlf and now !=' '*/
01217                                                 goto endofheader;
01218                                         case F_COMMENT:/*everything is allowed in a comment*/
01219                                                 comment=tmp;
01220                                                 state=P_COMMENT;
01221                                                 break;
01222                                         case P_COMMENT: /*everything is allowed in a 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; /*mark the end*/
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                                                 /*hmm next, param?*/
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                                                 /*previous=crlf and now !=' '*/
01271                                                 goto endofheader;
01272                                         case F_COMMENT:/*everything is allowed in a comment*/
01273                                                 comment=tmp;
01274                                                 state=P_COMMENT;
01275                                                 break;
01276                                         case P_COMMENT: /*everything is allowed in a 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; /*mark the end*/
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                                                 /* do  nothing,  eat ","*/
01313                                                 break;  
01314                                         case F_CRLF:
01315                                         case F_LF:
01316                                         case F_CR:
01317                                                 /*previous=crlf and now !=' '*/
01318                                                 goto endofheader;
01319                                         case F_COMMENT:/*everything is allowed in a comment*/
01320                                                 comment=tmp;
01321                                                 state=P_COMMENT;
01322                                                 break;
01323                                         case P_COMMENT: /*everything is allowed in a 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: /*must be terminated in ']'*/
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; /*mark the end*/
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                                                 /*previous=crlf and now !=' '*/
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                                                 /*previous=crlf and now !=' '*/
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:/*everything is allowed in a 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                                                 /*previous=crlf and now !=' '*/
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; /*mark the end*/
01449                                                 state=L_PORT;
01450                                                 break;
01451                                         case F_CRLF:
01452                                         case F_LF:
01453                                         case F_CR:
01454                                                 /*previous=crlf and now !=' '*/
01455                                                 goto endofheader;
01456                                         case F_COMMENT:/*everything is allowed in a 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                                                 /*check if number?*/
01484                                                 break;
01485                                         case F_PARAM:
01486                                                 /*state=P_PARAM*/;
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                                                 /*previous=crlf and now !=' '*/
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; /*end of packet, probably should be goto error*/
01551         
01552 endofheader:
01553         state=saved_state;
01554         printf("end of header reached, state=%d\n", state);
01555 endofpacket:
01556         /* check if error*/
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