249 lines
7.7 KiB
C
249 lines
7.7 KiB
C
|
|
/*
|
|
******************************************************************************
|
|
* INTERPEAK SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip6_address.c,v $ $Revision: 1.9.16.1 $
|
|
* $Source: /home/interpeak/CVSRoot/ipmip6/src/ipmip6_address.c,v $
|
|
* $Author: jhorteli $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
#include "ipmip6_config.h"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_os.h>
|
|
#include <ipcom_list.h>
|
|
#include <ipcom_sock.h>
|
|
#include <ipcom_sock6.h>
|
|
#include <ipcom_inet.h>
|
|
#include <ipcom_sysvar.h>
|
|
|
|
#include <ipmip.h>
|
|
#include <private/ipmip_util.h>
|
|
|
|
#include "ipmip6_h.h"
|
|
#include <private/ipmip6_address.h>
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmip6_address_apply_prefix
|
|
*===========================================================================
|
|
* Description: Set a prefix in an address.
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipmip6_address_apply_prefix(struct Ip_in6_addr *addr,
|
|
const struct Ip_in6_addr *prefix,
|
|
Ip_u8 prefix_len)
|
|
{
|
|
int blen;
|
|
int plen;
|
|
|
|
/* Convert to bytes. */
|
|
plen = prefix_len >> 3;
|
|
/* Any bits left in the next byte that we need to match? */
|
|
blen = prefix_len & 7;
|
|
|
|
/* Check the whole bytes. */
|
|
ipcom_memcpy(addr, prefix, plen);
|
|
|
|
/* Need to set any trailing bits */
|
|
if (blen)
|
|
{
|
|
/* Create a usable mask */
|
|
blen = (Ip_u8) (0xff00 >> blen);
|
|
|
|
/* Clear the bits belonging to the prefix */
|
|
addr->in6.addr8[plen] &= ~blen;
|
|
|
|
/* OR the bits belonging to the prefix */
|
|
addr->in6.addr8[plen] |= prefix->in6.addr8[plen] & blen;
|
|
}
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmip6_address_unicast_routable
|
|
*===========================================================================
|
|
* Description: Determines whether a given address is unicast routable or not.
|
|
* Parameters: addr - The address to determine its routability.
|
|
* Returns: IP_TRUE if routable, IP_FALSE otherwise.
|
|
*
|
|
*/
|
|
IP_GLOBAL Ip_bool
|
|
ipmip6_address_unicast_routable(struct Ip_in6_addr *addr)
|
|
{
|
|
/* Address must be unicast routable. Site local is OK,
|
|
* but Link Local is not
|
|
* RFC 3775, 3.1 and 4.6 */
|
|
if (IP_IN6_IS_ADDR_LINK_LOCAL(addr) ||
|
|
IP_IN6_IS_ADDR_MULTICAST(addr))
|
|
{
|
|
return IP_FALSE;
|
|
}
|
|
|
|
/* OK Ip address */
|
|
return IP_TRUE;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmip6_address_cmp_prefix2prefix
|
|
*===========================================================================
|
|
* Description: Compare two prefixes.
|
|
* Parameters: prefix1 - A prefix
|
|
* prefix2 - A prefix
|
|
* Returns: IP_TRUE if they are equal, IP_FALSE otherwise.
|
|
*
|
|
*/
|
|
IP_GLOBAL Ip_bool
|
|
ipmip6_address_cmp_prefix2prefix(Ipmip6_address_t *prefix1,
|
|
Ipmip6_address_t *prefix2)
|
|
{
|
|
/* Prefix length mismatch? */
|
|
if (prefix1->len != prefix2->len)
|
|
return IP_FALSE;
|
|
|
|
/* Compare bits */
|
|
return ipmip_util_cmp_bitarray(&prefix1->prefix, &prefix2->prefix, prefix1->len);
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmip6_address_set_prefix
|
|
*===========================================================================
|
|
* Description: Set a prefix in an address.
|
|
* Parameters: data - The address to set the prefix to.
|
|
* prefix - The prefix to set.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipmip6_address_create_prefix(struct Ip_in6_addr *addr,
|
|
const struct Ip_in6_addr *prefix,
|
|
Ip_u8 prefix_len)
|
|
{
|
|
ipcom_memset(addr, 0, sizeof(*addr));
|
|
ipmip6_address_apply_prefix(addr, prefix, prefix_len);
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmip6_address_create_anycast
|
|
*===========================================================================
|
|
* Description: Set a prefix in an address.
|
|
* Parameters: addr - [OUT] The created anycast address
|
|
* prefix - The base prefix
|
|
* anycast - The anycast address.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipmip6_address_create_anycast(Ipmip6_address_t *addr,
|
|
Ipmip6_address_t *prefix,
|
|
Ip_u8 anycast)
|
|
{
|
|
/* Initialize it all to 0xff */
|
|
ipcom_memset(&addr->prefix, 0xff, sizeof(addr->prefix));
|
|
|
|
/* Set the prefix */
|
|
ipmip6_address_apply_prefix(&addr->prefix, &prefix->prefix, prefix->len);
|
|
|
|
/* Store prefix length. */
|
|
addr->len = prefix->len;
|
|
|
|
/* EUI64? */
|
|
if (addr->len == 64)
|
|
{
|
|
/* Clear the global and group bit if we're doing EUI64 */
|
|
addr->prefix.in6.addr8[8] &= 0xfd;
|
|
}
|
|
|
|
/* Set the anycast address. Mask in the highest bit, since anycast
|
|
* address is only 7 bits */
|
|
addr->prefix.in6.addr8[15] = anycast | 0x80;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|