Browse code

parser directory cleanup

Jan Janak authored on 08/07/2002 17:14:39
Showing 21 changed files
... ...
@@ -34,7 +34,7 @@
34 34
 #include "parser/msg_parser.h"
35 35
 #include "ip_addr.h"
36 36
 #include "resolve.h"
37
-
37
+#include "parser/parse_hname2.h"
38 38
 
39 39
 
40 40
 #include "stats.h"
41 41
new file mode 100644
... ...
@@ -0,0 +1,56 @@
0
+/* 
1
+ * $Id$ 
2
+ */
3
+
4
+#include "hf.h"
5
+#include "parse_via.h"
6
+#include "parse_to.h"
7
+#include "parse_cseq.h"
8
+#include "../dprint.h"
9
+#include "../mem/mem.h"
10
+#include "parse_def.h"
11
+
12
+
13
+/* 
14
+ * Frees a hdr_field structure,
15
+ * WARNING: it frees only parsed (and not name.s, body.s)
16
+ */
17
+void clean_hdr_field(struct hdr_field* hf)
18
+{
19
+	if (hf->parsed){
20
+		switch(hf->type){
21
+		case HDR_VIA:
22
+			free_via_list(hf->parsed);
23
+			break;
24
+
25
+		case HDR_TO:
26
+			free_to(hf->parsed);
27
+			break;
28
+
29
+		case HDR_CSEQ:
30
+			free_cseq(hf->parsed);
31
+			break;
32
+
33
+		default:
34
+			LOG(L_CRIT, "BUG: clean_hdr_field: unknown header type %d\n",
35
+			    hf->type);
36
+			break;
37
+		}
38
+	}
39
+}
40
+
41
+
42
+/* 
43
+ * Frees a hdr_field list,
44
+ * WARNING: frees only ->parsed and ->next*/
45
+void free_hdr_field_lst(struct hdr_field* hf)
46
+{
47
+	struct hdr_field* foo;
48
+	
49
+	while(hf) {
50
+		foo=hf;
51
+		hf=hf->next;
52
+		clean_hdr_field(foo);
53
+		pkg_free(foo);
54
+	}
55
+}
0 56
new file mode 100644
... ...
@@ -0,0 +1,54 @@
0
+/* 
1
+ * $Id$ 
2
+ */
3
+
4
+#ifndef HF_H
5
+#define HF_H
6
+
7
+#include "../str.h"
8
+
9
+
10
+/* Header types and flags */
11
+#define HDR_EOH              -1  /* End of header found */
12
+#define HDR_ERROR             0  /* Error while parsing */
13
+#define HDR_VIA               1  /* Via header field */
14
+#define HDR_VIA1              1  /* First Via header field */
15
+#define HDR_VIA2              2  /* only used as flag*/
16
+#define HDR_TO                4  /* To header field */
17
+#define HDR_FROM              8  /* From header field */
18
+#define HDR_CSEQ             16  /* CSeq header field */
19
+#define HDR_CALLID           32  /* Call-Id header field */
20
+#define HDR_CONTACT          64  /* Contact header field */
21
+#define HDR_MAXFORWARDS     128  /* MaxForwards header field */
22
+#define HDR_ROUTE           256  /* Route header field */
23
+#define HDR_RECORDROUTE     512  /* Record-Route header field */
24
+#define HDR_CONTENTTYPE    1024  /* Content-Type header field */
25
+#define HDR_CONTENTLENGTH  2048  /* Content-Length header field */
26
+#define HDR_OTHER         65536  /* Unknown header type */ 
27
+
28
+
29
+/* 
30
+ * Format: name':' body 
31
+ */
32
+struct hdr_field {   
33
+	int type;                /* Header field type */
34
+	str name;                /* Header field name */
35
+	str body;                /* Header field body */
36
+	void* parsed;            /* Parsed data structures */
37
+	struct hdr_field* next;  /* Next header field in the list */
38
+};
39
+
40
+
41
+/* frees a hdr_field structure,
42
+ * WARNING: it frees only parsed (and not name.s, body.s)
43
+ */
44
+void clean_hdr_field(struct hdr_field* hf);
45
+
46
+
47
+/* frees a hdr_field list,
48
+ * WARNING: frees only ->parsed and ->next
49
+ */
50
+void free_hdr_field_lst(struct hdr_field* hf);
51
+
52
+
53
+#endif
... ...
@@ -17,185 +17,20 @@
17 17
 #include "../mem/mem.h"
18 18
 #include "../error.h"
19 19
 #include "../globals.h"
20
+#include "parse_hname.h"
21
+#include "parse_hname2.h"
22
+
20 23
 
21 24
 #ifdef DEBUG_DMALLOC
22 25
 #include <mem/dmalloc.h>
23 26
 #endif
24 27
 
25 28
 
26
-
27
-
28
-
29
-/* parses the first line, returns pointer to  next line  & fills fl;
30
-   also  modifies buffer (to avoid extra copy ops) */
31
-char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl)
32
-{
33
-	
34
-	char *tmp;
35
-	char* second;
36
-	char* third;
37
-	char* nl;
38
-	int offset;
39
-	/* int l; */
40
-	char* end;
41
-	char s1,s2,s3;
42
-	char *prn;
43
-	unsigned int t;
44
-
45
-	/* grammar:
46
-		request  =  method SP uri SP version CRLF
47
-		response =  version SP status  SP reason  CRLF
48
-		(version = "SIP/2.0")
49
-	*/
50
-	
51
-
52
-	end=buffer+len;
53
-	/* see if it's a reply (status) */
54
-
55
-	/* jku  -- parse well-known methods */
56
-
57
-	/* drop messages which are so short they are for sure useless;
58
-           utilize knowledge of minimum size in parsing the first
59
-	   token 
60
-        */
61
-	if (len <=16 ) {
62
-		LOG(L_INFO, "ERROR: parse_first_line: message too short: %d\n", len);
63
-		goto error1;
64
-	}
65
-
66
-	tmp=buffer;
67
-  	/* is it perhaps a reply, ie does it start with "SIP...." ? */
68
-	if ( 	(*tmp=='S' || *tmp=='s') && 
69
-		strncasecmp( tmp+1, SIP_VERSION+1, SIP_VERSION_LEN-1)==0 &&
70
-		(*(tmp+SIP_VERSION_LEN)==' ')) {
71
-			fl->type=SIP_REPLY;
72
-			fl->u.reply.version.len=SIP_VERSION_LEN;
73
-			tmp=buffer+SIP_VERSION_LEN;
74
-	} else IFISMETHOD( INVITE, 'I' )
75
-	else IFISMETHOD( CANCEL, 'C')
76
-	else IFISMETHOD( ACK, 'A' )
77
-	else IFISMETHOD( BYE, 'B' ) 
78
-	/* if you want to add another method XXX, include METHOD_XXX in
79
-           H-file (this is the value which you will take later in
80
-           processing and define XXX_LEN as length of method name;
81
-	   then just call IFISMETHOD( XXX, 'X' ) ... 'X' is the first
82
-	   latter; everything must be capitals
83
-	*/
84
-	else {
85
-		/* neither reply, nor any of known method requests, 
86
-		   let's believe it is an unknown method request
87
-        	*/
88
-		tmp=eat_token_end(buffer,buffer+len);
89
-		if ((tmp==buffer)||(tmp>=end)){
90
-			LOG(L_INFO, "ERROR:parse_first_line: empty  or bad first line\n");
91
-			goto error1;
92
-		}
93
-		if (*tmp!=' ') {
94
-			LOG(L_INFO, "ERROR:parse_first_line: method not followed by SP\n");
95
-			goto error1;
96
-		}
97
-		fl->type=SIP_REQUEST;
98
-		fl->u.request.method_value=METHOD_OTHER;
99
-		fl->u.request.method.len=tmp-buffer;
100
-	}
101
-
102
-
103
-	/* identifying type of message over now; 
104
-	   tmp points at space after; go ahead */
105
-
106
-	fl->u.request.method.s=buffer;  /* store ptr to first token */
107
-	(*tmp)=0;			/* mark the 1st token end */
108
-	second=tmp+1;			/* jump to second token */
109
-	offset=second-buffer;
110
-
111
-/* EoJku */
112
-	
113
-	/* next element */
114
-	tmp=eat_token_end(second, second+len-offset);
115
-	if (tmp>=end){
116
-		goto error;
117
-	}
118
-	offset+=tmp-second;
119
-	third=eat_space_end(tmp, tmp+len-offset);
120
-	offset+=third-tmp;
121
-	if ((third==tmp)||(tmp>=end)){
122
-		goto error;
123
-	}
124
-	*tmp=0; /* mark the end of the token */
125
-	fl->u.request.uri.s=second;
126
-	fl->u.request.uri.len=tmp-second;
127
-
128
-	/* jku: parse status code */
129
-	if (fl->type==SIP_REPLY) {
130
-		if (fl->u.request.uri.len!=3) {
131
-			LOG(L_INFO, "ERROR:parse_first_line: len(status code)!=3: %s\n",
132
-				second );
133
-			goto error;
134
-		}
135
-		s1=*second; s2=*(second+1);s3=*(second+2);
136
-		if (s1>='0' && s1<='9' && 
137
-		    s2>='0' && s2<='9' &&
138
-		    s3>='0' && s3<='9' ) {
139
-			fl->u.reply.statuscode=(s1-'0')*100+10*(s2-'0')+(s3-'0');
140
-		} else {
141
-			LOG(L_INFO, "ERROR:parse_first_line: status_code non-numerical: %s\n",
142
-				second );
143
-			goto error;
144
-		}
145
-	}
146
-	/* EoJku */
147
-
148
-	/*  last part: for a request it must be the version, for a reply
149
-	 *  it can contain almost anything, including spaces, so we don't care
150
-	 *  about it*/
151
-	if (fl->type==SIP_REQUEST){
152
-		tmp=eat_token_end(third,third+len-offset);
153
-		offset+=tmp-third;
154
-		if ((tmp==third)||(tmp>=end)){
155
-			goto error;
156
-		}
157
-		if (! is_empty_end(tmp, tmp+len-offset)){
158
-			goto error;
159
-		}
160
-	}else{
161
-		tmp=eat_token2_end(third,third+len-offset,'\r'); /* find end of line 
162
-												  ('\n' or '\r') */
163
-		if (tmp>=end){ /* no crlf in packet => invalid */
164
-			goto error;
165
-		}
166
-		offset+=tmp-third;
167
-	}
168
-	nl=eat_line(tmp,len-offset);
169
-	if (nl>=end){ /* no crlf in packet or only 1 line > invalid */
170
-		goto error;
171
-	}
172
-	*tmp=0;
173
-	fl->u.request.version.s=third;
174
-	fl->u.request.version.len=tmp-third;
175
-
176
-	return nl;
177
-
178
-error:
179
-	LOG(L_INFO, "ERROR:parse_first_line: bad %s first line\n",
180
-		(fl->type==SIP_REPLY)?"reply(status)":"request");
181
-
182
-	LOG(L_INFO, "ERROR: at line 0 char %d: \n", offset );
183
-	prn=pkg_malloc( offset );
184
-	if (prn) {
185
-		for (t=0; t<offset; t++)
186
-			if (*(buffer+t)) *(prn+t)=*(buffer+t);
187
-			else *(prn+t)='�';
188
-		LOG(L_INFO, "ERROR: parsed so far: %.*s\n", offset, prn );
189
-		pkg_free( prn );
190
-	};
191
-error1:
192
-	fl->type=SIP_INVALID;
193
-	LOG(L_INFO, "ERROR:parse_first_line: bad message\n");
194
-	/* skip  line */
195
-	nl=eat_line(buffer,len);
196
-	return nl;
197
-}
198
-
29
+#ifdef NEW_HNAME
30
+#	define parse_hname(_b,_e,_h) parse_hname2((_b),(_e),(_h))
31
+#else
32
+#	define parse_hname(_b,_e,_h) parse_hname1((_b),(_e),(_h))
33
+#endif
199 34
 
200 35
 
201 36
 /* returns pointer to next header line, and fill hdr_f ;
... ...
@@ -326,267 +161,6 @@ error:
326 326
 
327 327
 
328 328
 
329
-char* parse_hostport(char* buf, str* host, short int* port)
330
-{
331
-	char *tmp;
332
-	int err;
333
-
334
-	host->s=buf;
335
-	for(tmp=buf;(*tmp)&&(*tmp!=':');tmp++);
336
-	host->len=tmp-buf;
337
-	if (*tmp==0){
338
-		*port=0;
339
-	}else{
340
-		*tmp=0;
341
-		*port=str2s((unsigned char*)(tmp+1), strlen(tmp+1), &err);
342
-		if (err ){
343
-			LOG(L_INFO, 
344
-					"ERROR: hostport: trailing chars in port number: %s\n",
345
-					tmp+1);
346
-			/* report error? */
347
-		}
348
-	}
349
-	return host->s;
350
-}
351
-
352
-
353
-
354
-/*BUGGY*/
355
-char * parse_cseq(char *buf, char* end, struct cseq_body* cb)
356
-{
357
-	char *t, *m, *m_end;
358
-	char c;
359
-
360
-	cb->error=PARSE_ERROR;
361
-	t=eat_space_end(buf, end);
362
-	if (t>=end) goto error;
363
-	
364
-	cb->number.s=t;
365
-	t=eat_token_end(t, end);
366
-	if (t>=end) goto error;
367
-	m=eat_space_end(t, end);
368
-	m_end=eat_token_end(m, end);
369
-	*t=0; /*null terminate it*/
370
-	cb->number.len=t-cb->number.s;
371
-
372
-	if (m_end>=end) goto error;
373
-	if (m_end==m){
374
-		/* null method*/
375
-		LOG(L_ERR,  "ERROR:parse_cseq: no method found\n");
376
-		goto error;
377
-	}
378
-	cb->method.s=m;
379
-	t=m_end;
380
-	c=*t;
381
-	*t=0; /*null terminate it*/
382
-	cb->method.len=t-cb->method.s;
383
-	t++;
384
-	/*check if the header ends here*/
385
-	if (c=='\n') goto check_continue;
386
-	do{
387
-		for (;(t<end)&&((*t==' ')||(*t=='\t')||(*t=='\r'));t++);
388
-		if (t>=end) goto error;
389
-		if (*t!='\n'){
390
-			LOG(L_ERR, "ERROR:parse_cseq: unexpected char <%c> at end of"
391
-					" cseq\n", *t);
392
-			goto error;
393
-		}
394
-		t++;
395
-check_continue:
396
-		;
397
-	}while( (t<end) && ((*t==' ')||(*t=='\t')) );
398
-
399
-	cb->error=PARSE_OK;
400
-	return t;
401
-error:
402
-	LOG(L_ERR, "ERROR: parse_cseq: bad cseq\n");
403
-	return t;
404
-}
405
-
406
-
407
-
408
-/* buf= pointer to begining of uri (sip:x@foo.bar:5060;a=b?h=i)
409
-   len= len of uri
410
-returns: fills uri & returns <0 on error or 0 if ok */
411
-int parse_uri(char *buf, int len, struct sip_uri* uri)
412
-{
413
-	char* next, *end;
414
-	char *user, *passwd, *host, *port, *params, *headers, *ipv6;
415
-	int host_len, port_len, params_len, headers_len;
416
-	int ret;
417
-	
418
-
419
-	ret=0;
420
-	host_len=0;
421
-	end=buf+len;
422
-	memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure */
423
-	/* look for "sip:"*/;
424
-	next=q_memchr(buf, ':',  len);
425
-	if ((next==0)||(strncmp(buf,"sip",next-buf)!=0)){
426
-		LOG(L_DBG, "ERROR: parse_uri: bad sip uri\n");
427
-		ser_error=ret=E_BAD_URI;
428
-		goto error;
429
-	}
430
-	buf=next+1; /* next char after ':' */
431
-	if (buf>end){
432
-		LOG(L_DBG, "ERROR: parse_uri: uri too short\n");
433
-		ser_error=ret=E_BAD_URI;
434
-		goto error;
435
-	}
436
-	/*look for '@' */
437
-	next=q_memchr(buf,'@', end-buf);
438
-	if (next==0){
439
-		/* no '@' found, => no userinfo */
440
-		uri->user.s=0;
441
-		uri->passwd.s=0;
442
-		host=buf;
443
-	}else{
444
-		/* found it */
445
-		user=buf;
446
-		/* try to find passwd */
447
-		passwd=q_memchr(user,':', next-user);
448
-		if (passwd==0){
449
-			/* no ':' found => no password */
450
-			uri->passwd.s=0;
451
-			uri->user.s=(char*)pkg_malloc(next-user+1);
452
-			if (uri->user.s==0){
453
-				LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
454
-				ser_error=ret=E_OUT_OF_MEM;
455
-				goto error;
456
-			}
457
-			memcpy(uri->user.s, user, next-user);
458
-			uri->user.len=next-user;
459
-			uri->user.s[next-user]=0; /* null terminate it, 
460
-									   usefull for easy printing*/
461
-		}else{
462
-			uri->user.s=(char*)pkg_malloc(passwd-user+1);
463
-			if (uri->user.s==0){
464
-				LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
465
-				ser_error=ret=E_OUT_OF_MEM;
466
-				goto error;
467
-			}
468
-			memcpy(uri->user.s, user, passwd-user);
469
-			uri->user.len=passwd-user;
470
-			uri->user.s[passwd-user]=0;
471
-			passwd++; /*skip ':' */
472
-			uri->passwd.s=(char*)pkg_malloc(next-passwd+1);
473
-			if (uri->passwd.s==0){
474
-				LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
475
-				ser_error=ret=E_OUT_OF_MEM;
476
-				goto error;
477
-			}
478
-			memcpy(uri->passwd.s, passwd, next-passwd);
479
-			uri->passwd.len=next-passwd;
480
-			uri->passwd.s[next-passwd]=0;
481
-		}
482
-		host=next+1; /* skip '@' */
483
-	}
484
-	/* try to find the rest */
485
-	if(host>=end){
486
-		LOG(L_DBG, "ERROR: parse_uri: missing hostport\n");
487
-		ser_error=ret=E_UNSPEC;
488
-		goto error;
489
-	}
490
-	next=host;
491
-	ipv6=q_memchr(host, '[', end-host);
492
-	if (ipv6){
493
-		host=ipv6+1; /* skip '[' in "[3ffe::abbcd]" */
494
-		if (host>=end){
495
-			LOG(L_DBG, "ERROR: parse_uri: bad ipv6 uri\n");
496
-			ret=E_UNSPEC;
497
-			goto error;
498
-		}
499
-		ipv6=q_memchr(host, ']', end-host);
500
-		if ((ipv6==0)||(ipv6==host)){
501
-			LOG(L_DBG, "ERROR: parse_uri: bad ipv6 uri - null address"
502
-					" or missing ']'\n");
503
-			ret=E_UNSPEC;
504
-			goto error;
505
-		}
506
-		host_len=ipv6-host;
507
-		next=ipv6;
508
-	}
509
-
510
-		
511
-	headers=q_memchr(next,'?',end-next);
512
-	params=q_memchr(next,';',end-next);
513
-	port=q_memchr(next,':',end-next);
514
-	if (host_len==0){ /* host not ipv6 addr */
515
-		host_len=(port)?port-host:(params)?params-host:(headers)?headers-host:
516
-				end-host;
517
-	}
518
-	/* get host */
519
-	uri->host.s=pkg_malloc(host_len+1);
520
-	if (uri->host.s==0){
521
-		LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
522
-		ret=E_OUT_OF_MEM;
523
-		goto error;
524
-	}
525
-	memcpy(uri->host.s, host, host_len);
526
-	uri->host.len=host_len;
527
-	uri->host.s[host_len]=0;
528
-	/* get port*/
529
-	if ((port)&&(port+1<end)){
530
-		port++;
531
-		if ( ((params) &&(params<port))||((headers) &&(headers<port)) ){
532
-			/* error -> invalid uri we found ';' or '?' before ':' */
533
-			LOG(L_DBG, "ERROR: parse_uri: malformed sip uri\n");
534
-			ser_error=ret=E_BAD_URI;
535
-			goto error;
536
-		}
537
-		port_len=(params)?params-port:(headers)?headers-port:end-port;
538
-		uri->port.s=pkg_malloc(port_len+1);
539
-		if (uri->port.s==0){
540
-			LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
541
-			ser_error=ret=E_OUT_OF_MEM;
542
-			goto error;
543
-		}
544
-		memcpy(uri->port.s, port, port_len);
545
-		uri->port.len=port_len;
546
-		uri->port.s[port_len]=0;
547
-	}else uri->port.s=0;
548
-	/* get params */
549
-	if ((params)&&(params+1<end)){
550
-		params++;
551
-		if ((headers) && (headers<params)){
552
-			/* error -> invalid uri we found '?' or '?' before ';' */
553
-			LOG(L_DBG, "ERROR: parse_uri: malformed sip uri\n");
554
-			ser_error=ret=E_BAD_URI;
555
-			goto error;
556
-		}
557
-		params_len=(headers)?headers-params:end-params;
558
-		uri->params.s=pkg_malloc(params_len+1);
559
-		if (uri->params.s==0){
560
-			LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
561
-			ser_error=ret=E_OUT_OF_MEM;
562
-			goto error;
563
-		}
564
-		memcpy(uri->params.s, params, params_len);
565
-		uri->params.len=params_len;
566
-		uri->params.s[params_len]=0;
567
-	}else uri->params.s=0;
568
-	/*get headers */
569
-	if ((headers)&&(headers+1<end)){
570
-		headers++;
571
-		headers_len=end-headers;
572
-		uri->headers.s=pkg_malloc(headers_len+1);
573
-		if(uri->headers.s==0){
574
-			LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
575
-			ser_error=ret=E_OUT_OF_MEM;
576
-			goto error;
577
-		}
578
-		memcpy(uri->headers.s, headers, headers_len);
579
-		uri->headers.len=headers_len;
580
-		uri->headers.s[headers_len]=0;
581
-	}else uri->headers.s=0;
582
-	
583
-	return ret;
584
-error:
585
-	free_uri(uri);
586
-	return ret;
587
-}
588
-
589
-
590 329
 /* parse the headers and adds them to msg->headers and msg->to, from etc.
591 330
  * It stops when all the headers requested in flags were parsed, on error
592 331
  * (bad header) or end of headers */
... ...
@@ -811,18 +385,6 @@ error:
811 811
 
812 812
 
813 813
 
814
-void free_uri(struct sip_uri* u)
815
-{
816
-	if (u){
817
-		if (u->user.s)    pkg_free(u->user.s);
818
-		if (u->passwd.s)  pkg_free(u->passwd.s);
819
-		if (u->host.s)    pkg_free(u->host.s);
820
-		if (u->port.s)    pkg_free(u->port.s);
821
-		if (u->params.s)  pkg_free(u->params.s);
822
-		if (u->headers.s) pkg_free(u->headers.s);
823
-	}
824
-}
825
-
826 814
 void free_reply_lump( struct lump_rpl *lump)
827 815
 {
828 816
 	struct lump_rpl *foo, *bar;
... ...
@@ -834,80 +396,6 @@ void free_reply_lump( struct lump_rpl *lump)
834 834
 	}
835 835
 }
836 836
 
837
-void free_via_param_list(struct via_param* vp)
838
-{
839
-	struct via_param* foo;
840
-	while(vp){
841
-		foo=vp;
842
-		vp=vp->next;
843
-		pkg_free(foo);
844
-	}
845
-}
846
-
847
-
848
-
849
-void free_via_list(struct via_body* vb)
850
-{
851
-	struct via_body* foo;
852
-	while(vb){
853
-		foo=vb;
854
-		vb=vb->next;
855
-		if (foo->param_lst) free_via_param_list(foo->param_lst);
856
-		pkg_free(foo);
857
-	}
858
-}
859
-
860
-void free_to(struct to_body* tb)
861
-{
862
-	struct to_param *tp=tb->param_lst;
863
-	struct to_param *foo;
864
-	while (tp){
865
-		foo = tp->next;
866
-		pkg_free(tp);
867
-		tp=foo;
868
-	}
869
-	pkg_free(tb);
870
-}
871
-
872
-/* frees a hdr_field structure,
873
- * WARNING: it frees only parsed (and not name.s, body.s)*/
874
-void clean_hdr_field(struct hdr_field* hf)
875
-{
876
-	if (hf->parsed){
877
-		switch(hf->type){
878
-			case HDR_VIA:
879
-				free_via_list(hf->parsed);
880
-				break;
881
-			case HDR_TO:
882
-				free_to(hf->parsed);
883
-				break;
884
-			case HDR_CSEQ:
885
-				pkg_free(hf->parsed);
886
-				break;
887
-			default:
888
-				LOG(L_CRIT, "BUG: clean_hdr_field: unknown header type %d\n",
889
-						hf->type);
890
-		}
891
-	}
892
-}
893
-
894
-
895
-
896
-/* frees a hdr_field list,
897
- * WARNING: frees only ->parsed and ->next*/
898
-void free_hdr_field_lst(struct hdr_field* hf)
899
-{
900
-	struct hdr_field* foo;
901
-	
902
-	while(hf){
903
-		foo=hf;
904
-		hf=hf->next;
905
-		clean_hdr_field(foo);
906
-		pkg_free(foo);
907
-	}
908
-}
909
-
910
-
911 837
 
912 838
 /*only the content*/
913 839
 void free_sip_msg(struct sip_msg* msg)
... ...
@@ -9,71 +9,23 @@
9 9
 #include "../data_lump.h"
10 10
 #include "../flags.h"
11 11
 #include "../ip_addr.h"
12
+#include "parse_def.h"
13
+#include "parse_cseq.h"
14
+#include "parse_to.h"
15
+#include "parse_via.h"
16
+#include "parse_uri.h"
17
+#include "parse_fline.h"
18
+#include "hf.h"
12 19
 
13
-#define SIP_REQUEST 1
14
-#define SIP_REPLY   2
15
-#define SIP_INVALID 0
16 20
 
17
-
18
-
19
-/*header types and flags*/
20
-#define HDR_EOH             -1
21
-#define HDR_ERROR            0
22
-#define HDR_VIA              1
23
-#define HDR_VIA1             1
24
-#define HDR_VIA2             2  /*only used as flag*/
25
-#define HDR_TO               4
26
-#define HDR_FROM             8
27
-#define HDR_CSEQ            16
28
-#define HDR_CALLID          32
29
-#define HDR_CONTACT         64
30
-#define HDR_MAXFORWARDS    128
31
-#define HDR_ROUTE          256
32
-#define HDR_RECORDROUTE    512
33
-#define HDR_CONTENTTYPE   1024
34
-#define HDR_CONTENTLENGTH 2048
35
-#define HDR_OTHER        65536 /*unknown header type*/
36
-
37
-
38
-/* maximum length of values appended to Via-branch parameter */
21
+/* Maximum length of values appended to Via-branch parameter */
39 22
 #ifdef USE_SYNONIM
40 23
 #define MAX_BRANCH_PARAM_LEN  22
41 24
 #else
42 25
 #define MAX_BRANCH_PARAM_LEN  48
43 26
 #endif
44
-/* via param types
45
- * WARNING: keep in sync w/ FIN_*, GEN_PARAM and PARAM_ERROR from via_parse.c*/
46
-enum{
47
-		PARAM_HIDDEN=230, PARAM_TTL, PARAM_BRANCH, PARAM_MADDR, PARAM_RECEIVED,
48
-		GEN_PARAM,
49
-		PARAM_ERROR
50
-};
51
-
52
-enum{
53
-		TAG_PARAM=400, GENERAL_PARAM
54
-};
55
-
56
-/* casting macro for accessing CSEQ body */
57
-#define get_cseq( p_msg)  ((struct cseq_body*)(p_msg)->cseq->parsed)
58
-#define get_to( p_msg)      ((struct to_body*)(p_msg)->to->parsed)
59
-
60
-#ifdef NEW_HNAME
61
-#	define parse_hname(_b,_e,_h) parse_hname2((_b),(_e),(_h))
62
-	void init_htable(void);
63
-#else
64
-#	define parse_hname(_b,_e,_h) parse_hname1((_b),(_e),(_h))
65
-#endif
66 27
 
67 28
 
68
-#define INVITE_LEN	6
69
-#define ACK_LEN		3
70
-#define CANCEL_LEN	6
71
-#define BYE_LEN		3
72
-
73
-#define CANCEL	"CANCEL"
74
-#define ACK		"ACK"
75
-#define INVITE "INVITE"
76
-
77 29
 /* convenience short-cut macros */
78 30
 #define REQ_LINE(_msg) ((_msg)->first_line.u.request)
79 31
 #define REQ_METHOD first_line.u.request.method_value
... ...
@@ -93,109 +45,18 @@ if (  (*tmp==(firstchar) || *tmp==((firstchar) | 32)) &&                  \
93 93
 }
94 94
 
95 95
 
96
-#define VIA_PARSE_OK	1
97
-#define VIA_PARSE_ERROR -1
98
-#define PARSE_ERROR -1
99
-#define PARSE_OK 1
100
-
101
-#define SIP_VERSION	"SIP/2.0"
102
-#define SIP_VERSION_LEN 7
103
-
104
-
105
-struct msg_start{
106
-	int type;
107
-	union {
108
-		struct {
109
-			str method;
110
-			str uri;
111
-			str version;
112
-			int method_value;
113
-		}request;
114
-		struct {
115
-			str version;
116
-			str status;
117
-			str reason;
118
-			unsigned int /* statusclass,*/ statuscode;
119
-		}reply;
120
-	}u;
121
-};
122
-
123
-struct hdr_field{   /* format: name':' body */
124
-	int type;
125
-	str name;
126
-	str body;
127
-	void* parsed;
128
-	struct hdr_field* next;
129
-};
130
-
131
-
132
-
133
-struct via_param{
134
-	int type;
135
-	str name;
136
-	str value;
137
-	int size; /* total size*/
138
-	struct via_param* next;
139
-};
140
-
141
-struct via_body{  /* format: name/version/transport host:port;params comment */
142
-	int error;
143
-	str hdr;   /* contains "Via" or "v" */
144
-	str name;
145
-	str version;
146
-	str transport;
147
-	str host;
148
-	int port;
149
-	str port_str;
150
-	str params;
151
-	str comment;
152
-	int bsize;    /* body size, not including hdr */
153
-	struct via_param* param_lst; /* list of parameters*/
154
-	struct via_param* last_param; /*last via parameter, internal use*/
155
-	/* shortcuts to "important" params*/
156
-	struct via_param* branch;
157
-
158
-	struct via_body* next; /* pointer to next via body string if
159
-         compact via or null */
160
-};
161
-
162
-
163
-
164
-struct to_param{
165
-	int type;
166
-	str name;
167
-	str value;
168
-	struct to_param* next;
169
-};
170
-
171
-struct to_body{
172
-	int error;
173
-	str body;
174
-	str uri;
175
-	str tag_value;
176
-	struct to_param *param_lst;
177
-	struct to_param *last_param;
178
-};
179
-
180
-
181
-struct cseq_body{
182
-	int error;
183
-	str number;
184
-	str method;
185
-};
96
+struct sip_msg {
97
+	unsigned int id;               /* message id, unique/process*/
98
+	struct msg_start first_line;   /* Message first line */
99
+	struct via_body* via1;         /* The first via */
100
+	struct via_body* via2;         /* The second via */
101
+	struct hdr_field* headers;     /* All the parsed headers*/
102
+	struct hdr_field* last_header; /* Pointer to the last parsed header*/
103
+	int parsed_flag;               /* Already parsed header field types */
186 104
 
105
+	     /* Via, To, CSeq, Call-Id, From, end of header*/
106
+	     /* first occurance of it; subsequent occurances saved in 'headers' */
187 107
 
188
-
189
-struct sip_msg{
190
-	unsigned int id; /* message id, unique/process*/
191
-	struct msg_start first_line;
192
-	struct via_body* via1;
193
-	struct via_body* via2;
194
-	struct hdr_field* headers; /* all the parsed headers*/
195
-	struct hdr_field* last_header; /* pointer to the last parsed header*/
196
-	int parsed_flag;
197
-	/* via, to, cseq, call-id, from, end of header*/
198
-	/* first occurance of it; subsequent occurances saved in 'headers' */
199 108
 	struct hdr_field* h_via1;
200 109
 	struct hdr_field* h_via2;
201 110
 	struct hdr_field* callid;
... ...
@@ -208,72 +69,47 @@ struct sip_msg{
208 208
 	struct hdr_field* record_route;
209 209
 	struct hdr_field* content_type;
210 210
 	struct hdr_field* content_length;
211
-	char* eoh; /* pointer to the end of header (if found) or null */
212
-	char* unparsed; /* here we stopped parsing*/
211
+
212
+	char* eoh;        /* pointer to the end of header (if found) or null */
213
+	char* unparsed;   /* here we stopped parsing*/
213 214
 
214 215
 	struct ip_addr src_ip;
215 216
 	struct ip_addr dst_ip;
216
-	char* orig; /* original message copy */
217
-	char* buf;  /* scratch pad, holds a modfied message,
218
-				   via, etc. point into it */
217
+	
218
+	char* orig;       /* original message copy */
219
+	char* buf;        /* scratch pad, holds a modfied message,
220
+			   *  via, etc. point into it 
221
+			   */
219 222
 	unsigned int len; /* message len (orig) */
220 223
 
221
-	/* modifications */
224
+	     /* modifications */
225
+	
222 226
 	str new_uri; /* changed first line uri*/
223
-
224
-	struct lump* add_rm;      /* used for all the forwarded messages */
225
-	struct lump* repl_add_rm; /* only for localy generated replies !!!*/
227
+	
228
+	struct lump* add_rm;         /* used for all the forwarded messages */
229
+	struct lump* repl_add_rm;    /* only for localy generated replies !!!*/
226 230
 	struct lump_rpl *reply_lump;
227
-
228
-	/* str add_to_branch; */ /* whatever whoever want to append to branch comes here */
231
+	
232
+	     /* str add_to_branch */ 
233
+	     /* whatever whoever want to append to branch comes here */
229 234
 	char add_to_branch_s[MAX_BRANCH_PARAM_LEN];
230 235
 	int add_to_branch_len;
231
-
232
-	/* index to TM hash table; stored in core to avoid unnecessary calcs */
236
+	
237
+	     /* index to TM hash table; stored in core to avoid unnecessary calcs */
233 238
 	unsigned int  hash_index;
234
-
235
-	/* allows to set various flags on the message; may be used for 
236
-	   simple inter-module communication or remembering processing state
237
-	   reached */
238
-	flag_t flags;
239
-
240 239
 	
240
+	     /* allows to set various flags on the message; may be used for 
241
+	      *	simple inter-module communication or remembering processing state
242
+	      * reached 
243
+	      */
244
+	flag_t flags;	
241 245
 };
242 246
 
243 247
 
244
-struct sip_uri{
245
-	str user;
246
-	str passwd;
247
-	str host;
248
-	str port;
249
-	str params;
250
-	str headers;
251
-};
252
-
253
-
254
-char* parse_fline(char* buffer, char* end, struct msg_start* fl);
255
-char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl);
256
-char* parse_hostport(char* buf, str* host, short int* port);
257
-
258 248
 int parse_msg(char* buf, unsigned int len, struct sip_msg* msg);
259
-int parse_uri(char *buf, int len, struct sip_uri* uri);
260
-int parse_headers(struct sip_msg* msg, int flags);
261
-
262
-void free_uri(struct sip_uri* u);
263 249
 
250
+int parse_headers(struct sip_msg* msg, int flags);
264 251
 
265
-/* char* parse_hname(char* buf, char* end, struct hdr_field* hdr); */
266
-char* parse_hname1(char* buf, char* end, struct hdr_field* hdr);
267
-char* parse_hname2(char* buf, char* end, struct hdr_field* hdr);
268
-
269
-char* parse_via(char* buffer, char* end, struct via_body *vb);
270
-char* parse_to(char* buffer, char* end, struct to_body *to_b);
271
-char* parse_cseq(char* buffer, char* end, struct cseq_body *cb);
272
-
273
-void free_via_param_list(struct via_param *vp);
274
-void free_via_list(struct via_body *vb);
275
-void clean_hdr_field(struct hdr_field* hf);
276
-void free_hdr_field_lst(struct hdr_field* hf);
277 252
 void free_sip_msg(struct sip_msg* msg);
278 253
 
279 254
 /* make sure all HFs needed for transaction identification have been
280 255
new file mode 100644
... ...
@@ -0,0 +1,71 @@
0
+/* 
1
+ * $Id 
2
+ */
3
+
4
+#include "parse_cseq.h"
5
+#include "parser_f.h"  /* eat_space_end and so on */
6
+#include "../dprint.h"
7
+#include "parse_def.h"
8
+#include "../mem/mem.h"
9
+
10
+/*
11
+ * Parse CSeq header field
12
+ */
13
+
14
+/*BUGGY*/
15
+char* parse_cseq(char *buf, char* end, struct cseq_body* cb)
16
+{
17
+	char *t, *m, *m_end;
18
+	char c;
19
+	
20
+	cb->error=PARSE_ERROR;
21
+	t=eat_space_end(buf, end);
22
+	if (t>=end) goto error;
23
+	
24
+	cb->number.s=t;
25
+	t=eat_token_end(t, end);
26
+	if (t>=end) goto error;
27
+	m=eat_space_end(t, end);
28
+	m_end=eat_token_end(m, end);
29
+	*t=0; /*null terminate it*/
30
+	cb->number.len=t-cb->number.s;
31
+
32
+	if (m_end>=end) goto error;
33
+	if (m_end==m){
34
+		/* null method*/
35
+		LOG(L_ERR,  "ERROR:parse_cseq: no method found\n");
36
+		goto error;
37
+	}
38
+	cb->method.s=m;
39
+	t=m_end;
40
+	c=*t;
41
+	*t=0; /*null terminate it*/
42
+	cb->method.len=t-cb->method.s;
43
+	t++;
44
+	/*check if the header ends here*/
45
+	if (c=='\n') goto check_continue;
46
+	do{
47
+		for (;(t<end)&&((*t==' ')||(*t=='\t')||(*t=='\r'));t++);
48
+		if (t>=end) goto error;
49
+		if (*t!='\n'){
50
+			LOG(L_ERR, "ERROR:parse_cseq: unexpected char <%c> at end of"
51
+					" cseq\n", *t);
52
+			goto error;
53
+		}
54
+		t++;
55
+check_continue:
56
+		;
57
+	}while( (t<end) && ((*t==' ')||(*t=='\t')) );
58
+
59
+	cb->error=PARSE_OK;
60
+	return t;
61
+error:
62
+	LOG(L_ERR, "ERROR: parse_cseq: bad cseq\n");
63
+	return t;
64
+}
65
+
66
+
67
+void free_cseq(struct cseq_body* cb)
68
+{
69
+	pkg_free(cb);
70
+}
0 71
new file mode 100644
... ...
@@ -0,0 +1,34 @@
0
+/*
1
+ * $Id$
2
+ */
3
+
4
+#ifndef PARSE_CSEQ
5
+#define PARSE_CSEQ
6
+
7
+#include "../str.h"
8
+
9
+
10
+struct cseq_body{
11
+	int error;  /* Error code */
12
+	str number; /* CSeq number */
13
+	str method; /* Associated method */
14
+};
15
+
16
+
17
+/* casting macro for accessing CSEQ body */
18
+#define get_cseq(p_msg) ((struct cseq_body*)(p_msg)->cseq->parsed)
19
+
20
+
21
+/*
22
+ * Parse CSeq header field
23
+ */
24
+char* parse_cseq(char *buf, char* end, struct cseq_body* cb);
25
+
26
+
27
+/*
28
+ * Free all associated memory
29
+ */
30
+void free_cseq(struct cseq_body* cb);
31
+
32
+
33
+#endif
0 34
new file mode 100644
... ...
@@ -0,0 +1,11 @@
0
+/*
1
+ * $Id$
2
+ */
3
+
4
+#ifndef PARSE_DEF
5
+#define PARSE_DEF
6
+
7
+#define PARSE_ERROR -1
8
+#define PARSE_OK 1
9
+
10
+#endif
... ...
@@ -9,6 +9,8 @@
9 9
 
10 10
 #include "../dprint.h"
11 11
 #include "msg_parser.h"
12
+#include "parser_f.h"
13
+#include "../mem/mem.h"
12 14
 
13 15
 
14 16
 /* grammar:
... ...
@@ -19,17 +21,17 @@
19 19
 
20 20
 /*known methods: INVITE, ACK, CANCEL, BYE*/
21 21
 
22
-enum{ START,
23
-		INVITE1, INVITE2, INVITE3, INVITE4, INVITE5,
24
-		ACK1,    ACK2,
25
-		CANCEL1, CANCEL2, CANCEL3, CANCEL4, CANCEL5,
26
-		BYE1, BYE2,
27
-		SIP1, SIP2, SIP3, SIP4, SIP5, SIP6,
28
-		FIN_INVITE=100, FIN_ACK, FIN_CANCEL, FIN_BYE, FIN_SIP,
29
-		P_METHOD=200, L_URI, P_URI, L_VER, 
30
-		VER1, VER2, VER3, VER4, VER5, VER6, FIN_VER,
31
-		L_STATUS, P_STATUS, L_REASON, P_REASON,
32
-		L_LF, F_CR, F_LF
22
+enum { START,
23
+       INVITE1, INVITE2, INVITE3, INVITE4, INVITE5,
24
+       ACK1, ACK2,
25
+       CANCEL1, CANCEL2, CANCEL3, CANCEL4, CANCEL5,
26
+       BYE1, BYE2,
27
+       SIP1, SIP2, SIP3, SIP4, SIP5, SIP6,
28
+       FIN_INVITE = 100, FIN_ACK, FIN_CANCEL, FIN_BYE, FIN_SIP,
29
+       P_METHOD = 200, L_URI, P_URI, L_VER, 
30
+       VER1, VER2, VER3, VER4, VER5, VER6, FIN_VER,
31
+       L_STATUS, P_STATUS, L_REASON, P_REASON,
32
+       L_LF, F_CR, F_LF
33 33
 };
34 34
 
35 35
 
... ...
@@ -1108,3 +1110,175 @@ error:
1108 1108
 	fl->type=SIP_INVALID;
1109 1109
 	return tmp;
1110 1110
 }
1111
+
1112
+
1113
+
1114
+/* parses the first line, returns pointer to  next line  & fills fl;
1115
+   also  modifies buffer (to avoid extra copy ops) */
1116
+char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl)
1117
+{
1118
+	
1119
+	char *tmp;
1120
+	char* second;
1121
+	char* third;
1122
+	char* nl;
1123
+	int offset;
1124
+	/* int l; */
1125
+	char* end;
1126
+	char s1,s2,s3;
1127
+	char *prn;
1128
+	unsigned int t;
1129
+
1130
+	/* grammar:
1131
+		request  =  method SP uri SP version CRLF
1132
+		response =  version SP status  SP reason  CRLF
1133
+		(version = "SIP/2.0")
1134
+	*/
1135
+	
1136
+
1137
+	end=buffer+len;
1138
+	/* see if it's a reply (status) */
1139
+
1140
+	/* jku  -- parse well-known methods */
1141
+
1142
+	/* drop messages which are so short they are for sure useless;
1143
+           utilize knowledge of minimum size in parsing the first
1144
+	   token 
1145
+        */
1146
+	if (len <=16 ) {
1147
+		LOG(L_INFO, "ERROR: parse_first_line: message too short: %d\n", len);
1148
+		goto error1;
1149
+	}
1150
+
1151
+	tmp=buffer;
1152
+  	/* is it perhaps a reply, ie does it start with "SIP...." ? */
1153
+	if ( 	(*tmp=='S' || *tmp=='s') && 
1154
+		strncasecmp( tmp+1, SIP_VERSION+1, SIP_VERSION_LEN-1)==0 &&
1155
+		(*(tmp+SIP_VERSION_LEN)==' ')) {
1156
+			fl->type=SIP_REPLY;
1157
+			fl->u.reply.version.len=SIP_VERSION_LEN;
1158
+			tmp=buffer+SIP_VERSION_LEN;
1159
+	} else IFISMETHOD( INVITE, 'I' )
1160
+	else IFISMETHOD( CANCEL, 'C')
1161
+	else IFISMETHOD( ACK, 'A' )
1162
+	else IFISMETHOD( BYE, 'B' ) 
1163
+	/* if you want to add another method XXX, include METHOD_XXX in
1164
+           H-file (this is the value which you will take later in
1165
+           processing and define XXX_LEN as length of method name;
1166
+	   then just call IFISMETHOD( XXX, 'X' ) ... 'X' is the first
1167
+	   latter; everything must be capitals
1168
+	*/
1169
+	else {
1170
+		/* neither reply, nor any of known method requests, 
1171
+		   let's believe it is an unknown method request
1172
+        	*/
1173
+		tmp=eat_token_end(buffer,buffer+len);
1174
+		if ((tmp==buffer)||(tmp>=end)){
1175
+			LOG(L_INFO, "ERROR:parse_first_line: empty  or bad first line\n");
1176
+			goto error1;
1177
+		}
1178
+		if (*tmp!=' ') {
1179
+			LOG(L_INFO, "ERROR:parse_first_line: method not followed by SP\n");
1180
+			goto error1;
1181
+		}
1182
+		fl->type=SIP_REQUEST;
1183
+		fl->u.request.method_value=METHOD_OTHER;
1184
+		fl->u.request.method.len=tmp-buffer;
1185
+	}
1186
+
1187
+
1188
+	/* identifying type of message over now; 
1189
+	   tmp points at space after; go ahead */
1190
+
1191
+	fl->u.request.method.s=buffer;  /* store ptr to first token */
1192
+	(*tmp)=0;			/* mark the 1st token end */
1193
+	second=tmp+1;			/* jump to second token */
1194
+	offset=second-buffer;
1195
+
1196
+/* EoJku */
1197
+	
1198
+	/* next element */
1199
+	tmp=eat_token_end(second, second+len-offset);
1200
+	if (tmp>=end){
1201
+		goto error;
1202
+	}
1203
+	offset+=tmp-second;
1204
+	third=eat_space_end(tmp, tmp+len-offset);
1205
+	offset+=third-tmp;
1206
+	if ((third==tmp)||(tmp>=end)){
1207
+		goto error;
1208
+	}
1209
+	*tmp=0; /* mark the end of the token */
1210
+	fl->u.request.uri.s=second;
1211
+	fl->u.request.uri.len=tmp-second;
1212
+
1213
+	/* jku: parse status code */
1214
+	if (fl->type==SIP_REPLY) {
1215
+		if (fl->u.request.uri.len!=3) {
1216
+			LOG(L_INFO, "ERROR:parse_first_line: len(status code)!=3: %s\n",
1217
+				second );
1218
+			goto error;
1219
+		}
1220
+		s1=*second; s2=*(second+1);s3=*(second+2);
1221
+		if (s1>='0' && s1<='9' && 
1222
+		    s2>='0' && s2<='9' &&
1223
+		    s3>='0' && s3<='9' ) {
1224
+			fl->u.reply.statuscode=(s1-'0')*100+10*(s2-'0')+(s3-'0');
1225
+		} else {
1226
+			LOG(L_INFO, "ERROR:parse_first_line: status_code non-numerical: %s\n",
1227
+				second );
1228
+			goto error;
1229
+		}
1230
+	}
1231
+	/* EoJku */
1232
+
1233
+	/*  last part: for a request it must be the version, for a reply
1234
+	 *  it can contain almost anything, including spaces, so we don't care
1235
+	 *  about it*/
1236
+	if (fl->type==SIP_REQUEST){
1237
+		tmp=eat_token_end(third,third+len-offset);
1238
+		offset+=tmp-third;
1239
+		if ((tmp==third)||(tmp>=end)){
1240
+			goto error;
1241
+		}
1242
+		if (! is_empty_end(tmp, tmp+len-offset)){
1243
+			goto error;
1244
+		}
1245
+	}else{
1246
+		tmp=eat_token2_end(third,third+len-offset,'\r'); /* find end of line 
1247
+												  ('\n' or '\r') */
1248
+		if (tmp>=end){ /* no crlf in packet => invalid */
1249
+			goto error;
1250
+		}
1251
+		offset+=tmp-third;
1252
+	}
1253
+	nl=eat_line(tmp,len-offset);
1254
+	if (nl>=end){ /* no crlf in packet or only 1 line > invalid */
1255
+		goto error;
1256
+	}
1257
+	*tmp=0;
1258
+	fl->u.request.version.s=third;
1259
+	fl->u.request.version.len=tmp-third;
1260
+
1261
+	return nl;
1262
+
1263
+error:
1264
+	LOG(L_INFO, "ERROR:parse_first_line: bad %s first line\n",
1265
+		(fl->type==SIP_REPLY)?"reply(status)":"request");
1266
+
1267
+	LOG(L_INFO, "ERROR: at line 0 char %d: \n", offset );
1268
+	prn=pkg_malloc( offset );
1269
+	if (prn) {
1270
+		for (t=0; t<offset; t++)
1271
+			if (*(buffer+t)) *(prn+t)=*(buffer+t);
1272
+			else *(prn+t)='�';
1273
+		LOG(L_INFO, "ERROR: parsed so far: %.*s\n", offset, prn );
1274
+		pkg_free( prn );
1275
+	};
1276
+error1:
1277
+	fl->type=SIP_INVALID;
1278
+	LOG(L_INFO, "ERROR:parse_first_line: bad message\n");
1279
+	/* skip  line */
1280
+	nl=eat_line(buffer,len);
1281
+	return nl;
1282
+}
1111 1283
new file mode 100644
... ...
@@ -0,0 +1,56 @@
0
+/*
1
+ * $Id$
2
+ */
3
+
4
+#ifndef PARSE_FLINE
5
+#define PARSE_FLINE
6
+
7
+#include "../str.h"
8
+
9
+/* Message is a request */
10
+#define SIP_REQUEST 1
11
+
12
+/* Message is a reply */
13
+#define SIP_REPLY   2
14
+
15
+/* Invalid message */
16
+#define SIP_INVALID 0
17
+
18
+
19
+#define SIP_VERSION "SIP/2.0"
20
+#define SIP_VERSION_LEN 7
21
+
22
+#define CANCEL "CANCEL"
23
+#define ACK    "ACK"
24
+#define INVITE "INVITE"
25
+
26
+#define INVITE_LEN 6
27
+#define CANCEL_LEN 6
28
+#define ACK_LEN 3
29
+#define BYE_LEN 3
30
+
31
+struct msg_start {
32
+	int type;                         /* Type of the Message - Request/Response */
33
+	union {
34
+		struct {
35
+			str method;       /* Method string */
36
+			str uri;          /* Request URI */
37
+			str version;      /* SIP version */
38
+			int method_value;
39
+		} request;
40
+		struct {
41
+			str version;      /* SIP version */
42
+			str status;       /* Reply status */
43
+			str reason;       /* Reply reason phrase */
44
+			unsigned int /* statusclass,*/ statuscode;
45
+		} reply;
46
+	}u;
47
+};
48
+
49
+
50
+char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl);
51
+
52
+char* parse_fline(char* buffer, char* end, struct msg_start* fl);
53
+
54
+
55
+#endif
0 56
new file mode 100644
... ...
@@ -0,0 +1,13 @@
0
+/*
1
+ * $Id$
2
+ */
3
+
4
+#ifndef PARSE_HNAME_H
5
+#define PARSE_HNAME_H
6
+
7
+#include "hf.h"
8
+
9
+/* returns end or pointer to next elem*/
10
+char* parse_hname1(char* p, char* end, struct hdr_field* hdr);
11
+
12
+#endif
... ...
@@ -14,6 +14,7 @@
14 14
 #include "msg_parser.h"
15 15
 #include "../strs.h"
16 16
 #include "../dprint.h"
17
+#include "../ut.h"  /* q_memchr */
17 18
 
18 19
 /*
19 20
  * Size of hash table, this is magic value
... ...
@@ -66,26 +67,11 @@ static struct ht_entry *hash_table;
66 66
 /*
67 67
  * Declarations
68 68
  */
69
-static inline char* q_memchr    (char* p, int c, unsigned int size);
70 69
 static inline char* skip_ws     (char* p, unsigned int size);
71 70
 void         init_htable (void);
72 71
 static void         set_entry   (unsigned int key, unsigned int val);
73 72
 static inline int   unify       (int key);
74 73
 
75
-/*
76
- * Fast replacement of standard memchr function
77
- */
78
-static inline char* q_memchr(char* p, int c, unsigned int size)
79
-{
80
-	char* end;
81
-
82
-	end=p+size;
83
-	for(;p<end;p++){
84
-		if (*p==(unsigned char)c) return p;
85
-	}
86
-	return 0;
87
-}
88