Browse code

RFC3903 SIP-If-Match parsing from Gregory McGarry

Jamey Hicks authored on 03/12/2004 13:37:57
Showing 9 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,31 @@
1
+#ifndef CASE_SIP_H
2
+#define CASE_SIP_H
3
+
4
+#define atch_CASE                            \
5
+        switch(LOWER_DWORD(val)) {          \
6
+        case _atch_:                        \
7
+		DBG("end of SIP-If-Match\n"); \
8
+                hdr->type = HDR_SIPIFMATCH; \
9
+                p += 4;                     \
10
+                goto dc_end;                \
11
+        }
12
+
13
+
14
+#define ifm_CASE				\
15
+	switch(LOWER_DWORD(val)) {		\
16
+	case _ifm_:				\
17
+		DBG("middle of SIP-If-Match: yet=0x%04x\n",LOWER_DWORD(val)); \
18
+		p += 4;				\
19
+		val = READ(p);			\
20
+		atch_CASE;			\
21
+		goto other;			\
22
+	}
23
+		
24
+#define sip_CASE          \
25
+	DBG("beginning of SIP-If-Match: yet=0x%04x\n",LOWER_DWORD(val)); \
26
+        p += 4;           \
27
+        val = READ(p);    \
28
+        ifm_CASE;         \
29
+        goto other;
30
+
31
+#endif /* CASE_SIP_H */
... ...
@@ -45,6 +45,8 @@
45 45
 #include "parse_rr.h"
46 46
 #include "contact/parse_contact.h"
47 47
 #include "parse_disposition.h"
48
+#include "parse_allow.h"
49
+#include "parse_sipifmatch.h"
48 50
 #include "../ut.h"
49 51
 
50 52
 
... ...
@@ -118,6 +120,7 @@ void clean_hdr_field(struct hdr_field* hf)
118 120
 			break;
119 121
 
120 122
 		case HDR_ALLOW:
123
+			free_allow((unsigned int **)(&(hf->parsed)));
121 124
 			break;
122 125
 
123 126
 		case HDR_EVENT:
... ...
@@ -158,6 +161,10 @@ void clean_hdr_field(struct hdr_field* hf)
158 161
 			free_to(hf->parsed);
159 162
 			break;
160 163
 
164
+		case HDR_SIPIFMATCH:
165
+			free_sipifmatch((str**)(&(hf->parsed)));
166
+			break;
167
+
161 168
 		default:
162 169
 			LOG(L_CRIT, "BUG: clean_hdr_field: unknown header type %d\n",
163 170
 			    hf->type);
... ...
@@ -73,7 +73,8 @@
73 73
 #define HDR_CONTENTDISPOSITION (1 << 27)  /* Content-Disposition hdr field */
74 74
 #define HDR_DIVERSION          (1 << 28)  /* Diversion header field */
75 75
 #define HDR_RPID               (1 << 29)  /* Remote-Party-ID header field */
76
-#define HDR_OTHER              (1 << 30)  /* Some other header field */
76
+#define HDR_SIPIFMATCH         (1 << 30)  /* SIP-If-Match header field */
77
+#define HDR_OTHER              (1 << 31)  /* Some other header field */
77 78
 
78 79
 
79 80
 /* returns true if the header links allocated memory on parse field */
... ...
@@ -47,6 +47,9 @@
47 47
 #define _oriz_ 0x7a69726f   /* "oriz" */
48 48
 #define _atio_ 0x6f697461   /* "atio" */
49 49
 #define _call_ 0x6c6c6163   /* "call" */
50
+#define _sip_  0x2d706973   /* "sip-" */
51
+#define _ifm_  0x6d2d6669   /* "if-m" */
52
+#define _atch_ 0x68637461   /* "atch" */
50 53
 #define __id2_ 0x2064692d   /* "-id " */
51 54
 #define __id1_ 0x3a64692d   /* "-id:" */
52 55
 #define _cont_ 0x746e6f63   /* "cont" */
... ...
@@ -204,6 +204,7 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
204 204
 	        case HDR_ACCEPTDISPOSITION:
205 205
 	        case HDR_DIVERSION:
206 206
 	        case HDR_RPID:
207
+	        case HDR_SIPIFMATCH:
207 208
 		case HDR_OTHER:
208 209
 			/* just skip over it */
209 210
 			hdr->body.s=tmp;
... ...
@@ -364,7 +365,7 @@ int parse_headers(struct sip_msg* msg, int flags, int next)
364 365
 				msg->parsed_flag|=HDR_ALLOW;
365 366
 				break;
366 367
 			case HDR_EVENT:
367
-				if (msg->allow==0) msg->event = hf;
368
+				if (msg->event==0) msg->event = hf;
368 369
 				msg->parsed_flag|=HDR_EVENT;
369 370
 				break;
370 371
 		        case HDR_ACCEPT:
... ...
@@ -425,6 +426,12 @@ int parse_headers(struct sip_msg* msg, int flags, int next)
425 426
 					DBG("parse_headers: this is the second via\n");
426 427
 				}
427 428
 				break;
429
+			case HDR_SIPIFMATCH:
430
+				if (msg->sipifmatch==0)
431
+					msg->sipifmatch=hf;
432
+
433
+				msg->parsed_flag|=HDR_SIPIFMATCH;
434
+				break;
428 435
 			default:
429 436
 				LOG(L_CRIT, "BUG: parse_headers: unknown header type %d\n",
430 437
 							hf->type);
... ...
@@ -193,6 +193,7 @@ struct sip_msg {
193 193
 	struct hdr_field* accept_disposition;
194 194
 	struct hdr_field* diversion;
195 195
 	struct hdr_field* rpid;
196
+	struct hdr_sipifmatch* sipifmatch;
196 197
 
197 198
 	char* eoh;        /* pointer to the end of header (if found) or null */
198 199
 	char* unparsed;   /* here we stopped parsing*/
... ...
@@ -84,7 +84,7 @@ static inline char* skip_ws(char* p, unsigned int size)
84 84
 #include "case_supp.h"     /* Supported */
85 85
 #include "case_dive.h"     /* Diversion */
86 86
 #include "case_remo.h"     /* Remote-Party-ID */
87
-
87
+#include "case_sip.h"      /* SIP-If-Match */
88 88
 
89 89
 #define READ(val) \
90 90
 (*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
... ...
@@ -111,6 +111,7 @@ static inline char* skip_ws(char* p, unsigned int size)
111 111
         case _acce_: acce_CASE; \
112 112
         case _orga_: orga_CASE; \
113 113
         case _prio_: prio_CASE; \
114
+        case _sip_:  sip_CASE; \
114 115
         case _subj_: subj_CASE; \
115 116
         case _user_: user_CASE; \
116 117
         case _dive_: dive_CASE; \
117 118
new file mode 100644
... ...
@@ -0,0 +1,85 @@
1
+#include <string.h>
2
+
3
+#include "parse_sipifmatch.h"
4
+#include "../dprint.h"
5
+#include "parse_def.h"
6
+#include "../mem/mem.h"
7
+#include "../trim.h"
8
+
9
+static inline char* skip_token(char* _b, int _l)
10
+{
11
+        int i = 0;
12
+
13
+        for(i = 0; i < _l; i++) {
14
+                switch(_b[i]) {
15
+                case ' ':
16
+                case '\r':
17
+                case '\n':
18
+                case '\t':
19
+                case ';':
20
+                        return _b + i;
21
+                }
22
+        }
23
+
24
+        return _b + _l;
25
+}
26
+
27
+
28
+int
29
+etag_parser(char *_s, int _l, str *_e)
30
+{
31
+        char* end;
32
+
33
+        _e->s = _s;
34
+        _e->len = _l;
35
+
36
+        trim_leading(_e);
37
+
38
+        if (_e->len == 0) {
39
+                LOG(L_ERR, "etag_parser(): Empty body\n");
40
+                return -1;
41
+        }
42
+
43
+        end = skip_token(_e->s, _e->len);
44
+        _e->len = end - _e->s;
45
+
46
+	return 0;
47
+}
48
+
49
+
50
+int
51
+parse_sipifmatch(struct hdr_field* _h)
52
+{
53
+	str *e;
54
+
55
+	DBG("parse_sipifmatch() called\n");
56
+
57
+        if (_h->parsed != 0) {
58
+                return 0;
59
+        }
60
+
61
+        e = (str*)pkg_malloc(sizeof(str));
62
+        if (e == 0) {
63
+                LOG(L_ERR, "parse_ifsipmatch(): No memory left\n");
64
+                return -1;
65
+        }
66
+
67
+        memset(e, 0, sizeof(str));
68
+
69
+        if (etag_parser(_h->body.s, _h->body.len, e) < 0) {
70
+                LOG(L_ERR, "parse_sipifmatch(): Error in tag_parser\n");
71
+                pkg_free(e);
72
+                return -2;
73
+        }
74
+
75
+        _h->parsed = (void*)e;
76
+        return 0;
77
+}
78
+
79
+
80
+void free_sipifmatch(str** _e)
81
+{
82
+	if (*_e)
83
+		pkg_free(*_e);
84
+	*_e = 0;
85
+}
0 86
new file mode 100644
... ...
@@ -0,0 +1,24 @@
1
+#ifndef PARSE_SIPIFMATCH_H
2
+#define PARSE_SIPIFMATCH_H
3
+
4
+#include "../str.h"
5
+#include "hf.h"
6
+
7
+typedef struct etag {
8
+	str text;       /* Original string representation */
9
+} etag_t;
10
+
11
+
12
+/*
13
+ * Parse Sipifmatch HF body
14
+ */
15
+int parse_sipifmatch(struct hdr_field* _h);
16
+
17
+
18
+/*
19
+ * Release memory
20
+ */
21
+void free_sipifmatch(str** _e);
22
+
23
+
24
+#endif /* PARSE_SIPIFMATCH_H */