/* ****************************************************************************** * 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 ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipdhcps6_config.h" /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #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 **************************************************************************** */