2 * hostapd / Configuration file parser
3 * Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
10 #ifndef CONFIG_NATIVE_WINDOWS
12 #endif /* CONFIG_NATIVE_WINDOWS */
14 #include "utils/common.h"
15 #include "utils/uuid.h"
16 #include "common/ieee802_11_defs.h"
17 #include "drivers/driver.h"
18 #include "eap_server/eap.h"
19 #include "radius/radius_client.h"
20 #include "ap/wpa_auth.h"
21 #include "ap/ap_config.h"
22 #include "config_file.h"
25 extern struct wpa_driver_ops
*wpa_drivers
[];
28 #ifndef CONFIG_NO_VLAN
29 static int hostapd_config_read_vlan_file(struct hostapd_bss_config
*bss
,
33 char buf
[128], *pos
, *pos2
;
34 int line
= 0, vlan_id
;
35 struct hostapd_vlan
*vlan
;
37 f
= fopen(fname
, "r");
39 wpa_printf(MSG_ERROR
, "VLAN file '%s' not readable.", fname
);
43 while (fgets(buf
, sizeof(buf
), f
)) {
49 while (*pos
!= '\0') {
60 vlan_id
= VLAN_ID_WILDCARD
;
63 vlan_id
= strtol(buf
, &pos
, 10);
64 if (buf
== pos
|| vlan_id
< 1 ||
65 vlan_id
> MAX_VLAN_ID
) {
66 wpa_printf(MSG_ERROR
, "Invalid VLAN ID at "
67 "line %d in '%s'", line
, fname
);
73 while (*pos
== ' ' || *pos
== '\t')
76 while (*pos2
!= ' ' && *pos2
!= '\t' && *pos2
!= '\0')
79 if (*pos
== '\0' || os_strlen(pos
) > IFNAMSIZ
) {
80 wpa_printf(MSG_ERROR
, "Invalid VLAN ifname at line %d "
81 "in '%s'", line
, fname
);
86 vlan
= os_zalloc(sizeof(*vlan
));
88 wpa_printf(MSG_ERROR
, "Out of memory while reading "
89 "VLAN interfaces from '%s'", fname
);
94 vlan
->vlan_id
= vlan_id
;
95 os_strlcpy(vlan
->ifname
, pos
, sizeof(vlan
->ifname
));
97 bss
->vlan_tail
->next
= vlan
;
100 bss
->vlan_tail
= vlan
;
107 #endif /* CONFIG_NO_VLAN */
110 static int hostapd_acl_comp(const void *a
, const void *b
)
112 const struct mac_acl_entry
*aa
= a
;
113 const struct mac_acl_entry
*bb
= b
;
114 return os_memcmp(aa
->addr
, bb
->addr
, sizeof(macaddr
));
118 static int hostapd_config_read_maclist(const char *fname
,
119 struct mac_acl_entry
**acl
, int *num
)
125 struct mac_acl_entry
*newacl
;
131 f
= fopen(fname
, "r");
133 wpa_printf(MSG_ERROR
, "MAC list file '%s' not found.", fname
);
137 while (fgets(buf
, sizeof(buf
), f
)) {
143 while (*pos
!= '\0') {
153 if (hwaddr_aton(buf
, addr
)) {
154 wpa_printf(MSG_ERROR
, "Invalid MAC address '%s' at "
155 "line %d in '%s'", buf
, line
, fname
);
162 while (*pos
!= '\0' && *pos
!= ' ' && *pos
!= '\t')
164 while (*pos
== ' ' || *pos
== '\t')
169 newacl
= os_realloc_array(*acl
, *num
+ 1, sizeof(**acl
));
170 if (newacl
== NULL
) {
171 wpa_printf(MSG_ERROR
, "MAC list reallocation failed");
177 os_memcpy((*acl
)[*num
].addr
, addr
, ETH_ALEN
);
178 (*acl
)[*num
].vlan_id
= vlan_id
;
184 qsort(*acl
, *num
, sizeof(**acl
), hostapd_acl_comp
);
191 static int hostapd_config_read_eap_user(const char *fname
,
192 struct hostapd_bss_config
*conf
)
195 char buf
[512], *pos
, *start
, *pos2
;
196 int line
= 0, ret
= 0, num_methods
;
197 struct hostapd_eap_user
*user
, *tail
= NULL
;
202 if (os_strncmp(fname
, "sqlite:", 7) == 0) {
203 os_free(conf
->eap_user_sqlite
);
204 conf
->eap_user_sqlite
= os_strdup(fname
+ 7);
208 f
= fopen(fname
, "r");
210 wpa_printf(MSG_ERROR
, "EAP user file '%s' not found.", fname
);
214 /* Lines: "user" METHOD,METHOD2 "password" (password optional) */
215 while (fgets(buf
, sizeof(buf
), f
)) {
221 while (*pos
!= '\0') {
233 if (buf
[0] != '"' && buf
[0] != '*') {
234 wpa_printf(MSG_ERROR
, "Invalid EAP identity (no \" in "
235 "start) on line %d in '%s'", line
, fname
);
239 user
= os_zalloc(sizeof(*user
));
241 wpa_printf(MSG_ERROR
, "EAP user allocation failed");
244 user
->force_version
= -1;
251 while (*pos
!= '"' && *pos
!= '\0')
254 wpa_printf(MSG_ERROR
, "Invalid EAP identity "
255 "(no \" in end) on line %d in '%s'",
260 user
->identity
= os_malloc(pos
- start
);
261 if (user
->identity
== NULL
) {
262 wpa_printf(MSG_ERROR
, "Failed to allocate "
263 "memory for EAP identity");
266 os_memcpy(user
->identity
, start
, pos
- start
);
267 user
->identity_len
= pos
- start
;
269 if (pos
[0] == '"' && pos
[1] == '*') {
270 user
->wildcard_prefix
= 1;
275 while (*pos
== ' ' || *pos
== '\t')
279 wpa_printf(MSG_ERROR
, "No EAP method on line %d in "
280 "'%s'", line
, fname
);
285 while (*pos
!= ' ' && *pos
!= '\t' && *pos
!= '\0')
295 char *pos3
= os_strchr(start
, ',');
299 user
->methods
[num_methods
].method
=
302 &user
->methods
[num_methods
].vendor
);
303 if (user
->methods
[num_methods
].vendor
==
305 user
->methods
[num_methods
].method
== EAP_TYPE_NONE
)
307 if (os_strcmp(start
, "TTLS-PAP") == 0) {
308 user
->ttls_auth
|= EAP_TTLS_AUTH_PAP
;
311 if (os_strcmp(start
, "TTLS-CHAP") == 0) {
312 user
->ttls_auth
|= EAP_TTLS_AUTH_CHAP
;
315 if (os_strcmp(start
, "TTLS-MSCHAP") == 0) {
317 EAP_TTLS_AUTH_MSCHAP
;
320 if (os_strcmp(start
, "TTLS-MSCHAPV2") == 0) {
322 EAP_TTLS_AUTH_MSCHAPV2
;
325 wpa_printf(MSG_ERROR
, "Unsupported EAP type "
326 "'%s' on line %d in '%s'",
332 if (num_methods
>= EAP_MAX_METHODS
)
339 if (num_methods
== 0 && user
->ttls_auth
== 0) {
340 wpa_printf(MSG_ERROR
, "No EAP types configured on "
341 "line %d in '%s'", line
, fname
);
348 while (*pos
== ' ' || *pos
== '\t')
353 if (os_strncmp(pos
, "[ver=0]", 7) == 0) {
354 user
->force_version
= 0;
358 if (os_strncmp(pos
, "[ver=1]", 7) == 0) {
359 user
->force_version
= 1;
363 if (os_strncmp(pos
, "[2]", 3) == 0) {
371 while (*pos
!= '"' && *pos
!= '\0')
374 wpa_printf(MSG_ERROR
, "Invalid EAP password "
375 "(no \" in end) on line %d in '%s'",
380 user
->password
= os_malloc(pos
- start
);
381 if (user
->password
== NULL
) {
382 wpa_printf(MSG_ERROR
, "Failed to allocate "
383 "memory for EAP password");
386 os_memcpy(user
->password
, start
, pos
- start
);
387 user
->password_len
= pos
- start
;
390 } else if (os_strncmp(pos
, "hash:", 5) == 0) {
393 while (*pos2
!= '\0' && *pos2
!= ' ' &&
394 *pos2
!= '\t' && *pos2
!= '#')
396 if (pos2
- pos
!= 32) {
397 wpa_printf(MSG_ERROR
, "Invalid password hash "
398 "on line %d in '%s'", line
, fname
);
401 user
->password
= os_malloc(16);
402 if (user
->password
== NULL
) {
403 wpa_printf(MSG_ERROR
, "Failed to allocate "
404 "memory for EAP password hash");
407 if (hexstr2bin(pos
, user
->password
, 16) < 0) {
408 wpa_printf(MSG_ERROR
, "Invalid hash password "
409 "on line %d in '%s'", line
, fname
);
412 user
->password_len
= 16;
413 user
->password_hash
= 1;
417 while (*pos2
!= '\0' && *pos2
!= ' ' &&
418 *pos2
!= '\t' && *pos2
!= '#')
420 if ((pos2
- pos
) & 1) {
421 wpa_printf(MSG_ERROR
, "Invalid hex password "
422 "on line %d in '%s'", line
, fname
);
425 user
->password
= os_malloc((pos2
- pos
) / 2);
426 if (user
->password
== NULL
) {
427 wpa_printf(MSG_ERROR
, "Failed to allocate "
428 "memory for EAP password");
431 if (hexstr2bin(pos
, user
->password
,
432 (pos2
- pos
) / 2) < 0) {
433 wpa_printf(MSG_ERROR
, "Invalid hex password "
434 "on line %d in '%s'", line
, fname
);
437 user
->password_len
= (pos2
- pos
) / 2;
441 while (*pos
== ' ' || *pos
== '\t')
443 if (os_strncmp(pos
, "[2]", 3) == 0) {
449 tail
= conf
->eap_user
= user
;
458 os_free(user
->password
);
459 os_free(user
->identity
);
470 #endif /* EAP_SERVER */
473 #ifndef CONFIG_NO_RADIUS
475 hostapd_config_read_radius_addr(struct hostapd_radius_server
**server
,
476 int *num_server
, const char *val
, int def_port
,
477 struct hostapd_radius_server
**curr_serv
)
479 struct hostapd_radius_server
*nserv
;
481 static int server_index
= 1;
483 nserv
= os_realloc_array(*server
, *num_server
+ 1, sizeof(*nserv
));
488 nserv
= &nserv
[*num_server
];
490 (*curr_serv
) = nserv
;
492 os_memset(nserv
, 0, sizeof(*nserv
));
493 nserv
->port
= def_port
;
494 ret
= hostapd_parse_ip_addr(val
, &nserv
->addr
);
495 nserv
->index
= server_index
++;
501 static struct hostapd_radius_attr
*
502 hostapd_parse_radius_attr(const char *value
)
506 struct hostapd_radius_attr
*attr
;
509 attr
= os_zalloc(sizeof(*attr
));
513 attr
->type
= atoi(value
);
515 pos
= os_strchr(value
, ':');
517 attr
->val
= wpabuf_alloc(1);
518 if (attr
->val
== NULL
) {
522 wpabuf_put_u8(attr
->val
, 0);
527 if (pos
[0] == '\0' || pos
[1] != ':') {
536 attr
->val
= wpabuf_alloc_copy(pos
, os_strlen(pos
));
539 len
= os_strlen(pos
);
543 attr
->val
= wpabuf_alloc(len
);
544 if (attr
->val
== NULL
)
546 if (hexstr2bin(pos
, wpabuf_put(attr
->val
, len
), len
) < 0) {
547 wpabuf_free(attr
->val
);
553 attr
->val
= wpabuf_alloc(4);
555 wpabuf_put_be32(attr
->val
, atoi(pos
));
562 if (attr
->val
== NULL
) {
571 static int hostapd_parse_das_client(struct hostapd_bss_config
*bss
,
576 secret
= os_strchr(val
, ' ');
582 if (hostapd_parse_ip_addr(val
, &bss
->radius_das_client_addr
))
585 os_free(bss
->radius_das_shared_secret
);
586 bss
->radius_das_shared_secret
= (u8
*) os_strdup(secret
);
587 if (bss
->radius_das_shared_secret
== NULL
)
589 bss
->radius_das_shared_secret_len
= os_strlen(secret
);
593 #endif /* CONFIG_NO_RADIUS */
596 static int hostapd_config_parse_key_mgmt(int line
, const char *value
)
599 char *start
, *end
, *buf
;
601 buf
= os_strdup(value
);
606 while (*start
!= '\0') {
607 while (*start
== ' ' || *start
== '\t')
612 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
616 if (os_strcmp(start
, "WPA-PSK") == 0)
617 val
|= WPA_KEY_MGMT_PSK
;
618 else if (os_strcmp(start
, "WPA-EAP") == 0)
619 val
|= WPA_KEY_MGMT_IEEE8021X
;
620 #ifdef CONFIG_IEEE80211R
621 else if (os_strcmp(start
, "FT-PSK") == 0)
622 val
|= WPA_KEY_MGMT_FT_PSK
;
623 else if (os_strcmp(start
, "FT-EAP") == 0)
624 val
|= WPA_KEY_MGMT_FT_IEEE8021X
;
625 #endif /* CONFIG_IEEE80211R */
626 #ifdef CONFIG_IEEE80211W
627 else if (os_strcmp(start
, "WPA-PSK-SHA256") == 0)
628 val
|= WPA_KEY_MGMT_PSK_SHA256
;
629 else if (os_strcmp(start
, "WPA-EAP-SHA256") == 0)
630 val
|= WPA_KEY_MGMT_IEEE8021X_SHA256
;
631 #endif /* CONFIG_IEEE80211W */
633 else if (os_strcmp(start
, "SAE") == 0)
634 val
|= WPA_KEY_MGMT_SAE
;
635 else if (os_strcmp(start
, "FT-SAE") == 0)
636 val
|= WPA_KEY_MGMT_FT_SAE
;
637 #endif /* CONFIG_SAE */
639 wpa_printf(MSG_ERROR
, "Line %d: invalid key_mgmt '%s'",
652 wpa_printf(MSG_ERROR
, "Line %d: no key_mgmt values "
653 "configured.", line
);
661 static int hostapd_config_parse_cipher(int line
, const char *value
)
663 int val
= wpa_parse_cipher(value
);
665 wpa_printf(MSG_ERROR
, "Line %d: invalid cipher '%s'.",
670 wpa_printf(MSG_ERROR
, "Line %d: no cipher values configured.",
678 static int hostapd_config_read_wep(struct hostapd_wep_keys
*wep
, int keyidx
,
681 size_t len
= os_strlen(val
);
683 if (keyidx
< 0 || keyidx
> 3 || wep
->key
[keyidx
] != NULL
)
687 if (len
< 2 || val
[len
- 1] != '"')
690 wep
->key
[keyidx
] = os_malloc(len
);
691 if (wep
->key
[keyidx
] == NULL
)
693 os_memcpy(wep
->key
[keyidx
], val
+ 1, len
);
694 wep
->len
[keyidx
] = len
;
699 wep
->key
[keyidx
] = os_malloc(len
);
700 if (wep
->key
[keyidx
] == NULL
)
702 wep
->len
[keyidx
] = len
;
703 if (hexstr2bin(val
, wep
->key
[keyidx
], len
) < 0)
713 static int hostapd_parse_rates(int **rate_list
, char *val
)
724 while (*pos
!= '\0') {
730 list
= os_malloc(sizeof(int) * (count
+ 2));
735 while (*pos
!= '\0') {
736 end
= os_strchr(pos
, ' ');
740 list
[count
++] = atoi(pos
);
752 static int hostapd_config_bss(struct hostapd_config
*conf
, const char *ifname
)
754 struct hostapd_bss_config
*bss
;
759 bss
= os_realloc_array(conf
->bss
, conf
->num_bss
+ 1,
760 sizeof(struct hostapd_bss_config
));
762 wpa_printf(MSG_ERROR
, "Failed to allocate memory for "
768 bss
= &(conf
->bss
[conf
->num_bss
]);
769 os_memset(bss
, 0, sizeof(*bss
));
770 bss
->radius
= os_zalloc(sizeof(*bss
->radius
));
771 if (bss
->radius
== NULL
) {
772 wpa_printf(MSG_ERROR
, "Failed to allocate memory for "
773 "multi-BSS RADIUS data");
778 conf
->last_bss
= bss
;
780 hostapd_config_defaults_bss(bss
);
781 os_strlcpy(bss
->iface
, ifname
, sizeof(bss
->iface
));
782 os_memcpy(bss
->ssid
.vlan
, bss
->iface
, IFNAMSIZ
+ 1);
788 /* convert floats with one decimal place to value*10 int, i.e.,
789 * "1.5" will return 15 */
790 static int hostapd_config_read_int10(const char *value
)
796 pos
= os_strchr(value
, '.');
800 if (*pos
>= '0' && *pos
<= '9')
808 static int valid_cw(int cw
)
810 return (cw
== 1 || cw
== 3 || cw
== 7 || cw
== 15 || cw
== 31 ||
811 cw
== 63 || cw
== 127 || cw
== 255 || cw
== 511 || cw
== 1023);
816 IEEE80211_TX_QUEUE_DATA0
= 0, /* used for EDCA AC_VO data */
817 IEEE80211_TX_QUEUE_DATA1
= 1, /* used for EDCA AC_VI data */
818 IEEE80211_TX_QUEUE_DATA2
= 2, /* used for EDCA AC_BE data */
819 IEEE80211_TX_QUEUE_DATA3
= 3 /* used for EDCA AC_BK data */
822 static int hostapd_config_tx_queue(struct hostapd_config
*conf
, char *name
,
827 struct hostapd_tx_queue_params
*queue
;
829 /* skip 'tx_queue_' prefix */
831 if (os_strncmp(pos
, "data", 4) == 0 &&
832 pos
[4] >= '0' && pos
[4] <= '9' && pos
[5] == '_') {
835 } else if (os_strncmp(pos
, "after_beacon_", 13) == 0 ||
836 os_strncmp(pos
, "beacon_", 7) == 0) {
837 wpa_printf(MSG_INFO
, "DEPRECATED: '%s' not used", name
);
840 wpa_printf(MSG_ERROR
, "Unknown tx_queue name '%s'", pos
);
844 if (num
>= NUM_TX_QUEUES
) {
845 /* for backwards compatibility, do not trigger failure */
846 wpa_printf(MSG_INFO
, "DEPRECATED: '%s' not used", name
);
850 queue
= &conf
->tx_queue
[num
];
852 if (os_strcmp(pos
, "aifs") == 0) {
853 queue
->aifs
= atoi(val
);
854 if (queue
->aifs
< 0 || queue
->aifs
> 255) {
855 wpa_printf(MSG_ERROR
, "Invalid AIFS value %d",
859 } else if (os_strcmp(pos
, "cwmin") == 0) {
860 queue
->cwmin
= atoi(val
);
861 if (!valid_cw(queue
->cwmin
)) {
862 wpa_printf(MSG_ERROR
, "Invalid cwMin value %d",
866 } else if (os_strcmp(pos
, "cwmax") == 0) {
867 queue
->cwmax
= atoi(val
);
868 if (!valid_cw(queue
->cwmax
)) {
869 wpa_printf(MSG_ERROR
, "Invalid cwMax value %d",
873 } else if (os_strcmp(pos
, "burst") == 0) {
874 queue
->burst
= hostapd_config_read_int10(val
);
876 wpa_printf(MSG_ERROR
, "Unknown tx_queue field '%s'", pos
);
884 #ifdef CONFIG_IEEE80211R
885 static int add_r0kh(struct hostapd_bss_config
*bss
, char *value
)
887 struct ft_remote_r0kh
*r0kh
;
890 r0kh
= os_zalloc(sizeof(*r0kh
));
894 /* 02:01:02:03:04:05 a.example.com 000102030405060708090a0b0c0d0e0f */
896 next
= os_strchr(pos
, ' ');
899 if (next
== NULL
|| hwaddr_aton(pos
, r0kh
->addr
)) {
900 wpa_printf(MSG_ERROR
, "Invalid R0KH MAC address: '%s'", pos
);
906 next
= os_strchr(pos
, ' ');
909 if (next
== NULL
|| next
- pos
> FT_R0KH_ID_MAX_LEN
) {
910 wpa_printf(MSG_ERROR
, "Invalid R0KH-ID: '%s'", pos
);
914 r0kh
->id_len
= next
- pos
- 1;
915 os_memcpy(r0kh
->id
, pos
, r0kh
->id_len
);
918 if (hexstr2bin(pos
, r0kh
->key
, sizeof(r0kh
->key
))) {
919 wpa_printf(MSG_ERROR
, "Invalid R0KH key: '%s'", pos
);
924 r0kh
->next
= bss
->r0kh_list
;
925 bss
->r0kh_list
= r0kh
;
931 static int add_r1kh(struct hostapd_bss_config
*bss
, char *value
)
933 struct ft_remote_r1kh
*r1kh
;
936 r1kh
= os_zalloc(sizeof(*r1kh
));
940 /* 02:01:02:03:04:05 02:01:02:03:04:05
941 * 000102030405060708090a0b0c0d0e0f */
943 next
= os_strchr(pos
, ' ');
946 if (next
== NULL
|| hwaddr_aton(pos
, r1kh
->addr
)) {
947 wpa_printf(MSG_ERROR
, "Invalid R1KH MAC address: '%s'", pos
);
953 next
= os_strchr(pos
, ' ');
956 if (next
== NULL
|| hwaddr_aton(pos
, r1kh
->id
)) {
957 wpa_printf(MSG_ERROR
, "Invalid R1KH-ID: '%s'", pos
);
963 if (hexstr2bin(pos
, r1kh
->key
, sizeof(r1kh
->key
))) {
964 wpa_printf(MSG_ERROR
, "Invalid R1KH key: '%s'", pos
);
969 r1kh
->next
= bss
->r1kh_list
;
970 bss
->r1kh_list
= r1kh
;
974 #endif /* CONFIG_IEEE80211R */
977 #ifdef CONFIG_IEEE80211N
978 static int hostapd_config_ht_capab(struct hostapd_config
*conf
,
981 if (os_strstr(capab
, "[LDPC]"))
982 conf
->ht_capab
|= HT_CAP_INFO_LDPC_CODING_CAP
;
983 if (os_strstr(capab
, "[HT40-]")) {
984 conf
->ht_capab
|= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
;
985 conf
->secondary_channel
= -1;
987 if (os_strstr(capab
, "[HT40+]")) {
988 conf
->ht_capab
|= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
;
989 conf
->secondary_channel
= 1;
991 if (os_strstr(capab
, "[SMPS-STATIC]")) {
992 conf
->ht_capab
&= ~HT_CAP_INFO_SMPS_MASK
;
993 conf
->ht_capab
|= HT_CAP_INFO_SMPS_STATIC
;
995 if (os_strstr(capab
, "[SMPS-DYNAMIC]")) {
996 conf
->ht_capab
&= ~HT_CAP_INFO_SMPS_MASK
;
997 conf
->ht_capab
|= HT_CAP_INFO_SMPS_DYNAMIC
;
999 if (os_strstr(capab
, "[GF]"))
1000 conf
->ht_capab
|= HT_CAP_INFO_GREEN_FIELD
;
1001 if (os_strstr(capab
, "[SHORT-GI-20]"))
1002 conf
->ht_capab
|= HT_CAP_INFO_SHORT_GI20MHZ
;
1003 if (os_strstr(capab
, "[SHORT-GI-40]"))
1004 conf
->ht_capab
|= HT_CAP_INFO_SHORT_GI40MHZ
;
1005 if (os_strstr(capab
, "[TX-STBC]"))
1006 conf
->ht_capab
|= HT_CAP_INFO_TX_STBC
;
1007 if (os_strstr(capab
, "[RX-STBC1]")) {
1008 conf
->ht_capab
&= ~HT_CAP_INFO_RX_STBC_MASK
;
1009 conf
->ht_capab
|= HT_CAP_INFO_RX_STBC_1
;
1011 if (os_strstr(capab
, "[RX-STBC12]")) {
1012 conf
->ht_capab
&= ~HT_CAP_INFO_RX_STBC_MASK
;
1013 conf
->ht_capab
|= HT_CAP_INFO_RX_STBC_12
;
1015 if (os_strstr(capab
, "[RX-STBC123]")) {
1016 conf
->ht_capab
&= ~HT_CAP_INFO_RX_STBC_MASK
;
1017 conf
->ht_capab
|= HT_CAP_INFO_RX_STBC_123
;
1019 if (os_strstr(capab
, "[DELAYED-BA]"))
1020 conf
->ht_capab
|= HT_CAP_INFO_DELAYED_BA
;
1021 if (os_strstr(capab
, "[MAX-AMSDU-7935]"))
1022 conf
->ht_capab
|= HT_CAP_INFO_MAX_AMSDU_SIZE
;
1023 if (os_strstr(capab
, "[DSSS_CCK-40]"))
1024 conf
->ht_capab
|= HT_CAP_INFO_DSSS_CCK40MHZ
;
1025 if (os_strstr(capab
, "[PSMP]"))
1026 conf
->ht_capab
|= HT_CAP_INFO_PSMP_SUPP
;
1027 if (os_strstr(capab
, "[LSIG-TXOP-PROT]"))
1028 conf
->ht_capab
|= HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT
;
1032 #endif /* CONFIG_IEEE80211N */
1035 #ifdef CONFIG_IEEE80211AC
1036 static int hostapd_config_vht_capab(struct hostapd_config
*conf
,
1039 if (os_strstr(capab
, "[MAX-MPDU-7991]"))
1040 conf
->vht_capab
|= VHT_CAP_MAX_MPDU_LENGTH_7991
;
1041 if (os_strstr(capab
, "[MAX-MPDU-11454]"))
1042 conf
->vht_capab
|= VHT_CAP_MAX_MPDU_LENGTH_11454
;
1043 if (os_strstr(capab
, "[VHT160]"))
1044 conf
->vht_capab
|= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ
;
1045 if (os_strstr(capab
, "[VHT160-80PLUS80]"))
1046 conf
->vht_capab
|= VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ
;
1047 if (os_strstr(capab
, "[VHT160-80PLUS80]"))
1048 conf
->vht_capab
|= VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ
;
1049 if (os_strstr(capab
, "[RXLDPC]"))
1050 conf
->vht_capab
|= VHT_CAP_RXLDPC
;
1051 if (os_strstr(capab
, "[SHORT-GI-80]"))
1052 conf
->vht_capab
|= VHT_CAP_SHORT_GI_80
;
1053 if (os_strstr(capab
, "[SHORT-GI-160]"))
1054 conf
->vht_capab
|= VHT_CAP_SHORT_GI_160
;
1055 if (os_strstr(capab
, "[TX-STBC-2BY1]"))
1056 conf
->vht_capab
|= VHT_CAP_TXSTBC
;
1057 if (os_strstr(capab
, "[RX-STBC-1]"))
1058 conf
->vht_capab
|= VHT_CAP_RXSTBC_1
;
1059 if (os_strstr(capab
, "[RX-STBC-12]"))
1060 conf
->vht_capab
|= VHT_CAP_RXSTBC_2
;
1061 if (os_strstr(capab
, "[RX-STBC-123]"))
1062 conf
->vht_capab
|= VHT_CAP_RXSTBC_3
;
1063 if (os_strstr(capab
, "[RX-STBC-1234]"))
1064 conf
->vht_capab
|= VHT_CAP_RXSTBC_4
;
1065 if (os_strstr(capab
, "[SU-BEAMFORMER]"))
1066 conf
->vht_capab
|= VHT_CAP_MU_BEAMFORMER_CAPABLE
;
1067 if (os_strstr(capab
, "[SU-BEAMFORMEE]"))
1068 conf
->vht_capab
|= VHT_CAP_MU_BEAMFORMEE_CAPABLE
;
1069 if (os_strstr(capab
, "[BF-ANTENNA-2]") &&
1070 (conf
->vht_capab
& VHT_CAP_MU_BEAMFORMER_CAPABLE
))
1071 conf
->vht_capab
|= VHT_CAP_BEAMFORMER_ANTENNAS_MAX
;
1072 if (os_strstr(capab
, "[SOUNDING-DIMENSION-2]") &&
1073 (conf
->vht_capab
& VHT_CAP_MU_BEAMFORMER_CAPABLE
))
1074 conf
->vht_capab
|= VHT_CAP_SOUNDING_DIMENTION_MAX
;
1075 if (os_strstr(capab
, "[MU-BEAMFORMER]"))
1076 conf
->vht_capab
|= VHT_CAP_MU_BEAMFORMER_CAPABLE
;
1077 if (os_strstr(capab
, "[MU-BEAMFORMEE]"))
1078 conf
->vht_capab
|= VHT_CAP_MU_BEAMFORMEE_CAPABLE
;
1079 if (os_strstr(capab
, "[VHT-TXOP-PS]"))
1080 conf
->vht_capab
|= VHT_CAP_VHT_TXOP_PS
;
1081 if (os_strstr(capab
, "[HTC-VHT]"))
1082 conf
->vht_capab
|= VHT_CAP_HTC_VHT
;
1083 if (os_strstr(capab
, "[MAX-A-MPDU-LEN-EXP0]"))
1084 conf
->vht_capab
|= VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT
;
1085 if (os_strstr(capab
, "[VHT-LINK-ADAPT2]") &&
1086 (conf
->vht_capab
& VHT_CAP_HTC_VHT
))
1087 conf
->vht_capab
|= VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB
;
1088 if (os_strstr(capab
, "[VHT-LINK-ADAPT3]") &&
1089 (conf
->vht_capab
& VHT_CAP_HTC_VHT
))
1090 conf
->vht_capab
|= VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB
;
1091 if (os_strstr(capab
, "[RX-ANTENNA-PATTERN]"))
1092 conf
->vht_capab
|= VHT_CAP_RX_ANTENNA_PATTERN
;
1093 if (os_strstr(capab
, "[TX-ANTENNA-PATTERN]"))
1094 conf
->vht_capab
|= VHT_CAP_TX_ANTENNA_PATTERN
;
1097 #endif /* CONFIG_IEEE80211AC */
1100 static int hostapd_config_check_bss(struct hostapd_bss_config
*bss
,
1101 struct hostapd_config
*conf
)
1103 if (bss
->ieee802_1x
&& !bss
->eap_server
&&
1104 !bss
->radius
->auth_servers
) {
1105 wpa_printf(MSG_ERROR
, "Invalid IEEE 802.1X configuration (no "
1106 "EAP authenticator configured).");
1110 if (bss
->wpa
&& bss
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
&&
1111 bss
->macaddr_acl
!= USE_EXTERNAL_RADIUS_AUTH
) {
1112 wpa_printf(MSG_ERROR
, "WPA-PSK using RADIUS enabled, but no "
1113 "RADIUS checking (macaddr_acl=2) enabled.");
1117 if (bss
->wpa
&& (bss
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
) &&
1118 bss
->ssid
.wpa_psk
== NULL
&& bss
->ssid
.wpa_passphrase
== NULL
&&
1119 bss
->ssid
.wpa_psk_file
== NULL
&&
1120 (bss
->wpa_psk_radius
!= PSK_RADIUS_REQUIRED
||
1121 bss
->macaddr_acl
!= USE_EXTERNAL_RADIUS_AUTH
)) {
1122 wpa_printf(MSG_ERROR
, "WPA-PSK enabled, but PSK or passphrase "
1123 "is not configured.");
1127 if (hostapd_mac_comp_empty(bss
->bssid
) != 0) {
1130 for (i
= 0; i
< conf
->num_bss
; i
++) {
1131 if ((&conf
->bss
[i
] != bss
) &&
1132 (hostapd_mac_comp(conf
->bss
[i
].bssid
,
1133 bss
->bssid
) == 0)) {
1134 wpa_printf(MSG_ERROR
, "Duplicate BSSID " MACSTR
1135 " on interface '%s' and '%s'.",
1136 MAC2STR(bss
->bssid
),
1137 conf
->bss
[i
].iface
, bss
->iface
);
1143 #ifdef CONFIG_IEEE80211R
1144 if (wpa_key_mgmt_ft(bss
->wpa_key_mgmt
) &&
1145 (bss
->nas_identifier
== NULL
||
1146 os_strlen(bss
->nas_identifier
) < 1 ||
1147 os_strlen(bss
->nas_identifier
) > FT_R0KH_ID_MAX_LEN
)) {
1148 wpa_printf(MSG_ERROR
, "FT (IEEE 802.11r) requires "
1149 "nas_identifier to be configured as a 1..48 octet "
1153 #endif /* CONFIG_IEEE80211R */
1155 #ifdef CONFIG_IEEE80211N
1156 if (conf
->ieee80211n
&& conf
->hw_mode
== HOSTAPD_MODE_IEEE80211B
) {
1157 bss
->disable_11n
= 1;
1158 wpa_printf(MSG_ERROR
, "HT (IEEE 802.11n) in 11b mode is not "
1159 "allowed, disabling HT capabilites");
1162 if (conf
->ieee80211n
&&
1163 bss
->ssid
.security_policy
== SECURITY_STATIC_WEP
) {
1164 bss
->disable_11n
= 1;
1165 wpa_printf(MSG_ERROR
, "HT (IEEE 802.11n) with WEP is not "
1166 "allowed, disabling HT capabilities");
1169 if (conf
->ieee80211n
&& bss
->wpa
&&
1170 !(bss
->wpa_pairwise
& WPA_CIPHER_CCMP
) &&
1171 !(bss
->rsn_pairwise
& (WPA_CIPHER_CCMP
| WPA_CIPHER_GCMP
))) {
1172 bss
->disable_11n
= 1;
1173 wpa_printf(MSG_ERROR
, "HT (IEEE 802.11n) with WPA/WPA2 "
1174 "requires CCMP/GCMP to be enabled, disabling HT "
1177 #endif /* CONFIG_IEEE80211N */
1180 if (bss
->wps_state
&& bss
->ignore_broadcast_ssid
) {
1181 wpa_printf(MSG_INFO
, "WPS: ignore_broadcast_ssid "
1182 "configuration forced WPS to be disabled");
1186 if (bss
->wps_state
&& bss
->ssid
.wep
.keys_set
&& bss
->wpa
== 0) {
1187 wpa_printf(MSG_INFO
, "WPS: WEP configuration forced WPS to be "
1192 if (bss
->wps_state
&& bss
->wpa
&&
1194 !(bss
->rsn_pairwise
& WPA_CIPHER_CCMP
))) {
1195 wpa_printf(MSG_INFO
, "WPS: WPA/TKIP configuration without "
1196 "WPA2/CCMP forced WPS to be disabled");
1199 #endif /* CONFIG_WPS2 */
1204 !(bss
->rsn_pairwise
& (WPA_CIPHER_CCMP
| WPA_CIPHER_GCMP
)))) {
1205 wpa_printf(MSG_ERROR
, "HS 2.0: WPA2-Enterprise/CCMP "
1206 "configuration is required for Hotspot 2.0 "
1210 #endif /* CONFIG_HS20 */
1216 static int hostapd_config_check(struct hostapd_config
*conf
)
1220 if (conf
->ieee80211d
&& (!conf
->country
[0] || !conf
->country
[1])) {
1221 wpa_printf(MSG_ERROR
, "Cannot enable IEEE 802.11d without "
1222 "setting the country_code");
1226 for (i
= 0; i
< conf
->num_bss
; i
++) {
1227 if (hostapd_config_check_bss(&conf
->bss
[i
], conf
))
1235 #ifdef CONFIG_INTERWORKING
1236 static int parse_roaming_consortium(struct hostapd_bss_config
*bss
, char *pos
,
1239 size_t len
= os_strlen(pos
);
1240 u8 oi
[MAX_ROAMING_CONSORTIUM_LEN
];
1242 struct hostapd_roaming_consortium
*rc
;
1244 if ((len
& 1) || len
< 2 * 3 || len
/ 2 > MAX_ROAMING_CONSORTIUM_LEN
||
1245 hexstr2bin(pos
, oi
, len
/ 2)) {
1246 wpa_printf(MSG_ERROR
, "Line %d: invalid roaming_consortium "
1252 rc
= os_realloc_array(bss
->roaming_consortium
,
1253 bss
->roaming_consortium_count
+ 1,
1254 sizeof(struct hostapd_roaming_consortium
));
1258 os_memcpy(rc
[bss
->roaming_consortium_count
].oi
, oi
, len
);
1259 rc
[bss
->roaming_consortium_count
].len
= len
;
1261 bss
->roaming_consortium
= rc
;
1262 bss
->roaming_consortium_count
++;
1268 static int parse_lang_string(struct hostapd_lang_string
**array
,
1269 unsigned int *count
, char *pos
)
1273 struct hostapd_lang_string
*ls
;
1275 sep
= os_strchr(pos
, ':');
1280 clen
= os_strlen(pos
);
1283 nlen
= os_strlen(sep
);
1287 ls
= os_realloc_array(*array
, *count
+ 1,
1288 sizeof(struct hostapd_lang_string
));
1293 ls
= &(*array
)[*count
];
1296 os_memset(ls
->lang
, 0, sizeof(ls
->lang
));
1297 os_memcpy(ls
->lang
, pos
, clen
);
1298 ls
->name_len
= nlen
;
1299 os_memcpy(ls
->name
, sep
, nlen
);
1305 static int parse_venue_name(struct hostapd_bss_config
*bss
, char *pos
,
1308 if (parse_lang_string(&bss
->venue_name
, &bss
->venue_name_count
, pos
)) {
1309 wpa_printf(MSG_ERROR
, "Line %d: Invalid venue_name '%s'",
1317 static int parse_3gpp_cell_net(struct hostapd_bss_config
*bss
, char *buf
,
1322 u8
*info
= NULL
, *ipos
;
1324 /* format: <MCC1,MNC1>[;<MCC2,MNC2>][;...] */
1327 for (pos
= buf
; *pos
; pos
++) {
1328 if ((*pos
< '0' && *pos
> '9') && *pos
!= ';' && *pos
!= ',')
1333 if (1 + count
* 3 > 0x7f)
1336 info
= os_zalloc(2 + 3 + count
* 3);
1341 *ipos
++ = 0; /* GUD - Version 1 */
1342 *ipos
++ = 3 + count
* 3; /* User Data Header Length (UDHL) */
1343 *ipos
++ = 0; /* PLMN List IEI */
1344 /* ext(b8) | Length of PLMN List value contents(b7..1) */
1345 *ipos
++ = 1 + count
* 3;
1346 *ipos
++ = count
; /* Number of PLMNs */
1349 while (pos
&& *pos
) {
1354 mnc
= os_strchr(pos
, ',');
1358 pos
= os_strchr(mnc
, ';');
1362 mnc_len
= os_strlen(mnc
);
1363 if (os_strlen(mcc
) != 3 || (mnc_len
!= 2 && mnc_len
!= 3))
1366 /* BC coded MCC,MNC */
1367 /* MCC digit 2 | MCC digit 1 */
1368 *ipos
++ = ((mcc
[1] - '0') << 4) | (mcc
[0] - '0');
1369 /* MNC digit 3 | MCC digit 3 */
1370 *ipos
++ = (((mnc_len
== 2) ? 0xf0 : ((mnc
[2] - '0') << 4))) |
1372 /* MNC digit 2 | MNC digit 1 */
1373 *ipos
++ = ((mnc
[1] - '0') << 4) | (mnc
[0] - '0');
1376 os_free(bss
->anqp_3gpp_cell_net
);
1377 bss
->anqp_3gpp_cell_net
= info
;
1378 bss
->anqp_3gpp_cell_net_len
= 2 + 3 + 3 * count
;
1379 wpa_hexdump(MSG_MSGDUMP
, "3GPP Cellular Network information",
1380 bss
->anqp_3gpp_cell_net
, bss
->anqp_3gpp_cell_net_len
);
1385 wpa_printf(MSG_ERROR
, "Line %d: Invalid anqp_3gpp_cell_net: %s",
1392 static int parse_nai_realm(struct hostapd_bss_config
*bss
, char *buf
, int line
)
1394 struct hostapd_nai_realm_data
*realm
;
1397 char *pos
, *end
, *rpos
;
1399 offsets
= os_calloc(bss
->nai_realm_count
* MAX_NAI_REALMS
,
1401 if (offsets
== NULL
)
1404 for (i
= 0; i
< bss
->nai_realm_count
; i
++) {
1405 realm
= &bss
->nai_realm_data
[i
];
1406 for (j
= 0; j
< MAX_NAI_REALMS
; j
++) {
1407 offsets
[i
* MAX_NAI_REALMS
+ j
] =
1409 realm
->realm
[j
] - realm
->realm_buf
: -1;
1413 realm
= os_realloc_array(bss
->nai_realm_data
, bss
->nai_realm_count
+ 1,
1414 sizeof(struct hostapd_nai_realm_data
));
1415 if (realm
== NULL
) {
1419 bss
->nai_realm_data
= realm
;
1421 /* patch the pointers after realloc */
1422 for (i
= 0; i
< bss
->nai_realm_count
; i
++) {
1423 realm
= &bss
->nai_realm_data
[i
];
1424 for (j
= 0; j
< MAX_NAI_REALMS
; j
++) {
1425 int offs
= offsets
[i
* MAX_NAI_REALMS
+ j
];
1427 realm
->realm
[j
] = realm
->realm_buf
+ offs
;
1429 realm
->realm
[j
] = NULL
;
1434 realm
= &bss
->nai_realm_data
[bss
->nai_realm_count
];
1435 os_memset(realm
, 0, sizeof(*realm
));
1438 realm
->encoding
= atoi(pos
);
1439 pos
= os_strchr(pos
, ',');
1444 end
= os_strchr(pos
, ',');
1449 len
= os_strlen(pos
);
1452 if (len
> MAX_NAI_REALMLEN
) {
1453 wpa_printf(MSG_ERROR
, "Too long a realm string (%d > max %d "
1454 "characters)", (int) len
, MAX_NAI_REALMLEN
);
1457 os_memcpy(realm
->realm_buf
, pos
, len
);
1464 while (pos
&& *pos
) {
1465 struct hostapd_nai_realm_eap
*eap
;
1467 if (realm
->eap_method_count
>= MAX_NAI_EAP_METHODS
) {
1468 wpa_printf(MSG_ERROR
, "Too many EAP methods");
1472 eap
= &realm
->eap_method
[realm
->eap_method_count
];
1473 realm
->eap_method_count
++;
1475 end
= os_strchr(pos
, ',');
1477 end
= pos
+ os_strlen(pos
);
1479 eap
->eap_method
= atoi(pos
);
1481 pos
= os_strchr(pos
, '[');
1482 if (pos
== NULL
|| pos
> end
)
1485 if (eap
->num_auths
>= MAX_NAI_AUTH_TYPES
) {
1486 wpa_printf(MSG_ERROR
, "Too many auth params");
1489 eap
->auth_id
[eap
->num_auths
] = atoi(pos
);
1490 pos
= os_strchr(pos
, ':');
1491 if (pos
== NULL
|| pos
> end
)
1494 eap
->auth_val
[eap
->num_auths
] = atoi(pos
);
1495 pos
= os_strchr(pos
, ']');
1496 if (pos
== NULL
|| pos
> end
)
1508 /* Split realm list into null terminated realms */
1509 rpos
= realm
->realm_buf
;
1512 if (i
>= MAX_NAI_REALMS
) {
1513 wpa_printf(MSG_ERROR
, "Too many realms");
1516 realm
->realm
[i
++] = rpos
;
1517 rpos
= os_strchr(rpos
, ';');
1523 bss
->nai_realm_count
++;
1528 wpa_printf(MSG_ERROR
, "Line %d: invalid nai_realm '%s'", line
, buf
);
1532 #endif /* CONFIG_INTERWORKING */
1536 static int hs20_parse_conn_capab(struct hostapd_bss_config
*bss
, char *buf
,
1542 if (bss
->hs20_connection_capability_len
>= 0xfff0)
1545 conn_cap
= os_realloc(bss
->hs20_connection_capability
,
1546 bss
->hs20_connection_capability_len
+ 4);
1547 if (conn_cap
== NULL
)
1550 bss
->hs20_connection_capability
= conn_cap
;
1551 conn_cap
+= bss
->hs20_connection_capability_len
;
1553 conn_cap
[0] = atoi(pos
);
1554 pos
= os_strchr(pos
, ':');
1558 WPA_PUT_LE16(conn_cap
+ 1, atoi(pos
));
1559 pos
= os_strchr(pos
, ':');
1563 conn_cap
[3] = atoi(pos
);
1564 bss
->hs20_connection_capability_len
+= 4;
1570 static int hs20_parse_wan_metrics(struct hostapd_bss_config
*bss
, char *buf
,
1576 /* <WAN Info>:<DL Speed>:<UL Speed>:<DL Load>:<UL Load>:<LMD> */
1578 wan_metrics
= os_zalloc(13);
1579 if (wan_metrics
== NULL
)
1584 if (hexstr2bin(pos
, wan_metrics
, 1) < 0)
1591 /* Downlink Speed */
1592 WPA_PUT_LE32(wan_metrics
+ 1, atoi(pos
));
1593 pos
= os_strchr(pos
, ':');
1599 WPA_PUT_LE32(wan_metrics
+ 5, atoi(pos
));
1600 pos
= os_strchr(pos
, ':');
1606 wan_metrics
[9] = atoi(pos
);
1607 pos
= os_strchr(pos
, ':');
1613 wan_metrics
[10] = atoi(pos
);
1614 pos
= os_strchr(pos
, ':');
1620 WPA_PUT_LE16(wan_metrics
+ 11, atoi(pos
));
1622 os_free(bss
->hs20_wan_metrics
);
1623 bss
->hs20_wan_metrics
= wan_metrics
;
1628 wpa_printf(MSG_ERROR
, "Line %d: Invalid hs20_wan_metrics '%s'",
1630 os_free(wan_metrics
);
1635 static int hs20_parse_oper_friendly_name(struct hostapd_bss_config
*bss
,
1636 char *pos
, int line
)
1638 if (parse_lang_string(&bss
->hs20_oper_friendly_name
,
1639 &bss
->hs20_oper_friendly_name_count
, pos
)) {
1640 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
1641 "hs20_oper_friendly_name '%s'", line
, pos
);
1646 #endif /* CONFIG_HS20 */
1649 #ifdef CONFIG_WPS_NFC
1650 static struct wpabuf
* hostapd_parse_bin(const char *buf
)
1655 len
= os_strlen(buf
);
1660 ret
= wpabuf_alloc(len
);
1664 if (hexstr2bin(buf
, wpabuf_put(ret
, len
), len
)) {
1671 #endif /* CONFIG_WPS_NFC */
1674 static int hostapd_config_fill(struct hostapd_config
*conf
,
1675 struct hostapd_bss_config
*bss
,
1676 char *buf
, char *pos
, int line
)
1681 if (os_strcmp(buf
, "interface") == 0) {
1682 os_strlcpy(conf
->bss
[0].iface
, pos
,
1683 sizeof(conf
->bss
[0].iface
));
1684 } else if (os_strcmp(buf
, "bridge") == 0) {
1685 os_strlcpy(bss
->bridge
, pos
, sizeof(bss
->bridge
));
1686 } else if (os_strcmp(buf
, "wds_bridge") == 0) {
1687 os_strlcpy(bss
->wds_bridge
, pos
,
1688 sizeof(bss
->wds_bridge
));
1689 } else if (os_strcmp(buf
, "driver") == 0) {
1691 /* clear to get error below if setting is invalid */
1692 conf
->driver
= NULL
;
1693 for (j
= 0; wpa_drivers
[j
]; j
++) {
1694 if (os_strcmp(pos
, wpa_drivers
[j
]->name
) == 0)
1696 conf
->driver
= wpa_drivers
[j
];
1700 if (conf
->driver
== NULL
) {
1701 wpa_printf(MSG_ERROR
, "Line %d: invalid/"
1702 "unknown driver '%s'", line
, pos
);
1705 } else if (os_strcmp(buf
, "debug") == 0) {
1706 wpa_printf(MSG_DEBUG
, "Line %d: DEPRECATED: 'debug' "
1707 "configuration variable is not used "
1709 } else if (os_strcmp(buf
, "logger_syslog_level") == 0) {
1710 bss
->logger_syslog_level
= atoi(pos
);
1711 } else if (os_strcmp(buf
, "logger_stdout_level") == 0) {
1712 bss
->logger_stdout_level
= atoi(pos
);
1713 } else if (os_strcmp(buf
, "logger_syslog") == 0) {
1714 bss
->logger_syslog
= atoi(pos
);
1715 } else if (os_strcmp(buf
, "logger_stdout") == 0) {
1716 bss
->logger_stdout
= atoi(pos
);
1717 } else if (os_strcmp(buf
, "dump_file") == 0) {
1718 bss
->dump_log_name
= os_strdup(pos
);
1719 } else if (os_strcmp(buf
, "ssid") == 0) {
1720 bss
->ssid
.ssid_len
= os_strlen(pos
);
1721 if (bss
->ssid
.ssid_len
> HOSTAPD_MAX_SSID_LEN
||
1722 bss
->ssid
.ssid_len
< 1) {
1723 wpa_printf(MSG_ERROR
, "Line %d: invalid SSID "
1727 os_memcpy(bss
->ssid
.ssid
, pos
,
1728 bss
->ssid
.ssid_len
);
1729 bss
->ssid
.ssid_set
= 1;
1731 } else if (os_strcmp(buf
, "ssid2") == 0) {
1733 char *str
= wpa_config_parse_string(pos
, &slen
);
1734 if (str
== NULL
|| slen
< 1 ||
1735 slen
> HOSTAPD_MAX_SSID_LEN
) {
1736 wpa_printf(MSG_ERROR
, "Line %d: invalid SSID "
1740 os_memcpy(bss
->ssid
.ssid
, str
, slen
);
1741 bss
->ssid
.ssid_len
= slen
;
1742 bss
->ssid
.ssid_set
= 1;
1745 } else if (os_strcmp(buf
, "utf8_ssid") == 0) {
1746 bss
->ssid
.utf8_ssid
= atoi(pos
) > 0;
1747 } else if (os_strcmp(buf
, "macaddr_acl") == 0) {
1748 bss
->macaddr_acl
= atoi(pos
);
1749 if (bss
->macaddr_acl
!= ACCEPT_UNLESS_DENIED
&&
1750 bss
->macaddr_acl
!= DENY_UNLESS_ACCEPTED
&&
1751 bss
->macaddr_acl
!= USE_EXTERNAL_RADIUS_AUTH
) {
1752 wpa_printf(MSG_ERROR
, "Line %d: unknown "
1754 line
, bss
->macaddr_acl
);
1756 } else if (os_strcmp(buf
, "accept_mac_file") == 0) {
1757 if (hostapd_config_read_maclist(pos
, &bss
->accept_mac
,
1758 &bss
->num_accept_mac
))
1760 wpa_printf(MSG_ERROR
, "Line %d: Failed to "
1761 "read accept_mac_file '%s'",
1765 } else if (os_strcmp(buf
, "deny_mac_file") == 0) {
1766 if (hostapd_config_read_maclist(pos
, &bss
->deny_mac
,
1767 &bss
->num_deny_mac
)) {
1768 wpa_printf(MSG_ERROR
, "Line %d: Failed to "
1769 "read deny_mac_file '%s'",
1773 } else if (os_strcmp(buf
, "wds_sta") == 0) {
1774 bss
->wds_sta
= atoi(pos
);
1775 } else if (os_strcmp(buf
, "ap_isolate") == 0) {
1776 bss
->isolate
= atoi(pos
);
1777 } else if (os_strcmp(buf
, "ap_max_inactivity") == 0) {
1778 bss
->ap_max_inactivity
= atoi(pos
);
1779 } else if (os_strcmp(buf
, "skip_inactivity_poll") == 0) {
1780 bss
->skip_inactivity_poll
= atoi(pos
);
1781 } else if (os_strcmp(buf
, "country_code") == 0) {
1782 os_memcpy(conf
->country
, pos
, 2);
1783 /* FIX: make this configurable */
1784 conf
->country
[2] = ' ';
1785 } else if (os_strcmp(buf
, "ieee80211d") == 0) {
1786 conf
->ieee80211d
= atoi(pos
);
1787 } else if (os_strcmp(buf
, "ieee8021x") == 0) {
1788 bss
->ieee802_1x
= atoi(pos
);
1789 } else if (os_strcmp(buf
, "eapol_version") == 0) {
1790 bss
->eapol_version
= atoi(pos
);
1791 if (bss
->eapol_version
< 1 ||
1792 bss
->eapol_version
> 2) {
1793 wpa_printf(MSG_ERROR
, "Line %d: invalid EAPOL "
1794 "version (%d): '%s'.",
1795 line
, bss
->eapol_version
, pos
);
1798 wpa_printf(MSG_DEBUG
, "eapol_version=%d",
1799 bss
->eapol_version
);
1801 } else if (os_strcmp(buf
, "eap_authenticator") == 0) {
1802 bss
->eap_server
= atoi(pos
);
1803 wpa_printf(MSG_ERROR
, "Line %d: obsolete "
1804 "eap_authenticator used; this has been "
1805 "renamed to eap_server", line
);
1806 } else if (os_strcmp(buf
, "eap_server") == 0) {
1807 bss
->eap_server
= atoi(pos
);
1808 } else if (os_strcmp(buf
, "eap_user_file") == 0) {
1809 if (hostapd_config_read_eap_user(pos
, bss
))
1811 } else if (os_strcmp(buf
, "ca_cert") == 0) {
1812 os_free(bss
->ca_cert
);
1813 bss
->ca_cert
= os_strdup(pos
);
1814 } else if (os_strcmp(buf
, "server_cert") == 0) {
1815 os_free(bss
->server_cert
);
1816 bss
->server_cert
= os_strdup(pos
);
1817 } else if (os_strcmp(buf
, "private_key") == 0) {
1818 os_free(bss
->private_key
);
1819 bss
->private_key
= os_strdup(pos
);
1820 } else if (os_strcmp(buf
, "private_key_passwd") == 0) {
1821 os_free(bss
->private_key_passwd
);
1822 bss
->private_key_passwd
= os_strdup(pos
);
1823 } else if (os_strcmp(buf
, "check_crl") == 0) {
1824 bss
->check_crl
= atoi(pos
);
1825 } else if (os_strcmp(buf
, "dh_file") == 0) {
1826 os_free(bss
->dh_file
);
1827 bss
->dh_file
= os_strdup(pos
);
1828 } else if (os_strcmp(buf
, "fragment_size") == 0) {
1829 bss
->fragment_size
= atoi(pos
);
1830 #ifdef EAP_SERVER_FAST
1831 } else if (os_strcmp(buf
, "pac_opaque_encr_key") == 0) {
1832 os_free(bss
->pac_opaque_encr_key
);
1833 bss
->pac_opaque_encr_key
= os_malloc(16);
1834 if (bss
->pac_opaque_encr_key
== NULL
) {
1835 wpa_printf(MSG_ERROR
, "Line %d: No memory for "
1836 "pac_opaque_encr_key", line
);
1838 } else if (hexstr2bin(pos
, bss
->pac_opaque_encr_key
,
1840 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
1841 "pac_opaque_encr_key", line
);
1844 } else if (os_strcmp(buf
, "eap_fast_a_id") == 0) {
1845 size_t idlen
= os_strlen(pos
);
1847 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
1848 "eap_fast_a_id", line
);
1851 os_free(bss
->eap_fast_a_id
);
1852 bss
->eap_fast_a_id
= os_malloc(idlen
/ 2);
1853 if (bss
->eap_fast_a_id
== NULL
||
1854 hexstr2bin(pos
, bss
->eap_fast_a_id
,
1856 wpa_printf(MSG_ERROR
, "Line %d: "
1858 "eap_fast_a_id", line
);
1861 bss
->eap_fast_a_id_len
= idlen
/ 2;
1863 } else if (os_strcmp(buf
, "eap_fast_a_id_info") == 0) {
1864 os_free(bss
->eap_fast_a_id_info
);
1865 bss
->eap_fast_a_id_info
= os_strdup(pos
);
1866 } else if (os_strcmp(buf
, "eap_fast_prov") == 0) {
1867 bss
->eap_fast_prov
= atoi(pos
);
1868 } else if (os_strcmp(buf
, "pac_key_lifetime") == 0) {
1869 bss
->pac_key_lifetime
= atoi(pos
);
1870 } else if (os_strcmp(buf
, "pac_key_refresh_time") == 0) {
1871 bss
->pac_key_refresh_time
= atoi(pos
);
1872 #endif /* EAP_SERVER_FAST */
1873 #ifdef EAP_SERVER_SIM
1874 } else if (os_strcmp(buf
, "eap_sim_db") == 0) {
1875 os_free(bss
->eap_sim_db
);
1876 bss
->eap_sim_db
= os_strdup(pos
);
1877 } else if (os_strcmp(buf
, "eap_sim_aka_result_ind") == 0) {
1878 bss
->eap_sim_aka_result_ind
= atoi(pos
);
1879 #endif /* EAP_SERVER_SIM */
1880 #ifdef EAP_SERVER_TNC
1881 } else if (os_strcmp(buf
, "tnc") == 0) {
1882 bss
->tnc
= atoi(pos
);
1883 #endif /* EAP_SERVER_TNC */
1884 #ifdef EAP_SERVER_PWD
1885 } else if (os_strcmp(buf
, "pwd_group") == 0) {
1886 bss
->pwd_group
= atoi(pos
);
1887 #endif /* EAP_SERVER_PWD */
1888 #endif /* EAP_SERVER */
1889 } else if (os_strcmp(buf
, "eap_message") == 0) {
1891 bss
->eap_req_id_text
= os_strdup(pos
);
1892 if (bss
->eap_req_id_text
== NULL
) {
1893 wpa_printf(MSG_ERROR
, "Line %d: Failed to "
1894 "allocate memory for "
1895 "eap_req_id_text", line
);
1899 bss
->eap_req_id_text_len
=
1900 os_strlen(bss
->eap_req_id_text
);
1901 term
= os_strstr(bss
->eap_req_id_text
, "\\0");
1904 os_memmove(term
, term
+ 1,
1905 bss
->eap_req_id_text_len
-
1906 (term
- bss
->eap_req_id_text
) - 1);
1907 bss
->eap_req_id_text_len
--;
1909 } else if (os_strcmp(buf
, "wep_key_len_broadcast") == 0) {
1910 bss
->default_wep_key_len
= atoi(pos
);
1911 if (bss
->default_wep_key_len
> 13) {
1912 wpa_printf(MSG_ERROR
, "Line %d: invalid WEP "
1913 "key len %lu (= %lu bits)", line
,
1915 bss
->default_wep_key_len
,
1917 bss
->default_wep_key_len
* 8);
1920 } else if (os_strcmp(buf
, "wep_key_len_unicast") == 0) {
1921 bss
->individual_wep_key_len
= atoi(pos
);
1922 if (bss
->individual_wep_key_len
< 0 ||
1923 bss
->individual_wep_key_len
> 13) {
1924 wpa_printf(MSG_ERROR
, "Line %d: invalid WEP "
1925 "key len %d (= %d bits)", line
,
1926 bss
->individual_wep_key_len
,
1927 bss
->individual_wep_key_len
* 8);
1930 } else if (os_strcmp(buf
, "wep_rekey_period") == 0) {
1931 bss
->wep_rekeying_period
= atoi(pos
);
1932 if (bss
->wep_rekeying_period
< 0) {
1933 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1935 line
, bss
->wep_rekeying_period
);
1938 } else if (os_strcmp(buf
, "eap_reauth_period") == 0) {
1939 bss
->eap_reauth_period
= atoi(pos
);
1940 if (bss
->eap_reauth_period
< 0) {
1941 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1943 line
, bss
->eap_reauth_period
);
1946 } else if (os_strcmp(buf
, "eapol_key_index_workaround") == 0) {
1947 bss
->eapol_key_index_workaround
= atoi(pos
);
1949 } else if (os_strcmp(buf
, "iapp_interface") == 0) {
1950 bss
->ieee802_11f
= 1;
1951 os_strlcpy(bss
->iapp_iface
, pos
,
1952 sizeof(bss
->iapp_iface
));
1953 #endif /* CONFIG_IAPP */
1954 } else if (os_strcmp(buf
, "own_ip_addr") == 0) {
1955 if (hostapd_parse_ip_addr(pos
, &bss
->own_ip_addr
)) {
1956 wpa_printf(MSG_ERROR
, "Line %d: invalid IP "
1957 "address '%s'", line
, pos
);
1960 } else if (os_strcmp(buf
, "nas_identifier") == 0) {
1961 bss
->nas_identifier
= os_strdup(pos
);
1962 #ifndef CONFIG_NO_RADIUS
1963 } else if (os_strcmp(buf
, "auth_server_addr") == 0) {
1964 if (hostapd_config_read_radius_addr(
1965 &bss
->radius
->auth_servers
,
1966 &bss
->radius
->num_auth_servers
, pos
, 1812,
1967 &bss
->radius
->auth_server
)) {
1968 wpa_printf(MSG_ERROR
, "Line %d: invalid IP "
1969 "address '%s'", line
, pos
);
1972 } else if (bss
->radius
->auth_server
&&
1973 os_strcmp(buf
, "auth_server_port") == 0) {
1974 bss
->radius
->auth_server
->port
= atoi(pos
);
1975 } else if (bss
->radius
->auth_server
&&
1976 os_strcmp(buf
, "auth_server_shared_secret") == 0) {
1977 int len
= os_strlen(pos
);
1979 /* RFC 2865, Ch. 3 */
1980 wpa_printf(MSG_ERROR
, "Line %d: empty shared "
1981 "secret is not allowed.", line
);
1984 bss
->radius
->auth_server
->shared_secret
=
1985 (u8
*) os_strdup(pos
);
1986 bss
->radius
->auth_server
->shared_secret_len
= len
;
1987 } else if (os_strcmp(buf
, "acct_server_addr") == 0) {
1988 if (hostapd_config_read_radius_addr(
1989 &bss
->radius
->acct_servers
,
1990 &bss
->radius
->num_acct_servers
, pos
, 1813,
1991 &bss
->radius
->acct_server
)) {
1992 wpa_printf(MSG_ERROR
, "Line %d: invalid IP "
1993 "address '%s'", line
, pos
);
1996 } else if (bss
->radius
->acct_server
&&
1997 os_strcmp(buf
, "acct_server_port") == 0) {
1998 bss
->radius
->acct_server
->port
= atoi(pos
);
1999 } else if (bss
->radius
->acct_server
&&
2000 os_strcmp(buf
, "acct_server_shared_secret") == 0) {
2001 int len
= os_strlen(pos
);
2003 /* RFC 2865, Ch. 3 */
2004 wpa_printf(MSG_ERROR
, "Line %d: empty shared "
2005 "secret is not allowed.", line
);
2008 bss
->radius
->acct_server
->shared_secret
=
2009 (u8
*) os_strdup(pos
);
2010 bss
->radius
->acct_server
->shared_secret_len
= len
;
2011 } else if (os_strcmp(buf
, "radius_retry_primary_interval") ==
2013 bss
->radius
->retry_primary_interval
= atoi(pos
);
2014 } else if (os_strcmp(buf
, "radius_acct_interim_interval") == 0)
2016 bss
->acct_interim_interval
= atoi(pos
);
2017 } else if (os_strcmp(buf
, "radius_request_cui") == 0) {
2018 bss
->radius_request_cui
= atoi(pos
);
2019 } else if (os_strcmp(buf
, "radius_auth_req_attr") == 0) {
2020 struct hostapd_radius_attr
*attr
, *a
;
2021 attr
= hostapd_parse_radius_attr(pos
);
2023 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2024 "radius_auth_req_attr", line
);
2026 } else if (bss
->radius_auth_req_attr
== NULL
) {
2027 bss
->radius_auth_req_attr
= attr
;
2029 a
= bss
->radius_auth_req_attr
;
2034 } else if (os_strcmp(buf
, "radius_acct_req_attr") == 0) {
2035 struct hostapd_radius_attr
*attr
, *a
;
2036 attr
= hostapd_parse_radius_attr(pos
);
2038 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2039 "radius_acct_req_attr", line
);
2041 } else if (bss
->radius_acct_req_attr
== NULL
) {
2042 bss
->radius_acct_req_attr
= attr
;
2044 a
= bss
->radius_acct_req_attr
;
2049 } else if (os_strcmp(buf
, "radius_das_port") == 0) {
2050 bss
->radius_das_port
= atoi(pos
);
2051 } else if (os_strcmp(buf
, "radius_das_client") == 0) {
2052 if (hostapd_parse_das_client(bss
, pos
) < 0) {
2053 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2054 "DAS client", line
);
2057 } else if (os_strcmp(buf
, "radius_das_time_window") == 0) {
2058 bss
->radius_das_time_window
= atoi(pos
);
2059 } else if (os_strcmp(buf
, "radius_das_require_event_timestamp")
2061 bss
->radius_das_require_event_timestamp
= atoi(pos
);
2062 #endif /* CONFIG_NO_RADIUS */
2063 } else if (os_strcmp(buf
, "auth_algs") == 0) {
2064 bss
->auth_algs
= atoi(pos
);
2065 if (bss
->auth_algs
== 0) {
2066 wpa_printf(MSG_ERROR
, "Line %d: no "
2067 "authentication algorithms allowed",
2071 } else if (os_strcmp(buf
, "max_num_sta") == 0) {
2072 bss
->max_num_sta
= atoi(pos
);
2073 if (bss
->max_num_sta
< 0 ||
2074 bss
->max_num_sta
> MAX_STA_COUNT
) {
2075 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
2076 "max_num_sta=%d; allowed range "
2077 "0..%d", line
, bss
->max_num_sta
,
2081 } else if (os_strcmp(buf
, "wpa") == 0) {
2082 bss
->wpa
= atoi(pos
);
2083 } else if (os_strcmp(buf
, "wpa_group_rekey") == 0) {
2084 bss
->wpa_group_rekey
= atoi(pos
);
2085 } else if (os_strcmp(buf
, "wpa_strict_rekey") == 0) {
2086 bss
->wpa_strict_rekey
= atoi(pos
);
2087 } else if (os_strcmp(buf
, "wpa_gmk_rekey") == 0) {
2088 bss
->wpa_gmk_rekey
= atoi(pos
);
2089 } else if (os_strcmp(buf
, "wpa_ptk_rekey") == 0) {
2090 bss
->wpa_ptk_rekey
= atoi(pos
);
2091 } else if (os_strcmp(buf
, "wpa_passphrase") == 0) {
2092 int len
= os_strlen(pos
);
2093 if (len
< 8 || len
> 63) {
2094 wpa_printf(MSG_ERROR
, "Line %d: invalid WPA "
2095 "passphrase length %d (expected "
2096 "8..63)", line
, len
);
2099 os_free(bss
->ssid
.wpa_passphrase
);
2100 bss
->ssid
.wpa_passphrase
= os_strdup(pos
);
2101 os_free(bss
->ssid
.wpa_psk
);
2102 bss
->ssid
.wpa_psk
= NULL
;
2104 } else if (os_strcmp(buf
, "wpa_psk") == 0) {
2105 os_free(bss
->ssid
.wpa_psk
);
2107 os_zalloc(sizeof(struct hostapd_wpa_psk
));
2108 if (bss
->ssid
.wpa_psk
== NULL
)
2110 else if (hexstr2bin(pos
, bss
->ssid
.wpa_psk
->psk
,
2112 pos
[PMK_LEN
* 2] != '\0') {
2113 wpa_printf(MSG_ERROR
, "Line %d: Invalid PSK "
2114 "'%s'.", line
, pos
);
2117 bss
->ssid
.wpa_psk
->group
= 1;
2118 os_free(bss
->ssid
.wpa_passphrase
);
2119 bss
->ssid
.wpa_passphrase
= NULL
;
2121 } else if (os_strcmp(buf
, "wpa_psk_file") == 0) {
2122 os_free(bss
->ssid
.wpa_psk_file
);
2123 bss
->ssid
.wpa_psk_file
= os_strdup(pos
);
2124 if (!bss
->ssid
.wpa_psk_file
) {
2125 wpa_printf(MSG_ERROR
, "Line %d: allocation "
2129 } else if (os_strcmp(buf
, "wpa_key_mgmt") == 0) {
2131 hostapd_config_parse_key_mgmt(line
, pos
);
2132 if (bss
->wpa_key_mgmt
== -1)
2134 } else if (os_strcmp(buf
, "wpa_psk_radius") == 0) {
2135 bss
->wpa_psk_radius
= atoi(pos
);
2136 if (bss
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
&&
2137 bss
->wpa_psk_radius
!= PSK_RADIUS_ACCEPTED
&&
2138 bss
->wpa_psk_radius
!= PSK_RADIUS_REQUIRED
) {
2139 wpa_printf(MSG_ERROR
, "Line %d: unknown "
2140 "wpa_psk_radius %d",
2141 line
, bss
->wpa_psk_radius
);
2144 } else if (os_strcmp(buf
, "wpa_pairwise") == 0) {
2146 hostapd_config_parse_cipher(line
, pos
);
2147 if (bss
->wpa_pairwise
== -1 ||
2148 bss
->wpa_pairwise
== 0)
2150 else if (bss
->wpa_pairwise
&
2151 (WPA_CIPHER_NONE
| WPA_CIPHER_WEP40
|
2152 WPA_CIPHER_WEP104
)) {
2153 wpa_printf(MSG_ERROR
, "Line %d: unsupported "
2154 "pairwise cipher suite '%s'",
2155 bss
->wpa_pairwise
, pos
);
2158 } else if (os_strcmp(buf
, "rsn_pairwise") == 0) {
2160 hostapd_config_parse_cipher(line
, pos
);
2161 if (bss
->rsn_pairwise
== -1 ||
2162 bss
->rsn_pairwise
== 0)
2164 else if (bss
->rsn_pairwise
&
2165 (WPA_CIPHER_NONE
| WPA_CIPHER_WEP40
|
2166 WPA_CIPHER_WEP104
)) {
2167 wpa_printf(MSG_ERROR
, "Line %d: unsupported "
2168 "pairwise cipher suite '%s'",
2169 bss
->rsn_pairwise
, pos
);
2172 #ifdef CONFIG_RSN_PREAUTH
2173 } else if (os_strcmp(buf
, "rsn_preauth") == 0) {
2174 bss
->rsn_preauth
= atoi(pos
);
2175 } else if (os_strcmp(buf
, "rsn_preauth_interfaces") == 0) {
2176 bss
->rsn_preauth_interfaces
= os_strdup(pos
);
2177 #endif /* CONFIG_RSN_PREAUTH */
2178 #ifdef CONFIG_PEERKEY
2179 } else if (os_strcmp(buf
, "peerkey") == 0) {
2180 bss
->peerkey
= atoi(pos
);
2181 #endif /* CONFIG_PEERKEY */
2182 #ifdef CONFIG_IEEE80211R
2183 } else if (os_strcmp(buf
, "mobility_domain") == 0) {
2184 if (os_strlen(pos
) != 2 * MOBILITY_DOMAIN_ID_LEN
||
2185 hexstr2bin(pos
, bss
->mobility_domain
,
2186 MOBILITY_DOMAIN_ID_LEN
) != 0) {
2187 wpa_printf(MSG_DEBUG
, "Line %d: Invalid "
2188 "mobility_domain '%s'", line
, pos
);
2192 } else if (os_strcmp(buf
, "r1_key_holder") == 0) {
2193 if (os_strlen(pos
) != 2 * FT_R1KH_ID_LEN
||
2194 hexstr2bin(pos
, bss
->r1_key_holder
,
2195 FT_R1KH_ID_LEN
) != 0) {
2196 wpa_printf(MSG_DEBUG
, "Line %d: Invalid "
2197 "r1_key_holder '%s'", line
, pos
);
2201 } else if (os_strcmp(buf
, "r0_key_lifetime") == 0) {
2202 bss
->r0_key_lifetime
= atoi(pos
);
2203 } else if (os_strcmp(buf
, "reassociation_deadline") == 0) {
2204 bss
->reassociation_deadline
= atoi(pos
);
2205 } else if (os_strcmp(buf
, "r0kh") == 0) {
2206 if (add_r0kh(bss
, pos
) < 0) {
2207 wpa_printf(MSG_DEBUG
, "Line %d: Invalid "
2208 "r0kh '%s'", line
, pos
);
2212 } else if (os_strcmp(buf
, "r1kh") == 0) {
2213 if (add_r1kh(bss
, pos
) < 0) {
2214 wpa_printf(MSG_DEBUG
, "Line %d: Invalid "
2215 "r1kh '%s'", line
, pos
);
2219 } else if (os_strcmp(buf
, "pmk_r1_push") == 0) {
2220 bss
->pmk_r1_push
= atoi(pos
);
2221 } else if (os_strcmp(buf
, "ft_over_ds") == 0) {
2222 bss
->ft_over_ds
= atoi(pos
);
2223 #endif /* CONFIG_IEEE80211R */
2224 #ifndef CONFIG_NO_CTRL_IFACE
2225 } else if (os_strcmp(buf
, "ctrl_interface") == 0) {
2226 os_free(bss
->ctrl_interface
);
2227 bss
->ctrl_interface
= os_strdup(pos
);
2228 } else if (os_strcmp(buf
, "ctrl_interface_group") == 0) {
2229 #ifndef CONFIG_NATIVE_WINDOWS
2232 const char *group
= pos
;
2234 grp
= getgrnam(group
);
2236 bss
->ctrl_interface_gid
= grp
->gr_gid
;
2237 bss
->ctrl_interface_gid_set
= 1;
2238 wpa_printf(MSG_DEBUG
, "ctrl_interface_group=%d"
2239 " (from group name '%s')",
2240 bss
->ctrl_interface_gid
, group
);
2244 /* Group name not found - try to parse this as gid */
2245 bss
->ctrl_interface_gid
= strtol(group
, &endp
, 10);
2246 if (*group
== '\0' || *endp
!= '\0') {
2247 wpa_printf(MSG_DEBUG
, "Line %d: Invalid group "
2248 "'%s'", line
, group
);
2252 bss
->ctrl_interface_gid_set
= 1;
2253 wpa_printf(MSG_DEBUG
, "ctrl_interface_group=%d",
2254 bss
->ctrl_interface_gid
);
2255 #endif /* CONFIG_NATIVE_WINDOWS */
2256 #endif /* CONFIG_NO_CTRL_IFACE */
2257 #ifdef RADIUS_SERVER
2258 } else if (os_strcmp(buf
, "radius_server_clients") == 0) {
2259 os_free(bss
->radius_server_clients
);
2260 bss
->radius_server_clients
= os_strdup(pos
);
2261 } else if (os_strcmp(buf
, "radius_server_auth_port") == 0) {
2262 bss
->radius_server_auth_port
= atoi(pos
);
2263 } else if (os_strcmp(buf
, "radius_server_ipv6") == 0) {
2264 bss
->radius_server_ipv6
= atoi(pos
);
2265 #endif /* RADIUS_SERVER */
2266 } else if (os_strcmp(buf
, "test_socket") == 0) {
2267 os_free(bss
->test_socket
);
2268 bss
->test_socket
= os_strdup(pos
);
2269 } else if (os_strcmp(buf
, "use_pae_group_addr") == 0) {
2270 bss
->use_pae_group_addr
= atoi(pos
);
2271 } else if (os_strcmp(buf
, "hw_mode") == 0) {
2272 if (os_strcmp(pos
, "a") == 0)
2273 conf
->hw_mode
= HOSTAPD_MODE_IEEE80211A
;
2274 else if (os_strcmp(pos
, "b") == 0)
2275 conf
->hw_mode
= HOSTAPD_MODE_IEEE80211B
;
2276 else if (os_strcmp(pos
, "g") == 0)
2277 conf
->hw_mode
= HOSTAPD_MODE_IEEE80211G
;
2278 else if (os_strcmp(pos
, "ad") == 0)
2279 conf
->hw_mode
= HOSTAPD_MODE_IEEE80211AD
;
2281 wpa_printf(MSG_ERROR
, "Line %d: unknown "
2282 "hw_mode '%s'", line
, pos
);
2285 } else if (os_strcmp(buf
, "wps_rf_bands") == 0) {
2286 if (os_strcmp(pos
, "a") == 0)
2287 bss
->wps_rf_bands
= WPS_RF_50GHZ
;
2288 else if (os_strcmp(pos
, "g") == 0 ||
2289 os_strcmp(pos
, "b") == 0)
2290 bss
->wps_rf_bands
= WPS_RF_24GHZ
;
2291 else if (os_strcmp(pos
, "ag") == 0 ||
2292 os_strcmp(pos
, "ga") == 0)
2294 WPS_RF_24GHZ
| WPS_RF_50GHZ
;
2296 wpa_printf(MSG_ERROR
, "Line %d: unknown "
2297 "wps_rf_band '%s'", line
, pos
);
2300 } else if (os_strcmp(buf
, "channel") == 0) {
2301 conf
->channel
= atoi(pos
);
2302 } else if (os_strcmp(buf
, "beacon_int") == 0) {
2303 int val
= atoi(pos
);
2304 /* MIB defines range as 1..65535, but very small values
2305 * cause problems with the current implementation.
2306 * Since it is unlikely that this small numbers are
2307 * useful in real life scenarios, do not allow beacon
2308 * period to be set below 15 TU. */
2309 if (val
< 15 || val
> 65535) {
2310 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2311 "beacon_int %d (expected "
2312 "15..65535)", line
, val
);
2315 conf
->beacon_int
= val
;
2316 } else if (os_strcmp(buf
, "dtim_period") == 0) {
2317 bss
->dtim_period
= atoi(pos
);
2318 if (bss
->dtim_period
< 1 || bss
->dtim_period
> 255) {
2319 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2321 line
, bss
->dtim_period
);
2324 } else if (os_strcmp(buf
, "rts_threshold") == 0) {
2325 conf
->rts_threshold
= atoi(pos
);
2326 if (conf
->rts_threshold
< 0 ||
2327 conf
->rts_threshold
> 2347) {
2328 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2330 line
, conf
->rts_threshold
);
2333 } else if (os_strcmp(buf
, "fragm_threshold") == 0) {
2334 conf
->fragm_threshold
= atoi(pos
);
2335 if (conf
->fragm_threshold
< 256 ||
2336 conf
->fragm_threshold
> 2346) {
2337 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2338 "fragm_threshold %d",
2339 line
, conf
->fragm_threshold
);
2342 } else if (os_strcmp(buf
, "send_probe_response") == 0) {
2343 int val
= atoi(pos
);
2344 if (val
!= 0 && val
!= 1) {
2345 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2346 "send_probe_response %d (expected "
2347 "0 or 1)", line
, val
);
2349 conf
->send_probe_response
= val
;
2350 } else if (os_strcmp(buf
, "supported_rates") == 0) {
2351 if (hostapd_parse_rates(&conf
->supported_rates
, pos
)) {
2352 wpa_printf(MSG_ERROR
, "Line %d: invalid rate "
2356 } else if (os_strcmp(buf
, "basic_rates") == 0) {
2357 if (hostapd_parse_rates(&conf
->basic_rates
, pos
)) {
2358 wpa_printf(MSG_ERROR
, "Line %d: invalid rate "
2362 } else if (os_strcmp(buf
, "preamble") == 0) {
2364 conf
->preamble
= SHORT_PREAMBLE
;
2366 conf
->preamble
= LONG_PREAMBLE
;
2367 } else if (os_strcmp(buf
, "ignore_broadcast_ssid") == 0) {
2368 bss
->ignore_broadcast_ssid
= atoi(pos
);
2369 } else if (os_strcmp(buf
, "wep_default_key") == 0) {
2370 bss
->ssid
.wep
.idx
= atoi(pos
);
2371 if (bss
->ssid
.wep
.idx
> 3) {
2372 wpa_printf(MSG_ERROR
, "Invalid "
2373 "wep_default_key index %d",
2377 } else if (os_strcmp(buf
, "wep_key0") == 0 ||
2378 os_strcmp(buf
, "wep_key1") == 0 ||
2379 os_strcmp(buf
, "wep_key2") == 0 ||
2380 os_strcmp(buf
, "wep_key3") == 0) {
2381 if (hostapd_config_read_wep(&bss
->ssid
.wep
,
2382 buf
[7] - '0', pos
)) {
2383 wpa_printf(MSG_ERROR
, "Line %d: invalid WEP "
2384 "key '%s'", line
, buf
);
2387 #ifndef CONFIG_NO_VLAN
2388 } else if (os_strcmp(buf
, "dynamic_vlan") == 0) {
2389 bss
->ssid
.dynamic_vlan
= atoi(pos
);
2390 } else if (os_strcmp(buf
, "vlan_file") == 0) {
2391 if (hostapd_config_read_vlan_file(bss
, pos
)) {
2392 wpa_printf(MSG_ERROR
, "Line %d: failed to "
2393 "read VLAN file '%s'", line
, pos
);
2396 } else if (os_strcmp(buf
, "vlan_naming") == 0) {
2397 bss
->ssid
.vlan_naming
= atoi(pos
);
2398 if (bss
->ssid
.vlan_naming
>= DYNAMIC_VLAN_NAMING_END
||
2399 bss
->ssid
.vlan_naming
< 0) {
2400 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2401 "naming scheme %d", line
,
2402 bss
->ssid
.vlan_naming
);
2405 #ifdef CONFIG_FULL_DYNAMIC_VLAN
2406 } else if (os_strcmp(buf
, "vlan_tagged_interface") == 0) {
2407 bss
->ssid
.vlan_tagged_interface
= os_strdup(pos
);
2408 #endif /* CONFIG_FULL_DYNAMIC_VLAN */
2409 #endif /* CONFIG_NO_VLAN */
2410 } else if (os_strcmp(buf
, "ap_table_max_size") == 0) {
2411 conf
->ap_table_max_size
= atoi(pos
);
2412 } else if (os_strcmp(buf
, "ap_table_expiration_time") == 0) {
2413 conf
->ap_table_expiration_time
= atoi(pos
);
2414 } else if (os_strncmp(buf
, "tx_queue_", 9) == 0) {
2415 if (hostapd_config_tx_queue(conf
, buf
, pos
)) {
2416 wpa_printf(MSG_ERROR
, "Line %d: invalid TX "
2417 "queue item", line
);
2420 } else if (os_strcmp(buf
, "wme_enabled") == 0 ||
2421 os_strcmp(buf
, "wmm_enabled") == 0) {
2422 bss
->wmm_enabled
= atoi(pos
);
2423 } else if (os_strcmp(buf
, "uapsd_advertisement_enabled") == 0) {
2424 bss
->wmm_uapsd
= atoi(pos
);
2425 } else if (os_strncmp(buf
, "wme_ac_", 7) == 0 ||
2426 os_strncmp(buf
, "wmm_ac_", 7) == 0) {
2427 if (hostapd_config_wmm_ac(conf
->wmm_ac_params
, buf
,
2429 wpa_printf(MSG_ERROR
, "Line %d: invalid WMM "
2433 } else if (os_strcmp(buf
, "bss") == 0) {
2434 if (hostapd_config_bss(conf
, pos
)) {
2435 wpa_printf(MSG_ERROR
, "Line %d: invalid bss "
2439 } else if (os_strcmp(buf
, "bssid") == 0) {
2440 if (hwaddr_aton(pos
, bss
->bssid
)) {
2441 wpa_printf(MSG_ERROR
, "Line %d: invalid bssid "
2445 #ifdef CONFIG_IEEE80211W
2446 } else if (os_strcmp(buf
, "ieee80211w") == 0) {
2447 bss
->ieee80211w
= atoi(pos
);
2448 } else if (os_strcmp(buf
, "assoc_sa_query_max_timeout") == 0) {
2449 bss
->assoc_sa_query_max_timeout
= atoi(pos
);
2450 if (bss
->assoc_sa_query_max_timeout
== 0) {
2451 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2452 "assoc_sa_query_max_timeout", line
);
2455 } else if (os_strcmp(buf
, "assoc_sa_query_retry_timeout") == 0)
2457 bss
->assoc_sa_query_retry_timeout
= atoi(pos
);
2458 if (bss
->assoc_sa_query_retry_timeout
== 0) {
2459 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2460 "assoc_sa_query_retry_timeout",
2464 #endif /* CONFIG_IEEE80211W */
2465 #ifdef CONFIG_IEEE80211N
2466 } else if (os_strcmp(buf
, "ieee80211n") == 0) {
2467 conf
->ieee80211n
= atoi(pos
);
2468 } else if (os_strcmp(buf
, "ht_capab") == 0) {
2469 if (hostapd_config_ht_capab(conf
, pos
) < 0) {
2470 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2474 } else if (os_strcmp(buf
, "require_ht") == 0) {
2475 conf
->require_ht
= atoi(pos
);
2476 #endif /* CONFIG_IEEE80211N */
2477 #ifdef CONFIG_IEEE80211AC
2478 } else if (os_strcmp(buf
, "ieee80211ac") == 0) {
2479 conf
->ieee80211ac
= atoi(pos
);
2480 } else if (os_strcmp(buf
, "vht_capab") == 0) {
2481 if (hostapd_config_vht_capab(conf
, pos
) < 0) {
2482 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2486 } else if (os_strcmp(buf
, "require_vht") == 0) {
2487 conf
->require_vht
= atoi(pos
);
2488 } else if (os_strcmp(buf
, "vht_oper_chwidth") == 0) {
2489 conf
->vht_oper_chwidth
= atoi(pos
);
2490 } else if (os_strcmp(buf
, "vht_oper_centr_freq_seg0_idx") == 0)
2492 conf
->vht_oper_centr_freq_seg0_idx
= atoi(pos
);
2493 } else if (os_strcmp(buf
, "vht_oper_centr_freq_seg1_idx") == 0)
2495 conf
->vht_oper_centr_freq_seg1_idx
= atoi(pos
);
2496 #endif /* CONFIG_IEEE80211AC */
2497 } else if (os_strcmp(buf
, "max_listen_interval") == 0) {
2498 bss
->max_listen_interval
= atoi(pos
);
2499 } else if (os_strcmp(buf
, "disable_pmksa_caching") == 0) {
2500 bss
->disable_pmksa_caching
= atoi(pos
);
2501 } else if (os_strcmp(buf
, "okc") == 0) {
2502 bss
->okc
= atoi(pos
);
2504 } else if (os_strcmp(buf
, "wps_state") == 0) {
2505 bss
->wps_state
= atoi(pos
);
2506 if (bss
->wps_state
< 0 || bss
->wps_state
> 2) {
2507 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2511 } else if (os_strcmp(buf
, "wps_independent") == 0) {
2512 bss
->wps_independent
= atoi(pos
);
2513 } else if (os_strcmp(buf
, "ap_setup_locked") == 0) {
2514 bss
->ap_setup_locked
= atoi(pos
);
2515 } else if (os_strcmp(buf
, "uuid") == 0) {
2516 if (uuid_str2bin(pos
, bss
->uuid
)) {
2517 wpa_printf(MSG_ERROR
, "Line %d: invalid UUID",
2521 } else if (os_strcmp(buf
, "wps_pin_requests") == 0) {
2522 os_free(bss
->wps_pin_requests
);
2523 bss
->wps_pin_requests
= os_strdup(pos
);
2524 } else if (os_strcmp(buf
, "device_name") == 0) {
2525 if (os_strlen(pos
) > 32) {
2526 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2527 "device_name", line
);
2530 os_free(bss
->device_name
);
2531 bss
->device_name
= os_strdup(pos
);
2532 } else if (os_strcmp(buf
, "manufacturer") == 0) {
2533 if (os_strlen(pos
) > 64) {
2534 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2535 "manufacturer", line
);
2538 os_free(bss
->manufacturer
);
2539 bss
->manufacturer
= os_strdup(pos
);
2540 } else if (os_strcmp(buf
, "model_name") == 0) {
2541 if (os_strlen(pos
) > 32) {
2542 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2543 "model_name", line
);
2546 os_free(bss
->model_name
);
2547 bss
->model_name
= os_strdup(pos
);
2548 } else if (os_strcmp(buf
, "model_number") == 0) {
2549 if (os_strlen(pos
) > 32) {
2550 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2551 "model_number", line
);
2554 os_free(bss
->model_number
);
2555 bss
->model_number
= os_strdup(pos
);
2556 } else if (os_strcmp(buf
, "serial_number") == 0) {
2557 if (os_strlen(pos
) > 32) {
2558 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2559 "serial_number", line
);
2562 os_free(bss
->serial_number
);
2563 bss
->serial_number
= os_strdup(pos
);
2564 } else if (os_strcmp(buf
, "device_type") == 0) {
2565 if (wps_dev_type_str2bin(pos
, bss
->device_type
))
2567 } else if (os_strcmp(buf
, "config_methods") == 0) {
2568 os_free(bss
->config_methods
);
2569 bss
->config_methods
= os_strdup(pos
);
2570 } else if (os_strcmp(buf
, "os_version") == 0) {
2571 if (hexstr2bin(pos
, bss
->os_version
, 4)) {
2572 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2573 "os_version", line
);
2576 } else if (os_strcmp(buf
, "ap_pin") == 0) {
2577 os_free(bss
->ap_pin
);
2578 bss
->ap_pin
= os_strdup(pos
);
2579 } else if (os_strcmp(buf
, "skip_cred_build") == 0) {
2580 bss
->skip_cred_build
= atoi(pos
);
2581 } else if (os_strcmp(buf
, "extra_cred") == 0) {
2582 os_free(bss
->extra_cred
);
2584 (u8
*) os_readfile(pos
, &bss
->extra_cred_len
);
2585 if (bss
->extra_cred
== NULL
) {
2586 wpa_printf(MSG_ERROR
, "Line %d: could not "
2587 "read Credentials from '%s'",
2591 } else if (os_strcmp(buf
, "wps_cred_processing") == 0) {
2592 bss
->wps_cred_processing
= atoi(pos
);
2593 } else if (os_strcmp(buf
, "ap_settings") == 0) {
2594 os_free(bss
->ap_settings
);
2596 (u8
*) os_readfile(pos
, &bss
->ap_settings_len
);
2597 if (bss
->ap_settings
== NULL
) {
2598 wpa_printf(MSG_ERROR
, "Line %d: could not "
2599 "read AP Settings from '%s'",
2603 } else if (os_strcmp(buf
, "upnp_iface") == 0) {
2604 bss
->upnp_iface
= os_strdup(pos
);
2605 } else if (os_strcmp(buf
, "friendly_name") == 0) {
2606 os_free(bss
->friendly_name
);
2607 bss
->friendly_name
= os_strdup(pos
);
2608 } else if (os_strcmp(buf
, "manufacturer_url") == 0) {
2609 os_free(bss
->manufacturer_url
);
2610 bss
->manufacturer_url
= os_strdup(pos
);
2611 } else if (os_strcmp(buf
, "model_description") == 0) {
2612 os_free(bss
->model_description
);
2613 bss
->model_description
= os_strdup(pos
);
2614 } else if (os_strcmp(buf
, "model_url") == 0) {
2615 os_free(bss
->model_url
);
2616 bss
->model_url
= os_strdup(pos
);
2617 } else if (os_strcmp(buf
, "upc") == 0) {
2619 bss
->upc
= os_strdup(pos
);
2620 } else if (os_strcmp(buf
, "pbc_in_m1") == 0) {
2621 bss
->pbc_in_m1
= atoi(pos
);
2622 #ifdef CONFIG_WPS_NFC
2623 } else if (os_strcmp(buf
, "wps_nfc_dev_pw_id") == 0) {
2624 bss
->wps_nfc_dev_pw_id
= atoi(pos
);
2625 if (bss
->wps_nfc_dev_pw_id
< 0x10 ||
2626 bss
->wps_nfc_dev_pw_id
> 0xffff) {
2627 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
2628 "wps_nfc_dev_pw_id value", line
);
2631 bss
->wps_nfc_pw_from_config
= 1;
2632 } else if (os_strcmp(buf
, "wps_nfc_dh_pubkey") == 0) {
2633 wpabuf_free(bss
->wps_nfc_dh_pubkey
);
2634 bss
->wps_nfc_dh_pubkey
= hostapd_parse_bin(pos
);
2635 bss
->wps_nfc_pw_from_config
= 1;
2636 } else if (os_strcmp(buf
, "wps_nfc_dh_privkey") == 0) {
2637 wpabuf_free(bss
->wps_nfc_dh_privkey
);
2638 bss
->wps_nfc_dh_privkey
= hostapd_parse_bin(pos
);
2639 bss
->wps_nfc_pw_from_config
= 1;
2640 } else if (os_strcmp(buf
, "wps_nfc_dev_pw") == 0) {
2641 wpabuf_free(bss
->wps_nfc_dev_pw
);
2642 bss
->wps_nfc_dev_pw
= hostapd_parse_bin(pos
);
2643 bss
->wps_nfc_pw_from_config
= 1;
2644 #endif /* CONFIG_WPS_NFC */
2645 #endif /* CONFIG_WPS */
2646 #ifdef CONFIG_P2P_MANAGER
2647 } else if (os_strcmp(buf
, "manage_p2p") == 0) {
2648 int manage
= atoi(pos
);
2650 bss
->p2p
|= P2P_MANAGE
;
2652 bss
->p2p
&= ~P2P_MANAGE
;
2653 } else if (os_strcmp(buf
, "allow_cross_connection") == 0) {
2655 bss
->p2p
|= P2P_ALLOW_CROSS_CONNECTION
;
2657 bss
->p2p
&= ~P2P_ALLOW_CROSS_CONNECTION
;
2658 #endif /* CONFIG_P2P_MANAGER */
2659 } else if (os_strcmp(buf
, "disassoc_low_ack") == 0) {
2660 bss
->disassoc_low_ack
= atoi(pos
);
2661 } else if (os_strcmp(buf
, "tdls_prohibit") == 0) {
2662 int val
= atoi(pos
);
2664 bss
->tdls
|= TDLS_PROHIBIT
;
2666 bss
->tdls
&= ~TDLS_PROHIBIT
;
2667 } else if (os_strcmp(buf
, "tdls_prohibit_chan_switch") == 0) {
2668 int val
= atoi(pos
);
2670 bss
->tdls
|= TDLS_PROHIBIT_CHAN_SWITCH
;
2672 bss
->tdls
&= ~TDLS_PROHIBIT_CHAN_SWITCH
;
2673 #ifdef CONFIG_RSN_TESTING
2674 } else if (os_strcmp(buf
, "rsn_testing") == 0) {
2675 extern int rsn_testing
;
2676 rsn_testing
= atoi(pos
);
2677 #endif /* CONFIG_RSN_TESTING */
2678 } else if (os_strcmp(buf
, "time_advertisement") == 0) {
2679 bss
->time_advertisement
= atoi(pos
);
2680 } else if (os_strcmp(buf
, "time_zone") == 0) {
2681 size_t tz_len
= os_strlen(pos
);
2682 if (tz_len
< 4 || tz_len
> 255) {
2683 wpa_printf(MSG_DEBUG
, "Line %d: invalid "
2688 os_free(bss
->time_zone
);
2689 bss
->time_zone
= os_strdup(pos
);
2690 if (bss
->time_zone
== NULL
)
2693 } else if (os_strcmp(buf
, "wnm_sleep_mode") == 0) {
2694 bss
->wnm_sleep_mode
= atoi(pos
);
2695 } else if (os_strcmp(buf
, "bss_transition") == 0) {
2696 bss
->bss_transition
= atoi(pos
);
2697 #endif /* CONFIG_WNM */
2698 #ifdef CONFIG_INTERWORKING
2699 } else if (os_strcmp(buf
, "interworking") == 0) {
2700 bss
->interworking
= atoi(pos
);
2701 } else if (os_strcmp(buf
, "access_network_type") == 0) {
2702 bss
->access_network_type
= atoi(pos
);
2703 if (bss
->access_network_type
< 0 ||
2704 bss
->access_network_type
> 15) {
2705 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2706 "access_network_type", line
);
2709 } else if (os_strcmp(buf
, "internet") == 0) {
2710 bss
->internet
= atoi(pos
);
2711 } else if (os_strcmp(buf
, "asra") == 0) {
2712 bss
->asra
= atoi(pos
);
2713 } else if (os_strcmp(buf
, "esr") == 0) {
2714 bss
->esr
= atoi(pos
);
2715 } else if (os_strcmp(buf
, "uesa") == 0) {
2716 bss
->uesa
= atoi(pos
);
2717 } else if (os_strcmp(buf
, "venue_group") == 0) {
2718 bss
->venue_group
= atoi(pos
);
2719 bss
->venue_info_set
= 1;
2720 } else if (os_strcmp(buf
, "venue_type") == 0) {
2721 bss
->venue_type
= atoi(pos
);
2722 bss
->venue_info_set
= 1;
2723 } else if (os_strcmp(buf
, "hessid") == 0) {
2724 if (hwaddr_aton(pos
, bss
->hessid
)) {
2725 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2729 } else if (os_strcmp(buf
, "roaming_consortium") == 0) {
2730 if (parse_roaming_consortium(bss
, pos
, line
) < 0)
2732 } else if (os_strcmp(buf
, "venue_name") == 0) {
2733 if (parse_venue_name(bss
, pos
, line
) < 0)
2735 } else if (os_strcmp(buf
, "network_auth_type") == 0) {
2737 u16 redirect_url_len
;
2738 if (hexstr2bin(pos
, &auth_type
, 1)) {
2739 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
2740 "network_auth_type '%s'",
2745 if (auth_type
== 0 || auth_type
== 2)
2746 redirect_url_len
= os_strlen(pos
+ 2);
2748 redirect_url_len
= 0;
2749 os_free(bss
->network_auth_type
);
2750 bss
->network_auth_type
=
2751 os_malloc(redirect_url_len
+ 3 + 1);
2752 if (bss
->network_auth_type
== NULL
) {
2756 *bss
->network_auth_type
= auth_type
;
2757 WPA_PUT_LE16(bss
->network_auth_type
+ 1,
2759 if (redirect_url_len
)
2760 os_memcpy(bss
->network_auth_type
+ 3,
2761 pos
+ 2, redirect_url_len
);
2762 bss
->network_auth_type_len
= 3 + redirect_url_len
;
2763 } else if (os_strcmp(buf
, "ipaddr_type_availability") == 0) {
2764 if (hexstr2bin(pos
, &bss
->ipaddr_type_availability
, 1))
2766 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
2767 "ipaddr_type_availability '%s'",
2769 bss
->ipaddr_type_configured
= 0;
2773 bss
->ipaddr_type_configured
= 1;
2774 } else if (os_strcmp(buf
, "domain_name") == 0) {
2775 int j
, num_domains
, domain_len
, domain_list_len
= 0;
2776 char *tok_start
, *tok_prev
;
2777 u8
*domain_list
, *domain_ptr
;
2779 domain_list_len
= os_strlen(pos
) + 1;
2780 domain_list
= os_malloc(domain_list_len
);
2781 if (domain_list
== NULL
) {
2786 domain_ptr
= domain_list
;
2789 while ((tok_prev
= os_strchr(tok_prev
, ','))) {
2794 for (j
= 0; j
< num_domains
; j
++) {
2795 tok_start
= os_strchr(tok_prev
, ',');
2797 domain_len
= tok_start
- tok_prev
;
2798 *domain_ptr
= domain_len
;
2799 os_memcpy(domain_ptr
+ 1, tok_prev
,
2801 domain_ptr
+= domain_len
+ 1;
2802 tok_prev
= ++tok_start
;
2804 domain_len
= os_strlen(tok_prev
);
2805 *domain_ptr
= domain_len
;
2806 os_memcpy(domain_ptr
+ 1, tok_prev
,
2808 domain_ptr
+= domain_len
+ 1;
2812 os_free(bss
->domain_name
);
2813 bss
->domain_name
= domain_list
;
2814 bss
->domain_name_len
= domain_list_len
;
2815 } else if (os_strcmp(buf
, "anqp_3gpp_cell_net") == 0) {
2816 if (parse_3gpp_cell_net(bss
, pos
, line
) < 0)
2818 } else if (os_strcmp(buf
, "nai_realm") == 0) {
2819 if (parse_nai_realm(bss
, pos
, line
) < 0)
2821 } else if (os_strcmp(buf
, "gas_frag_limit") == 0) {
2822 bss
->gas_frag_limit
= atoi(pos
);
2823 } else if (os_strcmp(buf
, "gas_comeback_delay") == 0) {
2824 bss
->gas_comeback_delay
= atoi(pos
);
2825 #endif /* CONFIG_INTERWORKING */
2826 #ifdef CONFIG_RADIUS_TEST
2827 } else if (os_strcmp(buf
, "dump_msk_file") == 0) {
2828 os_free(bss
->dump_msk_file
);
2829 bss
->dump_msk_file
= os_strdup(pos
);
2830 #endif /* CONFIG_RADIUS_TEST */
2832 } else if (os_strcmp(buf
, "hs20") == 0) {
2833 bss
->hs20
= atoi(pos
);
2834 } else if (os_strcmp(buf
, "disable_dgaf") == 0) {
2835 bss
->disable_dgaf
= atoi(pos
);
2836 } else if (os_strcmp(buf
, "hs20_oper_friendly_name") == 0) {
2837 if (hs20_parse_oper_friendly_name(bss
, pos
, line
) < 0)
2839 } else if (os_strcmp(buf
, "hs20_wan_metrics") == 0) {
2840 if (hs20_parse_wan_metrics(bss
, pos
, line
) < 0) {
2844 } else if (os_strcmp(buf
, "hs20_conn_capab") == 0) {
2845 if (hs20_parse_conn_capab(bss
, pos
, line
) < 0) {
2849 } else if (os_strcmp(buf
, "hs20_operating_class") == 0) {
2851 size_t oper_class_len
;
2852 oper_class_len
= os_strlen(pos
);
2853 if (oper_class_len
< 2 || (oper_class_len
& 0x01)) {
2854 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
2855 "hs20_operating_class '%s'",
2860 oper_class_len
/= 2;
2861 oper_class
= os_malloc(oper_class_len
);
2862 if (oper_class
== NULL
) {
2866 if (hexstr2bin(pos
, oper_class
, oper_class_len
)) {
2867 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
2868 "hs20_operating_class '%s'",
2870 os_free(oper_class
);
2874 os_free(bss
->hs20_operating_class
);
2875 bss
->hs20_operating_class
= oper_class
;
2876 bss
->hs20_operating_class_len
= oper_class_len
;
2877 #endif /* CONFIG_HS20 */
2878 #ifdef CONFIG_TESTING_OPTIONS
2879 #define PARSE_TEST_PROBABILITY(_val) \
2880 } else if (os_strcmp(buf, #_val) == 0) { \
2883 conf->_val = strtod(pos, &end); \
2884 if (*end || conf->_val < 0.0d || \
2885 conf->_val > 1.0d) { \
2886 wpa_printf(MSG_ERROR, \
2887 "Line %d: Invalid value '%s'", \
2892 PARSE_TEST_PROBABILITY(ignore_probe_probability
)
2893 PARSE_TEST_PROBABILITY(ignore_auth_probability
)
2894 PARSE_TEST_PROBABILITY(ignore_assoc_probability
)
2895 PARSE_TEST_PROBABILITY(ignore_reassoc_probability
)
2896 PARSE_TEST_PROBABILITY(corrupt_gtk_rekey_mic_probability
)
2897 #endif /* CONFIG_TESTING_OPTIONS */
2898 } else if (os_strcmp(buf
, "vendor_elements") == 0) {
2899 struct wpabuf
*elems
;
2900 size_t len
= os_strlen(pos
);
2902 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
2903 "vendor_elements '%s'", line
, pos
);
2908 wpabuf_free(bss
->vendor_elements
);
2909 bss
->vendor_elements
= NULL
;
2913 elems
= wpabuf_alloc(len
);
2917 if (hexstr2bin(pos
, wpabuf_put(elems
, len
), len
)) {
2919 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
2920 "vendor_elements '%s'", line
, pos
);
2924 wpabuf_free(bss
->vendor_elements
);
2925 bss
->vendor_elements
= elems
;
2926 } else if (os_strcmp(buf
, "sae_anti_clogging_threshold") == 0) {
2927 bss
->sae_anti_clogging_threshold
= atoi(pos
);
2928 } else if (os_strcmp(buf
, "sae_groups") == 0) {
2929 if (hostapd_parse_rates(&bss
->sae_groups
, pos
)) {
2930 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
2931 "sae_groups value '%s'", line
, pos
);
2935 wpa_printf(MSG_ERROR
, "Line %d: unknown configuration "
2936 "item '%s'", line
, buf
);
2945 static void hostapd_set_security_params(struct hostapd_bss_config
*bss
)
2947 if (bss
->individual_wep_key_len
== 0) {
2948 /* individual keys are not use; can use key idx0 for
2950 bss
->broadcast_key_idx_min
= 0;
2953 if ((bss
->wpa
& 2) && bss
->rsn_pairwise
== 0)
2954 bss
->rsn_pairwise
= bss
->wpa_pairwise
;
2955 bss
->wpa_group
= wpa_select_ap_group_cipher(bss
->wpa
, bss
->wpa_pairwise
,
2958 bss
->radius
->auth_server
= bss
->radius
->auth_servers
;
2959 bss
->radius
->acct_server
= bss
->radius
->acct_servers
;
2961 if (bss
->wpa
&& bss
->ieee802_1x
) {
2962 bss
->ssid
.security_policy
= SECURITY_WPA
;
2963 } else if (bss
->wpa
) {
2964 bss
->ssid
.security_policy
= SECURITY_WPA_PSK
;
2965 } else if (bss
->ieee802_1x
) {
2966 int cipher
= WPA_CIPHER_NONE
;
2967 bss
->ssid
.security_policy
= SECURITY_IEEE_802_1X
;
2968 bss
->ssid
.wep
.default_len
= bss
->default_wep_key_len
;
2969 if (bss
->default_wep_key_len
)
2970 cipher
= bss
->default_wep_key_len
>= 13 ?
2971 WPA_CIPHER_WEP104
: WPA_CIPHER_WEP40
;
2972 bss
->wpa_group
= cipher
;
2973 bss
->wpa_pairwise
= cipher
;
2974 bss
->rsn_pairwise
= cipher
;
2975 } else if (bss
->ssid
.wep
.keys_set
) {
2976 int cipher
= WPA_CIPHER_WEP40
;
2977 if (bss
->ssid
.wep
.len
[0] >= 13)
2978 cipher
= WPA_CIPHER_WEP104
;
2979 bss
->ssid
.security_policy
= SECURITY_STATIC_WEP
;
2980 bss
->wpa_group
= cipher
;
2981 bss
->wpa_pairwise
= cipher
;
2982 bss
->rsn_pairwise
= cipher
;
2984 bss
->ssid
.security_policy
= SECURITY_PLAINTEXT
;
2985 bss
->wpa_group
= WPA_CIPHER_NONE
;
2986 bss
->wpa_pairwise
= WPA_CIPHER_NONE
;
2987 bss
->rsn_pairwise
= WPA_CIPHER_NONE
;
2993 * hostapd_config_read - Read and parse a configuration file
2994 * @fname: Configuration file name (including path, if needed)
2995 * Returns: Allocated configuration data structure
2997 struct hostapd_config
* hostapd_config_read(const char *fname
)
2999 struct hostapd_config
*conf
;
3000 struct hostapd_bss_config
*bss
;
3002 char buf
[512], *pos
;
3007 f
= fopen(fname
, "r");
3009 wpa_printf(MSG_ERROR
, "Could not open configuration file '%s' "
3010 "for reading.", fname
);
3014 conf
= hostapd_config_defaults();
3020 /* set default driver based on configuration */
3021 conf
->driver
= wpa_drivers
[0];
3022 if (conf
->driver
== NULL
) {
3023 wpa_printf(MSG_ERROR
, "No driver wrappers registered!");
3024 hostapd_config_free(conf
);
3029 bss
= conf
->last_bss
= conf
->bss
;
3031 while (fgets(buf
, sizeof(buf
), f
)) {
3032 bss
= conf
->last_bss
;
3038 while (*pos
!= '\0') {
3048 pos
= os_strchr(buf
, '=');
3050 wpa_printf(MSG_ERROR
, "Line %d: invalid line '%s'",
3057 errors
+= hostapd_config_fill(conf
, bss
, buf
, pos
, line
);
3062 for (i
= 0; i
< conf
->num_bss
; i
++)
3063 hostapd_set_security_params(&conf
->bss
[i
]);
3065 if (hostapd_config_check(conf
))
3068 #ifndef WPA_IGNORE_CONFIG_ERRORS
3070 wpa_printf(MSG_ERROR
, "%d errors found in configuration file "
3071 "'%s'", errors
, fname
);
3072 hostapd_config_free(conf
);
3075 #endif /* WPA_IGNORE_CONFIG_ERRORS */
3081 int hostapd_set_iface(struct hostapd_config
*conf
,
3082 struct hostapd_bss_config
*bss
, char *field
, char *value
)
3087 errors
= hostapd_config_fill(conf
, bss
, field
, value
, 0);
3089 wpa_printf(MSG_INFO
, "Failed to set configuration field '%s' "
3090 "to value '%s'", field
, value
);
3094 for (i
= 0; i
< conf
->num_bss
; i
++)
3095 hostapd_set_security_params(&conf
->bss
[i
]);
3097 if (hostapd_config_check(conf
)) {
3098 wpa_printf(MSG_ERROR
, "Configuration check failed");