2 * hostapd / Configuration file
3 * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
16 #ifndef CONFIG_NATIVE_WINDOWS
18 #endif /* CONFIG_NATIVE_WINDOWS */
24 #include "radius_client.h"
25 #include "wpa_common.h"
28 #define MAX_STA_COUNT 2007
31 static int hostapd_config_read_vlan_file(struct hostapd_bss_config
*bss
,
35 char buf
[128], *pos
, *pos2
;
36 int line
= 0, vlan_id
;
37 struct hostapd_vlan
*vlan
;
39 f
= fopen(fname
, "r");
41 printf("VLAN file '%s' not readable.\n", fname
);
45 while (fgets(buf
, sizeof(buf
), f
)) {
51 while (*pos
!= '\0') {
62 vlan_id
= VLAN_ID_WILDCARD
;
65 vlan_id
= strtol(buf
, &pos
, 10);
66 if (buf
== pos
|| vlan_id
< 1 ||
67 vlan_id
> MAX_VLAN_ID
) {
68 printf("Invalid VLAN ID at line %d in '%s'\n",
75 while (*pos
== ' ' || *pos
== '\t')
78 while (*pos2
!= ' ' && *pos2
!= '\t' && *pos2
!= '\0')
81 if (*pos
== '\0' || strlen(pos
) > IFNAMSIZ
) {
82 printf("Invalid VLAN ifname at line %d in '%s'\n",
88 vlan
= malloc(sizeof(*vlan
));
90 printf("Out of memory while reading VLAN interfaces "
91 "from '%s'\n", fname
);
96 memset(vlan
, 0, sizeof(*vlan
));
97 vlan
->vlan_id
= vlan_id
;
98 strncpy(vlan
->ifname
, pos
, sizeof(vlan
->ifname
));
100 bss
->vlan_tail
->next
= vlan
;
103 bss
->vlan_tail
= vlan
;
112 static void hostapd_config_free_vlan(struct hostapd_bss_config
*bss
)
114 struct hostapd_vlan
*vlan
, *prev
;
128 /* convert floats with one decimal place to value*10 int, i.e.,
129 * "1.5" will return 15 */
130 static int hostapd_config_read_int10(const char *value
)
136 pos
= strchr(value
, '.');
140 if (*pos
>= '0' && *pos
<= '9')
148 static void hostapd_config_defaults_bss(struct hostapd_bss_config
*bss
)
150 bss
->logger_syslog_level
= HOSTAPD_LEVEL_INFO
;
151 bss
->logger_stdout_level
= HOSTAPD_LEVEL_INFO
;
152 bss
->logger_syslog
= (unsigned int) -1;
153 bss
->logger_stdout
= (unsigned int) -1;
155 bss
->auth_algs
= HOSTAPD_AUTH_OPEN
| HOSTAPD_AUTH_SHARED_KEY
;
157 bss
->wep_rekeying_period
= 300;
158 /* use key0 in individual key and key1 in broadcast key */
159 bss
->broadcast_key_idx_min
= 1;
160 bss
->broadcast_key_idx_max
= 2;
161 bss
->eap_reauth_period
= 3600;
163 bss
->wpa_group_rekey
= 600;
164 bss
->wpa_gmk_rekey
= 86400;
165 bss
->wpa_key_mgmt
= WPA_KEY_MGMT_PSK
;
166 bss
->wpa_pairwise
= WPA_CIPHER_TKIP
;
167 bss
->wpa_group
= WPA_CIPHER_TKIP
;
169 bss
->max_num_sta
= MAX_STA_COUNT
;
171 bss
->dtim_period
= 2;
173 bss
->radius_server_auth_port
= 1812;
174 bss
->ap_max_inactivity
= AP_MAX_INACTIVITY
;
175 bss
->eapol_version
= EAPOL_VERSION
;
179 static struct hostapd_config
* hostapd_config_defaults(void)
181 struct hostapd_config
*conf
;
182 struct hostapd_bss_config
*bss
;
184 const int aCWmin
= 15, aCWmax
= 1024;
185 const struct hostapd_wme_ac_params ac_bk
=
186 { aCWmin
, aCWmax
, 7, 0, 0 }; /* background traffic */
187 const struct hostapd_wme_ac_params ac_be
=
188 { aCWmin
, aCWmax
, 3, 0, 0 }; /* best effort traffic */
189 const struct hostapd_wme_ac_params ac_vi
= /* video traffic */
190 { aCWmin
>> 1, aCWmin
, 2, 3000 / 32, 1 };
191 const struct hostapd_wme_ac_params ac_vo
= /* voice traffic */
192 { aCWmin
>> 2, aCWmin
>> 1, 2, 1500 / 32, 1 };
194 conf
= wpa_zalloc(sizeof(*conf
));
195 bss
= wpa_zalloc(sizeof(*bss
));
196 if (conf
== NULL
|| bss
== NULL
) {
197 printf("Failed to allocate memory for configuration data.\n");
203 /* set default driver based on configuration */
204 conf
->driver
= driver_lookup("default");
205 if (conf
->driver
== NULL
) {
206 printf("No default driver registered!\n");
212 bss
->radius
= wpa_zalloc(sizeof(*bss
->radius
));
213 if (bss
->radius
== NULL
) {
219 hostapd_config_defaults_bss(bss
);
224 conf
->beacon_int
= 100;
225 conf
->rts_threshold
= -1; /* use driver default: 2347 */
226 conf
->fragm_threshold
= -1; /* user driver default: 2346 */
227 conf
->send_probe_response
= 1;
228 conf
->bridge_packets
= INTERNAL_BRIDGE_DO_NOT_CONTROL
;
230 memcpy(conf
->country
, "US ", 3);
232 for (i
= 0; i
< NUM_TX_QUEUES
; i
++)
233 conf
->tx_queue
[i
].aifs
= -1; /* use hw default */
235 conf
->wme_ac_params
[0] = ac_be
;
236 conf
->wme_ac_params
[1] = ac_bk
;
237 conf
->wme_ac_params
[2] = ac_vi
;
238 conf
->wme_ac_params
[3] = ac_vo
;
244 static int hostapd_parse_ip_addr(const char *txt
, struct hostapd_ip_addr
*addr
)
246 if (inet_aton(txt
, &addr
->u
.v4
)) {
252 if (inet_pton(AF_INET6
, txt
, &addr
->u
.v6
) > 0) {
256 #endif /* CONFIG_IPV6 */
262 int hostapd_mac_comp(const void *a
, const void *b
)
264 return memcmp(a
, b
, sizeof(macaddr
));
268 int hostapd_mac_comp_empty(const void *a
)
270 macaddr empty
= { 0 };
271 return memcmp(a
, empty
, sizeof(macaddr
));
275 static int hostapd_config_read_maclist(const char *fname
, macaddr
**acl
,
287 f
= fopen(fname
, "r");
289 printf("MAC list file '%s' not found.\n", fname
);
293 while (fgets(buf
, sizeof(buf
), f
)) {
299 while (*pos
!= '\0') {
309 if (hwaddr_aton(buf
, addr
)) {
310 printf("Invalid MAC address '%s' at line %d in '%s'\n",
316 newacl
= (macaddr
*) realloc(*acl
, (*num
+ 1) * ETH_ALEN
);
317 if (newacl
== NULL
) {
318 printf("MAC list reallocation failed\n");
324 memcpy((*acl
)[*num
], addr
, ETH_ALEN
);
330 qsort(*acl
, *num
, sizeof(macaddr
), hostapd_mac_comp
);
336 static int hostapd_config_read_wpa_psk(const char *fname
,
337 struct hostapd_ssid
*ssid
)
341 int line
= 0, ret
= 0, len
, ok
;
343 struct hostapd_wpa_psk
*psk
;
348 f
= fopen(fname
, "r");
350 printf("WPA PSK file '%s' not found.\n", fname
);
354 while (fgets(buf
, sizeof(buf
), f
)) {
360 while (*pos
!= '\0') {
370 if (hwaddr_aton(buf
, addr
)) {
371 printf("Invalid MAC address '%s' on line %d in '%s'\n",
377 psk
= wpa_zalloc(sizeof(*psk
));
379 printf("WPA PSK allocation failed\n");
383 if (memcmp(addr
, "\x00\x00\x00\x00\x00\x00", ETH_ALEN
) == 0)
386 memcpy(psk
->addr
, addr
, ETH_ALEN
);
390 printf("No PSK on line %d in '%s'\n", line
, fname
);
399 if (len
== 64 && hexstr2bin(pos
, psk
->psk
, PMK_LEN
) == 0)
401 else if (len
>= 8 && len
< 64) {
402 pbkdf2_sha1(pos
, ssid
->ssid
, ssid
->ssid_len
,
403 4096, psk
->psk
, PMK_LEN
);
407 printf("Invalid PSK '%s' on line %d in '%s'\n",
414 psk
->next
= ssid
->wpa_psk
;
424 int hostapd_setup_wpa_psk(struct hostapd_bss_config
*conf
)
426 struct hostapd_ssid
*ssid
= &conf
->ssid
;
428 if (ssid
->wpa_passphrase
!= NULL
) {
429 if (ssid
->wpa_psk
!= NULL
) {
430 printf("Warning: both WPA PSK and passphrase set. "
431 "Using passphrase.\n");
434 ssid
->wpa_psk
= wpa_zalloc(sizeof(struct hostapd_wpa_psk
));
435 if (ssid
->wpa_psk
== NULL
) {
436 printf("Unable to alloc space for PSK\n");
439 wpa_hexdump_ascii(MSG_DEBUG
, "SSID",
440 (u8
*) ssid
->ssid
, ssid
->ssid_len
);
441 wpa_hexdump_ascii(MSG_DEBUG
, "PSK (ASCII passphrase)",
442 (u8
*) ssid
->wpa_passphrase
,
443 strlen(ssid
->wpa_passphrase
));
444 pbkdf2_sha1(ssid
->wpa_passphrase
,
445 ssid
->ssid
, ssid
->ssid_len
,
446 4096, ssid
->wpa_psk
->psk
, PMK_LEN
);
447 wpa_hexdump(MSG_DEBUG
, "PSK (from passphrase)",
448 ssid
->wpa_psk
->psk
, PMK_LEN
);
449 ssid
->wpa_psk
->group
= 1;
451 memset(ssid
->wpa_passphrase
, 0,
452 strlen(ssid
->wpa_passphrase
));
453 free(ssid
->wpa_passphrase
);
454 ssid
->wpa_passphrase
= NULL
;
457 if (ssid
->wpa_psk_file
) {
458 if (hostapd_config_read_wpa_psk(ssid
->wpa_psk_file
,
461 free(ssid
->wpa_psk_file
);
462 ssid
->wpa_psk_file
= NULL
;
470 static int hostapd_config_read_eap_user(const char *fname
,
471 struct hostapd_bss_config
*conf
)
474 char buf
[512], *pos
, *start
, *pos2
;
475 int line
= 0, ret
= 0, num_methods
;
476 struct hostapd_eap_user
*user
, *tail
= NULL
;
481 f
= fopen(fname
, "r");
483 printf("EAP user file '%s' not found.\n", fname
);
487 /* Lines: "user" METHOD,METHOD2 "password" (password optional) */
488 while (fgets(buf
, sizeof(buf
), f
)) {
494 while (*pos
!= '\0') {
506 if (buf
[0] != '"' && buf
[0] != '*') {
507 printf("Invalid EAP identity (no \" in start) on "
508 "line %d in '%s'\n", line
, fname
);
512 user
= wpa_zalloc(sizeof(*user
));
514 printf("EAP user allocation failed\n");
517 user
->force_version
= -1;
524 while (*pos
!= '"' && *pos
!= '\0')
527 printf("Invalid EAP identity (no \" in end) on"
528 " line %d in '%s'\n", line
, fname
);
532 user
->identity
= malloc(pos
- start
);
533 if (user
->identity
== NULL
) {
534 printf("Failed to allocate memory for EAP "
538 memcpy(user
->identity
, start
, pos
- start
);
539 user
->identity_len
= pos
- start
;
541 if (pos
[0] == '"' && pos
[1] == '*') {
542 user
->wildcard_prefix
= 1;
547 while (*pos
== ' ' || *pos
== '\t')
551 printf("No EAP method on line %d in '%s'\n",
557 while (*pos
!= ' ' && *pos
!= '\t' && *pos
!= '\0')
567 char *pos3
= strchr(start
, ',');
571 user
->methods
[num_methods
].method
=
572 eap_get_type(start
, &user
->methods
[num_methods
]
574 if (user
->methods
[num_methods
].vendor
==
576 user
->methods
[num_methods
].method
== EAP_TYPE_NONE
)
578 printf("Unsupported EAP type '%s' on line %d "
579 "in '%s'\n", start
, line
, fname
);
584 if (num_methods
>= EAP_USER_MAX_METHODS
)
590 if (num_methods
== 0) {
591 printf("No EAP types configured on line %d in '%s'\n",
599 while (*pos
== ' ' || *pos
== '\t')
604 if (strncmp(pos
, "[ver=0]", 7) == 0) {
605 user
->force_version
= 0;
609 if (strncmp(pos
, "[ver=1]", 7) == 0) {
610 user
->force_version
= 1;
614 if (strncmp(pos
, "[2]", 3) == 0) {
622 while (*pos
!= '"' && *pos
!= '\0')
625 printf("Invalid EAP password (no \" in end) "
626 "on line %d in '%s'\n", line
, fname
);
630 user
->password
= malloc(pos
- start
);
631 if (user
->password
== NULL
) {
632 printf("Failed to allocate memory for EAP "
636 memcpy(user
->password
, start
, pos
- start
);
637 user
->password_len
= pos
- start
;
640 } else if (strncmp(pos
, "hash:", 5) == 0) {
643 while (*pos2
!= '\0' && *pos2
!= ' ' &&
644 *pos2
!= '\t' && *pos2
!= '#')
646 if (pos2
- pos
!= 32) {
647 printf("Invalid password hash on line %d in "
648 "'%s'\n", line
, fname
);
651 user
->password
= malloc(16);
652 if (user
->password
== NULL
) {
653 printf("Failed to allocate memory for EAP "
657 if (hexstr2bin(pos
, user
->password
, 16) < 0) {
658 printf("Invalid hash password on line %d in "
659 "'%s'\n", line
, fname
);
662 user
->password_len
= 16;
663 user
->password_hash
= 1;
667 while (*pos2
!= '\0' && *pos2
!= ' ' &&
668 *pos2
!= '\t' && *pos2
!= '#')
670 if ((pos2
- pos
) & 1) {
671 printf("Invalid hex password on line %d in "
672 "'%s'\n", line
, fname
);
675 user
->password
= malloc((pos2
- pos
) / 2);
676 if (user
->password
== NULL
) {
677 printf("Failed to allocate memory for EAP "
681 if (hexstr2bin(pos
, user
->password
,
682 (pos2
- pos
) / 2) < 0) {
683 printf("Invalid hex password on line %d in "
684 "'%s'\n", line
, fname
);
687 user
->password_len
= (pos2
- pos
) / 2;
691 while (*pos
== ' ' || *pos
== '\t')
693 if (strncmp(pos
, "[2]", 3) == 0) {
699 tail
= conf
->eap_user
= user
;
708 free(user
->password
);
709 free(user
->identity
);
720 #endif /* EAP_SERVER */
724 hostapd_config_read_radius_addr(struct hostapd_radius_server
**server
,
725 int *num_server
, const char *val
, int def_port
,
726 struct hostapd_radius_server
**curr_serv
)
728 struct hostapd_radius_server
*nserv
;
730 static int server_index
= 1;
732 nserv
= realloc(*server
, (*num_server
+ 1) * sizeof(*nserv
));
737 nserv
= &nserv
[*num_server
];
739 (*curr_serv
) = nserv
;
741 memset(nserv
, 0, sizeof(*nserv
));
742 nserv
->port
= def_port
;
743 ret
= hostapd_parse_ip_addr(val
, &nserv
->addr
);
744 nserv
->index
= server_index
++;
750 static int hostapd_config_parse_key_mgmt(int line
, const char *value
)
753 char *start
, *end
, *buf
;
760 while (start
!= '\0') {
761 while (*start
== ' ' || *start
== '\t')
766 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
770 if (strcmp(start
, "WPA-PSK") == 0)
771 val
|= WPA_KEY_MGMT_PSK
;
772 else if (strcmp(start
, "WPA-EAP") == 0)
773 val
|= WPA_KEY_MGMT_IEEE8021X
;
775 printf("Line %d: invalid key_mgmt '%s'\n",
788 printf("Line %d: no key_mgmt values configured.\n", line
);
796 static int hostapd_config_parse_cipher(int line
, const char *value
)
799 char *start
, *end
, *buf
;
806 while (start
!= '\0') {
807 while (*start
== ' ' || *start
== '\t')
812 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
816 if (strcmp(start
, "CCMP") == 0)
817 val
|= WPA_CIPHER_CCMP
;
818 else if (strcmp(start
, "TKIP") == 0)
819 val
|= WPA_CIPHER_TKIP
;
820 else if (strcmp(start
, "WEP104") == 0)
821 val
|= WPA_CIPHER_WEP104
;
822 else if (strcmp(start
, "WEP40") == 0)
823 val
|= WPA_CIPHER_WEP40
;
824 else if (strcmp(start
, "NONE") == 0)
825 val
|= WPA_CIPHER_NONE
;
827 printf("Line %d: invalid cipher '%s'.", line
, start
);
839 printf("Line %d: no cipher values configured.", line
);
846 static int hostapd_config_check_bss(struct hostapd_bss_config
*bss
,
847 struct hostapd_config
*conf
)
849 if (bss
->ieee802_1x
&& !bss
->eap_server
&&
850 !bss
->radius
->auth_servers
) {
851 printf("Invalid IEEE 802.1X configuration (no EAP "
852 "authenticator configured).\n");
856 if (bss
->wpa
&& (bss
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
) &&
857 bss
->ssid
.wpa_psk
== NULL
&& bss
->ssid
.wpa_passphrase
== NULL
&&
858 bss
->ssid
.wpa_psk_file
== NULL
) {
859 printf("WPA-PSK enabled, but PSK or passphrase is not "
864 if (hostapd_mac_comp_empty(bss
->bssid
) != 0) {
867 for (i
= 0; i
< conf
->num_bss
; i
++) {
868 if ((&conf
->bss
[i
] != bss
) &&
869 (hostapd_mac_comp(conf
->bss
[i
].bssid
,
871 printf("Duplicate BSSID " MACSTR
872 " on interface '%s' and '%s'.\n",
874 conf
->bss
[i
].iface
, bss
->iface
);
884 static int hostapd_config_check(struct hostapd_config
*conf
)
888 for (i
= 0; i
< conf
->num_bss
; i
++) {
889 if (hostapd_config_check_bss(&conf
->bss
[i
], conf
))
897 static int hostapd_config_read_wep(struct hostapd_wep_keys
*wep
, int keyidx
,
900 size_t len
= strlen(val
);
902 if (keyidx
< 0 || keyidx
> 3 || wep
->key
[keyidx
] != NULL
)
906 if (len
< 2 || val
[len
- 1] != '"')
909 wep
->key
[keyidx
] = malloc(len
);
910 if (wep
->key
[keyidx
] == NULL
)
912 memcpy(wep
->key
[keyidx
], val
+ 1, len
);
913 wep
->len
[keyidx
] = len
;
918 wep
->key
[keyidx
] = malloc(len
);
919 if (wep
->key
[keyidx
] == NULL
)
921 wep
->len
[keyidx
] = len
;
922 if (hexstr2bin(val
, wep
->key
[keyidx
], len
) < 0)
932 static int hostapd_parse_rates(int **rate_list
, char *val
)
943 while (*pos
!= '\0') {
949 list
= malloc(sizeof(int) * (count
+ 2));
954 while (*pos
!= '\0') {
955 end
= strchr(pos
, ' ');
959 list
[count
++] = atoi(pos
);
971 static int hostapd_config_bss(struct hostapd_config
*conf
, const char *ifname
)
973 struct hostapd_bss_config
*bss
;
978 bss
= realloc(conf
->bss
, (conf
->num_bss
+ 1) *
979 sizeof(struct hostapd_bss_config
));
981 printf("Failed to allocate memory for multi-BSS entry\n");
986 bss
= &(conf
->bss
[conf
->num_bss
]);
987 memset(bss
, 0, sizeof(*bss
));
988 bss
->radius
= wpa_zalloc(sizeof(*bss
->radius
));
989 if (bss
->radius
== NULL
) {
990 printf("Failed to allocate memory for multi-BSS RADIUS "
996 conf
->last_bss
= bss
;
998 hostapd_config_defaults_bss(bss
);
999 snprintf(bss
->iface
, sizeof(bss
->iface
), "%s", ifname
);
1000 memcpy(bss
->ssid
.vlan
, bss
->iface
, IFNAMSIZ
+ 1);
1006 static int valid_cw(int cw
)
1008 return (cw
== 1 || cw
== 3 || cw
== 7 || cw
== 15 || cw
== 31 ||
1009 cw
== 63 || cw
== 127 || cw
== 255 || cw
== 511 || cw
== 1023);
1014 IEEE80211_TX_QUEUE_DATA0
= 0, /* used for EDCA AC_VO data */
1015 IEEE80211_TX_QUEUE_DATA1
= 1, /* used for EDCA AC_VI data */
1016 IEEE80211_TX_QUEUE_DATA2
= 2, /* used for EDCA AC_BE data */
1017 IEEE80211_TX_QUEUE_DATA3
= 3, /* used for EDCA AC_BK data */
1018 IEEE80211_TX_QUEUE_DATA4
= 4,
1019 IEEE80211_TX_QUEUE_AFTER_BEACON
= 6,
1020 IEEE80211_TX_QUEUE_BEACON
= 7
1023 static int hostapd_config_tx_queue(struct hostapd_config
*conf
, char *name
,
1028 struct hostapd_tx_queue_params
*queue
;
1030 /* skip 'tx_queue_' prefix */
1032 if (strncmp(pos
, "data", 4) == 0 &&
1033 pos
[4] >= '0' && pos
[4] <= '9' && pos
[5] == '_') {
1036 } else if (strncmp(pos
, "after_beacon_", 13) == 0) {
1037 num
= IEEE80211_TX_QUEUE_AFTER_BEACON
;
1039 } else if (strncmp(pos
, "beacon_", 7) == 0) {
1040 num
= IEEE80211_TX_QUEUE_BEACON
;
1043 printf("Unknown tx_queue name '%s'\n", pos
);
1047 queue
= &conf
->tx_queue
[num
];
1049 if (strcmp(pos
, "aifs") == 0) {
1050 queue
->aifs
= atoi(val
);
1051 if (queue
->aifs
< 0 || queue
->aifs
> 255) {
1052 printf("Invalid AIFS value %d\n", queue
->aifs
);
1055 } else if (strcmp(pos
, "cwmin") == 0) {
1056 queue
->cwmin
= atoi(val
);
1057 if (!valid_cw(queue
->cwmin
)) {
1058 printf("Invalid cwMin value %d\n", queue
->cwmin
);
1061 } else if (strcmp(pos
, "cwmax") == 0) {
1062 queue
->cwmax
= atoi(val
);
1063 if (!valid_cw(queue
->cwmax
)) {
1064 printf("Invalid cwMax value %d\n", queue
->cwmax
);
1067 } else if (strcmp(pos
, "burst") == 0) {
1068 queue
->burst
= hostapd_config_read_int10(val
);
1070 printf("Unknown tx_queue field '%s'\n", pos
);
1074 queue
->configured
= 1;
1080 static int hostapd_config_wme_ac(struct hostapd_config
*conf
, char *name
,
1085 struct hostapd_wme_ac_params
*ac
;
1087 /* skip 'wme_ac_' prefix */
1089 if (strncmp(pos
, "be_", 3) == 0) {
1092 } else if (strncmp(pos
, "bk_", 3) == 0) {
1095 } else if (strncmp(pos
, "vi_", 3) == 0) {
1098 } else if (strncmp(pos
, "vo_", 3) == 0) {
1102 printf("Unknown wme name '%s'\n", pos
);
1106 ac
= &conf
->wme_ac_params
[num
];
1108 if (strcmp(pos
, "aifs") == 0) {
1110 if (v
< 1 || v
> 255) {
1111 printf("Invalid AIFS value %d\n", v
);
1115 } else if (strcmp(pos
, "cwmin") == 0) {
1117 if (v
< 0 || v
> 12) {
1118 printf("Invalid cwMin value %d\n", v
);
1122 } else if (strcmp(pos
, "cwmax") == 0) {
1124 if (v
< 0 || v
> 12) {
1125 printf("Invalid cwMax value %d\n", v
);
1129 } else if (strcmp(pos
, "txop_limit") == 0) {
1131 if (v
< 0 || v
> 0xffff) {
1132 printf("Invalid txop value %d\n", v
);
1136 } else if (strcmp(pos
, "acm") == 0) {
1138 if (v
< 0 || v
> 1) {
1139 printf("Invalid acm value %d\n", v
);
1142 ac
->admission_control_mandatory
= v
;
1144 printf("Unknown wme_ac_ field '%s'\n", pos
);
1152 struct hostapd_config
* hostapd_config_read(const char *fname
)
1154 struct hostapd_config
*conf
;
1155 struct hostapd_bss_config
*bss
;
1157 char buf
[256], *pos
;
1162 f
= fopen(fname
, "r");
1164 printf("Could not open configuration file '%s' for reading.\n",
1169 conf
= hostapd_config_defaults();
1174 bss
= conf
->last_bss
= conf
->bss
;
1176 while (fgets(buf
, sizeof(buf
), f
)) {
1177 bss
= conf
->last_bss
;
1183 while (*pos
!= '\0') {
1193 pos
= strchr(buf
, '=');
1195 printf("Line %d: invalid line '%s'\n", line
, buf
);
1202 if (strcmp(buf
, "interface") == 0) {
1203 snprintf(conf
->bss
[0].iface
,
1204 sizeof(conf
->bss
[0].iface
), "%s", pos
);
1205 } else if (strcmp(buf
, "bridge") == 0) {
1206 snprintf(bss
->bridge
, sizeof(bss
->bridge
), "%s", pos
);
1207 } else if (strcmp(buf
, "driver") == 0) {
1208 conf
->driver
= driver_lookup(pos
);
1209 if (conf
->driver
== NULL
) {
1210 printf("Line %d: invalid/unknown driver "
1211 "'%s'\n", line
, pos
);
1214 } else if (strcmp(buf
, "debug") == 0) {
1215 bss
->debug
= atoi(pos
);
1216 } else if (strcmp(buf
, "logger_syslog_level") == 0) {
1217 bss
->logger_syslog_level
= atoi(pos
);
1218 } else if (strcmp(buf
, "logger_stdout_level") == 0) {
1219 bss
->logger_stdout_level
= atoi(pos
);
1220 } else if (strcmp(buf
, "logger_syslog") == 0) {
1221 bss
->logger_syslog
= atoi(pos
);
1222 } else if (strcmp(buf
, "logger_stdout") == 0) {
1223 bss
->logger_stdout
= atoi(pos
);
1224 } else if (strcmp(buf
, "dump_file") == 0) {
1225 bss
->dump_log_name
= strdup(pos
);
1226 } else if (strcmp(buf
, "ssid") == 0) {
1227 bss
->ssid
.ssid_len
= strlen(pos
);
1228 if (bss
->ssid
.ssid_len
> HOSTAPD_MAX_SSID_LEN
||
1229 bss
->ssid
.ssid_len
< 1) {
1230 printf("Line %d: invalid SSID '%s'\n", line
,
1234 memcpy(bss
->ssid
.ssid
, pos
,
1235 bss
->ssid
.ssid_len
);
1236 bss
->ssid
.ssid
[bss
->ssid
.ssid_len
] = '\0';
1237 bss
->ssid
.ssid_set
= 1;
1239 } else if (strcmp(buf
, "macaddr_acl") == 0) {
1240 bss
->macaddr_acl
= atoi(pos
);
1241 if (bss
->macaddr_acl
!= ACCEPT_UNLESS_DENIED
&&
1242 bss
->macaddr_acl
!= DENY_UNLESS_ACCEPTED
&&
1243 bss
->macaddr_acl
!= USE_EXTERNAL_RADIUS_AUTH
) {
1244 printf("Line %d: unknown macaddr_acl %d\n",
1245 line
, bss
->macaddr_acl
);
1247 } else if (strcmp(buf
, "accept_mac_file") == 0) {
1248 if (hostapd_config_read_maclist(pos
, &bss
->accept_mac
,
1249 &bss
->num_accept_mac
))
1251 printf("Line %d: Failed to read "
1252 "accept_mac_file '%s'\n",
1256 } else if (strcmp(buf
, "deny_mac_file") == 0) {
1257 if (hostapd_config_read_maclist(pos
, &bss
->deny_mac
,
1258 &bss
->num_deny_mac
))
1260 printf("Line %d: Failed to read "
1261 "deny_mac_file '%s'\n",
1265 } else if (strcmp(buf
, "ap_max_inactivity") == 0) {
1266 bss
->ap_max_inactivity
= atoi(pos
);
1267 } else if (strcmp(buf
, "country_code") == 0) {
1268 memcpy(conf
->country
, pos
, 2);
1269 /* FIX: make this configurable */
1270 conf
->country
[2] = ' ';
1271 } else if (strcmp(buf
, "ieee80211d") == 0) {
1272 conf
->ieee80211d
= atoi(pos
);
1273 } else if (strcmp(buf
, "ieee80211h") == 0) {
1274 conf
->ieee80211h
= atoi(pos
);
1275 } else if (strcmp(buf
, "assoc_ap_addr") == 0) {
1276 if (hwaddr_aton(pos
, bss
->assoc_ap_addr
)) {
1277 printf("Line %d: invalid MAC address '%s'\n",
1282 } else if (strcmp(buf
, "ieee8021x") == 0) {
1283 bss
->ieee802_1x
= atoi(pos
);
1284 } else if (strcmp(buf
, "eapol_version") == 0) {
1285 bss
->eapol_version
= atoi(pos
);
1286 if (bss
->eapol_version
< 1 ||
1287 bss
->eapol_version
> 2) {
1288 printf("Line %d: invalid EAPOL "
1289 "version (%d): '%s'.\n",
1290 line
, bss
->eapol_version
, pos
);
1293 wpa_printf(MSG_DEBUG
, "eapol_version=%d",
1294 bss
->eapol_version
);
1296 } else if (strcmp(buf
, "eap_authenticator") == 0) {
1297 bss
->eap_server
= atoi(pos
);
1298 printf("Line %d: obsolete eap_authenticator used; "
1299 "this has been renamed to eap_server\n", line
);
1300 } else if (strcmp(buf
, "eap_server") == 0) {
1301 bss
->eap_server
= atoi(pos
);
1302 } else if (strcmp(buf
, "eap_user_file") == 0) {
1303 if (hostapd_config_read_eap_user(pos
, bss
))
1305 } else if (strcmp(buf
, "ca_cert") == 0) {
1307 bss
->ca_cert
= strdup(pos
);
1308 } else if (strcmp(buf
, "server_cert") == 0) {
1309 free(bss
->server_cert
);
1310 bss
->server_cert
= strdup(pos
);
1311 } else if (strcmp(buf
, "private_key") == 0) {
1312 free(bss
->private_key
);
1313 bss
->private_key
= strdup(pos
);
1314 } else if (strcmp(buf
, "private_key_passwd") == 0) {
1315 free(bss
->private_key_passwd
);
1316 bss
->private_key_passwd
= strdup(pos
);
1317 } else if (strcmp(buf
, "check_crl") == 0) {
1318 bss
->check_crl
= atoi(pos
);
1320 } else if (strcmp(buf
, "eap_sim_db") == 0) {
1321 free(bss
->eap_sim_db
);
1322 bss
->eap_sim_db
= strdup(pos
);
1323 #endif /* EAP_SIM */
1324 #endif /* EAP_SERVER */
1325 } else if (strcmp(buf
, "eap_message") == 0) {
1327 bss
->eap_req_id_text
= strdup(pos
);
1328 if (bss
->eap_req_id_text
== NULL
) {
1329 printf("Line %d: Failed to allocate memory "
1330 "for eap_req_id_text\n", line
);
1334 bss
->eap_req_id_text_len
=
1335 strlen(bss
->eap_req_id_text
);
1336 term
= strstr(bss
->eap_req_id_text
, "\\0");
1339 memmove(term
, term
+ 1,
1340 bss
->eap_req_id_text_len
-
1341 (term
- bss
->eap_req_id_text
) - 1);
1342 bss
->eap_req_id_text_len
--;
1344 } else if (strcmp(buf
, "wep_key_len_broadcast") == 0) {
1345 bss
->default_wep_key_len
= atoi(pos
);
1346 if (bss
->default_wep_key_len
> 13) {
1347 printf("Line %d: invalid WEP key len %lu "
1348 "(= %lu bits)\n", line
,
1350 bss
->default_wep_key_len
,
1352 bss
->default_wep_key_len
* 8);
1355 } else if (strcmp(buf
, "wep_key_len_unicast") == 0) {
1356 bss
->individual_wep_key_len
= atoi(pos
);
1357 if (bss
->individual_wep_key_len
< 0 ||
1358 bss
->individual_wep_key_len
> 13) {
1359 printf("Line %d: invalid WEP key len %d "
1360 "(= %d bits)\n", line
,
1361 bss
->individual_wep_key_len
,
1362 bss
->individual_wep_key_len
* 8);
1365 } else if (strcmp(buf
, "wep_rekey_period") == 0) {
1366 bss
->wep_rekeying_period
= atoi(pos
);
1367 if (bss
->wep_rekeying_period
< 0) {
1368 printf("Line %d: invalid period %d\n",
1369 line
, bss
->wep_rekeying_period
);
1372 } else if (strcmp(buf
, "eap_reauth_period") == 0) {
1373 bss
->eap_reauth_period
= atoi(pos
);
1374 if (bss
->eap_reauth_period
< 0) {
1375 printf("Line %d: invalid period %d\n",
1376 line
, bss
->eap_reauth_period
);
1379 } else if (strcmp(buf
, "eapol_key_index_workaround") == 0) {
1380 bss
->eapol_key_index_workaround
= atoi(pos
);
1382 } else if (strcmp(buf
, "iapp_interface") == 0) {
1383 bss
->ieee802_11f
= 1;
1384 snprintf(bss
->iapp_iface
, sizeof(bss
->iapp_iface
),
1386 #endif /* CONFIG_IAPP */
1387 } else if (strcmp(buf
, "own_ip_addr") == 0) {
1388 if (hostapd_parse_ip_addr(pos
, &bss
->own_ip_addr
)) {
1389 printf("Line %d: invalid IP address '%s'\n",
1393 } else if (strcmp(buf
, "nas_identifier") == 0) {
1394 bss
->nas_identifier
= strdup(pos
);
1395 } else if (strcmp(buf
, "auth_server_addr") == 0) {
1396 if (hostapd_config_read_radius_addr(
1397 &bss
->radius
->auth_servers
,
1398 &bss
->radius
->num_auth_servers
, pos
, 1812,
1399 &bss
->radius
->auth_server
)) {
1400 printf("Line %d: invalid IP address '%s'\n",
1404 } else if (bss
->radius
->auth_server
&&
1405 strcmp(buf
, "auth_server_port") == 0) {
1406 bss
->radius
->auth_server
->port
= atoi(pos
);
1407 } else if (bss
->radius
->auth_server
&&
1408 strcmp(buf
, "auth_server_shared_secret") == 0) {
1409 int len
= strlen(pos
);
1411 /* RFC 2865, Ch. 3 */
1412 printf("Line %d: empty shared secret is not "
1413 "allowed.\n", line
);
1416 bss
->radius
->auth_server
->shared_secret
=
1418 bss
->radius
->auth_server
->shared_secret_len
= len
;
1419 } else if (strcmp(buf
, "acct_server_addr") == 0) {
1420 if (hostapd_config_read_radius_addr(
1421 &bss
->radius
->acct_servers
,
1422 &bss
->radius
->num_acct_servers
, pos
, 1813,
1423 &bss
->radius
->acct_server
)) {
1424 printf("Line %d: invalid IP address '%s'\n",
1428 } else if (bss
->radius
->acct_server
&&
1429 strcmp(buf
, "acct_server_port") == 0) {
1430 bss
->radius
->acct_server
->port
= atoi(pos
);
1431 } else if (bss
->radius
->acct_server
&&
1432 strcmp(buf
, "acct_server_shared_secret") == 0) {
1433 int len
= strlen(pos
);
1435 /* RFC 2865, Ch. 3 */
1436 printf("Line %d: empty shared secret is not "
1437 "allowed.\n", line
);
1440 bss
->radius
->acct_server
->shared_secret
=
1442 bss
->radius
->acct_server
->shared_secret_len
= len
;
1443 } else if (strcmp(buf
, "radius_retry_primary_interval") == 0) {
1444 bss
->radius
->retry_primary_interval
= atoi(pos
);
1445 } else if (strcmp(buf
, "radius_acct_interim_interval") == 0) {
1446 bss
->radius
->acct_interim_interval
= atoi(pos
);
1447 } else if (strcmp(buf
, "auth_algs") == 0) {
1448 bss
->auth_algs
= atoi(pos
);
1449 if (bss
->auth_algs
== 0) {
1450 printf("Line %d: no authentication algorithms "
1455 } else if (strcmp(buf
, "max_num_sta") == 0) {
1456 bss
->max_num_sta
= atoi(pos
);
1457 if (bss
->max_num_sta
< 0 ||
1458 bss
->max_num_sta
> MAX_STA_COUNT
) {
1459 printf("Line %d: Invalid max_num_sta=%d; "
1460 "allowed range 0..%d\n", line
,
1461 bss
->max_num_sta
, MAX_STA_COUNT
);
1464 } else if (strcmp(buf
, "wpa") == 0) {
1465 bss
->wpa
= atoi(pos
);
1466 } else if (strcmp(buf
, "wpa_group_rekey") == 0) {
1467 bss
->wpa_group_rekey
= atoi(pos
);
1468 } else if (strcmp(buf
, "wpa_strict_rekey") == 0) {
1469 bss
->wpa_strict_rekey
= atoi(pos
);
1470 } else if (strcmp(buf
, "wpa_gmk_rekey") == 0) {
1471 bss
->wpa_gmk_rekey
= atoi(pos
);
1472 } else if (strcmp(buf
, "wpa_passphrase") == 0) {
1473 int len
= strlen(pos
);
1474 if (len
< 8 || len
> 63) {
1475 printf("Line %d: invalid WPA passphrase length"
1476 " %d (expected 8..63)\n", line
, len
);
1479 free(bss
->ssid
.wpa_passphrase
);
1480 bss
->ssid
.wpa_passphrase
= strdup(pos
);
1482 } else if (strcmp(buf
, "wpa_psk") == 0) {
1483 free(bss
->ssid
.wpa_psk
);
1485 wpa_zalloc(sizeof(struct hostapd_wpa_psk
));
1486 if (bss
->ssid
.wpa_psk
== NULL
)
1488 else if (hexstr2bin(pos
, bss
->ssid
.wpa_psk
->psk
,
1490 pos
[PMK_LEN
* 2] != '\0') {
1491 printf("Line %d: Invalid PSK '%s'.\n", line
,
1495 bss
->ssid
.wpa_psk
->group
= 1;
1497 } else if (strcmp(buf
, "wpa_psk_file") == 0) {
1498 free(bss
->ssid
.wpa_psk_file
);
1499 bss
->ssid
.wpa_psk_file
= strdup(pos
);
1500 if (!bss
->ssid
.wpa_psk_file
) {
1501 printf("Line %d: allocation failed\n", line
);
1504 } else if (strcmp(buf
, "wpa_key_mgmt") == 0) {
1506 hostapd_config_parse_key_mgmt(line
, pos
);
1507 if (bss
->wpa_key_mgmt
== -1)
1509 } else if (strcmp(buf
, "wpa_pairwise") == 0) {
1511 hostapd_config_parse_cipher(line
, pos
);
1512 if (bss
->wpa_pairwise
== -1 ||
1513 bss
->wpa_pairwise
== 0)
1515 else if (bss
->wpa_pairwise
&
1516 (WPA_CIPHER_NONE
| WPA_CIPHER_WEP40
|
1517 WPA_CIPHER_WEP104
)) {
1518 printf("Line %d: unsupported pairwise "
1519 "cipher suite '%s'\n",
1520 bss
->wpa_pairwise
, pos
);
1523 if (bss
->wpa_pairwise
& WPA_CIPHER_TKIP
)
1524 bss
->wpa_group
= WPA_CIPHER_TKIP
;
1526 bss
->wpa_group
= WPA_CIPHER_CCMP
;
1528 #ifdef CONFIG_RSN_PREAUTH
1529 } else if (strcmp(buf
, "rsn_preauth") == 0) {
1530 bss
->rsn_preauth
= atoi(pos
);
1531 } else if (strcmp(buf
, "rsn_preauth_interfaces") == 0) {
1532 bss
->rsn_preauth_interfaces
= strdup(pos
);
1533 #endif /* CONFIG_RSN_PREAUTH */
1534 #ifdef CONFIG_PEERKEY
1535 } else if (strcmp(buf
, "peerkey") == 0) {
1536 bss
->peerkey
= atoi(pos
);
1537 #endif /* CONFIG_PEERKEY */
1538 } else if (strcmp(buf
, "ctrl_interface") == 0) {
1539 free(bss
->ctrl_interface
);
1540 bss
->ctrl_interface
= strdup(pos
);
1541 } else if (strcmp(buf
, "ctrl_interface_group") == 0) {
1542 #ifndef CONFIG_NATIVE_WINDOWS
1545 const char *group
= pos
;
1547 grp
= getgrnam(group
);
1549 bss
->ctrl_interface_gid
= grp
->gr_gid
;
1550 bss
->ctrl_interface_gid_set
= 1;
1551 wpa_printf(MSG_DEBUG
, "ctrl_interface_group=%d"
1552 " (from group name '%s')",
1553 bss
->ctrl_interface_gid
, group
);
1557 /* Group name not found - try to parse this as gid */
1558 bss
->ctrl_interface_gid
= strtol(group
, &endp
, 10);
1559 if (*group
== '\0' || *endp
!= '\0') {
1560 wpa_printf(MSG_DEBUG
, "Line %d: Invalid group "
1561 "'%s'", line
, group
);
1565 bss
->ctrl_interface_gid_set
= 1;
1566 wpa_printf(MSG_DEBUG
, "ctrl_interface_group=%d",
1567 bss
->ctrl_interface_gid
);
1568 #endif /* CONFIG_NATIVE_WINDOWS */
1569 #ifdef RADIUS_SERVER
1570 } else if (strcmp(buf
, "radius_server_clients") == 0) {
1571 free(bss
->radius_server_clients
);
1572 bss
->radius_server_clients
= strdup(pos
);
1573 } else if (strcmp(buf
, "radius_server_auth_port") == 0) {
1574 bss
->radius_server_auth_port
= atoi(pos
);
1575 } else if (strcmp(buf
, "radius_server_ipv6") == 0) {
1576 bss
->radius_server_ipv6
= atoi(pos
);
1577 #endif /* RADIUS_SERVER */
1578 } else if (strcmp(buf
, "test_socket") == 0) {
1579 free(bss
->test_socket
);
1580 bss
->test_socket
= strdup(pos
);
1581 } else if (strcmp(buf
, "use_pae_group_addr") == 0) {
1582 bss
->use_pae_group_addr
= atoi(pos
);
1583 } else if (strcmp(buf
, "hw_mode") == 0) {
1584 if (strcmp(pos
, "a") == 0)
1585 conf
->hw_mode
= HOSTAPD_MODE_IEEE80211A
;
1586 else if (strcmp(pos
, "b") == 0)
1587 conf
->hw_mode
= HOSTAPD_MODE_IEEE80211B
;
1588 else if (strcmp(pos
, "g") == 0)
1589 conf
->hw_mode
= HOSTAPD_MODE_IEEE80211G
;
1591 printf("Line %d: unknown hw_mode '%s'\n",
1595 } else if (strcmp(buf
, "channel") == 0) {
1596 conf
->channel
= atoi(pos
);
1597 } else if (strcmp(buf
, "beacon_int") == 0) {
1598 int val
= atoi(pos
);
1599 /* MIB defines range as 1..65535, but very small values
1600 * cause problems with the current implementation.
1601 * Since it is unlikely that this small numbers are
1602 * useful in real life scenarios, do not allow beacon
1603 * period to be set below 15 TU. */
1604 if (val
< 15 || val
> 65535) {
1605 printf("Line %d: invalid beacon_int %d "
1606 "(expected 15..65535)\n",
1610 conf
->beacon_int
= val
;
1611 } else if (strcmp(buf
, "dtim_period") == 0) {
1612 bss
->dtim_period
= atoi(pos
);
1613 if (bss
->dtim_period
< 1 || bss
->dtim_period
> 255) {
1614 printf("Line %d: invalid dtim_period %d\n",
1615 line
, bss
->dtim_period
);
1618 } else if (strcmp(buf
, "rts_threshold") == 0) {
1619 conf
->rts_threshold
= atoi(pos
);
1620 if (conf
->rts_threshold
< 0 ||
1621 conf
->rts_threshold
> 2347) {
1622 printf("Line %d: invalid rts_threshold %d\n",
1623 line
, conf
->rts_threshold
);
1626 } else if (strcmp(buf
, "fragm_threshold") == 0) {
1627 conf
->fragm_threshold
= atoi(pos
);
1628 if (conf
->fragm_threshold
< 256 ||
1629 conf
->fragm_threshold
> 2346) {
1630 printf("Line %d: invalid fragm_threshold %d\n",
1631 line
, conf
->fragm_threshold
);
1634 } else if (strcmp(buf
, "send_probe_response") == 0) {
1635 int val
= atoi(pos
);
1636 if (val
!= 0 && val
!= 1) {
1637 printf("Line %d: invalid send_probe_response "
1638 "%d (expected 0 or 1)\n", line
, val
);
1640 conf
->send_probe_response
= val
;
1641 } else if (strcmp(buf
, "supported_rates") == 0) {
1642 if (hostapd_parse_rates(&conf
->supported_rates
, pos
)) {
1643 printf("Line %d: invalid rate list\n", line
);
1646 } else if (strcmp(buf
, "basic_rates") == 0) {
1647 if (hostapd_parse_rates(&conf
->basic_rates
, pos
)) {
1648 printf("Line %d: invalid rate list\n", line
);
1651 } else if (strcmp(buf
, "ignore_broadcast_ssid") == 0) {
1652 bss
->ignore_broadcast_ssid
= atoi(pos
);
1653 } else if (strcmp(buf
, "bridge_packets") == 0) {
1654 conf
->bridge_packets
= atoi(pos
);
1655 } else if (strcmp(buf
, "wep_default_key") == 0) {
1656 bss
->ssid
.wep
.idx
= atoi(pos
);
1657 if (bss
->ssid
.wep
.idx
> 3) {
1658 printf("Invalid wep_default_key index %d\n",
1662 } else if (strcmp(buf
, "wep_key0") == 0 ||
1663 strcmp(buf
, "wep_key1") == 0 ||
1664 strcmp(buf
, "wep_key2") == 0 ||
1665 strcmp(buf
, "wep_key3") == 0) {
1666 if (hostapd_config_read_wep(&bss
->ssid
.wep
,
1667 buf
[7] - '0', pos
)) {
1668 printf("Line %d: invalid WEP key '%s'\n",
1672 } else if (strcmp(buf
, "dynamic_vlan") == 0) {
1673 bss
->ssid
.dynamic_vlan
= atoi(pos
);
1674 } else if (strcmp(buf
, "vlan_file") == 0) {
1675 if (hostapd_config_read_vlan_file(bss
, pos
)) {
1676 printf("Line %d: failed to read VLAN file "
1677 "'%s'\n", line
, pos
);
1680 #ifdef CONFIG_FULL_DYNAMIC_VLAN
1681 } else if (strcmp(buf
, "vlan_tagged_interface") == 0) {
1682 bss
->ssid
.vlan_tagged_interface
= strdup(pos
);
1683 #endif /* CONFIG_FULL_DYNAMIC_VLAN */
1684 } else if (strcmp(buf
, "passive_scan_interval") == 0) {
1685 conf
->passive_scan_interval
= atoi(pos
);
1686 } else if (strcmp(buf
, "passive_scan_listen") == 0) {
1687 conf
->passive_scan_listen
= atoi(pos
);
1688 } else if (strcmp(buf
, "passive_scan_mode") == 0) {
1689 conf
->passive_scan_mode
= atoi(pos
);
1690 } else if (strcmp(buf
, "ap_table_max_size") == 0) {
1691 conf
->ap_table_max_size
= atoi(pos
);
1692 } else if (strcmp(buf
, "ap_table_expiration_time") == 0) {
1693 conf
->ap_table_expiration_time
= atoi(pos
);
1694 } else if (strncmp(buf
, "tx_queue_", 9) == 0) {
1695 if (hostapd_config_tx_queue(conf
, buf
, pos
)) {
1696 printf("Line %d: invalid TX queue item\n",
1700 } else if (strcmp(buf
, "wme_enabled") == 0) {
1701 bss
->wme_enabled
= atoi(pos
);
1702 } else if (strncmp(buf
, "wme_ac_", 7) == 0) {
1703 if (hostapd_config_wme_ac(conf
, buf
, pos
)) {
1704 printf("Line %d: invalid wme ac item\n",
1708 } else if (strcmp(buf
, "bss") == 0) {
1709 if (hostapd_config_bss(conf
, pos
)) {
1710 printf("Line %d: invalid bss item\n", line
);
1713 } else if (strcmp(buf
, "bssid") == 0) {
1714 if (bss
== conf
->bss
) {
1715 printf("Line %d: bssid item not allowed "
1716 "for the default interface\n", line
);
1718 } else if (hwaddr_aton(pos
, bss
->bssid
)) {
1719 printf("Line %d: invalid bssid item\n", line
);
1722 #ifdef CONFIG_IEEE80211W
1723 } else if (strcmp(buf
, "ieee80211w") == 0) {
1724 bss
->ieee80211w
= atoi(pos
);
1725 #endif /* CONFIG_IEEE80211W */
1727 printf("Line %d: unknown configuration item '%s'\n",
1735 if (bss
->individual_wep_key_len
== 0) {
1736 /* individual keys are not use; can use key idx0 for broadcast
1738 bss
->broadcast_key_idx_min
= 0;
1741 for (i
= 0; i
< conf
->num_bss
; i
++) {
1742 bss
= &conf
->bss
[i
];
1744 bss
->radius
->auth_server
= bss
->radius
->auth_servers
;
1745 bss
->radius
->acct_server
= bss
->radius
->acct_servers
;
1747 if (bss
->wpa
&& bss
->ieee802_1x
) {
1748 bss
->ssid
.security_policy
= SECURITY_WPA
;
1749 } else if (bss
->wpa
) {
1750 bss
->ssid
.security_policy
= SECURITY_WPA_PSK
;
1751 } else if (bss
->ieee802_1x
) {
1752 bss
->ssid
.security_policy
= SECURITY_IEEE_802_1X
;
1753 bss
->ssid
.wep
.default_len
= bss
->default_wep_key_len
;
1754 } else if (bss
->ssid
.wep
.keys_set
)
1755 bss
->ssid
.security_policy
= SECURITY_STATIC_WEP
;
1757 bss
->ssid
.security_policy
= SECURITY_PLAINTEXT
;
1760 if (hostapd_config_check(conf
))
1764 printf("%d errors found in configuration file '%s'\n",
1766 hostapd_config_free(conf
);
1774 int hostapd_wep_key_cmp(struct hostapd_wep_keys
*a
, struct hostapd_wep_keys
*b
)
1778 if (a
->idx
!= b
->idx
|| a
->default_len
!= b
->default_len
)
1780 for (i
= 0; i
< NUM_WEP_KEYS
; i
++)
1781 if (a
->len
[i
] != b
->len
[i
] ||
1782 memcmp(a
->key
[i
], b
->key
[i
], a
->len
[i
]) != 0)
1788 static void hostapd_config_free_radius(struct hostapd_radius_server
*servers
,
1793 for (i
= 0; i
< num_servers
; i
++) {
1794 free(servers
[i
].shared_secret
);
1800 static void hostapd_config_free_eap_user(struct hostapd_eap_user
*user
)
1802 free(user
->identity
);
1803 free(user
->password
);
1808 static void hostapd_config_free_wep(struct hostapd_wep_keys
*keys
)
1811 for (i
= 0; i
< NUM_WEP_KEYS
; i
++) {
1813 keys
->key
[i
] = NULL
;
1818 static void hostapd_config_free_bss(struct hostapd_bss_config
*conf
)
1820 struct hostapd_wpa_psk
*psk
, *prev
;
1821 struct hostapd_eap_user
*user
, *prev_user
;
1826 psk
= conf
->ssid
.wpa_psk
;
1833 free(conf
->ssid
.wpa_passphrase
);
1834 free(conf
->ssid
.wpa_psk_file
);
1835 #ifdef CONFIG_FULL_DYNAMIC_VLAN
1836 free(conf
->ssid
.vlan_tagged_interface
);
1837 #endif /* CONFIG_FULL_DYNAMIC_VLAN */
1839 user
= conf
->eap_user
;
1843 hostapd_config_free_eap_user(prev_user
);
1846 free(conf
->dump_log_name
);
1847 free(conf
->eap_req_id_text
);
1848 free(conf
->accept_mac
);
1849 free(conf
->deny_mac
);
1850 free(conf
->nas_identifier
);
1851 hostapd_config_free_radius(conf
->radius
->auth_servers
,
1852 conf
->radius
->num_auth_servers
);
1853 hostapd_config_free_radius(conf
->radius
->acct_servers
,
1854 conf
->radius
->num_acct_servers
);
1855 free(conf
->rsn_preauth_interfaces
);
1856 free(conf
->ctrl_interface
);
1857 free(conf
->ca_cert
);
1858 free(conf
->server_cert
);
1859 free(conf
->private_key
);
1860 free(conf
->private_key_passwd
);
1861 free(conf
->eap_sim_db
);
1862 free(conf
->radius_server_clients
);
1863 free(conf
->test_socket
);
1865 hostapd_config_free_vlan(conf
);
1866 if (conf
->ssid
.dyn_vlan_keys
) {
1867 struct hostapd_ssid
*ssid
= &conf
->ssid
;
1869 for (i
= 0; i
<= ssid
->max_dyn_vlan_keys
; i
++) {
1870 if (ssid
->dyn_vlan_keys
[i
] == NULL
)
1872 hostapd_config_free_wep(ssid
->dyn_vlan_keys
[i
]);
1873 free(ssid
->dyn_vlan_keys
[i
]);
1875 free(ssid
->dyn_vlan_keys
);
1876 ssid
->dyn_vlan_keys
= NULL
;
1881 void hostapd_config_free(struct hostapd_config
*conf
)
1888 for (i
= 0; i
< conf
->num_bss
; i
++)
1889 hostapd_config_free_bss(&conf
->bss
[i
]);
1896 /* Perform a binary search for given MAC address from a pre-sorted list.
1897 * Returns 1 if address is in the list or 0 if not. */
1898 int hostapd_maclist_found(macaddr
*list
, int num_entries
, const u8
*addr
)
1900 int start
, end
, middle
, res
;
1903 end
= num_entries
- 1;
1905 while (start
<= end
) {
1906 middle
= (start
+ end
) / 2;
1907 res
= memcmp(list
[middle
], addr
, ETH_ALEN
);
1920 int hostapd_rate_found(int *list
, int rate
)
1927 for (i
= 0; list
[i
] >= 0; i
++)
1928 if (list
[i
] == rate
)
1935 const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan
*vlan
, int vlan_id
)
1937 struct hostapd_vlan
*v
= vlan
;
1939 if (v
->vlan_id
== vlan_id
|| v
->vlan_id
== VLAN_ID_WILDCARD
)
1947 const u8
* hostapd_get_psk(const struct hostapd_bss_config
*conf
,
1948 const u8
*addr
, const u8
*prev_psk
)
1950 struct hostapd_wpa_psk
*psk
;
1951 int next_ok
= prev_psk
== NULL
;
1953 for (psk
= conf
->ssid
.wpa_psk
; psk
!= NULL
; psk
= psk
->next
) {
1955 (psk
->group
|| memcmp(psk
->addr
, addr
, ETH_ALEN
) == 0))
1958 if (psk
->psk
== prev_psk
)
1966 const struct hostapd_eap_user
*
1967 hostapd_get_eap_user(const struct hostapd_bss_config
*conf
, const u8
*identity
,
1968 size_t identity_len
, int phase2
)
1970 struct hostapd_eap_user
*user
= conf
->eap_user
;
1973 if (!phase2
&& user
->identity
== NULL
) {
1974 /* Wildcard match */
1978 if (!phase2
&& user
->wildcard_prefix
&&
1979 identity_len
>= user
->identity_len
&&
1980 memcmp(user
->identity
, identity
, user
->identity_len
) == 0)
1982 /* Wildcard prefix match */
1986 if (user
->phase2
== !!phase2
&&
1987 user
->identity_len
== identity_len
&&
1988 memcmp(user
->identity
, identity
, identity_len
) == 0)