Strip, prefix, rewriteuser, ... all the SET_* actions preserve the
[sip-router] / parser / parse_uri.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License 
24  * along with this program; if not, write to the Free Software 
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  *
27  * History:
28  * --------
29  * 2003-04-04  convenience inbound-uri parser parse_orig_ruri
30  *             introduced (jiri)
31  * 2003-04-11  new parse_uri introduced (better, parses also some parameters,
32  *              works in one pass) (andrei)
33  * 2003-04-11  ser_error is now set in parse_uri (andrei)
34  * 2003-04-26  ZSW (jiri)
35  * 2003-07-03  sips:, r2, lr=on support added (andrei)
36  * 2005-02-25  preliminary tel uri support (andrei)
37  * 2005-03-03  more tel uri fixes (andrei)
38  * 2006-04-20  comp uri param. support (rfc3486) if defined USE_COMP  (andrei)
39  * 2007-09-10  introduced phone2tel option which allows NOT to consider
40  *             user=phone URIs as TEL URIs
41  *
42  */
43
44
45 #include "../globals.h"
46 #include "parse_uri.h"
47 #include <string.h>
48 #include "../dprint.h"
49 /* #ifdef PARSE_URI_OLD */ /* ZSW */
50 #include "../ut.h"   /* q_memchr */
51 /* #endif */
52 #include "../error.h"
53
54 /* buf= pointer to begining of uri (sip:x@foo.bar:5060;a=b?h=i)
55  * len= len of uri
56  * returns: fills uri & returns <0 on error or 0 if ok 
57  */
58 #ifndef PARSE_URI_OLD
59 int parse_uri(char* buf, int len, struct sip_uri* uri)
60 {
61         enum states  {  URI_INIT, URI_USER, URI_PASSWORD, URI_PASSWORD_ALPHA,
62                                         URI_HOST, URI_HOST_P,
63                                         URI_HOST6_P, URI_HOST6_END, URI_PORT, 
64                                         URI_PARAM, URI_PARAM_P, URI_VAL_P, URI_HEADERS,
65                                         /* param states */
66                                         /* transport */
67                                         PT_T, PT_R, PT_A, PT_N, PT_S, PT_P, PT_O, PT_R2, PT_T2,
68                                         PT_eq,
69                                         /* ttl */
70                                               PTTL_T2, PTTL_L, PTTL_eq,
71                                         /* user */
72                                         PU_U, PU_S, PU_E, PU_R, PU_eq,
73                                         /* method */
74                                         PM_M, PM_E, PM_T, PM_H, PM_O, PM_D, PM_eq,
75                                         /* maddr */
76                                               PMA_A, PMA_D, PMA_D2, PMA_R, PMA_eq,
77                                         /* lr */
78                                         PLR_L, PLR_R_FIN, PLR_eq,
79                                         /* r2 */
80                                         PR2_R, PR2_2_FIN, PR2_eq,
81 #ifdef USE_COMP
82                                         /* comp */
83                                         PCOMP_C, PCOMP_O, PCOMP_M, PCOMP_P, PCOMP_eq,
84                                         
85                                         /* comp values */
86                                         /* sigcomp */
87                                         VCOMP_S, VCOMP_SIGC_I, VCOMP_SIGC_G,
88                                         VCOMP_SIGC_C, VCOMP_SIGC_O,  VCOMP_SIGC_M,
89                                         VCOMP_SIGC_P_FIN,
90                                         /* sergz */
91                                                         VCOMP_SGZ_E, VCOMP_SGZ_R, VCOMP_SGZ_G,
92                                                         VCOMP_SGZ_Z_FIN,
93 #endif
94                                         
95                                         /* transport values */
96                                         /* udp */
97                                         VU_U, VU_D, VU_P_FIN,
98                                         /* tcp */
99                                         VT_T, VT_C, VT_P_FIN,
100                                         /* tls */
101                                               VTLS_L, VTLS_S_FIN,
102                                         /* sctp */
103                                         VS_S, VS_C, VS_T, VS_P_FIN
104         };
105         register enum states state;
106         char* s;
107         char* b; /* param start */
108         char *v; /* value start */
109         str* param; /* current param */
110         str* param_val; /* current param val */
111         str user;
112         str password;
113         int port_no;
114         register char* p;
115         char* end;
116         char* pass;
117         int found_user;
118         int error_headers;
119         unsigned int scheme;
120         uri_type backup_urit;
121         uri_flags backup_urif;
122
123 #ifdef USE_COMP
124         str comp_str; /* not returned for now */
125         str comp_val; /* not returned for now */
126 #endif
127         
128 #define SIP_SCH         0x3a706973
129 #define SIPS_SCH        0x73706973
130 #define TEL_SCH         0x3a6c6574
131         
132 #define case_port( ch, var) \
133         case ch: \
134                          (var)=(var)*10+ch-'0'; \
135                          break
136                          
137 #define still_at_user  \
138                                                 if (found_user==0){ \
139                                                         user.s=uri->host.s; \
140                                                         if (pass){\
141                                                                 user.len=pass-user.s; \
142                                                                 password.s=pass+1; \
143                                                                 password.len=p-password.s; \
144                                                         }else{ \
145                                                                 user.len=p-user.s; \
146                                                         }\
147                                                         /* save the uri type/scheme */ \
148                                                         backup_urit=uri->type; \
149                                                         backup_urif=uri->flags; \
150                                                         /* everything else is 0 */ \
151                                                         memset(uri, 0, sizeof(struct sip_uri)); \
152                                                         /* restore the scheme & flags, copy user & pass */ \
153                                                         uri->type=backup_urit; \
154                                                         uri->flags=backup_urif; \
155                                                         uri->user=user; \
156                                                         if (pass)       uri->passwd=password;  \
157                                                         s=p+1; \
158                                                         found_user=1;\
159                                                         error_headers=0; \
160                                                         state=URI_HOST; \
161                                                 }else goto error_bad_char 
162
163 #define check_host_end \
164                                         case ':': \
165                                                 /* found the host */ \
166                                                 uri->host.s=s; \
167                                                 uri->host.len=p-s; \
168                                                 state=URI_PORT; \
169                                                 s=p+1; \
170                                                 break; \
171                                         case ';': \
172                                                 uri->host.s=s; \
173                                                 uri->host.len=p-s; \
174                                                 state=URI_PARAM; \
175                                                 s=p+1; \
176                                                 break; \
177                                         case '?': \
178                                                 uri->host.s=s; \
179                                                 uri->host.len=p-s; \
180                                                 state=URI_HEADERS; \
181                                                 s=p+1; \
182                                                 break; \
183                                         case '&': \
184                                         case '@': \
185                                                 goto error_bad_char 
186
187
188 #define param_set(t_start, v_start) \
189                                         param->s=(t_start);\
190                                         param->len=(p-(t_start));\
191                                         param_val->s=(v_start); \
192                                         param_val->len=(p-(v_start)) 
193
194 #define semicolon_case \
195                                         case';': \
196                                                 if (pass){ \
197                                                         found_user=1;/* no user, pass cannot contain ';'*/ \
198                                                         pass=0; \
199                                                 } \
200                                                 state=URI_PARAM   /* new param */ 
201
202 #define question_case \
203                                         case '?': \
204                                                 uri->params.s=s; \
205                                                 uri->params.len=p-s; \
206                                                 state=URI_HEADERS; \
207                                                 s=p+1; \
208                                                 if (pass){ \
209                                                         found_user=1;/* no user, pass cannot contain '?'*/ \
210                                                         pass=0; \
211                                                 }
212
213 #define colon_case \
214                                         case ':': \
215                                                 if (found_user==0){ \
216                                                         /*might be pass but only if user not found yet*/ \
217                                                         if (pass){ \
218                                                                 found_user=1; /* no user */ \
219                                                                 pass=0; \
220                                                         }else{ \
221                                                                 pass=p; \
222                                                         } \
223                                                 } \
224                                                 state=URI_PARAM_P /* generic param */
225
226 #define param_common_cases \
227                                         case '@': \
228                                                 /* ughhh, this is still the user */ \
229                                                 still_at_user; \
230                                                 break; \
231                                         semicolon_case; \
232                                                 break; \
233                                         question_case; \
234                                                 break; \
235                                         colon_case; \
236                                                 break
237
238 #define value_common_cases \
239                                         case '@': \
240                                                 /* ughhh, this is still the user */ \
241                                                 still_at_user; \
242                                                 break; \
243                                         semicolon_case; \
244                                                 param_set(b, v); \
245                                                 break; \
246                                         question_case; \
247                                                 param_set(b, v); \
248                                                 break; \
249                                         colon_case; \
250                                                 state=URI_VAL_P; \
251                                                 break
252
253 #define param_switch(old_state, c1, c2, new_state) \
254                         case old_state: \
255                                 switch(*p){ \
256                                         case c1: \
257                                         case c2: \
258                                                 state=(new_state); \
259                                                 break; \
260                                         param_common_cases; \
261                                         default: \
262                                                 state=URI_PARAM_P; \
263                                 } \
264                                 break
265 #define param_switch1(old_state, c1, new_state) \
266                         case old_state: \
267                                 switch(*p){ \
268                                         case c1: \
269                                                 state=(new_state); \
270                                                 break; \
271                                         param_common_cases; \
272                                         default: \
273                                                 state=URI_PARAM_P; \
274                                 } \
275                                 break
276 #define param_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
277                         case old_state : \
278                                 switch(*p){ \
279                                         case c1: \
280                                         case c2: \
281                                                 state=(new_state_c); \
282                                                 break; \
283                                         case d1: \
284                                         case d2: \
285                                                 state=(new_state_d); \
286                                                 break; \
287                                         param_common_cases; \
288                                         default: \
289                                                 state=URI_PARAM_P; \
290                                 } \
291                                 break
292 #define value_switch(old_state, c1, c2, new_state) \
293                         case old_state: \
294                                 switch(*p){ \
295                                         case c1: \
296                                         case c2: \
297                                                 state=(new_state); \
298                                                 break; \
299                                         value_common_cases; \
300                                         default: \
301                                                 state=URI_VAL_P; \
302                                 } \
303                                 break
304 #define value_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
305                         case old_state: \
306                                 switch(*p){ \
307                                         case c1: \
308                                         case c2: \
309                                                 state=(new_state_c); \
310                                                 break; \
311                                         case d1: \
312                                         case d2: \
313                                                 state=(new_state_d); \
314                                                 break; \
315                                         value_common_cases; \
316                                         default: \
317                                                 state=URI_VAL_P; \
318                                 } \
319                                 break
320
321 #define transport_fin(c_state, proto_no) \
322                         case c_state: \
323                                 switch(*p){ \
324                                         case '@': \
325                                                 still_at_user; \
326                                                 break; \
327                                         semicolon_case; \
328                                                 param_set(b, v); \
329                                                 uri->proto=(proto_no); \
330                                                 break; \
331                                         question_case; \
332                                                 param_set(b, v); \
333                                                 uri->proto=(proto_no); \
334                                                 break; \
335                                         colon_case;  \
336                                         default: \
337                                                 state=URI_VAL_P; \
338                                                 break; \
339                                 } \
340                                 break
341                         
342
343 #ifdef USE_COMP
344 #define comp_fin(c_state, comp_no) \
345                         case c_state: \
346                                 switch(*p){ \
347                                         case '@': \
348                                                 still_at_user; \
349                                                 break; \
350                                         semicolon_case; \
351                                                 /* param_set(b, v); */ \
352                                                 uri->comp=(comp_no); \
353                                                 break; \
354                                         question_case; \
355                                                 /* param_set(b, v) */; \
356                                                 uri->comp=(comp_no); \
357                                                 break; \
358                                         colon_case;  \
359                                         default: \
360                                                 state=URI_VAL_P; \
361                                                 break; \
362                                 } \
363                                 break
364                         
365 #endif
366
367         /* init */
368         end=buf+len;
369         p=buf+4;
370         found_user=0;
371         error_headers=0;
372         b=v=0;
373         param=param_val=0;
374         pass=0;
375         password.s=0; /* fixes gcc 4.0 warning */
376         password.len=0;
377         port_no=0;
378         state=URI_INIT;
379         memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure*/
380         /*look for sip:, sips: or tel:*/
381         if (len<5) goto error_too_short;
382         scheme=buf[0]+(buf[1]<<8)+(buf[2]<<16)+(buf[3]<<24);
383         scheme|=0x20202020;
384         if (scheme==SIP_SCH){
385                 uri->type=SIP_URI_T;
386         }else if(scheme==SIPS_SCH){
387                 if(buf[4]==':'){ p++; uri->type=SIPS_URI_T;}
388                 else goto error_bad_uri;
389         }else if (scheme==TEL_SCH){
390                 uri->type=TEL_URI_T;
391         }else goto error_bad_uri;
392         
393         s=p;
394         for(;p<end; p++){
395                 switch((unsigned char)state){
396                         case URI_INIT:
397                                 switch(*p){
398                                         case '[':
399                                                 /* uri =  [ipv6address]... */
400                                                 state=URI_HOST6_P;
401                                                 s=p;
402                                                 break;
403                                         case ']':
404                                                 /* invalid, no uri can start with ']' */
405                                         case ':':
406                                                 /* the same as above for ':' */
407                                                 goto error_bad_char;
408                                         case '@': /* error no user part, or
409                                                                  be forgiving and accept it ? */
410                                         default:
411                                                 state=URI_USER;
412                                 }
413                                 break; 
414                         case URI_USER:
415                                 switch(*p){
416                                         case '@':
417                                                 /* found the user*/
418                                                 uri->user.s=s;
419                                                 uri->user.len=p-s;
420                                                 state=URI_HOST;
421                                                 found_user=1;
422                                                 s=p+1; /* skip '@' */
423                                                 break;
424                                         case ':':
425                                                 /* found the user, or the host? */
426                                                 uri->user.s=s;
427                                                 uri->user.len=p-s;
428                                                 state=URI_PASSWORD;
429                                                 s=p+1; /* skip ':' */
430                                                 break;
431                                         case ';':
432                                                 /* this could be still the user or
433                                                  * params?*/
434                                                 uri->host.s=s;
435                                                 uri->host.len=p-s;
436                                                 state=URI_PARAM;
437                                                 s=p+1;
438                                                 break;
439                                         case '?': /* still user or headers? */
440                                                 uri->host.s=s;
441                                                 uri->host.len=p-s;
442                                                 state=URI_HEADERS;
443                                                 s=p+1;
444                                                 break;
445                                                 /* almost anything permitted in the user part */
446                                         case '.':
447                                         case '-':
448                                         case '(':
449                                         case ')':
450                                                 /* tel uri visual separators, set flag meaning, that
451                                                  * user should be normalized before usage
452                                                  */
453                                                 uri->flags|=URI_USER_NORMALIZE;
454                                                 break;
455                                         case '[':
456                                         case ']': /* the user part cannot contain "[]" */
457                                                 goto error_bad_char;
458                                 }
459                                 break;
460                         case URI_PASSWORD: /* this can also be the port (missing user)*/
461                                 switch(*p){
462                                         case '@':
463                                                 /* found the password*/
464                                                 uri->passwd.s=s;
465                                                 uri->passwd.len=p-s;
466                                                 port_no=0;
467                                                 state=URI_HOST;
468                                                 found_user=1;
469                                                 s=p+1; /* skip '@' */
470                                                 break;
471                                         case ';':
472                                                 /* upps this is the port */
473                                                 uri->port.s=s;
474                                                 uri->port.len=p-s;
475                                                 uri->port_no=port_no;
476                                                 /* user contains in fact the host */
477                                                 uri->host.s=uri->user.s;
478                                                 uri->host.len=uri->user.len;
479                                                 uri->user.s=0;
480                                                 uri->user.len=0;
481                                                 state=URI_PARAM;
482                                                 found_user=1; /*  there is no user part */
483                                                 s=p+1;
484                                                 break;
485                                         case '?':
486                                                 /* upps this is the port */
487                                                 uri->port.s=s;
488                                                 uri->port.len=p-s;
489                                                 uri->port_no=port_no;
490                                                 /* user contains in fact the host */
491                                                 uri->host.s=uri->user.s;
492                                                 uri->host.len=uri->user.len;
493                                                 uri->user.s=0;
494                                                 uri->user.len=0;
495                                                 state=URI_HEADERS;
496                                                 found_user=1; /*  there is no user part */
497                                                 s=p+1;
498                                                 break;
499                                         case_port('0', port_no);
500                                         case_port('1', port_no);
501                                         case_port('2', port_no);
502                                         case_port('3', port_no);
503                                         case_port('4', port_no);
504                                         case_port('5', port_no);
505                                         case_port('6', port_no);
506                                         case_port('7', port_no);
507                                         case_port('8', port_no);
508                                         case_port('9', port_no);
509                                         case '[':
510                                         case ']':
511                                         case ':':
512                                                 goto error_bad_char;
513                                         default:
514                                                 /* it can't be the port, non number found */
515                                                 port_no=0;
516                                                 state=URI_PASSWORD_ALPHA;
517                                 }
518                                 break;
519                         case URI_PASSWORD_ALPHA:
520                                 switch(*p){
521                                         case '@':
522                                                 /* found the password*/
523                                                 uri->passwd.s=s;
524                                                 uri->passwd.len=p-s;
525                                                 state=URI_HOST;
526                                                 found_user=1;
527                                                 s=p+1; /* skip '@' */
528                                                 break;
529                                         case ';': /* contains non-numbers => cannot be port no*/
530                                         case '?':
531                                                 goto error_bad_port;
532                                         case '[':
533                                         case ']':
534                                         case ':':
535                                                 goto error_bad_char;
536                                 }
537                                 break;
538                         case URI_HOST:
539                                 switch(*p){
540                                         case '[':
541                                                 state=URI_HOST6_P;
542                                                 break;
543                                         case ':': 
544                                         case ';':
545                                         case '?': /* null host name ->invalid */
546                                         case '&':
547                                         case '@': /*chars not allowed in hosts names */
548                                                 goto error_bad_host;
549                                         default:
550                                                 state=URI_HOST_P;
551                                 }
552                                 break;
553                         case URI_HOST_P:
554                                 switch(*p){
555                                         check_host_end;
556                                 }
557                                 break;
558                         case URI_HOST6_END:
559                                 switch(*p){
560                                         check_host_end;
561                                         default: /*no chars allowed after [ipv6] */
562                                                 goto error_bad_host;
563                                 }
564                                 break;
565                         case URI_HOST6_P:
566                                 switch(*p){
567                                         case ']':
568                                                 state=URI_HOST6_END;
569                                                 break;
570                                         case '[':
571                                         case '&':
572                                         case '@':
573                                         case ';':
574                                         case '?':
575                                                 goto error_bad_host;
576                                 }
577                                 break;
578                         case URI_PORT:
579                                 switch(*p){
580                                         case ';':
581                                                 uri->port.s=s;
582                                                 uri->port.len=p-s;
583                                                 uri->port_no=port_no;
584                                                 state=URI_PARAM;
585                                                 s=p+1;
586                                                 break;
587                                         case '?':
588                                                 uri->port.s=s;
589                                                 uri->port.len=p-s;
590                                                 uri->port_no=port_no;
591                                                 state=URI_HEADERS;
592                                                 s=p+1;
593                                                 break;
594                                         case_port('0', port_no);
595                                         case_port('1', port_no);
596                                         case_port('2', port_no);
597                                         case_port('3', port_no);
598                                         case_port('4', port_no);
599                                         case_port('5', port_no);
600                                         case_port('6', port_no);
601                                         case_port('7', port_no);
602                                         case_port('8', port_no);
603                                         case_port('9', port_no);
604                                         case '&':
605                                         case '@':
606                                         case ':':
607                                         default:
608                                                 goto error_bad_port;
609                                 }
610                                 break;
611                         case URI_PARAM: /* beginning of a new param */
612                                 switch(*p){
613                                         param_common_cases;
614                                         /* recognized params */
615                                         case 't':
616                                         case 'T':
617                                                 b=p;
618                                                 state=PT_T;
619                                                 break;
620                                         case 'u':
621                                         case 'U':
622                                                 b=p;
623                                                 state=PU_U;
624                                                 break;
625                                         case 'm':
626                                         case 'M':
627                                                 b=p;
628                                                 state=PM_M;
629                                                 break;
630                                         case 'l':
631                                         case 'L':
632                                                 b=p;
633                                                 state=PLR_L;
634                                                 break;
635                                         case 'r':
636                                         case 'R':
637                                                 b=p;
638                                                 state=PR2_R;
639                                                 break;
640 #ifdef USE_COMP
641                                         case 'c':
642                                         case 'C':
643                                                 b=p;
644                                                 state=PCOMP_C;
645                                                 break;
646 #endif
647                                         default:
648                                                 state=URI_PARAM_P;
649                                 }
650                                 break;
651                         case URI_PARAM_P: /* ignore current param */
652                                 /* supported params:
653                                  *  maddr, transport, ttl, lr, user, method, r2  */
654                                 switch(*p){
655                                         param_common_cases;
656                                 };
657                                 break;
658                         /* ugly but fast param names parsing */
659                         /*transport */
660                         param_switch_big(PT_T,  'r', 'R', 't', 'T', PT_R, PTTL_T2);
661                         param_switch(PT_R,  'a', 'A', PT_A);
662                         param_switch(PT_A,  'n', 'N', PT_N);
663                         param_switch(PT_N,  's', 'S', PT_S);
664                         param_switch(PT_S,  'p', 'P', PT_P);
665                         param_switch(PT_P,  'o', 'O', PT_O);
666                         param_switch(PT_O,  'r', 'R', PT_R2);
667                         param_switch(PT_R2, 't', 'T', PT_T2);
668                         param_switch1(PT_T2, '=',  PT_eq);
669                         /* value parsing */
670                         case PT_eq:
671                                 param=&uri->transport;
672                                 param_val=&uri->transport_val;
673                                 switch (*p){
674                                         param_common_cases;
675                                         case 'u':
676                                         case 'U':
677                                                 v=p;
678                                                 state=VU_U;
679                                                 break;
680                                         case 't':
681                                         case 'T':
682                                                 v=p;
683                                                 state=VT_T;
684                                                 break;
685                                         case 's':
686                                         case 'S':
687                                                 v=p;
688                                                 state=VS_S;
689                                                 break;
690                                         default:
691                                                 v=p;
692                                                 state=URI_VAL_P;
693                                 }
694                                 break;
695                                 /* generic value */
696                         case URI_VAL_P:
697                                 switch(*p){
698                                         value_common_cases;
699                                 }
700                                 break;
701                         /* udp */
702                         value_switch(VU_U,  'd', 'D', VU_D);
703                         value_switch(VU_D,  'p', 'P', VU_P_FIN);
704                         transport_fin(VU_P_FIN, PROTO_UDP);
705                         /* tcp */
706                         value_switch_big(VT_T,  'c', 'C', 'l', 'L', VT_C, VTLS_L);
707                         value_switch(VT_C,  'p', 'P', VT_P_FIN);
708                         transport_fin(VT_P_FIN, PROTO_TCP);
709                         /* tls */
710                         value_switch(VTLS_L, 's', 'S', VTLS_S_FIN);
711                         transport_fin(VTLS_S_FIN, PROTO_TLS);
712                         /* sctp */
713                         value_switch(VS_S, 'c', 'C', VS_C);
714                         value_switch(VS_C, 't', 'T', VS_T);
715                         value_switch(VS_T, 'p', 'P', VS_P_FIN);
716                         transport_fin(VS_P_FIN, PROTO_SCTP);
717                         
718                         /* ttl */
719                         param_switch(PTTL_T2,  'l', 'L', PTTL_L);
720                         param_switch1(PTTL_L,  '=', PTTL_eq);
721                         case PTTL_eq:
722                                 param=&uri->ttl;
723                                 param_val=&uri->ttl_val;
724                                 switch(*p){
725                                         param_common_cases;
726                                         default:
727                                                 v=p;
728                                                 state=URI_VAL_P;
729                                 }
730                                 break;
731                         
732                         /* user param */
733                         param_switch(PU_U, 's', 'S', PU_S);
734                         param_switch(PU_S, 'e', 'E', PU_E);
735                         param_switch(PU_E, 'r', 'R', PU_R);
736                         param_switch1(PU_R, '=', PU_eq);
737                         case PU_eq:
738                                 param=&uri->user_param;
739                                 param_val=&uri->user_param_val;
740                                 switch(*p){
741                                         param_common_cases;
742                                         default:
743                                                 v=p;
744                                                 state=URI_VAL_P;
745                                 }
746                                 break;
747                         
748                         /* method*/
749                         param_switch_big(PM_M, 'e', 'E', 'a', 'A', PM_E, PMA_A);
750                         param_switch(PM_E, 't', 'T', PM_T);
751                         param_switch(PM_T, 'h', 'H', PM_H);
752                         param_switch(PM_H, 'o', 'O', PM_O);
753                         param_switch(PM_O, 'd', 'D', PM_D);
754                         param_switch1(PM_D, '=', PM_eq);
755                         case PM_eq:
756                                 param=&uri->method;
757                                 param_val=&uri->method_val;
758                                 switch(*p){
759                                         param_common_cases;
760                                         default:
761                                                 v=p;
762                                                 state=URI_VAL_P;
763                                 }
764                                 break;
765
766                         /*maddr*/
767                         param_switch(PMA_A,  'd', 'D', PMA_D);
768                         param_switch(PMA_D,  'd', 'D', PMA_D2);
769                         param_switch(PMA_D2, 'r', 'R', PMA_R);
770                         param_switch1(PMA_R, '=', PMA_eq);
771                         case PMA_eq:
772                                 param=&uri->maddr;
773                                 param_val=&uri->maddr_val;
774                                 switch(*p){
775                                         param_common_cases;
776                                         default:
777                                                 v=p;
778                                                 state=URI_VAL_P;
779                                 }
780                                 break;
781                         
782                         /* lr */
783                         param_switch(PLR_L,  'r', 'R', PLR_R_FIN);
784                         case PLR_R_FIN:
785                                 switch(*p){
786                                         case '@':
787                                                 still_at_user; 
788                                                 break;
789                                         case '=':
790                                                 state=PLR_eq;
791                                                 break;
792                                         semicolon_case; 
793                                                 uri->lr.s=b;
794                                                 uri->lr.len=(p-b);
795                                                 break;
796                                         question_case; 
797                                                 uri->lr.s=b;
798                                                 uri->lr.len=(p-b);
799                                                 break;
800                                         colon_case;
801                                                 break;
802                                         default:
803                                                 state=URI_PARAM_P;
804                                 }
805                                 break;
806                                 /* handle lr=something case */
807                         case PLR_eq:
808                                 param=&uri->lr;
809                                 param_val=&uri->lr_val;
810                                 switch(*p){
811                                         param_common_cases;
812                                         default:
813                                                 v=p;
814                                                 state=URI_VAL_P;
815                                 }
816                                 break;
817                         /* r2 */
818                         param_switch1(PR2_R,  '2', PR2_2_FIN);
819                         case PR2_2_FIN:
820                                 switch(*p){
821                                         case '@':
822                                                 still_at_user; 
823                                                 break;
824                                         case '=':
825                                                 state=PR2_eq;
826                                                 break;
827                                         semicolon_case; 
828                                                 uri->r2.s=b;
829                                                 uri->r2.len=(p-b);
830                                                 break;
831                                         question_case; 
832                                                 uri->r2.s=b;
833                                                 uri->r2.len=(p-b);
834                                                 break;
835                                         colon_case;
836                                                 break;
837                                         default:
838                                                 state=URI_PARAM_P;
839                                 }
840                                 break;
841                                 /* handle lr=something case */
842                         case PR2_eq:
843                                 param=&uri->r2;
844                                 param_val=&uri->r2_val;
845                                 switch(*p){
846                                         param_common_cases;
847                                         default:
848                                                 v=p;
849                                                 state=URI_VAL_P;
850                                 }
851                                 break;
852 #ifdef USE_COMP
853                         param_switch(PCOMP_C,  'o', 'O' , PCOMP_O);
854                         param_switch(PCOMP_O,  'm', 'M' , PCOMP_M);
855                         param_switch(PCOMP_M,  'p', 'P' , PCOMP_P);
856                         param_switch1(PCOMP_P,  '=', PCOMP_eq);
857                         /* value */
858                         case PCOMP_eq:
859                                 param=&comp_str;
860                                 param_val=&comp_val;
861                                 switch (*p){
862                                         param_common_cases;
863                                         case 's':
864                                         case 'S':
865                                                 v=p;
866                                                 state=VCOMP_S;
867                                                 break;
868                                         default:
869                                                 v=p;
870                                                 state=URI_VAL_P;
871                                 }
872                                 break;
873                         /* sigcomp*/
874                         value_switch_big(VCOMP_S, 'i', 'I', 'e', 'E',
875                                                                         VCOMP_SIGC_I, VCOMP_SGZ_E);
876                         value_switch(VCOMP_SIGC_I, 'g', 'G', VCOMP_SIGC_G);
877                         value_switch(VCOMP_SIGC_G, 'c', 'C', VCOMP_SIGC_C);
878                         value_switch(VCOMP_SIGC_C, 'o', 'O', VCOMP_SIGC_O);
879                         value_switch(VCOMP_SIGC_O, 'm', 'M', VCOMP_SIGC_M);
880                         value_switch(VCOMP_SIGC_M, 'p', 'P', VCOMP_SIGC_P_FIN);
881                         comp_fin(VCOMP_SIGC_P_FIN, COMP_SIGCOMP);
882                         
883                         /* sergz*/
884                         value_switch(VCOMP_SGZ_E, 'r', 'R', VCOMP_SGZ_R);
885                         value_switch(VCOMP_SGZ_R, 'g', 'G', VCOMP_SGZ_G);
886                         value_switch(VCOMP_SGZ_G, 'z', 'Z', VCOMP_SGZ_Z_FIN);
887                         comp_fin(VCOMP_SGZ_Z_FIN, COMP_SERGZ);
888 #endif
889                                 
890                                 
891                                 
892                         case URI_HEADERS:
893                                 /* for now nobody needs them so we completely ignore the 
894                                  * headers (they are not allowed in request uri) --andrei */
895                                 switch(*p){
896                                         case '@':
897                                                 /* yak, we are still at user */
898                                                 still_at_user;
899                                                 break;
900                                         case ';':
901                                                 /* we might be still parsing user, try it */
902                                                 if (found_user) goto error_bad_char;
903                                                 error_headers=1; /* if this is not the user
904                                                                                         we have an error */
905                                                 /* if pass is set => it cannot be user:pass
906                                                  * => error (';') is illegal in a header */
907                                                 if (pass) goto error_headers;
908                                                 break;
909                                         case ':':
910                                                 if (found_user==0){
911                                                         /*might be pass but only if user not found yet*/
912                                                         if (pass){
913                                                                 found_user=1; /* no user */
914                                                                 pass=0;
915                                                         }else{
916                                                                 pass=p;
917                                                         }
918                                                 }
919                                                 break;
920                                         case '?':
921                                                 if (pass){
922                                                         found_user=1; /* no user, pass cannot contain '?'*/
923                                                         pass=0;
924                                                 }
925                                                 break;
926                                 }
927                                 break;
928                         default:
929                                 goto error_bug;
930                 }
931         }
932         /*end of uri */
933         switch (state){
934                 case URI_INIT: /* error empty uri */
935                         goto error_too_short;
936                 case URI_USER:
937                         /* this is the host, it can't be the user */
938                         if (found_user) goto error_bad_uri;
939                         uri->host.s=s;
940                         uri->host.len=p-s;
941                         state=URI_HOST;
942                         break;
943                 case URI_PASSWORD:
944                         /* this is the port, it can't be the passwd */
945                         if (found_user) goto error_bad_port;
946                         uri->port.s=s;
947                         uri->port.len=p-s;
948                         uri->port_no=port_no;
949                         uri->host=uri->user;
950                         uri->user.s=0;
951                         uri->user.len=0;
952                         break;
953                 case URI_PASSWORD_ALPHA:
954                         /* this is the port, it can't be the passwd */
955                         goto error_bad_port;
956                 case URI_HOST_P:
957                 case URI_HOST6_END:
958                         uri->host.s=s;
959                         uri->host.len=p-s;
960                         break;
961                 case URI_HOST: /* error: null host */
962                 case URI_HOST6_P: /* error: unterminated ipv6 reference*/
963                         goto error_bad_host;
964                 case URI_PORT:
965                         uri->port.s=s;
966                         uri->port.len=p-s;
967                         uri->port_no=port_no;
968                         break;
969                 case URI_PARAM:
970                 case URI_PARAM_P:
971                 /* intermediate param states */
972                 case PT_T: /* transport */
973                 case PT_R:
974                 case PT_A:
975                 case PT_N:
976                 case PT_S:
977                 case PT_P:
978                 case PT_O:
979                 case PT_R2:
980                 case PT_T2:
981                 case PT_eq: /* ignore empty transport params */
982                 case PTTL_T2: /* ttl */
983                 case PTTL_L:
984                 case PTTL_eq:
985                 case PU_U:  /* user */
986                 case PU_S:
987                 case PU_E:
988                 case PU_R:
989                 case PU_eq:
990                 case PM_M: /* method */
991                 case PM_E:
992                 case PM_T:
993                 case PM_H:
994                 case PM_O:
995                 case PM_D:
996                 case PM_eq:
997                 case PLR_L: /* lr */
998                 case PR2_R:  /* r2 */
999 #ifdef USE_COMP
1000                 case PCOMP_C:
1001                 case PCOMP_O:
1002                 case PCOMP_M:
1003                 case PCOMP_P:
1004                 case PCOMP_eq:
1005 #endif
1006                         uri->params.s=s;
1007                         uri->params.len=p-s;
1008                         break;
1009                 /* fin param states */
1010                 case PLR_R_FIN:
1011                 case PLR_eq:
1012                         uri->params.s=s;
1013                         uri->params.len=p-s;
1014                         uri->lr.s=b;
1015                         uri->lr.len=p-b;
1016                         break;
1017                 case PR2_2_FIN:
1018                 case PR2_eq:
1019                         uri->params.s=s;
1020                         uri->params.len=p-s;
1021                         uri->r2.s=b;
1022                         uri->r2.len=p-b;
1023                         break;
1024                 case URI_VAL_P:
1025                 /* intermediate value states */
1026                 case VU_U:
1027                 case VU_D:
1028                 case VT_T:
1029                 case VT_C:
1030                 case VTLS_L:
1031                 case VS_S:
1032                 case VS_C:
1033                 case VS_T:
1034                         uri->params.s=s;
1035                         uri->params.len=p-s;
1036                         param_set(b, v);
1037                         break;
1038 #ifdef USE_COMP
1039                 case VCOMP_S:
1040                 case VCOMP_SIGC_I:
1041                 case VCOMP_SIGC_G:
1042                 case VCOMP_SIGC_C:
1043                 case VCOMP_SIGC_O:
1044                 case VCOMP_SIGC_M:
1045                 case VCOMP_SGZ_E:
1046                 case VCOMP_SGZ_R:
1047                 case VCOMP_SGZ_G:
1048                         /* unrecognized comp method, assume none */
1049                         uri->params.s=s;
1050                         uri->params.len=p-s;
1051                         /* uri->comp=COMP_NONE ; */
1052                         break;
1053 #endif
1054                 /* fin value states */
1055                 case VU_P_FIN:
1056                         uri->params.s=s;
1057                         uri->params.len=p-s;
1058                         param_set(b, v);
1059                         uri->proto=PROTO_UDP;
1060                         break;
1061                 case VT_P_FIN:
1062                         uri->params.s=s;
1063                         uri->params.len=p-s;
1064                         param_set(b, v);
1065                         uri->proto=PROTO_TCP;
1066                         break;
1067                 case VTLS_S_FIN:
1068                         uri->params.s=s;
1069                         uri->params.len=p-s;
1070                         param_set(b, v);
1071                         uri->proto=PROTO_TLS;
1072                         break;
1073                 case VS_P_FIN:
1074                         uri->params.s=s;
1075                         uri->params.len=p-s;
1076                         param_set(b, v);
1077                         uri->proto=PROTO_SCTP;
1078                         break;
1079 #ifdef USE_COMP
1080                 case VCOMP_SIGC_P_FIN:
1081                         uri->params.s=s;
1082                         uri->params.len=p-s;
1083                         /* param_set(b, v); */
1084                         uri->comp=COMP_SIGCOMP;
1085                         break;
1086                 case VCOMP_SGZ_Z_FIN:
1087                         uri->params.s=s;
1088                         uri->params.len=p-s;
1089                         /* param_set(b, v); */
1090                         uri->comp=COMP_SERGZ;
1091                         break;
1092 #endif
1093                 /* headers */
1094                 case URI_HEADERS:
1095                         uri->headers.s=s;
1096                         uri->headers.len=p-s;
1097                         if (error_headers) goto error_headers;
1098                         break;
1099                 default:
1100                         goto error_bug;
1101         }
1102         switch(uri->type){
1103                 case SIPS_URI_T:
1104                 case SIP_URI_T:
1105                         if ((phone2tel) &&
1106                              (uri->user_param_val.len == 5) &&
1107                                  (strncmp(uri->user_param_val.s, "phone", 5) == 0)
1108                                 ) {
1109                                 uri->type = TEL_URI_T;
1110                                 uri->flags |= URI_SIP_USER_PHONE;
1111                                 /* move params from user into uri->params */
1112                                 p=q_memchr(uri->user.s, ';', uri->user.len);
1113                                 if (p){
1114                                         /* NOTE: 
1115                                          * specialized uri params (user, maddr, etc.) still hold
1116                                          * the values from the sip-uri envelope
1117                                          * while uri->params point to the params in the embedded tel uri
1118                                          */
1119                                         uri->params.s=p+1;
1120                                         uri->params.len=uri->user.s+uri->user.len-uri->params.s;
1121                                         uri->user.len=p-uri->user.s;
1122                                 } else {
1123                                         uri->params.len=0;
1124                                 }
1125                         } else {
1126                                 uri->flags&=~URI_USER_NORMALIZE;
1127                         }
1128                         break;
1129                 case TEL_URI_T:
1130                 case TELS_URI_T:
1131                         /* fix tel uris, move the number in uri and empty the host */
1132                         uri->user=uri->host;
1133                         uri->host.s="";
1134                         uri->host.len=0;
1135                         break;
1136                 case ERROR_URI_T:
1137                         LOG(L_ERR, "ERROR: parse_uri unexpected error (BUG?)\n"); 
1138                         goto error_bad_uri;
1139                         break; /* do nothing, avoids a compilation warning */
1140         }
1141 #ifdef EXTRA_DEBUG
1142         /* do stuff */
1143         DBG("parsed uri:\n type=%d user=<%.*s>(%d)\n passwd=<%.*s>(%d)\n"
1144                         " host=<%.*s>(%d)\n port=<%.*s>(%d): %d\n params=<%.*s>(%d)\n"
1145                         " headers=<%.*s>(%d)\n",
1146                         uri->type,
1147                         uri->user.len, ZSW(uri->user.s), uri->user.len,
1148                         uri->passwd.len, ZSW(uri->passwd.s), uri->passwd.len,
1149                         uri->host.len, ZSW(uri->host.s), uri->host.len,
1150                         uri->port.len, ZSW(uri->port.s), uri->port.len, uri->port_no,
1151                         uri->params.len, ZSW(uri->params.s), uri->params.len,
1152                         uri->headers.len, ZSW(uri->headers.s), uri->headers.len
1153                 );
1154         DBG(" uri flags : ");
1155                 if (uri->flags & URI_USER_NORMALIZE) DBG("user_need_norm ");
1156                 if (uri->flags & URI_SIP_USER_PHONE) DBG("sip_user_phone ");
1157                 DBG("   value=%d\n",uri->flags);
1158         DBG(" uri params:\n   transport=<%.*s>, val=<%.*s>, proto=%d\n",
1159                         uri->transport.len, ZSW(uri->transport.s), uri->transport_val.len,
1160                         ZSW(uri->transport_val.s), uri->proto);
1161         DBG("   user-param=<%.*s>, val=<%.*s>\n",
1162                         uri->user_param.len, ZSW(uri->user_param.s), 
1163                         uri->user_param_val.len, ZSW(uri->user_param_val.s));
1164         DBG("   method=<%.*s>, val=<%.*s>\n",
1165                         uri->method.len, ZSW(uri->method.s), 
1166                         uri->method_val.len, ZSW(uri->method_val.s));
1167         DBG("   ttl=<%.*s>, val=<%.*s>\n",
1168                         uri->ttl.len, ZSW(uri->ttl.s), 
1169                         uri->ttl_val.len, ZSW(uri->ttl_val.s));
1170         DBG("   maddr=<%.*s>, val=<%.*s>\n",
1171                         uri->maddr.len, ZSW(uri->maddr.s), 
1172                         uri->maddr_val.len, ZSW(uri->maddr_val.s));
1173         DBG("   lr=<%.*s>\n", uri->lr.len, ZSW(uri->lr.s)); 
1174         DBG("   r2=<%.*s>\n", uri->r2.len, ZSW(uri->r2.s));
1175 #ifdef USE_COMP
1176         DBG("   comp=%d\n", uri->comp);
1177 #endif
1178
1179 #endif
1180         return 0;
1181         
1182 error_too_short:
1183         DBG("parse_uri: uri too short: <%.*s> (%d)\n",
1184                 len, ZSW(buf), len);
1185         goto error_exit;
1186 error_bad_char:
1187         DBG("parse_uri: bad char '%c' in state %d"
1188                 " parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1189                 *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
1190                 len, ZSW(buf), len);
1191         goto error_exit;
1192 error_bad_host:
1193         DBG("parse_uri: bad host in uri (error at char %c in"
1194                 " state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
1195                 *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
1196                 len, ZSW(buf), len);
1197         goto error_exit;
1198 error_bad_port:
1199         DBG("parse_uri: bad port in uri (error at char %c in"
1200                 " state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
1201                 *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
1202                 len, ZSW(buf), len);
1203         goto error_exit;
1204 error_bad_uri:
1205         DBG("parse_uri: bad uri,  state %d"
1206                 " parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1207                 state, (int)(p-buf), ZSW(buf), (int)(p-buf), len,
1208                 ZSW(buf), len);
1209         goto error_exit;
1210 error_headers:
1211         DBG("parse_uri: bad uri headers: <%.*s>(%d)"
1212                 " / <%.*s>(%d)\n",
1213                 uri->headers.len, ZSW(uri->headers.s), uri->headers.len,
1214                 len, ZSW(buf), len);
1215         goto error_exit;
1216 error_bug:
1217         LOG(L_CRIT, "BUG: parse_uri: bad  state %d"
1218                         " parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1219                          state, (int)(p-buf), ZSW(buf), (int)(p-buf), len, ZSW(buf), len);
1220 error_exit:
1221         ser_error=E_BAD_URI;
1222         uri->type=ERROR_URI_T;
1223         return E_BAD_URI;
1224 }
1225
1226 #else /* PARSE_URI_OLD */
1227
1228 int parse_uri(char *buf, int len, struct sip_uri* uri)
1229 {
1230         char* next, *end;
1231         char *user, *passwd, *host, *port, *params, *headers, *ipv6;
1232         int host_len, port_len, params_len, headers_len;
1233         int err;
1234         int ret;
1235         
1236         
1237         ret=0;
1238         host_len=0;
1239         end=buf+len;
1240         memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure */
1241         /* look for "sip:"*/;
1242         next=q_memchr(buf, ':',  len);
1243         if ((next==0)||(strncasecmp(buf,"sip",next-buf)!=0)){
1244                 LOG(L_DBG, "ERROR: parse_uri: bad sip uri\n");
1245                 ser_error=ret=E_BAD_URI;
1246                 return ret;
1247         }
1248         buf=next+1; /* next char after ':' */
1249         if (buf>end){
1250                 LOG(L_DBG, "ERROR: parse_uri: uri too short\n");
1251                 ser_error=ret=E_BAD_URI;
1252                 return ret;
1253         }
1254         /*look for '@' */
1255         next=q_memchr(buf,'@', end-buf);
1256         if (next==0){
1257                 /* no '@' found, => no userinfo */
1258                 uri->user.s=0;
1259                 uri->passwd.s=0;
1260                 host=buf;
1261         }else{
1262                 /* found it */
1263                 user=buf;
1264                 /* try to find passwd */
1265                 passwd=q_memchr(user,':', next-user);
1266                 if (passwd==0){
1267                         /* no ':' found => no password */
1268                         uri->passwd.s=0;
1269                         uri->user.s=user;
1270                         uri->user.len=next-user;
1271                 }else{
1272                         uri->user.s=user;
1273                         uri->user.len=passwd-user;
1274                         passwd++; /*skip ':' */
1275                         uri->passwd.s=passwd;
1276                         uri->passwd.len=next-passwd;
1277                 }
1278                 host=next+1; /* skip '@' */
1279         }
1280         /* try to find the rest */
1281         if(host>=end){
1282                 LOG(L_DBG, "ERROR: parse_uri: missing hostport\n");
1283                 ser_error=ret=E_UNSPEC;
1284                 return ret;
1285         }
1286         next=host;
1287         ipv6=q_memchr(host, '[', end-host);
1288         if (ipv6){
1289                 host=ipv6+1; /* skip '[' in "[3ffe::abbcd]" */
1290                 if (host>=end){
1291                         LOG(L_DBG, "ERROR: parse_uri: bad ipv6 uri\n");
1292                         ret=E_UNSPEC;
1293                         return ret;
1294                 }
1295                 ipv6=q_memchr(host, ']', end-host);
1296                 if ((ipv6==0)||(ipv6==host)){
1297                         LOG(L_DBG, "ERROR: parse_uri: bad ipv6 uri - null address"
1298                                         " or missing ']'\n");
1299                         ret=E_UNSPEC;
1300                         return ret;
1301                 }
1302                 host_len=ipv6-host;
1303                 next=ipv6;
1304         }
1305
1306                 
1307         headers=q_memchr(next,'?',end-next);
1308         params=q_memchr(next,';',end-next);
1309         port=q_memchr(next,':',end-next);
1310         if (host_len==0){ /* host not ipv6 addr */
1311                 host_len=(port)?port-host:(params)?params-host:(headers)?headers-host:
1312                                 end-host;
1313         }
1314         /* get host */
1315         uri->host.s=host;
1316         uri->host.len=host_len;
1317
1318         /* get port*/
1319         if ((port)&&(port+1<end)){
1320                 port++;
1321                 if ( ((params) &&(params<port))||((headers) &&(headers<port)) ){
1322                         /* error -> invalid uri we found ';' or '?' before ':' */
1323                         LOG(L_DBG, "ERROR: parse_uri: malformed sip uri\n");
1324                         ser_error=ret=E_BAD_URI;
1325                         return ret;
1326                 }
1327                 port_len=(params)?params-port:(headers)?headers-port:end-port;
1328                 uri->port.s=port;
1329                 uri->port.len=port_len;
1330         }else uri->port.s=0;
1331         /* get params */
1332         if ((params)&&(params+1<end)){
1333                 params++;
1334                 if ((headers) && (headers<params)){
1335                         /* error -> invalid uri we found '?' or '?' before ';' */
1336                         LOG(L_DBG, "ERROR: parse_uri: malformed sip uri\n");
1337                         ser_error=ret=E_BAD_URI;
1338                         return ret;
1339                 }
1340                 params_len=(headers)?headers-params:end-params;
1341                 uri->params.s=params;
1342                 uri->params.len=params_len;
1343         }else uri->params.s=0;
1344         /*get headers */
1345         if ((headers)&&(headers+1<end)){
1346                 headers++;
1347                 headers_len=end-headers;
1348                 uri->headers.s=headers;
1349                 uri->headers.len=headers_len;
1350         }else uri->headers.s=0;
1351
1352         err=0;
1353         if (uri->port.s) uri->port_no=str2s(uri->port.s, uri->port.len, &err);
1354         if (err){
1355                 LOG(L_DBG, "ERROR: parse_uri: bad port number in sip uri: %.*s\n",
1356                                 uri->port.len, ZSW(uri->port.s));
1357                 ser_error=ret=E_BAD_URI;
1358                 return ret;
1359         }
1360
1361         return ret;
1362 }
1363 #endif
1364
1365
1366
1367
1368 static inline int _parse_ruri(str *uri,
1369         int *status, struct sip_uri *parsed_uri)
1370 {
1371         if (*status) return 1;
1372
1373         if (parse_uri(uri->s, uri->len, parsed_uri)<0) {
1374                 LOG(L_ERR, "ERROR: _parse_ruri: bad uri <%.*s>\n", 
1375                                 uri->len, ZSW(uri->s));
1376                 *status=0;
1377                 return -1;
1378         }
1379         *status=1;
1380         return 1;
1381 }
1382
1383 int parse_sip_msg_uri(struct sip_msg* msg)
1384 {
1385         char* tmp;
1386         int tmp_len;
1387         if (msg->parsed_uri_ok) return 1;
1388
1389         if (msg->new_uri.s){
1390                 tmp=msg->new_uri.s;
1391                 tmp_len=msg->new_uri.len;
1392         }else{
1393                 tmp=msg->first_line.u.request.uri.s;
1394                 tmp_len=msg->first_line.u.request.uri.len;
1395         }
1396         if (parse_uri(tmp, tmp_len, &msg->parsed_uri)<0){
1397                 LOG(L_ERR, "ERROR: parse_sip_msg_uri: bad uri <%.*s>\n",
1398                                         tmp_len, tmp);
1399                 msg->parsed_uri_ok=0;
1400                 return -1;
1401         }
1402         msg->parsed_uri_ok=1;
1403         return 1;
1404 }
1405
1406 int parse_orig_ruri(struct sip_msg* msg)
1407 {
1408         int ret;
1409
1410         ret=_parse_ruri(&REQ_LINE(msg).uri,
1411                 &msg->parsed_orig_ruri_ok, &msg->parsed_orig_ruri);
1412         if (ret<0) LOG(L_ERR, "ERROR: parse_orig_ruri failed\n");
1413         return ret;
1414 }
1415
1416 inline int normalize_tel_user(char* res, str* src) {
1417         int i, l;
1418         l=0;
1419         for (i=0; i<src->len; i++) {
1420                 switch (src->s[i]) {
1421                         case '-':
1422                         case '.':
1423                         case '(':
1424                         case ')':
1425                                 break;
1426                         default:
1427                                 res[l++]=src->s[i];
1428                 }
1429         }  
1430         return l;
1431 }
1432
1433
1434 str     s_sip  = STR_STATIC_INIT("sip");
1435 str     s_sips = STR_STATIC_INIT("sips");
1436 str     s_tel  = STR_STATIC_INIT("tel");
1437 str     s_tels = STR_STATIC_INIT("tels");
1438 static str      s_null = STR_STATIC_INIT("");
1439
1440 inline void uri_type_to_str(uri_type type, str *s) {
1441         switch (type) {
1442         case SIP_URI_T:
1443                 *s = s_sip;
1444                 break;
1445         case SIPS_URI_T:
1446                 *s = s_sips;
1447                 break;
1448         case TEL_URI_T:
1449                 *s = s_tel;
1450                 break;
1451         case TELS_URI_T:
1452                 *s = s_tels;
1453                 break;
1454         default:
1455                 *s = s_null;
1456         }
1457 }
1458
1459 static str      s_udp  = STR_STATIC_INIT("udp");
1460 static str      s_tcp  = STR_STATIC_INIT("tcp");
1461 static str      s_tls  = STR_STATIC_INIT("tls");
1462 static str      s_sctp = STR_STATIC_INIT("sctp");
1463
1464 inline void proto_type_to_str(unsigned short type, str *s) {
1465         switch (type) {
1466         case PROTO_UDP:
1467                 *s = s_udp;
1468                 break;
1469         case PROTO_TCP:
1470                 *s = s_tcp;
1471                 break;
1472         case PROTO_TLS:
1473                 *s = s_tls;
1474                 break;
1475         case PROTO_SCTP:
1476                 *s = s_sctp;
1477                 break;
1478         default:
1479                 *s = s_null;
1480         }
1481 }