📄 vlan_init.c
字号:
{ 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 (os_strcmp(ifname, vlan->ifname) == 0) { os_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; os_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; }}static void vlan_dellink(char *ifname, struct hostapd_data *hapd){ char vlan_ifname[IFNAMSIZ]; char br_name[IFNAMSIZ]; struct hostapd_vlan *first, *prev, *vlan = hapd->conf->vlan; char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface; int numports; first = prev = vlan; while (vlan) { if (os_strcmp(ifname, vlan->ifname) == 0) { os_snprintf(br_name, sizeof(br_name), "brvlan%d", vlan->vlan_id); if (tagged_interface) { os_snprintf(vlan_ifname, sizeof(vlan_ifname), "vlan%d", vlan->vlan_id); numports = br_getnumports(br_name); if (numports == 1) { br_delif(br_name, vlan_ifname); vlan_rem(vlan_ifname); ifconfig_down(br_name); br_delbr(br_name); } } if (vlan == first) { hapd->conf->vlan = vlan->next; } else { prev->next = vlan->next; } os_free(vlan); break; } prev = vlan; vlan = vlan->next; }}static voidvlan_read_ifnames(struct nlmsghdr *h, size_t len, int del, struct hostapd_data *hapd){ struct ifinfomsg *ifi; int attrlen, nlmsg_len, rta_len; struct rtattr *attr; if (len < sizeof(*ifi)) return; ifi = NLMSG_DATA(h); nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); attrlen = h->nlmsg_len - nlmsg_len; if (attrlen < 0) return; attr = (struct rtattr *) (((char *) ifi) + nlmsg_len); rta_len = RTA_ALIGN(sizeof(struct rtattr)); while (RTA_OK(attr, attrlen)) { char ifname[IFNAMSIZ + 1]; if (attr->rta_type == IFLA_IFNAME) { int n = attr->rta_len - rta_len; if (n < 0) break; os_memset(ifname, 0, sizeof(ifname)); if ((size_t) n > sizeof(ifname)) n = sizeof(ifname); os_memcpy(ifname, ((char *) attr) + rta_len, n); if (del) vlan_dellink(ifname, hapd); else vlan_newlink(ifname, hapd); } attr = RTA_NEXT(attr, attrlen); }}static void vlan_event_receive(int sock, void *eloop_ctx, void *sock_ctx){ char buf[8192]; int left; struct sockaddr_nl from; socklen_t fromlen; struct nlmsghdr *h; struct hostapd_data *hapd = eloop_ctx; fromlen = sizeof(from); left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr *) &from, &fromlen); if (left < 0) { if (errno != EINTR && errno != EAGAIN) perror("recvfrom(netlink)"); return; } h = (struct nlmsghdr *) buf; while (left >= (int) sizeof(*h)) { int len, plen; len = h->nlmsg_len; plen = len - sizeof(*h); if (len > left || plen < 0) { printf("Malformed netlink message: " "len=%d left=%d plen=%d", len, left, plen); break; } switch (h->nlmsg_type) { case RTM_NEWLINK: vlan_read_ifnames(h, plen, 0, hapd); break; case RTM_DELLINK: vlan_read_ifnames(h, plen, 1, hapd); break; } len = NLMSG_ALIGN(len); left -= len; h = (struct nlmsghdr *) ((char *) h + len); } if (left > 0) { printf("%d extra bytes in the end of netlink message", left); }}static struct full_dynamic_vlan *full_dynamic_vlan_init(struct hostapd_data *hapd){ struct sockaddr_nl local; struct full_dynamic_vlan *priv; priv = os_zalloc(sizeof(*priv)); if (priv == NULL) return NULL; vlan_set_name_type(VLAN_NAME_TYPE_PLUS_VID_NO_PAD); priv->s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (priv->s < 0) { perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)"); os_free(priv); return NULL; } os_memset(&local, 0, sizeof(local)); local.nl_family = AF_NETLINK; local.nl_groups = RTMGRP_LINK; if (bind(priv->s, (struct sockaddr *) &local, sizeof(local)) < 0) { perror("bind(netlink)"); close(priv->s); os_free(priv); return NULL; } if (eloop_register_read_sock(priv->s, vlan_event_receive, hapd, NULL)) { close(priv->s); os_free(priv); return NULL; } return priv;}static void full_dynamic_vlan_deinit(struct full_dynamic_vlan *priv){ if (priv == NULL) return; eloop_unregister_read_sock(priv->s); close(priv->s); os_free(priv);}#endif /* CONFIG_FULL_DYNAMIC_VLAN */int vlan_setup_encryption_dyn(struct hostapd_data *hapd, struct hostapd_ssid *mssid, const char *dyn_vlan){ int i; if (dyn_vlan == NULL) return 0; /* Static WEP keys are set here; IEEE 802.1X and WPA uses their own * functions for setting up dynamic broadcast keys. */ for (i = 0; i < 4; i++) { if (mssid->wep.key[i] && hostapd_set_encryption(dyn_vlan, hapd, "WEP", NULL, i, mssid->wep.key[i], mssid->wep.len[i], i == mssid->wep.idx)) { printf("VLAN: Could not set WEP encryption for " "dynamic VLAN.\n"); return -1; } } return 0;}static int vlan_dynamic_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan){ while (vlan) { if (vlan->vlan_id != VLAN_ID_WILDCARD && hostapd_if_add(hapd, HOSTAPD_IF_VLAN, vlan->ifname, NULL)) { if (errno != EEXIST) { printf("Could not add VLAN iface: %s: %s\n", vlan->ifname, strerror(errno)); return -1; } } vlan = vlan->next; } return 0;}static void vlan_dynamic_remove(struct hostapd_data *hapd, struct hostapd_vlan *vlan){ struct hostapd_vlan *next; while (vlan) { next = vlan->next; if (vlan->vlan_id != VLAN_ID_WILDCARD && hostapd_if_remove(hapd, HOSTAPD_IF_VLAN, vlan->ifname, NULL)) { printf("Could not remove VLAN iface: %s: %s\n", vlan->ifname, strerror(errno)); }#ifdef CONFIG_FULL_DYNAMIC_VLAN if (vlan->clean) vlan_dellink(vlan->ifname, hapd);#endif /* CONFIG_FULL_DYNAMIC_VLAN */ vlan = next; }}int vlan_init(struct hostapd_data *hapd){ if (vlan_dynamic_add(hapd, hapd->conf->vlan)) return -1;#ifdef CONFIG_FULL_DYNAMIC_VLAN hapd->full_dynamic_vlan = full_dynamic_vlan_init(hapd);#endif /* CONFIG_FULL_DYNAMIC_VLAN */ return 0;}void vlan_deinit(struct hostapd_data *hapd){ vlan_dynamic_remove(hapd, hapd->conf->vlan);#ifdef CONFIG_FULL_DYNAMIC_VLAN full_dynamic_vlan_deinit(hapd->full_dynamic_vlan);#endif /* CONFIG_FULL_DYNAMIC_VLAN */}int vlan_reconfig(struct hostapd_data *hapd, struct hostapd_config *oldconf, struct hostapd_bss_config *oldbss){ vlan_dynamic_remove(hapd, oldbss->vlan); if (vlan_dynamic_add(hapd, hapd->conf->vlan)) return -1; return 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; 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_if_add(hapd, HOSTAPD_IF_VLAN, n->ifname, NULL)) { os_free(n); return NULL; } n->next = hapd->conf->vlan; hapd->conf->vlan = n; return n;}int vlan_remove_dynamic(struct hostapd_data *hapd, int vlan_id){ struct hostapd_vlan *vlan; if (vlan_id <= 0 || vlan_id > MAX_VLAN_ID) return 1; vlan = hapd->conf->vlan; while (vlan) { if (vlan->vlan_id == vlan_id && vlan->dynamic_vlan > 0) { vlan->dynamic_vlan--; break; } vlan = vlan->next; } if (vlan == NULL) return 1; if (vlan->dynamic_vlan == 0) hostapd_if_remove(hapd, HOSTAPD_IF_VLAN, vlan->ifname, NULL); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -