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 static int hostapd_config_check_bss(struct hostapd_bss_config
*bss
,
1136 struct hostapd_config
*conf
)
1138 if (bss
->ieee802_1x
&& !bss
->eap_server
&&
1139 !bss
->radius
->auth_servers
) {
1140 wpa_printf(MSG_ERROR
, "Invalid IEEE 802.1X configuration (no "
1141 "EAP authenticator configured).");
1145 if (bss
->wpa
&& bss
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
&&
1146 bss
->macaddr_acl
!= USE_EXTERNAL_RADIUS_AUTH
) {
1147 wpa_printf(MSG_ERROR
, "WPA-PSK using RADIUS enabled, but no "
1148 "RADIUS checking (macaddr_acl=2) enabled.");
1152 if (bss
->wpa
&& (bss
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
) &&
1153 bss
->ssid
.wpa_psk
== NULL
&& bss
->ssid
.wpa_passphrase
== NULL
&&
1154 bss
->ssid
.wpa_psk_file
== NULL
&&
1155 (bss
->wpa_psk_radius
!= PSK_RADIUS_REQUIRED
||
1156 bss
->macaddr_acl
!= USE_EXTERNAL_RADIUS_AUTH
)) {
1157 wpa_printf(MSG_ERROR
, "WPA-PSK enabled, but PSK or passphrase "
1158 "is not configured.");
1162 if (hostapd_mac_comp_empty(bss
->bssid
) != 0) {
1165 for (i
= 0; i
< conf
->num_bss
; i
++) {
1166 if ((&conf
->bss
[i
] != bss
) &&
1167 (hostapd_mac_comp(conf
->bss
[i
].bssid
,
1168 bss
->bssid
) == 0)) {
1169 wpa_printf(MSG_ERROR
, "Duplicate BSSID " MACSTR
1170 " on interface '%s' and '%s'.",
1171 MAC2STR(bss
->bssid
),
1172 conf
->bss
[i
].iface
, bss
->iface
);
1178 #ifdef CONFIG_IEEE80211R
1179 if (wpa_key_mgmt_ft(bss
->wpa_key_mgmt
) &&
1180 (bss
->nas_identifier
== NULL
||
1181 os_strlen(bss
->nas_identifier
) < 1 ||
1182 os_strlen(bss
->nas_identifier
) > FT_R0KH_ID_MAX_LEN
)) {
1183 wpa_printf(MSG_ERROR
, "FT (IEEE 802.11r) requires "
1184 "nas_identifier to be configured as a 1..48 octet "
1188 #endif /* CONFIG_IEEE80211R */
1190 #ifdef CONFIG_IEEE80211N
1191 if (conf
->ieee80211n
&& conf
->hw_mode
== HOSTAPD_MODE_IEEE80211B
) {
1192 bss
->disable_11n
= 1;
1193 wpa_printf(MSG_ERROR
, "HT (IEEE 802.11n) in 11b mode is not "
1194 "allowed, disabling HT capabilites");
1197 if (conf
->ieee80211n
&&
1198 bss
->ssid
.security_policy
== SECURITY_STATIC_WEP
) {
1199 bss
->disable_11n
= 1;
1200 wpa_printf(MSG_ERROR
, "HT (IEEE 802.11n) with WEP is not "
1201 "allowed, disabling HT capabilities");
1204 if (conf
->ieee80211n
&& bss
->wpa
&&
1205 !(bss
->wpa_pairwise
& WPA_CIPHER_CCMP
) &&
1206 !(bss
->rsn_pairwise
& WPA_CIPHER_CCMP
)) {
1207 bss
->disable_11n
= 1;
1208 wpa_printf(MSG_ERROR
, "HT (IEEE 802.11n) with WPA/WPA2 "
1209 "requires CCMP to be enabled, disabling HT "
1212 #endif /* CONFIG_IEEE80211N */
1215 if (bss
->wps_state
&& bss
->ignore_broadcast_ssid
) {
1216 wpa_printf(MSG_INFO
, "WPS: ignore_broadcast_ssid "
1217 "configuration forced WPS to be disabled");
1221 if (bss
->wps_state
&& bss
->ssid
.wep
.keys_set
&& bss
->wpa
== 0) {
1222 wpa_printf(MSG_INFO
, "WPS: WEP configuration forced WPS to be "
1226 #endif /* CONFIG_WPS2 */
1232 static int hostapd_config_check(struct hostapd_config
*conf
)
1236 if (conf
->ieee80211d
&& (!conf
->country
[0] || !conf
->country
[1])) {
1237 wpa_printf(MSG_ERROR
, "Cannot enable IEEE 802.11d without "
1238 "setting the country_code");
1242 for (i
= 0; i
< conf
->num_bss
; i
++) {
1243 if (hostapd_config_check_bss(&conf
->bss
[i
], conf
))
1251 #ifdef CONFIG_INTERWORKING
1252 static int parse_roaming_consortium(struct hostapd_bss_config
*bss
, char *pos
,
1255 size_t len
= os_strlen(pos
);
1256 u8 oi
[MAX_ROAMING_CONSORTIUM_LEN
];
1258 struct hostapd_roaming_consortium
*rc
;
1260 if ((len
& 1) || len
< 2 * 3 || len
/ 2 > MAX_ROAMING_CONSORTIUM_LEN
||
1261 hexstr2bin(pos
, oi
, len
/ 2)) {
1262 wpa_printf(MSG_ERROR
, "Line %d: invalid roaming_consortium "
1268 rc
= os_realloc(bss
->roaming_consortium
,
1269 sizeof(struct hostapd_roaming_consortium
) *
1270 (bss
->roaming_consortium_count
+ 1));
1274 os_memcpy(rc
[bss
->roaming_consortium_count
].oi
, oi
, len
);
1275 rc
[bss
->roaming_consortium_count
].len
= len
;
1277 bss
->roaming_consortium
= rc
;
1278 bss
->roaming_consortium_count
++;
1284 static int parse_venue_name(struct hostapd_bss_config
*bss
, char *pos
,
1289 struct hostapd_venue_name
*vn
;
1291 sep
= os_strchr(pos
, ':');
1296 clen
= os_strlen(pos
);
1299 nlen
= os_strlen(sep
);
1303 vn
= os_realloc(bss
->venue_name
,
1304 sizeof(struct hostapd_venue_name
) *
1305 (bss
->venue_name_count
+ 1));
1309 bss
->venue_name
= vn
;
1310 vn
= &bss
->venue_name
[bss
->venue_name_count
];
1311 bss
->venue_name_count
++;
1313 os_memset(vn
->lang
, 0, sizeof(vn
->lang
));
1314 os_memcpy(vn
->lang
, pos
, clen
);
1315 vn
->name_len
= nlen
;
1316 os_memcpy(vn
->name
, sep
, nlen
);
1321 wpa_printf(MSG_ERROR
, "Line %d: Invalid venue_name '%s'",
1325 #endif /* CONFIG_INTERWORKING */
1328 #ifdef CONFIG_WPS_NFC
1329 static struct wpabuf
* hostapd_parse_bin(const char *buf
)
1334 len
= os_strlen(buf
);
1339 ret
= wpabuf_alloc(len
);
1343 if (hexstr2bin(buf
, wpabuf_put(ret
, len
), len
)) {
1350 #endif /* CONFIG_WPS_NFC */
1353 static int hostapd_config_fill(struct hostapd_config
*conf
,
1354 struct hostapd_bss_config
*bss
,
1355 char *buf
, char *pos
, int line
)
1360 if (os_strcmp(buf
, "interface") == 0) {
1361 os_strlcpy(conf
->bss
[0].iface
, pos
,
1362 sizeof(conf
->bss
[0].iface
));
1363 } else if (os_strcmp(buf
, "bridge") == 0) {
1364 os_strlcpy(bss
->bridge
, pos
, sizeof(bss
->bridge
));
1365 } else if (os_strcmp(buf
, "wds_bridge") == 0) {
1366 os_strlcpy(bss
->wds_bridge
, pos
,
1367 sizeof(bss
->wds_bridge
));
1368 } else if (os_strcmp(buf
, "driver") == 0) {
1370 /* clear to get error below if setting is invalid */
1371 conf
->driver
= NULL
;
1372 for (j
= 0; wpa_drivers
[j
]; j
++) {
1373 if (os_strcmp(pos
, wpa_drivers
[j
]->name
) == 0)
1375 conf
->driver
= wpa_drivers
[j
];
1379 if (conf
->driver
== NULL
) {
1380 wpa_printf(MSG_ERROR
, "Line %d: invalid/"
1381 "unknown driver '%s'", line
, pos
);
1384 } else if (os_strcmp(buf
, "debug") == 0) {
1385 wpa_printf(MSG_DEBUG
, "Line %d: DEPRECATED: 'debug' "
1386 "configuration variable is not used "
1388 } else if (os_strcmp(buf
, "logger_syslog_level") == 0) {
1389 bss
->logger_syslog_level
= atoi(pos
);
1390 } else if (os_strcmp(buf
, "logger_stdout_level") == 0) {
1391 bss
->logger_stdout_level
= atoi(pos
);
1392 } else if (os_strcmp(buf
, "logger_syslog") == 0) {
1393 bss
->logger_syslog
= atoi(pos
);
1394 } else if (os_strcmp(buf
, "logger_stdout") == 0) {
1395 bss
->logger_stdout
= atoi(pos
);
1396 } else if (os_strcmp(buf
, "dump_file") == 0) {
1397 bss
->dump_log_name
= os_strdup(pos
);
1398 } else if (os_strcmp(buf
, "ssid") == 0) {
1399 bss
->ssid
.ssid_len
= os_strlen(pos
);
1400 if (bss
->ssid
.ssid_len
> HOSTAPD_MAX_SSID_LEN
||
1401 bss
->ssid
.ssid_len
< 1) {
1402 wpa_printf(MSG_ERROR
, "Line %d: invalid SSID "
1406 os_memcpy(bss
->ssid
.ssid
, pos
,
1407 bss
->ssid
.ssid_len
);
1408 bss
->ssid
.ssid
[bss
->ssid
.ssid_len
] = '\0';
1409 bss
->ssid
.ssid_set
= 1;
1411 } else if (os_strcmp(buf
, "macaddr_acl") == 0) {
1412 bss
->macaddr_acl
= atoi(pos
);
1413 if (bss
->macaddr_acl
!= ACCEPT_UNLESS_DENIED
&&
1414 bss
->macaddr_acl
!= DENY_UNLESS_ACCEPTED
&&
1415 bss
->macaddr_acl
!= USE_EXTERNAL_RADIUS_AUTH
) {
1416 wpa_printf(MSG_ERROR
, "Line %d: unknown "
1418 line
, bss
->macaddr_acl
);
1420 } else if (os_strcmp(buf
, "accept_mac_file") == 0) {
1421 if (hostapd_config_read_maclist(pos
, &bss
->accept_mac
,
1422 &bss
->num_accept_mac
))
1424 wpa_printf(MSG_ERROR
, "Line %d: Failed to "
1425 "read accept_mac_file '%s'",
1429 } else if (os_strcmp(buf
, "deny_mac_file") == 0) {
1430 if (hostapd_config_read_maclist(pos
, &bss
->deny_mac
,
1431 &bss
->num_deny_mac
)) {
1432 wpa_printf(MSG_ERROR
, "Line %d: Failed to "
1433 "read deny_mac_file '%s'",
1437 } else if (os_strcmp(buf
, "wds_sta") == 0) {
1438 bss
->wds_sta
= atoi(pos
);
1439 } else if (os_strcmp(buf
, "ap_isolate") == 0) {
1440 bss
->isolate
= atoi(pos
);
1441 } else if (os_strcmp(buf
, "ap_max_inactivity") == 0) {
1442 bss
->ap_max_inactivity
= atoi(pos
);
1443 } else if (os_strcmp(buf
, "skip_inactivity_poll") == 0) {
1444 bss
->skip_inactivity_poll
= atoi(pos
);
1445 } else if (os_strcmp(buf
, "country_code") == 0) {
1446 os_memcpy(conf
->country
, pos
, 2);
1447 /* FIX: make this configurable */
1448 conf
->country
[2] = ' ';
1449 } else if (os_strcmp(buf
, "ieee80211d") == 0) {
1450 conf
->ieee80211d
= atoi(pos
);
1451 } else if (os_strcmp(buf
, "ieee8021x") == 0) {
1452 bss
->ieee802_1x
= atoi(pos
);
1453 } else if (os_strcmp(buf
, "eapol_version") == 0) {
1454 bss
->eapol_version
= atoi(pos
);
1455 if (bss
->eapol_version
< 1 ||
1456 bss
->eapol_version
> 2) {
1457 wpa_printf(MSG_ERROR
, "Line %d: invalid EAPOL "
1458 "version (%d): '%s'.",
1459 line
, bss
->eapol_version
, pos
);
1462 wpa_printf(MSG_DEBUG
, "eapol_version=%d",
1463 bss
->eapol_version
);
1465 } else if (os_strcmp(buf
, "eap_authenticator") == 0) {
1466 bss
->eap_server
= atoi(pos
);
1467 wpa_printf(MSG_ERROR
, "Line %d: obsolete "
1468 "eap_authenticator used; this has been "
1469 "renamed to eap_server", line
);
1470 } else if (os_strcmp(buf
, "eap_server") == 0) {
1471 bss
->eap_server
= atoi(pos
);
1472 } else if (os_strcmp(buf
, "eap_user_file") == 0) {
1473 if (hostapd_config_read_eap_user(pos
, bss
))
1475 } else if (os_strcmp(buf
, "ca_cert") == 0) {
1476 os_free(bss
->ca_cert
);
1477 bss
->ca_cert
= os_strdup(pos
);
1478 } else if (os_strcmp(buf
, "server_cert") == 0) {
1479 os_free(bss
->server_cert
);
1480 bss
->server_cert
= os_strdup(pos
);
1481 } else if (os_strcmp(buf
, "private_key") == 0) {
1482 os_free(bss
->private_key
);
1483 bss
->private_key
= os_strdup(pos
);
1484 } else if (os_strcmp(buf
, "private_key_passwd") == 0) {
1485 os_free(bss
->private_key_passwd
);
1486 bss
->private_key_passwd
= os_strdup(pos
);
1487 } else if (os_strcmp(buf
, "check_crl") == 0) {
1488 bss
->check_crl
= atoi(pos
);
1489 } else if (os_strcmp(buf
, "dh_file") == 0) {
1490 os_free(bss
->dh_file
);
1491 bss
->dh_file
= os_strdup(pos
);
1492 } else if (os_strcmp(buf
, "fragment_size") == 0) {
1493 bss
->fragment_size
= atoi(pos
);
1494 #ifdef EAP_SERVER_FAST
1495 } else if (os_strcmp(buf
, "pac_opaque_encr_key") == 0) {
1496 os_free(bss
->pac_opaque_encr_key
);
1497 bss
->pac_opaque_encr_key
= os_malloc(16);
1498 if (bss
->pac_opaque_encr_key
== NULL
) {
1499 wpa_printf(MSG_ERROR
, "Line %d: No memory for "
1500 "pac_opaque_encr_key", line
);
1502 } else if (hexstr2bin(pos
, bss
->pac_opaque_encr_key
,
1504 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
1505 "pac_opaque_encr_key", line
);
1508 } else if (os_strcmp(buf
, "eap_fast_a_id") == 0) {
1509 size_t idlen
= os_strlen(pos
);
1511 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
1512 "eap_fast_a_id", line
);
1515 os_free(bss
->eap_fast_a_id
);
1516 bss
->eap_fast_a_id
= os_malloc(idlen
/ 2);
1517 if (bss
->eap_fast_a_id
== NULL
||
1518 hexstr2bin(pos
, bss
->eap_fast_a_id
,
1520 wpa_printf(MSG_ERROR
, "Line %d: "
1522 "eap_fast_a_id", line
);
1525 bss
->eap_fast_a_id_len
= idlen
/ 2;
1527 } else if (os_strcmp(buf
, "eap_fast_a_id_info") == 0) {
1528 os_free(bss
->eap_fast_a_id_info
);
1529 bss
->eap_fast_a_id_info
= os_strdup(pos
);
1530 } else if (os_strcmp(buf
, "eap_fast_prov") == 0) {
1531 bss
->eap_fast_prov
= atoi(pos
);
1532 } else if (os_strcmp(buf
, "pac_key_lifetime") == 0) {
1533 bss
->pac_key_lifetime
= atoi(pos
);
1534 } else if (os_strcmp(buf
, "pac_key_refresh_time") == 0) {
1535 bss
->pac_key_refresh_time
= atoi(pos
);
1536 #endif /* EAP_SERVER_FAST */
1537 #ifdef EAP_SERVER_SIM
1538 } else if (os_strcmp(buf
, "eap_sim_db") == 0) {
1539 os_free(bss
->eap_sim_db
);
1540 bss
->eap_sim_db
= os_strdup(pos
);
1541 } else if (os_strcmp(buf
, "eap_sim_aka_result_ind") == 0) {
1542 bss
->eap_sim_aka_result_ind
= atoi(pos
);
1543 #endif /* EAP_SERVER_SIM */
1544 #ifdef EAP_SERVER_TNC
1545 } else if (os_strcmp(buf
, "tnc") == 0) {
1546 bss
->tnc
= atoi(pos
);
1547 #endif /* EAP_SERVER_TNC */
1548 #ifdef EAP_SERVER_PWD
1549 } else if (os_strcmp(buf
, "pwd_group") == 0) {
1550 bss
->pwd_group
= atoi(pos
);
1551 #endif /* EAP_SERVER_PWD */
1552 #endif /* EAP_SERVER */
1553 } else if (os_strcmp(buf
, "eap_message") == 0) {
1555 bss
->eap_req_id_text
= os_strdup(pos
);
1556 if (bss
->eap_req_id_text
== NULL
) {
1557 wpa_printf(MSG_ERROR
, "Line %d: Failed to "
1558 "allocate memory for "
1559 "eap_req_id_text", line
);
1563 bss
->eap_req_id_text_len
=
1564 os_strlen(bss
->eap_req_id_text
);
1565 term
= os_strstr(bss
->eap_req_id_text
, "\\0");
1568 os_memmove(term
, term
+ 1,
1569 bss
->eap_req_id_text_len
-
1570 (term
- bss
->eap_req_id_text
) - 1);
1571 bss
->eap_req_id_text_len
--;
1573 } else if (os_strcmp(buf
, "wep_key_len_broadcast") == 0) {
1574 bss
->default_wep_key_len
= atoi(pos
);
1575 if (bss
->default_wep_key_len
> 13) {
1576 wpa_printf(MSG_ERROR
, "Line %d: invalid WEP "
1577 "key len %lu (= %lu bits)", line
,
1579 bss
->default_wep_key_len
,
1581 bss
->default_wep_key_len
* 8);
1584 } else if (os_strcmp(buf
, "wep_key_len_unicast") == 0) {
1585 bss
->individual_wep_key_len
= atoi(pos
);
1586 if (bss
->individual_wep_key_len
< 0 ||
1587 bss
->individual_wep_key_len
> 13) {
1588 wpa_printf(MSG_ERROR
, "Line %d: invalid WEP "
1589 "key len %d (= %d bits)", line
,
1590 bss
->individual_wep_key_len
,
1591 bss
->individual_wep_key_len
* 8);
1594 } else if (os_strcmp(buf
, "wep_rekey_period") == 0) {
1595 bss
->wep_rekeying_period
= atoi(pos
);
1596 if (bss
->wep_rekeying_period
< 0) {
1597 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1599 line
, bss
->wep_rekeying_period
);
1602 } else if (os_strcmp(buf
, "eap_reauth_period") == 0) {
1603 bss
->eap_reauth_period
= atoi(pos
);
1604 if (bss
->eap_reauth_period
< 0) {
1605 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1607 line
, bss
->eap_reauth_period
);
1610 } else if (os_strcmp(buf
, "eapol_key_index_workaround") == 0) {
1611 bss
->eapol_key_index_workaround
= atoi(pos
);
1613 } else if (os_strcmp(buf
, "iapp_interface") == 0) {
1614 bss
->ieee802_11f
= 1;
1615 os_strlcpy(bss
->iapp_iface
, pos
,
1616 sizeof(bss
->iapp_iface
));
1617 #endif /* CONFIG_IAPP */
1618 } else if (os_strcmp(buf
, "own_ip_addr") == 0) {
1619 if (hostapd_parse_ip_addr(pos
, &bss
->own_ip_addr
)) {
1620 wpa_printf(MSG_ERROR
, "Line %d: invalid IP "
1621 "address '%s'", line
, pos
);
1624 } else if (os_strcmp(buf
, "nas_identifier") == 0) {
1625 bss
->nas_identifier
= os_strdup(pos
);
1626 #ifndef CONFIG_NO_RADIUS
1627 } else if (os_strcmp(buf
, "auth_server_addr") == 0) {
1628 if (hostapd_config_read_radius_addr(
1629 &bss
->radius
->auth_servers
,
1630 &bss
->radius
->num_auth_servers
, pos
, 1812,
1631 &bss
->radius
->auth_server
)) {
1632 wpa_printf(MSG_ERROR
, "Line %d: invalid IP "
1633 "address '%s'", line
, pos
);
1636 } else if (bss
->radius
->auth_server
&&
1637 os_strcmp(buf
, "auth_server_port") == 0) {
1638 bss
->radius
->auth_server
->port
= atoi(pos
);
1639 } else if (bss
->radius
->auth_server
&&
1640 os_strcmp(buf
, "auth_server_shared_secret") == 0) {
1641 int len
= os_strlen(pos
);
1643 /* RFC 2865, Ch. 3 */
1644 wpa_printf(MSG_ERROR
, "Line %d: empty shared "
1645 "secret is not allowed.", line
);
1648 bss
->radius
->auth_server
->shared_secret
=
1649 (u8
*) os_strdup(pos
);
1650 bss
->radius
->auth_server
->shared_secret_len
= len
;
1651 } else if (os_strcmp(buf
, "acct_server_addr") == 0) {
1652 if (hostapd_config_read_radius_addr(
1653 &bss
->radius
->acct_servers
,
1654 &bss
->radius
->num_acct_servers
, pos
, 1813,
1655 &bss
->radius
->acct_server
)) {
1656 wpa_printf(MSG_ERROR
, "Line %d: invalid IP "
1657 "address '%s'", line
, pos
);
1660 } else if (bss
->radius
->acct_server
&&
1661 os_strcmp(buf
, "acct_server_port") == 0) {
1662 bss
->radius
->acct_server
->port
= atoi(pos
);
1663 } else if (bss
->radius
->acct_server
&&
1664 os_strcmp(buf
, "acct_server_shared_secret") == 0) {
1665 int len
= os_strlen(pos
);
1667 /* RFC 2865, Ch. 3 */
1668 wpa_printf(MSG_ERROR
, "Line %d: empty shared "
1669 "secret is not allowed.", line
);
1672 bss
->radius
->acct_server
->shared_secret
=
1673 (u8
*) os_strdup(pos
);
1674 bss
->radius
->acct_server
->shared_secret_len
= len
;
1675 } else if (os_strcmp(buf
, "radius_retry_primary_interval") ==
1677 bss
->radius
->retry_primary_interval
= atoi(pos
);
1678 } else if (os_strcmp(buf
, "radius_acct_interim_interval") == 0)
1680 bss
->acct_interim_interval
= atoi(pos
);
1681 } else if (os_strcmp(buf
, "radius_request_cui") == 0) {
1682 bss
->radius_request_cui
= atoi(pos
);
1683 } else if (os_strcmp(buf
, "radius_auth_req_attr") == 0) {
1684 struct hostapd_radius_attr
*attr
, *a
;
1685 attr
= hostapd_parse_radius_attr(pos
);
1687 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1688 "radius_auth_req_attr", line
);
1690 } else if (bss
->radius_auth_req_attr
== NULL
) {
1691 bss
->radius_auth_req_attr
= attr
;
1693 a
= bss
->radius_auth_req_attr
;
1698 } else if (os_strcmp(buf
, "radius_acct_req_attr") == 0) {
1699 struct hostapd_radius_attr
*attr
, *a
;
1700 attr
= hostapd_parse_radius_attr(pos
);
1702 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1703 "radius_acct_req_attr", line
);
1705 } else if (bss
->radius_acct_req_attr
== NULL
) {
1706 bss
->radius_acct_req_attr
= attr
;
1708 a
= bss
->radius_acct_req_attr
;
1713 } else if (os_strcmp(buf
, "radius_das_port") == 0) {
1714 bss
->radius_das_port
= atoi(pos
);
1715 } else if (os_strcmp(buf
, "radius_das_client") == 0) {
1716 if (hostapd_parse_das_client(bss
, pos
) < 0) {
1717 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1718 "DAS client", line
);
1721 } else if (os_strcmp(buf
, "radius_das_time_window") == 0) {
1722 bss
->radius_das_time_window
= atoi(pos
);
1723 } else if (os_strcmp(buf
, "radius_das_require_event_timestamp")
1725 bss
->radius_das_require_event_timestamp
= atoi(pos
);
1726 #endif /* CONFIG_NO_RADIUS */
1727 } else if (os_strcmp(buf
, "auth_algs") == 0) {
1728 bss
->auth_algs
= atoi(pos
);
1729 if (bss
->auth_algs
== 0) {
1730 wpa_printf(MSG_ERROR
, "Line %d: no "
1731 "authentication algorithms allowed",
1735 } else if (os_strcmp(buf
, "max_num_sta") == 0) {
1736 bss
->max_num_sta
= atoi(pos
);
1737 if (bss
->max_num_sta
< 0 ||
1738 bss
->max_num_sta
> MAX_STA_COUNT
) {
1739 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
1740 "max_num_sta=%d; allowed range "
1741 "0..%d", line
, bss
->max_num_sta
,
1745 } else if (os_strcmp(buf
, "wpa") == 0) {
1746 bss
->wpa
= atoi(pos
);
1747 } else if (os_strcmp(buf
, "wpa_group_rekey") == 0) {
1748 bss
->wpa_group_rekey
= atoi(pos
);
1749 } else if (os_strcmp(buf
, "wpa_strict_rekey") == 0) {
1750 bss
->wpa_strict_rekey
= atoi(pos
);
1751 } else if (os_strcmp(buf
, "wpa_gmk_rekey") == 0) {
1752 bss
->wpa_gmk_rekey
= atoi(pos
);
1753 } else if (os_strcmp(buf
, "wpa_ptk_rekey") == 0) {
1754 bss
->wpa_ptk_rekey
= atoi(pos
);
1755 } else if (os_strcmp(buf
, "wpa_passphrase") == 0) {
1756 int len
= os_strlen(pos
);
1757 if (len
< 8 || len
> 63) {
1758 wpa_printf(MSG_ERROR
, "Line %d: invalid WPA "
1759 "passphrase length %d (expected "
1760 "8..63)", line
, len
);
1763 os_free(bss
->ssid
.wpa_passphrase
);
1764 bss
->ssid
.wpa_passphrase
= os_strdup(pos
);
1765 os_free(bss
->ssid
.wpa_psk
);
1766 bss
->ssid
.wpa_psk
= NULL
;
1768 } else if (os_strcmp(buf
, "wpa_psk") == 0) {
1769 os_free(bss
->ssid
.wpa_psk
);
1771 os_zalloc(sizeof(struct hostapd_wpa_psk
));
1772 if (bss
->ssid
.wpa_psk
== NULL
)
1774 else if (hexstr2bin(pos
, bss
->ssid
.wpa_psk
->psk
,
1776 pos
[PMK_LEN
* 2] != '\0') {
1777 wpa_printf(MSG_ERROR
, "Line %d: Invalid PSK "
1778 "'%s'.", line
, pos
);
1781 bss
->ssid
.wpa_psk
->group
= 1;
1782 os_free(bss
->ssid
.wpa_passphrase
);
1783 bss
->ssid
.wpa_passphrase
= NULL
;
1785 } else if (os_strcmp(buf
, "wpa_psk_file") == 0) {
1786 os_free(bss
->ssid
.wpa_psk_file
);
1787 bss
->ssid
.wpa_psk_file
= os_strdup(pos
);
1788 if (!bss
->ssid
.wpa_psk_file
) {
1789 wpa_printf(MSG_ERROR
, "Line %d: allocation "
1793 } else if (os_strcmp(buf
, "wpa_key_mgmt") == 0) {
1795 hostapd_config_parse_key_mgmt(line
, pos
);
1796 if (bss
->wpa_key_mgmt
== -1)
1798 } else if (os_strcmp(buf
, "wpa_psk_radius") == 0) {
1799 bss
->wpa_psk_radius
= atoi(pos
);
1800 if (bss
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
&&
1801 bss
->wpa_psk_radius
!= PSK_RADIUS_ACCEPTED
&&
1802 bss
->wpa_psk_radius
!= PSK_RADIUS_REQUIRED
) {
1803 wpa_printf(MSG_ERROR
, "Line %d: unknown "
1804 "wpa_psk_radius %d",
1805 line
, bss
->wpa_psk_radius
);
1808 } else if (os_strcmp(buf
, "wpa_pairwise") == 0) {
1810 hostapd_config_parse_cipher(line
, pos
);
1811 if (bss
->wpa_pairwise
== -1 ||
1812 bss
->wpa_pairwise
== 0)
1814 else if (bss
->wpa_pairwise
&
1815 (WPA_CIPHER_NONE
| WPA_CIPHER_WEP40
|
1816 WPA_CIPHER_WEP104
)) {
1817 wpa_printf(MSG_ERROR
, "Line %d: unsupported "
1818 "pairwise cipher suite '%s'",
1819 bss
->wpa_pairwise
, pos
);
1822 } else if (os_strcmp(buf
, "rsn_pairwise") == 0) {
1824 hostapd_config_parse_cipher(line
, pos
);
1825 if (bss
->rsn_pairwise
== -1 ||
1826 bss
->rsn_pairwise
== 0)
1828 else if (bss
->rsn_pairwise
&
1829 (WPA_CIPHER_NONE
| WPA_CIPHER_WEP40
|
1830 WPA_CIPHER_WEP104
)) {
1831 wpa_printf(MSG_ERROR
, "Line %d: unsupported "
1832 "pairwise cipher suite '%s'",
1833 bss
->rsn_pairwise
, pos
);
1836 #ifdef CONFIG_RSN_PREAUTH
1837 } else if (os_strcmp(buf
, "rsn_preauth") == 0) {
1838 bss
->rsn_preauth
= atoi(pos
);
1839 } else if (os_strcmp(buf
, "rsn_preauth_interfaces") == 0) {
1840 bss
->rsn_preauth_interfaces
= os_strdup(pos
);
1841 #endif /* CONFIG_RSN_PREAUTH */
1842 #ifdef CONFIG_PEERKEY
1843 } else if (os_strcmp(buf
, "peerkey") == 0) {
1844 bss
->peerkey
= atoi(pos
);
1845 #endif /* CONFIG_PEERKEY */
1846 #ifdef CONFIG_IEEE80211R
1847 } else if (os_strcmp(buf
, "mobility_domain") == 0) {
1848 if (os_strlen(pos
) != 2 * MOBILITY_DOMAIN_ID_LEN
||
1849 hexstr2bin(pos
, bss
->mobility_domain
,
1850 MOBILITY_DOMAIN_ID_LEN
) != 0) {
1851 wpa_printf(MSG_DEBUG
, "Line %d: Invalid "
1852 "mobility_domain '%s'", line
, pos
);
1856 } else if (os_strcmp(buf
, "r1_key_holder") == 0) {
1857 if (os_strlen(pos
) != 2 * FT_R1KH_ID_LEN
||
1858 hexstr2bin(pos
, bss
->r1_key_holder
,
1859 FT_R1KH_ID_LEN
) != 0) {
1860 wpa_printf(MSG_DEBUG
, "Line %d: Invalid "
1861 "r1_key_holder '%s'", line
, pos
);
1865 } else if (os_strcmp(buf
, "r0_key_lifetime") == 0) {
1866 bss
->r0_key_lifetime
= atoi(pos
);
1867 } else if (os_strcmp(buf
, "reassociation_deadline") == 0) {
1868 bss
->reassociation_deadline
= atoi(pos
);
1869 } else if (os_strcmp(buf
, "r0kh") == 0) {
1870 if (add_r0kh(bss
, pos
) < 0) {
1871 wpa_printf(MSG_DEBUG
, "Line %d: Invalid "
1872 "r0kh '%s'", line
, pos
);
1876 } else if (os_strcmp(buf
, "r1kh") == 0) {
1877 if (add_r1kh(bss
, pos
) < 0) {
1878 wpa_printf(MSG_DEBUG
, "Line %d: Invalid "
1879 "r1kh '%s'", line
, pos
);
1883 } else if (os_strcmp(buf
, "pmk_r1_push") == 0) {
1884 bss
->pmk_r1_push
= atoi(pos
);
1885 } else if (os_strcmp(buf
, "ft_over_ds") == 0) {
1886 bss
->ft_over_ds
= atoi(pos
);
1887 #endif /* CONFIG_IEEE80211R */
1888 #ifndef CONFIG_NO_CTRL_IFACE
1889 } else if (os_strcmp(buf
, "ctrl_interface") == 0) {
1890 os_free(bss
->ctrl_interface
);
1891 bss
->ctrl_interface
= os_strdup(pos
);
1892 } else if (os_strcmp(buf
, "ctrl_interface_group") == 0) {
1893 #ifndef CONFIG_NATIVE_WINDOWS
1896 const char *group
= pos
;
1898 grp
= getgrnam(group
);
1900 bss
->ctrl_interface_gid
= grp
->gr_gid
;
1901 bss
->ctrl_interface_gid_set
= 1;
1902 wpa_printf(MSG_DEBUG
, "ctrl_interface_group=%d"
1903 " (from group name '%s')",
1904 bss
->ctrl_interface_gid
, group
);
1908 /* Group name not found - try to parse this as gid */
1909 bss
->ctrl_interface_gid
= strtol(group
, &endp
, 10);
1910 if (*group
== '\0' || *endp
!= '\0') {
1911 wpa_printf(MSG_DEBUG
, "Line %d: Invalid group "
1912 "'%s'", line
, group
);
1916 bss
->ctrl_interface_gid_set
= 1;
1917 wpa_printf(MSG_DEBUG
, "ctrl_interface_group=%d",
1918 bss
->ctrl_interface_gid
);
1919 #endif /* CONFIG_NATIVE_WINDOWS */
1920 #endif /* CONFIG_NO_CTRL_IFACE */
1921 #ifdef RADIUS_SERVER
1922 } else if (os_strcmp(buf
, "radius_server_clients") == 0) {
1923 os_free(bss
->radius_server_clients
);
1924 bss
->radius_server_clients
= os_strdup(pos
);
1925 } else if (os_strcmp(buf
, "radius_server_auth_port") == 0) {
1926 bss
->radius_server_auth_port
= atoi(pos
);
1927 } else if (os_strcmp(buf
, "radius_server_ipv6") == 0) {
1928 bss
->radius_server_ipv6
= atoi(pos
);
1929 #endif /* RADIUS_SERVER */
1930 } else if (os_strcmp(buf
, "test_socket") == 0) {
1931 os_free(bss
->test_socket
);
1932 bss
->test_socket
= os_strdup(pos
);
1933 } else if (os_strcmp(buf
, "use_pae_group_addr") == 0) {
1934 bss
->use_pae_group_addr
= atoi(pos
);
1935 } else if (os_strcmp(buf
, "hw_mode") == 0) {
1936 if (os_strcmp(pos
, "a") == 0)
1937 conf
->hw_mode
= HOSTAPD_MODE_IEEE80211A
;
1938 else if (os_strcmp(pos
, "b") == 0)
1939 conf
->hw_mode
= HOSTAPD_MODE_IEEE80211B
;
1940 else if (os_strcmp(pos
, "g") == 0)
1941 conf
->hw_mode
= HOSTAPD_MODE_IEEE80211G
;
1943 wpa_printf(MSG_ERROR
, "Line %d: unknown "
1944 "hw_mode '%s'", line
, pos
);
1947 } else if (os_strcmp(buf
, "wps_rf_bands") == 0) {
1948 if (os_strcmp(pos
, "a") == 0)
1949 bss
->wps_rf_bands
= WPS_RF_50GHZ
;
1950 else if (os_strcmp(pos
, "g") == 0 ||
1951 os_strcmp(pos
, "b") == 0)
1952 bss
->wps_rf_bands
= WPS_RF_24GHZ
;
1953 else if (os_strcmp(pos
, "ag") == 0 ||
1954 os_strcmp(pos
, "ga") == 0)
1956 WPS_RF_24GHZ
| WPS_RF_50GHZ
;
1958 wpa_printf(MSG_ERROR
, "Line %d: unknown "
1959 "wps_rf_band '%s'", line
, pos
);
1962 } else if (os_strcmp(buf
, "channel") == 0) {
1963 conf
->channel
= atoi(pos
);
1964 } else if (os_strcmp(buf
, "beacon_int") == 0) {
1965 int val
= atoi(pos
);
1966 /* MIB defines range as 1..65535, but very small values
1967 * cause problems with the current implementation.
1968 * Since it is unlikely that this small numbers are
1969 * useful in real life scenarios, do not allow beacon
1970 * period to be set below 15 TU. */
1971 if (val
< 15 || val
> 65535) {
1972 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1973 "beacon_int %d (expected "
1974 "15..65535)", line
, val
);
1977 conf
->beacon_int
= val
;
1978 } else if (os_strcmp(buf
, "dtim_period") == 0) {
1979 bss
->dtim_period
= atoi(pos
);
1980 if (bss
->dtim_period
< 1 || bss
->dtim_period
> 255) {
1981 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1983 line
, bss
->dtim_period
);
1986 } else if (os_strcmp(buf
, "rts_threshold") == 0) {
1987 conf
->rts_threshold
= atoi(pos
);
1988 if (conf
->rts_threshold
< 0 ||
1989 conf
->rts_threshold
> 2347) {
1990 wpa_printf(MSG_ERROR
, "Line %d: invalid "
1992 line
, conf
->rts_threshold
);
1995 } else if (os_strcmp(buf
, "fragm_threshold") == 0) {
1996 conf
->fragm_threshold
= atoi(pos
);
1997 if (conf
->fragm_threshold
< 256 ||
1998 conf
->fragm_threshold
> 2346) {
1999 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2000 "fragm_threshold %d",
2001 line
, conf
->fragm_threshold
);
2004 } else if (os_strcmp(buf
, "send_probe_response") == 0) {
2005 int val
= atoi(pos
);
2006 if (val
!= 0 && val
!= 1) {
2007 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2008 "send_probe_response %d (expected "
2009 "0 or 1)", line
, val
);
2011 conf
->send_probe_response
= val
;
2012 } else if (os_strcmp(buf
, "supported_rates") == 0) {
2013 if (hostapd_parse_rates(&conf
->supported_rates
, pos
)) {
2014 wpa_printf(MSG_ERROR
, "Line %d: invalid rate "
2018 } else if (os_strcmp(buf
, "basic_rates") == 0) {
2019 if (hostapd_parse_rates(&conf
->basic_rates
, pos
)) {
2020 wpa_printf(MSG_ERROR
, "Line %d: invalid rate "
2024 } else if (os_strcmp(buf
, "preamble") == 0) {
2026 conf
->preamble
= SHORT_PREAMBLE
;
2028 conf
->preamble
= LONG_PREAMBLE
;
2029 } else if (os_strcmp(buf
, "ignore_broadcast_ssid") == 0) {
2030 bss
->ignore_broadcast_ssid
= atoi(pos
);
2031 } else if (os_strcmp(buf
, "wep_default_key") == 0) {
2032 bss
->ssid
.wep
.idx
= atoi(pos
);
2033 if (bss
->ssid
.wep
.idx
> 3) {
2034 wpa_printf(MSG_ERROR
, "Invalid "
2035 "wep_default_key index %d",
2039 } else if (os_strcmp(buf
, "wep_key0") == 0 ||
2040 os_strcmp(buf
, "wep_key1") == 0 ||
2041 os_strcmp(buf
, "wep_key2") == 0 ||
2042 os_strcmp(buf
, "wep_key3") == 0) {
2043 if (hostapd_config_read_wep(&bss
->ssid
.wep
,
2044 buf
[7] - '0', pos
)) {
2045 wpa_printf(MSG_ERROR
, "Line %d: invalid WEP "
2046 "key '%s'", line
, buf
);
2049 #ifndef CONFIG_NO_VLAN
2050 } else if (os_strcmp(buf
, "dynamic_vlan") == 0) {
2051 bss
->ssid
.dynamic_vlan
= atoi(pos
);
2052 } else if (os_strcmp(buf
, "vlan_file") == 0) {
2053 if (hostapd_config_read_vlan_file(bss
, pos
)) {
2054 wpa_printf(MSG_ERROR
, "Line %d: failed to "
2055 "read VLAN file '%s'", line
, pos
);
2058 #ifdef CONFIG_FULL_DYNAMIC_VLAN
2059 } else if (os_strcmp(buf
, "vlan_tagged_interface") == 0) {
2060 bss
->ssid
.vlan_tagged_interface
= os_strdup(pos
);
2061 #endif /* CONFIG_FULL_DYNAMIC_VLAN */
2062 #endif /* CONFIG_NO_VLAN */
2063 } else if (os_strcmp(buf
, "ap_table_max_size") == 0) {
2064 conf
->ap_table_max_size
= atoi(pos
);
2065 } else if (os_strcmp(buf
, "ap_table_expiration_time") == 0) {
2066 conf
->ap_table_expiration_time
= atoi(pos
);
2067 } else if (os_strncmp(buf
, "tx_queue_", 9) == 0) {
2068 if (hostapd_config_tx_queue(conf
, buf
, pos
)) {
2069 wpa_printf(MSG_ERROR
, "Line %d: invalid TX "
2070 "queue item", line
);
2073 } else if (os_strcmp(buf
, "wme_enabled") == 0 ||
2074 os_strcmp(buf
, "wmm_enabled") == 0) {
2075 bss
->wmm_enabled
= atoi(pos
);
2076 } else if (os_strcmp(buf
, "uapsd_advertisement_enabled") == 0) {
2077 bss
->wmm_uapsd
= atoi(pos
);
2078 } else if (os_strncmp(buf
, "wme_ac_", 7) == 0 ||
2079 os_strncmp(buf
, "wmm_ac_", 7) == 0) {
2080 if (hostapd_config_wmm_ac(conf
, buf
, pos
)) {
2081 wpa_printf(MSG_ERROR
, "Line %d: invalid WMM "
2085 } else if (os_strcmp(buf
, "bss") == 0) {
2086 if (hostapd_config_bss(conf
, pos
)) {
2087 wpa_printf(MSG_ERROR
, "Line %d: invalid bss "
2091 } else if (os_strcmp(buf
, "bssid") == 0) {
2092 if (hwaddr_aton(pos
, bss
->bssid
)) {
2093 wpa_printf(MSG_ERROR
, "Line %d: invalid bssid "
2097 #ifdef CONFIG_IEEE80211W
2098 } else if (os_strcmp(buf
, "ieee80211w") == 0) {
2099 bss
->ieee80211w
= atoi(pos
);
2100 } else if (os_strcmp(buf
, "assoc_sa_query_max_timeout") == 0) {
2101 bss
->assoc_sa_query_max_timeout
= atoi(pos
);
2102 if (bss
->assoc_sa_query_max_timeout
== 0) {
2103 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2104 "assoc_sa_query_max_timeout", line
);
2107 } else if (os_strcmp(buf
, "assoc_sa_query_retry_timeout") == 0)
2109 bss
->assoc_sa_query_retry_timeout
= atoi(pos
);
2110 if (bss
->assoc_sa_query_retry_timeout
== 0) {
2111 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2112 "assoc_sa_query_retry_timeout",
2116 #endif /* CONFIG_IEEE80211W */
2117 #ifdef CONFIG_IEEE80211N
2118 } else if (os_strcmp(buf
, "ieee80211n") == 0) {
2119 conf
->ieee80211n
= atoi(pos
);
2120 } else if (os_strcmp(buf
, "ht_capab") == 0) {
2121 if (hostapd_config_ht_capab(conf
, pos
) < 0) {
2122 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2126 } else if (os_strcmp(buf
, "require_ht") == 0) {
2127 conf
->require_ht
= atoi(pos
);
2128 #endif /* CONFIG_IEEE80211N */
2129 } else if (os_strcmp(buf
, "max_listen_interval") == 0) {
2130 bss
->max_listen_interval
= atoi(pos
);
2131 } else if (os_strcmp(buf
, "disable_pmksa_caching") == 0) {
2132 bss
->disable_pmksa_caching
= atoi(pos
);
2133 } else if (os_strcmp(buf
, "okc") == 0) {
2134 bss
->okc
= atoi(pos
);
2136 } else if (os_strcmp(buf
, "wps_state") == 0) {
2137 bss
->wps_state
= atoi(pos
);
2138 if (bss
->wps_state
< 0 || bss
->wps_state
> 2) {
2139 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2143 } else if (os_strcmp(buf
, "ap_setup_locked") == 0) {
2144 bss
->ap_setup_locked
= atoi(pos
);
2145 } else if (os_strcmp(buf
, "uuid") == 0) {
2146 if (uuid_str2bin(pos
, bss
->uuid
)) {
2147 wpa_printf(MSG_ERROR
, "Line %d: invalid UUID",
2151 } else if (os_strcmp(buf
, "wps_pin_requests") == 0) {
2152 os_free(bss
->wps_pin_requests
);
2153 bss
->wps_pin_requests
= os_strdup(pos
);
2154 } else if (os_strcmp(buf
, "device_name") == 0) {
2155 if (os_strlen(pos
) > 32) {
2156 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2157 "device_name", line
);
2160 os_free(bss
->device_name
);
2161 bss
->device_name
= os_strdup(pos
);
2162 } else if (os_strcmp(buf
, "manufacturer") == 0) {
2163 if (os_strlen(pos
) > 64) {
2164 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2165 "manufacturer", line
);
2168 os_free(bss
->manufacturer
);
2169 bss
->manufacturer
= os_strdup(pos
);
2170 } else if (os_strcmp(buf
, "model_name") == 0) {
2171 if (os_strlen(pos
) > 32) {
2172 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2173 "model_name", line
);
2176 os_free(bss
->model_name
);
2177 bss
->model_name
= os_strdup(pos
);
2178 } else if (os_strcmp(buf
, "model_number") == 0) {
2179 if (os_strlen(pos
) > 32) {
2180 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2181 "model_number", line
);
2184 os_free(bss
->model_number
);
2185 bss
->model_number
= os_strdup(pos
);
2186 } else if (os_strcmp(buf
, "serial_number") == 0) {
2187 if (os_strlen(pos
) > 32) {
2188 wpa_printf(MSG_ERROR
, "Line %d: Too long "
2189 "serial_number", line
);
2192 os_free(bss
->serial_number
);
2193 bss
->serial_number
= os_strdup(pos
);
2194 } else if (os_strcmp(buf
, "device_type") == 0) {
2195 if (wps_dev_type_str2bin(pos
, bss
->device_type
))
2197 } else if (os_strcmp(buf
, "config_methods") == 0) {
2198 os_free(bss
->config_methods
);
2199 bss
->config_methods
= os_strdup(pos
);
2200 } else if (os_strcmp(buf
, "os_version") == 0) {
2201 if (hexstr2bin(pos
, bss
->os_version
, 4)) {
2202 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2203 "os_version", line
);
2206 } else if (os_strcmp(buf
, "ap_pin") == 0) {
2207 os_free(bss
->ap_pin
);
2208 bss
->ap_pin
= os_strdup(pos
);
2209 } else if (os_strcmp(buf
, "skip_cred_build") == 0) {
2210 bss
->skip_cred_build
= atoi(pos
);
2211 } else if (os_strcmp(buf
, "extra_cred") == 0) {
2212 os_free(bss
->extra_cred
);
2214 (u8
*) os_readfile(pos
, &bss
->extra_cred_len
);
2215 if (bss
->extra_cred
== NULL
) {
2216 wpa_printf(MSG_ERROR
, "Line %d: could not "
2217 "read Credentials from '%s'",
2221 } else if (os_strcmp(buf
, "wps_cred_processing") == 0) {
2222 bss
->wps_cred_processing
= atoi(pos
);
2223 } else if (os_strcmp(buf
, "ap_settings") == 0) {
2224 os_free(bss
->ap_settings
);
2226 (u8
*) os_readfile(pos
, &bss
->ap_settings_len
);
2227 if (bss
->ap_settings
== NULL
) {
2228 wpa_printf(MSG_ERROR
, "Line %d: could not "
2229 "read AP Settings from '%s'",
2233 } else if (os_strcmp(buf
, "upnp_iface") == 0) {
2234 bss
->upnp_iface
= os_strdup(pos
);
2235 } else if (os_strcmp(buf
, "friendly_name") == 0) {
2236 os_free(bss
->friendly_name
);
2237 bss
->friendly_name
= os_strdup(pos
);
2238 } else if (os_strcmp(buf
, "manufacturer_url") == 0) {
2239 os_free(bss
->manufacturer_url
);
2240 bss
->manufacturer_url
= os_strdup(pos
);
2241 } else if (os_strcmp(buf
, "model_description") == 0) {
2242 os_free(bss
->model_description
);
2243 bss
->model_description
= os_strdup(pos
);
2244 } else if (os_strcmp(buf
, "model_url") == 0) {
2245 os_free(bss
->model_url
);
2246 bss
->model_url
= os_strdup(pos
);
2247 } else if (os_strcmp(buf
, "upc") == 0) {
2249 bss
->upc
= os_strdup(pos
);
2250 } else if (os_strcmp(buf
, "pbc_in_m1") == 0) {
2251 bss
->pbc_in_m1
= atoi(pos
);
2252 #ifdef CONFIG_WPS_NFC
2253 } else if (os_strcmp(buf
, "wps_nfc_dev_pw_id") == 0) {
2254 bss
->wps_nfc_dev_pw_id
= atoi(pos
);
2255 if (bss
->wps_nfc_dev_pw_id
< 0x10 ||
2256 bss
->wps_nfc_dev_pw_id
> 0xffff) {
2257 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
2258 "wps_nfc_dev_pw_id value", line
);
2261 } else if (os_strcmp(buf
, "wps_nfc_dh_pubkey") == 0) {
2262 wpabuf_free(bss
->wps_nfc_dh_pubkey
);
2263 bss
->wps_nfc_dh_pubkey
= hostapd_parse_bin(pos
);
2264 } else if (os_strcmp(buf
, "wps_nfc_dh_privkey") == 0) {
2265 wpabuf_free(bss
->wps_nfc_dh_privkey
);
2266 bss
->wps_nfc_dh_privkey
= hostapd_parse_bin(pos
);
2267 } else if (os_strcmp(buf
, "wps_nfc_dev_pw") == 0) {
2268 wpabuf_free(bss
->wps_nfc_dev_pw
);
2269 bss
->wps_nfc_dev_pw
= hostapd_parse_bin(pos
);
2270 #endif /* CONFIG_WPS_NFC */
2271 #endif /* CONFIG_WPS */
2272 #ifdef CONFIG_P2P_MANAGER
2273 } else if (os_strcmp(buf
, "manage_p2p") == 0) {
2274 int manage
= atoi(pos
);
2276 bss
->p2p
|= P2P_MANAGE
;
2278 bss
->p2p
&= ~P2P_MANAGE
;
2279 } else if (os_strcmp(buf
, "allow_cross_connection") == 0) {
2281 bss
->p2p
|= P2P_ALLOW_CROSS_CONNECTION
;
2283 bss
->p2p
&= ~P2P_ALLOW_CROSS_CONNECTION
;
2284 #endif /* CONFIG_P2P_MANAGER */
2285 } else if (os_strcmp(buf
, "disassoc_low_ack") == 0) {
2286 bss
->disassoc_low_ack
= atoi(pos
);
2287 } else if (os_strcmp(buf
, "tdls_prohibit") == 0) {
2288 int val
= atoi(pos
);
2290 bss
->tdls
|= TDLS_PROHIBIT
;
2292 bss
->tdls
&= ~TDLS_PROHIBIT
;
2293 } else if (os_strcmp(buf
, "tdls_prohibit_chan_switch") == 0) {
2294 int val
= atoi(pos
);
2296 bss
->tdls
|= TDLS_PROHIBIT_CHAN_SWITCH
;
2298 bss
->tdls
&= ~TDLS_PROHIBIT_CHAN_SWITCH
;
2299 #ifdef CONFIG_RSN_TESTING
2300 } else if (os_strcmp(buf
, "rsn_testing") == 0) {
2301 extern int rsn_testing
;
2302 rsn_testing
= atoi(pos
);
2303 #endif /* CONFIG_RSN_TESTING */
2304 } else if (os_strcmp(buf
, "time_advertisement") == 0) {
2305 bss
->time_advertisement
= atoi(pos
);
2306 } else if (os_strcmp(buf
, "time_zone") == 0) {
2307 size_t tz_len
= os_strlen(pos
);
2308 if (tz_len
< 4 || tz_len
> 255) {
2309 wpa_printf(MSG_DEBUG
, "Line %d: invalid "
2314 os_free(bss
->time_zone
);
2315 bss
->time_zone
= os_strdup(pos
);
2316 if (bss
->time_zone
== NULL
)
2318 #ifdef CONFIG_INTERWORKING
2319 } else if (os_strcmp(buf
, "interworking") == 0) {
2320 bss
->interworking
= atoi(pos
);
2321 } else if (os_strcmp(buf
, "access_network_type") == 0) {
2322 bss
->access_network_type
= atoi(pos
);
2323 if (bss
->access_network_type
< 0 ||
2324 bss
->access_network_type
> 15) {
2325 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2326 "access_network_type", line
);
2329 } else if (os_strcmp(buf
, "internet") == 0) {
2330 bss
->internet
= atoi(pos
);
2331 } else if (os_strcmp(buf
, "asra") == 0) {
2332 bss
->asra
= atoi(pos
);
2333 } else if (os_strcmp(buf
, "esr") == 0) {
2334 bss
->esr
= atoi(pos
);
2335 } else if (os_strcmp(buf
, "uesa") == 0) {
2336 bss
->uesa
= atoi(pos
);
2337 } else if (os_strcmp(buf
, "venue_group") == 0) {
2338 bss
->venue_group
= atoi(pos
);
2339 bss
->venue_info_set
= 1;
2340 } else if (os_strcmp(buf
, "venue_type") == 0) {
2341 bss
->venue_type
= atoi(pos
);
2342 bss
->venue_info_set
= 1;
2343 } else if (os_strcmp(buf
, "hessid") == 0) {
2344 if (hwaddr_aton(pos
, bss
->hessid
)) {
2345 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2349 } else if (os_strcmp(buf
, "roaming_consortium") == 0) {
2350 if (parse_roaming_consortium(bss
, pos
, line
) < 0)
2352 } else if (os_strcmp(buf
, "venue_name") == 0) {
2353 if (parse_venue_name(bss
, pos
, line
) < 0)
2355 } else if (os_strcmp(buf
, "gas_frag_limit") == 0) {
2356 bss
->gas_frag_limit
= atoi(pos
);
2357 } else if (os_strcmp(buf
, "gas_comeback_delay") == 0) {
2358 bss
->gas_comeback_delay
= atoi(pos
);
2359 #endif /* CONFIG_INTERWORKING */
2360 #ifdef CONFIG_RADIUS_TEST
2361 } else if (os_strcmp(buf
, "dump_msk_file") == 0) {
2362 os_free(bss
->dump_msk_file
);
2363 bss
->dump_msk_file
= os_strdup(pos
);
2364 #endif /* CONFIG_RADIUS_TEST */
2366 wpa_printf(MSG_ERROR
, "Line %d: unknown configuration "
2367 "item '%s'", line
, buf
);
2376 static void hostapd_set_security_params(struct hostapd_bss_config
*bss
)
2380 if (bss
->individual_wep_key_len
== 0) {
2381 /* individual keys are not use; can use key idx0 for
2383 bss
->broadcast_key_idx_min
= 0;
2386 /* Select group cipher based on the enabled pairwise cipher
2390 pairwise
|= bss
->wpa_pairwise
;
2392 if (bss
->rsn_pairwise
== 0)
2393 bss
->rsn_pairwise
= bss
->wpa_pairwise
;
2394 pairwise
|= bss
->rsn_pairwise
;
2396 if (pairwise
& WPA_CIPHER_TKIP
)
2397 bss
->wpa_group
= WPA_CIPHER_TKIP
;
2399 bss
->wpa_group
= WPA_CIPHER_CCMP
;
2401 bss
->radius
->auth_server
= bss
->radius
->auth_servers
;
2402 bss
->radius
->acct_server
= bss
->radius
->acct_servers
;
2404 if (bss
->wpa
&& bss
->ieee802_1x
) {
2405 bss
->ssid
.security_policy
= SECURITY_WPA
;
2406 } else if (bss
->wpa
) {
2407 bss
->ssid
.security_policy
= SECURITY_WPA_PSK
;
2408 } else if (bss
->ieee802_1x
) {
2409 int cipher
= WPA_CIPHER_NONE
;
2410 bss
->ssid
.security_policy
= SECURITY_IEEE_802_1X
;
2411 bss
->ssid
.wep
.default_len
= bss
->default_wep_key_len
;
2412 if (bss
->default_wep_key_len
)
2413 cipher
= bss
->default_wep_key_len
>= 13 ?
2414 WPA_CIPHER_WEP104
: WPA_CIPHER_WEP40
;
2415 bss
->wpa_group
= cipher
;
2416 bss
->wpa_pairwise
= cipher
;
2417 bss
->rsn_pairwise
= cipher
;
2418 } else if (bss
->ssid
.wep
.keys_set
) {
2419 int cipher
= WPA_CIPHER_WEP40
;
2420 if (bss
->ssid
.wep
.len
[0] >= 13)
2421 cipher
= WPA_CIPHER_WEP104
;
2422 bss
->ssid
.security_policy
= SECURITY_STATIC_WEP
;
2423 bss
->wpa_group
= cipher
;
2424 bss
->wpa_pairwise
= cipher
;
2425 bss
->rsn_pairwise
= cipher
;
2427 bss
->ssid
.security_policy
= SECURITY_PLAINTEXT
;
2428 bss
->wpa_group
= WPA_CIPHER_NONE
;
2429 bss
->wpa_pairwise
= WPA_CIPHER_NONE
;
2430 bss
->rsn_pairwise
= WPA_CIPHER_NONE
;
2436 * hostapd_config_read - Read and parse a configuration file
2437 * @fname: Configuration file name (including path, if needed)
2438 * Returns: Allocated configuration data structure
2440 struct hostapd_config
* hostapd_config_read(const char *fname
)
2442 struct hostapd_config
*conf
;
2443 struct hostapd_bss_config
*bss
;
2445 char buf
[512], *pos
;
2450 f
= fopen(fname
, "r");
2452 wpa_printf(MSG_ERROR
, "Could not open configuration file '%s' "
2453 "for reading.", fname
);
2457 conf
= hostapd_config_defaults();
2463 /* set default driver based on configuration */
2464 conf
->driver
= wpa_drivers
[0];
2465 if (conf
->driver
== NULL
) {
2466 wpa_printf(MSG_ERROR
, "No driver wrappers registered!");
2467 hostapd_config_free(conf
);
2472 bss
= conf
->last_bss
= conf
->bss
;
2474 while (fgets(buf
, sizeof(buf
), f
)) {
2475 bss
= conf
->last_bss
;
2481 while (*pos
!= '\0') {
2491 pos
= os_strchr(buf
, '=');
2493 wpa_printf(MSG_ERROR
, "Line %d: invalid line '%s'",
2500 errors
+= hostapd_config_fill(conf
, bss
, buf
, pos
, line
);
2505 for (i
= 0; i
< conf
->num_bss
; i
++)
2506 hostapd_set_security_params(&conf
->bss
[i
]);
2508 if (hostapd_config_check(conf
))
2511 #ifndef WPA_IGNORE_CONFIG_ERRORS
2513 wpa_printf(MSG_ERROR
, "%d errors found in configuration file "
2514 "'%s'", errors
, fname
);
2515 hostapd_config_free(conf
);
2518 #endif /* WPA_IGNORE_CONFIG_ERRORS */
2524 int hostapd_set_iface(struct hostapd_config
*conf
,
2525 struct hostapd_bss_config
*bss
, char *field
, char *value
)
2530 errors
= hostapd_config_fill(conf
, bss
, field
, value
, 0);
2532 wpa_printf(MSG_INFO
, "Failed to set configuration field '%s' "
2533 "to value '%s'", field
, value
);
2537 for (i
= 0; i
< conf
->num_bss
; i
++)
2538 hostapd_set_security_params(&conf
->bss
[i
]);
2540 if (hostapd_config_check(conf
)) {
2541 wpa_printf(MSG_ERROR
, "Configuration check failed");