📄 param_parser.c
字号:
/* * $Id: param_parser.c,v 1.5 2004/08/24 09:01:29 janakj Exp $ * * 32-bit Digest parameter name parser * * Copyright (C) 2001-2003 FhG Fokus * * 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 */#include "param_parser.h"#include "digest_keys.h"#include "../../trim.h"#include "../../ut.h"#define LOWER_BYTE(b) ((b) | 0x20)#define LOWER_DWORD(d) ((d) | 0x20202020)/* * Parse short (less than 4 bytes) parameter names */#define PARSE_SHORT \ switch(LOWER_BYTE(*p)) { \ case 'u': \ if (LOWER_BYTE(*(p + 1)) == 'r') { \ if (LOWER_BYTE(*(p + 2)) == 'i') { \ *_type = PAR_URI; \ p += 3; \ goto end; \ } \ } \ break; \ \ case 'q': \ if (LOWER_BYTE(*(p + 1)) == 'o') { \ if (LOWER_BYTE(*(p + 2)) == 'p') { \ *_type = PAR_QOP; \ p += 3; \ goto end; \ } \ } \ break; \ \ case 'n': \ if (LOWER_BYTE(*(p + 1)) == 'c') { \ *_type = PAR_NC; \ p += 2; \ goto end; \ } \ break; \ }/* * Read 4-bytes from memory and store them in an integer variable * Reading byte by byte ensures, that the code works also on HW which * does not allow reading 4-bytes at once from unaligned memory position * (Sparc for example) */#define READ(val) \(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))#define name_CASE \ switch(LOWER_DWORD(val)) { \ case _name_: \ *_type = PAR_USERNAME; \ p += 4; \ goto end; \ }#define user_CASE \ p += 4; \ val = READ(p); \ name_CASE; \ goto other;#define real_CASE \ p += 4; \ if (LOWER_BYTE(*p) == 'm') { \ *_type = PAR_REALM; \ p++; \ goto end; \ }#define nonc_CASE \ p += 4; \ if (LOWER_BYTE(*p) == 'e') { \ *_type = PAR_NONCE; \ p++; \ goto end; \ }#define onse_CASE \ switch(LOWER_DWORD(val)) { \ case _onse_: \ *_type = PAR_RESPONSE; \ p += 4; \ goto end; \ }#define resp_CASE \ p += 4; \ val = READ(p); \ onse_CASE; \ goto other;#define cnon_CASE \ p += 4; \ if (LOWER_BYTE(*p) == 'c') { \ p++; \ if (LOWER_BYTE(*p) == 'e') { \ *_type = PAR_CNONCE; \ p++; \ goto end; \ } \ } \ goto other;#define opaq_CASE \ p += 4; \ if (LOWER_BYTE(*p) == 'u') { \ p++; \ if (LOWER_BYTE(*p) == 'e') { \ *_type = PAR_OPAQUE; \ p++; \ goto end; \ } \ } \ goto other;#define rith_CASE \ switch(LOWER_DWORD(val)) { \ case _rith_: \ p += 4; \ if (LOWER_BYTE(*p) == 'm') { \ *_type = PAR_ALGORITHM; \ p++; \ goto end; \ } \ goto other; \ }#define algo_CASE \ p += 4; \ val = READ(p); \ rith_CASE; \ goto other#define FIRST_QUATERNIONS \ case _user_: user_CASE; \ case _real_: real_CASE; \ case _nonc_: nonc_CASE; \ case _resp_: resp_CASE; \ case _cnon_: cnon_CASE; \ case _opaq_: opaq_CASE; \ case _algo_: algo_CASE;int parse_param_name(str* _s, dig_par_t* _type){ register char* p; register int val; char* end; end = _s->s + _s->len; p = _s->s; val = READ(p); if (_s->len < 4) { goto other; } switch(LOWER_DWORD(val)) { FIRST_QUATERNIONS; default: PARSE_SHORT; goto other; } end: _s->len -= p - _s->s; _s->s = p; trim_leading(_s); if (_s->s[0] == '=') { return 0; } other: p = q_memchr(p, '=', end - p); if (!p) { return -1; /* Parse error */ } else { *_type = PAR_OTHER; _s->len -= p - _s->s; _s->s = p; return 0; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -