parse_uri.c

Go to the documentation of this file.
00001 /*
00002  * $Id: parse_uri.c 5344 2008-12-13 13:42:12Z klaus_darilion $
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  * History:
00023  * --------
00024  * 2003-04-04  convenience inbound-uri parser parse_orig_ruri
00025  *             introduced (jiri)
00026  * 2003-04-11  new parse_uri introduced (better, parses also some parameters,
00027  *              works in one pass) (andrei)
00028  * 2003-04-11  ser_error is now set in parse_uri (andrei)
00029  * 2003-04-26  ZSW (jiri)
00030  * 2003-07-03  sips:, r2, lr=on support added (andrei)
00031  * 2005-02-25  preliminary tel uri support (andrei)
00032  * 2005-03-03  more tel uri fixes (andrei)
00033  * 2006-11-28  Added statistic support for the number of bad URI's
00034  *             (Jeffrey Magder - SOMA Networks
00035  */
00036 
00037 /*!
00038  * \file
00039  * \brief SIP URI parser
00040  * \ingroup parser
00041  */
00042 
00043 #include "parse_uri.h"
00044 #include <string.h>
00045 #include "../dprint.h"
00046 #include "../ut.h" 
00047 #include "../error.h"
00048 #include "../errinfo.h"
00049 #include "../core_stats.h"
00050 
00051 /*! buf= pointer to begining of uri (sip:x@foo.bar:5060;a=b?h=i)
00052  * len= len of uri
00053  * returns: fills uri & returns <0 on error or 0 if ok 
00054  */
00055 int parse_uri(char* buf, int len, struct sip_uri* uri)
00056 {
00057    enum states  { URI_INIT, URI_USER, URI_PASSWORD, URI_PASSWORD_ALPHA,
00058                URI_HOST, URI_HOST_P,
00059                URI_HOST6_P, URI_HOST6_END, URI_PORT, 
00060                URI_PARAM, URI_PARAM_P, URI_VAL_P, URI_HEADERS,
00061                /* param states */
00062                /* transport */
00063                PT_T, PT_R, PT_A, PT_N, PT_S, PT_P, PT_O, PT_R2, PT_T2,
00064                PT_eq,
00065                /* ttl */
00066                      PTTL_T2, PTTL_L, PTTL_eq,
00067                /* user */
00068                PU_U, PU_S, PU_E, PU_R, PU_eq,
00069                /* method */
00070                PM_M, PM_E, PM_T, PM_H, PM_O, PM_D, PM_eq,
00071                /* maddr */
00072                      PMA_A, PMA_D, PMA_D2, PMA_R, PMA_eq,
00073                /* lr */
00074                PLR_L, PLR_R_FIN, PLR_eq,
00075                /* r2 */
00076                PR2_R, PR2_2_FIN, PR2_eq,
00077                
00078                /* transport values */
00079                /* udp */
00080                VU_U, VU_D, VU_P_FIN,
00081                /* tcp */
00082                VT_T, VT_C, VT_P_FIN,
00083                /* tls */
00084                      VTLS_L, VTLS_S_FIN,
00085                /* sctp */
00086                VS_S, VS_C, VS_T, VS_P_FIN
00087    };
00088    register enum states state;
00089    char* s;
00090    char* b; /* param start */
00091    char *v; /* value start */
00092    str* param; /* current param */
00093    str* param_val; /* current param val */
00094    str user;
00095    str password;
00096    int port_no;
00097    register char* p;
00098    char* end;
00099    char* pass;
00100    int found_user;
00101    int error_headers;
00102    unsigned int scheme;
00103    uri_type backup;
00104    
00105 #define SIP_SCH      0x3a706973
00106 #define SIPS_SCH  0x73706973
00107 #define TEL_SCH      0x3a6c6574
00108    
00109 #define case_port( ch, var) \
00110    case ch: \
00111           (var)=(var)*10+ch-'0'; \
00112           break
00113           
00114 #define still_at_user  \
00115                   if (found_user==0){ \
00116                      user.s=uri->host.s; \
00117                      if (pass){\
00118                         user.len=pass-user.s; \
00119                         password.s=pass+1; \
00120                         password.len=p-password.s; \
00121                      }else{ \
00122                         user.len=p-user.s; \
00123                      }\
00124                      /* save the uri type/scheme */ \
00125                      backup=uri->type; \
00126                      /* everything else is 0 */ \
00127                      memset(uri, 0, sizeof(struct sip_uri)); \
00128                      /* restore the scheme, copy user & pass */ \
00129                      uri->type=backup; \
00130                      uri->user=user; \
00131                      if (pass)   uri->passwd=password;  \
00132                      s=p+1; \
00133                      found_user=1;\
00134                      error_headers=0; \
00135                      state=URI_HOST; \
00136                   }else goto error_bad_char 
00137 
00138 #define check_host_end \
00139                case ':': \
00140                   /* found the host */ \
00141                   uri->host.s=s; \
00142                   uri->host.len=p-s; \
00143                   state=URI_PORT; \
00144                   s=p+1; \
00145                   break; \
00146                case ';': \
00147                   uri->host.s=s; \
00148                   uri->host.len=p-s; \
00149                   state=URI_PARAM; \
00150                   s=p+1; \
00151                   break; \
00152                case '?': \
00153                   uri->host.s=s; \
00154                   uri->host.len=p-s; \
00155                   state=URI_HEADERS; \
00156                   s=p+1; \
00157                   break; \
00158                case '&': \
00159                case '@': \
00160                   goto error_bad_char 
00161 
00162 
00163 #define param_set(t_start, v_start) \
00164                param->s=(t_start);\
00165                param->len=(p-(t_start));\
00166                param_val->s=(v_start); \
00167                param_val->len=(p-(v_start)) 
00168 
00169 #define semicolon_case \
00170                case';': \
00171                   if (pass){ \
00172                      found_user=1;/* no user, pass cannot contain ';'*/ \
00173                      pass=0; \
00174                   } \
00175                   state=URI_PARAM   /* new param */ 
00176 
00177 #define question_case \
00178                case '?': \
00179                   uri->params.s=s; \
00180                   uri->params.len=p-s; \
00181                   state=URI_HEADERS; \
00182                   s=p+1; \
00183                   if (pass){ \
00184                      found_user=1;/* no user, pass cannot contain '?'*/ \
00185                      pass=0; \
00186                   }
00187 
00188 #define colon_case \
00189                case ':': \
00190                   if (found_user==0){ \
00191                      /*might be pass but only if user not found yet*/ \
00192                      if (pass){ \
00193                         found_user=1; /* no user */ \
00194                         pass=0; \
00195                      }else{ \
00196                         pass=p; \
00197                      } \
00198                   } \
00199                   state=URI_PARAM_P /* generic param */
00200 
00201 #define param_common_cases \
00202                case '@': \
00203                   /* ughhh, this is still the user */ \
00204                   still_at_user; \
00205                   break; \
00206                semicolon_case; \
00207                   break; \
00208                question_case; \
00209                   break; \
00210                colon_case; \
00211                   break
00212 
00213 #define value_common_cases \
00214                case '@': \
00215                   /* ughhh, this is still the user */ \
00216                   still_at_user; \
00217                   break; \
00218                semicolon_case; \
00219                   param_set(b, v); \
00220                   break; \
00221                question_case; \
00222                   param_set(b, v); \
00223                   break; \
00224                colon_case; \
00225                   state=URI_VAL_P; \
00226                   break
00227 
00228 #define param_switch(old_state, c1, c2, new_state) \
00229          case old_state: \
00230             switch(*p){ \
00231                case c1: \
00232                case c2: \
00233                   state=(new_state); \
00234                   break; \
00235                param_common_cases; \
00236                default: \
00237                   state=URI_PARAM_P; \
00238             } \
00239             break
00240 #define param_switch1(old_state, c1, new_state) \
00241          case old_state: \
00242             switch(*p){ \
00243                case c1: \
00244                   state=(new_state); \
00245                   break; \
00246                param_common_cases; \
00247                default: \
00248                   state=URI_PARAM_P; \
00249             } \
00250             break
00251 #define param_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
00252          case old_state : \
00253             switch(*p){ \
00254                case c1: \
00255                case c2: \
00256                   state=(new_state_c); \
00257                   break; \
00258                case d1: \
00259                case d2: \
00260                   state=(new_state_d); \
00261                   break; \
00262                param_common_cases; \
00263                default: \
00264                   state=URI_PARAM_P; \
00265             } \
00266             break
00267 #define value_switch(old_state, c1, c2, new_state) \
00268          case old_state: \
00269             switch(*p){ \
00270                case c1: \
00271                case c2: \
00272                   state=(new_state); \
00273                   break; \
00274                value_common_cases; \
00275                default: \
00276                   state=URI_VAL_P; \
00277             } \
00278             break
00279 #define value_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
00280          case old_state: \
00281             switch(*p){ \
00282                case c1: \
00283                case c2: \
00284                   state=(new_state_c); \
00285                   break; \
00286                case d1: \
00287                case d2: \
00288                   state=(new_state_d); \
00289                   break; \
00290                value_common_cases; \
00291                default: \
00292                   state=URI_VAL_P; \
00293             } \
00294             break
00295 
00296 #define transport_fin(c_state, proto_no) \
00297          case c_state: \
00298             switch(*p){ \
00299                case '@': \
00300                   still_at_user; \
00301                   break; \
00302                semicolon_case; \
00303                   param_set(b, v); \
00304                   uri->proto=(proto_no); \
00305                   break; \
00306                question_case; \
00307                   param_set(b, v); \
00308                   uri->proto=(proto_no); \
00309                   break; \
00310                colon_case;  \
00311                default: \
00312                   state=URI_VAL_P; \
00313                   break; \
00314             } \
00315             break
00316          
00317    
00318 
00319    /* init */
00320    end=buf+len;
00321    p=buf+4;
00322    found_user=0;
00323    error_headers=0;
00324    b=v=0;
00325    param=param_val=0;
00326    pass=0;
00327    password.s = 0;
00328    password.len = 0;
00329    port_no=0;
00330    state=URI_INIT;
00331    memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure*/
00332    /*look for sip:, sips: or tel:*/
00333    if (len<5) goto error_too_short;
00334    scheme=buf[0]+(buf[1]<<8)+(buf[2]<<16)+(buf[3]<<24);
00335    scheme|=0x20202020;
00336    if (scheme==SIP_SCH){
00337       uri->type=SIP_URI_T;
00338    }else if(scheme==SIPS_SCH){
00339       if(buf[4]==':'){ p++; uri->type=SIPS_URI_T;}
00340       else goto error_bad_uri;
00341    }else if (scheme==TEL_SCH){
00342       uri->type=TEL_URI_T;
00343    }else goto error_bad_uri;
00344    
00345    s=p;
00346    for(;p<end; p++){
00347       switch((unsigned char)state){
00348          case URI_INIT:
00349             switch(*p){
00350                case '[':
00351                   /* uri =  [ipv6address]... */
00352                   state=URI_HOST6_P;
00353                   s=p;
00354                   break;
00355                case ']':
00356                   /* invalid, no uri can start with ']' */
00357                case ':':
00358                   /* the same as above for ':' */
00359                   goto error_bad_char;
00360                case '@': /* error no user part */
00361                   goto error_bad_char;
00362                default:
00363                   state=URI_USER;
00364             }
00365             break; 
00366          case URI_USER:
00367             switch(*p){
00368                case '@':
00369                   /* found the user*/
00370                   uri->user.s=s;
00371                   uri->user.len=p-s;
00372                   state=URI_HOST;
00373                   found_user=1;
00374                   s=p+1; /* skip '@' */
00375                   break;
00376                case ':':
00377                   /* found the user, or the host? */
00378                   uri->user.s=s;
00379                   uri->user.len=p-s;
00380                   state=URI_PASSWORD;
00381                   s=p+1; /* skip ':' */
00382                   break;
00383                case ';':
00384                   /* this could be still the user or
00385                    * params?*/
00386                   uri->host.s=s;
00387                   uri->host.len=p-s;
00388                   state=URI_PARAM;
00389                   s=p+1;
00390                   break;
00391                case '?': /* still user or headers? */
00392                   uri->host.s=s;
00393                   uri->host.len=p-s;
00394                   state=URI_HEADERS;
00395                   s=p+1;
00396                   break;
00397                   /* almost anything permitted in the user part */
00398                case '[':
00399                case ']': /* the user part cannot contain "[]" */
00400                   goto error_bad_char;
00401             }
00402             break;
00403          case URI_PASSWORD: /* this can also be the port (missing user)*/
00404             switch(*p){
00405                case '@':
00406                   /* found the password*/
00407                   uri->passwd.s=s;
00408                   uri->passwd.len=p-s;
00409                   port_no=0;
00410                   state=URI_HOST;
00411                   found_user=1;
00412                   s=p+1; /* skip '@' */
00413                   break;
00414                case ';':
00415                   /* upps this is the port */
00416                   uri->port.s=s;
00417                   uri->port.len=p-s;
00418                   uri->port_no=port_no;
00419                   /* user contains in fact the host */
00420                   uri->host.s=uri->user.s;
00421                   uri->host.len=uri->user.len;
00422                   uri->user.s=0;
00423                   uri->user.len=0;
00424                   state=URI_PARAM;
00425                   found_user=1; /*  there is no user part */
00426                   s=p+1;
00427                   break;
00428                case '?':
00429                   /* upps this is the port */
00430                   uri->port.s=s;
00431                   uri->port.len=p-s;
00432                   uri->port_no=port_no;
00433                   /* user contains in fact the host */
00434                   uri->host.s=uri->user.s;
00435                   uri->host.len=uri->user.len;
00436                   uri->user.s=0;
00437                   uri->user.len=0;
00438                   state=URI_HEADERS;
00439                   found_user=1; /*  there is no user part */
00440                   s=p+1;
00441                   break;
00442                case_port('0', port_no);
00443                case_port('1', port_no);
00444                case_port('2', port_no);
00445                case_port('3', port_no);
00446                case_port('4', port_no);
00447                case_port('5', port_no);
00448                case_port('6', port_no);
00449                case_port('7', port_no);
00450                case_port('8', port_no);
00451                case_port('9', port_no);
00452                case '[':
00453                case ']':
00454                case ':':
00455                   goto error_bad_char;
00456                default:
00457                   /* it can't be the port, non number found */
00458                   port_no=0;
00459                   state=URI_PASSWORD_ALPHA;
00460             }
00461             break;
00462          case URI_PASSWORD_ALPHA:
00463             switch(*p){
00464                case '@':
00465                   /* found the password*/
00466                   uri->passwd.s=s;
00467                   uri->passwd.len=p-s;
00468                   state=URI_HOST;
00469                   found_user=1;
00470                   s=p+1; /* skip '@' */
00471                   break;
00472                case ';': /* contains non-numbers => cannot be port no*/
00473                case '?':
00474                   goto error_bad_port;
00475                case '[':
00476                case ']':
00477                case ':':
00478                   goto error_bad_char;
00479             }
00480             break;
00481          case URI_HOST:
00482             switch(*p){
00483                case '[':
00484                   state=URI_HOST6_P;
00485                   break;
00486                case ':': 
00487                case ';':
00488                case '?': /* null host name ->invalid */
00489                case '&':
00490                case '@': /*chars not allowed in hosts names */
00491                   goto error_bad_host;
00492                default:
00493                   state=URI_HOST_P;
00494             }
00495             break;
00496          case URI_HOST_P:
00497             switch(*p){
00498                check_host_end;
00499             }
00500             break;
00501          case URI_HOST6_END:
00502             switch(*p){
00503                check_host_end;
00504                default: /*no chars allowed after [ipv6] */
00505                   goto error_bad_host;
00506             }
00507             break;
00508          case URI_HOST6_P:
00509             switch(*p){
00510                case ']':
00511                   state=URI_HOST6_END;
00512                   break;
00513                case '[':
00514                case '&':
00515                case '@':
00516                case ';':
00517                case '?':
00518                   goto error_bad_host;
00519             }
00520             break;
00521          case URI_PORT:
00522             switch(*p){
00523                case ';':
00524                   uri->port.s=s;
00525                   uri->port.len=p-s;
00526                   uri->port_no=port_no;
00527                   state=URI_PARAM;
00528                   s=p+1;
00529                   break;
00530                case '?':
00531                   uri->port.s=s;
00532                   uri->port.len=p-s;
00533                   uri->port_no=port_no;
00534                   state=URI_HEADERS;
00535                   s=p+1;
00536                   break;
00537                case_port('0', port_no);
00538                case_port('1', port_no);
00539                case_port('2', port_no);
00540                case_port('3', port_no);
00541                case_port('4', port_no);
00542                case_port('5', port_no);
00543                case_port('6', port_no);
00544                case_port('7', port_no);
00545                case_port('8', port_no);
00546                case_port('9', port_no);
00547                case '&':
00548                case '@':
00549                case ':':
00550                default:
00551                   goto error_bad_port;
00552             }
00553             break;
00554          case URI_PARAM: /* beginning of a new param */
00555             switch(*p){
00556                param_common_cases;
00557                /* recognized params */
00558                case 't':
00559                case 'T':
00560                   b=p;
00561                   state=PT_T;
00562                   break;
00563                case 'u':
00564                case 'U':
00565                   b=p;
00566                   state=PU_U;
00567                   break;
00568                case 'm':
00569                case 'M':
00570                   b=p;
00571                   state=PM_M;
00572                   break;
00573                case 'l':
00574                case 'L':
00575                   b=p;
00576                   state=PLR_L;
00577                   break;
00578                case 'r':
00579                case 'R':
00580                   b=p;
00581                   state=PR2_R;
00582                default:
00583                   state=URI_PARAM_P;
00584             }
00585             break;
00586          case URI_PARAM_P: /* ignore current param */
00587             /* supported params:
00588              *  maddr, transport, ttl, lr, user, method, r2  */
00589             switch(*p){
00590                param_common_cases;
00591             };
00592             break;
00593          /* ugly but fast param names parsing */
00594          /*transport */
00595          param_switch_big(PT_T,  'r', 'R', 't', 'T', PT_R, PTTL_T2);
00596          param_switch(PT_R,  'a', 'A', PT_A);
00597          param_switch(PT_A,  'n', 'N', PT_N);
00598          param_switch(PT_N,  's', 'S', PT_S);
00599          param_switch(PT_S,  'p', 'P', PT_P);
00600          param_switch(PT_P,  'o', 'O', PT_O);
00601          param_switch(PT_O,  'r', 'R', PT_R2);
00602          param_switch(PT_R2, 't', 'T', PT_T2);
00603          param_switch1(PT_T2, '=',  PT_eq);
00604          /* value parsing */
00605          case PT_eq:
00606             param=&uri->transport;
00607             param_val=&uri->transport_val;
00608             switch (*p){
00609                param_common_cases;
00610                case 'u':
00611                case 'U':
00612                   v=p;
00613                   state=VU_U;
00614                   break;
00615                case 't':
00616                case 'T':
00617                   v=p;
00618                   state=VT_T;
00619                   break;
00620                case 's':
00621                case 'S':
00622                   v=p;
00623                   state=VS_S;
00624                   break;
00625                default:
00626                   v=p;
00627                   state=URI_VAL_P;
00628             }
00629             break;
00630             /* generic value */
00631          case URI_VAL_P:
00632             switch(*p){
00633                value_common_cases;
00634             }
00635             break;
00636          /* udp */
00637          value_switch(VU_U,  'd', 'D', VU_D);
00638          value_switch(VU_D,  'p', 'P', VU_P_FIN);
00639          transport_fin(VU_P_FIN, PROTO_UDP);
00640          /* tcp */
00641          value_switch_big(VT_T,  'c', 'C', 'l', 'L', VT_C, VTLS_L);
00642          value_switch(VT_C,  'p', 'P', VT_P_FIN);
00643          transport_fin(VT_P_FIN, PROTO_TCP);
00644          /* tls */
00645          value_switch(VTLS_L, 's', 'S', VTLS_S_FIN);
00646          transport_fin(VTLS_S_FIN, PROTO_TLS);
00647          /* sctp */
00648          value_switch(VS_S, 'c', 'C', VS_C);
00649          value_switch(VS_C, 't', 'T', VS_T);
00650          value_switch(VS_T, 'p', 'P', VS_P_FIN);
00651          transport_fin(VS_P_FIN, PROTO_SCTP);
00652          
00653          /* ttl */
00654          param_switch(PTTL_T2,  'l', 'L', PTTL_L);
00655          param_switch1(PTTL_L,  '=', PTTL_eq);
00656          case PTTL_eq:
00657             param=&uri->ttl;
00658             param_val=&uri->ttl_val;
00659             switch(*p){
00660                param_common_cases;
00661                default:
00662                   v=p;
00663                   state=URI_VAL_P;
00664             }
00665             break;
00666          
00667          /* user param */
00668          param_switch(PU_U, 's', 'S', PU_S);
00669          param_switch(PU_S, 'e', 'E', PU_E);
00670          param_switch(PU_E, 'r', 'R', PU_R);
00671          param_switch1(PU_R, '=', PU_eq);
00672          case PU_eq:
00673             param=&uri->user_param;
00674             param_val=&uri->user_param_val;
00675             switch(*p){
00676                param_common_cases;
00677                default:
00678                   v=p;
00679                   state=URI_VAL_P;
00680             }
00681             break;
00682          
00683          /* method*/
00684          param_switch_big(PM_M, 'e', 'E', 'a', 'A', PM_E, PMA_A);
00685          param_switch(PM_E, 't', 'T', PM_T);
00686          param_switch(PM_T, 'h', 'H', PM_H);
00687          param_switch(PM_H, 'o', 'O', PM_O);
00688          param_switch(PM_O, 'd', 'D', PM_D);
00689          param_switch1(PM_D, '=', PM_eq);
00690          case PM_eq:
00691             param=&uri->method;
00692             param_val=&uri->method_val;
00693             switch(*p){
00694                param_common_cases;
00695                default:
00696                   v=p;
00697                   state=URI_VAL_P;
00698             }
00699             break;
00700 
00701          /*maddr*/
00702          param_switch(PMA_A,  'd', 'D', PMA_D);
00703          param_switch(PMA_D,  'd', 'D', PMA_D2);
00704          param_switch(PMA_D2, 'r', 'R', PMA_R);
00705          param_switch1(PMA_R, '=', PMA_eq);
00706          case PMA_eq:
00707             param=&uri->maddr;
00708             param_val=&uri->maddr_val;
00709             switch(*p){
00710                param_common_cases;
00711                default:
00712                   v=p;
00713                   state=URI_VAL_P;
00714             }
00715             break;
00716          
00717          /* lr */
00718          param_switch(PLR_L,  'r', 'R', PLR_R_FIN);
00719          case PLR_R_FIN:
00720             switch(*p){
00721                case '@':
00722                   still_at_user; 
00723                   break;
00724                case '=':
00725                   state=PLR_eq;
00726                   break;
00727                semicolon_case; 
00728                   uri->lr.s=b;
00729                   uri->lr.len=(p-b);
00730                   break;
00731                question_case; 
00732                   uri->lr.s=b;
00733                   uri->lr.len=(p-b);
00734                   break;
00735                colon_case;
00736                   break;
00737                default:
00738                   state=URI_PARAM_P;
00739             }
00740             break;
00741             /* handle lr=something case */
00742          case PLR_eq:
00743             param=&uri->lr;
00744             param_val=&uri->lr_val;
00745             switch(*p){
00746                param_common_cases;
00747                default:
00748                   v=p;
00749                   state=URI_VAL_P;
00750             }
00751             break;
00752          /* r2 */
00753          param_switch1(PR2_R,  '2', PR2_2_FIN);
00754          case PR2_2_FIN:
00755             switch(*p){
00756                case '@':
00757                   still_at_user; 
00758                   break;
00759                case '=':
00760                   state=PR2_eq;
00761                   break;
00762                semicolon_case; 
00763                   uri->r2.s=b;
00764                   uri->r2.len=(p-b);
00765                   break;
00766                question_case; 
00767                   uri->r2.s=b;
00768                   uri->r2.len=(p-b);
00769                   break;
00770                colon_case;
00771                   break;
00772                default:
00773                   state=URI_PARAM_P;
00774             }
00775             break;
00776             /* handle lr=something case */
00777          case PR2_eq:
00778             param=&uri->r2;
00779             param_val=&uri->r2_val;
00780             switch(*p){
00781                param_common_cases;
00782                default:
00783                   v=p;
00784                   state=URI_VAL_P;
00785             }
00786             break;
00787             
00788             
00789          case URI_HEADERS:
00790             /* for now nobody needs them so we completely ignore the 
00791              * headers (they are not allowed in request uri) --andrei */
00792             switch(*p){
00793                case '@':
00794                   /* yak, we are still at user */
00795                   still_at_user;
00796                   break;
00797                case ';':
00798                   /* we might be still parsing user, try it */
00799                   if (found_user) goto error_bad_char;
00800                   error_headers=1; /* if this is not the user
00801                                  we have an error */
00802                   /* if pass is set => it cannot be user:pass
00803                    * => error (';') is illegal in a header */
00804                   if (pass) goto error_headers;
00805                   break;
00806                case ':':
00807                   if (found_user==0){
00808                      /*might be pass but only if user not found yet*/
00809                      if (pass){
00810                         found_user=1; /* no user */
00811                         pass=0;
00812                      }else{
00813                         pass=p;
00814                      }
00815                   }
00816                   break;
00817                case '?':
00818                   if (pass){
00819                      found_user=1; /* no user, pass cannot contain '?'*/
00820                      pass=0;
00821                   }
00822                   break;
00823             }
00824             break;
00825          default:
00826             goto error_bug;
00827       }
00828    }
00829    /*end of uri */
00830    switch (state){
00831       case URI_INIT: /* error empty uri */
00832          goto error_too_short;
00833       case URI_USER:
00834          /* this is the host, it can't be the user */
00835          if (found_user) goto error_bad_uri;
00836          uri->host.s=s;
00837          uri->host.len=p-s;
00838          state=URI_HOST;
00839          break;
00840       case URI_PASSWORD:
00841          /* this is the port, it can't be the passwd */
00842          if (found_user) goto error_bad_port;
00843          uri->port.s=s;
00844          uri->port.len=p-s;
00845          uri->port_no=port_no;
00846          uri->host=uri->user;
00847          uri->user.s=0;
00848          uri->user.len=0;
00849          break;
00850       case URI_PASSWORD_ALPHA:
00851          /* this is the port, it can't be the passwd */
00852          goto error_bad_port;
00853       case URI_HOST_P:
00854       case URI_HOST6_END:
00855          uri->host.s=s;
00856          uri->host.len=p-s;
00857          break;
00858       case URI_HOST: /* error: null host */
00859       case URI_HOST6_P: /* error: unterminated ipv6 reference*/
00860          goto error_bad_host;
00861       case URI_PORT:
00862          uri->port.s=s;
00863          uri->port.len=p-s;
00864          uri->port_no=port_no;
00865          break;
00866       case URI_PARAM:
00867       case URI_PARAM_P:
00868       /* intermediate param states */
00869       case PT_T: /* transport */
00870       case PT_R:
00871       case PT_A:
00872       case PT_N:
00873       case PT_S:
00874       case PT_P:
00875       case PT_O:
00876       case PT_R2:
00877       case PT_T2:
00878       case PT_eq: /* ignore empty transport params */
00879       case PTTL_T2: /* ttl */
00880       case PTTL_L:
00881       case PTTL_eq:
00882       case PU_U:  /* user */
00883       case PU_S:
00884       case PU_E:
00885       case PU_R:
00886       case PU_eq:
00887       case PM_M: /* method */
00888       case PM_E:
00889       case PM_T:
00890       case PM_H:
00891       case PM_O:
00892       case PM_D:
00893       case PM_eq:
00894       case PLR_L: /* lr */
00895       case PR2_R:  /* r2 */
00896          uri->params.s=s;
00897          uri->params.len=p-s;
00898          break;
00899       /* fin param states */
00900       case PLR_R_FIN:
00901       case PLR_eq:
00902          uri->params.s=s;
00903          uri->params.len=p-s;
00904          uri->lr.s=b;
00905          uri->lr.len=p-b;
00906          break;
00907       case PR2_2_FIN:
00908       case PR2_eq:
00909          uri->params.s=s;
00910          uri->params.len=p-s;
00911          uri->r2.s=b;
00912          uri->r2.len=p-b;
00913          break;
00914       case URI_VAL_P:
00915       /* intermediate value states */
00916       case VU_U:
00917       case VU_D:
00918       case VT_T:
00919       case VT_C:
00920       case VTLS_L:
00921       case VS_S:
00922       case VS_C:
00923       case VS_T:
00924          uri->params.s=s;
00925          uri->params.len=p-s;
00926          param_set(b, v);
00927          break;
00928       /* fin value states */
00929       case VU_P_FIN:
00930          uri->params.s=s;
00931          uri->params.len=p-s;
00932          param_set(b, v);
00933          uri->proto=PROTO_UDP;
00934          break;
00935       case VT_P_FIN:
00936          uri->params.s=s;
00937          uri->params.len=p-s;
00938          param_set(b, v);
00939          uri->proto=PROTO_TCP;
00940          break;
00941       case VTLS_S_FIN:
00942          uri->params.s=s;
00943          uri->params.len=p-s;
00944          param_set(b, v);
00945          uri->proto=PROTO_TLS;
00946          break;
00947       case VS_P_FIN:
00948          uri->params.s=s;
00949          uri->params.len=p-s;
00950          param_set(b, v);
00951          uri->proto=PROTO_SCTP;
00952          break;
00953       /* headers */
00954       case URI_HEADERS:
00955          uri->headers.s=s;
00956          uri->headers.len=p-s;
00957          if (error_headers) goto error_headers;
00958          break;
00959       default:
00960          goto error_bug;
00961    }
00962    switch(uri->type){
00963       case SIP_URI_T:
00964          if ((uri->user_param_val.len == 5) &&
00965             (strncasecmp(uri->user_param_val.s, "phone", 5) == 0)) {
00966             uri->type = TEL_URI_T;
00967             /* move params from user into uri->params */
00968             p=memchr(uri->user.s, ';', uri->user.len);
00969             if (p){
00970                uri->params.s=p+1;
00971                uri->params.len=uri->user.s+uri->user.len-uri->params.s;
00972                uri->user.len=p-uri->user.s;
00973             }
00974          }
00975          break;
00976       case SIPS_URI_T:
00977          if ((uri->user_param_val.len == 5) &&
00978             (strncasecmp(uri->user_param_val.s, "phone", 5) == 0)) {
00979             uri->type = TELS_URI_T;
00980             p=memchr(uri->user.s, ';', uri->user.len);
00981             if (p){
00982                uri->params.s=p+1;
00983                uri->params.len=uri->user.s+uri->user.len-uri->params.s;
00984                uri->user.len=p-uri->user.s;
00985             }
00986          }
00987          break;
00988       case TEL_URI_T:
00989       case TELS_URI_T:
00990          /* fix tel uris, move the number in uri and empty the host */
00991          uri->user=uri->host;
00992          uri->host.s="";
00993          uri->host.len=0;
00994          break;
00995       case ERROR_URI_T:
00996          LM_ERR("unexpected error (BUG?)\n"); 
00997          goto error_bad_uri;
00998          break; /* do nothing, avoids a compilation warning */
00999    }
01000 #ifdef EXTRA_DEBUG
01001    /* do stuff */
01002    LM_DBG("parsed uri:\n type=%d user=<%.*s>(%d)\n passwd=<%.*s>(%d)\n"
01003          " host=<%.*s>(%d)\n port=<%.*s>(%d): %d\n params=<%.*s>(%d)\n"
01004          " headers=<%.*s>(%d)\n",
01005          uri->type,
01006          uri->user.len, ZSW(uri->user.s), uri->user.len,
01007          uri->passwd.len, ZSW(uri->passwd.s), uri->passwd.len,
01008          uri->host.len, ZSW(uri->host.s), uri->host.len,
01009          uri->port.len, ZSW(uri->port.s), uri->port.len, uri->port_no,
01010          uri->params.len, ZSW(uri->params.s), uri->params.len,
01011          uri->headers.len, ZSW(uri->headers.s), uri->headers.len
01012       );
01013    LM_DBG(" uri params:\n   transport=<%.*s>, val=<%.*s>, proto=%d\n",
01014          uri->transport.len, ZSW(uri->transport.s), uri->transport_val.len,
01015          ZSW(uri->transport_val.s), uri->proto);
01016    LM_DBG("   user-param=<%.*s>, val=<%.*s>\n",
01017          uri->user_param.len, ZSW(uri->user_param.s), 
01018          uri->user_param_val.len, ZSW(uri->user_param_val.s));
01019    LM_DBG("   method=<%.*s>, val=<%.*s>\n",
01020          uri->method.len, ZSW(uri->method.s), 
01021          uri->method_val.len, ZSW(uri->method_val.s));
01022    LM_DBG("   ttl=<%.*s>, val=<%.*s>\n",
01023          uri->ttl.len, ZSW(uri->ttl.s), 
01024          uri->ttl_val.len, ZSW(uri->ttl_val.s));
01025    LM_DBG("   maddr=<%.*s>, val=<%.*s>\n",
01026          uri->maddr.len, ZSW(uri->maddr.s), 
01027          uri->maddr_val.len, ZSW(uri->maddr_val.s));
01028    LM_DBG("   lr=<%.*s>\n", uri->lr.len, ZSW(uri->lr.s)); 
01029 #endif
01030    return 0;
01031    
01032 error_too_short:
01033    LM_ERR("uri too short: <%.*s> (%d)\n",
01034          len, ZSW(buf), len);
01035    goto error_exit;
01036 error_bad_char:
01037    LM_ERR("bad char '%c' in state %d"
01038          " parsed: <%.*s> (%d) / <%.*s> (%d)\n",
01039          *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
01040          len, ZSW(buf), len);
01041    goto error_exit;
01042 error_bad_host:
01043    LM_ERR("bad host in uri (error at char %c in"
01044          " state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
01045          *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
01046          len, ZSW(buf), len);
01047    goto error_exit;
01048 error_bad_port:
01049    LM_ERR("bad port in uri (error at char %c in"
01050          " state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
01051          *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
01052          len, ZSW(buf), len);
01053    goto error_exit;
01054 error_bad_uri:
01055    LM_ERR("bad uri,  state %d parsed: <%.*s> (%d) / <%.*s> (%d)\n",
01056           state, (int)(p-buf), ZSW(buf), (int)(p-buf), len,
01057           ZSW(buf), len);
01058    goto error_exit;
01059 error_headers:
01060    LM_ERR("bad uri headers: <%.*s>(%d) / <%.*s>(%d)\n",
01061          uri->headers.len, ZSW(uri->headers.s), uri->headers.len,
01062          len, ZSW(buf), len);
01063    goto error_exit;
01064 error_bug:
01065    LM_CRIT("bad  state %d parsed: <%.*s> (%d) / <%.*s> (%d)\n",
01066           state, (int)(p-buf), ZSW(buf), (int)(p-buf), len, ZSW(buf), len);
01067 error_exit:
01068    ser_error=E_BAD_URI;
01069    uri->type=ERROR_URI_T;
01070    update_stat(bad_URIs, 1);
01071    return E_BAD_URI;
01072 }
01073 
01074 
01075 int parse_sip_msg_uri(struct sip_msg* msg)
01076 {
01077    char* tmp;
01078    int tmp_len;
01079    if (msg->parsed_uri_ok) return 1;
01080 
01081    if (msg->new_uri.s){
01082       tmp=msg->new_uri.s;
01083       tmp_len=msg->new_uri.len;
01084    }else{
01085       tmp=msg->first_line.u.request.uri.s;
01086       tmp_len=msg->first_line.u.request.uri.len;
01087    }
01088    if (parse_uri(tmp, tmp_len, &msg->parsed_uri)<0){
01089       LM_ERR("bad uri <%.*s>\n", tmp_len, tmp);
01090       msg->parsed_uri_ok=0;
01091       set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM, "error parsing r-uri");
01092       set_err_reply(400, "bad r-uri");
01093       return -1;
01094    }
01095    msg->parsed_uri_ok=1;
01096    return 0;
01097 }
01098 
01099 
01100 int parse_orig_ruri(struct sip_msg* msg)
01101 {
01102    str *uri;
01103 
01104    if (msg->parsed_orig_ruri_ok)
01105       return 1;
01106 
01107    uri = &REQ_LINE(msg).uri;
01108 
01109    if (parse_uri(uri->s, uri->len, &msg->parsed_orig_ruri)<0) {
01110       LM_ERR("bad uri <%.*s>\n", uri->len, ZSW(uri->s));
01111       msg->parsed_orig_ruri_ok = 0;
01112       set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
01113             "error parsing incoming uri");
01114       set_err_reply(400, "bad i-uri");
01115       return -1;
01116    }
01117 
01118    msg->parsed_orig_ruri_ok = 1;
01119    return 0;
01120 }

Generated on Thu May 24 00:00:28 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6