original files of m241
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipdhcps6.c,v $ $Revision: 1.43.42.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcps6/src/ipdhcps6.c,v $
|
||||
* $Author: ulf $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcps6_config.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_sock.h>
|
||||
#include <ipcom_sock6.h>
|
||||
#ifdef IPNET
|
||||
#include <ipnet_netif.h>
|
||||
#endif
|
||||
|
||||
#include "ipdhcps6_h.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
Ip_u16 ipdhcps6_client_port = 546;
|
||||
Ip_u16 ipdhcps6_server_port = 547;
|
||||
char *ipdhcps6_log_id = "dhcps6";
|
||||
|
||||
struct Ip_in6_addr ipdhcps6_all_dhcp_relay_agents_and_servers =
|
||||
{
|
||||
{ { 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02 } }
|
||||
};
|
||||
|
||||
struct Ip_in6_addr ipdhcps6_all_dhcp_servers =
|
||||
{
|
||||
{ { 0xFF, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03 } }
|
||||
};
|
||||
|
||||
struct Ipdhcps6_data *ipdhcps6 = IP_NULL;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_get_u16
|
||||
*===========================================================================
|
||||
* Description: Returns the value in host byte order.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_u16
|
||||
ipdhcps6_get_u16(const Ip_u16 *u16)
|
||||
{
|
||||
Ip_u16 val;
|
||||
|
||||
ipcom_memcpy(&val, u16, sizeof(val));
|
||||
return ip_ntohs(val);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_set_u16
|
||||
*===========================================================================
|
||||
* Description: Sets the value in network byte order
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_set_u16(Ip_u16 *u16, Ip_u16 val)
|
||||
{
|
||||
val = ip_htons(val);
|
||||
ipcom_memcpy(u16, &val, sizeof(val));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_get_u16
|
||||
*===========================================================================
|
||||
* Description: Returns the value in host byte order.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipdhcps6_get_u32(const Ip_u32 *u32)
|
||||
{
|
||||
Ip_u32 val;
|
||||
|
||||
ipcom_memcpy(&val, u32, sizeof(val));
|
||||
return ip_ntohl(val);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_set_u16
|
||||
*===========================================================================
|
||||
* Description: Sets the value in network byte order
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_set_u32(Ip_u32 *u32, Ip_u32 val)
|
||||
{
|
||||
val = ip_htonl(val);
|
||||
ipcom_memcpy(u32, &val, sizeof(val));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_delete_hash_db_cb
|
||||
*===========================================================================
|
||||
* Description: Deletes each element in a hash based database.
|
||||
* Parameters: obj - The hash element to delete.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_delete_hash_db_cb(void *obj, void *not_used)
|
||||
{
|
||||
(void) not_used;
|
||||
ipcom_free(obj);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_get_netifbyindex
|
||||
*===========================================================================
|
||||
* Description: Get Ipcom_netif.
|
||||
* Parameters: ifindex - interface index.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ipcom_netif *
|
||||
ipdhcps6_get_netifbyindex(Ip_u32 ifindex)
|
||||
{
|
||||
#ifdef IPNET
|
||||
Ipnet_netif *netif = IP_NULL;
|
||||
|
||||
netif = ipnet_if_indextonetif(IPCOM_VR_ANY, ifindex);
|
||||
|
||||
return (netif ? &netif->ipcom : IP_NULL);
|
||||
#else
|
||||
return IP_NULL; /* current NO support IPLITE */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,893 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Copyright (C) 2007 Wind River Systems
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01a,17jul07,ps initial checkin of dhcpv6 authentication key database module
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_list.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_sysvar.h>
|
||||
|
||||
#include <ipnet.h>
|
||||
#include <ipnet_routesock.h>
|
||||
|
||||
#include "ipdhcps6.h"
|
||||
#include "ipdhcps6_h.h"
|
||||
#include "ipdhcps6_host.h"
|
||||
#include "ipdhcps6_prefix.h"
|
||||
#include "ipdhcps6_subnet.h"
|
||||
#include "ipdhcps6_duid.h"
|
||||
#include "ipdhcps6_cvthex.h"
|
||||
#include "ipdhcps6_authhash.h"
|
||||
|
||||
#define IPDHCPS6_DUID_LL_ACTUALSIZE 10
|
||||
#define IPDHCPS6_DUID_LLT_ACTUALSIZE 14
|
||||
#define IPDHCPS6_DUID_EN_ACTUALSIZE 14
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_authdata_obj_hash
|
||||
*===========================================================================
|
||||
* Description: Returns a hash value based on an authkey value.
|
||||
* Parameters: dbentry - The option to return a hash value for.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
|
||||
IP_STATIC unsigned
|
||||
ipdhcps6_authdb_obj_hash (Ipdhcps6_authkey_dbentry *dbentry)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_DHCPV6_AUTH
|
||||
int i;
|
||||
unsigned char *cptr;
|
||||
|
||||
printf ("ipdhcps6_authdb_obj_hash called: ");
|
||||
|
||||
cptr = (unsigned char *) &(dbentry->duid.data.ll.link_addr);
|
||||
for (i = 0 ; i < 6 ; i++)
|
||||
{ printf ("%2x ", cptr [i]);
|
||||
}
|
||||
printf ("\n");
|
||||
#endif
|
||||
|
||||
return ipcom_hash_update(&(dbentry->duid.data), dbentry->duid.len, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_authdb_key_hash
|
||||
*===========================================================================
|
||||
* Description: Returns a hash value for a DUID key.
|
||||
* Parameters: key - Pointer to the Ipdhcps6_authkey_duid structure
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
|
||||
IP_STATIC unsigned
|
||||
ipdhcps6_authdb_key_hash(Ipdhcps6_duid *key)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_DHCPV6_AUTH
|
||||
int i;
|
||||
unsigned char *cptr;
|
||||
printf ("ipdhcps6_authdb_key_hash called: ");
|
||||
|
||||
cptr = (unsigned char *) &(key->data.ll.link_addr);
|
||||
for (i = 0 ; i < 6 ; i++)
|
||||
{ printf ("%2x ", cptr [i]);
|
||||
}
|
||||
printf ("\n");
|
||||
#endif
|
||||
|
||||
return ipcom_hash_update(&(key->data), key->len, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_authdb_hash_cmp
|
||||
*===========================================================================
|
||||
* Description: Compares a hash object and a hash key for equality.
|
||||
* Parameters: dbentry - An authkey_dbentry structure.
|
||||
* key - A pointer to the search key.
|
||||
* Returns: IP_TRUE if the search key matches the prefix entry.
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_bool
|
||||
ipdhcps6_authdb_hash_cmp(Ipdhcps6_authkey_dbentry *dbentry, Ipdhcps6_duid *key)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_DHCPV6_AUTH
|
||||
printf ("ipdhcps6_authdb_hash_cmp called\n");
|
||||
#endif
|
||||
|
||||
if (dbentry->duid.len != key->len)
|
||||
return IP_FALSE;
|
||||
|
||||
return ipcom_memcmp(&(dbentry->duid.data), &(key->data),
|
||||
key->len) == 0;
|
||||
}
|
||||
|
||||
/*************/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_authtrans_obj_hash
|
||||
*===========================================================================
|
||||
* Description: Returns a hash value based on an authkey value.
|
||||
* Parameters: dbentry - The option to return a hash value for.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
|
||||
IP_STATIC unsigned
|
||||
ipdhcps6_authtrans_obj_hash (Ipdhcps6_authtrans_dbentry *dbentry)
|
||||
{
|
||||
#ifdef DEBUG_DHCPV6_AUTH
|
||||
int i;
|
||||
unsigned char *cptr;
|
||||
|
||||
printf ("ipdhcps6_authtrans_obj_hash called: ");
|
||||
|
||||
cptr = (unsigned char *) &(dbentry->duid.data);
|
||||
|
||||
switch (dbentry->duid.data.generic.content)
|
||||
{ case IPDHCPS6_DUID_LL:
|
||||
printf ("LL content\n");
|
||||
break;
|
||||
|
||||
case IPDHCPS6_DUID_LLT:
|
||||
printf ("LLT content\n");
|
||||
break;
|
||||
|
||||
case IPDHCPS6_DUID_EN:
|
||||
printf ("EN content\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("default case content\n");
|
||||
|
||||
}
|
||||
|
||||
for (i = 0 ; i < dbentry->duid.len ; i++)
|
||||
{ printf ("%2x ", cptr [i]);
|
||||
}
|
||||
printf ("\n");
|
||||
#endif
|
||||
|
||||
return ipcom_hash_update(&(dbentry->duid.data), dbentry->duid.len, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_authtrans_key_hash
|
||||
*===========================================================================
|
||||
* Description: Returns a hash value for a DUID key.
|
||||
* Parameters: key - Pointer to the Ipdhcps6_authkey_duid structure
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
|
||||
IP_STATIC unsigned
|
||||
ipdhcps6_authtrans_key_hash(Ipdhcps6_duid *key)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_DHCPV6_AUTH
|
||||
int i;
|
||||
unsigned char *cptr;
|
||||
printf ("ipdhcps6_authtrans_key_hash called: ");
|
||||
|
||||
cptr = (unsigned char *) &(key->data);
|
||||
|
||||
switch (key->data.generic.content)
|
||||
{ case IPDHCPS6_DUID_LL:
|
||||
printf ("LL content\n");
|
||||
break;
|
||||
|
||||
case IPDHCPS6_DUID_LLT:
|
||||
printf ("LLT content\n");
|
||||
break;
|
||||
|
||||
case IPDHCPS6_DUID_EN:
|
||||
printf ("EN content\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("default case content\n");
|
||||
}
|
||||
|
||||
for (i = 0 ; i < key->len ; i++)
|
||||
{ printf ("%2x ", cptr [i]);
|
||||
}
|
||||
printf ("\n");
|
||||
#endif
|
||||
|
||||
return ipcom_hash_update(&(key->data), key->len, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_authtrans_hash_cmp
|
||||
*===========================================================================
|
||||
* Description: Compares a hash object and a hash key for equality.
|
||||
* Parameters: prefix - A prefix structure.
|
||||
* key - A pointer to the search key.
|
||||
* Returns: IP_TRUE if the search key matches the prefix entry.
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_bool
|
||||
ipdhcps6_authtrans_hash_cmp(Ipdhcps6_authtrans_dbentry *dbentry, Ipdhcps6_duid *key)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_DHCPV6_AUTH
|
||||
printf ("ipdhcps6_authtrans_hash_cmp called\n");
|
||||
#endif
|
||||
|
||||
if (dbentry->duid.len != key->len)
|
||||
return IP_FALSE;
|
||||
|
||||
return ipcom_memcmp(&(dbentry->duid.data), &(key->data),
|
||||
key->len) == 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
IP_STATIC Ipcom_hash *client_authkey_db;
|
||||
IP_STATIC Ipcom_hash *client_transaction_db;
|
||||
|
||||
IP_GLOBAL Ipcom_hash *
|
||||
ipdhcps6_authdb_hash_create(void)
|
||||
{
|
||||
return ipcom_hash_new ((Ipcom_hash_obj_func) ipdhcps6_authdb_obj_hash,
|
||||
(Ipcom_hash_key_func) ipdhcps6_authdb_key_hash,
|
||||
(Ipcom_hash_cmp_func) ipdhcps6_authdb_hash_cmp);
|
||||
}
|
||||
|
||||
IP_GLOBAL Ipcom_hash *
|
||||
ipdhcps6_authtrans_hash_create(void)
|
||||
{
|
||||
return ipcom_hash_new ((Ipcom_hash_obj_func) ipdhcps6_authtrans_obj_hash,
|
||||
(Ipcom_hash_key_func) ipdhcps6_authtrans_key_hash,
|
||||
(Ipcom_hash_cmp_func) ipdhcps6_authtrans_hash_cmp);
|
||||
}
|
||||
|
||||
IP_GLOBAL Ipdhcps6_duid *ipdhcps6_authdb_create_ll_duid (int len, Ip_u16 hwtype, Ip_u8 *link_addr)
|
||||
{
|
||||
Ipdhcps6_duid *retval = (Ipdhcps6_duid *)
|
||||
ipcom_malloc (sizeof (struct Ipdhcps6_duid_struct));
|
||||
|
||||
(void)len;
|
||||
|
||||
if (IP_NULL == retval)
|
||||
return IP_NULL;
|
||||
|
||||
retval->len = IPDHCPS6_DUID_LL_ACTUALSIZE;
|
||||
retval->data.ll.content = IPDHCPS6_DUID_LL;
|
||||
retval->data.ll.hardware_type = hwtype;
|
||||
|
||||
ipcom_memcpy (retval->data.ll.link_addr, link_addr, 6);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
IP_GLOBAL Ip_err ipdhcps6_add_client_authkey (Ipdhcps6_duid *client_duid,
|
||||
Ip_u8 *key, int keylen)
|
||||
{
|
||||
|
||||
Ip_u16 duid_content;
|
||||
|
||||
Ipdhcps6_authkey_dbentry *new_authdb_entry = (Ipdhcps6_authkey_dbentry *)
|
||||
ipcom_malloc (sizeof (struct Ipdhcps6_authkey_dbentry));
|
||||
|
||||
if (IP_NULL == new_authdb_entry)
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
new_authdb_entry->secret.key = (Ip_u8 *) ipcom_malloc ((Ip_size_t)keylen);
|
||||
if (IP_NULL == new_authdb_entry->secret.key)
|
||||
{ ipcom_free (new_authdb_entry);
|
||||
IPCOM_LOG0 (DEBUG, "ipdhcps6_add_client_authkey: no memory!\n");
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy in key
|
||||
*/
|
||||
ipcom_memcpy (new_authdb_entry->secret.key, key, (Ip_size_t)keylen);
|
||||
new_authdb_entry->secret.len = keylen;
|
||||
|
||||
/*
|
||||
* copy in duid data
|
||||
*/
|
||||
|
||||
new_authdb_entry->duid.len = client_duid->len;
|
||||
duid_content = client_duid->data.ll.content;
|
||||
|
||||
switch (duid_content)
|
||||
{
|
||||
case IPDHCPS6_DUID_LL:
|
||||
new_authdb_entry->duid.data.ll.hardware_type = client_duid->data.ll.hardware_type;
|
||||
new_authdb_entry->duid.data.ll.content = IPDHCPS6_DUID_LL;
|
||||
|
||||
ipcom_memcpy (new_authdb_entry->duid.data.ll.link_addr,
|
||||
client_duid->data.ll.link_addr, 6);
|
||||
break;
|
||||
|
||||
case IPDHCPS6_DUID_EN: /* not yet implemented */
|
||||
case IPDHCPS6_DUID_LLT: /* not yet implemented */
|
||||
default:
|
||||
/* Coverity defect fix for RESOURCE_LEAK */
|
||||
ipcom_free( new_authdb_entry->secret.key);
|
||||
ipcom_free (new_authdb_entry);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if (IPCOM_SUCCESS != ipcom_hash_add (client_authkey_db, new_authdb_entry))
|
||||
{
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
IP_GLOBAL Ip_err ipdhcps6_client_wants_auth (union Ipdhcps6_duid_data *client, int len)
|
||||
{
|
||||
Ip_u16 client_duid_content;
|
||||
Ipdhcps6_authtrans_dbentry *client_dbentry = IP_NULL;
|
||||
|
||||
client_dbentry = (Ipdhcps6_authtrans_dbentry *)
|
||||
ipcom_malloc (sizeof (struct Ipdhcps6_authtrans_dbentry));
|
||||
if (IP_NULL == client_dbentry)
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
|
||||
client_duid_content = ip_ntohs (client->generic.content);
|
||||
|
||||
switch (client_duid_content)
|
||||
{ case IPDHCPS6_DUID_LLT:
|
||||
client_dbentry->duid.len = IPDHCPS6_DUID_LLT_ACTUALSIZE;
|
||||
client_dbentry->duid.data.llt.content = IPDHCPS6_DUID_LLT;
|
||||
client_dbentry->duid.data.llt.hardware_type = client->llt.hardware_type;
|
||||
client_dbentry->duid.data.llt.time = client->llt.time;
|
||||
ipcom_memcpy (client_dbentry->duid.data.llt.link_addr,
|
||||
client->llt.link_addr, 6);
|
||||
break;
|
||||
|
||||
case IPDHCPS6_DUID_EN:
|
||||
|
||||
/*
|
||||
* FIXME
|
||||
* using the duid union structure we have, we know we will have
|
||||
* enough space to copy in the first 8 bytes of the enterprise
|
||||
* ID. This may or may not be enough to be unique; we'll need
|
||||
* to revisit this later. Look at "len" to see if we were given
|
||||
* less than 8 bytes for the ID; if so, only copy the bytes
|
||||
* given.
|
||||
*/
|
||||
|
||||
client_dbentry->duid.len =
|
||||
(Ip_u16)(len < IPDHCPS6_DUID_EN_ACTUALSIZE ?
|
||||
len : IPDHCPS6_DUID_EN_ACTUALSIZE);
|
||||
|
||||
client_dbentry->duid.data.en.content = IPDHCPS6_DUID_EN;
|
||||
client_dbentry->duid.data.en.enterprise_number_1 =
|
||||
client->en.enterprise_number_1;
|
||||
client_dbentry->duid.data.en.enterprise_number_2 =
|
||||
client->en.enterprise_number_2;
|
||||
|
||||
ipcom_memcpy (client_dbentry->duid.data.en.id,
|
||||
client->en.id, (Ip_size_t)(8 - (IPDHCPS6_DUID_EN_ACTUALSIZE - len)));
|
||||
|
||||
break;
|
||||
|
||||
case IPDHCPS6_DUID_LL:
|
||||
client_dbentry->duid.len = IPDHCPS6_DUID_LL_ACTUALSIZE;
|
||||
client_dbentry->duid.data.ll.content = IPDHCPS6_DUID_LL;
|
||||
client_dbentry->duid.data.ll.hardware_type = client->ll.hardware_type;
|
||||
ipcom_memcpy (client_dbentry->duid.data.ll.link_addr,
|
||||
client->ll.link_addr, 6);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* set replay counters
|
||||
*/
|
||||
|
||||
client_dbentry->server_replay1 = 0xdeadbeef;
|
||||
client_dbentry->server_replay2 = 0x0;
|
||||
client_dbentry->client_replay1 = 0x0;
|
||||
client_dbentry->client_replay2 = 0x0;
|
||||
|
||||
if (IPCOM_SUCCESS != ipcom_hash_add (client_transaction_db, client_dbentry))
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
IP_GLOBAL Ip_err ipdhcps6_client_no_auth (union Ipdhcps6_duid_data *client, int len)
|
||||
{
|
||||
|
||||
Ip_u16 client_duid_content;
|
||||
Ipdhcps6_duid client_dbkey;
|
||||
Ipdhcps6_authkey_dbentry *client_dbobj = IP_NULL;
|
||||
|
||||
client_duid_content = ip_ntohs (client->generic.content);
|
||||
|
||||
switch (client_duid_content)
|
||||
{ case IPDHCPS6_DUID_LLT:
|
||||
client_dbkey.len = IPDHCPS6_DUID_LLT_ACTUALSIZE;
|
||||
client_dbkey.data.llt.content = IPDHCPS6_DUID_LLT;
|
||||
client_dbkey.data.llt.hardware_type = client->llt.hardware_type;
|
||||
client_dbkey.data.llt.time = client->llt.time;
|
||||
ipcom_memcpy (client_dbkey.data.llt.link_addr,
|
||||
client->llt.link_addr, 6);
|
||||
break;
|
||||
|
||||
case IPDHCPS6_DUID_EN:
|
||||
/*
|
||||
* FIXME
|
||||
* using the duid union structure we have, we know we will have
|
||||
* enough space to copy in the first 8 bytes of the enterprise
|
||||
* ID. This may or may not be enough to be unique; we'll need
|
||||
* to revisit this later. Look at "len" to see if we were given
|
||||
* less than 8 bytes for the ID; if so, only copy the bytes
|
||||
* given.
|
||||
*/
|
||||
|
||||
client_dbkey.len =
|
||||
(Ip_u16)(len < IPDHCPS6_DUID_EN_ACTUALSIZE ?
|
||||
len : IPDHCPS6_DUID_EN_ACTUALSIZE);
|
||||
|
||||
client_dbkey.data.en.content = IPDHCPS6_DUID_EN;
|
||||
client_dbkey.data.en.enterprise_number_1 =
|
||||
client->en.enterprise_number_1;
|
||||
client_dbkey.data.en.enterprise_number_2 =
|
||||
client->en.enterprise_number_2;
|
||||
|
||||
ipcom_memcpy (client_dbkey.data.en.id,
|
||||
client->en.id, (Ip_size_t)(8 - (IPDHCPS6_DUID_EN_ACTUALSIZE - len)));
|
||||
|
||||
break;
|
||||
|
||||
case IPDHCPS6_DUID_LL:
|
||||
client_dbkey.len = IPDHCPS6_DUID_LL_ACTUALSIZE;
|
||||
client_dbkey.data.ll.content = IPDHCPS6_DUID_LL;
|
||||
client_dbkey.data.ll.hardware_type = client->ll.hardware_type;
|
||||
ipcom_memcpy (client_dbkey.data.ll.link_addr,
|
||||
client->ll.link_addr, 6);
|
||||
break;
|
||||
|
||||
default:
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
client_dbobj = ipcom_hash_get (client_transaction_db, &client_dbkey);
|
||||
if (IP_NULL == client_dbobj)
|
||||
{
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
ipcom_hash_remove (client_transaction_db, client_dbobj);
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
IP_GLOBAL Ipdhcps6_authtrans_dbentry *
|
||||
ipdhcps6_client_requested_auth (union Ipdhcps6_duid_data *client, int len)
|
||||
{
|
||||
Ip_u16 client_duid_content;
|
||||
Ipdhcps6_duid client_dbkey;
|
||||
Ipdhcps6_authtrans_dbentry *client_dbobj = IP_NULL;
|
||||
|
||||
client_duid_content = ip_ntohs (client->generic.content);
|
||||
|
||||
switch (client_duid_content)
|
||||
{ case IPDHCPS6_DUID_LLT:
|
||||
client_dbkey.len = IPDHCPS6_DUID_LLT_ACTUALSIZE;
|
||||
client_dbkey.data.llt.content = IPDHCPS6_DUID_LLT;
|
||||
client_dbkey.data.llt.hardware_type = client->llt.hardware_type;
|
||||
client_dbkey.data.llt.time = client->llt.time;
|
||||
ipcom_memcpy (client_dbkey.data.llt.link_addr,
|
||||
client->llt.link_addr, 6);
|
||||
break;
|
||||
|
||||
case IPDHCPS6_DUID_EN:
|
||||
/*
|
||||
* FIXME
|
||||
* using the duid union structure we have, we know we will have
|
||||
* enough space to copy in the first 8 bytes of the enterprise
|
||||
* ID. This may or may not be enough to be unique; we'll need
|
||||
* to revisit this later. Look at "len" to see if we were given
|
||||
* less than 8 bytes for the ID; if so, only copy the bytes
|
||||
* given.
|
||||
*/
|
||||
|
||||
client_dbkey.len =
|
||||
(Ip_u16)(len < IPDHCPS6_DUID_EN_ACTUALSIZE ?
|
||||
len : IPDHCPS6_DUID_EN_ACTUALSIZE);
|
||||
|
||||
client_dbkey.data.en.content = IPDHCPS6_DUID_EN;
|
||||
client_dbkey.data.en.enterprise_number_1 =
|
||||
client->en.enterprise_number_1;
|
||||
client_dbkey.data.en.enterprise_number_2 =
|
||||
client->en.enterprise_number_2;
|
||||
|
||||
ipcom_memcpy (client_dbkey.data.en.id,
|
||||
client->en.id, (Ip_size_t)(8 - (IPDHCPS6_DUID_EN_ACTUALSIZE - len)));
|
||||
|
||||
break;
|
||||
|
||||
case IPDHCPS6_DUID_LL:
|
||||
client_dbkey.len = IPDHCPS6_DUID_LL_ACTUALSIZE;
|
||||
client_dbkey.data.ll.content = IPDHCPS6_DUID_LL;
|
||||
client_dbkey.data.ll.hardware_type = client->ll.hardware_type;
|
||||
ipcom_memcpy (client_dbkey.data.ll.link_addr,
|
||||
client->ll.link_addr, 6);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* invalid DUID type; ignore it and return failure */
|
||||
return IP_NULL;
|
||||
}
|
||||
|
||||
client_dbobj = ipcom_hash_get (client_transaction_db, &client_dbkey);
|
||||
if (IP_NULL == client_dbobj)
|
||||
return IP_NULL;
|
||||
|
||||
return client_dbobj;
|
||||
|
||||
}
|
||||
|
||||
#define MAX_IPDHCPV6_AUTH_KEY_SIZE 128
|
||||
|
||||
IP_STATIC int authKeyInitialized = 0;
|
||||
IP_STATIC int authRealmInitialized = 0;
|
||||
|
||||
IP_STATIC Ip_u8 authKeyFromSysVars [256];
|
||||
IP_STATIC Ip_size_t authKeyLenFromSysVars = 0;
|
||||
|
||||
IP_STATIC Ip_u8 authKey [128];
|
||||
IP_STATIC Ip_size_t authKeyLen = 0;
|
||||
|
||||
IP_STATIC Ip_u8 authRealmFromSysVars [128];
|
||||
IP_STATIC Ip_size_t authRealmLenFromSysVars = 0;
|
||||
|
||||
|
||||
IP_STATIC Ip_err ipdhcps6_set_default_auth_key_from_sysvars (void)
|
||||
{
|
||||
|
||||
authKeyLenFromSysVars = sizeof (authKeyFromSysVars);
|
||||
|
||||
(void)ipcom_sysvar_get("ipdhcps6.authkey", (char *) authKeyFromSysVars,
|
||||
&authKeyLenFromSysVars);
|
||||
|
||||
/*
|
||||
* check if the value we read is a valid hex key; convert to
|
||||
* a key buffer.
|
||||
*/
|
||||
|
||||
if (ipdhcps6_check_is_hex_string ((char *) authKeyFromSysVars))
|
||||
{
|
||||
/* we need at least 4 characters to proceed here; "0x--" or more */
|
||||
if (authKeyLenFromSysVars >= 4)
|
||||
{ char *kptr = (char *) authKeyFromSysVars;
|
||||
kptr += 2; /* get past leading "0x" */
|
||||
|
||||
authKeyLen = (authKeyLenFromSysVars - 2) / 2;
|
||||
if (! ipdhcps6_cvt_hex_to_membuf (kptr, authKey, (int)authKeyLen) )
|
||||
{ authKeyLen = 0;
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
authKeyLen = 0;
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
authKeyInitialized = 1;
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
IP_GLOBAL Ip_err ipdhcps6_set_default_auth_key (char *authkey)
|
||||
{
|
||||
Ip_size_t auth_key_len;
|
||||
|
||||
auth_key_len = strlen (authkey);
|
||||
|
||||
if (auth_key_len > ((MAX_IPDHCPV6_AUTH_KEY_SIZE + 1) * 2))
|
||||
{ return IPCOM_ERR_FAILED; /* given key is too large */
|
||||
}
|
||||
|
||||
/*
|
||||
* check if the value we read is a valid hex key; convert to
|
||||
* a key buffer.
|
||||
*/
|
||||
|
||||
if (ipdhcps6_check_is_hex_string (authkey))
|
||||
{
|
||||
/* we need at least 4 characters to proceed here; "0x--" or more */
|
||||
if (auth_key_len >= 4)
|
||||
{ char *kptr = authkey;
|
||||
kptr += 2; /* get past leading "0x" */
|
||||
|
||||
authKeyLen = (auth_key_len - 2) / 2;
|
||||
if (! ipdhcps6_cvt_hex_to_membuf (kptr, authKey, (int)authKeyLen) )
|
||||
{ authKeyLen = 0;
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
authKeyLen = 0;
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
authKeyInitialized = 1;
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
IP_GLOBAL Ip_err ipdhcps6_get_default_auth_key (Ip_size_t *len, Ip_u8 **key)
|
||||
{
|
||||
if (authKeyInitialized)
|
||||
{
|
||||
*len = authKeyLen;
|
||||
*key = authKey;
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IPCOM_SUCCESS == ipdhcps6_set_default_auth_key_from_sysvars ())
|
||||
{
|
||||
*len = authKeyLen;
|
||||
*key = authKey;
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
}
|
||||
*key = IP_NULL;
|
||||
*len = 0;
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
}
|
||||
|
||||
IP_STATIC Ip_err ipdhcps6_set_auth_realm_from_sysvars ()
|
||||
{
|
||||
|
||||
authRealmLenFromSysVars = sizeof (authRealmFromSysVars);
|
||||
|
||||
if (ipcom_sysvar_get("ipdhcps6.authrealm", (char *) authRealmFromSysVars,
|
||||
&authRealmLenFromSysVars) == IP_NULL)
|
||||
{
|
||||
/* Don't set it if we dont got it */
|
||||
authRealmLenFromSysVars = 0;
|
||||
}
|
||||
|
||||
|
||||
if (authRealmLenFromSysVars > 0)
|
||||
{
|
||||
authRealmInitialized = 1;
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
IP_GLOBAL Ip_err ipdhcps6_set_auth_realm (char *auth_realm)
|
||||
{
|
||||
Ip_size_t realm_len;
|
||||
|
||||
authRealmInitialized = 0;
|
||||
|
||||
realm_len = strlen (auth_realm);
|
||||
|
||||
if ((unsigned)realm_len > (sizeof (authRealmFromSysVars) - 1))
|
||||
{ /* passed in realm is too large. */
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
strncpy ((char *) authRealmFromSysVars, auth_realm, realm_len);
|
||||
authRealmFromSysVars [realm_len] = '\0';
|
||||
authRealmLenFromSysVars = realm_len;
|
||||
|
||||
authRealmInitialized = 1;
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
IP_GLOBAL Ip_err ipdhcps6_get_auth_realm (Ip_size_t *len, Ip_u8 **realm)
|
||||
{
|
||||
|
||||
if (authRealmInitialized)
|
||||
{ *len = authRealmLenFromSysVars;
|
||||
*realm = authRealmFromSysVars;
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
else
|
||||
{ if (IPCOM_SUCCESS == ipdhcps6_set_auth_realm_from_sysvars ())
|
||||
{
|
||||
*len = authRealmLenFromSysVars;
|
||||
*realm = authRealmFromSysVars;
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
*len = 0;
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
IP_GLOBAL void ipdhcps6_authdb_init (void)
|
||||
{
|
||||
client_authkey_db = ipdhcps6_authdb_hash_create ();
|
||||
client_transaction_db = ipdhcps6_authtrans_hash_create ();
|
||||
}
|
||||
|
||||
|
||||
IP_GLOBAL Ip_err ipdhcps6_find_key_for_client (union Ipdhcps6_duid_data *client,
|
||||
int duid_len,
|
||||
Ip_u8 **key, Ip_size_t *key_len)
|
||||
{
|
||||
|
||||
Ip_u16 client_duid_content;
|
||||
Ipdhcps6_duid client_dbkey;
|
||||
Ipdhcps6_authkey_dbentry *client_dbobj = IP_NULL;
|
||||
|
||||
client_duid_content = ip_ntohs (client->generic.content);
|
||||
|
||||
switch (client_duid_content)
|
||||
{ case IPDHCPS6_DUID_LLT:
|
||||
client_dbkey.len = IPDHCPS6_DUID_LL_ACTUALSIZE;
|
||||
client_dbkey.data.ll.content = IPDHCPS6_DUID_LL;
|
||||
client_dbkey.data.ll.hardware_type = client->llt.hardware_type;
|
||||
ipcom_memcpy (client_dbkey.data.ll.link_addr,
|
||||
client->llt.link_addr, 6);
|
||||
break;
|
||||
|
||||
case IPDHCPS6_DUID_EN:
|
||||
/*
|
||||
* FIXME
|
||||
* using the duid union structure we have, we know we will have
|
||||
* enough space to copy in the first 8 bytes of the enterprise
|
||||
* ID. This may or may not be enough to be unique; we'll need
|
||||
* to revisit this later. Look at "len" to see if we were given
|
||||
* less than 8 bytes for the ID; if so, only copy the bytes
|
||||
* given.
|
||||
*/
|
||||
|
||||
client_dbkey.len =
|
||||
(Ip_u16)(duid_len < IPDHCPS6_DUID_EN_ACTUALSIZE ?
|
||||
duid_len : IPDHCPS6_DUID_EN_ACTUALSIZE);
|
||||
|
||||
client_dbkey.data.en.content = IPDHCPS6_DUID_EN;
|
||||
client_dbkey.data.en.enterprise_number_1 =
|
||||
client->en.enterprise_number_1;
|
||||
client_dbkey.data.en.enterprise_number_2 =
|
||||
client->en.enterprise_number_2;
|
||||
|
||||
ipcom_memcpy (client_dbkey.data.en.id,
|
||||
client->en.id, (Ip_size_t)(8 - (IPDHCPS6_DUID_EN_ACTUALSIZE - duid_len)));
|
||||
break;
|
||||
|
||||
case IPDHCPS6_DUID_LL:
|
||||
client_dbkey.len = IPDHCPS6_DUID_LL_ACTUALSIZE;
|
||||
client_dbkey.data.ll.content = IPDHCPS6_DUID_LL;
|
||||
client_dbkey.data.ll.hardware_type = client->ll.hardware_type;
|
||||
ipcom_memcpy (client_dbkey.data.ll.link_addr,
|
||||
client->ll.link_addr, 6);
|
||||
break;
|
||||
|
||||
default:
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
client_dbobj = ipcom_hash_get (client_authkey_db, &client_dbkey);
|
||||
if (IP_NULL == client_dbobj)
|
||||
{
|
||||
/* use default system auth key */
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use client specific key */
|
||||
*key_len = (Ip_size_t)client_dbobj->secret.len;
|
||||
*key = client_dbobj->secret.key;
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
}
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK API HEADER FILE
|
||||
*
|
||||
* Copyright 2007 Wind River Systems
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01a,17jul07,ps initial checkin of dhcpv6 authentication key database module
|
||||
*/
|
||||
|
||||
|
||||
#ifndef IPDHCPS6_AUTHHASH_H
|
||||
#define IPDHCPS6_AUTHHASH_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcps6_config.h"
|
||||
#include "ipdhcps6_duid.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_hash.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Ipdhcps6_authkey_secret
|
||||
{
|
||||
int len;
|
||||
Ip_u8 *key;
|
||||
};
|
||||
typedef struct Ipdhcps6_authkey_secret Ipdhcps6_authkey_secret;
|
||||
|
||||
|
||||
struct Ipdhcps6_authkey_duid
|
||||
{
|
||||
int len;
|
||||
Ip_u8 *duid;
|
||||
};
|
||||
typedef struct Ipdhcps6_authkey_duid Ipdhcps6_authkey_duid;
|
||||
|
||||
struct Ipdhcps6_authkey_dbentry
|
||||
{
|
||||
Ipdhcps6_duid duid;
|
||||
Ipdhcps6_authkey_secret secret;
|
||||
};
|
||||
typedef struct Ipdhcps6_authkey_dbentry Ipdhcps6_authkey_dbentry;
|
||||
|
||||
struct Ipdhcps6_authtrans_dbentry
|
||||
{
|
||||
Ipdhcps6_duid duid;
|
||||
Ip_u16 flags;
|
||||
Ip_u32 client_replay1;
|
||||
Ip_u32 client_replay2;
|
||||
Ip_u32 server_replay1;
|
||||
Ip_u32 server_replay2;
|
||||
|
||||
};
|
||||
typedef struct Ipdhcps6_authtrans_dbentry Ipdhcps6_authtrans_dbentry;
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ipdhcps6_duid *ipdhcps6_authdb_create_ll_duid (int len, Ip_u16 hwtype, Ip_u8 *link_addr);
|
||||
|
||||
IP_GLOBAL Ip_err ipdhcps6_client_wants_auth (union Ipdhcps6_duid_data *client, int len);
|
||||
|
||||
IP_GLOBAL Ip_err ipdhcps6_client_no_auth (union Ipdhcps6_duid_data *client, int len);
|
||||
|
||||
IP_GLOBAL Ipdhcps6_authtrans_dbentry
|
||||
*ipdhcps6_client_requested_auth (union Ipdhcps6_duid_data *client, int len);
|
||||
|
||||
IP_GLOBAL Ip_err ipdhcps6_get_auth_realm (Ip_size_t *len, Ip_u8 **realm);
|
||||
|
||||
IP_GLOBAL Ip_err ipdhcps6_get_default_auth_key (Ip_size_t *len, Ip_u8 **key);
|
||||
|
||||
IP_GLOBAL Ip_err ipdhcps6_find_key_for_client (union Ipdhcps6_duid_data *client,
|
||||
int duid_len,
|
||||
Ip_u8 **key, Ip_size_t *key_len);
|
||||
|
||||
IP_GLOBAL Ipcom_hash *ipdhcps6_authdb_hash_create(void);
|
||||
IP_GLOBAL Ipcom_hash *ipdhcps6_authtrans_hash_create(void);
|
||||
IP_GLOBAL Ip_err ipdhcps6_add_client_authkey (Ipdhcps6_duid *client_duid,Ip_u8 *key, int keylen);
|
||||
IP_GLOBAL Ip_err ipdhcps6_set_default_auth_key (char *authkey);
|
||||
IP_GLOBAL Ip_err ipdhcps6_set_auth_realm (char *auth_realm);
|
||||
IP_GLOBAL void ipdhcps6_authdb_init (void);
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK INTERNAL API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipdhcps6_cmd.h,v $ $Revision: 1.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcps6/src/ipdhcps6_cmd.h,v $
|
||||
* $Author: kenneth $ $Date: 2005-05-09 18:58:10 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* Copyright Interpeak AB 2000-2004 <www.interpeak.se>. All rights reserved.
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPDHCPS6_CMD_H
|
||||
#define IPDHCPS6_CMD_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/* Shell commands for DHCPv6 server */
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcps6_config.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_os.h>
|
||||
|
||||
#include "ipdhcps6_cmd.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL int ipdhcps6_cmd_dhcps6(int argc, char **argv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Copyright (C) 2007 Wind River Systems
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01a,17jul07,ps initial checkin of dhcpv6 authentication key database module
|
||||
01b,20jul07,ten Remove unused local variable
|
||||
*/
|
||||
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
|
||||
#include "ipdhcps6_cvthex.h"
|
||||
|
||||
/*
|
||||
* convert two hex digits into an unsigned char value.
|
||||
* returns: 1 if successful, 0 if not
|
||||
*/
|
||||
|
||||
IP_STATIC int ipdhcps6_cvt_two_hexdigits_to_unsigned (char *str, unsigned char *result)
|
||||
{
|
||||
unsigned char r;
|
||||
switch (*str)
|
||||
{ case '0': r = 0x0; break;
|
||||
case '1': r = 0x1; break;
|
||||
case '2': r = 0x2; break;
|
||||
case '3': r = 0x3; break;
|
||||
case '4': r = 0x4; break;
|
||||
case '5': r = 0x5; break;
|
||||
case '6': r = 0x6; break;
|
||||
case '7': r = 0x7; break;
|
||||
case '8': r = 0x8; break;
|
||||
case '9': r = 0x9; break;
|
||||
|
||||
case 'A':
|
||||
case 'a':
|
||||
r = 0xA; break;
|
||||
case 'B':
|
||||
case 'b':
|
||||
r = 0xB; break;
|
||||
case 'C':
|
||||
case 'c':
|
||||
r = 0xC; break;
|
||||
case 'D':
|
||||
case 'd':
|
||||
r = 0xD; break;
|
||||
case 'E':
|
||||
case 'e':
|
||||
r = 0xE; break;
|
||||
case 'F':
|
||||
case 'f':
|
||||
r = 0xF; break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
str++;
|
||||
r <<= 4;
|
||||
switch (*str)
|
||||
{ case '0': r += 0x0; break;
|
||||
case '1': r += 0x1; break;
|
||||
case '2': r += 0x2; break;
|
||||
case '3': r += 0x3; break;
|
||||
case '4': r += 0x4; break;
|
||||
case '5': r += 0x5; break;
|
||||
case '6': r += 0x6; break;
|
||||
case '7': r += 0x7; break;
|
||||
case '8': r += 0x8; break;
|
||||
case '9': r += 0x9; break;
|
||||
|
||||
case 'A':
|
||||
case 'a':
|
||||
r += 0xA; break;
|
||||
case 'B':
|
||||
case 'b':
|
||||
r += 0xB; break;
|
||||
case 'C':
|
||||
case 'c':
|
||||
r += 0xC; break;
|
||||
case 'D':
|
||||
case 'd':
|
||||
r += 0xD; break;
|
||||
case 'E':
|
||||
case 'e':
|
||||
r += 0xE; break;
|
||||
case 'F':
|
||||
case 'f':
|
||||
r += 0xF; break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
*result = r;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a hex digit string into a buffer of unsigned chars.
|
||||
* returns 1 if successful, 0 if not.
|
||||
*/
|
||||
|
||||
int ipdhcps6_cvt_hex_to_membuf (char *str, unsigned char *buf, int len)
|
||||
{
|
||||
char *cptr;
|
||||
|
||||
if (ipcom_strlen (str) < (unsigned)(2 * len))
|
||||
return 0;
|
||||
|
||||
cptr = str;
|
||||
|
||||
while (len--)
|
||||
{
|
||||
if (1 != ipdhcps6_cvt_two_hexdigits_to_unsigned (cptr, buf))
|
||||
return 0;
|
||||
cptr += 2;
|
||||
buf++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* see if a char string is a string of hex digits starting with "0x"
|
||||
*/
|
||||
|
||||
int ipdhcps6_check_is_hex_string (char *str)
|
||||
{
|
||||
Ip_size_t len;
|
||||
unsigned char c;
|
||||
|
||||
if (0 != ipcom_strncmp (str, "0x", 2))
|
||||
return 0;
|
||||
|
||||
str += 2;
|
||||
len = ipcom_strlen (str);
|
||||
|
||||
if ( !len || (0 != (len % 2)) )
|
||||
return 0;
|
||||
|
||||
while (len--)
|
||||
{ c = (unsigned char) (*str);
|
||||
if (! ipcom_isxdigit(c))
|
||||
return 0;
|
||||
str++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Copyright (C) 2007 Wind River Systems
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01a,17jul07,ps initial checkin of dhcpv6 authentication key database module
|
||||
*/
|
||||
|
||||
IP_GLOBAL int ipdhcps6_cvt_hex_to_membuf (char *str, unsigned char *buf, int len);
|
||||
IP_GLOBAL int ipdhcps6_check_is_hex_string (char *str);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipdhcps6_duid.c,v $ $Revision: 1.20 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcps6/src/ipdhcps6_duid.c,v $
|
||||
* $Author: kenneth $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcps6_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_netif.h>
|
||||
#include <ipcom_sock.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_sysvar.h>
|
||||
#include <ipcom_type.h>
|
||||
#include <ipnet_ctrl.h>
|
||||
|
||||
#include "ipdhcps6.h"
|
||||
#include "ipdhcps6_h.h"
|
||||
#include "ipdhcps6_duid.h"
|
||||
#include "ipnet_routesock.h"
|
||||
#include "ipcom_sysctl.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_duid_initialize
|
||||
*===========================================================================
|
||||
* Description: Initializes the DUID for the server.
|
||||
* Parameters:
|
||||
* Returns: IPCOM_SUCCESS - operation completed successfully
|
||||
* IPCOM_ERR_INVALID_INTERFACE - the specified network
|
||||
* interface was not found
|
||||
* IPCOM_ERR_FAILED - Could not read the MAC address from the
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_duid_initialize(void)
|
||||
{
|
||||
char ifname[IP_IFNAMSIZ];
|
||||
Ip_size_t ifname_size = sizeof(ifname);
|
||||
Ip_u32 ifindex;
|
||||
Ipdhcps6_option *duid;
|
||||
Ip_u16 duid_len;
|
||||
union Ipdhcps6_duid_data *serverid;
|
||||
int name[6];
|
||||
Ip_u8 *if_data;
|
||||
Ip_size_t if_data_len;
|
||||
struct Ipnet_if_msghdr *ifm;
|
||||
struct Ip_sockaddr_dl *hwaddr;
|
||||
|
||||
if (ipcom_sysvar_get("ipdhcps6.duid.ifname", ifname, &ifname_size) == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "No interface specified to calculate server ID (use sysvar ipdhcps6.duid.ifname)");
|
||||
return IPCOM_ERR_INVALID_INTERFACE;
|
||||
}
|
||||
|
||||
ifindex = ipcom_if_nametoindex(ifname);
|
||||
if (ifindex == 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "Interface %s was not found", ifname);
|
||||
return IPCOM_ERR_INVALID_INTERFACE;
|
||||
}
|
||||
|
||||
name[0] = IP_CTL_NET;
|
||||
name[1] = IP_AF_ROUTE;
|
||||
name[2] = 0;
|
||||
name[3] = IP_AF_INET6;
|
||||
name[4] = IP_NET_RT_IFLIST;
|
||||
name[5] = (int)ifindex;
|
||||
|
||||
if (ipcom_sysctl(name, 6, IP_NULL, &if_data_len, IP_NULL, 0) < 0)
|
||||
{
|
||||
IPCOM_LOG1(CRIT, "ipcom_sysctl failed: %s", ipcom_strerror(ipcom_errno));
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if_data = ipcom_malloc(if_data_len);
|
||||
if (if_data == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(CRIT, "out of memory");
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (ipcom_sysctl(name, 6, if_data, &if_data_len, IP_NULL, 0) < 0)
|
||||
{
|
||||
IPCOM_LOG1(CRIT, "ipcom_sysctl failed: %s", ipcom_strerror(ipcom_errno));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
ifm = (struct Ipnet_if_msghdr *) if_data;
|
||||
hwaddr = (struct Ip_sockaddr_dl *) &if_data[sizeof(struct Ipnet_if_msghdr)];
|
||||
|
||||
duid_len = sizeof(struct Ipdhcps6_duid_ll_data);
|
||||
duid = ipcom_malloc((Ip_size_t)(duid_len + IPDHCPS6_OPTION_HDR_LEN));
|
||||
if (duid == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(CRIT, "ipdhcps6_duid_initialize: out of memory");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
ipdhcps6_set_u16(&duid->len, duid_len);
|
||||
ipdhcps6_set_u16(&duid->code, IPDHCPS6_OPTION_SERVERID);
|
||||
serverid = &duid->data.serverid;
|
||||
serverid->ll.content = ip_htons(IPDHCPS6_DUID_LL);
|
||||
if ((IP_IFT_ETHER == ifm->ifm_data.ifi_type) || (IP_IFT_IEEE80211 == ifm->ifm_data.ifi_type))
|
||||
ipdhcps6_set_u16(&serverid->ll.hardware_type , 1);
|
||||
ipcom_memcpy(serverid->ll.link_addr, IP_SOCKADDR_DL_LLADDR(hwaddr), hwaddr->sdl_alen);
|
||||
|
||||
ipdhcps6->duid = duid;
|
||||
ipcom_free(if_data);
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
errout:
|
||||
ipcom_free(if_data);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK INTERNAL API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipdhcps6_h.h,v $ $Revision: 1.15.14.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcps6/src/ipdhcps6_h.h,v $
|
||||
* $Author: ulf $ $Date: 2011-11-16 10:33:28 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* Copyright Interpeak AB 2000-2004 <www.interpeak.se>. All rights reserved.
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPDHCPS6_H_H
|
||||
#define IPDHCPS6_H_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcps6_config.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_hash.h>
|
||||
#include <ipcom_list.h>
|
||||
#include <ipcom_os.h>
|
||||
#include <ipcom_route.h>
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_tmo2.h>
|
||||
|
||||
#include "ipdhcps6.h"
|
||||
#include "ipdhcps6_h.h"
|
||||
#include "ipdhcps6_option.h"
|
||||
#include "ipdhcps6_host.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef IPCOM_SYSLOG_PRIORITY /* for 64-bit compile warning */
|
||||
#undef IPCOM_SYSLOG_PRIORITY
|
||||
#endif
|
||||
|
||||
#if defined(_WRS_CONFIG_IPDHCPS6_SYSLOG_PRIORITY)
|
||||
#define IPCOM_SYSLOG_PRIORITY _WRS_CONFIG_IPDHCPS6_SYSLOG_PRIORITY
|
||||
#else
|
||||
#define IPCOM_SYSLOG_PRIORITY IPCOM_LOG_DEBUG
|
||||
#endif
|
||||
|
||||
#ifdef IPCOM_SYSLOG_FACILITY /* for 64-bit compile warning */
|
||||
#undef IPCOM_SYSLOG_FACILITY
|
||||
#endif
|
||||
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPDHCPS6
|
||||
|
||||
#if !defined(IPCOM_RELEASE) || IPCOM_RELEASE < 50900
|
||||
#define Ip_ipv6_mreq Ip_ip6_mreq
|
||||
#define ipv6mr_multiaddr imr_multiaddr
|
||||
#define Ipcom_hash_foreach_cb_func Ipcom_hash_forech_cb_func
|
||||
#endif
|
||||
|
||||
#define IPDHCPS6_SET_IN6_ADDR(dst, src) ipcom_memcpy(dst, src, sizeof(struct Ip_in6_addr))
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
struct Ipdhcps6_host_struct;
|
||||
struct Ipdhcps6_message_struct;
|
||||
struct Ipdhcps6_subnet_entry_struct;
|
||||
|
||||
/* A pool of addresses to hand out */
|
||||
typedef struct Ipdhcps6_addr_pool_struct
|
||||
{
|
||||
struct Ipdhcps6_addr_pool_struct *next;
|
||||
|
||||
/* Pool description */
|
||||
Ipdhcps6_poolinfo info;
|
||||
}
|
||||
Ipdhcps6_addr_pool;
|
||||
|
||||
/* Address that is currently leased by a client */
|
||||
typedef struct Ipdhcps6_active_lease_addr_struct
|
||||
{
|
||||
/* The IPv6 address value */
|
||||
struct Ip_in6_addr addr;
|
||||
/* The IAID specified by the client for this address */
|
||||
Ip_u32 iaid;
|
||||
/* The host that is using (or has been using) this address */
|
||||
struct Ipdhcps6_host_struct *host;
|
||||
/* Points back to pool where this address has been drawn */
|
||||
Ipcom_hash *active_leases;
|
||||
/* Timeout handler when this entry will expire */
|
||||
Ipcom_tmo2 tmo;
|
||||
|
||||
/* Can't store a backpointer to the pool, since due to construct it may
|
||||
* disappear at any time */
|
||||
Ip_u32 valid;
|
||||
Ip_u32 preferred;
|
||||
|
||||
/* Prefix information */
|
||||
Ip_u16 ia_type;
|
||||
Ip_u8 prefix_len;
|
||||
|
||||
/* The same host lease list */
|
||||
Ipcom_list next;
|
||||
}
|
||||
Ipdhcps6_lease_addr;
|
||||
|
||||
|
||||
|
||||
/* The database structure.
|
||||
Access to this structure is only allowed when holding the mutex
|
||||
*/
|
||||
struct Ipdhcps6_database
|
||||
{
|
||||
/* Mutext use to protect data in this structure */
|
||||
Ipcom_mutex mutex;
|
||||
|
||||
/* Contains all configured subnets (key is subnet) */
|
||||
Ipcom_route *subnets;
|
||||
|
||||
/* Contains all configured prefixes (key is ID number) */
|
||||
Ipcom_hash *prefixes;
|
||||
|
||||
/* Contains all configured hosts (key is DUID) */
|
||||
Ipcom_hash *hosts;
|
||||
|
||||
/* Contains the options that applies to all subnets and hosts (key is option ID) */
|
||||
Ipcom_hash *options;
|
||||
|
||||
/* Contains the prefix information to send to a PPP interface */
|
||||
Ipcom_hash *if_prefix_info;
|
||||
};
|
||||
|
||||
/* Global data structure for the DHCPv6 server. */
|
||||
struct Ipdhcps6_data
|
||||
{
|
||||
/* IPDHCPS6_FLAG_xxx flags */
|
||||
Ip_u32 flags;
|
||||
/* Socket used for UDP communication */
|
||||
int sock;
|
||||
/* Socket used to listen for stack events */
|
||||
int rt_sock;
|
||||
/* Socket used for IPD communication */
|
||||
int ipd;
|
||||
/* Buffer where received packets can be stored */
|
||||
Ip_u8 recv_buf[IPDHCPS6_RECV_BUF_SIZE];
|
||||
/* Buffer where the response message can be stored */
|
||||
Ip_u8 send_buf[IPDHCPS6_RECV_BUF_SIZE];
|
||||
/* Last prefix key created */
|
||||
int prefix_key;
|
||||
/* The number of allowed hops for relayed packets */
|
||||
Ip_u8 hop_count_limit;
|
||||
|
||||
/* The server DUID */
|
||||
const Ipdhcps6_option *duid;
|
||||
|
||||
/* The DHCP database */
|
||||
struct Ipdhcps6_database db;
|
||||
|
||||
/* Queue of pending timeouts */
|
||||
Ipcom_pqueue *timeouts;
|
||||
|
||||
/* Buffer to convert IPv6 addresses to strings when logging */
|
||||
char addr_str[40];
|
||||
};
|
||||
|
||||
#define IPDHCPS6_FLAG_OPEN (1 << 0) /* The server has been opened (started) */
|
||||
#define IPDHCPS6_FLAG_RELAY (1 << 1) /* Running as DHCPv6 relay (server otherwise) */
|
||||
|
||||
/* If the relay agent relays messages to the All_DHCP_Servers multicast
|
||||
* address or other multicast addresses, it sets the Hop Limit field to
|
||||
* 32.
|
||||
*/
|
||||
#define IPDHCP6_RELAY_MULTICAST_HOPS 32
|
||||
|
||||
|
||||
IP_EXTERN struct Ipdhcps6_data *ipdhcps6;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL void ipdhcps6_delete_hash_db_cb(void *obj, void *not_used);
|
||||
|
||||
IP_GLOBAL Ipcom_netif *
|
||||
ipdhcps6_get_netifbyindex(Ip_u32 ifindex);
|
||||
|
||||
IP_GLOBAL Ip_u16
|
||||
ipdhcps6_get_u16(const Ip_u16 *u16);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_set_u16(Ip_u16 *u16, Ip_u16 val);
|
||||
|
||||
IP_GLOBAL Ip_u32
|
||||
ipdhcps6_get_u32(const Ip_u32 *u32);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_set_u32(Ip_u32 *u32, Ip_u32 val);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_create_mask(struct Ip_in6_addr *mask, int netbits);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_msg_next_response_opt(Ip_u16 written, struct Ipdhcps6_message_struct *msg,
|
||||
Ipdhcps6_option **next_response_opt, Ip_u16 *opt_buf_left);
|
||||
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_user_get(Ipdhcps6_user *user);
|
||||
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_relay_do_forward_client(struct Ipdhcps6_message_struct *msg);
|
||||
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_relay_do_forward_relay(struct Ipdhcps6_message_struct *msg);
|
||||
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_relay_process_reply(struct Ipdhcps6_message_struct *msg,
|
||||
Ipdhcps6_option *options,
|
||||
Ip_u16 optslen);
|
||||
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_pool_process_non_temporary_addr_request(Ip_u8 msg_type,
|
||||
struct Ipdhcps6_subnet_entry_struct *subnet,
|
||||
struct Ipdhcps6_host_struct *host,
|
||||
struct Ipdhcps6_option_struct *opt,
|
||||
struct Ipdhcps6_option_struct *response_opt,
|
||||
Ip_u16 response_optlen,
|
||||
Ip_u16 *bytes_written);
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_pool_process_prefix_delegation_request(Ip_u8 msg_type,
|
||||
struct Ipdhcps6_subnet_entry_struct *subnet,
|
||||
struct Ipdhcps6_host_struct *host,
|
||||
struct Ipdhcps6_option_struct *in_opt,
|
||||
struct Ipdhcps6_option_struct *out_opt,
|
||||
Ip_u16 out_opt_buf_len,
|
||||
Ip_u16 *bytes_written);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_pool_delete_from_subnet(struct Ipdhcps6_subnet_entry_struct *sn_entry);
|
||||
|
||||
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_process_message(struct Ipdhcps6_message_struct *msg);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_dns_free(Ipdhcps6_host *host);
|
||||
IP_GLOBAL char*
|
||||
ipdhcps6_dns_get_domain(char* domainname);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,660 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_RCPL8_2024030303 $ $RCSfile: ipdhcps6_host.c,v $ $Revision: 1.26.12.3 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcps6/src/ipdhcps6_host.c,v $
|
||||
* $Author: jchang1 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcps6_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_time.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_hash.h>
|
||||
#include <ipcom_list.h>
|
||||
#include <ipcom_netif.h>
|
||||
#include <ipcom_type.h>
|
||||
|
||||
#ifdef IPPPP
|
||||
#include <ipppp.h>
|
||||
#endif
|
||||
|
||||
#include <ipnet.h>
|
||||
|
||||
#include "ipdhcps6.h"
|
||||
#include "ipdhcps6_h.h"
|
||||
#include "ipdhcps6_host.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
struct Ipdhcps6_host_list_cb_data
|
||||
{
|
||||
/* The error code */
|
||||
Ip_err err;
|
||||
|
||||
/* Number of options stored in the 'clientid' buffer */
|
||||
int total_bytes;
|
||||
/* Number of elements that can fit into 'clientid' */
|
||||
int buf_len;
|
||||
/* Points to where the next client ID should be written */
|
||||
Ipdhcps6_option *clientid;
|
||||
};
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_obj_hash
|
||||
*===========================================================================
|
||||
* Description: Returns a hash value based on a DHCP host.
|
||||
* Parameters: opt - The host to return a hash value for.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC unsigned
|
||||
ipdhcps6_host_obj_hash(Ipdhcps6_host *host)
|
||||
{
|
||||
return ipcom_hash_update(host->duid,
|
||||
ipdhcps6_get_u16(&host->duid->len) + IPDHCPS6_OPTION_HDR_LEN,
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_key_hash
|
||||
*===========================================================================
|
||||
* Description: Returns a hash value for a client id (DUID).
|
||||
* Parameters: code - Pointer to a host client id option.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC unsigned
|
||||
ipdhcps6_host_key_hash(Ipdhcps6_option *duid)
|
||||
{
|
||||
return ipcom_hash_update(duid,
|
||||
ipdhcps6_get_u16(&duid->len) + IPDHCPS6_OPTION_HDR_LEN,
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_cmp
|
||||
*===========================================================================
|
||||
* Description: Checks if the client id options matches the host entry.
|
||||
* Parameters: host - A host entry.
|
||||
* duid - The client id to match.
|
||||
* Returns: IP_TRUE if the client id in the host matches.
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_bool
|
||||
ipdhcps6_host_cmp(Ipdhcps6_host *host, Ipdhcps6_option *duid)
|
||||
{
|
||||
Ip_u16 duid_len;
|
||||
|
||||
duid_len = ipdhcps6_get_u16(&duid->len);
|
||||
|
||||
if (duid_len != ipdhcps6_get_u16(&host->duid->len))
|
||||
return IP_FALSE;
|
||||
|
||||
return ipcom_memcmp(host->duid, duid, (Ip_size_t)(duid_len + IPDHCPS6_OPTION_HDR_LEN)) == 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_list_cb
|
||||
*===========================================================================
|
||||
* Description: Stores pointers to all options in the hash table.
|
||||
* Parameters: opt - The option to add.
|
||||
* ol - Callback paramters
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipdhcps6_host_list_cb(Ipdhcps6_host *host, struct Ipdhcps6_host_list_cb_data *hl)
|
||||
{
|
||||
Ip_u16 len;
|
||||
|
||||
len = (Ip_u16) (ipdhcps6_get_u16(&host->duid->len) + IPDHCPS6_OPTION_HDR_LEN);
|
||||
hl->total_bytes += len;
|
||||
|
||||
if (hl->clientid == IP_NULL || hl->err != IPCOM_SUCCESS)
|
||||
/* Just calculate the number of elements */
|
||||
return;
|
||||
|
||||
if (hl->total_bytes <= hl->buf_len)
|
||||
{
|
||||
ipcom_memcpy(hl->clientid, host->duid, len);
|
||||
hl->clientid = (Ipdhcps6_option *) ((Ip_u8 *) hl->clientid + len);
|
||||
}
|
||||
else
|
||||
hl->err = IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_delete_host_db_cb
|
||||
*===========================================================================
|
||||
* Description: Deletes all elements in a host database.
|
||||
* Parameters: host - The host to be deleted.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipdhcps6_delete_host_db_cb(Ipdhcps6_host *host, void *not_used)
|
||||
{
|
||||
(void) not_used;
|
||||
if(host != IP_NULL)
|
||||
{
|
||||
ipdhcps6_option_delete_db(host->options);
|
||||
ipcom_free(host);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_new
|
||||
*===========================================================================
|
||||
* Description: Creates a new host entry.
|
||||
* Parameters: duid - The client ID of the host entry.
|
||||
* Returns: The host entry or IP_NULL if out of memory.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ipdhcps6_host *
|
||||
ipdhcps6_host_new(Ipdhcps6_option *duid, struct Ip_sockaddr_in6 *addr)
|
||||
{
|
||||
Ipdhcps6_host *host;
|
||||
Ip_u16 duid_len;
|
||||
|
||||
duid_len = (Ip_u16) (ipdhcps6_get_u16(&duid->len) + IPDHCPS6_OPTION_HDR_LEN);
|
||||
host = (Ipdhcps6_host *) ipcom_calloc(1, sizeof(Ipdhcps6_host) + duid_len);
|
||||
if (host == IP_NULL)
|
||||
goto out_of_memory;
|
||||
|
||||
host->options = ipdhcps6_option_new_db();
|
||||
if (host->options == IP_NULL)
|
||||
goto out_of_memory;
|
||||
|
||||
host->duid = (Ipdhcps6_option *) (host + 1);
|
||||
ipcom_memcpy(host->duid, duid, duid_len);
|
||||
host->last_servered = ipcom_time(IP_NULL);
|
||||
host->is_allowed_to_use_unicast = IP_FALSE;
|
||||
ipcom_list_init(&host->leases_head);
|
||||
|
||||
if (addr != IP_NULL)
|
||||
ipcom_memcpy(&host->addr, addr, sizeof(struct Ip_sockaddr_in6));
|
||||
|
||||
ipcom_memset(&host->user, 0, sizeof(host->user));
|
||||
if (ipcom_hash_add(ipdhcps6->db.hosts, host) != IPCOM_SUCCESS)
|
||||
goto out_of_memory;
|
||||
|
||||
return host;
|
||||
|
||||
out_of_memory:
|
||||
if (host != IP_NULL)
|
||||
{
|
||||
if (host->options != IP_NULL)
|
||||
ipcom_hash_delete(host->options);
|
||||
ipcom_free(host);
|
||||
}
|
||||
return IP_NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_try_get_user
|
||||
*===========================================================================
|
||||
* Description: Creates a new host entry.
|
||||
* Parameters: duid - The client ID of the host entry.
|
||||
* Returns: The host entry or IP_NULL if out of memory.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_host_try_get_user(Ipdhcps6_host *host, Ipcom_netif *netif)
|
||||
{
|
||||
ip_assert(IP_NULL != host);
|
||||
ip_assert(IP_NULL != netif);
|
||||
|
||||
/* change "debug" to "\0", confuse if configured the prefix name with "debug" */
|
||||
ipcom_strncpy(host->user.name, "\0", IPCOM_AUTH_USERNAME_MAX);
|
||||
|
||||
switch (netif->type)
|
||||
{
|
||||
#ifdef IPPPP
|
||||
case IP_IFT_PPP:
|
||||
{
|
||||
struct Ip_pppreq pppreq;
|
||||
Ip_fd tmp_fd = IP_INVALID_SOCKET;
|
||||
|
||||
host->ifindex = (int)netif->ifindex;
|
||||
ipcom_memcpy(pppreq.pppr_name, netif->name, IP_IFNAMSIZ);
|
||||
|
||||
tmp_fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0);
|
||||
if (ipcom_socketioctl(tmp_fd,IP_SIOCXPPPGPEERUSER, &pppreq) >= 0)
|
||||
{
|
||||
ipcom_strncpy(host->user.name, pppreq.pppru.username, IPCOM_AUTH_USERNAME_MAX);
|
||||
(void)ipdhcps6_user_get(&host->user);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* IPPPP */
|
||||
/* more type if needed */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_get
|
||||
*===========================================================================
|
||||
* Description: Returns the host matching DUID.
|
||||
* Parameters: duid - The client ID of the host entry to return.
|
||||
* Returns: The host entry or IP_NULL if no matching host exist.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ipdhcps6_host *
|
||||
ipdhcps6_host_get(Ipdhcps6_option *duid)
|
||||
{
|
||||
return (Ipdhcps6_host *) ipcom_hash_get(ipdhcps6->db.hosts, duid);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_new_db
|
||||
*===========================================================================
|
||||
* Description: Creates a new host database.
|
||||
* Parameters:
|
||||
* Returns: An empty host database, or IP_NULL if out of memory.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ipcom_hash *
|
||||
ipdhcps6_host_new_db(void)
|
||||
{
|
||||
return ipcom_hash_new((Ipcom_hash_obj_func)ipdhcps6_host_obj_hash,
|
||||
(Ipcom_hash_key_func)ipdhcps6_host_key_hash,
|
||||
(Ipcom_hash_cmp_func)ipdhcps6_host_cmp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_delete_db
|
||||
*===========================================================================
|
||||
* Description: Deletes all elements in the host database, memory for
|
||||
* the hash table holding the entries is also deleted.
|
||||
* Parameters: options - The host database to delete.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_host_delete_db(Ipcom_hash *hosts)
|
||||
{
|
||||
if (hosts != IP_NULL)
|
||||
{
|
||||
ipcom_hash_for_each(hosts, ipdhcps6_delete_host_db_cb, IP_NULL);
|
||||
ipcom_hash_delete(hosts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_has_prefix
|
||||
*===========================================================================
|
||||
* Description: Returns if this host has at least 1 prefix.
|
||||
* Parameters: host - Host to look in.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_bool
|
||||
ipdhcps6_host_has_prefix(const Ipdhcps6_host *host)
|
||||
{
|
||||
return host->user.prefix_ids[0][0] != '\0';
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_add
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_host_add(Ipdhcps6_option *duid)
|
||||
{
|
||||
Ipdhcps6_host *host;
|
||||
|
||||
if (ipdhcps6 == IP_NULL || IP_BIT_ISFALSE(ipdhcps6->flags, IPDHCPS6_FLAG_OPEN))
|
||||
return IPCOM_ERR_NOT_OPENED;
|
||||
|
||||
ipcom_mutex_lock(ipdhcps6->db.mutex);
|
||||
|
||||
if (ipcom_hash_get(ipdhcps6->db.hosts, duid) != IP_NULL)
|
||||
{
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
return IPCOM_ERR_DUPLICATE;
|
||||
}
|
||||
|
||||
host = ipdhcps6_host_new(duid, IP_NULL);
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
|
||||
return host != IP_NULL ? IPCOM_SUCCESS : IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_delete
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_host_delete(Ipdhcps6_option *duid)
|
||||
{
|
||||
Ipdhcps6_host *host;
|
||||
|
||||
if (ipdhcps6 == IP_NULL || !IP_BIT_ISSET(ipdhcps6->flags, IPDHCPS6_FLAG_OPEN))
|
||||
return IPCOM_ERR_NOT_OPENED;
|
||||
|
||||
ipcom_mutex_lock(ipdhcps6->db.mutex);
|
||||
|
||||
host = (Ipdhcps6_host *) ipcom_hash_get(ipdhcps6->db.hosts, duid);
|
||||
if (host == IP_NULL)
|
||||
{
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
return IPCOM_ERR_NOT_FOUND;
|
||||
}
|
||||
ipcom_hash_remove(ipdhcps6->db.hosts, host);
|
||||
ipcom_free(host);
|
||||
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_list
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_host_list(Ipdhcps6_option *duid, int *duid_len)
|
||||
{
|
||||
struct Ipdhcps6_host_list_cb_data lc;
|
||||
|
||||
if (ipdhcps6 == IP_NULL || !IP_BIT_ISSET(ipdhcps6->flags, IPDHCPS6_FLAG_OPEN))
|
||||
return IPCOM_ERR_NOT_OPENED;
|
||||
|
||||
ipcom_mutex_lock(ipdhcps6->db.mutex);
|
||||
|
||||
lc.err = IPCOM_SUCCESS;
|
||||
lc.total_bytes = 0;
|
||||
lc.buf_len = *duid_len;
|
||||
lc.clientid = duid;
|
||||
|
||||
ipcom_hash_for_each(ipdhcps6->db.hosts,
|
||||
(void(*)(void *, void *)) ipdhcps6_host_list_cb,
|
||||
&lc);
|
||||
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
|
||||
*duid_len = lc.total_bytes;
|
||||
return lc.err;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_to_string
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_host_to_string(Ipdhcps6_option *duid, char *str, int str_len)
|
||||
{
|
||||
Ipdhcps6_host *host;
|
||||
Ip_err err;
|
||||
Ip_size_t len;
|
||||
char ifname[IP_IFNAMSIZ];
|
||||
Ipcom_list *cur = IP_NULL;
|
||||
Ipdhcps6_lease_addr *le = IP_NULL;
|
||||
char domain[128];
|
||||
if (ipdhcps6 == IP_NULL || IP_BIT_ISFALSE(ipdhcps6->flags, IPDHCPS6_FLAG_OPEN))
|
||||
return IPCOM_ERR_NOT_OPENED;
|
||||
|
||||
ipcom_mutex_lock(ipdhcps6->db.mutex);
|
||||
|
||||
host = (Ipdhcps6_host *) ipcom_hash_get(ipdhcps6->db.hosts, duid);
|
||||
if (host == IP_NULL)
|
||||
{
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
return IPCOM_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
err = ipdhcps6_option_to_string(duid, str, str_len);
|
||||
if (err != IPCOM_SUCCESS)
|
||||
goto buf_to_small;
|
||||
|
||||
len = ipcom_strlen(str);
|
||||
str += len;
|
||||
str_len -= len;
|
||||
|
||||
if (IP_IN6_IS_ADDR_UNSPECIFIED(&host->addr))
|
||||
{
|
||||
err = ipcom_snprintf(str, (Ip_size_t)str_len, IP_LF "\taddr: unknown" IP_LF);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = ipcom_snprintf(str, (Ip_size_t)str_len, IP_LF "\taddr: %s",
|
||||
ipcom_inet_ntop(IP_AF_INET6,
|
||||
&host->addr.sin6_addr,
|
||||
ipdhcps6->addr_str,
|
||||
sizeof(ipdhcps6->addr_str)));
|
||||
|
||||
if (err > 0 && host->addr.sin6_scope_id != 0)
|
||||
{
|
||||
len = ipcom_strlen(str);
|
||||
str += len;
|
||||
str_len -= len;
|
||||
err = ipcom_snprintf(str, (Ip_size_t)str_len, "%s%s" IP_LF, "%%",
|
||||
ipcom_if_indextoname(host->addr.sin6_scope_id, ifname));
|
||||
}
|
||||
}
|
||||
if (err < 0)
|
||||
goto buf_to_small;
|
||||
|
||||
len = ipcom_strlen(str);
|
||||
str += len;
|
||||
str_len -= len;
|
||||
|
||||
if(host->fqdn.fullName[0]!='\0')
|
||||
{
|
||||
err = ipcom_snprintf(str, (Ip_size_t)str_len, "\tFQDN:%s.%s"IP_LF,host->fqdn.fullName, ipdhcps6_dns_get_domain(domain));
|
||||
if (err < 0)
|
||||
goto buf_to_small;
|
||||
len = ipcom_strlen(str);
|
||||
str += len;
|
||||
str_len -= len;
|
||||
}
|
||||
err = ipcom_snprintf(str, (Ip_size_t)str_len, "\tlast served %d seconds ago" IP_LF,
|
||||
ipcom_time(IP_NULL) - host->last_servered);
|
||||
if (err < 0)
|
||||
goto buf_to_small;
|
||||
|
||||
len = ipcom_strlen(str);
|
||||
str += len;
|
||||
str_len -= len;
|
||||
|
||||
for (cur = ipcom_list_first(&host->leases_head);
|
||||
IP_NULL != cur;
|
||||
cur = ipcom_list_next(cur))
|
||||
{
|
||||
le = ipcom_list_entry(cur, Ipdhcps6_lease_addr, next);
|
||||
ip_assert(IP_NULL != le);
|
||||
if (le->prefix_len)
|
||||
err = ipcom_snprintf(str, (Ip_size_t)str_len, "\tlease addr: %s/%d, preferred: %ds, valid: %ds" IP_LF,
|
||||
ipcom_inet_ntop(IP_AF_INET6,
|
||||
&le->addr,
|
||||
ipdhcps6->addr_str,
|
||||
sizeof(ipdhcps6->addr_str)),
|
||||
le->prefix_len,
|
||||
le->preferred,
|
||||
le->valid);
|
||||
else
|
||||
err = ipcom_snprintf(str, (Ip_size_t)str_len, "\tlease addr: %s, preferred: %ds, valid: %ds" IP_LF,
|
||||
ipcom_inet_ntop(IP_AF_INET6,
|
||||
&le->addr,
|
||||
ipdhcps6->addr_str,
|
||||
sizeof(ipdhcps6->addr_str)),
|
||||
le->preferred,
|
||||
le->valid);
|
||||
if (err < 0)
|
||||
goto buf_to_small;
|
||||
}
|
||||
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
buf_to_small:
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_host_get_user
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_host_get_user(Ipdhcps6_option *duid, char *username, int username_len)
|
||||
{
|
||||
Ipdhcps6_host *host;
|
||||
Ip_err err = IPCOM_SUCCESS;
|
||||
|
||||
ipcom_mutex_lock(ipdhcps6->db.mutex);
|
||||
|
||||
host = (Ipdhcps6_host *) ipcom_hash_get(ipdhcps6->db.hosts, duid);
|
||||
if (host == IP_NULL)
|
||||
{
|
||||
err = IPCOM_ERR_NOT_FOUND;
|
||||
goto cleanup;
|
||||
}
|
||||
if (ipcom_strlen(host->user.name) == 0)
|
||||
{
|
||||
err = IPCOM_ERR_NOT_SUPPORTED;
|
||||
goto cleanup;
|
||||
}
|
||||
ipcom_strncpy(username, host->user.name, (Ip_size_t)username_len);
|
||||
|
||||
cleanup:
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipdhcps6_host.h,v $ $Revision: 1.7.18.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcps6/src/ipdhcps6_host.h,v $
|
||||
* $Author: ulf $ $Date: 2011-11-16 10:33:28 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPDHCPS6_HOST_H
|
||||
#define IPDHCPS6_HOST_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcps6_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_netif.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
struct Ipdhcps6_active_lease_addr_struct;
|
||||
|
||||
typedef struct Ipdhcps6_fqdn
|
||||
{
|
||||
char fullName[255];
|
||||
Ip_bool ptr_status;
|
||||
/*Ptr update successfully or not*/
|
||||
Ip_bool aaaa_status;
|
||||
/*AAAA update successfully or not*/
|
||||
Ip_bool agent;
|
||||
Ip_bool oro;
|
||||
struct Ip_in6_addr addr;
|
||||
} Ipdhcps6_fqdn;
|
||||
/* DHCP host structure */
|
||||
typedef struct Ipdhcps6_host_struct
|
||||
{
|
||||
/* The client ID for this host */
|
||||
Ipdhcps6_option *duid;
|
||||
/* The currently leased by a client with this host */
|
||||
Ipcom_list leases_head;
|
||||
/* The interface used to communicate with this host */
|
||||
int ifindex;
|
||||
/* The unicast address for this host */
|
||||
struct Ip_sockaddr_in6 addr;
|
||||
/* Last time this host contacted the DHCP server */
|
||||
Ip_time_t last_servered;
|
||||
/* Is IP_TRUE if a Server Unicast Option has been sent to this host */
|
||||
Ip_bool is_allowed_to_use_unicast;
|
||||
/* Options for this host */
|
||||
Ipcom_hash *options;
|
||||
/* User associated with this host, ipcom_strlen(user.name) != 0 only if the user is known */
|
||||
Ipdhcps6_user user;
|
||||
Ipdhcps6_fqdn fqdn;
|
||||
}
|
||||
Ipdhcps6_host;
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ipdhcps6_host *
|
||||
ipdhcps6_host_new(Ipdhcps6_option *duid, struct Ip_sockaddr_in6 *addr);
|
||||
|
||||
IP_GLOBAL Ipdhcps6_host *
|
||||
ipdhcps6_host_get(Ipdhcps6_option *duid);
|
||||
|
||||
IP_GLOBAL Ipcom_hash *
|
||||
ipdhcps6_host_new_db(void);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_host_delete_db(Ipcom_hash *hosts);
|
||||
|
||||
IP_GLOBAL Ip_bool
|
||||
ipdhcps6_host_has_prefix(const Ipdhcps6_host *host);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_host_try_get_user(Ipdhcps6_host *host, Ipcom_netif *netif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipdhcps6_msg.h,v $ $Revision: 1.9.16.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcps6/src/ipdhcps6_msg.h,v $
|
||||
* $Author: ulf $ $Date: 2011-11-16 10:33:28 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* Copyright Interpeak AB 2000-2004 <www.interpeak.se>. All rights reserved.
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPDHCPS6_MSG_H
|
||||
#define IPDHCPS6_MSG_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcps6_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
|
||||
#include "ipdhcps6_option.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* DHCP Message Types */
|
||||
|
||||
/* A client sends a Solicit message to locate servers. */
|
||||
#define IPDHCPS6_MSG_SOLICIT 1
|
||||
/* A server sends an Advertise message to indicate
|
||||
that it is available for DHCP service, in
|
||||
response to a Solicit message received from a
|
||||
client. */
|
||||
#define IPDHCPS6_MSG_ADVERTISE 2
|
||||
/* A client sends a Request message to request
|
||||
configuration parameters, including IP
|
||||
addresses, from a specific server. */
|
||||
#define IPDHCPS6_MSG_REQUEST 3
|
||||
/* A client sends a Confirm message to any
|
||||
available server to determine whether the
|
||||
addresses it was assigned are still appropriate
|
||||
to the link to which the client is connected. */
|
||||
#define IPDHCPS6_MSG_CONFIRM 4
|
||||
/* A client sends a Renew message to the server
|
||||
that originally provided the client's addresses
|
||||
and configuration parameters to extend the
|
||||
lifetimes on the addresses assigned to the
|
||||
client and to update other configuration
|
||||
parameters. */
|
||||
#define IPDHCPS6_MSG_RENEW 5
|
||||
/* A client sends a Rebind message to any
|
||||
available server to extend the lifetimes on the
|
||||
addresses assigned to the client and to update
|
||||
other configuration parameters; this message is
|
||||
sent after a client receives no response to a
|
||||
Renew message. */
|
||||
#define IPDHCPS6_MSG_REBIND 6
|
||||
/* A server sends a Reply message containing
|
||||
assigned addresses and configuration parameters
|
||||
in response to a Solicit, Request, Renew,
|
||||
Rebind message received from a client. A
|
||||
server sends a Reply message containing
|
||||
configuration parameters in response to an
|
||||
Information-request message. A server sends a
|
||||
Reply message in response to a Confirm message
|
||||
confirming or denying that the addresses
|
||||
assigned to the client are appropriate to the
|
||||
link to which the client is connected. A
|
||||
server sends a Reply message to acknowledge
|
||||
receipt of a Release or Decline message. */
|
||||
#define IPDHCPS6_MSG_REPLY 7
|
||||
/* A client sends a Release message to the server
|
||||
that assigned addresses to the client to
|
||||
indicate that the client will no longer use one
|
||||
or more of the assigned addresses. */
|
||||
#define IPDHCPS6_MSG_RELEASE 8
|
||||
/* A client sends a Decline message to a server to
|
||||
indicate that the client has determined that
|
||||
one or more addresses assigned by the server
|
||||
are already in use on the link to which the
|
||||
client is connected. */
|
||||
#define IPDHCPS6_MSG_DECLINE 9
|
||||
/* A server sends a Reconfigure message to a
|
||||
client to inform the client that the server has
|
||||
new or updated configuration parameters, and
|
||||
that the client is to initiate a Renew/Reply
|
||||
or Information-request/Reply transaction with
|
||||
the server in order to receive the updated
|
||||
information. */
|
||||
#define IPDHCPS6_MSG_RECONFIGURE 10
|
||||
/* A client sends an Information-request
|
||||
message to a server to request configuration
|
||||
parameters without the assignment of any IP
|
||||
addresses to the client. */
|
||||
#define IPDHCPS6_MSG_INFORMATION_REQUEST 11
|
||||
/* A relay agent sends a Relay-forward message
|
||||
to relay messages to servers, either directly
|
||||
or through another relay agent. The received
|
||||
message, either a client message or a
|
||||
Relay-forward message from another relay
|
||||
agent, is encapsulated in an option in the
|
||||
Relay-forward message. */
|
||||
#define IPDHCPS6_MSG_RELAY_FORW 12
|
||||
/* A server sends a Relay-reply message to a relay
|
||||
agent containing a message that the relay
|
||||
agent delivers to a client. The Relay-reply
|
||||
message may be relayed by other relay agents
|
||||
for delivery to the destination relay agent.
|
||||
The server encapsulates the client message as
|
||||
an option in the Relay-reply message, which the
|
||||
relay agent extracts and relays to the client. */
|
||||
#define IPDHCPS6_MSG_RELAY_REPL 13
|
||||
|
||||
|
||||
|
||||
/* Status Codes */
|
||||
|
||||
/* Success */
|
||||
#define IPDHCPS6_CODE_SUCCESS 0
|
||||
/* Failure, reason unspecified; this status code is sent by either a client
|
||||
or a server to indicate a failure not explicitly specified in the DHCPv6
|
||||
protocol specification */
|
||||
#define IPDHCPS6_CODE_UNSPEC_FAIL 1
|
||||
/* Server has no addresses available to assign to the IA(s) */
|
||||
#define IPDHCPS6_CODE_NO_ADDRS_AVAIL 2
|
||||
/* Client record (binding) unavailable */
|
||||
#define IPDHCPS6_CODE_NO_BINDING 3
|
||||
/* The prefix for the address is not appropriate to the link to which the
|
||||
client is attached */
|
||||
#define IPDHCPS6_CODE_NOT_ON_LINK 4
|
||||
/* Sent by a server to a client to force the client to send messages to the
|
||||
server using the All_DHCP_Relay_Agents_and_Servers address */
|
||||
#define IPDHCPS6_CODE_USE_MULTICAST 5
|
||||
/* The deligating server (this DHCPv6 server) will not give any prefixes
|
||||
to the requesting router */
|
||||
#define IPDHCPS6_CODE_NO_PREFIX_AVAIL 6
|
||||
|
||||
/*FLAGS used for FQDN*/
|
||||
|
||||
#define IPDHCPS6_DNS_AAAA 0
|
||||
#define IPDHCPS6_DNS_PTR 1
|
||||
#define IPDHCPS6_DNS_MAX_NAME_LEN 255
|
||||
|
||||
#define IPDHCPS6_DNS_DEFAULT_TTL 3600
|
||||
#define IPDHCPS6_DNS_MIN_TTL 60*10
|
||||
#define IPDHCPS6_FQDN_FLAG_S 0x01
|
||||
#define IPDHCPS6_FQDN_FLAG_O 0x02
|
||||
#define IPDHCPS6_FQDN_FLAG_N 0x04
|
||||
#define IPDHCPS6_DNS_MD5_VALUE_LEN 16
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
struct Ipdhcps6_subnet_entry_struct;
|
||||
|
||||
typedef struct Ipdhcps6_message_struct
|
||||
{
|
||||
/* The interface to use for send response,
|
||||
also the interface the request was received on */
|
||||
Ip_u32 ifindex;
|
||||
/* The address the request was sent to */
|
||||
struct Ip_sockaddr_in6 local_addr;
|
||||
/* The address the request was sent from */
|
||||
struct Ip_sockaddr_in6 peer_addr;
|
||||
/* The address the response should be sent to */
|
||||
struct Ip_sockaddr_in6 response_addr;
|
||||
/* Will be != if the response must be sent on a specific interface */
|
||||
Ip_u32 response_ifindex;
|
||||
/* The subnet that maches this message */
|
||||
struct Ipdhcps6_subnet_entry_struct *subnet;
|
||||
|
||||
/* The length of the received message */
|
||||
Ip_u16 recv_buf_len;
|
||||
/* Pointer to the recieved message */
|
||||
Ip_u8 *recv_buf;
|
||||
|
||||
/* Set to IP_TRUE if a response should be sent */
|
||||
Ip_bool send_response;
|
||||
/* The maximum length of the send buffer */
|
||||
Ip_u16 send_buf_maxlen;
|
||||
/* The actual length of data written to the send buffer */
|
||||
Ip_u16 send_buf_len;
|
||||
/* The send buffer */
|
||||
Ip_u8 *send_buf;
|
||||
|
||||
/* Set to IP_TRUE if hop limit field should be set when
|
||||
* relay agent relays messages to the All_DHCP_Servers multicast
|
||||
* address or other multicast addresses. Fix for WIND00195425.
|
||||
*/
|
||||
Ip_bool mhop_limit;
|
||||
}
|
||||
Ipdhcps6_message;
|
||||
|
||||
|
||||
/*
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| msg-type | transaction-id |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| |
|
||||
. options .
|
||||
. (variable) .
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
|
||||
|
||||
msg-type Identifies the DHCP message type; the
|
||||
available message types are listed in
|
||||
section 5.3.
|
||||
|
||||
transaction-id The transaction ID for this message exchange.
|
||||
|
||||
options Options carried in this message.
|
||||
*/
|
||||
#include "ipcom_align16.h"
|
||||
typedef IP_PACKED1 struct Ipdhcps6_msg_hdr_struct
|
||||
{
|
||||
Ip_u8 type;
|
||||
Ip_u8 transaction_id_1;
|
||||
Ip_u8 transaction_id_2;
|
||||
Ip_u8 transaction_id_3;
|
||||
/* The options (header is 4 bytes so the this is the smallest possible size) */
|
||||
Ip_u8 options[4];
|
||||
}
|
||||
IP_PACKED2 Ipdhcps6_msg_hdr;
|
||||
#include "ipcom_align16.h"
|
||||
|
||||
|
||||
/*
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| msg-type | hop-count | |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
||||
| |
|
||||
| link-address |
|
||||
| |
|
||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
|
||||
| | |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
||||
| |
|
||||
| peer-address |
|
||||
| |
|
||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
|
||||
| | |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
||||
. .
|
||||
. options (variable number and length) .... .
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
#include "ipcom_align16.h"
|
||||
typedef IP_PACKED1 struct Ipdhcps6_relay_msg_hdr_struct
|
||||
{
|
||||
Ip_u8 type;
|
||||
Ip_u8 hop_count;
|
||||
struct Ip_in6_addr link_addr;
|
||||
struct Ip_in6_addr peer_addr;
|
||||
Ip_u8 options[1];
|
||||
}
|
||||
IP_PACKED2 Ipdhcps6_relay_msg_hdr;
|
||||
#include "ipcom_align16.h"
|
||||
|
||||
|
||||
#define IPDHCPS6_MSG_HDR_LEN 4
|
||||
#define IPDHCP_RELAY_MSG_HDR_LEN 34
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL const char *
|
||||
ipdhcps6_msg_type_to_string(Ip_u8 type);
|
||||
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_msg_process_solicit(Ipdhcps6_message *msg,
|
||||
Ipdhcps6_option *options, Ip_u16 optlen);
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_msg_process_confirm(Ipdhcps6_message *msg,
|
||||
Ipdhcps6_option *options, Ip_u16 optlen);
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_msg_process_request(Ipdhcps6_message *msg,
|
||||
Ipdhcps6_option *options, Ip_u16 optlen);
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_msg_process_renew(Ipdhcps6_message *msg,
|
||||
Ipdhcps6_option *options, Ip_u16 optlen);
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_msg_process_rebind(Ipdhcps6_message *msg,
|
||||
Ipdhcps6_option *options, Ip_u16 optlen);
|
||||
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_msg_process_release(Ipdhcps6_message *msg,
|
||||
Ipdhcps6_option *options, Ip_u16 optlen);
|
||||
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_msg_process_decline(Ipdhcps6_message * msg,
|
||||
Ipdhcps6_option *options,
|
||||
Ip_u16 optslen);
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_msg_process_relay_forw(Ipdhcps6_message *msg,
|
||||
Ipdhcps6_option *options, Ip_u16 optlen);
|
||||
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_msg_process_information_request(Ipdhcps6_message *msg,
|
||||
Ipdhcps6_option *options,
|
||||
Ip_u16 optlen);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_msg_get_first_option(Ipdhcps6_msg_hdr *msg,
|
||||
Ip_u16 msg_len,
|
||||
Ipdhcps6_option **poptions,
|
||||
Ip_u16 *poptslen);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_msg_first_response_opt(Ipdhcps6_message *msg,
|
||||
Ipdhcps6_option **response_opt,
|
||||
Ip_u16 *optlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,752 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_RCPL8_2024030303 $ $RCSfile: ipdhcps6_prefix.c,v $ $Revision: 1.25.12.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcps6/src/ipdhcps6_prefix.c,v $
|
||||
* $Author: jchang1 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcps6_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_list.h>
|
||||
#include <ipcom_syslog.h>
|
||||
|
||||
#include <ipnet.h>
|
||||
#include <ipnet_routesock.h>
|
||||
|
||||
#include "ipdhcps6.h"
|
||||
#include "ipdhcps6_h.h"
|
||||
#include "ipdhcps6_host.h"
|
||||
#include "ipdhcps6_prefix.h"
|
||||
#include "ipdhcps6_subnet.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct Ipdhcps6_prefix_list_data_struct
|
||||
{
|
||||
Ipdhcps6_prefix *prefix;
|
||||
int index;
|
||||
}
|
||||
Ipdhcps6_prefix_list_data;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_prefix_obj_hash
|
||||
*===========================================================================
|
||||
* Description: Returns a hash value based on a DHCP option.
|
||||
* Parameters: opt - The option to return a hash value for.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC unsigned
|
||||
ipdhcps6_prefix_obj_hash(Ipdhcps6_prefix *prefix)
|
||||
{
|
||||
return ipcom_hash_update(prefix->key, ipcom_strlen(prefix->key), 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_prefix_key_hash
|
||||
*===========================================================================
|
||||
* Description: Returns a hash value for a prefix key.
|
||||
* Parameters: key - The prefix ID number.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC unsigned
|
||||
ipdhcps6_prefix_key_hash(char *key)
|
||||
{
|
||||
return ipcom_hash_update(key, ipcom_strlen(key), 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_prefix_hash_cmp
|
||||
*===========================================================================
|
||||
* Description: Compares a hash object and a hash key for equality.
|
||||
* Parameters: prefix - A prefix structure.
|
||||
* key - A pointer to the search key.
|
||||
* Returns: IP_TRUE if the search key matches the prefix entry.
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_bool
|
||||
ipdhcps6_prefix_hash_cmp(Ipdhcps6_prefix *prefix, char *key)
|
||||
{
|
||||
return ipcom_strcmp(prefix->key, key) == 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_prefix_free_cb
|
||||
*===========================================================================
|
||||
* Description: Frees the specified prefix.
|
||||
* Parameters: prefix - A prefix structure.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipdhcps6_prefix_free_cb(Ipdhcps6_prefix *prefix, void *unused)
|
||||
{
|
||||
(void) unused;
|
||||
ipcom_free(prefix);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_prefix_list_cb
|
||||
*===========================================================================
|
||||
* Description: Makes a deep copy of all prefix entries.
|
||||
* Parameters: prefix - A prefix structure.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipdhcps6_prefix_list_cb(Ipdhcps6_prefix *prefix, Ipdhcps6_prefix_list_data *list_data)
|
||||
{
|
||||
ipcom_memcpy(&list_data->prefix[list_data->index++], prefix, sizeof(Ipdhcps6_prefix));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_prefix_get_ptr
|
||||
*===========================================================================
|
||||
* Description: Returns the prefix entry corrensponding to the specified key.
|
||||
* Parameters: key - The ID number for the prefix to return
|
||||
* Returns: The matching prefix entry or IP_NULL if no match was found.
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ipdhcps6_prefix *
|
||||
ipdhcps6_prefix_get_ptr(IP_CONST char *key)
|
||||
{
|
||||
return ipcom_hash_get(ipdhcps6->db.prefixes, (void *) key);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_prefix_get_ptr_from_host
|
||||
*===========================================================================
|
||||
* Description: Returns the prefix entry on a specific host.
|
||||
* Parameters: host - The host to which this prefix must be assigned.
|
||||
* prefix - The address of the prefix to find.
|
||||
* prefix_len - The length of the prefix to find.
|
||||
* Returns: The matching prefix entry or IP_NULL if no match was found.
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ipdhcps6_prefix *
|
||||
ipdhcps6_prefix_get_ptr_from_host(Ipdhcps6_host *host,
|
||||
struct Ip_in6_addr *prefix,
|
||||
int prefix_len)
|
||||
{
|
||||
Ipdhcps6_prefix *p;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < IPDHCPS6_PREFIX_PER_USER; i++)
|
||||
{
|
||||
if (host->user.prefix_ids[i][0] == '\0')
|
||||
continue;
|
||||
p = ipdhcps6_prefix_get_ptr(host->user.prefix_ids[i]);
|
||||
if (p == IP_NULL)
|
||||
continue;
|
||||
if (prefix_len == p->prefix_len
|
||||
&& IP_IN6_ARE_ADDR_EQUAL(prefix, &p->prefix))
|
||||
return p;
|
||||
}
|
||||
return IP_NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_prefix_add_del_rt
|
||||
*===========================================================================
|
||||
* Description: Adds/deletes a route to the prefix that is beeing handed out.
|
||||
* Parameters: ifindex - The interface that have to be used to reach this prefix.
|
||||
* prefix - The prefix that is beeing handed out.
|
||||
* prefixlen - The prefix length.
|
||||
* add - IP_TRUE if the route should be added, it will be deleted
|
||||
* otherwise.
|
||||
* Returns: IPCOM_SUCCESS - operation was successful.
|
||||
* IPCOM_ERR_NO_MEMORY - could not allocate enough memory.
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipdhcps6_prefix_add_del_rt(int ifindex, struct Ip_in6_addr *prefix, int prefixlen , Ip_bool add)
|
||||
{
|
||||
struct Ip_sockaddr_in6 *gw;
|
||||
struct Ip_sockaddr_in6 *net;
|
||||
struct Ip_sockaddr_in6 *mask;
|
||||
struct Ipnet_rt_msghdr *rtm = IP_NULL;
|
||||
Ip_u16 rtm_len;
|
||||
int rt_sock;
|
||||
struct Ip_in6_ifreq ifreq6;
|
||||
Ip_err err;
|
||||
|
||||
rt_sock = ipcom_socket(IP_AF_ROUTE, IP_SOCK_RAW, 0);
|
||||
if (rt_sock == IP_INVALID_SOCKET)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Failed to open routing socket");
|
||||
err = IPCOM_ERR_SOCKCALLFAILED;
|
||||
/* Coverity defect fix for NEGATIVE_RETURNS */
|
||||
return err;
|
||||
}
|
||||
|
||||
(void)ipcom_if_indextoname((Ip_u32)ifindex, ifreq6.ifr_name);
|
||||
if (ipcom_socketioctl(rt_sock, IP_SIOCGIFDSTADDR_IN6, &ifreq6) < 0)
|
||||
/* Not a point-to-point interface or no peer address set, ignore t */
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
/* Peer address present, route any packets destinated to the network defined
|
||||
by the prefix to the PPP peer */
|
||||
rtm_len = sizeof(struct Ipnet_rt_msghdr) + sizeof(struct Ip_sockaddr_in6) * 3;
|
||||
rtm = ipcom_calloc(1, rtm_len);
|
||||
if (rtm == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Out of memory while adding route.");
|
||||
err = IPCOM_ERR_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
net = (struct Ip_sockaddr_in6 *) (rtm + 1);
|
||||
gw = (struct Ip_sockaddr_in6 *) (net + 1);
|
||||
mask = (struct Ip_sockaddr_in6 *) (gw + 1);
|
||||
|
||||
rtm->rtm_msglen = rtm_len;
|
||||
rtm->rtm_version = IPNET_RTM_VERSION;
|
||||
rtm->rtm_type = (Ip_u8)(add ? IPNET_RTM_ADD : IPNET_RTM_DELETE);
|
||||
rtm->rtm_index = (Ip_u32)ifindex;
|
||||
rtm->rtm_flags = IPNET_RTF_UP | IPNET_RTF_GATEWAY | IPNET_RTF_DONE
|
||||
| IPNET_RTF_MASK | IPNET_RTF_DYNAMIC;
|
||||
rtm->rtm_addrs = IPNET_RTA_DST | IPNET_RTA_GATEWAY | IPNET_RTA_NETMASK;
|
||||
rtm->rtm_pid = ipcom_getpid();
|
||||
rtm->rtm_rmx.rmx_expire = IPCOM_ADDR_INFINITE;
|
||||
|
||||
/* Network */
|
||||
IPCOM_SA_LEN_SET(net, sizeof(*net));
|
||||
net->sin6_family = IP_AF_INET6;
|
||||
IPDHCPS6_SET_IN6_ADDR(&net->sin6_addr, prefix);
|
||||
|
||||
/* Mask */
|
||||
IPCOM_SA_LEN_SET(mask, sizeof(*mask));
|
||||
mask->sin6_family = IP_AF_INET6;
|
||||
ipdhcps6_create_mask(&mask->sin6_addr, prefixlen);
|
||||
|
||||
/* Gateway */
|
||||
ipcom_memcpy(gw, &ifreq6.ifr_ifru.ifru_dstaddr, IPCOM_SA_LEN_GET(&ifreq6.ifr_ifru.ifru_dstaddr));
|
||||
|
||||
if (ipcom_send(rt_sock, rtm, rtm->rtm_msglen, 0) < 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "Failed to send route socket message: %s",
|
||||
ipcom_strerror(ipcom_errno));
|
||||
}
|
||||
err = IPCOM_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
ipcom_socketclose(rt_sock);
|
||||
ipcom_free(rtm);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_prefix_add_del_prefixes
|
||||
*===========================================================================
|
||||
* Description: Adds or deletes all prefixes that this host should get.
|
||||
* Parameters: subnet - The subnet the requesting router is located at.
|
||||
* host - The host entry for the requesting router.
|
||||
* response_opt - Buffer to where all OPTION_IAPREFIX options
|
||||
* will be copied.
|
||||
* response_optlen - Length of the 'response_opt' buffer.
|
||||
* bytes_written - Number of bytes written to 'opt' or the requeried
|
||||
* length of 'opt' if failed with IPCOM_ERR_NO_MEMORY.
|
||||
* Returns: IPCOM_SUCCESS - operation was successful.
|
||||
* IPCOM_ERR_NO_MEMORY - the 'response_opt' buffer was not large enough.
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipdhcps6_prefix_add_del_prefixes(Ipdhcps6_subnet_entry *subnet,
|
||||
Ipdhcps6_host *host,
|
||||
Ipdhcps6_option_iaprefix *response_opt,
|
||||
Ip_u16 response_optlen,
|
||||
Ip_u16 *bytes_written,
|
||||
Ip_bool add)
|
||||
{
|
||||
Ipdhcps6_prefix *prefix;
|
||||
Ip_u16 written;
|
||||
Ip_err err;
|
||||
int i;
|
||||
|
||||
(void) subnet;
|
||||
*bytes_written = 0;
|
||||
for (i = 0; i < IPDHCPS6_PREFIX_PER_USER; i++)
|
||||
{
|
||||
if (host->user.prefix_ids[i][0] == '\0')
|
||||
continue;
|
||||
prefix = ipdhcps6_prefix_get_ptr(host->user.prefix_ids[i]);
|
||||
if (prefix == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG2(WARNING, "Prefix %s was specified for user %s but not found in the prefix database",
|
||||
host->user.prefix_ids[i], host->user.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (add)
|
||||
{
|
||||
err = ipdhcps6_option_add_iaprefix(response_opt,
|
||||
(Ip_u16) (response_optlen - *bytes_written),
|
||||
&written,
|
||||
prefix);
|
||||
if (err != IPCOM_SUCCESS)
|
||||
return err;
|
||||
*bytes_written += written;
|
||||
response_opt = (Ipdhcps6_option_iaprefix *) ((Ip_u8 *) response_opt + written);
|
||||
}
|
||||
err = ipdhcps6_prefix_add_del_rt(host->ifindex, &prefix->prefix, prefix->prefix_len, add);
|
||||
}
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_prefix_renew_prefixes
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns: IPCOM_SUCCESS - operation was successful.
|
||||
* IPCOM_ERR_NO_MEMORY - the 'response_opt' buffer was not large enough.
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipdhcps6_prefix_renew_prefixes(Ipdhcps6_subnet_entry *subnet,
|
||||
Ipdhcps6_host *host,
|
||||
Ipdhcps6_option *request_ia_pd_opt,
|
||||
Ipdhcps6_option_iaprefix *response_opt,
|
||||
Ip_u16 response_optlen,
|
||||
Ip_u16 *bytes_written)
|
||||
{
|
||||
Ipdhcps6_prefix *prefix;
|
||||
Ipdhcps6_option_iaprefix *response_ptr;
|
||||
Ipdhcps6_option_iaprefix *request_ptr;
|
||||
Ipdhcps6_option_iaprefix iaprefix;
|
||||
const Ip_u16 iaprefix_len = 25;
|
||||
Ip_u16 id_pd_opt_len;
|
||||
Ip_u16 request_offset;
|
||||
Ip_u16 request_iaprefix_len;
|
||||
|
||||
(void)subnet;
|
||||
id_pd_opt_len = (Ip_u16) (ipdhcps6_get_u16(&request_ia_pd_opt->len)
|
||||
- ip_offsetof(struct Ipdhcps6_option_prefix_delegation_data, options)
|
||||
- IPDHCPS6_OPTION_HDR_LEN);
|
||||
|
||||
ipcom_memset(&prefix, 0, sizeof(prefix));
|
||||
|
||||
ipdhcps6_set_u16(&iaprefix.code, IPDHCPS6_OPTION_IAPREFIX);
|
||||
ipdhcps6_set_u16(&iaprefix.len, iaprefix_len);
|
||||
*bytes_written = 0;
|
||||
for (request_offset = 0; request_offset < id_pd_opt_len;)
|
||||
{
|
||||
/* Point to the IAPREFIX option to process in the reqeust */
|
||||
request_ptr = (Ipdhcps6_option_iaprefix *)
|
||||
((Ip_u8 *) request_ia_pd_opt->data.ia_pd.options + request_offset);
|
||||
|
||||
if (response_optlen < *bytes_written + iaprefix_len + IPDHCPS6_OPTION_HDR_LEN)
|
||||
/* The OPTION_IAPREFIX does not fit into the response buffer */
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
|
||||
ipcom_memcpy(IPDHCPS6_OPTION_IAPREFIX_GET_PREFIX_PTR(&iaprefix),
|
||||
IPDHCPS6_OPTION_IAPREFIX_GET_PREFIX_PTR(request_ptr),
|
||||
sizeof(struct Ip_in6_addr));
|
||||
IPDHCPS6_OPTION_IAPREFIX_SET_LEN(&iaprefix, IPDHCPS6_OPTION_IAPREFIX_GET_LEN(request_ptr));
|
||||
|
||||
prefix = ipdhcps6_prefix_get_ptr_from_host(host,
|
||||
IPDHCPS6_OPTION_IAPREFIX_GET_PREFIX_PTR(&iaprefix),
|
||||
IPDHCPS6_OPTION_IAPREFIX_GET_LEN(&iaprefix));
|
||||
if (prefix == IP_NULL)
|
||||
{
|
||||
/* This prefix is no longer used by the subnet */
|
||||
iaprefix.preferred_lifetime = 0;
|
||||
iaprefix.valid_lifetime = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Extend the lifetime another period */
|
||||
ipdhcps6_set_u32(&iaprefix.preferred_lifetime, prefix->preferred);
|
||||
ipdhcps6_set_u32(&iaprefix.valid_lifetime, prefix->valid);
|
||||
}
|
||||
|
||||
/* Point to where the this IAPREFIX should be written into the response buffer */
|
||||
response_ptr = (Ipdhcps6_option_iaprefix *) ((Ip_u8 *) response_opt + *bytes_written);
|
||||
/* Add the option to the response */
|
||||
ipcom_memcpy(response_ptr, &iaprefix, iaprefix_len + IPDHCPS6_OPTION_HDR_LEN);
|
||||
*bytes_written += iaprefix_len + IPDHCPS6_OPTION_HDR_LEN;
|
||||
|
||||
/* Move to the next IAPREFIX in the reqeust buffer */
|
||||
request_iaprefix_len = ipdhcps6_get_u16(&request_ptr->len);
|
||||
request_offset += request_iaprefix_len + IPDHCPS6_OPTION_HDR_LEN;
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_prefix_process_request
|
||||
*===========================================================================
|
||||
* Description: Adds prefix to the requesting router (using OPTION_IA_PD).
|
||||
* Parameters: msg - The message type in the request.
|
||||
* host - The entry for the requesting router.
|
||||
* opt - The OPTION_IA_PD option sent by the requesting router.
|
||||
* response_opt - Pointer into the response buffer where the
|
||||
* OPTION_IA_PD options containing the prefixes should be written.
|
||||
* response_optlen - The length of the 'reponse_opt'
|
||||
* bytes_written - Number of bytes written to 'opt' or the requeried
|
||||
* length of 'opt' if failed with IPCOM_ERR_NO_MEMORY.
|
||||
* Returns: IPCOM_SUCCESS - operation was successful.
|
||||
* IPCOM_ERR_NO_MEMORY - the 'response_opt'. was to small.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_prefix_process_request(Ip_u16 msg_type,
|
||||
Ipdhcps6_subnet_entry *subnet,
|
||||
Ipdhcps6_host *host,
|
||||
Ipdhcps6_option *opt,
|
||||
Ipdhcps6_option *response_opt,
|
||||
Ip_u16 response_optlen,
|
||||
Ip_u16 *bytes_written)
|
||||
{
|
||||
Ip_u16 ia_pd_opt_len;
|
||||
Ipdhcps6_option_iaprefix *iaprefix;
|
||||
Ip_err err;
|
||||
Ip_u16 hdr_len;
|
||||
|
||||
*bytes_written = 0;
|
||||
ia_pd_opt_len = ipdhcps6_get_u16(&opt->len);
|
||||
hdr_len = ip_offsetof(struct Ipdhcps6_option_prefix_delegation_data, options);
|
||||
if (ia_pd_opt_len != hdr_len)
|
||||
{
|
||||
if (ia_pd_opt_len < hdr_len
|
||||
|| ipdhcps6_option_check((Ipdhcps6_option *) opt->data.ia_pd.options,
|
||||
(Ip_u16) (ia_pd_opt_len - hdr_len)))
|
||||
{
|
||||
/* Error in length field in the OPTION_IA_PD option, drop the message */
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (subnet == IP_NULL)
|
||||
{
|
||||
/* No configuration for the subnet the requesting router is located at */
|
||||
return ipdhcps6_option_add_status_code(response_opt, response_optlen,
|
||||
bytes_written, IPDHCPS6_CODE_NO_PREFIX_AVAIL,
|
||||
"No configuration create for the subnet from where the request originates.");
|
||||
}
|
||||
|
||||
if (ipdhcps6_host_has_prefix(host) == IP_FALSE)
|
||||
{
|
||||
return ipdhcps6_option_add_status_code(response_opt, response_optlen,
|
||||
bytes_written, IPDHCPS6_CODE_NO_PREFIX_AVAIL,
|
||||
"The host has not been given any prefixes.");
|
||||
}
|
||||
|
||||
ia_pd_opt_len = ip_offsetof(struct Ipdhcps6_option_prefix_delegation_data, options);
|
||||
if (response_optlen < ia_pd_opt_len + IPDHCPS6_OPTION_HDR_LEN)
|
||||
/* Not the response buffer is not big enough to hold the IPDHCPS6_OPTION_IA_PD header */
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
|
||||
/* Add the IPDHCPS6_OPTION_IA_PD header */
|
||||
ipdhcps6_set_u16(&response_opt->code, IPDHCPS6_OPTION_IA_PD);
|
||||
ipcom_memcpy(&response_opt->data.ia_pd.iaid, opt->data.ia_pd.iaid, sizeof(response_opt->data.ia_pd.iaid));
|
||||
/* Let the client calculate the T1 and T2 times */
|
||||
ipdhcps6_set_u32(&response_opt->data.ia_pd.t1, 0);
|
||||
ipdhcps6_set_u32(&response_opt->data.ia_pd.t2, 0);
|
||||
response_optlen -= ia_pd_opt_len + IPDHCPS6_OPTION_HDR_LEN;
|
||||
|
||||
/* Pointer to where the first IPDHCPS6_OPTION_IAPREFIX should be written */
|
||||
iaprefix = response_opt->data.ia_pd.options;
|
||||
|
||||
switch (msg_type)
|
||||
{
|
||||
case IPDHCPS6_MSG_SOLICIT:
|
||||
case IPDHCPS6_MSG_REQUEST:
|
||||
err = ipdhcps6_prefix_add_del_prefixes(subnet, host, iaprefix, response_optlen, bytes_written, IP_TRUE);
|
||||
break;
|
||||
case IPDHCPS6_MSG_RELEASE:
|
||||
err = ipdhcps6_prefix_add_del_prefixes(subnet, host, iaprefix, response_optlen, bytes_written, IP_FALSE);
|
||||
break;
|
||||
case IPDHCPS6_MSG_RENEW:
|
||||
case IPDHCPS6_MSG_REBIND:
|
||||
err = ipdhcps6_prefix_renew_prefixes(subnet, host, opt, iaprefix, response_optlen, bytes_written);
|
||||
break;
|
||||
default:
|
||||
/* This message type should not forward here */
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*bytes_written += ia_pd_opt_len;
|
||||
ipdhcps6_set_u16(&response_opt->len, *bytes_written);
|
||||
*bytes_written += IPDHCPS6_OPTION_HDR_LEN;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_prefix_new_db
|
||||
*===========================================================================
|
||||
* Description: Deletes all elements in the subnet database, memory for
|
||||
* the route table holding the entries is also deleted.
|
||||
* Parameters: subnets - The subnet database to delete.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ipcom_hash *
|
||||
ipdhcps6_prefix_new_db(void)
|
||||
{
|
||||
return ipcom_hash_new((Ipcom_hash_obj_func) ipdhcps6_prefix_obj_hash,
|
||||
(Ipcom_hash_key_func) ipdhcps6_prefix_key_hash,
|
||||
(Ipcom_hash_cmp_func) ipdhcps6_prefix_hash_cmp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_prefix_delete_db
|
||||
*===========================================================================
|
||||
* Description: Frees all prefix entries in the list.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_prefix_delete_db(Ipcom_hash *prefix_db)
|
||||
{
|
||||
if(prefix_db != IP_NULL)
|
||||
{
|
||||
ipcom_hash_for_each(prefix_db,
|
||||
(Ipcom_hash_foreach_cb_func) ipdhcps6_prefix_free_cb,
|
||||
IP_NULL);
|
||||
ipcom_hash_delete(prefix_db);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_prefix_add
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_prefix_add(Ipdhcps6_prefix *prefix)
|
||||
{
|
||||
Ipdhcps6_prefix *p = IP_NULL;
|
||||
Ip_err err;
|
||||
|
||||
if (ipdhcps6 == IP_NULL || IP_BIT_ISFALSE(ipdhcps6->flags, IPDHCPS6_FLAG_OPEN))
|
||||
return IPCOM_ERR_NOT_OPENED;
|
||||
|
||||
ipcom_mutex_lock(ipdhcps6->db.mutex);
|
||||
|
||||
if (ipdhcps6_prefix_get_ptr(prefix->key) != IP_NULL)
|
||||
{
|
||||
err = IPCOM_ERR_DUPLICATE;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
p = ipcom_malloc(sizeof(Ipdhcps6_prefix));
|
||||
if (p == IP_NULL)
|
||||
{
|
||||
err = IPCOM_ERR_NO_MEMORY;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
ipcom_memcpy(p, prefix, sizeof(Ipdhcps6_prefix));
|
||||
if ((err = ipcom_hash_add(ipdhcps6->db.prefixes, p)) != IPCOM_SUCCESS)
|
||||
goto errout;
|
||||
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
errout:
|
||||
ipcom_free(p);
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_subnet_delete
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_prefix_delete(Ipdhcps6_prefix *prefix)
|
||||
{
|
||||
Ipdhcps6_prefix *p;
|
||||
Ip_err err = IPCOM_SUCCESS;
|
||||
|
||||
if (ipdhcps6 == IP_NULL || IP_BIT_ISFALSE(ipdhcps6->flags, IPDHCPS6_FLAG_OPEN))
|
||||
return IPCOM_ERR_NOT_OPENED;
|
||||
|
||||
ipcom_mutex_lock(ipdhcps6->db.mutex);
|
||||
|
||||
if ((p = ipdhcps6_prefix_get_ptr(prefix->key)) == IP_NULL)
|
||||
{
|
||||
err = IPCOM_ERR_NOT_FOUND;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
(void) ipcom_hash_remove(ipdhcps6->db.prefixes, p);
|
||||
ipcom_free(p);
|
||||
|
||||
cleanup:
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_subnet_list
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_prefix_list(Ipdhcps6_prefix prefix[], int *num_elem)
|
||||
{
|
||||
Ipdhcps6_prefix_list_data cb_data;
|
||||
|
||||
if (ipdhcps6 == IP_NULL || IP_BIT_ISFALSE(ipdhcps6->flags, IPDHCPS6_FLAG_OPEN))
|
||||
return IPCOM_ERR_NOT_OPENED;
|
||||
|
||||
ipcom_mutex_lock(ipdhcps6->db.mutex);
|
||||
|
||||
if (prefix == IP_NULL)
|
||||
{
|
||||
*num_elem = (int)ipdhcps6->db.prefixes->elem;
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
if (*num_elem < (int) ipdhcps6->db.prefixes->elem)
|
||||
{
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
*num_elem = (int)ipdhcps6->db.prefixes->elem;
|
||||
|
||||
cb_data.prefix = prefix;
|
||||
cb_data.index = 0;
|
||||
ipcom_hash_for_each(ipdhcps6->db.prefixes,
|
||||
(Ipcom_hash_foreach_cb_func) ipdhcps6_prefix_list_cb,
|
||||
&cb_data);
|
||||
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipdhcps6_prefix.h,v $ $Revision: 1.2.56.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcps6/src/ipdhcps6_prefix.h,v $
|
||||
* $Author: ulf $ $Date: 2011-11-16 10:33:28 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* Copyright Interpeak AB 2000-2002 <www.interpeak.se>. All rights reserved.
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPDHCPS6_PREFIX_H
|
||||
#define IPDHCPS6_PREFIX_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcps6_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_list.h>
|
||||
|
||||
#include "ipdhcps6.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/* Forward declarations */
|
||||
struct Ipdhcps6_subnet_entry_struct;
|
||||
struct Ipdhcps6_host_struct;
|
||||
struct Ipdhcps6_option_struct;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_prefix_process_request(Ip_u16 msg_type,
|
||||
struct Ipdhcps6_subnet_entry_struct *subnet,
|
||||
struct Ipdhcps6_host_struct *host,
|
||||
struct Ipdhcps6_option_struct *opt,
|
||||
struct Ipdhcps6_option_struct *response_opt,
|
||||
Ip_u16 response_optlen,
|
||||
Ip_u16 *bytes_written);
|
||||
|
||||
IP_GLOBAL Ipcom_hash *
|
||||
ipdhcps6_prefix_new_db(void);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_prefix_delete_db(Ipcom_hash *prefix_db);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,525 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipdhcps6_relay.c,v $ $Revision: 1.13 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcps6/src/ipdhcps6_relay.c,v $
|
||||
* $Author: fguo $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcps6_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_inet.h>
|
||||
#include <ipcom_sock.h>
|
||||
#include <ipcom_sock6.h>
|
||||
#include <ipcom_sysctl.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_sysvar.h>
|
||||
#include <ipnet_routesock.h>
|
||||
|
||||
#include "ipdhcps6_h.h"
|
||||
#include "ipdhcps6_msg.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_relay_route_init_addrs
|
||||
*===========================================================================
|
||||
* Description: Sets the address pointer to point to the correct entry
|
||||
* in the 'rt' buffer.
|
||||
* Parameters: msg - The first socket address in the route socket message.
|
||||
* addrs - The IPNET_RTA_xxx from the message.
|
||||
* sas - Will contain the route pointer.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipdhcps6_relay_route_init_addrs(void *msg, Ip_u32 addrs, struct Ip_sockaddr_in6 **sas)
|
||||
{
|
||||
int i;
|
||||
Ip_size_t offset = 0;
|
||||
|
||||
for (i = 0; i < IPNET_RTAX_MAX; i++)
|
||||
{
|
||||
if (IP_BIT_ISSET(addrs, 1 << i))
|
||||
{
|
||||
sas[i] = (struct Ip_sockaddr_in6 *) &((Ip_u8 *) msg)[offset];
|
||||
offset += IPCOM_SA_LEN_GET(sas[i]);
|
||||
}
|
||||
else
|
||||
sas[i] = IP_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_relay_get_scope_weight
|
||||
*===========================================================================
|
||||
* Description: Return relative scope.
|
||||
* Parameters: addr - An IPv6 address
|
||||
* Returns: An integer where bigger value means higher scope.
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipdhcps6_relay_get_scope_weight(IP_CONST struct Ip_in6_addr *addr)
|
||||
{
|
||||
if (IP_IN6_IS_ADDR_AGGR_GLOB_UNICAST(addr))
|
||||
return 2;
|
||||
if (IP_IN6_IS_ADDR_SITE_LOCAL(addr))
|
||||
return 1;
|
||||
if (IP_IN6_IS_ADDR_LINK_LOCAL(addr) || IP_IN6_IS_ADDR_UNSPECIFIED(addr))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_relay_get_link_address
|
||||
*===========================================================================
|
||||
* Description: Returns the interface address with the broadest scope on the
|
||||
* specified link.
|
||||
* Parameters: ifindex - Interface index of a local interface.
|
||||
* link_addr - Buffer where the link local address will
|
||||
* be stored.
|
||||
* Returns: 0 = success
|
||||
* -1 = address could not be returned
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipdhcps6_relay_get_link_address(Ip_u32 ifindex, struct Ip_in6_addr *link_addr)
|
||||
{
|
||||
int name[6];
|
||||
int ret = -1;
|
||||
Ip_u8 *if_data = IP_NULL;
|
||||
struct Ipnet_ifa_msghdr *ifa;
|
||||
struct Ipnet_if_msghdr *ifm;
|
||||
struct Ip_sockaddr_in6 *addrs[IPNET_RTAX_MAX];
|
||||
Ip_size_t if_data_len;
|
||||
Ip_size_t if_data_offset;
|
||||
Ip_size_t offset;
|
||||
int scope_weight;
|
||||
IP_CONST struct Ip_in6_addr *selected_addr = &ip_in6addr_any;
|
||||
|
||||
/* Find out our link local address on this interface */
|
||||
name[0] = IP_CTL_NET;
|
||||
name[1] = IP_AF_ROUTE;
|
||||
name[2] = 0;
|
||||
name[3] = IP_AF_INET6;
|
||||
name[4] = IP_NET_RT_IFLIST;
|
||||
name[5] = (int)ifindex;
|
||||
|
||||
if (ipcom_sysctl(name, 6, IP_NULL, &if_data_len, IP_NULL, 0) < 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipdhcps6_relay_get_link_address: ipcom_sysctl() failed: %s",
|
||||
ipcom_strerror(ipcom_errno));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if_data = ipcom_malloc(if_data_len);
|
||||
if (if_data == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipdhcps6_relay_get_link_address: out of memory");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (ipcom_sysctl(name, 6, if_data, &if_data_len, IP_NULL, 0) < 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipdhcps6_relay_get_link_address: ipcom_sysctl() failed: %s",
|
||||
ipcom_strerror(ipcom_errno));
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ifm = (struct Ipnet_if_msghdr *) &if_data[0];
|
||||
if_data_offset = ifm->ifm_msglen;
|
||||
|
||||
offset = 0;
|
||||
while (offset < if_data_len - if_data_offset)
|
||||
{
|
||||
ifa = (struct Ipnet_ifa_msghdr *) &if_data[if_data_offset + offset];
|
||||
ipdhcps6_relay_route_init_addrs(ifa + 1, ifa->ifam_addrs, addrs);
|
||||
|
||||
offset += ifa->ifam_msglen;
|
||||
|
||||
scope_weight = ipdhcps6_relay_get_scope_weight(&addrs[IPNET_RTAX_IFA]->sin6_addr);
|
||||
if (scope_weight > ipdhcps6_relay_get_scope_weight(selected_addr))
|
||||
/* This address has broader scope the last selected address */
|
||||
selected_addr = &addrs[IPNET_RTAX_IFA]->sin6_addr;
|
||||
}
|
||||
|
||||
if (selected_addr == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG1(INFO, "ipdhcps6_relay_get_link_address: no address found address on interface %u using ::",
|
||||
ifindex);
|
||||
selected_addr = &ip_in6addr_any;
|
||||
}
|
||||
|
||||
|
||||
IPDHCPS6_SET_IN6_ADDR(link_addr, selected_addr);
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
ipcom_free(if_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_relay_get_next_hop_addr
|
||||
*===========================================================================
|
||||
* Description: Sets the IPv6 address and UDP port of the next hop server/relay.
|
||||
* Parameters: ifindex - The interface the request was received at.
|
||||
* response_addr - Will contain the response address.
|
||||
* response_ifindex - Will be set if 'response_addr' contains a
|
||||
* multicast address.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipdhcps6_relay_get_next_hop_addr(Ip_u32 ifindex,
|
||||
struct Ip_sockaddr_in6 *response_addr,
|
||||
Ip_u32 *response_ifindex)
|
||||
{
|
||||
char *sysvar_name = ipdhcps6->addr_str;
|
||||
char *ifname;
|
||||
char next_hop_addr[IP_INET6_ADDRSTRLEN];
|
||||
Ip_size_t next_hop_addr_size = sizeof(next_hop_addr);
|
||||
|
||||
ipcom_strcpy(sysvar_name, "ipdhcps6.relay.map.");
|
||||
ifname = sysvar_name + ipcom_strlen(sysvar_name);
|
||||
|
||||
if (ipcom_if_indextoname(ifindex, ifname) == IP_NULL)
|
||||
/* The interface has been detached */
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
if (ipcom_sysvar_get(sysvar_name, next_hop_addr, &next_hop_addr_size)
|
||||
== IP_NULL)
|
||||
{
|
||||
IPCOM_LOG1(INFO,
|
||||
"Did not relay message since no relay mapping was specified for interface %d",
|
||||
ifindex);
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
}
|
||||
|
||||
|
||||
*response_ifindex = ipcom_if_nametoindex(next_hop_addr);
|
||||
if (*response_ifindex)
|
||||
/* The next hop address was an interface name */
|
||||
IPDHCPS6_SET_IN6_ADDR(&response_addr->sin6_addr,
|
||||
&ipdhcps6_all_dhcp_servers);
|
||||
else if (ipcom_getsockaddrbyaddr(IP_AF_INET6,
|
||||
next_hop_addr,
|
||||
(struct Ip_sockaddr *) response_addr) < 0)
|
||||
{
|
||||
IPCOM_LOG1(INFO,
|
||||
"'%s' is not a valid unicast IPv6 address, discarding message",
|
||||
response_addr);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
response_addr->sin6_port = ip_htons(ipdhcps6_server_port);
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_relay_do_forward
|
||||
*===========================================================================
|
||||
* Description: Relays a request from a client or another relay agent.
|
||||
* Parameters: msg - The received message, will contain the reply if such
|
||||
* should be sent.
|
||||
* hop_count - The number of times the request has already been
|
||||
* forwarded.
|
||||
* Returns: IPCOM_SUCCESS - message was processed successfully (dropped
|
||||
* messages also counts as successful processing).
|
||||
* IPCOM_ERR_FAILED - critical error encountered.
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipdhcps6_relay_do_forward(Ipdhcps6_message *msg, Ip_u8 hop_count)
|
||||
{
|
||||
Ipdhcps6_relay_msg_hdr *relay_msg;
|
||||
Ip_u16 opts_buf_len;
|
||||
Ipdhcps6_option *opt;
|
||||
Ip_u16 bytes_written;
|
||||
Ip_err err;
|
||||
|
||||
if (hop_count >= ipdhcps6->hop_count_limit)
|
||||
{
|
||||
IPCOM_LOG2(INFO, "Discarding message since the hop count (%u) is too high (%u)",
|
||||
hop_count, ipdhcps6->hop_count_limit);
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
if (msg->recv_buf_len + IPDHCP_RELAY_MSG_HDR_LEN + 8
|
||||
> IPDHCPS6_RECV_BUF_SIZE)
|
||||
{
|
||||
IPCOM_LOG1(WARNING,
|
||||
"Discarding message since it is too big to be relayed, increase IPDHCPS6_RECV_BUF_SIZE (%d)",
|
||||
IPDHCPS6_RECV_BUF_SIZE);
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
err = ipdhcps6_relay_get_next_hop_addr(msg->ifindex,
|
||||
&msg->response_addr,
|
||||
&msg->response_ifindex);
|
||||
if (err != IPCOM_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Fix for WIND00195425 start */
|
||||
if (IP_TRUE == IP_IN6_IS_ADDR_MULTICAST(&msg->response_addr.sin6_addr))
|
||||
{
|
||||
msg->mhop_limit = IP_TRUE;
|
||||
}
|
||||
/* Fix for WIND00195425 end */
|
||||
|
||||
/* Add a relay header */
|
||||
relay_msg = (Ipdhcps6_relay_msg_hdr *) msg->send_buf;
|
||||
relay_msg->type = IPDHCPS6_MSG_RELAY_FORW;
|
||||
|
||||
if (IPDHCPS6_MSG_RELAY_FORW == ((Ipdhcps6_relay_msg_hdr *) msg->recv_buf)->type)
|
||||
{
|
||||
relay_msg->hop_count = hop_count + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the relay agent received the message to be relayed from a client,
|
||||
* the hop-count in the Relay-forward message is set to 0 (defect WIND00190002)
|
||||
*/
|
||||
relay_msg->hop_count = 0;
|
||||
}
|
||||
ipdhcps6_relay_get_link_address(msg->ifindex, &relay_msg->link_addr);
|
||||
IPDHCPS6_SET_IN6_ADDR(&relay_msg->peer_addr,
|
||||
&msg->peer_addr.sin6_addr);
|
||||
|
||||
ipdhcps6_msg_first_response_opt(msg, &opt, &opts_buf_len);
|
||||
|
||||
err = ipdhcps6_option_add_relay_message(opt,
|
||||
opts_buf_len,
|
||||
&bytes_written,
|
||||
msg->recv_buf,
|
||||
msg->recv_buf_len);
|
||||
if (err != IPCOM_SUCCESS)
|
||||
return err;
|
||||
ipdhcps6_msg_next_response_opt(bytes_written,
|
||||
msg,
|
||||
&opt,
|
||||
&opts_buf_len);
|
||||
|
||||
err = ipdhcps6_option_add_interface_id(opt,
|
||||
opts_buf_len,
|
||||
&bytes_written,
|
||||
msg->ifindex);
|
||||
if (err != IPCOM_SUCCESS)
|
||||
return err;
|
||||
ipdhcps6_msg_next_response_opt(bytes_written,
|
||||
msg,
|
||||
&opt,
|
||||
&opts_buf_len);
|
||||
|
||||
msg->send_response = IP_TRUE;
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_relay_do_forward_client
|
||||
*===========================================================================
|
||||
* Description: Relays a request from a client.
|
||||
* Parameters: msg - The received message, will contain the reply if such
|
||||
* should be sent.
|
||||
* Returns: IPCOM_SUCCESS - message was processed successfully (dropped
|
||||
* messages also counts as successful processing).
|
||||
* IPCOM_ERR_FAILED - critical error encountered.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_relay_do_forward_client(Ipdhcps6_message *msg)
|
||||
{
|
||||
return ipdhcps6_relay_do_forward(msg, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_relay_do_forward_relay
|
||||
*===========================================================================
|
||||
* Description: Relays a request from another relay agent.
|
||||
* Parameters: msg - The received message, will contain the reply if such
|
||||
* should be sent.
|
||||
* Returns: IPCOM_SUCCESS - message was processed successfully (dropped
|
||||
* messages also counts as successful processing).
|
||||
* IPCOM_ERR_FAILED - critical error encountered.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_relay_do_forward_relay(Ipdhcps6_message *msg)
|
||||
{
|
||||
Ipdhcps6_relay_msg_hdr *recv_relay_msg;
|
||||
|
||||
recv_relay_msg = (Ipdhcps6_relay_msg_hdr *) msg->recv_buf;
|
||||
return ipdhcps6_relay_do_forward(msg, recv_relay_msg->hop_count);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_relay_process_reply
|
||||
*===========================================================================
|
||||
* Description: Processes a response on a previously relayed message.
|
||||
* Parameters: msg - The received message, will contain the reply if such
|
||||
* should be sent.
|
||||
* in_opts - Points to the first option included in the incoming
|
||||
* message. All options are packed into this buffer without padding.
|
||||
* in_opts_len - The length of all options in the buffer pointer to
|
||||
* by 'in_opts'.
|
||||
* Returns: IPCOM_SUCCESS - message was processed successfully (dropped
|
||||
* messages also counts as successful processing).
|
||||
* IPCOM_ERR_FAILED - critical error encountered.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_relay_process_reply(Ipdhcps6_message *msg,
|
||||
Ipdhcps6_option *in_opts,
|
||||
Ip_u16 in_opts_len)
|
||||
{
|
||||
Ipdhcps6_relay_msg_hdr *relay_msg = (Ipdhcps6_relay_msg_hdr *) msg->recv_buf;
|
||||
Ipdhcps6_option *relay_message_opt;
|
||||
Ipdhcps6_option *interface_id_opt;
|
||||
|
||||
relay_message_opt = ipdhcps6_option_get_ptr(in_opts,
|
||||
in_opts_len,
|
||||
IPDHCPS6_OPTION_RELAY_MSG);
|
||||
interface_id_opt = ipdhcps6_option_get_ptr(in_opts,
|
||||
in_opts_len,
|
||||
IPDHCPS6_OPTION_INTERFACE_ID);
|
||||
if (relay_message_opt == IP_NULL || interface_id_opt == IP_NULL)
|
||||
{
|
||||
/* This relay always includes the interface ID option */
|
||||
IPCOM_LOG0(INFO,
|
||||
"Ignoring relay-reply packet since it does not contain a "
|
||||
"relay message option and interface ID option");
|
||||
return IPCOM_ERR_IGNORED_PACKET;
|
||||
}
|
||||
|
||||
if (ipdhcps6_get_u16(&interface_id_opt->len) != sizeof(Ip_u32))
|
||||
{
|
||||
/* This relay always includes the interface ID option */
|
||||
IPCOM_LOG0(INFO,
|
||||
"Ignoring relay-reply packet since the length of the interface ID options is not 4");
|
||||
return IPCOM_ERR_IGNORED_PACKET;
|
||||
}
|
||||
|
||||
msg->send_buf_len = ipdhcps6_get_u16(&relay_message_opt->len);
|
||||
ip_assert(msg->send_buf_len <= msg->send_buf_maxlen);
|
||||
ipcom_memcpy(msg->send_buf,
|
||||
&relay_message_opt->data,
|
||||
msg->send_buf_len);
|
||||
|
||||
msg->response_ifindex = ipdhcps6_get_u32((Ip_u32 *) &interface_id_opt->data);
|
||||
|
||||
IPDHCPS6_SET_IN6_ADDR(&msg->response_addr.sin6_addr, &relay_msg->peer_addr);
|
||||
if (IP_IN6_IS_ADDR_LINK_LOCAL(&msg->response_addr.sin6_addr))
|
||||
msg->response_addr.sin6_scope_id = msg->response_ifindex;
|
||||
else
|
||||
msg->response_addr.sin6_scope_id = 0;
|
||||
|
||||
/* Don't change port if we're forwarding to another relay */
|
||||
if (((Ipdhcps6_msg_hdr *) msg->send_buf)->type == IPDHCPS6_MSG_RELAY_REPL)
|
||||
msg->response_addr.sin6_port = ip_htons(ipdhcps6_server_port);
|
||||
else
|
||||
msg->response_addr.sin6_port = ip_htons(ipdhcps6_client_port);
|
||||
|
||||
msg->send_response = IP_TRUE;
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,512 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_RCPL8_2024030303 $ $RCSfile: ipdhcps6_subnet.c,v $ $Revision: 1.23.18.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcps6/src/ipdhcps6_subnet.c,v $
|
||||
* $Author: jchang1 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcps6_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_list.h>
|
||||
#include <ipcom_hash.h>
|
||||
#include <ipcom_route.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipnet.h>
|
||||
|
||||
#include "ipdhcps6.h"
|
||||
#include "ipdhcps6_h.h"
|
||||
#include "ipdhcps6_subnet.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
struct Ipdhcps6_subnet_list_cb_data
|
||||
{
|
||||
/* The result of the operation */
|
||||
Ip_err err;
|
||||
|
||||
/* Number of elements in the route table */
|
||||
int num_elements;
|
||||
|
||||
/* The size of the 'subnets' array */
|
||||
int subnet_elements;
|
||||
/* Array of subnet structures, can be IP_NULL in which case the number
|
||||
of elements is stored in 'num_elements' */
|
||||
Ipdhcps6_subnet *subnets;
|
||||
};
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_subnet_notify_func
|
||||
*===========================================================================
|
||||
* Description: Handles callbacks from the subnet table.
|
||||
* Parameters: rtab - The table head.
|
||||
* e - The entry that caused this function to be called.
|
||||
* code - The reason why this function was called.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipdhcps6_subnet_notify_func(Ipcom_route *rtab, Ipdhcps6_subnet_entry *sn, int code)
|
||||
{
|
||||
(void) rtab;
|
||||
if (code == IPCOM_ROUTE_CODE_REMOVE || code == IPCOM_ROUTE_CODE_DUPLICATE)
|
||||
{
|
||||
ipdhcps6_option_delete_db(sn->options);
|
||||
ipdhcps6_pool_delete_from_subnet(sn);
|
||||
ipcom_free(sn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_subnet_delete_db
|
||||
*===========================================================================
|
||||
* Description: Deletes all elements in the subnet database, memory for
|
||||
* the route table holding the entries is also deleted.
|
||||
* Parameters: subnets - The subnet database to delete.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_bool
|
||||
ipdhcps6_subnet_list_cb(Ipdhcps6_subnet_entry *sn,
|
||||
struct Ipdhcps6_subnet_list_cb_data *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = data->num_elements++;
|
||||
if (data->subnets == IP_NULL)
|
||||
return IP_FALSE;
|
||||
|
||||
if (data->num_elements > data->subnet_elements)
|
||||
{
|
||||
data->err = IPCOM_ERR_NO_MEMORY;
|
||||
return IP_FALSE;
|
||||
}
|
||||
|
||||
ipcom_memcpy(&data->subnets[i], &sn->subnet, sizeof(sn->subnet));
|
||||
data->subnets[i].prefix = sn->subnet.addr;
|
||||
data->subnets[i].ifindex = (Ip_u32)sn->subnet.ifindex;
|
||||
data->subnets[i].prefix_len = sn->prefix_len;
|
||||
return IP_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_create_mask
|
||||
*===========================================================================
|
||||
* Description: Creates a mask which contains 'netbits' number of '1' bits
|
||||
* staring with the most significant bit.
|
||||
* Parameters: mask - Mask buffer.
|
||||
* netbits - Number of bits.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_create_mask(struct Ip_in6_addr *mask, int netbits)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i = 0; i < netbits / 8; i++)
|
||||
mask->in6.addr8[i] = 0xff;
|
||||
for (j = 0; j < netbits % 8; j++)
|
||||
IP_BIT_SET(mask->in6.addr8[i], 0x80 >> j);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_subnet_get_from_addr
|
||||
*===========================================================================
|
||||
* Description: Returns the subnet entry matching the sender of this message
|
||||
* (DHCPv6 client address, not relay address).
|
||||
* Parameters: addr - The address of the requesting DHCPv6 client.
|
||||
* ifindex - The interface this message was received on.
|
||||
* Returns: The matching subnet or IP_NULL if no match was found.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ipdhcps6_subnet_entry *
|
||||
ipdhcps6_subnet_get_from_addr(struct Ip_in6_addr *addr, int ifindex)
|
||||
{
|
||||
Ipdhcps6_subnet_key key;
|
||||
|
||||
IPDHCPS6_SET_IN6_ADDR(&key.addr, addr);
|
||||
key.ifindex = ifindex;
|
||||
return (Ipdhcps6_subnet_entry *)
|
||||
ipcom_route_lookup(ipdhcps6->db.subnets, &key, IP_NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_subnet_get
|
||||
*===========================================================================
|
||||
* Description: Returns the subnet entry matching the sender of this message
|
||||
* (DHCPv6 client address, not relay address).
|
||||
* Parameters: addr - The address of the requesting DHCPv6 client.
|
||||
* ifindex - The interface this message was received on.
|
||||
* Returns: The matching subnet or IP_NULL if no match was found.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ipdhcps6_subnet_entry *
|
||||
ipdhcps6_subnet_get(struct Ip_in6_addr *subnet, int ifindex)
|
||||
{
|
||||
Ip_bool perfect_match;
|
||||
Ipdhcps6_subnet_entry *sn;
|
||||
Ipdhcps6_subnet_key key;
|
||||
|
||||
IPDHCPS6_SET_IN6_ADDR(&key.addr, subnet);
|
||||
key.ifindex = ifindex;
|
||||
|
||||
sn = (Ipdhcps6_subnet_entry *)
|
||||
ipcom_route_lookup(ipdhcps6->db.subnets, &key, &perfect_match);
|
||||
|
||||
if (sn != IP_NULL && perfect_match)
|
||||
return sn;
|
||||
return IP_NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_subnet_new_db
|
||||
*===========================================================================
|
||||
* Description: Creates a new radix tree to store subnet entries in.
|
||||
* Parameters:
|
||||
* Returns: A empty radix tree.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ipcom_route *
|
||||
ipdhcps6_subnet_new_db(void)
|
||||
{
|
||||
return ipcom_route_new_table(sizeof(Ipdhcps6_subnet_key) * 8,
|
||||
(Ipcom_route_notify_func) ipdhcps6_subnet_notify_func);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_subnet_remove_subnets
|
||||
*===========================================================================
|
||||
* Description: Remove all subnets in radix tree.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_subnet_remove_subnets(void)
|
||||
{
|
||||
struct Ip_if_nameindex *ni;
|
||||
int i;
|
||||
Ipdhcps6_subnet subnet;
|
||||
|
||||
ni = ipcom_if_nameindex();
|
||||
if (ni == IP_NULL)
|
||||
{
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
for (i = 0; ni[i].if_index != 0; i++)
|
||||
{
|
||||
ipdhcps6_subnet_from_ifindex(&subnet, ni[i].if_index);
|
||||
ipdhcps6_subnet_delete(&subnet);
|
||||
}
|
||||
|
||||
ipcom_if_freenameindex(ni);
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_subnet_delete_db
|
||||
*===========================================================================
|
||||
* Description: Deletes all elements in the subnet database, memory for
|
||||
* the route table holding the entries is also deleted.
|
||||
* Parameters: subnets - The subnet database to delete.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_subnet_delete_db(Ipcom_route *subnets)
|
||||
{
|
||||
if (subnets != IP_NULL)
|
||||
ipcom_route_free_table(subnets);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_subnet_from_ifname
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC void
|
||||
ipdhcps6_subnet_from_ifindex(Ipdhcps6_subnet *subnet,
|
||||
Ip_u32 ifindex)
|
||||
{
|
||||
/* The link local addresses are defined by the fe80::/10
|
||||
prefix in RFC 3315 chapter 4.1 */
|
||||
(void)ipcom_inet_pton(IP_AF_INET6, "fe80::", &subnet->prefix);
|
||||
subnet->ifindex = ifindex;
|
||||
subnet->prefix_len = 10;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_subnet_add
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_subnet_add(Ipdhcps6_subnet *subnet)
|
||||
{
|
||||
Ipdhcps6_subnet_entry *sn_entry;
|
||||
char str[40];
|
||||
|
||||
if (ipdhcps6 == IP_NULL || IP_BIT_ISFALSE(ipdhcps6->flags, IPDHCPS6_FLAG_OPEN))
|
||||
return IPCOM_ERR_NOT_OPENED;
|
||||
|
||||
ipcom_mutex_lock(ipdhcps6->db.mutex);
|
||||
|
||||
if (ipdhcps6_subnet_get(&subnet->prefix, (int)subnet->ifindex) != IP_NULL)
|
||||
{
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
return IPCOM_ERR_DUPLICATE;
|
||||
}
|
||||
|
||||
sn_entry = ipcom_calloc(1, sizeof(*sn_entry));
|
||||
if (sn_entry == IP_NULL)
|
||||
goto out_of_memory;
|
||||
|
||||
sn_entry->subnet.addr = subnet->prefix;
|
||||
sn_entry->subnet.ifindex = (int)subnet->ifindex;
|
||||
sn_entry->hdr.key = &sn_entry->subnet;
|
||||
sn_entry->hdr.mask = &sn_entry->mask;
|
||||
sn_entry->prefix_len = subnet->prefix_len;
|
||||
|
||||
if (IP_IN6_IS_ADDR_LINK_LOCAL(&subnet->prefix))
|
||||
sn_entry->mask.ifindex = ~0u;
|
||||
else
|
||||
sn_entry->mask.ifindex = 0;
|
||||
ipdhcps6_create_mask(&sn_entry->mask.addr, subnet->prefix_len);
|
||||
|
||||
sn_entry->options = ipdhcps6_option_new_db();
|
||||
if (sn_entry->options == IP_NULL)
|
||||
goto out_of_memory;
|
||||
|
||||
if (ipcom_route_add(ipdhcps6->db.subnets, &sn_entry->hdr) != IPCOM_SUCCESS)
|
||||
goto out_of_memory;
|
||||
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
out_of_memory:
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
if (sn_entry != IP_NULL)
|
||||
{
|
||||
if (sn_entry->options != IP_NULL)
|
||||
ipcom_hash_delete(sn_entry->options);
|
||||
ipcom_free(sn_entry);
|
||||
}
|
||||
IPCOM_LOG1(CRIT, "Out of memory when adding subnet %s",
|
||||
ipcom_inet_ntop(IP_AF_INET6, &subnet->prefix, str, sizeof(str)));
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_subnet_delete
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_subnet_delete(Ipdhcps6_subnet *subnet)
|
||||
{
|
||||
Ip_bool perfect_match;
|
||||
Ipcom_route_entry *sn_elem;
|
||||
Ipdhcps6_subnet_key key;
|
||||
|
||||
if (ipdhcps6 == IP_NULL || !IP_BIT_ISSET(ipdhcps6->flags, IPDHCPS6_FLAG_OPEN))
|
||||
return IPCOM_ERR_NOT_OPENED;
|
||||
|
||||
ipcom_mutex_lock(ipdhcps6->db.mutex);
|
||||
|
||||
key.addr = subnet->prefix;
|
||||
key.ifindex = (int)subnet->ifindex;
|
||||
sn_elem = ipcom_route_lookup(ipdhcps6->db.subnets, &key, &perfect_match);
|
||||
if (sn_elem == IP_NULL || perfect_match == IP_FALSE)
|
||||
{
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
return IPCOM_ERR_NOT_FOUND;
|
||||
}
|
||||
(void) ipcom_route_remove(ipdhcps6->db.subnets, sn_elem);
|
||||
|
||||
ipcom_mutex_unlock(ipdhcps6->db.mutex);
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_subnet_delete
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_subnet_list(Ipdhcps6_subnet subnets[], int *num_subnets)
|
||||
{
|
||||
struct Ipdhcps6_subnet_list_cb_data cb_data;
|
||||
|
||||
if (ipdhcps6 == IP_NULL || !IP_BIT_ISSET(ipdhcps6->flags, IPDHCPS6_FLAG_OPEN))
|
||||
return IPCOM_ERR_NOT_OPENED;
|
||||
|
||||
cb_data.num_elements = 0;
|
||||
cb_data.subnet_elements = *num_subnets;
|
||||
cb_data.subnets = subnets;
|
||||
cb_data.err = IPCOM_SUCCESS;
|
||||
|
||||
ipcom_route_walk_tree(ipdhcps6->db.subnets,
|
||||
(Ip_bool(*)(Ipcom_route_entry *, void *)) ipdhcps6_subnet_list_cb,
|
||||
&cb_data);
|
||||
|
||||
*num_subnets = cb_data.num_elements;
|
||||
|
||||
return cb_data.err;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_subnet_to_string
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_subnet_to_string(const Ipdhcps6_subnet *subnet, char *str, int str_len)
|
||||
{
|
||||
int ret;
|
||||
char ifname[IP_IFNAMSIZ];
|
||||
char addr[40];
|
||||
|
||||
if (IP_IN6_IS_ADDR_LINK_LOCAL(&subnet->prefix))
|
||||
ret = ipcom_snprintf(str, (Ip_size_t)str_len, "%s (%s/%d)",
|
||||
ipcom_if_indextoname(subnet->ifindex, ifname),
|
||||
ipcom_inet_ntop(IP_AF_INET6, &subnet->prefix, addr, sizeof(addr)),
|
||||
subnet->prefix_len);
|
||||
else
|
||||
ret = ipcom_snprintf(str, (Ip_size_t)str_len, "%s/%d",
|
||||
ipcom_inet_ntop(IP_AF_INET6, &subnet->prefix, addr, sizeof(addr)),
|
||||
subnet->prefix_len);
|
||||
|
||||
if (ret < 0)
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_RCPL8_2024030303 $ $RCSfile: ipdhcps6_subnet.h,v $ $Revision: 1.4.36.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcps6/src/ipdhcps6_subnet.h,v $
|
||||
* $Author: jchang1 $ $Date: 2022-09-22 09:39:18 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* Copyright Interpeak AB 2000-2002 <www.interpeak.se>. All rights reserved.
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPDHCPS6_SUBNET_H
|
||||
#define IPDHCPS6_SUBNET_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcps6_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
|
||||
#include "ipdhcps6_msg.h"
|
||||
#include "ipdhcps6_subnet.h"
|
||||
#include "ipdhcps6_prefix.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct Ipdhcps6_subnet_key_struct
|
||||
{
|
||||
struct Ip_in6_addr addr;
|
||||
int ifindex;
|
||||
}
|
||||
Ipdhcps6_subnet_key;
|
||||
|
||||
|
||||
/* Subnet structure */
|
||||
typedef struct Ipdhcps6_subnet_entry_struct
|
||||
{
|
||||
Ipcom_route_entry hdr;
|
||||
/* The IPv6 subnet */
|
||||
Ipdhcps6_subnet_key subnet;
|
||||
/* Subnet mask */
|
||||
Ipdhcps6_subnet_key mask;
|
||||
/* Prefix length */
|
||||
int prefix_len;
|
||||
/* Options for this subnet */
|
||||
Ipcom_hash *options;
|
||||
|
||||
/* Will be !=IP_NULL if an address pool has been assigned to this subnet */
|
||||
Ipdhcps6_addr_pool *pools;
|
||||
|
||||
/* Hash table of leases that is currently assigned from the pools
|
||||
The elements are of type Ipdhcps6_lease_addr */
|
||||
Ipcom_hash *active_leases;
|
||||
}
|
||||
Ipdhcps6_subnet_entry;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ipdhcps6_subnet_entry *
|
||||
ipdhcps6_subnet_get_from_addr(struct Ip_in6_addr *addr, int ifindex);
|
||||
|
||||
IP_GLOBAL Ipdhcps6_subnet_entry *
|
||||
ipdhcps6_subnet_get(struct Ip_in6_addr *subnet, int ifindex);
|
||||
|
||||
IP_GLOBAL Ipcom_route *
|
||||
ipdhcps6_subnet_new_db(void);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_subnet_remove_subnets(void);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipdhcps6_subnet_delete_db(Ipcom_route *subnets);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipdhcps6_user.c,v $ $Revision: 1.7.54.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcps6/src/ipdhcps6_user.c,v $
|
||||
* $Author: ulf $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcps6_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_sysvar.h>
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_syslog.h>
|
||||
|
||||
#include "ipdhcps6.h"
|
||||
#include "ipdhcps6_h.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPDHCPS6_USER_SYSVAR_NAME (36 + IPCOM_AUTH_USERNAME_MAX)
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
typedef struct Ipdhcps6_list_cb_data_struct
|
||||
{
|
||||
Ipdhcps6_user *users;
|
||||
int users_len;
|
||||
int num_users;
|
||||
}
|
||||
Ipdhcps6_list_cb_data;
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_user_prefix_ids_from_str
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipdhcps6_user_prefix_ids_from_str(Ipdhcps6_user *user, const char *str_prefixes)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < IPDHCPS6_PREFIX_PER_USER; i++)
|
||||
ipcom_memset(user->prefix_ids[i], 0, IPDHCPS6_KEY_LEN);
|
||||
|
||||
for (i = 0, j = 0; *str_prefixes != '\0'; str_prefixes++)
|
||||
{
|
||||
if (*str_prefixes == ' ')
|
||||
{
|
||||
i = 0;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
if (j >= IPDHCPS6_PREFIX_PER_USER)
|
||||
{
|
||||
IPCOM_LOG2(ERR, "Too many prefixes for user %s, max is %d",
|
||||
user->name, IPDHCPS6_PREFIX_PER_USER);
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
user->prefix_ids[j][i++] = *str_prefixes;
|
||||
}
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_user_list_cb
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipdhcps6_user_list_cb(const char *name, const char *value, int flags,
|
||||
Ipdhcps6_list_cb_data *cb_data)
|
||||
{
|
||||
const char *username;
|
||||
const char *username_end;
|
||||
|
||||
(void) flags;
|
||||
username_end = ipcom_strstr(name, ".ipdhcps6.prefix");
|
||||
if (username_end == IP_NULL)
|
||||
return 0;
|
||||
|
||||
if (++cb_data->num_users * sizeof(Ipdhcps6_user) >= (Ip_size_t) cb_data->users_len
|
||||
&& cb_data->users)
|
||||
{
|
||||
Ipdhcps6_user *user = &cb_data->users[cb_data->num_users - 1];
|
||||
int i = 0;
|
||||
|
||||
username = username_end - 1;
|
||||
while (*username != '.')
|
||||
--username;
|
||||
while (++username != username_end)
|
||||
user->name[i++] = *username;
|
||||
user->name[i] = '\0';
|
||||
|
||||
(void) ipdhcps6_user_prefix_ids_from_str(user, value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_user_get
|
||||
*===========================================================================
|
||||
* Description: Adds a DHCPv6 host to the database.
|
||||
* Parameters: user - The username must be filled in, this function will
|
||||
* fill in all prefixes assigned to this user.
|
||||
* Returns: IPCOM_SUCCESS - operation was successful.
|
||||
* IPCOM_ERR_NOT_FOUND - the user was not found.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipdhcps6_user_get(Ipdhcps6_user *user)
|
||||
{
|
||||
char sysvar_name[IPDHCPS6_USER_SYSVAR_NAME];
|
||||
char prefix_ids[IPDHCPS6_PREFIX_PER_USER * IPDHCPS6_KEY_LEN];
|
||||
Ip_size_t ids_len = sizeof(prefix_ids);
|
||||
|
||||
if (user->name[0] == '\0')
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
|
||||
ipcom_sprintf(sysvar_name, "ipcom.users.%s.ipdhcps6.prefix_list", user->name);
|
||||
if (ipcom_sysvar_get(sysvar_name, prefix_ids, &ids_len) == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG1(DEBUG, "No prefix configuration found for user %s", user->name);
|
||||
return IPCOM_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
return ipdhcps6_user_prefix_ids_from_str(user, prefix_ids);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_user_add
|
||||
*===========================================================================
|
||||
* Description: Fills in all user information for the user 'user->name'.
|
||||
* Parameters: user - The user to find information for.
|
||||
* Returns: IPCOM_SUCCESS - operation was successful.
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_user_add(Ipdhcps6_user *user)
|
||||
{
|
||||
char sysvar_name[IPDHCPS6_USER_SYSVAR_NAME];
|
||||
char prefix_ids[IPDHCPS6_PREFIX_PER_USER * IPDHCPS6_KEY_LEN];
|
||||
int i;
|
||||
|
||||
ipcom_sprintf(sysvar_name, "ipcom.users.%s.ipdhcps6.prefix_list", user->name);
|
||||
prefix_ids[0] = '\0';
|
||||
|
||||
for (i = 0; i < IPDHCPS6_PREFIX_PER_USER; i++)
|
||||
{
|
||||
if (ipcom_strlen(user->prefix_ids[i]) == 0)
|
||||
continue;
|
||||
if (prefix_ids[0] != '\0')
|
||||
ipcom_strcat(prefix_ids, " ");
|
||||
ipcom_strcat(prefix_ids, user->prefix_ids[i]);
|
||||
}
|
||||
|
||||
return ipcom_sysvar_set(sysvar_name, prefix_ids, IPCOM_SYSVAR_FLAG_OVERWRITE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_user_delete
|
||||
*===========================================================================
|
||||
* Description: Deletes a DHCPv6 user from the database.
|
||||
* Parameters: username - The name of the user to delete DHCPv6 config for.
|
||||
* Returns: IPCOM_SUCCESS - operation was successful.
|
||||
* IPCOM_ERR_NOT_FOUND - the subnet or option was not found.
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_user_delete(const char *username)
|
||||
{
|
||||
char sysvar_name[IPDHCPS6_USER_SYSVAR_NAME];
|
||||
|
||||
ipcom_sprintf(sysvar_name, "ipcom.users.%s.ipdhcps6.prefix_list", username);
|
||||
return ipcom_sysvar_unset(sysvar_name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcps6_user_list
|
||||
*===========================================================================
|
||||
* Description: Lists all DHCPv6 users in the database.
|
||||
* Parameters: users - Buffer that will contain the client ID:s.
|
||||
* Can be IP_NULL if the required length of the 'user' buffer
|
||||
* (in bytes) should be returned in 'user_len'.
|
||||
* users_len - The length of the 'users' buffer. Will contain
|
||||
* the actual number of bytes copied to 'user' after return.
|
||||
* Returns: IPCOM_SUCCESS - operation was successful.
|
||||
* IPCOM_ERR_NO_MEMORY - the 'users' buffer was not large enough.
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipdhcps6_user_list(Ipdhcps6_user *users, int *users_len)
|
||||
{
|
||||
Ipdhcps6_list_cb_data cb_data;
|
||||
Ip_err err = IPCOM_SUCCESS;
|
||||
|
||||
cb_data.users = users;
|
||||
cb_data.users_len = *users_len;
|
||||
cb_data.num_users = 0;
|
||||
ipcom_sysvar_for_each("ipcom.users",
|
||||
(int (*)(const char *, const char *, int, void *)) ipdhcps6_user_list_cb,
|
||||
&cb_data);
|
||||
|
||||
if (users && (Ip_size_t) *users_len < cb_data.num_users * sizeof(Ipdhcps6_user))
|
||||
err = IPCOM_ERR_NO_MEMORY;
|
||||
*users_len = cb_data.num_users * sizeof(Ipdhcps6_user);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user