Files
m241Neelima/components/ip_net2-6.9/ipsctp/src/ipsctp_mib.c
T
2026-07-30 11:19:44 +05:30

780 lines
22 KiB
C

/*
******************************************************************************
* SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipsctp_mib.c,v $ $Revision: 1.11 $
* $Source: /home/interpeak/CVSRoot/ipsctp/src/ipsctp_mib.c,v $
* $Author: kenneth $ $Date: 2010-09-22 18:57:04 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Jiangang Yang <jiangang.yang@windriver.com>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "ipsctp_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_type.h>
#include <ipcom_cstyle.h>
#include <ipcom_clib.h>
#include <ipcom_mib2_api.h>
#include "ipnet_usr_sock.h"
#include "ipsctp.h"
#include "ipsctp_h.h"
#ifdef IPSCTP_MIB
/*
****************************************************************************
* 4 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 5 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 6 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipsctp_mib_stats_lookup
*===========================================================================
* Description: get SCTP global statistics
* Parameters:
* Returns:
*/
IP_PUBLIC int
ipsctp_mib_stats_lookup(Ipsctp_mib_stats **stats)
{
void *suspend_handle;
if (stats == IP_NULL)
return -1;
*stats = ipcom_malloc(sizeof(Ipsctp_mib_stats));
if (*stats == IP_NULL)
return -1;
suspend_handle = ipnet_suspend_stack();
if (suspend_handle == IP_NULL)
{
ipcom_free(*stats);
*stats = IP_NULL;
return -1;
}
**stats = ipsctp->mib_stats;
ipnet_resume_stack(suspend_handle);
return 0;
}
/*
*===========================================================================
* ipsctp_mib_stats_lookup
*===========================================================================
* Description: get SCTP global statistics
* Parameters:
* Returns:
*/
IP_PUBLIC void
ipsctp_mib_stats_get(Ipsctp_mib_stats **stats)
{
if (stats == IP_NULL)
return;
*stats = &ipsctp->mib_stats;
return;
}
/*
*===========================================================================
* ipsctp_mib_params_lookup
*===========================================================================
* Description: get SCTP global parameters
* Parameters:
* Returns:
*/
IP_PUBLIC int
ipsctp_mib_params_lookup(Ipsctp_params **params)
{
void *suspend_handle;
if (params == IP_NULL)
return -1;
*params = ipcom_malloc(sizeof(Ipsctp_params));
if (*params == IP_NULL)
return -1;
suspend_handle = ipnet_suspend_stack();
if (suspend_handle == IP_NULL)
{
ipcom_free(*params);
*params = IP_NULL;
return -1;
}
(*params)->sctpRtoInitial = (Ip_u32)ipcom_sysvar_get_as_int0("ipsctp.Rto.Initial", IPSCTP_RTO_INITIAL_DEFAULT);
(*params)->sctpRtoMax = (Ip_u32)ipcom_sysvar_get_as_int0("ipsctp.Rto.Max", IPSCTP_RTO_MAX_DEFAULT);
(*params)->sctpRtoMin = (Ip_u32)ipcom_sysvar_get_as_int0("ipsctp.Rto.Min", IPSCTP_RTO_MIN_DEFAULT);
(*params)->sctpRtoAlgorithm = (Ip_s32)ipcom_sysvar_get_as_int0("ipsctp.Rto.Algorithm", IPSCTP_RTO_ALGORITHM_DEFAULT);
(*params)->sctpMaxAssocs = (Ip_s32)ipcom_sysvar_get_as_int0("ipsctp.Max.Associations", IPSCTP_MAX_ASSOCIATIONS_DEFAULT);
(*params)->sctpValCookieLife = (Ip_u32)ipcom_sysvar_get_as_int0("ipsctp.Valid.Cookie.Life", IPSCTP_VALID_COOKIE_LIFE_DEFAULT);
(*params)->sctpMaxInitRetr = (Ip_u32)ipcom_sysvar_get_as_int0("ipsctp.Max.Init.Retransmits", IPSCTP_MAX_INIT_RETRANSMITS_DEFAULT);
ipnet_resume_stack(suspend_handle);
return 0;
}
/*
*===========================================================================
* ipsctp_mib_assoc_entry_lookup
*===========================================================================
* Description: get SCTP Association entry.
* Parameters:
* Returns:
*/
IP_PUBLIC Ipsctp_assoc_entry *
ipsctp_mib_assoc_entry_lookup(Ip_u32 vtag,
int /*boolean_t*/ getnext)
{
Ipsctp_tcb *tcb;
Ipsctp_assoc_entry *assoc_entry;
void *suspend_handle;
assoc_entry = ipcom_calloc(1, sizeof(Ipsctp_assoc_entry));
if (assoc_entry == IP_NULL)
return IP_NULL;
ipcom_memset(assoc_entry, 0, sizeof(*assoc_entry));
suspend_handle = ipnet_suspend_stack();
if (suspend_handle == IP_NULL)
{
ipcom_free(assoc_entry);
return IP_NULL;
}
/* find matching TCB from SCTP HashTable */
if (vtag != 0)
{
/* get next tcb from hashtable */
unsigned hash_index;
void *obj = IP_NULL;
Ipsctp_tcb_lookup_key key;
Ipsctp_hash *head = ipsctp->tcb_hashtable;
ipcom_memset(&key, 0, sizeof(key));
key.vtag = vtag;
key.strict_match = 0;
/* find the current one */
#ifdef IPCOM_FORWARDER_NAE
hash_index = ipsctp_hash_key_hash_func(head,&key) % head->size;
#else
hash_index = head->key_hash_func(&key) % head->size;
#endif
while ((hash_index < head->size) && ((obj = head->table[hash_index]) != IP_NULL))
{
#ifdef IPCOM_FORWARDER_NAE
if(ipsctp_hash_obj_key_cmp_func(head,obj,&key))
#else
if (head->obj_key_cmp(obj, &key))
#endif
break;
hash_index = hash_index + 1;
}
if (getnext)
{
/* find the next one */
hash_index = hash_index + 1;
obj = IP_NULL;
while ((hash_index < head->size) && ((obj = head->table[hash_index]) == IP_NULL))
{
hash_index = hash_index + 1;
}
}
tcb = obj;
}
else if(getnext)
{
/* get first tcb from hashtable */
unsigned hash_index = 0;
void *obj = IP_NULL;
Ipsctp_hash *head = ipsctp->tcb_hashtable;
while ((hash_index < head->size) && ((obj = head->table[hash_index]) == IP_NULL))
{
hash_index = hash_index + 1;
}
tcb = obj;
}
else
{
tcb = IP_NULL;
}
if (tcb == IP_NULL)
{
ipcom_free(assoc_entry);
assoc_entry = IP_NULL;
goto exit_func;
}
assoc_entry->sctpAssocId = tcb->my_vtag;
assoc_entry->sctpAssocRemHostName[0] = '\0';
assoc_entry->sctpAssocHeartBeatInterval = tcb->hb_interval;
assoc_entry->sctpAssocLocalPort = tcb->instance->lport;
assoc_entry->sctpAssocRemPort = tcb->rport;
#ifdef IPCOM_USE_INET
if (tcb->primary_transport->paddr.sa.sa_family == IP_AF_INET)
{
assoc_entry->sctpAssocRemPrimAddrType = 1 ;
*(Ip_u32 *)assoc_entry->sctpAssocRemPrimAddr = tcb->primary_transport->paddr.sin.sin_addr.s_addr;
}
#endif
#ifdef IPCOM_USE_INET6
if (tcb->primary_transport->paddr.sa.sa_family == IP_AF_INET6)
{
assoc_entry->sctpAssocRemPrimAddrType = 2 ;
((Ip_u32 *)assoc_entry->sctpAssocRemPrimAddr)[0] = tcb->primary_transport->paddr.sin6.sin6_addr.in6.addr32[0];
((Ip_u32 *)assoc_entry->sctpAssocRemPrimAddr)[1] = tcb->primary_transport->paddr.sin6.sin6_addr.in6.addr32[1];
((Ip_u32 *)assoc_entry->sctpAssocRemPrimAddr)[2] = tcb->primary_transport->paddr.sin6.sin6_addr.in6.addr32[2];
((Ip_u32 *)assoc_entry->sctpAssocRemPrimAddr)[3] = tcb->primary_transport->paddr.sin6.sin6_addr.in6.addr32[3];
}
#endif
assoc_entry->sctpAssocHeartBeatInterval = tcb->hb_interval;
assoc_entry->sctpAssocState = tcb->state;
assoc_entry->sctpAssocInStreams = tcb->streamincnt;
assoc_entry->sctpAssocOutStreams = tcb->streamoutcnt;
assoc_entry->sctpAssocMaxRetr = tcb->max_send_times;
assoc_entry->sctpAssocPrimProcess = 0;
assoc_entry->sctpAssocT1expireds = tcb->cnt_timo_init + tcb->cnt_timo_cookie;
assoc_entry->sctpAssocT2expireds = tcb->cnt_timo_shutdown + tcb->cnt_timo_shutdownack;
assoc_entry->sctpAssocRtxChunks = tcb->marked_retrans;
assoc_entry->sctpAssocStartTime = tcb->start_time;
assoc_entry->sctpAssocDiscontinuityTime = tcb->discontinuity_time;
exit_func:
ipnet_resume_stack(suspend_handle);
return assoc_entry;
}
/*
*===========================================================================
* ipsctp_mib_set_assoc_state
*===========================================================================
* Description: set SCTP Association entry state.
* Parameters:
* Returns:
*/
IP_PUBLIC void
ipsctp_mib_set_assoc_state(Ipsctp_assoc_entry *assoc_entry,
Ip_s32 state)
{
Ipnet_sig *sig;
Ipcom_pipe *pipe;
if (assoc_entry == IP_NULL
|| (state >= IPSCTP_STATE_CLOSED && state < IPSCTP_STATE_MAX))
return;
sig = ipcom_slab_alloc(ipnet->slabs.poll);
if (sig == IP_NULL)
{
return;
}
else
{
ipnet_usr_sock_init_sig(sig, IPNET_SIG_SCTP_SET_STATE);
sig->d.sctp_set_state.vtag = assoc_entry->sctpAssocId;
sig->d.sctp_set_state.state = state;
pipe = ipnet_usr_sock_get_pipe();
ipcom_pipe_send(pipe, sig);
}
return;
}
/*
*===========================================================================
* ipsctp_mib_assoc_local_addr_entry_lookup
*===========================================================================
* Description: get SCTP Association entry.
* Parameters:
* Returns:
*/
IP_PUBLIC Ipsctp_assoc_local_addr_entry *
ipsctp_mib_assoc_local_addr_entry_lookup(Ip_u32 vtag,
Ip_s32 addrType,
Ip_u8 *addr,
int get_next)
{
Ipsctp_tcb *tcb = IP_NULL;
Ipsctp_assoc_local_addr_entry *assoc_addr = IP_NULL;
void *suspend_handle;
unsigned hash_index = 0;
Ipsctp_hash *head = ipsctp->tcb_hashtable;
suspend_handle = ipnet_suspend_stack();
if (suspend_handle == IP_NULL)
return IP_NULL;
if (vtag != 0)
{
void *obj = IP_NULL;
Ipsctp_tcb_lookup_key key;
ipcom_memset(&key, 0, sizeof(key));
key.vtag = vtag;
key.strict_match = 0;
/* find the current one */
#ifdef IPCOM_FORWARDER_NAE
hash_index = ipsctp_hash_key_hash_func(head,&key) % head->size;
#else
hash_index = head->key_hash_func(&key) % head->size;
#endif
while ((hash_index < head->size) && ((obj = head->table[hash_index]) != IP_NULL))
{
#ifdef IPCOM_FORWARDER_NAE
if(ipsctp_hash_obj_key_cmp_func(head,obj,&key))
#else
if (head->obj_key_cmp(obj, &key))
#endif
{
tcb = obj;
break;
}
hash_index = hash_index + 1;
}
}
else if (get_next)
{
/* get first tcb from hashtable */
goto next_tcb_first_addr;
}
else
{
tcb = IP_NULL;
}
if (tcb == IP_NULL)
{
goto exit_func;
}
find_address_entry:
/* get local address entry */
{
Ipsctp_addr *local_addr;
Ipsctp_laddr_entry *laddr_entry;
laddr_entry = (Ipsctp_laddr_entry *)ipcom_list_first(&tcb->instance->laddr_list);
while (laddr_entry)
{
local_addr = &laddr_entry->laddr;
if (addr == IP_NULL)
{
break;
}
#ifdef IPCOM_USE_INET
if (addrType == 1 && local_addr->sa.sa_family == IP_AF_INET
&& (*(Ip_u32 *)addr) == local_addr->sin.sin_addr.s_addr
)
{
break;
}
#endif
#ifdef IPCOM_USE_INET6
if (addrType == 2 && local_addr->sa.sa_family == IP_AF_INET6
&& IP_IN6_ARE_ADDR_EQUAL(addr, &local_addr->sin6.sin6_addr))
{
break;
}
#endif
laddr_entry = (Ipsctp_laddr_entry *)ipcom_list_next(&laddr_entry->next);
}
/*found_addr_entry:*/
if (laddr_entry)
{
if (get_next)
{
laddr_entry = (Ipsctp_laddr_entry *)ipcom_list_next(&laddr_entry->next);
if (laddr_entry != IP_NULL)
{
local_addr = &laddr_entry->laddr;
get_next = 0;
}
}
}
else
{
goto exit_func;
}
if (laddr_entry && local_addr)
{
assoc_addr = ipcom_calloc(1, sizeof(*assoc_addr));
if (assoc_addr == IP_NULL)
{
goto exit_func;
}
#ifdef IPCOM_USE_INET
if (local_addr->sa.sa_family == IP_AF_INET)
{
assoc_addr->sctpAssocLocalAddrType = 1;
*(Ip_u32 *)assoc_addr->sctpAssocLocalAddr = local_addr->sin.sin_addr.s_addr;
}
#endif
#ifdef IPCOM_USE_INET6
if (local_addr->sa.sa_family == IP_AF_INET6)
{
assoc_addr->sctpAssocLocalAddrType = 2;
((Ip_u32 *)assoc_addr->sctpAssocLocalAddr)[0] = local_addr->sin6.sin6_addr.in6.addr32[0];
((Ip_u32 *)assoc_addr->sctpAssocLocalAddr)[1] = local_addr->sin6.sin6_addr.in6.addr32[1];
((Ip_u32 *)assoc_addr->sctpAssocLocalAddr)[2] = local_addr->sin6.sin6_addr.in6.addr32[2];
((Ip_u32 *)assoc_addr->sctpAssocLocalAddr)[3] = local_addr->sin6.sin6_addr.in6.addr32[3];
}
#endif
assoc_addr->sctpAssocLocalAddrStartTime = laddr_entry->start_time;
assoc_addr->sctpAssocId = tcb->my_vtag;
goto exit_func;
}
}
if (!get_next)
goto exit_func;
/* get next tcb from hashtable */
hash_index = hash_index + 1;
next_tcb_first_addr:
tcb = IP_NULL;
while ((hash_index < head->size) && ((tcb = head->table[hash_index]) == IP_NULL))
{
hash_index = hash_index + 1;
}
/* find the first address entry of this TCB */
if (tcb)
{
addr = IP_NULL;
get_next = 0;
addrType = 0;
goto find_address_entry;
}
exit_func:
ipnet_resume_stack(suspend_handle);
return assoc_addr;
}
/*
*===========================================================================
* ipsctp_mib_assoc_rem_addr_entry_lookup
*===========================================================================
* Description: get SCTP Association entry.
* Parameters:
* Returns:
*/
IP_PUBLIC Ipsctp_assoc_rem_addr_entry *
ipsctp_mib_assoc_rem_addr_entry_lookup(Ip_u32 vtag,
Ip_s32 addrType,
Ip_u8 *addr,
int get_next)
{
Ipsctp_tcb *tcb = IP_NULL;
Ipsctp_assoc_rem_addr_entry *assoc_addr = IP_NULL;
void *suspend_handle;
unsigned hash_index = 0;
Ipsctp_hash *head = ipsctp->tcb_hashtable;
suspend_handle = ipnet_suspend_stack();
if (suspend_handle == IP_NULL)
return IP_NULL;
if (vtag != 0)
{
void *obj = IP_NULL;
Ipsctp_tcb_lookup_key key;
ipcom_memset(&key, 0, sizeof(key));
key.vtag = vtag;
key.strict_match = 0;
/* find the current one */
#ifdef IPCOM_FORWARDER_NAE
hash_index = ipsctp_hash_key_hash_func(head,&key) % head->size;
#else
hash_index = head->key_hash_func(&key) % head->size;
#endif
while ((hash_index < head->size) && ((obj = head->table[hash_index]) != IP_NULL))
{
#ifdef IPCOM_FORWARDER_NAE
if(ipsctp_hash_obj_key_cmp_func(head,obj,&key))
#else
if (head->obj_key_cmp(obj, &key))
#endif
{
tcb = obj;
break;
}
hash_index = hash_index + 1;
}
}
else if (get_next)
{
/* get first tcb from hashtable */
goto next_tcb_first_addr;
}
else
{
tcb = IP_NULL;
}
if (tcb == IP_NULL)
{
goto exit_func;
}
find_address_entry:
/* get remote address entry */
{
Ipsctp_addr *rem_addr;
Ipsctp_transport *transport_entry;
transport_entry = (Ipsctp_transport *)ipcom_list_first(&tcb->transport_list);
while (transport_entry)
{
rem_addr = &transport_entry->paddr;
if (addr == IP_NULL)
{
break;
}
#ifdef IPCOM_USE_INET
if (addrType == 1 && rem_addr->sa.sa_family == IP_AF_INET
&& (*(Ip_u32 *)addr) == rem_addr->sin.sin_addr.s_addr
)
{
break;
}
#endif
#ifdef IPCOM_USE_INET6
if (addrType == 2 && rem_addr->sa.sa_family == IP_AF_INET6
&& IP_IN6_ARE_ADDR_EQUAL(addr, &rem_addr->sin6.sin6_addr))
{
break;
}
#endif
transport_entry = (Ipsctp_transport *)ipcom_list_next(&transport_entry->trans_next);
}
/*found_addr_entry:*/
if (transport_entry)
{
if (get_next)
{
transport_entry = (Ipsctp_transport *)ipcom_list_next(&transport_entry->trans_next);
if (transport_entry != IP_NULL)
{
rem_addr = &transport_entry->paddr;
get_next = 0;
}
}
}
else
{
goto exit_func;
}
if (transport_entry && rem_addr)
{
assoc_addr = ipcom_calloc(1, sizeof(*assoc_addr));
if (assoc_addr == IP_NULL)
{
goto exit_func;
}
#ifdef IPCOM_USE_INET
if (rem_addr->sa.sa_family == IP_AF_INET)
{
assoc_addr->sctpAssocRemAddrType = 1;
*(Ip_u32 *)assoc_addr->sctpAssocRemAddr = rem_addr->sin.sin_addr.s_addr;
}
#endif
#ifdef IPCOM_USE_INET6
if (rem_addr->sa.sa_family == IP_AF_INET6)
{
assoc_addr->sctpAssocRemAddrType = 2;
((Ip_u32 *)assoc_addr->sctpAssocRemAddr)[0] = rem_addr->sin6.sin6_addr.in6.addr32[0];
((Ip_u32 *)assoc_addr->sctpAssocRemAddr)[1] = rem_addr->sin6.sin6_addr.in6.addr32[1];
((Ip_u32 *)assoc_addr->sctpAssocRemAddr)[2] = rem_addr->sin6.sin6_addr.in6.addr32[2];
((Ip_u32 *)assoc_addr->sctpAssocRemAddr)[3] = rem_addr->sin6.sin6_addr.in6.addr32[3];
}
#endif
if (IP_BIT_ISSET(transport_entry->state, IPSCTP_ADDR_REACHABLE))
{
assoc_addr->sctpAssocRemAddrActive = 1;
}
else
{
assoc_addr->sctpAssocRemAddrActive = 2;
}
if (IP_BIT_ISSET(transport_entry->state, IPSCTP_ADDR_NOHB))
{
assoc_addr->sctpAssocRemAddrHBActive = 2;
}
else
{
assoc_addr->sctpAssocRemAddrHBActive = 1;
}
assoc_addr->sctpAssocRemAddrRTO = transport_entry->rto;
assoc_addr->sctpAssocRemAddrMaxPathRtx = transport_entry->err_thresh;
assoc_addr->sctpAssocRemAddrRtx = transport_entry->marked_retrans;
assoc_addr->sctpAssocRemAddrStartTime = transport_entry->start_time;
assoc_addr->sctpAssocId = tcb->my_vtag;
goto exit_func;
}
}
if (!get_next)
goto exit_func;
/* get next tcb from hashtable */
hash_index = hash_index + 1;
next_tcb_first_addr:
tcb = IP_NULL;
while ((hash_index < head->size) && ((tcb = head->table[hash_index]) == IP_NULL))
{
hash_index = hash_index + 1;
}
/* find the first address entry of this TCB */
if (tcb)
{
addr = IP_NULL;
get_next = 0;
addrType = 0;
goto find_address_entry;
}
exit_func:
ipnet_resume_stack(suspend_handle);
return assoc_addr;
}
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/