- malloc replacements
[sip-router] / msg_parser.c
1 /*
2  * $Id$
3  *
4  * sip msg. header proxy parser 
5  *
6  */
7
8 #include <string.h>
9 #include <stdlib.h>
10
11 #include "msg_parser.h"
12 #include "parser_f.h"
13 #include "ut.h"
14 #include "error.h"
15 #include "dprint.h"
16 #include "mem.h"
17
18 #ifdef DEBUG_DMALLOC
19 #include <dmalloc.h>
20 #endif
21
22
23
24 #define DEBUG
25
26
27
28 /* parses the first line, returns pointer to  next line  & fills fl;
29    also  modifies buffer (to avoid extra copy ops) */
30 char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl)
31 {
32         
33         char *tmp;
34         char* second;
35         char* third;
36         char* nl;
37         int offset;
38         /* int l; */
39         char* end;
40         char s1,s2,s3;
41         
42         /* grammar:
43                 request  =  method SP uri SP version CRLF
44                 response =  version SP status  SP reason  CRLF
45                 (version = "SIP/2.0")
46         */
47         
48
49         end=buffer+len;
50         /* see if it's a reply (status) */
51
52         /* jku  -- parse well-known methods */
53
54         /* drop messages which are so short they are for sure useless;
55            utilize knowledge of minimum size in parsing the first
56            token 
57         */
58         if (len <=16 ) {
59                 LOG(L_INFO, "ERROR: parse_first_line: message too short\n");
60                 goto error1;
61         }
62
63         tmp=buffer;
64         /* is it perhaps a reply, ie does it start with "SIP...." ? */
65         if (    (*tmp=='S' || *tmp=='s') && 
66                 strncasecmp( tmp+1, SIP_VERSION+1, SIP_VERSION_LEN-1)==0 &&
67                 (*(tmp+SIP_VERSION_LEN)==' ')) {
68                         fl->type=SIP_REPLY;
69                         fl->u.reply.version.len=SIP_VERSION_LEN;
70                         tmp=buffer+SIP_VERSION_LEN;
71         } else IFISMETHOD( INVITE, 'I' )
72         else IFISMETHOD( CANCEL, 'C')
73         else IFISMETHOD( ACK, 'A' )
74         else IFISMETHOD( BYE, 'B' )
75         /* if you want to add another method XXX, include METHOD_XXX in
76            H-file (this is the value which you will take later in
77            processing and define XXX_LEN as length of method name;
78            then just call IFISMETHOD( XXX, 'X' ) ... 'X' is the first
79            latter; everything must be capitals
80         */
81         else {
82                 /* neither reply, nor any of known method requests, 
83                    let's believe it is an unknown method request
84                 */
85                 tmp=eat_token_end(buffer,buffer+len);
86                 if ((tmp==buffer)||(tmp>=end)){
87                         LOG(L_INFO, "ERROR:parse_first_line: empty  or bad first line\n");
88                         goto error1;
89                 }
90                 if (*tmp!=' ') {
91                         LOG(L_INFO, "ERROR:parse_first_line: method not followed by SP\n");
92                         goto error1;
93                 }
94                 fl->type=SIP_REQUEST;
95                 fl->u.request.method_value=METHOD_OTHER;
96                 fl->u.request.method.len=tmp-buffer;
97         }
98
99
100         /* identifying type of message over now; 
101            tmp points at space after; go ahead */
102
103         fl->u.request.method.s=buffer;  /* store ptr to first token */
104         (*tmp)=0;                       /* mark the 1st token end */
105         second=tmp+1;                   /* jump to second token */
106         offset=second-buffer;
107
108 /* EoJku */
109         
110         /* next element */
111         tmp=eat_token_end(second, second+len-offset);
112         if (tmp>=end){
113                 goto error;
114         }
115         offset+=tmp-second;
116         third=eat_space_end(tmp, tmp+len-offset);
117         offset+=third-tmp;
118         if ((third==tmp)||(tmp>=end)){
119                 goto error;
120         }
121         *tmp=0; /* mark the end of the token */
122         fl->u.request.uri.s=second;
123         fl->u.request.uri.len=tmp-second;
124
125         /* jku: parse status code */
126         if (fl->type==SIP_REPLY) {
127                 if (fl->u.request.uri.len!=3) {
128                         LOG(L_INFO, "ERROR:parse_first_line: len(status code)!=3: %s\n",
129                                 second );
130                         goto error;
131                 }
132                 s1=*second; s2=*(second+1);s3=*(second+2);
133                 if (s1>='0' && s1<='9' && 
134                     s2>='0' && s2<='9' &&
135                     s3>='0' && s3<='9' ) {
136                         fl->u.reply.statusclass=s1-'0';
137                         fl->u.reply.statuscode=fl->u.reply.statusclass*100+10*(s2-'0')+(s3-'0');
138                 } else {
139                         LOG(L_INFO, "ERROR:parse_first_line: status_code non-numerical: %s\n",
140                                 second );
141                         goto error;
142                 }
143         }
144         /* EoJku */
145
146         /*  last part: for a request it must be the version, for a reply
147          *  it can contain almost anything, including spaces, so we don't care
148          *  about it*/
149         if (fl->type==SIP_REQUEST){
150                 tmp=eat_token_end(third,third+len-offset);
151                 offset+=tmp-third;
152                 if ((tmp==third)||(tmp>=end)){
153                         goto error;
154                 }
155                 if (! is_empty_end(tmp, tmp+len-offset)){
156                         goto error;
157                 }
158         }else{
159                 tmp=eat_token2_end(third,third+len-offset,'\r'); /* find end of line 
160                                                                                                   ('\n' or '\r') */
161                 if (tmp>=end){ /* no crlf in packet => invalid */
162                         goto error;
163                 }
164                 offset+=tmp-third;
165         }
166         nl=eat_line(tmp,len-offset);
167         if (nl>=end){ /* no crlf in packet or only 1 line > invalid */
168                 goto error;
169         }
170         *tmp=0;
171         fl->u.request.version.s=third;
172         fl->u.request.version.len=tmp-third;
173         
174         return nl;
175
176 error:
177         LOG(L_INFO, "ERROR:parse_first_line: bad %s first line\n", 
178                 (fl->type==SIP_REPLY)?"reply(status)":"request");
179 error1:
180         fl->type=SIP_INVALID;
181         LOG(L_INFO, "ERROR: at line 0 char %d\n", offset);
182         /* skip  line */
183         nl=eat_line(buffer,len);
184         return nl;
185 }
186
187
188
189 /* returns pointer to next header line, and fill hdr_f ;
190  * if at end of header returns pointer to the last crlf  (always buf)*/
191 char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
192 {
193
194         char* tmp;
195         char *match;
196         struct via_body *vb;
197         struct cseq_body* cseq_b;
198
199         if ((*buf)=='\n' || (*buf)=='\r'){
200                 /* double crlf or lflf or crcr */
201                 DBG("found end of header\n");
202                 hdr->type=HDR_EOH;
203                 return buf;
204         }
205
206         tmp=parse_hname(buf, end, hdr);
207         if (hdr->type==HDR_ERROR){
208                 LOG(L_ERR, "ERROR: get_hdr_field: bad header\n");
209                 goto error;
210         }
211         switch(hdr->type){
212                 case HDR_VIA:
213                         vb=pkg_malloc(sizeof(struct via_body));
214                         if (vb==0){
215                                 LOG(L_ERR, "get_hdr_field: out of memory\n");
216                                 goto error;
217                         }
218                         memset(vb,0,sizeof(struct via_body));
219
220                         hdr->body.s=tmp;
221                         tmp=parse_via(tmp, end, vb);
222                         if (vb->error==VIA_PARSE_ERROR){
223                                 LOG(L_ERR, "ERROR: get_hdr_field: bad via\n");
224                                 pkg_free(vb);
225                                 goto error;
226                         }
227                         hdr->parsed=vb;
228                         vb->hdr.s=hdr->name.s;
229                         vb->hdr.len=hdr->name.len;
230                         hdr->body.len=tmp-hdr->body.s;
231                         break;
232                 case HDR_CSEQ:
233                         cseq_b=pkg_malloc(sizeof(struct cseq_body));
234                         if (cseq_b==0){
235                                 LOG(L_ERR, "get_hdr_field: out of memory\n");
236                                 goto error;
237                         }
238                         memset(cseq_b, 0, sizeof(struct cseq_body));
239                         hdr->body.s=tmp;
240                         tmp=parse_cseq(tmp, end, cseq_b);
241                         if (cseq_b->error==PARSE_ERROR){
242                                 LOG(L_ERR, "ERROR: get_hdr_field: bad cseq\n");
243                                 pkg_free(cseq_b);
244                                 goto error;
245                         }
246                         hdr->parsed=cseq_b;
247                         hdr->body.len=tmp-hdr->body.s;
248                         DBG("get_hdr_field: cseq <%s>: <%s> <%s>\n",
249                                         hdr->name.s, cseq_b->number.s, cseq_b->method.s);
250                         break;
251                 case HDR_TO:
252                 case HDR_FROM:
253                 case HDR_CALLID:
254                 case HDR_CONTACT:
255                 case HDR_OTHER:
256                         /* just skip over it */
257                         hdr->body.s=tmp;
258                         /* find end of header */
259                         
260                         /* find lf */
261                         do{
262                                 match=q_memchr(tmp, '\n', end-tmp);
263                                 if (match){
264                                         match++;
265                                 }else {
266                                         tmp=end;
267                                         LOG(L_ERR,
268                                                         "ERROR: get_hdr_field: bad body for <%s>(%d)\n",
269                                                         hdr->name.s, hdr->type);
270                                         goto error;
271                                 }
272                         }while( match<end &&( (*match==' ')||(*match=='\t') ) );
273                         *(match-1)=0; /*null terminate*/
274                         hdr->body.len=match-hdr->body.s;
275                         tmp=match;
276                         break;
277                 default:
278                         LOG(L_CRIT, "BUG: get_hdr_field: unknown header type %d\n",
279                                         hdr->type);
280                         goto error;
281         }
282
283         return tmp;
284 error:
285         DBG("get_hdr_field: error exit\n");
286         hdr->type=HDR_ERROR;
287         return tmp;
288 }
289
290
291
292 char* parse_hostport(char* buf, str* host, short int* port)
293 {
294         char *tmp;
295         int err;
296         
297         host->s=buf;
298         for(tmp=buf;(*tmp)&&(*tmp!=':');tmp++);
299         host->len=tmp-buf;
300         if (*tmp==0){
301                 *port=0;
302         }else{
303                 *tmp=0;
304                 *port=str2s(tmp+1, strlen(tmp+1), &err);
305                 if (err ){
306                         LOG(L_INFO, 
307                                         "ERROR: hostport: trailing chars in port number: %s\n",
308                                         tmp+1);
309                         /* report error? */
310                 }
311         }
312         return host->s;
313 }
314
315
316
317 /*BUGGY*/
318 char * parse_cseq(char *buf, char* end, struct cseq_body* cb)
319 {
320         char *t;
321         char c;
322
323         cb->error=PARSE_ERROR;
324         t=eat_space_end(buf, end);
325         if (t>=end) goto error;
326         
327         cb->number.s=t;
328         t=eat_token_end(t, end);
329         if (t>=end) goto error;
330         *t=0; /*null terminate it*/
331         cb->number.len=t-cb->number.s;
332         t++;
333         t=eat_space_end(t, end);
334         if (t>=end) goto error;
335         cb->method.s=t;
336         t=eat_token_end(t, end);
337         if (t>=end) goto error;
338         c=*t;
339         *t=0; /*null terminate it*/
340         cb->method.len=t-cb->method.s;
341         t++;
342         /*check if the header ends here*/
343         if (c=='\n') goto check_continue;
344         do{
345                 for (;(t<end)&&((*t==' ')||(*t=='\t')||(*t=='\r'));t++);
346                 if (t>=end) goto error;
347                 if (*t!='\n'){
348                         LOG(L_ERR, "ERROR:parse_cseq: unexpected char <%c> at end of"
349                                         " cseq\n", *t);
350                         goto error;
351                 }
352                 t++;
353 check_continue:
354         }while( (t<end) && ((*t==' ')||(*t=='\t')) );
355
356         cb->error=PARSE_OK;
357         return t;
358 error:
359         LOG(L_ERR, "ERROR: parse_cseq: bad cseq\n");
360         return t;
361 }
362
363
364
365 /* buf= pointer to begining of uri (sip:x@foo.bar:5060;a=b?h=i)
366    len= len of uri
367 returns: fills uri & returns <0 on error or 0 if ok */
368 int parse_uri(char *buf, int len, struct sip_uri* uri)
369 {
370         char* next, *end;
371         char *user, *passwd, *host, *port, *params, *headers;
372         int host_len, port_len, params_len, headers_len;
373         int ret;
374         
375
376         ret=0;
377         end=buf+len;
378         memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure */
379         /* look for "sip:"*/;
380         next=q_memchr(buf, ':',  len);
381         if ((next==0)||(strncmp(buf,"sip",next-buf)!=0)){
382                 LOG(L_DBG, "ERROR: parse_uri: bad sip uri\n");
383                 ret=E_UNSPEC;
384                 goto error;
385         }
386         buf=next+1; /* next char after ':' */
387         if (buf>end){
388                 LOG(L_DBG, "ERROR: parse_uri: uri too short\n");
389                 ret=E_UNSPEC;
390                 goto error;
391         }
392         /*look for '@' */
393         next=q_memchr(buf,'@', end-buf);
394         if (next==0){
395                 /* no '@' found, => no userinfo */
396                 uri->user.s=0;
397                 uri->passwd.s=0;
398                 host=buf;
399         }else{
400                 /* found it */
401                 user=buf;
402                 /* try to find passwd */
403                 passwd=q_memchr(user,':', next-user);
404                 if (passwd==0){
405                         /* no ':' found => no password */
406                         uri->passwd.s=0;
407                         uri->user.s=(char*)pkg_malloc(next-user+1);
408                         if (uri->user.s==0){
409                                 LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
410                                 ret=E_OUT_OF_MEM;
411                                 goto error;
412                         }
413                         memcpy(uri->user.s, user, next-user);
414                         uri->user.len=next-user;
415                         uri->user.s[next-user]=0; /* null terminate it, 
416                                                                            usefull for easy printing*/
417                 }else{
418                         uri->user.s=(char*)pkg_malloc(passwd-user+1);
419                         if (uri->user.s==0){
420                                 LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
421                                 ret=E_OUT_OF_MEM;
422                                 goto error;
423                         }
424                         memcpy(uri->user.s, user, passwd-user);
425                         uri->user.len=passwd-user;
426                         uri->user.s[passwd-user]=0;
427                         passwd++; /*skip ':' */
428                         uri->passwd.s=(char*)pkg_malloc(next-passwd+1);
429                         if (uri->passwd.s==0){
430                                 LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
431                                 ret=E_OUT_OF_MEM;
432                                 goto error;
433                         }
434                         memcpy(uri->passwd.s, passwd, next-passwd);
435                         uri->passwd.len=next-passwd;
436                         uri->passwd.s[next-passwd]=0;
437                 }
438                 host=next+1; /* skip '@' */
439         }
440         /* try to find the rest */
441         if(host>=end){
442                 LOG(L_DBG, "ERROR: parse_uri: missing hostport\n");
443                 ret=E_UNSPEC;
444                 goto error;
445         }
446         headers=q_memchr(host,'?',end-host);
447         params=q_memchr(host,';',end-host);
448         port=q_memchr(host,':',end-host);
449         host_len=(port)?port-host:(params)?params-host:(headers)?headers-host:end-host;
450         /* get host */
451         uri->host.s=pkg_malloc(host_len+1);
452         if (uri->host.s==0){
453                 LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
454                 ret=E_OUT_OF_MEM;
455                 goto error;
456         }
457         memcpy(uri->host.s, host, host_len);
458         uri->host.len=host_len;
459         uri->host.s[host_len]=0;
460         /* get port*/
461         if ((port)&&(port+1<end)){
462                 port++;
463                 if ( ((params) &&(params<port))||((headers) &&(headers<port)) ){
464                         /* error -> invalid uri we found ';' or '?' before ':' */
465                         LOG(L_DBG, "ERROR: parse_uri: malformed sip uri\n");
466                         ret=E_UNSPEC;
467                         goto error;
468                 }
469                 port_len=(params)?params-port:(headers)?headers-port:end-port;
470                 uri->port.s=pkg_malloc(port_len+1);
471                 if (uri->port.s==0){
472                         LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
473                         ret=E_OUT_OF_MEM;
474                         goto error;
475                 }
476                 memcpy(uri->port.s, port, port_len);
477                 uri->port.len=port_len;
478                 uri->port.s[port_len]=0;
479         }else uri->port.s=0;
480         /* get params */
481         if ((params)&&(params+1<end)){
482                 params++;
483                 if ((headers) && (headers<params)){
484                         /* error -> invalid uri we found '?' or '?' before ';' */
485                         LOG(L_DBG, "ERROR: parse_uri: malformed sip uri\n");
486                         ret=E_UNSPEC;
487                         goto error;
488                 }
489                 params_len=(headers)?headers-params:end-params;
490                 uri->params.s=pkg_malloc(params_len+1);
491                 if (uri->params.s==0){
492                         LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
493                         ret=E_OUT_OF_MEM;
494                         goto error;
495                 }
496                 memcpy(uri->params.s, params, params_len);
497                 uri->params.len=params_len;
498                 uri->params.s[params_len]=0;
499         }else uri->params.s=0;
500         /*get headers */
501         if ((headers)&&(headers+1<end)){
502                 headers++;
503                 headers_len=end-headers;
504                 uri->headers.s=pkg_malloc(headers_len+1);
505                 if(uri->headers.s==0){
506                         LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
507                         ret=E_OUT_OF_MEM;
508                         goto error;
509                 }
510                 memcpy(uri->headers.s, headers, headers_len);
511                 uri->headers.len=headers_len;
512                 uri->headers.s[headers_len]=0;
513         }else uri->headers.s=0;
514         
515         return ret;
516 error:
517         return ret;
518 }
519
520
521 #ifdef OLD_PARSER
522 /* parses a via body, returns next via (for compact vias) & fills vb,
523  * the buffer should be null terminated! */
524 char* parse_via_body(char* buffer,unsigned int len, struct via_body * vb)
525 {
526         /* format: sent-proto sent-by  *(";" params) [comment] 
527
528                    sent-proto = name"/"version"/"transport
529                    sent-by    = host [":" port]
530                    
531         */
532
533         char* tmp;
534         char *name,*version, *transport, *comment, *params, *hostport;
535         int name_len, version_len, transport_len, comment_len, params_len;
536         char * next_via;
537         str host;
538         short int port;
539         int offset;
540         
541
542         name=version=transport=comment=params=hostport=next_via=host.s=0;
543         name_len=version_len=transport_len=comment_len=params_len=host.len=0;
544         name=eat_space_end(buffer, buffer+len);
545         if (name-buffer==len) goto error;
546         offset=name-buffer;
547         tmp=name;
548
549         version=eat_token2_end(tmp,tmp+len-offset,'/');
550         if (version+1-buffer>=len) goto error;
551         *version=0;
552         name_len=version-name;
553         version++;
554         offset+=version-tmp;
555         
556         transport=eat_token2_end(tmp,tmp+len-offset,'/');
557         if (transport+1-buffer>=len) goto error;
558         *transport=0;
559         version_len=transport-version;
560         transport++;
561         offset+=transport-tmp;
562         
563         tmp=eat_token_end(transport,transport+len-offset);
564         if (tmp+1-buffer>=len) goto error;
565         *tmp=0;
566         transport_len=tmp-transport;
567         tmp++;
568         offset+=tmp-transport;
569         
570         hostport=eat_space_end(tmp,tmp+len-offset);
571         if (hostport+1-buffer>=len) goto error;
572         offset+=hostport-tmp;
573
574         /* find end of hostport */
575         for(tmp=hostport; (tmp-buffer)<len &&
576                         (*tmp!=' ')&&(*tmp!=';')&&(*tmp!=','); tmp++);
577         if (tmp-buffer<len){
578                 switch (*tmp){
579                         case ' ':
580                                 *tmp=0;
581                                 tmp++;
582                                 /*the rest is comment? */
583                                 if (tmp-buffer<len){
584                                         comment=tmp;
585                                         /* eat the comment */
586                                         for(;((tmp-buffer)<len)&&
587                                                 (*tmp!=',');tmp++);
588                                         /* mark end of compact via (also end of comment)*/
589                                         comment_len=tmp-comment;
590                                         if (tmp-buffer<len){
591                                                 *tmp=0;
592                                         }else break;
593                                         /* eat space & ',' */
594                                         for(tmp=tmp+1;((tmp-buffer)<len)&&
595                                                 (*tmp==' '|| *tmp==',');tmp++);
596                                         
597                                 }
598                                 break;
599
600                         case ';':
601                                 *tmp=0;
602                                 tmp++;
603                                 if (tmp-buffer>=len) goto error;
604                                 params=tmp;
605                                 /* eat till end, first space  or ',' */
606                                 for(;((tmp-buffer)<len)&&
607                                         (*tmp!=' '&& *tmp!=',');tmp++);
608                                 params_len=tmp-params;
609                                 if (tmp-buffer==len)  break;
610                                 if (*tmp==' '){
611                                         /* eat comment */
612                                         *tmp=0;
613                                         tmp++;
614                                         comment=tmp;
615                                         for(;((tmp-buffer)<len)&&
616                                                 (*tmp!=',');tmp++);
617                                         comment_len=tmp-comment;
618                                         if (tmp-buffer==len)  break;
619                                 }
620                                 /* mark end of via*/
621                                 *tmp=0;
622                                 
623                                 /* eat space & ',' */
624                                 for(tmp=tmp+1;((tmp-buffer)<len)&&
625                                         (*tmp==' '|| *tmp==',');tmp++);
626                                 break;
627
628                         case ',':
629                                 *tmp=0;
630                                 tmp++;
631                                 if (tmp-buffer<len){
632                                         /* eat space and ',' */
633                                         for(;((tmp-buffer)<len)&&
634                                                 (*tmp==' '|| *tmp==',');
635                                            tmp++);
636                                 }
637                 }
638         }
639         /* if we are not at the end of the body => we found another compact via */
640         if (tmp-buffer<len) next_via=tmp;
641         
642         /* parse hostport */
643         parse_hostport(hostport, &host, &port);
644         vb->name.s=name;
645         vb->name.len=name_len;
646         vb->version.s=version;
647         vb->version.len=version_len;
648         vb->transport.s=transport;
649         vb->transport.len=transport_len;
650         vb->host.s=host.s;
651         vb->host.len=host.len;
652         vb->port=port;
653         vb->params.s=params;
654         vb->params.len=params_len;
655         vb->comment.s=comment;
656         vb->comment.len=comment_len;
657         vb->next=next_via;
658         vb->error=VIA_PARSE_OK;
659
660         
661         /* tmp points to end of body or to next via (if compact)*/
662         
663         return tmp;
664
665 error:
666         vb->error=VIA_PARSE_ERROR;
667         return tmp;
668 }
669 #endif
670
671
672 /* parse the headers and adds them to msg->headers and msg->to, from etc.
673  * It stops when all the headers requested in flags were parsed, on error
674  * (bad header) or end of headers */
675 int parse_headers(struct sip_msg* msg, int flags)
676 {
677         struct hdr_field* hf;
678         char* tmp;
679         char* rest;
680         char* end;
681         
682         end=msg->buf+msg->len;
683         tmp=msg->unparsed;
684         
685         DBG("parse_headers: flags=%d\n", flags);
686         while( tmp<end && (flags & msg->parsed_flag) != flags){
687                 hf=pkg_malloc(sizeof(struct hdr_field));
688                 memset(hf,0, sizeof(struct hdr_field));
689                 if (hf==0){
690                         LOG(L_ERR, "ERROR:parse_headers: memory allocation error\n");
691                         goto error;
692                 }
693                 hf->type=HDR_ERROR;
694                 rest=get_hdr_field(tmp, msg->buf+msg->len, hf);
695                 switch (hf->type){
696                         case HDR_ERROR:
697                                 LOG(L_INFO,"ERROR: bad header  field\n");
698                                 goto  error;
699                         case HDR_EOH:
700                                 msg->eoh=tmp; /* or rest?*/
701                                 msg->parsed_flag|=HDR_EOH;
702                                 goto skip;
703                         case HDR_OTHER: /*do nothing*/
704                                 break;
705                         case HDR_CALLID:
706                                 if (msg->callid==0) msg->callid=hf;
707                                 msg->parsed_flag|=HDR_CALLID;
708                                 break;
709                         case HDR_TO:
710                                 if (msg->to==0) msg->to=hf;
711                                 msg->parsed_flag|=HDR_TO;
712                                 break;
713                         case HDR_CSEQ:
714                                 if (msg->cseq==0) msg->cseq=hf;
715                                 msg->parsed_flag|=HDR_CSEQ;
716                                 break;
717                         case HDR_FROM:
718                                 if (msg->from==0) msg->from=hf;
719                                 msg->parsed_flag|=HDR_FROM;
720                                 break;
721                         case HDR_CONTACT:
722                                 if (msg->contact==0) msg->contact=hf;
723                                 msg->parsed_flag|=HDR_CONTACT;
724                                 break;
725                         case HDR_VIA:
726                                 msg->parsed_flag|=HDR_VIA;
727                                 DBG("parse_headers: Via1 found, flags=%d\n", flags);
728                                 if (msg->h_via1==0) {
729                                         msg->h_via1=hf;
730                                         msg->via1=hf->parsed;
731                                         if (msg->via1->next){
732                                                 msg->via2=msg->via1->next;
733                                                 msg->parsed_flag|=HDR_VIA2;
734                                         }
735                                 }else if (msg->h_via2==0){
736                                         msg->h_via2=hf;
737                                         msg->via2=hf->parsed;
738                                         msg->parsed_flag|=HDR_VIA2;
739                                 DBG("parse_headers: Via2 found, flags=%d\n", flags);
740                                 }
741                                 break;
742                         default:
743                                 LOG(L_CRIT, "BUG: parse_headers: unknown header type %d\n",
744                                                         hf->type);
745                                 goto error;
746                 }
747                 /* add the header to the list*/
748                 if (msg->last_header==0){
749                         msg->headers=hf;
750                         msg->last_header=hf;
751                 }else{
752                         msg->last_header->next=hf;
753                         msg->last_header=hf;
754                 }
755         #ifdef DEBUG
756                 DBG("header field type %d, name=<%s>, body=<%s>\n",
757                         hf->type, hf->name.s, hf->body.s);
758         #endif
759                 tmp=rest;
760         }
761 skip:
762         msg->unparsed=tmp;
763         return 0;
764         
765 error:
766         if (hf) pkg_free(hf);
767         return -1;
768 }
769
770
771
772
773
774 /* returns 0 if ok, -1 for errors */
775 int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
776 {
777
778         char *tmp, *bar;
779         char* rest;
780         char* first_via;
781         char* second_via;
782         struct msg_start *fl;
783         int offset;
784         int flags;
785
786         /* eat crlf from the beginning */
787         for (tmp=buf; (*tmp=='\n' || *tmp=='\r')&&
788                         tmp-buf < len ; tmp++);
789         offset=tmp-buf;
790         fl=&(msg->first_line);
791         rest=parse_first_line(tmp, len-offset, fl);
792         offset+=rest-tmp;
793         tmp=rest;
794         switch(fl->type){
795                 case SIP_INVALID:
796                         DBG("parse_msg: invalid message\n");
797                         goto error;
798                         break;
799                 case SIP_REQUEST:
800                         DBG("SIP Request:\n");
801                         DBG(" method:  <%s>\n",fl->u.request.method);
802                         DBG(" uri:     <%s>\n",fl->u.request.uri);
803                         DBG(" version: <%s>\n",fl->u.request.version);
804                         flags=HDR_VIA;
805                         break;
806                 case SIP_REPLY:
807                         DBG("SIP Reply  (status):\n");
808                         DBG(" version: <%s>\n",fl->u.reply.version);
809                         DBG(" status:  <%s>\n",fl->u.reply.status);
810                         DBG(" reason:  <%s>\n",fl->u.reply.reason);
811                         flags=HDR_VIA|HDR_VIA2;
812                         break;
813                 default:
814                         DBG("unknown type %d\n",fl->type);
815         }
816         msg->unparsed=tmp;
817         /*find first Via: */
818         first_via=0;
819         second_via=0;
820         if (parse_headers(msg, flags)==-1) goto error;
821
822 #ifdef DEBUG
823         /* dump parsed data */
824         if (msg->via1){
825                 DBG(" first  via: <%s/%s/%s> <%s:%s(%d)>",
826                         msg->via1->name.s, msg->via1->version.s,
827                         msg->via1->transport.s, msg->via1->host.s,
828                         msg->via1->port_str, msg->via1->port);
829                 if (msg->via1->params.s)  DBG(";<%s>", msg->via1->params.s);
830                 if (msg->via1->comment.s) DBG(" <%s>", msg->via1->comment.s);
831                 DBG ("\n");
832         }
833         if (msg->via2){
834                 DBG(" first  via: <%s/%s/%s> <%s:%s(%d)>",
835                         msg->via2->name.s, msg->via2->version.s,
836                         msg->via2->transport.s, msg->via2->host.s,
837                         msg->via2->port_str, msg->via2->port);
838                 if (msg->via2->params.s)  DBG(";<%s>", msg->via2->params.s);
839                 if (msg->via2->comment.s) DBG(" <%s>", msg->via2->comment.s);
840                 DBG ("\n");
841         }
842 #endif
843         
844
845 #ifdef DEBUG
846         DBG("exiting parse_msg\n");
847 #endif
848
849         return 0;
850         
851 error:
852         return -1;
853 }
854
855
856
857 void free_uri(struct sip_uri* u)
858 {
859         if (u){
860                 if (u->user.s)    pkg_free(u->user.s);
861                 if (u->passwd.s)  pkg_free(u->passwd.s);
862                 if (u->host.s)    pkg_free(u->host.s);
863                 if (u->port.s)    pkg_free(u->port.s);
864                 if (u->params.s)  pkg_free(u->params.s);
865                 if (u->headers.s) pkg_free(u->headers.s);
866         }
867 }
868
869
870
871 void free_via_list(struct via_body* vb)
872 {
873         struct via_body* foo;
874         while(vb){
875                 foo=vb;
876                 vb=vb->next;
877                 pkg_free(foo);
878         }
879 }
880
881
882 /* frees a hdr_field structure, 
883  * WARNING: it frees only parsed (and not name.s, body.s)*/
884 void clean_hdr_field(struct hdr_field* hf)
885 {
886         if (hf->parsed){
887                 switch(hf->type){
888                         case HDR_VIA:
889                                 free_via_list(hf->parsed);
890                                 break;
891                         case HDR_CSEQ:
892                                 pkg_free(hf->parsed);
893                                 break;
894                         default:
895                                 LOG(L_CRIT, "BUG: clean_hdr_field: unknown header type %d\n",
896                                                 hf->type);
897                 }
898         }
899 }
900
901
902
903 /* frees a hdr_field list,
904  * WARNING: frees only ->parsed and ->next*/
905 void free_hdr_field_lst(struct hdr_field* hf)
906 {
907         struct hdr_field* foo;
908         
909         while(hf){
910                 foo=hf;
911                 hf=hf->next;
912                 clean_hdr_field(foo);
913                 pkg_free(foo);
914         }
915 }
916
917
918
919 /*only the content*/
920 void free_sip_msg(struct sip_msg* msg)
921 {
922         if (msg->new_uri.s) { pkg_free(msg->new_uri.s); msg->new_uri.len=0; }
923         if (msg->headers)         free_hdr_field_lst(msg->headers);
924         if (msg->add_rm)      free_lump_list(msg->add_rm);
925         if (msg->repl_add_rm) free_lump_list(msg->repl_add_rm);
926         free(msg->orig);
927         free(msg->buf);
928 }
929
930
931