220 lines
6.3 KiB
C
220 lines
6.3 KiB
C
/* 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 <ipcom_type.h>
|
|
#include <ipcom_cstyle.h>
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_err.h>
|
|
#include <ipcom_sock.h>
|
|
#include <ipcom_syslog.h>
|
|
#include <ipcom_sysvar.h>
|
|
#include <ipcom_errno.h>
|
|
#include <ipcom_err.h>
|
|
#include <ipcom_os.h>
|
|
#include <ipcom_ipd.h>
|
|
#include <ipcom_os.h>
|
|
#include <ipcom_sock.h>
|
|
|
|
#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;
|
|
}
|
|
|