Lines Matching +full:always +full:- +full:wait +full:- +full:for +full:- +full:ack

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * Network Address Translation (NAT) for the SCTP protocol.
54 * Traditional address and port number look ups are inadequate for SCTP's
55 * operation due to both processing requirements and issues with multi-homing.
59 * - Support for global multi-homing
60 * - Support for ASCONF modification from Internet Draft
61 * (draft-stewart-behave-sctpnat-04, R. Stewart and M. Tuexen, "Stream control
63 * provide support for multi-homed privately addressed hosts
64 * - Support for forwarding of T-flagged packets
65 * - Generation and delivery of AbortM/ErrorM packets upon detection of NAT
67 * - Per-port forwarding rules
68 * - Dynamically controllable logging and statistics
69 * - Dynamic management of timers
70 * - Dynamic control of hash-table size
96 /* ----------------------------------------------------------------------
98 * ----------------------------------------------------------------------
171 * @brief Log current statistics for the libalias instance
177 * statistics about the libalias instance - including SCTP statistics
203 * - Return pointers to the first and next SCTP chunks within an SCTP Packet
204 * - Define possible return values of the packet parsing process
205 * - SCTP message types for storing in the sctp_nat_msg structure @{
211 …nkhead) (struct sctp_chunkhdr *)(((char *)chunkhead) + SCTP_SIZE32(ntohs(chunkhead->chunk_length)))
214 …EXTPARAM(param) (struct sctp_paramhdr *)(((char *)param) + SCTP_SIZE32(ntohs(param->param_length)))
220 #define SN_ASCONFACK_PARAM_SIZE 8 /**< Size of SCTP ASCONF ACK param in bytes */
223 #define SN_PARSE_OK 0 /**< Packet parsed for SCTP messages */
224 #define SN_PARSE_ERROR_IPSHL 1 /**< Packet parsing error - IP and SCTP common header len…
225 #define SN_PARSE_ERROR_AS_MALLOC 2 /**< Packet parsing error - assoc malloc */
226 #define SN_PARSE_ERROR_CHHL 3 /**< Packet parsing error - Chunk header len */
227 #define SN_PARSE_ERROR_DIR 4 /**< Packet parsing error - Direction */
228 #define SN_PARSE_ERROR_VTAG 5 /**< Packet parsing error - Vtag */
229 #define SN_PARSE_ERROR_CHUNK 6 /**< Packet parsing error - Chunk */
230 #define SN_PARSE_ERROR_PORT 7 /**< Packet parsing error - Port=0 */
231 #define SN_PARSE_ERROR_LOOKUP 8 /**< Packet parsing error - Lookup */
232 #define SN_PARSE_ERROR_PARTIALLOOKUP 9 /**< Packet parsing error - partial lookup only found */
233 #define SN_PARSE_ERROR_LOOKUP_ABORT 10 /**< Packet parsing error - Lookup - but abort packet */
238 #define SN_SCTP_INITACK 0x0002 /**< a packet containing an INIT-ACK chunk */
239 #define SN_SCTP_SHUTCOMP 0x0010 /**< a packet containing a SHUTDOWN-COMPLETE chunk */
240 #define SN_SCTP_SHUTACK 0x0020 /**< a packet containing a SHUTDOWN-ACK chunk */
242 #define SN_SCTP_ASCONFACK 0x0200 /**< a packet containing an ASCONF-ACK chunk */
250 #define SN_INi 0x0010 /**< Initialising, waiting for InitAck state */
251 #define SN_INa 0x0020 /**< Initialising, waiting for AddIpAck state */
272 * Defines minimum/maximum/default values for the hash table size @{
276 #define SN_DEFAULT_HASH_SIZE 2003 /**< A reasonable default size for the hash tables */
281 #define SN_WAIT_TOLOCAL 0x10 /**< assoc waiting for TOLOCAL asconf ACK*/
282 #define SN_WAIT_TOGLOBAL 0x20 /**< assoc waiting for TOLOCAL asconf ACK*/
294 * times for the provided libalias instance @{
303 #define SN_X_T(la) (LibAliasTime + sysctl_holddown_timer) /**< Wait after a shutdown complete in …
307 * Sysctl variables to modify NAT functionality in real-time along with associated functions
326 …imer = 15; /**< Seconds to hold an association in the table waiting for an INIT-ACK or AddIP-ACK */
330 …own_timer = 15; /**< Seconds to hold an association in the table waiting for a SHUTDOWN-COMPLETE */
332 …ld an association in the table after it has been shutdown (to allow for lost SHUTDOWN-COMPLETEs) */
334 static u_int sysctl_hashtable_size = SN_DEFAULT_HASH_SIZE; /**< Sets the hash table size for any NE…
337 (0 - No response, 1 - NAT will send ErrorM only to local side,
338 2 - NAT will send local ErrorM and global ErrorM if there was a partial association match
339 3 - NAT will send ErrorM to both local and global) */
341 …esponset to receipt of global OOTB AddIP (0 - No response, 1 - NAT will accept OOTB global AddIP m…
349 …ures the global address tracking option within the NAT (0 - Global tracking is disabled, > 0 - ena…
354 #define SN_LOCALandPARTIAL_ERROR_ON_OOTB 2 /**< Send local errorM and global errorM for out of the …
369 "Level of detail (0 - default, 1 - event, 2 - info, 3 - detail, 4 - debug, 5 - max debug)");
373 "Timeout value (s) while waiting for (INIT-ACK|AddIP-ACK)");
381 "Timeout value (s) while waiting for SHUTDOWN-COMPLETE");
385 "Hold association in table for this many seconds after receiving a SHUTDOWN-COMPLETE");
389 "Size of hash tables used for NAT lookups (100 < prime_number > 1000001)");
393 "ErrorM sent on receipt of ootb packet:\n\t0 - none,\n"
394 "\t1 - to local only,\n"
395 "\t2 - to local and global if a partial association match,\n"
396 "\t3 - to local and global (DoS risk)");
401 "\t0 - No response,\n"
402 "\t1 - NAT will accept OOTB global AddIP messages for processing (Security risk)");
423 "\t0 - Global tracking is disabled,\n"
424 "\t> 0 - enables tracking but limits the number of global IP addresses to this value");
429 * @brief sysctl callback for changing net.inet.ip.fw.sctp.log_level
432 * it is in the valid range (SN_LOG_LOW -> SN_LOG_DEBUG)
450 * @brief sysctl callback for changing net.inet.ip.fw.sctp.(init_timer|up_timer|shutdown_timer)
452 * Updates the timer-based sysctl variables. The new values are sanity-checked
453 * to make sure that they are within the range SN_MIN_TIMER-SN_MAX_TIMER. The
477 * @brief sysctl callback for changing net.inet.ip.alias.sctp.hashtable_size
481 * SN_MIN_HASH_SIZE-SN_MAX_HASH_SIZE. We then check the provided number to see
498for (;(((size % 3) == 0) || ((size % 5) == 0) || ((size % 7) == 0) || ((size % 11) == 0)); size+=2… in sysctl_chg_hashtable_size()
505 * @brief sysctl callback for changing net.inet.ip.alias.sctp.error_on_ootb
529 * @brief sysctl callback for changing net.inet.ip.alias.sctp.accept_global_ootb_addip
531 * If set to 1 the NAT will accept ootb global addip messages for processing (Security risk)
549 * @brief sysctl callback for changing net.inet.ip.alias.sctp.initialising_chunk_proc_limit
572 * @brief sysctl callback for changing net.inet.ip.alias.sctp.chunk_proc_limit
594 * @brief sysctl callback for changing net.inet.ip.alias.sctp.param_proc_limit
616 * @brief sysctl callback for changing net.inet.ip.alias.sctp.track_global_addresses
618 *Configures the global address tracking option within the NAT (0 - Global
619 *tracking is disabled, > 0 - enables tracking but limits the number of global
636 /* ----------------------------------------------------------------------
638 * ----------------------------------------------------------------------
643 * Creates the look-up tables and the timer queue and initialises all state
653 la->sctpNatTableSize = sysctl_hashtable_size; in AliasSctpInit()
655 SctpAliasLog("Initialising SCTP NAT Instance (hash_table_size:%d)\n", la->sctpNatTableSize)); in AliasSctpInit()
656 la->sctpTableLocal = sn_calloc(la->sctpNatTableSize, sizeof(struct sctpNatTableL)); in AliasSctpInit()
657 la->sctpTableGlobal = sn_calloc(la->sctpNatTableSize, sizeof(struct sctpNatTableG)); in AliasSctpInit()
658 la->sctpNatTimer.TimerQ = sn_calloc(SN_TIMER_QUEUE_SIZE, sizeof(struct sctpTimerQ)); in AliasSctpInit()
660 for (i = 0; i < la->sctpNatTableSize; i++) { in AliasSctpInit()
661 LIST_INIT(&la->sctpTableLocal[i]); in AliasSctpInit()
662 LIST_INIT(&la->sctpTableGlobal[i]); in AliasSctpInit()
666 for (i = 0; i < SN_TIMER_QUEUE_SIZE; i++) in AliasSctpInit()
667 LIST_INIT(&la->sctpNatTimer.TimerQ[i]); in AliasSctpInit()
669 la->sctpNatTimer.loc_time=time_uptime; /* LibAliasTime is not set yet */ in AliasSctpInit()
671 la->sctpNatTimer.loc_time=LibAliasTime; in AliasSctpInit()
673 la->sctpNatTimer.cur_loc = 0; in AliasSctpInit()
674 la->sctpLinkCount = 0; in AliasSctpInit()
678 * @brief Cleans-up the SCTP NAT Implementation prior to unloading
681 * We then free memory allocated to the look-up tables and the time queue
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
698 for (i = 0; i < SN_TIMER_QUEUE_SIZE; i++) { in AliasSctpTerm()
699 assoc1 = LIST_FIRST(&la->sctpNatTimer.TimerQ[i]); in AliasSctpTerm()
708 sn_free(la->sctpTableLocal); in AliasSctpTerm()
709 sn_free(la->sctpTableGlobal); in AliasSctpTerm()
710 sn_free(la->sctpNatTimer.TimerQ); in AliasSctpTerm()
718 * - Validating the direction parameter passed by the caller
719 * - Checking and handling any expired timers for the NAT
720 * - Calling sctp_PktParser() to parse the packet
721 * - Call ProcessSctpMsg() to decide the appropriate outcome and to update
723 * - Based on the return code either:
724 * - NAT the packet
725 * - Construct and send an ErrorM|AbortM packet
726 * - Mark the association for removal from the tables
727 * - Potentially remove the association from all lookup tables
728 * - Return the appropriate result to libalias
760 if ((assoc != NULL) && (ntohs(pip->ip_off) & IP_MF)) { in SctpAlias()
765 logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); in SctpAlias()
770 logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); in SctpAlias()
782 logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); in SctpAlias()
795 logsctpassoc(assoc, "-"); in SctpAlias()
805 DifferentialChecksum(&(msg.ip_hdr->ip_sum), in SctpAlias()
806 &(assoc->l_addr), &(msg.ip_hdr->ip_dst), 2); in SctpAlias()
807 msg.ip_hdr->ip_dst = assoc->l_addr; /* change dst address to local address*/ in SctpAlias()
810 DifferentialChecksum(&(msg.ip_hdr->ip_sum), in SctpAlias()
811 &(assoc->a_addr), &(msg.ip_hdr->ip_src), 2); in SctpAlias()
812 msg.ip_hdr->ip_src = assoc->a_addr; /* change src to alias addr*/ in SctpAlias()
816 …SN_LOG(SN_LOG_LOW, logsctperror("ERROR: Invalid direction", msg.sctp_hdr->v_tag, rtnval, direction… in SctpAlias()
821 SN_LOG(SN_LOG_DETAIL, logsctperror("SN_DROP_PKT", msg.sctp_hdr->v_tag, rtnval, direction)); in SctpAlias()
830 SN_LOG(SN_LOG_LOW, logsctperror("SN_PROCESSING_ERROR", msg.sctp_hdr->v_tag, rtnval, direction)); in SctpAlias()
831 assoc->state = SN_RM;/* Mark for removal*/ in SctpAlias()
835 /* Remove association if tagged for removal */ in SctpAlias()
836 if (assoc->state == SN_RM) { in SctpAlias()
837 if (assoc->TableRegister) { in SctpAlias()
868 * such there is always space in the existing packet buffer to fit the AbortM
872 * tables. It may also be used for an unexpected packet - a packet with no
875 * up-state is a Heartbeat packet, which is big enough to be transformed to an
880 * - Packet type (AbortM | ErrorM)
881 * - Initial packet direction (SN_TO_LOCAL | SN_TO_GLOBAL)
882 * - NAT response (Send packet | Reply packet)
899 * however are always available in libkern. in local_sctp_finalize_crc32()
910 * For BIG-ENDIAN.. aka Motorola byte order the result is in in local_sctp_finalize_crc32()
911 * little-endian form. So we must manually swap the bytes. Then we in local_sctp_finalize_crc32()
921 * For INTEL platforms the result comes out in network order. No in local_sctp_finalize_crc32()
939 if (ntohs(sm->ip_hdr->ip_len) < ip_size) { /* short packet, cannot send error cause */ in TxAbortErrorM()
941 ip_size = ip_size - sizeof(struct sctp_error_cause); in TxAbortErrorM()
942 sctp_size = sctp_size - sizeof(struct sctp_error_cause); in TxAbortErrorM()
951 ip->ip_v = sm->ip_hdr->ip_v; in TxAbortErrorM()
952 ip->ip_hl = 5; /* 5*32 bit words */ in TxAbortErrorM()
953 ip->ip_tos = 0; in TxAbortErrorM()
954 ip->ip_len = htons(ip_size); in TxAbortErrorM()
955 ip->ip_id = sm->ip_hdr->ip_id; in TxAbortErrorM()
956 ip->ip_off = 0; in TxAbortErrorM()
957 ip->ip_ttl = 255; in TxAbortErrorM()
958 ip->ip_p = IPPROTO_SCTP; in TxAbortErrorM()
965 chunk_hdr->chunk_type = (sndrply & SN_TX_ABORT) ? SCTP_ABORT_ASSOCIATION : SCTP_OPERATION_ERROR; in TxAbortErrorM()
966 chunk_hdr->chunk_flags = SCTP_MIDDLEBOX_FLAG; in TxAbortErrorM()
968 …error_cause->code = htons((sndrply & SN_REFLECT_ERROR) ? SCTP_MISSING_NAT : SCTP_NAT_TABLE_COLLISI… in TxAbortErrorM()
969 error_cause->length = htons(sizeof(struct sctp_error_cause)); in TxAbortErrorM()
970 chunk_hdr->chunk_length = htons(sizeof(*chunk_hdr) + sizeof(struct sctp_error_cause)); in TxAbortErrorM()
972 chunk_hdr->chunk_length = htons(sizeof(*chunk_hdr)); in TxAbortErrorM()
978 chunk_hdr->chunk_flags |= SCTP_HAD_NO_TCB; /* set Tbit */ in TxAbortErrorM()
979 sctp_hdr->v_tag = sm->sctp_hdr->v_tag; in TxAbortErrorM()
982 sctp_hdr->v_tag = (direction == SN_TO_LOCAL) ? assoc->g_vtag : assoc->l_vtag ; in TxAbortErrorM()
985 sctp_hdr->v_tag = sm->sctp_hdr->v_tag; in TxAbortErrorM()
988 sctp_hdr->v_tag = sm->sctpchnk.Init->initiate_tag; in TxAbortErrorM()
994 ip->ip_src = (direction == SN_TO_LOCAL) ? sm->ip_hdr->ip_src : assoc->a_addr; in TxAbortErrorM()
995 ip->ip_dst = (direction == SN_TO_LOCAL) ? assoc->l_addr : sm->ip_hdr->ip_dst; in TxAbortErrorM()
996 sctp_hdr->src_port = sm->sctp_hdr->src_port; in TxAbortErrorM()
997 sctp_hdr->dest_port = sm->sctp_hdr->dest_port; in TxAbortErrorM()
999 ip->ip_src = sm->ip_hdr->ip_dst; in TxAbortErrorM()
1000 ip->ip_dst = sm->ip_hdr->ip_src; in TxAbortErrorM()
1001 sctp_hdr->src_port = sm->sctp_hdr->dest_port; in TxAbortErrorM()
1002 sctp_hdr->dest_port = sm->sctp_hdr->src_port; in TxAbortErrorM()
1006 ip->ip_sum = in_cksum_hdr(ip); in TxAbortErrorM()
1009 sctp_hdr->checksum = 0; in TxAbortErrorM()
1010 …sctp_hdr->checksum = local_sctp_finalize_crc32(calculate_crc32c(0xffffffff, (unsigned char *) sctp… in TxAbortErrorM()
1012 memcpy(sm->ip_hdr, ip, ip_size); in TxAbortErrorM()
1014 SN_LOG(SN_LOG_EVENT,SctpAliasLog("%s %s 0x%x (->%s:%u vtag=0x%x crc=0x%x)\n", in TxAbortErrorM()
1017 (include_error_cause ? ntohs(error_cause->code) : 0), in TxAbortErrorM()
1018 inet_ntoa_r(ip->ip_dst, INET_NTOA_BUF(addrbuf)), in TxAbortErrorM()
1019 ntohs(sctp_hdr->dest_port), in TxAbortErrorM()
1020 ntohl(sctp_hdr->v_tag), ntohl(sctp_hdr->checksum))); in TxAbortErrorM()
1023 /* ----------------------------------------------------------------------
1025 * ----------------------------------------------------------------------
1033 * @brief Parses SCTP packets for the key SCTP chunk that will be processed
1035 * This module parses SCTP packets for the key SCTP chunk that will be processed
1072 sm->msg = SN_SCTP_OTHER;/* Initialise to largest value*/ in sctp_PktParser()
1073 sm->chunk_length = 0; /* only care about length for key chunks */ in sctp_PktParser()
1075 sm->ip_hdr = pip; in sctp_PktParser()
1077 bytes_left = ntohs(pip->ip_len) - (pip->ip_hl << 2); in sctp_PktParser()
1081 sm->sctp_hdr = NULL; in sctp_PktParser()
1085 sm->sctp_hdr = sctp_hdr = (struct sctphdr *) ip_next(pip); in sctp_PktParser()
1086 bytes_left -= sizeof(struct sctphdr); in sctp_PktParser()
1088 /* Check for valid ports (zero valued ports would find partially initialised associations */ in sctp_PktParser()
1089 if (sctp_hdr->src_port == 0 || sctp_hdr->dest_port == 0) in sctp_PktParser()
1093 if (bytes_left < SN_MIN_CHUNK_SIZE) /* malformed chunk - could cause endless loop*/ in sctp_PktParser()
1094 return (SN_PARSE_ERROR_CHHL); /* packet not long enough for this chunk */ in sctp_PktParser()
1099 chunk_length = SCTP_SIZE32(ntohs(chunk_hdr->chunk_length)); in sctp_PktParser()
1100 …if ((chunk_length < SN_MIN_CHUNK_SIZE) || (chunk_length > bytes_left)) /* malformed chunk - could … in sctp_PktParser()
1103 if ((chunk_hdr->chunk_flags & SCTP_HAD_NO_TCB) && in sctp_PktParser()
1104 ((chunk_hdr->chunk_type == SCTP_ABORT_ASSOCIATION) || in sctp_PktParser()
1105 (chunk_hdr->chunk_type == SCTP_SHUTDOWN_COMPLETE))) { in sctp_PktParser()
1106 /* T-Bit set */ in sctp_PktParser()
1108 …*passoc = FindSctpGlobalT(la, pip->ip_src, sctp_hdr->v_tag, sctp_hdr->dest_port, sctp_hdr->src_po… in sctp_PktParser()
1110 …*passoc = FindSctpLocalT(la, pip->ip_dst, sctp_hdr->v_tag, sctp_hdr->dest_port, sctp_hdr->src_port… in sctp_PktParser()
1114 …*passoc = FindSctpGlobal(la, pip->ip_src, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port… in sctp_PktParser()
1116 …*passoc = FindSctpLocal(la, pip->ip_src, pip->ip_dst, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_h… in sctp_PktParser()
1122 switch (chunk_hdr->chunk_type) { in sctp_PktParser()
1126 sm->msg = SN_SCTP_INIT; in sctp_PktParser()
1127 sm->sctpchnk.Init = (struct sctp_init *) ((char *) chunk_hdr + sizeof(struct sctp_chunkhdr)); in sctp_PktParser()
1128 sm->chunk_length = chunk_length; in sctp_PktParser()
1131 if (sctp_hdr->v_tag == 0) { //Init requires vtag=0 in sctp_PktParser()
1136 /* Initialize association - sn_malloc initializes memory to zeros */ in sctp_PktParser()
1137 (*passoc)->state = SN_ID; in sctp_PktParser()
1138 LIST_INIT(&((*passoc)->Gaddr)); /* always initialise to avoid memory problems */ in sctp_PktParser()
1139 (*passoc)->TableRegister = SN_NULL_TBL; in sctp_PktParser()
1148 sm->msg = SN_SCTP_INITACK; in sctp_PktParser()
1149 …sm->sctpchnk.InitAck = (struct sctp_init_ack *) ((char *) chunk_hdr + sizeof(struct sctp_chunkhdr)… in sctp_PktParser()
1150 sm->chunk_length = chunk_length; in sctp_PktParser()
1153 sm->msg = SN_SCTP_ABORT; in sctp_PktParser()
1154 sm->chunk_length = chunk_length; in sctp_PktParser()
1159 if (sm->msg > SN_SCTP_SHUTACK) { in sctp_PktParser()
1160 sm->msg = SN_SCTP_SHUTACK; in sctp_PktParser()
1161 sm->chunk_length = chunk_length; in sctp_PktParser()
1165 if (sm->msg > SN_SCTP_SHUTCOMP) { in sctp_PktParser()
1166 sm->msg = SN_SCTP_SHUTCOMP; in sctp_PktParser()
1167 sm->chunk_length = chunk_length; in sctp_PktParser()
1171 if (sm->msg > SN_SCTP_ASCONF) { in sctp_PktParser()
1176 if (ntohs(param_hdr->param_type) == SCTP_IPV4_ADDRESS) { in sctp_PktParser()
1179 ipv4addr.s_addr = ((struct sctp_ipv4addr_param *) param_hdr)->addr; in sctp_PktParser()
1180 …*passoc = FindSctpGlobal(la, ipv4addr, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port, &… in sctp_PktParser()
1184 …sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_chunk) - sizeof(struct sctp_ipv4addr… in sctp_PktParser()
1190 …sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_chunk) - sizeof(struct sctp_ipv6addr… in sctp_PktParser()
1192 sm->msg = SN_SCTP_ASCONF; in sctp_PktParser()
1193 sm->sctpchnk.Asconf = param_hdr; in sctp_PktParser()
1200 /* Initialize association - sn_malloc initializes memory to zeros */ in sctp_PktParser()
1201 (*passoc)->state = SN_ID; in sctp_PktParser()
1202 LIST_INIT(&((*passoc)->Gaddr)); /* always initialise to avoid memory problems */ in sctp_PktParser()
1203 (*passoc)->TableRegister = SN_NULL_TBL; in sctp_PktParser()
1209 if (sm->msg > SN_SCTP_ASCONFACK) { in sctp_PktParser()
1215 sm->msg = SN_SCTP_ASCONFACK; in sctp_PktParser()
1216 sm->sctpchnk.Asconf = param_hdr; in sctp_PktParser()
1217 sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_ack_chunk); in sctp_PktParser()
1224 …/* if no association is found exit - we need to find an Init or AddIP within sysctl_initialising_c… in sctp_PktParser()
1229 bytes_left-= chunk_length; in sctp_PktParser()
1242 chunk_length = SCTP_SIZE32(ntohs(chunk_hdr->chunk_length)); in sctp_PktParser()
1246 return (SN_PARSE_OK); /* limit for processing chunks, take what we get */ in sctp_PktParser()
1258 * GetAsconfVtags scans an Asconf Chunk for the vtags parameter, and then
1270 * @return 1 - success | 0 - fail
1290 param = sm->sctpchnk.Asconf; in GetAsconfVtags()
1291 param_size = SCTP_SIZE32(ntohs(param->param_length)); in GetAsconfVtags()
1292 bytes_left = sm->chunk_length; in GetAsconfVtags()
1295 if (ntohs(param->param_type) == SCTP_VTAG_PARAM) { in GetAsconfVtags()
1302 *g_vtag = vtag_param->local_vtag; in GetAsconfVtags()
1303 *l_vtag = vtag_param->remote_vtag; in GetAsconfVtags()
1306 *g_vtag = vtag_param->remote_vtag; in GetAsconfVtags()
1307 *l_vtag = vtag_param->local_vtag; in GetAsconfVtags()
1313 bytes_left -= param_size; in GetAsconfVtags()
1318 param_size = SCTP_SIZE32(ntohs(param->param_length)); in GetAsconfVtags()
1322 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); in GetAsconfVtags()
1332 * AddGlobalIPAddresses scans an SCTP chunk (in sm) for Global IP addresses, and
1353 g_addr = sm->ip_hdr->ip_dst; in AddGlobalIPAddresses()
1357 g_addr = sm->ip_hdr->ip_src; in AddGlobalIPAddresses()
1359 switch (sm->msg) { in AddGlobalIPAddresses()
1361 bytes_left = sm->chunk_length - sizeof(struct sctp_init_chunk); in AddGlobalIPAddresses()
1362 param = (struct sctp_paramhdr *)((char *)sm->sctpchnk.Init + sizeof(struct sctp_init)); in AddGlobalIPAddresses()
1365 bytes_left = sm->chunk_length - sizeof(struct sctp_init_ack_chunk); in AddGlobalIPAddresses()
1366 param = (struct sctp_paramhdr *)((char *)sm->sctpchnk.InitAck + sizeof(struct sctp_init_ack)); in AddGlobalIPAddresses()
1369 bytes_left = sm->chunk_length; in AddGlobalIPAddresses()
1370 param = sm->sctpchnk.Asconf; in AddGlobalIPAddresses()
1375 param_size = SCTP_SIZE32(ntohs(param->param_length)); in AddGlobalIPAddresses()
1379 …if ((assoc->state == SN_ID) && ((sm->msg == SN_SCTP_INIT) || (bytes_left < SN_MIN_PARAM_SIZE))) {/… in AddGlobalIPAddresses()
1383 … logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking", in AddGlobalIPAddresses()
1384 sm->sctp_hdr->v_tag, 0, direction)); in AddGlobalIPAddresses()
1385 assoc->num_Gaddr = 0; /* don't track any more for this assoc*/ in AddGlobalIPAddresses()
1389 G_Addr->g_addr = g_addr; in AddGlobalIPAddresses()
1393 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); in AddGlobalIPAddresses()
1398 if (assoc->num_Gaddr >= sysctl_track_global_addresses) { in AddGlobalIPAddresses()
1401 sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction)); in AddGlobalIPAddresses()
1404 switch (ntohs(param->param_type)) { in AddGlobalIPAddresses()
1406 /* skip to address parameter - leave param_size so bytes left will be calculated properly*/ in AddGlobalIPAddresses()
1407 param = (struct sctp_paramhdr *) &((struct sctp_asconf_addrv4_param *) param)->addrp; in AddGlobalIPAddresses()
1415 … logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking", in AddGlobalIPAddresses()
1416 sm->sctp_hdr->v_tag, 0, direction)); in AddGlobalIPAddresses()
1417 assoc->num_Gaddr = 0; /* don't track any more for this assoc*/ in AddGlobalIPAddresses()
1423 if ((sm->msg == SN_SCTP_ASCONF) && (ipv4_param->addr == INADDR_ANY)) { /* use packet address */ in AddGlobalIPAddresses()
1424 G_Addr->g_addr = g_addr; in AddGlobalIPAddresses()
1428 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); in AddGlobalIPAddresses()
1431 G_Addr->g_addr.s_addr = ipv4_param->addr; in AddGlobalIPAddresses()
1435 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); in AddGlobalIPAddresses()
1439 bytes_left -= param_size; in AddGlobalIPAddresses()
1444 param_size = SCTP_SIZE32(ntohs(param->param_length)); in AddGlobalIPAddresses()
1448 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); in AddGlobalIPAddresses()
1455 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); in AddGlobalIPAddresses()
1470 * @return 1 - success | 0 - fail
1476 first_G_Addr = LIST_FIRST(&(assoc->Gaddr)); in Add_Global_Address_to_List()
1478 LIST_INSERT_HEAD(&(assoc->Gaddr), G_addr, list_Gaddr); /* add new address to beginning of list*/ in Add_Global_Address_to_List()
1480 LIST_FOREACH(iter_G_Addr, &(assoc->Gaddr), list_Gaddr) { in Add_Global_Address_to_List()
1481 if (G_addr->g_addr.s_addr == iter_G_Addr->g_addr.s_addr) in Add_Global_Address_to_List()
1486 assoc->num_Gaddr++; in Add_Global_Address_to_List()
1493 * RmGlobalIPAddresses scans an ASCONF chunk for DelIP parameters to remove the
1513 bytes_left = sm->chunk_length; in RmGlobalIPAddresses()
1515 param = sm->sctpchnk.Asconf; in RmGlobalIPAddresses()
1517 param_size = SCTP_SIZE32(ntohs(param->param_length)); in RmGlobalIPAddresses()
1520 logsctperror("RmGlobalIPAddress: truncated packet - cannot remove IP addresses", in RmGlobalIPAddresses()
1521 sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction)); in RmGlobalIPAddresses()
1527 if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS) { in RmGlobalIPAddresses()
1529 if (asconf_ipv4_param->addrp.addr == INADDR_ANY) { /* remove all bar pkt address */ in RmGlobalIPAddresses()
1530 LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) { in RmGlobalIPAddresses()
1531 if (G_Addr->g_addr.s_addr != sm->ip_hdr->ip_src.s_addr) { in RmGlobalIPAddresses()
1532 if (assoc->num_Gaddr > 1) { /* only delete if more than one */ in RmGlobalIPAddresses()
1535 assoc->num_Gaddr--; in RmGlobalIPAddresses()
1539 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); in RmGlobalIPAddresses()
1545 LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) { in RmGlobalIPAddresses()
1546 if (G_Addr->g_addr.s_addr == asconf_ipv4_param->addrp.addr) { in RmGlobalIPAddresses()
1547 if (assoc->num_Gaddr > 1) { /* only delete if more than one */ in RmGlobalIPAddresses()
1550 assoc->num_Gaddr--; in RmGlobalIPAddresses()
1555 sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); in RmGlobalIPAddresses()
1561 bytes_left -= param_size; in RmGlobalIPAddresses()
1566 logsctperror("RmGlobalIPAddress: truncated packet - may not have removed all IP addresses", in RmGlobalIPAddresses()
1567 sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction)); in RmGlobalIPAddresses()
1572 param_size = SCTP_SIZE32(ntohs(param->param_length)); in RmGlobalIPAddresses()
1576 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); in RmGlobalIPAddresses()
1586 * matched with an ASCONFack. This is difficult for a NAT, since every
1589 * ACK.
1591 * Currently we only look for an ACK when the NAT is setting up a new
1592 * association (ie AddIP for a connection that the NAT does not know about
1596 * an ACK that it is responding to the AddIP and activate the new association.
1602 * @return 1 - success | 0 - fail
1613 param = sm->sctpchnk.Asconf; in IsASCONFack()
1614 param_size = SCTP_SIZE32(ntohs(param->param_length)); in IsASCONFack()
1616 return (1); /*success - default acknowledgement of everything */ in IsASCONFack()
1618 bytes_left = sm->chunk_length; in IsASCONFack()
1623 if (ntohs(param->param_type) == SCTP_SUCCESS_REPORT) in IsASCONFack()
1624 return (1); /* success - but can't match correlation IDs - should only be one */ in IsASCONFack()
1626 bytes_left -= param_size; in IsASCONFack()
1632 param_size = SCTP_SIZE32(ntohs(param->param_length)); in IsASCONFack()
1639 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); in IsASCONFack()
1656 * @return SCTP_ADD_IP_ADDRESS | SCTP_DEL_IP_ADDRESS | 0 - fail
1667 param = sm->sctpchnk.Asconf; in IsADDorDEL()
1668 param_size = SCTP_SIZE32(ntohs(param->param_length)); in IsADDorDEL()
1670 bytes_left = sm->chunk_length; in IsADDorDEL()
1675 if (ntohs(param->param_type) == SCTP_ADD_IP_ADDRESS) in IsADDorDEL()
1677 else if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS) in IsADDorDEL()
1680 bytes_left -= param_size; in IsADDorDEL()
1686 param_size = SCTP_SIZE32(ntohs(param->param_length)); in IsADDorDEL()
1693 sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction)); in IsADDorDEL()
1700 /* ----------------------------------------------------------------------
1702 * ----------------------------------------------------------------------
1707 * - Process an already parsed packet
1708 * - Use the existing NAT Hash Tables
1709 * - Determine the next state for the association
1710 * - Update the NAT Hash Tables and Timer Queues
1711 * - Return the appropriate action to take with the packet
1716 * This function is the base state machine. It calls the processing engine for
1731 switch (assoc->state) { in ProcessSctpMsg()
1735 assoc->state = SN_RM;/* Mark for removal*/ in ProcessSctpMsg()
1738 case SN_INi: /* Initialising - Init */ in ProcessSctpMsg()
1740 case SN_INa: /* Initialising - AddIP */ in ProcessSctpMsg()
1753 * This function looks for an Incoming INIT or AddIP message.
1767 switch (sm->msg) { in ID_process()
1772 if (!GetAsconfVtags(la, sm, &(assoc->l_vtag), &(assoc->g_vtag), direction)) in ID_process()
1780 assoc->l_addr = sm->ip_hdr->ip_src; in ID_process()
1781 assoc->a_addr = FindAliasAddress(la, assoc->l_addr); in ID_process()
1782 assoc->l_port = sm->sctp_hdr->src_port; in ID_process()
1783 assoc->g_port = sm->sctp_hdr->dest_port; in ID_process()
1784 if (sm->msg == SN_SCTP_INIT) in ID_process()
1785 assoc->g_vtag = sm->sctpchnk.Init->initiate_tag; in ID_process()
1787 return ((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR); in ID_process()
1788 if (sm->msg == SN_SCTP_ASCONF) { in ID_process()
1789 if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_dst)) /* DB clash */ in ID_process()
1791 assoc->TableRegister |= SN_WAIT_TOLOCAL; /* wait for tolocal ack */ in ID_process()
1795 assoc->l_addr = FindSctpRedirectAddress(la, sm); in ID_process()
1796 assoc->a_addr = sm->ip_hdr->ip_dst; in ID_process()
1797 assoc->l_port = sm->sctp_hdr->dest_port; in ID_process()
1798 assoc->g_port = sm->sctp_hdr->src_port; in ID_process()
1799 if (sm->msg == SN_SCTP_INIT) in ID_process()
1800 assoc->l_vtag = sm->sctpchnk.Init->initiate_tag; in ID_process()
1801 if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_src)) /* DB clash */ in ID_process()
1802 return ((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR); in ID_process()
1803 if (sm->msg == SN_SCTP_ASCONF) { in ID_process()
1806 assoc->TableRegister |= SN_WAIT_TOGLOBAL; /* wait for toglobal ack */ in ID_process()
1810 assoc->state = (sm->msg == SN_SCTP_INIT) ? SN_INi : SN_INa; in ID_process()
1811 assoc->exp = SN_I_T(la); in ID_process()
1817 return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ in ID_process()
1821 * @brief Process SCTP message while waiting for an INIT-ACK message
1823 * Only an INIT-ACK, resent INIT, or an ABORT SCTP packet are valid in this
1836 switch (sm->msg) { in INi_process()
1840 case SN_SCTP_INITACK: /* a packet containing an INIT-ACK chunk */ in INi_process()
1843 if (assoc->num_Gaddr) /*If tracking global addresses for this association */ in INi_process()
1845 assoc->l_vtag = sm->sctpchnk.Init->initiate_tag; in INi_process()
1846 if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_src)) { /* DB clash */ in INi_process()
1847 assoc->state = SN_RM;/* Mark for removal*/ in INi_process()
1852 assoc->l_addr = sm->ip_hdr->ip_src; // Only if not set in Init! * in INi_process()
1853 assoc->g_vtag = sm->sctpchnk.Init->initiate_tag; in INi_process()
1855 assoc->state = SN_RM;/* Mark for removal*/ in INi_process()
1860 assoc->state = SN_UP;/* association established for NAT */ in INi_process()
1864 assoc->state = SN_RM;/* Mark for removal*/ in INi_process()
1869 return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ in INi_process()
1873 * @brief Process SCTP message while waiting for an AddIp-ACK message
1875 * Only an AddIP-ACK, resent AddIP, or an ABORT message are valid, all other
1888 switch (sm->msg) { in INa_process()
1892 case SN_SCTP_ASCONFACK: /* a packet containing an ASCONF chunk with a ADDIP-ACK */ in INa_process()
1895 if (!(assoc->TableRegister & SN_WAIT_TOLOCAL)) /* wrong direction */ in INa_process()
1899 if (!(assoc->TableRegister & SN_WAIT_TOGLOBAL)) /* wrong direction */ in INa_process()
1903 assoc->TableRegister &= SN_BOTH_TBL; /* remove wait flags */ in INa_process()
1904 assoc->state = SN_UP; /* association established for NAT */ in INa_process()
1908 assoc->state = SN_RM;/* Mark for removal*/ in INa_process()
1912 assoc->state = SN_RM;/* Mark for removal*/ in INa_process()
1917 return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ in INa_process()
1923 * While in the SN_UP state, all packets for the particular association
1924 * are passed. Only a SHUT-ACK or an ABORT will cause a change of state.
1936 switch (sm->msg) { in UP_process()
1937 case SN_SCTP_SHUTACK: /* a packet containing a SHUTDOWN-ACK chunk */ in UP_process()
1938 assoc->state = SN_CL; in UP_process()
1942 assoc->state = SN_RM;/* Mark for removal*/ in UP_process()
1945 …if ((direction == SN_TO_LOCAL) && assoc->num_Gaddr) /*If tracking global addresses for this associ… in UP_process()
1959 return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ in UP_process()
1965 * This function waits for a SHUT-COMP to close the association. Depending on
1967 * immediately, but leave it up until SN_X_T(la). Only SHUT-COMP, SHUT-ACK, and
1980 switch (sm->msg) { in CL_process()
1981 case SN_SCTP_SHUTCOMP: /* a packet containing a SHUTDOWN-COMPLETE chunk */ in CL_process()
1982 assoc->state = SN_CL; /* Stay in Close state until timeout */ in CL_process()
1984 sctp_ResetTimeOut(la, assoc, SN_X_T(la));/* allow to stay open for Tbit packets*/ in CL_process()
1986 assoc->state = SN_RM;/* Mark for removal*/ in CL_process()
1988 case SN_SCTP_SHUTACK: /* a packet containing a SHUTDOWN-ACK chunk */ in CL_process()
1989 assoc->state = SN_CL; /* Stay in Close state until timeout */ in CL_process()
1993 assoc->state = SN_RM;/* Mark for removal*/ in CL_process()
1998 return (SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */ in CL_process()
2001 /* ----------------------------------------------------------------------
2003 * ----------------------------------------------------------------------
2007 * The Hash functions facilitate searching the NAT Hash Tables for associations
2013 * Searches the local look-up table for the association entry matching the
2033 i = SN_TABLE_HASH(l_vtag, l_port, la->sctpNatTableSize); in FindSctpLocal()
2034 LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) { in FindSctpLocal()
2035 if ((assoc->l_vtag == l_vtag) && (assoc->l_port == l_port) && (assoc->g_port == g_port)\ in FindSctpLocal()
2036 && (assoc->l_addr.s_addr == l_addr.s_addr)) { in FindSctpLocal()
2037 if (assoc->num_Gaddr) { in FindSctpLocal()
2038 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { in FindSctpLocal()
2039 if (G_Addr->g_addr.s_addr == g_addr.s_addr) in FindSctpLocal()
2052 * @brief Check for Global Clash
2054 * Searches the global look-up table for the association entry matching the
2058 * @param Cassoc association being checked for a clash
2070 if (Cassoc->g_vtag != 0) { /* an init packet, vtag==0 */ in FindSctpGlobalClash()
2071 i = SN_TABLE_HASH(Cassoc->g_vtag, Cassoc->g_port, la->sctpNatTableSize); in FindSctpGlobalClash()
2072 LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { in FindSctpGlobalClash()
2073 …if ((assoc->g_vtag == Cassoc->g_vtag) && (assoc->g_port == Cassoc->g_port) && (assoc->l_port == Ca… in FindSctpGlobalClash()
2074 if (assoc->num_Gaddr) { in FindSctpGlobalClash()
2075 LIST_FOREACH(G_AddrC, &(Cassoc->Gaddr), list_Gaddr) { in FindSctpGlobalClash()
2076 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { in FindSctpGlobalClash()
2077 if (G_Addr->g_addr.s_addr == G_AddrC->g_addr.s_addr) in FindSctpGlobalClash()
2093 * Searches the global look-up table for the association entry matching the
2097 * partial match. If the NAT is tracking global IP addresses for this
2118 i = SN_TABLE_HASH(g_vtag, g_port, la->sctpNatTableSize); in FindSctpGlobal()
2119 LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { in FindSctpGlobal()
2120 if ((assoc->g_vtag == g_vtag) && (assoc->g_port == g_port) && (assoc->l_port == l_port)) { in FindSctpGlobal()
2122 if (assoc->num_Gaddr) { in FindSctpGlobal()
2123 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { in FindSctpGlobal()
2124 if (G_Addr->g_addr.s_addr == g_addr.s_addr) in FindSctpGlobal()
2137 * @brief Find the SCTP association for a T-Flag message (given the global port and local vtag)
2139 * Searches the local look-up table for a unique association entry matching the
2159 i = SN_TABLE_HASH(l_vtag, g_port, la->sctpNatTableSize); in FindSctpLocalT()
2160 LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { in FindSctpLocalT()
2161 if ((assoc->g_vtag == l_vtag) && (assoc->g_port == g_port) && (assoc->l_port == l_port)) { in FindSctpLocalT()
2162 if (assoc->num_Gaddr) { in FindSctpLocalT()
2163 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { in FindSctpLocalT()
2164 if (G_Addr->g_addr.s_addr == g_addr.s_addr) in FindSctpLocalT()
2180 * @brief Find the SCTP association for a T-Flag message (given the local port and global vtag)
2182 * Searches the global look-up table for a unique association entry matching the
2201 i = SN_TABLE_HASH(g_vtag, l_port, la->sctpNatTableSize); in FindSctpGlobalT()
2202 LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) { in FindSctpGlobalT()
2203 if ((assoc->l_vtag == g_vtag) && (assoc->l_port == l_port) && (assoc->g_port == g_port)) { in FindSctpGlobalT()
2204 if (assoc->num_Gaddr) { in FindSctpGlobalT()
2205 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { in FindSctpGlobalT()
2206 if (G_Addr->g_addr.s_addr == g_addr.s_addr) in FindSctpGlobalT()
2221 * Searches the local look-up table for an existing association with the same
2222 * details. If a match exists and is ONLY in the local look-up table then this
2224 * look-up table and add the new association
2240 found = FindSctpLocal(la, assoc->l_addr, g_addr, assoc->l_vtag, assoc->l_port, assoc->g_port); in AddSctpAssocLocal()
2244 * - the local receiver if receiving it for the first time will establish in AddSctpAssocLocal()
2246 * - if receiving an init from a different global address after sending a in AddSctpAssocLocal()
2251 …if ((found->TableRegister == SN_LOCAL_TBL) && (found->g_port == assoc->g_port)) { /* resent messag… in AddSctpAssocLocal()
2260 …LIST_INSERT_HEAD(&la->sctpTableLocal[SN_TABLE_HASH(assoc->l_vtag, assoc->l_port, la->sctpNatTableS… in AddSctpAssocLocal()
2262 assoc->TableRegister |= SN_LOCAL_TBL; in AddSctpAssocLocal()
2263 la->sctpLinkCount++; //increment link count in AddSctpAssocLocal()
2265 if (assoc->TableRegister == SN_BOTH_TBL) { in AddSctpAssocLocal()
2266 /* libalias log -- controlled by libalias */ in AddSctpAssocLocal()
2267 if (la->packetAliasMode & PKT_ALIAS_LOG) in AddSctpAssocLocal()
2279 * Searches the global look-up table for an existing association with the same
2280 * details. If a match exists and is ONLY in the global look-up table then this
2282 * look-up table and add the new association
2299 if ((found->TableRegister == SN_GLOBAL_TBL) && in AddSctpAssocGlobal()
2300 (found->l_addr.s_addr == assoc->l_addr.s_addr) && in AddSctpAssocGlobal()
2301 (found->l_port == assoc->l_port)) { /* resent message */ in AddSctpAssocGlobal()
2310 …LIST_INSERT_HEAD(&la->sctpTableGlobal[SN_TABLE_HASH(assoc->g_vtag, assoc->g_port, la->sctpNatTable… in AddSctpAssocGlobal()
2312 assoc->TableRegister |= SN_GLOBAL_TBL; in AddSctpAssocGlobal()
2313 la->sctpLinkCount++; //increment link count in AddSctpAssocGlobal()
2315 if (assoc->TableRegister == SN_BOTH_TBL) { in AddSctpAssocGlobal()
2316 /* libalias log -- controlled by libalias */ in AddSctpAssocGlobal()
2317 if (la->packetAliasMode & PKT_ALIAS_LOG) in AddSctpAssocGlobal()
2329 * For each of the two (local/global) look-up tables, remove the association
2332 * NOTE: The calling code is responsible for freeing memory allocated to the
2351 if (assoc->TableRegister == SN_BOTH_TBL) { in RmSctpAssoc()
2355 if (assoc->TableRegister & SN_LOCAL_TBL) { in RmSctpAssoc()
2356 assoc->TableRegister ^= SN_LOCAL_TBL; in RmSctpAssoc()
2357 la->sctpLinkCount--; //decrement link count in RmSctpAssoc()
2361 if (assoc->TableRegister & SN_GLOBAL_TBL) { in RmSctpAssoc()
2362 assoc->TableRegister ^= SN_GLOBAL_TBL; in RmSctpAssoc()
2363 la->sctpLinkCount--; //decrement link count in RmSctpAssoc()
2367 /* libalias logging -- controlled by libalias log definition */ in RmSctpAssoc()
2368 if (la->packetAliasMode & PKT_ALIAS_LOG) in RmSctpAssoc()
2385 gaddr1 = LIST_FIRST(&(assoc->Gaddr)); in freeGlobalAddressList()
2392 /* ----------------------------------------------------------------------
2394 * ----------------------------------------------------------------------
2402 * it has to be changed to a shorter time (usually only for aborts and closing).
2405 * for normal packets sent during an association. When a timer expires, it is
2408 * every U_T (every few minutes) for a particular association.
2424 add_loc = assoc->exp - la->sctpNatTimer.loc_time + la->sctpNatTimer.cur_loc; in sctp_AddTimeOut()
2426 add_loc -= SN_TIMER_QUEUE_SIZE; in sctp_AddTimeOut()
2427 LIST_INSERT_HEAD(&la->sctpNatTimer.TimerQ[add_loc], assoc, timer_Q); in sctp_AddTimeOut()
2428 assoc->exp_loc = add_loc; in sctp_AddTimeOut()
2450 * Reset the actual timeout for the specified association. If it is earlier than
2451 * the existing timeout, then remove and re-install the association into the
2461 if (newexp < assoc->exp) { in sctp_ResetTimeOut()
2463 assoc->exp = newexp; in sctp_ResetTimeOut()
2466 assoc->exp = newexp; in sctp_ResetTimeOut()
2474 * the timer queue until now (the current time). For each association in the
2477 * - Log the timer expiry
2478 * - Remove the association from the NAT tables
2479 * - Release the memory used by the association
2492 while(LibAliasTime >= la->sctpNatTimer.loc_time) { in sctp_CheckTimers()
2493 while (!LIST_EMPTY(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc])) { in sctp_CheckTimers()
2494 assoc = LIST_FIRST(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc]); in sctp_CheckTimers()
2495 //SLIST_REMOVE_HEAD(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc], timer_Q); in sctp_CheckTimers()
2497 if (LibAliasTime >= assoc->exp) { /* state expired */ in sctp_CheckTimers()
2498 SN_LOG(((assoc->state == SN_CL) ? (SN_LOG_DEBUG) : (SN_LOG_INFO)), in sctp_CheckTimers()
2499 logsctperror("Timer Expired", assoc->g_vtag, assoc->state, SN_TO_NODIR)); in sctp_CheckTimers()
2508 ++la->sctpNatTimer.loc_time; in sctp_CheckTimers()
2509 if (++la->sctpNatTimer.cur_loc >= SN_TIMER_QUEUE_SIZE) in sctp_CheckTimers()
2510 la->sctpNatTimer.cur_loc = 0; in sctp_CheckTimers()
2514 /* ----------------------------------------------------------------------
2516 * ----------------------------------------------------------------------
2547 SctpAliasLog("->%c %s (vt=%u) %d\n", dir, errormsg, ntohl(vtag), error); in logsctperror()
2562 ploc = "TO_LOCAL -"; in logsctpparse()
2565 ploc = "TO_GLOBAL -"; in logsctpparse()
2570 switch (sm->msg) { in logsctpparse()
2606 * @param s Character that indicates the state of processing for this packet
2614 switch (assoc->state) { in logsctpassoc()
2638 s, sp, assoc->exp, inet_ntoa_r(assoc->l_addr, addrbuf), in logsctpassoc()
2639 ntohl(assoc->l_vtag), ntohs(assoc->l_port), in logsctpassoc()
2640 ntohl(assoc->g_vtag), ntohs(assoc->g_port), in logsctpassoc()
2641 assoc->TableRegister); in logsctpassoc()
2643 LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { in logsctpassoc()
2645 inet_ntoa_r(G_Addr->g_addr, addrbuf)); in logsctpassoc()
2659 SctpAliasLog("G->\n"); in logSctpGlobal()
2660 for (i = 0; i < la->sctpNatTableSize; i++) { in logSctpGlobal()
2661 LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) { in logSctpGlobal()
2677 SctpAliasLog("L->\n"); in logSctpLocal()
2678 for (i = 0; i < la->sctpNatTableSize; i++) { in logSctpLocal()
2679 LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) { in logSctpLocal()
2696 SctpAliasLog("t->\n"); in logTimerQ()
2697 for (i = 0; i < SN_TIMER_QUEUE_SIZE; i++) { in logTimerQ()
2698 LIST_FOREACH(assoc, &la->sctpNatTimer.TimerQ[i], timer_Q) { in logTimerQ()
2700 //SctpAliasLog(la->logDesc," l=%d ",i); in logTimerQ()