4 * Copyright (C) 2001-2003 FhG Fokus
6 * This file is part of ser, a free SIP server.
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
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:
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.
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
29 * 2003-04-04 convenience inbound-uri parser parse_orig_ruri
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
45 #include "../globals.h"
46 #include "parse_uri.h"
48 #include "../dprint.h"
49 /* #ifdef PARSE_URI_OLD */ /* ZSW */
50 #include "../ut.h" /* q_memchr */
54 /* buf= pointer to begining of uri (sip:x@foo.bar:5060;a=b?h=i)
56 * returns: fills uri & returns <0 on error or 0 if ok
59 int parse_uri(char* buf, int len, struct sip_uri* uri)
61 enum states { URI_INIT, URI_USER, URI_PASSWORD, URI_PASSWORD_ALPHA,
63 URI_HOST6_P, URI_HOST6_END, URI_PORT,
64 URI_PARAM, URI_PARAM_P, URI_VAL_P, URI_HEADERS,
67 PT_T, PT_R, PT_A, PT_N, PT_S, PT_P, PT_O, PT_R2, PT_T2,
70 PTTL_T2, PTTL_L, PTTL_eq,
72 PU_U, PU_S, PU_E, PU_R, PU_eq,
74 PM_M, PM_E, PM_T, PM_H, PM_O, PM_D, PM_eq,
76 PMA_A, PMA_D, PMA_D2, PMA_R, PMA_eq,
78 PLR_L, PLR_R_FIN, PLR_eq,
80 PR2_R, PR2_2_FIN, PR2_eq,
83 PCOMP_C, PCOMP_O, PCOMP_M, PCOMP_P, PCOMP_eq,
87 VCOMP_S, VCOMP_SIGC_I, VCOMP_SIGC_G,
88 VCOMP_SIGC_C, VCOMP_SIGC_O, VCOMP_SIGC_M,
91 VCOMP_SGZ_E, VCOMP_SGZ_R, VCOMP_SGZ_G,
95 /* transport values */
103 VS_S, VS_C, VS_T, VS_P_FIN
105 register enum states state;
107 char* b; /* param start */
108 char *v; /* value start */
109 str* param; /* current param */
110 str* param_val; /* current param val */
120 uri_type backup_urit;
121 uri_flags backup_urif;
124 str comp_str; /* not returned for now */
125 str comp_val; /* not returned for now */
128 #define SIP_SCH 0x3a706973
129 #define SIPS_SCH 0x73706973
130 #define TEL_SCH 0x3a6c6574
132 #define case_port( ch, var) \
134 (var)=(var)*10+ch-'0'; \
137 #define still_at_user \
138 if (found_user==0){ \
139 user.s=uri->host.s; \
141 user.len=pass-user.s; \
143 password.len=p-password.s; \
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; \
156 if (pass) uri->passwd=password; \
161 }else goto error_bad_char
163 #define check_host_end \
165 /* found the host */ \
188 #define param_set(t_start, v_start) \
190 param->len=(p-(t_start));\
191 param_val->s=(v_start); \
192 param_val->len=(p-(v_start))
194 #define semicolon_case \
197 found_user=1;/* no user, pass cannot contain ';'*/ \
200 state=URI_PARAM /* new param */
202 #define question_case \
205 uri->params.len=p-s; \
209 found_user=1;/* no user, pass cannot contain '?'*/ \
215 if (found_user==0){ \
216 /*might be pass but only if user not found yet*/ \
218 found_user=1; /* no user */ \
224 state=URI_PARAM_P /* generic param */
226 #define param_common_cases \
228 /* ughhh, this is still the user */ \
238 #define value_common_cases \
240 /* ughhh, this is still the user */ \
253 #define param_switch(old_state, c1, c2, new_state) \
260 param_common_cases; \
265 #define param_switch1(old_state, c1, new_state) \
271 param_common_cases; \
276 #define param_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
281 state=(new_state_c); \
285 state=(new_state_d); \
287 param_common_cases; \
292 #define value_switch(old_state, c1, c2, new_state) \
299 value_common_cases; \
304 #define value_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
309 state=(new_state_c); \
313 state=(new_state_d); \
315 value_common_cases; \
321 #define transport_fin(c_state, proto_no) \
329 uri->proto=(proto_no); \
333 uri->proto=(proto_no); \
344 #define comp_fin(c_state, comp_no) \
351 /* param_set(b, v); */ \
352 uri->comp=(comp_no); \
355 /* param_set(b, v) */; \
356 uri->comp=(comp_no); \
375 password.s=0; /* fixes gcc 4.0 warning */
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);
384 if (scheme==SIP_SCH){
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){
391 }else goto error_bad_uri;
395 switch((unsigned char)state){
399 /* uri = [ipv6address]... */
404 /* invalid, no uri can start with ']' */
406 /* the same as above for ':' */
408 case '@': /* error no user part, or
409 be forgiving and accept it ? */
422 s=p+1; /* skip '@' */
425 /* found the user, or the host? */
429 s=p+1; /* skip ':' */
432 /* this could be still the user or
439 case '?': /* still user or headers? */
445 /* almost anything permitted in the user part */
450 /* tel uri visual separators, set flag meaning, that
451 * user should be normalized before usage
453 uri->flags|=URI_USER_NORMALIZE;
456 case ']': /* the user part cannot contain "[]" */
460 case URI_PASSWORD: /* this can also be the port (missing user)*/
463 /* found the password*/
469 s=p+1; /* skip '@' */
472 /* upps this is the port */
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;
482 found_user=1; /* there is no user part */
486 /* upps this is the port */
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;
496 found_user=1; /* there is no user part */
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);
514 /* it can't be the port, non number found */
516 state=URI_PASSWORD_ALPHA;
519 case URI_PASSWORD_ALPHA:
522 /* found the password*/
527 s=p+1; /* skip '@' */
529 case ';': /* contains non-numbers => cannot be port no*/
545 case '?': /* null host name ->invalid */
547 case '@': /*chars not allowed in hosts names */
561 default: /*no chars allowed after [ipv6] */
583 uri->port_no=port_no;
590 uri->port_no=port_no;
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);
611 case URI_PARAM: /* beginning of a new param */
614 /* recognized params */
651 case URI_PARAM_P: /* ignore current param */
653 * maddr, transport, ttl, lr, user, method, r2 */
658 /* ugly but fast param names parsing */
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);
671 param=&uri->transport;
672 param_val=&uri->transport_val;
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);
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);
710 value_switch(VTLS_L, 's', 'S', VTLS_S_FIN);
711 transport_fin(VTLS_S_FIN, PROTO_TLS);
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);
719 param_switch(PTTL_T2, 'l', 'L', PTTL_L);
720 param_switch1(PTTL_L, '=', PTTL_eq);
723 param_val=&uri->ttl_val;
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);
738 param=&uri->user_param;
739 param_val=&uri->user_param_val;
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);
757 param_val=&uri->method_val;
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);
773 param_val=&uri->maddr_val;
783 param_switch(PLR_L, 'r', 'R', PLR_R_FIN);
806 /* handle lr=something case */
809 param_val=&uri->lr_val;
818 param_switch1(PR2_R, '2', PR2_2_FIN);
841 /* handle lr=something case */
844 param_val=&uri->r2_val;
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);
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);
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);
893 /* for now nobody needs them so we completely ignore the
894 * headers (they are not allowed in request uri) --andrei */
897 /* yak, we are still at user */
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
905 /* if pass is set => it cannot be user:pass
906 * => error (';') is illegal in a header */
907 if (pass) goto error_headers;
911 /*might be pass but only if user not found yet*/
913 found_user=1; /* no user */
922 found_user=1; /* no user, pass cannot contain '?'*/
934 case URI_INIT: /* error empty uri */
935 goto error_too_short;
937 /* this is the host, it can't be the user */
938 if (found_user) goto error_bad_uri;
944 /* this is the port, it can't be the passwd */
945 if (found_user) goto error_bad_port;
948 uri->port_no=port_no;
953 case URI_PASSWORD_ALPHA:
954 /* this is the port, it can't be the passwd */
961 case URI_HOST: /* error: null host */
962 case URI_HOST6_P: /* error: unterminated ipv6 reference*/
967 uri->port_no=port_no;
971 /* intermediate param states */
972 case PT_T: /* transport */
981 case PT_eq: /* ignore empty transport params */
982 case PTTL_T2: /* ttl */
985 case PU_U: /* user */
990 case PM_M: /* method */
1007 uri->params.len=p-s;
1009 /* fin param states */
1013 uri->params.len=p-s;
1020 uri->params.len=p-s;
1025 /* intermediate value states */
1035 uri->params.len=p-s;
1048 /* unrecognized comp method, assume none */
1050 uri->params.len=p-s;
1051 /* uri->comp=COMP_NONE ; */
1054 /* fin value states */
1057 uri->params.len=p-s;
1059 uri->proto=PROTO_UDP;
1063 uri->params.len=p-s;
1065 uri->proto=PROTO_TCP;
1069 uri->params.len=p-s;
1071 uri->proto=PROTO_TLS;
1075 uri->params.len=p-s;
1077 uri->proto=PROTO_SCTP;
1080 case VCOMP_SIGC_P_FIN:
1082 uri->params.len=p-s;
1083 /* param_set(b, v); */
1084 uri->comp=COMP_SIGCOMP;
1086 case VCOMP_SGZ_Z_FIN:
1088 uri->params.len=p-s;
1089 /* param_set(b, v); */
1090 uri->comp=COMP_SERGZ;
1096 uri->headers.len=p-s;
1097 if (error_headers) goto error_headers;
1106 (uri->user_param_val.len == 5) &&
1107 (strncmp(uri->user_param_val.s, "phone", 5) == 0)
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);
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
1120 uri->params.len=uri->user.s+uri->user.len-uri->params.s;
1121 uri->user.len=p-uri->user.s;
1126 uri->flags&=~URI_USER_NORMALIZE;
1131 /* fix tel uris, move the number in uri and empty the host */
1132 uri->user=uri->host;
1137 LOG(L_ERR, "ERROR: parse_uri unexpected error (BUG?)\n");
1139 break; /* do nothing, avoids a compilation warning */
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",
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
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));
1176 DBG(" comp=%d\n", uri->comp);
1183 DBG("parse_uri: uri too short: <%.*s> (%d)\n",
1184 len, ZSW(buf), len);
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);
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);
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);
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,
1211 DBG("parse_uri: bad uri headers: <%.*s>(%d)"
1213 uri->headers.len, ZSW(uri->headers.s), uri->headers.len,
1214 len, ZSW(buf), len);
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);
1221 ser_error=E_BAD_URI;
1222 uri->type=ERROR_URI_T;
1226 #else /* PARSE_URI_OLD */
1228 int parse_uri(char *buf, int len, struct sip_uri* uri)
1231 char *user, *passwd, *host, *port, *params, *headers, *ipv6;
1232 int host_len, port_len, params_len, headers_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;
1248 buf=next+1; /* next char after ':' */
1250 LOG(L_DBG, "ERROR: parse_uri: uri too short\n");
1251 ser_error=ret=E_BAD_URI;
1255 next=q_memchr(buf,'@', end-buf);
1257 /* no '@' found, => no userinfo */
1264 /* try to find passwd */
1265 passwd=q_memchr(user,':', next-user);
1267 /* no ':' found => no password */
1270 uri->user.len=next-user;
1273 uri->user.len=passwd-user;
1274 passwd++; /*skip ':' */
1275 uri->passwd.s=passwd;
1276 uri->passwd.len=next-passwd;
1278 host=next+1; /* skip '@' */
1280 /* try to find the rest */
1282 LOG(L_DBG, "ERROR: parse_uri: missing hostport\n");
1283 ser_error=ret=E_UNSPEC;
1287 ipv6=q_memchr(host, '[', end-host);
1289 host=ipv6+1; /* skip '[' in "[3ffe::abbcd]" */
1291 LOG(L_DBG, "ERROR: parse_uri: bad ipv6 uri\n");
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");
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:
1316 uri->host.len=host_len;
1319 if ((port)&&(port+1<end)){
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;
1327 port_len=(params)?params-port:(headers)?headers-port:end-port;
1329 uri->port.len=port_len;
1330 }else uri->port.s=0;
1332 if ((params)&&(params+1<end)){
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;
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;
1345 if ((headers)&&(headers+1<end)){
1347 headers_len=end-headers;
1348 uri->headers.s=headers;
1349 uri->headers.len=headers_len;
1350 }else uri->headers.s=0;
1353 if (uri->port.s) uri->port_no=str2s(uri->port.s, uri->port.len, &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;
1368 static inline int _parse_ruri(str *uri,
1369 int *status, struct sip_uri *parsed_uri)
1371 if (*status) return 1;
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));
1383 int parse_sip_msg_uri(struct sip_msg* msg)
1387 if (msg->parsed_uri_ok) return 1;
1389 if (msg->new_uri.s){
1391 tmp_len=msg->new_uri.len;
1393 tmp=msg->first_line.u.request.uri.s;
1394 tmp_len=msg->first_line.u.request.uri.len;
1396 if (parse_uri(tmp, tmp_len, &msg->parsed_uri)<0){
1397 LOG(L_ERR, "ERROR: parse_sip_msg_uri: bad uri <%.*s>\n",
1399 msg->parsed_uri_ok=0;
1402 msg->parsed_uri_ok=1;
1406 int parse_orig_ruri(struct sip_msg* msg)
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");
1416 inline int normalize_tel_user(char* res, str* src) {
1419 for (i=0; i<src->len; i++) {
1420 switch (src->s[i]) {
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("");
1440 inline void uri_type_to_str(uri_type type, str *s) {
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");
1464 inline void proto_type_to_str(unsigned short type, str *s) {