|
@@ -44,20 +44,20 @@
|
|
|
|
|
|
#define READ(val) \
|
|
#define READ(val) \
|
|
(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
|
|
(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
|
|
-#define advance(_ptr,_n,_str,_error) \
|
|
|
|
- do{\
|
|
|
|
- if ((_ptr)+(_n)>(_str).s+(_str).len)\
|
|
|
|
- goto _error;\
|
|
|
|
- (_ptr) = (_ptr) + (_n);\
|
|
|
|
- }while(0);
|
|
|
|
-#define one_of_16( _x , _t ) \
|
|
|
|
- (_x==_t[0]||_x==_t[15]||_x==_t[8]||_x==_t[2]||_x==_t[3]||_x==_t[4]\
|
|
|
|
- ||_x==_t[5]||_x==_t[6]||_x==_t[7]||_x==_t[1]||_x==_t[9]||_x==_t[10]\
|
|
|
|
- ||_x==_t[11]||_x==_t[12]||_x==_t[13]||_x==_t[14])
|
|
|
|
-#define one_of_8( _x , _t ) \
|
|
|
|
- (_x==_t[0]||_x==_t[7]||_x==_t[1]||_x==_t[2]||_x==_t[3]||_x==_t[4]\
|
|
|
|
- ||_x==_t[5]||_x==_t[6])
|
|
|
|
-
|
|
|
|
|
|
+#define advance(_ptr, _n, _str, _error) \
|
|
|
|
+ do { \
|
|
|
|
+ if((_ptr) + (_n) > (_str).s + (_str).len) \
|
|
|
|
+ goto _error; \
|
|
|
|
+ (_ptr) = (_ptr) + (_n); \
|
|
|
|
+ } while(0);
|
|
|
|
+#define one_of_16(_x, _t) \
|
|
|
|
+ (_x == _t[0] || _x == _t[15] || _x == _t[8] || _x == _t[2] || _x == _t[3] \
|
|
|
|
+ || _x == _t[4] || _x == _t[5] || _x == _t[6] || _x == _t[7] \
|
|
|
|
+ || _x == _t[1] || _x == _t[9] || _x == _t[10] || _x == _t[11] \
|
|
|
|
+ || _x == _t[12] || _x == _t[13] || _x == _t[14])
|
|
|
|
+#define one_of_8(_x, _t) \
|
|
|
|
+ (_x == _t[0] || _x == _t[7] || _x == _t[1] || _x == _t[2] || _x == _t[3] \
|
|
|
|
+ || _x == _t[4] || _x == _t[5] || _x == _t[6])
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -68,6 +68,7 @@
|
|
*/
|
|
*/
|
|
int check_content_type(struct sip_msg *msg)
|
|
int check_content_type(struct sip_msg *msg)
|
|
{
|
|
{
|
|
|
|
+ /* clang-format off */
|
|
static unsigned int appl[16] = {
|
|
static unsigned int appl[16] = {
|
|
0x6c707061/*appl*/,0x6c707041/*Appl*/,0x6c705061/*aPpl*/,
|
|
0x6c707061/*appl*/,0x6c707041/*Appl*/,0x6c705061/*aPpl*/,
|
|
0x6c705041/*APpl*/,0x6c507061/*apPl*/,0x6c507041/*ApPl*/,
|
|
0x6c705041/*APpl*/,0x6c507061/*apPl*/,0x6c507041/*ApPl*/,
|
|
@@ -90,55 +91,55 @@ int check_content_type(struct sip_msg *msg)
|
|
0x00706473/*sdp_*/,0x00706453/*Sdp_*/,0x00704473/*sDp_*/,
|
|
0x00706473/*sdp_*/,0x00706453/*Sdp_*/,0x00704473/*sDp_*/,
|
|
0x00704453/*SDp_*/,0x00506473/*sdP_*/,0x00506453/*SdP_*/,
|
|
0x00704453/*SDp_*/,0x00506473/*sdP_*/,0x00506453/*SdP_*/,
|
|
0x00504473/*sDP_*/,0x00504453/*SDP_*/};
|
|
0x00504473/*sDP_*/,0x00504453/*SDP_*/};
|
|
- str str_type;
|
|
|
|
- unsigned int x;
|
|
|
|
- char *p;
|
|
|
|
|
|
+ /* clang-format on */
|
|
|
|
+ str str_type;
|
|
|
|
+ unsigned int x;
|
|
|
|
+ char *p;
|
|
|
|
|
|
- if (!msg->content_type)
|
|
|
|
- {
|
|
|
|
|
|
+ if(!msg->content_type) {
|
|
LM_WARN("the header Content-TYPE is absent!"
|
|
LM_WARN("the header Content-TYPE is absent!"
|
|
- "let's assume the content is text/plain ;-)\n");
|
|
|
|
|
|
+ "let's assume the content is text/plain ;-)\n");
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
- trim_len(str_type.len,str_type.s,msg->content_type->body);
|
|
|
|
- if (str_type.len>=15 && (*str_type.s=='m' || *str_type.s=='M')
|
|
|
|
|
|
+ trim_len(str_type.len, str_type.s, msg->content_type->body);
|
|
|
|
+ if(str_type.len >= 15 && (*str_type.s == 'm' || *str_type.s == 'M')
|
|
&& strncasecmp(str_type.s, "multipart/mixed", 15) == 0) {
|
|
&& strncasecmp(str_type.s, "multipart/mixed", 15) == 0) {
|
|
return 2;
|
|
return 2;
|
|
}
|
|
}
|
|
p = str_type.s;
|
|
p = str_type.s;
|
|
- advance(p,4,str_type,error_1);
|
|
|
|
- x = READ(p-4);
|
|
|
|
- if (!one_of_16(x,appl))
|
|
|
|
|
|
+ advance(p, 4, str_type, error_1);
|
|
|
|
+ x = READ(p - 4);
|
|
|
|
+ if(!one_of_16(x, appl))
|
|
goto other;
|
|
goto other;
|
|
- advance(p,4,str_type,error_1);
|
|
|
|
- x = READ(p-4);
|
|
|
|
- if (!one_of_16(x,icat))
|
|
|
|
|
|
+ advance(p, 4, str_type, error_1);
|
|
|
|
+ x = READ(p - 4);
|
|
|
|
+ if(!one_of_16(x, icat))
|
|
goto other;
|
|
goto other;
|
|
- advance(p,3,str_type,error_1);
|
|
|
|
- x = READ(p-3) & 0x00ffffff;
|
|
|
|
- if (!one_of_8(x,ion_))
|
|
|
|
|
|
+ advance(p, 3, str_type, error_1);
|
|
|
|
+ x = READ(p - 3) & 0x00ffffff;
|
|
|
|
+ if(!one_of_8(x, ion_))
|
|
goto other;
|
|
goto other;
|
|
|
|
|
|
/* skip spaces and tabs if any */
|
|
/* skip spaces and tabs if any */
|
|
- while (*p==' ' || *p=='\t')
|
|
|
|
- advance(p,1,str_type,error_1);
|
|
|
|
- if (*p!='/')
|
|
|
|
- {
|
|
|
|
|
|
+ while(*p == ' ' || *p == '\t')
|
|
|
|
+ advance(p, 1, str_type, error_1);
|
|
|
|
+ if(*p != '/') {
|
|
LM_ERR("no / found after primary type\n");
|
|
LM_ERR("no / found after primary type\n");
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
- advance(p,1,str_type,error_1);
|
|
|
|
- while ((*p==' ' || *p=='\t') && p+1<str_type.s+str_type.len)
|
|
|
|
- advance(p,1,str_type,error_1);
|
|
|
|
|
|
+ advance(p, 1, str_type, error_1);
|
|
|
|
+ while((*p == ' ' || *p == '\t') && p + 1 < str_type.s + str_type.len)
|
|
|
|
+ advance(p, 1, str_type, error_1);
|
|
|
|
|
|
- advance(p,3,str_type,error_1);
|
|
|
|
- x = READ(p-3) & 0x00ffffff;
|
|
|
|
- if (!one_of_8(x,sdp_))
|
|
|
|
|
|
+ advance(p, 3, str_type, error_1);
|
|
|
|
+ x = READ(p - 3) & 0x00ffffff;
|
|
|
|
+ if(!one_of_8(x, sdp_))
|
|
goto other;
|
|
goto other;
|
|
|
|
|
|
- if (*p==';'||*p==' '||*p=='\t'||*p=='\n'||*p=='\r'||*p==0) {
|
|
|
|
- LM_DBG("type <%.*s> found valid\n", (int)(p-str_type.s), str_type.s);
|
|
|
|
|
|
+ if(*p == ';' || *p == ' ' || *p == '\t' || *p == '\n' || *p == '\r'
|
|
|
|
+ || *p == 0) {
|
|
|
|
+ LM_DBG("type <%.*s> found valid\n", (int)(p - str_type.s), str_type.s);
|
|
return 1;
|
|
return 1;
|
|
} else {
|
|
} else {
|
|
LM_ERR("bad end for type!\n");
|
|
LM_ERR("bad end for type!\n");
|
|
@@ -157,7 +158,7 @@ other:
|
|
/*
|
|
/*
|
|
* Get message body and check Content-Type header field
|
|
* Get message body and check Content-Type header field
|
|
*/
|
|
*/
|
|
-int extract_body(struct sip_msg *msg, str *body )
|
|
|
|
|
|
+int extract_body(struct sip_msg *msg, str *body)
|
|
{
|
|
{
|
|
char c;
|
|
char c;
|
|
int skip;
|
|
int skip;
|
|
@@ -168,7 +169,7 @@ int extract_body(struct sip_msg *msg, str *body )
|
|
unsigned int mime;
|
|
unsigned int mime;
|
|
|
|
|
|
body->s = get_body(msg);
|
|
body->s = get_body(msg);
|
|
- if (body->s==0) {
|
|
|
|
|
|
+ if(body->s == 0) {
|
|
LM_ERR("failed to get the message body\n");
|
|
LM_ERR("failed to get the message body\n");
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
@@ -178,18 +179,18 @@ int extract_body(struct sip_msg *msg, str *body )
|
|
* parcing as get_body() parsed all headers and Conten-Length
|
|
* parcing as get_body() parsed all headers and Conten-Length
|
|
* body header is automaticaly parsed when found.
|
|
* body header is automaticaly parsed when found.
|
|
*/
|
|
*/
|
|
- if (msg->content_length==0) {
|
|
|
|
|
|
+ if(msg->content_length == 0) {
|
|
LM_ERR("failed to get the content length in message\n");
|
|
LM_ERR("failed to get the content length in message\n");
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
|
|
|
|
body->len = get_content_length(msg);
|
|
body->len = get_content_length(msg);
|
|
- if (body->len==0) {
|
|
|
|
|
|
+ if(body->len == 0) {
|
|
LM_ERR("message body has length zero\n");
|
|
LM_ERR("message body has length zero\n");
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
|
|
|
|
- if (body->len + body->s > msg->buf + msg->len) {
|
|
|
|
|
|
+ if(body->len + body->s > msg->buf + msg->len) {
|
|
LM_ERR("content-length exceeds packet-length by %d\n",
|
|
LM_ERR("content-length exceeds packet-length by %d\n",
|
|
(int)((body->len + body->s) - (msg->buf + msg->len)));
|
|
(int)((body->len + body->s) - (msg->buf + msg->len)));
|
|
goto error;
|
|
goto error;
|
|
@@ -198,60 +199,57 @@ int extract_body(struct sip_msg *msg, str *body )
|
|
/* no need for parse_headers(msg, EOH), get_body will
|
|
/* no need for parse_headers(msg, EOH), get_body will
|
|
* parse everything */
|
|
* parse everything */
|
|
/*is the content type correct?*/
|
|
/*is the content type correct?*/
|
|
- if((ret = check_content_type(msg))==-1)
|
|
|
|
- {
|
|
|
|
|
|
+ if((ret = check_content_type(msg)) == -1) {
|
|
LM_ERR("content type mismatching\n");
|
|
LM_ERR("content type mismatching\n");
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
|
|
|
|
- if(ret!=2)
|
|
|
|
|
|
+ if(ret != 2)
|
|
goto done;
|
|
goto done;
|
|
|
|
|
|
/* multipart body */
|
|
/* multipart body */
|
|
- if(get_mixed_part_delimiter(&msg->content_type->body,&mpdel) < 0) {
|
|
|
|
|
|
+ if(get_mixed_part_delimiter(&msg->content_type->body, &mpdel) < 0) {
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
- p1 = find_sdp_line_delimiter(body->s, body->s+body->len, mpdel);
|
|
|
|
- if (p1 == NULL) {
|
|
|
|
|
|
+ p1 = find_sdp_line_delimiter(body->s, body->s + body->len, mpdel);
|
|
|
|
+ if(p1 == NULL) {
|
|
LM_ERR("empty multipart content\n");
|
|
LM_ERR("empty multipart content\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
- p2=p1;
|
|
|
|
|
|
+ p2 = p1;
|
|
c = 0;
|
|
c = 0;
|
|
- for(;;)
|
|
|
|
- {
|
|
|
|
|
|
+ for(;;) {
|
|
p1 = p2;
|
|
p1 = p2;
|
|
- if (p1 == NULL || p1 >= body->s+body->len)
|
|
|
|
|
|
+ if(p1 == NULL || p1 >= body->s + body->len)
|
|
break; /* No parts left */
|
|
break; /* No parts left */
|
|
- p2 = find_next_sdp_line_delimiter(p1, body->s+body->len,
|
|
|
|
- mpdel, body->s+body->len);
|
|
|
|
|
|
+ p2 = find_next_sdp_line_delimiter(
|
|
|
|
+ p1, body->s + body->len, mpdel, body->s + body->len);
|
|
/* p2 is text limit for application parsing */
|
|
/* p2 is text limit for application parsing */
|
|
rest = eat_line(p1 + mpdel.len + 2, p2 - p1 - mpdel.len - 2);
|
|
rest = eat_line(p1 + mpdel.len + 2, p2 - p1 - mpdel.len - 2);
|
|
- if ( rest > p2 ) {
|
|
|
|
- LM_ERR("Unparsable <%.*s>\n", (int)(p1-p1), p1);
|
|
|
|
|
|
+ if(rest > p2) {
|
|
|
|
+ LM_ERR("Unparsable <%.*s>\n", (int)(p1 - p1), p1);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
- while( rest<p2 ) {
|
|
|
|
- memset(&hf,0, sizeof(struct hdr_field));
|
|
|
|
|
|
+ while(rest < p2) {
|
|
|
|
+ memset(&hf, 0, sizeof(struct hdr_field));
|
|
rest = get_sdp_hdr_field(rest, p2, &hf);
|
|
rest = get_sdp_hdr_field(rest, p2, &hf);
|
|
- if(hf.type==HDR_EOH_T)
|
|
|
|
|
|
+ if(hf.type == HDR_EOH_T)
|
|
break;
|
|
break;
|
|
- if(hf.type==HDR_ERROR_T)
|
|
|
|
|
|
+ if(hf.type == HDR_ERROR_T)
|
|
return -1;
|
|
return -1;
|
|
- if(hf.type==HDR_CONTENTTYPE_T) {
|
|
|
|
- if(decode_mime_type(hf.body.s, hf.body.s + hf.body.len,
|
|
|
|
- &mime)==NULL)
|
|
|
|
|
|
+ if(hf.type == HDR_CONTENTTYPE_T) {
|
|
|
|
+ if(decode_mime_type(hf.body.s, hf.body.s + hf.body.len, &mime)
|
|
|
|
+ == NULL)
|
|
return -1;
|
|
return -1;
|
|
- if (((((unsigned int)mime)>>16) == TYPE_APPLICATION)
|
|
|
|
- && ((mime&0x00ff) == SUBTYPE_SDP)) {
|
|
|
|
|
|
+ if(((((unsigned int)mime) >> 16) == TYPE_APPLICATION)
|
|
|
|
+ && ((mime & 0x00ff) == SUBTYPE_SDP)) {
|
|
c = 1;
|
|
c = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} /* end of while */
|
|
} /* end of while */
|
|
- if(c==1)
|
|
|
|
- {
|
|
|
|
|
|
+ if(c == 1) {
|
|
body->s = rest;
|
|
body->s = rest;
|
|
- body->len = p2-rest;
|
|
|
|
|
|
+ body->len = p2 - rest;
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -260,12 +258,12 @@ error:
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
done:
|
|
done:
|
|
- for (skip = 0; skip < body->len; skip++) {
|
|
|
|
|
|
+ for(skip = 0; skip < body->len; skip++) {
|
|
c = body->s[body->len - skip - 1];
|
|
c = body->s[body->len - skip - 1];
|
|
- if (c != '\r' && c != '\n')
|
|
|
|
|
|
+ if(c != '\r' && c != '\n')
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- if (skip == body->len) {
|
|
|
|
|
|
+ if(skip == body->len) {
|
|
LM_ERR("empty body");
|
|
LM_ERR("empty body");
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
@@ -283,24 +281,23 @@ done:
|
|
/*
|
|
/*
|
|
* Extract URI from the Contact header field
|
|
* Extract URI from the Contact header field
|
|
*/
|
|
*/
|
|
-int
|
|
|
|
-get_contact_uri(struct sip_msg* _m, struct sip_uri *uri, contact_t** _c)
|
|
|
|
|
|
+int get_contact_uri(struct sip_msg *_m, struct sip_uri *uri, contact_t **_c)
|
|
{
|
|
{
|
|
- if ((parse_headers(_m, HDR_CONTACT_F, 0) == -1) || !_m->contact)
|
|
|
|
|
|
+ if((parse_headers(_m, HDR_CONTACT_F, 0) == -1) || !_m->contact)
|
|
return -1;
|
|
return -1;
|
|
- if (!_m->contact->parsed && parse_contact(_m->contact) < 0) {
|
|
|
|
|
|
+ if(!_m->contact->parsed && parse_contact(_m->contact) < 0) {
|
|
LM_ERR("failed to parse Contact body\n");
|
|
LM_ERR("failed to parse Contact body\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
- *_c = ((contact_body_t*)_m->contact->parsed)->contacts;
|
|
|
|
- if (*_c == NULL)
|
|
|
|
|
|
+ *_c = ((contact_body_t *)_m->contact->parsed)->contacts;
|
|
|
|
+ if(*_c == NULL)
|
|
/* no contacts found */
|
|
/* no contacts found */
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
- if (parse_uri((*_c)->uri.s, (*_c)->uri.len, uri) < 0 || uri->host.len <= 0) {
|
|
|
|
- LM_ERR("failed to parse Contact URI [%.*s]\n",
|
|
|
|
- (*_c)->uri.len, ((*_c)->uri.s)?(*_c)->uri.s:"");
|
|
|
|
|
|
+ if(parse_uri((*_c)->uri.s, (*_c)->uri.len, uri) < 0 || uri->host.len <= 0) {
|
|
|
|
+ LM_ERR("failed to parse Contact URI [%.*s]\n", (*_c)->uri.len,
|
|
|
|
+ ((*_c)->uri.s) ? (*_c)->uri.s : "");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
-}
|
|
|
|
|
|
+}
|