From patchwork Mon Apr 8 12:16:20 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: michael-dev X-Patchwork-Id: 249368 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 732372C0095 for ; Thu, 6 Jun 2013 20:12:51 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 7EC1E9C1B6; Thu, 6 Jun 2013 06:11:57 -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 PFOzJ-+O28Ig; Thu, 6 Jun 2013 06:11:57 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id C93559C12C; Thu, 6 Jun 2013 06:09:40 -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 DF35A9C1BA for ; Thu, 6 Jun 2013 06:09:38 -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 2NQzea+mkJi7 for ; Thu, 6 Jun 2013 06:09:33 -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 B26709C12A for ; Thu, 6 Jun 2013 06:09:09 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.fem.tu-ilmenau.de (Postfix) with ESMTP id 82F026512 for ; Thu, 6 Jun 2013 12:09:09 +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 sVeUhRDOtQ+f; Thu, 6 Jun 2013 12:09:08 +0200 (CEST) Received: from a234.fem.tu-ilmenau.de (unknown [10.42.51.234]) by mail.fem.tu-ilmenau.de (Postfix) with ESMTP; Thu, 6 Jun 2013 12:09:07 +0200 (CEST) Received: by a234.fem.tu-ilmenau.de (Postfix, from userid 0) id 206E520A667; Thu, 6 Jun 2013 12:09:07 +0200 (CEST) Message-Id: <1cfbcf87a57da7fa6f45cd201337237f4af86e8b.1370512966.git.michael-dev@fami-braun.de> In-Reply-To: References: From: Michael Braun Date: Mon, 8 Apr 2013 14:16:20 +0200 Subject: [PATCHv2 12/21] parse untagged/tagged VLANs from config files To: hostap@lists.shmoo.com 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 Reply-To: projekt-wlan@fem.tu-ilmenau.de 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 diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 08a0ad3..90d1259 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -26,13 +26,140 @@ extern struct wpa_driver_ops *wpa_drivers[]; #ifndef CONFIG_NO_VLAN +/** + * 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) +{ + char *pos, *pos2; + vlan_t vlan_id = VLAN_NULL; +#ifdef CONFIG_VLAN_TAGGED + int i; +#endif + + *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; + + 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; + + pos = buf; +#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; + } +#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; + } + 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; + } + } +#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; +} + + static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss, const char *fname) { FILE *f; - char buf[128], *pos, *pos2; - int line = 0; - vlan_t vlan_id = VLAN_NULL; + char buf[128]; + int line = 0, ret; struct hostapd_vlan *vlan; f = fopen(fname, "r"); @@ -43,59 +170,14 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss, 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 (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); - return -1; - } - vlan_alloc(&vlan_id, untagged_vlan_id, 0, NULL); - } - - 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); - return -1; - } - - vlan = os_zalloc(sizeof(*vlan)); - if (vlan == NULL) { - wpa_printf(MSG_ERROR, "Out of memory while reading " - "VLAN interfaces from '%s'", fname); + 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,122 @@ 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]; +#ifdef CONFIG_VLAN_TAGGED + int i; + char *pos2; + int untagged = 0; + int num_tagged = 0; + int *tagged = NULL; +#endif /* CONFIG_VLAN_TAGGED */ + + 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 */ + vlan_alloc(&(acl->vlan_id), untagged, num_tagged, tagged); +#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 +325,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 +339,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);