336 lines
10 KiB
C
336 lines
10 KiB
C
/*
|
|
******************************************************************************
|
|
* SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: iplite_ctrl.c,v $ $Revision: 1.31 $
|
|
* $Source: /home/interpeak/CVSRoot/iplite2/src/iplite_ctrl.c,v $
|
|
* $Author: kenneth $
|
|
* $State: Exp $ $Locker: $o
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
* Functions for IP_PUBLIC int iplite_ctrl(struct Iplite_tag *tag) function.
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
#ifndef IPCOM_KERNEL
|
|
#define IPCOM_KERNEL
|
|
#endif
|
|
#include "iplite_config.h"
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_err.h>
|
|
#include <ipcom_clib.h>
|
|
|
|
#include "iplite.h"
|
|
#include "iplite_cmd.h"
|
|
#include "iplite_h.h"
|
|
#include "iplite_sock.h"
|
|
|
|
#ifdef IPCOM_USE_TCP
|
|
#include "iplite_tcp.h"
|
|
#endif
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_STATIC int iplite_ctrl_sock(struct Iplite_tag *tag);
|
|
|
|
#ifdef IPCOM_USE_INET6
|
|
IP_STATIC int iplite_ctrl_ip6_nc(struct Iplite_tag *tag);
|
|
#endif
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* iplite_ctrl_sock
|
|
*===========================================================================
|
|
* Description: Get state of sockets.
|
|
* Parameters: tag - The tag structure fill in.
|
|
* Returns: 0 >= success, <0 error code.
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
iplite_ctrl_sock(struct Iplite_tag *tag)
|
|
{
|
|
struct Iplite_tag_sock_data *sock_tag;
|
|
|
|
sock_tag = (struct Iplite_tag_sock_data*) tag;
|
|
|
|
if (tag->size < sizeof(*sock_tag))
|
|
{
|
|
tag->size = sizeof(*sock_tag);
|
|
return -IP_ERRNO_ENOSPC;
|
|
}
|
|
|
|
if (tag->type == IPLITE_CTRL_NEW_ENUM_SOCK_DATA)
|
|
sock_tag->fd = 0;
|
|
else if (tag->type == IPLITE_CTRL_CONT_ENUM_SOCK_DATA)
|
|
{
|
|
if (sock_tag->fd < 0 || sock_tag->fd >= IPLITE_CONF_MAX_SOCKETS)
|
|
return -IP_ERRNO_EINVAL;
|
|
sock_tag->fd++;
|
|
}
|
|
else
|
|
return -IP_ERRNO_EINVAL;
|
|
|
|
for (; sock_tag->fd < IPLITE_CONF_MAX_SOCKETS; sock_tag->fd++)
|
|
{
|
|
Iplite_socket *sock = iplite.sockets[sock_tag->fd];
|
|
if (sock != IP_NULL)
|
|
{
|
|
sock_tag->domain = sock->ipcom.domain;
|
|
sock_tag->type = sock->ipcom.type;
|
|
sock_tag->protocol = sock->proto;
|
|
#ifdef IPCOM_USE_TCP
|
|
if (sock->proto == IP_IPPROTO_TCP)
|
|
sock_tag->tcp_state = iplite_tcp_get_state(sock);
|
|
#endif
|
|
sock_tag->saddr.in_addr.sin_port = ip_htons(sock->sport);
|
|
sock_tag->daddr.in_addr.sin_port = ip_htons(sock->dport);
|
|
sock_tag->saddr.in_addr.sin_family = (Ip_u8) sock->ipcom.domain;
|
|
sock_tag->daddr.in_addr.sin_family = (Ip_u8) sock->ipcom.domain;
|
|
#ifdef IPCOM_USE_INET
|
|
if (sock->ipcom.domain == IP_AF_INET)
|
|
{
|
|
sock_tag->saddr.in_addr.sin_len = sizeof(sock_tag->saddr.in_addr);
|
|
sock_tag->saddr.in_addr.sin_addr.s_addr = sock->d->ip4.saddr_n;
|
|
sock_tag->daddr.in_addr.sin_len = sizeof(sock_tag->daddr.in_addr);
|
|
sock_tag->daddr.in_addr.sin_addr.s_addr = sock->d->ip4.daddr_n;
|
|
}
|
|
#endif /* IPCOM_USE_INET */
|
|
#ifdef IPCOM_USE_INET6
|
|
if (sock->ipcom.domain == IP_AF_INET6)
|
|
{
|
|
sock_tag->saddr.in6_addr.sin6_len = sizeof(sock_tag->saddr.in6_addr);
|
|
sock_tag->saddr.in6_addr.sin6_addr = sock->d->ip6.saddr;
|
|
sock_tag->daddr.in6_addr.sin6_len = sizeof(sock_tag->daddr.in6_addr);
|
|
sock_tag->daddr.in6_addr.sin6_addr = sock->d->ip6.daddr;
|
|
}
|
|
#endif /* IPCOM_USE_INET6 */
|
|
return IPLITE_CTRL_SUCCESS;
|
|
}
|
|
}
|
|
return IPLITE_CTRL_ENUM_DONE;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* iplite_ctrl_ip6_nc
|
|
*===========================================================================
|
|
* Description: Sets and gets IPv6 neighbor cache entries.
|
|
* Parameters: tag - Contains the information to set/add/delete.
|
|
* Returns: 0 = success, <0 = error.
|
|
*
|
|
*/
|
|
#ifdef IPCOM_USE_INET6
|
|
IP_STATIC int
|
|
iplite_ctrl_ip6_nc(struct Iplite_tag *tag)
|
|
{
|
|
struct Iplite_tag_nc_entry *nc_tag = (struct Iplite_tag_nc_entry*) tag;
|
|
Iplite_ip6_nc_entry *nc;
|
|
Iplite_netif *netif;
|
|
/*Ip_bool prev_entry;*/
|
|
|
|
if (tag->size < sizeof(*nc_tag))
|
|
{
|
|
tag->size = sizeof(*nc_tag);
|
|
return -IP_ERRNO_ENOSPC;
|
|
}
|
|
|
|
switch (tag->type)
|
|
{
|
|
case IPLITE_CTRL_NEW_ENUM_NC_ENTRY :
|
|
/*prev_entry = IP_FALSE;*/
|
|
/* Fall through */
|
|
case IPLITE_CTRL_CONT_ENUM_NC_ENTRY :
|
|
return IPLITE_CTRL_SUCCESS;
|
|
|
|
case IPLITE_CTRL_ADD_NC_ENTRY :
|
|
case IPLITE_CTRL_DEL_NC_ENTRY :
|
|
if (nc_tag->ifindex != 0)
|
|
{
|
|
netif = iplite_if_indextonetif(nc_tag->ifindex);
|
|
if (netif == IP_NULL)
|
|
/* The specified interface does not exist */
|
|
return -IP_ERRNO_ENXIO;
|
|
}
|
|
else
|
|
{
|
|
/* Use the interface specified by the route table */
|
|
netif = IP_NULL;
|
|
}
|
|
nc = iplite_ip6_neighbor_cache_find(netif, &nc_tag->addr.sin6_addr);
|
|
if (nc == IP_NULL)
|
|
return -IP_ERRNO_ENOBUFS;
|
|
|
|
|
|
if(tag->type == IPLITE_CTRL_ADD_NC_ENTRY)
|
|
{
|
|
iplite_ip6_neighbor_cache_update(nc, IPLITE_IP6_ND_REACHABLE,
|
|
IP_SOCKADDR_DL_LLADDR(&nc_tag->link_addr));
|
|
}
|
|
else
|
|
{
|
|
/* Schedule for deletion */
|
|
nc->status = IPLITE_IP6_ND_STALE;
|
|
nc->next_timeout = 0;
|
|
}
|
|
|
|
return IPLITE_CTRL_SUCCESS;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return -IP_ERRNO_EINVAL;
|
|
}
|
|
#endif /* IPCOM_USE_INET6 */
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* iplite_ctrl_islocked
|
|
*===========================================================================
|
|
* Description: SNMP helper function to access ndp tables
|
|
* Code semaphore must be locked.
|
|
* Parameters: tag - The data to set or get.
|
|
* Returns: 0 = succcess, -1 = error
|
|
* (get error code from ipcom_errno)
|
|
*
|
|
*/
|
|
#if defined(IPCOM_USE_MIB2) && defined(IPCOM_USE_INET6)
|
|
IP_GLOBAL int
|
|
iplite_ctrl_islocked(struct Iplite_tag *tag)
|
|
{
|
|
int retval = -IP_ERRNO_EINVAL;
|
|
ip_assert(tag != IP_NULL);
|
|
|
|
if (IP_BIT_ISSET(tag->type, IPLITE_CTRL_NC_ENTRY_BASE))
|
|
retval = iplite_ctrl_ip6_nc(tag);
|
|
|
|
if (retval < 0)
|
|
goto errout;
|
|
return retval;
|
|
|
|
errout:
|
|
return ipcom_errno_set(-retval);
|
|
}
|
|
#endif /* defined(IPCOM_USE_MIB2) && defined(IPCOM_USE_INET6) */
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* iplite_ctrl
|
|
*===========================================================================
|
|
* Description: Sets/gets runtime configuration for IPLITE.
|
|
* Parameters: tag - The data to set or get.
|
|
* Returns: 0 = succcess, -1 = error
|
|
* (get error code from ipcom_errno)
|
|
*
|
|
*/
|
|
IP_PUBLIC int
|
|
iplite_ctrl(struct Iplite_tag *tag)
|
|
{
|
|
int retval;
|
|
|
|
ip_assert(tag != IP_NULL);
|
|
|
|
/* Block all ipcom_socket() calls until the stack is configured */
|
|
while (IP_BIT_ISFALSE(iplite_flags, IPLITE_FLAG_CONFIGURED))
|
|
ipcom_millisleep(100);
|
|
|
|
IPLITE_CODE_LOCK();
|
|
|
|
#ifdef IPCOM_USE_INET6
|
|
if (IP_BIT_ISSET(tag->type, IPLITE_CTRL_NC_ENTRY_BASE))
|
|
retval = iplite_ctrl_ip6_nc(tag);
|
|
else
|
|
#endif
|
|
if (IP_BIT_ISSET(tag->type, IPLITE_CTRL_SOCK_BASE))
|
|
retval = iplite_ctrl_sock(tag);
|
|
else
|
|
retval = -IP_ERRNO_EINVAL;
|
|
|
|
IPLITE_CODE_UNLOCK();
|
|
|
|
if (retval < 0)
|
|
return ipcom_errno_set(-retval);
|
|
return retval;
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|
|
|