From patchwork Sat Jul 27 19:55:52 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: michael-dev X-Patchwork-Id: 262519 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from maxx.maxx.shmoo.com (maxx.shmoo.com [205.134.188.171]) by ozlabs.org (Postfix) with ESMTP id 1F8EB2C010F for ; Sun, 28 Jul 2013 06:00:39 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 0DD6B17C0E7; Sat, 27 Jul 2013 16:00:37 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5HS5qEmAC3TJ; Sat, 27 Jul 2013 16:00:36 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 8490917C0F3; Sat, 27 Jul 2013 15:57:34 -0400 (EDT) X-Original-To: mailman-post+hostap@maxx.shmoo.com Delivered-To: mailman-post+hostap@maxx.shmoo.com Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 076D017C0E7 for ; Sat, 27 Jul 2013 15:57:33 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id s2i6LOSm3gMR for ; Sat, 27 Jul 2013 15:57:27 -0400 (EDT) Received: from mail.fem.tu-ilmenau.de (mail.fem.tu-ilmenau.de [141.24.101.79]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id A744517C0F3 for ; Sat, 27 Jul 2013 15:55:53 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.fem.tu-ilmenau.de (Postfix) with ESMTP id 3987C64F8 for ; Sat, 27 Jul 2013 21:55:53 +0200 (CEST) X-Virus-Scanned: amavisd-new at fem.tu-ilmenau.de Received: from mail.fem.tu-ilmenau.de ([127.0.0.1]) by localhost (mail.fem.tu-ilmenau.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id xyNh3DXQg8az; Sat, 27 Jul 2013 21:55:52 +0200 (CEST) Received: from a234.fem.tu-ilmenau.de (unknown [10.42.51.234]) by mail.fem.tu-ilmenau.de (Postfix) with ESMTP; Sat, 27 Jul 2013 21:55:52 +0200 (CEST) Received: from [10.42.51.234] (localhost [127.0.0.1]) by a234.fem.tu-ilmenau.de (Postfix) with ESMTP id 217E3BED2D; Sat, 27 Jul 2013 21:55:52 +0200 (CEST) Subject: [PATCH v4 17/25] parse untagged/tagged VLANs from config files To: hostap@lists.shmoo.com From: Michael Braun Date: Sat, 27 Jul 2013 21:55:52 +0200 Message-ID: <20130727195552.17627.65417.stgit@ray-controller> In-Reply-To: <20130727195247.17627.28374.stgit@ray-controller> References: <20130727195247.17627.28374.stgit@ray-controller> User-Agent: StGit/0.16 MIME-Version: 1.0 Cc: projekt-wlan@fem.tu-ilmenau.de X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.11 Precedence: list List-Id: HostAP Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: hostap-bounces@lists.shmoo.com Errors-To: hostap-bounces@lists.shmoo.com Signed-hostap: Michael Braun --- hostapd/config_file.c | 348 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 259 insertions(+), 89 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 165bc96..bf865ea 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -26,76 +26,158 @@ extern struct wpa_driver_ops *wpa_drivers[]; #ifndef CONFIG_NO_VLAN -static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss, - const char *fname) +/** + * Parses current line. + * @param vlan: where the new VLAN is written to + * + * Returns -1 on fatal error. + * Returns 0 else + * *vlan = NULL if no VLAN is found. + */ +int hostapd_config_parse_vlan(char* buf, const int line, const char *fname, + struct hostapd_vlan **vlan) { - FILE *f; - char buf[128], *pos, *pos2; - int line = 0; + char *pos, *pos2; vlan_t vlan_id = VLAN_NULL; - struct hostapd_vlan *vlan; +#ifdef CONFIG_VLAN_TAGGED + int i; +#endif - f = fopen(fname, "r"); - if (!f) { - wpa_printf(MSG_ERROR, "VLAN file '%s' not readable.", fname); - return -1; + *vlan = NULL; + + if (buf[0] == '#') + return 0; + pos = buf; + while (*pos != '\0') { + if (*pos == '\n') { + *pos = '\0'; + break; + } + pos++; } + if (buf[0] == '\0') + return 0; - while (fgets(buf, sizeof(buf), f)) { - line++; + if (buf[0] == '*') { + vlan_alloc(&vlan_id, VLAN_ID_WILDCARD, 0, NULL); + pos = buf + 1; + } else { + int untagged = 0; + int num_tagged = 0; + int *tagged = NULL; - if (buf[0] == '#') - continue; pos = buf; - while (*pos != '\0') { - if (*pos == '\n') { - *pos = '\0'; - break; - } - pos++; +#ifdef CONFIG_VLAN_TAGGED + /* count number of tagged vlans, separated by minus */ + pos2 = pos; + while (*pos2 != '\0' && *pos2 != ' ' && *pos2 != '\t') { + if (*pos2 == 't') + num_tagged++; + pos2++; } - if (buf[0] == '\0') - continue; - - if (buf[0] == '*') { - vlan_alloc(&vlan_id, VLAN_ID_WILDCARD, 0, NULL); - pos = buf + 1; - } else { - int untagged_vlan_id = strtol(buf, &pos, 10); - if (buf == pos || untagged_vlan_id < 1 || - untagged_vlan_id > MAX_VLAN_ID) { - wpa_printf(MSG_ERROR, "Invalid VLAN ID at " - "line %d in '%s'", line, fname); - fclose(f); + /* replace first minus with \0 for atoi */ + pos2 = pos; + while (*pos2 != '\0' && *pos2 != ' ' && + *pos2 != '\t' && *pos2 != 't') + pos2++; + *pos2 = '\0'; pos2++; +#endif /* CONFIG_VLAN_TAGGED */ + untagged = atoi(pos); + if (untagged < 0 && untagged > MAX_VLAN_ID) { + wpa_printf(MSG_ERROR, "Invalid VLAN ID %d at " + "line %d in '%s'", untagged, line, fname); + return -1; + } +#ifndef CONFIG_VLAN_TAGGED + while (*pos != '\0' && *pos != ' ' && *pos != '\t') + pos++; +#else + pos = pos2; + if (num_tagged > 0) { + tagged = os_zalloc(sizeof(*tagged) * num_tagged); + if (!tagged) { + wpa_printf(MSG_ERROR, "Out of memory parsing " + "'%s' at line %d in '%s'", buf, + line, fname); return -1; } - vlan_alloc(&vlan_id, untagged_vlan_id, 0, NULL); + for (i=0; i < num_tagged; i++) { + while (*pos2 != '\0' && *pos2 != ' ' && + *pos2 != '\t' && *pos2 != 't') + pos2++; + *pos2 = '\0'; pos2++; + tagged[i] = atoi(pos); + if (tagged[i] < 1 || tagged[i] > MAX_VLAN_ID) { + wpa_printf(MSG_ERROR, "Invalid tagged " + "VLAN ID %d at line %d in " + "'%s'", tagged[i], line, + fname); + return -1; + } + pos = pos2; + } } - - while (*pos == ' ' || *pos == '\t') - pos++; - pos2 = pos; - while (*pos2 != ' ' && *pos2 != '\t' && *pos2 != '\0') - pos2++; - *pos2 = '\0'; - if (*pos == '\0' || os_strlen(pos) > IFNAMSIZ) { - wpa_printf(MSG_ERROR, "Invalid VLAN ifname at line %d " - "in '%s'", line, fname); - fclose(f); +#endif /* CONFIG_VLAN_TAGGED */ + if (!untagged && !num_tagged) { + wpa_printf(MSG_ERROR, "No VLAN ID at line %d in '%s'", + line, fname); return -1; } + vlan_alloc(&vlan_id, untagged, num_tagged, tagged); + os_free(tagged); + } + + while (*pos == ' ' || *pos == '\t') + pos++; + pos2 = pos; + while (*pos2 != ' ' && *pos2 != '\t' && *pos2 != '\0') + pos2++; + *pos2 = '\0'; + if (*pos == '\0' || os_strlen(pos) > IFNAMSIZ) { + wpa_printf(MSG_ERROR, "Invalid VLAN ifname at line %d in '%s'", + line, fname); + return -1; + } + + *vlan = os_zalloc(sizeof(**vlan)); + if (*vlan == NULL) { + wpa_printf(MSG_ERROR, "Out of memory while reading VLAN " + "interfaces from '%s'", fname); + return -1; + } + + vlan_alloc_copy(&((*vlan)->vlan_id), &vlan_id); + vlan_free(&vlan_id); + os_strlcpy((*vlan)->ifname, pos, sizeof((*vlan)->ifname)); + + return 0; +} - vlan = os_zalloc(sizeof(*vlan)); - if (vlan == NULL) { - wpa_printf(MSG_ERROR, "Out of memory while reading " - "VLAN interfaces from '%s'", fname); + +static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss, + const char *fname) +{ + FILE *f; + char buf[128]; + int line = 0, ret; + struct hostapd_vlan *vlan; + + f = fopen(fname, "r"); + if (!f) { + wpa_printf(MSG_ERROR, "VLAN file '%s' not readable.", fname); + return -1; + } + + while (fgets(buf, sizeof(buf), f)) { + line++; + ret = hostapd_config_parse_vlan(buf, line, fname, &vlan); + if (ret < 0) { fclose(f); - return -1; + return ret; } + if (!vlan) + continue; - vlan_alloc_copy(&vlan->vlan_id, &vlan_id); - vlan_free(&vlan_id); - os_strlcpy(vlan->ifname, pos, sizeof(vlan->ifname)); vlan->next = bss->vlan; bss->vlan = vlan; } @@ -115,15 +197,128 @@ static int hostapd_acl_comp(const void *a, const void *b) } +/** + * Parses current line. + * Returns -1 on fatal error. + * Returns 0 if no acl is found + * Returns 1 else + */ +static int hostapd_config_parse_mac(char* buf, const char *fname, + const int line, struct mac_acl_entry *acl) +{ + char *pos; + u8 addr[ETH_ALEN]; +#ifndef CONFIG_NO_VLAN + int untagged = 0; +#ifdef CONFIG_VLAN_TAGGED + int i; + char *pos2; + int num_tagged = 0; + int *tagged = NULL; +#endif /* CONFIG_VLAN_TAGGED */ +#endif /* CONFIG_NO_VLAN */ + + if (buf[0] == '#') + return 0; + + pos = buf; + while (*pos != '\0') { + if (*pos == '\n') { + *pos = '\0'; + break; + } + pos++; + } + if (buf[0] == '\0') + return 0; + + if (hwaddr_aton(buf, addr)) { + wpa_printf(MSG_ERROR, "Invalid MAC address '%s' at line %d in " + "'%s'", buf, line, fname); + return -1; + } + + os_memset(acl, 0, sizeof(*acl)); + os_memcpy(acl->addr, addr, ETH_ALEN); + acl->vlan_id = VLAN_NULL; + +#ifndef CONFIG_NO_VLAN + pos = buf; + while (*pos != '\0' && *pos != ' ' && *pos != '\t') + pos++; + while (*pos == ' ' || *pos == '\t') + pos++; + if (*pos == '\0') + return 1; // no VLAN + +#ifdef CONFIG_VLAN_TAGGED + /* count number of tagged vlans, separated by minus */ + pos2 = pos; + while (*pos2 != '\0' && *pos2 != ' ' && + *pos2 != '\t') { + if (*pos2 == 't') + num_tagged++; + pos2++; + } + /* replace first minus with \0 for atoi */ + pos2 = pos; + while (*pos2 != '\0' && *pos2 != ' ' && + *pos2 != '\t' && *pos2 != 't') + pos2++; + *pos2 = '\0'; pos2++; +#endif /* CONFIG_VLAN_TAGGED */ + untagged = atoi(pos); + if (untagged < 0 && untagged > MAX_VLAN_ID) { + wpa_printf(MSG_ERROR, "Invalid VLAN ID %d at line %d in '%s'", + untagged, line, fname); + return -1; + } +#ifdef CONFIG_VLAN_TAGGED + if (num_tagged == 0) { + vlan_alloc(&(acl->vlan_id), untagged, num_tagged, tagged); + return 1; + } + tagged = os_zalloc(sizeof(*tagged) * num_tagged); + if (!tagged) { + wpa_printf(MSG_ERROR, "Out of memory parsing '%s' at line %d " + "in '%s'", buf, line, fname); + return -1; + } + for (i=0; i < num_tagged; i++) { + pos = pos2; + while (*pos2 != '\0' && *pos2 != ' ' && + *pos2 != '\t' && *pos2 != 't') + pos2++; + *pos2 = '\0'; pos2++; + tagged[i] = atoi(pos); + if (tagged[i] < 1 && tagged[i] > MAX_VLAN_ID) { + wpa_printf(MSG_ERROR, "Invalid tagged VLAN ID %d at " + "line %d in '%s'", tagged[i], line, fname); + return -1; + } + } +#endif /* CONFIG_VLAN_TAGGED */ +#ifdef CONFIG_VLAN_TAGGED + vlan_alloc(&(acl->vlan_id), untagged, num_tagged, tagged); +#else + vlan_alloc(&(acl->vlan_id), untagged, 0, NULL); +#endif +#ifdef CONFIG_VLAN_TAGGED + os_free(tagged); +#endif /* CONFIG_VLAN_TAGGED */ +#endif /* CONFIG_NO_VLAN */ + + return 1; +} + + static int hostapd_config_read_maclist(const char *fname, struct mac_acl_entry **acl, int *num) { FILE *f; - char buf[128], *pos; - int line = 0; - u8 addr[ETH_ALEN]; - struct mac_acl_entry *newacl; - vlan_t vlan_id = VLAN_NULL; + char buf[128]; + int line = 0, ret; + struct mac_acl_entry *newacl, aclentry; if (!fname) return 0; @@ -136,35 +331,13 @@ static int hostapd_config_read_maclist(const char *fname, while (fgets(buf, sizeof(buf), f)) { line++; - - if (buf[0] == '#') - continue; - pos = buf; - while (*pos != '\0') { - if (*pos == '\n') { - *pos = '\0'; - break; - } - pos++; - } - if (buf[0] == '\0') - continue; - - if (hwaddr_aton(buf, addr)) { - wpa_printf(MSG_ERROR, "Invalid MAC address '%s' at " - "line %d in '%s'", buf, line, fname); + ret = hostapd_config_parse_mac(buf, fname, line, &aclentry); + if (ret < 0) { fclose(f); - return -1; + return ret; } - - vlan_id = VLAN_NULL; - pos = buf; - while (*pos != '\0' && *pos != ' ' && *pos != '\t') - pos++; - while (*pos == ' ' || *pos == '\t') - pos++; - if (*pos != '\0') - vlan_alloc(&vlan_id, atoi(pos), 0, NULL); + if (ret == 0) + continue; newacl = os_realloc_array(*acl, *num + 1, sizeof(**acl)); if (newacl == NULL) { @@ -172,12 +345,9 @@ static int hostapd_config_read_maclist(const char *fname, fclose(f); return -1; } - *acl = newacl; - os_memcpy((*acl)[*num].addr, addr, ETH_ALEN); - vlan_alloc_copy(&(*acl)[*num].vlan_id, &vlan_id); + os_memcpy(&((*acl)[*num]), &aclentry, sizeof(aclentry)); (*num)++; - vlan_free(&vlan_id); } fclose(f);