/* ipmacsec_ioctl.c - MACsec Ioctl implementation */ /* * Copyright (c) 2010 Wind River Systems, Inc. * * The right to copy, distribute, modify, or otherwise make use * of this software may be licensed only pursuant to the terms * of an applicable Wind River license agreement. * */ /* modification history -------------------- 01a,15feb10,mry Created */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* * Implements MACsec Ioctl handlers and interface fns. * This is provided for legacy reasons only. The main interface to MACsec * SecY is via Netlink. */ /* **************************************************************************** * 2 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipmacsec_debug.h" #include "ipmacsec_h.h" #include "ipmacsec.h" #include "ipmacsec_ioctl.h" /* **************************************************************************** * 3 CONFIGURATION **************************************************************************** */ #include "ipmacsec_config.h" /* **************************************************************************** * 4 DEFINES **************************************************************************** */ /* **************************************************************************** * 5 TYPES **************************************************************************** */ /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ IP_GLOBAL int ipmacsec_ioctl(Ipnet_netif *netif, Ip_u32 request, void *data); /* * **************************************************************************** * 8 DATA **************************************************************************** */ /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ /* **************************************************************************** * 10 PRIVATE FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipmacsec_ioctl *=========================================================================== * Description: MACsec Ioctl handler. * Only supports the SecY Enable/Disable operations * Parameters: * Returns: 0 upon success, < 0 upon failure. * */ IPMACSEC_PRIVATE int ipmacsec_ioctl(Ipnet_netif *netif, Ip_u32 request, void *data) { struct Ip_secyreq *secyreq; Ipmacsec_ioctl_cmd cmd; ip_assert(netif); if (request != IP_SIOCXSECY) { #ifdef IPMACSEC_DEBUG_IOCTL IPCOM_LOG1(ERR, "ipmacsec_ioctl :: request 0x%x != IP_SIOCXSECY ", request); #endif return -1; } if (!netif->secy) { #ifdef IPMACSEC_DEBUG_IOCTL IPCOM_LOG1(ERR, "ipmacsec_ioctl :: Null secy for interface %s", netif->ipcom.name); #endif return -1; } secyreq = (struct Ip_secyreq *)data; #ifdef IPMACSEC_DEBUG_IOCTL IPCOM_LOG6(DEBUG2, "MACSEC-IOCTL: interface %s, command %u, data %.2x %.2x %.2x %.2x", netif->ipcom.name, secyreq->command, secyreq->data[0], secyreq->data[1], secyreq->data[2], secyreq->data[3]); #endif cmd = (Ipmacsec_ioctl_cmd)secyreq->command; switch (cmd) { case IPMACSEC_IOCTL_CMD_SECY_ENABLE: return ipmacsec_secy_enable(netif->secy); case IPMACSEC_IOCTL_CMD_SECY_DISABLE: return ipmacsec_secy_disable(netif->secy); default: #ifdef IPMACSEC_DEBUG_IOCTL IPCOM_LOG1(ERR, "ipmacsec_ioctl ::Unrecognized MACsec Ioctl cmd %u", cmd); #endif break; } return 0; } /* **************************************************************************** * 11 PUBLIC FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipmacsec_send_ioctl *=========================================================================== * Description: see "ipmacsec_ioctl.h" * Parameters: * Returns: * */ IP_PUBLIC int ipmacsec_send_ioctl(char *ifname, Ip_u32 command, Ip_u8 *data, Ip_u32 datalen) { int rc = 0, sock = IP_INVALID_SOCKET; struct Ip_secyreq secyreq; if (data && (datalen > sizeof(secyreq.data))) { #ifdef IPMACSEC_DEBUG_IOCTL IPCOM_LOG2(ERR, "ipmacsec_send_ioctl :: datalen too large (%u > %u)\n", datalen, sizeof(secyreq.data)); #endif return -1; } if (datalen && !data) { #ifdef IPMACSEC_DEBUG_IOCTL IPCOM_LOG0(ERR, "ipmacsec_send_ioctl :: Null data"); #endif return -1; } ipcom_memset(&secyreq, 0, sizeof(secyreq)); ipcom_strncpy(secyreq.if_name, ifname, IP_IFNAMSIZ); secyreq.if_name[IP_IFNAMSIZ-1] = '\0'; secyreq.command = command; ipcom_memcpy(secyreq.data, data, datalen); sock = ipcom_socket(IP_PF_PACKET, IP_SOCK_RAW, 0); if (sock == IP_INVALID_SOCKET) { #ifdef IPMACSEC_DEBUG_IOCTL IPCOM_LOG1(ERR, "ipmacsec_send_ioctl :: ipcom_socket() failed, errno: %d\n", ipcom_errno); #endif return -1; } if ((rc = ipcom_socketioctl(sock, IP_SIOCXSECY, &secyreq)) < 0) { #ifdef IPMACSEC_DEBUG_IOCTL int errno = *ipcom_errno_get(); IPCOM_LOG2(ERR, "ipmacsec_send_ioctl :: ioctl(IP_SIOCXSECY) failed (%d: %s)", errno, ipcom_strerror(errno)); #endif } ipcom_socketclose(sock); return rc; }