alias_sctp.c (186543) | alias_sctp.c (188294) |
---|---|
1//* $Id$ */ 2//#ifndef lint 3//static char vcid[] = "$Id$"; 4//#endif /* lint */ | |
5/** 6 * @file alias_sctp.c 7 * Copyright (c) 2008, Centre for Advanced Internet Architectures 8 * Swinburne University of Technology, Melbourne, Australia 9 * (CRICOS number 00111D). 10 * | 1/** 2 * @file alias_sctp.c 3 * Copyright (c) 2008, Centre for Advanced Internet Architectures 4 * Swinburne University of Technology, Melbourne, Australia 5 * (CRICOS number 00111D). 6 * |
11 * Alias_sctp forms part of the libalias kernel module to handle 12 * Network Address Translation (NAT) for the SCTP protocol. 13 * 14 * This software was developed by David A. Hayes and Jason But 15 * 16 * The design is outlined in CAIA technical report number 080618A 17 * (D. Hayes and J. But, "Alias_sctp Version 0.1: SCTP NAT implementation in IPFW") 18 * 19 * Development is part of the CAIA SONATA project, 20 * proposed by Jason But and Grenville Armitage: 21 * http://caia.swin.edu.au/urp/sonata/ 22 * 23 * 24 * This project has been made possible in part by a grant from 25 * the Cisco University Research Program Fund at Community 26 * Foundation Silicon Valley. 27 * 28 * 29 * 30 * All rights reserved. 31 * | |
32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 1. Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in the 39 * documentation and/or other materials provided with the distribution. --- 9 unchanged lines hidden (view full) --- 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55 * SUCH DAMAGE. 56 * | 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. --- 9 unchanged lines hidden (view full) --- 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * |
32 * Alias_sctp forms part of the libalias kernel module to handle 33 * Network Address Translation (NAT) for the SCTP protocol. 34 * 35 * This software was developed by David A. Hayes and Jason But 36 * 37 * The design is outlined in CAIA technical report number 080618A 38 * (D. Hayes and J. But, "Alias_sctp Version 0.1: SCTP NAT implementation in IPFW") 39 * 40 * Development is part of the CAIA SONATA project, 41 * proposed by Jason But and Grenville Armitage: 42 * http://caia.swin.edu.au/urp/sonata/ 43 * 44 * 45 * This project has been made possible in part by a grant from 46 * the Cisco University Research Program Fund at Community 47 * Foundation Silicon Valley. 48 * |
|
57 */ 58/** @mainpage 59 * Alias_sctp is part of the SONATA (http://caia.swin.edu.au/urp/sonata) project 60 * to develop and release a BSD licensed implementation of a Network Address 61 * Translation (NAT) module that supports the Stream Control Transmission 62 * Protocol (SCTP). 63 * 64 * Traditional address and port number look ups are inadequate for SCTP's --- 10 unchanged lines hidden (view full) --- 75 * - Generation and delivery of AbortM/ErrorM packets upon detection of NAT 76 * collisions 77 * - Per-port forwarding rules 78 * - Dynamically controllable logging and statistics 79 * - Dynamic management of timers 80 * - Dynamic control of hash-table size 81 */ 82 | 49 */ 50/** @mainpage 51 * Alias_sctp is part of the SONATA (http://caia.swin.edu.au/urp/sonata) project 52 * to develop and release a BSD licensed implementation of a Network Address 53 * Translation (NAT) module that supports the Stream Control Transmission 54 * Protocol (SCTP). 55 * 56 * Traditional address and port number look ups are inadequate for SCTP's --- 10 unchanged lines hidden (view full) --- 67 * - Generation and delivery of AbortM/ErrorM packets upon detection of NAT 68 * collisions 69 * - Per-port forwarding rules 70 * - Dynamically controllable logging and statistics 71 * - Dynamic management of timers 72 * - Dynamic control of hash-table size 73 */ 74 |
75/* $FreeBSD: head/sys/netinet/libalias/alias_sctp.c 188294 2009-02-07 18:49:42Z piso $ */ 76 |
|
83#ifdef _KERNEL 84#include <machine/stdarg.h> 85#include <sys/param.h> 86#include <sys/systm.h> 87#include <sys/kernel.h> 88#include <sys/module.h> 89#include <sys/syslog.h> 90#include <netinet/libalias/alias_sctp.h> --- 11 unchanged lines hidden (view full) --- 102#endif //#ifdef _KERNEL 103 104/* ---------------------------------------------------------------------- 105 * FUNCTION PROTOTYPES 106 * ---------------------------------------------------------------------- 107 */ 108/* Packet Parsing Functions */ 109static int sctp_PktParser(struct libalias *la, int direction, struct ip *pip, | 77#ifdef _KERNEL 78#include <machine/stdarg.h> 79#include <sys/param.h> 80#include <sys/systm.h> 81#include <sys/kernel.h> 82#include <sys/module.h> 83#include <sys/syslog.h> 84#include <netinet/libalias/alias_sctp.h> --- 11 unchanged lines hidden (view full) --- 96#endif //#ifdef _KERNEL 97 98/* ---------------------------------------------------------------------- 99 * FUNCTION PROTOTYPES 100 * ---------------------------------------------------------------------- 101 */ 102/* Packet Parsing Functions */ 103static int sctp_PktParser(struct libalias *la, int direction, struct ip *pip, |
110 struct sctp_nat_msg *sm, struct sctp_nat_assoc **passoc); | 104 struct sctp_nat_msg *sm, struct sctp_nat_assoc **passoc); |
111static int GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, | 105static int GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, |
112 uint32_t *l_vtag, uint32_t *g_vtag, int direction); | 106 uint32_t *l_vtag, uint32_t *g_vtag, int direction); |
113static int IsASCONFack(struct libalias *la, struct sctp_nat_msg *sm, int direction); 114 115static void AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction); 116static int Add_Global_Address_to_List(struct sctp_nat_assoc *assoc, struct sctp_GlobalAddress *G_addr); 117static void RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction); 118static int IsADDorDEL(struct libalias *la, struct sctp_nat_msg *sm, int direction); 119 120/* State Machine Functions */ 121static int ProcessSctpMsg(struct libalias *la, int direction, \ | 107static int IsASCONFack(struct libalias *la, struct sctp_nat_msg *sm, int direction); 108 109static void AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction); 110static int Add_Global_Address_to_List(struct sctp_nat_assoc *assoc, struct sctp_GlobalAddress *G_addr); 111static void RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction); 112static int IsADDorDEL(struct libalias *la, struct sctp_nat_msg *sm, int direction); 113 114/* State Machine Functions */ 115static int ProcessSctpMsg(struct libalias *la, int direction, \ |
122 struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc); | 116 struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc); |
123 124static int ID_process(struct libalias *la, int direction,\ | 117 118static int ID_process(struct libalias *la, int direction,\ |
125 struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); | 119 struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); |
126static int INi_process(struct libalias *la, int direction,\ | 120static int INi_process(struct libalias *la, int direction,\ |
127 struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); | 121 struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); |
128static int INa_process(struct libalias *la, int direction,\ | 122static int INa_process(struct libalias *la, int direction,\ |
129 struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); | 123 struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); |
130static int UP_process(struct libalias *la, int direction,\ | 124static int UP_process(struct libalias *la, int direction,\ |
131 struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); | 125 struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); |
132static int CL_process(struct libalias *la, int direction,\ | 126static int CL_process(struct libalias *la, int direction,\ |
133 struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); | 127 struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); |
134static void TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm,\ | 128static void TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm,\ |
135 struct sctp_nat_assoc *assoc, int sndrply, int direction); | 129 struct sctp_nat_assoc *assoc, int sndrply, int direction); |
136 137/* Hash Table Functions */ 138static struct sctp_nat_assoc* 139FindSctpLocal(struct libalias *la, struct in_addr l_addr, struct in_addr g_addr, uint32_t l_vtag, uint16_t l_port, uint16_t g_port); 140static struct sctp_nat_assoc* 141FindSctpGlobal(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint16_t g_port, uint16_t l_port, int *partial_match); 142static struct sctp_nat_assoc* 143FindSctpGlobalClash(struct libalias *la, struct sctp_nat_assoc *Cassoc); --- 40 unchanged lines hidden (view full) --- 184 * 185 * Calls the higher level ShowAliasStats() in alias_db.c which logs all current 186 * statistics about the libalias instance - including SCTP statistics 187 * 188 * @param la Pointer to the libalias instance 189 */ 190void SctpShowAliasStats(struct libalias *la); 191 | 130 131/* Hash Table Functions */ 132static struct sctp_nat_assoc* 133FindSctpLocal(struct libalias *la, struct in_addr l_addr, struct in_addr g_addr, uint32_t l_vtag, uint16_t l_port, uint16_t g_port); 134static struct sctp_nat_assoc* 135FindSctpGlobal(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint16_t g_port, uint16_t l_port, int *partial_match); 136static struct sctp_nat_assoc* 137FindSctpGlobalClash(struct libalias *la, struct sctp_nat_assoc *Cassoc); --- 40 unchanged lines hidden (view full) --- 178 * 179 * Calls the higher level ShowAliasStats() in alias_db.c which logs all current 180 * statistics about the libalias instance - including SCTP statistics 181 * 182 * @param la Pointer to the libalias instance 183 */ 184void SctpShowAliasStats(struct libalias *la); 185 |
192/** @ingroup external 193 * @brief Find the address to redirect incoming packets 194 * 195 * This function is defined in alias_db.c, since it calls static functions in 196 * this file 197 * 198 * Given a destination port for incoming packets to the NAT, discover what 199 * (if any) internal IP address this packet should be re-directed to 200 * 201 * @param la Pointer to the libalias instance 202 * @param sm Pointer to the incoming message 203 * 204 * @return Address to redirect an incoming INIT to 205 */ 206struct in_addr FindSctpRedirectAddress(struct libalias *la, struct sctp_nat_msg *sm); 207 | |
208#ifdef _KERNEL 209 210MALLOC_DEFINE(M_SCTPNAT, "sctpnat", "sctp nat dbs"); 211/* Use kernel allocator. */ 212#ifdef _SYS_MALLOC_H_ 213#define sn_malloc(x) malloc(x, M_SCTPNAT, M_NOWAIT|M_ZERO) 214#define sn_calloc(n,x) sn_malloc(x * n) 215#define sn_free(x) free(x, M_SCTPNAT) --- 143 unchanged lines hidden (view full) --- 359/** @brief net.inet.ip.alias.sctp.shutdown_timer */ 360static u_int sysctl_shutdown_timer = 15; /**< Seconds to hold an association in the table waiting for a SHUTDOWN-COMPLETE */ 361/** @brief net.inet.ip.alias.sctp.holddown_timer */ 362static u_int sysctl_holddown_timer = 0; /**< Seconds to hold an association in the table after it has been shutdown (to allow for lost SHUTDOWN-COMPLETEs) */ 363/** @brief net.inet.ip.alias.sctp.hashtable_size */ 364static u_int sysctl_hashtable_size = SN_DEFAULT_HASH_SIZE; /**< Sets the hash table size for any NEW NAT instances (existing instances retain their existing Hash Table */ 365/** @brief net.inet.ip.alias.sctp.error_on_ootb */ 366static u_int sysctl_error_on_ootb = 1; /**< NAT response to receipt of OOTB packet | 186#ifdef _KERNEL 187 188MALLOC_DEFINE(M_SCTPNAT, "sctpnat", "sctp nat dbs"); 189/* Use kernel allocator. */ 190#ifdef _SYS_MALLOC_H_ 191#define sn_malloc(x) malloc(x, M_SCTPNAT, M_NOWAIT|M_ZERO) 192#define sn_calloc(n,x) sn_malloc(x * n) 193#define sn_free(x) free(x, M_SCTPNAT) --- 143 unchanged lines hidden (view full) --- 337/** @brief net.inet.ip.alias.sctp.shutdown_timer */ 338static u_int sysctl_shutdown_timer = 15; /**< Seconds to hold an association in the table waiting for a SHUTDOWN-COMPLETE */ 339/** @brief net.inet.ip.alias.sctp.holddown_timer */ 340static u_int sysctl_holddown_timer = 0; /**< Seconds to hold an association in the table after it has been shutdown (to allow for lost SHUTDOWN-COMPLETEs) */ 341/** @brief net.inet.ip.alias.sctp.hashtable_size */ 342static u_int sysctl_hashtable_size = SN_DEFAULT_HASH_SIZE; /**< Sets the hash table size for any NEW NAT instances (existing instances retain their existing Hash Table */ 343/** @brief net.inet.ip.alias.sctp.error_on_ootb */ 344static u_int sysctl_error_on_ootb = 1; /**< NAT response to receipt of OOTB packet |
367 (0 - No response, 1 - NAT will send ErrorM only to local side, 368 2 - NAT will send local ErrorM and global ErrorM if there was a partial association match 369 3 - NAT will send ErrorM to both local and global) */ | 345 (0 - No response, 1 - NAT will send ErrorM only to local side, 346 2 - NAT will send local ErrorM and global ErrorM if there was a partial association match 347 3 - NAT will send ErrorM to both local and global) */ |
370/** @brief net.inet.ip.alias.sctp.accept_global_ootb_addip */ 371static u_int sysctl_accept_global_ootb_addip = 0; /**<NAT responset to receipt of global OOTB AddIP (0 - No response, 1 - NAT will accept OOTB global AddIP messages for processing (Security risk)) */ 372/** @brief net.inet.ip.alias.sctp.initialising_chunk_proc_limit */ 373static u_int sysctl_initialising_chunk_proc_limit = 2; /**< A limit on the number of chunks that should be searched if there is no matching association (DoS prevention) */ 374/** @brief net.inet.ip.alias.sctp.param_proc_limit */ 375static u_int sysctl_chunk_proc_limit = 5; /**< A limit on the number of chunks that should be searched (DoS prevention) */ 376/** @brief net.inet.ip.alias.sctp.param_proc_limit */ 377static u_int sysctl_param_proc_limit = 25; /**< A limit on the number of parameters (in chunks) that should be searched (DoS prevention) */ 378/** @brief net.inet.ip.alias.sctp.track_global_addresses */ 379static u_int sysctl_track_global_addresses = 0; /**< Configures the global address tracking option within the NAT (0 - Global tracking is disabled, > 0 - enables tracking but limits the number of global IP addresses to this value) | 348/** @brief net.inet.ip.alias.sctp.accept_global_ootb_addip */ 349static u_int sysctl_accept_global_ootb_addip = 0; /**<NAT responset to receipt of global OOTB AddIP (0 - No response, 1 - NAT will accept OOTB global AddIP messages for processing (Security risk)) */ 350/** @brief net.inet.ip.alias.sctp.initialising_chunk_proc_limit */ 351static u_int sysctl_initialising_chunk_proc_limit = 2; /**< A limit on the number of chunks that should be searched if there is no matching association (DoS prevention) */ 352/** @brief net.inet.ip.alias.sctp.param_proc_limit */ 353static u_int sysctl_chunk_proc_limit = 5; /**< A limit on the number of chunks that should be searched (DoS prevention) */ 354/** @brief net.inet.ip.alias.sctp.param_proc_limit */ 355static u_int sysctl_param_proc_limit = 25; /**< A limit on the number of parameters (in chunks) that should be searched (DoS prevention) */ 356/** @brief net.inet.ip.alias.sctp.track_global_addresses */ 357static u_int sysctl_track_global_addresses = 0; /**< Configures the global address tracking option within the NAT (0 - Global tracking is disabled, > 0 - enables tracking but limits the number of global IP addresses to this value) |
380 If set to >=1 the NAT will track that many global IP addresses. This may reduce look up table conflicts, but increases processing */ | 358 If set to >=1 the NAT will track that many global IP addresses. This may reduce look up table conflicts, but increases processing */ |
381 382#define SN_NO_ERROR_ON_OOTB 0 /**< Send no errorM on out of the blue packets */ 383#define SN_LOCAL_ERROR_ON_OOTB 1 /**< Send only local errorM on out of the blue packets */ 384#define SN_LOCALandPARTIAL_ERROR_ON_OOTB 2 /**< Send local errorM and global errorM for out of the blue packets only if partial match found */ 385#define SN_ERROR_ON_OOTB 3 /**< Send errorM on out of the blue packets */ 386 387#ifdef SYSCTL_NODE 388 389SYSCTL_DECL(_net_inet); 390SYSCTL_DECL(_net_inet_ip); 391SYSCTL_DECL(_net_inet_ip_alias); 392 393SYSCTL_NODE(_net_inet_ip_alias, OID_AUTO, sctp, CTLFLAG_RW, NULL, "SCTP NAT"); 394 395SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, log_level, CTLTYPE_UINT | CTLFLAG_RW, | 359 360#define SN_NO_ERROR_ON_OOTB 0 /**< Send no errorM on out of the blue packets */ 361#define SN_LOCAL_ERROR_ON_OOTB 1 /**< Send only local errorM on out of the blue packets */ 362#define SN_LOCALandPARTIAL_ERROR_ON_OOTB 2 /**< Send local errorM and global errorM for out of the blue packets only if partial match found */ 363#define SN_ERROR_ON_OOTB 3 /**< Send errorM on out of the blue packets */ 364 365#ifdef SYSCTL_NODE 366 367SYSCTL_DECL(_net_inet); 368SYSCTL_DECL(_net_inet_ip); 369SYSCTL_DECL(_net_inet_ip_alias); 370 371SYSCTL_NODE(_net_inet_ip_alias, OID_AUTO, sctp, CTLFLAG_RW, NULL, "SCTP NAT"); 372 373SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, log_level, CTLTYPE_UINT | CTLFLAG_RW, |
396 &sysctl_log_level, 0, sysctl_chg_loglevel, "IU", 397 "Level of detail (0 - default, 1 - event, 2 - info, 3 - detail, 4 - debug, 5 - max debug)"); | 374 &sysctl_log_level, 0, sysctl_chg_loglevel, "IU", 375 "Level of detail (0 - default, 1 - event, 2 - info, 3 - detail, 4 - debug, 5 - max debug)"); |
398SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, init_timer, CTLTYPE_UINT | CTLFLAG_RW, | 376SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, init_timer, CTLTYPE_UINT | CTLFLAG_RW, |
399 &sysctl_init_timer, 0, sysctl_chg_timer, "IU", 400 "Timeout value (s) while waiting for (INIT-ACK|AddIP-ACK)"); | 377 &sysctl_init_timer, 0, sysctl_chg_timer, "IU", 378 "Timeout value (s) while waiting for (INIT-ACK|AddIP-ACK)"); |
401SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, up_timer, CTLTYPE_UINT | CTLFLAG_RW, | 379SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, up_timer, CTLTYPE_UINT | CTLFLAG_RW, |
402 &sysctl_up_timer, 0, sysctl_chg_timer, "IU", 403 "Timeout value (s) to keep an association up with no traffic"); | 380 &sysctl_up_timer, 0, sysctl_chg_timer, "IU", 381 "Timeout value (s) to keep an association up with no traffic"); |
404SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, shutdown_timer, CTLTYPE_UINT | CTLFLAG_RW, | 382SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, shutdown_timer, CTLTYPE_UINT | CTLFLAG_RW, |
405 &sysctl_shutdown_timer, 0, sysctl_chg_timer, "IU", 406 "Timeout value (s) while waiting for SHUTDOWN-COMPLETE"); | 383 &sysctl_shutdown_timer, 0, sysctl_chg_timer, "IU", 384 "Timeout value (s) while waiting for SHUTDOWN-COMPLETE"); |
407SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, holddown_timer, CTLTYPE_UINT | CTLFLAG_RW, | 385SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, holddown_timer, CTLTYPE_UINT | CTLFLAG_RW, |
408 &sysctl_holddown_timer, 0, sysctl_chg_timer, "IU", 409 "Hold association in table for this many seconds after receiving a SHUTDOWN-COMPLETE"); | 386 &sysctl_holddown_timer, 0, sysctl_chg_timer, "IU", 387 "Hold association in table for this many seconds after receiving a SHUTDOWN-COMPLETE"); |
410SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, hashtable_size, CTLTYPE_UINT | CTLFLAG_RW, | 388SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, hashtable_size, CTLTYPE_UINT | CTLFLAG_RW, |
411 &sysctl_hashtable_size, 0, sysctl_chg_hashtable_size, "IU", 412 "Size of hash tables used for NAT lookups (100 < prime_number > 1000001)"); | 389 &sysctl_hashtable_size, 0, sysctl_chg_hashtable_size, "IU", 390 "Size of hash tables used for NAT lookups (100 < prime_number > 1000001)"); |
413SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, error_on_ootb, CTLTYPE_UINT | CTLFLAG_RW, | 391SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, error_on_ootb, CTLTYPE_UINT | CTLFLAG_RW, |
414 &sysctl_error_on_ootb, 0, sysctl_chg_error_on_ootb, "IU", 415 "ErrorM sent on receipt of ootb packet:\n\t0 - none,\n\t1 - to local only,\n\t2 - to local and global if a partial association match,\n\t3 - to local and global (DoS risk)"); | 392 &sysctl_error_on_ootb, 0, sysctl_chg_error_on_ootb, "IU", 393 "ErrorM sent on receipt of ootb packet:\n\t0 - none,\n\t1 - to local only,\n\t2 - to local and global if a partial association match,\n\t3 - to local and global (DoS risk)"); |
416SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, accept_global_ootb_addip, CTLTYPE_UINT | CTLFLAG_RW, | 394SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, accept_global_ootb_addip, CTLTYPE_UINT | CTLFLAG_RW, |
417 &sysctl_accept_global_ootb_addip, 0, sysctl_chg_accept_global_ootb_addip, "IU", 418 "NAT response to receipt of global OOTB AddIP:\n\t0 - No response,\n\t1 - NAT will accept OOTB global AddIP messages for processing (Security risk)"); | 395 &sysctl_accept_global_ootb_addip, 0, sysctl_chg_accept_global_ootb_addip, "IU", 396 "NAT response to receipt of global OOTB AddIP:\n\t0 - No response,\n\t1 - NAT will accept OOTB global AddIP messages for processing (Security risk)"); |
419SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, initialising_chunk_proc_limit, CTLTYPE_UINT | CTLFLAG_RW, | 397SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, initialising_chunk_proc_limit, CTLTYPE_UINT | CTLFLAG_RW, |
420 &sysctl_initialising_chunk_proc_limit, 0, sysctl_chg_initialising_chunk_proc_limit, "IU", 421 "Number of chunks that should be processed if there is no current association found:\n\t > 0 (A high value is a DoS risk)"); | 398 &sysctl_initialising_chunk_proc_limit, 0, sysctl_chg_initialising_chunk_proc_limit, "IU", 399 "Number of chunks that should be processed if there is no current association found:\n\t > 0 (A high value is a DoS risk)"); |
422SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, chunk_proc_limit, CTLTYPE_UINT | CTLFLAG_RW, | 400SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, chunk_proc_limit, CTLTYPE_UINT | CTLFLAG_RW, |
423 &sysctl_chunk_proc_limit, 0, sysctl_chg_chunk_proc_limit, "IU", 424 "Number of chunks that should be processed to find key chunk:\n\t>= initialising_chunk_proc_limit (A high value is a DoS risk)"); | 401 &sysctl_chunk_proc_limit, 0, sysctl_chg_chunk_proc_limit, "IU", 402 "Number of chunks that should be processed to find key chunk:\n\t>= initialising_chunk_proc_limit (A high value is a DoS risk)"); |
425SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, param_proc_limit, CTLTYPE_UINT | CTLFLAG_RW, | 403SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, param_proc_limit, CTLTYPE_UINT | CTLFLAG_RW, |
426 &sysctl_param_proc_limit, 0, sysctl_chg_param_proc_limit, "IU", 427 "Number of parameters (in a chunk) that should be processed to find key parameters:\n\t> 1 (A high value is a DoS risk)"); | 404 &sysctl_param_proc_limit, 0, sysctl_chg_param_proc_limit, "IU", 405 "Number of parameters (in a chunk) that should be processed to find key parameters:\n\t> 1 (A high value is a DoS risk)"); |
428SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, track_global_addresses, CTLTYPE_UINT | CTLFLAG_RW, | 406SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, track_global_addresses, CTLTYPE_UINT | CTLFLAG_RW, |
429 &sysctl_track_global_addresses, 0, sysctl_chg_track_global_addresses, "IU", 430 "Configures the global address tracking option within the NAT:\n\t0 - Global tracking is disabled,\n\t> 0 - enables tracking but limits the number of global IP addresses to this value"); | 407 &sysctl_track_global_addresses, 0, sysctl_chg_track_global_addresses, "IU", 408 "Configures the global address tracking option within the NAT:\n\t0 - Global tracking is disabled,\n\t> 0 - enables tracking but limits the number of global IP addresses to this value"); |
431 432#endif /* SYSCTL_NODE */ 433 434/** @} 435 * @ingroup sysctl 436 * @brief sysctl callback for changing net.inet.ip.fw.sctp.log_level 437 * 438 * Updates the variable sysctl_log_level to the provided value and ensures 439 * it is in the valid range (SN_LOG_LOW -> SN_LOG_DEBUG) 440 */ 441int sysctl_chg_loglevel(SYSCTL_HANDLER_ARGS) 442{ | 409 410#endif /* SYSCTL_NODE */ 411 412/** @} 413 * @ingroup sysctl 414 * @brief sysctl callback for changing net.inet.ip.fw.sctp.log_level 415 * 416 * Updates the variable sysctl_log_level to the provided value and ensures 417 * it is in the valid range (SN_LOG_LOW -> SN_LOG_DEBUG) 418 */ 419int sysctl_chg_loglevel(SYSCTL_HANDLER_ARGS) 420{ |
443 u_int level = *(u_int *)arg1; 444 int error; | 421 u_int level = *(u_int *)arg1; 422 int error; |
445 | 423 |
446 error = sysctl_handle_int(oidp, &level, 0, req); 447 if (error) return (error); | 424 error = sysctl_handle_int(oidp, &level, 0, req); 425 if (error) return (error); |
448 | 426 |
449 sysctl_log_level = (level > SN_LOG_DEBUG_MAX)?(SN_LOG_DEBUG_MAX):(level); 450 sysctl_log_level = (level < SN_LOG_LOW)?(SN_LOG_LOW):(level); | 427 sysctl_log_level = (level > SN_LOG_DEBUG_MAX)?(SN_LOG_DEBUG_MAX):(level); 428 sysctl_log_level = (level < SN_LOG_LOW)?(SN_LOG_LOW):(level); |
451 | 429 |
452 return (0); | 430 return (0); |
453} 454 455/** @ingroup sysctl 456 * @brief sysctl callback for changing net.inet.ip.fw.sctp.(init_timer|up_timer|shutdown_timer) 457 * 458 * Updates the timer-based sysctl variables. The new values are sanity-checked 459 * to make sure that they are within the range SN_MIN_TIMER-SN_MAX_TIMER. The 460 * holddown timer is allowed to be 0 461 */ 462int sysctl_chg_timer(SYSCTL_HANDLER_ARGS) 463{ | 431} 432 433/** @ingroup sysctl 434 * @brief sysctl callback for changing net.inet.ip.fw.sctp.(init_timer|up_timer|shutdown_timer) 435 * 436 * Updates the timer-based sysctl variables. The new values are sanity-checked 437 * to make sure that they are within the range SN_MIN_TIMER-SN_MAX_TIMER. The 438 * holddown timer is allowed to be 0 439 */ 440int sysctl_chg_timer(SYSCTL_HANDLER_ARGS) 441{ |
464 u_int timer = *(u_int *)arg1; 465 int error; | 442 u_int timer = *(u_int *)arg1; 443 int error; |
466 | 444 |
467 error = sysctl_handle_int(oidp, &timer, 0, req); 468 if (error) return (error); | 445 error = sysctl_handle_int(oidp, &timer, 0, req); 446 if (error) return (error); |
469 | 447 |
470 timer = (timer > SN_MAX_TIMER)?(SN_MAX_TIMER):(timer); | 448 timer = (timer > SN_MAX_TIMER)?(SN_MAX_TIMER):(timer); |
471 | 449 |
472 if (((u_int *)arg1) != &sysctl_holddown_timer) 473 { 474 timer = (timer < SN_MIN_TIMER)?(SN_MIN_TIMER):(timer); 475 } | 450 if (((u_int *)arg1) != &sysctl_holddown_timer) 451 { 452 timer = (timer < SN_MIN_TIMER)?(SN_MIN_TIMER):(timer); 453 } |
476 | 454 |
477 *(u_int *)arg1 = timer; | 455 *(u_int *)arg1 = timer; |
478 | 456 |
479 return (0); | 457 return (0); |
480} 481 482/** @ingroup sysctl 483 * @brief sysctl callback for changing net.inet.ip.alias.sctp.hashtable_size 484 * 485 * Updates the hashtable_size sysctl variable. The new value should be a prime 486 * number. We sanity check to ensure that the size is within the range 487 * SN_MIN_HASH_SIZE-SN_MAX_HASH_SIZE. We then check the provided number to see 488 * if it is prime. We approximate by checking that (2,3,5,7,11) are not factors, 489 * incrementing the user provided value until we find a suitable number. 490 */ 491int sysctl_chg_hashtable_size(SYSCTL_HANDLER_ARGS) 492{ | 458} 459 460/** @ingroup sysctl 461 * @brief sysctl callback for changing net.inet.ip.alias.sctp.hashtable_size 462 * 463 * Updates the hashtable_size sysctl variable. The new value should be a prime 464 * number. We sanity check to ensure that the size is within the range 465 * SN_MIN_HASH_SIZE-SN_MAX_HASH_SIZE. We then check the provided number to see 466 * if it is prime. We approximate by checking that (2,3,5,7,11) are not factors, 467 * incrementing the user provided value until we find a suitable number. 468 */ 469int sysctl_chg_hashtable_size(SYSCTL_HANDLER_ARGS) 470{ |
493 u_int size = *(u_int *)arg1; 494 int error; | 471 u_int size = *(u_int *)arg1; 472 int error; |
495 | 473 |
496 error = sysctl_handle_int(oidp, &size, 0, req); 497 if (error) return (error); | 474 error = sysctl_handle_int(oidp, &size, 0, req); 475 if (error) return (error); |
498 | 476 |
499 size = (size < SN_MIN_HASH_SIZE)?(SN_MIN_HASH_SIZE):((size > SN_MAX_HASH_SIZE)?(SN_MAX_HASH_SIZE):(size)); | 477 size = (size < SN_MIN_HASH_SIZE)?(SN_MIN_HASH_SIZE):((size > SN_MAX_HASH_SIZE)?(SN_MAX_HASH_SIZE):(size)); |
500 | 478 |
501 size |= 0x00000001; /* make odd */ | 479 size |= 0x00000001; /* make odd */ |
502 | 480 |
503 for(;(((size % 3) == 0) || ((size % 5) == 0) || ((size % 7) == 0) || ((size % 11) == 0)); size+=2); 504 sysctl_hashtable_size = size; | 481 for(;(((size % 3) == 0) || ((size % 5) == 0) || ((size % 7) == 0) || ((size % 11) == 0)); size+=2); 482 sysctl_hashtable_size = size; |
505 | 483 |
506 return (0); | 484 return (0); |
507} 508 509/** @ingroup sysctl 510 * @brief sysctl callback for changing net.inet.ip.alias.sctp.error_on_ootb 511 * 512 * Updates the error_on_clash sysctl variable. 513 * If set to 0, no ErrorM will be sent if there is a look up table clash 514 * If set to 1, an ErrorM is sent only to the local side 515 * If set to 2, an ErrorM is sent to the local side and global side if there is 516 * a partial association match 517 * If set to 3, an ErrorM is sent to both local and global sides (DoS) risk. 518 */ 519int sysctl_chg_error_on_ootb(SYSCTL_HANDLER_ARGS) 520{ | 485} 486 487/** @ingroup sysctl 488 * @brief sysctl callback for changing net.inet.ip.alias.sctp.error_on_ootb 489 * 490 * Updates the error_on_clash sysctl variable. 491 * If set to 0, no ErrorM will be sent if there is a look up table clash 492 * If set to 1, an ErrorM is sent only to the local side 493 * If set to 2, an ErrorM is sent to the local side and global side if there is 494 * a partial association match 495 * If set to 3, an ErrorM is sent to both local and global sides (DoS) risk. 496 */ 497int sysctl_chg_error_on_ootb(SYSCTL_HANDLER_ARGS) 498{ |
521 u_int flag = *(u_int *)arg1; 522 int error; | 499 u_int flag = *(u_int *)arg1; 500 int error; |
523 | 501 |
524 error = sysctl_handle_int(oidp, &flag, 0, req); 525 if (error) return (error); | 502 error = sysctl_handle_int(oidp, &flag, 0, req); 503 if (error) return (error); |
526 | 504 |
527 sysctl_error_on_ootb = (flag > SN_ERROR_ON_OOTB) ? SN_ERROR_ON_OOTB: flag; | 505 sysctl_error_on_ootb = (flag > SN_ERROR_ON_OOTB) ? SN_ERROR_ON_OOTB: flag; |
528 | 506 |
529 return (0); | 507 return (0); |
530} 531 532/** @ingroup sysctl 533 * @brief sysctl callback for changing net.inet.ip.alias.sctp.accept_global_ootb_addip 534 * 535 * If set to 1 the NAT will accept ootb global addip messages for processing (Security risk) 536 * Default is 0, only responding to local ootb AddIP messages 537 */ 538int sysctl_chg_accept_global_ootb_addip(SYSCTL_HANDLER_ARGS) 539{ | 508} 509 510/** @ingroup sysctl 511 * @brief sysctl callback for changing net.inet.ip.alias.sctp.accept_global_ootb_addip 512 * 513 * If set to 1 the NAT will accept ootb global addip messages for processing (Security risk) 514 * Default is 0, only responding to local ootb AddIP messages 515 */ 516int sysctl_chg_accept_global_ootb_addip(SYSCTL_HANDLER_ARGS) 517{ |
540 u_int flag = *(u_int *)arg1; 541 int error; | 518 u_int flag = *(u_int *)arg1; 519 int error; |
542 | 520 |
543 error = sysctl_handle_int(oidp, &flag, 0, req); 544 if (error) return (error); | 521 error = sysctl_handle_int(oidp, &flag, 0, req); 522 if (error) return (error); |
545 | 523 |
546 sysctl_accept_global_ootb_addip = (flag == 1) ? 1: 0; | 524 sysctl_accept_global_ootb_addip = (flag == 1) ? 1: 0; |
547 | 525 |
548 return (0); | 526 return (0); |
549} 550 551/** @ingroup sysctl 552 * @brief sysctl callback for changing net.inet.ip.alias.sctp.initialising_chunk_proc_limit 553 * 554 * Updates the initialising_chunk_proc_limit sysctl variable. Number of chunks 555 * that should be processed if there is no current association found: > 0 (A 556 * high value is a DoS risk) 557 */ 558int sysctl_chg_initialising_chunk_proc_limit(SYSCTL_HANDLER_ARGS) 559{ | 527} 528 529/** @ingroup sysctl 530 * @brief sysctl callback for changing net.inet.ip.alias.sctp.initialising_chunk_proc_limit 531 * 532 * Updates the initialising_chunk_proc_limit sysctl variable. Number of chunks 533 * that should be processed if there is no current association found: > 0 (A 534 * high value is a DoS risk) 535 */ 536int sysctl_chg_initialising_chunk_proc_limit(SYSCTL_HANDLER_ARGS) 537{ |
560 u_int proclimit = *(u_int *)arg1; 561 int error; | 538 u_int proclimit = *(u_int *)arg1; 539 int error; |
562 | 540 |
563 error = sysctl_handle_int(oidp, &proclimit, 0, req); 564 if (error) return (error); | 541 error = sysctl_handle_int(oidp, &proclimit, 0, req); 542 if (error) return (error); |
565 | 543 |
566 sysctl_initialising_chunk_proc_limit = (proclimit < 1) ? 1: proclimit; 567 sysctl_chunk_proc_limit = 568 (sysctl_chunk_proc_limit < sysctl_initialising_chunk_proc_limit) ? sysctl_initialising_chunk_proc_limit : sysctl_chunk_proc_limit; | 544 sysctl_initialising_chunk_proc_limit = (proclimit < 1) ? 1: proclimit; 545 sysctl_chunk_proc_limit = 546 (sysctl_chunk_proc_limit < sysctl_initialising_chunk_proc_limit) ? sysctl_initialising_chunk_proc_limit : sysctl_chunk_proc_limit; |
569 | 547 |
570 return (0); | 548 return (0); |
571} 572 573/** @ingroup sysctl 574 * @brief sysctl callback for changing net.inet.ip.alias.sctp.chunk_proc_limit 575 * 576 * Updates the chunk_proc_limit sysctl variable. 577 * Number of chunks that should be processed to find key chunk: 578 * >= initialising_chunk_proc_limit (A high value is a DoS risk) 579 */ 580int sysctl_chg_chunk_proc_limit(SYSCTL_HANDLER_ARGS) 581{ | 549} 550 551/** @ingroup sysctl 552 * @brief sysctl callback for changing net.inet.ip.alias.sctp.chunk_proc_limit 553 * 554 * Updates the chunk_proc_limit sysctl variable. 555 * Number of chunks that should be processed to find key chunk: 556 * >= initialising_chunk_proc_limit (A high value is a DoS risk) 557 */ 558int sysctl_chg_chunk_proc_limit(SYSCTL_HANDLER_ARGS) 559{ |
582 u_int proclimit = *(u_int *)arg1; 583 int error; | 560 u_int proclimit = *(u_int *)arg1; 561 int error; |
584 | 562 |
585 error = sysctl_handle_int(oidp, &proclimit, 0, req); 586 if (error) return (error); | 563 error = sysctl_handle_int(oidp, &proclimit, 0, req); 564 if (error) return (error); |
587 | 565 |
588 sysctl_chunk_proc_limit = 589 (proclimit < sysctl_initialising_chunk_proc_limit) ? sysctl_initialising_chunk_proc_limit : proclimit; | 566 sysctl_chunk_proc_limit = 567 (proclimit < sysctl_initialising_chunk_proc_limit) ? sysctl_initialising_chunk_proc_limit : proclimit; |
590 | 568 |
591 return (0); | 569 return (0); |
592} 593 594 595/** @ingroup sysctl 596 * @brief sysctl callback for changing net.inet.ip.alias.sctp.param_proc_limit 597 * 598 * Updates the param_proc_limit sysctl variable. 599 * Number of parameters that should be processed to find key parameters: 600 * > 1 (A high value is a DoS risk) 601 */ 602int sysctl_chg_param_proc_limit(SYSCTL_HANDLER_ARGS) 603{ | 570} 571 572 573/** @ingroup sysctl 574 * @brief sysctl callback for changing net.inet.ip.alias.sctp.param_proc_limit 575 * 576 * Updates the param_proc_limit sysctl variable. 577 * Number of parameters that should be processed to find key parameters: 578 * > 1 (A high value is a DoS risk) 579 */ 580int sysctl_chg_param_proc_limit(SYSCTL_HANDLER_ARGS) 581{ |
604 u_int proclimit = *(u_int *)arg1; 605 int error; | 582 u_int proclimit = *(u_int *)arg1; 583 int error; |
606 | 584 |
607 error = sysctl_handle_int(oidp, &proclimit, 0, req); 608 if (error) return (error); | 585 error = sysctl_handle_int(oidp, &proclimit, 0, req); 586 if (error) return (error); |
609 | 587 |
610 sysctl_param_proc_limit = 611 (proclimit < 2) ? 2 : proclimit; | 588 sysctl_param_proc_limit = 589 (proclimit < 2) ? 2 : proclimit; |
612 | 590 |
613 return (0); | 591 return (0); |
614} 615 616/** @ingroup sysctl 617 * @brief sysctl callback for changing net.inet.ip.alias.sctp.track_global_addresses 618 * 619 *Configures the global address tracking option within the NAT (0 - Global 620 *tracking is disabled, > 0 - enables tracking but limits the number of global 621 *IP addresses to this value) 622 */ 623int sysctl_chg_track_global_addresses(SYSCTL_HANDLER_ARGS) 624{ | 592} 593 594/** @ingroup sysctl 595 * @brief sysctl callback for changing net.inet.ip.alias.sctp.track_global_addresses 596 * 597 *Configures the global address tracking option within the NAT (0 - Global 598 *tracking is disabled, > 0 - enables tracking but limits the number of global 599 *IP addresses to this value) 600 */ 601int sysctl_chg_track_global_addresses(SYSCTL_HANDLER_ARGS) 602{ |
625 u_int num_to_track = *(u_int *)arg1; 626 int error; | 603 u_int num_to_track = *(u_int *)arg1; 604 int error; |
627 | 605 |
628 error = sysctl_handle_int(oidp, &num_to_track, 0, req); 629 if (error) return (error); | 606 error = sysctl_handle_int(oidp, &num_to_track, 0, req); 607 if (error) return (error); |
630 | 608 |
631 sysctl_track_global_addresses = (num_to_track > SN_MAX_GLOBAL_ADDRESSES) ? SN_MAX_GLOBAL_ADDRESSES : num_to_track; | 609 sysctl_track_global_addresses = (num_to_track > SN_MAX_GLOBAL_ADDRESSES) ? SN_MAX_GLOBAL_ADDRESSES : num_to_track; |
632 | 610 |
633 return (0); | 611 return (0); |
634} 635 636 637/* ---------------------------------------------------------------------- 638 * CODE BEGINS HERE 639 * ---------------------------------------------------------------------- 640 */ 641/** 642 * @brief Initialises the SCTP NAT Implementation 643 * 644 * Creates the look-up tables and the timer queue and initialises all state 645 * variables 646 * 647 * @param la Pointer to the relevant libalias instance 648 */ 649void AliasSctpInit(struct libalias *la) 650{ | 612} 613 614 615/* ---------------------------------------------------------------------- 616 * CODE BEGINS HERE 617 * ---------------------------------------------------------------------- 618 */ 619/** 620 * @brief Initialises the SCTP NAT Implementation 621 * 622 * Creates the look-up tables and the timer queue and initialises all state 623 * variables 624 * 625 * @param la Pointer to the relevant libalias instance 626 */ 627void AliasSctpInit(struct libalias *la) 628{ |
651 /* Initialise association tables*/ 652 int i; 653 la->sctpNatTableSize = sysctl_hashtable_size; 654 SN_LOG(SN_LOG_EVENT, 655 SctpAliasLog("Initialising SCTP NAT Instance (hash_table_size:%d)\n", la->sctpNatTableSize)); 656 la->sctpTableLocal = sn_calloc(la->sctpNatTableSize, sizeof(struct sctpNatTableL)); 657 la->sctpTableGlobal = sn_calloc(la->sctpNatTableSize, sizeof(struct sctpNatTableG)); 658 la->sctpNatTimer.TimerQ = sn_calloc(SN_TIMER_QUEUE_SIZE, sizeof(struct sctpTimerQ)); 659 /* Initialise hash table */ 660 for (i = 0; i < la->sctpNatTableSize; i++) { 661 LIST_INIT(&la->sctpTableLocal[i]); 662 LIST_INIT(&la->sctpTableGlobal[i]); 663 } | 629 /* Initialise association tables*/ 630 int i; 631 la->sctpNatTableSize = sysctl_hashtable_size; 632 SN_LOG(SN_LOG_EVENT, 633 SctpAliasLog("Initialising SCTP NAT Instance (hash_table_size:%d)\n", la->sctpNatTableSize)); 634 la->sctpTableLocal = sn_calloc(la->sctpNatTableSize, sizeof(struct sctpNatTableL)); 635 la->sctpTableGlobal = sn_calloc(la->sctpNatTableSize, sizeof(struct sctpNatTableG)); 636 la->sctpNatTimer.TimerQ = sn_calloc(SN_TIMER_QUEUE_SIZE, sizeof(struct sctpTimerQ)); 637 /* Initialise hash table */ 638 for (i = 0; i < la->sctpNatTableSize; i++) { 639 LIST_INIT(&la->sctpTableLocal[i]); 640 LIST_INIT(&la->sctpTableGlobal[i]); 641 } |
664 | 642 |
665 /* Initialise circular timer Q*/ 666 for (i = 0; i < SN_TIMER_QUEUE_SIZE; i++) 667 LIST_INIT(&la->sctpNatTimer.TimerQ[i]); | 643 /* Initialise circular timer Q*/ 644 for (i = 0; i < SN_TIMER_QUEUE_SIZE; i++) 645 LIST_INIT(&la->sctpNatTimer.TimerQ[i]); |
668#ifdef _KERNEL | 646#ifdef _KERNEL |
669 la->sctpNatTimer.loc_time=time_uptime; /* la->timeStamp is not set yet */ | 647 la->sctpNatTimer.loc_time=time_uptime; /* la->timeStamp is not set yet */ |
670#else | 648#else |
671 la->sctpNatTimer.loc_time=la->timeStamp; | 649 la->sctpNatTimer.loc_time=la->timeStamp; |
672#endif | 650#endif |
673 la->sctpNatTimer.cur_loc = 0; 674 la->sctpLinkCount = 0; | 651 la->sctpNatTimer.cur_loc = 0; 652 la->sctpLinkCount = 0; |
675} 676 677/** 678 * @brief Cleans-up the SCTP NAT Implementation prior to unloading 679 * 680 * Removes all entries from the timer queue, freeing associations as it goes. 681 * We then free memory allocated to the look-up tables and the time queue 682 * 683 * NOTE: We do not need to traverse the look-up tables as each association 684 * will always have an entry in the timer queue, freeing this memory 685 * once will free all memory allocated to entries in the look-up tables 686 * 687 * @param la Pointer to the relevant libalias instance 688 */ 689void AliasSctpTerm(struct libalias *la) 690{ | 653} 654 655/** 656 * @brief Cleans-up the SCTP NAT Implementation prior to unloading 657 * 658 * Removes all entries from the timer queue, freeing associations as it goes. 659 * We then free memory allocated to the look-up tables and the time queue 660 * 661 * NOTE: We do not need to traverse the look-up tables as each association 662 * will always have an entry in the timer queue, freeing this memory 663 * once will free all memory allocated to entries in the look-up tables 664 * 665 * @param la Pointer to the relevant libalias instance 666 */ 667void AliasSctpTerm(struct libalias *la) 668{ |
691 struct sctp_nat_assoc *assoc1, *assoc2; 692 int i; | 669 struct sctp_nat_assoc *assoc1, *assoc2; 670 int i; |
693 | 671 |
694 LIBALIAS_LOCK_ASSERT(la); 695 SN_LOG(SN_LOG_EVENT, 696 SctpAliasLog("Removing SCTP NAT Instance\n")); 697 for (i = 0; i < SN_TIMER_QUEUE_SIZE; i++) { 698 assoc1 = LIST_FIRST(&la->sctpNatTimer.TimerQ[i]); 699 while (assoc1 != NULL) { 700 freeGlobalAddressList(assoc1); 701 assoc2 = LIST_NEXT(assoc1, timer_Q); 702 sn_free(assoc1); 703 assoc1 = assoc2; 704 } 705 } | 672 LIBALIAS_LOCK_ASSERT(la); 673 SN_LOG(SN_LOG_EVENT, 674 SctpAliasLog("Removing SCTP NAT Instance\n")); 675 for (i = 0; i < SN_TIMER_QUEUE_SIZE; i++) { 676 assoc1 = LIST_FIRST(&la->sctpNatTimer.TimerQ[i]); 677 while (assoc1 != NULL) { 678 freeGlobalAddressList(assoc1); 679 assoc2 = LIST_NEXT(assoc1, timer_Q); 680 sn_free(assoc1); 681 assoc1 = assoc2; 682 } 683 } |
706 | 684 |
707 sn_free(la->sctpTableLocal); 708 sn_free(la->sctpTableGlobal); 709 sn_free(la->sctpNatTimer.TimerQ); | 685 sn_free(la->sctpTableLocal); 686 sn_free(la->sctpTableGlobal); 687 sn_free(la->sctpNatTimer.TimerQ); |
710} 711 712/** 713 * @brief Handles SCTP packets passed from libalias 714 * 715 * This function needs to actually NAT/drop packets and possibly create and 716 * send AbortM or ErrorM packets in response. The process involves: 717 * - Validating the direction parameter passed by the caller --- 12 unchanged lines hidden (view full) --- 730 * @param pip Pointer to IP packet to process 731 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 732 * 733 * @return PKT_ALIAS_OK | PKT_ALIAS_IGNORE | PKT_ALIAS_ERROR 734 */ 735int 736SctpAlias(struct libalias *la, struct ip *pip, int direction) 737{ | 688} 689 690/** 691 * @brief Handles SCTP packets passed from libalias 692 * 693 * This function needs to actually NAT/drop packets and possibly create and 694 * send AbortM or ErrorM packets in response. The process involves: 695 * - Validating the direction parameter passed by the caller --- 12 unchanged lines hidden (view full) --- 708 * @param pip Pointer to IP packet to process 709 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 710 * 711 * @return PKT_ALIAS_OK | PKT_ALIAS_IGNORE | PKT_ALIAS_ERROR 712 */ 713int 714SctpAlias(struct libalias *la, struct ip *pip, int direction) 715{ |
738 int rtnval; 739 struct sctp_nat_msg msg; 740 struct sctp_nat_assoc *assoc = NULL; | 716 int rtnval; 717 struct sctp_nat_msg msg; 718 struct sctp_nat_assoc *assoc = NULL; |
741 | 719 |
742 if ((direction != SN_TO_LOCAL) && (direction != SN_TO_GLOBAL)) { 743 SctpAliasLog("ERROR: Invalid direction\n"); 744 return(PKT_ALIAS_ERROR); 745 } | 720 if ((direction != SN_TO_LOCAL) && (direction != SN_TO_GLOBAL)) { 721 SctpAliasLog("ERROR: Invalid direction\n"); 722 return(PKT_ALIAS_ERROR); 723 } |
746 | 724 |
747 sctp_CheckTimers(la); /* Check timers */ | 725 sctp_CheckTimers(la); /* Check timers */ |
748 | 726 |
749 /* Parse the packet */ 750 rtnval = sctp_PktParser(la, direction, pip, &msg, &assoc); //using *char (change to mbuf when get code from paolo) 751 switch (rtnval) { 752 case SN_PARSE_OK: 753 break; 754 case SN_PARSE_ERROR_CHHL: 755 /* Not an error if there is a chunk length parsing error and this is a fragmented packet */ 756 if (ntohs(pip->ip_off) & IP_MF) { 757 rtnval = SN_PARSE_OK; 758 break; 759 } 760 SN_LOG(SN_LOG_EVENT, 761 logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); 762 return(PKT_ALIAS_ERROR); 763 case SN_PARSE_ERROR_PARTIALLOOKUP: 764 if (sysctl_error_on_ootb > SN_LOCALandPARTIAL_ERROR_ON_OOTB) { 765 SN_LOG(SN_LOG_EVENT, 766 logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); 767 return(PKT_ALIAS_ERROR); 768 } 769 case SN_PARSE_ERROR_LOOKUP: 770 if (sysctl_error_on_ootb == SN_ERROR_ON_OOTB || 771 (sysctl_error_on_ootb == SN_LOCALandPARTIAL_ERROR_ON_OOTB && direction == SN_TO_LOCAL) || 772 (sysctl_error_on_ootb == SN_LOCAL_ERROR_ON_OOTB && direction == SN_TO_GLOBAL)) { 773 TxAbortErrorM(la, &msg, assoc, SN_REFLECT_ERROR, direction); /*NB assoc=NULL */ 774 return(PKT_ALIAS_RESPOND); 775 } 776 default: 777 SN_LOG(SN_LOG_EVENT, 778 logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); 779 return(PKT_ALIAS_ERROR); 780 } | 727 /* Parse the packet */ 728 rtnval = sctp_PktParser(la, direction, pip, &msg, &assoc); //using *char (change to mbuf when get code from paolo) 729 switch (rtnval) { 730 case SN_PARSE_OK: 731 break; 732 case SN_PARSE_ERROR_CHHL: 733 /* Not an error if there is a chunk length parsing error and this is a fragmented packet */ 734 if (ntohs(pip->ip_off) & IP_MF) { 735 rtnval = SN_PARSE_OK; 736 break; 737 } 738 SN_LOG(SN_LOG_EVENT, 739 logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); 740 return(PKT_ALIAS_ERROR); 741 case SN_PARSE_ERROR_PARTIALLOOKUP: 742 if (sysctl_error_on_ootb > SN_LOCALandPARTIAL_ERROR_ON_OOTB) { 743 SN_LOG(SN_LOG_EVENT, 744 logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); 745 return(PKT_ALIAS_ERROR); 746 } 747 case SN_PARSE_ERROR_LOOKUP: 748 if (sysctl_error_on_ootb == SN_ERROR_ON_OOTB || 749 (sysctl_error_on_ootb == SN_LOCALandPARTIAL_ERROR_ON_OOTB && direction == SN_TO_LOCAL) || 750 (sysctl_error_on_ootb == SN_LOCAL_ERROR_ON_OOTB && direction == SN_TO_GLOBAL)) { 751 TxAbortErrorM(la, &msg, assoc, SN_REFLECT_ERROR, direction); /*NB assoc=NULL */ 752 return(PKT_ALIAS_RESPOND); 753 } 754 default: 755 SN_LOG(SN_LOG_EVENT, 756 logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); 757 return(PKT_ALIAS_ERROR); 758 } |
781 | 759 |
782 SN_LOG(SN_LOG_DETAIL, 783 logsctpassoc(assoc, "*"); 784 logsctpparse(direction, &msg); 785 ); | 760 SN_LOG(SN_LOG_DETAIL, 761 logsctpassoc(assoc, "*"); 762 logsctpparse(direction, &msg); 763 ); |
786 | 764 |
787 /* Process the SCTP message */ 788 rtnval = ProcessSctpMsg(la, direction, &msg, assoc); | 765 /* Process the SCTP message */ 766 rtnval = ProcessSctpMsg(la, direction, &msg, assoc); |
789 | 767 |
790 SN_LOG(SN_LOG_DEBUG_MAX, 791 logsctpassoc(assoc, "-"); 792 logSctpLocal(la); 793 logSctpGlobal(la); 794 ); 795 SN_LOG(SN_LOG_DEBUG, logTimerQ(la)); | 768 SN_LOG(SN_LOG_DEBUG_MAX, 769 logsctpassoc(assoc, "-"); 770 logSctpLocal(la); 771 logSctpGlobal(la); 772 ); 773 SN_LOG(SN_LOG_DEBUG, logTimerQ(la)); |
796 | 774 |
797 switch(rtnval){ 798 case SN_NAT_PKT: 799 switch(direction) { 800 case SN_TO_LOCAL: 801 DifferentialChecksum(&(msg.ip_hdr->ip_sum), 802 &(assoc->l_addr), &(msg.ip_hdr->ip_dst), 2); 803 msg.ip_hdr->ip_dst = assoc->l_addr; /* change dst address to local address*/ 804 break; 805 case SN_TO_GLOBAL: 806 DifferentialChecksum(&(msg.ip_hdr->ip_sum), 807 &(assoc->a_addr), &(msg.ip_hdr->ip_src), 2); 808 msg.ip_hdr->ip_src = assoc->a_addr; /* change src to alias addr*/ 809 break; 810 default: 811 rtnval = SN_DROP_PKT; /* shouldn't get here, but if it does drop packet */ 812 SN_LOG(SN_LOG_LOW, logsctperror("ERROR: Invalid direction", msg.sctp_hdr->v_tag, rtnval, direction)); 813 break; 814 } 815 break; 816 case SN_DROP_PKT: 817 SN_LOG(SN_LOG_DETAIL, logsctperror("SN_DROP_PKT", msg.sctp_hdr->v_tag, rtnval, direction)); 818 break; 819 case SN_REPLY_ABORT: 820 case SN_REPLY_ERROR: 821 case SN_SEND_ABORT: 822 TxAbortErrorM(la, &msg, assoc, rtnval, direction); 823 break; 824 default: 825 // big error, remove association and go to idle and write log messages 826 SN_LOG(SN_LOG_LOW, logsctperror("SN_PROCESSING_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); 827 assoc->state=SN_RM;/* Mark for removal*/ 828 break; 829 } | 775 switch(rtnval){ 776 case SN_NAT_PKT: 777 switch(direction) { 778 case SN_TO_LOCAL: 779 DifferentialChecksum(&(msg.ip_hdr->ip_sum), 780 &(assoc->l_addr), &(msg.ip_hdr->ip_dst), 2); 781 msg.ip_hdr->ip_dst = assoc->l_addr; /* change dst address to local address*/ 782 break; 783 case SN_TO_GLOBAL: 784 DifferentialChecksum(&(msg.ip_hdr->ip_sum), 785 &(assoc->a_addr), &(msg.ip_hdr->ip_src), 2); 786 msg.ip_hdr->ip_src = assoc->a_addr; /* change src to alias addr*/ 787 break; 788 default: 789 rtnval = SN_DROP_PKT; /* shouldn't get here, but if it does drop packet */ 790 SN_LOG(SN_LOG_LOW, logsctperror("ERROR: Invalid direction", msg.sctp_hdr->v_tag, rtnval, direction)); 791 break; 792 } 793 break; 794 case SN_DROP_PKT: 795 SN_LOG(SN_LOG_DETAIL, logsctperror("SN_DROP_PKT", msg.sctp_hdr->v_tag, rtnval, direction)); 796 break; 797 case SN_REPLY_ABORT: 798 case SN_REPLY_ERROR: 799 case SN_SEND_ABORT: 800 TxAbortErrorM(la, &msg, assoc, rtnval, direction); 801 break; 802 default: 803 // big error, remove association and go to idle and write log messages 804 SN_LOG(SN_LOG_LOW, logsctperror("SN_PROCESSING_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); 805 assoc->state=SN_RM;/* Mark for removal*/ 806 break; 807 } |
830 | 808 |
831 /* Remove association if tagged for removal */ 832 if (assoc->state == SN_RM) { 833 if (assoc->TableRegister) { 834 sctp_RmTimeOut(la, assoc); 835 RmSctpAssoc(la, assoc); 836 } 837 LIBALIAS_LOCK_ASSERT(la); 838 freeGlobalAddressList(assoc); 839 sn_free(assoc); 840 } 841 switch(rtnval) { 842 case SN_NAT_PKT: 843 return(PKT_ALIAS_OK); 844 case SN_SEND_ABORT: 845 return(PKT_ALIAS_OK); 846 case SN_REPLY_ABORT: 847 case SN_REPLY_ERROR: 848 case SN_REFLECT_ERROR: 849 return(PKT_ALIAS_RESPOND); 850 case SN_DROP_PKT: 851 default: 852 return(PKT_ALIAS_ERROR); 853 } | 809 /* Remove association if tagged for removal */ 810 if (assoc->state == SN_RM) { 811 if (assoc->TableRegister) { 812 sctp_RmTimeOut(la, assoc); 813 RmSctpAssoc(la, assoc); 814 } 815 LIBALIAS_LOCK_ASSERT(la); 816 freeGlobalAddressList(assoc); 817 sn_free(assoc); 818 } 819 switch(rtnval) { 820 case SN_NAT_PKT: 821 return(PKT_ALIAS_OK); 822 case SN_SEND_ABORT: 823 return(PKT_ALIAS_OK); 824 case SN_REPLY_ABORT: 825 case SN_REPLY_ERROR: 826 case SN_REFLECT_ERROR: 827 return(PKT_ALIAS_RESPOND); 828 case SN_DROP_PKT: 829 default: 830 return(PKT_ALIAS_ERROR); 831 } |
854} 855 856/** 857 * @brief Send an AbortM or ErrorM 858 * 859 * We construct the new SCTP packet to send in place of the existing packet we 860 * have been asked to NAT. This function can only be called if the original 861 * packet was successfully parsed as a valid SCTP packet. --- 22 unchanged lines hidden (view full) --- 884 * @param sm Pointer to sctp message information 885 * @param assoc Pointer to current association details 886 * @param sndrply SN_SEND_ABORT | SN_REPLY_ABORT | SN_REPLY_ERROR 887 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 888 */ 889static void 890TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int sndrply, int direction) 891{ | 832} 833 834/** 835 * @brief Send an AbortM or ErrorM 836 * 837 * We construct the new SCTP packet to send in place of the existing packet we 838 * have been asked to NAT. This function can only be called if the original 839 * packet was successfully parsed as a valid SCTP packet. --- 22 unchanged lines hidden (view full) --- 862 * @param sm Pointer to sctp message information 863 * @param assoc Pointer to current association details 864 * @param sndrply SN_SEND_ABORT | SN_REPLY_ABORT | SN_REPLY_ERROR 865 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 866 */ 867static void 868TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int sndrply, int direction) 869{ |
892 int sctp_size = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_error_cause); 893 int ip_size = sizeof(struct ip) + sctp_size; 894 int include_error_cause = 1; 895 char tmp_ip[ip_size]; | 870 int sctp_size = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_error_cause); 871 int ip_size = sizeof(struct ip) + sctp_size; 872 int include_error_cause = 1; 873 char tmp_ip[ip_size]; |
896 | 874 |
897 if (ntohs(sm->ip_hdr->ip_len) < ip_size) { /* short packet, cannot send error cause */ 898 include_error_cause = 0; 899 ip_size = ip_size - sizeof(struct sctp_error_cause); 900 sctp_size = sctp_size - sizeof(struct sctp_error_cause); 901 } 902 /* Assign header pointers packet */ 903 struct ip* ip = (struct ip *) tmp_ip; 904 struct sctphdr* sctp_hdr = (struct sctphdr *) ((char *) ip + sizeof(*ip)); 905 struct sctp_chunkhdr* chunk_hdr = (struct sctp_chunkhdr *) ((char *) sctp_hdr + sizeof(*sctp_hdr)); 906 struct sctp_error_cause* error_cause = (struct sctp_error_cause *) ((char *) chunk_hdr + sizeof(*chunk_hdr)); | 875 if (ntohs(sm->ip_hdr->ip_len) < ip_size) { /* short packet, cannot send error cause */ 876 include_error_cause = 0; 877 ip_size = ip_size - sizeof(struct sctp_error_cause); 878 sctp_size = sctp_size - sizeof(struct sctp_error_cause); 879 } 880 /* Assign header pointers packet */ 881 struct ip* ip = (struct ip *) tmp_ip; 882 struct sctphdr* sctp_hdr = (struct sctphdr *) ((char *) ip + sizeof(*ip)); 883 struct sctp_chunkhdr* chunk_hdr = (struct sctp_chunkhdr *) ((char *) sctp_hdr + sizeof(*sctp_hdr)); 884 struct sctp_error_cause* error_cause = (struct sctp_error_cause *) ((char *) chunk_hdr + sizeof(*chunk_hdr)); |
907 | 885 |
908 /* construct ip header */ 909 ip->ip_v = sm->ip_hdr->ip_v; 910 ip->ip_hl = 5; /* 5*32 bit words */ 911 ip->ip_tos = 0; 912 ip->ip_len = htons(ip_size); 913 ip->ip_id = sm->ip_hdr->ip_id; 914 ip->ip_off = 0; 915 ip->ip_ttl = 255; 916 ip->ip_p = IPPROTO_SCTP; 917 /* 918 The definitions below should be removed when they make it into the SCTP stack 919 */ | 886 /* construct ip header */ 887 ip->ip_v = sm->ip_hdr->ip_v; 888 ip->ip_hl = 5; /* 5*32 bit words */ 889 ip->ip_tos = 0; 890 ip->ip_len = htons(ip_size); 891 ip->ip_id = sm->ip_hdr->ip_id; 892 ip->ip_off = 0; 893 ip->ip_ttl = 255; 894 ip->ip_p = IPPROTO_SCTP; 895 /* 896 The definitions below should be removed when they make it into the SCTP stack 897 */ |
920#define SCTP_MIDDLEBOX_FLAG 0x02 921#define SCTP_NAT_TABLE_COLLISION 0x00b0 922#define SCTP_MISSING_NAT 0x00b1 | 898#define SCTP_MIDDLEBOX_FLAG 0x02 899#define SCTP_NAT_TABLE_COLLISION 0x00b0 900#define SCTP_MISSING_NAT 0x00b1 |
923 chunk_hdr->chunk_type = (sndrply & SN_TX_ABORT) ? SCTP_ABORT_ASSOCIATION : SCTP_OPERATION_ERROR; 924 chunk_hdr->chunk_flags = SCTP_MIDDLEBOX_FLAG; 925 if (include_error_cause) { 926 error_cause->code = htons((sndrply & SN_REFLECT_ERROR) ? SCTP_MISSING_NAT : SCTP_NAT_TABLE_COLLISION); 927 error_cause->length = htons(sizeof(struct sctp_error_cause)); 928 chunk_hdr->chunk_length = htons(sizeof(*chunk_hdr) + sizeof(struct sctp_error_cause)); 929 } else { 930 chunk_hdr->chunk_length = htons(sizeof(*chunk_hdr)); 931 } | 901 chunk_hdr->chunk_type = (sndrply & SN_TX_ABORT) ? SCTP_ABORT_ASSOCIATION : SCTP_OPERATION_ERROR; 902 chunk_hdr->chunk_flags = SCTP_MIDDLEBOX_FLAG; 903 if (include_error_cause) { 904 error_cause->code = htons((sndrply & SN_REFLECT_ERROR) ? SCTP_MISSING_NAT : SCTP_NAT_TABLE_COLLISION); 905 error_cause->length = htons(sizeof(struct sctp_error_cause)); 906 chunk_hdr->chunk_length = htons(sizeof(*chunk_hdr) + sizeof(struct sctp_error_cause)); 907 } else { 908 chunk_hdr->chunk_length = htons(sizeof(*chunk_hdr)); 909 } |
932 | 910 |
933 /* set specific values */ 934 switch(sndrply) { 935 case SN_REFLECT_ERROR: 936 chunk_hdr->chunk_flags |= SCTP_HAD_NO_TCB; /* set Tbit */ 937 sctp_hdr->v_tag = sm->sctp_hdr->v_tag; 938 break; 939 case SN_REPLY_ERROR: 940 sctp_hdr->v_tag = (direction == SN_TO_LOCAL) ? assoc->g_vtag : assoc->l_vtag ; 941 break; 942 case SN_SEND_ABORT: 943 sctp_hdr->v_tag = sm->sctp_hdr->v_tag; 944 break; 945 case SN_REPLY_ABORT: 946 sctp_hdr->v_tag = sm->sctpchnk.Init->initiate_tag; 947 break; 948 } | 911 /* set specific values */ 912 switch(sndrply) { 913 case SN_REFLECT_ERROR: 914 chunk_hdr->chunk_flags |= SCTP_HAD_NO_TCB; /* set Tbit */ 915 sctp_hdr->v_tag = sm->sctp_hdr->v_tag; 916 break; 917 case SN_REPLY_ERROR: 918 sctp_hdr->v_tag = (direction == SN_TO_LOCAL) ? assoc->g_vtag : assoc->l_vtag ; 919 break; 920 case SN_SEND_ABORT: 921 sctp_hdr->v_tag = sm->sctp_hdr->v_tag; 922 break; 923 case SN_REPLY_ABORT: 924 sctp_hdr->v_tag = sm->sctpchnk.Init->initiate_tag; 925 break; 926 } |
949 | 927 |
950 /* Set send/reply values */ 951 if (sndrply == SN_SEND_ABORT) { /*pass through NAT */ 952 ip->ip_src = (direction == SN_TO_LOCAL) ? sm->ip_hdr->ip_src : assoc->a_addr; 953 ip->ip_dst = (direction == SN_TO_LOCAL) ? assoc->l_addr : sm->ip_hdr->ip_dst; 954 sctp_hdr->src_port = sm->sctp_hdr->src_port; 955 sctp_hdr->dest_port = sm->sctp_hdr->dest_port; 956 } else { /* reply and reflect */ 957 ip->ip_src = sm->ip_hdr->ip_dst; 958 ip->ip_dst = sm->ip_hdr->ip_src; 959 sctp_hdr->src_port = sm->sctp_hdr->dest_port; 960 sctp_hdr->dest_port = sm->sctp_hdr->src_port; 961 } | 928 /* Set send/reply values */ 929 if (sndrply == SN_SEND_ABORT) { /*pass through NAT */ 930 ip->ip_src = (direction == SN_TO_LOCAL) ? sm->ip_hdr->ip_src : assoc->a_addr; 931 ip->ip_dst = (direction == SN_TO_LOCAL) ? assoc->l_addr : sm->ip_hdr->ip_dst; 932 sctp_hdr->src_port = sm->sctp_hdr->src_port; 933 sctp_hdr->dest_port = sm->sctp_hdr->dest_port; 934 } else { /* reply and reflect */ 935 ip->ip_src = sm->ip_hdr->ip_dst; 936 ip->ip_dst = sm->ip_hdr->ip_src; 937 sctp_hdr->src_port = sm->sctp_hdr->dest_port; 938 sctp_hdr->dest_port = sm->sctp_hdr->src_port; 939 } |
962 | 940 |
963 /* Calculate IP header checksum */ 964 ip->ip_sum = in_cksum_hdr(ip); | 941 /* Calculate IP header checksum */ 942 ip->ip_sum = in_cksum_hdr(ip); |
965 | 943 |
966 /* calculate SCTP header CRC32 */ 967 sctp_hdr->checksum = 0; 968 sctp_hdr->checksum = sctp_csum_finalize(update_crc32(0xffffffff, (unsigned char *) sctp_hdr, sctp_size)); | 944 /* calculate SCTP header CRC32 */ 945 sctp_hdr->checksum = 0; 946 sctp_hdr->checksum = sctp_finalize_crc32(update_crc32(0xffffffff, (unsigned char *) sctp_hdr, sctp_size)); |
969 | 947 |
970 memcpy(sm->ip_hdr, ip, ip_size); | 948 memcpy(sm->ip_hdr, ip, ip_size); |
971 | 949 |
972 SN_LOG(SN_LOG_EVENT,SctpAliasLog("%s %s 0x%x (->%s:%u vtag=0x%x crc=0x%x)\n", 973 ((sndrply == SN_SEND_ABORT) ? "Sending" : "Replying"), 974 ((sndrply & SN_TX_ERROR) ? "ErrorM" : "AbortM"), 975 (include_error_cause ? ntohs(error_cause->code) : 0), 976 inet_ntoa(ip->ip_dst),ntohs(sctp_hdr->dest_port), 977 ntohl(sctp_hdr->v_tag), ntohl(sctp_hdr->checksum))); | 950 SN_LOG(SN_LOG_EVENT,SctpAliasLog("%s %s 0x%x (->%s:%u vtag=0x%x crc=0x%x)\n", 951 ((sndrply == SN_SEND_ABORT) ? "Sending" : "Replying"), 952 ((sndrply & SN_TX_ERROR) ? "ErrorM" : "AbortM"), 953 (include_error_cause ? ntohs(error_cause->code) : 0), 954 inet_ntoa(ip->ip_dst),ntohs(sctp_hdr->dest_port), 955 ntohl(sctp_hdr->v_tag), ntohl(sctp_hdr->checksum))); |
978} 979 980/* ---------------------------------------------------------------------- 981 * PACKET PARSER CODE 982 * ---------------------------------------------------------------------- 983 */ 984/** @addtogroup packet_parser 985 * --- 13 unchanged lines hidden (view full) --- 999 * @param pip 1000 * @param sm Pointer to sctp message information 1001 * @param passoc Pointer to the association this SCTP Message belongs to 1002 * 1003 * @return SN_PARSE_OK | SN_PARSE_ERROR_* 1004 */ 1005static int 1006sctp_PktParser(struct libalias *la, int direction, struct ip *pip, | 956} 957 958/* ---------------------------------------------------------------------- 959 * PACKET PARSER CODE 960 * ---------------------------------------------------------------------- 961 */ 962/** @addtogroup packet_parser 963 * --- 13 unchanged lines hidden (view full) --- 977 * @param pip 978 * @param sm Pointer to sctp message information 979 * @param passoc Pointer to the association this SCTP Message belongs to 980 * 981 * @return SN_PARSE_OK | SN_PARSE_ERROR_* 982 */ 983static int 984sctp_PktParser(struct libalias *la, int direction, struct ip *pip, |
1007 struct sctp_nat_msg *sm, struct sctp_nat_assoc **passoc) | 985 struct sctp_nat_msg *sm, struct sctp_nat_assoc **passoc) |
1008//sctp_PktParser(int direction, struct mbuf *ipak, int ip_hdr_len,struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc) 1009{ | 986//sctp_PktParser(int direction, struct mbuf *ipak, int ip_hdr_len,struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc) 987{ |
1010 struct sctphdr *sctp_hdr; 1011 struct sctp_chunkhdr *chunk_hdr; 1012 struct sctp_paramhdr *param_hdr; 1013 struct in_addr ipv4addr; 1014 int bytes_left; /* bytes left in ip packet */ 1015 int chunk_length; 1016 int chunk_count; 1017 int partial_match = 0; 1018 // mbuf *mp; 1019 // int mlen; | 988 struct sctphdr *sctp_hdr; 989 struct sctp_chunkhdr *chunk_hdr; 990 struct sctp_paramhdr *param_hdr; 991 struct in_addr ipv4addr; 992 int bytes_left; /* bytes left in ip packet */ 993 int chunk_length; 994 int chunk_count; 995 int partial_match = 0; 996 // mbuf *mp; 997 // int mlen; |
1020 | 998 |
1021 // mlen = SCTP_HEADER_LEN(i_pak); 1022 // mp = SCTP_HEADER_TO_CHAIN(i_pak); /* does nothing in bsd since header and chain not separate */ | 999 // mlen = SCTP_HEADER_LEN(i_pak); 1000 // mp = SCTP_HEADER_TO_CHAIN(i_pak); /* does nothing in bsd since header and chain not separate */ |
1023 | 1001 |
1024 /* 1025 * Note, that if the VTag is zero, it must be an INIT 1026 * Also, I am only interested in the content of INIT and ADDIP chunks 1027 */ | 1002 /* 1003 * Note, that if the VTag is zero, it must be an INIT 1004 * Also, I am only interested in the content of INIT and ADDIP chunks 1005 */ |
1028 | 1006 |
1029 // no mbuf stuff from Paolo yet so ... 1030 sm->ip_hdr = pip; 1031 /* remove ip header length from the bytes_left */ 1032 bytes_left = ntohs(pip->ip_len) - (pip->ip_hl << 2); | 1007 // no mbuf stuff from Paolo yet so ... 1008 sm->ip_hdr = pip; 1009 /* remove ip header length from the bytes_left */ 1010 bytes_left = ntohs(pip->ip_len) - (pip->ip_hl << 2); |
1033 | 1011 |
1034 /* Check SCTP header length and move to first chunk */ 1035 if (bytes_left < sizeof(struct sctphdr)) { 1036 sm->sctp_hdr = NULL; 1037 return(SN_PARSE_ERROR_IPSHL); /* packet not long enough*/ 1038 } | 1012 /* Check SCTP header length and move to first chunk */ 1013 if (bytes_left < sizeof(struct sctphdr)) { 1014 sm->sctp_hdr = NULL; 1015 return(SN_PARSE_ERROR_IPSHL); /* packet not long enough*/ 1016 } |
1039 | 1017 |
1040 sm->sctp_hdr = sctp_hdr = (struct sctphdr *) ip_next(pip); 1041 bytes_left -= sizeof(struct sctphdr); | 1018 sm->sctp_hdr = sctp_hdr = (struct sctphdr *) ip_next(pip); 1019 bytes_left -= sizeof(struct sctphdr); |
1042 | 1020 |
1043 /* Check for valid ports (zero valued ports would find partially initialised associations */ 1044 if (sctp_hdr->src_port == 0 || sctp_hdr->dest_port == 0) 1045 return(SN_PARSE_ERROR_PORT); | 1021 /* Check for valid ports (zero valued ports would find partially initialised associations */ 1022 if (sctp_hdr->src_port == 0 || sctp_hdr->dest_port == 0) 1023 return(SN_PARSE_ERROR_PORT); |
1046 | 1024 |
1047 /* Check length of first chunk */ 1048 if (bytes_left < SN_MIN_CHUNK_SIZE) /* malformed chunk - could cause endless loop*/ 1049 return(SN_PARSE_ERROR_CHHL); /* packet not long enough for this chunk */ | 1025 /* Check length of first chunk */ 1026 if (bytes_left < SN_MIN_CHUNK_SIZE) /* malformed chunk - could cause endless loop*/ 1027 return(SN_PARSE_ERROR_CHHL); /* packet not long enough for this chunk */ |
1050 | 1028 |
1051 /* First chunk */ 1052 chunk_hdr = SN_SCTP_FIRSTCHUNK(sctp_hdr); | 1029 /* First chunk */ 1030 chunk_hdr = SN_SCTP_FIRSTCHUNK(sctp_hdr); |
1053 | 1031 |
1054 chunk_length = SCTP_SIZE32(ntohs(chunk_hdr->chunk_length)); 1055 if ((chunk_length < SN_MIN_CHUNK_SIZE) || (chunk_length > bytes_left)) /* malformed chunk - could cause endless loop*/ 1056 return(SN_PARSE_ERROR_CHHL); | 1032 chunk_length = SCTP_SIZE32(ntohs(chunk_hdr->chunk_length)); 1033 if ((chunk_length < SN_MIN_CHUNK_SIZE) || (chunk_length > bytes_left)) /* malformed chunk - could cause endless loop*/ 1034 return(SN_PARSE_ERROR_CHHL); |
1057 | 1035 |
1058 if ((chunk_hdr->chunk_flags & SCTP_HAD_NO_TCB) && 1059 ((chunk_hdr->chunk_type == SCTP_ABORT_ASSOCIATION) || 1060 (chunk_hdr->chunk_type == SCTP_SHUTDOWN_COMPLETE))) { 1061 /* T-Bit set */ 1062 if (direction == SN_TO_LOCAL) 1063 *passoc = FindSctpGlobalT(la, pip->ip_src, sctp_hdr->v_tag, sctp_hdr->dest_port, sctp_hdr->src_port); 1064 else 1065 *passoc = FindSctpLocalT(la, pip->ip_dst, sctp_hdr->v_tag, sctp_hdr->dest_port, sctp_hdr->src_port); 1066 } else { 1067 /* Proper v_tag settings */ 1068 if (direction == SN_TO_LOCAL) 1069 *passoc = FindSctpGlobal(la, pip->ip_src, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port, &partial_match); 1070 else 1071 *passoc = FindSctpLocal(la, pip->ip_src, pip->ip_dst, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port); 1072 } 1073 1074 chunk_count = 1; 1075 /* Real packet parsing occurs below */ 1076 sm->msg = SN_SCTP_OTHER;/* Initialise to largest value*/ 1077 sm->chunk_length = 0; /* only care about length for key chunks */ 1078 while (IS_SCTP_CONTROL(chunk_hdr)) { 1079 switch(chunk_hdr->chunk_type) { 1080 case SCTP_INITIATION: 1081 if (chunk_length < sizeof(struct sctp_init_chunk)) /* malformed chunk*/ 1082 return(SN_PARSE_ERROR_CHHL); 1083 sm->msg = SN_SCTP_INIT; 1084 sm->sctpchnk.Init = (struct sctp_init *) ((char *) chunk_hdr + sizeof(struct sctp_chunkhdr)); 1085 sm->chunk_length = chunk_length; 1086 /* if no existing association, create a new one */ 1087 if (*passoc == NULL) { 1088 if (sctp_hdr->v_tag == 0){ //Init requires vtag=0 1089 *passoc = (struct sctp_nat_assoc *) sn_malloc(sizeof(struct sctp_nat_assoc)); 1090 if (*passoc == NULL) {/* out of resources */ 1091 return(SN_PARSE_ERROR_AS_MALLOC); 1092 } 1093 /* Initialise association - malloc initialises memory to zeros */ 1094 (*passoc)->state = SN_ID; 1095 LIST_INIT(&((*passoc)->Gaddr)); /* always initialise to avoid memory problems */ 1096 (*passoc)->TableRegister = SN_NULL_TBL; 1097 return(SN_PARSE_OK); 1098 } 1099 return(SN_PARSE_ERROR_VTAG); 1100 } 1101 return(SN_PARSE_ERROR_LOOKUP); 1102 case SCTP_INITIATION_ACK: 1103 if (chunk_length < sizeof(struct sctp_init_ack_chunk)) /* malformed chunk*/ 1104 return(SN_PARSE_ERROR_CHHL); 1105 sm->msg = SN_SCTP_INITACK; 1106 sm->sctpchnk.InitAck = (struct sctp_init_ack *) ((char *) chunk_hdr + sizeof(struct sctp_chunkhdr)); 1107 sm->chunk_length = chunk_length; 1108 return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK)); 1109 case SCTP_ABORT_ASSOCIATION: /* access only minimum sized chunk */ 1110 sm->msg = SN_SCTP_ABORT; 1111 sm->chunk_length = chunk_length; 1112 return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP_ABORT):(SN_PARSE_OK)); 1113 case SCTP_SHUTDOWN_ACK: 1114 if (chunk_length < sizeof(struct sctp_shutdown_ack_chunk)) /* malformed chunk*/ 1115 return(SN_PARSE_ERROR_CHHL); 1116 if (sm->msg > SN_SCTP_SHUTACK) { 1117 sm->msg = SN_SCTP_SHUTACK; 1118 sm->chunk_length = chunk_length; 1119 } 1120 break; 1121 case SCTP_SHUTDOWN_COMPLETE: /* minimum sized chunk */ 1122 if (sm->msg > SN_SCTP_SHUTCOMP) { 1123 sm->msg = SN_SCTP_SHUTCOMP; 1124 sm->chunk_length = chunk_length; 1125 } 1126 return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK)); 1127 case SCTP_ASCONF: 1128 if (sm->msg > SN_SCTP_ASCONF) { 1129 if (chunk_length < (sizeof(struct sctp_asconf_chunk) + sizeof(struct sctp_ipv4addr_param))) /* malformed chunk*/ 1130 return(SN_PARSE_ERROR_CHHL); 1131 //leave parameter searching to later, if required 1132 param_hdr = (struct sctp_paramhdr *) ((char *) chunk_hdr + sizeof(struct sctp_asconf_chunk)); /*compulsory IP parameter*/ 1133 if (ntohs(param_hdr->param_type) == SCTP_IPV4_ADDRESS) { 1134 if ((*passoc == NULL) && (direction == SN_TO_LOCAL)) { /* AddIP with no association */ 1135 /* try look up with the ASCONF packet's alternative address */ 1136 ipv4addr.s_addr = ((struct sctp_ipv4addr_param *) param_hdr)->addr; 1137 *passoc = FindSctpGlobal(la, ipv4addr, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port, &partial_match); 1138 } 1139 param_hdr = (struct sctp_paramhdr *) 1140 ((char *) param_hdr + sizeof(struct sctp_ipv4addr_param)); /*asconf's compulsory address parameter */ 1141 sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_chunk) - sizeof(struct sctp_ipv4addr_param); /* rest of chunk */ | 1036 if ((chunk_hdr->chunk_flags & SCTP_HAD_NO_TCB) && 1037 ((chunk_hdr->chunk_type == SCTP_ABORT_ASSOCIATION) || 1038 (chunk_hdr->chunk_type == SCTP_SHUTDOWN_COMPLETE))) { 1039 /* T-Bit set */ 1040 if (direction == SN_TO_LOCAL) 1041 *passoc = FindSctpGlobalT(la, pip->ip_src, sctp_hdr->v_tag, sctp_hdr->dest_port, sctp_hdr->src_port); 1042 else 1043 *passoc = FindSctpLocalT(la, pip->ip_dst, sctp_hdr->v_tag, sctp_hdr->dest_port, sctp_hdr->src_port); |
1142 } else { | 1044 } else { |
1143 if (chunk_length < (sizeof(struct sctp_asconf_chunk) + sizeof(struct sctp_ipv6addr_param))) /* malformed chunk*/ 1144 return(SN_PARSE_ERROR_CHHL); 1145 param_hdr = (struct sctp_paramhdr *) 1146 ((char *) param_hdr + sizeof(struct sctp_ipv6addr_param)); /*asconf's compulsory address parameter */ 1147 sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_chunk) - sizeof(struct sctp_ipv6addr_param); /* rest of chunk */ | 1045 /* Proper v_tag settings */ 1046 if (direction == SN_TO_LOCAL) 1047 *passoc = FindSctpGlobal(la, pip->ip_src, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port, &partial_match); 1048 else 1049 *passoc = FindSctpLocal(la, pip->ip_src, pip->ip_dst, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port); |
1148 } | 1050 } |
1149 sm->msg = SN_SCTP_ASCONF; 1150 sm->sctpchnk.Asconf = param_hdr; | 1051 1052 chunk_count = 1; 1053 /* Real packet parsing occurs below */ 1054 sm->msg = SN_SCTP_OTHER;/* Initialise to largest value*/ 1055 sm->chunk_length = 0; /* only care about length for key chunks */ 1056 while (IS_SCTP_CONTROL(chunk_hdr)) { 1057 switch(chunk_hdr->chunk_type) { 1058 case SCTP_INITIATION: 1059 if (chunk_length < sizeof(struct sctp_init_chunk)) /* malformed chunk*/ 1060 return(SN_PARSE_ERROR_CHHL); 1061 sm->msg = SN_SCTP_INIT; 1062 sm->sctpchnk.Init = (struct sctp_init *) ((char *) chunk_hdr + sizeof(struct sctp_chunkhdr)); 1063 sm->chunk_length = chunk_length; 1064 /* if no existing association, create a new one */ 1065 if (*passoc == NULL) { 1066 if (sctp_hdr->v_tag == 0){ //Init requires vtag=0 1067 *passoc = (struct sctp_nat_assoc *) sn_malloc(sizeof(struct sctp_nat_assoc)); 1068 if (*passoc == NULL) {/* out of resources */ 1069 return(SN_PARSE_ERROR_AS_MALLOC); 1070 } 1071 /* Initialise association - malloc initialises memory to zeros */ 1072 (*passoc)->state = SN_ID; 1073 LIST_INIT(&((*passoc)->Gaddr)); /* always initialise to avoid memory problems */ 1074 (*passoc)->TableRegister = SN_NULL_TBL; 1075 return(SN_PARSE_OK); 1076 } 1077 return(SN_PARSE_ERROR_VTAG); 1078 } 1079 return(SN_PARSE_ERROR_LOOKUP); 1080 case SCTP_INITIATION_ACK: 1081 if (chunk_length < sizeof(struct sctp_init_ack_chunk)) /* malformed chunk*/ 1082 return(SN_PARSE_ERROR_CHHL); 1083 sm->msg = SN_SCTP_INITACK; 1084 sm->sctpchnk.InitAck = (struct sctp_init_ack *) ((char *) chunk_hdr + sizeof(struct sctp_chunkhdr)); 1085 sm->chunk_length = chunk_length; 1086 return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK)); 1087 case SCTP_ABORT_ASSOCIATION: /* access only minimum sized chunk */ 1088 sm->msg = SN_SCTP_ABORT; 1089 sm->chunk_length = chunk_length; 1090 return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP_ABORT):(SN_PARSE_OK)); 1091 case SCTP_SHUTDOWN_ACK: 1092 if (chunk_length < sizeof(struct sctp_shutdown_ack_chunk)) /* malformed chunk*/ 1093 return(SN_PARSE_ERROR_CHHL); 1094 if (sm->msg > SN_SCTP_SHUTACK) { 1095 sm->msg = SN_SCTP_SHUTACK; 1096 sm->chunk_length = chunk_length; 1097 } 1098 break; 1099 case SCTP_SHUTDOWN_COMPLETE: /* minimum sized chunk */ 1100 if (sm->msg > SN_SCTP_SHUTCOMP) { 1101 sm->msg = SN_SCTP_SHUTCOMP; 1102 sm->chunk_length = chunk_length; 1103 } 1104 return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK)); 1105 case SCTP_ASCONF: 1106 if (sm->msg > SN_SCTP_ASCONF) { 1107 if (chunk_length < (sizeof(struct sctp_asconf_chunk) + sizeof(struct sctp_ipv4addr_param))) /* malformed chunk*/ 1108 return(SN_PARSE_ERROR_CHHL); 1109 //leave parameter searching to later, if required 1110 param_hdr = (struct sctp_paramhdr *) ((char *) chunk_hdr + sizeof(struct sctp_asconf_chunk)); /*compulsory IP parameter*/ 1111 if (ntohs(param_hdr->param_type) == SCTP_IPV4_ADDRESS) { 1112 if ((*passoc == NULL) && (direction == SN_TO_LOCAL)) { /* AddIP with no association */ 1113 /* try look up with the ASCONF packet's alternative address */ 1114 ipv4addr.s_addr = ((struct sctp_ipv4addr_param *) param_hdr)->addr; 1115 *passoc = FindSctpGlobal(la, ipv4addr, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port, &partial_match); 1116 } 1117 param_hdr = (struct sctp_paramhdr *) 1118 ((char *) param_hdr + sizeof(struct sctp_ipv4addr_param)); /*asconf's compulsory address parameter */ 1119 sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_chunk) - sizeof(struct sctp_ipv4addr_param); /* rest of chunk */ 1120 } else { 1121 if (chunk_length < (sizeof(struct sctp_asconf_chunk) + sizeof(struct sctp_ipv6addr_param))) /* malformed chunk*/ 1122 return(SN_PARSE_ERROR_CHHL); 1123 param_hdr = (struct sctp_paramhdr *) 1124 ((char *) param_hdr + sizeof(struct sctp_ipv6addr_param)); /*asconf's compulsory address parameter */ 1125 sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_chunk) - sizeof(struct sctp_ipv6addr_param); /* rest of chunk */ 1126 } 1127 sm->msg = SN_SCTP_ASCONF; 1128 sm->sctpchnk.Asconf = param_hdr; |
1151 | 1129 |
1152 if (*passoc == NULL) { /* AddIP with no association */ 1153 *passoc = (struct sctp_nat_assoc *) sn_malloc(sizeof(struct sctp_nat_assoc)); 1154 if (*passoc == NULL) {/* out of resources */ 1155 return(SN_PARSE_ERROR_AS_MALLOC); 1156 } 1157 /* Initialise association - malloc initialises memory to zeros */ 1158 (*passoc)->state = SN_ID; 1159 LIST_INIT(&((*passoc)->Gaddr)); /* always initialise to avoid memory problems */ 1160 (*passoc)->TableRegister = SN_NULL_TBL; 1161 return(SN_PARSE_OK); 1162 } 1163 } 1164 break; 1165 case SCTP_ASCONF_ACK: 1166 if (sm->msg > SN_SCTP_ASCONFACK) { 1167 if (chunk_length < sizeof(struct sctp_asconf_ack_chunk)) /* malformed chunk*/ 1168 return(SN_PARSE_ERROR_CHHL); 1169 //leave parameter searching to later, if required 1170 param_hdr = (struct sctp_paramhdr *) ((char *) chunk_hdr 1171 + sizeof(struct sctp_asconf_ack_chunk)); 1172 sm->msg = SN_SCTP_ASCONFACK; 1173 sm->sctpchnk.Asconf = param_hdr; 1174 sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_ack_chunk); 1175 } 1176 break; 1177 default: 1178 break; /* do nothing*/ 1179 } | 1130 if (*passoc == NULL) { /* AddIP with no association */ 1131 *passoc = (struct sctp_nat_assoc *) sn_malloc(sizeof(struct sctp_nat_assoc)); 1132 if (*passoc == NULL) {/* out of resources */ 1133 return(SN_PARSE_ERROR_AS_MALLOC); 1134 } 1135 /* Initialise association - malloc initialises memory to zeros */ 1136 (*passoc)->state = SN_ID; 1137 LIST_INIT(&((*passoc)->Gaddr)); /* always initialise to avoid memory problems */ 1138 (*passoc)->TableRegister = SN_NULL_TBL; 1139 return(SN_PARSE_OK); 1140 } 1141 } 1142 break; 1143 case SCTP_ASCONF_ACK: 1144 if (sm->msg > SN_SCTP_ASCONFACK) { 1145 if (chunk_length < sizeof(struct sctp_asconf_ack_chunk)) /* malformed chunk*/ 1146 return(SN_PARSE_ERROR_CHHL); 1147 //leave parameter searching to later, if required 1148 param_hdr = (struct sctp_paramhdr *) ((char *) chunk_hdr 1149 + sizeof(struct sctp_asconf_ack_chunk)); 1150 sm->msg = SN_SCTP_ASCONFACK; 1151 sm->sctpchnk.Asconf = param_hdr; 1152 sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_ack_chunk); 1153 } 1154 break; 1155 default: 1156 break; /* do nothing*/ 1157 } |
1180 | 1158 |
1181 /* if no association is found exit - we need to find an Init or AddIP within sysctl_initialising_chunk_proc_limit */ 1182 if ((*passoc == NULL) && (chunk_count >= sysctl_initialising_chunk_proc_limit)) 1183 return(SN_PARSE_ERROR_LOOKUP); | 1159 /* if no association is found exit - we need to find an Init or AddIP within sysctl_initialising_chunk_proc_limit */ 1160 if ((*passoc == NULL) && (chunk_count >= sysctl_initialising_chunk_proc_limit)) 1161 return(SN_PARSE_ERROR_LOOKUP); |
1184 | 1162 |
1185 /* finished with this chunk, on to the next chunk*/ 1186 bytes_left-= chunk_length; | 1163 /* finished with this chunk, on to the next chunk*/ 1164 bytes_left-= chunk_length; |
1187 | 1165 |
1188 /* Is this the end of the packet ? */ 1189 if (bytes_left == 0) 1190 return(SN_PARSE_OK); | 1166 /* Is this the end of the packet ? */ 1167 if (bytes_left == 0) 1168 return (*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK); |
1191 | 1169 |
1192 /* Are there enough bytes in packet to at least retrieve length of next chunk ? */ 1193 if (bytes_left < SN_MIN_CHUNK_SIZE) 1194 return(SN_PARSE_ERROR_CHHL); | 1170 /* Are there enough bytes in packet to at least retrieve length of next chunk ? */ 1171 if (bytes_left < SN_MIN_CHUNK_SIZE) 1172 return(SN_PARSE_ERROR_CHHL); |
1195 | 1173 |
1196 chunk_hdr = SN_SCTP_NEXTCHUNK(chunk_hdr); | 1174 chunk_hdr = SN_SCTP_NEXTCHUNK(chunk_hdr); |
1197 | 1175 |
1198 /* Is the chunk long enough to not cause endless look and are there enough bytes in packet to read the chunk ? */ 1199 chunk_length = SCTP_SIZE32(ntohs(chunk_hdr->chunk_length)); 1200 if ((chunk_length < SN_MIN_CHUNK_SIZE) || (chunk_length > bytes_left)) 1201 return(SN_PARSE_ERROR_CHHL); 1202 if(++chunk_count > sysctl_chunk_proc_limit) 1203 return(SN_PARSE_OK); /* limit for processing chunks, take what we get */ 1204 } | 1176 /* Is the chunk long enough to not cause endless look and are there enough bytes in packet to read the chunk ? */ 1177 chunk_length = SCTP_SIZE32(ntohs(chunk_hdr->chunk_length)); 1178 if ((chunk_length < SN_MIN_CHUNK_SIZE) || (chunk_length > bytes_left)) 1179 return(SN_PARSE_ERROR_CHHL); 1180 if(++chunk_count > sysctl_chunk_proc_limit) 1181 return(SN_PARSE_OK); /* limit for processing chunks, take what we get */ 1182 } |
1205 | 1183 |
1206 if (*passoc == NULL) 1207 return (partial_match)?(SN_PARSE_ERROR_PARTIALLOOKUP):(SN_PARSE_ERROR_LOOKUP); 1208 else 1209 return(SN_PARSE_OK); | 1184 if (*passoc == NULL) 1185 return (partial_match)?(SN_PARSE_ERROR_PARTIALLOOKUP):(SN_PARSE_ERROR_LOOKUP); 1186 else 1187 return(SN_PARSE_OK); |
1210} 1211 1212/** @ingroup packet_parser 1213 * @brief Extract Vtags from Asconf Chunk 1214 * 1215 * GetAsconfVtags scans an Asconf Chunk for the vtags parameter, and then 1216 * extracts the vtags. 1217 * --- 6 unchanged lines hidden (view full) --- 1224 * @param g_vtag Pointer to the local vtag in the association this SCTP Message belongs to 1225 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1226 * 1227 * @return 1 - success | 0 - fail 1228 */ 1229static int 1230GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, uint32_t *g_vtag, int direction) 1231{ | 1188} 1189 1190/** @ingroup packet_parser 1191 * @brief Extract Vtags from Asconf Chunk 1192 * 1193 * GetAsconfVtags scans an Asconf Chunk for the vtags parameter, and then 1194 * extracts the vtags. 1195 * --- 6 unchanged lines hidden (view full) --- 1202 * @param g_vtag Pointer to the local vtag in the association this SCTP Message belongs to 1203 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1204 * 1205 * @return 1 - success | 0 - fail 1206 */ 1207static int 1208GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, uint32_t *g_vtag, int direction) 1209{ |
1232 /* To be removed when information is in the sctp headers */ | 1210 /* To be removed when information is in the sctp headers */ |
1233#define SCTP_VTAG_PARAM 0xC007 | 1211#define SCTP_VTAG_PARAM 0xC007 |
1234 struct sctp_vtag_param { 1235 struct sctp_paramhdr ph;/* type=SCTP_VTAG_PARAM */ 1236 uint32_t local_vtag; 1237 uint32_t remote_vtag; 1238 } __attribute__((packed)); | 1212 struct sctp_vtag_param { 1213 struct sctp_paramhdr ph;/* type=SCTP_VTAG_PARAM */ 1214 uint32_t local_vtag; 1215 uint32_t remote_vtag; 1216 } __attribute__((packed)); |
1239 | 1217 |
1240 struct sctp_vtag_param *vtag_param; 1241 struct sctp_paramhdr *param; 1242 int bytes_left; 1243 int param_size; 1244 int param_count; | 1218 struct sctp_vtag_param *vtag_param; 1219 struct sctp_paramhdr *param; 1220 int bytes_left; 1221 int param_size; 1222 int param_count; |
1245 | 1223 |
1246 param_count = 1; 1247 param = sm->sctpchnk.Asconf; 1248 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1249 bytes_left = sm->chunk_length; 1250 /* step through Asconf parameters */ 1251 while((bytes_left >= param_size) && (bytes_left >= SN_VTAG_PARAM_SIZE)) { 1252 if (ntohs(param->param_type) == SCTP_VTAG_PARAM) { 1253 vtag_param = (struct sctp_vtag_param *) param; 1254 switch(direction) { 1255 /* The Internet draft is a little ambigious as to order of these vtags. 1256 We think it is this way around. If we are wrong, the order will need 1257 to be changed. */ 1258 case SN_TO_GLOBAL: 1259 *g_vtag = vtag_param->local_vtag; 1260 *l_vtag = vtag_param->remote_vtag; 1261 break; 1262 case SN_TO_LOCAL: 1263 *g_vtag = vtag_param->remote_vtag; 1264 *l_vtag = vtag_param->local_vtag; 1265 break; 1266 } 1267 return(1); /* found */ 1268 } | 1224 param_count = 1; 1225 param = sm->sctpchnk.Asconf; 1226 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1227 bytes_left = sm->chunk_length; 1228 /* step through Asconf parameters */ 1229 while((bytes_left >= param_size) && (bytes_left >= SN_VTAG_PARAM_SIZE)) { 1230 if (ntohs(param->param_type) == SCTP_VTAG_PARAM) { 1231 vtag_param = (struct sctp_vtag_param *) param; 1232 switch(direction) { 1233 /* The Internet draft is a little ambigious as to order of these vtags. 1234 We think it is this way around. If we are wrong, the order will need 1235 to be changed. */ 1236 case SN_TO_GLOBAL: 1237 *g_vtag = vtag_param->local_vtag; 1238 *l_vtag = vtag_param->remote_vtag; 1239 break; 1240 case SN_TO_LOCAL: 1241 *g_vtag = vtag_param->remote_vtag; 1242 *l_vtag = vtag_param->local_vtag; 1243 break; 1244 } 1245 return(1); /* found */ 1246 } |
1269 | 1247 |
1270 bytes_left -= param_size; 1271 if (bytes_left < SN_MIN_PARAM_SIZE) return(0); | 1248 bytes_left -= param_size; 1249 if (bytes_left < SN_MIN_PARAM_SIZE) return(0); |
1272 | 1250 |
1273 param = SN_SCTP_NEXTPARAM(param); 1274 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1275 if (++param_count > sysctl_param_proc_limit) { 1276 SN_LOG(SN_LOG_EVENT, 1277 logsctperror("Parameter parse limit exceeded (GetAsconfVtags)", 1278 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); 1279 return(0); /* not found limit exceeded*/ 1280 } 1281 } 1282 return(0); /* not found */ | 1251 param = SN_SCTP_NEXTPARAM(param); 1252 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1253 if (++param_count > sysctl_param_proc_limit) { 1254 SN_LOG(SN_LOG_EVENT, 1255 logsctperror("Parameter parse limit exceeded (GetAsconfVtags)", 1256 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); 1257 return(0); /* not found limit exceeded*/ 1258 } 1259 } 1260 return(0); /* not found */ |
1283} 1284 1285/** @ingroup packet_parser 1286 * @brief AddGlobalIPAddresses from Init,InitAck,or AddIP packets 1287 * 1288 * AddGlobalIPAddresses scans an SCTP chunk (in sm) for Global IP addresses, and 1289 * adds them. 1290 * 1291 * @param sm Pointer to sctp message information 1292 * @param assoc Pointer to the association this SCTP Message belongs to 1293 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1294 * 1295 */ 1296static void 1297AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction) 1298{ | 1261} 1262 1263/** @ingroup packet_parser 1264 * @brief AddGlobalIPAddresses from Init,InitAck,or AddIP packets 1265 * 1266 * AddGlobalIPAddresses scans an SCTP chunk (in sm) for Global IP addresses, and 1267 * adds them. 1268 * 1269 * @param sm Pointer to sctp message information 1270 * @param assoc Pointer to the association this SCTP Message belongs to 1271 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1272 * 1273 */ 1274static void 1275AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction) 1276{ |
1299 struct sctp_ipv4addr_param *ipv4_param; 1300 struct sctp_paramhdr *param = NULL; 1301 struct sctp_GlobalAddress *G_Addr; 1302 struct in_addr g_addr = {0}; 1303 int bytes_left = 0; 1304 int param_size; 1305 int param_count, addr_param_count = 0; | 1277 struct sctp_ipv4addr_param *ipv4_param; 1278 struct sctp_paramhdr *param = NULL; 1279 struct sctp_GlobalAddress *G_Addr; 1280 struct in_addr g_addr = {0}; 1281 int bytes_left = 0; 1282 int param_size; 1283 int param_count, addr_param_count = 0; |
1306 | 1284 |
1307 switch(direction) { 1308 case SN_TO_GLOBAL: /* does not contain global addresses */ 1309 g_addr = sm->ip_hdr->ip_dst; 1310 bytes_left = 0; /* force exit */ 1311 break; 1312 case SN_TO_LOCAL: 1313 g_addr = sm->ip_hdr->ip_src; 1314 param_count = 1; 1315 switch(sm->msg) { 1316 case SN_SCTP_INIT: 1317 bytes_left = sm->chunk_length - sizeof(struct sctp_init_chunk); 1318 param = (struct sctp_paramhdr *)((char *)sm->sctpchnk.Init + sizeof(struct sctp_init)); 1319 break; 1320 case SN_SCTP_INITACK: 1321 bytes_left = sm->chunk_length - sizeof(struct sctp_init_ack_chunk); 1322 param = (struct sctp_paramhdr *)((char *)sm->sctpchnk.InitAck + sizeof(struct sctp_init_ack)); 1323 break; 1324 case SN_SCTP_ASCONF: 1325 bytes_left = sm->chunk_length; 1326 param = sm->sctpchnk.Asconf; 1327 break; 1328 } 1329 } 1330 if (bytes_left >= SN_MIN_PARAM_SIZE) 1331 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1332 else 1333 param_size = bytes_left+1; /* force skip loop */ | 1285 switch(direction) { 1286 case SN_TO_GLOBAL: /* does not contain global addresses */ 1287 g_addr = sm->ip_hdr->ip_dst; 1288 bytes_left = 0; /* force exit */ 1289 break; 1290 case SN_TO_LOCAL: 1291 g_addr = sm->ip_hdr->ip_src; 1292 param_count = 1; 1293 switch(sm->msg) { 1294 case SN_SCTP_INIT: 1295 bytes_left = sm->chunk_length - sizeof(struct sctp_init_chunk); 1296 param = (struct sctp_paramhdr *)((char *)sm->sctpchnk.Init + sizeof(struct sctp_init)); 1297 break; 1298 case SN_SCTP_INITACK: 1299 bytes_left = sm->chunk_length - sizeof(struct sctp_init_ack_chunk); 1300 param = (struct sctp_paramhdr *)((char *)sm->sctpchnk.InitAck + sizeof(struct sctp_init_ack)); 1301 break; 1302 case SN_SCTP_ASCONF: 1303 bytes_left = sm->chunk_length; 1304 param = sm->sctpchnk.Asconf; 1305 break; 1306 } 1307 } 1308 if (bytes_left >= SN_MIN_PARAM_SIZE) 1309 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1310 else 1311 param_size = bytes_left+1; /* force skip loop */ |
1334 | 1312 |
1335 if ((assoc->state == SN_ID) && ((sm->msg == SN_SCTP_INIT) || (bytes_left < SN_MIN_PARAM_SIZE))) {/* add pkt address */ 1336 G_Addr = (struct sctp_GlobalAddress *) sn_malloc(sizeof(struct sctp_GlobalAddress)); 1337 if (G_Addr == NULL) {/* out of resources */ 1338 SN_LOG(SN_LOG_EVENT, 1339 logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking", 1340 sm->sctp_hdr->v_tag, 0, direction)); 1341 assoc->num_Gaddr = 0; /* don't track any more for this assoc*/ 1342 sysctl_track_global_addresses=0; 1343 return; 1344 } 1345 G_Addr->g_addr = g_addr; 1346 if (!Add_Global_Address_to_List(assoc, G_Addr)) 1347 SN_LOG(SN_LOG_EVENT, 1348 logsctperror("AddGlobalIPAddress: Address already in list", 1349 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); 1350 } | 1313 if ((assoc->state == SN_ID) && ((sm->msg == SN_SCTP_INIT) || (bytes_left < SN_MIN_PARAM_SIZE))) {/* add pkt address */ 1314 G_Addr = (struct sctp_GlobalAddress *) sn_malloc(sizeof(struct sctp_GlobalAddress)); 1315 if (G_Addr == NULL) {/* out of resources */ 1316 SN_LOG(SN_LOG_EVENT, 1317 logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking", 1318 sm->sctp_hdr->v_tag, 0, direction)); 1319 assoc->num_Gaddr = 0; /* don't track any more for this assoc*/ 1320 sysctl_track_global_addresses=0; 1321 return; 1322 } 1323 G_Addr->g_addr = g_addr; 1324 if (!Add_Global_Address_to_List(assoc, G_Addr)) 1325 SN_LOG(SN_LOG_EVENT, 1326 logsctperror("AddGlobalIPAddress: Address already in list", 1327 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); 1328 } |
1351 | 1329 |
1352 /* step through parameters */ 1353 while((bytes_left >= param_size) && (bytes_left >= sizeof(struct sctp_ipv4addr_param))) { 1354 if (assoc->num_Gaddr >= sysctl_track_global_addresses) { 1355 SN_LOG(SN_LOG_EVENT, 1356 logsctperror("AddGlobalIPAddress: Maximum Number of addresses reached", 1357 sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction)); 1358 return; 1359 } 1360 switch(ntohs(param->param_type)) { 1361 case SCTP_ADD_IP_ADDRESS: 1362 /* skip to address parameter - leave param_size so bytes left will be calculated properly*/ 1363 param = (struct sctp_paramhdr *) &((struct sctp_asconf_addrv4_param *) param)->addrp; 1364 case SCTP_IPV4_ADDRESS: 1365 ipv4_param = (struct sctp_ipv4addr_param *) param; 1366 /* add addresses to association */ 1367 G_Addr = (struct sctp_GlobalAddress *) sn_malloc(sizeof(struct sctp_GlobalAddress)); 1368 if (G_Addr == NULL) {/* out of resources */ 1369 SN_LOG(SN_LOG_EVENT, 1370 logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking", 1371 sm->sctp_hdr->v_tag, 0, direction)); 1372 assoc->num_Gaddr = 0; /* don't track any more for this assoc*/ 1373 sysctl_track_global_addresses=0; 1374 return; 1375 } 1376 /* add address */ 1377 addr_param_count++; 1378 if ((sm->msg == SN_SCTP_ASCONF) && (ipv4_param->addr == INADDR_ANY)) { /* use packet address */ 1379 G_Addr->g_addr = g_addr; 1380 if (!Add_Global_Address_to_List(assoc, G_Addr)) 1381 SN_LOG(SN_LOG_EVENT, 1382 logsctperror("AddGlobalIPAddress: Address already in list", 1383 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); 1384 return; /*shouldn't be any other addresses if the zero address is given*/ 1385 } else { 1386 G_Addr->g_addr.s_addr = ipv4_param->addr; 1387 if (!Add_Global_Address_to_List(assoc, G_Addr)) 1388 SN_LOG(SN_LOG_EVENT, 1389 logsctperror("AddGlobalIPAddress: Address already in list", 1390 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); 1391 } 1392 } | 1330 /* step through parameters */ 1331 while((bytes_left >= param_size) && (bytes_left >= sizeof(struct sctp_ipv4addr_param))) { 1332 if (assoc->num_Gaddr >= sysctl_track_global_addresses) { 1333 SN_LOG(SN_LOG_EVENT, 1334 logsctperror("AddGlobalIPAddress: Maximum Number of addresses reached", 1335 sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction)); 1336 return; 1337 } 1338 switch(ntohs(param->param_type)) { 1339 case SCTP_ADD_IP_ADDRESS: 1340 /* skip to address parameter - leave param_size so bytes left will be calculated properly*/ 1341 param = (struct sctp_paramhdr *) &((struct sctp_asconf_addrv4_param *) param)->addrp; 1342 case SCTP_IPV4_ADDRESS: 1343 ipv4_param = (struct sctp_ipv4addr_param *) param; 1344 /* add addresses to association */ 1345 G_Addr = (struct sctp_GlobalAddress *) sn_malloc(sizeof(struct sctp_GlobalAddress)); 1346 if (G_Addr == NULL) {/* out of resources */ 1347 SN_LOG(SN_LOG_EVENT, 1348 logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking", 1349 sm->sctp_hdr->v_tag, 0, direction)); 1350 assoc->num_Gaddr = 0; /* don't track any more for this assoc*/ 1351 sysctl_track_global_addresses=0; 1352 return; 1353 } 1354 /* add address */ 1355 addr_param_count++; 1356 if ((sm->msg == SN_SCTP_ASCONF) && (ipv4_param->addr == INADDR_ANY)) { /* use packet address */ 1357 G_Addr->g_addr = g_addr; 1358 if (!Add_Global_Address_to_List(assoc, G_Addr)) 1359 SN_LOG(SN_LOG_EVENT, 1360 logsctperror("AddGlobalIPAddress: Address already in list", 1361 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); 1362 return; /*shouldn't be any other addresses if the zero address is given*/ 1363 } else { 1364 G_Addr->g_addr.s_addr = ipv4_param->addr; 1365 if (!Add_Global_Address_to_List(assoc, G_Addr)) 1366 SN_LOG(SN_LOG_EVENT, 1367 logsctperror("AddGlobalIPAddress: Address already in list", 1368 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); 1369 } 1370 } |
1393 | 1371 |
1394 bytes_left -= param_size; 1395 if (bytes_left < SN_MIN_PARAM_SIZE) 1396 break; | 1372 bytes_left -= param_size; 1373 if (bytes_left < SN_MIN_PARAM_SIZE) 1374 break; |
1397 | 1375 |
1398 param = SN_SCTP_NEXTPARAM(param); 1399 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1400 if (++param_count > sysctl_param_proc_limit) { 1401 SN_LOG(SN_LOG_EVENT, 1402 logsctperror("Parameter parse limit exceeded (AddGlobalIPAddress)", 1403 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); 1404 break; /* limit exceeded*/ 1405 } 1406 } 1407 if (addr_param_count == 0) { 1408 SN_LOG(SN_LOG_DETAIL, 1409 logsctperror("AddGlobalIPAddress: no address parameters to add", | 1376 param = SN_SCTP_NEXTPARAM(param); 1377 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1378 if (++param_count > sysctl_param_proc_limit) { 1379 SN_LOG(SN_LOG_EVENT, 1380 logsctperror("Parameter parse limit exceeded (AddGlobalIPAddress)", 1381 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); 1382 break; /* limit exceeded*/ 1383 } 1384 } 1385 if (addr_param_count == 0) { 1386 SN_LOG(SN_LOG_DETAIL, 1387 logsctperror("AddGlobalIPAddress: no address parameters to add", |
1410 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); | 1388 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); |
1411 } | 1389 } |
1412} 1413 1414/** 1415 * @brief Add_Global_Address_to_List 1416 * 1417 * Adds a global IP address to an associations address list, if it is not 1418 * already there. The first address added us usually the packet's address, and 1419 * is most likely to be used, so it is added at the beginning. Subsequent 1420 * addresses are added after this one. 1421 * 1422 * @param assoc Pointer to the association this SCTP Message belongs to 1423 * @param G_addr Pointer to the global address to add 1424 * 1425 * @return 1 - success | 0 - fail 1426 */ 1427static int Add_Global_Address_to_List(struct sctp_nat_assoc *assoc, struct sctp_GlobalAddress *G_addr) 1428{ | 1390} 1391 1392/** 1393 * @brief Add_Global_Address_to_List 1394 * 1395 * Adds a global IP address to an associations address list, if it is not 1396 * already there. The first address added us usually the packet's address, and 1397 * is most likely to be used, so it is added at the beginning. Subsequent 1398 * addresses are added after this one. 1399 * 1400 * @param assoc Pointer to the association this SCTP Message belongs to 1401 * @param G_addr Pointer to the global address to add 1402 * 1403 * @return 1 - success | 0 - fail 1404 */ 1405static int Add_Global_Address_to_List(struct sctp_nat_assoc *assoc, struct sctp_GlobalAddress *G_addr) 1406{ |
1429 struct sctp_GlobalAddress *iter_G_Addr = NULL, *first_G_Addr = NULL; 1430 first_G_Addr = LIST_FIRST(&(assoc->Gaddr)); 1431 if (first_G_Addr == NULL) { 1432 LIST_INSERT_HEAD(&(assoc->Gaddr), G_addr, list_Gaddr); /* add new address to beginning of list*/ 1433 } else { 1434 LIST_FOREACH(iter_G_Addr, &(assoc->Gaddr), list_Gaddr) { 1435 if (G_addr->g_addr.s_addr == iter_G_Addr->g_addr.s_addr) 1436 return(0); /* already exists, so don't add */ 1437 } 1438 LIST_INSERT_AFTER(first_G_Addr, G_addr, list_Gaddr); /* add address to end of list*/ 1439 } 1440 assoc->num_Gaddr++; 1441 return(1); /* success */ | 1407 struct sctp_GlobalAddress *iter_G_Addr = NULL, *first_G_Addr = NULL; 1408 first_G_Addr = LIST_FIRST(&(assoc->Gaddr)); 1409 if (first_G_Addr == NULL) { 1410 LIST_INSERT_HEAD(&(assoc->Gaddr), G_addr, list_Gaddr); /* add new address to beginning of list*/ 1411 } else { 1412 LIST_FOREACH(iter_G_Addr, &(assoc->Gaddr), list_Gaddr) { 1413 if (G_addr->g_addr.s_addr == iter_G_Addr->g_addr.s_addr) 1414 return(0); /* already exists, so don't add */ 1415 } 1416 LIST_INSERT_AFTER(first_G_Addr, G_addr, list_Gaddr); /* add address to end of list*/ 1417 } 1418 assoc->num_Gaddr++; 1419 return(1); /* success */ |
1442} 1443 1444/** @ingroup packet_parser 1445 * @brief RmGlobalIPAddresses from DelIP packets 1446 * 1447 * RmGlobalIPAddresses scans an ASCONF chunk for DelIP parameters to remove the 1448 * given Global IP addresses from the association. It will not delete the 1449 * the address if it is a list of one address. 1450 * 1451 * 1452 * @param sm Pointer to sctp message information 1453 * @param assoc Pointer to the association this SCTP Message belongs to 1454 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1455 * 1456 */ 1457static void 1458RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction) 1459{ | 1420} 1421 1422/** @ingroup packet_parser 1423 * @brief RmGlobalIPAddresses from DelIP packets 1424 * 1425 * RmGlobalIPAddresses scans an ASCONF chunk for DelIP parameters to remove the 1426 * given Global IP addresses from the association. It will not delete the 1427 * the address if it is a list of one address. 1428 * 1429 * 1430 * @param sm Pointer to sctp message information 1431 * @param assoc Pointer to the association this SCTP Message belongs to 1432 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1433 * 1434 */ 1435static void 1436RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction) 1437{ |
1460 struct sctp_asconf_addrv4_param *asconf_ipv4_param; 1461 struct sctp_paramhdr *param; 1462 struct sctp_GlobalAddress *G_Addr, *G_Addr_tmp; 1463 struct in_addr g_addr; 1464 int bytes_left; 1465 int param_size; 1466 int param_count; | 1438 struct sctp_asconf_addrv4_param *asconf_ipv4_param; 1439 struct sctp_paramhdr *param; 1440 struct sctp_GlobalAddress *G_Addr, *G_Addr_tmp; 1441 struct in_addr g_addr; 1442 int bytes_left; 1443 int param_size; 1444 int param_count; |
1467 | 1445 |
1468 if(direction == SN_TO_GLOBAL) 1469 g_addr = sm->ip_hdr->ip_dst; 1470 else 1471 g_addr = sm->ip_hdr->ip_src; | 1446 if(direction == SN_TO_GLOBAL) 1447 g_addr = sm->ip_hdr->ip_dst; 1448 else 1449 g_addr = sm->ip_hdr->ip_src; |
1472 | 1450 |
1473 bytes_left = sm->chunk_length; 1474 param_count = 1; 1475 param = sm->sctpchnk.Asconf; 1476 if (bytes_left >= SN_MIN_PARAM_SIZE) { 1477 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1478 } else { 1479 SN_LOG(SN_LOG_EVENT, 1480 logsctperror("RmGlobalIPAddress: truncated packet - cannot remove IP addresses", | 1451 bytes_left = sm->chunk_length; 1452 param_count = 1; 1453 param = sm->sctpchnk.Asconf; 1454 if (bytes_left >= SN_MIN_PARAM_SIZE) { 1455 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1456 } else { 1457 SN_LOG(SN_LOG_EVENT, 1458 logsctperror("RmGlobalIPAddress: truncated packet - cannot remove IP addresses", |
1481 sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction)); | 1459 sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction)); |
1482 return; 1483 } 1484 1485 /* step through Asconf parameters */ 1486 while((bytes_left >= param_size) && (bytes_left >= sizeof(struct sctp_ipv4addr_param))) { 1487 if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS) { 1488 asconf_ipv4_param = (struct sctp_asconf_addrv4_param *) param; 1489 if (asconf_ipv4_param->addrp.addr == INADDR_ANY) { /* remove all bar pkt address */ 1490 LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) { 1491 if(G_Addr->g_addr.s_addr != sm->ip_hdr->ip_src.s_addr) { 1492 if (assoc->num_Gaddr > 1) { /* only delete if more than one */ 1493 LIST_REMOVE(G_Addr, list_Gaddr); 1494 sn_free(G_Addr); 1495 assoc->num_Gaddr--; 1496 } else { 1497 SN_LOG(SN_LOG_EVENT, 1498 logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)", 1499 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); 1500 } 1501 } | 1460 return; |
1502 } | 1461 } |
1503 return; /*shouldn't be any other addresses if the zero address is given*/ 1504 } else { 1505 LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) { 1506 if(G_Addr->g_addr.s_addr == asconf_ipv4_param->addrp.addr) { 1507 if (assoc->num_Gaddr > 1) { /* only delete if more than one */ 1508 LIST_REMOVE(G_Addr, list_Gaddr); 1509 sn_free(G_Addr); 1510 assoc->num_Gaddr--; 1511 break; /* Since add only adds new addresses, there should be no double entries */ 1512 } else { 1513 SN_LOG(SN_LOG_EVENT, 1514 logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)", 1515 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); 1516 } 1517 } 1518 } 1519 } 1520 } 1521 bytes_left -= param_size; 1522 if (bytes_left == 0) return; 1523 else if (bytes_left < SN_MIN_PARAM_SIZE) { 1524 SN_LOG(SN_LOG_EVENT, 1525 logsctperror("RmGlobalIPAddress: truncated packet - may not have removed all IP addresses", 1526 sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction)); 1527 return; 1528 } | 1462 1463 /* step through Asconf parameters */ 1464 while((bytes_left >= param_size) && (bytes_left >= sizeof(struct sctp_ipv4addr_param))) { 1465 if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS) { 1466 asconf_ipv4_param = (struct sctp_asconf_addrv4_param *) param; 1467 if (asconf_ipv4_param->addrp.addr == INADDR_ANY) { /* remove all bar pkt address */ 1468 LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) { 1469 if(G_Addr->g_addr.s_addr != sm->ip_hdr->ip_src.s_addr) { 1470 if (assoc->num_Gaddr > 1) { /* only delete if more than one */ 1471 LIST_REMOVE(G_Addr, list_Gaddr); 1472 sn_free(G_Addr); 1473 assoc->num_Gaddr--; 1474 } else { 1475 SN_LOG(SN_LOG_EVENT, 1476 logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)", 1477 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); 1478 } 1479 } 1480 } 1481 return; /*shouldn't be any other addresses if the zero address is given*/ 1482 } else { 1483 LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) { 1484 if(G_Addr->g_addr.s_addr == asconf_ipv4_param->addrp.addr) { 1485 if (assoc->num_Gaddr > 1) { /* only delete if more than one */ 1486 LIST_REMOVE(G_Addr, list_Gaddr); 1487 sn_free(G_Addr); 1488 assoc->num_Gaddr--; 1489 break; /* Since add only adds new addresses, there should be no double entries */ 1490 } else { 1491 SN_LOG(SN_LOG_EVENT, 1492 logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)", 1493 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); 1494 } 1495 } 1496 } 1497 } 1498 } 1499 bytes_left -= param_size; 1500 if (bytes_left == 0) return; 1501 else if (bytes_left < SN_MIN_PARAM_SIZE) { 1502 SN_LOG(SN_LOG_EVENT, 1503 logsctperror("RmGlobalIPAddress: truncated packet - may not have removed all IP addresses", 1504 sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction)); 1505 return; 1506 } |
1529 | 1507 |
1530 param = SN_SCTP_NEXTPARAM(param); 1531 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1532 if (++param_count > sysctl_param_proc_limit) { 1533 SN_LOG(SN_LOG_EVENT, 1534 logsctperror("Parameter parse limit exceeded (RmGlobalIPAddress)", 1535 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); 1536 return; /* limit exceeded*/ 1537 } 1538 } | 1508 param = SN_SCTP_NEXTPARAM(param); 1509 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1510 if (++param_count > sysctl_param_proc_limit) { 1511 SN_LOG(SN_LOG_EVENT, 1512 logsctperror("Parameter parse limit exceeded (RmGlobalIPAddress)", 1513 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); 1514 return; /* limit exceeded*/ 1515 } 1516 } |
1539} 1540 1541/** @ingroup packet_parser 1542 * @brief Check that ASCONF was successful 1543 * 1544 * Each ASCONF configuration parameter carries a correlation ID which should be 1545 * matched with an ASCONFack. This is difficult for a NAT, since every 1546 * association could potentially have a number of outstanding ASCONF --- 11 unchanged lines hidden (view full) --- 1558 * @param sm Pointer to sctp message information 1559 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1560 * 1561 * @return 1 - success | 0 - fail 1562 */ 1563static int 1564IsASCONFack(struct libalias *la, struct sctp_nat_msg *sm, int direction) 1565{ | 1517} 1518 1519/** @ingroup packet_parser 1520 * @brief Check that ASCONF was successful 1521 * 1522 * Each ASCONF configuration parameter carries a correlation ID which should be 1523 * matched with an ASCONFack. This is difficult for a NAT, since every 1524 * association could potentially have a number of outstanding ASCONF --- 11 unchanged lines hidden (view full) --- 1536 * @param sm Pointer to sctp message information 1537 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1538 * 1539 * @return 1 - success | 0 - fail 1540 */ 1541static int 1542IsASCONFack(struct libalias *la, struct sctp_nat_msg *sm, int direction) 1543{ |
1566 struct sctp_paramhdr *param; 1567 int bytes_left; 1568 int param_size; 1569 int param_count; | 1544 struct sctp_paramhdr *param; 1545 int bytes_left; 1546 int param_size; 1547 int param_count; |
1570 | 1548 |
1571 param_count = 1; 1572 param = sm->sctpchnk.Asconf; 1573 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1574 if (param_size == 8) 1575 return(1); /*success - default acknowledgement of everything */ | 1549 param_count = 1; 1550 param = sm->sctpchnk.Asconf; 1551 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1552 if (param_size == 8) 1553 return(1); /*success - default acknowledgement of everything */ |
1576 | 1554 |
1577 bytes_left = sm->chunk_length; 1578 if (bytes_left < param_size) 1579 return(0); /* not found */ 1580 /* step through Asconf parameters */ 1581 while(bytes_left >= SN_ASCONFACK_PARAM_SIZE) { 1582 if (ntohs(param->param_type) == SCTP_SUCCESS_REPORT) 1583 return(1); /* success - but can't match correlation IDs - should only be one */ 1584 /* check others just in case */ 1585 bytes_left -= param_size; 1586 if (bytes_left >= SN_MIN_PARAM_SIZE) { 1587 param = SN_SCTP_NEXTPARAM(param); 1588 } else { 1589 return(0); 1590 } 1591 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1592 if (bytes_left < param_size) return(0); | 1555 bytes_left = sm->chunk_length; 1556 if (bytes_left < param_size) 1557 return(0); /* not found */ 1558 /* step through Asconf parameters */ 1559 while(bytes_left >= SN_ASCONFACK_PARAM_SIZE) { 1560 if (ntohs(param->param_type) == SCTP_SUCCESS_REPORT) 1561 return(1); /* success - but can't match correlation IDs - should only be one */ 1562 /* check others just in case */ 1563 bytes_left -= param_size; 1564 if (bytes_left >= SN_MIN_PARAM_SIZE) { 1565 param = SN_SCTP_NEXTPARAM(param); 1566 } else { 1567 return(0); 1568 } 1569 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1570 if (bytes_left < param_size) return(0); |
1593 | 1571 |
1594 if (++param_count > sysctl_param_proc_limit) { 1595 SN_LOG(SN_LOG_EVENT, 1596 logsctperror("Parameter parse limit exceeded (IsASCONFack)", 1597 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); 1598 return(0); /* not found limit exceeded*/ 1599 } 1600 } 1601 return(0); /* not success */ | 1572 if (++param_count > sysctl_param_proc_limit) { 1573 SN_LOG(SN_LOG_EVENT, 1574 logsctperror("Parameter parse limit exceeded (IsASCONFack)", 1575 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); 1576 return(0); /* not found limit exceeded*/ 1577 } 1578 } 1579 return(0); /* not success */ |
1602} 1603 1604/** @ingroup packet_parser 1605 * @brief Check to see if ASCONF contains an Add IP or Del IP parameter 1606 * 1607 * IsADDorDEL scans an ASCONF packet to see if it contains an AddIP or DelIP 1608 * parameter 1609 * 1610 * @param la Pointer to the relevant libalias instance 1611 * @param sm Pointer to sctp message information 1612 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1613 * 1614 * @return SCTP_ADD_IP_ADDRESS | SCTP_DEL_IP_ADDRESS | 0 - fail 1615 */ 1616static int 1617IsADDorDEL(struct libalias *la, struct sctp_nat_msg *sm, int direction) 1618{ | 1580} 1581 1582/** @ingroup packet_parser 1583 * @brief Check to see if ASCONF contains an Add IP or Del IP parameter 1584 * 1585 * IsADDorDEL scans an ASCONF packet to see if it contains an AddIP or DelIP 1586 * parameter 1587 * 1588 * @param la Pointer to the relevant libalias instance 1589 * @param sm Pointer to sctp message information 1590 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1591 * 1592 * @return SCTP_ADD_IP_ADDRESS | SCTP_DEL_IP_ADDRESS | 0 - fail 1593 */ 1594static int 1595IsADDorDEL(struct libalias *la, struct sctp_nat_msg *sm, int direction) 1596{ |
1619 struct sctp_paramhdr *param; 1620 int bytes_left; 1621 int param_size; 1622 int param_count; | 1597 struct sctp_paramhdr *param; 1598 int bytes_left; 1599 int param_size; 1600 int param_count; |
1623 | 1601 |
1624 param_count = 1; 1625 param = sm->sctpchnk.Asconf; 1626 param_size = SCTP_SIZE32(ntohs(param->param_length)); | 1602 param_count = 1; 1603 param = sm->sctpchnk.Asconf; 1604 param_size = SCTP_SIZE32(ntohs(param->param_length)); |
1627 | 1605 |
1628 bytes_left = sm->chunk_length; 1629 if (bytes_left < param_size) 1630 return(0); /* not found */ 1631 /* step through Asconf parameters */ 1632 while(bytes_left >= SN_ASCONFACK_PARAM_SIZE) { 1633 if (ntohs(param->param_type) == SCTP_ADD_IP_ADDRESS) 1634 return(SCTP_ADD_IP_ADDRESS); 1635 else if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS) 1636 return(SCTP_DEL_IP_ADDRESS); 1637 /* check others just in case */ 1638 bytes_left -= param_size; 1639 if (bytes_left >= SN_MIN_PARAM_SIZE) { 1640 param = SN_SCTP_NEXTPARAM(param); 1641 } else { 1642 return(0); /*Neither found */ 1643 } 1644 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1645 if (bytes_left < param_size) return(0); | 1606 bytes_left = sm->chunk_length; 1607 if (bytes_left < param_size) 1608 return(0); /* not found */ 1609 /* step through Asconf parameters */ 1610 while(bytes_left >= SN_ASCONFACK_PARAM_SIZE) { 1611 if (ntohs(param->param_type) == SCTP_ADD_IP_ADDRESS) 1612 return(SCTP_ADD_IP_ADDRESS); 1613 else if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS) 1614 return(SCTP_DEL_IP_ADDRESS); 1615 /* check others just in case */ 1616 bytes_left -= param_size; 1617 if (bytes_left >= SN_MIN_PARAM_SIZE) { 1618 param = SN_SCTP_NEXTPARAM(param); 1619 } else { 1620 return(0); /*Neither found */ 1621 } 1622 param_size = SCTP_SIZE32(ntohs(param->param_length)); 1623 if (bytes_left < param_size) return(0); |
1646 | 1624 |
1647 if (++param_count > sysctl_param_proc_limit) { 1648 SN_LOG(SN_LOG_EVENT, 1649 logsctperror("Parameter parse limit exceeded IsADDorDEL)", 1650 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); 1651 return(0); /* not found limit exceeded*/ 1652 } 1653 } 1654 return(0); /*Neither found */ | 1625 if (++param_count > sysctl_param_proc_limit) { 1626 SN_LOG(SN_LOG_EVENT, 1627 logsctperror("Parameter parse limit exceeded IsADDorDEL)", 1628 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); 1629 return(0); /* not found limit exceeded*/ 1630 } 1631 } 1632 return(0); /*Neither found */ |
1655} 1656 1657/* ---------------------------------------------------------------------- 1658 * STATE MACHINE CODE 1659 * ---------------------------------------------------------------------- 1660 */ 1661/** @addtogroup state_machine 1662 * --- 15 unchanged lines hidden (view full) --- 1678 * @param sm Pointer to sctp message information 1679 * @param assoc Pointer to the association this SCTP Message belongs to 1680 * 1681 * @return SN_DROP_PKT | SN_NAT_PKT | SN_REPLY_ABORT | SN_REPLY_ERROR | SN_PROCESSING_ERROR 1682 */ 1683static int 1684ProcessSctpMsg(struct libalias *la, int direction, struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc) 1685{ | 1633} 1634 1635/* ---------------------------------------------------------------------- 1636 * STATE MACHINE CODE 1637 * ---------------------------------------------------------------------- 1638 */ 1639/** @addtogroup state_machine 1640 * --- 15 unchanged lines hidden (view full) --- 1656 * @param sm Pointer to sctp message information 1657 * @param assoc Pointer to the association this SCTP Message belongs to 1658 * 1659 * @return SN_DROP_PKT | SN_NAT_PKT | SN_REPLY_ABORT | SN_REPLY_ERROR | SN_PROCESSING_ERROR 1660 */ 1661static int 1662ProcessSctpMsg(struct libalias *la, int direction, struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc) 1663{ |
1686 int rtnval; | 1664 int rtnval; |
1687 | 1665 |
1688 switch (assoc->state) { 1689 case SN_ID: /* Idle */ 1690 rtnval = ID_process(la, direction, assoc, sm); 1691 if (rtnval != SN_NAT_PKT) { 1692 assoc->state = SN_RM;/* Mark for removal*/ 1693 } 1694 return(rtnval); 1695 case SN_INi: /* Initialising - Init */ 1696 return(INi_process(la, direction, assoc, sm)); 1697 case SN_INa: /* Initialising - AddIP */ 1698 return(INa_process(la, direction, assoc, sm)); 1699 case SN_UP: /* Association UP */ 1700 return(UP_process(la, direction, assoc, sm)); 1701 case SN_CL: /* Association Closing */ 1702 return(CL_process(la, direction, assoc, sm)); 1703 } 1704 return(SN_PROCESSING_ERROR); | 1666 switch (assoc->state) { 1667 case SN_ID: /* Idle */ 1668 rtnval = ID_process(la, direction, assoc, sm); 1669 if (rtnval != SN_NAT_PKT) { 1670 assoc->state = SN_RM;/* Mark for removal*/ 1671 } 1672 return(rtnval); 1673 case SN_INi: /* Initialising - Init */ 1674 return(INi_process(la, direction, assoc, sm)); 1675 case SN_INa: /* Initialising - AddIP */ 1676 return(INa_process(la, direction, assoc, sm)); 1677 case SN_UP: /* Association UP */ 1678 return(UP_process(la, direction, assoc, sm)); 1679 case SN_CL: /* Association Closing */ 1680 return(CL_process(la, direction, assoc, sm)); 1681 } 1682 return(SN_PROCESSING_ERROR); |
1705} 1706 1707/** @ingroup state_machine 1708 * @brief Process SCTP message while in the Idle state 1709 * 1710 * This function looks for an Incoming INIT or AddIP message. 1711 * 1712 * All other SCTP messages are invalid when in SN_ID, and are dropped. 1713 * 1714 * @param la Pointer to the relevant libalias instance 1715 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1716 * @param sm Pointer to sctp message information 1717 * @param assoc Pointer to the association this SCTP Message belongs to 1718 * 1719 * @return SN_NAT_PKT | SN_DROP_PKT | SN_REPLY_ABORT | SN_REPLY_ERROR 1720 */ 1721static int 1722ID_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) 1723{ | 1683} 1684 1685/** @ingroup state_machine 1686 * @brief Process SCTP message while in the Idle state 1687 * 1688 * This function looks for an Incoming INIT or AddIP message. 1689 * 1690 * All other SCTP messages are invalid when in SN_ID, and are dropped. 1691 * 1692 * @param la Pointer to the relevant libalias instance 1693 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1694 * @param sm Pointer to sctp message information 1695 * @param assoc Pointer to the association this SCTP Message belongs to 1696 * 1697 * @return SN_NAT_PKT | SN_DROP_PKT | SN_REPLY_ABORT | SN_REPLY_ERROR 1698 */ 1699static int 1700ID_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) 1701{ |
1724 switch(sm->msg) { 1725 case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk with ADDIP */ 1726 if (!sysctl_accept_global_ootb_addip && (direction == SN_TO_LOCAL)) 1727 return(SN_DROP_PKT); 1728 /* if this Asconf packet does not contain the Vtag parameters it is of no use in Idle state */ 1729 if (!GetAsconfVtags(la, sm, &(assoc->l_vtag), &(assoc->g_vtag), direction)) 1730 return(SN_DROP_PKT); 1731 case SN_SCTP_INIT: /* a packet containing an INIT chunk or an ASCONF AddIP */ 1732 if (sysctl_track_global_addresses) 1733 AddGlobalIPAddresses(sm, assoc, direction); 1734 switch(direction){ 1735 case SN_TO_GLOBAL: 1736 assoc->l_addr = sm->ip_hdr->ip_src; 1737 assoc->a_addr = FindAliasAddress(la, assoc->l_addr); 1738 assoc->l_port = sm->sctp_hdr->src_port; 1739 assoc->g_port = sm->sctp_hdr->dest_port; 1740 if(sm->msg == SN_SCTP_INIT) 1741 assoc->g_vtag = sm->sctpchnk.Init->initiate_tag; 1742 if (AddSctpAssocGlobal(la, assoc)) /* DB clash *///**** need to add dst address 1743 return((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR); 1744 if(sm->msg == SN_SCTP_ASCONF) { 1745 if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_dst)) /* DB clash */ 1746 return(SN_REPLY_ERROR); 1747 assoc->TableRegister |= SN_WAIT_TOLOCAL; /* wait for tolocal ack */ 1748 } 1749 break; 1750 case SN_TO_LOCAL: 1751 assoc->l_addr = FindSctpRedirectAddress(la, sm); 1752 assoc->a_addr = sm->ip_hdr->ip_dst; 1753 assoc->l_port = sm->sctp_hdr->dest_port; 1754 assoc->g_port = sm->sctp_hdr->src_port; 1755 if(sm->msg == SN_SCTP_INIT) 1756 assoc->l_vtag = sm->sctpchnk.Init->initiate_tag; 1757 if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_src)) /* DB clash */ 1758 return((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR); 1759 if(sm->msg == SN_SCTP_ASCONF) { 1760 if (AddSctpAssocGlobal(la, assoc)) /* DB clash */ //**** need to add src address 1761 return(SN_REPLY_ERROR); 1762 assoc->TableRegister |= SN_WAIT_TOGLOBAL; /* wait for toglobal ack */ 1763 } 1764 break; 1765 } 1766 assoc->state = (sm->msg == SN_SCTP_INIT) ? SN_INi : SN_INa; 1767 assoc->exp = SN_I_T(la); 1768 sctp_AddTimeOut(la,assoc); 1769 return(SN_NAT_PKT); 1770 default: /* Any other type of SCTP message is not valid in Idle */ 1771 return(SN_DROP_PKT); 1772 } 1773 return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ | 1702 switch(sm->msg) { 1703 case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk with ADDIP */ 1704 if (!sysctl_accept_global_ootb_addip && (direction == SN_TO_LOCAL)) 1705 return(SN_DROP_PKT); 1706 /* if this Asconf packet does not contain the Vtag parameters it is of no use in Idle state */ 1707 if (!GetAsconfVtags(la, sm, &(assoc->l_vtag), &(assoc->g_vtag), direction)) 1708 return(SN_DROP_PKT); 1709 case SN_SCTP_INIT: /* a packet containing an INIT chunk or an ASCONF AddIP */ 1710 if (sysctl_track_global_addresses) 1711 AddGlobalIPAddresses(sm, assoc, direction); 1712 switch(direction){ 1713 case SN_TO_GLOBAL: 1714 assoc->l_addr = sm->ip_hdr->ip_src; 1715 assoc->a_addr = FindAliasAddress(la, assoc->l_addr); 1716 assoc->l_port = sm->sctp_hdr->src_port; 1717 assoc->g_port = sm->sctp_hdr->dest_port; 1718 if(sm->msg == SN_SCTP_INIT) 1719 assoc->g_vtag = sm->sctpchnk.Init->initiate_tag; 1720 if (AddSctpAssocGlobal(la, assoc)) /* DB clash *///**** need to add dst address 1721 return((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR); 1722 if(sm->msg == SN_SCTP_ASCONF) { 1723 if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_dst)) /* DB clash */ 1724 return(SN_REPLY_ERROR); 1725 assoc->TableRegister |= SN_WAIT_TOLOCAL; /* wait for tolocal ack */ 1726 } 1727 break; 1728 case SN_TO_LOCAL: 1729 assoc->l_addr = FindSctpRedirectAddress(la, sm); 1730 assoc->a_addr = sm->ip_hdr->ip_dst; 1731 assoc->l_port = sm->sctp_hdr->dest_port; 1732 assoc->g_port = sm->sctp_hdr->src_port; 1733 if(sm->msg == SN_SCTP_INIT) 1734 assoc->l_vtag = sm->sctpchnk.Init->initiate_tag; 1735 if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_src)) /* DB clash */ 1736 return((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR); 1737 if(sm->msg == SN_SCTP_ASCONF) { 1738 if (AddSctpAssocGlobal(la, assoc)) /* DB clash */ //**** need to add src address 1739 return(SN_REPLY_ERROR); 1740 assoc->TableRegister |= SN_WAIT_TOGLOBAL; /* wait for toglobal ack */ 1741 } 1742 break; 1743 } 1744 assoc->state = (sm->msg == SN_SCTP_INIT) ? SN_INi : SN_INa; 1745 assoc->exp = SN_I_T(la); 1746 sctp_AddTimeOut(la,assoc); 1747 return(SN_NAT_PKT); 1748 default: /* Any other type of SCTP message is not valid in Idle */ 1749 return(SN_DROP_PKT); 1750 } 1751return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ |
1774} 1775 1776/** @ingroup state_machine 1777 * @brief Process SCTP message while waiting for an INIT-ACK message 1778 * 1779 * Only an INIT-ACK, resent INIT, or an ABORT SCTP packet are valid in this 1780 * state, all other packets are dropped. 1781 * 1782 * @param la Pointer to the relevant libalias instance 1783 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1784 * @param sm Pointer to sctp message information 1785 * @param assoc Pointer to the association this SCTP Message belongs to 1786 * 1787 * @return SN_NAT_PKT | SN_DROP_PKT | SN_REPLY_ABORT 1788 */ 1789static int 1790INi_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) 1791{ | 1752} 1753 1754/** @ingroup state_machine 1755 * @brief Process SCTP message while waiting for an INIT-ACK message 1756 * 1757 * Only an INIT-ACK, resent INIT, or an ABORT SCTP packet are valid in this 1758 * state, all other packets are dropped. 1759 * 1760 * @param la Pointer to the relevant libalias instance 1761 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1762 * @param sm Pointer to sctp message information 1763 * @param assoc Pointer to the association this SCTP Message belongs to 1764 * 1765 * @return SN_NAT_PKT | SN_DROP_PKT | SN_REPLY_ABORT 1766 */ 1767static int 1768INi_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) 1769{ |
1792 switch(sm->msg) { 1793 case SN_SCTP_INIT: /* a packet containing a retransmitted INIT chunk */ 1794 sctp_ResetTimeOut(la, assoc, SN_I_T(la)); 1795 return(SN_NAT_PKT); 1796 case SN_SCTP_INITACK: /* a packet containing an INIT-ACK chunk */ 1797 switch(direction){ 1798 case SN_TO_LOCAL: 1799 if (assoc->num_Gaddr) /*If tracking global addresses for this association */ 1800 AddGlobalIPAddresses(sm, assoc, direction); 1801 assoc->l_vtag = sm->sctpchnk.Init->initiate_tag; 1802 if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_src)) { /* DB clash */ 1803 assoc->state = SN_RM;/* Mark for removal*/ 1804 return(SN_SEND_ABORT); 1805 } 1806 break; 1807 case SN_TO_GLOBAL: 1808 assoc->l_addr = sm->ip_hdr->ip_src; // Only if not set in Init! * 1809 assoc->g_vtag = sm->sctpchnk.Init->initiate_tag; 1810 if (AddSctpAssocGlobal(la, assoc)) { /* DB clash */ 1811 assoc->state = SN_RM;/* Mark for removal*/ 1812 return(SN_SEND_ABORT); 1813 } 1814 break; 1815 } 1816 assoc->state = SN_UP;/* association established for NAT */ 1817 sctp_ResetTimeOut(la,assoc, SN_U_T(la)); 1818 return(SN_NAT_PKT); 1819 case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */ 1820 assoc->state = SN_RM;/* Mark for removal*/ 1821 return(SN_NAT_PKT); 1822 default: 1823 return(SN_DROP_PKT); 1824 } 1825 return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ | 1770 switch(sm->msg) { 1771 case SN_SCTP_INIT: /* a packet containing a retransmitted INIT chunk */ 1772 sctp_ResetTimeOut(la, assoc, SN_I_T(la)); 1773 return(SN_NAT_PKT); 1774 case SN_SCTP_INITACK: /* a packet containing an INIT-ACK chunk */ 1775 switch(direction){ 1776 case SN_TO_LOCAL: 1777 if (assoc->num_Gaddr) /*If tracking global addresses for this association */ 1778 AddGlobalIPAddresses(sm, assoc, direction); 1779 assoc->l_vtag = sm->sctpchnk.Init->initiate_tag; 1780 if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_src)) { /* DB clash */ 1781 assoc->state = SN_RM;/* Mark for removal*/ 1782 return(SN_SEND_ABORT); 1783 } 1784 break; 1785 case SN_TO_GLOBAL: 1786 assoc->l_addr = sm->ip_hdr->ip_src; // Only if not set in Init! * 1787 assoc->g_vtag = sm->sctpchnk.Init->initiate_tag; 1788 if (AddSctpAssocGlobal(la, assoc)) { /* DB clash */ 1789 assoc->state = SN_RM;/* Mark for removal*/ 1790 return(SN_SEND_ABORT); 1791 } 1792 break; 1793 } 1794 assoc->state = SN_UP;/* association established for NAT */ 1795 sctp_ResetTimeOut(la,assoc, SN_U_T(la)); 1796 return(SN_NAT_PKT); 1797 case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */ 1798 assoc->state = SN_RM;/* Mark for removal*/ 1799 return(SN_NAT_PKT); 1800 default: 1801 return(SN_DROP_PKT); 1802 } 1803 return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ |
1826} 1827 1828/** @ingroup state_machine 1829 * @brief Process SCTP message while waiting for an AddIp-ACK message 1830 * 1831 * Only an AddIP-ACK, resent AddIP, or an ABORT message are valid, all other 1832 * SCTP packets are dropped 1833 * 1834 * @param la Pointer to the relevant libalias instance 1835 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1836 * @param sm Pointer to sctp message information 1837 * @param assoc Pointer to the association this SCTP Message belongs to 1838 * 1839 * @return SN_NAT_PKT | SN_DROP_PKT 1840 */ 1841static int 1842INa_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) 1843{ | 1804} 1805 1806/** @ingroup state_machine 1807 * @brief Process SCTP message while waiting for an AddIp-ACK message 1808 * 1809 * Only an AddIP-ACK, resent AddIP, or an ABORT message are valid, all other 1810 * SCTP packets are dropped 1811 * 1812 * @param la Pointer to the relevant libalias instance 1813 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1814 * @param sm Pointer to sctp message information 1815 * @param assoc Pointer to the association this SCTP Message belongs to 1816 * 1817 * @return SN_NAT_PKT | SN_DROP_PKT 1818 */ 1819static int 1820INa_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) 1821{ |
1844 switch(sm->msg) { 1845 case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk*/ 1846 sctp_ResetTimeOut(la,assoc, SN_I_T(la)); 1847 return(SN_NAT_PKT); 1848 case SN_SCTP_ASCONFACK: /* a packet containing an ASCONF chunk with a ADDIP-ACK */ 1849 switch(direction){ 1850 case SN_TO_LOCAL: 1851 if (!(assoc->TableRegister & SN_WAIT_TOLOCAL)) /* wrong direction */ 1852 return(SN_DROP_PKT); 1853 break; 1854 case SN_TO_GLOBAL: 1855 if (!(assoc->TableRegister & SN_WAIT_TOGLOBAL)) /* wrong direction */ 1856 return(SN_DROP_PKT); 1857 } 1858 if (IsASCONFack(la,sm,direction)) { 1859 assoc->TableRegister &= SN_BOTH_TBL; /* remove wait flags */ 1860 assoc->state = SN_UP; /* association established for NAT */ 1861 sctp_ResetTimeOut(la,assoc, SN_U_T(la)); 1862 return(SN_NAT_PKT); 1863 } else { 1864 assoc->state = SN_RM;/* Mark for removal*/ 1865 return(SN_NAT_PKT); 1866 } 1867 case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */ 1868 assoc->state = SN_RM;/* Mark for removal*/ 1869 return(SN_NAT_PKT); 1870 default: 1871 return(SN_DROP_PKT); 1872 } 1873 return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ | 1822 switch(sm->msg) { 1823 case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk*/ 1824 sctp_ResetTimeOut(la,assoc, SN_I_T(la)); 1825 return(SN_NAT_PKT); 1826 case SN_SCTP_ASCONFACK: /* a packet containing an ASCONF chunk with a ADDIP-ACK */ 1827 switch(direction){ 1828 case SN_TO_LOCAL: 1829 if (!(assoc->TableRegister & SN_WAIT_TOLOCAL)) /* wrong direction */ 1830 return(SN_DROP_PKT); 1831 break; 1832 case SN_TO_GLOBAL: 1833 if (!(assoc->TableRegister & SN_WAIT_TOGLOBAL)) /* wrong direction */ 1834 return(SN_DROP_PKT); 1835 } 1836 if (IsASCONFack(la,sm,direction)) { 1837 assoc->TableRegister &= SN_BOTH_TBL; /* remove wait flags */ 1838 assoc->state = SN_UP; /* association established for NAT */ 1839 sctp_ResetTimeOut(la,assoc, SN_U_T(la)); 1840 return(SN_NAT_PKT); 1841 } else { 1842 assoc->state = SN_RM;/* Mark for removal*/ 1843 return(SN_NAT_PKT); 1844 } 1845 case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */ 1846 assoc->state = SN_RM;/* Mark for removal*/ 1847 return(SN_NAT_PKT); 1848 default: 1849 return(SN_DROP_PKT); 1850 } 1851 return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ |
1874} 1875 1876/** @ingroup state_machine 1877 * @brief Process SCTP messages while association is UP redirecting packets 1878 * 1879 * While in the SN_UP state, all packets for the particular association 1880 * are passed. Only a SHUT-ACK or an ABORT will cause a change of state. 1881 * 1882 * @param la Pointer to the relevant libalias instance 1883 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1884 * @param sm Pointer to sctp message information 1885 * @param assoc Pointer to the association this SCTP Message belongs to 1886 * 1887 * @return SN_NAT_PKT | SN_DROP_PKT 1888 */ 1889static int 1890UP_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) 1891{ | 1852} 1853 1854/** @ingroup state_machine 1855 * @brief Process SCTP messages while association is UP redirecting packets 1856 * 1857 * While in the SN_UP state, all packets for the particular association 1858 * are passed. Only a SHUT-ACK or an ABORT will cause a change of state. 1859 * 1860 * @param la Pointer to the relevant libalias instance 1861 * @param direction SN_TO_LOCAL | SN_TO_GLOBAL 1862 * @param sm Pointer to sctp message information 1863 * @param assoc Pointer to the association this SCTP Message belongs to 1864 * 1865 * @return SN_NAT_PKT | SN_DROP_PKT 1866 */ 1867static int 1868UP_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) 1869{ |
1892 switch(sm->msg) { 1893 case SN_SCTP_SHUTACK: /* a packet containing a SHUTDOWN-ACK chunk */ 1894 assoc->state = SN_CL; 1895 sctp_ResetTimeOut(la,assoc, SN_C_T(la)); 1896 return(SN_NAT_PKT); 1897 case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */ 1898 assoc->state = SN_RM;/* Mark for removal*/ 1899 return(SN_NAT_PKT); 1900 case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk*/ 1901 if ((direction == SN_TO_LOCAL) && assoc->num_Gaddr) /*If tracking global addresses for this association & from global side */ 1902 switch(IsADDorDEL(la,sm,direction)) { 1903 case SCTP_ADD_IP_ADDRESS: 1904 AddGlobalIPAddresses(sm, assoc, direction); 1905 break; 1906 case SCTP_DEL_IP_ADDRESS: 1907 RmGlobalIPAddresses(sm, assoc, direction); 1908 break; 1909 } /* fall through to default */ 1910 default: 1911 sctp_ResetTimeOut(la,assoc, SN_U_T(la)); 1912 return(SN_NAT_PKT); /* forward packet */ 1913 } 1914 return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ | 1870 switch(sm->msg) { 1871 case SN_SCTP_SHUTACK: /* a packet containing a SHUTDOWN-ACK chunk */ 1872 assoc->state = SN_CL; 1873 sctp_ResetTimeOut(la,assoc, SN_C_T(la)); 1874 return(SN_NAT_PKT); 1875 case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */ 1876 assoc->state = SN_RM;/* Mark for removal*/ 1877 return(SN_NAT_PKT); 1878 case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk*/ 1879 if ((direction == SN_TO_LOCAL) && assoc->num_Gaddr) /*If tracking global addresses for this association & from global side */ 1880 switch(IsADDorDEL(la,sm,direction)) { 1881 case SCTP_ADD_IP_ADDRESS: 1882 AddGlobalIPAddresses(sm, assoc, direction); 1883 break; 1884 case SCTP_DEL_IP_ADDRESS: 1885 RmGlobalIPAddresses(sm, assoc, direction); 1886 break; 1887 } /* fall through to default */ 1888 default: 1889 sctp_ResetTimeOut(la,assoc, SN_U_T(la)); 1890 return(SN_NAT_PKT); /* forward packet */ 1891 } 1892 return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ |
1915} 1916 1917/** @ingroup state_machine 1918 * @brief Process SCTP message while association is in the process of closing 1919 * 1920 * This function waits for a SHUT-COMP to close the association. Depending on 1921 * the the setting of sysctl_holddown_timer it may not remove the association 1922 * immediately, but leave it up until SN_X_T(la). Only SHUT-COMP, SHUT-ACK, and --- 4 unchanged lines hidden (view full) --- 1927 * @param sm Pointer to sctp message information 1928 * @param assoc Pointer to the association this SCTP Message belongs to 1929 * 1930 * @return SN_NAT_PKT | SN_DROP_PKT 1931 */ 1932static int 1933CL_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) 1934{ | 1893} 1894 1895/** @ingroup state_machine 1896 * @brief Process SCTP message while association is in the process of closing 1897 * 1898 * This function waits for a SHUT-COMP to close the association. Depending on 1899 * the the setting of sysctl_holddown_timer it may not remove the association 1900 * immediately, but leave it up until SN_X_T(la). Only SHUT-COMP, SHUT-ACK, and --- 4 unchanged lines hidden (view full) --- 1905 * @param sm Pointer to sctp message information 1906 * @param assoc Pointer to the association this SCTP Message belongs to 1907 * 1908 * @return SN_NAT_PKT | SN_DROP_PKT 1909 */ 1910static int 1911CL_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm) 1912{ |
1935 switch(sm->msg) { 1936 case SN_SCTP_SHUTCOMP: /* a packet containing a SHUTDOWN-COMPLETE chunk */ 1937 assoc->state = SN_CL; /* Stay in Close state until timeout */ 1938 if (sysctl_holddown_timer > 0) 1939 sctp_ResetTimeOut(la, assoc, SN_X_T(la));/* allow to stay open for Tbit packets*/ 1940 else 1941 assoc->state = SN_RM;/* Mark for removal*/ 1942 return(SN_NAT_PKT); 1943 case SN_SCTP_SHUTACK: /* a packet containing a SHUTDOWN-ACK chunk */ 1944 assoc->state = SN_CL; /* Stay in Close state until timeout */ 1945 sctp_ResetTimeOut(la, assoc, SN_C_T(la)); 1946 return(SN_NAT_PKT); 1947 case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */ 1948 assoc->state = SN_RM;/* Mark for removal*/ 1949 return(SN_NAT_PKT); 1950 default: 1951 return(SN_DROP_PKT); 1952 } 1953 return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ | 1913 switch(sm->msg) { 1914 case SN_SCTP_SHUTCOMP: /* a packet containing a SHUTDOWN-COMPLETE chunk */ 1915 assoc->state = SN_CL; /* Stay in Close state until timeout */ 1916 if (sysctl_holddown_timer > 0) 1917 sctp_ResetTimeOut(la, assoc, SN_X_T(la));/* allow to stay open for Tbit packets*/ 1918 else 1919 assoc->state = SN_RM;/* Mark for removal*/ 1920 return(SN_NAT_PKT); 1921 case SN_SCTP_SHUTACK: /* a packet containing a SHUTDOWN-ACK chunk */ 1922 assoc->state = SN_CL; /* Stay in Close state until timeout */ 1923 sctp_ResetTimeOut(la, assoc, SN_C_T(la)); 1924 return(SN_NAT_PKT); 1925 case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */ 1926 assoc->state = SN_RM;/* Mark for removal*/ 1927 return(SN_NAT_PKT); 1928 default: 1929 return(SN_DROP_PKT); 1930 } 1931 return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ |
1954} 1955 1956/* ---------------------------------------------------------------------- 1957 * HASH TABLE CODE 1958 * ---------------------------------------------------------------------- 1959 */ 1960/** @addtogroup Hash 1961 * --- 13 unchanged lines hidden (view full) --- 1975 * @param l_port local Port 1976 * @param g_port global Port 1977 * 1978 * @return pointer to association or NULL 1979 */ 1980static struct sctp_nat_assoc* 1981FindSctpLocal(struct libalias *la, struct in_addr l_addr, struct in_addr g_addr, uint32_t l_vtag, uint16_t l_port, uint16_t g_port) 1982{ | 1932} 1933 1934/* ---------------------------------------------------------------------- 1935 * HASH TABLE CODE 1936 * ---------------------------------------------------------------------- 1937 */ 1938/** @addtogroup Hash 1939 * --- 13 unchanged lines hidden (view full) --- 1953 * @param l_port local Port 1954 * @param g_port global Port 1955 * 1956 * @return pointer to association or NULL 1957 */ 1958static struct sctp_nat_assoc* 1959FindSctpLocal(struct libalias *la, struct in_addr l_addr, struct in_addr g_addr, uint32_t l_vtag, uint16_t l_port, uint16_t g_port) 1960{ |
1983 u_int i; 1984 struct sctp_nat_assoc *assoc = NULL; 1985 struct sctp_GlobalAddress *G_Addr = NULL; | 1961 u_int i; 1962 struct sctp_nat_assoc *assoc = NULL; 1963 struct sctp_GlobalAddress *G_Addr = NULL; |
1986 | 1964 |
1987 if (l_vtag != 0) { /* an init packet, vtag==0 */ 1988 i = SN_TABLE_HASH(l_vtag, l_port, la->sctpNatTableSize); 1989 LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) { 1990 if ((assoc->l_vtag == l_vtag) && (assoc->l_port == l_port) && (assoc->g_port == g_port)\ 1991 && (assoc->l_addr.s_addr == l_addr.s_addr)) { 1992 if (assoc->num_Gaddr) { 1993 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { 1994 if(G_Addr->g_addr.s_addr == g_addr.s_addr) 1995 return(assoc); 1996 } 1997 } else { 1998 return(assoc); | 1965 if (l_vtag != 0) { /* an init packet, vtag==0 */ 1966 i = SN_TABLE_HASH(l_vtag, l_port, la->sctpNatTableSize); 1967 LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) { 1968 if ((assoc->l_vtag == l_vtag) && (assoc->l_port == l_port) && (assoc->g_port == g_port)\ 1969 && (assoc->l_addr.s_addr == l_addr.s_addr)) { 1970 if (assoc->num_Gaddr) { 1971 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { 1972 if(G_Addr->g_addr.s_addr == g_addr.s_addr) 1973 return(assoc); 1974 } 1975 } else { 1976 return(assoc); 1977 } 1978 } 1979 } |
1999 } | 1980 } |
2000 } 2001 } 2002 } 2003 return(NULL); | 1981 return(NULL); |
2004} 2005 2006/** @ingroup Hash 2007 * @brief Check for Global Clash 2008 * 2009 * Searches the global look-up table for the association entry matching the 2010 * provided global <(addresses):ports:vtag> tuple 2011 * 2012 * @param la Pointer to the relevant libalias instance 2013 * @param Cassoc association being checked for a clash 2014 * 2015 * @return pointer to association or NULL 2016 */ 2017static struct sctp_nat_assoc* 2018FindSctpGlobalClash(struct libalias *la, struct sctp_nat_assoc *Cassoc) 2019{ | 1982} 1983 1984/** @ingroup Hash 1985 * @brief Check for Global Clash 1986 * 1987 * Searches the global look-up table for the association entry matching the 1988 * provided global <(addresses):ports:vtag> tuple 1989 * 1990 * @param la Pointer to the relevant libalias instance 1991 * @param Cassoc association being checked for a clash 1992 * 1993 * @return pointer to association or NULL 1994 */ 1995static struct sctp_nat_assoc* 1996FindSctpGlobalClash(struct libalias *la, struct sctp_nat_assoc *Cassoc) 1997{ |
2020 u_int i; 2021 struct sctp_nat_assoc *assoc = NULL; 2022 struct sctp_GlobalAddress *G_Addr = NULL; 2023 struct sctp_GlobalAddress *G_AddrC = NULL; | 1998 u_int i; 1999 struct sctp_nat_assoc *assoc = NULL; 2000 struct sctp_GlobalAddress *G_Addr = NULL; 2001 struct sctp_GlobalAddress *G_AddrC = NULL; |
2024 | 2002 |
2025 if (Cassoc->g_vtag != 0) { /* an init packet, vtag==0 */ 2026 i = SN_TABLE_HASH(Cassoc->g_vtag, Cassoc->g_port, la->sctpNatTableSize); 2027 LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { 2028 if ((assoc->g_vtag == Cassoc->g_vtag) && (assoc->g_port == Cassoc->g_port) && (assoc->l_port == Cassoc->l_port)) { 2029 if (assoc->num_Gaddr) { 2030 LIST_FOREACH(G_AddrC, &(Cassoc->Gaddr), list_Gaddr) { 2031 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { 2032 if(G_Addr->g_addr.s_addr == G_AddrC->g_addr.s_addr) 2033 return(assoc); 2034 } 2035 } 2036 } else { 2037 return(assoc); | 2003 if (Cassoc->g_vtag != 0) { /* an init packet, vtag==0 */ 2004 i = SN_TABLE_HASH(Cassoc->g_vtag, Cassoc->g_port, la->sctpNatTableSize); 2005 LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { 2006 if ((assoc->g_vtag == Cassoc->g_vtag) && (assoc->g_port == Cassoc->g_port) && (assoc->l_port == Cassoc->l_port)) { 2007 if (assoc->num_Gaddr) { 2008 LIST_FOREACH(G_AddrC, &(Cassoc->Gaddr), list_Gaddr) { 2009 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { 2010 if(G_Addr->g_addr.s_addr == G_AddrC->g_addr.s_addr) 2011 return(assoc); 2012 } 2013 } 2014 } else { 2015 return(assoc); 2016 } 2017 } 2018 } |
2038 } | 2019 } |
2039 } 2040 } 2041 } 2042 return(NULL); | 2020 return(NULL); |
2043} 2044 2045/** @ingroup Hash 2046 * @brief Find the SCTP association given the global port and vtag 2047 * 2048 * Searches the global look-up table for the association entry matching the 2049 * provided global <address:ports:vtag> tuple 2050 * --- 8 unchanged lines hidden (view full) --- 2059 * @param g_port global port 2060 * @param l_port local port 2061 * 2062 * @return pointer to association or NULL 2063 */ 2064static struct sctp_nat_assoc* 2065FindSctpGlobal(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint16_t g_port, uint16_t l_port, int *partial_match) 2066{ | 2021} 2022 2023/** @ingroup Hash 2024 * @brief Find the SCTP association given the global port and vtag 2025 * 2026 * Searches the global look-up table for the association entry matching the 2027 * provided global <address:ports:vtag> tuple 2028 * --- 8 unchanged lines hidden (view full) --- 2037 * @param g_port global port 2038 * @param l_port local port 2039 * 2040 * @return pointer to association or NULL 2041 */ 2042static struct sctp_nat_assoc* 2043FindSctpGlobal(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint16_t g_port, uint16_t l_port, int *partial_match) 2044{ |
2067 u_int i; 2068 struct sctp_nat_assoc *assoc = NULL; 2069 struct sctp_GlobalAddress *G_Addr = NULL; | 2045 u_int i; 2046 struct sctp_nat_assoc *assoc = NULL; 2047 struct sctp_GlobalAddress *G_Addr = NULL; |
2070 | 2048 |
2071 *partial_match = 0; 2072 if (g_vtag != 0) { /* an init packet, vtag==0 */ 2073 i = SN_TABLE_HASH(g_vtag, g_port, la->sctpNatTableSize); 2074 LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { 2075 if ((assoc->g_vtag == g_vtag) && (assoc->g_port == g_port) && (assoc->l_port == l_port)) { 2076 *partial_match = 1; 2077 if (assoc->num_Gaddr) { 2078 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { 2079 if(G_Addr->g_addr.s_addr == g_addr.s_addr) 2080 return(assoc); 2081 } 2082 } else { 2083 return(assoc); | 2049 *partial_match = 0; 2050 if (g_vtag != 0) { /* an init packet, vtag==0 */ 2051 i = SN_TABLE_HASH(g_vtag, g_port, la->sctpNatTableSize); 2052 LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { 2053 if ((assoc->g_vtag == g_vtag) && (assoc->g_port == g_port) && (assoc->l_port == l_port)) { 2054 *partial_match = 1; 2055 if (assoc->num_Gaddr) { 2056 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { 2057 if(G_Addr->g_addr.s_addr == g_addr.s_addr) 2058 return(assoc); 2059 } 2060 } else { 2061 return(assoc); 2062 } 2063 } 2064 } |
2084 } | 2065 } |
2085 } 2086 } 2087 } 2088 return(NULL); | 2066 return(NULL); |
2089} 2090 2091/** @ingroup Hash 2092 * @brief Find the SCTP association for a T-Flag message (given the global port and local vtag) 2093 * 2094 * Searches the local look-up table for a unique association entry matching the 2095 * provided global port and local vtag information 2096 * 2097 * @param la Pointer to the relevant libalias instance 2098 * @param g_addr global address 2099 * @param l_vtag local Vtag 2100 * @param g_port global Port 2101 * @param l_port local Port 2102 * 2103 * @return pointer to association or NULL 2104 */ 2105static struct sctp_nat_assoc* 2106FindSctpLocalT(struct libalias *la, struct in_addr g_addr, uint32_t l_vtag, uint16_t g_port, uint16_t l_port) 2107{ | 2067} 2068 2069/** @ingroup Hash 2070 * @brief Find the SCTP association for a T-Flag message (given the global port and local vtag) 2071 * 2072 * Searches the local look-up table for a unique association entry matching the 2073 * provided global port and local vtag information 2074 * 2075 * @param la Pointer to the relevant libalias instance 2076 * @param g_addr global address 2077 * @param l_vtag local Vtag 2078 * @param g_port global Port 2079 * @param l_port local Port 2080 * 2081 * @return pointer to association or NULL 2082 */ 2083static struct sctp_nat_assoc* 2084FindSctpLocalT(struct libalias *la, struct in_addr g_addr, uint32_t l_vtag, uint16_t g_port, uint16_t l_port) 2085{ |
2108 u_int i; 2109 struct sctp_nat_assoc *assoc = NULL, *lastmatch = NULL; 2110 struct sctp_GlobalAddress *G_Addr = NULL; 2111 int cnt = 0; | 2086 u_int i; 2087 struct sctp_nat_assoc *assoc = NULL, *lastmatch = NULL; 2088 struct sctp_GlobalAddress *G_Addr = NULL; 2089 int cnt = 0; |
2112 | 2090 |
2113 if (l_vtag != 0) { /* an init packet, vtag==0 */ 2114 i = SN_TABLE_HASH(l_vtag, g_port, la->sctpNatTableSize); 2115 LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { 2116 if ((assoc->g_vtag == l_vtag) && (assoc->g_port == g_port) && (assoc->l_port == l_port)) { 2117 if (assoc->num_Gaddr) { 2118 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { 2119 if(G_Addr->g_addr.s_addr == G_Addr->g_addr.s_addr) 2120 return(assoc); /* full match */ 2121 } 2122 } else { 2123 if (++cnt > 1) return(NULL); 2124 lastmatch = assoc; | 2091 if (l_vtag != 0) { /* an init packet, vtag==0 */ 2092 i = SN_TABLE_HASH(l_vtag, g_port, la->sctpNatTableSize); 2093 LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { 2094 if ((assoc->g_vtag == l_vtag) && (assoc->g_port == g_port) && (assoc->l_port == l_port)) { 2095 if (assoc->num_Gaddr) { 2096 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { 2097 if(G_Addr->g_addr.s_addr == G_Addr->g_addr.s_addr) 2098 return(assoc); /* full match */ 2099 } 2100 } else { 2101 if (++cnt > 1) return(NULL); 2102 lastmatch = assoc; 2103 } 2104 } 2105 } |
2125 } | 2106 } |
2126 } 2127 } 2128 } 2129 /* If there is more than one match we do not know which local address to send to */ 2130 return( cnt ? lastmatch : NULL ); | 2107 /* If there is more than one match we do not know which local address to send to */ 2108 return( cnt ? lastmatch : NULL ); |
2131} 2132 2133/** @ingroup Hash 2134 * @brief Find the SCTP association for a T-Flag message (given the local port and global vtag) 2135 * 2136 * Searches the global look-up table for a unique association entry matching the 2137 * provided local port and global vtag information 2138 * 2139 * @param la Pointer to the relevant libalias instance 2140 * @param g_addr global address 2141 * @param g_vtag global vtag 2142 * @param l_port local port 2143 * @param g_port global port 2144 * 2145 * @return pointer to association or NULL 2146 */ 2147static struct sctp_nat_assoc* 2148FindSctpGlobalT(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint16_t l_port, uint16_t g_port) 2149{ | 2109} 2110 2111/** @ingroup Hash 2112 * @brief Find the SCTP association for a T-Flag message (given the local port and global vtag) 2113 * 2114 * Searches the global look-up table for a unique association entry matching the 2115 * provided local port and global vtag information 2116 * 2117 * @param la Pointer to the relevant libalias instance 2118 * @param g_addr global address 2119 * @param g_vtag global vtag 2120 * @param l_port local port 2121 * @param g_port global port 2122 * 2123 * @return pointer to association or NULL 2124 */ 2125static struct sctp_nat_assoc* 2126FindSctpGlobalT(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint16_t l_port, uint16_t g_port) 2127{ |
2150 u_int i; 2151 struct sctp_nat_assoc *assoc = NULL; 2152 struct sctp_GlobalAddress *G_Addr = NULL; | 2128 u_int i; 2129 struct sctp_nat_assoc *assoc = NULL; 2130 struct sctp_GlobalAddress *G_Addr = NULL; |
2153 | 2131 |
2154 if (g_vtag != 0) { /* an init packet, vtag==0 */ 2155 i = SN_TABLE_HASH(g_vtag, l_port, la->sctpNatTableSize); 2156 LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) { 2157 if ((assoc->l_vtag == g_vtag) && (assoc->l_port == l_port) && (assoc->g_port == g_port)) { 2158 if (assoc->num_Gaddr) { 2159 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { 2160 if(G_Addr->g_addr.s_addr == g_addr.s_addr) 2161 return(assoc); 2162 } 2163 } else { 2164 return(assoc); | 2132 if (g_vtag != 0) { /* an init packet, vtag==0 */ 2133 i = SN_TABLE_HASH(g_vtag, l_port, la->sctpNatTableSize); 2134 LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) { 2135 if ((assoc->l_vtag == g_vtag) && (assoc->l_port == l_port) && (assoc->g_port == g_port)) { 2136 if (assoc->num_Gaddr) { 2137 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { 2138 if(G_Addr->g_addr.s_addr == g_addr.s_addr) 2139 return(assoc); 2140 } 2141 } else { 2142 return(assoc); 2143 } 2144 } 2145 } |
2165 } | 2146 } |
2166 } 2167 } 2168 } 2169 return(NULL); | 2147 return(NULL); |
2170} 2171 2172/** @ingroup Hash 2173 * @brief Add the sctp association information to the local look up table 2174 * 2175 * Searches the local look-up table for an existing association with the same 2176 * details. If a match exists and is ONLY in the local look-up table then this 2177 * is a repeated INIT packet, we need to remove this association from the --- 5 unchanged lines hidden (view full) --- 2183 * @param assoc pointer to sctp association 2184 * @param g_addr global address 2185 * 2186 * @return SN_ADD_OK | SN_ADD_CLASH 2187 */ 2188static int 2189AddSctpAssocLocal(struct libalias *la, struct sctp_nat_assoc *assoc, struct in_addr g_addr) 2190{ | 2148} 2149 2150/** @ingroup Hash 2151 * @brief Add the sctp association information to the local look up table 2152 * 2153 * Searches the local look-up table for an existing association with the same 2154 * details. If a match exists and is ONLY in the local look-up table then this 2155 * is a repeated INIT packet, we need to remove this association from the --- 5 unchanged lines hidden (view full) --- 2161 * @param assoc pointer to sctp association 2162 * @param g_addr global address 2163 * 2164 * @return SN_ADD_OK | SN_ADD_CLASH 2165 */ 2166static int 2167AddSctpAssocLocal(struct libalias *la, struct sctp_nat_assoc *assoc, struct in_addr g_addr) 2168{ |
2191 struct sctp_nat_assoc *found; | 2169 struct sctp_nat_assoc *found; |
2192 | 2170 |
2193 LIBALIAS_LOCK_ASSERT(la); 2194 found = FindSctpLocal(la, assoc->l_addr, g_addr, assoc->l_vtag, assoc->l_port, assoc->g_port); 2195 /* 2196 * Note that if a different global address initiated this Init, 2197 * ie it wasn't resent as presumed: 2198 * - the local receiver if receiving it for the first time will establish 2199 * an association with the new global host 2200 * - if receiving an init from a different global address after sending a 2201 * lost initack it will send an initack to the new global host, the first 2202 * association attempt will then be blocked if retried. 2203 */ 2204 if (found != NULL) { 2205 if ((found->TableRegister == SN_LOCAL_TBL) && (found->g_port == assoc->g_port)) { /* resent message */ 2206 RmSctpAssoc(la, found); 2207 sctp_RmTimeOut(la, found); 2208 freeGlobalAddressList(found); 2209 sn_free(found); 2210 } else 2211 return(SN_ADD_CLASH); 2212 } | 2171 LIBALIAS_LOCK_ASSERT(la); 2172 found = FindSctpLocal(la, assoc->l_addr, g_addr, assoc->l_vtag, assoc->l_port, assoc->g_port); 2173 /* 2174 * Note that if a different global address initiated this Init, 2175 * ie it wasn't resent as presumed: 2176 * - the local receiver if receiving it for the first time will establish 2177 * an association with the new global host 2178 * - if receiving an init from a different global address after sending a 2179 * lost initack it will send an initack to the new global host, the first 2180 * association attempt will then be blocked if retried. 2181 */ 2182 if (found != NULL) { 2183 if ((found->TableRegister == SN_LOCAL_TBL) && (found->g_port == assoc->g_port)) { /* resent message */ 2184 RmSctpAssoc(la, found); 2185 sctp_RmTimeOut(la, found); 2186 freeGlobalAddressList(found); 2187 sn_free(found); 2188 } else 2189 return(SN_ADD_CLASH); 2190 } |
2213 | 2191 |
2214 LIST_INSERT_HEAD(&la->sctpTableLocal[SN_TABLE_HASH(assoc->l_vtag, assoc->l_port, la->sctpNatTableSize)], 2215 assoc, list_L); 2216 assoc->TableRegister |= SN_LOCAL_TBL; 2217 la->sctpLinkCount++; //increment link count | 2192 LIST_INSERT_HEAD(&la->sctpTableLocal[SN_TABLE_HASH(assoc->l_vtag, assoc->l_port, la->sctpNatTableSize)], 2193 assoc, list_L); 2194 assoc->TableRegister |= SN_LOCAL_TBL; 2195 la->sctpLinkCount++; //increment link count |
2218 | 2196 |
2219 if (assoc->TableRegister == SN_BOTH_TBL) { 2220 /* libalias log -- controlled by libalias */ 2221 if (la->packetAliasMode & PKT_ALIAS_LOG) 2222 SctpShowAliasStats(la); | 2197 if (assoc->TableRegister == SN_BOTH_TBL) { 2198 /* libalias log -- controlled by libalias */ 2199 if (la->packetAliasMode & PKT_ALIAS_LOG) 2200 SctpShowAliasStats(la); |
2223 | 2201 |
2224 SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "^")); 2225 } | 2202 SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "^")); 2203 } |
2226 | 2204 |
2227 return(SN_ADD_OK); | 2205 return(SN_ADD_OK); |
2228} 2229 2230/** @ingroup Hash 2231 * @brief Add the sctp association information to the global look up table 2232 * 2233 * Searches the global look-up table for an existing association with the same 2234 * details. If a match exists and is ONLY in the global look-up table then this 2235 * is a repeated INIT packet, we need to remove this association from the --- 4 unchanged lines hidden (view full) --- 2240 * @param la Pointer to the relevant libalias instance 2241 * @param assoc pointer to sctp association 2242 * 2243 * @return SN_ADD_OK | SN_ADD_CLASH 2244 */ 2245static int 2246AddSctpAssocGlobal(struct libalias *la, struct sctp_nat_assoc *assoc) 2247{ | 2206} 2207 2208/** @ingroup Hash 2209 * @brief Add the sctp association information to the global look up table 2210 * 2211 * Searches the global look-up table for an existing association with the same 2212 * details. If a match exists and is ONLY in the global look-up table then this 2213 * is a repeated INIT packet, we need to remove this association from the --- 4 unchanged lines hidden (view full) --- 2218 * @param la Pointer to the relevant libalias instance 2219 * @param assoc pointer to sctp association 2220 * 2221 * @return SN_ADD_OK | SN_ADD_CLASH 2222 */ 2223static int 2224AddSctpAssocGlobal(struct libalias *la, struct sctp_nat_assoc *assoc) 2225{ |
2248 struct sctp_nat_assoc *found; | 2226 struct sctp_nat_assoc *found; |
2249 | 2227 |
2250 LIBALIAS_LOCK_ASSERT(la); 2251 found = FindSctpGlobalClash(la, assoc); 2252 if (found != NULL) { 2253 if ((found->TableRegister == SN_GLOBAL_TBL) && \ 2254 (found->l_addr.s_addr == assoc->l_addr.s_addr) && (found->l_port == assoc->l_port)) { /* resent message */ 2255 RmSctpAssoc(la, found); 2256 sctp_RmTimeOut(la, found); 2257 freeGlobalAddressList(found); 2258 sn_free(found); 2259 } else 2260 return(SN_ADD_CLASH); 2261 } | 2228 LIBALIAS_LOCK_ASSERT(la); 2229 found = FindSctpGlobalClash(la, assoc); 2230 if (found != NULL) { 2231 if ((found->TableRegister == SN_GLOBAL_TBL) && \ 2232 (found->l_addr.s_addr == assoc->l_addr.s_addr) && (found->l_port == assoc->l_port)) { /* resent message */ 2233 RmSctpAssoc(la, found); 2234 sctp_RmTimeOut(la, found); 2235 freeGlobalAddressList(found); 2236 sn_free(found); 2237 } else 2238 return(SN_ADD_CLASH); 2239 } |
2262 | 2240 |
2263 LIST_INSERT_HEAD(&la->sctpTableGlobal[SN_TABLE_HASH(assoc->g_vtag, assoc->g_port, la->sctpNatTableSize)], 2264 assoc, list_G); 2265 assoc->TableRegister |= SN_GLOBAL_TBL; 2266 la->sctpLinkCount++; //increment link count | 2241 LIST_INSERT_HEAD(&la->sctpTableGlobal[SN_TABLE_HASH(assoc->g_vtag, assoc->g_port, la->sctpNatTableSize)], 2242 assoc, list_G); 2243 assoc->TableRegister |= SN_GLOBAL_TBL; 2244 la->sctpLinkCount++; //increment link count |
2267 | 2245 |
2268 if (assoc->TableRegister == SN_BOTH_TBL) { 2269 /* libalias log -- controlled by libalias */ 2270 if (la->packetAliasMode & PKT_ALIAS_LOG) 2271 SctpShowAliasStats(la); | 2246 if (assoc->TableRegister == SN_BOTH_TBL) { 2247 /* libalias log -- controlled by libalias */ 2248 if (la->packetAliasMode & PKT_ALIAS_LOG) 2249 SctpShowAliasStats(la); |
2272 | 2250 |
2273 SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "^")); 2274 } | 2251 SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "^")); 2252 } |
2275 | 2253 |
2276 return(SN_ADD_OK); | 2254 return(SN_ADD_OK); |
2277} 2278 2279/** @ingroup Hash 2280 * @brief Remove the sctp association information from the look up table 2281 * 2282 * For each of the two (local/global) look-up tables, remove the association 2283 * from that table IF it has been registered in that table. 2284 * 2285 * NOTE: The calling code is responsible for freeing memory allocated to the 2286 * association structure itself 2287 * 2288 * NOTE: The association is NOT removed from the timer queue 2289 * 2290 * @param la Pointer to the relevant libalias instance 2291 * @param assoc pointer to sctp association 2292 */ 2293static void 2294RmSctpAssoc(struct libalias *la, struct sctp_nat_assoc *assoc) 2295{ | 2255} 2256 2257/** @ingroup Hash 2258 * @brief Remove the sctp association information from the look up table 2259 * 2260 * For each of the two (local/global) look-up tables, remove the association 2261 * from that table IF it has been registered in that table. 2262 * 2263 * NOTE: The calling code is responsible for freeing memory allocated to the 2264 * association structure itself 2265 * 2266 * NOTE: The association is NOT removed from the timer queue 2267 * 2268 * @param la Pointer to the relevant libalias instance 2269 * @param assoc pointer to sctp association 2270 */ 2271static void 2272RmSctpAssoc(struct libalias *la, struct sctp_nat_assoc *assoc) 2273{ |
2296 // struct sctp_nat_assoc *found; 2297 if (assoc == NULL) { 2298 /* very bad, log and die*/ 2299 SN_LOG(SN_LOG_LOW, 2300 logsctperror("ERROR: alias_sctp:RmSctpAssoc(NULL)\n", 0, 0, SN_TO_NODIR)); 2301 return; 2302 } 2303 /* log if association is fully up and now closing */ 2304 if (assoc->TableRegister == SN_BOTH_TBL) { 2305 SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "$")); 2306 } 2307 LIBALIAS_LOCK_ASSERT(la); 2308 if (assoc->TableRegister & SN_LOCAL_TBL) { 2309 assoc->TableRegister ^= SN_LOCAL_TBL; 2310 la->sctpLinkCount--; //decrement link count 2311 LIST_REMOVE(assoc, list_L); 2312 } | 2274 // struct sctp_nat_assoc *found; 2275 if (assoc == NULL) { 2276 /* very bad, log and die*/ 2277 SN_LOG(SN_LOG_LOW, 2278 logsctperror("ERROR: alias_sctp:RmSctpAssoc(NULL)\n", 0, 0, SN_TO_NODIR)); 2279 return; 2280 } 2281 /* log if association is fully up and now closing */ 2282 if (assoc->TableRegister == SN_BOTH_TBL) { 2283 SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "$")); 2284 } 2285 LIBALIAS_LOCK_ASSERT(la); 2286 if (assoc->TableRegister & SN_LOCAL_TBL) { 2287 assoc->TableRegister ^= SN_LOCAL_TBL; 2288 la->sctpLinkCount--; //decrement link count 2289 LIST_REMOVE(assoc, list_L); 2290 } |
2313 | 2291 |
2314 if (assoc->TableRegister & SN_GLOBAL_TBL) { 2315 assoc->TableRegister ^= SN_GLOBAL_TBL; 2316 la->sctpLinkCount--; //decrement link count 2317 LIST_REMOVE(assoc, list_G); 2318 } 2319 // sn_free(assoc); //Don't remove now, remove if needed later 2320 /* libalias logging -- controlled by libalias log definition */ 2321 if (la->packetAliasMode & PKT_ALIAS_LOG) 2322 SctpShowAliasStats(la); | 2292 if (assoc->TableRegister & SN_GLOBAL_TBL) { 2293 assoc->TableRegister ^= SN_GLOBAL_TBL; 2294 la->sctpLinkCount--; //decrement link count 2295 LIST_REMOVE(assoc, list_G); 2296 } 2297 // sn_free(assoc); //Don't remove now, remove if needed later 2298 /* libalias logging -- controlled by libalias log definition */ 2299 if (la->packetAliasMode & PKT_ALIAS_LOG) 2300 SctpShowAliasStats(la); |
2323} 2324 2325/** 2326 * @ingroup Hash 2327 * @brief free the Global Address List memory 2328 * 2329 * freeGlobalAddressList deletes all global IP addresses in an associations 2330 * global IP address list. 2331 * 2332 * @param assoc 2333 */ 2334static void freeGlobalAddressList(struct sctp_nat_assoc *assoc) 2335{ | 2301} 2302 2303/** 2304 * @ingroup Hash 2305 * @brief free the Global Address List memory 2306 * 2307 * freeGlobalAddressList deletes all global IP addresses in an associations 2308 * global IP address list. 2309 * 2310 * @param assoc 2311 */ 2312static void freeGlobalAddressList(struct sctp_nat_assoc *assoc) 2313{ |
2336 struct sctp_GlobalAddress *gaddr1=NULL,*gaddr2=NULL; 2337 /*free global address list*/ 2338 gaddr1 = LIST_FIRST(&(assoc->Gaddr)); 2339 while (gaddr1 != NULL) { 2340 gaddr2 = LIST_NEXT(gaddr1, list_Gaddr); 2341 sn_free(gaddr1); 2342 gaddr1 = gaddr2; 2343 } | 2314 struct sctp_GlobalAddress *gaddr1=NULL,*gaddr2=NULL; 2315 /*free global address list*/ 2316 gaddr1 = LIST_FIRST(&(assoc->Gaddr)); 2317 while (gaddr1 != NULL) { 2318 gaddr2 = LIST_NEXT(gaddr1, list_Gaddr); 2319 sn_free(gaddr1); 2320 gaddr1 = gaddr2; 2321 } |
2344} 2345/* ---------------------------------------------------------------------- 2346 * TIMER QUEUE CODE 2347 * ---------------------------------------------------------------------- 2348 */ 2349/** @addtogroup Timer 2350 * 2351 * The timer queue management functions are designed to operate efficiently with --- 15 unchanged lines hidden (view full) --- 2367 * association into the list at that queue position 2368 * 2369 * @param la 2370 * @param assoc 2371 */ 2372static void 2373sctp_AddTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc) 2374{ | 2322} 2323/* ---------------------------------------------------------------------- 2324 * TIMER QUEUE CODE 2325 * ---------------------------------------------------------------------- 2326 */ 2327/** @addtogroup Timer 2328 * 2329 * The timer queue management functions are designed to operate efficiently with --- 15 unchanged lines hidden (view full) --- 2345 * association into the list at that queue position 2346 * 2347 * @param la 2348 * @param assoc 2349 */ 2350static void 2351sctp_AddTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc) 2352{ |
2375 int add_loc; 2376 LIBALIAS_LOCK_ASSERT(la); 2377 add_loc = assoc->exp - la->sctpNatTimer.loc_time + la->sctpNatTimer.cur_loc; 2378 if (add_loc >= SN_TIMER_QUEUE_SIZE) 2379 add_loc -= SN_TIMER_QUEUE_SIZE; 2380 LIST_INSERT_HEAD(&la->sctpNatTimer.TimerQ[add_loc], assoc, timer_Q); 2381 assoc->exp_loc = add_loc; | 2353 int add_loc; 2354 LIBALIAS_LOCK_ASSERT(la); 2355 add_loc = assoc->exp - la->sctpNatTimer.loc_time + la->sctpNatTimer.cur_loc; 2356 if (add_loc >= SN_TIMER_QUEUE_SIZE) 2357 add_loc -= SN_TIMER_QUEUE_SIZE; 2358 LIST_INSERT_HEAD(&la->sctpNatTimer.TimerQ[add_loc], assoc, timer_Q); 2359 assoc->exp_loc = add_loc; |
2382} 2383 2384/** @ingroup Timer 2385 * @brief Remove an association from timer queue 2386 * 2387 * This is an O(1) operation to remove the association pointer from its 2388 * current position in the timer queue 2389 * 2390 * @param la Pointer to the relevant libalias instance 2391 * @param assoc pointer to sctp association 2392 */ 2393static void 2394sctp_RmTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc) 2395{ | 2360} 2361 2362/** @ingroup Timer 2363 * @brief Remove an association from timer queue 2364 * 2365 * This is an O(1) operation to remove the association pointer from its 2366 * current position in the timer queue 2367 * 2368 * @param la Pointer to the relevant libalias instance 2369 * @param assoc pointer to sctp association 2370 */ 2371static void 2372sctp_RmTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc) 2373{ |
2396 LIBALIAS_LOCK_ASSERT(la); 2397 LIST_REMOVE(assoc, timer_Q);/* Note this is O(1) */ | 2374 LIBALIAS_LOCK_ASSERT(la); 2375 LIST_REMOVE(assoc, timer_Q);/* Note this is O(1) */ |
2398} 2399 2400 2401/** @ingroup Timer 2402 * @brief Reset timer in timer queue 2403 * 2404 * Reset the actual timeout for the specified association. If it is earlier than 2405 * the existing timeout, then remove and re-install the association into the 2406 * queue 2407 * 2408 * @param la Pointer to the relevant libalias instance 2409 * @param assoc pointer to sctp association 2410 * @param newexp New expiration time 2411 */ 2412static void 2413sctp_ResetTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc, int newexp) 2414{ | 2376} 2377 2378 2379/** @ingroup Timer 2380 * @brief Reset timer in timer queue 2381 * 2382 * Reset the actual timeout for the specified association. If it is earlier than 2383 * the existing timeout, then remove and re-install the association into the 2384 * queue 2385 * 2386 * @param la Pointer to the relevant libalias instance 2387 * @param assoc pointer to sctp association 2388 * @param newexp New expiration time 2389 */ 2390static void 2391sctp_ResetTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc, int newexp) 2392{ |
2415 if (newexp < assoc->exp) { 2416 sctp_RmTimeOut(la, assoc); 2417 assoc->exp = newexp; 2418 sctp_AddTimeOut(la, assoc); 2419 } else { 2420 assoc->exp = newexp; 2421 } | 2393 if (newexp < assoc->exp) { 2394 sctp_RmTimeOut(la, assoc); 2395 assoc->exp = newexp; 2396 sctp_AddTimeOut(la, assoc); 2397 } else { 2398 assoc->exp = newexp; 2399 } |
2422} 2423 2424/** @ingroup Timer 2425 * @brief Check timer Q against current time 2426 * 2427 * Loop through each entry in the timer queue since the last time we processed 2428 * the timer queue until now (the current time). For each association in the 2429 * event list, we remove it from that position in the timer queue and check if --- 5 unchanged lines hidden (view full) --- 2435 * If the timer hasn't really expired we place the association into its new 2436 * correct position in the timer queue. 2437 * 2438 * @param la Pointer to the relevant libalias instance 2439 */ 2440void 2441sctp_CheckTimers(struct libalias *la) 2442{ | 2400} 2401 2402/** @ingroup Timer 2403 * @brief Check timer Q against current time 2404 * 2405 * Loop through each entry in the timer queue since the last time we processed 2406 * the timer queue until now (the current time). For each association in the 2407 * event list, we remove it from that position in the timer queue and check if --- 5 unchanged lines hidden (view full) --- 2413 * If the timer hasn't really expired we place the association into its new 2414 * correct position in the timer queue. 2415 * 2416 * @param la Pointer to the relevant libalias instance 2417 */ 2418void 2419sctp_CheckTimers(struct libalias *la) 2420{ |
2443 struct sctp_nat_assoc *assoc; | 2421 struct sctp_nat_assoc *assoc; |
2444 | 2422 |
2445 LIBALIAS_LOCK_ASSERT(la); 2446 while(la->timeStamp >= la->sctpNatTimer.loc_time) { 2447 while (!LIST_EMPTY(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc])) { 2448 assoc = LIST_FIRST(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc]); 2449 //SLIST_REMOVE_HEAD(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc], timer_Q); 2450 LIST_REMOVE(assoc, timer_Q); 2451 if (la->timeStamp >= assoc->exp) { /* state expired */ 2452 SN_LOG(((assoc->state == SN_CL)?(SN_LOG_DEBUG):(SN_LOG_INFO)), 2453 logsctperror("Timer Expired", assoc->g_vtag, assoc->state, SN_TO_NODIR)); 2454 RmSctpAssoc(la, assoc); 2455 freeGlobalAddressList(assoc); 2456 sn_free(assoc); 2457 } else {/* state not expired, reschedule timer*/ 2458 sctp_AddTimeOut(la, assoc); 2459 } 2460 } 2461 /* Goto next location in the timer queue*/ 2462 ++la->sctpNatTimer.loc_time; 2463 if (++la->sctpNatTimer.cur_loc >= SN_TIMER_QUEUE_SIZE) 2464 la->sctpNatTimer.cur_loc = 0; 2465 } | 2423 LIBALIAS_LOCK_ASSERT(la); 2424 while(la->timeStamp >= la->sctpNatTimer.loc_time) { 2425 while (!LIST_EMPTY(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc])) { 2426 assoc = LIST_FIRST(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc]); 2427 //SLIST_REMOVE_HEAD(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc], timer_Q); 2428 LIST_REMOVE(assoc, timer_Q); 2429 if (la->timeStamp >= assoc->exp) { /* state expired */ 2430 SN_LOG(((assoc->state == SN_CL)?(SN_LOG_DEBUG):(SN_LOG_INFO)), 2431 logsctperror("Timer Expired", assoc->g_vtag, assoc->state, SN_TO_NODIR)); 2432 RmSctpAssoc(la, assoc); 2433 freeGlobalAddressList(assoc); 2434 sn_free(assoc); 2435 } else {/* state not expired, reschedule timer*/ 2436 sctp_AddTimeOut(la, assoc); 2437 } 2438 } 2439 /* Goto next location in the timer queue*/ 2440 ++la->sctpNatTimer.loc_time; 2441 if (++la->sctpNatTimer.cur_loc >= SN_TIMER_QUEUE_SIZE) 2442 la->sctpNatTimer.cur_loc = 0; 2443 } |
2466} 2467 2468/* ---------------------------------------------------------------------- 2469 * LOGGING CODE 2470 * ---------------------------------------------------------------------- 2471 */ 2472/** @addtogroup Logging 2473 * --- 7 unchanged lines hidden (view full) --- 2481 * @param errormsg Error message to be logged 2482 * @param vtag Current Vtag 2483 * @param error Error number 2484 * @param direction Direction of packet 2485 */ 2486static void 2487logsctperror(char* errormsg, uint32_t vtag, int error, int direction) 2488{ | 2444} 2445 2446/* ---------------------------------------------------------------------- 2447 * LOGGING CODE 2448 * ---------------------------------------------------------------------- 2449 */ 2450/** @addtogroup Logging 2451 * --- 7 unchanged lines hidden (view full) --- 2459 * @param errormsg Error message to be logged 2460 * @param vtag Current Vtag 2461 * @param error Error number 2462 * @param direction Direction of packet 2463 */ 2464static void 2465logsctperror(char* errormsg, uint32_t vtag, int error, int direction) 2466{ |
2489 char dir; 2490 switch(direction) { 2491 case SN_TO_LOCAL: 2492 dir = 'L'; 2493 break; 2494 case SN_TO_GLOBAL: 2495 dir = 'G'; 2496 break; 2497 default: 2498 dir = '*'; 2499 break; 2500 } 2501 SctpAliasLog("->%c %s (vt=%u) %d\n", dir, errormsg, ntohl(vtag), error); | 2467 char dir; 2468 switch(direction) { 2469 case SN_TO_LOCAL: 2470 dir = 'L'; 2471 break; 2472 case SN_TO_GLOBAL: 2473 dir = 'G'; 2474 break; 2475 default: 2476 dir = '*'; 2477 break; 2478 } 2479 SctpAliasLog("->%c %s (vt=%u) %d\n", dir, errormsg, ntohl(vtag), error); |
2502} 2503 2504/** @ingroup Logging 2505 * @brief Log what the parser parsed 2506 * 2507 * @param direction Direction of packet 2508 * @param sm Pointer to sctp message information 2509 */ 2510static void 2511logsctpparse(int direction, struct sctp_nat_msg *sm) 2512{ | 2480} 2481 2482/** @ingroup Logging 2483 * @brief Log what the parser parsed 2484 * 2485 * @param direction Direction of packet 2486 * @param sm Pointer to sctp message information 2487 */ 2488static void 2489logsctpparse(int direction, struct sctp_nat_msg *sm) 2490{ |
2513 char *ploc, *pstate; 2514 switch(direction) { 2515 case SN_TO_LOCAL: 2516 ploc = "TO_LOCAL -"; 2517 break; 2518 case SN_TO_GLOBAL: 2519 ploc = "TO_GLOBAL -"; 2520 break; 2521 default: 2522 ploc = ""; 2523 } 2524 switch(sm->msg) { 2525 case SN_SCTP_INIT: 2526 pstate = "Init"; 2527 break; 2528 case SN_SCTP_INITACK: 2529 pstate = "InitAck"; 2530 break; 2531 case SN_SCTP_ABORT: 2532 pstate = "Abort"; 2533 break; 2534 case SN_SCTP_SHUTACK: 2535 pstate = "ShutAck"; 2536 break; 2537 case SN_SCTP_SHUTCOMP: 2538 pstate = "ShutComp"; 2539 break; 2540 case SN_SCTP_ASCONF: 2541 pstate = "Asconf"; 2542 break; 2543 case SN_SCTP_ASCONFACK: 2544 pstate = "AsconfAck"; 2545 break; 2546 case SN_SCTP_OTHER: 2547 pstate = "Other"; 2548 break; 2549 default: 2550 pstate = "***ERROR***"; 2551 break; 2552 } 2553 SctpAliasLog("Parsed: %s %s\n", ploc, pstate); | 2491 char *ploc, *pstate; 2492 switch(direction) { 2493 case SN_TO_LOCAL: 2494 ploc = "TO_LOCAL -"; 2495 break; 2496 case SN_TO_GLOBAL: 2497 ploc = "TO_GLOBAL -"; 2498 break; 2499 default: 2500 ploc = ""; 2501 } 2502 switch(sm->msg) { 2503 case SN_SCTP_INIT: 2504 pstate = "Init"; 2505 break; 2506 case SN_SCTP_INITACK: 2507 pstate = "InitAck"; 2508 break; 2509 case SN_SCTP_ABORT: 2510 pstate = "Abort"; 2511 break; 2512 case SN_SCTP_SHUTACK: 2513 pstate = "ShutAck"; 2514 break; 2515 case SN_SCTP_SHUTCOMP: 2516 pstate = "ShutComp"; 2517 break; 2518 case SN_SCTP_ASCONF: 2519 pstate = "Asconf"; 2520 break; 2521 case SN_SCTP_ASCONFACK: 2522 pstate = "AsconfAck"; 2523 break; 2524 case SN_SCTP_OTHER: 2525 pstate = "Other"; 2526 break; 2527 default: 2528 pstate = "***ERROR***"; 2529 break; 2530 } 2531 SctpAliasLog("Parsed: %s %s\n", ploc, pstate); |
2554} 2555 2556/** @ingroup Logging 2557 * @brief Log an SCTP association's details 2558 * 2559 * @param assoc pointer to sctp association 2560 * @param s Character that indicates the state of processing for this packet 2561 */ 2562static void logsctpassoc(struct sctp_nat_assoc *assoc, char* s) 2563{ | 2532} 2533 2534/** @ingroup Logging 2535 * @brief Log an SCTP association's details 2536 * 2537 * @param assoc pointer to sctp association 2538 * @param s Character that indicates the state of processing for this packet 2539 */ 2540static void logsctpassoc(struct sctp_nat_assoc *assoc, char* s) 2541{ |
2564 struct sctp_GlobalAddress *G_Addr = NULL; 2565 char *sp; 2566 switch(assoc->state) { 2567 case SN_ID: 2568 sp = "ID "; 2569 break; 2570 case SN_INi: 2571 sp = "INi "; 2572 break; 2573 case SN_INa: 2574 sp = "INa "; 2575 break; 2576 case SN_UP: 2577 sp = "UP "; 2578 break; 2579 case SN_CL: 2580 sp = "CL "; 2581 break; 2582 case SN_RM: 2583 sp = "RM "; 2584 break; 2585 default: 2586 sp = "***ERROR***"; 2587 break; 2588 } 2589 SctpAliasLog("%sAssoc: %s exp=%u la=%s lv=%u lp=%u gv=%u gp=%u tbl=%d\n", 2590 s, sp, assoc->exp, inet_ntoa(assoc->l_addr), ntohl(assoc->l_vtag), 2591 ntohs(assoc->l_port), ntohl(assoc->g_vtag), ntohs(assoc->g_port), 2592 assoc->TableRegister); 2593 /* list global addresses */ 2594 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { 2595 SctpAliasLog("\t\tga=%s\n",inet_ntoa(G_Addr->g_addr)); 2596 } | 2542 struct sctp_GlobalAddress *G_Addr = NULL; 2543 char *sp; 2544 switch(assoc->state) { 2545 case SN_ID: 2546 sp = "ID "; 2547 break; 2548 case SN_INi: 2549 sp = "INi "; 2550 break; 2551 case SN_INa: 2552 sp = "INa "; 2553 break; 2554 case SN_UP: 2555 sp = "UP "; 2556 break; 2557 case SN_CL: 2558 sp = "CL "; 2559 break; 2560 case SN_RM: 2561 sp = "RM "; 2562 break; 2563 default: 2564 sp = "***ERROR***"; 2565 break; 2566 } 2567 SctpAliasLog("%sAssoc: %s exp=%u la=%s lv=%u lp=%u gv=%u gp=%u tbl=%d\n", 2568 s, sp, assoc->exp, inet_ntoa(assoc->l_addr), ntohl(assoc->l_vtag), 2569 ntohs(assoc->l_port), ntohl(assoc->g_vtag), ntohs(assoc->g_port), 2570 assoc->TableRegister); 2571 /* list global addresses */ 2572 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { 2573 SctpAliasLog("\t\tga=%s\n",inet_ntoa(G_Addr->g_addr)); 2574 } |
2597} 2598 2599/** @ingroup Logging 2600 * @brief Output Global table to log 2601 * 2602 * @param la Pointer to the relevant libalias instance 2603 */ 2604static void logSctpGlobal(struct libalias *la) 2605{ | 2575} 2576 2577/** @ingroup Logging 2578 * @brief Output Global table to log 2579 * 2580 * @param la Pointer to the relevant libalias instance 2581 */ 2582static void logSctpGlobal(struct libalias *la) 2583{ |
2606 u_int i; 2607 struct sctp_nat_assoc *assoc = NULL; | 2584 u_int i; 2585 struct sctp_nat_assoc *assoc = NULL; |
2608 | 2586 |
2609 SctpAliasLog("G->\n"); 2610 for (i=0; i < la->sctpNatTableSize; i++) { 2611 LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { 2612 logsctpassoc(assoc, " "); 2613 } 2614 } | 2587 SctpAliasLog("G->\n"); 2588 for (i=0; i < la->sctpNatTableSize; i++) { 2589 LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { 2590 logsctpassoc(assoc, " "); 2591 } 2592 } |
2615} 2616 2617/** @ingroup Logging 2618 * @brief Output Local table to log 2619 * 2620 * @param la Pointer to the relevant libalias instance 2621 */ 2622static void logSctpLocal(struct libalias *la) 2623{ | 2593} 2594 2595/** @ingroup Logging 2596 * @brief Output Local table to log 2597 * 2598 * @param la Pointer to the relevant libalias instance 2599 */ 2600static void logSctpLocal(struct libalias *la) 2601{ |
2624 u_int i; 2625 struct sctp_nat_assoc *assoc = NULL; | 2602 u_int i; 2603 struct sctp_nat_assoc *assoc = NULL; |
2626 | 2604 |
2627 SctpAliasLog("L->\n"); 2628 for (i=0; i < la->sctpNatTableSize; i++) { 2629 LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) { 2630 logsctpassoc(assoc, " "); 2631 } 2632 } | 2605 SctpAliasLog("L->\n"); 2606 for (i=0; i < la->sctpNatTableSize; i++) { 2607 LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) { 2608 logsctpassoc(assoc, " "); 2609 } 2610 } |
2633} 2634 2635/** @ingroup Logging 2636 * @brief Output timer queue to log 2637 * 2638 * @param la Pointer to the relevant libalias instance 2639 */ 2640static void logTimerQ(struct libalias *la) 2641{ | 2611} 2612 2613/** @ingroup Logging 2614 * @brief Output timer queue to log 2615 * 2616 * @param la Pointer to the relevant libalias instance 2617 */ 2618static void logTimerQ(struct libalias *la) 2619{ |
2642 static char buf[50]; 2643 u_int i; 2644 struct sctp_nat_assoc *assoc = NULL; | 2620 static char buf[50]; 2621 u_int i; 2622 struct sctp_nat_assoc *assoc = NULL; |
2645 | 2623 |
2646 SctpAliasLog("t->\n"); 2647 for (i=0; i < SN_TIMER_QUEUE_SIZE; i++) { 2648 LIST_FOREACH(assoc, &la->sctpNatTimer.TimerQ[i], timer_Q) { 2649 snprintf(buf, 50, " l=%u ",i); 2650 //SctpAliasLog(la->logDesc," l=%d ",i); 2651 logsctpassoc(assoc, buf); 2652 } 2653 } | 2624 SctpAliasLog("t->\n"); 2625 for (i=0; i < SN_TIMER_QUEUE_SIZE; i++) { 2626 LIST_FOREACH(assoc, &la->sctpNatTimer.TimerQ[i], timer_Q) { 2627 snprintf(buf, 50, " l=%u ",i); 2628 //SctpAliasLog(la->logDesc," l=%d ",i); 2629 logsctpassoc(assoc, buf); 2630 } 2631 } |
2654} 2655 2656/** @ingroup Logging 2657 * @brief Sctp NAT logging function 2658 * 2659 * This function is based on a similar function in alias_db.c 2660 * 2661 * @param str/stream logging descriptor 2662 * @param format printf type string 2663 */ 2664#ifdef _KERNEL 2665static void 2666SctpAliasLog(const char *format, ...) 2667{ | 2632} 2633 2634/** @ingroup Logging 2635 * @brief Sctp NAT logging function 2636 * 2637 * This function is based on a similar function in alias_db.c 2638 * 2639 * @param str/stream logging descriptor 2640 * @param format printf type string 2641 */ 2642#ifdef _KERNEL 2643static void 2644SctpAliasLog(const char *format, ...) 2645{ |
2668 char buffer[LIBALIAS_BUF_SIZE]; 2669 va_list ap; 2670 va_start(ap, format); 2671 vsnprintf(buffer, LIBALIAS_BUF_SIZE, format, ap); 2672 va_end(ap); 2673 log(LOG_SECURITY | LOG_INFO, 2674 "alias_sctp: %s", buffer); | 2646 char buffer[LIBALIAS_BUF_SIZE]; 2647 va_list ap; 2648 va_start(ap, format); 2649 vsnprintf(buffer, LIBALIAS_BUF_SIZE, format, ap); 2650 va_end(ap); 2651 log(LOG_SECURITY | LOG_INFO, 2652 "alias_sctp: %s", buffer); |
2675} 2676#else 2677static void 2678SctpAliasLog(FILE *stream, const char *format, ...) 2679{ | 2653} 2654#else 2655static void 2656SctpAliasLog(FILE *stream, const char *format, ...) 2657{ |
2680 va_list ap; | 2658 va_list ap; |
2681 | 2659 |
2682 va_start(ap, format); 2683 vfprintf(stream, format, ap); 2684 va_end(ap); 2685 fflush(stream); | 2660 va_start(ap, format); 2661 vfprintf(stream, format, ap); 2662 va_end(ap); 2663 fflush(stream); |
2686} 2687#endif | 2664} 2665#endif |