2 * hostapd / Configuration file parser
3 * Copyright (c) 2003-2012, 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_malloc(sizeof(*vlan
));
88 wpa_printf(MSG_ERROR
, "Out of memory while reading "
89 "VLAN interfaces from '%s'", fname
);
94 os_memset(vlan
, 0, sizeof(*vlan
));
95 vlan
->vlan_id
= vlan_id
;
96 os_strlcpy(vlan
->ifname
, pos
, sizeof(vlan
->ifname
));
98 bss
->vlan_tail
->next
= vlan
;
101 bss
->vlan_tail
= vlan
;
108 #endif /* CONFIG_NO_VLAN */
111 static int hostapd_acl_comp(const void *a
, const void *b
)
113 const struct mac_acl_entry
*aa
= a
;
114 const struct mac_acl_entry
*bb
= b
;
115 return os_memcmp(aa
->addr
, bb
->addr
, sizeof(macaddr
));
119 static int hostapd_config_read_maclist(const char *fname
,
120 struct mac_acl_entry
**acl
, int *num
)
126 struct mac_acl_entry
*newacl
;
132 f
= fopen(fname
, "r");
134 wpa_printf(MSG_ERROR
, "MAC list file '%s' not found.", fname
);
138 while (fgets(buf
, sizeof(buf
), f
)) {
144 while (*pos
!= '\0') {
154 if (hwaddr_aton(buf
, addr
)) {
155 wpa_printf(MSG_ERROR
, "Invalid MAC address '%s' at "
156 "line %d in '%s'", buf
, line
, fname
);
163 while (*pos
!= '\0' && *pos
!= ' ' && *pos
!= '\t')
165 while (*pos
== ' ' || *pos
== '\t')
170 newacl
= os_realloc(*acl
, (*num
+ 1) * sizeof(**acl
));
171 if (newacl
== NULL
) {
172 wpa_printf(MSG_ERROR
, "MAC list reallocation failed");
178 os_memcpy((*acl
)[*num
].addr
, addr
, ETH_ALEN
);
179 (*acl
)[*num
].vlan_id
= vlan_id
;
185 qsort(*acl
, *num
, sizeof(**acl
), hostapd_acl_comp
);
192 static int hostapd_config_read_eap_user(const char *fname
,
193 struct hostapd_bss_config
*conf
)
196 char buf
[512], *pos
, *start
, *pos2
;
197 int line
= 0, ret
= 0, num_methods
;
198 struct hostapd_eap_user
*user
, *tail
= NULL
;
203 f
= fopen(fname
, "r");
205 wpa_printf(MSG_ERROR
, "EAP user file '%s' not found.", fname
);
209 /* Lines: "user" METHOD,METHOD2 "password" (password optional) */
210 while (fgets(buf
, sizeof(buf
), f
)) {
216 while (*pos
!= '\0') {
228 if (buf
[0] != '"' && buf
[0] != '*') {
229 wpa_printf(MSG_ERROR
, "Invalid EAP identity (no \" in "
230 "start) on line %d in '%s'", line
, fname
);
234 user
= os_zalloc(sizeof(*user
));
236 wpa_printf(MSG_ERROR
, "EAP user allocation failed");
239 user
->force_version
= -1;
246 while (*pos
!= '"' && *pos
!= '\0')
249 wpa_printf(MSG_ERROR
, "Invalid EAP identity "
250 "(no \" in end) on line %d in '%s'",
255 user
->identity
= os_malloc(pos
- start
);
256 if (user
->identity
== NULL
) {
257 wpa_printf(MSG_ERROR
, "Failed to allocate "
258 "memory for EAP identity");
261 os_memcpy(user
->identity
, start
, pos
- start
);
262 user
->identity_len
= pos
- start
;
264 if (pos
[0] == '"' && pos
[1] == '*') {
265 user
->wildcard_prefix
= 1;
270 while (*pos
== ' ' || *pos
== '\t')
274 wpa_printf(MSG_ERROR
, "No EAP method on line %d in "
275 "'%s'", line
, fname
);
280 while (*pos
!= ' ' && *pos
!= '\t' && *pos
!= '\0')
290 char *pos3
= os_strchr(start
, ',');
294 user
->methods
[num_methods
].method
=
297 &user
->methods
[num_methods
].vendor
);
298 if (user
->methods
[num_methods
].vendor
==
300 user
->methods
[num_methods
].method
== EAP_TYPE_NONE
)
302 if (os_strcmp(start
, "TTLS-PAP") == 0) {
303 user
->ttls_auth
|= EAP_TTLS_AUTH_PAP
;
306 if (os_strcmp(start
, "TTLS-CHAP") == 0) {
307 user
->ttls_auth
|= EAP_TTLS_AUTH_CHAP
;
310 if (os_strcmp(start
, "TTLS-MSCHAP") == 0) {
312 EAP_TTLS_AUTH_MSCHAP
;
315 if (os_strcmp(start
, "TTLS-MSCHAPV2") == 0) {
317 EAP_TTLS_AUTH_MSCHAPV2
;
320 wpa_printf(MSG_ERROR
, "Unsupported EAP type "
321 "'%s' on line %d in '%s'",
327 if (num_methods
>= EAP_MAX_METHODS
)
334 if (num_methods
== 0 && user
->ttls_auth
== 0) {
335 wpa_printf(MSG_ERROR
, "No EAP types configured on "
336 "line %d in '%s'", line
, fname
);
343 while (*pos
== ' ' || *pos
== '\t')
348 if (os_strncmp(pos
, "[ver=0]", 7) == 0) {
349 user
->force_version
= 0;
353 if (os_strncmp(pos
, "[ver=1]", 7) == 0) {
354 user
->force_version
= 1;
358 if (os_strncmp(pos
, "[2]", 3) == 0) {
366 while (*pos
!= '"' && *pos
!= '\0')
369 wpa_printf(MSG_ERROR
, "Invalid EAP password "
370 "(no \" in end) on line %d in '%s'",
375 user
->password
= os_malloc(pos
- start
);
376 if (user
->password
== NULL
) {
377 wpa_printf(MSG_ERROR
, "Failed to allocate "
378 "memory for EAP password");
381 os_memcpy(user
->password
, start
, pos
- start
);
382 user
->password_len
= pos
- start
;
385 } else if (os_strncmp(pos
, "hash:", 5) == 0) {
388 while (*pos2
!= '\0' && *pos2
!= ' ' &&
389 *pos2
!= '\t' && *pos2
!= '#')
391 if (pos2
- pos
!= 32) {
392 wpa_printf(MSG_ERROR
, "Invalid password hash "
393 "on line %d in '%s'", line
, fname
);
396 user
->password
= os_malloc(16);
397 if (user
->password
== NULL
) {
398 wpa_printf(MSG_ERROR
, "Failed to allocate "
399 "memory for EAP password hash");
402 if (hexstr2bin(pos
, user
->password
, 16) < 0) {
403 wpa_printf(MSG_ERROR
, "Invalid hash password "
404 "on line %d in '%s'", line
, fname
);
407 user
->password_len
= 16;
408 user
->password_hash
= 1;
412 while (*pos2
!= '\0' && *pos2
!= ' ' &&
413 *pos2
!= '\t' && *pos2
!= '#')
415 if ((pos2
- pos
) & 1) {
416 wpa_printf(MSG_ERROR
, "Invalid hex password "
417 "on line %d in '%s'", line
, fname
);
420 user
->password
= os_malloc((pos2
- pos
) / 2);
421 if (user
->password
== NULL
) {
422 wpa_printf(MSG_ERROR
, "Failed to allocate "
423 "memory for EAP password");
426 if (hexstr2bin(pos
, user
->password
,
427 (pos2
- pos
) / 2) < 0) {
428 wpa_printf(MSG_ERROR
, "Invalid hex password "
429 "on line %d in '%s'", line
, fname
);
432 user
->password_len
= (pos2
- pos
) / 2;
436 while (*pos
== ' ' || *pos
== '\t')
438 if (os_strncmp(pos
, "[2]", 3) == 0) {
444 tail
= conf
->eap_user
= user
;
453 os_free(user
->password
);
454 os_free(user
->identity
);
465 #endif /* EAP_SERVER */
468 #ifndef CONFIG_NO_RADIUS
470 hostapd_config_read_radius_addr(struct hostapd_radius_server
**server
,
471 int *num_server
, const char *val
, int def_port
,
472 struct hostapd_radius_server
**curr_serv
)
474 struct hostapd_radius_server
*nserv
;
476 static int server_index
= 1;
478 nserv
= os_realloc(*server
, (*num_server
+ 1) * sizeof(*nserv
));
483 nserv
= &nserv
[*num_server
];
485 (*curr_serv
) = nserv
;
487 os_memset(nserv
, 0, sizeof(*nserv
));
488 nserv
->port
= def_port
;
489 ret
= hostapd_parse_ip_addr(val
, &nserv
->addr
);
490 nserv
->index
= server_index
++;
496 static struct hostapd_radius_attr
*
497 hostapd_parse_radius_attr(const char *value
)
501 struct hostapd_radius_attr
*attr
;
504 attr
= os_zalloc(sizeof(*attr
));
508 attr
->type
= atoi(value
);
510 pos
= os_strchr(value
, ':');
512 attr
->val
= wpabuf_alloc(1);
513 if (attr
->val
== NULL
) {
517 wpabuf_put_u8(attr
->val
, 0);
522 if (pos
[0] == '\0' || pos
[1] != ':') {
531 attr
->val
= wpabuf_alloc_copy(pos
, os_strlen(pos
));
534 len
= os_strlen(pos
);
538 attr
->val
= wpabuf_alloc(len
);
539 if (attr
->val
== NULL
)
541 if (hexstr2bin(pos
, wpabuf_put(attr
->val
, len
), len
) < 0) {
542 wpabuf_free(attr
->val
);
548 attr
->val
= wpabuf_alloc(4);
550 wpabuf_put_be32(attr
->val
, atoi(pos
));
557 if (attr
->val
== NULL
) {
566 static int hostapd_parse_das_client(struct hostapd_bss_config
*bss
,
572 secret
= os_strchr(val
, ' ');
577 len
= os_strlen(secret
);
579 if (hostapd_parse_ip_addr(val
, &bss
->radius_das_client_addr
))
582 os_free(bss
->radius_das_shared_secret
);
583 bss
->radius_das_shared_secret
= os_malloc(len
);
584 if (bss
->radius_das_shared_secret
== NULL
)
587 os_memcpy(bss
->radius_das_shared_secret
, secret
, len
);
588 bss
->radius_das_shared_secret_len
= len
;
592 #endif /* CONFIG_NO_RADIUS */
595 static int hostapd_config_parse_key_mgmt(int line
, const char *value
)
598 char *start
, *end
, *buf
;
600 buf
= os_strdup(value
);
605 while (*start
!= '\0') {
606 while (*start
== ' ' || *start
== '\t')
611 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
615 if (os_strcmp(start
, "WPA-PSK") == 0)
616 val
|= WPA_KEY_MGMT_PSK
;
617 else if (os_strcmp(start
, "WPA-EAP") == 0)
618 val
|= WPA_KEY_MGMT_IEEE8021X
;
619 #ifdef CONFIG_IEEE80211R
620 else if (os_strcmp(start
, "FT-PSK") == 0)
621 val
|= WPA_KEY_MGMT_FT_PSK
;
622 else if (os_strcmp(start
, "FT-EAP") == 0)
623 val
|= WPA_KEY_MGMT_FT_IEEE8021X
;
624 #endif /* CONFIG_IEEE80211R */
625 #ifdef CONFIG_IEEE80211W
626 else if (os_strcmp(start
, "WPA-PSK-SHA256") == 0)
627 val
|= WPA_KEY_MGMT_PSK_SHA256
;
628 else if (os_strcmp(start
, "WPA-EAP-SHA256") == 0)
629 val
|= WPA_KEY_MGMT_IEEE8021X_SHA256
;
630 #endif /* CONFIG_IEEE80211W */
632 wpa_printf(MSG_ERROR
, "Line %d: invalid key_mgmt '%s'",
645 wpa_printf(MSG_ERROR
, "Line %d: no key_mgmt values "
646 "configured.", line
);
654 static int hostapd_config_parse_cipher(int line
, const char *value
)
657 char *start
, *end
, *buf
;
659 buf
= os_strdup(value
);
664 while (*start
!= '\0') {
665 while (*start
== ' ' || *start
== '\t')
670 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
674 if (os_strcmp(start
, "CCMP") == 0)
675 val
|= WPA_CIPHER_CCMP
;
676 else if (os_strcmp(start
, "TKIP") == 0)
677 val
|= WPA_CIPHER_TKIP
;
678 else if (os_strcmp(start
, "WEP104") == 0)
679 val
|= WPA_CIPHER_WEP104
;
680 else if (os_strcmp(start
, "WEP40") == 0)
681 val
|= WPA_CIPHER_WEP40
;
682 else if (os_strcmp(start
, "NONE") == 0)
683 val
|= WPA_CIPHER_NONE
;
685 wpa_printf(MSG_ERROR
, "Line %d: invalid cipher '%s'.",
698 wpa_printf(MSG_ERROR
, "Line %d: no cipher values configured.",
706 static int hostapd_config_read_wep(struct hostapd_wep_keys
*wep
, int keyidx
,
709 size_t len
= os_strlen(val
);
711 if (keyidx
< 0 || keyidx
> 3 || wep
->key
[keyidx
] != NULL
)
715 if (len
< 2 || val
[len
- 1] != '"')
718 wep
->key
[keyidx
] = os_malloc(len
);
719 if (wep
->key
[keyidx
] == NULL
)
721 os_memcpy(wep
->key
[keyidx
], val
+ 1, len
);
722 wep
->len
[keyidx
] = len
;
727 wep
->key
[keyidx
] = os_malloc(len
);
728 if (wep
->key
[keyidx
] == NULL
)
730 wep
->len
[keyidx
] = len
;
731 if (hexstr2bin(val
, wep
->key
[keyidx
], len
) < 0)
741 static int hostapd_parse_rates(int **rate_list
, char *val
)
752 while (*pos
!= '\0') {
758 list
= os_malloc(sizeof(int) * (count
+ 2));
763 while (*pos
!= '\0') {
764 end
= os_strchr(pos
, ' ');
768 list
[count
++] = atoi(pos
);
780 static int hostapd_config_bss(struct hostapd_config
*conf
, const char *ifname
)
782 struct hostapd_bss_config
*bss
;
787 bss
= os_realloc(conf
->bss
, (conf
->num_bss
+ 1) *
788 sizeof(struct hostapd_bss_config
));
790 wpa_printf(MSG_ERROR
, "Failed to allocate memory for "
796 bss
= &(conf
->bss
[conf
->num_bss
]);
797 os_memset(bss
, 0, sizeof(*bss
));
798 bss
->radius
= os_zalloc(sizeof(*bss
->radius
));
799 if (bss
->radius
== NULL
) {
800 wpa_printf(MSG_ERROR
, "Failed to allocate memory for "
801 "multi-BSS RADIUS data");
806 conf
->last_bss
= bss
;
808 hostapd_config_defaults_bss(bss
);
809 os_strlcpy(bss
->iface
, ifname
, sizeof(bss
->iface
));
810 os_memcpy(bss
->ssid
.vlan
, bss
->iface
, IFNAMSIZ
+ 1);
816 /* convert floats with one decimal place to value*10 int, i.e.,
817 * "1.5" will return 15 */
818 static int hostapd_config_read_int10(const char *value
)
824 pos
= os_strchr(value
, '.');
828 if (*pos
>= '0' && *pos
<= '9')
836 static int valid_cw(int cw
)
838 return (cw
== 1 || cw
== 3 || cw
== 7 || cw
== 15 || cw
== 31 ||
839 cw
== 63 || cw
== 127 || cw
== 255 || cw
== 511 || cw
== 1023);
844 IEEE80211_TX_QUEUE_DATA0
= 0, /* used for EDCA AC_VO data */
845 IEEE80211_TX_QUEUE_DATA1
= 1, /* used for EDCA AC_VI data */
846 IEEE80211_TX_QUEUE_DATA2
= 2, /* used for EDCA AC_BE data */
847 IEEE80211_TX_QUEUE_DATA3
= 3 /* used for EDCA AC_BK data */
850 static int hostapd_config_tx_queue(struct hostapd_config
*conf
, char *name
,
855 struct hostapd_tx_queue_params
*queue
;
857 /* skip 'tx_queue_' prefix */
859 if (os_strncmp(pos
, "data", 4) == 0 &&
860 pos
[4] >= '0' && pos
[4] <= '9' && pos
[5] == '_') {
863 } else if (os_strncmp(pos
, "after_beacon_", 13) == 0 ||
864 os_strncmp(pos
, "beacon_", 7) == 0) {
865 wpa_printf(MSG_INFO
, "DEPRECATED: '%s' not used", name
);
868 wpa_printf(MSG_ERROR
, "Unknown tx_queue name '%s'", pos
);
872 if (num
>= NUM_TX_QUEUES
) {
873 /* for backwards compatibility, do not trigger failure */
874 wpa_printf(MSG_INFO
, "DEPRECATED: '%s' not used", name
);
878 queue
= &conf
->tx_queue
[num
];
880 if (os_strcmp(pos
, "aifs") == 0) {
881 queue
->aifs
= atoi(val
);
882 if (queue
->aifs
< 0 || queue
->aifs
> 255) {
883 wpa_printf(MSG_ERROR
, "Invalid AIFS value %d",
887 } else if (os_strcmp(pos
, "cwmin") == 0) {
888 queue
->cwmin
= atoi(val
);
889 if (!valid_cw(queue
->cwmin
)) {
890 wpa_printf(MSG_ERROR
, "Invalid cwMin value %d",
894 } else if (os_strcmp(pos
, "cwmax") == 0) {
895 queue
->cwmax
= atoi(val
);
896 if (!valid_cw(queue
->cwmax
)) {
897 wpa_printf(MSG_ERROR
, "Invalid cwMax value %d",
901 } else if (os_strcmp(pos
, "burst") == 0) {
902 queue
->burst
= hostapd_config_read_int10(val
);
904 wpa_printf(MSG_ERROR
, "Unknown tx_queue field '%s'", pos
);
912 static int hostapd_config_wmm_ac(struct hostapd_config
*conf
, char *name
,
917 struct hostapd_wmm_ac_params
*ac
;
919 /* skip 'wme_ac_' or 'wmm_ac_' prefix */
921 if (os_strncmp(pos
, "be_", 3) == 0) {
924 } else if (os_strncmp(pos
, "bk_", 3) == 0) {
927 } else if (os_strncmp(pos
, "vi_", 3) == 0) {
930 } else if (os_strncmp(pos
, "vo_", 3) == 0) {
934 wpa_printf(MSG_ERROR
, "Unknown WMM name '%s'", pos
);
938 ac
= &conf
->wmm_ac_params
[num
];
940 if (os_strcmp(pos
, "aifs") == 0) {
942 if (v
< 1 || v
> 255) {
943 wpa_printf(MSG_ERROR
, "Invalid AIFS value %d", v
);
947 } else if (os_strcmp(pos
, "cwmin") == 0) {
949 if (v
< 0 || v
> 12) {
950 wpa_printf(MSG_ERROR
, "Invalid cwMin value %d", v
);
954 } else if (os_strcmp(pos
, "cwmax") == 0) {
956 if (v
< 0 || v
> 12) {
957 wpa_printf(MSG_ERROR
, "Invalid cwMax value %d", v
);
961 } else if (os_strcmp(pos
, "txop_limit") == 0) {
963 if (v
< 0 || v
> 0xffff) {
964 wpa_printf(MSG_ERROR
, "Invalid txop value %d", v
);
968 } else if (os_strcmp(pos
, "acm") == 0) {
970 if (v
< 0 || v
> 1) {
971 wpa_printf(MSG_ERROR
, "Invalid acm value %d", v
);
974 ac
->admission_control_mandatory
= v
;
976 wpa_printf(MSG_ERROR
, "Unknown wmm_ac_ field '%s'", pos
);
984 #ifdef CONFIG_IEEE80211R
985 static int add_r0kh(struct hostapd_bss_config
*bss
, char *value
)
987 struct ft_remote_r0kh
*r0kh
;
990 r0kh
= os_zalloc(sizeof(*r0kh
));
994 /* 02:01:02:03:04:05 a.example.com 000102030405060708090a0b0c0d0e0f */
996 next
= os_strchr(pos
, ' ');
999 if (next
== NULL
|| hwaddr_aton(pos
, r0kh
->addr
)) {
1000 wpa_printf(MSG_ERROR
, "Invalid R0KH MAC address: '%s'", pos
);
1006 next
= os_strchr(pos
, ' ');
1009 if (next
== NULL
|| next
- pos
> FT_R0KH_ID_MAX_LEN
) {
1010 wpa_printf(MSG_ERROR
, "Invalid R0KH-ID: '%s'", pos
);
1014 r0kh
->id_len
= next
- pos
- 1;
1015 os_memcpy(r0kh
->id
, pos
, r0kh
->id_len
);
1018 if (hexstr2bin(pos
, r0kh
->key
, sizeof(r0kh
->key
))) {
1019 wpa_printf(MSG_ERROR
, "Invalid R0KH key: '%s'", pos
);
1024 r0kh
->next
= bss
->r0kh_list
;
1025 bss
->r0kh_list
= r0kh
;
1031 static int add_r1kh(struct hostapd_bss_config
*bss
, char *value
)
1033 struct ft_remote_r1kh
*r1kh
;
1036 r1kh
= os_zalloc(sizeof(*r1kh
));
1040 /* 02:01:02:03:04:05 02:01:02:03:04:05
1041 * 000102030405060708090a0b0c0d0e0f */
1043 next
= os_strchr(pos
, ' ');
1046 if (next
== NULL
|| hwaddr_aton(pos
, r1kh
->addr
)) {
1047 wpa_printf(MSG_ERROR
, "Invalid R1KH MAC address: '%s'", pos
);
1053 next
= os_strchr(pos
, ' ');
1056 if (next
== NULL
|| hwaddr_aton(pos
, r1kh
->id
)) {
1057 wpa_printf(MSG_ERROR
, "Invalid R1KH-ID: '%s'", pos
);
1063 if (hexstr2bin(pos
, r1kh
->key
, sizeof(r1kh
->key
))) {
1064 wpa_printf(MSG_ERROR
, "Invalid R1KH key: '%s'", pos
);
1069 r1kh
->next
= bss
->r1kh_list
;
1070 bss
->r1kh_list
= r1kh
;
1074 #endif /* CONFIG_IEEE80211R */
1077 #ifdef CONFIG_IEEE80211N
1078 static int hostapd_config_ht_capab(struct hostapd_config
*conf
,
1081 if (os_strstr(capab
, "[LDPC]"))
1082 conf
->ht_capab
|= HT_CAP_INFO_LDPC_CODING_CAP
;
1083 if (os_strstr(capab
, "[HT40-]")) {
1084 conf
->ht_capab
|= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
;
1085 conf
->secondary_channel
= -1;
1087 if (os_strstr(capab
, "[HT40+]")) {
1088 conf
->ht_capab
|= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
;
1089 conf
->secondary_channel
= 1;
1091 if (os_strstr(capab
, "[SMPS-STATIC]")) {
1092 conf
->ht_capab
&= ~HT_CAP_INFO_SMPS_MASK
;
1093 conf
->ht_capab
|= HT_CAP_INFO_SMPS_STATIC
;
1095 if (os_strstr(capab
, "[SMPS-DYNAMIC]")) {
1096 conf
->ht_capab
&= ~HT_CAP_INFO_SMPS_MASK
;
1097 conf
->ht_capab
|= HT_CAP_INFO_SMPS_DYNAMIC
;
1099 if (os_strstr(capab
, "[GF]"))
1100 conf
->ht_capab
|= HT_CAP_INFO_GREEN_FIELD
;
1101 if (os_strstr(capab
, "[SHORT-GI-20]"))
1102 conf
->ht_capab
|= HT_CAP_INFO_SHORT_GI20MHZ
;
1103 if (os_strstr(capab
, "[SHORT-GI-40]"))
1104 conf
->ht_capab
|= HT_CAP_INFO_SHORT_GI40MHZ
;
1105 if (os_strstr(capab
, "[TX-STBC]"))
1106 conf
->ht_capab
|= HT_CAP_INFO_TX_STBC
;
1107 if (os_strstr(capab
, "[RX-STBC1]")) {
1108 conf
->ht_capab
&= ~HT_CAP_INFO_RX_STBC_MASK
;
1109 conf
->ht_capab
|= HT_CAP_INFO_RX_STBC_1
;
1111 if (os_strstr(capab
, "[RX-STBC12]")) {
1112 conf
->ht_capab
&= ~HT_CAP_INFO_RX_STBC_MASK
;
1113 conf
->ht_capab
|= HT_CAP_INFO_RX_STBC_12
;
1115 if (os_strstr(capab
, "[RX-STBC123]")) {
1116 conf
->ht_capab
&= ~HT_CAP_INFO_RX_STBC_MASK
;
1117 conf
->ht_capab
|= HT_CAP_INFO_RX_STBC_123
;
1119 if (os_strstr(capab
, "[DELAYED-BA]"))
1120 conf
->ht_capab
|= HT_CAP_INFO_DELAYED_BA
;
1121 if (os_strstr(capab
, "[MAX-AMSDU-7935]"))
1122 conf
->ht_capab
|= HT_CAP_INFO_MAX_AMSDU_SIZE
;
1123 if (os_strstr(capab
, "[DSSS_CCK-40]"))
1124 conf
->ht_capab
|= HT_CAP_INFO_DSSS_CCK40MHZ
;
1125 if (os_strstr(capab
, "[PSMP]"))
1126 conf
->ht_capab
|= HT_CAP_INFO_PSMP_SUPP
;
1127 if (os_strstr(capab
, "[LSIG-TXOP-PROT]"))
1128 conf
->ht_capab
|= HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT
;
1132 #endif /* CONFIG_IEEE80211N */
1135 #ifdef CONFIG_IEEE80211AC
1136 static int hostapd_config_vht_capab(struct hostapd_config
*conf
,
1139 if (os_strstr(capab
, "[MAX-MPDU-7991]"))
1140 conf
->vht_capab
|= VHT_CAP_MAX_MPDU_LENGTH_7991
;
1141 if (os_strstr(capab
, "[MAX-MPDU-11454]"))
1142 conf
->vht_capab
|= VHT_CAP_MAX_MPDU_LENGTH_11454
;
1143 if (os_strstr(capab
, "[VHT160]"))
1144 conf
->vht_capab
|= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ
;
1145 if (os_strstr(capab
, "[VHT160-80PLUS80]"))
1146 conf
->vht_capab
|= VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ
;
1147 if (os_strstr(capab
, "[VHT160-80PLUS80]"))
1148 conf
->vht_capab
|= VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ
;
1149 if (os_strstr(capab
, "[RXLDPC]"))
1150 conf
->vht_capab
|= VHT_CAP_RXLDPC
;
1151 if (os_strstr(capab
, "[SHORT-GI-80]"))
1152 conf
->vht_capab
|= VHT_CAP_SHORT_GI_80
;
1153 if (os_strstr(capab
, "[SHORT-GI-160]"))
1154 conf
->vht_capab
|= VHT_CAP_SHORT_GI_160
;
1155 if (os_strstr(capab
, "[TX-STBC-2BY1]"))
1156 conf
->vht_capab
|= VHT_CAP_TXSTBC
;
1157 if (os_strstr(capab
, "[RX-STBC-1]"))
1158 conf
->vht_capab
|= VHT_CAP_RXSTBC_1
;
1159 if (os_strstr(capab
, "[RX-STBC-12]"))
1160 conf
->vht_capab
|= VHT_CAP_RXSTBC_2
;
1161 if (os_strstr(capab
, "[RX-STBC-123]"))
1162 conf
->vht_capab
|= VHT_CAP_RXSTBC_3
;
1163 if (os_strstr(capab
, "[RX-STBC-1234]"))
1164 conf
->vht_capab
|= VHT_CAP_RXSTBC_4
;
1165 if (os_strstr(capab
, "[SU-BEAMFORMER]"))
1166 conf
->vht_capab
|= VHT_CAP_MU_BEAMFORMER_CAPABLE
;
1167 if (os_strstr(capab
, "[SU-BEAMFORMEE]"))
1168 conf
->vht_capab
|= VHT_CAP_MU_BEAMFORMEE_CAPABLE
;
1169 if (os_strstr(capab
, "[BF-ANTENNA-2]") &&
1170 (conf
->vht_capab
& VHT_CAP_MU_BEAMFORMER_CAPABLE
))
1171 conf
->vht_capab
|= VHT_CAP_BEAMFORMER_ANTENNAS_MAX
;
1172 if (os_strstr(capab
, "[SOUNDING-DIMENSION-2]") &&
1173 (conf
->vht_capab
& VHT_CAP_MU_BEAMFORMER_CAPABLE
))
1174 conf
->vht_capab
|= VHT_CAP_SOUNDING_DIMENTION_MAX
;
1175 if (os_strstr(capab
, "[MU-BEAMFORMER]"))
1176 conf
->vht_capab
|= VHT_CAP_MU_BEAMFORMER_CAPABLE
;
1177 if (os_strstr(capab
, "[MU-BEAMFORMEE]"))
1178 conf
->vht_capab
|= VHT_CAP_MU_BEAMFORMEE_CAPABLE
;
1179 if (os_strstr(capab
, "[VHT-TXOP-PS]"))
1180 conf
->vht_capab
|= VHT_CAP_VHT_TXOP_PS
;
1181 if (os_strstr(capab
, "[HTC-VHT]"))
1182 conf
->vht_capab
|= VHT_CAP_HTC_VHT
;
1183 if (os_strstr(capab
, "[MAX-A-MPDU-LEN-EXP0]"))
1184 conf
->vht_capab
|= VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT
;
1185 if (os_strstr(capab
, "[VHT-LINK-ADAPT2]") &&
1186 (conf
->vht_capab
& VHT_CAP_HTC_VHT
))
1187 conf
->vht_capab
|= VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB
;
1188 if (os_strstr(capab
, "[VHT-LINK-ADAPT3]") &&
1189 (conf
->vht_capab
& VHT_CAP_HTC_VHT
))
1190 conf
->vht_capab
|= VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB
;
1191 if (os_strstr(capab
, "[RX-ANTENNA-PATTERN]"))
1192 conf
->vht_capab
|= VHT_CAP_RX_ANTENNA_PATTERN
;
1193 if (os_strstr(capab
, "[TX-ANTENNA-PATTERN]"))
1194 conf
->vht_capab
|= VHT_CAP_TX_ANTENNA_PATTERN
;
1197 #endif /* CONFIG_IEEE80211AC */
1200 static int hostapd_config_check_bss(struct hostapd_bss_config
*bss
,
1201 struct hostapd_config
*conf
)
1203 if (bss
->ieee802_1x
&& !bss
->eap_server
&&
1204 !bss
->radius
->auth_servers
) {
1205 wpa_printf(MSG_ERROR
, "Invalid IEEE 802.1X configuration (no "
1206 "EAP authenticator configured).");
1210 if (bss
->wpa
&& bss
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
&&
1211 bss
->macaddr_acl
!= USE_EXTERNAL_RADIUS_AUTH
) {
1212 wpa_printf(MSG_ERROR
, "WPA-PSK using RADIUS enabled, but no "
1213 "RADIUS checking (macaddr_acl=2) enabled.");
1217 if (bss
->wpa
&& (bss
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
) &&
1218 bss
->ssid
.wpa_psk
== NULL
&& bss
->ssid
.wpa_passphrase
== NULL
&&
1219 bss
->ssid
.wpa_psk_file
== NULL
&&
1220 (bss
->wpa_psk_radius
!= PSK_RADIUS_REQUIRED
||
1221 bss
->macaddr_acl
!= USE_EXTERNAL_RADIUS_AUTH
)) {
1222 wpa_printf(MSG_ERROR
, "WPA-PSK enabled, but PSK or passphrase "
1223 "is not configured.");
1227 if (hostapd_mac_comp_empty(bss
->bssid
) != 0) {
1230 for (i
= 0; i
< conf
->num_bss
; i
++) {
1231 if ((&conf
->bss
[i
] != bss
) &&
1232 (hostapd_mac_comp(conf
->bss
[i
].bssid
,
1233 bss
->bssid
) == 0)) {
1234 wpa_printf(MSG_ERROR
, "Duplicate BSSID " MACSTR
1235 " on interface '%s' and '%s'.",
1236 MAC2STR(bss
->bssid
),
1237 conf
->bss
[i
].iface
, bss
->iface
);
1243 #ifdef CONFIG_IEEE80211R
1244 if (wpa_key_mgmt_ft(bss
->wpa_key_mgmt
) &&
1245 (bss
->nas_identifier
== NULL
||
1246 os_strlen(bss
->nas_identifier
) < 1 ||
1247 os_strlen(bss
->nas_identifier
) > FT_R0KH_ID_MAX_LEN
)) {
1248 wpa_printf(MSG_ERROR
, "FT (IEEE 802.11r) requires "
1249 "nas_identifier to be configured as a 1..48 octet "
1253 #endif /* CONFIG_IEEE80211R */
1255 #ifdef CONFIG_IEEE80211N
1256 if (conf
->ieee80211n
&& conf
->hw_mode
== HOSTAPD_MODE_IEEE80211B
) {
1257 bss
->disable_11n
= 1;
1258 wpa_printf(MSG_ERROR
, "HT (IEEE 802.11n) in 11b mode is not "
1259 "allowed, disabling HT capabilites");
1262 if (conf
->ieee80211n
&&
1263 bss
->ssid
.security_policy
== SECURITY_STATIC_WEP
) {
1264 bss
->disable_11n
= 1;
1265 wpa_printf(MSG_ERROR
, "HT (IEEE 802.11n) with WEP is not "
1266 "allowed, disabling HT capabilities");
1269 if (conf
->ieee80211n
&& bss
->wpa
&&
1270 !(bss
->wpa_pairwise
& WPA_CIPHER_CCMP
) &&
1271 !(bss
->rsn_pairwise
& WPA_CIPHER_CCMP
)) {
1272 bss
->disable_11n
= 1;
1273 wpa_printf(MSG_ERROR
, "HT (IEEE 802.11n) with WPA/WPA2 "
1274 "requires CCMP to be enabled, disabling HT "
1277 #endif /* CONFIG_IEEE80211N */
1280 if (bss
->wps_state
&& bss
->ignore_broadcast_ssid
) {
1281 wpa_printf(MSG_INFO
, "WPS: ignore_broadcast_ssid "
1282 "configuration forced WPS to be disabled");
1286 if (bss
->wps_state
&& bss
->ssid
.wep
.keys_set
&& bss
->wpa
== 0) {
1287 wpa_printf(MSG_INFO
, "WPS: WEP configuration forced WPS to be "
1291 #endif /* CONFIG_WPS2 */
1297 static int hostapd_config_check(struct hostapd_config
*conf
)
1301 if (conf
->ieee80211d
&& (!conf
->country
[0] || !conf
->country
[1])) {
1302 wpa_printf(MSG_ERROR
, "Cannot enable IEEE 802.11d without "
1303 "setting the country_code");
1307 for (i
= 0; i
< conf
->num_bss
; i
++) {
1308 if (hostapd_config_check_bss(&conf
->bss
[i
], conf
))
1316 #ifdef CONFIG_INTERWORKING
1317 static int parse_roaming_consortium(struct hostapd_bss_config
*bss
, char *pos
,
1320 size_t len
= os_strlen(pos
);
1321 u8 oi
[MAX_ROAMING_CONSORTIUM_LEN
];
1323 struct hostapd_roaming_consortium
*rc
;
1325 if ((len
& 1) || len
< 2 * 3 || len
/ 2 > MAX_ROAMING_CONSORTIUM_LEN
||
1326 hexstr2bin(pos
, oi
, len
/ 2)) {
1327 wpa_printf(MSG_ERROR
, "Line %d: invalid roaming_consortium "
1333 rc
= os_realloc(bss
->roaming_consortium
,
1334 sizeof(struct hostapd_roaming_consortium
) *
1335 (bss
->roaming_consortium_count
+ 1));
1339 os_memcpy(rc
[bss
->roaming_consortium_count
].oi
, oi
, len
);
1340 rc
[bss
->roaming_consortium_count
].len
= len
;
1342 bss
->roaming_consortium
= rc
;
1343 bss
->roaming_consortium_count
++;
1349 static int parse_venue_name(struct hostapd_bss_config
*bss
, char *pos
,
1354 struct hostapd_venue_name
*vn
;
1356 sep
= os_strchr(pos
, ':');
1361 clen
= os_strlen(pos
);
1364 nlen
= os_strlen(sep
);
1368 vn
= os_realloc(bss
->venue_name
,
1369 sizeof(struct hostapd_venue_name
) *
1370 (bss
->venue_name_count
+ 1));
1374 bss
->venue_name
= vn
;
1375 vn
= &bss
->venue_name
[bss
->venue_name_count
];
1376 bss
->venue_name_count
++;
1378 os_memset(vn
->lang
, 0, sizeof(vn
->lang
));
1379 os_memcpy(vn
->lang
, pos
, clen
);
1380 vn
->name_len
= nlen
;
1381 os_memcpy(vn
->name
, sep
, nlen
);
1386 wpa_printf(MSG_ERROR
, "Line %d: Invalid venue_name '%s'",
1390 #endif /* CONFIG_INTERWORKING */
1393 #ifdef CONFIG_WPS_NFC
1394 static struct wpabuf
* hostapd_parse_bin(const char *buf
)
1399 len
= os_strlen(buf
);
1404 ret
= wpabuf_alloc(len
);
1408 if (hexstr2bin(buf
, wpabuf_put(ret
, len
), len
)) {
1415 #endif /* CONFIG_WPS_NFC */
1418 static int hostapd_config_fill(struct hostapd_config
*conf
,
1419 struct hostapd_bss_config
*bss
,
1420 char *buf
, char *pos
, int line
)
1425 if (os_strcmp(buf
, "interface") == 0) {
1426 os_strlcpy(conf
->bss
[0].iface
, pos
,
1427 sizeof(conf
->bss
[0].iface
));
1428 } else if (os_strcmp(buf
, "bridge") == 0) {
1429 os_strlcpy(bss
->bridge
, pos
, sizeof(bss
->bridge
));
1430 } else if (os_strcmp(buf
, "wds_bridge") == 0) {
1431 os_strlcpy(bss
->wds_bridge
, pos
,
1432 sizeof(bss
->wds_bridge
));
1433 } else if (os_strcmp(buf
, "driver") == 0) {
1435 /* clear to get error below if setting is invalid */
1436 conf
->driver
= NULL
;
1437 for (j
= 0; wpa_drivers
[j
]; j
++) {
1438 if (os_strcmp(pos
, wpa_drivers
[j
]->name
) == 0)
1440 conf
->driver
= wpa_drivers
[j
];
1444 if (conf
->driver
== NULL
) {
1445 wpa_printf(MSG_ERROR
, "Line %d: invalid/"
1446 "unknown driver '%s'", line
, pos
);
1449 } else if (os_strcmp(buf
, "debug") == 0) {
1450 wpa_printf(MSG_DEBUG
, "Line %d: DEPRECATED: 'debug' "
1451 "configuration variable is not used "
1453 } else if (os_strcmp(buf
, "logger_syslog_level") == 0) {
1454 bss
->logger_syslog_level
= atoi(pos
);
1455 } else if (os_strcmp(buf
, "logger_stdout_level") == 0) {
1456 bss
->logger_stdout_level
= atoi(pos
);
1457 } else if (os_strcmp(buf
, "logger_syslog") == 0) {
1458 bss
->logger_syslog
= atoi(pos
);
1459 } else if (os_strcmp(buf
, "logger_stdout") == 0) {
1460 bss
->logger_stdout
= atoi(pos
);
1461 } else if (os_strcmp(buf
, "dump_file") == 0) {
1462 bss
->dump_log_name
= os_strdup(pos
);
1463 } else if (os_strcmp(buf
, "ssid") == 0) {
1464 bss
->ssid
.ssid_len
= os_strlen(pos
);
1465 if (bss
->ssid
.ssid_len
> HOSTAPD_MAX_SSID_LEN
||
1466 bss
->ssid
.ssid_len
< 1) {
1467 wpa_printf(MSG_ERROR
, "Line %d: invalid SSID "
1471 os_memcpy(bss
->ssid
.ssid
, pos
,
1472 bss
->ssid
.ssid_len
);
1473 bss
->ssid
.ssid
[bss
->ssid
.ssid_len
] = '\0';
1474 bss
->ssid
.ssid_set
= 1;
1476 } else if (os_strcmp(buf
, "macaddr_acl") == 0) {
1477 bss
->macaddr_acl
= atoi(pos
);
1478 if (bss
->macaddr_acl
!= ACCEPT_UNLESS_DENIED
&&
1479 bss
->macaddr_acl
!= DENY_UNLESS_ACCEPTED
&&
1480 bss
->macaddr_acl
!= USE_EXTERNAL_RADIUS_AUTH
) {
1481 wpa_printf(MSG_ERROR
, "Line %d: unknown "
1483 line
, bss
->macaddr_acl
);
1485 } else if (os_strcmp(buf
, "accept_mac_file") == 0) {
1486 if (hostapd_config_read_maclist(pos
, &bss
->accept_mac
,
1487 &bss
->num_accept_mac
))
1489 wpa_printf(MSG_ERROR
, "Line %d: Failed to "
1490 "read accept_mac_file '%s'",
1494 } else if (os_strcmp(buf
, "deny_mac_file") == 0) {
1495 if (hostapd_config_read_maclist(pos
, &bss
->deny_mac
,
1496 &bss
->num_deny_mac
)) {
1497 wpa_printf(MSG_ERROR
, "Line %d: Failed to "
1498 "read deny_mac_file '%s'",
1502 } else if (os_strcmp(buf
, "wds_sta") == 0) {
1503 bss
->wds_sta
= atoi(pos
);
1504 } else if (os_strcmp(buf
, "ap_isolate") == 0) {
1505 bss
->isolate
= atoi(pos
);
1506 } else if (os_strcmp(buf
, "ap_max_inactivity") == 0) {
1507 bss
->ap_max_inactivity
= atoi(pos
);
1508 } else if (os_strcmp(buf
, "skip_inactivity_poll") == 0) {
1509 bss
->skip_inactivity_poll
= atoi(pos
);
1510 } else if (os_strcmp(buf
, "country_code") == 0) {
1511 os_memcpy(conf
->country
, pos
, 2);
1512 /* FIX: make this configurable */
1513 conf
->country
[2] = ' ';
1514 } else if (os_strcmp(buf
, "ieee80211d") == 0) {
1515 conf
->ieee80211d
= atoi(pos
);
1516 } else if (os_strcmp(buf
, "ieee8021x") == 0) {
1517 bss
->ieee802_1x
= atoi(pos
);
1518 } else if (os_strcmp(buf
, "eapol_version") == 0) {
1519 bss
->eapol_version
= atoi(pos
);
1520 if (bss
->eapol_version
< 1 ||
1521 bss
->eapol_version
> 2) {
1522 wpa_printf(MSG_ERROR
, "Line %d: invalid EAPOL "
1523 "version (%d): '%s'.",
1524 line
, bss
->eapol_version
, pos
);
1527 wpa_printf(MSG_DEBUG
, "eapol_version=%d",
1528 bss
->eapol_version
);
1530 } else if (os_strcmp(buf
, "eap_authenticator") == 0) {
1531 bss
->eap_server
= atoi(pos
);
1532 wpa_printf(MSG_ERROR
, "Line %d: obsolete "
1533 "eap_authenticator used; this has been "
1534 "renamed to eap_server", line
);
1535 } else if (os_strcmp(buf
, "eap_server") == 0) {
1536 bss
->eap_server
= atoi(pos
);
1537 } else if (os_strcmp(buf
, "eap_user_file") == 0) {
1538 if (hostapd_config_read_eap_user(pos
, bss
))
1540 } else if (os_strcmp(buf
, "ca_cert") == 0) {
1541 os_free(bss
->ca_cert
);
1542 bss
->ca_cert
= os_strdup(pos
);
1543 } else if (os_strcmp(buf
, "server_cert") == 0) {
1544 os_free(bss
->server_cert
);
1545 bss
->server_cert
= os_strdup(pos
);
1546 } else if (os_strcmp(buf
, "private_key") == 0) {
1547 os_free(bss
->private_key
);
1548 bss
->private_key
= os_strdup(pos
);
1549 } else if (os_strcmp(buf
, "private_key_passwd") == 0) {
1550 os_free(bss
->private_key_passwd
);
1551 bss
->private_key_passwd
= os_strdup(pos
);
1552 } else if (os_strcmp(buf
, "check_crl") == 0) {
1553 bss
->check_crl
= atoi(pos
);
1554 } else if (os_strcmp(buf
, "dh_file") == 0) {
1555 os_free(bss
->dh_file
);
1556 bss
->dh_file
= os_strdup(pos
);
1557 } else if (os_strcmp(buf
, "fragment_size") == 0) {
1558 bss
->fragment_size
= atoi(pos
);
1559 #ifdef EAP_SERVER_FAST
1560 } else if (os_strcmp(buf
, "pac_opaque_encr_key") == 0) {
1561 os_free(bss
->pac_opaque_encr_key
);
1562 bss
->pac_opaque_encr_key
= os_malloc(16);
1563 if (bss
->pac_opaque_encr_key
== NULL
) {
1564 wpa_printf(MSG_ERROR
, "Line %d: No memory for "
1565 "pac_opaque_encr_key", line
);
1567 } else if (hexstr2bin(pos
, bss
->pac_opaque_encr_key
,
1569 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
1570 "pac_opaque_encr_key", line
);
1573 } else if (os_strcmp(buf
, "eap_fast_a_id") == 0) {
1574 size_t idlen
= os_strlen(pos
);
1576 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
1577 "eap_fast_a_id", line
);
1580 os_free(bss
->eap_fast_a_id
);
1581 bss
->eap_fast_a_id
= os_malloc(idlen
/ 2);
1582 if (bss
->eap_fast_a_id
== NULL
||
1583 hexstr2bin(pos
, bss
->eap_fast_a_id
,
1585 wpa_printf(MSG_ERROR
, "Line %d: "
1587 "eap_fast_a_id", line
);
1590 bss
->eap_fast_a_id_len
= idlen
/ 2;
1592 } else if (os_strcmp(buf
, "eap_fast_a_id_info") == 0) {
1593 os_free(bss
->eap_fast_a_id_info
);
1594 bss
->eap_fast_a_id_info
= os_strdup(pos
);
1595 } else if (os_strcmp(buf
, "eap_fast_prov") == 0) {
1596 bss
->eap_fast_prov
= atoi(pos
);
1597 } else if (os_strcmp(buf
, "pac_key_lifetime") == 0) {
1598 bss
->pac_key_lifetime
= atoi(pos
);
1599 } else if (os_strcmp(buf
, "pac_key_refresh_time") == 0) {
1600 bss
->pac_key_refresh_time
= atoi(pos
);
1601 #endif /* EAP_SERVER_FAST */
1602 #ifdef EAP_SERVER_SIM
1603 } else if (os_strcmp(buf
, "eap_sim_db") == 0) {
1604 os_free(bss
->eap_sim_db
);
1605 bss
->eap_sim_db
= os_strdup(pos
);
1606 } else if (os_strcmp(buf
, "eap_sim_aka_result_ind") == 0) {
1607 bss
->eap_sim_aka_result_ind
= atoi(pos
);
1608 #endif /* EAP_SERVER_SIM */
1609 #ifdef EAP_SERVER_TNC
1610 } else if (os_strcmp(buf
, "tnc") == 0) {
1611 bss
->tnc
= atoi(pos
);
1612 #endif /* EAP_SERVER_TNC */
1613 #ifdef EAP_SERVER_PWD
1614 } else if (os_strcmp(buf
, "pwd_group") == 0) {
1615 bss
->pwd_group
= atoi(pos
);
1616 #endif /* EAP_SERVER_PWD */
1617 #endif /* EAP_SERVER */
1618 } else if (os_strcmp(buf
, "eap_message") == 0) {
1620 bss
->eap_req_id_text
= os_strdup(pos
);
1621 if (bss
->eap_req_id_text
== NULL
) {
1622 wpa_printf(MSG_ERROR
, "Line %d: Failed to "
1623 "allocate memory for "
1624 "eap_req_id_text", line
);
1628 bss
->eap_req_id_text_len
=
1629 os_strlen(bss
->eap_req_id_text
);
1630 term
= os_strstr(bss
->eap_req_id_text
, "\\0");
1633 os_memmove(term
, term
+ 1,
1634 bss
->eap_req_id_text_len
-
1635 (term
- bss
->eap_req_id_text
) - 1);
1636 bss
->eap_req_id_text_len
--;
1638 } else if (os_strcmp(buf
, "wep_key_len_broadcast") == 0) {
1639 bss
->default_wep_key_len
= atoi(pos
);
1640 if (bss
->default_wep_key_len
> 13) {
1641 wpa_printf(MSG_ERROR
, "Line %d: invalid WEP "
1642 "key len %lu (= %lu bits)", line
,
1644 bss
->default_wep_key_len
,
1646 bss
->default_wep_key_len
* 8);
1649 } else if (os_strcmp(buf
, "wep_key_len_unicast") == 0) {
1650 bss
->individual_wep_key_len
= atoi(pos
);
1651 if (bss
->individual_wep_key_len
< 0 ||
1652 bss
->individual_wep_key_len
> 13) {
1653 wpa_printf(MSG_ERROR
, "Line %d: invalid WEP "
1654 "key len %d (= %d bits)", line
,
1655 bss
->individual_wep_key_len
,
1656 bss
->individual_wep_key_len
* 8);
1659 } else if (os_strcmp(buf
, "wep_rekey_period") == 0) {
1660 bss
->wep_rekeying_period
= atoi(pos
);
1661 if (bss
->wep_rekeying_period
< 0) {
1662 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1664 line
, bss
->wep_rekeying_period
);
1667 } else if (os_strcmp(buf
, "eap_reauth_period") == 0) {
1668 bss
->eap_reauth_period
= atoi(pos
);
1669 if (bss
->eap_reauth_period
< 0) {
1670 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1672 line
, bss
->eap_reauth_period
);
1675 } else if (os_strcmp(buf
, "eapol_key_index_workaround") == 0) {
1676 bss
->eapol_key_index_workaround
= atoi(pos
);
1678 } else if (os_strcmp(buf
, "iapp_interface") == 0) {
1679 bss
->ieee802_11f
= 1;
1680 os_strlcpy(bss
->iapp_iface
, pos
,
1681 sizeof(bss
->iapp_iface
));
1682 #endif /* CONFIG_IAPP */
1683 } else if (os_strcmp(buf
, "own_ip_addr") == 0) {
1684 if (hostapd_parse_ip_addr(pos
, &bss
->own_ip_addr
)) {
1685 wpa_printf(MSG_ERROR
, "Line %d: invalid IP "
1686 "address '%s'", line
, pos
);
1689 } else if (os_strcmp(buf
, "nas_identifier") == 0) {
1690 bss
->nas_identifier
= os_strdup(pos
);
1691 #ifndef CONFIG_NO_RADIUS
1692 } else if (os_strcmp(buf
, "auth_server_addr") == 0) {
1693 if (hostapd_config_read_radius_addr(
1694 &bss
->radius
->auth_servers
,
1695 &bss
->radius
->num_auth_servers
, pos
, 1812,
1696 &bss
->radius
->auth_server
)) {
1697 wpa_printf(MSG_ERROR
, "Line %d: invalid IP "
1698 "address '%s'", line
, pos
);
1701 } else if (bss
->radius
->auth_server
&&
1702 os_strcmp(buf
, "auth_server_port") == 0) {
1703 bss
->radius
->auth_server
->port
= atoi(pos
);
1704 } else if (bss
->radius
->auth_server
&&
1705 os_strcmp(buf
, "auth_server_shared_secret") == 0) {
1706 int len
= os_strlen(pos
);
1708 /* RFC 2865, Ch. 3 */
1709 wpa_printf(MSG_ERROR
, "Line %d: empty shared "
1710 "secret is not allowed.", line
);
1713 bss
->radius
->auth_server
->shared_secret
=
1714 (u8
*) os_strdup(pos
);
1715 bss
->radius
->auth_server
->shared_secret_len
= len
;
1716 } else if (os_strcmp(buf
, "acct_server_addr") == 0) {
1717 if (hostapd_config_read_radius_addr(
1718 &bss
->radius
->acct_servers
,
1719 &bss
->radius
->num_acct_servers
, pos
, 1813,
1720 &bss
->radius
->acct_server
)) {
1721 wpa_printf(MSG_ERROR
, "Line %d: invalid IP "
1722 "address '%s'", line
, pos
);
1725 } else if (bss
->radius
->acct_server
&&
1726 os_strcmp(buf
, "acct_server_port") == 0) {
1727 bss
->radius
->acct_server
->port
= atoi(pos
);
1728 } else if (bss
->radius
->acct_server
&&
1729 os_strcmp(buf
, "acct_server_shared_secret") == 0) {
1730 int len
= os_strlen(pos
);
1732 /* RFC 2865, Ch. 3 */
1733 wpa_printf(MSG_ERROR
, "Line %d: empty shared "
1734 "secret is not allowed.", line
);
1737 bss
->radius
->acct_server
->shared_secret
=
1738 (u8
*) os_strdup(pos
);
1739 bss
->radius
->acct_server
->shared_secret_len
= len
;
1740 } else if (os_strcmp(buf
, "radius_retry_primary_interval") ==
1742 bss
->radius
->retry_primary_interval
= atoi(pos
);
1743 } else if (os_strcmp(buf
, "radius_acct_interim_interval") == 0)
1745 bss
->acct_interim_interval
= atoi(pos
);
1746 } else if (os_strcmp(buf
, "radius_request_cui") == 0) {
1747 bss
->radius_request_cui
= atoi(pos
);
1748 } else if (os_strcmp(buf
, "radius_auth_req_attr") == 0) {
1749 struct hostapd_radius_attr
*attr
, *a
;
1750 attr
= hostapd_parse_radius_attr(pos
);
1752 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1753 "radius_auth_req_attr", line
);
1755 } else if (bss
->radius_auth_req_attr
== NULL
) {
1756 bss
->radius_auth_req_attr
= attr
;
1758 a
= bss
->radius_auth_req_attr
;
1763 } else if (os_strcmp(buf
, "radius_acct_req_attr") == 0) {
1764 struct hostapd_radius_attr
*attr
, *a
;
1765 attr
= hostapd_parse_radius_attr(pos
);
1767 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1768 "radius_acct_req_attr", line
);
1770 } else if (bss
->radius_acct_req_attr
== NULL
) {
1771 bss
->radius_acct_req_attr
= attr
;
1773 a
= bss
->radius_acct_req_attr
;
1778 } else if (os_strcmp(buf
, "radius_das_port") == 0) {
1779 bss
->radius_das_port
= atoi(pos
);
1780 } else if (os_strcmp(buf
, "radius_das_client") == 0) {
1781 if (hostapd_parse_das_client(bss
, pos
) < 0) {
1782 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1783 "DAS client", line
);
1786 } else if (os_strcmp(buf
, "radius_das_time_window") == 0) {
1787 bss
->radius_das_time_window
= atoi(pos
);
1788 } else if (os_strcmp(buf
, "radius_das_require_event_timestamp")
1790 bss
->radius_das_require_event_timestamp
= atoi(pos
);
1791 #endif /* CONFIG_NO_RADIUS */
1792 } else if (os_strcmp(buf
, "auth_algs") == 0) {
1793 bss
->auth_algs
= atoi(pos
);
1794 if (bss
->auth_algs
== 0) {
1795 wpa_printf(MSG_ERROR
, "Line %d: no "
1796 "authentication algorithms allowed",
1800 } else if (os_strcmp(buf
, "max_num_sta") == 0) {
1801 bss
->max_num_sta
= atoi(pos
);
1802 if (bss
->max_num_sta
< 0 ||
1803 bss
->max_num_sta
> MAX_STA_COUNT
) {
1804 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
1805 "max_num_sta=%d; allowed range "
1806 "0..%d", line
, bss
->max_num_sta
,
1810 } else if (os_strcmp(buf
, "wpa") == 0) {
1811 bss
->wpa
= atoi(pos
);
1812 } else if (os_strcmp(buf
, "wpa_group_rekey") == 0) {
1813 bss
->wpa_group_rekey
= atoi(pos
);
1814 } else if (os_strcmp(buf
, "wpa_strict_rekey") == 0) {
1815 bss
->wpa_strict_rekey
= atoi(pos
);
1816 } else if (os_strcmp(buf
, "wpa_gmk_rekey") == 0) {
1817 bss
->wpa_gmk_rekey
= atoi(pos
);
1818 } else if (os_strcmp(buf
, "wpa_ptk_rekey") == 0) {
1819 bss
->wpa_ptk_rekey
= atoi(pos
);
1820 } else if (os_strcmp(buf
, "wpa_passphrase") == 0) {
1821 int len
= os_strlen(pos
);
1822 if (len
< 8 || len
> 63) {
1823 wpa_printf(MSG_ERROR
, "Line %d: invalid WPA "
1824 "passphrase length %d (expected "
1825 "8..63)", line
, len
);
1828 os_free(bss
->ssid
.wpa_passphrase
);
1829 bss
->ssid
.wpa_passphrase
= os_strdup(pos
);
1830 os_free(bss
->ssid
.wpa_psk
);
1831 bss
->ssid
.wpa_psk
= NULL
;
1833 } else if (os_strcmp(buf
, "wpa_psk") == 0) {
1834 os_free(bss
->ssid
.wpa_psk
);
1836 os_zalloc(sizeof(struct hostapd_wpa_psk
));
1837 if (bss
->ssid
.wpa_psk
== NULL
)
1839 else if (hexstr2bin(pos
, bss
->ssid
.wpa_psk
->psk
,
1841 pos
[PMK_LEN
* 2] != '\0') {
1842 wpa_printf(MSG_ERROR
, "Line %d: Invalid PSK "
1843 "'%s'.", line
, pos
);
1846 bss
->ssid
.wpa_psk
->group
= 1;
1847 os_free(bss
->ssid
.wpa_passphrase
);
1848 bss
->ssid
.wpa_passphrase
= NULL
;
1850 } else if (os_strcmp(buf
, "wpa_psk_file") == 0) {
1851 os_free(bss
->ssid
.wpa_psk_file
);
1852 bss
->ssid
.wpa_psk_file
= os_strdup(pos
);
1853 if (!bss
->ssid
.wpa_psk_file
) {
1854 wpa_printf(MSG_ERROR
, "Line %d: allocation "
1858 } else if (os_strcmp(buf
, "wpa_key_mgmt") == 0) {
1860 hostapd_config_parse_key_mgmt(line
, pos
);
1861 if (bss
->wpa_key_mgmt
== -1)
1863 } else if (os_strcmp(buf
, "wpa_psk_radius") == 0) {
1864 bss
->wpa_psk_radius
= atoi(pos
);
1865 if (bss
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
&&
1866 bss
->wpa_psk_radius
!= PSK_RADIUS_ACCEPTED
&&
1867 bss
->wpa_psk_radius
!= PSK_RADIUS_REQUIRED
) {
1868 wpa_printf(MSG_ERROR
, "Line %d: unknown "
1869 "wpa_psk_radius %d",
1870 line
, bss
->wpa_psk_radius
);
1873 } else if (os_strcmp(buf
, "wpa_pairwise") == 0) {
1875 hostapd_config_parse_cipher(line
, pos
);
1876 if (bss
->wpa_pairwise
== -1 ||
1877 bss
->wpa_pairwise
== 0)
1879 else if (bss
->wpa_pairwise
&
1880 (WPA_CIPHER_NONE
| WPA_CIPHER_WEP40
|
1881 WPA_CIPHER_WEP104
)) {
1882 wpa_printf(MSG_ERROR
, "Line %d: unsupported "
1883 "pairwise cipher suite '%s'",
1884 bss
->wpa_pairwise
, pos
);
1887 } else if (os_strcmp(buf
, "rsn_pairwise") == 0) {
1889 hostapd_config_parse_cipher(line
, pos
);
1890 if (bss
->rsn_pairwise
== -1 ||
1891 bss
->rsn_pairwise
== 0)
1893 else if (bss
->rsn_pairwise
&
1894 (WPA_CIPHER_NONE
| WPA_CIPHER_WEP40
|
1895 WPA_CIPHER_WEP104
)) {
1896 wpa_printf(MSG_ERROR
, "Line %d: unsupported "
1897 "pairwise cipher suite '%s'",
1898 bss
->rsn_pairwise
, pos
);
1901 #ifdef CONFIG_RSN_PREAUTH
1902 } else if (os_strcmp(buf
, "rsn_preauth") == 0) {
1903 bss
->rsn_preauth
= atoi(pos
);
1904 } else if (os_strcmp(buf
, "rsn_preauth_interfaces") == 0) {
1905 bss
->rsn_preauth_interfaces
= os_strdup(pos
);
1906 #endif /* CONFIG_RSN_PREAUTH */
1907 #ifdef CONFIG_PEERKEY
1908 } else if (os_strcmp(buf
, "peerkey") == 0) {
1909 bss
->peerkey
= atoi(pos
);
1910 #endif /* CONFIG_PEERKEY */
1911 #ifdef CONFIG_IEEE80211R
1912 } else if (os_strcmp(buf
, "mobility_domain") == 0) {
1913 if (os_strlen(pos
) != 2 * MOBILITY_DOMAIN_ID_LEN
||
1914 hexstr2bin(pos
, bss
->mobility_domain
,
1915 MOBILITY_DOMAIN_ID_LEN
) != 0) {
1916 wpa_printf(MSG_DEBUG
, "Line %d: Invalid "
1917 "mobility_domain '%s'", line
, pos
);
1921 } else if (os_strcmp(buf
, "r1_key_holder") == 0) {
1922 if (os_strlen(pos
) != 2 * FT_R1KH_ID_LEN
||
1923 hexstr2bin(pos
, bss
->r1_key_holder
,
1924 FT_R1KH_ID_LEN
) != 0) {
1925 wpa_printf(MSG_DEBUG
, "Line %d: Invalid "
1926 "r1_key_holder '%s'", line
, pos
);
1930 } else if (os_strcmp(buf
, "r0_key_lifetime") == 0) {
1931 bss
->r0_key_lifetime
= atoi(pos
);
1932 } else if (os_strcmp(buf
, "reassociation_deadline") == 0) {
1933 bss
->reassociation_deadline
= atoi(pos
);
1934 } else if (os_strcmp(buf
, "r0kh") == 0) {
1935 if (add_r0kh(bss
, pos
) < 0) {
1936 wpa_printf(MSG_DEBUG
, "Line %d: Invalid "
1937 "r0kh '%s'", line
, pos
);
1941 } else if (os_strcmp(buf
, "r1kh") == 0) {
1942 if (add_r1kh(bss
, pos
) < 0) {
1943 wpa_printf(MSG_DEBUG
, "Line %d: Invalid "
1944 "r1kh '%s'", line
, pos
);
1948 } else if (os_strcmp(buf
, "pmk_r1_push") == 0) {
1949 bss
->pmk_r1_push
= atoi(pos
);
1950 } else if (os_strcmp(buf
, "ft_over_ds") == 0) {
1951 bss
->ft_over_ds
= atoi(pos
);
1952 #endif /* CONFIG_IEEE80211R */
1953 #ifndef CONFIG_NO_CTRL_IFACE
1954 } else if (os_strcmp(buf
, "ctrl_interface") == 0) {
1955 os_free(bss
->ctrl_interface
);
1956 bss
->ctrl_interface
= os_strdup(pos
);
1957 } else if (os_strcmp(buf
, "ctrl_interface_group") == 0) {
1958 #ifndef CONFIG_NATIVE_WINDOWS
1961 const char *group
= pos
;
1963 grp
= getgrnam(group
);
1965 bss
->ctrl_interface_gid
= grp
->gr_gid
;
1966 bss
->ctrl_interface_gid_set
= 1;
1967 wpa_printf(MSG_DEBUG
, "ctrl_interface_group=%d"
1968 " (from group name '%s')",
1969 bss
->ctrl_interface_gid
, group
);
1973 /* Group name not found - try to parse this as gid */
1974 bss
->ctrl_interface_gid
= strtol(group
, &endp
, 10);
1975 if (*group
== '\0' || *endp
!= '\0') {
1976 wpa_printf(MSG_DEBUG
, "Line %d: Invalid group "
1977 "'%s'", line
, group
);
1981 bss
->ctrl_interface_gid_set
= 1;
1982 wpa_printf(MSG_DEBUG
, "ctrl_interface_group=%d",
1983 bss
->ctrl_interface_gid
);
1984 #endif /* CONFIG_NATIVE_WINDOWS */
1985 #endif /* CONFIG_NO_CTRL_IFACE */
1986 #ifdef RADIUS_SERVER
1987 } else if (os_strcmp(buf
, "radius_server_clients") == 0) {
1988 os_free(bss
->radius_server_clients
);
1989 bss
->radius_server_clients
= os_strdup(pos
);
1990 } else if (os_strcmp(buf
, "radius_server_auth_port") == 0) {
1991 bss
->radius_server_auth_port
= atoi(pos
);
1992 } else if (os_strcmp(buf
, "radius_server_ipv6") == 0) {
1993 bss
->radius_server_ipv6
= atoi(pos
);
1994 #endif /* RADIUS_SERVER */
1995 } else if (os_strcmp(buf
, "test_socket") == 0) {
1996 os_free(bss
->test_socket
);
1997 bss
->test_socket
= os_strdup(pos
);
1998 } else if (os_strcmp(buf
, "use_pae_group_addr") == 0) {
1999 bss
->use_pae_group_addr
= atoi(pos
);
2000 } else if (os_strcmp(buf
, "hw_mode") == 0) {
2001 if (os_strcmp(pos
, "a") == 0)
2002 conf
->hw_mode
= HOSTAPD_MODE_IEEE80211A
;
2003 else if (os_strcmp(pos
, "b") == 0)
2004 conf
->hw_mode
= HOSTAPD_MODE_IEEE80211B
;
2005 else if (os_strcmp(pos
, "g") == 0)
2006 conf
->hw_mode
= HOSTAPD_MODE_IEEE80211G
;
2008 wpa_printf(MSG_ERROR
, "Line %d: unknown "
2009 "hw_mode '%s'", line
, pos
);
2012 } else if (os_strcmp(buf
, "wps_rf_bands") == 0) {
2013 if (os_strcmp(pos
, "a") == 0)
2014 bss
->wps_rf_bands
= WPS_RF_50GHZ
;
2015 else if (os_strcmp(pos
, "g") == 0 ||
2016 os_strcmp(pos
, "b") == 0)
2017 bss
->wps_rf_bands
= WPS_RF_24GHZ
;
2018 else if (os_strcmp(pos
, "ag") == 0 ||
2019 os_strcmp(pos
, "ga") == 0)
2021 WPS_RF_24GHZ
| WPS_RF_50GHZ
;
2023 wpa_printf(MSG_ERROR
, "Line %d: unknown "
2024 "wps_rf_band '%s'", line
, pos
);
2027 } else if (os_strcmp(buf
, "channel") == 0) {
2028 conf
->channel
= atoi(pos
);
2029 } else if (os_strcmp(buf
, "beacon_int") == 0) {
2030 int val
= atoi(pos
);
2031 /* MIB defines range as 1..65535, but very small values
2032 * cause problems with the current implementation.
2033 * Since it is unlikely that this small numbers are
2034 * useful in real life scenarios, do not allow beacon
2035 * period to be set below 15 TU. */
2036 if (val
< 15 || val
> 65535) {
2037 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2038 "beacon_int %d (expected "
2039 "15..65535)", line
, val
);
2042 conf
->beacon_int
= val
;
2043 } else if (os_strcmp(buf
, "dtim_period") == 0) {
2044 bss
->dtim_period
= atoi(pos
);
2045 if (bss
->dtim_period
< 1 || bss
->dtim_period
> 255) {
2046 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2048 line
, bss
->dtim_period
);
2051 } else if (os_strcmp(buf
, "rts_threshold") == 0) {
2052 conf
->rts_threshold
= atoi(pos
);
2053 if (conf
->rts_threshold
< 0 ||
2054 conf
->rts_threshold
> 2347) {
2055 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2057 line
, conf
->rts_threshold
);
2060 } else if (os_strcmp(buf
, "fragm_threshold") == 0) {
2061 conf
->fragm_threshold
= atoi(pos
);
2062 if (conf
->fragm_threshold
< 256 ||
2063 conf
->fragm_threshold
> 2346) {
2064 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2065 "fragm_threshold %d",
2066 line
, conf
->fragm_threshold
);
2069 } else if (os_strcmp(buf
, "send_probe_response") == 0) {
2070 int val
= atoi(pos
);
2071 if (val
!= 0 && val
!= 1) {
2072 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2073 "send_probe_response %d (expected "
2074 "0 or 1)", line
, val
);
2076 conf
->send_probe_response
= val
;
2077 } else if (os_strcmp(buf
, "supported_rates") == 0) {
2078 if (hostapd_parse_rates(&conf
->supported_rates
, pos
)) {
2079 wpa_printf(MSG_ERROR
, "Line %d: invalid rate "
2083 } else if (os_strcmp(buf
, "basic_rates") == 0) {
2084 if (hostapd_parse_rates(&conf
->basic_rates
, pos
)) {
2085 wpa_printf(MSG_ERROR
, "Line %d: invalid rate "
2089 } else if (os_strcmp(buf
, "preamble") == 0) {
2091 conf
->preamble
= SHORT_PREAMBLE
;
2093 conf
->preamble
= LONG_PREAMBLE
;
2094 } else if (os_strcmp(buf
, "ignore_broadcast_ssid") == 0) {
2095 bss
->ignore_broadcast_ssid
= atoi(pos
);
2096 } else if (os_strcmp(buf
, "wep_default_key") == 0) {
2097 bss
->ssid
.wep
.idx
= atoi(pos
);
2098 if (bss
->ssid
.wep
.idx
> 3) {
2099 wpa_printf(MSG_ERROR
, "Invalid "
2100 "wep_default_key index %d",
2104 } else if (os_strcmp(buf
, "wep_key0") == 0 ||
2105 os_strcmp(buf
, "wep_key1") == 0 ||
2106 os_strcmp(buf
, "wep_key2") == 0 ||
2107 os_strcmp(buf
, "wep_key3") == 0) {
2108 if (hostapd_config_read_wep(&bss
->ssid
.wep
,
2109 buf
[7] - '0', pos
)) {
2110 wpa_printf(MSG_ERROR
, "Line %d: invalid WEP "
2111 "key '%s'", line
, buf
);
2114 #ifndef CONFIG_NO_VLAN
2115 } else if (os_strcmp(buf
, "dynamic_vlan") == 0) {
2116 bss
->ssid
.dynamic_vlan
= atoi(pos
);
2117 } else if (os_strcmp(buf
, "vlan_file") == 0) {
2118 if (hostapd_config_read_vlan_file(bss
, pos
)) {
2119 wpa_printf(MSG_ERROR
, "Line %d: failed to "
2120 "read VLAN file '%s'", line
, pos
);
2123 #ifdef CONFIG_FULL_DYNAMIC_VLAN
2124 } else if (os_strcmp(buf
, "vlan_tagged_interface") == 0) {
2125 bss
->ssid
.vlan_tagged_interface
= os_strdup(pos
);
2126 #endif /* CONFIG_FULL_DYNAMIC_VLAN */
2127 #endif /* CONFIG_NO_VLAN */
2128 } else if (os_strcmp(buf
, "ap_table_max_size") == 0) {
2129 conf
->ap_table_max_size
= atoi(pos
);
2130 } else if (os_strcmp(buf
, "ap_table_expiration_time") == 0) {
2131 conf
->ap_table_expiration_time
= atoi(pos
);
2132 } else if (os_strncmp(buf
, "tx_queue_", 9) == 0) {
2133 if (hostapd_config_tx_queue(conf
, buf
, pos
)) {
2134 wpa_printf(MSG_ERROR
, "Line %d: invalid TX "
2135 "queue item", line
);
2138 } else if (os_strcmp(buf
, "wme_enabled") == 0 ||
2139 os_strcmp(buf
, "wmm_enabled") == 0) {
2140 bss
->wmm_enabled
= atoi(pos
);
2141 } else if (os_strcmp(buf
, "uapsd_advertisement_enabled") == 0) {
2142 bss
->wmm_uapsd
= atoi(pos
);
2143 } else if (os_strncmp(buf
, "wme_ac_", 7) == 0 ||
2144 os_strncmp(buf
, "wmm_ac_", 7) == 0) {
2145 if (hostapd_config_wmm_ac(conf
, buf
, pos
)) {
2146 wpa_printf(MSG_ERROR
, "Line %d: invalid WMM "
2150 } else if (os_strcmp(buf
, "bss") == 0) {
2151 if (hostapd_config_bss(conf
, pos
)) {
2152 wpa_printf(MSG_ERROR
, "Line %d: invalid bss "
2156 } else if (os_strcmp(buf
, "bssid") == 0) {
2157 if (hwaddr_aton(pos
, bss
->bssid
)) {
2158 wpa_printf(MSG_ERROR
, "Line %d: invalid bssid "
2162 #ifdef CONFIG_IEEE80211W
2163 } else if (os_strcmp(buf
, "ieee80211w") == 0) {
2164 bss
->ieee80211w
= atoi(pos
);
2165 } else if (os_strcmp(buf
, "assoc_sa_query_max_timeout") == 0) {
2166 bss
->assoc_sa_query_max_timeout
= atoi(pos
);
2167 if (bss
->assoc_sa_query_max_timeout
== 0) {
2168 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2169 "assoc_sa_query_max_timeout", line
);
2172 } else if (os_strcmp(buf
, "assoc_sa_query_retry_timeout") == 0)
2174 bss
->assoc_sa_query_retry_timeout
= atoi(pos
);
2175 if (bss
->assoc_sa_query_retry_timeout
== 0) {
2176 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2177 "assoc_sa_query_retry_timeout",
2181 #endif /* CONFIG_IEEE80211W */
2182 #ifdef CONFIG_IEEE80211N
2183 } else if (os_strcmp(buf
, "ieee80211n") == 0) {
2184 conf
->ieee80211n
= atoi(pos
);
2185 } else if (os_strcmp(buf
, "ht_capab") == 0) {
2186 if (hostapd_config_ht_capab(conf
, pos
) < 0) {
2187 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2191 } else if (os_strcmp(buf
, "require_ht") == 0) {
2192 conf
->require_ht
= atoi(pos
);
2193 #endif /* CONFIG_IEEE80211N */
2194 #ifdef CONFIG_IEEE80211AC
2195 } else if (os_strcmp(buf
, "ieee80211ac") == 0) {
2196 conf
->ieee80211ac
= atoi(pos
);
2197 } else if (os_strcmp(buf
, "vht_capab") == 0) {
2198 if (hostapd_config_vht_capab(conf
, pos
) < 0) {
2199 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2203 } else if (os_strcmp(buf
, "vht_oper_chwidth") == 0) {
2204 conf
->vht_oper_chwidth
= atoi(pos
);
2205 #endif /* CONFIG_IEEE80211AC */
2206 } else if (os_strcmp(buf
, "max_listen_interval") == 0) {
2207 bss
->max_listen_interval
= atoi(pos
);
2208 } else if (os_strcmp(buf
, "disable_pmksa_caching") == 0) {
2209 bss
->disable_pmksa_caching
= atoi(pos
);
2210 } else if (os_strcmp(buf
, "okc") == 0) {
2211 bss
->okc
= atoi(pos
);
2213 } else if (os_strcmp(buf
, "wps_state") == 0) {
2214 bss
->wps_state
= atoi(pos
);
2215 if (bss
->wps_state
< 0 || bss
->wps_state
> 2) {
2216 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2220 } else if (os_strcmp(buf
, "ap_setup_locked") == 0) {
2221 bss
->ap_setup_locked
= atoi(pos
);
2222 } else if (os_strcmp(buf
, "uuid") == 0) {
2223 if (uuid_str2bin(pos
, bss
->uuid
)) {
2224 wpa_printf(MSG_ERROR
, "Line %d: invalid UUID",
2228 } else if (os_strcmp(buf
, "wps_pin_requests") == 0) {
2229 os_free(bss
->wps_pin_requests
);
2230 bss
->wps_pin_requests
= os_strdup(pos
);
2231 } else if (os_strcmp(buf
, "device_name") == 0) {
2232 if (os_strlen(pos
) > 32) {
2233 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2234 "device_name", line
);
2237 os_free(bss
->device_name
);
2238 bss
->device_name
= os_strdup(pos
);
2239 } else if (os_strcmp(buf
, "manufacturer") == 0) {
2240 if (os_strlen(pos
) > 64) {
2241 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2242 "manufacturer", line
);
2245 os_free(bss
->manufacturer
);
2246 bss
->manufacturer
= os_strdup(pos
);
2247 } else if (os_strcmp(buf
, "model_name") == 0) {
2248 if (os_strlen(pos
) > 32) {
2249 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2250 "model_name", line
);
2253 os_free(bss
->model_name
);
2254 bss
->model_name
= os_strdup(pos
);
2255 } else if (os_strcmp(buf
, "model_number") == 0) {
2256 if (os_strlen(pos
) > 32) {
2257 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2258 "model_number", line
);
2261 os_free(bss
->model_number
);
2262 bss
->model_number
= os_strdup(pos
);
2263 } else if (os_strcmp(buf
, "serial_number") == 0) {
2264 if (os_strlen(pos
) > 32) {
2265 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2266 "serial_number", line
);
2269 os_free(bss
->serial_number
);
2270 bss
->serial_number
= os_strdup(pos
);
2271 } else if (os_strcmp(buf
, "device_type") == 0) {
2272 if (wps_dev_type_str2bin(pos
, bss
->device_type
))
2274 } else if (os_strcmp(buf
, "config_methods") == 0) {
2275 os_free(bss
->config_methods
);
2276 bss
->config_methods
= os_strdup(pos
);
2277 } else if (os_strcmp(buf
, "os_version") == 0) {
2278 if (hexstr2bin(pos
, bss
->os_version
, 4)) {
2279 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2280 "os_version", line
);
2283 } else if (os_strcmp(buf
, "ap_pin") == 0) {
2284 os_free(bss
->ap_pin
);
2285 bss
->ap_pin
= os_strdup(pos
);
2286 } else if (os_strcmp(buf
, "skip_cred_build") == 0) {
2287 bss
->skip_cred_build
= atoi(pos
);
2288 } else if (os_strcmp(buf
, "extra_cred") == 0) {
2289 os_free(bss
->extra_cred
);
2291 (u8
*) os_readfile(pos
, &bss
->extra_cred_len
);
2292 if (bss
->extra_cred
== NULL
) {
2293 wpa_printf(MSG_ERROR
, "Line %d: could not "
2294 "read Credentials from '%s'",
2298 } else if (os_strcmp(buf
, "wps_cred_processing") == 0) {
2299 bss
->wps_cred_processing
= atoi(pos
);
2300 } else if (os_strcmp(buf
, "ap_settings") == 0) {
2301 os_free(bss
->ap_settings
);
2303 (u8
*) os_readfile(pos
, &bss
->ap_settings_len
);
2304 if (bss
->ap_settings
== NULL
) {
2305 wpa_printf(MSG_ERROR
, "Line %d: could not "
2306 "read AP Settings from '%s'",
2310 } else if (os_strcmp(buf
, "upnp_iface") == 0) {
2311 bss
->upnp_iface
= os_strdup(pos
);
2312 } else if (os_strcmp(buf
, "friendly_name") == 0) {
2313 os_free(bss
->friendly_name
);
2314 bss
->friendly_name
= os_strdup(pos
);
2315 } else if (os_strcmp(buf
, "manufacturer_url") == 0) {
2316 os_free(bss
->manufacturer_url
);
2317 bss
->manufacturer_url
= os_strdup(pos
);
2318 } else if (os_strcmp(buf
, "model_description") == 0) {
2319 os_free(bss
->model_description
);
2320 bss
->model_description
= os_strdup(pos
);
2321 } else if (os_strcmp(buf
, "model_url") == 0) {
2322 os_free(bss
->model_url
);
2323 bss
->model_url
= os_strdup(pos
);
2324 } else if (os_strcmp(buf
, "upc") == 0) {
2326 bss
->upc
= os_strdup(pos
);
2327 } else if (os_strcmp(buf
, "pbc_in_m1") == 0) {
2328 bss
->pbc_in_m1
= atoi(pos
);
2329 #ifdef CONFIG_WPS_NFC
2330 } else if (os_strcmp(buf
, "wps_nfc_dev_pw_id") == 0) {
2331 bss
->wps_nfc_dev_pw_id
= atoi(pos
);
2332 if (bss
->wps_nfc_dev_pw_id
< 0x10 ||
2333 bss
->wps_nfc_dev_pw_id
> 0xffff) {
2334 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
2335 "wps_nfc_dev_pw_id value", line
);
2338 } else if (os_strcmp(buf
, "wps_nfc_dh_pubkey") == 0) {
2339 wpabuf_free(bss
->wps_nfc_dh_pubkey
);
2340 bss
->wps_nfc_dh_pubkey
= hostapd_parse_bin(pos
);
2341 } else if (os_strcmp(buf
, "wps_nfc_dh_privkey") == 0) {
2342 wpabuf_free(bss
->wps_nfc_dh_privkey
);
2343 bss
->wps_nfc_dh_privkey
= hostapd_parse_bin(pos
);
2344 } else if (os_strcmp(buf
, "wps_nfc_dev_pw") == 0) {
2345 wpabuf_free(bss
->wps_nfc_dev_pw
);
2346 bss
->wps_nfc_dev_pw
= hostapd_parse_bin(pos
);
2347 #endif /* CONFIG_WPS_NFC */
2348 #endif /* CONFIG_WPS */
2349 #ifdef CONFIG_P2P_MANAGER
2350 } else if (os_strcmp(buf
, "manage_p2p") == 0) {
2351 int manage
= atoi(pos
);
2353 bss
->p2p
|= P2P_MANAGE
;
2355 bss
->p2p
&= ~P2P_MANAGE
;
2356 } else if (os_strcmp(buf
, "allow_cross_connection") == 0) {
2358 bss
->p2p
|= P2P_ALLOW_CROSS_CONNECTION
;
2360 bss
->p2p
&= ~P2P_ALLOW_CROSS_CONNECTION
;
2361 #endif /* CONFIG_P2P_MANAGER */
2362 } else if (os_strcmp(buf
, "disassoc_low_ack") == 0) {
2363 bss
->disassoc_low_ack
= atoi(pos
);
2364 } else if (os_strcmp(buf
, "tdls_prohibit") == 0) {
2365 int val
= atoi(pos
);
2367 bss
->tdls
|= TDLS_PROHIBIT
;
2369 bss
->tdls
&= ~TDLS_PROHIBIT
;
2370 } else if (os_strcmp(buf
, "tdls_prohibit_chan_switch") == 0) {
2371 int val
= atoi(pos
);
2373 bss
->tdls
|= TDLS_PROHIBIT_CHAN_SWITCH
;
2375 bss
->tdls
&= ~TDLS_PROHIBIT_CHAN_SWITCH
;
2376 #ifdef CONFIG_RSN_TESTING
2377 } else if (os_strcmp(buf
, "rsn_testing") == 0) {
2378 extern int rsn_testing
;
2379 rsn_testing
= atoi(pos
);
2380 #endif /* CONFIG_RSN_TESTING */
2381 } else if (os_strcmp(buf
, "time_advertisement") == 0) {
2382 bss
->time_advertisement
= atoi(pos
);
2383 } else if (os_strcmp(buf
, "time_zone") == 0) {
2384 size_t tz_len
= os_strlen(pos
);
2385 if (tz_len
< 4 || tz_len
> 255) {
2386 wpa_printf(MSG_DEBUG
, "Line %d: invalid "
2391 os_free(bss
->time_zone
);
2392 bss
->time_zone
= os_strdup(pos
);
2393 if (bss
->time_zone
== NULL
)
2395 #ifdef CONFIG_INTERWORKING
2396 } else if (os_strcmp(buf
, "interworking") == 0) {
2397 bss
->interworking
= atoi(pos
);
2398 } else if (os_strcmp(buf
, "access_network_type") == 0) {
2399 bss
->access_network_type
= atoi(pos
);
2400 if (bss
->access_network_type
< 0 ||
2401 bss
->access_network_type
> 15) {
2402 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2403 "access_network_type", line
);
2406 } else if (os_strcmp(buf
, "internet") == 0) {
2407 bss
->internet
= atoi(pos
);
2408 } else if (os_strcmp(buf
, "asra") == 0) {
2409 bss
->asra
= atoi(pos
);
2410 } else if (os_strcmp(buf
, "esr") == 0) {
2411 bss
->esr
= atoi(pos
);
2412 } else if (os_strcmp(buf
, "uesa") == 0) {
2413 bss
->uesa
= atoi(pos
);
2414 } else if (os_strcmp(buf
, "venue_group") == 0) {
2415 bss
->venue_group
= atoi(pos
);
2416 bss
->venue_info_set
= 1;
2417 } else if (os_strcmp(buf
, "venue_type") == 0) {
2418 bss
->venue_type
= atoi(pos
);
2419 bss
->venue_info_set
= 1;
2420 } else if (os_strcmp(buf
, "hessid") == 0) {
2421 if (hwaddr_aton(pos
, bss
->hessid
)) {
2422 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2426 } else if (os_strcmp(buf
, "roaming_consortium") == 0) {
2427 if (parse_roaming_consortium(bss
, pos
, line
) < 0)
2429 } else if (os_strcmp(buf
, "venue_name") == 0) {
2430 if (parse_venue_name(bss
, pos
, line
) < 0)
2432 } else if (os_strcmp(buf
, "network_auth_type") == 0) {
2434 u16 redirect_url_len
;
2435 if (hexstr2bin(pos
, &auth_type
, 1)) {
2436 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
2437 "network_auth_type '%s'",
2442 if (auth_type
== 0 || auth_type
== 2)
2443 redirect_url_len
= os_strlen(pos
+ 2);
2445 redirect_url_len
= 0;
2446 os_free(bss
->network_auth_type
);
2447 bss
->network_auth_type
=
2448 os_malloc(redirect_url_len
+ 3 + 1);
2449 if (bss
->network_auth_type
== NULL
) {
2453 *bss
->network_auth_type
= auth_type
;
2454 WPA_PUT_LE16(bss
->network_auth_type
+ 1,
2456 if (redirect_url_len
)
2457 os_memcpy(bss
->network_auth_type
+ 3,
2458 pos
+ 2, redirect_url_len
);
2459 bss
->network_auth_type_len
= 3 + redirect_url_len
;
2460 } else if (os_strcmp(buf
, "gas_frag_limit") == 0) {
2461 bss
->gas_frag_limit
= atoi(pos
);
2462 } else if (os_strcmp(buf
, "gas_comeback_delay") == 0) {
2463 bss
->gas_comeback_delay
= atoi(pos
);
2464 #endif /* CONFIG_INTERWORKING */
2465 #ifdef CONFIG_RADIUS_TEST
2466 } else if (os_strcmp(buf
, "dump_msk_file") == 0) {
2467 os_free(bss
->dump_msk_file
);
2468 bss
->dump_msk_file
= os_strdup(pos
);
2469 #endif /* CONFIG_RADIUS_TEST */
2471 } else if (os_strcmp(buf
, "hs20") == 0) {
2472 bss
->hs20
= atoi(pos
);
2473 } else if (os_strcmp(buf
, "disable_dgaf") == 0) {
2474 bss
->disable_dgaf
= atoi(pos
);
2475 #endif /* CONFIG_HS20 */
2477 wpa_printf(MSG_ERROR
, "Line %d: unknown configuration "
2478 "item '%s'", line
, buf
);
2487 static void hostapd_set_security_params(struct hostapd_bss_config
*bss
)
2491 if (bss
->individual_wep_key_len
== 0) {
2492 /* individual keys are not use; can use key idx0 for
2494 bss
->broadcast_key_idx_min
= 0;
2497 /* Select group cipher based on the enabled pairwise cipher
2501 pairwise
|= bss
->wpa_pairwise
;
2503 if (bss
->rsn_pairwise
== 0)
2504 bss
->rsn_pairwise
= bss
->wpa_pairwise
;
2505 pairwise
|= bss
->rsn_pairwise
;
2507 if (pairwise
& WPA_CIPHER_TKIP
)
2508 bss
->wpa_group
= WPA_CIPHER_TKIP
;
2510 bss
->wpa_group
= WPA_CIPHER_CCMP
;
2512 bss
->radius
->auth_server
= bss
->radius
->auth_servers
;
2513 bss
->radius
->acct_server
= bss
->radius
->acct_servers
;
2515 if (bss
->wpa
&& bss
->ieee802_1x
) {
2516 bss
->ssid
.security_policy
= SECURITY_WPA
;
2517 } else if (bss
->wpa
) {
2518 bss
->ssid
.security_policy
= SECURITY_WPA_PSK
;
2519 } else if (bss
->ieee802_1x
) {
2520 int cipher
= WPA_CIPHER_NONE
;
2521 bss
->ssid
.security_policy
= SECURITY_IEEE_802_1X
;
2522 bss
->ssid
.wep
.default_len
= bss
->default_wep_key_len
;
2523 if (bss
->default_wep_key_len
)
2524 cipher
= bss
->default_wep_key_len
>= 13 ?
2525 WPA_CIPHER_WEP104
: WPA_CIPHER_WEP40
;
2526 bss
->wpa_group
= cipher
;
2527 bss
->wpa_pairwise
= cipher
;
2528 bss
->rsn_pairwise
= cipher
;
2529 } else if (bss
->ssid
.wep
.keys_set
) {
2530 int cipher
= WPA_CIPHER_WEP40
;
2531 if (bss
->ssid
.wep
.len
[0] >= 13)
2532 cipher
= WPA_CIPHER_WEP104
;
2533 bss
->ssid
.security_policy
= SECURITY_STATIC_WEP
;
2534 bss
->wpa_group
= cipher
;
2535 bss
->wpa_pairwise
= cipher
;
2536 bss
->rsn_pairwise
= cipher
;
2538 bss
->ssid
.security_policy
= SECURITY_PLAINTEXT
;
2539 bss
->wpa_group
= WPA_CIPHER_NONE
;
2540 bss
->wpa_pairwise
= WPA_CIPHER_NONE
;
2541 bss
->rsn_pairwise
= WPA_CIPHER_NONE
;
2547 * hostapd_config_read - Read and parse a configuration file
2548 * @fname: Configuration file name (including path, if needed)
2549 * Returns: Allocated configuration data structure
2551 struct hostapd_config
* hostapd_config_read(const char *fname
)
2553 struct hostapd_config
*conf
;
2554 struct hostapd_bss_config
*bss
;
2556 char buf
[512], *pos
;
2561 f
= fopen(fname
, "r");
2563 wpa_printf(MSG_ERROR
, "Could not open configuration file '%s' "
2564 "for reading.", fname
);
2568 conf
= hostapd_config_defaults();
2574 /* set default driver based on configuration */
2575 conf
->driver
= wpa_drivers
[0];
2576 if (conf
->driver
== NULL
) {
2577 wpa_printf(MSG_ERROR
, "No driver wrappers registered!");
2578 hostapd_config_free(conf
);
2583 bss
= conf
->last_bss
= conf
->bss
;
2585 while (fgets(buf
, sizeof(buf
), f
)) {
2586 bss
= conf
->last_bss
;
2592 while (*pos
!= '\0') {
2602 pos
= os_strchr(buf
, '=');
2604 wpa_printf(MSG_ERROR
, "Line %d: invalid line '%s'",
2611 errors
+= hostapd_config_fill(conf
, bss
, buf
, pos
, line
);
2616 for (i
= 0; i
< conf
->num_bss
; i
++)
2617 hostapd_set_security_params(&conf
->bss
[i
]);
2619 if (hostapd_config_check(conf
))
2622 #ifndef WPA_IGNORE_CONFIG_ERRORS
2624 wpa_printf(MSG_ERROR
, "%d errors found in configuration file "
2625 "'%s'", errors
, fname
);
2626 hostapd_config_free(conf
);
2629 #endif /* WPA_IGNORE_CONFIG_ERRORS */
2635 int hostapd_set_iface(struct hostapd_config
*conf
,
2636 struct hostapd_bss_config
*bss
, char *field
, char *value
)
2641 errors
= hostapd_config_fill(conf
, bss
, field
, value
, 0);
2643 wpa_printf(MSG_INFO
, "Failed to set configuration field '%s' "
2644 "to value '%s'", field
, value
);
2648 for (i
= 0; i
< conf
->num_bss
; i
++)
2649 hostapd_set_security_params(&conf
->bss
[i
]);
2651 if (hostapd_config_check(conf
)) {
2652 wpa_printf(MSG_ERROR
, "Configuration check failed");