📄 radius_pdu.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * radius_pdu.c - parse and generate RADIUS Accounting PDUs * * Taken from gw/smsc/smpp_pdu.c writen by Lars Wirzenius. * This makes heavy use of C pre-processor macro magic. * * Stipe Tolj <tolj@wapme-systems.de> */#include <string.h>#include "radius_pdu.h"#define MIN_RADIUS_PDU_LEN 20#define MAX_RADIUS_PDU_LEN 4095 static unsigned long decode_integer(Octstr *os, long pos, int octets){ unsigned long u; int i; gw_assert(octstr_len(os) >= pos + octets); u = 0; for (i = 0; i < octets; ++i) u = (u << 8) | octstr_get_char(os, pos + i); return u;}static void append_encoded_integer(Octstr *os, unsigned long u, long octets){ long i; for (i = 0; i < octets; ++i) octstr_append_char(os, (u >> ((octets - i - 1) * 8)) & 0xFF);}/*static void *get_header_element(RADIUS_PDU *pdu, unsigned char *e) { switch (pdu->type) { #define INTEGER(name, octets) \ if (strcmp(#name, e) == 0) return (void*) *(&p->name); #define NULTERMINATED(name, max_octets) #define OCTETS(name, field_giving_octets) \ if (strcmp(#name, e) == 0) return (void*) p->name; #define PDU(name, id, fields) \ case id: { \ struct name *p = &pdu->u.name; \ } break; #include "radius_pdu.def" default: error(0, "Unknown RADIUS_PDU type, internal error."); gw_free(pdu); return NULL; }}*/RADIUS_PDU *radius_pdu_create(int type, RADIUS_PDU *req){ RADIUS_PDU *pdu; pdu = gw_malloc(sizeof(*pdu)); pdu->type = type; switch (type) { #define INTEGER(name, octets) \ if (strcmp(#name, "code") == 0) p->name = type; \ else p->name = 0; #define OCTETS(name, field_giving_octets) p->name = NULL; #define PDU(name, id, fields) \ case id: { \ struct name *p = &pdu->u.name; \ pdu->type_name = #name; \ fields \ } break; #include "radius_pdu.def" default: error(0, "Unknown RADIUS_PDU type, internal error."); gw_free(pdu); return NULL; } #define ATTR(attr, type, string, min, max) #define UNASSIGNED(attr) #define ATTRIBUTES(fields) \ pdu->attr = dict_create(20, (void (*)(void *))octstr_destroy); #include "radius_attributes.def" return pdu;}void radius_pdu_destroy(RADIUS_PDU *pdu){ if (pdu == NULL) return; switch (pdu->type) { #define INTEGER(name, octets) p->name = 0; #define OCTETS(name, field_giving_octets) octstr_destroy(p->name); #define PDU(name, id, fields) \ case id: { struct name *p = &pdu->u.name; fields } break; #include "radius_pdu.def" default: error(0, "Unknown RADIUS_PDU type, internal error while destroying."); } #define ATTR(attr, type, string, min, max) #define UNASSIGNED(attr) #define ATTRIBUTES(fields) dict_destroy(pdu->attr); #include "radius_attributes.def" gw_free(pdu);}/*static void radius_type_append(Octstr **os, int type, int pmin, int pmax, Octstr *value) { long l; switch (type) { case t_int: octstr_parse_long(&l, value, 0, 10); append_encoded_integer(*os, l, pmin); break; case t_string: octstr_append(*os, value); break; case t_ipaddr: ret = octstr_create(""); for (i = 0; i < 4; i++) { int c = octstr_get_char(value, i); Octstr *b = octstr_format("%d", c); octstr_append(ret, b); i < 3 ? octstr_append_cstr(ret, ".") : NULL; octstr_destroy(b); } break; default: panic(0, "RADIUS: Attribute type %d does not exist.", type); break; }}*/static Octstr *radius_attr_pack(RADIUS_PDU *pdu) { Octstr *os; os = octstr_create(""); gw_assert(pdu != NULL); #define ATTR(atype, type, string, pmin, pmax) \ { \ Octstr *attr_strg = octstr_create(string); \ Octstr *attr_val = dict_get(p->attr, attr_str); \ if (attr_str != NULL) { \ int attr_len = octstr_len(attr_val) + 2; \ octstr_format_append(os, "%02X", atype); \ octstr_append_data(os, (char*) &attr_len, 2); \ radius_type_append(&os, type, pmin, pmax, attr_val); \ } \ octstr_destroy(attr_str); \ } #define UNASSIGNED(attr) #define ATTRIBUTES(fields) #include "radius_attributes.def" return os;}Octstr *radius_pdu_pack(RADIUS_PDU *pdu){ Octstr *os,*oos; Octstr *temp; os = octstr_create(""); gw_assert(pdu != NULL); /* switch (pdu->type) { #define INTEGER(name, octets) p = *(&p); #define NULTERMINATED(name, max_octets) p = *(&p); #define OCTETS(name, field_giving_octets) \ p->field_giving_octets = octstr_len(p->name); #define PDU(name, id, fields) \ case id: { struct name *p = &pdu->u.name; fields } break; #include "radius_pdu.def" default: error(0, "Unknown RADIUS_PDU type, internal error while packing."); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -