📄 config.c
字号:
/* * hostapd / Configuration file * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> * Copyright (c) 2007-2008, Intel Corporation * * 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"#ifndef CONFIG_NATIVE_WINDOWS#include <grp.h>#endif /* CONFIG_NATIVE_WINDOWS */#include "hostapd.h"#include "driver.h"#include "sha1.h"#include "eap_server/eap.h"#include "radius/radius_client.h"#include "wpa_common.h"#include "wpa.h"#include "uuid.h"#include "eap_common/eap_wsc_common.h"#define MAX_STA_COUNT 2007extern struct wpa_driver_ops *hostapd_drivers[];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_id; 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++; 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_id = VLAN_ID_WILDCARD; pos = buf + 1; } else { vlan_id = strtol(buf, &pos, 10); if (buf == pos || vlan_id < 1 || vlan_id > MAX_VLAN_ID) { wpa_printf(MSG_ERROR, "Invalid VLAN ID at " "line %d in '%s'", line, fname); fclose(f); return -1; } } 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_malloc(sizeof(*vlan)); if (vlan == NULL) { wpa_printf(MSG_ERROR, "Out of memory while reading " "VLAN interfaces from '%s'", fname); fclose(f); return -1; } os_memset(vlan, 0, sizeof(*vlan)); vlan->vlan_id = vlan_id; os_strlcpy(vlan->ifname, pos, sizeof(vlan->ifname)); if (bss->vlan_tail) bss->vlan_tail->next = vlan; else bss->vlan = vlan; bss->vlan_tail = vlan; } fclose(f); return 0;}static void hostapd_config_free_vlan(struct hostapd_bss_config *bss){ struct hostapd_vlan *vlan, *prev; vlan = bss->vlan; prev = NULL; while (vlan) { prev = vlan; vlan = vlan->next; os_free(prev); } bss->vlan = NULL;}/* convert floats with one decimal place to value*10 int, i.e., * "1.5" will return 15 */static int hostapd_config_read_int10(const char *value){ int i, d; char *pos; i = atoi(value); pos = os_strchr(value, '.'); d = 0; if (pos) { pos++; if (*pos >= '0' && *pos <= '9') d = *pos - '0'; } return i * 10 + d;}static void hostapd_config_defaults_bss(struct hostapd_bss_config *bss){ bss->logger_syslog_level = HOSTAPD_LEVEL_INFO; bss->logger_stdout_level = HOSTAPD_LEVEL_INFO; bss->logger_syslog = (unsigned int) -1; bss->logger_stdout = (unsigned int) -1; bss->auth_algs = WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED; bss->wep_rekeying_period = 300; /* use key0 in individual key and key1 in broadcast key */ bss->broadcast_key_idx_min = 1; bss->broadcast_key_idx_max = 2; bss->eap_reauth_period = 3600; bss->wpa_group_rekey = 600; bss->wpa_gmk_rekey = 86400; bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK; bss->wpa_pairwise = WPA_CIPHER_TKIP; bss->wpa_group = WPA_CIPHER_TKIP; bss->rsn_pairwise = 0; bss->max_num_sta = MAX_STA_COUNT; bss->dtim_period = 2; bss->radius_server_auth_port = 1812; bss->ap_max_inactivity = AP_MAX_INACTIVITY; bss->eapol_version = EAPOL_VERSION; bss->max_listen_interval = 65535;#ifdef CONFIG_IEEE80211W bss->assoc_sa_query_max_timeout = 1000; bss->assoc_sa_query_retry_timeout = 201;#endif /* CONFIG_IEEE80211W */#ifdef EAP_FAST /* both anonymous and authenticated provisioning */ bss->eap_fast_prov = 3; bss->pac_key_lifetime = 7 * 24 * 60 * 60; bss->pac_key_refresh_time = 1 * 24 * 60 * 60;#endif /* EAP_FAST */}static struct hostapd_config * hostapd_config_defaults(void){ struct hostapd_config *conf; struct hostapd_bss_config *bss; int i; const int aCWmin = 15, aCWmax = 1024; const struct hostapd_wme_ac_params ac_bk = { aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */ const struct hostapd_wme_ac_params ac_be = { aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */ const struct hostapd_wme_ac_params ac_vi = /* video traffic */ { aCWmin >> 1, aCWmin, 2, 3000 / 32, 1 }; const struct hostapd_wme_ac_params ac_vo = /* voice traffic */ { aCWmin >> 2, aCWmin >> 1, 2, 1500 / 32, 1 }; conf = os_zalloc(sizeof(*conf)); bss = os_zalloc(sizeof(*bss)); if (conf == NULL || bss == NULL) { wpa_printf(MSG_ERROR, "Failed to allocate memory for " "configuration data."); os_free(conf); os_free(bss); return NULL; } /* set default driver based on configuration */ conf->driver = hostapd_drivers[0]; if (conf->driver == NULL) { wpa_printf(MSG_ERROR, "No driver wrappers registered!"); os_free(conf); os_free(bss); return NULL; } bss->radius = os_zalloc(sizeof(*bss->radius)); if (bss->radius == NULL) { os_free(conf); os_free(bss); return NULL; } hostapd_config_defaults_bss(bss); conf->num_bss = 1; conf->bss = bss; conf->beacon_int = 100; conf->rts_threshold = -1; /* use driver default: 2347 */ conf->fragm_threshold = -1; /* user driver default: 2346 */ conf->send_probe_response = 1; conf->bridge_packets = INTERNAL_BRIDGE_DO_NOT_CONTROL; for (i = 0; i < NUM_TX_QUEUES; i++) conf->tx_queue[i].aifs = -1; /* use hw default */ conf->wme_ac_params[0] = ac_be; conf->wme_ac_params[1] = ac_bk; conf->wme_ac_params[2] = ac_vi; conf->wme_ac_params[3] = ac_vo;#ifdef CONFIG_IEEE80211N conf->ht_capab = HT_CAP_INFO_SMPS_DISABLED;#endif /* CONFIG_IEEE80211N */ return conf;}int hostapd_mac_comp(const void *a, const void *b){ return os_memcmp(a, b, sizeof(macaddr));}int hostapd_mac_comp_empty(const void *a){ macaddr empty = { 0 }; return os_memcmp(a, empty, sizeof(macaddr));}static int hostapd_acl_comp(const void *a, const void *b){ const struct mac_acl_entry *aa = a; const struct mac_acl_entry *bb = b; return os_memcmp(aa->addr, bb->addr, sizeof(macaddr));}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; int vlan_id; if (!fname) return 0; f = fopen(fname, "r"); if (!f) { wpa_printf(MSG_ERROR, "MAC list file '%s' not found.", fname); return -1; } 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); fclose(f); return -1; } vlan_id = 0; pos = buf; while (*pos != '\0' && *pos != ' ' && *pos != '\t') pos++; while (*pos == ' ' || *pos == '\t') pos++; if (*pos != '\0') vlan_id = atoi(pos); newacl = os_realloc(*acl, (*num + 1) * sizeof(**acl)); if (newacl == NULL) { wpa_printf(MSG_ERROR, "MAC list reallocation failed"); fclose(f); return -1; } *acl = newacl; os_memcpy((*acl)[*num].addr, addr, ETH_ALEN); (*acl)[*num].vlan_id = vlan_id; (*num)++; } fclose(f); qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp); return 0;}static int hostapd_config_read_wpa_psk(const char *fname, struct hostapd_ssid *ssid){ FILE *f; char buf[128], *pos; int line = 0, ret = 0, len, ok; u8 addr[ETH_ALEN]; struct hostapd_wpa_psk *psk; if (!fname) return 0; f = fopen(fname, "r"); if (!f) { wpa_printf(MSG_ERROR, "WPA PSK file '%s' not found.", fname); return -1; } 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' on " "line %d in '%s'", buf, line, fname); ret = -1; break; } psk = os_zalloc(sizeof(*psk)); if (psk == NULL) { wpa_printf(MSG_ERROR, "WPA PSK allocation failed"); ret = -1; break; } if (is_zero_ether_addr(addr)) psk->group = 1; else os_memcpy(psk->addr, addr, ETH_ALEN); pos = buf + 17; if (*pos == '\0') { wpa_printf(MSG_ERROR, "No PSK on line %d in '%s'", line, fname); os_free(psk); ret = -1; break; } pos++; ok = 0; len = os_strlen(pos); if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0) ok = 1; else if (len >= 8 && len < 64) { pbkdf2_sha1(pos, ssid->ssid, ssid->ssid_len, 4096, psk->psk, PMK_LEN); ok = 1; } if (!ok) { wpa_printf(MSG_ERROR, "Invalid PSK '%s' on line %d in " "'%s'", pos, line, fname); os_free(psk); ret = -1; break; } psk->next = ssid->wpa_psk; ssid->wpa_psk = psk; } fclose(f); return ret;}int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf){ struct hostapd_ssid *ssid = &conf->ssid; if (ssid->wpa_passphrase != NULL) { if (ssid->wpa_psk != NULL) { wpa_printf(MSG_ERROR, "Warning: both WPA PSK and " "passphrase set. Using passphrase."); os_free(ssid->wpa_psk); } ssid->wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk)); if (ssid->wpa_psk == NULL) { wpa_printf(MSG_ERROR, "Unable to alloc space for PSK"); return -1; } wpa_hexdump_ascii(MSG_DEBUG, "SSID", (u8 *) ssid->ssid, ssid->ssid_len); wpa_hexdump_ascii(MSG_DEBUG, "PSK (ASCII passphrase)", (u8 *) ssid->wpa_passphrase, os_strlen(ssid->wpa_passphrase)); pbkdf2_sha1(ssid->wpa_passphrase, ssid->ssid, ssid->ssid_len, 4096, ssid->wpa_psk->psk, PMK_LEN); wpa_hexdump(MSG_DEBUG, "PSK (from passphrase)", ssid->wpa_psk->psk, PMK_LEN); ssid->wpa_psk->group = 1; } if (ssid->wpa_psk_file) { if (hostapd_config_read_wpa_psk(ssid->wpa_psk_file, &conf->ssid)) return -1; } return 0;}#ifdef EAP_SERVERstatic int hostapd_config_read_eap_user(const char *fname, struct hostapd_bss_config *conf){ FILE *f; char buf[512], *pos, *start, *pos2; int line = 0, ret = 0, num_methods;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -