Browse code

- added another first line parser (test only) - default= use new malloc - removed some debugging options

Andrei Pelinescu-Onciul authored on 23/11/2001 18:06:20
Showing 5 changed files
... ...
@@ -28,7 +28,7 @@ NAME=ser
28 28
 # DEBUG compiles in some extra debugging code
29 29
 # OLD_PARSER uses the old and stable parser (from ser 8.3.2)
30 30
 # DNS_IP_HACK faster ip address resolver for ip strings (e.g "127.0.0.1")
31
-DEFS=-DNOCR -DMACROEATER -DDNS_IP_HACK -DPKG_MALLOC#-DSTATS -DNO_DEBUG 
31
+DEFS=-DNOCR -DMACROEATER -DDNS_IP_HACK -DPKG_MALLOC -DNO_DEBUG#-DSTATS -DNO_DEBUG 
32 32
 #-DNO_LOG
33 33
 
34 34
 PROFILE=  # -pg #set this if you want profiling
... ...
@@ -21,8 +21,6 @@
21 21
 
22 22
 
23 23
 
24
-#define DEBUG
25
-
26 24
 
27 25
 
28 26
 /* parses the first line, returns pointer to  next line  & fills fl;
... ...
@@ -789,6 +787,9 @@ int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
789 789
 	offset=tmp-buf;
790 790
 	fl=&(msg->first_line);
791 791
 	rest=parse_first_line(tmp, len-offset, fl);
792
+#if 0
793
+	rest=parse_fline(tmp, buf+len, fl);
794
+#endif
792 795
 	offset+=rest-tmp;
793 796
 	tmp=rest;
794 797
 	switch(fl->type){
... ...
@@ -154,7 +154,7 @@ struct sip_uri{
154 154
 };
155 155
 
156 156
 
157
-
157
+char* parse_fline(char* buffer, char* end, struct msg_start* fl);
158 158
 char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl);
159 159
 #ifdef OLD_PARSER 
160 160
 char* get_hdr_field(char *buffer, unsigned int len, struct hdr_field*  hdr_f);
161 161
new file mode 100644
... ...
@@ -0,0 +1,1134 @@
0
+/*
1
+ * $Id$
2
+ * 
3
+ * sip first line parsing automaton
4
+ * 
5
+ */
6
+
7
+
8
+
9
+#include "dprint.h"
10
+#include "msg_parser.h"
11
+
12
+
13
+/* grammar:
14
+	request  =  method SP uri SP version CRLF
15
+	response =  version SP status  SP reason  CRLF
16
+	(version = "SIP/2.0")
17
+*/
18
+
19
+/*known methods: INVITE, ACK, CANCEL, BYE*/
20
+
21
+enum{ START,
22
+		INVITE1, INVITE2, INVITE3, INVITE4, INVITE5,
23
+		ACK1,    ACK2,
24
+		CANCEL1, CANCEL2, CANCEL3, CANCEL4, CANCEL5,
25
+		BYE1, BYE2,
26
+		SIP1, SIP2, SIP3, SIP4, SIP5, SIP6,
27
+		FIN_INVITE=100, FIN_ACK, FIN_CANCEL, FIN_BYE, FIN_SIP,
28
+		P_METHOD=200, L_URI, P_URI, L_VER, 
29
+		VER1, VER2, VER3, VER4, VER5, VER6, FIN_VER,
30
+		L_STATUS, P_STATUS, L_REASON, P_REASON,
31
+		L_LF, F_CR, F_LF
32
+};
33
+
34
+
35
+
36
+char* parse_fline(char* buffer, char* end, struct msg_start* fl)
37
+{
38
+	char* tmp;
39
+	register int state;
40
+	unsigned short stat;
41
+
42
+	stat=0;
43
+	fl->type=SIP_REQUEST;
44
+	state=START;
45
+	for(tmp=buffer;tmp<end;tmp++){
46
+		switch(*tmp){
47
+			case ' ':
48
+			case '\t':
49
+				switch(state){
50
+					case START: /*allow space at the beginnig, althoug not
51
+								  legal*/
52
+						break;
53
+					case L_URI:
54
+					case L_VER:
55
+					case L_STATUS:
56
+					case L_REASON:
57
+					case L_LF:
58
+						 /*eat  space*/
59
+						break;
60
+					case FIN_INVITE:
61
+						*tmp=0;
62
+						fl->u.request.method.len=tmp-fl->u.request.method.s;
63
+						fl->u.request.method_value=METHOD_INVITE;
64
+						state=L_URI;
65
+						break;
66
+					case FIN_ACK:
67
+						*tmp=0;
68
+						fl->u.request.method.len=tmp-fl->u.request.method.s;
69
+						fl->u.request.method_value=METHOD_ACK;
70
+						state=L_URI;
71
+						break;
72
+					case FIN_CANCEL:
73
+						*tmp=0;
74
+						fl->u.request.method.len=tmp-fl->u.request.method.s;
75
+						fl->u.request.method_value=METHOD_CANCEL;
76
+						state=L_URI;
77
+						break;
78
+					case FIN_BYE:
79
+						*tmp=0;
80
+						fl->u.request.method.len=tmp-fl->u.request.method.s;
81
+						fl->u.request.method_value=METHOD_BYE;
82
+						state=L_URI;
83
+						break;
84
+					case FIN_SIP:
85
+						*tmp=0;
86
+						fl->u.reply.version.len=tmp-fl->u.reply.version.s;
87
+						state=L_STATUS;
88
+						fl->type=SIP_REPLY;
89
+						break;
90
+					case P_URI:
91
+						*tmp=0;
92
+						fl->u.request.uri.len=tmp-fl->u.request.uri.s;
93
+						state=L_VER;
94
+						break;
95
+					case FIN_VER:
96
+						*tmp=0;
97
+						fl->u.request.version.len=tmp-fl->u.request.version.s;
98
+						state=L_LF;
99
+						break;
100
+					case P_STATUS:
101
+						*tmp=0;
102
+						fl->u.reply.status.len=tmp-fl->u.reply.status.s;
103
+						state=L_REASON;
104
+						break;
105
+					case P_REASON:
106
+					 /*	*tmp=0;
107
+						fl->u.reply.reason.len=tmp-fl->u.reply.reason.s;
108
+						*/
109
+						break;
110
+					case VER1:
111
+					case VER2:
112
+					case VER3:
113
+					case VER4:
114
+					case VER5:
115
+					case VER6:
116
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
117
+								" in request\n");
118
+						goto error;
119
+					case P_METHOD:
120
+					default:
121
+						*tmp=0;
122
+						fl->u.request.method.len=tmp-fl->u.request.method.s;
123
+						fl->u.request.method_value=METHOD_OTHER;
124
+						state=L_URI;
125
+				}
126
+				break;
127
+			case 's':
128
+			case 'S':
129
+				switch(state){
130
+					case START:
131
+						state=SIP1;
132
+						fl->u.reply.version.s=tmp;
133
+						break;
134
+					case P_URI:
135
+					case P_REASON:
136
+					case P_METHOD:
137
+						break;
138
+					case L_REASON:
139
+						fl->u.reply.reason.s=tmp;
140
+						state=P_REASON;
141
+						break;
142
+					case P_STATUS:
143
+					case L_STATUS:
144
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
145
+								"character <%c> in request status\n", *tmp);
146
+						goto error;
147
+					case L_LF:
148
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
149
+								"character <%c> in request\n", *tmp);
150
+						goto error;
151
+					case L_URI:
152
+						fl->u.request.uri.s=tmp;
153
+						state=P_URI;
154
+						break;
155
+					case L_VER:
156
+						fl->u.request.version.s=tmp;
157
+						state=VER1;
158
+						break;
159
+					case VER1:
160
+					case VER2:
161
+					case VER3:
162
+					case VER4:
163
+					case VER5:
164
+					case VER6:
165
+					case FIN_VER:
166
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
167
+								" in request\n");
168
+						goto error;
169
+					default:
170
+						state=P_METHOD;
171
+				}
172
+				break;
173
+					
174
+			case 'i':
175
+			case 'I':
176
+				switch(state){
177
+					case START:
178
+						state=INVITE1;
179
+						fl->u.request.method.s=tmp;
180
+						break;
181
+					case INVITE3:
182
+						state=INVITE4;
183
+						break;
184
+					case SIP1:
185
+						state=SIP2;
186
+						break;
187
+					case P_URI:
188
+					case P_REASON:
189
+					case P_METHOD:
190
+						break;
191
+					case L_REASON:
192
+						fl->u.reply.reason.s=tmp;
193
+						state=P_REASON;
194
+						break;
195
+					case P_STATUS:
196
+					case L_STATUS:
197
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
198
+								"character <%c> in request status\n", *tmp);
199
+						goto error;
200
+					case L_LF:
201
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
202
+								"character <%c> in request\n", *tmp);
203
+						goto error;
204
+					case L_URI:
205
+						fl->u.request.uri.s=tmp;
206
+						state=P_URI;
207
+						break;
208
+					case VER1:
209
+						state=VER2;
210
+						break;
211
+					case L_VER:
212
+					case VER2:
213
+					case VER3:
214
+					case VER4:
215
+					case VER5:
216
+					case VER6:
217
+					case FIN_VER:
218
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
219
+								" in request\n");
220
+						goto error;
221
+					default:
222
+						state=P_METHOD;
223
+				}
224
+				break;
225
+				
226
+			case 'p':
227
+			case 'P':
228
+				switch(state){
229
+					case START:
230
+						state=P_METHOD;
231
+						fl->u.request.method.s=tmp;
232
+						break;
233
+					case SIP2:
234
+						state=SIP3;
235
+						break;
236
+					case P_URI:
237
+					case P_REASON:
238
+					case P_METHOD:
239
+						break;
240
+					case L_REASON:
241
+						fl->u.reply.reason.s=tmp;
242
+						state=P_REASON;
243
+						break;
244
+					case P_STATUS:
245
+					case L_STATUS:
246
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
247
+								"character <%c> in request status\n", *tmp);
248
+						goto error;
249
+					case L_LF:
250
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
251
+								"character <%c> in request\n", *tmp);
252
+						goto error;
253
+					case L_URI:
254
+						fl->u.request.uri.s=tmp;
255
+						state=P_URI;
256
+						break;
257
+					case VER2:
258
+						state=VER3;
259
+						break;
260
+					case L_VER:
261
+					case VER1:
262
+					case VER3:
263
+					case VER4:
264
+					case VER5:
265
+					case VER6:
266
+					case FIN_VER:
267
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
268
+								" in request\n");
269
+						goto error;
270
+					default:
271
+						state=P_METHOD;
272
+				}
273
+				break;
274
+
275
+			
276
+			case '/':
277
+				switch(state){
278
+					case START:
279
+						state=P_METHOD;
280
+						fl->u.request.method.s=tmp;
281
+						break;
282
+					case SIP3:
283
+						state=SIP4;
284
+						break;
285
+					case P_URI:
286
+					case P_REASON:
287
+					case P_METHOD:
288
+						break;
289
+					case L_REASON:
290
+						fl->u.reply.reason.s=tmp;
291
+						state=P_REASON;
292
+						break;
293
+					case P_STATUS:
294
+					case L_STATUS:
295
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
296
+								"character <%c> in request status\n", *tmp);
297
+						goto error;
298
+					case L_LF:
299
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
300
+								"character <%c> in request\n", *tmp);
301
+						goto error;
302
+					case L_URI:
303
+						fl->u.request.uri.s=tmp;
304
+						state=P_URI;
305
+						break;
306
+					case VER3:
307
+						state=VER4;
308
+						break;
309
+					case L_VER:
310
+					case VER1:
311
+					case VER2:
312
+					case VER4:
313
+					case VER5:
314
+					case VER6:
315
+					case FIN_VER:
316
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
317
+								" in request\n");
318
+						goto error;
319
+					default:
320
+						state=P_METHOD;
321
+				}
322
+				break;
323
+			
324
+			case '2':
325
+				switch(state){
326
+					case START:
327
+						state=P_METHOD;
328
+						fl->u.request.method.s=tmp;
329
+						break;
330
+					case SIP4:
331
+						state=SIP5;
332
+						break;
333
+					case P_URI:
334
+					case P_REASON:
335
+					case P_METHOD:
336
+						break;
337
+					case L_REASON:
338
+						fl->u.reply.reason.s=tmp;
339
+						state=P_REASON;
340
+						break;
341
+					case P_STATUS:
342
+						stat=stat*10+*tmp-'0';
343
+						break;
344
+					case L_STATUS:
345
+						stat=*tmp-'0';
346
+						fl->u.reply.status.s=tmp;
347
+						break;
348
+					case L_LF:
349
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
350
+								"character <%c> in request\n", *tmp);
351
+						goto error;
352
+					case L_URI:
353
+						fl->u.request.uri.s=tmp;
354
+						state=P_URI;
355
+						break;
356
+					case VER4:
357
+						state=VER5;
358
+						break;
359
+					case L_VER:
360
+					case VER1:
361
+					case VER2:
362
+					case VER3:
363
+					case VER5:
364
+					case VER6:
365
+					case FIN_VER:
366
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
367
+								" in request\n");
368
+						goto error;
369
+					default:
370
+						state=P_METHOD;
371
+				}
372
+				break;
373
+			
374
+			case '.':
375
+				switch(state){
376
+					case START:
377
+						state=P_METHOD;
378
+						fl->u.request.method.s=tmp;
379
+						break;
380
+					case SIP5:
381
+						state=SIP6;
382
+						break;
383
+					case P_URI:
384
+					case P_REASON:
385
+					case P_METHOD:
386
+						break;
387
+					case L_REASON:
388
+						fl->u.reply.reason.s=tmp;
389
+						state=P_REASON;
390
+						break;
391
+					case P_STATUS:
392
+					case L_STATUS:
393
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
394
+								"character <%c> in request status\n", *tmp);
395
+						goto error;
396
+					case L_LF:
397
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
398
+								"character <%c> in request\n", *tmp);
399
+						goto error;
400
+					case L_URI:
401
+						fl->u.request.uri.s=tmp;
402
+						state=P_URI;
403
+						break;
404
+					case VER5:
405
+						state=VER6;
406
+						break;
407
+					case L_VER:
408
+					case VER1:
409
+					case VER2:
410
+					case VER3:
411
+					case VER4:
412
+					case VER6:
413
+					case FIN_VER:
414
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
415
+								" in request\n");
416
+						goto error;
417
+					default:
418
+						state=P_METHOD;
419
+				}
420
+				break;
421
+			
422
+			case '0':
423
+				switch(state){
424
+					case START:
425
+						state=P_METHOD;
426
+						fl->u.request.method.s=tmp;
427
+						break;
428
+					case SIP6:
429
+						state=FIN_SIP;
430
+						break;
431
+					case P_URI:
432
+					case P_REASON:
433
+					case P_METHOD:
434
+						break;
435
+					case L_REASON:
436
+						fl->u.reply.reason.s=tmp;
437
+						state=P_REASON;
438
+						break;
439
+					case P_STATUS:
440
+						stat=stat*10;
441
+						break;
442
+					case L_STATUS:
443
+						stat=0;
444
+						fl->u.reply.status.s=tmp;
445
+						break;
446
+					case L_LF:
447
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
448
+								"character <%c> in request\n", *tmp);
449
+						goto error;
450
+					case L_URI:
451
+						fl->u.request.uri.s=tmp;
452
+						state=P_URI;
453
+						break;
454
+					case VER6:
455
+						state=FIN_VER;
456
+						break;
457
+					case L_VER:
458
+					case VER1:
459
+					case VER2:
460
+					case VER3:
461
+					case VER4:
462
+					case VER5:
463
+					case FIN_VER:
464
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
465
+								" in request\n");
466
+						goto error;
467
+					default:
468
+						state=P_METHOD;
469
+				}
470
+				break;
471
+			
472
+			case 'n':
473
+			case 'N':
474
+				switch(state){
475
+					case START:
476
+						state=P_METHOD;
477
+						fl->u.request.method.s=tmp;
478
+						break;
479
+					case INVITE1:
480
+						state=INVITE2;
481
+						break;
482
+					case CANCEL2:
483
+						state=CANCEL3;
484
+						break;
485
+					case P_URI:
486
+					case P_REASON:
487
+					case P_METHOD:
488
+						break;
489
+					case L_REASON:
490
+						fl->u.reply.reason.s=tmp;
491
+						state=P_REASON;
492
+						break;
493
+					case P_STATUS:
494
+					case L_STATUS:
495
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
496
+								"character <%c> in request status\n", *tmp);
497
+						goto error;
498
+					case L_LF:
499
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
500
+								"character <%c> in request\n", *tmp);
501
+						goto error;
502
+					case L_URI:
503
+						fl->u.request.uri.s=tmp;
504
+						state=P_URI;
505
+						break;
506
+						state=VER3;
507
+						break;
508
+					case L_VER:
509
+					case VER1:
510
+					case VER2:
511
+					case VER3:
512
+					case VER4:
513
+					case VER5:
514
+					case VER6:
515
+					case FIN_VER:
516
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
517
+								" in request\n");
518
+						goto error;
519
+					default:
520
+						state=P_METHOD;
521
+				}
522
+				break;
523
+
524
+			case 'v':
525
+			case 'V':
526
+				switch(state){
527
+					case START:
528
+						state=P_METHOD;
529
+						fl->u.request.method.s=tmp;
530
+						break;
531
+					case INVITE2:
532
+						state=INVITE3;
533
+						break;
534
+					case P_URI:
535
+					case P_REASON:
536
+					case P_METHOD:
537
+						break;
538
+					case L_REASON:
539
+						fl->u.reply.reason.s=tmp;
540
+						state=P_REASON;
541
+						break;
542
+					case P_STATUS:
543
+					case L_STATUS:
544
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
545
+								"character <%c> in request status\n", *tmp);
546
+						goto error;
547
+					case L_LF:
548
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
549
+								"character <%c> in request\n", *tmp);
550
+						goto error;
551
+					case L_URI:
552
+						fl->u.request.uri.s=tmp;
553
+						state=P_URI;
554
+						break;
555
+						state=VER3;
556
+						break;
557
+					case L_VER:
558
+					case VER1:
559
+					case VER2:
560
+					case VER3:
561
+					case VER4:
562
+					case VER5:
563
+					case VER6:
564
+					case FIN_VER:
565
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
566
+								" in request\n");
567
+						goto error;
568
+					default:
569
+						state=P_METHOD;
570
+				}
571
+				break;
572
+
573
+			case 't':
574
+			case 'T':
575
+				switch(state){
576
+					case START:
577
+						state=P_METHOD;
578
+						fl->u.request.method.s=tmp;
579
+						break;
580
+					case INVITE4:
581
+						state=INVITE5;
582
+						break;
583
+					case P_URI:
584
+					case P_REASON:
585
+					case P_METHOD:
586
+						break;
587
+					case L_REASON:
588
+						fl->u.reply.reason.s=tmp;
589
+						state=P_REASON;
590
+						break;
591
+					case P_STATUS:
592
+					case L_STATUS:
593
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
594
+								"character <%c> in request status\n", *tmp);
595
+						goto error;
596
+					case L_LF:
597
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
598
+								"character <%c> in request\n", *tmp);
599
+						goto error;
600
+					case L_URI:
601
+						fl->u.request.uri.s=tmp;
602
+						state=P_URI;
603
+						break;
604
+						state=VER3;
605
+						break;
606
+					case L_VER:
607
+					case VER1:
608
+					case VER2:
609
+					case VER3:
610
+					case VER4:
611
+					case VER5:
612
+					case VER6:
613
+					case FIN_VER:
614
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
615
+								" in request\n");
616
+						goto error;
617
+					default:
618
+						state=P_METHOD;
619
+				}
620
+				break;
621
+
622
+			case 'e':
623
+			case 'E':
624
+				switch(state){
625
+					case START:
626
+						state=P_METHOD;
627
+						fl->u.request.method.s=tmp;
628
+						break;
629
+					case INVITE5:
630
+						state=FIN_INVITE;
631
+						break;
632
+					case CANCEL4:
633
+						state=CANCEL5;
634
+						break;
635
+					case BYE2:
636
+						state=FIN_BYE;
637
+						break;
638
+					case P_URI:
639
+					case P_REASON:
640
+					case P_METHOD:
641
+						break;
642
+					case L_REASON:
643
+						fl->u.reply.reason.s=tmp;
644
+						state=P_REASON;
645
+						break;
646
+					case P_STATUS:
647
+					case L_STATUS:
648
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
649
+								"character <%c> in request status\n", *tmp);
650
+						goto error;
651
+					case L_LF:
652
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
653
+								"character <%c> in request\n", *tmp);
654
+						goto error;
655
+					case L_URI:
656
+						fl->u.request.uri.s=tmp;
657
+						state=P_URI;
658
+						break;
659
+						state=VER3;
660
+						break;
661
+					case L_VER:
662
+					case VER1:
663
+					case VER2:
664
+					case VER3:
665
+					case VER4:
666
+					case VER5:
667
+					case VER6:
668
+					case FIN_VER:
669
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
670
+								" in request\n");
671
+						goto error;
672
+					default:
673
+						state=P_METHOD;
674
+				}
675
+				break;
676
+
677
+			case 'a':
678
+			case 'A':
679
+				switch(state){
680
+					case START:
681
+						state=ACK1;
682
+						fl->u.request.method.s=tmp;
683
+						break;
684
+					case CANCEL1:
685
+						state=CANCEL2;
686
+						break;
687
+					case BYE2:
688
+						state=FIN_BYE;
689
+						break;
690
+					case P_URI:
691
+					case P_REASON:
692
+					case P_METHOD:
693
+						break;
694
+					case L_REASON:
695
+						fl->u.reply.reason.s=tmp;
696
+						state=P_REASON;
697
+						break;
698
+					case P_STATUS:
699
+					case L_STATUS:
700
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
701
+								"character <%c> in request status\n", *tmp);
702
+						goto error;
703
+					case L_LF:
704
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
705
+								"character <%c> in request\n", *tmp);
706
+						goto error;
707
+					case L_URI:
708
+						fl->u.request.uri.s=tmp;
709
+						state=P_URI;
710
+						break;
711
+						state=VER3;
712
+						break;
713
+					case L_VER:
714
+					case VER1:
715
+					case VER2:
716
+					case VER3:
717
+					case VER4:
718
+					case VER5:
719
+					case VER6:
720
+					case FIN_VER:
721
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
722
+								" in request\n");
723
+						goto error;
724
+					default:
725
+						state=P_METHOD;
726
+				}
727
+				break;
728
+
729
+			case 'c':
730
+			case 'C':
731
+				switch(state){
732
+					case START:
733
+						state=CANCEL1;
734
+						fl->u.request.method.s=tmp;
735
+						break;
736
+					case CANCEL3:
737
+						state=CANCEL4;
738
+						break;
739
+					case ACK1:
740
+						state=ACK2;
741
+						break;
742
+					case P_URI:
743
+					case P_REASON:
744
+					case P_METHOD:
745
+						break;
746
+					case L_REASON:
747
+						fl->u.reply.reason.s=tmp;
748
+						state=P_REASON;
749
+						break;
750
+					case P_STATUS:
751
+					case L_STATUS:
752
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
753
+								"character <%c> in request status\n", *tmp);
754
+						goto error;
755
+					case L_LF:
756
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
757
+								"character <%c> in request\n", *tmp);
758
+						goto error;
759
+					case L_URI:
760
+						fl->u.request.uri.s=tmp;
761
+						state=P_URI;
762
+						break;
763
+						state=VER3;
764
+						break;
765
+					case L_VER:
766
+					case VER1:
767
+					case VER2:
768
+					case VER3:
769
+					case VER4:
770
+					case VER5:
771
+					case VER6:
772
+					case FIN_VER:
773
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
774
+								" in request\n");
775
+						goto error;
776
+					default:
777
+						state=P_METHOD;
778
+				}
779
+				break;
780
+
781
+			case 'k':
782
+			case 'K':
783
+				switch(state){
784
+					case START:
785
+						state=P_METHOD;
786
+						fl->u.request.method.s=tmp;
787
+						break;
788
+					case ACK2:
789
+						state=FIN_ACK;
790
+						break;
791
+					case P_URI:
792
+					case P_REASON:
793
+					case P_METHOD:
794
+						break;
795
+					case L_REASON:
796
+						fl->u.reply.reason.s=tmp;
797
+						state=P_REASON;
798
+						break;
799
+					case P_STATUS:
800
+					case L_STATUS:
801
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
802
+								"character <%c> in request status\n", *tmp);
803
+						goto error;
804
+					case L_LF:
805
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
806
+								"character <%c> in request\n", *tmp);
807
+						goto error;
808
+					case L_URI:
809
+						fl->u.request.uri.s=tmp;
810
+						state=P_URI;
811
+						break;
812
+						state=VER3;
813
+						break;
814
+					case L_VER:
815
+					case VER1:
816
+					case VER2:
817
+					case VER3:
818
+					case VER4:
819
+					case VER5:
820
+					case VER6:
821
+					case FIN_VER:
822
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
823
+								" in request\n");
824
+						goto error;
825
+					default:
826
+						state=P_METHOD;
827
+				}
828
+				break;
829
+
830
+			case 'l':
831
+			case 'L':
832
+				switch(state){
833
+					case START:
834
+						state=P_METHOD;
835
+						fl->u.request.method.s=tmp;
836
+						break;
837
+					case CANCEL5:
838
+						state=FIN_CANCEL;
839
+						break;
840
+					case P_URI:
841
+					case P_REASON:
842
+					case P_METHOD:
843
+						break;
844
+					case L_REASON:
845
+						fl->u.reply.reason.s=tmp;
846
+						state=P_REASON;
847
+						break;
848
+					case P_STATUS:
849
+					case L_STATUS:
850
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
851
+								"character <%c> in request status\n", *tmp);
852
+						goto error;
853
+					case L_LF:
854
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
855
+								"character <%c> in request\n", *tmp);
856
+						goto error;
857
+					case L_URI:
858
+						fl->u.request.uri.s=tmp;
859
+						state=P_URI;
860
+						break;
861
+						state=VER3;
862
+						break;
863
+					case L_VER:
864
+					case VER1:
865
+					case VER2:
866
+					case VER3:
867
+					case VER4:
868
+					case VER5:
869
+					case VER6:
870
+					case FIN_VER:
871
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
872
+								" in request\n");
873
+						goto error;
874
+					default:
875
+						state=P_METHOD;
876
+				}
877
+				break;
878
+
879
+			case 'b':
880
+			case 'B':
881
+				switch(state){
882
+					case START:
883
+						state=BYE1;
884
+						fl->u.request.method.s=tmp;
885
+						break;
886
+					case P_URI:
887
+					case P_REASON:
888
+					case P_METHOD:
889
+						break;
890
+					case L_REASON:
891
+						fl->u.reply.reason.s=tmp;
892
+						state=P_REASON;
893
+						break;
894
+					case P_STATUS:
895
+					case L_STATUS:
896
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
897
+								"character <%c> in request status\n", *tmp);
898
+						goto error;
899
+					case L_LF:
900
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
901
+								"character <%c> in request\n", *tmp);
902
+						goto error;
903
+					case L_URI:
904
+						fl->u.request.uri.s=tmp;
905
+						state=P_URI;
906
+						break;
907
+						state=VER3;
908
+						break;
909
+					case L_VER:
910
+					case VER1:
911
+					case VER2:
912
+					case VER3:
913
+					case VER4:
914
+					case VER5:
915
+					case VER6:
916
+					case FIN_VER:
917
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
918
+								" in request\n");
919
+						goto error;
920
+					default:
921
+						state=P_METHOD;
922
+				}
923
+				break;
924
+
925
+			case 'y':
926
+			case 'Y':
927
+				switch(state){
928
+					case START:
929
+						state=P_METHOD;
930
+						fl->u.request.method.s=tmp;
931
+						break;
932
+					case BYE1:
933
+						state=BYE2;
934
+						break;
935
+					case P_URI:
936
+					case P_REASON:
937
+					case P_METHOD:
938
+						break;
939
+					case L_REASON:
940
+						fl->u.reply.reason.s=tmp;
941
+						state=P_REASON;
942
+						break;
943
+					case P_STATUS:
944
+					case L_STATUS:
945
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
946
+								"character <%c> in request status\n", *tmp);
947
+						goto error;
948
+					case L_LF:
949
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
950
+								"character <%c> in request\n", *tmp);
951
+						goto error;
952
+					case L_URI:
953
+						fl->u.request.uri.s=tmp;
954
+						state=P_URI;
955
+						break;
956
+						state=VER3;
957
+						break;
958
+					case L_VER:
959
+					case VER1:
960
+					case VER2:
961
+					case VER3:
962
+					case VER4:
963
+					case VER5:
964
+					case VER6:
965
+					case FIN_VER:
966
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
967
+								" in request\n");
968
+						goto error;
969
+					default:
970
+						state=P_METHOD;
971
+				}
972
+				break;
973
+
974
+			case '\r':
975
+				switch(state){
976
+					case P_REASON:
977
+						*tmp=0;
978
+						fl->u.reply.reason.len=tmp-fl->u.reply.reason.s;
979
+						state=F_CR;
980
+						break;
981
+					case L_LF:
982
+						state=F_CR;
983
+						break;
984
+					case FIN_VER:
985
+						*tmp=0;
986
+						fl->u.request.version.len=tmp-fl->u.request.version.s;
987
+						state=F_CR;
988
+						break;
989
+					case L_REASON:
990
+						state=F_CR;
991
+						break;
992
+					default:
993
+						LOG(L_ERR, "ERROR: parse_first_line: invalid
994
+								message\n");
995
+						goto error;
996
+				}
997
+				break;
998
+
999
+			case '\n':
1000
+				switch(state){
1001
+					case P_REASON:
1002
+						*tmp=0;
1003
+						fl->u.reply.reason.len=tmp-fl->u.reply.reason.s;
1004
+						state=F_LF;
1005
+						goto skip;
1006
+					case FIN_VER:
1007
+						*tmp=0;
1008
+						fl->u.request.version.len=tmp-fl->u.request.version.s;
1009
+						state=F_LF;
1010
+						goto skip;
1011
+					case L_REASON:
1012
+					case L_LF:
1013
+					case F_CR:
1014
+						state=F_LF;
1015
+						goto skip;
1016
+					default:
1017
+						LOG(L_ERR, "ERROR: parse_first_line: invalid
1018
+								message\n");
1019
+						goto error;
1020
+				}
1021
+				break;
1022
+
1023
+			case '1':
1024
+			case '3':
1025
+			case '4':
1026
+			case '5':
1027
+			case '6':
1028
+			case '7':
1029
+			case '8':
1030
+			case '9':
1031
+				switch(state){
1032
+					case START:
1033
+						state=P_METHOD;
1034
+						fl->u.request.method.s=tmp;
1035
+						break;
1036
+					case P_URI:
1037
+					case P_REASON:
1038
+					case P_METHOD:
1039
+						break;
1040
+					case L_REASON:
1041
+						fl->u.reply.reason.s=tmp;
1042
+						state=P_REASON;
1043
+						break;
1044
+					case P_STATUS:
1045
+						stat=stat*10+*tmp-'0';
1046
+						break;
1047
+					case L_STATUS:
1048
+						stat=*tmp-'0';
1049
+						state=P_STATUS;
1050
+						fl->u.reply.status.s=tmp;
1051
+						break;
1052
+					case L_LF:
1053
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
1054
+								"character <%c> in request\n", *tmp);
1055
+						goto error;
1056
+					case L_URI:
1057
+						fl->u.request.uri.s=tmp;
1058
+						state=P_URI;
1059
+						break;
1060
+						state=VER3;
1061
+						break;
1062
+					case L_VER:
1063
+					case VER1:
1064
+					case VER2:
1065
+					case VER3:
1066
+					case VER4:
1067
+					case VER5:
1068
+					case VER6:
1069
+					case FIN_VER:
1070
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
1071
+								" in request\n");
1072
+						goto error;
1073
+					default:
1074
+						state=P_METHOD;
1075
+				}
1076
+						
1077
+			default:
1078
+				switch(state){
1079
+					case START:
1080
+						state=P_METHOD;
1081
+						fl->u.request.method.s=tmp;
1082
+						break;
1083
+					case P_URI:
1084
+					case P_REASON:
1085
+					case P_METHOD:
1086
+						break;
1087
+					case L_REASON:
1088
+						fl->u.reply.reason.s=tmp;
1089
+						state=P_REASON;
1090
+						break;
1091
+					case P_STATUS:
1092
+					case L_STATUS:
1093
+						LOG(L_ERR, "ERROR: parse_first_line: non-number "
1094
+								"character <%c> in request status\n", *tmp);
1095
+						goto error;
1096
+					case L_LF:
1097
+						LOG(L_ERR, "ERROR: parse_first_line: invalid "
1098
+								"character <%c> in request\n", *tmp);
1099
+						goto error;
1100
+					case L_URI:
1101
+						fl->u.request.uri.s=tmp;
1102
+						state=P_URI;
1103
+						break;
1104
+						state=VER3;
1105
+						break;
1106
+					case L_VER:
1107
+					case VER1:
1108
+					case VER2:
1109
+					case VER3:
1110
+					case VER4:
1111
+					case VER5:
1112
+					case VER6:
1113
+					case FIN_VER:
1114
+						LOG(L_ERR, "ERROR: parse_first_line: invalid version "
1115
+								" in request\n");
1116
+						goto error;
1117
+					default:
1118
+						state=P_METHOD;
1119
+				}
1120
+		}
1121
+	}
1122
+skip:
1123
+	if (fl->type==SIP_REPLY){
1124
+		fl->u.reply.statuscode=stat;
1125
+		fl->u.reply.statusclass=stat/100;
1126
+	}
1127
+	return tmp;
1128
+	
1129
+error:
1130
+	LOG(L_ERR, "ERROR: while parsing first line (state=%d)\n", state);
1131
+	fl->type=SIP_INVALID;
1132
+	return tmp;
1133
+}
... ...
@@ -10,7 +10,7 @@
10 10
 
11 11
 /* 
12 12
  * still TODO/test:
13
- *  - parse next via
13
+ *  x parse next via
14 14
  *  - return a list of header structs
15 15
  *  - return list of params
16 16
  */