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 */ |