780 lines
22 KiB
C
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
|
|
****************************************************************************
|
|
*/
|