4
* Copyright (C) 2001-2003 FhG Fokus
6
* This file is part of Kamailio, a free SIP server.
8
* Kamailio is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version
13
* Kamailio is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
* 2003-11-06 body len is computed using the message len (it's
25
* not taken any more from the msg. content-length) (andrei)
26
* 2008-08-30 body len is taken from Conent-length header as it is more
27
* reliable (UDP packages may contain garbage at the end)(bogdan)
32
#include <sys/types.h>
34
#include "rtpproxy_funcs.h"
35
#include "../../dprint.h"
36
#include "../../config.h"
38
#include "../../forward.h"
39
#include "../../resolve.h"
40
#include "../../globals.h"
41
#include "../../udp_server.h"
43
#include "../../parser/msg_parser.h"
44
#include "../../trim.h"
45
#include "../../parser/parse_from.h"
46
#include "../../parser/contact/parse_contact.h"
47
#include "../../parser/parse_uri.h"
48
#include "../../parser/parse_content.h"
49
#include "../../parser/parser_f.h"
50
#include "../../parser/sdp/sdp_helpr_funcs.h"
53
(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
54
#define advance(_ptr,_n,_str,_error) \
56
if ((_ptr)+(_n)>(_str).s+(_str).len)\
58
(_ptr) = (_ptr) + (_n);\
60
#define one_of_16( _x , _t ) \
61
(_x==_t[0]||_x==_t[15]||_x==_t[8]||_x==_t[2]||_x==_t[3]||_x==_t[4]\
62
||_x==_t[5]||_x==_t[6]||_x==_t[7]||_x==_t[1]||_x==_t[9]||_x==_t[10]\
63
||_x==_t[11]||_x==_t[12]||_x==_t[13]||_x==_t[14])
64
#define one_of_8( _x , _t ) \
65
(_x==_t[0]||_x==_t[7]||_x==_t[1]||_x==_t[2]||_x==_t[3]||_x==_t[4]\
66
||_x==_t[5]||_x==_t[6])
76
int check_content_type(struct sip_msg *msg)
78
static unsigned int appl[16] = {
79
0x6c707061/*appl*/,0x6c707041/*Appl*/,0x6c705061/*aPpl*/,
80
0x6c705041/*APpl*/,0x6c507061/*apPl*/,0x6c507041/*ApPl*/,
81
0x6c505061/*aPPl*/,0x6c505041/*APPl*/,0x4c707061/*appL*/,
82
0x4c707041/*AppL*/,0x4c705061/*aPpL*/,0x4c705041/*APpL*/,
83
0x4c507061/*apPL*/,0x4c507041/*ApPL*/,0x4c505061/*aPPL*/,
85
static unsigned int icat[16] = {
86
0x74616369/*icat*/,0x74616349/*Icat*/,0x74614369/*iCat*/,
87
0x74614349/*ICat*/,0x74416369/*icAt*/,0x74416349/*IcAt*/,
88
0x74414369/*iCAt*/,0x74414349/*ICAt*/,0x54616369/*icaT*/,
89
0x54616349/*IcaT*/,0x54614369/*iCaT*/,0x54614349/*ICaT*/,
90
0x54416369/*icAT*/,0x54416349/*IcAT*/,0x54414369/*iCAT*/,
92
static unsigned int ion_[8] = {
93
0x006e6f69/*ion_*/,0x006e6f49/*Ion_*/,0x006e4f69/*iOn_*/,
94
0x006e4f49/*IOn_*/,0x004e6f69/*ioN_*/,0x004e6f49/*IoN_*/,
95
0x004e4f69/*iON_*/,0x004e4f49/*ION_*/};
96
static unsigned int sdp_[8] = {
97
0x00706473/*sdp_*/,0x00706453/*Sdp_*/,0x00704473/*sDp_*/,
98
0x00704453/*SDp_*/,0x00506473/*sdP_*/,0x00506453/*SdP_*/,
99
0x00504473/*sDP_*/,0x00504453/*SDP_*/};
104
if (!msg->content_type)
106
LM_WARN("the header Content-TYPE is absent!"
107
"let's assume the content is text/plain ;-)\n");
111
trim_len(str_type.len,str_type.s,msg->content_type->body);
112
if (str_type.len>=15 && (*str_type.s=='m' || *str_type.s=='M')
113
&& strncasecmp(str_type.s, "multipart/mixed", 15) == 0) {
117
advance(p,4,str_type,error_1);
119
if (!one_of_16(x,appl))
121
advance(p,4,str_type,error_1);
123
if (!one_of_16(x,icat))
125
advance(p,3,str_type,error_1);
126
x = READ(p-3) & 0x00ffffff;
127
if (!one_of_8(x,ion_))
130
/* skip spaces and tabs if any */
131
while (*p==' ' || *p=='\t')
132
advance(p,1,str_type,error_1);
135
LM_ERR("no / found after primary type\n");
138
advance(p,1,str_type,error_1);
139
while ((*p==' ' || *p=='\t') && p+1<str_type.s+str_type.len)
140
advance(p,1,str_type,error_1);
142
advance(p,3,str_type,error_1);
143
x = READ(p-3) & 0x00ffffff;
144
if (!one_of_8(x,sdp_))
147
if (*p==';'||*p==' '||*p=='\t'||*p=='\n'||*p=='\r'||*p==0) {
148
LM_DBG("type <%.*s> found valid\n", (int)(p-str_type.s), str_type.s);
151
LM_ERR("bad end for type!\n");
156
LM_ERR("body ended :-(!\n");
160
LM_ERR("invalid type for a message\n");
166
* Get message body and check Content-Type header field
168
int extract_body(struct sip_msg *msg, str *body )
173
char *rest, *p1, *p2;
177
body->s = get_body(msg);
179
LM_ERR("failed to get the message body\n");
184
* Better use the content-len value - no need of any explicit
185
* parcing as get_body() parsed all headers and Conten-Length
186
* body header is automaticaly parsed when found.
188
if (msg->content_length==0) {
189
LM_ERR("failed to get the content length in message\n");
193
body->len = get_content_length(msg);
195
LM_ERR("message body has length zero\n");
199
if (body->len + body->s > msg->buf + msg->len) {
200
LM_ERR("content-length exceeds packet-length by %d\n",
201
(int)((body->len + body->s) - (msg->buf + msg->len)));
205
/* no need for parse_headers(msg, EOH), get_body will
206
* parse everything */
207
/*is the content type correct?*/
208
if((ret = check_content_type(msg))==-1)
210
LM_ERR("content type mismatching\n");
218
if(get_mixed_part_delimiter(&msg->content_type->body,&mpdel) < 0) {
221
p1 = find_sdp_line_delimiter(body->s, body->s+body->len, mpdel);
223
LM_ERR("empty multipart content\n");
231
if (p1 == NULL || p1 >= body->s+body->len)
232
break; /* No parts left */
233
p2 = find_next_sdp_line_delimiter(p1, body->s+body->len,
234
mpdel, body->s+body->len);
235
/* p2 is text limit for application parsing */
236
rest = eat_line(p1 + mpdel.len + 2, p2 - p1 - mpdel.len - 2);
238
LM_ERR("Unparsable <%.*s>\n", (int)(p1-p1), p1);
242
memset(&hf,0, sizeof(struct hdr_field));
243
rest = get_sdp_hdr_field(rest, p2, &hf);
244
if(hf.type==HDR_EOH_T)
246
if(hf.type==HDR_ERROR_T)
248
if(hf.type==HDR_CONTENTTYPE_T) {
249
if(decode_mime_type(hf.body.s, hf.body.s + hf.body.len,
252
if (((((unsigned int)mime)>>16) == TYPE_APPLICATION)
253
&& ((mime&0x00ff) == SUBTYPE_SDP)) {
260
if (rest < p2 && *rest == '\r') rest++;
261
if (rest < p2 && *rest == '\n') rest++;
262
if (rest < p2 && p2[-1] == '\n') p2--;
263
if (rest < p2 && p2[-1] == '\r') p2--;
274
/*LM_DBG("DEBUG:extract_body:=|%.*s|\n",body->len,body->s);*/
279
* ser_memmem() returns the location of the first occurrence of data
280
* pattern b2 of size len2 in memory block b1 of size len1 or
281
* NULL if none is found. Obtained from NetBSD.
284
ser_memmem(const void *b1, const void *b2, size_t len1, size_t len2)
286
/* Initialize search pointer */
287
char *sp = (char *) b1;
289
/* Initialize pattern pointer */
290
char *pp = (char *) b2;
292
/* Initialize end of search address space pointer */
293
char *eos = sp + len1 - len2;
296
if(!(b1 && b2 && len1 && len2))
301
if (memcmp(sp, pp, len2) == 0)
311
* Some helper functions taken verbatim from tm module.
315
* Extract Call-ID value
316
* assumes the callid header is already parsed
317
* (so make sure it is, before calling this function or
318
* it might fail even if the message _has_ a callid)
321
get_callid(struct sip_msg* _m, str* _cid)
324
if ((parse_headers(_m, HDR_CALLID_F, 0) == -1)) {
325
LM_ERR("failed to parse call-id header\n");
329
if (_m->callid == NULL) {
330
LM_ERR("call-id not found\n");
334
_cid->s = _m->callid->body.s;
335
_cid->len = _m->callid->body.len;
341
* Extract tag from To header field of a response
344
get_to_tag(struct sip_msg* _m, str* _tag)
347
if (parse_to_header(_m) < 0) {
348
LM_ERR("To header field missing\n");
352
if (get_to(_m)->tag_value.len) {
353
_tag->s = get_to(_m)->tag_value.s;
354
_tag->len = get_to(_m)->tag_value.len;
356
_tag->s = NULL; /* fixes gcc 4.0 warnings */
364
* Extract tag from From header field of a request
367
get_from_tag(struct sip_msg* _m, str* _tag)
370
if (parse_from_header(_m)<0) {
371
LM_ERR("failed to parse From header\n");
375
if (get_from(_m)->tag_value.len) {
376
_tag->s = get_from(_m)->tag_value.s;
377
_tag->len = get_from(_m)->tag_value.len;
379
_tag->s = NULL; /* fixes gcc 4.0 warnings */
387
* Extract URI from the Contact header field
390
get_contact_uri(struct sip_msg* _m, struct sip_uri *uri, contact_t** _c)
393
if ((parse_headers(_m, HDR_CONTACT_F, 0) == -1) || !_m->contact)
395
if (!_m->contact->parsed && parse_contact(_m->contact) < 0) {
396
LM_ERR("failed to parse Contact body\n");
399
*_c = ((contact_body_t*)_m->contact->parsed)->contacts;
401
/* no contacts found */
404
if (parse_uri((*_c)->uri.s, (*_c)->uri.len, uri) < 0 || uri->host.len <= 0) {
405
LM_ERR("failed to parse Contact URI [%.*s]\n",
406
(*_c)->uri.len, ((*_c)->uri.s)?(*_c)->uri.s:"");
413
* Extract branch from Via header
416
get_via_branch(struct sip_msg* msg, int vianum, str* _branch)
418
struct via_body *via;
421
if (parse_via_header(msg, vianum, &via) < 0)
424
for (p = via->param_lst; p; p = p->next)
426
if (p->name.len == strlen("branch")
427
&& strncasecmp(p->name.s, "branch", strlen("branch")) == 0) {
428
_branch->s = p->value.s;
429
_branch->len = p->value.len;