Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <ctype.h>
00032 #include "../mem/mem.h"
00033 #include "parse_def.h"
00034 #include "parse_identityinfo.h"
00035 #include "parser_f.h"
00036
00037
00039 void parse_identityinfo(char *buffer, char *end, struct identityinfo_body *ii_b)
00040 {
00041 int status = II_START;
00042 int mainstatus = II_M_START;
00043 char *p;
00044
00045
00046 if (!buffer || !end || !ii_b) return ;
00047
00048
00049 ii_b->error = PARSE_ERROR;
00050
00051 for(p = buffer; p < end; p++) {
00052 switch(*p) {
00053 case '<':
00054 if (status == II_START) {
00055 status=II_URI_BEGIN;
00056 mainstatus = II_M_URI_BEGIN;
00057 ii_b->uri.s = p + 1;
00058 } else
00059 goto parseerror;
00060 break;
00061 case 'h':
00062 case 'H':
00063 switch (status) {
00064 case II_URI_BEGIN:
00065 if (end - p <= 8 || strncasecmp(p,"http",strlen("http")))
00066 goto parseerror;
00067 p+=4;
00068 if (*p == 's' || *p == 'S') p++;
00069 if (memcmp(p,"://",strlen("://")))
00070 goto parseerror;
00071 p+=2;
00072 status = II_URI_DOMAIN;
00073 break;
00074 case II_URI_DOMAIN:
00075 status = II_URI_IPV4;
00076 case II_URI_IPV4:
00077 case II_URI_IPV6:
00078 case II_URI_PATH:
00079 case II_TOKEN:
00080 case II_TAG:
00081 break;
00082 case II_EQUAL:
00083 status = II_TOKEN;
00084 mainstatus = II_M_TOKEN;
00085 ii_b->alg.s = p;
00086 break;
00087 case II_LWSCRLF:
00088 ii_b->error=PARSE_OK;
00089 return ;
00090 default:
00091 goto parseerror;
00092 }
00093 break;
00094 case '/':
00095 switch(status){
00096 case II_URI_IPV4:
00097 ii_b->domain.len = p - ii_b->domain.s;
00098 status = II_URI_PATH;
00099 break;
00100 case II_URI_PATH:
00101 break;
00102 case II_URI_IPV6:
00103 default:
00104 goto parseerror;
00105 }
00106 break;
00107 case '>':
00108 if (status == II_URI_PATH) {
00109 ii_b->uri.len = p - ii_b->uri.s;
00110 status = II_URI_END;
00111 mainstatus = II_M_URI_END;
00112 } else
00113 goto parseerror;
00114 break;
00115 case ' ':
00116 case '\t':
00117 switch (status) {
00118 case II_EQUAL:
00119 case II_TAG:
00120 case II_SEMIC:
00121 case II_URI_END:
00122 status = II_LWS;
00123 break;
00124 case II_LWS:
00125 case II_LWSCRLFSP:
00126 break;
00127 case II_LWSCRLF:
00128 status = II_LWSCRLFSP;
00129 break;
00130 default:
00131 goto parseerror;
00132 }
00133 break;
00134 case '\r':
00135 switch (status) {
00136 case II_TOKEN:
00137 ii_b->alg.len = p - ii_b->alg.s;
00138 status = II_ENDHEADER;
00139 break;
00140 case II_EQUAL:
00141 case II_TAG:
00142 case II_SEMIC:
00143 case II_URI_END:
00144 case II_LWS:
00145 status = II_LWSCR;
00146 break;
00147 case II_LWSCRLF:
00148 ii_b->error=PARSE_OK;
00149 return ;
00150 default:
00151 goto parseerror;
00152 }
00153 break;
00154 case '\n':
00155 switch (status) {
00156 case II_LWSCRLF:
00157 ii_b->error=PARSE_OK;
00158 return ;
00159 case II_EQUAL:
00160 case II_TAG:
00161 case II_SEMIC:
00162 case II_URI_END:
00163 case II_LWS:
00164 case II_LWSCR:
00165 status = II_LWSCRLF;
00166 break;
00167 case II_TOKEN:
00168 ii_b->alg.len = p - ii_b->alg.s;
00169 case II_ENDHEADER:
00170 p=eat_lws_end(p, end);
00171
00172 if (p>=end) {
00173 LOG(L_ERR, "ERROR: parse_identityinfo: strange EoHF\n");
00174 goto parseerror;
00175 }
00176 ii_b->error=PARSE_OK;
00177 return ;
00178 default:
00179 goto parseerror;
00180 }
00181 break;
00182 case ';':
00183 switch (status) {
00184 case II_URI_END:
00185 case II_LWS:
00186 case II_LWSCRLFSP:
00187 if (mainstatus == II_M_URI_END) {
00188 status = II_SEMIC;
00189 mainstatus = II_M_SEMIC;
00190 } else
00191 goto parseerror;
00192 break;
00193 default:
00194 goto parseerror;
00195 }
00196 break;
00197 case 'a':
00198 case 'A':
00199 switch (status) {
00200 case II_LWS:
00201 case II_LWSCRLFSP:
00202 case II_SEMIC:
00203 if (mainstatus == II_M_SEMIC) {
00204 mainstatus = II_M_TAG;
00205 status = II_TAG;
00206 if (end - p <= 3 || strncasecmp(p,"alg",strlen("alg")))
00207 goto parseerror;
00208 p+=2;
00209 } else
00210 goto parseerror;
00211 break;
00212 case II_URI_DOMAIN:
00213 status = II_URI_IPV4;
00214 case II_URI_IPV4:
00215 case II_URI_IPV6:
00216 case II_URI_PATH:
00217 case II_TOKEN:
00218 break;
00219 case II_EQUAL:
00220 status = II_TOKEN;
00221 mainstatus = II_M_TOKEN;
00222 ii_b->alg.s = p;
00223 break;
00224 case II_LWSCRLF:
00225 ii_b->error=PARSE_OK;
00226 return ;
00227 default:
00228 goto parseerror;
00229 }
00230 break;
00231 case '=':
00232 switch (status) {
00233 case II_TAG:
00234 case II_LWS:
00235 case II_LWSCRLFSP:
00236 if (mainstatus == II_M_TAG) {
00237 status = II_EQUAL;
00238 mainstatus = II_M_EQUAL;
00239 } else
00240 goto parseerror;
00241 break;
00242 case II_URI_PATH:
00243 break;
00244 default:
00245 goto parseerror;
00246 }
00247 break;
00248 case '[':
00249 switch (status) {
00250 case II_URI_DOMAIN:
00251 status = II_URI_IPV6;
00252 ii_b->domain.s = p + 1;
00253 break;
00254 default:
00255 goto parseerror;
00256 }
00257 break;
00258 case ']':
00259 switch (status) {
00260 case II_URI_IPV6:
00261 ii_b->domain.len = p - ii_b->domain.s;
00262 status = II_URI_PATH;
00263 break;
00264 case II_URI_IPV4:
00265 case II_URI_PATH:
00266 goto parseerror;
00267 }
00268 break;
00269 case ':':
00270 if (status == II_URI_IPV4) {
00271 ii_b->domain.len = p - ii_b->domain.s;
00272 status = II_URI_PATH;
00273 }
00274 break;
00275 default:
00276 switch (status) {
00277 case II_EQUAL:
00278 case II_LWS:
00279 case II_LWSCRLFSP:
00280 if (mainstatus == II_M_EQUAL) {
00281 status = II_TOKEN;
00282 mainstatus = II_M_TOKEN;
00283 ii_b->alg.s = p;
00284 } else
00285 goto parseerror;
00286 break;
00287 case II_TOKEN:
00288 break;
00289 case II_LWSCRLF:
00290 ii_b->error=PARSE_OK;
00291 return ;
00292 case II_URI_DOMAIN:
00293 ii_b->domain.s = p;
00294 status = II_URI_IPV4;
00295 case II_URI_IPV4:
00296 case II_URI_IPV6:
00297 if (isalnum(*p)
00298 || *p == '-'
00299 || *p == '.'
00300 || *p == ':' )
00301 break;
00302 case II_START:
00303 goto parseerror;
00304 }
00305 break;
00306 }
00307 }
00308
00309 ii_b->error=PARSE_OK;
00310 return ;
00311
00312 parseerror:
00313 LOG( L_ERR , "ERROR: parse_identityinfo: "
00314 "unexpected char [%c] in status %d: <<%.*s>> .\n",
00315 *p,status, (int)(p-buffer), ZSW(p));
00316 return ;
00317 }
00318
00319 int parse_identityinfo_header(struct sip_msg *msg)
00320 {
00321 struct identityinfo_body* identityinfo_b;
00322
00323
00324 if ( !msg->identity_info
00325 && (parse_headers(msg,HDR_IDENTITY_INFO_F,0)==-1
00326 || !msg->identity_info) ) {
00327 LOG(L_ERR,"ERROR:parse_identityinfo_header: bad msg or missing IDENTITY-INFO header\n");
00328 goto error;
00329 }
00330
00331
00332 if (msg->identity_info->parsed)
00333 return 0;
00334
00335 identityinfo_b=pkg_malloc(sizeof(*identityinfo_b));
00336 if (identityinfo_b==0){
00337 LOG(L_ERR, "ERROR:parse_identityinfo_header: out of memory\n");
00338 goto error;
00339 }
00340 memset(identityinfo_b, 0, sizeof(*identityinfo_b));
00341
00342 parse_identityinfo(msg->identity_info->body.s,
00343 msg->identity_info->body.s + msg->identity_info->body.len+1,
00344 identityinfo_b);
00345 if (identityinfo_b->error==PARSE_ERROR){
00346 free_identityinfo(identityinfo_b);
00347 goto error;
00348 }
00349 msg->identity_info->parsed=(void*)identityinfo_b;
00350
00351 return 0;
00352 error:
00353 return -1;
00354 }
00355
00356 void free_identityinfo(struct identityinfo_body *ii_b)
00357 {
00358 pkg_free(ii_b);
00359 }