⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vlan_init.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * hostapd / VLAN initialization * Copyright 2003, Instant802 Networks, Inc. * Copyright 2005-2006, Devicescape Software, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#include "includes.h"#include "hostapd.h"#include "driver.h"#include "vlan_init.h"#ifdef CONFIG_FULL_DYNAMIC_VLAN#include <net/if.h>#include <sys/ioctl.h>#include <linux/sockios.h>#include <linux/if_vlan.h>#include <linux/if_bridge.h>#include "priv_netlink.h"#include "eloop.h"struct full_dynamic_vlan {	int s; /* socket on which to listen for new/removed interfaces. */};static int ifconfig_helper(const char *if_name, int up){	int fd;	struct ifreq ifr;	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {		perror("socket[AF_INET,SOCK_STREAM]");		return -1;	}	os_memset(&ifr, 0, sizeof(ifr));	os_strlcpy(ifr.ifr_name, if_name, IFNAMSIZ);	if (ioctl(fd, SIOCGIFFLAGS, &ifr) != 0) {		perror("ioctl[SIOCGIFFLAGS]");		close(fd);		return -1;	}	if (up)		ifr.ifr_flags |= IFF_UP;	else		ifr.ifr_flags &= ~IFF_UP;	if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0) {		perror("ioctl[SIOCSIFFLAGS]");		close(fd);		return -1;	}	close(fd);	return 0;}static int ifconfig_up(const char *if_name){	return ifconfig_helper(if_name, 1);}static int ifconfig_down(const char *if_name){	return ifconfig_helper(if_name, 0);}/* * These are only available in recent linux headers (without the leading * underscore). */#define _GET_VLAN_REALDEV_NAME_CMD	8#define _GET_VLAN_VID_CMD		9/* This value should be 256 ONLY. If it is something else, then hostapd * might crash!, as this value has been hard-coded in 2.4.x kernel * bridging code. */#define MAX_BR_PORTS      		256static int br_delif(const char *br_name, const char *if_name){	int fd;	struct ifreq ifr;	unsigned long args[2];	int if_index;	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {		perror("socket[AF_INET,SOCK_STREAM]");		return -1;	}	if_index = if_nametoindex(if_name);	if (if_index == 0) {		printf("Failure determining interface index for '%s'\n",		       if_name);		close(fd);		return -1;	}	args[0] = BRCTL_DEL_IF;	args[1] = if_index;	os_strlcpy(ifr.ifr_name, br_name, sizeof(ifr.ifr_name));	ifr.ifr_data = (__caddr_t) args;	if (ioctl(fd, SIOCDEVPRIVATE, &ifr) < 0 && errno != EINVAL) {		/* No error if interface already removed. */		perror("ioctl[SIOCDEVPRIVATE,BRCTL_DEL_IF]");		close(fd);		return -1;	}	close(fd);	return 0;}/*	Add interface 'if_name' to the bridge 'br_name'	returns -1 on error	returns 1 if the interface is already part of the bridge	returns 0 otherwise*/static int br_addif(const char *br_name, const char *if_name){	int fd;	struct ifreq ifr;	unsigned long args[2];	int if_index;	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {		perror("socket[AF_INET,SOCK_STREAM]");		return -1;	}	if_index = if_nametoindex(if_name);	if (if_index == 0) {		printf("Failure determining interface index for '%s'\n",		       if_name);		close(fd);		return -1;	}	args[0] = BRCTL_ADD_IF;	args[1] = if_index;	os_strlcpy(ifr.ifr_name, br_name, sizeof(ifr.ifr_name));	ifr.ifr_data = (__caddr_t) args;	if (ioctl(fd, SIOCDEVPRIVATE, &ifr) < 0) {		if (errno == EBUSY) {			/* The interface is already added. */			close(fd);			return 1;		}		perror("ioctl[SIOCDEVPRIVATE,BRCTL_ADD_IF]");		close(fd);		return -1;	}	close(fd);	return 0;}static int br_delbr(const char *br_name){	int fd;	unsigned long arg[2];	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {		perror("socket[AF_INET,SOCK_STREAM]");		return -1;	}	arg[0] = BRCTL_DEL_BRIDGE;	arg[1] = (unsigned long) br_name;	if (ioctl(fd, SIOCGIFBR, arg) < 0 && errno != ENXIO) {		/* No error if bridge already removed. */		perror("ioctl[BRCTL_DEL_BRIDGE]");		close(fd);		return -1;	}	close(fd);	return 0;}/*	Add a bridge with the name 'br_name'.	returns -1 on error	returns 1 if the bridge already exists	returns 0 otherwise*/static int br_addbr(const char *br_name){	int fd;	unsigned long arg[2];	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {		perror("socket[AF_INET,SOCK_STREAM]");		return -1;	}	arg[0] = BRCTL_ADD_BRIDGE;	arg[1] = (unsigned long) br_name;	if (ioctl(fd, SIOCGIFBR, arg) < 0) { 		if (errno == EEXIST) {			/* The bridge is already added. */			close(fd);			return 1;		} else {			perror("ioctl[BRCTL_ADD_BRIDGE]");			close(fd);			return -1;		}	}	close(fd);	return 0;}static int br_getnumports(const char *br_name){	int fd;	int i;	int port_cnt = 0;	unsigned long arg[4];	int ifindices[MAX_BR_PORTS];	struct ifreq ifr;	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {		perror("socket[AF_INET,SOCK_STREAM]");		return -1;	}	arg[0] = BRCTL_GET_PORT_LIST;	arg[1] = (unsigned long) ifindices;	arg[2] = MAX_BR_PORTS;	arg[3] = 0;	os_memset(ifindices, 0, sizeof(ifindices));	os_strlcpy(ifr.ifr_name, br_name, sizeof(ifr.ifr_name));	ifr.ifr_data = (__caddr_t) arg;	if (ioctl(fd, SIOCDEVPRIVATE, &ifr) < 0) {		perror("ioctl[SIOCDEVPRIVATE,BRCTL_GET_PORT_LIST]");		close(fd);		return -1;	}	for (i = 1; i < MAX_BR_PORTS; i++) {		if (ifindices[i] > 0) {			port_cnt++;		}	}	close(fd);	return port_cnt;}static int vlan_rem(const char *if_name){	int fd;	struct vlan_ioctl_args if_request;	if ((os_strlen(if_name) + 1) > sizeof(if_request.device1)) {		fprintf(stderr, "Interface name to long.\n");		return -1;	}	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {		perror("socket[AF_INET,SOCK_STREAM]");		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) {		perror("ioctl[SIOCSIFVLAN,DEL_VLAN_CMD]");		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*/static int vlan_add(const char *if_name, int vid){	int fd;	struct vlan_ioctl_args if_request;	ifconfig_up(if_name);	if ((os_strlen(if_name) + 1) > sizeof(if_request.device1)) {		fprintf(stderr, "Interface name to long.\n");		return -1;	}	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {		perror("socket[AF_INET,SOCK_STREAM]");		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 (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);				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) {		perror("ioctl[SIOCSIFVLAN,ADD_VLAN_CMD]");		close(fd);		return -1;	}	close(fd);	return 0;}static int vlan_set_name_type(unsigned int name_type){	int fd;	struct vlan_ioctl_args if_request;	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {		perror("socket[AF_INET,SOCK_STREAM]");		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) {		perror("ioctl[SIOCSIFVLAN,SET_VLAN_NAME_TYPE_CMD]");		close(fd);		return -1;	}	close(fd);	return 0;}static void vlan_newlink(char *ifname, struct hostapd_data *hapd)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -