示例#1
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 ((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;
    }

    memset(&if_request, 0, sizeof(if_request));

    /* Determine if a suitable vlan device already exists. */

    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
                    && 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. */

    memset(&if_request, 0, sizeof(if_request));
    strcpy(if_request.device1, if_name);
    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;
}
示例#2
0
static void vlan_newlink(char *ifname, struct hostapd_data *hapd)
{
    char vlan_ifname[IFNAMSIZ];
    char br_name[IFNAMSIZ];
    struct hostapd_vlan *vlan = hapd->conf->vlan;
    char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface;

    while (vlan) {
        if (strcmp(ifname, vlan->ifname) == 0) {

            snprintf(br_name, sizeof(br_name), "brvlan%d",
                     vlan->vlan_id);

            if (!br_addbr(br_name))
                vlan->clean |= DVLAN_CLEAN_BR;

            ifconfig_up(br_name);

            if (tagged_interface) {

                if (!vlan_add(tagged_interface, vlan->vlan_id))
                    vlan->clean |= DVLAN_CLEAN_VLAN;

                snprintf(vlan_ifname, sizeof(vlan_ifname),
                         "vlan%d", vlan->vlan_id);

                if (!br_addif(br_name, vlan_ifname))
                    vlan->clean |= DVLAN_CLEAN_VLAN_PORT;

                ifconfig_up(vlan_ifname);
            }

            if (!br_addif(br_name, ifname))
                vlan->clean |= DVLAN_CLEAN_WLAN_PORT;

            ifconfig_up(ifname);

            break;
        }
        vlan = vlan->next;
    }
}
示例#3
0
struct hostapd_vlan * vlan_add_dynamic(struct hostapd_data *hapd,
				       struct hostapd_vlan *vlan,
				       int vlan_id)
{
	struct hostapd_vlan *n;
	char *ifname, *pos;

	if (vlan == NULL || vlan_id <= 0 || vlan_id > MAX_VLAN_ID ||
	    vlan->vlan_id != VLAN_ID_WILDCARD)
		return NULL;

	wpa_printf(MSG_DEBUG, "VLAN: %s(vlan_id=%d ifname=%s)",
		   __func__, vlan_id, vlan->ifname);
	ifname = os_strdup(vlan->ifname);
	if (ifname == NULL)
		return NULL;
	pos = os_strchr(ifname, '#');
	if (pos == NULL) {
		os_free(ifname);
		return NULL;
	}
	*pos++ = '\0';

	n = os_zalloc(sizeof(*n));
	if (n == NULL) {
		os_free(ifname);
		return NULL;
	}

	n->vlan_id = vlan_id;
	n->dynamic_vlan = 1;

	os_snprintf(n->ifname, sizeof(n->ifname), "%s%d%s", ifname, vlan_id,
		    pos);
	os_free(ifname);

	if (hostapd_vlan_if_add(hapd, n->ifname)) {
		os_free(n);
		return NULL;
	}

	n->next = hapd->conf->vlan;
	hapd->conf->vlan = n;

#ifdef CONFIG_FULL_DYNAMIC_VLAN
	ifconfig_up(n->ifname);
#endif /* CONFIG_FULL_DYNAMIC_VLAN */

	return n;
}
示例#4
0
static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan,
		       int existsok)
{
	int ret, i;

	for (i = 0; i < NUM_WEP_KEYS; i++) {
		if (!hapd->conf->ssid.wep.key[i])
			continue;
		wpa_printf(MSG_ERROR,
			   "VLAN: Refusing to set up VLAN iface %s with WEP",
			   vlan->ifname);
		return -1;
	}

	if (!if_nametoindex(vlan->ifname))
		ret = hostapd_vlan_if_add(hapd, vlan->ifname);
	else if (!existsok)
		return -1;
	else
		ret = 0;

	if (ret)
		return ret;

	ifconfig_up(vlan->ifname); /* else wpa group will fail fatal */

	if (hapd->wpa_auth)
		ret = wpa_auth_ensure_group(hapd->wpa_auth, vlan->vlan_id);

	if (ret == 0)
		return ret;

	wpa_printf(MSG_ERROR, "WPA initialization for VLAN %d failed (%d)",
		   vlan->vlan_id, ret);
	if (wpa_auth_release_group(hapd->wpa_auth, vlan->vlan_id))
		wpa_printf(MSG_ERROR, "WPA deinit of %s failed", vlan->ifname);

	/* group state machine setup failed */
	if (hostapd_vlan_if_remove(hapd, vlan->ifname))
		wpa_printf(MSG_ERROR, "Removal of %s failed", vlan->ifname);

	return ret;
}
示例#5
0
static int vlan_dynamic_add(struct hostapd_data *hapd,
			    struct hostapd_vlan *vlan)
{
	while (vlan) {
		if (vlan->vlan_id != VLAN_ID_WILDCARD) {
			if (hostapd_vlan_if_add(hapd, vlan->ifname)) {
				if (errno != EEXIST) {
					wpa_printf(MSG_ERROR, "VLAN: Could "
						   "not add VLAN %s: %s",
						   vlan->ifname,
						   strerror(errno));
					return -1;
				}
			}
#ifdef CONFIG_FULL_DYNAMIC_VLAN
			ifconfig_up(vlan->ifname);
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
		}

		vlan = vlan->next;
	}

	return 0;
}
示例#6
0
static void vlan_newlink(char *ifname, struct hostapd_data *hapd)
{
	char vlan_ifname[IFNAMSIZ];
	char br_name[IFNAMSIZ];
	struct hostapd_vlan *vlan = hapd->conf->vlan;
	char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface;
	int vlan_naming = hapd->conf->ssid.vlan_naming;
	int clean;

	wpa_printf(MSG_DEBUG, "VLAN: vlan_newlink(%s)", ifname);

	while (vlan) {
		if (os_strcmp(ifname, vlan->ifname) == 0 && !vlan->configured) {
			vlan->configured = 1;

			if (hapd->conf->vlan_bridge[0]) {
				os_snprintf(br_name, sizeof(br_name), "%s%d",
					    hapd->conf->vlan_bridge,
					    vlan->vlan_id);
			} else if (tagged_interface) {
				os_snprintf(br_name, sizeof(br_name),
				            "br%s.%d", tagged_interface,
					    vlan->vlan_id);
			} else {
				os_snprintf(br_name, sizeof(br_name),
				            "brvlan%d", vlan->vlan_id);
			}

			dyn_iface_get(hapd, br_name,
				      br_addbr(br_name) ? 0 : DVLAN_CLEAN_BR);

			ifconfig_up(br_name);

			if (tagged_interface) {
				if (vlan_naming ==
				    DYNAMIC_VLAN_NAMING_WITH_DEVICE)
					os_snprintf(vlan_ifname,
						    sizeof(vlan_ifname),
						    "%s.%d", tagged_interface,
						    vlan->vlan_id);
				else
					os_snprintf(vlan_ifname,
						    sizeof(vlan_ifname),
						    "vlan%d", vlan->vlan_id);

				clean = 0;
				ifconfig_up(tagged_interface);
				if (!vlan_add(tagged_interface, vlan->vlan_id,
					      vlan_ifname))
					clean |= DVLAN_CLEAN_VLAN;

				if (!br_addif(br_name, vlan_ifname))
					clean |= DVLAN_CLEAN_VLAN_PORT;

				dyn_iface_get(hapd, vlan_ifname, clean);

				ifconfig_up(vlan_ifname);
			}

			if (!br_addif(br_name, ifname))
				vlan->clean |= DVLAN_CLEAN_WLAN_PORT;

			ifconfig_up(ifname);

			break;
		}
		vlan = vlan->next;
	}
}
示例#7
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 (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;
}