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