mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
282 lines
5.3 KiB
282 lines
5.3 KiB
/*
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2007 iptelorg GmbH
|
|
*
|
|
* This file is part of ser, a free SIP server.
|
|
*
|
|
* ser is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version
|
|
*
|
|
* For a license to use the ser software under conditions
|
|
* other than those described here, or to purchase support for this
|
|
* software, please contact iptel.org by e-mail at the following addresses:
|
|
* info@iptel.org
|
|
*
|
|
* ser is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* 2007-05-28 lightweight parser implemented for build_local_reparse()
|
|
* function. Basically copy-pasted from the core parser (Miklos)
|
|
*/
|
|
|
|
#include "../../parser/keys.h"
|
|
#include "../../parser/hf.h"
|
|
#include "../../parser/parser_f.h"
|
|
#include "lw_parser.h"
|
|
|
|
/* macros from the core parser */
|
|
#define LOWER_BYTE(b) ((b) | 0x20)
|
|
#define LOWER_DWORD(d) ((d) | 0x20202020)
|
|
|
|
#define READ(val) \
|
|
(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
|
|
|
|
/*
|
|
* lightweight header field name parser
|
|
* used by build_local_reparse() function in order to construct ACK or CANCEL request
|
|
* from the INVITE buffer
|
|
* this parser supports only the header fields which are needed by build_local_reparse()
|
|
*/
|
|
char *lw_get_hf_name(char *begin, char *end,
|
|
enum _hdr_types_t *type)
|
|
{
|
|
|
|
char *p;
|
|
unsigned int val;
|
|
|
|
if (end - begin < 4) {
|
|
*type = HDR_ERROR_T;
|
|
return begin;
|
|
}
|
|
|
|
p = begin;
|
|
val = LOWER_DWORD(READ(p));
|
|
|
|
switch(val) {
|
|
|
|
case _cseq_: /* Cseq */
|
|
*type = HDR_CSEQ_T;
|
|
p += 4;
|
|
break;
|
|
|
|
case _via1_: /* Via */
|
|
case _via2_:
|
|
*type = HDR_VIA_T;
|
|
p += 3;
|
|
break;
|
|
|
|
case _from_: /* From */
|
|
*type = HDR_FROM_T;
|
|
p += 4;
|
|
break;
|
|
|
|
case _to12_: /* To */
|
|
*type = HDR_TO_T;
|
|
p += 2;
|
|
break;
|
|
|
|
case _requ_: /* Require */
|
|
p += 4;
|
|
val = LOWER_DWORD(READ(p));
|
|
|
|
switch(val) {
|
|
|
|
case _ire1_:
|
|
case _ire2_:
|
|
p += 3;
|
|
*type = HDR_REQUIRE_T;
|
|
break;
|
|
|
|
default:
|
|
p -= 4;
|
|
*type = HDR_OTHER_T;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case _prox_: /* Proxy-Require */
|
|
|
|
if ((LOWER_DWORD(READ(p+4)) == _y_re_)
|
|
&& (LOWER_DWORD(READ(p+8)) == _quir_)
|
|
&& (LOWER_BYTE(*(p+12)) == 'e')) {
|
|
|
|
p += 13;
|
|
*type = HDR_PROXYREQUIRE_T;
|
|
break;
|
|
|
|
} else {
|
|
*type = HDR_OTHER_T;
|
|
break;
|
|
}
|
|
|
|
case _cont_: /* Content-Length */
|
|
|
|
if ((LOWER_DWORD(READ(p+4)) == _ent__)
|
|
&& (LOWER_DWORD(READ(p+8)) == _leng_)
|
|
&& (LOWER_BYTE(*(p+12)) == 't')
|
|
&& (LOWER_BYTE(*(p+13)) == 'h')) {
|
|
|
|
p += 14;
|
|
*type = HDR_CONTENTLENGTH_T;
|
|
break;
|
|
} else {
|
|
*type = HDR_OTHER_T;
|
|
break;
|
|
}
|
|
|
|
case _call_: /* Call-Id */
|
|
|
|
p += 4;
|
|
val = LOWER_DWORD(READ(p));
|
|
|
|
switch(val) {
|
|
|
|
case __id1_:
|
|
case __id2_:
|
|
p += 3;
|
|
*type = HDR_CALLID_T;
|
|
break;
|
|
|
|
default:
|
|
p -= 4;
|
|
*type = HDR_OTHER_T;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case _rout_: /* Route */
|
|
|
|
if (LOWER_BYTE(*(p+4)) == 'e') {
|
|
p += 5;
|
|
*type = HDR_ROUTE_T;
|
|
break;
|
|
} else {
|
|
*type = HDR_OTHER_T;
|
|
break;
|
|
}
|
|
|
|
case _max__: /* Max-Forwards */
|
|
|
|
if ((LOWER_DWORD(READ(p+4)) == _forw_)
|
|
&& (LOWER_DWORD(READ(p+8)) == _ards_)) {
|
|
|
|
p += 12;
|
|
*type = HDR_MAXFORWARDS_T;
|
|
break;
|
|
} else {
|
|
*type = HDR_OTHER_T;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
/* compact headers */
|
|
switch(LOWER_BYTE(*p)) {
|
|
|
|
case 'v': /* Via */
|
|
if ((*(p+1) == ' ') || (*(p+1) == ':')) {
|
|
p++;
|
|
*type = HDR_VIA_T;
|
|
break;
|
|
}
|
|
*type = HDR_OTHER_T;
|
|
break;
|
|
|
|
case 'f': /* From */
|
|
if ((*(p+1) == ' ') || (*(p+1) == ':')) {
|
|
p++;
|
|
*type = HDR_FROM_T;
|
|
break;
|
|
}
|
|
*type = HDR_OTHER_T;
|
|
break;
|
|
|
|
case 't': /* To */
|
|
if (LOWER_BYTE(*(p+1)) == 'o') {
|
|
p += 2;
|
|
*type = HDR_TO_T;
|
|
break;
|
|
}
|
|
if ((*(p+1) == ' ') || (*(p+1) == ':')) {
|
|
p++;
|
|
*type = HDR_TO_T;
|
|
break;
|
|
}
|
|
*type = HDR_OTHER_T;
|
|
break;
|
|
|
|
case 'l': /* Content-Length */
|
|
if ((*(p+1) == ' ') || (*(p+1) == ':')) {
|
|
p++;
|
|
*type = HDR_CONTENTLENGTH_T;
|
|
break;
|
|
}
|
|
*type = HDR_OTHER_T;
|
|
break;
|
|
|
|
case 'i': /* Call-Id */
|
|
if ((*(p+1) == ' ') || (*(p+1) == ':')) {
|
|
p++;
|
|
*type = HDR_CALLID_T;
|
|
break;
|
|
}
|
|
*type = HDR_OTHER_T;
|
|
break;
|
|
|
|
default:
|
|
*type = HDR_OTHER_T;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
/* returns a pointer to the next line */
|
|
char *lw_next_line(char *buf, char *buf_end)
|
|
{
|
|
char *c;
|
|
|
|
c = buf;
|
|
do {
|
|
while ((c < buf_end) && (*c != '\n')) c++;
|
|
if (c < buf_end) c++;
|
|
|
|
} while ((c < buf_end) &&
|
|
((*c == ' ') || (*c == '\t'))); /* next line begins with whitespace line folding */
|
|
|
|
return c;
|
|
}
|
|
|
|
#ifdef USE_DNS_FAILOVER
|
|
/* returns the pointer to the first VIA header */
|
|
char *lw_find_via(char *buf, char *buf_end)
|
|
{
|
|
char *p;
|
|
unsigned int val;
|
|
|
|
/* skip the first line */
|
|
p = eat_line(buf, buf_end - buf);
|
|
|
|
while (buf_end - p > 4) {
|
|
val = LOWER_DWORD(READ(p));
|
|
if ((val == _via1_) || (val == _via2_)
|
|
|| ((LOWER_BYTE(*p) == 'v') /* compact header */
|
|
&& ((*(p+1) == ' ') || (*(p+1) == ':')) )
|
|
) return p;
|
|
|
|
p = lw_next_line(p, buf_end);
|
|
}
|
|
/* not found */
|
|
return 0;
|
|
}
|
|
#endif
|