parse_uri.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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. * [email protected]
  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. #include "parse_uri.h"
  28. #include <string.h>
  29. #include "../dprint.h"
  30. #include "../ut.h" /* q_memchr */
  31. #include "../error.h"
  32. /* buf= pointer to begining of uri (sip:[email protected]:5060;a=b?h=i)
  33. * len= len of uri
  34. * returns: fills uri & returns <0 on error or 0 if ok
  35. */
  36. int parse_uri(char *buf, int len, struct sip_uri* uri)
  37. {
  38. char* next, *end;
  39. char *user, *passwd, *host, *port, *params, *headers, *ipv6;
  40. int host_len, port_len, params_len, headers_len;
  41. int err;
  42. int ret;
  43. ret=0;
  44. host_len=0;
  45. end=buf+len;
  46. memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure */
  47. /* look for "sip:"*/;
  48. next=q_memchr(buf, ':', len);
  49. if ((next==0)||(strncasecmp(buf,"sip",next-buf)!=0)){
  50. LOG(L_DBG, "ERROR: parse_uri: bad sip uri\n");
  51. ser_error=ret=E_BAD_URI;
  52. return ret;
  53. }
  54. buf=next+1; /* next char after ':' */
  55. if (buf>end){
  56. LOG(L_DBG, "ERROR: parse_uri: uri too short\n");
  57. ser_error=ret=E_BAD_URI;
  58. return ret;
  59. }
  60. /*look for '@' */
  61. next=q_memchr(buf,'@', end-buf);
  62. if (next==0){
  63. /* no '@' found, => no userinfo */
  64. uri->user.s=0;
  65. uri->passwd.s=0;
  66. host=buf;
  67. }else{
  68. /* found it */
  69. user=buf;
  70. /* try to find passwd */
  71. passwd=q_memchr(user,':', next-user);
  72. if (passwd==0){
  73. /* no ':' found => no password */
  74. uri->passwd.s=0;
  75. uri->user.s=user;
  76. uri->user.len=next-user;
  77. }else{
  78. uri->user.s=user;
  79. uri->user.len=passwd-user;
  80. passwd++; /*skip ':' */
  81. uri->passwd.s=passwd;
  82. uri->passwd.len=next-passwd;
  83. }
  84. host=next+1; /* skip '@' */
  85. }
  86. /* try to find the rest */
  87. if(host>=end){
  88. LOG(L_DBG, "ERROR: parse_uri: missing hostport\n");
  89. ser_error=ret=E_UNSPEC;
  90. return ret;
  91. }
  92. next=host;
  93. ipv6=q_memchr(host, '[', end-host);
  94. if (ipv6){
  95. host=ipv6+1; /* skip '[' in "[3ffe::abbcd]" */
  96. if (host>=end){
  97. LOG(L_DBG, "ERROR: parse_uri: bad ipv6 uri\n");
  98. ret=E_UNSPEC;
  99. return ret;
  100. }
  101. ipv6=q_memchr(host, ']', end-host);
  102. if ((ipv6==0)||(ipv6==host)){
  103. LOG(L_DBG, "ERROR: parse_uri: bad ipv6 uri - null address"
  104. " or missing ']'\n");
  105. ret=E_UNSPEC;
  106. return ret;
  107. }
  108. host_len=ipv6-host;
  109. next=ipv6;
  110. }
  111. headers=q_memchr(next,'?',end-next);
  112. params=q_memchr(next,';',end-next);
  113. port=q_memchr(next,':',end-next);
  114. if (host_len==0){ /* host not ipv6 addr */
  115. host_len=(port)?port-host:(params)?params-host:(headers)?headers-host:
  116. end-host;
  117. }
  118. /* get host */
  119. uri->host.s=host;
  120. uri->host.len=host_len;
  121. /* get port*/
  122. if ((port)&&(port+1<end)){
  123. port++;
  124. if ( ((params) &&(params<port))||((headers) &&(headers<port)) ){
  125. /* error -> invalid uri we found ';' or '?' before ':' */
  126. LOG(L_DBG, "ERROR: parse_uri: malformed sip uri\n");
  127. ser_error=ret=E_BAD_URI;
  128. return ret;
  129. }
  130. port_len=(params)?params-port:(headers)?headers-port:end-port;
  131. uri->port.s=port;
  132. uri->port.len=port_len;
  133. }else uri->port.s=0;
  134. /* get params */
  135. if ((params)&&(params+1<end)){
  136. params++;
  137. if ((headers) && (headers<params)){
  138. /* error -> invalid uri we found '?' or '?' before ';' */
  139. LOG(L_DBG, "ERROR: parse_uri: malformed sip uri\n");
  140. ser_error=ret=E_BAD_URI;
  141. return ret;
  142. }
  143. params_len=(headers)?headers-params:end-params;
  144. uri->params.s=params;
  145. uri->params.len=params_len;
  146. }else uri->params.s=0;
  147. /*get headers */
  148. if ((headers)&&(headers+1<end)){
  149. headers++;
  150. headers_len=end-headers;
  151. uri->headers.s=headers;
  152. uri->headers.len=headers_len;
  153. }else uri->headers.s=0;
  154. err=0;
  155. if (uri->port.s) uri->port_no=str2s(uri->port.s, uri->port.len, &err);
  156. if (err){
  157. LOG(L_DBG, "ERROR: parse_uri: bad port number in sip uri: %s\n",
  158. uri->port.s);
  159. ser_error=ret=E_BAD_URI;
  160. return ret;
  161. }
  162. return ret;
  163. }
  164. int parse_sip_msg_uri(struct sip_msg* msg)
  165. {
  166. char* tmp;
  167. int tmp_len;
  168. if (msg->parsed_uri_ok) return 1;
  169. else{
  170. if (msg->new_uri.s){
  171. tmp=msg->new_uri.s;
  172. tmp_len=msg->new_uri.len;
  173. }else{
  174. tmp=msg->first_line.u.request.uri.s;
  175. tmp_len=msg->first_line.u.request.uri.len;
  176. }
  177. if (parse_uri(tmp, tmp_len, &msg->parsed_uri)<0){
  178. LOG(L_ERR, "ERROR: parse_sip_msg_uri: bad uri <%.*s>\n",
  179. tmp_len, tmp);
  180. msg->parsed_uri_ok=0;
  181. return -1;
  182. }
  183. msg->parsed_uri_ok=1;
  184. return 1;
  185. }
  186. }