FreeBSD kernel IPv4 code
alias_sctp.c File Reference
#include <machine/stdarg.h>
#include <sys/param.h>
#include <sys/gsb_crc32.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/syslog.h>
#include <netinet/libalias/alias_sctp.h>
#include <netinet/libalias/alias.h>
#include <netinet/libalias/alias_local.h>
#include <netinet/sctp_crc32.h>
#include <machine/in_cksum.h>
Include dependency graph for alias_sctp.c:

Go to the source code of this file.

Macros

#define SN_SCTP_FIRSTCHUNK(sctphead)   (struct sctp_chunkhdr *)(((char *)sctphead) + sizeof(struct sctphdr))
 
#define SN_SCTP_NEXTCHUNK(chunkhead)   (struct sctp_chunkhdr *)(((char *)chunkhead) + SCTP_SIZE32(ntohs(chunkhead->chunk_length)))
 
#define SN_SCTP_NEXTPARAM(param)   (struct sctp_paramhdr *)(((char *)param) + SCTP_SIZE32(ntohs(param->param_length)))
 
#define SN_MIN_CHUNK_SIZE   4
 
#define SN_MIN_PARAM_SIZE   4
 
#define SN_VTAG_PARAM_SIZE   12
 
#define SN_ASCONFACK_PARAM_SIZE   8
 
#define SN_PARSE_OK   0
 
#define SN_PARSE_ERROR_IPSHL   1
 
#define SN_PARSE_ERROR_AS_MALLOC   2
 
#define SN_PARSE_ERROR_CHHL   3
 
#define SN_PARSE_ERROR_DIR   4
 
#define SN_PARSE_ERROR_VTAG   5
 
#define SN_PARSE_ERROR_CHUNK   6
 
#define SN_PARSE_ERROR_PORT   7
 
#define SN_PARSE_ERROR_LOOKUP   8
 
#define SN_PARSE_ERROR_PARTIALLOOKUP   9
 
#define SN_PARSE_ERROR_LOOKUP_ABORT   10
 
#define SN_SCTP_ABORT   0x0000
 
#define SN_SCTP_INIT   0x0001
 
#define SN_SCTP_INITACK   0x0002
 
#define SN_SCTP_SHUTCOMP   0x0010
 
#define SN_SCTP_SHUTACK   0x0020
 
#define SN_SCTP_ASCONF   0x0100
 
#define SN_SCTP_ASCONFACK   0x0200
 
#define SN_SCTP_OTHER   0xFFFF
 
#define SN_ID   0x0000
 
#define SN_INi   0x0010
 
#define SN_INa   0x0020
 
#define SN_UP   0x0100
 
#define SN_CL   0x1000
 
#define SN_RM   0x2000
 
#define SN_LOG_LOW   0
 
#define SN_LOG_EVENT   1
 
#define SN_LOG_INFO   2
 
#define SN_LOG_DETAIL   3
 
#define SN_LOG_DEBUG   4
 
#define SN_LOG_DEBUG_MAX   5
 
#define SN_LOG(level, action)   if (sysctl_log_level >= level) { action; }
 
#define SN_MIN_HASH_SIZE   101
 
#define SN_MAX_HASH_SIZE   1000001
 
#define SN_DEFAULT_HASH_SIZE   2003
 
#define SN_LOCAL_TBL   0x01
 
#define SN_GLOBAL_TBL   0x02
 
#define SN_BOTH_TBL   0x03
 
#define SN_WAIT_TOLOCAL   0x10
 
#define SN_WAIT_TOGLOBAL   0x20
 
#define SN_NULL_TBL   0x00
 
#define SN_MAX_GLOBAL_ADDRESSES   100
 
#define SN_ADD_OK   0
 
#define SN_ADD_CLASH   1
 
#define SN_TABLE_HASH(vtag, port, size)   (((u_int) vtag + (u_int) port) % (u_int) size)
 
#define SN_MIN_TIMER   1
 
#define SN_MAX_TIMER   600
 
#define SN_TIMER_QUEUE_SIZE   SN_MAX_TIMER+2
 
#define SN_I_T(la)   (LibAliasTime + sysctl_init_timer)
 
#define SN_U_T(la)   (LibAliasTime + sysctl_up_timer)
 
#define SN_C_T(la)   (LibAliasTime + sysctl_shutdown_timer)
 
#define SN_X_T(la)   (LibAliasTime + sysctl_holddown_timer)
 
#define SN_NO_ERROR_ON_OOTB   0
 
#define SN_LOCAL_ERROR_ON_OOTB   1
 
#define SN_LOCALandPARTIAL_ERROR_ON_OOTB   2
 
#define SN_ERROR_ON_OOTB   3
 
#define SCTP_MIDDLEBOX_FLAG   0x02
 
#define SCTP_NAT_TABLE_COLLISION   0x00b0
 
#define SCTP_MISSING_NAT   0x00b1
 
#define SCTP_VTAG_PARAM   0xC007
 

Functions

static int sctp_PktParser (struct libalias *la, int direction, struct ip *pip, struct sctp_nat_msg *sm, struct sctp_nat_assoc **passoc)
 Parses SCTP packets for the key SCTP chunk that will be processed. More...
 
static int GetAsconfVtags (struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, uint32_t *g_vtag, int direction)
 Extract Vtags from Asconf Chunk. More...
 
static int IsASCONFack (struct libalias *la, struct sctp_nat_msg *sm, int direction)
 Check that ASCONF was successful. More...
 
static void AddGlobalIPAddresses (struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction)
 AddGlobalIPAddresses from Init,InitAck,or AddIP packets. More...
 
static int Add_Global_Address_to_List (struct sctp_nat_assoc *assoc, struct sctp_GlobalAddress *G_addr)
 Add_Global_Address_to_List. More...
 
static void RmGlobalIPAddresses (struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction)
 RmGlobalIPAddresses from DelIP packets. More...
 
static int IsADDorDEL (struct libalias *la, struct sctp_nat_msg *sm, int direction)
 Check to see if ASCONF contains an Add IP or Del IP parameter. More...
 
static int ProcessSctpMsg (struct libalias *la, int direction, struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc)
 Process SCTP message. More...
 
static int ID_process (struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
 Process SCTP message while in the Idle state. More...
 
static int INi_process (struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
 Process SCTP message while waiting for an INIT-ACK message. More...
 
static int INa_process (struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
 Process SCTP message while waiting for an AddIp-ACK message. More...
 
static int UP_process (struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
 Process SCTP messages while association is UP redirecting packets. More...
 
static int CL_process (struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
 Process SCTP message while association is in the process of closing. More...
 
static void TxAbortErrorM (struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int sndrply, int direction)
 
static struct sctp_nat_assocFindSctpLocal (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)
 Find the SCTP association given the local address, port and vtag. More...
 
static struct sctp_nat_assocFindSctpGlobal (struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint16_t g_port, uint16_t l_port, int *partial_match)
 Find the SCTP association given the global port and vtag. More...
 
static struct sctp_nat_assocFindSctpGlobalClash (struct libalias *la, struct sctp_nat_assoc *Cassoc)
 Check for Global Clash. More...
 
static struct sctp_nat_assocFindSctpLocalT (struct libalias *la, struct in_addr g_addr, uint32_t l_vtag, uint16_t g_port, uint16_t l_port)
 Find the SCTP association for a T-Flag message (given the global port and local vtag) More...
 
static struct sctp_nat_assocFindSctpGlobalT (struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint16_t l_port, uint16_t g_port)
 Find the SCTP association for a T-Flag message (given the local port and global vtag) More...
 
static int AddSctpAssocLocal (struct libalias *la, struct sctp_nat_assoc *assoc, struct in_addr g_addr)
 Add the sctp association information to the local look up table. More...
 
static int AddSctpAssocGlobal (struct libalias *la, struct sctp_nat_assoc *assoc)
 Add the sctp association information to the global look up table. More...
 
static void RmSctpAssoc (struct libalias *la, struct sctp_nat_assoc *assoc)
 Remove the sctp association information from the look up table. More...
 
static void freeGlobalAddressList (struct sctp_nat_assoc *assoc)
 free the Global Address List memory More...
 
static void sctp_AddTimeOut (struct libalias *la, struct sctp_nat_assoc *assoc)
 Add an association timeout to the timer queue. More...
 
static void sctp_RmTimeOut (struct libalias *la, struct sctp_nat_assoc *assoc)
 Remove an association from timer queue. More...
 
static void sctp_ResetTimeOut (struct libalias *la, struct sctp_nat_assoc *assoc, int newexp)
 Reset timer in timer queue. More...
 
void sctp_CheckTimers (struct libalias *la)
 Check timer Q against current time. More...
 
static void logsctperror (char *errormsg, uint32_t vtag, int error, int direction)
 Log sctp nat errors. More...
 
static void logsctpparse (int direction, struct sctp_nat_msg *sm)
 Log what the parser parsed. More...
 
static void logsctpassoc (struct sctp_nat_assoc *assoc, char *s)
 Log an SCTP association's details. More...
 
static void logTimerQ (struct libalias *la)
 Output timer queue to log. More...
 
static void logSctpGlobal (struct libalias *la)
 Output Global table to log. More...
 
static void logSctpLocal (struct libalias *la)
 Output Local table to log. More...
 
static void SctpAliasLog (const char *format,...)
 Sctp NAT logging function. More...
 
void SctpShowAliasStats (struct libalias *la)
 Log current statistics for the libalias instance. More...
 
static MALLOC_DEFINE (M_SCTPNAT, "sctpnat", "sctp nat dbs")
 
int sysctl_chg_loglevel (SYSCTL_HANDLER_ARGS)
 sysctl callback for changing net.inet.ip.fw.sctp.log_level More...
 
int sysctl_chg_timer (SYSCTL_HANDLER_ARGS)
 sysctl callback for changing net.inet.ip.fw.sctp.(init_timer|up_timer|shutdown_timer) More...
 
int sysctl_chg_hashtable_size (SYSCTL_HANDLER_ARGS)
 sysctl callback for changing net.inet.ip.alias.sctp.hashtable_size More...
 
int sysctl_chg_error_on_ootb (SYSCTL_HANDLER_ARGS)
 sysctl callback for changing net.inet.ip.alias.sctp.error_on_ootb More...
 
int sysctl_chg_accept_global_ootb_addip (SYSCTL_HANDLER_ARGS)
 sysctl callback for changing net.inet.ip.alias.sctp.accept_global_ootb_addip More...
 
int sysctl_chg_initialising_chunk_proc_limit (SYSCTL_HANDLER_ARGS)
 sysctl callback for changing net.inet.ip.alias.sctp.initialising_chunk_proc_limit More...
 
int sysctl_chg_chunk_proc_limit (SYSCTL_HANDLER_ARGS)
 sysctl callback for changing net.inet.ip.alias.sctp.chunk_proc_limit More...
 
int sysctl_chg_param_proc_limit (SYSCTL_HANDLER_ARGS)
 sysctl callback for changing net.inet.ip.alias.sctp.param_proc_limit More...
 
int sysctl_chg_track_global_addresses (SYSCTL_HANDLER_ARGS)
 sysctl callback for changing net.inet.ip.alias.sctp.track_global_addresses More...
 
void AliasSctpInit (struct libalias *la)
 Initialises the SCTP NAT Implementation. More...
 
void AliasSctpTerm (struct libalias *la)
 Cleans-up the SCTP NAT Implementation prior to unloading. More...
 
int SctpAlias (struct libalias *la, struct ip *pip, int direction)
 Handles SCTP packets passed from libalias. More...
 
static uint32_t local_sctp_finalize_crc32 (uint32_t crc32c)
 Send an AbortM or ErrorM. More...
 

Variables

static u_int sysctl_log_level = 0
 net.inet.ip.alias.sctp.log_level More...
 
static u_int sysctl_init_timer = 15
 net.inet.ip.alias.sctp.init_timer More...
 
static u_int sysctl_up_timer = 300
 net.inet.ip.alias.sctp.up_timer More...
 
static u_int sysctl_shutdown_timer = 15
 net.inet.ip.alias.sctp.shutdown_timer More...
 
static u_int sysctl_holddown_timer = 0
 net.inet.ip.alias.sctp.holddown_timer More...
 
static u_int sysctl_hashtable_size = SN_DEFAULT_HASH_SIZE
 net.inet.ip.alias.sctp.hashtable_size More...
 
static u_int sysctl_error_on_ootb = 1
 net.inet.ip.alias.sctp.error_on_ootb More...
 
static u_int sysctl_accept_global_ootb_addip = 0
 net.inet.ip.alias.sctp.accept_global_ootb_addip More...
 
static u_int sysctl_initialising_chunk_proc_limit = 2
 net.inet.ip.alias.sctp.initialising_chunk_proc_limit More...
 
static u_int sysctl_chunk_proc_limit = 5
 net.inet.ip.alias.sctp.param_proc_limit More...
 
static u_int sysctl_param_proc_limit = 25
 net.inet.ip.alias.sctp.param_proc_limit More...
 
static u_int sysctl_track_global_addresses = 0
 net.inet.ip.alias.sctp.track_global_addresses More...
 

Macro Definition Documentation

◆ SCTP_MIDDLEBOX_FLAG

#define SCTP_MIDDLEBOX_FLAG   0x02

◆ SCTP_MISSING_NAT

#define SCTP_MISSING_NAT   0x00b1

◆ SCTP_NAT_TABLE_COLLISION

#define SCTP_NAT_TABLE_COLLISION   0x00b0

◆ SCTP_VTAG_PARAM

#define SCTP_VTAG_PARAM   0xC007

Function Documentation

◆ Add_Global_Address_to_List()

static int Add_Global_Address_to_List ( struct sctp_nat_assoc assoc,
struct sctp_GlobalAddress G_addr 
)
static

Add_Global_Address_to_List.

Adds a global IP address to an associations address list, if it is not already there. The first address added us usually the packet's address, and is most likely to be used, so it is added at the beginning. Subsequent addresses are added after this one.

Parameters
assocPointer to the association this SCTP Message belongs to
G_addrPointer to the global address to add
Returns
1 - success | 0 - fail

Definition at line 1474 of file alias_sctp.c.

◆ AliasSctpInit()

void AliasSctpInit ( struct libalias la)

Initialises the SCTP NAT Implementation.

Creates the look-up tables and the timer queue and initialises all state variables

Parameters
laPointer to the relevant libalias instance

Definition at line 653 of file alias_sctp.c.

Referenced by LibAliasInit().

Here is the caller graph for this function:

◆ AliasSctpTerm()

void AliasSctpTerm ( struct libalias la)

Cleans-up the SCTP NAT Implementation prior to unloading.

Removes all entries from the timer queue, freeing associations as it goes. We then free memory allocated to the look-up tables and the time queue

NOTE: We do not need to traverse the look-up tables as each association will always have an entry in the timer queue, freeing this memory once will free all memory allocated to entries in the look-up tables

Parameters
laPointer to the relevant libalias instance

Definition at line 694 of file alias_sctp.c.

Referenced by LibAliasInit(), and LibAliasUninit().

Here is the caller graph for this function:

◆ local_sctp_finalize_crc32()

static uint32_t local_sctp_finalize_crc32 ( uint32_t  crc32c)
static

Send an AbortM or ErrorM.

We construct the new SCTP packet to send in place of the existing packet we have been asked to NAT. This function can only be called if the original packet was successfully parsed as a valid SCTP packet.

An AbortM (without cause) packet is the smallest SCTP packet available and as such there is always space in the existing packet buffer to fit the AbortM packet. An ErrorM packet is 4 bytes longer than the (the error cause is not optional). An ErrorM is sent in response to an AddIP when the Vtag/address combination, if added, will produce a conflict in the association look up tables. It may also be used for an unexpected packet - a packet with no matching association in the NAT table and we are requesting an AddIP so we can add it. The smallest valid SCTP packet while the association is in an up-state is a Heartbeat packet, which is big enough to be transformed to an ErrorM.

We create a temporary character array to store the packet as we are constructing it. We then populate the array with appropriate values based on:

  • Packet type (AbortM | ErrorM)
  • Initial packet direction (SN_TO_LOCAL | SN_TO_GLOBAL)
  • NAT response (Send packet | Reply packet)

Once complete, we copy the contents of the temporary packet over the original SCTP packet we were asked to NAT

Parameters
laPointer to the relevant libalias instance
smPointer to sctp message information
assocPointer to current association details
sndrplySN_SEND_ABORT | SN_REPLY_ABORT | SN_REPLY_ERROR
directionSN_TO_LOCAL | SN_TO_GLOBAL

Definition at line 895 of file alias_sctp.c.

◆ MALLOC_DEFINE()

static MALLOC_DEFINE ( M_SCTPNAT  ,
"sctpnat"  ,
"sctp nat dbs"   
)
static

◆ SctpAlias()

int SctpAlias ( struct libalias la,
struct ip pip,
int  direction 
)

Handles SCTP packets passed from libalias.

This function needs to actually NAT/drop packets and possibly create and send AbortM or ErrorM packets in response. The process involves:

  • Validating the direction parameter passed by the caller
  • Checking and handling any expired timers for the NAT
  • Calling sctp_PktParser() to parse the packet
  • Call ProcessSctpMsg() to decide the appropriate outcome and to update the NAT tables
  • Based on the return code either:
    • NAT the packet
    • Construct and send an ErrorM|AbortM packet
    • Mark the association for removal from the tables
  • Potentially remove the association from all lookup tables
  • Return the appropriate result to libalias
Parameters
laPointer to the relevant libalias instance
pipPointer to IP packet to process
directionSN_TO_LOCAL | SN_TO_GLOBAL
Returns
PKT_ALIAS_OK | PKT_ALIAS_IGNORE | PKT_ALIAS_ERROR

Definition at line 741 of file alias_sctp.c.

Referenced by LibAliasInLocked(), and LibAliasOutLocked().

Here is the caller graph for this function:

◆ TxAbortErrorM()

static void TxAbortErrorM ( struct libalias la,
struct sctp_nat_msg sm,
struct sctp_nat_assoc assoc,
int  sndrply,
int  direction 
)
static

Definition at line 932 of file alias_sctp.c.