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