X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mech_eap.git;a=blobdiff_plain;f=libeap%2Fsrc%2Fap%2Fvlan_ioctl.c;fp=libeap%2Fsrc%2Fap%2Fvlan_ioctl.c;h=987b612e1d9f8ab608dc30fffe761e8b4c3cb7cf;hp=0000000000000000000000000000000000000000;hb=f3746d009c6d7f50025af1f58a85e5fee9680be6;hpb=244f18d04aaf29e68495b5ffeb40ef5cca50942f diff --git a/libeap/src/ap/vlan_ioctl.c b/libeap/src/ap/vlan_ioctl.c new file mode 100644 index 0000000..987b612 --- /dev/null +++ b/libeap/src/ap/vlan_ioctl.c @@ -0,0 +1,155 @@ +/* + * hostapd / VLAN ioctl API + * Copyright 2003, Instant802 Networks, Inc. + * Copyright 2005-2006, Devicescape Software, Inc. + * Copyright (c) 2009, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "utils/includes.h" +#include + +#include "utils/common.h" +#include "common/linux_vlan.h" +#include "vlan_util.h" + + +int vlan_rem(const char *if_name) +{ + int fd; + struct vlan_ioctl_args if_request; + + wpa_printf(MSG_DEBUG, "VLAN: vlan_rem(%s)", if_name); + if ((os_strlen(if_name) + 1) > sizeof(if_request.device1)) { + wpa_printf(MSG_ERROR, "VLAN: Interface name too long: '%s'", + if_name); + return -1; + } + + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + wpa_printf(MSG_ERROR, "VLAN: %s: socket(AF_INET,SOCK_STREAM) " + "failed: %s", __func__, strerror(errno)); + return -1; + } + + os_memset(&if_request, 0, sizeof(if_request)); + + os_strlcpy(if_request.device1, if_name, sizeof(if_request.device1)); + if_request.cmd = DEL_VLAN_CMD; + + if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) { + wpa_printf(MSG_ERROR, "VLAN: %s: DEL_VLAN_CMD failed for %s: " + "%s", __func__, if_name, strerror(errno)); + close(fd); + return -1; + } + + close(fd); + return 0; +} + + +/* + Add a vlan interface with VLAN ID 'vid' and tagged interface + 'if_name'. + + returns -1 on error + returns 1 if the interface already exists + returns 0 otherwise +*/ +int vlan_add(const char *if_name, int vid, const char *vlan_if_name) +{ + int fd; + struct vlan_ioctl_args if_request; + + wpa_printf(MSG_DEBUG, "VLAN: vlan_add(if_name=%s, vid=%d)", + if_name, vid); + ifconfig_up(if_name); + + if ((os_strlen(if_name) + 1) > sizeof(if_request.device1)) { + wpa_printf(MSG_ERROR, "VLAN: Interface name too long: '%s'", + if_name); + return -1; + } + + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + wpa_printf(MSG_ERROR, "VLAN: %s: socket(AF_INET,SOCK_STREAM) " + "failed: %s", __func__, strerror(errno)); + return -1; + } + + os_memset(&if_request, 0, sizeof(if_request)); + + /* Determine if a suitable vlan device already exists. */ + + os_snprintf(if_request.device1, sizeof(if_request.device1), "vlan%d", + vid); + + if_request.cmd = GET_VLAN_VID_CMD; + + if (ioctl(fd, SIOCSIFVLAN, &if_request) == 0 && + if_request.u.VID == vid) { + if_request.cmd = GET_VLAN_REALDEV_NAME_CMD; + + if (ioctl(fd, SIOCSIFVLAN, &if_request) == 0 && + os_strncmp(if_request.u.device2, if_name, + sizeof(if_request.u.device2)) == 0) { + close(fd); + wpa_printf(MSG_DEBUG, + "VLAN: vlan_add: if_name %s exists already", + if_request.device1); + return 1; + } + } + + /* A suitable vlan device does not already exist, add one. */ + + os_memset(&if_request, 0, sizeof(if_request)); + os_strlcpy(if_request.device1, if_name, sizeof(if_request.device1)); + if_request.u.VID = vid; + if_request.cmd = ADD_VLAN_CMD; + + if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) { + wpa_printf(MSG_ERROR, + "VLAN: %s: ADD_VLAN_CMD failed for %s: %s", + __func__, if_request.device1, strerror(errno)); + close(fd); + return -1; + } + + close(fd); + return 0; +} + + +int vlan_set_name_type(unsigned int name_type) +{ + int fd; + struct vlan_ioctl_args if_request; + + wpa_printf(MSG_DEBUG, "VLAN: vlan_set_name_type(name_type=%u)", + name_type); + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + wpa_printf(MSG_ERROR, + "VLAN: %s: socket(AF_INET,SOCK_STREAM) failed: %s", + __func__, strerror(errno)); + return -1; + } + + os_memset(&if_request, 0, sizeof(if_request)); + + if_request.u.name_type = name_type; + if_request.cmd = SET_VLAN_NAME_TYPE_CMD; + if (ioctl(fd, SIOCSIFVLAN, &if_request) < 0) { + wpa_printf(MSG_ERROR, + "VLAN: %s: SET_VLAN_NAME_TYPE_CMD name_type=%u failed: %s", + __func__, name_type, strerror(errno)); + close(fd); + return -1; + } + + close(fd); + return 0; +}