📄 radius_acct.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_acct.c - RADIUS accounting proxy thread** Stipe Tolj <tolj@wapme-systems.de>*/#include <string.h>#include <fcntl.h>#include <errno.h>#include "gwlib/gwlib.h"#include "radius/radius_acct.h"#include "radius/radius_pdu.h"static Dict *radius_table = NULL; /* maps client ip -> msisdn */static Dict *session_table = NULL; /* maps session id -> client ip */static Dict *client_table = NULL; /* maps client ip -> session id *//* we will initialize hash tables in the size of our NAS ports */#define RADIUS_NAS_PORTS 30static Mutex *radius_mutex = NULL;static int run_thread = 0;/* * Beware that the official UDP port for RADIUS accounting packets * is 1813 (according to RFC2866). The previously used port 1646 has * been conflicting with an other protocol and "should" not be used. */static Octstr *our_host = NULL;static long our_port = 1813;static Octstr *remote_host = NULL;static long remote_port = 1813;/* the shared secrets for NAS and remote RADIUS communication */static Octstr *secret_nas = NULL;static Octstr *secret_radius = NULL;/* the global unified-prefix list */static Octstr *unified_prefix = NULL;/************************************************************************* * *//* * Updates the internal RADIUS mapping tables. Returns 1 if the * mapping has been processes and the PDU should be proxied to the * remote RADIUS server, otherwise if it is a duplicate returns 0. */static int update_tables(RADIUS_PDU *pdu){ Octstr *client_ip, *msisdn; Octstr *type, *session_id; int ret = 0; Octstr *rm_item; client_ip = msisdn = type = session_id = NULL; /* only add if we have a Accounting-Request PDU */ if (pdu->type == 0x04) { /* check if we have a START or STOP event */ type = dict_get(pdu->attr, octstr_imm("Acct-Status-Type")); /* get the sesion id */ session_id = dict_get(pdu->attr, octstr_imm("Acct-Session-Id")); /* grep the needed data */ client_ip = dict_get(pdu->attr, octstr_imm("Framed-IP-Address")); msisdn = dict_get(pdu->attr, octstr_imm("Calling-Station-Id")); /* we can't add mapping without both components */ if (client_ip == NULL || msisdn == NULL) { warning(0, "RADIUS: NAS did either not send 'Framed-IP-Address' or/and " "'Calling-Station-Id', dropping mapping but will forward."); /* anyway forward the packet to remote RADIUS server */ return 1; } if (octstr_compare(type, octstr_imm("1")) == 0 && session_id && msisdn) { /* session START */ if (dict_get(radius_table, client_ip) == NULL && dict_get(session_table, session_id) == NULL) { Octstr *put_msisdn = octstr_duplicate(msisdn); Octstr *put_client_ip = octstr_duplicate(client_ip); Octstr *put_session_id = octstr_duplicate(session_id); Octstr *old_session_id, *old_client_ip; /* ok, this is a new session. If it contains an IP that is still * in the session/client tables then remove the old session from the * two tables session/client */ if ((old_session_id = dict_get(client_table, client_ip)) != NULL && (old_client_ip = dict_get(session_table, old_session_id)) != NULL && octstr_compare(old_session_id, session_id) != 0) { rm_item = dict_remove(client_table, client_ip); octstr_destroy(rm_item); rm_item = dict_remove(session_table, old_session_id); octstr_destroy(rm_item); octstr_destroy(old_session_id); octstr_destroy(old_client_ip); } /* insert both, new client IP and session to mapping tables */ dict_put(radius_table, client_ip, put_msisdn); dict_put(session_table, session_id, put_client_ip); dict_put(client_table, client_ip, put_session_id); info(0, "RADIUS: Mapping `%s <-> %s' for session id <%s> added.", octstr_get_cstr(client_ip), octstr_get_cstr(msisdn), octstr_get_cstr(session_id)); ret = 1; } else { warning(0, "RADIUS: Duplicate mapping `%s <-> %s' for session " "id <%s> received, ignoring.", octstr_get_cstr(client_ip), octstr_get_cstr(msisdn), octstr_get_cstr(session_id)); } } else if (octstr_compare(type, octstr_imm("2")) == 0) { /* session STOP */ Octstr *comp_client_ip; if ((msisdn = dict_get(radius_table, client_ip)) != NULL && (comp_client_ip = dict_get(session_table, session_id)) != NULL && octstr_compare(client_ip, comp_client_ip) == 0) { dict_remove(radius_table, client_ip); rm_item = dict_remove(client_table, client_ip); octstr_destroy(rm_item); dict_remove(session_table, session_id); info(0, "RADIUS: Mapping `%s <-> %s' for session id <%s> removed.", octstr_get_cstr(client_ip), octstr_get_cstr(msisdn), octstr_get_cstr(session_id)); octstr_destroy(msisdn); octstr_destroy(comp_client_ip); ret = 1; } else { warning(0, "RADIUS: Could not find mapping for `%s' session " "id <%s>, ignoring.", octstr_get_cstr(client_ip), octstr_get_cstr(session_id)); } } else { error(0, "RADIUS: unknown Acct-Status-Type `%s' received, ignoring.", octstr_get_cstr(type)); } } return ret;}/************************************************************************* * The main proxy thread. */static void proxy_thread(void *arg){ int ss, cs; /* server and client sockets */ int fl; /* socket flags */ Octstr *addr = NULL; int forward; Octstr *tmp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -