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 @@
0
+#ifndef CASE_SIP_H
1
+#define CASE_SIP_H
2
+
3
+#define atch_CASE                            \
4
+        switch(LOWER_DWORD(val)) {          \
5
+        case _atch_:                        \
6
+		DBG("end of SIP-If-Match\n"); \
7
+                hdr->type = HDR_SIPIFMATCH; \
8
+                p += 4;                     \
9
+                goto dc_end;                \
10
+        }
11
+
12
+
13
+#define ifm_CASE				\
14
+	switch(LOWER_DWORD(val)) {		\
15
+	case _ifm_:				\
16
+		DBG("middle of SIP-If-Match: yet=0x%04x\n",LOWER_DWORD(val)); \
17
+		p += 4;				\
18
+		val = READ(p);			\
19
+		atch_CASE;			\
20
+		goto other;			\
21
+	}
22
+		
23
+#define sip_CASE          \
24
+	DBG("beginning of SIP-If-Match: yet=0x%04x\n",LOWER_DWORD(val)); \
25
+        p += 4;           \
26
+        val = READ(p);    \
27
+        ifm_CASE;         \
28
+        goto other;
29
+
30
+#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 118
 			break;
119 119
 
120 120
 		case HDR_ALLOW:
121
+			free_allow((unsigned int **)(&(hf->parsed)));
121 122
 			break;
122 123
 
123 124
 		case HDR_EVENT:
... ...
@@ -158,6 +161,10 @@ void clean_hdr_field(struct hdr_field* hf)
158 158
 			free_to(hf->parsed);
159 159
 			break;
160 160
 
161
+		case HDR_SIPIFMATCH:
162
+			free_sipifmatch((str**)(&(hf->parsed)));
163
+			break;
164
+
161 165
 		default:
162 166
 			LOG(L_CRIT, "BUG: clean_hdr_field: unknown header type %d\n",
163 167
 			    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 364
 				msg->parsed_flag|=HDR_ALLOW;
365 365
 				break;
366 366
 			case HDR_EVENT:
367
-				if (msg->allow==0) msg->event = hf;
367
+				if (msg->event==0) msg->event = hf;
368 368
 				msg->parsed_flag|=HDR_EVENT;
369 369
 				break;
370 370
 		        case HDR_ACCEPT:
... ...
@@ -425,6 +426,12 @@ int parse_headers(struct sip_msg* msg, int flags, int next)
425 425
 					DBG("parse_headers: this is the second via\n");
426 426
 				}
427 427
 				break;
428
+			case HDR_SIPIFMATCH:
429
+				if (msg->sipifmatch==0)
430
+					msg->sipifmatch=hf;
431
+
432
+				msg->parsed_flag|=HDR_SIPIFMATCH;
433
+				break;
428 434
 			default:
429 435
 				LOG(L_CRIT, "BUG: parse_headers: unknown header type %d\n",
430 436
 							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 @@
0
+#include <string.h>
1
+
2
+#include "parse_sipifmatch.h"
3
+#include "../dprint.h"
4
+#include "parse_def.h"
5
+#include "../mem/mem.h"
6
+#include "../trim.h"
7
+
8
+static inline char* skip_token(char* _b, int _l)
9
+{
10
+        int i = 0;
11
+
12
+        for(i = 0; i < _l; i++) {
13
+                switch(_b[i]) {
14
+                case ' ':
15
+                case '\r':
16
+                case '\n':
17
+                case '\t':
18
+                case ';':
19
+                        return _b + i;
20
+                }
21
+        }
22
+
23
+        return _b + _l;
24
+}
25
+
26
+
27
+int
28
+etag_parser(char *_s, int _l, str *_e)
29
+{
30
+        char* end;
31
+
32
+        _e->s = _s;
33
+        _e->len = _l;
34
+
35
+        trim_leading(_e);
36
+
37
+        if (_e->len == 0) {
38
+                LOG(L_ERR, "etag_parser(): Empty body\n");
39
+                return -1;
40
+        }
41
+
42
+        end = skip_token(_e->s, _e->len);
43
+        _e->len = end - _e->s;
44
+
45
+	return 0;
46
+}
47
+
48
+
49
+int
50
+parse_sipifmatch(struct hdr_field* _h)
51
+{
52
+	str *e;
53
+
54
+	DBG("parse_sipifmatch() called\n");
55
+
56
+        if (_h->parsed != 0) {
57
+                return 0;
58
+        }
59
+
60
+        e = (str*)pkg_malloc(sizeof(str));
61
+        if (e == 0) {
62
+                LOG(L_ERR, "parse_ifsipmatch(): No memory left\n");
63
+                return -1;
64
+        }
65
+
66
+        memset(e, 0, sizeof(str));
67
+
68
+        if (etag_parser(_h->body.s, _h->body.len, e) < 0) {
69
+                LOG(L_ERR, "parse_sipifmatch(): Error in tag_parser\n");
70
+                pkg_free(e);
71
+                return -2;
72
+        }
73
+
74
+        _h->parsed = (void*)e;
75
+        return 0;
76
+}
77
+
78
+
79
+void free_sipifmatch(str** _e)
80
+{
81
+	if (*_e)
82
+		pkg_free(*_e);
83
+	*_e = 0;
84
+}
0 85
new file mode 100644
... ...
@@ -0,0 +1,24 @@
0
+#ifndef PARSE_SIPIFMATCH_H
1
+#define PARSE_SIPIFMATCH_H
2
+
3
+#include "../str.h"
4
+#include "hf.h"
5
+
6
+typedef struct etag {
7
+	str text;       /* Original string representation */
8
+} etag_t;
9
+
10
+
11
+/*
12
+ * Parse Sipifmatch HF body
13
+ */
14
+int parse_sipifmatch(struct hdr_field* _h);
15
+
16
+
17
+/*
18
+ * Release memory
19
+ */
20
+void free_sipifmatch(str** _e);
21
+
22
+
23
+#endif /* PARSE_SIPIFMATCH_H */