parse_uri.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  *
00006  * This file is part of ser, a free SIP server.
00007  *
00008  * ser 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  * For a license to use the ser software under conditions
00014  * other than those described here, or to purchase support for this
00015  * software, please contact iptel.org by e-mail at the following addresses:
00016  *    info@iptel.org
00017  *
00018  * ser is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License 
00024  * along with this program; if not, write to the Free Software 
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026  *
00027  * History:
00028  * --------
00029  * 2003-04-04  convenience inbound-uri parser parse_orig_ruri
00030  *             introduced (jiri)
00031  * 2003-04-11  new parse_uri introduced (better, parses also some parameters,
00032  *              works in one pass) (andrei)
00033  * 2003-04-11  ser_error is now set in parse_uri (andrei)
00034  * 2003-04-26  ZSW (jiri)
00035  * 2003-07-03  sips:, r2, lr=on support added (andrei)
00036  * 2005-02-25  preliminary tel uri support (andrei)
00037  * 2005-03-03  more tel uri fixes (andrei)
00038  * 2006-04-20  comp uri param. support (rfc3486) if defined USE_COMP  (andrei)
00039  * 2007-09-10  introduced phone2tel option which allows NOT to consider
00040  *             user=phone URIs as TEL URIs
00041  *
00042  */
00043 
00051 #include "../globals.h"
00052 #include "parse_uri.h"
00053 #include <string.h>
00054 #include "../dprint.h"
00055 #include "../ut.h"   /* q_memchr */
00056 #include "../error.h"
00057 #include "../core_stats.h"
00058 
00059 /* buf= pointer to begining of uri (sip:x@foo.bar:5060;a=b?h=i)
00060  * len= len of uri
00061  * returns: fills uri & returns <0 on error or 0 if ok 
00062  */
00063 int parse_uri(char* buf, int len, struct sip_uri* uri)
00064 {
00065         enum states  {  URI_INIT, URI_USER, URI_PASSWORD, URI_PASSWORD_ALPHA,
00066                                         URI_HOST, URI_HOST_P,
00067                                         URI_HOST6_P, URI_HOST6_END, URI_PORT, 
00068                                         URI_PARAM, URI_PARAM_P, URI_VAL_P, URI_HEADERS,
00069                                         /* param states */
00070                                         /* transport */
00071                                         PT_T, PT_R, PT_A, PT_N, PT_S, PT_P, PT_O, PT_R2, PT_T2,
00072                                         PT_eq,
00073                                         /* ttl */
00074                                               PTTL_T2, PTTL_L, PTTL_eq,
00075                                         /* user */
00076                                         PU_U, PU_S, PU_E, PU_R, PU_eq,
00077                                         /* method */
00078                                         PM_M, PM_E, PM_T, PM_H, PM_O, PM_D, PM_eq,
00079                                         /* maddr */
00080                                               PMA_A, PMA_D, PMA_D2, PMA_R, PMA_eq,
00081                                         /* lr */
00082                                         PLR_L, PLR_R_FIN, PLR_eq,
00083                                         /* r2 */
00084                                         PR2_R, PR2_2_FIN, PR2_eq,
00085                                         /* gr */
00086                                         PGR_G, PGR_R_FIN, PGR_eq,
00087 #ifdef USE_COMP
00088                                         /* comp */
00089                                         PCOMP_C, PCOMP_O, PCOMP_M, PCOMP_P, PCOMP_eq,
00090                                         
00091                                         /* comp values */
00092                                         /* sigcomp */
00093                                         VCOMP_S, VCOMP_SIGC_I, VCOMP_SIGC_G,
00094                                         VCOMP_SIGC_C, VCOMP_SIGC_O,  VCOMP_SIGC_M,
00095                                         VCOMP_SIGC_P_FIN,
00096                                         /* sergz */
00097                                                         VCOMP_SGZ_E, VCOMP_SGZ_R, VCOMP_SGZ_G,
00098                                                         VCOMP_SGZ_Z_FIN,
00099 #endif
00100                                         
00101                                         /* transport values */
00102                                         /* udp */
00103                                         VU_U, VU_D, VU_P_FIN,
00104                                         /* tcp */
00105                                         VT_T, VT_C, VT_P_FIN,
00106                                         /* tls */
00107                                               VTLS_L, VTLS_S_FIN,
00108                                         /* sctp */
00109                                         VS_S, VS_C, VS_T, VS_P_FIN
00110         };
00111         register enum states state;
00112         char* s;
00113         char* b; /* param start */
00114         char *v; /* value start */
00115         str* param; /* current param */
00116         str* param_val; /* current param val */
00117         str user;
00118         str password;
00119         int port_no;
00120         register char* p;
00121         char* end;
00122         char* pass;
00123         int found_user;
00124         int error_headers;
00125         unsigned int scheme;
00126         uri_type backup_urit;
00127         uri_flags backup_urif;
00128 
00129 #ifdef USE_COMP
00130         str comp_str; /* not returned for now */
00131         str comp_val; /* not returned for now */
00132 #endif
00133         
00134 #define SIP_SCH         0x3a706973
00135 #define SIPS_SCH        0x73706973
00136 #define TEL_SCH         0x3a6c6574
00137 #define URN_SCH         0x3a6e7275
00138         
00139 #define case_port( ch, var) \
00140         case ch: \
00141                          (var)=(var)*10+ch-'0'; \
00142                          break
00143                          
00144 #define still_at_user  \
00145                                                 if (found_user==0){ \
00146                                                         user.s=uri->host.s; \
00147                                                         if (pass){\
00148                                                                 user.len=pass-user.s; \
00149                                                                 password.s=pass+1; \
00150                                                                 password.len=p-password.s; \
00151                                                         }else{ \
00152                                                                 user.len=p-user.s; \
00153                                                         }\
00154                                                         /* save the uri type/scheme */ \
00155                                                         backup_urit=uri->type; \
00156                                                         backup_urif=uri->flags; \
00157                                                         /* everything else is 0 */ \
00158                                                         memset(uri, 0, sizeof(struct sip_uri)); \
00159                                                         /* restore the scheme & flags, copy user & pass */ \
00160                                                         uri->type=backup_urit; \
00161                                                         uri->flags=backup_urif; \
00162                                                         uri->user=user; \
00163                                                         if (pass)       uri->passwd=password;  \
00164                                                         s=p+1; \
00165                                                         found_user=1;\
00166                                                         error_headers=0; \
00167                                                         state=URI_HOST; \
00168                                                 }else goto error_bad_char 
00169 
00170 #define check_host_end \
00171                                         case ':': \
00172                                                 /* found the host */ \
00173                                                 uri->host.s=s; \
00174                                                 uri->host.len=p-s; \
00175                                                 state=URI_PORT; \
00176                                                 s=p+1; \
00177                                                 break; \
00178                                         case ';': \
00179                                                 uri->host.s=s; \
00180                                                 uri->host.len=p-s; \
00181                                                 state=URI_PARAM; \
00182                                                 s=p+1; \
00183                                                 break; \
00184                                         case '?': \
00185                                                 uri->host.s=s; \
00186                                                 uri->host.len=p-s; \
00187                                                 state=URI_HEADERS; \
00188                                                 s=p+1; \
00189                                                 break; \
00190                                         case '&': \
00191                                         case '@': \
00192                                                 goto error_bad_char 
00193 
00194 
00195 #define param_set(t_start, v_start) \
00196                                         param->s=(t_start);\
00197                                         param->len=(p-(t_start));\
00198                                         param_val->s=(v_start); \
00199                                         param_val->len=(p-(v_start)) 
00200 
00201 #define semicolon_case \
00202                                         case';': \
00203                                                 if (pass){ \
00204                                                         found_user=1;/* no user, pass cannot contain ';'*/ \
00205                                                         pass=0; \
00206                                                 } \
00207                                                 state=URI_PARAM   /* new param */ 
00208 
00209 #define question_case \
00210                                         case '?': \
00211                                                 uri->params.s=s; \
00212                                                 uri->params.len=p-s; \
00213                                                 state=URI_HEADERS; \
00214                                                 s=p+1; \
00215                                                 if (pass){ \
00216                                                         found_user=1;/* no user, pass cannot contain '?'*/ \
00217                                                         pass=0; \
00218                                                 }
00219 
00220 #define colon_case \
00221                                         case ':': \
00222                                                 if (found_user==0){ \
00223                                                         /*might be pass but only if user not found yet*/ \
00224                                                         if (pass){ \
00225                                                                 found_user=1; /* no user */ \
00226                                                                 pass=0; \
00227                                                         }else{ \
00228                                                                 pass=p; \
00229                                                         } \
00230                                                 } \
00231                                                 state=URI_PARAM_P /* generic param */
00232 
00233 #define param_common_cases \
00234                                         case '@': \
00235                                                 /* ughhh, this is still the user */ \
00236                                                 still_at_user; \
00237                                                 break; \
00238                                         semicolon_case; \
00239                                                 break; \
00240                                         question_case; \
00241                                                 break; \
00242                                         colon_case; \
00243                                                 break
00244 
00245 #define value_common_cases \
00246                                         case '@': \
00247                                                 /* ughhh, this is still the user */ \
00248                                                 still_at_user; \
00249                                                 break; \
00250                                         semicolon_case; \
00251                                                 param_set(b, v); \
00252                                                 break; \
00253                                         question_case; \
00254                                                 param_set(b, v); \
00255                                                 break; \
00256                                         colon_case; \
00257                                                 state=URI_VAL_P; \
00258                                                 break
00259 
00260 #define param_switch(old_state, c1, c2, new_state) \
00261                         case old_state: \
00262                                 switch(*p){ \
00263                                         case c1: \
00264                                         case c2: \
00265                                                 state=(new_state); \
00266                                                 break; \
00267                                         param_common_cases; \
00268                                         default: \
00269                                                 state=URI_PARAM_P; \
00270                                 } \
00271                                 break
00272 #define param_switch1(old_state, c1, new_state) \
00273                         case old_state: \
00274                                 switch(*p){ \
00275                                         case c1: \
00276                                                 state=(new_state); \
00277                                                 break; \
00278                                         param_common_cases; \
00279                                         default: \
00280                                                 state=URI_PARAM_P; \
00281                                 } \
00282                                 break
00283 #define param_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
00284                         case old_state : \
00285                                 switch(*p){ \
00286                                         case c1: \
00287                                         case c2: \
00288                                                 state=(new_state_c); \
00289                                                 break; \
00290                                         case d1: \
00291                                         case d2: \
00292                                                 state=(new_state_d); \
00293                                                 break; \
00294                                         param_common_cases; \
00295                                         default: \
00296                                                 state=URI_PARAM_P; \
00297                                 } \
00298                                 break
00299 #define value_switch(old_state, c1, c2, new_state) \
00300                         case old_state: \
00301                                 switch(*p){ \
00302                                         case c1: \
00303                                         case c2: \
00304                                                 state=(new_state); \
00305                                                 break; \
00306                                         value_common_cases; \
00307                                         default: \
00308                                                 state=URI_VAL_P; \
00309                                 } \
00310                                 break
00311 #define value_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
00312                         case old_state: \
00313                                 switch(*p){ \
00314                                         case c1: \
00315                                         case c2: \
00316                                                 state=(new_state_c); \
00317                                                 break; \
00318                                         case d1: \
00319                                         case d2: \
00320                                                 state=(new_state_d); \
00321                                                 break; \
00322                                         value_common_cases; \
00323                                         default: \
00324                                                 state=URI_VAL_P; \
00325                                 } \
00326                                 break
00327 
00328 #define transport_fin(c_state, proto_no) \
00329                         case c_state: \
00330                                 switch(*p){ \
00331                                         case '@': \
00332                                                 still_at_user; \
00333                                                 break; \
00334                                         semicolon_case; \
00335                                                 param_set(b, v); \
00336                                                 uri->proto=(proto_no); \
00337                                                 break; \
00338                                         question_case; \
00339                                                 param_set(b, v); \
00340                                                 uri->proto=(proto_no); \
00341                                                 break; \
00342                                         colon_case;  \
00343                                         default: \
00344                                                 state=URI_VAL_P; \
00345                                                 break; \
00346                                 } \
00347                                 break
00348                         
00349 
00350 #ifdef USE_COMP
00351 #define comp_fin(c_state, comp_no) \
00352                         case c_state: \
00353                                 switch(*p){ \
00354                                         case '@': \
00355                                                 still_at_user; \
00356                                                 break; \
00357                                         semicolon_case; \
00358                                                 /* param_set(b, v); */ \
00359                                                 uri->comp=(comp_no); \
00360                                                 break; \
00361                                         question_case; \
00362                                                 /* param_set(b, v) */; \
00363                                                 uri->comp=(comp_no); \
00364                                                 break; \
00365                                         colon_case;  \
00366                                         default: \
00367                                                 state=URI_VAL_P; \
00368                                                 break; \
00369                                 } \
00370                                 break
00371                         
00372 #endif
00373 
00374         /* init */
00375         end=buf+len;
00376         p=buf+4;
00377         found_user=0;
00378         error_headers=0;
00379         b=v=0;
00380         param=param_val=0;
00381         pass=0;
00382         password.s=0; /* fixes gcc 4.0 warning */
00383         password.len=0;
00384         port_no=0;
00385         state=URI_INIT;
00386         memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure*/
00387         /*look for sip:, sips: ,tel: or urn:*/
00388         if (len<5) goto error_too_short;
00389         scheme=buf[0]+(buf[1]<<8)+(buf[2]<<16)+(buf[3]<<24);
00390         scheme|=0x20202020;
00391         if (scheme==SIP_SCH){
00392                 uri->type=SIP_URI_T;
00393         }else if(scheme==SIPS_SCH){
00394                 if(buf[4]==':'){ p++; uri->type=SIPS_URI_T;}
00395                 else goto error_bad_uri;
00396         }else if (scheme==TEL_SCH){
00397                 uri->type=TEL_URI_T;
00398         }else if (scheme==URN_SCH){
00399                 uri->type=URN_URI_T;
00400         }else goto error_bad_uri;
00401         
00402         s=p;
00403         for(;p<end; p++){
00404                 switch((unsigned char)state){
00405                         case URI_INIT:
00406                                 switch(*p){
00407                                         case '[':
00408                                                 /* uri =  [ipv6address]... */
00409                                                 state=URI_HOST6_P;
00410                                                 s=p;
00411                                                 break;
00412                                         case ']':
00413                                                 /* invalid, no uri can start with ']' */
00414                                         case ':':
00415                                                 /* the same as above for ':' */
00416                                                 goto error_bad_char;
00417                                         case '@': /* error no user part, or
00418                                                                  be forgiving and accept it ? */
00419                                         default:
00420                                                 state=URI_USER;
00421                                 }
00422                                 break; 
00423                         case URI_USER:
00424                                 switch(*p){
00425                                         case '@':
00426                                                 /* found the user*/
00427                                                 uri->user.s=s;
00428                                                 uri->user.len=p-s;
00429                                                 state=URI_HOST;
00430                                                 found_user=1;
00431                                                 s=p+1; /* skip '@' */
00432                                                 break;
00433                                         case ':':
00434                                                 /* found the user, or the host? */
00435                                                 uri->user.s=s;
00436                                                 uri->user.len=p-s;
00437                                                 state=URI_PASSWORD;
00438                                                 s=p+1; /* skip ':' */
00439                                                 break;
00440                                         case ';':
00441                                                 /* this could be still the user or
00442                                                  * params?*/
00443                                                 uri->host.s=s;
00444                                                 uri->host.len=p-s;
00445                                                 state=URI_PARAM;
00446                                                 s=p+1;
00447                                                 break;
00448                                         case '?': /* still user or headers? */
00449                                                 uri->host.s=s;
00450                                                 uri->host.len=p-s;
00451                                                 state=URI_HEADERS;
00452                                                 s=p+1;
00453                                                 break;
00454                                                 /* almost anything permitted in the user part */
00455                                         case '.':
00456                                         case '-':
00457                                         case '(':
00458                                         case ')':
00459                                                 /* tel uri visual separators, set flag meaning, that
00460                                                  * user should be normalized before usage
00461                                                  */
00462                                                 uri->flags|=URI_USER_NORMALIZE;
00463                                                 break;
00464                                         case '[':
00465                                         case ']': /* the user part cannot contain "[]" */
00466                                                 goto error_bad_char;
00467                                 }
00468                                 break;
00469                         case URI_PASSWORD: /* this can also be the port (missing user)*/
00470                                 switch(*p){
00471                                         case '@':
00472                                                 /* found the password*/
00473                                                 uri->passwd.s=s;
00474                                                 uri->passwd.len=p-s;
00475                                                 port_no=0;
00476                                                 state=URI_HOST;
00477                                                 found_user=1;
00478                                                 s=p+1; /* skip '@' */
00479                                                 break;
00480                                         case ';':
00481                                                 /* upps this is the port */
00482                                                 uri->port.s=s;
00483                                                 uri->port.len=p-s;
00484                                                 uri->port_no=port_no;
00485                                                 /* user contains in fact the host */
00486                                                 uri->host.s=uri->user.s;
00487                                                 uri->host.len=uri->user.len;
00488                                                 uri->user.s=0;
00489                                                 uri->user.len=0;
00490                                                 state=URI_PARAM;
00491                                                 found_user=1; /*  there is no user part */
00492                                                 s=p+1;
00493                                                 break;
00494                                         case '?':
00495                                                 /* upps this is the port */
00496                                                 uri->port.s=s;
00497                                                 uri->port.len=p-s;
00498                                                 uri->port_no=port_no;
00499                                                 /* user contains in fact the host */
00500                                                 uri->host.s=uri->user.s;
00501                                                 uri->host.len=uri->user.len;
00502                                                 uri->user.s=0;
00503                                                 uri->user.len=0;
00504                                                 state=URI_HEADERS;
00505                                                 found_user=1; /*  there is no user part */
00506                                                 s=p+1;
00507                                                 break;
00508                                         case_port('0', port_no);
00509                                         case_port('1', port_no);
00510                                         case_port('2', port_no);
00511                                         case_port('3', port_no);
00512                                         case_port('4', port_no);
00513                                         case_port('5', port_no);
00514                                         case_port('6', port_no);
00515                                         case_port('7', port_no);
00516                                         case_port('8', port_no);
00517                                         case_port('9', port_no);
00518                                         case '[':
00519                                         case ']':
00520                                         case ':':
00521                                                 goto error_bad_char;
00522                                         default:
00523                                                 /* it can't be the port, non number found */
00524                                                 port_no=0;
00525                                                 state=URI_PASSWORD_ALPHA;
00526                                 }
00527                                 break;
00528                         case URI_PASSWORD_ALPHA:
00529                                 switch(*p){
00530                                         case '@':
00531                                                 /* found the password*/
00532                                                 uri->passwd.s=s;
00533                                                 uri->passwd.len=p-s;
00534                                                 state=URI_HOST;
00535                                                 found_user=1;
00536                                                 s=p+1; /* skip '@' */
00537                                                 break;
00538                                         case ';': /* contains non-numbers => cannot be port no*/
00539                                         case '?':
00540                                                 goto error_bad_port;
00541                                         case '[':
00542                                         case ']':
00543                                         case ':':
00544                                                 goto error_bad_char;
00545                                 }
00546                                 break;
00547                         case URI_HOST:
00548                                 switch(*p){
00549                                         case '[':
00550                                                 state=URI_HOST6_P;
00551                                                 break;
00552                                         case ':': 
00553                                         case ';':
00554                                         case '?': /* null host name ->invalid */
00555                                         case '&':
00556                                         case '@': /*chars not allowed in hosts names */
00557                                                 goto error_bad_host;
00558                                         default:
00559                                                 state=URI_HOST_P;
00560                                 }
00561                                 break;
00562                         case URI_HOST_P:
00563                                 switch(*p){
00564                                         check_host_end;
00565                                 }
00566                                 break;
00567                         case URI_HOST6_END:
00568                                 switch(*p){
00569                                         check_host_end;
00570                                         default: /*no chars allowed after [ipv6] */
00571                                                 goto error_bad_host;
00572                                 }
00573                                 break;
00574                         case URI_HOST6_P:
00575                                 switch(*p){
00576                                         case ']':
00577                                                 state=URI_HOST6_END;
00578                                                 break;
00579                                         case '[':
00580                                         case '&':
00581                                         case '@':
00582                                         case ';':
00583                                         case '?':
00584                                                 goto error_bad_host;
00585                                 }
00586                                 break;
00587                         case URI_PORT:
00588                                 switch(*p){
00589                                         case ';':
00590                                                 uri->port.s=s;
00591                                                 uri->port.len=p-s;
00592                                                 uri->port_no=port_no;
00593                                                 state=URI_PARAM;
00594                                                 s=p+1;
00595                                                 break;
00596                                         case '?':
00597                                                 uri->port.s=s;
00598                                                 uri->port.len=p-s;
00599                                                 uri->port_no=port_no;
00600                                                 state=URI_HEADERS;
00601                                                 s=p+1;
00602                                                 break;
00603                                         case_port('0', port_no);
00604                                         case_port('1', port_no);
00605                                         case_port('2', port_no);
00606                                         case_port('3', port_no);
00607                                         case_port('4', port_no);
00608                                         case_port('5', port_no);
00609                                         case_port('6', port_no);
00610                                         case_port('7', port_no);
00611                                         case_port('8', port_no);
00612                                         case_port('9', port_no);
00613                                         case '&':
00614                                         case '@':
00615                                         case ':':
00616                                         default:
00617                                                 goto error_bad_port;
00618                                 }
00619                                 break;
00620                         case URI_PARAM: /* beginning of a new param */
00621                                 switch(*p){
00622                                         param_common_cases;
00623                                         /* recognized params */
00624                                         case 't':
00625                                         case 'T':
00626                                                 b=p;
00627                                                 state=PT_T;
00628                                                 break;
00629                                         case 'u':
00630                                         case 'U':
00631                                                 b=p;
00632                                                 state=PU_U;
00633                                                 break;
00634                                         case 'm':
00635                                         case 'M':
00636                                                 b=p;
00637                                                 state=PM_M;
00638                                                 break;
00639                                         case 'l':
00640                                         case 'L':
00641                                                 b=p;
00642                                                 state=PLR_L;
00643                                                 break;
00644                                         case 'r':
00645                                         case 'R':
00646                                                 b=p;
00647                                                 state=PR2_R;
00648                                                 break;
00649                                         case 'g':
00650                                         case 'G':
00651                                                 b=p;
00652                                                 state=PGR_G;
00653                                                 break;
00654 #ifdef USE_COMP
00655                                         case 'c':
00656                                         case 'C':
00657                                                 b=p;
00658                                                 state=PCOMP_C;
00659                                                 break;
00660 #endif
00661                                         default:
00662                                                 state=URI_PARAM_P;
00663                                 }
00664                                 break;
00665                         case URI_PARAM_P: /* ignore current param */
00666                                 /* supported params:
00667                                  *  maddr, transport, ttl, lr, user, method, r2  */
00668                                 switch(*p){
00669                                         param_common_cases;
00670                                 };
00671                                 break;
00672                         /* ugly but fast param names parsing */
00673                         /*transport */
00674                         param_switch_big(PT_T,  'r', 'R', 't', 'T', PT_R, PTTL_T2);
00675                         param_switch(PT_R,  'a', 'A', PT_A);
00676                         param_switch(PT_A,  'n', 'N', PT_N);
00677                         param_switch(PT_N,  's', 'S', PT_S);
00678                         param_switch(PT_S,  'p', 'P', PT_P);
00679                         param_switch(PT_P,  'o', 'O', PT_O);
00680                         param_switch(PT_O,  'r', 'R', PT_R2);
00681                         param_switch(PT_R2, 't', 'T', PT_T2);
00682                         param_switch1(PT_T2, '=',  PT_eq);
00683                         /* value parsing */
00684                         case PT_eq:
00685                                 param=&uri->transport;
00686                                 param_val=&uri->transport_val;
00687                                 switch (*p){
00688                                         param_common_cases;
00689                                         case 'u':
00690                                         case 'U':
00691                                                 v=p;
00692                                                 state=VU_U;
00693                                                 break;
00694                                         case 't':
00695                                         case 'T':
00696                                                 v=p;
00697                                                 state=VT_T;
00698                                                 break;
00699                                         case 's':
00700                                         case 'S':
00701                                                 v=p;
00702                                                 state=VS_S;
00703                                                 break;
00704                                         default:
00705                                                 v=p;
00706                                                 state=URI_VAL_P;
00707                                 }
00708                                 break;
00709                                 /* generic value */
00710                         case URI_VAL_P:
00711                                 switch(*p){
00712                                         value_common_cases;
00713                                 }
00714                                 break;
00715                         /* udp */
00716                         value_switch(VU_U,  'd', 'D', VU_D);
00717                         value_switch(VU_D,  'p', 'P', VU_P_FIN);
00718                         transport_fin(VU_P_FIN, PROTO_UDP);
00719                         /* tcp */
00720                         value_switch_big(VT_T,  'c', 'C', 'l', 'L', VT_C, VTLS_L);
00721                         value_switch(VT_C,  'p', 'P', VT_P_FIN);
00722                         transport_fin(VT_P_FIN, PROTO_TCP);
00723                         /* tls */
00724                         value_switch(VTLS_L, 's', 'S', VTLS_S_FIN);
00725                         transport_fin(VTLS_S_FIN, PROTO_TLS);
00726                         /* sctp */
00727                         value_switch(VS_S, 'c', 'C', VS_C);
00728                         value_switch(VS_C, 't', 'T', VS_T);
00729                         value_switch(VS_T, 'p', 'P', VS_P_FIN);
00730                         transport_fin(VS_P_FIN, PROTO_SCTP);
00731                         
00732                         /* ttl */
00733                         param_switch(PTTL_T2,  'l', 'L', PTTL_L);
00734                         param_switch1(PTTL_L,  '=', PTTL_eq);
00735                         case PTTL_eq:
00736                                 param=&uri->ttl;
00737                                 param_val=&uri->ttl_val;
00738                                 switch(*p){
00739                                         param_common_cases;
00740                                         default:
00741                                                 v=p;
00742                                                 state=URI_VAL_P;
00743                                 }
00744                                 break;
00745                         
00746                         /* user param */
00747                         param_switch(PU_U, 's', 'S', PU_S);
00748                         param_switch(PU_S, 'e', 'E', PU_E);
00749                         param_switch(PU_E, 'r', 'R', PU_R);
00750                         param_switch1(PU_R, '=', PU_eq);
00751                         case PU_eq:
00752                                 param=&uri->user_param;
00753                                 param_val=&uri->user_param_val;
00754                                 switch(*p){
00755                                         param_common_cases;
00756                                         default:
00757                                                 v=p;
00758                                                 state=URI_VAL_P;
00759                                 }
00760                                 break;
00761                         
00762                         /* method*/
00763                         param_switch_big(PM_M, 'e', 'E', 'a', 'A', PM_E, PMA_A);
00764                         param_switch(PM_E, 't', 'T', PM_T);
00765                         param_switch(PM_T, 'h', 'H', PM_H);
00766                         param_switch(PM_H, 'o', 'O', PM_O);
00767                         param_switch(PM_O, 'd', 'D', PM_D);
00768                         param_switch1(PM_D, '=', PM_eq);
00769                         case PM_eq:
00770                                 param=&uri->method;
00771                                 param_val=&uri->method_val;
00772                                 switch(*p){
00773                                         param_common_cases;
00774                                         default:
00775                                                 v=p;
00776                                                 state=URI_VAL_P;
00777                                 }
00778                                 break;
00779 
00780                         /*maddr*/
00781                         param_switch(PMA_A,  'd', 'D', PMA_D);
00782                         param_switch(PMA_D,  'd', 'D', PMA_D2);
00783                         param_switch(PMA_D2, 'r', 'R', PMA_R);
00784                         param_switch1(PMA_R, '=', PMA_eq);
00785                         case PMA_eq:
00786                                 param=&uri->maddr;
00787                                 param_val=&uri->maddr_val;
00788                                 switch(*p){
00789                                         param_common_cases;
00790                                         default:
00791                                                 v=p;
00792                                                 state=URI_VAL_P;
00793                                 }
00794                                 break;
00795                         
00796                         /* lr */
00797                         param_switch(PLR_L,  'r', 'R', PLR_R_FIN);
00798                         case PLR_R_FIN:
00799                                 switch(*p){
00800                                         case '@':
00801                                                 still_at_user; 
00802                                                 break;
00803                                         case '=':
00804                                                 state=PLR_eq;
00805                                                 break;
00806                                         semicolon_case; 
00807                                                 uri->lr.s=b;
00808                                                 uri->lr.len=(p-b);
00809                                                 break;
00810                                         question_case; 
00811                                                 uri->lr.s=b;
00812                                                 uri->lr.len=(p-b);
00813                                                 break;
00814                                         colon_case;
00815                                                 break;
00816                                         default:
00817                                                 state=URI_PARAM_P;
00818                                 }
00819                                 break;
00820                                 /* handle lr=something case */
00821                         case PLR_eq:
00822                                 param=&uri->lr;
00823                                 param_val=&uri->lr_val;
00824                                 switch(*p){
00825                                         param_common_cases;
00826                                         default:
00827                                                 v=p;
00828                                                 state=URI_VAL_P;
00829                                 }
00830                                 break;
00831                         /* r2 */
00832                         param_switch1(PR2_R,  '2', PR2_2_FIN);
00833                         case PR2_2_FIN:
00834                                 switch(*p){
00835                                         case '@':
00836                                                 still_at_user; 
00837                                                 break;
00838                                         case '=':
00839                                                 state=PR2_eq;
00840                                                 break;
00841                                         semicolon_case; 
00842                                                 uri->r2.s=b;
00843                                                 uri->r2.len=(p-b);
00844                                                 break;
00845                                         question_case; 
00846                                                 uri->r2.s=b;
00847                                                 uri->r2.len=(p-b);
00848                                                 break;
00849                                         colon_case;
00850                                                 break;
00851                                         default:
00852                                                 state=URI_PARAM_P;
00853                                 }
00854                                 break;
00855                                 /* handle lr=something case */
00856                         case PR2_eq:
00857                                 param=&uri->r2;
00858                                 param_val=&uri->r2_val;
00859                                 switch(*p){
00860                                         param_common_cases;
00861                                         default:
00862                                                 v=p;
00863                                                 state=URI_VAL_P;
00864                                 }
00865                                 break;
00866                         /* gr */
00867                         param_switch(PGR_G,  'r', 'R', PGR_R_FIN);
00868                         case PGR_R_FIN:
00869                                 switch(*p){
00870                                         case '@':
00871                                                 still_at_user;
00872                                                 break;
00873                                         case '=':
00874                                                 state=PGR_eq;
00875                                                 break;
00876                                         semicolon_case;
00877                                                 uri->gr.s=b;
00878                                                 uri->gr.len=(p-b);
00879                                                 break;
00880                                         question_case;
00881                                                 uri->gr.s=b;
00882                                                 uri->gr.len=(p-b);
00883                                                 break;
00884                                         colon_case;
00885                                                 break;
00886                                         default:
00887                                                 state=URI_PARAM_P;
00888                                 }
00889                                 break;
00890                                 /* handle gr=something case */
00891                         case PGR_eq:
00892                                 param=&uri->gr;
00893                                 param_val=&uri->gr_val;
00894                                 switch(*p){
00895                                         param_common_cases;
00896                                         default:
00897                                                 v=p;
00898                                                 state=URI_VAL_P;
00899                                 }
00900                                 break;
00901 
00902 #ifdef USE_COMP
00903                         param_switch(PCOMP_C,  'o', 'O' , PCOMP_O);
00904                         param_switch(PCOMP_O,  'm', 'M' , PCOMP_M);
00905                         param_switch(PCOMP_M,  'p', 'P' , PCOMP_P);
00906                         param_switch1(PCOMP_P,  '=', PCOMP_eq);
00907                         /* value */
00908                         case PCOMP_eq:
00909                                 param=&comp_str;
00910                                 param_val=&comp_val;
00911                                 switch (*p){
00912                                         param_common_cases;
00913                                         case 's':
00914                                         case 'S':
00915                                                 v=p;
00916                                                 state=VCOMP_S;
00917                                                 break;
00918                                         default:
00919                                                 v=p;
00920                                                 state=URI_VAL_P;
00921                                 }
00922                                 break;
00923                         /* sigcomp*/
00924                         value_switch_big(VCOMP_S, 'i', 'I', 'e', 'E',
00925                                                                         VCOMP_SIGC_I, VCOMP_SGZ_E);
00926                         value_switch(VCOMP_SIGC_I, 'g', 'G', VCOMP_SIGC_G);
00927                         value_switch(VCOMP_SIGC_G, 'c', 'C', VCOMP_SIGC_C);
00928                         value_switch(VCOMP_SIGC_C, 'o', 'O', VCOMP_SIGC_O);
00929                         value_switch(VCOMP_SIGC_O, 'm', 'M', VCOMP_SIGC_M);
00930                         value_switch(VCOMP_SIGC_M, 'p', 'P', VCOMP_SIGC_P_FIN);
00931                         comp_fin(VCOMP_SIGC_P_FIN, COMP_SIGCOMP);
00932                         
00933                         /* sergz*/
00934                         value_switch(VCOMP_SGZ_E, 'r', 'R', VCOMP_SGZ_R);
00935                         value_switch(VCOMP_SGZ_R, 'g', 'G', VCOMP_SGZ_G);
00936                         value_switch(VCOMP_SGZ_G, 'z', 'Z', VCOMP_SGZ_Z_FIN);
00937                         comp_fin(VCOMP_SGZ_Z_FIN, COMP_SERGZ);
00938 #endif
00939                                 
00940                                 
00941                                 
00942                         case URI_HEADERS:
00943                                 /* for now nobody needs them so we completely ignore the 
00944                                  * headers (they are not allowed in request uri) --andrei */
00945                                 switch(*p){
00946                                         case '@':
00947                                                 /* yak, we are still at user */
00948                                                 still_at_user;
00949                                                 break;
00950                                         case ';':
00951                                                 /* we might be still parsing user, try it */
00952                                                 if (found_user) goto error_bad_char;
00953                                                 error_headers=1; /* if this is not the user
00954                                                                                         we have an error */
00955                                                 /* if pass is set => it cannot be user:pass
00956                                                  * => error (';') is illegal in a header */
00957                                                 if (pass) goto error_headers;
00958                                                 break;
00959                                         case ':':
00960                                                 if (found_user==0){
00961                                                         /*might be pass but only if user not found yet*/
00962                                                         if (pass){
00963                                                                 found_user=1; /* no user */
00964                                                                 pass=0;
00965                                                         }else{
00966                                                                 pass=p;
00967                                                         }
00968                                                 }
00969                                                 break;
00970                                         case '?':
00971                                                 if (pass){
00972                                                         found_user=1; /* no user, pass cannot contain '?'*/
00973                                                         pass=0;
00974                                                 }
00975                                                 break;
00976                                 }
00977                                 break;
00978                         default:
00979                                 goto error_bug;
00980                 }
00981         }
00982         /*end of uri */
00983         switch (state){
00984                 case URI_INIT: /* error empty uri */
00985                         goto error_too_short;
00986                 case URI_USER:
00987                         /* this is the host, it can't be the user */
00988                         if (found_user) goto error_bad_uri;
00989                         uri->host.s=s;
00990                         uri->host.len=p-s;
00991                         state=URI_HOST;
00992                         break;
00993                 case URI_PASSWORD:
00994                         /* this is the port, it can't be the passwd */
00995                         if (found_user) goto error_bad_port;
00996                         uri->port.s=s;
00997                         uri->port.len=p-s;
00998                         uri->port_no=port_no;
00999                         uri->host=uri->user;
01000                         uri->user.s=0;
01001                         uri->user.len=0;
01002                         break;
01003                 case URI_PASSWORD_ALPHA:
01004                         /* it might be an urn, check scheme and set host */
01005                         if (scheme==URN_SCH){
01006                                 uri->host.s=s;
01007                                 uri->host.len=p-s;
01008                                 DBG("parsed urn scheme...\n");
01009                         /* this is the port, it can't be the passwd */
01010                         }else goto error_bad_port;
01011                 case URI_HOST_P:
01012                 case URI_HOST6_END:
01013                         uri->host.s=s;
01014                         uri->host.len=p-s;
01015                         break;
01016                 case URI_HOST: /* error: null host */
01017                 case URI_HOST6_P: /* error: unterminated ipv6 reference*/
01018                         goto error_bad_host;
01019                 case URI_PORT:
01020                         uri->port.s=s;
01021                         uri->port.len=p-s;
01022                         uri->port_no=port_no;
01023                         break;
01024                 case URI_PARAM:
01025                 case URI_PARAM_P:
01026                 /* intermediate param states */
01027                 case PT_T: /* transport */
01028                 case PT_R:
01029                 case PT_A:
01030                 case PT_N:
01031                 case PT_S:
01032                 case PT_P:
01033                 case PT_O:
01034                 case PT_R2:
01035                 case PT_T2:
01036                 case PT_eq: /* ignore empty transport params */
01037                 case PTTL_T2: /* ttl */
01038                 case PTTL_L:
01039                 case PTTL_eq:
01040                 case PU_U:  /* user */
01041                 case PU_S:
01042                 case PU_E:
01043                 case PU_R:
01044                 case PU_eq:
01045                 case PM_M: /* method */
01046                 case PM_E:
01047                 case PM_T:
01048                 case PM_H:
01049                 case PM_O:
01050                 case PM_D:
01051                 case PM_eq:
01052                 case PLR_L: /* lr */
01053                 case PR2_R: /* r2 */
01054                 case PGR_G: /* gr */
01055 #ifdef USE_COMP
01056                 case PCOMP_C:
01057                 case PCOMP_O:
01058                 case PCOMP_M:
01059                 case PCOMP_P:
01060                 case PCOMP_eq:
01061 #endif
01062                         uri->params.s=s;
01063                         uri->params.len=p-s;
01064                         break;
01065                 /* fin param states */
01066                 case PLR_R_FIN:
01067                 case PLR_eq:
01068                         uri->params.s=s;
01069                         uri->params.len=p-s;
01070                         uri->lr.s=b;
01071                         uri->lr.len=p-b;
01072                         break;
01073                 case PR2_2_FIN:
01074                 case PR2_eq:
01075                         uri->params.s=s;
01076                         uri->params.len=p-s;
01077                         uri->r2.s=b;
01078                         uri->r2.len=p-b;
01079                         break;
01080                 case PGR_R_FIN:
01081                 case PGR_eq:
01082                         uri->params.s=s;
01083                         uri->params.len=p-s;
01084                         uri->gr.s=b;
01085                         uri->gr.len=p-b;
01086                         break;
01087                 case URI_VAL_P:
01088                 /* intermediate value states */
01089                 case VU_U:
01090                 case VU_D:
01091                 case VT_T:
01092                 case VT_C:
01093                 case VTLS_L:
01094                 case VS_S:
01095                 case VS_C:
01096                 case VS_T:
01097                         uri->params.s=s;
01098                         uri->params.len=p-s;
01099                         param_set(b, v);
01100                         break;
01101 #ifdef USE_COMP
01102                 case VCOMP_S:
01103                 case VCOMP_SIGC_I:
01104                 case VCOMP_SIGC_G:
01105                 case VCOMP_SIGC_C:
01106                 case VCOMP_SIGC_O:
01107                 case VCOMP_SIGC_M:
01108                 case VCOMP_SGZ_E:
01109                 case VCOMP_SGZ_R:
01110                 case VCOMP_SGZ_G:
01111                         /* unrecognized comp method, assume none */
01112                         uri->params.s=s;
01113                         uri->params.len=p-s;
01114                         /* uri->comp=COMP_NONE ; */
01115                         break;
01116 #endif
01117                 /* fin value states */
01118                 case VU_P_FIN:
01119                         uri->params.s=s;
01120                         uri->params.len=p-s;
01121                         param_set(b, v);
01122                         uri->proto=PROTO_UDP;
01123                         break;
01124                 case VT_P_FIN:
01125                         uri->params.s=s;
01126                         uri->params.len=p-s;
01127                         param_set(b, v);
01128                         uri->proto=PROTO_TCP;
01129                         break;
01130                 case VTLS_S_FIN:
01131                         uri->params.s=s;
01132                         uri->params.len=p-s;
01133                         param_set(b, v);
01134                         uri->proto=PROTO_TLS;
01135                         break;
01136                 case VS_P_FIN:
01137                         uri->params.s=s;
01138                         uri->params.len=p-s;
01139                         param_set(b, v);
01140                         uri->proto=PROTO_SCTP;
01141                         break;
01142 #ifdef USE_COMP
01143                 case VCOMP_SIGC_P_FIN:
01144                         uri->params.s=s;
01145                         uri->params.len=p-s;
01146                         /* param_set(b, v); */
01147                         uri->comp=COMP_SIGCOMP;
01148                         break;
01149                 case VCOMP_SGZ_Z_FIN:
01150                         uri->params.s=s;
01151                         uri->params.len=p-s;
01152                         /* param_set(b, v); */
01153                         uri->comp=COMP_SERGZ;
01154                         break;
01155 #endif
01156                 /* headers */
01157                 case URI_HEADERS:
01158                         uri->headers.s=s;
01159                         uri->headers.len=p-s;
01160                         if (error_headers) goto error_headers;
01161                         break;
01162                 default:
01163                         goto error_bug;
01164         }
01165         switch(uri->type){
01166                 case SIPS_URI_T:
01167                 case SIP_URI_T:
01168                         /* save the original sip: URI parameters in sip_params */
01169                         uri->sip_params=uri->params;
01170                         if ((phone2tel) &&
01171                              (uri->user_param_val.len == 5) &&
01172                                  (strncmp(uri->user_param_val.s, "phone", 5) == 0)
01173                                 ) {
01174                                 uri->type = TEL_URI_T;
01175                                 uri->flags |= URI_SIP_USER_PHONE;
01176                                 /* move params from user into uri->params */
01177                                 p=q_memchr(uri->user.s, ';', uri->user.len);
01178                                 if (p){
01179                                         /* NOTE: 
01180                                          * specialized uri params (user, maddr, etc.) still hold
01181                                          * the values from the sip-uri envelope
01182                                          * while uri->params point to the params in the embedded tel uri
01183                                          */
01184                                         uri->params.s=p+1;
01185                                         uri->params.len=uri->user.s+uri->user.len-uri->params.s;
01186                                         uri->user.len=p-uri->user.s;
01187                                 } else {
01188                                         uri->params.s=0;
01189                                         uri->params.len=0;
01190                                 }
01191                         } else {
01192                                 uri->flags&=~URI_USER_NORMALIZE;
01193                         }
01194                         break;
01195                 case TEL_URI_T:
01196                 case TELS_URI_T:
01197                         /* fix tel uris, move the number in uri and empty the host */
01198                         uri->user=uri->host;
01199                         uri->host.s="";
01200                         uri->host.len=0;
01201                         break;
01202                 /* urn: do nothing */
01203                 case URN_URI_T:
01204                         break;
01205                 case ERROR_URI_T:
01206                         LOG(L_ERR, "ERROR: parse_uri unexpected error (BUG?)\n"); 
01207                         goto error_bad_uri;
01208                         break; /* do nothing, avoids a compilation warning */
01209         }
01210 #ifdef EXTRA_DEBUG
01211         /* do stuff */
01212         DBG("parsed uri:\n type=%d user=<%.*s>(%d)\n passwd=<%.*s>(%d)\n"
01213                         " host=<%.*s>(%d)\n port=<%.*s>(%d): %d\n params=<%.*s>(%d)\n"
01214                         " headers=<%.*s>(%d)\n",
01215                         uri->type,
01216                         uri->user.len, ZSW(uri->user.s), uri->user.len,
01217                         uri->passwd.len, ZSW(uri->passwd.s), uri->passwd.len,
01218                         uri->host.len, ZSW(uri->host.s), uri->host.len,
01219                         uri->port.len, ZSW(uri->port.s), uri->port.len, uri->port_no,
01220                         uri->params.len, ZSW(uri->params.s), uri->params.len,
01221                         uri->headers.len, ZSW(uri->headers.s), uri->headers.len
01222                 );
01223         DBG(" uri flags : ");
01224                 if (uri->flags & URI_USER_NORMALIZE) DBG("user_need_norm ");
01225                 if (uri->flags & URI_SIP_USER_PHONE) DBG("sip_user_phone ");
01226                 DBG("   value=%d\n",uri->flags);
01227         DBG(" uri params:\n   transport=<%.*s>, val=<%.*s>, proto=%d\n",
01228                         uri->transport.len, ZSW(uri->transport.s), uri->transport_val.len,
01229                         ZSW(uri->transport_val.s), uri->proto);
01230         DBG("   user-param=<%.*s>, val=<%.*s>\n",
01231                         uri->user_param.len, ZSW(uri->user_param.s), 
01232                         uri->user_param_val.len, ZSW(uri->user_param_val.s));
01233         DBG("   method=<%.*s>, val=<%.*s>\n",
01234                         uri->method.len, ZSW(uri->method.s), 
01235                         uri->method_val.len, ZSW(uri->method_val.s));
01236         DBG("   ttl=<%.*s>, val=<%.*s>\n",
01237                         uri->ttl.len, ZSW(uri->ttl.s), 
01238                         uri->ttl_val.len, ZSW(uri->ttl_val.s));
01239         DBG("   maddr=<%.*s>, val=<%.*s>\n",
01240                         uri->maddr.len, ZSW(uri->maddr.s), 
01241                         uri->maddr_val.len, ZSW(uri->maddr_val.s));
01242         DBG("   lr=<%.*s>\n", uri->lr.len, ZSW(uri->lr.s)); 
01243         DBG("   r2=<%.*s>\n", uri->r2.len, ZSW(uri->r2.s));
01244 #ifdef USE_COMP
01245         DBG("   comp=%d\n", uri->comp);
01246 #endif
01247 
01248 #endif
01249         return 0;
01250         
01251 error_too_short:
01252         DBG("parse_uri: uri too short: <%.*s> (%d)\n",
01253                 len, ZSW(buf), len);
01254         goto error_exit;
01255 error_bad_char:
01256         DBG("parse_uri: bad char '%c' in state %d"
01257                 " parsed: <%.*s> (%d) / <%.*s> (%d)\n",
01258                 *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
01259                 len, ZSW(buf), len);
01260         goto error_exit;
01261 error_bad_host:
01262         DBG("parse_uri: bad host in uri (error at char %c in"
01263                 " state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
01264                 *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
01265                 len, ZSW(buf), len);
01266         goto error_exit;
01267 error_bad_port:
01268         DBG("parse_uri: bad port in uri (error at char %c in"
01269                 " state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
01270                 *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
01271                 len, ZSW(buf), len);
01272         goto error_exit;
01273 error_bad_uri:
01274         DBG("parse_uri: bad uri,  state %d"
01275                 " parsed: <%.*s> (%d) / <%.*s> (%d)\n",
01276                 state, (int)(p-buf), ZSW(buf), (int)(p-buf), len,
01277                 ZSW(buf), len);
01278         goto error_exit;
01279 error_headers:
01280         DBG("parse_uri: bad uri headers: <%.*s>(%d)"
01281                 " / <%.*s>(%d)\n",
01282                 uri->headers.len, ZSW(uri->headers.s), uri->headers.len,
01283                 len, ZSW(buf), len);
01284         goto error_exit;
01285 error_bug:
01286         LOG(L_CRIT, "BUG: parse_uri: bad  state %d"
01287                         " parsed: <%.*s> (%d) / <%.*s> (%d)\n",
01288                          state, (int)(p-buf), ZSW(buf), (int)(p-buf), len, ZSW(buf), len);
01289 error_exit:
01290         ser_error=E_BAD_URI;
01291         uri->type=ERROR_URI_T;
01292         STATS_BAD_URI();
01293         return E_BAD_URI;
01294 }
01295 
01296 
01297 static inline int _parse_ruri(str *uri,
01298         int *status, struct sip_uri *parsed_uri)
01299 {
01300         if (*status) return 1;
01301 
01302         if (parse_uri(uri->s, uri->len, parsed_uri)<0) {
01303                 LOG(L_ERR, "ERROR: _parse_ruri: bad uri <%.*s>\n", 
01304                                 uri->len, ZSW(uri->s));
01305                 *status=0;
01306                 return -1;
01307         }
01308         *status=1;
01309         return 1;
01310 }
01311 
01312 int parse_sip_msg_uri(struct sip_msg* msg)
01313 {
01314         char* tmp;
01315         int tmp_len;
01316         if (msg->parsed_uri_ok) return 1;
01317 
01318         if (msg->new_uri.s){
01319                 tmp=msg->new_uri.s;
01320                 tmp_len=msg->new_uri.len;
01321         }else{
01322                 tmp=msg->first_line.u.request.uri.s;
01323                 tmp_len=msg->first_line.u.request.uri.len;
01324         }
01325         if (parse_uri(tmp, tmp_len, &msg->parsed_uri)<0){
01326                 DBG("ERROR: parse_sip_msg_uri: bad uri <%.*s>\n",
01327                         tmp_len, tmp);
01328                 msg->parsed_uri_ok=0;
01329                 return -1;
01330         }
01331         msg->parsed_uri_ok=1;
01332         return 1;
01333 }
01334 
01335 int parse_orig_ruri(struct sip_msg* msg)
01336 {
01337         int ret;
01338 
01339         ret=_parse_ruri(&REQ_LINE(msg).uri,
01340                 &msg->parsed_orig_ruri_ok, &msg->parsed_orig_ruri);
01341         if (ret<0) LOG(L_ERR, "ERROR: parse_orig_ruri failed\n");
01342         return ret;
01343 }
01344 
01345 inline int normalize_tel_user(char* res, str* src) {
01346         int i, l;
01347         l=0;
01348         for (i=0; i<src->len; i++) {
01349                 switch (src->s[i]) {
01350                         case '-':
01351                         case '.':
01352                         case '(':
01353                         case ')':
01354                                 break;
01355                         default:
01356                                 res[l++]=src->s[i];
01357                 }
01358         }  
01359         return l;
01360 }
01361 
01362 
01363 str     s_sip  = STR_STATIC_INIT("sip");
01364 str     s_sips = STR_STATIC_INIT("sips");
01365 str     s_tel  = STR_STATIC_INIT("tel");
01366 str     s_tels = STR_STATIC_INIT("tels");
01367 str     s_urn  = STR_STATIC_INIT("urn");
01368 static str      s_null = STR_STATIC_INIT("");
01369 
01370 inline void uri_type_to_str(uri_type type, str *s) {
01371         switch (type) {
01372         case SIP_URI_T:
01373                 *s = s_sip;
01374                 break;
01375         case SIPS_URI_T:
01376                 *s = s_sips;
01377                 break;
01378         case TEL_URI_T:
01379                 *s = s_tel;
01380                 break;
01381         case TELS_URI_T:
01382                 *s = s_tels;
01383                 break;
01384         case URN_URI_T:
01385                 *s = s_urn;
01386                 break;
01387         default:
01388                 *s = s_null;
01389         }
01390 }
01391 
01392 static str      s_udp  = STR_STATIC_INIT("udp");
01393 static str      s_tcp  = STR_STATIC_INIT("tcp");
01394 static str      s_tls  = STR_STATIC_INIT("tls");
01395 static str      s_sctp = STR_STATIC_INIT("sctp");
01396 
01397 inline void proto_type_to_str(unsigned short type, str *s) {
01398         switch (type) {
01399         case PROTO_UDP:
01400                 *s = s_udp;
01401                 break;
01402         case PROTO_TCP:
01403                 *s = s_tcp;
01404                 break;
01405         case PROTO_TLS:
01406                 *s = s_tls;
01407                 break;
01408         case PROTO_SCTP:
01409                 *s = s_sctp;
01410                 break;
01411         default:
01412                 *s = s_null;
01413         }
01414 }