mirror of
https://github.com/lwfinger/rtl8188eu.git
synced 2024-11-14 09:09:35 +00:00
rtl8188eu: Flatten hap/
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
This commit is contained in:
parent
81aeb84017
commit
4de1397841
603 changed files with 71 additions and 220876 deletions
124
Makefile
124
Makefile
|
@ -104,80 +104,80 @@ ifeq ($(CONFIG_MP_INCLUDED), y)
|
||||||
_OS_INTFS_FILES += os_dep/ioctl_mp.o
|
_OS_INTFS_FILES += os_dep/ioctl_mp.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
_HAL_INTFS_FILES := hal/hal_intf.o \
|
_HAL_INTFS_FILES := hal_intf.o \
|
||||||
hal/hal_com.o \
|
hal_com.o \
|
||||||
hal/hal_com_phycfg.o \
|
hal_com_phycfg.o \
|
||||||
hal/hal_phy.o \
|
hal_phy.o \
|
||||||
hal/hal_dm.o \
|
hal_dm.o \
|
||||||
hal/hal_btcoex_wifionly.o \
|
hal_btcoex_wifionly.o \
|
||||||
hal/hal_btcoex.o \
|
hal_btcoex.o \
|
||||||
hal/hal_mp.o \
|
hal_mp.o \
|
||||||
hal/hal_mcc.o \
|
hal_mcc.o \
|
||||||
hal/hal_$(HCI_NAME).o \
|
hal_$(HCI_NAME).o \
|
||||||
hal/hal_$(HCI_NAME)_led.o
|
hal_$(HCI_NAME)_led.o
|
||||||
|
|
||||||
|
|
||||||
_OUTSRC_FILES := hal/phydm_debug.o \
|
_OUTSRC_FILES := phydm_debug.o \
|
||||||
hal/phydm_antdiv.o\
|
phydm_antdiv.o\
|
||||||
hal/phydm_antdect.o\
|
phydm_antdect.o\
|
||||||
hal/phydm_interface.o\
|
phydm_interface.o\
|
||||||
hal/phydm_hwconfig.o\
|
phydm_hwconfig.o\
|
||||||
hal/phydm.o\
|
phydm.o\
|
||||||
hal/halphyrf_ce.o\
|
halphyrf_ce.o\
|
||||||
hal/phydm_edcaturbocheck.o\
|
phydm_edcaturbocheck.o\
|
||||||
hal/phydm_dig.o\
|
phydm_dig.o\
|
||||||
hal/phydm_pathdiv.o\
|
phydm_pathdiv.o\
|
||||||
hal/phydm_rainfo.o\
|
phydm_rainfo.o\
|
||||||
hal/phydm_dynamicbbpowersaving.o\
|
phydm_dynamicbbpowersaving.o\
|
||||||
hal/phydm_powertracking_ce.o\
|
phydm_powertracking_ce.o\
|
||||||
hal/phydm_dynamictxpower.o\
|
phydm_dynamictxpower.o\
|
||||||
hal/phydm_adaptivity.o\
|
phydm_adaptivity.o\
|
||||||
hal/phydm_cfotracking.o\
|
phydm_cfotracking.o\
|
||||||
hal/phydm_noisemonitor.o\
|
phydm_noisemonitor.o\
|
||||||
hal/phydm_acs.o\
|
phydm_acs.o\
|
||||||
hal/phydm_dfs.o\
|
phydm_dfs.o\
|
||||||
hal/phydm_hal_txbf_api.o\
|
phydm_hal_txbf_api.o\
|
||||||
hal/phydm_adc_sampling.o\
|
phydm_adc_sampling.o\
|
||||||
hal/phydm_kfree.o\
|
phydm_kfree.o\
|
||||||
hal/phydm_ccx.o
|
phydm_ccx.o
|
||||||
|
|
||||||
|
|
||||||
EXTRA_CFLAGS += -I$(src)/platform
|
EXTRA_CFLAGS += -I$(src)/platform
|
||||||
|
|
||||||
EXTRA_CFLAGS += -I$(src)/hal/btc
|
EXTRA_CFLAGS += -I$(src)/btc
|
||||||
|
|
||||||
RTL871X = rtl8188e
|
RTL871X = rtl8188e
|
||||||
|
|
||||||
_HAL_INTFS_FILES += hal/HalPwrSeqCmd.o \
|
_HAL_INTFS_FILES += HalPwrSeqCmd.o \
|
||||||
hal/Hal8188EPwrSeq.o\
|
Hal8188EPwrSeq.o\
|
||||||
hal/$(RTL871X)_xmit.o\
|
$(RTL871X)_xmit.o\
|
||||||
hal/$(RTL871X)_sreset.o
|
$(RTL871X)_sreset.o
|
||||||
|
|
||||||
_HAL_INTFS_FILES += hal/$(RTL871X)_hal_init.o \
|
_HAL_INTFS_FILES += $(RTL871X)_hal_init.o \
|
||||||
hal/$(RTL871X)_phycfg.o \
|
$(RTL871X)_phycfg.o \
|
||||||
hal/$(RTL871X)_rf6052.o \
|
$(RTL871X)_rf6052.o \
|
||||||
hal/$(RTL871X)_dm.o \
|
$(RTL871X)_dm.o \
|
||||||
hal/$(RTL871X)_rxdesc.o \
|
$(RTL871X)_rxdesc.o \
|
||||||
hal/$(RTL871X)_cmd.o \
|
$(RTL871X)_cmd.o \
|
||||||
hal/hal8188e_s_fw.o \
|
hal8188e_s_fw.o \
|
||||||
hal/hal8188e_t_fw.o \
|
hal8188e_t_fw.o \
|
||||||
hal/$(HCI_NAME)_halinit.o \
|
$(HCI_NAME)_halinit.o \
|
||||||
hal/rtl8188eu_led.o \
|
rtl8188eu_led.o \
|
||||||
hal/rtl8188eu_xmit.o \
|
rtl8188eu_xmit.o \
|
||||||
hal/rtl8188eu_recv.o
|
rtl8188eu_recv.o
|
||||||
|
|
||||||
_HAL_INTFS_FILES += hal/$(HCI_NAME)_ops_linux.o
|
_HAL_INTFS_FILES += $(HCI_NAME)_ops_linux.o
|
||||||
|
|
||||||
_HAL_INTFS_FILES +=hal/HalEfuseMask8188E_USB.o
|
_HAL_INTFS_FILES +=HalEfuseMask8188E_USB.o
|
||||||
|
|
||||||
#hal/OUTSRC/Hal8188EFWImg_CE.o
|
#OUTSRC/Hal8188EFWImg_CE.o
|
||||||
_OUTSRC_FILES += hal/halhwimg8188e_mac.o\
|
_OUTSRC_FILES += halhwimg8188e_mac.o\
|
||||||
hal/halhwimg8188e_bb.o\
|
halhwimg8188e_bb.o\
|
||||||
hal/halhwimg8188e_rf.o\
|
halhwimg8188e_rf.o\
|
||||||
hal/halphyrf_8188e_ce.o\
|
halphyrf_8188e_ce.o\
|
||||||
hal/phydm_regconfig8188e.o\
|
phydm_regconfig8188e.o\
|
||||||
hal/hal8188erateadaptive.o\
|
hal8188erateadaptive.o\
|
||||||
hal/phydm_rtl8188e.o
|
phydm_rtl8188e.o
|
||||||
|
|
||||||
########### AUTO_CFG #################################
|
########### AUTO_CFG #################################
|
||||||
|
|
||||||
|
@ -497,7 +497,7 @@ clean:
|
||||||
cd hal ; rm -fr */*/*/*.mod.c */*/*/*.mod */*/*/*.o */*/*/.*.cmd */*/*/*.ko
|
cd hal ; rm -fr */*/*/*.mod.c */*/*/*.mod */*/*/*.o */*/*/.*.cmd */*/*/*.ko
|
||||||
cd hal ; rm -fr */*/*.mod.c */*/*.mod */*/*.o */*/.*.cmd */*/*.ko
|
cd hal ; rm -fr */*/*.mod.c */*/*.mod */*/*.o */*/.*.cmd */*/*.ko
|
||||||
cd hal ; rm -fr */*.mod.c */*.mod */*.o */.*.cmd */*.ko
|
cd hal ; rm -fr */*.mod.c */*.mod */*.o */.*.cmd */*.ko
|
||||||
cd hal/led ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko .*.cmd
|
cd led ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko .*.cmd
|
||||||
cd core ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
|
cd core ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
|
||||||
cd os_dep/linux ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
|
cd os_dep/linux ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
|
||||||
cd os_dep ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
|
cd os_dep ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
|
||||||
|
|
|
@ -1,340 +0,0 @@
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 2, June 1991
|
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
|
||||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
License is intended to guarantee your freedom to share and change free
|
|
||||||
software--to make sure the software is free for all its users. This
|
|
||||||
General Public License applies to most of the Free Software
|
|
||||||
Foundation's software and to any other program whose authors commit to
|
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
|
||||||
the GNU Library General Public License instead.) You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
this service if you wish), that you receive source code or can get it
|
|
||||||
if you want it, that you can change the software or use pieces of it
|
|
||||||
in new free programs; and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
|
||||||
These restrictions translate to certain responsibilities for you if you
|
|
||||||
distribute copies of the software, or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must give the recipients all the rights that
|
|
||||||
you have. You must make sure that they, too, receive or can get the
|
|
||||||
source code. And you must show them these terms so they know their
|
|
||||||
rights.
|
|
||||||
|
|
||||||
We protect your rights with two steps: (1) copyright the software, and
|
|
||||||
(2) offer you this license which gives you legal permission to copy,
|
|
||||||
distribute and/or modify the software.
|
|
||||||
|
|
||||||
Also, for each author's protection and ours, we want to make certain
|
|
||||||
that everyone understands that there is no warranty for this free
|
|
||||||
software. If the software is modified by someone else and passed on, we
|
|
||||||
want its recipients to know that what they have is not the original, so
|
|
||||||
that any problems introduced by others will not reflect on the original
|
|
||||||
authors' reputations.
|
|
||||||
|
|
||||||
Finally, any free program is threatened constantly by software
|
|
||||||
patents. We wish to avoid the danger that redistributors of a free
|
|
||||||
program will individually obtain patent licenses, in effect making the
|
|
||||||
program proprietary. To prevent this, we have made it clear that any
|
|
||||||
patent must be licensed for everyone's free use or not licensed at all.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License applies to any program or other work which contains
|
|
||||||
a notice placed by the copyright holder saying it may be distributed
|
|
||||||
under the terms of this General Public License. The "Program", below,
|
|
||||||
refers to any such program or work, and a "work based on the Program"
|
|
||||||
means either the Program or any derivative work under copyright law:
|
|
||||||
that is to say, a work containing the Program or a portion of it,
|
|
||||||
either verbatim or with modifications and/or translated into another
|
|
||||||
language. (Hereinafter, translation is included without limitation in
|
|
||||||
the term "modification".) Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running the Program is not restricted, and the output from the Program
|
|
||||||
is covered only if its contents constitute a work based on the
|
|
||||||
Program (independent of having been made by running the Program).
|
|
||||||
Whether that is true depends on what the Program does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Program's
|
|
||||||
source code as you receive it, in any medium, provided that you
|
|
||||||
conspicuously and appropriately publish on each copy an appropriate
|
|
||||||
copyright notice and disclaimer of warranty; keep intact all the
|
|
||||||
notices that refer to this License and to the absence of any warranty;
|
|
||||||
and give any other recipients of the Program a copy of this License
|
|
||||||
along with the Program.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy, and
|
|
||||||
you may at your option offer warranty protection in exchange for a fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Program or any portion
|
|
||||||
of it, thus forming a work based on the Program, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) You must cause the modified files to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
b) You must cause any work that you distribute or publish, that in
|
|
||||||
whole or in part contains or is derived from the Program or any
|
|
||||||
part thereof, to be licensed as a whole at no charge to all third
|
|
||||||
parties under the terms of this License.
|
|
||||||
|
|
||||||
c) If the modified program normally reads commands interactively
|
|
||||||
when run, you must cause it, when started running for such
|
|
||||||
interactive use in the most ordinary way, to print or display an
|
|
||||||
announcement including an appropriate copyright notice and a
|
|
||||||
notice that there is no warranty (or else, saying that you provide
|
|
||||||
a warranty) and that users may redistribute the program under
|
|
||||||
these conditions, and telling the user how to view a copy of this
|
|
||||||
License. (Exception: if the Program itself is interactive but
|
|
||||||
does not normally print such an announcement, your work based on
|
|
||||||
the Program is not required to print an announcement.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Program,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Program, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Program.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Program
|
|
||||||
with the Program (or with a work based on the Program) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may copy and distribute the Program (or a work based on it,
|
|
||||||
under Section 2) in object code or executable form under the terms of
|
|
||||||
Sections 1 and 2 above provided that you also do one of the following:
|
|
||||||
|
|
||||||
a) Accompany it with the complete corresponding machine-readable
|
|
||||||
source code, which must be distributed under the terms of Sections
|
|
||||||
1 and 2 above on a medium customarily used for software interchange; or,
|
|
||||||
|
|
||||||
b) Accompany it with a written offer, valid for at least three
|
|
||||||
years, to give any third party, for a charge no more than your
|
|
||||||
cost of physically performing source distribution, a complete
|
|
||||||
machine-readable copy of the corresponding source code, to be
|
|
||||||
distributed under the terms of Sections 1 and 2 above on a medium
|
|
||||||
customarily used for software interchange; or,
|
|
||||||
|
|
||||||
c) Accompany it with the information you received as to the offer
|
|
||||||
to distribute corresponding source code. (This alternative is
|
|
||||||
allowed only for noncommercial distribution and only if you
|
|
||||||
received the program in object code or executable form with such
|
|
||||||
an offer, in accord with Subsection b above.)
|
|
||||||
|
|
||||||
The source code for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For an executable work, complete source
|
|
||||||
code means all the source code for all modules it contains, plus any
|
|
||||||
associated interface definition files, plus the scripts used to
|
|
||||||
control compilation and installation of the executable. However, as a
|
|
||||||
special exception, the source code distributed need not include
|
|
||||||
anything that is normally distributed (in either source or binary
|
|
||||||
form) with the major components (compiler, kernel, and so on) of the
|
|
||||||
operating system on which the executable runs, unless that component
|
|
||||||
itself accompanies the executable.
|
|
||||||
|
|
||||||
If distribution of executable or object code is made by offering
|
|
||||||
access to copy from a designated place, then offering equivalent
|
|
||||||
access to copy the source code from the same place counts as
|
|
||||||
distribution of the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
|
||||||
except as expressly provided under this License. Any attempt
|
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
|
||||||
void, and will automatically terminate your rights under this License.
|
|
||||||
However, parties who have received copies, or rights, from you under
|
|
||||||
this License will not have their licenses terminated so long as such
|
|
||||||
parties remain in full compliance.
|
|
||||||
|
|
||||||
5. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Program or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Program (or any work based on the
|
|
||||||
Program), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Program or works based on it.
|
|
||||||
|
|
||||||
6. Each time you redistribute the Program (or any work based on the
|
|
||||||
Program), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute or modify the Program subject to
|
|
||||||
these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties to
|
|
||||||
this License.
|
|
||||||
|
|
||||||
7. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Program at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Program by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Program.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under
|
|
||||||
any particular circumstance, the balance of the section is intended to
|
|
||||||
apply and the section as a whole is intended to apply in other
|
|
||||||
circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system, which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Program under this License
|
|
||||||
may add an explicit geographical distribution limitation excluding
|
|
||||||
those countries, so that distribution is permitted only in or among
|
|
||||||
countries not thus excluded. In such case, this License incorporates
|
|
||||||
the limitation as if written in the body of this License.
|
|
||||||
|
|
||||||
9. The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies a version number of this License which applies to it and "any
|
|
||||||
later version", you have the option of following the terms and conditions
|
|
||||||
either of that version or of any later version published by the Free
|
|
||||||
Software Foundation. If the Program does not specify a version number of
|
|
||||||
this License, you may choose any version ever published by the Free Software
|
|
||||||
Foundation.
|
|
||||||
|
|
||||||
10. If you wish to incorporate parts of the Program into other free
|
|
||||||
programs whose distribution conditions are different, write to the author
|
|
||||||
to ask for permission. For software which is copyrighted by the Free
|
|
||||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
|
||||||
make exceptions for this. Our decision will be guided by the two goals
|
|
||||||
of preserving the free status of all derivatives of our free software and
|
|
||||||
of promoting the sharing and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
|
||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
|
||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
|
||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
|
||||||
REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
|
||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
|
||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
|
||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
|
||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
||||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) 19yy <name of author>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program is interactive, make it output a short notice like this
|
|
||||||
when it starts in an interactive mode:
|
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, the commands you use may
|
|
||||||
be called something other than `show w' and `show c'; they could even be
|
|
||||||
mouse-clicks or menu items--whatever suits your program.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
|
||||||
necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
|
||||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1989
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
This General Public License does not permit incorporating your program into
|
|
||||||
proprietary programs. If your program is a subroutine library, you may
|
|
||||||
consider it more useful to permit linking proprietary applications with the
|
|
||||||
library. If this is what you want to do, use the GNU Library General
|
|
||||||
Public License instead of this License.
|
|
|
@ -1,72 +0,0 @@
|
||||||
wpa_supplicant and hostapd
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2002-2011, Jouni Malinen <j@w1.fi> and contributors
|
|
||||||
All Rights Reserved.
|
|
||||||
|
|
||||||
These programs are dual-licensed under both the GPL version 2 and BSD
|
|
||||||
license (the one with advertisement clause removed). Either license
|
|
||||||
may be used at your option.
|
|
||||||
|
|
||||||
|
|
||||||
This package may include either wpa_supplicant, hostapd, or both. See
|
|
||||||
README file respective subdirectories (wpa_supplicant/README or
|
|
||||||
hostapd/README) for more details.
|
|
||||||
|
|
||||||
Source code files were moved around in v0.6.x releases and compared to
|
|
||||||
earlier releases, the programs are now built by first going to a
|
|
||||||
subdirectory (wpa_supplicant or hostapd) and creating build
|
|
||||||
configuration (.config) and running 'make' there (for Linux/BSD/cygwin
|
|
||||||
builds).
|
|
||||||
|
|
||||||
|
|
||||||
License
|
|
||||||
-------
|
|
||||||
|
|
||||||
GPL v2:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License version 2 as
|
|
||||||
published by the Free Software Foundation.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
(this copy of the license is in COPYING file)
|
|
||||||
|
|
||||||
|
|
||||||
Alternatively, this software may be distributed, used, and modified
|
|
||||||
under the terms of BSD license:
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name(s) of the above-listed copyright holder(s) nor the
|
|
||||||
names of its contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
@ -1,816 +0,0 @@
|
||||||
LOCAL_PATH := $(call my-dir)
|
|
||||||
|
|
||||||
WPA_BUILD_HOSTAPD := false
|
|
||||||
ifneq ($(TARGET_SIMULATOR),true)
|
|
||||||
ifneq ($(BOARD_HOSTAPD_DRIVER),)
|
|
||||||
WPA_BUILD_HOSTAPD := true
|
|
||||||
CONFIG_DRIVER_$(BOARD_HOSTAPD_DRIVER) := y
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(LOCAL_PATH)/.config
|
|
||||||
|
|
||||||
# To ignore possible wrong network configurations
|
|
||||||
L_CFLAGS = -DWPA_IGNORE_CONFIG_ERRORS
|
|
||||||
|
|
||||||
# To force sizeof(enum) = 4
|
|
||||||
ifeq ($(TARGET_ARCH),arm)
|
|
||||||
L_CFLAGS += -mabi=aapcs-linux
|
|
||||||
endif
|
|
||||||
|
|
||||||
# To allow non-ASCII characters in SSID
|
|
||||||
L_CFLAGS += -DWPA_UNICODE_SSID
|
|
||||||
|
|
||||||
# OpenSSL is configured without engines on Android
|
|
||||||
L_CFLAGS += -DOPENSSL_NO_ENGINE
|
|
||||||
|
|
||||||
INCLUDES = $(LOCAL_PATH)
|
|
||||||
INCLUDES += $(LOCAL_PATH)/src
|
|
||||||
INCLUDES += $(LOCAL_PATH)/src/utils
|
|
||||||
INCLUDES += external/openssl/include
|
|
||||||
INCLUDES += frameworks/base/cmds/keystore
|
|
||||||
ifdef CONFIG_DRIVER_NL80211
|
|
||||||
INCLUDES += external/libnl_2/include
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
ifndef CONFIG_OS
|
|
||||||
ifdef CONFIG_NATIVE_WINDOWS
|
|
||||||
CONFIG_OS=win32
|
|
||||||
else
|
|
||||||
CONFIG_OS=unix
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_OS), internal)
|
|
||||||
L_CFLAGS += -DOS_NO_C_LIB_DEFINES
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_NATIVE_WINDOWS
|
|
||||||
L_CFLAGS += -DCONFIG_NATIVE_WINDOWS
|
|
||||||
LIBS += -lws2_32
|
|
||||||
endif
|
|
||||||
|
|
||||||
OBJS = main.c
|
|
||||||
OBJS += config_file.c
|
|
||||||
|
|
||||||
OBJS += src/ap/hostapd.c
|
|
||||||
OBJS += src/ap/wpa_auth_glue.c
|
|
||||||
OBJS += src/ap/drv_callbacks.c
|
|
||||||
OBJS += src/ap/ap_drv_ops.c
|
|
||||||
OBJS += src/ap/utils.c
|
|
||||||
OBJS += src/ap/authsrv.c
|
|
||||||
OBJS += src/ap/ieee802_1x.c
|
|
||||||
OBJS += src/ap/ap_config.c
|
|
||||||
OBJS += src/ap/ieee802_11_auth.c
|
|
||||||
OBJS += src/ap/sta_info.c
|
|
||||||
OBJS += src/ap/wpa_auth.c
|
|
||||||
OBJS += src/ap/tkip_countermeasures.c
|
|
||||||
OBJS += src/ap/ap_mlme.c
|
|
||||||
OBJS += src/ap/wpa_auth_ie.c
|
|
||||||
OBJS += src/ap/preauth_auth.c
|
|
||||||
OBJS += src/ap/pmksa_cache_auth.c
|
|
||||||
OBJS_d =
|
|
||||||
OBJS_p =
|
|
||||||
LIBS =
|
|
||||||
LIBS_c =
|
|
||||||
HOBJS =
|
|
||||||
LIBS_h =
|
|
||||||
|
|
||||||
NEED_RC4=y
|
|
||||||
NEED_AES=y
|
|
||||||
NEED_MD5=y
|
|
||||||
NEED_SHA1=y
|
|
||||||
|
|
||||||
OBJS += src/drivers/drivers.c
|
|
||||||
L_CFLAGS += -DHOSTAPD
|
|
||||||
|
|
||||||
ifdef CONFIG_WPA_TRACE
|
|
||||||
L_CFLAGS += -DWPA_TRACE
|
|
||||||
OBJS += src/utils/trace.c
|
|
||||||
HOBJS += src/utils/trace.c
|
|
||||||
LDFLAGS += -rdynamic
|
|
||||||
L_CFLAGS += -funwind-tables
|
|
||||||
ifdef CONFIG_WPA_TRACE_BFD
|
|
||||||
L_CFLAGS += -DWPA_TRACE_BFD
|
|
||||||
LIBS += -lbfd
|
|
||||||
LIBS_c += -lbfd
|
|
||||||
LIBS_h += -lbfd
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
OBJS += src/utils/eloop.c
|
|
||||||
OBJS += src/utils/common.c
|
|
||||||
OBJS += src/utils/wpa_debug.c
|
|
||||||
OBJS += src/utils/wpabuf.c
|
|
||||||
OBJS += src/utils/os_$(CONFIG_OS).c
|
|
||||||
OBJS += src/utils/ip_addr.c
|
|
||||||
|
|
||||||
OBJS += src/common/ieee802_11_common.c
|
|
||||||
OBJS += src/common/wpa_common.c
|
|
||||||
|
|
||||||
OBJS += src/eapol_auth/eapol_auth_sm.c
|
|
||||||
|
|
||||||
|
|
||||||
ifndef CONFIG_NO_DUMP_STATE
|
|
||||||
# define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to
|
|
||||||
# a file (undefine it, if you want to save in binary size)
|
|
||||||
L_CFLAGS += -DHOSTAPD_DUMP_STATE
|
|
||||||
OBJS += dump_state.c
|
|
||||||
OBJS += src/eapol_auth/eapol_auth_dump.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_NO_RADIUS
|
|
||||||
L_CFLAGS += -DCONFIG_NO_RADIUS
|
|
||||||
CONFIG_NO_ACCOUNTING=y
|
|
||||||
else
|
|
||||||
OBJS += src/radius/radius.c
|
|
||||||
OBJS += src/radius/radius_client.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_NO_ACCOUNTING
|
|
||||||
L_CFLAGS += -DCONFIG_NO_ACCOUNTING
|
|
||||||
else
|
|
||||||
OBJS += src/ap/accounting.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_NO_VLAN
|
|
||||||
L_CFLAGS += -DCONFIG_NO_VLAN
|
|
||||||
else
|
|
||||||
OBJS += src/ap/vlan_init.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_NO_CTRL_IFACE
|
|
||||||
L_CFLAGS += -DCONFIG_NO_CTRL_IFACE
|
|
||||||
else
|
|
||||||
OBJS += ctrl_iface.c
|
|
||||||
OBJS += src/ap/ctrl_iface_ap.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
OBJS += src/crypto/md5.c
|
|
||||||
|
|
||||||
L_CFLAGS += -DCONFIG_CTRL_IFACE -DCONFIG_CTRL_IFACE_UNIX
|
|
||||||
|
|
||||||
ifdef CONFIG_IAPP
|
|
||||||
L_CFLAGS += -DCONFIG_IAPP
|
|
||||||
OBJS += src/ap/iapp.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_RSN_PREAUTH
|
|
||||||
L_CFLAGS += -DCONFIG_RSN_PREAUTH
|
|
||||||
CONFIG_L2_PACKET=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_PEERKEY
|
|
||||||
L_CFLAGS += -DCONFIG_PEERKEY
|
|
||||||
OBJS += src/ap/peerkey_auth.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_IEEE80211W
|
|
||||||
L_CFLAGS += -DCONFIG_IEEE80211W
|
|
||||||
NEED_SHA256=y
|
|
||||||
NEED_AES_OMAC1=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_IEEE80211R
|
|
||||||
L_CFLAGS += -DCONFIG_IEEE80211R
|
|
||||||
OBJS += src/ap/wpa_auth_ft.c
|
|
||||||
NEED_SHA256=y
|
|
||||||
NEED_AES_OMAC1=y
|
|
||||||
NEED_AES_UNWRAP=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_IEEE80211N
|
|
||||||
L_CFLAGS += -DCONFIG_IEEE80211N
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(LOCAL_PATH)/src/drivers/drivers.mk
|
|
||||||
|
|
||||||
OBJS += $(DRV_AP_OBJS)
|
|
||||||
L_CFLAGS += $(DRV_AP_CFLAGS)
|
|
||||||
LDFLAGS += $(DRV_AP_LDFLAGS)
|
|
||||||
LIBS += $(DRV_AP_LIBS)
|
|
||||||
|
|
||||||
ifdef CONFIG_L2_PACKET
|
|
||||||
ifdef CONFIG_DNET_PCAP
|
|
||||||
ifdef CONFIG_L2_FREEBSD
|
|
||||||
LIBS += -lpcap
|
|
||||||
OBJS += src/l2_packet/l2_packet_freebsd.c
|
|
||||||
else
|
|
||||||
LIBS += -ldnet -lpcap
|
|
||||||
OBJS += src/l2_packet/l2_packet_pcap.c
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
OBJS += src/l2_packet/l2_packet_linux.c
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
OBJS += src/l2_packet/l2_packet_none.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_MD5
|
|
||||||
L_CFLAGS += -DEAP_SERVER_MD5
|
|
||||||
OBJS += src/eap_server/eap_server_md5.c
|
|
||||||
CHAP=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_TLS
|
|
||||||
L_CFLAGS += -DEAP_SERVER_TLS
|
|
||||||
OBJS += src/eap_server/eap_server_tls.c
|
|
||||||
TLS_FUNCS=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_PEAP
|
|
||||||
L_CFLAGS += -DEAP_SERVER_PEAP
|
|
||||||
OBJS += src/eap_server/eap_server_peap.c
|
|
||||||
OBJS += src/eap_common/eap_peap_common.c
|
|
||||||
TLS_FUNCS=y
|
|
||||||
CONFIG_EAP_MSCHAPV2=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_TTLS
|
|
||||||
L_CFLAGS += -DEAP_SERVER_TTLS
|
|
||||||
OBJS += src/eap_server/eap_server_ttls.c
|
|
||||||
TLS_FUNCS=y
|
|
||||||
CHAP=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_MSCHAPV2
|
|
||||||
L_CFLAGS += -DEAP_SERVER_MSCHAPV2
|
|
||||||
OBJS += src/eap_server/eap_server_mschapv2.c
|
|
||||||
MS_FUNCS=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_GTC
|
|
||||||
L_CFLAGS += -DEAP_SERVER_GTC
|
|
||||||
OBJS += src/eap_server/eap_server_gtc.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_SIM
|
|
||||||
L_CFLAGS += -DEAP_SERVER_SIM
|
|
||||||
OBJS += src/eap_server/eap_server_sim.c
|
|
||||||
CONFIG_EAP_SIM_COMMON=y
|
|
||||||
NEED_AES_CBC=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_AKA
|
|
||||||
L_CFLAGS += -DEAP_SERVER_AKA
|
|
||||||
OBJS += src/eap_server/eap_server_aka.c
|
|
||||||
CONFIG_EAP_SIM_COMMON=y
|
|
||||||
NEED_SHA256=y
|
|
||||||
NEED_AES_CBC=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_AKA_PRIME
|
|
||||||
L_CFLAGS += -DEAP_SERVER_AKA_PRIME
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_SIM_COMMON
|
|
||||||
OBJS += src/eap_common/eap_sim_common.c
|
|
||||||
# Example EAP-SIM/AKA interface for GSM/UMTS authentication. This can be
|
|
||||||
# replaced with another file implementating the interface specified in
|
|
||||||
# eap_sim_db.h.
|
|
||||||
OBJS += src/eap_server/eap_sim_db.c
|
|
||||||
NEED_FIPS186_2_PRF=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_PAX
|
|
||||||
L_CFLAGS += -DEAP_SERVER_PAX
|
|
||||||
OBJS += src/eap_server/eap_server_pax.c src/eap_common/eap_pax_common.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_PSK
|
|
||||||
L_CFLAGS += -DEAP_SERVER_PSK
|
|
||||||
OBJS += src/eap_server/eap_server_psk.c src/eap_common/eap_psk_common.c
|
|
||||||
NEED_AES_OMAC1=y
|
|
||||||
NEED_AES_ENCBLOCK=y
|
|
||||||
NEED_AES_EAX=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_SAKE
|
|
||||||
L_CFLAGS += -DEAP_SERVER_SAKE
|
|
||||||
OBJS += src/eap_server/eap_server_sake.c src/eap_common/eap_sake_common.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_GPSK
|
|
||||||
L_CFLAGS += -DEAP_SERVER_GPSK
|
|
||||||
OBJS += src/eap_server/eap_server_gpsk.c src/eap_common/eap_gpsk_common.c
|
|
||||||
ifdef CONFIG_EAP_GPSK_SHA256
|
|
||||||
L_CFLAGS += -DEAP_SERVER_GPSK_SHA256
|
|
||||||
endif
|
|
||||||
NEED_SHA256=y
|
|
||||||
NEED_AES_OMAC1=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_PWD
|
|
||||||
L_CFLAGS += -DEAP_SERVER_PWD
|
|
||||||
OBJS += src/eap_server/eap_server_pwd.c src/eap_common/eap_pwd_common.c
|
|
||||||
NEED_SHA256=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_VENDOR_TEST
|
|
||||||
L_CFLAGS += -DEAP_SERVER_VENDOR_TEST
|
|
||||||
OBJS += src/eap_server/eap_server_vendor_test.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_FAST
|
|
||||||
L_CFLAGS += -DEAP_SERVER_FAST
|
|
||||||
OBJS += src/eap_server/eap_server_fast.c
|
|
||||||
OBJS += src/eap_common/eap_fast_common.c
|
|
||||||
TLS_FUNCS=y
|
|
||||||
NEED_T_PRF=y
|
|
||||||
NEED_AES_UNWRAP=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_WPS
|
|
||||||
ifdef CONFIG_WPS2
|
|
||||||
L_CFLAGS += -DCONFIG_WPS2
|
|
||||||
endif
|
|
||||||
|
|
||||||
L_CFLAGS += -DCONFIG_WPS -DEAP_SERVER_WSC
|
|
||||||
OBJS += src/utils/uuid.c
|
|
||||||
OBJS += src/ap/wps_hostapd.c
|
|
||||||
OBJS += src/eap_server/eap_server_wsc.c src/eap_common/eap_wsc_common.c
|
|
||||||
OBJS += src/wps/wps.c
|
|
||||||
OBJS += src/wps/wps_common.c
|
|
||||||
OBJS += src/wps/wps_attr_parse.c
|
|
||||||
OBJS += src/wps/wps_attr_build.c
|
|
||||||
OBJS += src/wps/wps_attr_process.c
|
|
||||||
OBJS += src/wps/wps_dev_attr.c
|
|
||||||
OBJS += src/wps/wps_enrollee.c
|
|
||||||
OBJS += src/wps/wps_registrar.c
|
|
||||||
NEED_DH_GROUPS=y
|
|
||||||
NEED_SHA256=y
|
|
||||||
NEED_BASE64=y
|
|
||||||
NEED_AES_CBC=y
|
|
||||||
NEED_MODEXP=y
|
|
||||||
CONFIG_EAP=y
|
|
||||||
|
|
||||||
ifdef CONFIG_WPS_UFD
|
|
||||||
L_CFLAGS += -DCONFIG_WPS_UFD
|
|
||||||
OBJS += src/wps/wps_ufd.c
|
|
||||||
NEED_WPS_OOB=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_WPS_NFC
|
|
||||||
L_CFLAGS += -DCONFIG_WPS_NFC
|
|
||||||
OBJS += src/wps/ndef.c
|
|
||||||
OBJS += src/wps/wps_nfc.c
|
|
||||||
NEED_WPS_OOB=y
|
|
||||||
ifdef CONFIG_WPS_NFC_PN531
|
|
||||||
PN531_PATH ?= /usr/local/src/nfc
|
|
||||||
L_CFLAGS += -DCONFIG_WPS_NFC_PN531
|
|
||||||
L_CFLAGS += -I${PN531_PATH}/inc
|
|
||||||
OBJS += src/wps/wps_nfc_pn531.c
|
|
||||||
LIBS += ${PN531_PATH}/lib/wpsnfc.dll
|
|
||||||
LIBS += ${PN531_PATH}/lib/libnfc_mapping_pn53x.dll
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_WPS_OOB
|
|
||||||
L_CFLAGS += -DCONFIG_WPS_OOB
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_WPS_UPNP
|
|
||||||
L_CFLAGS += -DCONFIG_WPS_UPNP
|
|
||||||
OBJS += src/wps/wps_upnp.c
|
|
||||||
OBJS += src/wps/wps_upnp_ssdp.c
|
|
||||||
OBJS += src/wps/wps_upnp_web.c
|
|
||||||
OBJS += src/wps/wps_upnp_event.c
|
|
||||||
OBJS += src/wps/wps_upnp_ap.c
|
|
||||||
OBJS += src/wps/upnp_xml.c
|
|
||||||
OBJS += src/wps/httpread.c
|
|
||||||
OBJS += src/wps/http_client.c
|
|
||||||
OBJS += src/wps/http_server.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_WPS_STRICT
|
|
||||||
L_CFLAGS += -DCONFIG_WPS_STRICT
|
|
||||||
OBJS += src/wps/wps_validate.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_WPS_TESTING
|
|
||||||
L_CFLAGS += -DCONFIG_WPS_TESTING
|
|
||||||
endif
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_IKEV2
|
|
||||||
L_CFLAGS += -DEAP_SERVER_IKEV2
|
|
||||||
OBJS += src/eap_server/eap_server_ikev2.c src/eap_server/ikev2.c
|
|
||||||
OBJS += src/eap_common/eap_ikev2_common.c src/eap_common/ikev2_common.c
|
|
||||||
NEED_DH_GROUPS=y
|
|
||||||
NEED_DH_GROUPS_ALL=y
|
|
||||||
NEED_MODEXP=y
|
|
||||||
NEED_CIPHER=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_TNC
|
|
||||||
L_CFLAGS += -DEAP_SERVER_TNC
|
|
||||||
OBJS += src/eap_server/eap_server_tnc.c
|
|
||||||
OBJS += src/eap_server/tncs.c
|
|
||||||
NEED_BASE64=y
|
|
||||||
ifndef CONFIG_DRIVER_BSD
|
|
||||||
LIBS += -ldl
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Basic EAP functionality is needed for EAPOL
|
|
||||||
OBJS += eap_register.c
|
|
||||||
OBJS += src/eap_server/eap_server.c
|
|
||||||
OBJS += src/eap_common/eap_common.c
|
|
||||||
OBJS += src/eap_server/eap_server_methods.c
|
|
||||||
OBJS += src/eap_server/eap_server_identity.c
|
|
||||||
L_CFLAGS += -DEAP_SERVER_IDENTITY
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP
|
|
||||||
L_CFLAGS += -DEAP_SERVER
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_PKCS12
|
|
||||||
L_CFLAGS += -DPKCS12_FUNCS
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef MS_FUNCS
|
|
||||||
OBJS += src/crypto/ms_funcs.c
|
|
||||||
NEED_DES=y
|
|
||||||
NEED_MD4=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CHAP
|
|
||||||
OBJS += src/eap_common/chap.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
NEED_DES=y
|
|
||||||
# Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS)
|
|
||||||
L_CFLAGS += -DEAP_TLS_FUNCS
|
|
||||||
OBJS += src/eap_server/eap_server_tls_common.c
|
|
||||||
NEED_TLS_PRF=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifndef CONFIG_TLS
|
|
||||||
CONFIG_TLS=openssl
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_TLS), openssl)
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
OBJS += src/crypto/tls_openssl.c
|
|
||||||
LIBS += -lssl
|
|
||||||
endif
|
|
||||||
OBJS += src/crypto/crypto_openssl.c
|
|
||||||
HOBJS += src/crypto/crypto_openssl.c
|
|
||||||
ifdef NEED_FIPS186_2_PRF
|
|
||||||
OBJS += src/crypto/fips_prf_openssl.c
|
|
||||||
endif
|
|
||||||
LIBS += -lcrypto
|
|
||||||
LIBS_h += -lcrypto
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_TLS), gnutls)
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
OBJS += src/crypto/tls_gnutls.c
|
|
||||||
LIBS += -lgnutls -lgpg-error
|
|
||||||
ifdef CONFIG_GNUTLS_EXTRA
|
|
||||||
L_CFLAGS += -DCONFIG_GNUTLS_EXTRA
|
|
||||||
LIBS += -lgnutls-extra
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
OBJS += src/crypto/crypto_gnutls.c
|
|
||||||
HOBJS += src/crypto/crypto_gnutls.c
|
|
||||||
ifdef NEED_FIPS186_2_PRF
|
|
||||||
OBJS += src/crypto/fips_prf_gnutls.c
|
|
||||||
endif
|
|
||||||
LIBS += -lgcrypt
|
|
||||||
LIBS_h += -lgcrypt
|
|
||||||
CONFIG_INTERNAL_SHA256=y
|
|
||||||
CONFIG_INTERNAL_RC4=y
|
|
||||||
CONFIG_INTERNAL_DH_GROUP5=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_TLS), schannel)
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
OBJS += src/crypto/tls_schannel.c
|
|
||||||
endif
|
|
||||||
OBJS += src/crypto/crypto_cryptoapi.c
|
|
||||||
OBJS_p += src/crypto/crypto_cryptoapi.c
|
|
||||||
CONFIG_INTERNAL_SHA256=y
|
|
||||||
CONFIG_INTERNAL_RC4=y
|
|
||||||
CONFIG_INTERNAL_DH_GROUP5=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_TLS), nss)
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
OBJS += src/crypto/tls_nss.c
|
|
||||||
LIBS += -lssl3
|
|
||||||
endif
|
|
||||||
OBJS += src/crypto/crypto_nss.c
|
|
||||||
ifdef NEED_FIPS186_2_PRF
|
|
||||||
OBJS += src/crypto/fips_prf_nss.c
|
|
||||||
endif
|
|
||||||
LIBS += -lnss3
|
|
||||||
LIBS_h += -lnss3
|
|
||||||
CONFIG_INTERNAL_MD4=y
|
|
||||||
CONFIG_INTERNAL_DH_GROUP5=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_TLS), internal)
|
|
||||||
ifndef CONFIG_CRYPTO
|
|
||||||
CONFIG_CRYPTO=internal
|
|
||||||
endif
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
OBJS += src/crypto/crypto_internal-rsa.c
|
|
||||||
OBJS += src/crypto/tls_internal.c
|
|
||||||
OBJS += src/tls/tlsv1_common.c
|
|
||||||
OBJS += src/tls/tlsv1_record.c
|
|
||||||
OBJS += src/tls/tlsv1_cred.c
|
|
||||||
OBJS += src/tls/tlsv1_server.c
|
|
||||||
OBJS += src/tls/tlsv1_server_write.c
|
|
||||||
OBJS += src/tls/tlsv1_server_read.c
|
|
||||||
OBJS += src/tls/asn1.c
|
|
||||||
OBJS += src/tls/rsa.c
|
|
||||||
OBJS += src/tls/x509v3.c
|
|
||||||
OBJS += src/tls/pkcs1.c
|
|
||||||
OBJS += src/tls/pkcs5.c
|
|
||||||
OBJS += src/tls/pkcs8.c
|
|
||||||
NEED_SHA256=y
|
|
||||||
NEED_BASE64=y
|
|
||||||
NEED_TLS_PRF=y
|
|
||||||
NEED_MODEXP=y
|
|
||||||
NEED_CIPHER=y
|
|
||||||
L_CFLAGS += -DCONFIG_TLS_INTERNAL
|
|
||||||
L_CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER
|
|
||||||
endif
|
|
||||||
ifdef NEED_CIPHER
|
|
||||||
NEED_DES=y
|
|
||||||
OBJS += src/crypto/crypto_internal-cipher.c
|
|
||||||
endif
|
|
||||||
ifdef NEED_MODEXP
|
|
||||||
OBJS += src/crypto/crypto_internal-modexp.c
|
|
||||||
OBJS += src/tls/bignum.c
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_CRYPTO), libtomcrypt)
|
|
||||||
OBJS += src/crypto/crypto_libtomcrypt.c
|
|
||||||
LIBS += -ltomcrypt -ltfm
|
|
||||||
LIBS_h += -ltomcrypt -ltfm
|
|
||||||
CONFIG_INTERNAL_SHA256=y
|
|
||||||
CONFIG_INTERNAL_RC4=y
|
|
||||||
CONFIG_INTERNAL_DH_GROUP5=y
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_CRYPTO), internal)
|
|
||||||
OBJS += src/crypto/crypto_internal.c
|
|
||||||
NEED_AES_DEC=y
|
|
||||||
L_CFLAGS += -DCONFIG_CRYPTO_INTERNAL
|
|
||||||
ifdef CONFIG_INTERNAL_LIBTOMMATH
|
|
||||||
L_CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH
|
|
||||||
ifdef CONFIG_INTERNAL_LIBTOMMATH_FAST
|
|
||||||
L_CFLAGS += -DLTM_FAST
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
LIBS += -ltommath
|
|
||||||
LIBS_h += -ltommath
|
|
||||||
endif
|
|
||||||
CONFIG_INTERNAL_AES=y
|
|
||||||
CONFIG_INTERNAL_DES=y
|
|
||||||
CONFIG_INTERNAL_SHA1=y
|
|
||||||
CONFIG_INTERNAL_MD4=y
|
|
||||||
CONFIG_INTERNAL_MD5=y
|
|
||||||
CONFIG_INTERNAL_SHA256=y
|
|
||||||
CONFIG_INTERNAL_RC4=y
|
|
||||||
CONFIG_INTERNAL_DH_GROUP5=y
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_CRYPTO), cryptoapi)
|
|
||||||
OBJS += src/crypto/crypto_cryptoapi.c
|
|
||||||
OBJS_p += src/crypto/crypto_cryptoapi.c
|
|
||||||
L_CFLAGS += -DCONFIG_CRYPTO_CRYPTOAPI
|
|
||||||
CONFIG_INTERNAL_SHA256=y
|
|
||||||
CONFIG_INTERNAL_RC4=y
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_TLS), none)
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
OBJS += src/crypto/tls_none.c
|
|
||||||
L_CFLAGS += -DEAP_TLS_NONE
|
|
||||||
CONFIG_INTERNAL_AES=y
|
|
||||||
CONFIG_INTERNAL_SHA1=y
|
|
||||||
CONFIG_INTERNAL_MD5=y
|
|
||||||
endif
|
|
||||||
OBJS += src/crypto/crypto_none.c
|
|
||||||
OBJS_p += src/crypto/crypto_none.c
|
|
||||||
CONFIG_INTERNAL_SHA256=y
|
|
||||||
CONFIG_INTERNAL_RC4=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifndef TLS_FUNCS
|
|
||||||
OBJS += src/crypto/tls_none.c
|
|
||||||
ifeq ($(CONFIG_TLS), internal)
|
|
||||||
CONFIG_INTERNAL_AES=y
|
|
||||||
CONFIG_INTERNAL_SHA1=y
|
|
||||||
CONFIG_INTERNAL_MD5=y
|
|
||||||
CONFIG_INTERNAL_RC4=y
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
AESOBJS = # none so far
|
|
||||||
ifdef CONFIG_INTERNAL_AES
|
|
||||||
AESOBJS += src/crypto/aes-internal.c src/crypto/aes-internal-enc.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
AESOBJS += src/crypto/aes-wrap.c
|
|
||||||
ifdef NEED_AES_EAX
|
|
||||||
AESOBJS += src/crypto/aes-eax.c
|
|
||||||
NEED_AES_CTR=y
|
|
||||||
endif
|
|
||||||
ifdef NEED_AES_CTR
|
|
||||||
AESOBJS += src/crypto/aes-ctr.c
|
|
||||||
endif
|
|
||||||
ifdef NEED_AES_ENCBLOCK
|
|
||||||
AESOBJS += src/crypto/aes-encblock.c
|
|
||||||
endif
|
|
||||||
ifdef NEED_AES_OMAC1
|
|
||||||
AESOBJS += src/crypto/aes-omac1.c
|
|
||||||
endif
|
|
||||||
ifdef NEED_AES_UNWRAP
|
|
||||||
NEED_AES_DEC=y
|
|
||||||
AESOBJS += src/crypto/aes-unwrap.c
|
|
||||||
endif
|
|
||||||
ifdef NEED_AES_CBC
|
|
||||||
NEED_AES_DEC=y
|
|
||||||
AESOBJS += src/crypto/aes-cbc.c
|
|
||||||
endif
|
|
||||||
ifdef NEED_AES_DEC
|
|
||||||
ifdef CONFIG_INTERNAL_AES
|
|
||||||
AESOBJS += src/crypto/aes-internal-dec.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
ifdef NEED_AES
|
|
||||||
OBJS += $(AESOBJS)
|
|
||||||
endif
|
|
||||||
|
|
||||||
SHA1OBJS =
|
|
||||||
ifdef NEED_SHA1
|
|
||||||
SHA1OBJS += src/crypto/sha1.c
|
|
||||||
ifdef CONFIG_INTERNAL_SHA1
|
|
||||||
SHA1OBJS += src/crypto/sha1-internal.c
|
|
||||||
ifdef NEED_FIPS186_2_PRF
|
|
||||||
SHA1OBJS += src/crypto/fips_prf_internal.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
SHA1OBJS += src/crypto/sha1-pbkdf2.c
|
|
||||||
ifdef NEED_T_PRF
|
|
||||||
SHA1OBJS += src/crypto/sha1-tprf.c
|
|
||||||
endif
|
|
||||||
ifdef NEED_TLS_PRF
|
|
||||||
SHA1OBJS += src/crypto/sha1-tlsprf.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_SHA1
|
|
||||||
OBJS += $(SHA1OBJS)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_MD5
|
|
||||||
ifdef CONFIG_INTERNAL_MD5
|
|
||||||
OBJS += src/crypto/md5-internal.c
|
|
||||||
HOBJS += src/crypto/md5-internal.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_MD4
|
|
||||||
ifdef CONFIG_INTERNAL_MD4
|
|
||||||
OBJS += src/crypto/md4-internal.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_DES
|
|
||||||
ifdef CONFIG_INTERNAL_DES
|
|
||||||
OBJS += src/crypto/des-internal.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_RC4
|
|
||||||
ifdef CONFIG_INTERNAL_RC4
|
|
||||||
OBJS += src/crypto/rc4.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_SHA256
|
|
||||||
OBJS += src/crypto/sha256.c
|
|
||||||
ifdef CONFIG_INTERNAL_SHA256
|
|
||||||
OBJS += src/crypto/sha256-internal.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_DH_GROUPS
|
|
||||||
OBJS += src/crypto/dh_groups.c
|
|
||||||
endif
|
|
||||||
ifdef NEED_DH_GROUPS_ALL
|
|
||||||
L_CFLAGS += -DALL_DH_GROUPS
|
|
||||||
endif
|
|
||||||
ifdef CONFIG_INTERNAL_DH_GROUP5
|
|
||||||
ifdef NEED_DH_GROUPS
|
|
||||||
OBJS += src/crypto/dh_group5.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_NO_RANDOM_POOL
|
|
||||||
L_CFLAGS += -DCONFIG_NO_RANDOM_POOL
|
|
||||||
else
|
|
||||||
OBJS += src/crypto/random.c
|
|
||||||
HOBJS += src/crypto/random.c
|
|
||||||
HOBJS += $(SHA1OBJS)
|
|
||||||
HOBJS += src/crypto/md5.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_RADIUS_SERVER
|
|
||||||
L_CFLAGS += -DRADIUS_SERVER
|
|
||||||
OBJS += src/radius/radius_server.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_IPV6
|
|
||||||
L_CFLAGS += -DCONFIG_IPV6
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_DRIVER_RADIUS_ACL
|
|
||||||
L_CFLAGS += -DCONFIG_DRIVER_RADIUS_ACL
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_FULL_DYNAMIC_VLAN
|
|
||||||
# define CONFIG_FULL_DYNAMIC_VLAN to have hostapd manipulate bridges
|
|
||||||
# and vlan interfaces for the vlan feature.
|
|
||||||
L_CFLAGS += -DCONFIG_FULL_DYNAMIC_VLAN
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_BASE64
|
|
||||||
OBJS += src/utils/base64.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_AP_MLME
|
|
||||||
OBJS += src/ap/beacon.c
|
|
||||||
OBJS += src/ap/wmm.c
|
|
||||||
OBJS += src/ap/ap_list.c
|
|
||||||
OBJS += src/ap/ieee802_11.c
|
|
||||||
OBJS += src/ap/hw_features.c
|
|
||||||
L_CFLAGS += -DNEED_AP_MLME
|
|
||||||
endif
|
|
||||||
ifdef CONFIG_IEEE80211N
|
|
||||||
OBJS += src/ap/ieee802_11_ht.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_P2P_MANAGER
|
|
||||||
L_CFLAGS += -DCONFIG_P2P_MANAGER
|
|
||||||
OBJS += src/ap/p2p_hostapd.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_NO_STDOUT_DEBUG
|
|
||||||
L_CFLAGS += -DCONFIG_NO_STDOUT_DEBUG
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_DEBUG_FILE
|
|
||||||
L_CFLAGS += -DCONFIG_DEBUG_FILE
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_ANDROID_LOG
|
|
||||||
L_CFLAGS += -DCONFIG_ANDROID_LOG
|
|
||||||
endif
|
|
||||||
|
|
||||||
OBJS_c = hostapd_cli.c src/common/wpa_ctrl.c src/utils/os_$(CONFIG_OS).c
|
|
||||||
ifdef CONFIG_WPA_TRACE
|
|
||||||
OBJS_c += src/utils/trace.c
|
|
||||||
OBJS_c += src/utils/wpa_debug.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(WPA_BUILD_HOSTAPD),true)
|
|
||||||
|
|
||||||
########################
|
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
LOCAL_MODULE := hostapd_cli
|
|
||||||
LOCAL_MODULE_TAGS := debug
|
|
||||||
LOCAL_SHARED_LIBRARIES := libc libcutils
|
|
||||||
LOCAL_CFLAGS := $(L_CFLAGS)
|
|
||||||
LOCAL_SRC_FILES := $(OBJS_c)
|
|
||||||
LOCAL_C_INCLUDES := $(INCLUDES)
|
|
||||||
include $(BUILD_EXECUTABLE)
|
|
||||||
|
|
||||||
########################
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
LOCAL_MODULE := hostapd
|
|
||||||
LOCAL_MODULE_TAGS := optional
|
|
||||||
ifdef CONFIG_DRIVER_CUSTOM
|
|
||||||
LOCAL_STATIC_LIBRARIES := libCustomWifi
|
|
||||||
endif
|
|
||||||
ifneq ($(BOARD_HOSTAPD_PRIVATE_LIB),)
|
|
||||||
LOCAL_STATIC_LIBRARIES += $(BOARD_HOSTAPD_PRIVATE_LIB)
|
|
||||||
endif
|
|
||||||
LOCAL_SHARED_LIBRARIES := libc libcutils libcrypto libssl
|
|
||||||
ifdef CONFIG_DRIVER_NL80211
|
|
||||||
LOCAL_SHARED_LIBRARIES += libnl_2
|
|
||||||
endif
|
|
||||||
LOCAL_CFLAGS := $(L_CFLAGS)
|
|
||||||
LOCAL_SRC_FILES := $(OBJS)
|
|
||||||
LOCAL_C_INCLUDES := $(INCLUDES)
|
|
||||||
include $(BUILD_EXECUTABLE)
|
|
||||||
|
|
||||||
endif # ifeq ($(WPA_BUILD_HOSTAPD),true)
|
|
|
@ -1,647 +0,0 @@
|
||||||
ChangeLog for hostapd
|
|
||||||
|
|
||||||
2010-04-18 - v0.7.2
|
|
||||||
* fix WPS internal Registrar use when an external Registrar is also
|
|
||||||
active
|
|
||||||
* bsd: Cleaned up driver wrapper and added various low-level
|
|
||||||
configuration options
|
|
||||||
* TNC: fixed issues with fragmentation
|
|
||||||
* EAP-TNC: add Flags field into fragment acknowledgement (needed to
|
|
||||||
interoperate with other implementations; may potentially breaks
|
|
||||||
compatibility with older wpa_supplicant/hostapd versions)
|
|
||||||
* cleaned up driver wrapper API for multi-BSS operations
|
|
||||||
* nl80211: fix multi-BSS and VLAN operations
|
|
||||||
* fix number of issues with IEEE 802.11r/FT; this version is not
|
|
||||||
backwards compatible with old versions
|
|
||||||
* add SA Query Request processing in AP mode (IEEE 802.11w)
|
|
||||||
* fix IGTK PN in group rekeying (IEEE 802.11w)
|
|
||||||
* fix WPS PBC session overlap detection to use correct attribute
|
|
||||||
* hostapd_notif_Assoc() can now be called with all IEs to simplify
|
|
||||||
driver wrappers
|
|
||||||
* work around interoperability issue with some WPS External Registrar
|
|
||||||
implementations
|
|
||||||
* nl80211: fix WPS IE update
|
|
||||||
* hostapd_cli: add support for action script operations (run a script
|
|
||||||
on hostapd events)
|
|
||||||
* fix DH padding with internal crypto code (mainly, for WPS)
|
|
||||||
* fix WPS association with both WPS IE and WPA/RSN IE present with
|
|
||||||
driver wrappers that use hostapd MLME (e.g., nl80211)
|
|
||||||
|
|
||||||
2010-01-16 - v0.7.1
|
|
||||||
* cleaned up driver wrapper API (struct wpa_driver_ops); the new API
|
|
||||||
is not fully backwards compatible, so out-of-tree driver wrappers
|
|
||||||
will need modifications
|
|
||||||
* cleaned up various module interfaces
|
|
||||||
* merge hostapd and wpa_supplicant developers' documentation into a
|
|
||||||
single document
|
|
||||||
* fixed HT Capabilities IE with nl80211 drivers
|
|
||||||
* moved generic AP functionality code into src/ap
|
|
||||||
* WPS: handle Selected Registrar as union of info from all Registrars
|
|
||||||
* remove obsolte Prism54.org driver wrapper
|
|
||||||
* added internal debugging mechanism with backtrace support and memory
|
|
||||||
allocation/freeing validation, etc. tests (CONFIG_WPA_TRACE=y)
|
|
||||||
* EAP-FAST server: piggyback Phase 2 start with the end of Phase 1
|
|
||||||
* WPS: add support for dynamically selecting whether to provision the
|
|
||||||
PSK as an ASCII passphrase or PSK
|
|
||||||
* added support for WDS (4-address frame) mode with per-station virtual
|
|
||||||
interfaces (wds_sta=1 in config file; only supported with
|
|
||||||
driver=nl80211 for now)
|
|
||||||
* fixed WPS Probe Request processing to handle missing required
|
|
||||||
attribute
|
|
||||||
* fixed PKCS#12 use with OpenSSL 1.0.0
|
|
||||||
* detect bridge interface automatically so that bridge parameter in
|
|
||||||
hostapd.conf becomes optional (though, it may now be used to
|
|
||||||
automatically add then WLAN interface into a bridge with
|
|
||||||
driver=nl80211)
|
|
||||||
|
|
||||||
2009-11-21 - v0.7.0
|
|
||||||
* increased hostapd_cli ping interval to 5 seconds and made this
|
|
||||||
configurable with a new command line options (-G<seconds>)
|
|
||||||
* driver_nl80211: use Linux socket filter to improve performance
|
|
||||||
* added support for external Registrars with WPS (UPnP transport)
|
|
||||||
* 802.11n: scan for overlapping BSSes before starting 20/40 MHz channel
|
|
||||||
* driver_nl80211: fixed STA accounting data collection (TX/RX bytes
|
|
||||||
reported correctly; TX/RX packets not yet available from kernel)
|
|
||||||
* added support for WPS USBA out-of-band mechanism with USB Flash
|
|
||||||
Drives (UFD) (CONFIG_WPS_UFD=y)
|
|
||||||
* fixed EAPOL/EAP reauthentication when using an external RADIUS
|
|
||||||
authentication server
|
|
||||||
* fixed TNC with EAP-TTLS
|
|
||||||
* fixed IEEE 802.11r key derivation function to match with the standard
|
|
||||||
(note: this breaks interoperability with previous version) [Bug 303]
|
|
||||||
* fixed SHA-256 based key derivation function to match with the
|
|
||||||
standard when using CCMP (for IEEE 802.11r and IEEE 802.11w)
|
|
||||||
(note: this breaks interoperability with previous version) [Bug 307]
|
|
||||||
* added number of code size optimizations to remove unnecessary
|
|
||||||
functionality from the program binary based on build configuration
|
|
||||||
(part of this automatic; part configurable with CONFIG_NO_* build
|
|
||||||
options)
|
|
||||||
* use shared driver wrapper files with wpa_supplicant
|
|
||||||
* driver_nl80211: multiple updates to provide support for new Linux
|
|
||||||
nl80211/mac80211 functionality
|
|
||||||
* updated management frame protection to use IEEE Std 802.11w-2009
|
|
||||||
* fixed number of small WPS issues and added workarounds to
|
|
||||||
interoperate with common deployed broken implementations
|
|
||||||
* added some IEEE 802.11n co-existance rules to disable 40 MHz channels
|
|
||||||
or modify primary/secondary channels if needed based on neighboring
|
|
||||||
networks
|
|
||||||
* added support for NFC out-of-band mechanism with WPS
|
|
||||||
* added preliminary support for IEEE 802.11r RIC processing
|
|
||||||
|
|
||||||
2009-01-06 - v0.6.7
|
|
||||||
* added support for Wi-Fi Protected Setup (WPS)
|
|
||||||
(hostapd can now be configured to act as an integrated WPS Registrar
|
|
||||||
and provision credentials for WPS Enrollees using PIN and PBC
|
|
||||||
methods; external wireless Registrar can configure the AP, but
|
|
||||||
external WLAN Manager Registrars are not supported); WPS support can
|
|
||||||
be enabled by adding CONFIG_WPS=y into .config and setting the
|
|
||||||
runtime configuration variables in hostapd.conf (see WPS section in
|
|
||||||
the example configuration file); new hostapd_cli commands wps_pin and
|
|
||||||
wps_pbc are used to configure WPS negotiation; see README-WPS for
|
|
||||||
more details
|
|
||||||
* added IEEE 802.11n HT capability configuration (ht_capab)
|
|
||||||
* added support for generating Country IE based on nl80211 regulatory
|
|
||||||
information (added if ieee80211d=1 in configuration)
|
|
||||||
* fixed WEP authentication (both Open System and Shared Key) with
|
|
||||||
mac80211
|
|
||||||
* added support for EAP-AKA' (draft-arkko-eap-aka-kdf)
|
|
||||||
* added support for using driver_test over UDP socket
|
|
||||||
* changed EAP-GPSK to use the IANA assigned EAP method type 51
|
|
||||||
* updated management frame protection to use IEEE 802.11w/D7.0
|
|
||||||
* fixed retransmission of EAP requests if no response is received
|
|
||||||
|
|
||||||
2008-11-23 - v0.6.6
|
|
||||||
* added a new configuration option, wpa_ptk_rekey, that can be used to
|
|
||||||
enforce frequent PTK rekeying, e.g., to mitigate some attacks against
|
|
||||||
TKIP deficiencies
|
|
||||||
* updated OpenSSL code for EAP-FAST to use an updated version of the
|
|
||||||
session ticket overriding API that was included into the upstream
|
|
||||||
OpenSSL 0.9.9 tree on 2008-11-15 (no additional OpenSSL patch is
|
|
||||||
needed with that version anymore)
|
|
||||||
* changed channel flags configuration to read the information from
|
|
||||||
the driver (e.g., via driver_nl80211 when using mac80211) instead of
|
|
||||||
using hostapd as the source of the regulatory information (i.e.,
|
|
||||||
information from CRDA is now used with mac80211); this allows 5 GHz
|
|
||||||
channels to be used with hostapd (if allowed in the current
|
|
||||||
regulatory domain)
|
|
||||||
* fixed EAP-TLS message processing for the last TLS message if it is
|
|
||||||
large enough to require fragmentation (e.g., if a large Session
|
|
||||||
Ticket data is included)
|
|
||||||
* fixed listen interval configuration for nl80211 drivers
|
|
||||||
|
|
||||||
2008-11-01 - v0.6.5
|
|
||||||
* added support for SHA-256 as X.509 certificate digest when using the
|
|
||||||
internal X.509/TLSv1 implementation
|
|
||||||
* fixed EAP-FAST PAC-Opaque padding (0.6.4 broke this for some peer
|
|
||||||
identity lengths)
|
|
||||||
* fixed internal TLSv1 implementation for abbreviated handshake (used
|
|
||||||
by EAP-FAST server)
|
|
||||||
* added support for setting VLAN ID for STAs based on local MAC ACL
|
|
||||||
(accept_mac_file) as an alternative for RADIUS server-based
|
|
||||||
configuration
|
|
||||||
* updated management frame protection to use IEEE 802.11w/D6.0
|
|
||||||
(adds a new association ping to protect against unauthenticated
|
|
||||||
authenticate or (re)associate request frames dropping association)
|
|
||||||
* added support for using SHA256-based stronger key derivation for WPA2
|
|
||||||
(IEEE 802.11w)
|
|
||||||
* added new "driver wrapper" for RADIUS-only configuration
|
|
||||||
(driver=none in hostapd.conf; CONFIG_DRIVER_NONE=y in .config)
|
|
||||||
* fixed WPA/RSN IE validation to verify that the proto (WPA vs. WPA2)
|
|
||||||
is enabled in configuration
|
|
||||||
* changed EAP-FAST configuration to use separate fields for A-ID and
|
|
||||||
A-ID-Info (eap_fast_a_id_info) to allow A-ID to be set to a fixed
|
|
||||||
16-octet len binary value for better interoperability with some peer
|
|
||||||
implementations; eap_fast_a_id is now configured as a hex string
|
|
||||||
* driver_nl80211: Updated to match the current Linux mac80211 AP mode
|
|
||||||
configuration (wireless-testing.git and Linux kernel releases
|
|
||||||
starting from 2.6.29)
|
|
||||||
|
|
||||||
2008-08-10 - v0.6.4
|
|
||||||
* added peer identity into EAP-FAST PAC-Opaque and skip Phase 2
|
|
||||||
Identity Request if identity is already known
|
|
||||||
* added support for EAP Sequences in EAP-FAST Phase 2
|
|
||||||
* added support for EAP-TNC (Trusted Network Connect)
|
|
||||||
(this version implements the EAP-TNC method and EAP-TTLS/EAP-FAST
|
|
||||||
changes needed to run two methods in sequence (IF-T) and the IF-IMV
|
|
||||||
and IF-TNCCS interfaces from TNCS)
|
|
||||||
* added support for optional cryptobinding with PEAPv0
|
|
||||||
* added fragmentation support for EAP-TNC
|
|
||||||
* added support for fragmenting EAP-TTLS/PEAP/FAST Phase 2 (tunneled)
|
|
||||||
data
|
|
||||||
* added support for opportunistic key caching (OKC)
|
|
||||||
|
|
||||||
2008-02-22 - v0.6.3
|
|
||||||
* fixed Reassociation Response callback processing when using internal
|
|
||||||
MLME (driver_{hostap,nl80211,test}.c)
|
|
||||||
* updated FT support to use the latest draft, IEEE 802.11r/D9.0
|
|
||||||
* copy optional Proxy-State attributes into RADIUS response when acting
|
|
||||||
as a RADIUS authentication server
|
|
||||||
* fixed EAPOL state machine to handle a case in which no response is
|
|
||||||
received from the RADIUS authentication server; previous version
|
|
||||||
could have triggered a crash in some cases after a timeout
|
|
||||||
* fixed EAP-SIM/AKA realm processing to allow decorated usernames to
|
|
||||||
be used
|
|
||||||
* added a workaround for EAP-SIM/AKA peers that include incorrect null
|
|
||||||
termination in the username
|
|
||||||
* fixed EAP-SIM/AKA protected result indication to include AT_COUNTER
|
|
||||||
attribute in notification messages only when using fast
|
|
||||||
reauthentication
|
|
||||||
* fixed EAP-SIM Start response processing for fast reauthentication
|
|
||||||
case
|
|
||||||
* added support for pending EAP processing in EAP-{PEAP,TTLS,FAST}
|
|
||||||
phase 2 to allow EAP-SIM and EAP-AKA to be used as the Phase 2 method
|
|
||||||
|
|
||||||
2008-01-01 - v0.6.2
|
|
||||||
* fixed EAP-SIM and EAP-AKA message parser to validate attribute
|
|
||||||
lengths properly to avoid potential crash caused by invalid messages
|
|
||||||
* added data structure for storing allocated buffers (struct wpabuf);
|
|
||||||
this does not affect hostapd usage, but many of the APIs changed
|
|
||||||
and various interfaces (e.g., EAP) is not compatible with old
|
|
||||||
versions
|
|
||||||
* added support for protecting EAP-AKA/Identity messages with
|
|
||||||
AT_CHECKCODE (optional feature in RFC 4187)
|
|
||||||
* added support for protected result indication with AT_RESULT_IND for
|
|
||||||
EAP-SIM and EAP-AKA (eap_sim_aka_result_ind=1)
|
|
||||||
* added support for configuring EAP-TTLS phase 2 non-EAP methods in
|
|
||||||
EAP server configuration; previously all four were enabled for every
|
|
||||||
phase 2 user, now all four are disabled by default and need to be
|
|
||||||
enabled with new method names TTLS-PAP, TTLS-CHAP, TTLS-MSCHAP,
|
|
||||||
TTLS-MSCHAPV2
|
|
||||||
* removed old debug printing mechanism and the related 'debug'
|
|
||||||
parameter in the configuration file; debug verbosity is now set with
|
|
||||||
-d (or -dd) command line arguments
|
|
||||||
* added support for EAP-IKEv2 (draft-tschofenig-eap-ikev2-15.txt);
|
|
||||||
only shared key/password authentication is supported in this version
|
|
||||||
|
|
||||||
2007-11-24 - v0.6.1
|
|
||||||
* added experimental, integrated TLSv1 server implementation with the
|
|
||||||
needed X.509/ASN.1/RSA/bignum processing (this can be enabled by
|
|
||||||
setting CONFIG_TLS=internal and CONFIG_INTERNAL_LIBTOMMATH=y in
|
|
||||||
.config); this can be useful, e.g., if the target system does not
|
|
||||||
have a suitable TLS library and a minimal code size is required
|
|
||||||
* added support for EAP-FAST server method to the integrated EAP
|
|
||||||
server
|
|
||||||
* updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest
|
|
||||||
draft (draft-ietf-emu-eap-gpsk-07.txt)
|
|
||||||
* added a new configuration parameter, rsn_pairwise, to allow different
|
|
||||||
pairwise cipher suites to be enabled for WPA and RSN/WPA2
|
|
||||||
(note: if wpa_pairwise differs from rsn_pairwise, the driver will
|
|
||||||
either need to support this or will have to use the WPA/RSN IEs from
|
|
||||||
hostapd; currently, the included madwifi and bsd driver interfaces do
|
|
||||||
not have support for this)
|
|
||||||
* updated FT support to use the latest draft, IEEE 802.11r/D8.0
|
|
||||||
|
|
||||||
2007-05-28 - v0.6.0
|
|
||||||
* added experimental IEEE 802.11r/D6.0 support
|
|
||||||
* updated EAP-SAKE to RFC 4763 and the IANA-allocated EAP type 48
|
|
||||||
* updated EAP-PSK to use the IANA-allocated EAP type 47
|
|
||||||
* fixed EAP-PSK bit ordering of the Flags field
|
|
||||||
* fixed configuration reloading (SIGHUP) to re-initialize WPA PSKs
|
|
||||||
by reading wpa_psk_file [Bug 181]
|
|
||||||
* fixed EAP-TTLS AVP parser processing for too short AVP lengths
|
|
||||||
* fixed IPv6 connection to RADIUS accounting server
|
|
||||||
* updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest
|
|
||||||
draft (draft-ietf-emu-eap-gpsk-04.txt)
|
|
||||||
* hlr_auc_gw: read GSM triplet file into memory and rotate through the
|
|
||||||
entries instead of only using the same three triplets every time
|
|
||||||
(this does not work properly with tests using multiple clients, but
|
|
||||||
provides bit better triplet data for testing a single client; anyway,
|
|
||||||
if a better quality triplets are needed, GSM-Milenage should be used
|
|
||||||
instead of hardcoded triplet file)
|
|
||||||
* fixed EAP-MSCHAPv2 server to use a space between S and M parameters
|
|
||||||
in Success Request [Bug 203]
|
|
||||||
* added support for sending EAP-AKA Notifications in error cases
|
|
||||||
* updated to use IEEE 802.11w/D2.0 for management frame protection
|
|
||||||
(still experimental)
|
|
||||||
* RADIUS server: added support for processing duplicate messages
|
|
||||||
(retransmissions from RADIUS client) by replying with the previous
|
|
||||||
reply
|
|
||||||
|
|
||||||
2006-11-24 - v0.5.6
|
|
||||||
* added support for configuring and controlling multiple BSSes per
|
|
||||||
radio interface (bss=<ifname> in hostapd.conf); this is only
|
|
||||||
available with Devicescape and test driver interfaces
|
|
||||||
* fixed PMKSA cache update in the end of successful RSN
|
|
||||||
pre-authentication
|
|
||||||
* added support for dynamic VLAN configuration (i.e., selecting VLAN-ID
|
|
||||||
for each STA based on RADIUS Access-Accept attributes); this requires
|
|
||||||
VLAN support from the kernel driver/802.11 stack and this is
|
|
||||||
currently only available with Devicescape and test driver interfaces
|
|
||||||
* driver_madwifi: fixed configuration of unencrypted modes (plaintext
|
|
||||||
and IEEE 802.1X without WEP)
|
|
||||||
* removed STAKey handshake since PeerKey handshake has replaced it in
|
|
||||||
IEEE 802.11ma and there are no known deployments of STAKey
|
|
||||||
* updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest
|
|
||||||
draft (draft-ietf-emu-eap-gpsk-01.txt)
|
|
||||||
* added preliminary implementation of IEEE 802.11w/D1.0 (management
|
|
||||||
frame protection)
|
|
||||||
(Note: this requires driver support to work properly.)
|
|
||||||
(Note2: IEEE 802.11w is an unapproved draft and subject to change.)
|
|
||||||
* hlr_auc_gw: added support for GSM-Milenage (for EAP-SIM)
|
|
||||||
* hlr_auc_gw: added support for reading per-IMSI Milenage keys and
|
|
||||||
parameters from a text file to make it possible to implement proper
|
|
||||||
GSM/UMTS authentication server for multiple SIM/USIM cards using
|
|
||||||
EAP-SIM/EAP-AKA
|
|
||||||
* fixed session timeout processing with drivers that do not use
|
|
||||||
ieee802_11.c (e.g., madwifi)
|
|
||||||
|
|
||||||
2006-08-27 - v0.5.5
|
|
||||||
* added 'hostapd_cli new_sta <addr>' command for adding a new STA into
|
|
||||||
hostapd (e.g., to initialize wired network authentication based on an
|
|
||||||
external signal)
|
|
||||||
* fixed hostapd to add PMKID KDE into 4-Way Handshake Message 1 when
|
|
||||||
using WPA2 even if PMKSA caching is not used
|
|
||||||
* added -P<pid file> argument for hostapd to write the current process
|
|
||||||
id into a file
|
|
||||||
* added support for RADIUS Authentication Server MIB (RFC 2619)
|
|
||||||
|
|
||||||
2006-06-20 - v0.5.4
|
|
||||||
* fixed nt_password_hash build [Bug 144]
|
|
||||||
* added PeerKey handshake implementation for IEEE 802.11e
|
|
||||||
direct link setup (DLS) to replace STAKey handshake
|
|
||||||
* added support for EAP Generalized Pre-Shared Key (EAP-GPSK,
|
|
||||||
draft-clancy-emu-eap-shared-secret-00.txt)
|
|
||||||
* fixed a segmentation fault when RSN pre-authentication was completed
|
|
||||||
successfully [Bug 152]
|
|
||||||
|
|
||||||
2006-04-27 - v0.5.3
|
|
||||||
* do not build nt_password_hash and hlr_auc_gw by default to avoid
|
|
||||||
requiring a TLS library for a successful build; these programs can be
|
|
||||||
build with 'make nt_password_hash' and 'make hlr_auc_gw'
|
|
||||||
* added a new configuration option, eapol_version, that can be used to
|
|
||||||
set EAPOL version to 1 (default is 2) to work around broken client
|
|
||||||
implementations that drop EAPOL frames which use version number 2
|
|
||||||
[Bug 89]
|
|
||||||
* added support for EAP-SAKE (no EAP method number allocated yet, so
|
|
||||||
this is using the same experimental type 255 as EAP-PSK)
|
|
||||||
* fixed EAP-MSCHAPv2 message length validation
|
|
||||||
|
|
||||||
2006-03-19 - v0.5.2
|
|
||||||
* fixed stdarg use in hostapd_logger(): if both stdout and syslog
|
|
||||||
logging was enabled, hostapd could trigger a segmentation fault in
|
|
||||||
vsyslog on some CPU -- C library combinations
|
|
||||||
* moved HLR/AuC gateway implementation for EAP-SIM/AKA into an external
|
|
||||||
program to make it easier to use for implementing real SS7 gateway;
|
|
||||||
eap_sim_db is not anymore used as a file name for GSM authentication
|
|
||||||
triplets; instead, it is path to UNIX domain socket that will be used
|
|
||||||
to communicate with the external gateway program (e.g., hlr_auc_gw)
|
|
||||||
* added example HLR/AuC gateway implementation, hlr_auc_gw, that uses
|
|
||||||
local information (GSM authentication triplets from a text file and
|
|
||||||
hardcoded AKA authentication data); this can be used to test EAP-SIM
|
|
||||||
and EAP-AKA
|
|
||||||
* added Milenage algorithm (example 3GPP AKA algorithm) to hlr_auc_gw
|
|
||||||
to make it possible to test EAP-AKA with real USIM cards (this is
|
|
||||||
disabled by default; define AKA_USE_MILENAGE when building hlr_auc_gw
|
|
||||||
to enable this)
|
|
||||||
* driver_madwifi: added support for getting station RSN IE from
|
|
||||||
madwifi-ng svn r1453 and newer; this fixes RSN that was apparently
|
|
||||||
broken with earlier change (r1357) in the driver
|
|
||||||
* changed EAP method registration to use a dynamic list of methods
|
|
||||||
instead of a static list generated at build time
|
|
||||||
* fixed WPA message 3/4 not to encrypt Key Data field (WPA IE)
|
|
||||||
[Bug 125]
|
|
||||||
* added ap_max_inactivity configuration parameter
|
|
||||||
|
|
||||||
2006-01-29 - v0.5.1
|
|
||||||
* driver_test: added better support for multiple APs and STAs by using
|
|
||||||
a directory with sockets that include MAC address for each device in
|
|
||||||
the name (test_socket=DIR:/tmp/test)
|
|
||||||
* added support for EAP expanded type (vendor specific EAP methods)
|
|
||||||
|
|
||||||
2005-12-18 - v0.5.0 (beginning of 0.5.x development releases)
|
|
||||||
* added experimental STAKey handshake implementation for IEEE 802.11e
|
|
||||||
direct link setup (DLS); note: this is disabled by default in both
|
|
||||||
build and runtime configuration (can be enabled with CONFIG_STAKEY=y
|
|
||||||
and stakey=1)
|
|
||||||
* added support for EAP methods to use callbacks to external programs
|
|
||||||
by buffering a pending request and processing it after the EAP method
|
|
||||||
is ready to continue
|
|
||||||
* improved EAP-SIM database interface to allow external request to GSM
|
|
||||||
HLR/AuC without blocking hostapd process
|
|
||||||
* added support for using EAP-SIM pseudonyms and fast re-authentication
|
|
||||||
* added support for EAP-AKA in the integrated EAP authenticator
|
|
||||||
* added support for matching EAP identity prefixes (e.g., "1"*) in EAP
|
|
||||||
user database to allow EAP-SIM/AKA selection without extra roundtrip
|
|
||||||
for EAP-Nak negotiation
|
|
||||||
* added support for storing EAP user password as NtPasswordHash instead
|
|
||||||
of plaintext password when using MSCHAP or MSCHAPv2 for
|
|
||||||
authentication (hash:<16-octet hex value>); added nt_password_hash
|
|
||||||
tool for hashing password to generate NtPasswordHash
|
|
||||||
|
|
||||||
2005-11-20 - v0.4.7 (beginning of 0.4.x stable releases)
|
|
||||||
* driver_wired: fixed EAPOL sending to optionally use PAE group address
|
|
||||||
as the destination instead of supplicant MAC address; this is
|
|
||||||
disabled by default, but should be enabled with use_pae_group_addr=1
|
|
||||||
in configuration file if the wired interface is used by only one
|
|
||||||
device at the time (common switch configuration)
|
|
||||||
* driver_madwifi: configure driver to use TKIP countermeasures in order
|
|
||||||
to get correct behavior (IEEE 802.11 association failing; previously,
|
|
||||||
association succeeded, but hostpad forced disassociation immediately)
|
|
||||||
* driver_madwifi: added support for madwifi-ng
|
|
||||||
|
|
||||||
2005-10-27 - v0.4.6
|
|
||||||
* added support for replacing user identity from EAP with RADIUS
|
|
||||||
User-Name attribute from Access-Accept message, if that is included,
|
|
||||||
for the RADIUS accounting messages (e.g., for EAP-PEAP/TTLS to get
|
|
||||||
tunneled identity into accounting messages when the RADIUS server
|
|
||||||
does not support better way of doing this with Class attribute)
|
|
||||||
* driver_madwifi: fixed EAPOL packet receive for configuration where
|
|
||||||
ath# is part of a bridge interface
|
|
||||||
* added a configuration file and log analyzer script for logwatch
|
|
||||||
* fixed EAPOL state machine step function to process all state
|
|
||||||
transitions before processing new events; this resolves a race
|
|
||||||
condition in which EAPOL-Start message could trigger hostapd to send
|
|
||||||
two EAP-Response/Identity frames to the authentication server
|
|
||||||
|
|
||||||
2005-09-25 - v0.4.5
|
|
||||||
* added client CA list to the TLS certificate request in order to make
|
|
||||||
it easier for the client to select which certificate to use
|
|
||||||
* added experimental support for EAP-PSK
|
|
||||||
* added support for WE-19 (hostap, madwifi)
|
|
||||||
|
|
||||||
2005-08-21 - v0.4.4
|
|
||||||
* fixed build without CONFIG_RSN_PREAUTH
|
|
||||||
* fixed FreeBSD build
|
|
||||||
|
|
||||||
2005-06-26 - v0.4.3
|
|
||||||
* fixed PMKSA caching to copy User-Name and Class attributes so that
|
|
||||||
RADIUS accounting gets correct information
|
|
||||||
* start RADIUS accounting only after successful completion of WPA
|
|
||||||
4-Way Handshake if WPA-PSK is used
|
|
||||||
* fixed PMKSA caching for the case where STA (re)associates without
|
|
||||||
first disassociating
|
|
||||||
|
|
||||||
2005-06-12 - v0.4.2
|
|
||||||
* EAP-PAX is now registered as EAP type 46
|
|
||||||
* fixed EAP-PAX MAC calculation
|
|
||||||
* fixed EAP-PAX CK and ICK key derivation
|
|
||||||
* renamed eap_authenticator configuration variable to eap_server to
|
|
||||||
better match with RFC 3748 (EAP) terminology
|
|
||||||
* driver_test: added support for testing hostapd with wpa_supplicant
|
|
||||||
by using test driver interface without any kernel drivers or network
|
|
||||||
cards
|
|
||||||
|
|
||||||
2005-05-22 - v0.4.1
|
|
||||||
* fixed RADIUS server initialization when only auth or acct server
|
|
||||||
is configured and the other one is left empty
|
|
||||||
* driver_madwifi: added support for RADIUS accounting
|
|
||||||
* driver_madwifi: added preliminary support for compiling against 'BSD'
|
|
||||||
branch of madwifi CVS tree
|
|
||||||
* driver_madwifi: fixed pairwise key removal to allow WPA reauth
|
|
||||||
without disassociation
|
|
||||||
* added support for reading additional certificates from PKCS#12 files
|
|
||||||
and adding them to the certificate chain
|
|
||||||
* fixed RADIUS Class attribute processing to only use Access-Accept
|
|
||||||
packets to update Class; previously, other RADIUS authentication
|
|
||||||
packets could have cleared Class attribute
|
|
||||||
* added support for more than one Class attribute in RADIUS packets
|
|
||||||
* added support for verifying certificate revocation list (CRL) when
|
|
||||||
using integrated EAP authenticator for EAP-TLS; new hostapd.conf
|
|
||||||
options 'check_crl'; CRL must be included in the ca_cert file for now
|
|
||||||
|
|
||||||
2005-04-25 - v0.4.0 (beginning of 0.4.x development releases)
|
|
||||||
* added support for including network information into
|
|
||||||
EAP-Request/Identity message (ASCII-0 (nul) in eap_message)
|
|
||||||
(e.g., to implement draft-adrange-eap-network-discovery-07.txt)
|
|
||||||
* fixed a bug which caused some RSN pre-authentication cases to use
|
|
||||||
freed memory and potentially crash hostapd
|
|
||||||
* fixed private key loading for cases where passphrase is not set
|
|
||||||
* added support for sending TLS alerts and aborting authentication
|
|
||||||
when receiving a TLS alert
|
|
||||||
* fixed WPA2 to add PMKSA cache entry when using integrated EAP
|
|
||||||
authenticator
|
|
||||||
* fixed PMKSA caching (EAP authentication was not skipped correctly
|
|
||||||
with the new state machine changes from IEEE 802.1X draft)
|
|
||||||
* added support for RADIUS over IPv6; own_ip_addr, auth_server_addr,
|
|
||||||
and acct_server_addr can now be IPv6 addresses (CONFIG_IPV6=y needs
|
|
||||||
to be added to .config to include IPv6 support); for RADIUS server,
|
|
||||||
radius_server_ipv6=1 needs to be set in hostapd.conf and addresses
|
|
||||||
in RADIUS clients file can then use IPv6 format
|
|
||||||
* added experimental support for EAP-PAX
|
|
||||||
* replaced hostapd control interface library (hostapd_ctrl.[ch]) with
|
|
||||||
the same implementation that wpa_supplicant is using (wpa_ctrl.[ch])
|
|
||||||
|
|
||||||
2005-02-12 - v0.3.7 (beginning of 0.3.x stable releases)
|
|
||||||
|
|
||||||
2005-01-23 - v0.3.5
|
|
||||||
* added support for configuring a forced PEAP version based on the
|
|
||||||
Phase 1 identity
|
|
||||||
* fixed PEAPv1 to use tunneled EAP-Success/Failure instead of EAP-TLV
|
|
||||||
to terminate authentication
|
|
||||||
* fixed EAP identifier duplicate processing with the new IEEE 802.1X
|
|
||||||
draft
|
|
||||||
* clear accounting data in the driver when starting a new accounting
|
|
||||||
session
|
|
||||||
* driver_madwifi: filter wireless events based on ifindex to allow more
|
|
||||||
than one network interface to be used
|
|
||||||
* fixed WPA message 2/4 processing not to cancel timeout for TimeoutEvt
|
|
||||||
setting if the packet does not pass MIC verification (e.g., due to
|
|
||||||
incorrect PSK); previously, message 1/4 was not tried again if an
|
|
||||||
invalid message 2/4 was received
|
|
||||||
* fixed reconfiguration of RADIUS client retransmission timer when
|
|
||||||
adding a new message to the pending list; previously, timer was not
|
|
||||||
updated at this point and if there was a pending message with long
|
|
||||||
time for the next retry, the new message needed to wait that long for
|
|
||||||
its first retry, too
|
|
||||||
|
|
||||||
2005-01-09 - v0.3.4
|
|
||||||
* added support for configuring multiple allowed EAP types for Phase 2
|
|
||||||
authentication (EAP-PEAP, EAP-TTLS)
|
|
||||||
* fixed EAPOL-Start processing to trigger WPA reauthentication
|
|
||||||
(previously, only EAPOL authentication was done)
|
|
||||||
|
|
||||||
2005-01-02 - v0.3.3
|
|
||||||
* added support for EAP-PEAP in the integrated EAP authenticator
|
|
||||||
* added support for EAP-GTC in the integrated EAP authenticator
|
|
||||||
* added support for configuring list of EAP methods for Phase 1 so that
|
|
||||||
the integrated EAP authenticator can, e.g., use the wildcard entry
|
|
||||||
for EAP-TLS and EAP-PEAP
|
|
||||||
* added support for EAP-TTLS in the integrated EAP authenticator
|
|
||||||
* added support for EAP-SIM in the integrated EAP authenticator
|
|
||||||
* added support for using hostapd as a RADIUS authentication server
|
|
||||||
with the integrated EAP authenticator taking care of EAP
|
|
||||||
authentication (new hostapd.conf options: radius_server_clients and
|
|
||||||
radius_server_auth_port); this is not included in default build; use
|
|
||||||
CONFIG_RADIUS_SERVER=y in .config to include
|
|
||||||
|
|
||||||
2004-12-19 - v0.3.2
|
|
||||||
* removed 'daemonize' configuration file option since it has not really
|
|
||||||
been used at all for more than year
|
|
||||||
* driver_madwifi: fixed group key setup and added get_ssid method
|
|
||||||
* added support for EAP-MSCHAPv2 in the integrated EAP authenticator
|
|
||||||
|
|
||||||
2004-12-12 - v0.3.1
|
|
||||||
* added support for integrated EAP-TLS authentication (new hostapd.conf
|
|
||||||
variables: ca_cert, server_cert, private_key, private_key_passwd);
|
|
||||||
this enabled dynamic keying (WPA2/WPA/IEEE 802.1X/WEP) without
|
|
||||||
external RADIUS server
|
|
||||||
* added support for reading PKCS#12 (PFX) files (as a replacement for
|
|
||||||
PEM/DER) to get certificate and private key (CONFIG_PKCS12)
|
|
||||||
|
|
||||||
2004-12-05 - v0.3.0 (beginning of 0.3.x development releases)
|
|
||||||
* added support for Acct-{Input,Output}-Gigawords
|
|
||||||
* added support for Event-Timestamp (in RADIUS Accounting-Requests)
|
|
||||||
* added support for RADIUS Authentication Client MIB (RFC2618)
|
|
||||||
* added support for RADIUS Accounting Client MIB (RFC2620)
|
|
||||||
* made EAP re-authentication period configurable (eap_reauth_period)
|
|
||||||
* fixed EAPOL reauthentication to trigger WPA/WPA2 reauthentication
|
|
||||||
* fixed EAPOL state machine to stop if STA is removed during
|
|
||||||
eapol_sm_step(); this fixes at least one segfault triggering bug with
|
|
||||||
IEEE 802.11i pre-authentication
|
|
||||||
* added support for multiple WPA pre-shared keys (e.g., one for each
|
|
||||||
client MAC address or keys shared by a group of clients);
|
|
||||||
new hostapd.conf field wpa_psk_file for setting path to a text file
|
|
||||||
containing PSKs, see hostapd.wpa_psk for an example
|
|
||||||
* added support for multiple driver interfaces to allow hostapd to be
|
|
||||||
used with other drivers
|
|
||||||
* added wired authenticator driver interface (driver=wired in
|
|
||||||
hostapd.conf, see wired.conf for example configuration)
|
|
||||||
* added madwifi driver interface (driver=madwifi in hostapd.conf, see
|
|
||||||
madwifi.conf for example configuration; Note: include files from
|
|
||||||
madwifi project is needed for building and a configuration file,
|
|
||||||
.config, needs to be created in hostapd directory with
|
|
||||||
CONFIG_DRIVER_MADWIFI=y to include this driver interface in hostapd
|
|
||||||
build)
|
|
||||||
* fixed an alignment issue that could cause SHA-1 to fail on some
|
|
||||||
platforms (e.g., Intel ixp425 with a compiler that does not 32-bit
|
|
||||||
align variables)
|
|
||||||
* fixed RADIUS reconnection after an error in sending interim
|
|
||||||
accounting packets
|
|
||||||
* added hostapd control interface for external programs and an example
|
|
||||||
CLI, hostapd_cli (like wpa_cli for wpa_supplicant)
|
|
||||||
* started adding dot11, dot1x, radius MIBs ('hostapd_cli mib',
|
|
||||||
'hostapd_cli sta <addr>')
|
|
||||||
* finished update from IEEE 802.1X-2001 to IEEE 802.1X-REV (now d11)
|
|
||||||
* added support for strict GTK rekeying (wpa_strict_rekey in
|
|
||||||
hostapd.conf)
|
|
||||||
* updated IAPP to use UDP port 3517 and multicast address 224.0.1.178
|
|
||||||
(instead of broadcast) for IAPP ADD-notify (moved from draft 3 to
|
|
||||||
IEEE 802.11F-2003)
|
|
||||||
* added Prism54 driver interface (driver=prism54 in hostapd.conf;
|
|
||||||
note: .config needs to be created in hostapd directory with
|
|
||||||
CONFIG_DRIVER_PRISM54=y to include this driver interface in hostapd
|
|
||||||
build)
|
|
||||||
* dual-licensed hostapd (GPLv2 and BSD licenses)
|
|
||||||
* fixed RADIUS accounting to generate a new session id for cases where
|
|
||||||
a station reassociates without first being complete deauthenticated
|
|
||||||
* fixed STA disassociation handler to mark next timeout state to
|
|
||||||
deauthenticate the station, i.e., skip long wait for inactivity poll
|
|
||||||
and extra disassociation, if the STA disassociates without
|
|
||||||
deauthenticating
|
|
||||||
* added integrated EAP authenticator that can be used instead of
|
|
||||||
external RADIUS authentication server; currently, only EAP-MD5 is
|
|
||||||
supported, so this cannot yet be used for key distribution; the EAP
|
|
||||||
method interface is generic, though, so adding new EAP methods should
|
|
||||||
be straightforward; new hostapd.conf variables: 'eap_authenticator'
|
|
||||||
and 'eap_user_file'; this obsoletes "minimal authentication server"
|
|
||||||
('minimal_eap' in hostapd.conf) which is now removed
|
|
||||||
* added support for FreeBSD and driver interface for the BSD net80211
|
|
||||||
layer (driver=bsd in hostapd.conf and CONFIG_DRIVER_BSD=y in
|
|
||||||
.config); please note that some of the required kernel mods have not
|
|
||||||
yet been committed
|
|
||||||
|
|
||||||
2004-07-17 - v0.2.4 (beginning of 0.2.x stable releases)
|
|
||||||
* fixed some accounting cases where Accounting-Start was sent when
|
|
||||||
IEEE 802.1X port was being deauthorized
|
|
||||||
|
|
||||||
2004-06-20 - v0.2.3
|
|
||||||
* modified RADIUS client to re-connect the socket in case of certain
|
|
||||||
error codes that are generated when a network interface state is
|
|
||||||
changes (e.g., when IP address changes or the interface is set UP)
|
|
||||||
* fixed couple of cases where EAPOL state for a station was freed
|
|
||||||
twice causing a segfault for hostapd
|
|
||||||
* fixed couple of bugs in processing WPA deauthentication (freed data
|
|
||||||
was used)
|
|
||||||
|
|
||||||
2004-05-31 - v0.2.2
|
|
||||||
* fixed WPA/WPA2 group rekeying to use key index correctly (GN/GM)
|
|
||||||
* fixed group rekeying to send zero TSC in EAPOL-Key messages to fix
|
|
||||||
cases where STAs dropped multicast frames as replay attacks
|
|
||||||
* added support for copying RADIUS Attribute 'Class' from
|
|
||||||
authentication messages into accounting messages
|
|
||||||
* send canned EAP failure if RADIUS server sends Access-Reject without
|
|
||||||
EAP message (previously, Supplicant was not notified in this case)
|
|
||||||
* fixed mixed WPA-PSK and WPA-EAP mode to work with WPA-PSK (i.e., do
|
|
||||||
not start EAPOL state machines if the STA selected to use WPA-PSK)
|
|
||||||
|
|
||||||
2004-05-06 - v0.2.1
|
|
||||||
* added WPA and IEEE 802.11i/RSN (WPA2) Authenticator functionality
|
|
||||||
- based on IEEE 802.11i/D10.0 but modified to interoperate with WPA
|
|
||||||
(i.e., IEEE 802.11i/D3.0)
|
|
||||||
- supports WPA-only, RSN-only, and mixed WPA/RSN mode
|
|
||||||
- both WPA-PSK and WPA-RADIUS/EAP are supported
|
|
||||||
- PMKSA caching and pre-authentication
|
|
||||||
- new hostapd.conf variables: wpa, wpa_psk, wpa_passphrase,
|
|
||||||
wpa_key_mgmt, wpa_pairwise, wpa_group_rekey, wpa_gmk_rekey,
|
|
||||||
rsn_preauth, rsn_preauth_interfaces
|
|
||||||
* fixed interim accounting to remove any pending accounting messages
|
|
||||||
to the STA before sending a new one
|
|
||||||
|
|
||||||
2004-02-15 - v0.2.0
|
|
||||||
* added support for Acct-Interim-Interval:
|
|
||||||
- draft-ietf-radius-acct-interim-01.txt
|
|
||||||
- use Acct-Interim-Interval attribute from Access-Accept if local
|
|
||||||
'radius_acct_interim_interval' is not set
|
|
||||||
- allow different update intervals for each STA
|
|
||||||
* fixed event loop to call signal handlers only after returning from
|
|
||||||
the real signal handler
|
|
||||||
* reset sta->timeout_next after successful association to make sure
|
|
||||||
that the previously registered inactivity timer will not remove the
|
|
||||||
STA immediately (e.g., if STA deauthenticates and re-associates
|
|
||||||
before the timer is triggered).
|
|
||||||
* added new hostapd.conf variable, nas_identifier, that can be used to
|
|
||||||
add an optional RADIUS Attribute, NAS-Identifier, into authentication
|
|
||||||
and accounting messages
|
|
||||||
* added support for Accounting-On and Accounting-Off messages
|
|
||||||
* fixed accounting session handling to send Accounting-Start only once
|
|
||||||
per session and not to send Accounting-Stop if the session was not
|
|
||||||
initialized properly
|
|
||||||
* fixed Accounting-Stop statistics in cases where the message was
|
|
||||||
previously sent after the kernel entry for the STA (and/or IEEE
|
|
||||||
802.1X data) was removed
|
|
||||||
|
|
||||||
|
|
||||||
Note:
|
|
||||||
|
|
||||||
Older changes up to and including v0.1.0 are included in the ChangeLog
|
|
||||||
of the Host AP driver.
|
|
|
@ -1,836 +0,0 @@
|
||||||
ifndef CC
|
|
||||||
CC=gcc
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifndef CFLAGS
|
|
||||||
CFLAGS = -MMD -O2 -Wall -g
|
|
||||||
endif
|
|
||||||
|
|
||||||
CFLAGS += -I../src
|
|
||||||
CFLAGS += -I../src/utils
|
|
||||||
|
|
||||||
# Uncomment following line and set the path to your kernel tree include
|
|
||||||
# directory if your C library does not include all header files.
|
|
||||||
# CFLAGS += -DUSE_KERNEL_HEADERS -I/usr/src/linux/include
|
|
||||||
|
|
||||||
-include .config
|
|
||||||
|
|
||||||
ifndef CONFIG_OS
|
|
||||||
ifdef CONFIG_NATIVE_WINDOWS
|
|
||||||
CONFIG_OS=win32
|
|
||||||
else
|
|
||||||
CONFIG_OS=unix
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_OS), internal)
|
|
||||||
CFLAGS += -DOS_NO_C_LIB_DEFINES
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_NATIVE_WINDOWS
|
|
||||||
CFLAGS += -DCONFIG_NATIVE_WINDOWS
|
|
||||||
LIBS += -lws2_32
|
|
||||||
endif
|
|
||||||
|
|
||||||
OBJS += main.o
|
|
||||||
OBJS += config_file.o
|
|
||||||
|
|
||||||
OBJS += ../src/ap/hostapd.o
|
|
||||||
OBJS += ../src/ap/wpa_auth_glue.o
|
|
||||||
OBJS += ../src/ap/drv_callbacks.o
|
|
||||||
OBJS += ../src/ap/ap_drv_ops.o
|
|
||||||
OBJS += ../src/ap/utils.o
|
|
||||||
OBJS += ../src/ap/authsrv.o
|
|
||||||
OBJS += ../src/ap/ieee802_1x.o
|
|
||||||
OBJS += ../src/ap/ap_config.o
|
|
||||||
OBJS += ../src/ap/ieee802_11_auth.o
|
|
||||||
OBJS += ../src/ap/sta_info.o
|
|
||||||
OBJS += ../src/ap/wpa_auth.o
|
|
||||||
OBJS += ../src/ap/tkip_countermeasures.o
|
|
||||||
OBJS += ../src/ap/ap_mlme.o
|
|
||||||
OBJS += ../src/ap/wpa_auth_ie.o
|
|
||||||
OBJS += ../src/ap/preauth_auth.o
|
|
||||||
OBJS += ../src/ap/pmksa_cache_auth.o
|
|
||||||
|
|
||||||
NEED_RC4=y
|
|
||||||
NEED_AES=y
|
|
||||||
NEED_MD5=y
|
|
||||||
NEED_SHA1=y
|
|
||||||
|
|
||||||
OBJS += ../src/drivers/drivers.o
|
|
||||||
CFLAGS += -DHOSTAPD
|
|
||||||
|
|
||||||
ifdef CONFIG_WPA_TRACE
|
|
||||||
CFLAGS += -DWPA_TRACE
|
|
||||||
OBJS += ../src/utils/trace.o
|
|
||||||
HOBJS += ../src/utils/trace.o
|
|
||||||
LDFLAGS += -rdynamic
|
|
||||||
CFLAGS += -funwind-tables
|
|
||||||
ifdef CONFIG_WPA_TRACE_BFD
|
|
||||||
CFLAGS += -DWPA_TRACE_BFD
|
|
||||||
LIBS += -lbfd
|
|
||||||
LIBS_c += -lbfd
|
|
||||||
LIBS_h += -lbfd
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
OBJS += ../src/utils/eloop.o
|
|
||||||
OBJS += ../src/utils/common.o
|
|
||||||
OBJS += ../src/utils/wpa_debug.o
|
|
||||||
OBJS += ../src/utils/wpabuf.o
|
|
||||||
OBJS += ../src/utils/os_$(CONFIG_OS).o
|
|
||||||
OBJS += ../src/utils/ip_addr.o
|
|
||||||
|
|
||||||
OBJS += ../src/common/ieee802_11_common.o
|
|
||||||
OBJS += ../src/common/wpa_common.o
|
|
||||||
|
|
||||||
OBJS += ../src/eapol_auth/eapol_auth_sm.o
|
|
||||||
|
|
||||||
|
|
||||||
ifndef CONFIG_NO_DUMP_STATE
|
|
||||||
# define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to
|
|
||||||
# a file (undefine it, if you want to save in binary size)
|
|
||||||
CFLAGS += -DHOSTAPD_DUMP_STATE
|
|
||||||
OBJS += dump_state.o
|
|
||||||
OBJS += ../src/eapol_auth/eapol_auth_dump.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_NO_RADIUS
|
|
||||||
CFLAGS += -DCONFIG_NO_RADIUS
|
|
||||||
CONFIG_NO_ACCOUNTING=y
|
|
||||||
else
|
|
||||||
OBJS += ../src/radius/radius.o
|
|
||||||
OBJS += ../src/radius/radius_client.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_NO_ACCOUNTING
|
|
||||||
CFLAGS += -DCONFIG_NO_ACCOUNTING
|
|
||||||
else
|
|
||||||
OBJS += ../src/ap/accounting.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_NO_VLAN
|
|
||||||
CFLAGS += -DCONFIG_NO_VLAN
|
|
||||||
else
|
|
||||||
OBJS += ../src/ap/vlan_init.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_NO_CTRL_IFACE
|
|
||||||
CFLAGS += -DCONFIG_NO_CTRL_IFACE
|
|
||||||
else
|
|
||||||
OBJS += ctrl_iface.o
|
|
||||||
OBJS += ../src/ap/ctrl_iface_ap.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
OBJS += ../src/crypto/md5.o
|
|
||||||
|
|
||||||
CFLAGS += -DCONFIG_CTRL_IFACE -DCONFIG_CTRL_IFACE_UNIX
|
|
||||||
|
|
||||||
ifdef CONFIG_IAPP
|
|
||||||
CFLAGS += -DCONFIG_IAPP
|
|
||||||
OBJS += ../src/ap/iapp.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_RSN_PREAUTH
|
|
||||||
CFLAGS += -DCONFIG_RSN_PREAUTH
|
|
||||||
CONFIG_L2_PACKET=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_PEERKEY
|
|
||||||
CFLAGS += -DCONFIG_PEERKEY
|
|
||||||
OBJS += ../src/ap/peerkey_auth.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_IEEE80211W
|
|
||||||
CFLAGS += -DCONFIG_IEEE80211W
|
|
||||||
NEED_SHA256=y
|
|
||||||
NEED_AES_OMAC1=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_IEEE80211R
|
|
||||||
CFLAGS += -DCONFIG_IEEE80211R
|
|
||||||
OBJS += ../src/ap/wpa_auth_ft.o
|
|
||||||
NEED_SHA256=y
|
|
||||||
NEED_AES_OMAC1=y
|
|
||||||
NEED_AES_UNWRAP=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_IEEE80211N
|
|
||||||
CFLAGS += -DCONFIG_IEEE80211N
|
|
||||||
endif
|
|
||||||
|
|
||||||
include ../src/drivers/drivers.mak
|
|
||||||
OBJS += $(DRV_AP_OBJS)
|
|
||||||
CFLAGS += $(DRV_AP_CFLAGS)
|
|
||||||
LDFLAGS += $(DRV_AP_LDFLAGS)
|
|
||||||
LIBS += $(DRV_AP_LIBS)
|
|
||||||
|
|
||||||
ifdef CONFIG_L2_PACKET
|
|
||||||
ifdef CONFIG_DNET_PCAP
|
|
||||||
ifdef CONFIG_L2_FREEBSD
|
|
||||||
LIBS += -lpcap
|
|
||||||
OBJS += ../src/l2_packet/l2_packet_freebsd.o
|
|
||||||
else
|
|
||||||
LIBS += -ldnet -lpcap
|
|
||||||
OBJS += ../src/l2_packet/l2_packet_pcap.o
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
OBJS += ../src/l2_packet/l2_packet_linux.o
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
OBJS += ../src/l2_packet/l2_packet_none.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_MD5
|
|
||||||
CFLAGS += -DEAP_SERVER_MD5
|
|
||||||
OBJS += ../src/eap_server/eap_server_md5.o
|
|
||||||
CHAP=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_TLS
|
|
||||||
CFLAGS += -DEAP_SERVER_TLS
|
|
||||||
OBJS += ../src/eap_server/eap_server_tls.o
|
|
||||||
TLS_FUNCS=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_PEAP
|
|
||||||
CFLAGS += -DEAP_SERVER_PEAP
|
|
||||||
OBJS += ../src/eap_server/eap_server_peap.o
|
|
||||||
OBJS += ../src/eap_common/eap_peap_common.o
|
|
||||||
TLS_FUNCS=y
|
|
||||||
CONFIG_EAP_MSCHAPV2=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_TTLS
|
|
||||||
CFLAGS += -DEAP_SERVER_TTLS
|
|
||||||
OBJS += ../src/eap_server/eap_server_ttls.o
|
|
||||||
TLS_FUNCS=y
|
|
||||||
CHAP=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_MSCHAPV2
|
|
||||||
CFLAGS += -DEAP_SERVER_MSCHAPV2
|
|
||||||
OBJS += ../src/eap_server/eap_server_mschapv2.o
|
|
||||||
MS_FUNCS=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_GTC
|
|
||||||
CFLAGS += -DEAP_SERVER_GTC
|
|
||||||
OBJS += ../src/eap_server/eap_server_gtc.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_SIM
|
|
||||||
CFLAGS += -DEAP_SERVER_SIM
|
|
||||||
OBJS += ../src/eap_server/eap_server_sim.o
|
|
||||||
CONFIG_EAP_SIM_COMMON=y
|
|
||||||
NEED_AES_CBC=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_AKA
|
|
||||||
CFLAGS += -DEAP_SERVER_AKA
|
|
||||||
OBJS += ../src/eap_server/eap_server_aka.o
|
|
||||||
CONFIG_EAP_SIM_COMMON=y
|
|
||||||
NEED_SHA256=y
|
|
||||||
NEED_AES_CBC=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_AKA_PRIME
|
|
||||||
CFLAGS += -DEAP_SERVER_AKA_PRIME
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_SIM_COMMON
|
|
||||||
OBJS += ../src/eap_common/eap_sim_common.o
|
|
||||||
# Example EAP-SIM/AKA interface for GSM/UMTS authentication. This can be
|
|
||||||
# replaced with another file implementating the interface specified in
|
|
||||||
# eap_sim_db.h.
|
|
||||||
OBJS += ../src/eap_server/eap_sim_db.o
|
|
||||||
NEED_FIPS186_2_PRF=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_PAX
|
|
||||||
CFLAGS += -DEAP_SERVER_PAX
|
|
||||||
OBJS += ../src/eap_server/eap_server_pax.o ../src/eap_common/eap_pax_common.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_PSK
|
|
||||||
CFLAGS += -DEAP_SERVER_PSK
|
|
||||||
OBJS += ../src/eap_server/eap_server_psk.o ../src/eap_common/eap_psk_common.o
|
|
||||||
NEED_AES_OMAC1=y
|
|
||||||
NEED_AES_ENCBLOCK=y
|
|
||||||
NEED_AES_EAX=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_SAKE
|
|
||||||
CFLAGS += -DEAP_SERVER_SAKE
|
|
||||||
OBJS += ../src/eap_server/eap_server_sake.o ../src/eap_common/eap_sake_common.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_GPSK
|
|
||||||
CFLAGS += -DEAP_SERVER_GPSK
|
|
||||||
OBJS += ../src/eap_server/eap_server_gpsk.o ../src/eap_common/eap_gpsk_common.o
|
|
||||||
ifdef CONFIG_EAP_GPSK_SHA256
|
|
||||||
CFLAGS += -DEAP_SERVER_GPSK_SHA256
|
|
||||||
endif
|
|
||||||
NEED_SHA256=y
|
|
||||||
NEED_AES_OMAC1=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_PWD
|
|
||||||
CFLAGS += -DEAP_SERVER_PWD
|
|
||||||
OBJS += ../src/eap_server/eap_server_pwd.o ../src/eap_common/eap_pwd_common.o
|
|
||||||
NEED_SHA256=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_VENDOR_TEST
|
|
||||||
CFLAGS += -DEAP_SERVER_VENDOR_TEST
|
|
||||||
OBJS += ../src/eap_server/eap_server_vendor_test.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_FAST
|
|
||||||
CFLAGS += -DEAP_SERVER_FAST
|
|
||||||
OBJS += ../src/eap_server/eap_server_fast.o
|
|
||||||
OBJS += ../src/eap_common/eap_fast_common.o
|
|
||||||
TLS_FUNCS=y
|
|
||||||
NEED_T_PRF=y
|
|
||||||
NEED_AES_UNWRAP=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_WPS
|
|
||||||
ifdef CONFIG_WPS2
|
|
||||||
CFLAGS += -DCONFIG_WPS2
|
|
||||||
endif
|
|
||||||
|
|
||||||
CFLAGS += -DCONFIG_WPS -DEAP_SERVER_WSC
|
|
||||||
OBJS += ../src/utils/uuid.o
|
|
||||||
OBJS += ../src/ap/wps_hostapd.o
|
|
||||||
OBJS += ../src/eap_server/eap_server_wsc.o ../src/eap_common/eap_wsc_common.o
|
|
||||||
OBJS += ../src/wps/wps.o
|
|
||||||
OBJS += ../src/wps/wps_common.o
|
|
||||||
OBJS += ../src/wps/wps_attr_parse.o
|
|
||||||
OBJS += ../src/wps/wps_attr_build.o
|
|
||||||
OBJS += ../src/wps/wps_attr_process.o
|
|
||||||
OBJS += ../src/wps/wps_dev_attr.o
|
|
||||||
OBJS += ../src/wps/wps_enrollee.o
|
|
||||||
OBJS += ../src/wps/wps_registrar.o
|
|
||||||
NEED_DH_GROUPS=y
|
|
||||||
NEED_SHA256=y
|
|
||||||
NEED_BASE64=y
|
|
||||||
NEED_AES_CBC=y
|
|
||||||
NEED_MODEXP=y
|
|
||||||
CONFIG_EAP=y
|
|
||||||
|
|
||||||
ifdef CONFIG_WPS_UFD
|
|
||||||
CFLAGS += -DCONFIG_WPS_UFD
|
|
||||||
OBJS += ../src/wps/wps_ufd.o
|
|
||||||
NEED_WPS_OOB=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_WPS_NFC
|
|
||||||
CFLAGS += -DCONFIG_WPS_NFC
|
|
||||||
OBJS += ../src/wps/ndef.o
|
|
||||||
OBJS += ../src/wps/wps_nfc.o
|
|
||||||
NEED_WPS_OOB=y
|
|
||||||
ifdef CONFIG_WPS_NFC_PN531
|
|
||||||
PN531_PATH ?= /usr/local/src/nfc
|
|
||||||
CFLAGS += -DCONFIG_WPS_NFC_PN531
|
|
||||||
CFLAGS += -I${PN531_PATH}/inc
|
|
||||||
OBJS += ../src/wps/wps_nfc_pn531.o
|
|
||||||
LIBS += ${PN531_PATH}/lib/wpsnfc.dll
|
|
||||||
LIBS += ${PN531_PATH}/lib/libnfc_mapping_pn53x.dll
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_WPS_OOB
|
|
||||||
CFLAGS += -DCONFIG_WPS_OOB
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_WPS_UPNP
|
|
||||||
CFLAGS += -DCONFIG_WPS_UPNP
|
|
||||||
OBJS += ../src/wps/wps_upnp.o
|
|
||||||
OBJS += ../src/wps/wps_upnp_ssdp.o
|
|
||||||
OBJS += ../src/wps/wps_upnp_web.o
|
|
||||||
OBJS += ../src/wps/wps_upnp_event.o
|
|
||||||
OBJS += ../src/wps/wps_upnp_ap.o
|
|
||||||
OBJS += ../src/wps/upnp_xml.o
|
|
||||||
OBJS += ../src/wps/httpread.o
|
|
||||||
OBJS += ../src/wps/http_client.o
|
|
||||||
OBJS += ../src/wps/http_server.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_WPS_STRICT
|
|
||||||
CFLAGS += -DCONFIG_WPS_STRICT
|
|
||||||
OBJS += ../src/wps/wps_validate.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_WPS_TESTING
|
|
||||||
CFLAGS += -DCONFIG_WPS_TESTING
|
|
||||||
endif
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_IKEV2
|
|
||||||
CFLAGS += -DEAP_SERVER_IKEV2
|
|
||||||
OBJS += ../src/eap_server/eap_server_ikev2.o ../src/eap_server/ikev2.o
|
|
||||||
OBJS += ../src/eap_common/eap_ikev2_common.o ../src/eap_common/ikev2_common.o
|
|
||||||
NEED_DH_GROUPS=y
|
|
||||||
NEED_DH_GROUPS_ALL=y
|
|
||||||
NEED_MODEXP=y
|
|
||||||
NEED_CIPHER=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP_TNC
|
|
||||||
CFLAGS += -DEAP_SERVER_TNC
|
|
||||||
OBJS += ../src/eap_server/eap_server_tnc.o
|
|
||||||
OBJS += ../src/eap_server/tncs.o
|
|
||||||
NEED_BASE64=y
|
|
||||||
ifndef CONFIG_DRIVER_BSD
|
|
||||||
LIBS += -ldl
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Basic EAP functionality is needed for EAPOL
|
|
||||||
OBJS += eap_register.o
|
|
||||||
OBJS += ../src/eap_server/eap_server.o
|
|
||||||
OBJS += ../src/eap_common/eap_common.o
|
|
||||||
OBJS += ../src/eap_server/eap_server_methods.o
|
|
||||||
OBJS += ../src/eap_server/eap_server_identity.o
|
|
||||||
CFLAGS += -DEAP_SERVER_IDENTITY
|
|
||||||
|
|
||||||
ifdef CONFIG_EAP
|
|
||||||
CFLAGS += -DEAP_SERVER
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_PKCS12
|
|
||||||
CFLAGS += -DPKCS12_FUNCS
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef MS_FUNCS
|
|
||||||
OBJS += ../src/crypto/ms_funcs.o
|
|
||||||
NEED_DES=y
|
|
||||||
NEED_MD4=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CHAP
|
|
||||||
OBJS += ../src/eap_common/chap.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
NEED_DES=y
|
|
||||||
# Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS)
|
|
||||||
CFLAGS += -DEAP_TLS_FUNCS
|
|
||||||
OBJS += ../src/eap_server/eap_server_tls_common.o
|
|
||||||
NEED_TLS_PRF=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifndef CONFIG_TLS
|
|
||||||
CONFIG_TLS=openssl
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_TLS), openssl)
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
OBJS += ../src/crypto/tls_openssl.o
|
|
||||||
LIBS += -lssl
|
|
||||||
endif
|
|
||||||
OBJS += ../src/crypto/crypto_openssl.o
|
|
||||||
HOBJS += ../src/crypto/crypto_openssl.o
|
|
||||||
ifdef NEED_FIPS186_2_PRF
|
|
||||||
OBJS += ../src/crypto/fips_prf_openssl.o
|
|
||||||
endif
|
|
||||||
LIBS += -lcrypto
|
|
||||||
LIBS_h += -lcrypto
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_TLS), gnutls)
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
OBJS += ../src/crypto/tls_gnutls.o
|
|
||||||
LIBS += -lgnutls -lgpg-error
|
|
||||||
ifdef CONFIG_GNUTLS_EXTRA
|
|
||||||
CFLAGS += -DCONFIG_GNUTLS_EXTRA
|
|
||||||
LIBS += -lgnutls-extra
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
OBJS += ../src/crypto/crypto_gnutls.o
|
|
||||||
HOBJS += ../src/crypto/crypto_gnutls.o
|
|
||||||
ifdef NEED_FIPS186_2_PRF
|
|
||||||
OBJS += ../src/crypto/fips_prf_gnutls.o
|
|
||||||
endif
|
|
||||||
LIBS += -lgcrypt
|
|
||||||
LIBS_h += -lgcrypt
|
|
||||||
CONFIG_INTERNAL_SHA256=y
|
|
||||||
CONFIG_INTERNAL_RC4=y
|
|
||||||
CONFIG_INTERNAL_DH_GROUP5=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_TLS), schannel)
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
OBJS += ../src/crypto/tls_schannel.o
|
|
||||||
endif
|
|
||||||
OBJS += ../src/crypto/crypto_cryptoapi.o
|
|
||||||
OBJS_p += ../src/crypto/crypto_cryptoapi.o
|
|
||||||
CONFIG_INTERNAL_SHA256=y
|
|
||||||
CONFIG_INTERNAL_RC4=y
|
|
||||||
CONFIG_INTERNAL_DH_GROUP5=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_TLS), nss)
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
OBJS += ../src/crypto/tls_nss.o
|
|
||||||
LIBS += -lssl3
|
|
||||||
endif
|
|
||||||
OBJS += ../src/crypto/crypto_nss.o
|
|
||||||
ifdef NEED_FIPS186_2_PRF
|
|
||||||
OBJS += ../src/crypto/fips_prf_nss.o
|
|
||||||
endif
|
|
||||||
LIBS += -lnss3
|
|
||||||
LIBS_h += -lnss3
|
|
||||||
CONFIG_INTERNAL_MD4=y
|
|
||||||
CONFIG_INTERNAL_DH_GROUP5=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_TLS), internal)
|
|
||||||
ifndef CONFIG_CRYPTO
|
|
||||||
CONFIG_CRYPTO=internal
|
|
||||||
endif
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
OBJS += ../src/crypto/crypto_internal-rsa.o
|
|
||||||
OBJS += ../src/crypto/tls_internal.o
|
|
||||||
OBJS += ../src/tls/tlsv1_common.o
|
|
||||||
OBJS += ../src/tls/tlsv1_record.o
|
|
||||||
OBJS += ../src/tls/tlsv1_cred.o
|
|
||||||
OBJS += ../src/tls/tlsv1_server.o
|
|
||||||
OBJS += ../src/tls/tlsv1_server_write.o
|
|
||||||
OBJS += ../src/tls/tlsv1_server_read.o
|
|
||||||
OBJS += ../src/tls/asn1.o
|
|
||||||
OBJS += ../src/tls/rsa.o
|
|
||||||
OBJS += ../src/tls/x509v3.o
|
|
||||||
OBJS += ../src/tls/pkcs1.o
|
|
||||||
OBJS += ../src/tls/pkcs5.o
|
|
||||||
OBJS += ../src/tls/pkcs8.o
|
|
||||||
NEED_SHA256=y
|
|
||||||
NEED_BASE64=y
|
|
||||||
NEED_TLS_PRF=y
|
|
||||||
NEED_MODEXP=y
|
|
||||||
NEED_CIPHER=y
|
|
||||||
CFLAGS += -DCONFIG_TLS_INTERNAL
|
|
||||||
CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER
|
|
||||||
endif
|
|
||||||
ifdef NEED_CIPHER
|
|
||||||
NEED_DES=y
|
|
||||||
OBJS += ../src/crypto/crypto_internal-cipher.o
|
|
||||||
endif
|
|
||||||
ifdef NEED_MODEXP
|
|
||||||
OBJS += ../src/crypto/crypto_internal-modexp.o
|
|
||||||
OBJS += ../src/tls/bignum.o
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_CRYPTO), libtomcrypt)
|
|
||||||
OBJS += ../src/crypto/crypto_libtomcrypt.o
|
|
||||||
LIBS += -ltomcrypt -ltfm
|
|
||||||
LIBS_h += -ltomcrypt -ltfm
|
|
||||||
CONFIG_INTERNAL_SHA256=y
|
|
||||||
CONFIG_INTERNAL_RC4=y
|
|
||||||
CONFIG_INTERNAL_DH_GROUP5=y
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_CRYPTO), internal)
|
|
||||||
OBJS += ../src/crypto/crypto_internal.o
|
|
||||||
NEED_AES_DEC=y
|
|
||||||
CFLAGS += -DCONFIG_CRYPTO_INTERNAL
|
|
||||||
ifdef CONFIG_INTERNAL_LIBTOMMATH
|
|
||||||
CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH
|
|
||||||
ifdef CONFIG_INTERNAL_LIBTOMMATH_FAST
|
|
||||||
CFLAGS += -DLTM_FAST
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
LIBS += -ltommath
|
|
||||||
LIBS_h += -ltommath
|
|
||||||
endif
|
|
||||||
CONFIG_INTERNAL_AES=y
|
|
||||||
CONFIG_INTERNAL_DES=y
|
|
||||||
CONFIG_INTERNAL_SHA1=y
|
|
||||||
CONFIG_INTERNAL_MD4=y
|
|
||||||
CONFIG_INTERNAL_MD5=y
|
|
||||||
CONFIG_INTERNAL_SHA256=y
|
|
||||||
CONFIG_INTERNAL_RC4=y
|
|
||||||
CONFIG_INTERNAL_DH_GROUP5=y
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_CRYPTO), cryptoapi)
|
|
||||||
OBJS += ../src/crypto/crypto_cryptoapi.o
|
|
||||||
OBJS_p += ../src/crypto/crypto_cryptoapi.o
|
|
||||||
CFLAGS += -DCONFIG_CRYPTO_CRYPTOAPI
|
|
||||||
CONFIG_INTERNAL_SHA256=y
|
|
||||||
CONFIG_INTERNAL_RC4=y
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_TLS), none)
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
OBJS += ../src/crypto/tls_none.o
|
|
||||||
CFLAGS += -DEAP_TLS_NONE
|
|
||||||
CONFIG_INTERNAL_AES=y
|
|
||||||
CONFIG_INTERNAL_SHA1=y
|
|
||||||
CONFIG_INTERNAL_MD5=y
|
|
||||||
endif
|
|
||||||
OBJS += ../src/crypto/crypto_none.o
|
|
||||||
OBJS_p += ../src/crypto/crypto_none.o
|
|
||||||
CONFIG_INTERNAL_SHA256=y
|
|
||||||
CONFIG_INTERNAL_RC4=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifndef TLS_FUNCS
|
|
||||||
OBJS += ../src/crypto/tls_none.o
|
|
||||||
ifeq ($(CONFIG_TLS), internal)
|
|
||||||
CONFIG_INTERNAL_AES=y
|
|
||||||
CONFIG_INTERNAL_SHA1=y
|
|
||||||
CONFIG_INTERNAL_MD5=y
|
|
||||||
CONFIG_INTERNAL_RC4=y
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
AESOBJS = # none so far
|
|
||||||
ifdef CONFIG_INTERNAL_AES
|
|
||||||
AESOBJS += ../src/crypto/aes-internal.o ../src/crypto/aes-internal-enc.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
AESOBJS += ../src/crypto/aes-wrap.o
|
|
||||||
ifdef NEED_AES_EAX
|
|
||||||
AESOBJS += ../src/crypto/aes-eax.o
|
|
||||||
NEED_AES_CTR=y
|
|
||||||
endif
|
|
||||||
ifdef NEED_AES_CTR
|
|
||||||
AESOBJS += ../src/crypto/aes-ctr.o
|
|
||||||
endif
|
|
||||||
ifdef NEED_AES_ENCBLOCK
|
|
||||||
AESOBJS += ../src/crypto/aes-encblock.o
|
|
||||||
endif
|
|
||||||
ifdef NEED_AES_OMAC1
|
|
||||||
AESOBJS += ../src/crypto/aes-omac1.o
|
|
||||||
endif
|
|
||||||
ifdef NEED_AES_UNWRAP
|
|
||||||
NEED_AES_DEC=y
|
|
||||||
AESOBJS += ../src/crypto/aes-unwrap.o
|
|
||||||
endif
|
|
||||||
ifdef NEED_AES_CBC
|
|
||||||
NEED_AES_DEC=y
|
|
||||||
AESOBJS += ../src/crypto/aes-cbc.o
|
|
||||||
endif
|
|
||||||
ifdef NEED_AES_DEC
|
|
||||||
ifdef CONFIG_INTERNAL_AES
|
|
||||||
AESOBJS += ../src/crypto/aes-internal-dec.o
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
ifdef NEED_AES
|
|
||||||
OBJS += $(AESOBJS)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_SHA1
|
|
||||||
SHA1OBJS += ../src/crypto/sha1.o
|
|
||||||
ifdef CONFIG_INTERNAL_SHA1
|
|
||||||
SHA1OBJS += ../src/crypto/sha1-internal.o
|
|
||||||
ifdef NEED_FIPS186_2_PRF
|
|
||||||
SHA1OBJS += ../src/crypto/fips_prf_internal.o
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
SHA1OBJS += ../src/crypto/sha1-pbkdf2.o
|
|
||||||
ifdef NEED_T_PRF
|
|
||||||
SHA1OBJS += ../src/crypto/sha1-tprf.o
|
|
||||||
endif
|
|
||||||
ifdef NEED_TLS_PRF
|
|
||||||
SHA1OBJS += ../src/crypto/sha1-tlsprf.o
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_SHA1
|
|
||||||
OBJS += $(SHA1OBJS)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_MD5
|
|
||||||
ifdef CONFIG_INTERNAL_MD5
|
|
||||||
OBJS += ../src/crypto/md5-internal.o
|
|
||||||
HOBJS += ../src/crypto/md5-internal.o
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_MD4
|
|
||||||
ifdef CONFIG_INTERNAL_MD4
|
|
||||||
OBJS += ../src/crypto/md4-internal.o
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_DES
|
|
||||||
ifdef CONFIG_INTERNAL_DES
|
|
||||||
OBJS += ../src/crypto/des-internal.o
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_RC4
|
|
||||||
ifdef CONFIG_INTERNAL_RC4
|
|
||||||
OBJS += ../src/crypto/rc4.o
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_SHA256
|
|
||||||
OBJS += ../src/crypto/sha256.o
|
|
||||||
ifdef CONFIG_INTERNAL_SHA256
|
|
||||||
OBJS += ../src/crypto/sha256-internal.o
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_DH_GROUPS
|
|
||||||
OBJS += ../src/crypto/dh_groups.o
|
|
||||||
endif
|
|
||||||
ifdef NEED_DH_GROUPS_ALL
|
|
||||||
CFLAGS += -DALL_DH_GROUPS
|
|
||||||
endif
|
|
||||||
ifdef CONFIG_INTERNAL_DH_GROUP5
|
|
||||||
ifdef NEED_DH_GROUPS
|
|
||||||
OBJS += ../src/crypto/dh_group5.o
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_NO_RANDOM_POOL
|
|
||||||
CFLAGS += -DCONFIG_NO_RANDOM_POOL
|
|
||||||
else
|
|
||||||
OBJS += ../src/crypto/random.o
|
|
||||||
HOBJS += ../src/crypto/random.o
|
|
||||||
HOBJS += $(SHA1OBJS)
|
|
||||||
HOBJS += ../src/crypto/md5.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_RADIUS_SERVER
|
|
||||||
CFLAGS += -DRADIUS_SERVER
|
|
||||||
OBJS += ../src/radius/radius_server.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_IPV6
|
|
||||||
CFLAGS += -DCONFIG_IPV6
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_DRIVER_RADIUS_ACL
|
|
||||||
CFLAGS += -DCONFIG_DRIVER_RADIUS_ACL
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_FULL_DYNAMIC_VLAN
|
|
||||||
# define CONFIG_FULL_DYNAMIC_VLAN to have hostapd manipulate bridges
|
|
||||||
# and vlan interfaces for the vlan feature.
|
|
||||||
CFLAGS += -DCONFIG_FULL_DYNAMIC_VLAN
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_BASE64
|
|
||||||
OBJS += ../src/utils/base64.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NEED_AP_MLME
|
|
||||||
OBJS += ../src/ap/beacon.o
|
|
||||||
OBJS += ../src/ap/wmm.o
|
|
||||||
OBJS += ../src/ap/ap_list.o
|
|
||||||
OBJS += ../src/ap/ieee802_11.o
|
|
||||||
OBJS += ../src/ap/hw_features.o
|
|
||||||
CFLAGS += -DNEED_AP_MLME
|
|
||||||
endif
|
|
||||||
ifdef CONFIG_IEEE80211N
|
|
||||||
OBJS += ../src/ap/ieee802_11_ht.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_P2P_MANAGER
|
|
||||||
CFLAGS += -DCONFIG_P2P_MANAGER
|
|
||||||
OBJS += ../src/ap/p2p_hostapd.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_NO_STDOUT_DEBUG
|
|
||||||
CFLAGS += -DCONFIG_NO_STDOUT_DEBUG
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_DEBUG_FILE
|
|
||||||
CFLAGS += -DCONFIG_DEBUG_FILE
|
|
||||||
endif
|
|
||||||
|
|
||||||
ALL=hostapd hostapd_cli
|
|
||||||
|
|
||||||
all: verify_config $(ALL)
|
|
||||||
|
|
||||||
Q=@
|
|
||||||
E=echo
|
|
||||||
ifeq ($(V), 1)
|
|
||||||
Q=
|
|
||||||
E=true
|
|
||||||
endif
|
|
||||||
|
|
||||||
%.o: %.c
|
|
||||||
$(Q)$(CC) -c -o $@ $(CFLAGS) $<
|
|
||||||
@$(E) " CC " $<
|
|
||||||
|
|
||||||
verify_config:
|
|
||||||
@if [ ! -r .config ]; then \
|
|
||||||
echo 'Building hostapd requires a configuration file'; \
|
|
||||||
echo '(.config). See README for more instructions. You can'; \
|
|
||||||
echo 'run "cp defconfig .config" to create an example'; \
|
|
||||||
echo 'configuration.'; \
|
|
||||||
exit 1; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
install: all
|
|
||||||
mkdir -p $(DESTDIR)/usr/local/bin
|
|
||||||
for i in $(ALL); do cp -f $$i $(DESTDIR)/usr/local/bin/$$i; done
|
|
||||||
|
|
||||||
../src/drivers/build.hostapd:
|
|
||||||
@if [ -f ../src/drivers/build.wpa_supplicant ]; then \
|
|
||||||
$(MAKE) -C ../src/drivers clean; \
|
|
||||||
fi
|
|
||||||
@touch ../src/drivers/build.hostapd
|
|
||||||
|
|
||||||
BCHECK=../src/drivers/build.hostapd
|
|
||||||
|
|
||||||
hostapd: $(BCHECK) $(OBJS)
|
|
||||||
$(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS)
|
|
||||||
@$(E) " LD " $@
|
|
||||||
|
|
||||||
OBJS_c = hostapd_cli.o ../src/common/wpa_ctrl.o ../src/utils/os_$(CONFIG_OS).o
|
|
||||||
ifdef CONFIG_WPA_TRACE
|
|
||||||
OBJS_c += ../src/utils/trace.o
|
|
||||||
OBJS_c += ../src/utils/wpa_debug.o
|
|
||||||
endif
|
|
||||||
hostapd_cli: $(OBJS_c)
|
|
||||||
$(Q)$(CC) $(LDFLAGS) -o hostapd_cli $(OBJS_c) $(LIBS_c)
|
|
||||||
@$(E) " LD " $@
|
|
||||||
|
|
||||||
NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS) ../src/crypto/md5.o
|
|
||||||
ifdef NEED_RC4
|
|
||||||
ifdef CONFIG_INTERNAL_RC4
|
|
||||||
NOBJS += ../src/crypto/rc4.o
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
ifdef CONFIG_INTERNAL_MD5
|
|
||||||
NOBJS += ../src/crypto/md5-internal.o
|
|
||||||
endif
|
|
||||||
NOBJS += ../src/crypto/crypto_openssl.o ../src/utils/os_$(CONFIG_OS).o
|
|
||||||
NOBJS += ../src/utils/wpa_debug.o
|
|
||||||
NOBJS += ../src/utils/wpabuf.o
|
|
||||||
ifdef CONFIG_WPA_TRACE
|
|
||||||
NOBJS += ../src/utils/trace.o
|
|
||||||
LIBS_n += -lbfd
|
|
||||||
endif
|
|
||||||
ifdef TLS_FUNCS
|
|
||||||
LIBS_n += -lcrypto
|
|
||||||
endif
|
|
||||||
|
|
||||||
HOBJS += hlr_auc_gw.o ../src/utils/common.o ../src/utils/wpa_debug.o ../src/utils/os_$(CONFIG_OS).o ../src/utils/wpabuf.o ../src/crypto/milenage.o
|
|
||||||
HOBJS += ../src/crypto/aes-encblock.o
|
|
||||||
ifdef CONFIG_INTERNAL_AES
|
|
||||||
HOBJS += ../src/crypto/aes-internal.o
|
|
||||||
HOBJS += ../src/crypto/aes-internal-enc.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
nt_password_hash: $(NOBJS)
|
|
||||||
$(Q)$(CC) $(LDFLAGS) -o nt_password_hash $(NOBJS) $(LIBS_n)
|
|
||||||
@$(E) " LD " $@
|
|
||||||
|
|
||||||
hlr_auc_gw: $(HOBJS)
|
|
||||||
$(Q)$(CC) $(LDFLAGS) -o hlr_auc_gw $(HOBJS) $(LIBS_h)
|
|
||||||
@$(E) " LD " $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(MAKE) -C ../src clean
|
|
||||||
rm -f core *~ *.o hostapd hostapd_cli nt_password_hash hlr_auc_gw
|
|
||||||
rm -f *.d
|
|
||||||
|
|
||||||
-include $(OBJS:%.o=%.d)
|
|
|
@ -1,387 +0,0 @@
|
||||||
hostapd - user space IEEE 802.11 AP and IEEE 802.1X/WPA/WPA2/EAP
|
|
||||||
Authenticator and RADIUS authentication server
|
|
||||||
================================================================
|
|
||||||
|
|
||||||
Copyright (c) 2002-2011, Jouni Malinen <j@w1.fi> and contributors
|
|
||||||
All Rights Reserved.
|
|
||||||
|
|
||||||
This program is dual-licensed under both the GPL version 2 and BSD
|
|
||||||
license. Either license may be used at your option.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
License
|
|
||||||
-------
|
|
||||||
|
|
||||||
GPL v2:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License version 2 as
|
|
||||||
published by the Free Software Foundation.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
(this copy of the license is in COPYING file)
|
|
||||||
|
|
||||||
|
|
||||||
Alternatively, this software may be distributed, used, and modified
|
|
||||||
under the terms of BSD license:
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name(s) of the above-listed copyright holder(s) nor the
|
|
||||||
names of its contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
============
|
|
||||||
|
|
||||||
Originally, hostapd was an optional user space component for Host AP
|
|
||||||
driver. It adds more features to the basic IEEE 802.11 management
|
|
||||||
included in the kernel driver: using external RADIUS authentication
|
|
||||||
server for MAC address based access control, IEEE 802.1X Authenticator
|
|
||||||
and dynamic WEP keying, RADIUS accounting, WPA/WPA2 (IEEE 802.11i/RSN)
|
|
||||||
Authenticator and dynamic TKIP/CCMP keying.
|
|
||||||
|
|
||||||
The current version includes support for other drivers, an integrated
|
|
||||||
EAP server (i.e., allow full authentication without requiring
|
|
||||||
an external RADIUS authentication server), and RADIUS authentication
|
|
||||||
server for EAP authentication.
|
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
|
||||||
------------
|
|
||||||
|
|
||||||
Current hardware/software requirements:
|
|
||||||
- drivers:
|
|
||||||
Host AP driver for Prism2/2.5/3.
|
|
||||||
(http://hostap.epitest.fi/)
|
|
||||||
Please note that station firmware version needs to be 1.7.0 or newer
|
|
||||||
to work in WPA mode.
|
|
||||||
|
|
||||||
madwifi driver for cards based on Atheros chip set (ar521x)
|
|
||||||
(http://sourceforge.net/projects/madwifi/)
|
|
||||||
Please note that you will need to add the correct path for
|
|
||||||
madwifi driver root directory in .config (see defconfig file for
|
|
||||||
an example: CFLAGS += -I<path>)
|
|
||||||
|
|
||||||
mac80211-based drivers that support AP mode (with driver=nl80211).
|
|
||||||
This includes drivers for Atheros (ath9k) and Broadcom (b43)
|
|
||||||
chipsets.
|
|
||||||
|
|
||||||
Any wired Ethernet driver for wired IEEE 802.1X authentication
|
|
||||||
(experimental code)
|
|
||||||
|
|
||||||
FreeBSD -current (with some kernel mods that have not yet been
|
|
||||||
committed when hostapd v0.3.0 was released)
|
|
||||||
BSD net80211 layer (e.g., Atheros driver)
|
|
||||||
|
|
||||||
|
|
||||||
Build configuration
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
In order to be able to build hostapd, you will need to create a build
|
|
||||||
time configuration file, .config that selects which optional
|
|
||||||
components are included. See defconfig file for example configuration
|
|
||||||
and list of available options.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
IEEE 802.1X
|
|
||||||
===========
|
|
||||||
|
|
||||||
IEEE Std 802.1X-2001 is a standard for port-based network access
|
|
||||||
control. In case of IEEE 802.11 networks, a "virtual port" is used
|
|
||||||
between each associated station and the AP. IEEE 802.11 specifies
|
|
||||||
minimal authentication mechanism for stations, whereas IEEE 802.1X
|
|
||||||
introduces a extensible mechanism for authenticating and authorizing
|
|
||||||
users.
|
|
||||||
|
|
||||||
IEEE 802.1X uses elements called Supplicant, Authenticator, Port
|
|
||||||
Access Entity, and Authentication Server. Supplicant is a component in
|
|
||||||
a station and it performs the authentication with the Authentication
|
|
||||||
Server. An access point includes an Authenticator that relays the packets
|
|
||||||
between a Supplicant and an Authentication Server. In addition, it has a
|
|
||||||
Port Access Entity (PAE) with Authenticator functionality for
|
|
||||||
controlling the virtual port authorization, i.e., whether to accept
|
|
||||||
packets from or to the station.
|
|
||||||
|
|
||||||
IEEE 802.1X uses Extensible Authentication Protocol (EAP). The frames
|
|
||||||
between a Supplicant and an Authenticator are sent using EAP over LAN
|
|
||||||
(EAPOL) and the Authenticator relays these frames to the Authentication
|
|
||||||
Server (and similarly, relays the messages from the Authentication
|
|
||||||
Server to the Supplicant). The Authentication Server can be colocated with the
|
|
||||||
Authenticator, in which case there is no need for additional protocol
|
|
||||||
for EAP frame transmission. However, a more common configuration is to
|
|
||||||
use an external Authentication Server and encapsulate EAP frame in the
|
|
||||||
frames used by that server. RADIUS is suitable for this, but IEEE
|
|
||||||
802.1X would also allow other mechanisms.
|
|
||||||
|
|
||||||
Host AP driver includes PAE functionality in the kernel driver. It
|
|
||||||
is a relatively simple mechanism for denying normal frames going to
|
|
||||||
or coming from an unauthorized port. PAE allows IEEE 802.1X related
|
|
||||||
frames to be passed between the Supplicant and the Authenticator even
|
|
||||||
on an unauthorized port.
|
|
||||||
|
|
||||||
User space daemon, hostapd, includes Authenticator functionality. It
|
|
||||||
receives 802.1X (EAPOL) frames from the Supplicant using the wlan#ap
|
|
||||||
device that is also used with IEEE 802.11 management frames. The
|
|
||||||
frames to the Supplicant are sent using the same device.
|
|
||||||
|
|
||||||
The normal configuration of the Authenticator would use an external
|
|
||||||
Authentication Server. hostapd supports RADIUS encapsulation of EAP
|
|
||||||
packets, so the Authentication Server should be a RADIUS server, like
|
|
||||||
FreeRADIUS (http://www.freeradius.org/). The Authenticator in hostapd
|
|
||||||
relays the frames between the Supplicant and the Authentication
|
|
||||||
Server. It also controls the PAE functionality in the kernel driver by
|
|
||||||
controlling virtual port authorization, i.e., station-AP
|
|
||||||
connection, based on the IEEE 802.1X state.
|
|
||||||
|
|
||||||
When a station would like to use the services of an access point, it
|
|
||||||
will first perform IEEE 802.11 authentication. This is normally done
|
|
||||||
with open systems authentication, so there is no security. After
|
|
||||||
this, IEEE 802.11 association is performed. If IEEE 802.1X is
|
|
||||||
configured to be used, the virtual port for the station is set in
|
|
||||||
Unauthorized state and only IEEE 802.1X frames are accepted at this
|
|
||||||
point. The Authenticator will then ask the Supplicant to authenticate
|
|
||||||
with the Authentication Server. After this is completed successfully,
|
|
||||||
the virtual port is set to Authorized state and frames from and to the
|
|
||||||
station are accepted.
|
|
||||||
|
|
||||||
Host AP configuration for IEEE 802.1X
|
|
||||||
-------------------------------------
|
|
||||||
|
|
||||||
The user space daemon has its own configuration file that can be used to
|
|
||||||
define AP options. Distribution package contains an example
|
|
||||||
configuration file (hostapd/hostapd.conf) that can be used as a basis
|
|
||||||
for configuration. It includes examples of all supported configuration
|
|
||||||
options and short description of each option. hostapd should be started
|
|
||||||
with full path to the configuration file as the command line argument,
|
|
||||||
e.g., './hostapd /etc/hostapd.conf'. If you have more that one wireless
|
|
||||||
LAN card, you can use one hostapd process for multiple interfaces by
|
|
||||||
giving a list of configuration files (one per interface) in the command
|
|
||||||
line.
|
|
||||||
|
|
||||||
hostapd includes a minimal co-located IEEE 802.1X server which can be
|
|
||||||
used to test IEEE 802.1X authentication. However, it should not be
|
|
||||||
used in normal use since it does not provide any security. This can be
|
|
||||||
configured by setting ieee8021x and minimal_eap options in the
|
|
||||||
configuration file.
|
|
||||||
|
|
||||||
An external Authentication Server (RADIUS) is configured with
|
|
||||||
auth_server_{addr,port,shared_secret} options. In addition,
|
|
||||||
ieee8021x and own_ip_addr must be set for this mode. With such
|
|
||||||
configuration, the co-located Authentication Server is not used and EAP
|
|
||||||
frames will be relayed using EAPOL between the Supplicant and the
|
|
||||||
Authenticator and RADIUS encapsulation between the Authenticator and
|
|
||||||
the Authentication Server. Other than this, the functionality is similar
|
|
||||||
to the case with the co-located Authentication Server.
|
|
||||||
|
|
||||||
Authentication Server and Supplicant
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
Any RADIUS server supporting EAP should be usable as an IEEE 802.1X
|
|
||||||
Authentication Server with hostapd Authenticator. FreeRADIUS
|
|
||||||
(http://www.freeradius.org/) has been successfully tested with hostapd
|
|
||||||
Authenticator and both Xsupplicant (http://www.open1x.org) and Windows
|
|
||||||
XP Supplicants. EAP/TLS was used with Xsupplicant and
|
|
||||||
EAP/MD5-Challenge with Windows XP.
|
|
||||||
|
|
||||||
http://www.missl.cs.umd.edu/wireless/eaptls/ has useful information
|
|
||||||
about using EAP/TLS with FreeRADIUS and Xsupplicant (just replace
|
|
||||||
Cisco access point with Host AP driver, hostapd daemon, and a Prism2
|
|
||||||
card ;-). http://www.freeradius.org/doc/EAP-MD5.html has information
|
|
||||||
about using EAP/MD5 with FreeRADIUS, including instructions for WinXP
|
|
||||||
configuration. http://www.denobula.com/EAPTLS.pdf has a HOWTO on
|
|
||||||
EAP/TLS use with WinXP Supplicant.
|
|
||||||
|
|
||||||
Automatic WEP key configuration
|
|
||||||
-------------------------------
|
|
||||||
|
|
||||||
EAP/TLS generates a session key that can be used to send WEP keys from
|
|
||||||
an AP to authenticated stations. The Authenticator in hostapd can be
|
|
||||||
configured to automatically select a random default/broadcast key
|
|
||||||
(shared by all authenticated stations) with wep_key_len_broadcast
|
|
||||||
option (5 for 40-bit WEP or 13 for 104-bit WEP). In addition,
|
|
||||||
wep_key_len_unicast option can be used to configure individual unicast
|
|
||||||
keys for stations. This requires support for individual keys in the
|
|
||||||
station driver.
|
|
||||||
|
|
||||||
WEP keys can be automatically updated by configuring rekeying. This
|
|
||||||
will improve security of the network since same WEP key will only be
|
|
||||||
used for a limited period of time. wep_rekey_period option sets the
|
|
||||||
interval for rekeying in seconds.
|
|
||||||
|
|
||||||
|
|
||||||
WPA/WPA2
|
|
||||||
========
|
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
|
|
||||||
Supported WPA/IEEE 802.11i features:
|
|
||||||
- WPA-PSK ("WPA-Personal")
|
|
||||||
- WPA with EAP (e.g., with RADIUS authentication server) ("WPA-Enterprise")
|
|
||||||
- key management for CCMP, TKIP, WEP104, WEP40
|
|
||||||
- RSN/WPA2 (IEEE 802.11i), including PMKSA caching and pre-authentication
|
|
||||||
|
|
||||||
WPA
|
|
||||||
---
|
|
||||||
|
|
||||||
The original security mechanism of IEEE 802.11 standard was not
|
|
||||||
designed to be strong and has proved to be insufficient for most
|
|
||||||
networks that require some kind of security. Task group I (Security)
|
|
||||||
of IEEE 802.11 working group (http://www.ieee802.org/11/) has worked
|
|
||||||
to address the flaws of the base standard and has in practice
|
|
||||||
completed its work in May 2004. The IEEE 802.11i amendment to the IEEE
|
|
||||||
802.11 standard was approved in June 2004 and this amendment is likely
|
|
||||||
to be published in July 2004.
|
|
||||||
|
|
||||||
Wi-Fi Alliance (http://www.wi-fi.org/) used a draft version of the
|
|
||||||
IEEE 802.11i work (draft 3.0) to define a subset of the security
|
|
||||||
enhancements that can be implemented with existing wlan hardware. This
|
|
||||||
is called Wi-Fi Protected Access<TM> (WPA). This has now become a
|
|
||||||
mandatory component of interoperability testing and certification done
|
|
||||||
by Wi-Fi Alliance. Wi-Fi provides information about WPA at its web
|
|
||||||
site (http://www.wi-fi.org/OpenSection/protected_access.asp).
|
|
||||||
|
|
||||||
IEEE 802.11 standard defined wired equivalent privacy (WEP) algorithm
|
|
||||||
for protecting wireless networks. WEP uses RC4 with 40-bit keys,
|
|
||||||
24-bit initialization vector (IV), and CRC32 to protect against packet
|
|
||||||
forgery. All these choices have proven to be insufficient: key space is
|
|
||||||
too small against current attacks, RC4 key scheduling is insufficient
|
|
||||||
(beginning of the pseudorandom stream should be skipped), IV space is
|
|
||||||
too small and IV reuse makes attacks easier, there is no replay
|
|
||||||
protection, and non-keyed authentication does not protect against bit
|
|
||||||
flipping packet data.
|
|
||||||
|
|
||||||
WPA is an intermediate solution for the security issues. It uses
|
|
||||||
Temporal Key Integrity Protocol (TKIP) to replace WEP. TKIP is a
|
|
||||||
compromise on strong security and possibility to use existing
|
|
||||||
hardware. It still uses RC4 for the encryption like WEP, but with
|
|
||||||
per-packet RC4 keys. In addition, it implements replay protection,
|
|
||||||
keyed packet authentication mechanism (Michael MIC).
|
|
||||||
|
|
||||||
Keys can be managed using two different mechanisms. WPA can either use
|
|
||||||
an external authentication server (e.g., RADIUS) and EAP just like
|
|
||||||
IEEE 802.1X is using or pre-shared keys without need for additional
|
|
||||||
servers. Wi-Fi calls these "WPA-Enterprise" and "WPA-Personal",
|
|
||||||
respectively. Both mechanisms will generate a master session key for
|
|
||||||
the Authenticator (AP) and Supplicant (client station).
|
|
||||||
|
|
||||||
WPA implements a new key handshake (4-Way Handshake and Group Key
|
|
||||||
Handshake) for generating and exchanging data encryption keys between
|
|
||||||
the Authenticator and Supplicant. This handshake is also used to
|
|
||||||
verify that both Authenticator and Supplicant know the master session
|
|
||||||
key. These handshakes are identical regardless of the selected key
|
|
||||||
management mechanism (only the method for generating master session
|
|
||||||
key changes).
|
|
||||||
|
|
||||||
|
|
||||||
IEEE 802.11i / WPA2
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
The design for parts of IEEE 802.11i that were not included in WPA has
|
|
||||||
finished (May 2004) and this amendment to IEEE 802.11 was approved in
|
|
||||||
June 2004. Wi-Fi Alliance is using the final IEEE 802.11i as a new
|
|
||||||
version of WPA called WPA2. This includes, e.g., support for more
|
|
||||||
robust encryption algorithm (CCMP: AES in Counter mode with CBC-MAC)
|
|
||||||
to replace TKIP and optimizations for handoff (reduced number of
|
|
||||||
messages in initial key handshake, pre-authentication, and PMKSA caching).
|
|
||||||
|
|
||||||
Some wireless LAN vendors are already providing support for CCMP in
|
|
||||||
their WPA products. There is no "official" interoperability
|
|
||||||
certification for CCMP and/or mixed modes using both TKIP and CCMP, so
|
|
||||||
some interoperability issues can be expected even though many
|
|
||||||
combinations seem to be working with equipment from different vendors.
|
|
||||||
Testing for WPA2 is likely to start during the second half of 2004.
|
|
||||||
|
|
||||||
hostapd configuration for WPA/WPA2
|
|
||||||
----------------------------------
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
# Enable WPA. Setting this variable configures the AP to require WPA (either
|
|
||||||
# WPA-PSK or WPA-RADIUS/EAP based on other configuration). For WPA-PSK, either
|
|
||||||
# wpa_psk or wpa_passphrase must be set and wpa_key_mgmt must include WPA-PSK.
|
|
||||||
# For WPA-RADIUS/EAP, ieee8021x must be set (but without dynamic WEP keys),
|
|
||||||
# RADIUS authentication server must be configured, and WPA-EAP must be included
|
|
||||||
# in wpa_key_mgmt.
|
|
||||||
# This field is a bit field that can be used to enable WPA (IEEE 802.11i/D3.0)
|
|
||||||
# and/or WPA2 (full IEEE 802.11i/RSN):
|
|
||||||
# bit0 = WPA
|
|
||||||
# bit1 = IEEE 802.11i/RSN (WPA2)
|
|
||||||
#wpa=1
|
|
||||||
|
|
||||||
# WPA pre-shared keys for WPA-PSK. This can be either entered as a 256-bit
|
|
||||||
# secret in hex format (64 hex digits), wpa_psk, or as an ASCII passphrase
|
|
||||||
# (8..63 characters) that will be converted to PSK. This conversion uses SSID
|
|
||||||
# so the PSK changes when ASCII passphrase is used and the SSID is changed.
|
|
||||||
#wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
|
|
||||||
#wpa_passphrase=secret passphrase
|
|
||||||
|
|
||||||
# Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The
|
|
||||||
# entries are separated with a space.
|
|
||||||
#wpa_key_mgmt=WPA-PSK WPA-EAP
|
|
||||||
|
|
||||||
# Set of accepted cipher suites (encryption algorithms) for pairwise keys
|
|
||||||
# (unicast packets). This is a space separated list of algorithms:
|
|
||||||
# CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i]
|
|
||||||
# TKIP = Temporal Key Integrity Protocol [IEEE 802.11i]
|
|
||||||
# Group cipher suite (encryption algorithm for broadcast and multicast frames)
|
|
||||||
# is automatically selected based on this configuration. If only CCMP is
|
|
||||||
# allowed as the pairwise cipher, group cipher will also be CCMP. Otherwise,
|
|
||||||
# TKIP will be used as the group cipher.
|
|
||||||
#wpa_pairwise=TKIP CCMP
|
|
||||||
|
|
||||||
# Time interval for rekeying GTK (broadcast/multicast encryption keys) in
|
|
||||||
# seconds.
|
|
||||||
#wpa_group_rekey=600
|
|
||||||
|
|
||||||
# Time interval for rekeying GMK (master key used internally to generate GTKs
|
|
||||||
# (in seconds).
|
|
||||||
#wpa_gmk_rekey=86400
|
|
||||||
|
|
||||||
# Enable IEEE 802.11i/RSN/WPA2 pre-authentication. This is used to speed up
|
|
||||||
# roaming be pre-authenticating IEEE 802.1X/EAP part of the full RSN
|
|
||||||
# authentication and key handshake before actually associating with a new AP.
|
|
||||||
#rsn_preauth=1
|
|
||||||
#
|
|
||||||
# Space separated list of interfaces from which pre-authentication frames are
|
|
||||||
# accepted (e.g., 'eth0' or 'eth0 wlan0wds0'. This list should include all
|
|
||||||
# interface that are used for connections to other APs. This could include
|
|
||||||
# wired interfaces and WDS links. The normal wireless data interface towards
|
|
||||||
# associated stations (e.g., wlan0) should not be added, since
|
|
||||||
# pre-authentication is only used with APs other than the currently associated
|
|
||||||
# one.
|
|
||||||
#rsn_preauth_interfaces=eth0
|
|
|
@ -1,291 +0,0 @@
|
||||||
hostapd and Wi-Fi Protected Setup (WPS)
|
|
||||||
=======================================
|
|
||||||
|
|
||||||
This document describes how the WPS implementation in hostapd can be
|
|
||||||
configured and how an external component on an AP (e.g., web UI) is
|
|
||||||
used to enable enrollment of client devices.
|
|
||||||
|
|
||||||
|
|
||||||
Introduction to WPS
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Wi-Fi Protected Setup (WPS) is a mechanism for easy configuration of a
|
|
||||||
wireless network. It allows automated generation of random keys (WPA
|
|
||||||
passphrase/PSK) and configuration of an access point and client
|
|
||||||
devices. WPS includes number of methods for setting up connections
|
|
||||||
with PIN method and push-button configuration (PBC) being the most
|
|
||||||
commonly deployed options.
|
|
||||||
|
|
||||||
While WPS can enable more home networks to use encryption in the
|
|
||||||
wireless network, it should be noted that the use of the PIN and
|
|
||||||
especially PBC mechanisms for authenticating the initial key setup is
|
|
||||||
not very secure. As such, use of WPS may not be suitable for
|
|
||||||
environments that require secure network access without chance for
|
|
||||||
allowing outsiders to gain access during the setup phase.
|
|
||||||
|
|
||||||
WPS uses following terms to describe the entities participating in the
|
|
||||||
network setup:
|
|
||||||
- access point: the WLAN access point
|
|
||||||
- Registrar: a device that control a network and can authorize
|
|
||||||
addition of new devices); this may be either in the AP ("internal
|
|
||||||
Registrar") or in an external device, e.g., a laptop, ("external
|
|
||||||
Registrar")
|
|
||||||
- Enrollee: a device that is being authorized to use the network
|
|
||||||
|
|
||||||
It should also be noted that the AP and a client device may change
|
|
||||||
roles (i.e., AP acts as an Enrollee and client device as a Registrar)
|
|
||||||
when WPS is used to configure the access point.
|
|
||||||
|
|
||||||
|
|
||||||
More information about WPS is available from Wi-Fi Alliance:
|
|
||||||
http://www.wi-fi.org/wifi-protected-setup
|
|
||||||
|
|
||||||
|
|
||||||
hostapd implementation
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
hostapd includes an optional WPS component that can be used as an
|
|
||||||
internal WPS Registrar to manage addition of new WPS enabled clients
|
|
||||||
to the network. In addition, WPS Enrollee functionality in hostapd can
|
|
||||||
be used to allow external WPS Registrars to configure the access
|
|
||||||
point, e.g., for initial network setup. In addition, hostapd can proxy a
|
|
||||||
WPS registration between a wireless Enrollee and an external Registrar
|
|
||||||
(e.g., Microsoft Vista or Atheros JumpStart) with UPnP.
|
|
||||||
|
|
||||||
|
|
||||||
hostapd configuration
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
WPS is an optional component that needs to be enabled in hostapd build
|
|
||||||
configuration (.config). Here is an example configuration that
|
|
||||||
includes WPS support and uses madwifi driver interface:
|
|
||||||
|
|
||||||
CONFIG_DRIVER_MADWIFI=y
|
|
||||||
CFLAGS += -I/usr/src/madwifi-0.9.3
|
|
||||||
CONFIG_WPS=y
|
|
||||||
CONFIG_WPS2=y
|
|
||||||
CONFIG_WPS_UPNP=y
|
|
||||||
|
|
||||||
|
|
||||||
Following section shows an example runtime configuration
|
|
||||||
(hostapd.conf) that enables WPS:
|
|
||||||
|
|
||||||
# Configure the driver and network interface
|
|
||||||
driver=madwifi
|
|
||||||
interface=ath0
|
|
||||||
|
|
||||||
# WPA2-Personal configuration for the AP
|
|
||||||
ssid=wps-test
|
|
||||||
wpa=2
|
|
||||||
wpa_key_mgmt=WPA-PSK
|
|
||||||
wpa_pairwise=CCMP
|
|
||||||
# Default WPA passphrase for legacy (non-WPS) clients
|
|
||||||
wpa_passphrase=12345678
|
|
||||||
# Enable random per-device PSK generation for WPS clients
|
|
||||||
# Please note that the file has to exists for hostapd to start (i.e., create an
|
|
||||||
# empty file as a starting point).
|
|
||||||
wpa_psk_file=/etc/hostapd.psk
|
|
||||||
|
|
||||||
# Enable control interface for PBC/PIN entry
|
|
||||||
ctrl_interface=/var/run/hostapd
|
|
||||||
|
|
||||||
# Enable internal EAP server for EAP-WSC (part of Wi-Fi Protected Setup)
|
|
||||||
eap_server=1
|
|
||||||
|
|
||||||
# WPS configuration (AP configured, do not allow external WPS Registrars)
|
|
||||||
wps_state=2
|
|
||||||
ap_setup_locked=1
|
|
||||||
# If UUID is not configured, it will be generated based on local MAC address.
|
|
||||||
uuid=87654321-9abc-def0-1234-56789abc0000
|
|
||||||
wps_pin_requests=/var/run/hostapd.pin-req
|
|
||||||
device_name=Wireless AP
|
|
||||||
manufacturer=Company
|
|
||||||
model_name=WAP
|
|
||||||
model_number=123
|
|
||||||
serial_number=12345
|
|
||||||
device_type=6-0050F204-1
|
|
||||||
os_version=01020300
|
|
||||||
config_methods=label display push_button keypad
|
|
||||||
|
|
||||||
# if external Registrars are allowed, UPnP support could be added:
|
|
||||||
#upnp_iface=br0
|
|
||||||
#friendly_name=WPS Access Point
|
|
||||||
|
|
||||||
|
|
||||||
External operations
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
WPS requires either a device PIN code (usually, 8-digit number) or a
|
|
||||||
pushbutton event (for PBC) to allow a new WPS Enrollee to join the
|
|
||||||
network. hostapd uses the control interface as an input channel for
|
|
||||||
these events.
|
|
||||||
|
|
||||||
The PIN value used in the commands must be processed by an UI to
|
|
||||||
remove non-digit characters and potentially, to verify the checksum
|
|
||||||
digit. "hostapd_cli wps_check_pin <PIN>" can be used to do such
|
|
||||||
processing. It returns FAIL if the PIN is invalid, or FAIL-CHECKSUM if
|
|
||||||
the checksum digit is incorrect, or the processed PIN (non-digit
|
|
||||||
characters removed) if the PIN is valid.
|
|
||||||
|
|
||||||
When a client device (WPS Enrollee) connects to hostapd (WPS
|
|
||||||
Registrar) in order to start PIN mode negotiation for WPS, an
|
|
||||||
identifier (Enrollee UUID) is sent. hostapd will need to be configured
|
|
||||||
with a device password (PIN) for this Enrollee. This is an operation
|
|
||||||
that requires user interaction (assuming there are no pre-configured
|
|
||||||
PINs on the AP for a set of Enrollee).
|
|
||||||
|
|
||||||
The PIN request with information about the device is appended to the
|
|
||||||
wps_pin_requests file (/var/run/hostapd.pin-req in this example). In
|
|
||||||
addition, hostapd control interface event is sent as a notification of
|
|
||||||
a new device. The AP could use, e.g., a web UI for showing active
|
|
||||||
Enrollees to the user and request a PIN for an Enrollee.
|
|
||||||
|
|
||||||
The PIN request file has one line for every Enrollee that connected to
|
|
||||||
the AP, but for which there was no PIN. Following information is
|
|
||||||
provided for each Enrollee (separated with tabulators):
|
|
||||||
- timestamp (seconds from 1970-01-01)
|
|
||||||
- Enrollee UUID
|
|
||||||
- MAC address
|
|
||||||
- Device name
|
|
||||||
- Manufacturer
|
|
||||||
- Model Name
|
|
||||||
- Model Number
|
|
||||||
- Serial Number
|
|
||||||
- Device category
|
|
||||||
|
|
||||||
Example line in the /var/run/hostapd.pin-req file:
|
|
||||||
1200188391 53b63a98-d29e-4457-a2ed-094d7e6a669c Intel(R) Centrino(R) Intel Corporation Intel(R) Centrino(R) - - 1-0050F204-1
|
|
||||||
|
|
||||||
Control interface data:
|
|
||||||
WPS-PIN-NEEDED [UUID-E|MAC Address|Device Name|Manufacturer|Model Name|Model Number|Serial Number|Device Category]
|
|
||||||
For example:
|
|
||||||
<2>WPS-PIN-NEEDED [53b63a98-d29e-4457-a2ed-094d7e6a669c|02:12:34:56:78:9a|Device|Manuf|Model|Model Number|Serial Number|1-0050F204-1]
|
|
||||||
|
|
||||||
When the user enters a PIN for a pending Enrollee, e.g., on the web
|
|
||||||
UI), hostapd needs to be notified of the new PIN over the control
|
|
||||||
interface. This can be done either by using the UNIX domain socket
|
|
||||||
-based control interface directly (src/common/wpa_ctrl.c provides
|
|
||||||
helper functions for using the interface) or by calling hostapd_cli.
|
|
||||||
|
|
||||||
Example command to add a PIN (12345670) for an Enrollee:
|
|
||||||
|
|
||||||
hostapd_cli wps_pin 53b63a98-d29e-4457-a2ed-094d7e6a669c 12345670
|
|
||||||
|
|
||||||
If the UUID-E is not available (e.g., Enrollee waits for the Registrar
|
|
||||||
to be selected before connecting), wildcard UUID may be used to allow
|
|
||||||
the PIN to be used once with any UUID:
|
|
||||||
|
|
||||||
hostapd_cli wps_pin any 12345670
|
|
||||||
|
|
||||||
To reduce likelihood of PIN being used with other devices or of
|
|
||||||
forgetting an active PIN available for potential attackers, expiration
|
|
||||||
time in seconds can be set for the new PIN (value 0 indicates no
|
|
||||||
expiration):
|
|
||||||
|
|
||||||
hostapd_cli wps_pin any 12345670 300
|
|
||||||
|
|
||||||
If the MAC address of the enrollee is known, it should be configured
|
|
||||||
to allow the AP to advertise list of authorized enrollees:
|
|
||||||
|
|
||||||
hostapd_cli wps_pin 53b63a98-d29e-4457-a2ed-094d7e6a669c \
|
|
||||||
12345670 300 00:11:22:33:44:55
|
|
||||||
|
|
||||||
|
|
||||||
After this, the Enrollee can connect to the AP again and complete WPS
|
|
||||||
negotiation. At that point, a new, random WPA PSK is generated for the
|
|
||||||
client device and the client can then use that key to connect to the
|
|
||||||
AP to access the network.
|
|
||||||
|
|
||||||
|
|
||||||
If the AP includes a pushbutton, WPS PBC mode can be used. It is
|
|
||||||
enabled by pushing a button on both the AP and the client at about the
|
|
||||||
same time (2 minute window). hostapd needs to be notified about the AP
|
|
||||||
button pushed event over the control interface, e.g., by calling
|
|
||||||
hostapd_cli:
|
|
||||||
|
|
||||||
hostapd_cli wps_pbc
|
|
||||||
|
|
||||||
At this point, the client has two minutes to complete WPS negotiation
|
|
||||||
which will generate a new WPA PSK in the same way as the PIN method
|
|
||||||
described above.
|
|
||||||
|
|
||||||
|
|
||||||
When an external Registrar is used, the AP can act as an Enrollee and
|
|
||||||
use its AP PIN. A static AP PIN (e.g., one one a label in the AP
|
|
||||||
device) can be configured in hostapd.conf (ap_pin parameter). A more
|
|
||||||
secure option is to use hostapd_cli wps_ap_pin command to enable the
|
|
||||||
AP PIN only based on user action (and even better security by using a
|
|
||||||
random AP PIN for each session, i.e., by using "wps_ap_pin random"
|
|
||||||
command with a timeout value). Following commands are available for
|
|
||||||
managing the dynamic AP PIN operations:
|
|
||||||
|
|
||||||
hostapd_cli wps_ap_pin disable
|
|
||||||
- disable AP PIN (i.e., do not allow external Registrars to use it to
|
|
||||||
learn the current AP settings or to reconfigure the AP)
|
|
||||||
|
|
||||||
hostapd_cli wps_ap_pin random [timeout]
|
|
||||||
- generate a random AP PIN and enable it
|
|
||||||
- if the optional timeout parameter is given, the AP PIN will be enabled
|
|
||||||
for the specified number of seconds
|
|
||||||
|
|
||||||
hostapd_cli wps_ap_pin get
|
|
||||||
- fetch the current AP PIN
|
|
||||||
|
|
||||||
hostapd_cli wps_ap_pin set <PIN> [timeout]
|
|
||||||
- set the AP PIN and enable it
|
|
||||||
- if the optional timeout parameter is given, the AP PIN will be enabled
|
|
||||||
for the specified number of seconds
|
|
||||||
|
|
||||||
hostapd_cli get_config
|
|
||||||
- display the current configuration
|
|
||||||
|
|
||||||
hostapd_cli wps_config <new SSID> <auth> <encr> <new key>
|
|
||||||
examples:
|
|
||||||
hostapd_cli wps_config testing WPA2PSK CCMP 12345678
|
|
||||||
hostapd_cli wps_config "no security" OPEN NONE ""
|
|
||||||
|
|
||||||
<auth> must be one of the following: OPEN WPAPSK WPA2PSK
|
|
||||||
<encr> must be one of the following: NONE WEP TKIP CCMP
|
|
||||||
|
|
||||||
|
|
||||||
Credential generation and configuration changes
|
|
||||||
-----------------------------------------------
|
|
||||||
|
|
||||||
By default, hostapd generates credentials for Enrollees and processing
|
|
||||||
AP configuration updates internally. However, it is possible to
|
|
||||||
control these operations from external programs, if desired.
|
|
||||||
|
|
||||||
The internal credential generation can be disabled with
|
|
||||||
skip_cred_build=1 option in the configuration. extra_cred option will
|
|
||||||
then need to be used to provide pre-configured Credential attribute(s)
|
|
||||||
for hostapd to use. The exact data from this binary file will be sent,
|
|
||||||
i.e., it will have to include valid WPS attributes. extra_cred can
|
|
||||||
also be used to add additional networks if the Registrar is used to
|
|
||||||
configure credentials for multiple networks.
|
|
||||||
|
|
||||||
Processing of received configuration updates can be disabled with
|
|
||||||
wps_cred_processing=1 option. When this is used, an external program
|
|
||||||
is responsible for creating hostapd configuration files and processing
|
|
||||||
configuration updates based on messages received from hostapd over
|
|
||||||
control interface. This will also include the initial configuration on
|
|
||||||
first successful registration if the AP is initially set in
|
|
||||||
unconfigured state.
|
|
||||||
|
|
||||||
Following control interface messages are sent out for external programs:
|
|
||||||
|
|
||||||
WPS-REG-SUCCESS <Enrollee MAC address <UUID-E>
|
|
||||||
For example:
|
|
||||||
<2>WPS-REG-SUCCESS 02:66:a0:ee:17:27 2b7093f1-d6fb-5108-adbb-bea66bb87333
|
|
||||||
|
|
||||||
This can be used to trigger change from unconfigured to configured
|
|
||||||
state (random configuration based on the first successful WPS
|
|
||||||
registration). In addition, this can be used to update AP UI about the
|
|
||||||
status of WPS registration progress.
|
|
||||||
|
|
||||||
|
|
||||||
WPS-NEW-AP-SETTINGS <hexdump of AP Setup attributes>
|
|
||||||
For example:
|
|
||||||
<2>WPS-NEW-AP-SETTINGS 10260001011045000c6a6b6d2d7770732d74657374100300020020100f00020008102700403065346230343536633236366665306433396164313535346131663462663731323433376163666462376633393965353466316631623032306164343438623510200006024231cede15101e000844
|
|
||||||
|
|
||||||
This can be used to update the externally stored AP configuration and
|
|
||||||
then update hostapd configuration (followed by restarting of hostapd).
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,20 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / Configuration file parser
|
|
||||||
* Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CONFIG_FILE_H
|
|
||||||
#define CONFIG_FILE_H
|
|
||||||
|
|
||||||
struct hostapd_config * hostapd_config_read(const char *fname);
|
|
||||||
|
|
||||||
#endif /* CONFIG_FILE_H */
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / UNIX domain socket -based control interface
|
|
||||||
* Copyright (c) 2004, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CTRL_IFACE_H
|
|
||||||
#define CTRL_IFACE_H
|
|
||||||
|
|
||||||
#ifndef CONFIG_NO_CTRL_IFACE
|
|
||||||
int hostapd_ctrl_iface_init(struct hostapd_data *hapd);
|
|
||||||
void hostapd_ctrl_iface_deinit(struct hostapd_data *hapd);
|
|
||||||
#else /* CONFIG_NO_CTRL_IFACE */
|
|
||||||
static inline int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void hostapd_ctrl_iface_deinit(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_NO_CTRL_IFACE */
|
|
||||||
|
|
||||||
#endif /* CTRL_IFACE_H */
|
|
|
@ -1,208 +0,0 @@
|
||||||
# Example hostapd build time configuration
|
|
||||||
#
|
|
||||||
# This file lists the configuration options that are used when building the
|
|
||||||
# hostapd binary. All lines starting with # are ignored. Configuration option
|
|
||||||
# lines must be commented out complete, if they are not to be included, i.e.,
|
|
||||||
# just setting VARIABLE=n is not disabling that variable.
|
|
||||||
#
|
|
||||||
# This file is included in Makefile, so variables like CFLAGS and LIBS can also
|
|
||||||
# be modified from here. In most cass, these lines should use += in order not
|
|
||||||
# to override previous values of the variables.
|
|
||||||
|
|
||||||
# Driver interface for Host AP driver
|
|
||||||
#CONFIG_DRIVER_HOSTAP=y
|
|
||||||
CONFIG_DRIVER_RTW=y
|
|
||||||
|
|
||||||
# Driver interface for wired authenticator
|
|
||||||
#CONFIG_DRIVER_WIRED=y
|
|
||||||
|
|
||||||
# Driver interface for madwifi driver
|
|
||||||
#CONFIG_DRIVER_MADWIFI=y
|
|
||||||
#CFLAGS += -I../../madwifi # change to the madwifi source directory
|
|
||||||
|
|
||||||
# Driver interface for drivers using the nl80211 kernel interface
|
|
||||||
#CONFIG_DRIVER_NL80211=y
|
|
||||||
|
|
||||||
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
|
|
||||||
#CONFIG_DRIVER_BSD=y
|
|
||||||
#CFLAGS += -I/usr/local/include
|
|
||||||
#LIBS += -L/usr/local/lib
|
|
||||||
#LIBS_p += -L/usr/local/lib
|
|
||||||
#LIBS_c += -L/usr/local/lib
|
|
||||||
|
|
||||||
# Driver interface for no driver (e.g., RADIUS server only)
|
|
||||||
#CONFIG_DRIVER_NONE=y
|
|
||||||
|
|
||||||
# IEEE 802.11F/IAPP
|
|
||||||
#CONFIG_IAPP=y
|
|
||||||
|
|
||||||
# WPA2/IEEE 802.11i RSN pre-authentication
|
|
||||||
#CONFIG_RSN_PREAUTH=y
|
|
||||||
|
|
||||||
# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
|
|
||||||
#CONFIG_PEERKEY=y
|
|
||||||
|
|
||||||
# IEEE 802.11w (management frame protection)
|
|
||||||
# This version is an experimental implementation based on IEEE 802.11w/D1.0
|
|
||||||
# draft and is subject to change since the standard has not yet been finalized.
|
|
||||||
# Driver support is also needed for IEEE 802.11w.
|
|
||||||
#CONFIG_IEEE80211W=y
|
|
||||||
|
|
||||||
# Integrated EAP server
|
|
||||||
CONFIG_EAP=y
|
|
||||||
|
|
||||||
# EAP-MD5 for the integrated EAP server
|
|
||||||
#CONFIG_EAP_MD5=y
|
|
||||||
|
|
||||||
# EAP-TLS for the integrated EAP server
|
|
||||||
#CONFIG_EAP_TLS=y
|
|
||||||
|
|
||||||
# EAP-MSCHAPv2 for the integrated EAP server
|
|
||||||
#CONFIG_EAP_MSCHAPV2=y
|
|
||||||
|
|
||||||
# EAP-PEAP for the integrated EAP server
|
|
||||||
#CONFIG_EAP_PEAP=y
|
|
||||||
|
|
||||||
# EAP-GTC for the integrated EAP server
|
|
||||||
#CONFIG_EAP_GTC=y
|
|
||||||
|
|
||||||
# EAP-TTLS for the integrated EAP server
|
|
||||||
#CONFIG_EAP_TTLS=y
|
|
||||||
|
|
||||||
# EAP-SIM for the integrated EAP server
|
|
||||||
#CONFIG_EAP_SIM=y
|
|
||||||
|
|
||||||
# EAP-AKA for the integrated EAP server
|
|
||||||
#CONFIG_EAP_AKA=y
|
|
||||||
|
|
||||||
# EAP-AKA' for the integrated EAP server
|
|
||||||
# This requires CONFIG_EAP_AKA to be enabled, too.
|
|
||||||
#CONFIG_EAP_AKA_PRIME=y
|
|
||||||
|
|
||||||
# EAP-PAX for the integrated EAP server
|
|
||||||
#CONFIG_EAP_PAX=y
|
|
||||||
|
|
||||||
# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
|
|
||||||
#CONFIG_EAP_PSK=y
|
|
||||||
|
|
||||||
# EAP-SAKE for the integrated EAP server
|
|
||||||
#CONFIG_EAP_SAKE=y
|
|
||||||
|
|
||||||
# EAP-GPSK for the integrated EAP server
|
|
||||||
#CONFIG_EAP_GPSK=y
|
|
||||||
# Include support for optional SHA256 cipher suite in EAP-GPSK
|
|
||||||
#CONFIG_EAP_GPSK_SHA256=y
|
|
||||||
|
|
||||||
# EAP-FAST for the integrated EAP server
|
|
||||||
# Note: Default OpenSSL package does not include support for all the
|
|
||||||
# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
|
|
||||||
# the OpenSSL library must be patched (openssl-0.9.9-session-ticket.patch)
|
|
||||||
# to add the needed functions.
|
|
||||||
#CONFIG_EAP_FAST=y
|
|
||||||
|
|
||||||
# Wi-Fi Protected Setup (WPS)
|
|
||||||
CONFIG_WPS=y
|
|
||||||
# Enable WSC 2.0 support
|
|
||||||
CONFIG_WPS2=y
|
|
||||||
# Enable UPnP support for external WPS Registrars
|
|
||||||
#CONFIG_WPS_UPNP=y
|
|
||||||
|
|
||||||
CONFIG_TLS=internal
|
|
||||||
CONFIG_INTERNAL_LIBTOMMATH=y
|
|
||||||
|
|
||||||
# EAP-IKEv2
|
|
||||||
#CONFIG_EAP_IKEV2=y
|
|
||||||
|
|
||||||
# Trusted Network Connect (EAP-TNC)
|
|
||||||
#CONFIG_EAP_TNC=y
|
|
||||||
|
|
||||||
# PKCS#12 (PFX) support (used to read private key and certificate file from
|
|
||||||
# a file that usually has extension .p12 or .pfx)
|
|
||||||
#CONFIG_PKCS12=y
|
|
||||||
|
|
||||||
# RADIUS authentication server. This provides access to the integrated EAP
|
|
||||||
# server from external hosts using RADIUS.
|
|
||||||
#CONFIG_RADIUS_SERVER=y
|
|
||||||
|
|
||||||
# Build IPv6 support for RADIUS operations
|
|
||||||
#CONFIG_IPV6=y
|
|
||||||
|
|
||||||
# IEEE Std 802.11r-2008 (Fast BSS Transition)
|
|
||||||
#CONFIG_IEEE80211R=y
|
|
||||||
|
|
||||||
# Use the hostapd's IEEE 802.11 authentication (ACL), but without
|
|
||||||
# the IEEE 802.11 Management capability (e.g., madwifi or FreeBSD/net80211)
|
|
||||||
#CONFIG_DRIVER_RADIUS_ACL=y
|
|
||||||
|
|
||||||
# IEEE 802.11n (High Throughput) support
|
|
||||||
CONFIG_IEEE80211N=y
|
|
||||||
|
|
||||||
# Remove debugging code that is printing out debug messages to stdout.
|
|
||||||
# This can be used to reduce the size of the hostapd considerably if debugging
|
|
||||||
# code is not needed.
|
|
||||||
#CONFIG_NO_STDOUT_DEBUG=y
|
|
||||||
|
|
||||||
# Add support for writing debug log to a file: -f /tmp/hostapd.log
|
|
||||||
# Disabled by default.
|
|
||||||
#CONFIG_DEBUG_FILE=y
|
|
||||||
|
|
||||||
# Remove support for RADIUS accounting
|
|
||||||
#CONFIG_NO_ACCOUNTING=y
|
|
||||||
|
|
||||||
# Remove support for RADIUS
|
|
||||||
#CONFIG_NO_RADIUS=y
|
|
||||||
|
|
||||||
# Remove support for VLANs
|
|
||||||
#CONFIG_NO_VLAN=y
|
|
||||||
|
|
||||||
# Enable support for fully dynamic VLANs. This enables hostapd to
|
|
||||||
# automatically create bridge and VLAN interfaces if necessary.
|
|
||||||
#CONFIG_FULL_DYNAMIC_VLAN=y
|
|
||||||
|
|
||||||
# Remove support for dumping state into a file on SIGUSR1 signal
|
|
||||||
# This can be used to reduce binary size at the cost of disabling a debugging
|
|
||||||
# option.
|
|
||||||
#CONFIG_NO_DUMP_STATE=y
|
|
||||||
|
|
||||||
# Enable tracing code for developer debugging
|
|
||||||
# This tracks use of memory allocations and other registrations and reports
|
|
||||||
# incorrect use with a backtrace of call (or allocation) location.
|
|
||||||
#CONFIG_WPA_TRACE=y
|
|
||||||
# For BSD, comment out these.
|
|
||||||
#LIBS += -lexecinfo
|
|
||||||
#LIBS_p += -lexecinfo
|
|
||||||
#LIBS_c += -lexecinfo
|
|
||||||
|
|
||||||
# Use libbfd to get more details for developer debugging
|
|
||||||
# This enables use of libbfd to get more detailed symbols for the backtraces
|
|
||||||
# generated by CONFIG_WPA_TRACE=y.
|
|
||||||
#CONFIG_WPA_TRACE_BFD=y
|
|
||||||
# For BSD, comment out these.
|
|
||||||
#LIBS += -lbfd -liberty -lz
|
|
||||||
#LIBS_p += -lbfd -liberty -lz
|
|
||||||
#LIBS_c += -lbfd -liberty -lz
|
|
||||||
|
|
||||||
# hostapd depends on strong random number generation being available from the
|
|
||||||
# operating system. os_get_random() function is used to fetch random data when
|
|
||||||
# needed, e.g., for key generation. On Linux and BSD systems, this works by
|
|
||||||
# reading /dev/urandom. It should be noted that the OS entropy pool needs to be
|
|
||||||
# properly initialized before hostapd is started. This is important especially
|
|
||||||
# on embedded devices that do not have a hardware random number generator and
|
|
||||||
# may by default start up with minimal entropy available for random number
|
|
||||||
# generation.
|
|
||||||
#
|
|
||||||
# As a safety net, hostapd is by default trying to internally collect
|
|
||||||
# additional entropy for generating random data to mix in with the data
|
|
||||||
# fetched from the OS. This by itself is not considered to be very strong, but
|
|
||||||
# it may help in cases where the system pool is not initialized properly.
|
|
||||||
# However, it is very strongly recommended that the system pool is initialized
|
|
||||||
# with enough entropy either by using hardware assisted random number
|
|
||||||
# generatior or by storing state over device reboots.
|
|
||||||
#
|
|
||||||
# If the os_get_random() is known to provide strong ramdom data (e.g., on
|
|
||||||
# Linux/BSD, the board in question is known to have reliable source of random
|
|
||||||
# data from /dev/urandom), the internal hostapd random pool can be disabled.
|
|
||||||
# This will save some in binary size and CPU use. However, this should only be
|
|
||||||
# considered for builds that are known to be used on devices that meet the
|
|
||||||
# requirements described above.
|
|
||||||
#CONFIG_NO_RANDOM_POOL=y
|
|
|
@ -1,183 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / State dump
|
|
||||||
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "utils/includes.h"
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
|
||||||
#include "radius/radius_client.h"
|
|
||||||
#include "radius/radius_server.h"
|
|
||||||
#include "eapol_auth/eapol_auth_sm.h"
|
|
||||||
#include "eapol_auth/eapol_auth_sm_i.h"
|
|
||||||
#include "eap_server/eap.h"
|
|
||||||
#include "ap/hostapd.h"
|
|
||||||
#include "ap/ap_config.h"
|
|
||||||
#include "ap/sta_info.h"
|
|
||||||
#include "dump_state.h"
|
|
||||||
|
|
||||||
|
|
||||||
static void fprint_char(FILE *f, char c)
|
|
||||||
{
|
|
||||||
if (c >= 32 && c < 127)
|
|
||||||
fprintf(f, "%c", c);
|
|
||||||
else
|
|
||||||
fprintf(f, "<%02x>", c);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ieee802_1x_dump_state(FILE *f, const char *prefix,
|
|
||||||
struct sta_info *sta)
|
|
||||||
{
|
|
||||||
struct eapol_state_machine *sm = sta->eapol_sm;
|
|
||||||
if (sm == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fprintf(f, "%sIEEE 802.1X:\n", prefix);
|
|
||||||
|
|
||||||
if (sm->identity) {
|
|
||||||
size_t i;
|
|
||||||
fprintf(f, "%sidentity=", prefix);
|
|
||||||
for (i = 0; i < sm->identity_len; i++)
|
|
||||||
fprint_char(f, sm->identity[i]);
|
|
||||||
fprintf(f, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(f, "%slast EAP type: Authentication Server: %d (%s) "
|
|
||||||
"Supplicant: %d (%s)\n", prefix,
|
|
||||||
sm->eap_type_authsrv,
|
|
||||||
eap_server_get_name(0, sm->eap_type_authsrv),
|
|
||||||
sm->eap_type_supp, eap_server_get_name(0, sm->eap_type_supp));
|
|
||||||
|
|
||||||
fprintf(f, "%scached_packets=%s\n", prefix,
|
|
||||||
sm->last_recv_radius ? "[RX RADIUS]" : "");
|
|
||||||
|
|
||||||
eapol_auth_dump_state(f, prefix, sm);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hostapd_dump_state - SIGUSR1 handler to dump hostapd state to a text file
|
|
||||||
*/
|
|
||||||
static void hostapd_dump_state(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
time_t now;
|
|
||||||
struct sta_info *sta;
|
|
||||||
int i;
|
|
||||||
#ifndef CONFIG_NO_RADIUS
|
|
||||||
char *buf;
|
|
||||||
#endif /* CONFIG_NO_RADIUS */
|
|
||||||
|
|
||||||
if (!hapd->conf->dump_log_name) {
|
|
||||||
wpa_printf(MSG_DEBUG, "Dump file not defined - ignoring dump "
|
|
||||||
"request");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "Dumping hostapd state to '%s'",
|
|
||||||
hapd->conf->dump_log_name);
|
|
||||||
f = fopen(hapd->conf->dump_log_name, "w");
|
|
||||||
if (f == NULL) {
|
|
||||||
wpa_printf(MSG_WARNING, "Could not open dump file '%s' for "
|
|
||||||
"writing.", hapd->conf->dump_log_name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
time(&now);
|
|
||||||
fprintf(f, "hostapd state dump - %s", ctime(&now));
|
|
||||||
fprintf(f, "num_sta=%d num_sta_non_erp=%d "
|
|
||||||
"num_sta_no_short_slot_time=%d\n"
|
|
||||||
"num_sta_no_short_preamble=%d\n",
|
|
||||||
hapd->num_sta, hapd->iface->num_sta_non_erp,
|
|
||||||
hapd->iface->num_sta_no_short_slot_time,
|
|
||||||
hapd->iface->num_sta_no_short_preamble);
|
|
||||||
|
|
||||||
for (sta = hapd->sta_list; sta != NULL; sta = sta->next) {
|
|
||||||
fprintf(f, "\nSTA=" MACSTR "\n", MAC2STR(sta->addr));
|
|
||||||
|
|
||||||
fprintf(f,
|
|
||||||
" AID=%d flags=0x%x %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n"
|
|
||||||
" capability=0x%x listen_interval=%d\n",
|
|
||||||
sta->aid,
|
|
||||||
sta->flags,
|
|
||||||
(sta->flags & WLAN_STA_AUTH ? "[AUTH]" : ""),
|
|
||||||
(sta->flags & WLAN_STA_ASSOC ? "[ASSOC]" : ""),
|
|
||||||
(sta->flags & WLAN_STA_PS ? "[PS]" : ""),
|
|
||||||
(sta->flags & WLAN_STA_TIM ? "[TIM]" : ""),
|
|
||||||
(sta->flags & WLAN_STA_PERM ? "[PERM]" : ""),
|
|
||||||
(ap_sta_is_authorized(sta) ? "[AUTHORIZED]" : ""),
|
|
||||||
(sta->flags & WLAN_STA_PENDING_POLL ? "[PENDING_POLL" :
|
|
||||||
""),
|
|
||||||
(sta->flags & WLAN_STA_SHORT_PREAMBLE ?
|
|
||||||
"[SHORT_PREAMBLE]" : ""),
|
|
||||||
(sta->flags & WLAN_STA_PREAUTH ? "[PREAUTH]" : ""),
|
|
||||||
(sta->flags & WLAN_STA_WMM ? "[WMM]" : ""),
|
|
||||||
(sta->flags & WLAN_STA_MFP ? "[MFP]" : ""),
|
|
||||||
(sta->flags & WLAN_STA_WPS ? "[WPS]" : ""),
|
|
||||||
(sta->flags & WLAN_STA_MAYBE_WPS ? "[MAYBE_WPS]" : ""),
|
|
||||||
(sta->flags & WLAN_STA_WDS ? "[WDS]" : ""),
|
|
||||||
(sta->flags & WLAN_STA_NONERP ? "[NonERP]" : ""),
|
|
||||||
sta->capability,
|
|
||||||
sta->listen_interval);
|
|
||||||
|
|
||||||
fprintf(f, " supported_rates=");
|
|
||||||
for (i = 0; i < sta->supported_rates_len; i++)
|
|
||||||
fprintf(f, "%02x ", sta->supported_rates[i]);
|
|
||||||
fprintf(f, "\n");
|
|
||||||
|
|
||||||
fprintf(f,
|
|
||||||
" timeout_next=%s\n",
|
|
||||||
(sta->timeout_next == STA_NULLFUNC ? "NULLFUNC POLL" :
|
|
||||||
(sta->timeout_next == STA_DISASSOC ? "DISASSOC" :
|
|
||||||
"DEAUTH")));
|
|
||||||
|
|
||||||
ieee802_1x_dump_state(f, " ", sta);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef CONFIG_NO_RADIUS
|
|
||||||
buf = os_malloc(4096);
|
|
||||||
if (buf) {
|
|
||||||
int count = radius_client_get_mib(hapd->radius, buf, 4096);
|
|
||||||
if (count < 0)
|
|
||||||
count = 0;
|
|
||||||
else if (count > 4095)
|
|
||||||
count = 4095;
|
|
||||||
buf[count] = '\0';
|
|
||||||
fprintf(f, "%s", buf);
|
|
||||||
|
|
||||||
#ifdef RADIUS_SERVER
|
|
||||||
count = radius_server_get_mib(hapd->radius_srv, buf, 4096);
|
|
||||||
if (count < 0)
|
|
||||||
count = 0;
|
|
||||||
else if (count > 4095)
|
|
||||||
count = 4095;
|
|
||||||
buf[count] = '\0';
|
|
||||||
fprintf(f, "%s", buf);
|
|
||||||
#endif /* RADIUS_SERVER */
|
|
||||||
|
|
||||||
os_free(buf);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_NO_RADIUS */
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int handle_dump_state_iface(struct hostapd_iface *iface, void *ctx)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < iface->num_bss; i++)
|
|
||||||
hostapd_dump_state(iface->bss[i]);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / State dump
|
|
||||||
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DUMP_STATE_H
|
|
||||||
#define DUMP_STATE_H
|
|
||||||
|
|
||||||
int handle_dump_state_iface(struct hostapd_iface *iface, void *ctx);
|
|
||||||
|
|
||||||
#endif /* DUMP_STATE_H */
|
|
|
@ -1,139 +0,0 @@
|
||||||
/*
|
|
||||||
* EAP method registration
|
|
||||||
* Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "includes.h"
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "eap_server/eap_methods.h"
|
|
||||||
#include "eap_register.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eap_server_register_methods - Register statically linked EAP server methods
|
|
||||||
* Returns: 0 on success, -1 or -2 on failure
|
|
||||||
*
|
|
||||||
* This function is called at program initialization to register all EAP
|
|
||||||
* methods that were linked in statically.
|
|
||||||
*/
|
|
||||||
int eap_server_register_methods(void)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_IDENTITY
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_identity_register();
|
|
||||||
#endif /* EAP_SERVER_IDENTITY */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_MD5
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_md5_register();
|
|
||||||
#endif /* EAP_SERVER_MD5 */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_TLS
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_tls_register();
|
|
||||||
#endif /* EAP_SERVER_TLS */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_MSCHAPV2
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_mschapv2_register();
|
|
||||||
#endif /* EAP_SERVER_MSCHAPV2 */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_PEAP
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_peap_register();
|
|
||||||
#endif /* EAP_SERVER_PEAP */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_TLV
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_tlv_register();
|
|
||||||
#endif /* EAP_SERVER_TLV */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_GTC
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_gtc_register();
|
|
||||||
#endif /* EAP_SERVER_GTC */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_TTLS
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_ttls_register();
|
|
||||||
#endif /* EAP_SERVER_TTLS */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_SIM
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_sim_register();
|
|
||||||
#endif /* EAP_SERVER_SIM */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_AKA
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_aka_register();
|
|
||||||
#endif /* EAP_SERVER_AKA */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_AKA_PRIME
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_aka_prime_register();
|
|
||||||
#endif /* EAP_SERVER_AKA_PRIME */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_PAX
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_pax_register();
|
|
||||||
#endif /* EAP_SERVER_PAX */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_PSK
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_psk_register();
|
|
||||||
#endif /* EAP_SERVER_PSK */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_SAKE
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_sake_register();
|
|
||||||
#endif /* EAP_SERVER_SAKE */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_GPSK
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_gpsk_register();
|
|
||||||
#endif /* EAP_SERVER_GPSK */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_VENDOR_TEST
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_vendor_test_register();
|
|
||||||
#endif /* EAP_SERVER_VENDOR_TEST */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_FAST
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_fast_register();
|
|
||||||
#endif /* EAP_SERVER_FAST */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_WSC
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_wsc_register();
|
|
||||||
#endif /* EAP_SERVER_WSC */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_IKEV2
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_ikev2_register();
|
|
||||||
#endif /* EAP_SERVER_IKEV2 */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_TNC
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_tnc_register();
|
|
||||||
#endif /* EAP_SERVER_TNC */
|
|
||||||
|
|
||||||
#ifdef EAP_SERVER_PWD
|
|
||||||
if (ret == 0)
|
|
||||||
ret = eap_server_pwd_register();
|
|
||||||
#endif /* EAP_SERVER_PWD */
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
/*
|
|
||||||
* EAP method registration
|
|
||||||
* Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EAP_REGISTER_H
|
|
||||||
#define EAP_REGISTER_H
|
|
||||||
|
|
||||||
int eap_server_register_methods(void);
|
|
||||||
|
|
||||||
#endif /* EAP_REGISTER_H */
|
|
|
@ -1,77 +0,0 @@
|
||||||
Interoperability testing of hostapd's IEEE 802.1X/EAPOL authentication
|
|
||||||
|
|
||||||
Test matrix
|
|
||||||
|
|
||||||
+) tested successfully
|
|
||||||
F) failed
|
|
||||||
-) peer did not support
|
|
||||||
?) not tested
|
|
||||||
|
|
||||||
XSupplicant --------------------------------.
|
|
||||||
Intel PROSet ---------------------------. |
|
|
||||||
Windows XP -------------------------. | |
|
|
||||||
Mac OS X 10.4 ------------------. | | |
|
|
||||||
Nokia S60 ------------------. | | | |
|
|
||||||
wpa_supplicant ---------. | | | | |
|
|
||||||
| | | | | |
|
|
||||||
|
|
||||||
EAP-MD5 + - ? ? -
|
|
||||||
EAP-GTC + - ? - -
|
|
||||||
EAP-MSCHAPv2 + - ? - -
|
|
||||||
EAP-TLS + + +1 + +
|
|
||||||
EAP-PEAPv0/MSCHAPv2 + + + + + +
|
|
||||||
EAP-PEAPv0/GTC + + + - +
|
|
||||||
EAP-PEAPv0/MD5 + - + - -
|
|
||||||
EAP-PEAPv0/TLS + F - + +
|
|
||||||
EAP-PEAPv0/SIM + + - - -
|
|
||||||
EAP-PEAPv0/AKA + + - - -
|
|
||||||
EAP-PEAPv0/PSK + - - - -
|
|
||||||
EAP-PEAPv0/PAX + - - - -
|
|
||||||
EAP-PEAPv0/SAKE + - - - -
|
|
||||||
EAP-PEAPv0/GPSK + - - - -
|
|
||||||
EAP-PEAPv1/MSCHAPv2 + + + - + +
|
|
||||||
EAP-PEAPv1/GTC + + + - +
|
|
||||||
EAP-PEAPv1/MD5 + - + - -
|
|
||||||
EAP-PEAPv1/TLS + F - - +
|
|
||||||
EAP-PEAPv1/SIM + + - - -
|
|
||||||
EAP-PEAPv1/AKA + + - - -
|
|
||||||
EAP-PEAPv1/PSK + - - - -
|
|
||||||
EAP-PEAPv1/PAX + - - - -
|
|
||||||
EAP-PEAPv1/SAKE + - - - -
|
|
||||||
EAP-PEAPv1/GPSK + - - - -
|
|
||||||
EAP-TTLS/CHAP + - + - + +
|
|
||||||
EAP-TTLS/MSCHAP + - + - + +
|
|
||||||
EAP-TTLS/MSCHAPv2 + + + - + +
|
|
||||||
EAP-TTLS/PAP + - + - + +
|
|
||||||
EAP-TTLS/EAP-MD5 + - - - - +
|
|
||||||
EAP-TTLS/EAP-GTC + + - - -
|
|
||||||
EAP-TTLS/EAP-MSCHAPv2 + + - - -
|
|
||||||
EAP-TTLS/EAP-TLS + F - - -
|
|
||||||
EAP-TTLS/EAP-SIM + + - - -
|
|
||||||
EAP-TTLS/EAP-AKA + + - - -
|
|
||||||
EAP-TTLS + TNC + - - - -
|
|
||||||
EAP-SIM + + - - +
|
|
||||||
EAP-AKA + + - - -
|
|
||||||
EAP-PAX + - - - -
|
|
||||||
EAP-SAKE + - - - -
|
|
||||||
EAP-GPSK + - - - -
|
|
||||||
EAP-FAST/MSCHAPv2(prov) + - F - F
|
|
||||||
EAP-FAST/GTC(auth) + - + - +
|
|
||||||
EAP-FAST/MSCHAPv2(aprov)+ - F - F
|
|
||||||
EAP-FAST/GTC(aprov) + - F - F
|
|
||||||
EAP-FAST/MD5(aprov) + - - - -
|
|
||||||
EAP-FAST/TLS(aprov) + - - - -
|
|
||||||
EAP-FAST/SIM(aprov) + - - - -
|
|
||||||
EAP-FAST/AKA(aprov) + - - - -
|
|
||||||
EAP-FAST/MSCHAPv2(auth) + - + - +
|
|
||||||
EAP-FAST/MD5(auth) + - + - -
|
|
||||||
EAP-FAST/TLS(auth) + - - - -
|
|
||||||
EAP-FAST/SIM(auth) + - - - -
|
|
||||||
EAP-FAST/AKA(auth) + - - - -
|
|
||||||
EAP-FAST + TNC + - - - -
|
|
||||||
EAP-IKEv2 + - - - -
|
|
||||||
EAP-TNC + - - - -
|
|
||||||
|
|
||||||
1) EAP-TLS itself worked, but peer certificate validation failed at
|
|
||||||
least when using the internal TLS server (peer included incorrect
|
|
||||||
certificates in the chain?)
|
|
|
@ -1,715 +0,0 @@
|
||||||
/*
|
|
||||||
* HLR/AuC testing gateway for hostapd EAP-SIM/AKA database/authenticator
|
|
||||||
* Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*
|
|
||||||
* This is an example implementation of the EAP-SIM/AKA database/authentication
|
|
||||||
* gateway interface to HLR/AuC. It is expected to be replaced with an
|
|
||||||
* implementation of SS7 gateway to GSM/UMTS authentication center (HLR/AuC) or
|
|
||||||
* a local implementation of SIM triplet and AKA authentication data generator.
|
|
||||||
*
|
|
||||||
* hostapd will send SIM/AKA authentication queries over a UNIX domain socket
|
|
||||||
* to and external program, e.g., this hlr_auc_gw. This interface uses simple
|
|
||||||
* text-based format:
|
|
||||||
*
|
|
||||||
* EAP-SIM / GSM triplet query/response:
|
|
||||||
* SIM-REQ-AUTH <IMSI> <max_chal>
|
|
||||||
* SIM-RESP-AUTH <IMSI> Kc1:SRES1:RAND1 Kc2:SRES2:RAND2 [Kc3:SRES3:RAND3]
|
|
||||||
* SIM-RESP-AUTH <IMSI> FAILURE
|
|
||||||
*
|
|
||||||
* EAP-AKA / UMTS query/response:
|
|
||||||
* AKA-REQ-AUTH <IMSI>
|
|
||||||
* AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES>
|
|
||||||
* AKA-RESP-AUTH <IMSI> FAILURE
|
|
||||||
*
|
|
||||||
* EAP-AKA / UMTS AUTS (re-synchronization):
|
|
||||||
* AKA-AUTS <IMSI> <AUTS> <RAND>
|
|
||||||
*
|
|
||||||
* IMSI and max_chal are sent as an ASCII string,
|
|
||||||
* Kc/SRES/RAND/AUTN/IK/CK/RES/AUTS as hex strings.
|
|
||||||
*
|
|
||||||
* The example implementation here reads GSM authentication triplets from a
|
|
||||||
* text file in IMSI:Kc:SRES:RAND format, IMSI in ASCII, other fields as hex
|
|
||||||
* strings. This is used to simulate an HLR/AuC. As such, it is not very useful
|
|
||||||
* for real life authentication, but it is useful both as an example
|
|
||||||
* implementation and for EAP-SIM testing.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "includes.h"
|
|
||||||
#include <sys/un.h>
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "crypto/milenage.h"
|
|
||||||
#include "crypto/random.h"
|
|
||||||
|
|
||||||
static const char *default_socket_path = "/tmp/hlr_auc_gw.sock";
|
|
||||||
static const char *socket_path;
|
|
||||||
static int serv_sock = -1;
|
|
||||||
|
|
||||||
/* GSM triplets */
|
|
||||||
struct gsm_triplet {
|
|
||||||
struct gsm_triplet *next;
|
|
||||||
char imsi[20];
|
|
||||||
u8 kc[8];
|
|
||||||
u8 sres[4];
|
|
||||||
u8 _rand[16];
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct gsm_triplet *gsm_db = NULL, *gsm_db_pos = NULL;
|
|
||||||
|
|
||||||
/* OPc and AMF parameters for Milenage (Example algorithms for AKA). */
|
|
||||||
struct milenage_parameters {
|
|
||||||
struct milenage_parameters *next;
|
|
||||||
char imsi[20];
|
|
||||||
u8 ki[16];
|
|
||||||
u8 opc[16];
|
|
||||||
u8 amf[2];
|
|
||||||
u8 sqn[6];
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct milenage_parameters *milenage_db = NULL;
|
|
||||||
|
|
||||||
#define EAP_SIM_MAX_CHAL 3
|
|
||||||
|
|
||||||
#define EAP_AKA_RAND_LEN 16
|
|
||||||
#define EAP_AKA_AUTN_LEN 16
|
|
||||||
#define EAP_AKA_AUTS_LEN 14
|
|
||||||
#define EAP_AKA_RES_MAX_LEN 16
|
|
||||||
#define EAP_AKA_IK_LEN 16
|
|
||||||
#define EAP_AKA_CK_LEN 16
|
|
||||||
|
|
||||||
|
|
||||||
static int open_socket(const char *path)
|
|
||||||
{
|
|
||||||
struct sockaddr_un addr;
|
|
||||||
int s;
|
|
||||||
|
|
||||||
s = socket(PF_UNIX, SOCK_DGRAM, 0);
|
|
||||||
if (s < 0) {
|
|
||||||
perror("socket(PF_UNIX)");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
|
||||||
addr.sun_family = AF_UNIX;
|
|
||||||
os_strlcpy(addr.sun_path, path, sizeof(addr.sun_path));
|
|
||||||
if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
|
||||||
perror("bind(PF_UNIX)");
|
|
||||||
close(s);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int read_gsm_triplets(const char *fname)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
char buf[200], *pos, *pos2;
|
|
||||||
struct gsm_triplet *g = NULL;
|
|
||||||
int line, ret = 0;
|
|
||||||
|
|
||||||
if (fname == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
f = fopen(fname, "r");
|
|
||||||
if (f == NULL) {
|
|
||||||
printf("Could not open GSM tripler data file '%s'\n", fname);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
line = 0;
|
|
||||||
while (fgets(buf, sizeof(buf), f)) {
|
|
||||||
line++;
|
|
||||||
|
|
||||||
/* Parse IMSI:Kc:SRES:RAND */
|
|
||||||
buf[sizeof(buf) - 1] = '\0';
|
|
||||||
if (buf[0] == '#')
|
|
||||||
continue;
|
|
||||||
pos = buf;
|
|
||||||
while (*pos != '\0' && *pos != '\n')
|
|
||||||
pos++;
|
|
||||||
if (*pos == '\n')
|
|
||||||
*pos = '\0';
|
|
||||||
pos = buf;
|
|
||||||
if (*pos == '\0')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
g = os_zalloc(sizeof(*g));
|
|
||||||
if (g == NULL) {
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* IMSI */
|
|
||||||
pos2 = strchr(pos, ':');
|
|
||||||
if (pos2 == NULL) {
|
|
||||||
printf("%s:%d - Invalid IMSI (%s)\n",
|
|
||||||
fname, line, pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*pos2 = '\0';
|
|
||||||
if (strlen(pos) >= sizeof(g->imsi)) {
|
|
||||||
printf("%s:%d - Too long IMSI (%s)\n",
|
|
||||||
fname, line, pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
os_strlcpy(g->imsi, pos, sizeof(g->imsi));
|
|
||||||
pos = pos2 + 1;
|
|
||||||
|
|
||||||
/* Kc */
|
|
||||||
pos2 = strchr(pos, ':');
|
|
||||||
if (pos2 == NULL) {
|
|
||||||
printf("%s:%d - Invalid Kc (%s)\n", fname, line, pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*pos2 = '\0';
|
|
||||||
if (strlen(pos) != 16 || hexstr2bin(pos, g->kc, 8)) {
|
|
||||||
printf("%s:%d - Invalid Kc (%s)\n", fname, line, pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos = pos2 + 1;
|
|
||||||
|
|
||||||
/* SRES */
|
|
||||||
pos2 = strchr(pos, ':');
|
|
||||||
if (pos2 == NULL) {
|
|
||||||
printf("%s:%d - Invalid SRES (%s)\n", fname, line,
|
|
||||||
pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*pos2 = '\0';
|
|
||||||
if (strlen(pos) != 8 || hexstr2bin(pos, g->sres, 4)) {
|
|
||||||
printf("%s:%d - Invalid SRES (%s)\n", fname, line,
|
|
||||||
pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos = pos2 + 1;
|
|
||||||
|
|
||||||
/* RAND */
|
|
||||||
pos2 = strchr(pos, ':');
|
|
||||||
if (pos2)
|
|
||||||
*pos2 = '\0';
|
|
||||||
if (strlen(pos) != 32 || hexstr2bin(pos, g->_rand, 16)) {
|
|
||||||
printf("%s:%d - Invalid RAND (%s)\n", fname, line,
|
|
||||||
pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos = pos2 + 1;
|
|
||||||
|
|
||||||
g->next = gsm_db;
|
|
||||||
gsm_db = g;
|
|
||||||
g = NULL;
|
|
||||||
}
|
|
||||||
free(g);
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct gsm_triplet * get_gsm_triplet(const char *imsi)
|
|
||||||
{
|
|
||||||
struct gsm_triplet *g = gsm_db_pos;
|
|
||||||
|
|
||||||
while (g) {
|
|
||||||
if (strcmp(g->imsi, imsi) == 0) {
|
|
||||||
gsm_db_pos = g->next;
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
g = g->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
g = gsm_db;
|
|
||||||
while (g && g != gsm_db_pos) {
|
|
||||||
if (strcmp(g->imsi, imsi) == 0) {
|
|
||||||
gsm_db_pos = g->next;
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
g = g->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int read_milenage(const char *fname)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
char buf[200], *pos, *pos2;
|
|
||||||
struct milenage_parameters *m = NULL;
|
|
||||||
int line, ret = 0;
|
|
||||||
|
|
||||||
if (fname == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
f = fopen(fname, "r");
|
|
||||||
if (f == NULL) {
|
|
||||||
printf("Could not open Milenage data file '%s'\n", fname);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
line = 0;
|
|
||||||
while (fgets(buf, sizeof(buf), f)) {
|
|
||||||
line++;
|
|
||||||
|
|
||||||
/* Parse IMSI Ki OPc AMF SQN */
|
|
||||||
buf[sizeof(buf) - 1] = '\0';
|
|
||||||
if (buf[0] == '#')
|
|
||||||
continue;
|
|
||||||
pos = buf;
|
|
||||||
while (*pos != '\0' && *pos != '\n')
|
|
||||||
pos++;
|
|
||||||
if (*pos == '\n')
|
|
||||||
*pos = '\0';
|
|
||||||
pos = buf;
|
|
||||||
if (*pos == '\0')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
m = os_zalloc(sizeof(*m));
|
|
||||||
if (m == NULL) {
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* IMSI */
|
|
||||||
pos2 = strchr(pos, ' ');
|
|
||||||
if (pos2 == NULL) {
|
|
||||||
printf("%s:%d - Invalid IMSI (%s)\n",
|
|
||||||
fname, line, pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*pos2 = '\0';
|
|
||||||
if (strlen(pos) >= sizeof(m->imsi)) {
|
|
||||||
printf("%s:%d - Too long IMSI (%s)\n",
|
|
||||||
fname, line, pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
os_strlcpy(m->imsi, pos, sizeof(m->imsi));
|
|
||||||
pos = pos2 + 1;
|
|
||||||
|
|
||||||
/* Ki */
|
|
||||||
pos2 = strchr(pos, ' ');
|
|
||||||
if (pos2 == NULL) {
|
|
||||||
printf("%s:%d - Invalid Ki (%s)\n", fname, line, pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*pos2 = '\0';
|
|
||||||
if (strlen(pos) != 32 || hexstr2bin(pos, m->ki, 16)) {
|
|
||||||
printf("%s:%d - Invalid Ki (%s)\n", fname, line, pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos = pos2 + 1;
|
|
||||||
|
|
||||||
/* OPc */
|
|
||||||
pos2 = strchr(pos, ' ');
|
|
||||||
if (pos2 == NULL) {
|
|
||||||
printf("%s:%d - Invalid OPc (%s)\n", fname, line, pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*pos2 = '\0';
|
|
||||||
if (strlen(pos) != 32 || hexstr2bin(pos, m->opc, 16)) {
|
|
||||||
printf("%s:%d - Invalid OPc (%s)\n", fname, line, pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos = pos2 + 1;
|
|
||||||
|
|
||||||
/* AMF */
|
|
||||||
pos2 = strchr(pos, ' ');
|
|
||||||
if (pos2 == NULL) {
|
|
||||||
printf("%s:%d - Invalid AMF (%s)\n", fname, line, pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*pos2 = '\0';
|
|
||||||
if (strlen(pos) != 4 || hexstr2bin(pos, m->amf, 2)) {
|
|
||||||
printf("%s:%d - Invalid AMF (%s)\n", fname, line, pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos = pos2 + 1;
|
|
||||||
|
|
||||||
/* SQN */
|
|
||||||
pos2 = strchr(pos, ' ');
|
|
||||||
if (pos2)
|
|
||||||
*pos2 = '\0';
|
|
||||||
if (strlen(pos) != 12 || hexstr2bin(pos, m->sqn, 6)) {
|
|
||||||
printf("%s:%d - Invalid SEQ (%s)\n", fname, line, pos);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos = pos2 + 1;
|
|
||||||
|
|
||||||
m->next = milenage_db;
|
|
||||||
milenage_db = m;
|
|
||||||
m = NULL;
|
|
||||||
}
|
|
||||||
free(m);
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct milenage_parameters * get_milenage(const char *imsi)
|
|
||||||
{
|
|
||||||
struct milenage_parameters *m = milenage_db;
|
|
||||||
|
|
||||||
while (m) {
|
|
||||||
if (strcmp(m->imsi, imsi) == 0)
|
|
||||||
break;
|
|
||||||
m = m->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void sim_req_auth(int s, struct sockaddr_un *from, socklen_t fromlen,
|
|
||||||
char *imsi)
|
|
||||||
{
|
|
||||||
int count, max_chal, ret;
|
|
||||||
char *pos;
|
|
||||||
char reply[1000], *rpos, *rend;
|
|
||||||
struct milenage_parameters *m;
|
|
||||||
struct gsm_triplet *g;
|
|
||||||
|
|
||||||
reply[0] = '\0';
|
|
||||||
|
|
||||||
pos = strchr(imsi, ' ');
|
|
||||||
if (pos) {
|
|
||||||
*pos++ = '\0';
|
|
||||||
max_chal = atoi(pos);
|
|
||||||
if (max_chal < 1 || max_chal < EAP_SIM_MAX_CHAL)
|
|
||||||
max_chal = EAP_SIM_MAX_CHAL;
|
|
||||||
} else
|
|
||||||
max_chal = EAP_SIM_MAX_CHAL;
|
|
||||||
|
|
||||||
rend = &reply[sizeof(reply)];
|
|
||||||
rpos = reply;
|
|
||||||
ret = snprintf(rpos, rend - rpos, "SIM-RESP-AUTH %s", imsi);
|
|
||||||
if (ret < 0 || ret >= rend - rpos)
|
|
||||||
return;
|
|
||||||
rpos += ret;
|
|
||||||
|
|
||||||
m = get_milenage(imsi);
|
|
||||||
if (m) {
|
|
||||||
u8 _rand[16], sres[4], kc[8];
|
|
||||||
for (count = 0; count < max_chal; count++) {
|
|
||||||
if (random_get_bytes(_rand, 16) < 0)
|
|
||||||
return;
|
|
||||||
gsm_milenage(m->opc, m->ki, _rand, sres, kc);
|
|
||||||
*rpos++ = ' ';
|
|
||||||
rpos += wpa_snprintf_hex(rpos, rend - rpos, kc, 8);
|
|
||||||
*rpos++ = ':';
|
|
||||||
rpos += wpa_snprintf_hex(rpos, rend - rpos, sres, 4);
|
|
||||||
*rpos++ = ':';
|
|
||||||
rpos += wpa_snprintf_hex(rpos, rend - rpos, _rand, 16);
|
|
||||||
}
|
|
||||||
*rpos = '\0';
|
|
||||||
goto send;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
while (count < max_chal && (g = get_gsm_triplet(imsi))) {
|
|
||||||
if (strcmp(g->imsi, imsi) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (rpos < rend)
|
|
||||||
*rpos++ = ' ';
|
|
||||||
rpos += wpa_snprintf_hex(rpos, rend - rpos, g->kc, 8);
|
|
||||||
if (rpos < rend)
|
|
||||||
*rpos++ = ':';
|
|
||||||
rpos += wpa_snprintf_hex(rpos, rend - rpos, g->sres, 4);
|
|
||||||
if (rpos < rend)
|
|
||||||
*rpos++ = ':';
|
|
||||||
rpos += wpa_snprintf_hex(rpos, rend - rpos, g->_rand, 16);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count == 0) {
|
|
||||||
printf("No GSM triplets found for %s\n", imsi);
|
|
||||||
ret = snprintf(rpos, rend - rpos, " FAILURE");
|
|
||||||
if (ret < 0 || ret >= rend - rpos)
|
|
||||||
return;
|
|
||||||
rpos += ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
send:
|
|
||||||
printf("Send: %s\n", reply);
|
|
||||||
if (sendto(s, reply, rpos - reply, 0,
|
|
||||||
(struct sockaddr *) from, fromlen) < 0)
|
|
||||||
perror("send");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void aka_req_auth(int s, struct sockaddr_un *from, socklen_t fromlen,
|
|
||||||
char *imsi)
|
|
||||||
{
|
|
||||||
/* AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES> */
|
|
||||||
char reply[1000], *pos, *end;
|
|
||||||
u8 _rand[EAP_AKA_RAND_LEN];
|
|
||||||
u8 autn[EAP_AKA_AUTN_LEN];
|
|
||||||
u8 ik[EAP_AKA_IK_LEN];
|
|
||||||
u8 ck[EAP_AKA_CK_LEN];
|
|
||||||
u8 res[EAP_AKA_RES_MAX_LEN];
|
|
||||||
size_t res_len;
|
|
||||||
int ret;
|
|
||||||
struct milenage_parameters *m;
|
|
||||||
|
|
||||||
m = get_milenage(imsi);
|
|
||||||
if (m) {
|
|
||||||
if (random_get_bytes(_rand, EAP_AKA_RAND_LEN) < 0)
|
|
||||||
return;
|
|
||||||
res_len = EAP_AKA_RES_MAX_LEN;
|
|
||||||
inc_byte_array(m->sqn, 6);
|
|
||||||
printf("AKA: Milenage with SQN=%02x%02x%02x%02x%02x%02x\n",
|
|
||||||
m->sqn[0], m->sqn[1], m->sqn[2],
|
|
||||||
m->sqn[3], m->sqn[4], m->sqn[5]);
|
|
||||||
milenage_generate(m->opc, m->amf, m->ki, m->sqn, _rand,
|
|
||||||
autn, ik, ck, res, &res_len);
|
|
||||||
} else {
|
|
||||||
printf("Unknown IMSI: %s\n", imsi);
|
|
||||||
#ifdef AKA_USE_FIXED_TEST_VALUES
|
|
||||||
printf("Using fixed test values for AKA\n");
|
|
||||||
memset(_rand, '0', EAP_AKA_RAND_LEN);
|
|
||||||
memset(autn, '1', EAP_AKA_AUTN_LEN);
|
|
||||||
memset(ik, '3', EAP_AKA_IK_LEN);
|
|
||||||
memset(ck, '4', EAP_AKA_CK_LEN);
|
|
||||||
memset(res, '2', EAP_AKA_RES_MAX_LEN);
|
|
||||||
res_len = EAP_AKA_RES_MAX_LEN;
|
|
||||||
#else /* AKA_USE_FIXED_TEST_VALUES */
|
|
||||||
return;
|
|
||||||
#endif /* AKA_USE_FIXED_TEST_VALUES */
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = reply;
|
|
||||||
end = &reply[sizeof(reply)];
|
|
||||||
ret = snprintf(pos, end - pos, "AKA-RESP-AUTH %s ", imsi);
|
|
||||||
if (ret < 0 || ret >= end - pos)
|
|
||||||
return;
|
|
||||||
pos += ret;
|
|
||||||
pos += wpa_snprintf_hex(pos, end - pos, _rand, EAP_AKA_RAND_LEN);
|
|
||||||
*pos++ = ' ';
|
|
||||||
pos += wpa_snprintf_hex(pos, end - pos, autn, EAP_AKA_AUTN_LEN);
|
|
||||||
*pos++ = ' ';
|
|
||||||
pos += wpa_snprintf_hex(pos, end - pos, ik, EAP_AKA_IK_LEN);
|
|
||||||
*pos++ = ' ';
|
|
||||||
pos += wpa_snprintf_hex(pos, end - pos, ck, EAP_AKA_CK_LEN);
|
|
||||||
*pos++ = ' ';
|
|
||||||
pos += wpa_snprintf_hex(pos, end - pos, res, res_len);
|
|
||||||
|
|
||||||
printf("Send: %s\n", reply);
|
|
||||||
|
|
||||||
if (sendto(s, reply, pos - reply, 0, (struct sockaddr *) from,
|
|
||||||
fromlen) < 0)
|
|
||||||
perror("send");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void aka_auts(int s, struct sockaddr_un *from, socklen_t fromlen,
|
|
||||||
char *imsi)
|
|
||||||
{
|
|
||||||
char *auts, *__rand;
|
|
||||||
u8 _auts[EAP_AKA_AUTS_LEN], _rand[EAP_AKA_RAND_LEN], sqn[6];
|
|
||||||
struct milenage_parameters *m;
|
|
||||||
|
|
||||||
/* AKA-AUTS <IMSI> <AUTS> <RAND> */
|
|
||||||
|
|
||||||
auts = strchr(imsi, ' ');
|
|
||||||
if (auts == NULL)
|
|
||||||
return;
|
|
||||||
*auts++ = '\0';
|
|
||||||
|
|
||||||
__rand = strchr(auts, ' ');
|
|
||||||
if (__rand == NULL)
|
|
||||||
return;
|
|
||||||
*__rand++ = '\0';
|
|
||||||
|
|
||||||
printf("AKA-AUTS: IMSI=%s AUTS=%s RAND=%s\n", imsi, auts, __rand);
|
|
||||||
if (hexstr2bin(auts, _auts, EAP_AKA_AUTS_LEN) ||
|
|
||||||
hexstr2bin(__rand, _rand, EAP_AKA_RAND_LEN)) {
|
|
||||||
printf("Could not parse AUTS/RAND\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m = get_milenage(imsi);
|
|
||||||
if (m == NULL) {
|
|
||||||
printf("Unknown IMSI: %s\n", imsi);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (milenage_auts(m->opc, m->ki, _rand, _auts, sqn)) {
|
|
||||||
printf("AKA-AUTS: Incorrect MAC-S\n");
|
|
||||||
} else {
|
|
||||||
memcpy(m->sqn, sqn, 6);
|
|
||||||
printf("AKA-AUTS: Re-synchronized: "
|
|
||||||
"SQN=%02x%02x%02x%02x%02x%02x\n",
|
|
||||||
sqn[0], sqn[1], sqn[2], sqn[3], sqn[4], sqn[5]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int process(int s)
|
|
||||||
{
|
|
||||||
char buf[1000];
|
|
||||||
struct sockaddr_un from;
|
|
||||||
socklen_t fromlen;
|
|
||||||
ssize_t res;
|
|
||||||
|
|
||||||
fromlen = sizeof(from);
|
|
||||||
res = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *) &from,
|
|
||||||
&fromlen);
|
|
||||||
if (res < 0) {
|
|
||||||
perror("recvfrom");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if ((size_t) res >= sizeof(buf))
|
|
||||||
res = sizeof(buf) - 1;
|
|
||||||
buf[res] = '\0';
|
|
||||||
|
|
||||||
printf("Received: %s\n", buf);
|
|
||||||
|
|
||||||
if (strncmp(buf, "SIM-REQ-AUTH ", 13) == 0)
|
|
||||||
sim_req_auth(s, &from, fromlen, buf + 13);
|
|
||||||
else if (strncmp(buf, "AKA-REQ-AUTH ", 13) == 0)
|
|
||||||
aka_req_auth(s, &from, fromlen, buf + 13);
|
|
||||||
else if (strncmp(buf, "AKA-AUTS ", 9) == 0)
|
|
||||||
aka_auts(s, &from, fromlen, buf + 9);
|
|
||||||
else
|
|
||||||
printf("Unknown request: %s\n", buf);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void cleanup(void)
|
|
||||||
{
|
|
||||||
struct gsm_triplet *g, *gprev;
|
|
||||||
struct milenage_parameters *m, *prev;
|
|
||||||
|
|
||||||
g = gsm_db;
|
|
||||||
while (g) {
|
|
||||||
gprev = g;
|
|
||||||
g = g->next;
|
|
||||||
free(gprev);
|
|
||||||
}
|
|
||||||
|
|
||||||
m = milenage_db;
|
|
||||||
while (m) {
|
|
||||||
prev = m;
|
|
||||||
m = m->next;
|
|
||||||
free(prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
close(serv_sock);
|
|
||||||
unlink(socket_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void handle_term(int sig)
|
|
||||||
{
|
|
||||||
printf("Signal %d - terminate\n", sig);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void usage(void)
|
|
||||||
{
|
|
||||||
printf("HLR/AuC testing gateway for hostapd EAP-SIM/AKA "
|
|
||||||
"database/authenticator\n"
|
|
||||||
"Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi>\n"
|
|
||||||
"\n"
|
|
||||||
"usage:\n"
|
|
||||||
"hlr_auc_gw [-h] [-s<socket path>] [-g<triplet file>] "
|
|
||||||
"[-m<milenage file>]\n"
|
|
||||||
"\n"
|
|
||||||
"options:\n"
|
|
||||||
" -h = show this usage help\n"
|
|
||||||
" -s<socket path> = path for UNIX domain socket\n"
|
|
||||||
" (default: %s)\n"
|
|
||||||
" -g<triplet file> = path for GSM authentication triplets\n"
|
|
||||||
" -m<milenage file> = path for Milenage keys\n",
|
|
||||||
default_socket_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
char *milenage_file = NULL;
|
|
||||||
char *gsm_triplet_file = NULL;
|
|
||||||
|
|
||||||
socket_path = default_socket_path;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
c = getopt(argc, argv, "g:hm:s:");
|
|
||||||
if (c < 0)
|
|
||||||
break;
|
|
||||||
switch (c) {
|
|
||||||
case 'g':
|
|
||||||
gsm_triplet_file = optarg;
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
usage();
|
|
||||||
return 0;
|
|
||||||
case 'm':
|
|
||||||
milenage_file = optarg;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
socket_path = optarg;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gsm_triplet_file && read_gsm_triplets(gsm_triplet_file) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (milenage_file && read_milenage(milenage_file) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
serv_sock = open_socket(socket_path);
|
|
||||||
if (serv_sock < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
printf("Listening for requests on %s\n", socket_path);
|
|
||||||
|
|
||||||
atexit(cleanup);
|
|
||||||
signal(SIGTERM, handle_term);
|
|
||||||
signal(SIGINT, handle_term);
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
process(serv_sock);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Parameters for Milenage (Example algorithms for AKA).
|
|
||||||
# The example Ki, OPc, and AMF values here are from 3GPP TS 35.208 v6.0.0
|
|
||||||
# 4.3.20 Test Set 20. SQN is the last used SQN value.
|
|
||||||
# These values can be used for both UMTS (EAP-AKA) and GSM (EAP-SIM)
|
|
||||||
# authentication. In case of GSM/EAP-SIM, AMF and SQN values are not used, but
|
|
||||||
# dummy values will need to be included in this file.
|
|
||||||
|
|
||||||
# IMSI Ki OPc AMF SQN
|
|
||||||
232010000000000 90dca4eda45b53cf0f12d7c9c3bc6a89 cb9cccc4b9258e6dca4760379fb82581 61df 000000000000
|
|
||||||
|
|
||||||
# These values are from Test Set 19 which has the AMF separation bit set to 1
|
|
||||||
# and as such, is suitable for EAP-AKA' test.
|
|
||||||
555444333222111 5122250214c33e723a5dd523fc145fc0 981d464c7c52eb6e5036234984ad0bcf c3ab 16f3b3f70fc1
|
|
|
@ -1,59 +0,0 @@
|
||||||
.TH HOSTAPD 8 "April 7, 2005" hostapd hostapd
|
|
||||||
.SH NAME
|
|
||||||
hostapd \- IEEE 802.11 AP, IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.B hostapd
|
|
||||||
[\-hdBKtv] [\-P <PID file>] <configuration file(s)>
|
|
||||||
.SH DESCRIPTION
|
|
||||||
This manual page documents briefly the
|
|
||||||
.B hostapd
|
|
||||||
daemon.
|
|
||||||
.PP
|
|
||||||
.B hostapd
|
|
||||||
is a user space daemon for access point and authentication servers.
|
|
||||||
It implements IEEE 802.11 access point management, IEEE 802.1X/WPA/WPA2/EAP Authenticators and RADIUS authentication server.
|
|
||||||
The current version supports Linux (Host AP, madwifi, mac80211-based drivers) and FreeBSD (net80211).
|
|
||||||
|
|
||||||
.B hostapd
|
|
||||||
is designed to be a "daemon" program that runs in the background and acts as the backend component controlling authentication.
|
|
||||||
.B hostapd
|
|
||||||
supports separate frontend programs and an example text-based frontend,
|
|
||||||
.BR hostapd_cli ,
|
|
||||||
is included with
|
|
||||||
.BR hostapd .
|
|
||||||
.SH OPTIONS
|
|
||||||
A summary of options is included below.
|
|
||||||
For a complete description, run
|
|
||||||
.BR hostapd
|
|
||||||
from the command line.
|
|
||||||
.TP
|
|
||||||
.B \-h
|
|
||||||
Show usage.
|
|
||||||
.TP
|
|
||||||
.B \-d
|
|
||||||
Show more debug messages.
|
|
||||||
.TP
|
|
||||||
.B \-dd
|
|
||||||
Show even more debug messages.
|
|
||||||
.TP
|
|
||||||
.B \-B
|
|
||||||
Run daemon in the background.
|
|
||||||
.TP
|
|
||||||
.B \-P <PID file>
|
|
||||||
Path to PID file.
|
|
||||||
.TP
|
|
||||||
.B \-K
|
|
||||||
Include key data in debug messages.
|
|
||||||
.TP
|
|
||||||
.B \-t
|
|
||||||
Include timestamps in some debug messages.
|
|
||||||
.TP
|
|
||||||
.B \-v
|
|
||||||
Show hostapd version.
|
|
||||||
.SH SEE ALSO
|
|
||||||
.BR hostapd_cli (1).
|
|
||||||
.SH AUTHOR
|
|
||||||
hostapd was written by Jouni Malinen <j@w1.fi>.
|
|
||||||
.PP
|
|
||||||
This manual page was written by Faidon Liambotis <faidon@cube.gr>,
|
|
||||||
for the Debian project (but may be used by others).
|
|
|
@ -1,6 +0,0 @@
|
||||||
# List of MAC addresses that are allowed to authenticate (IEEE 802.11)
|
|
||||||
# with the AP. Optional VLAN ID can be assigned for clients based on the
|
|
||||||
# MAC address if dynamic VLANs (hostapd.conf dynamic_vlan option) are used.
|
|
||||||
00:11:22:33:44:55
|
|
||||||
00:66:77:88:99:aa
|
|
||||||
00:00:22:33:44:55 1
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +0,0 @@
|
||||||
# List of MAC addresses that are not allowed to authenticate (IEEE 802.11)
|
|
||||||
# with the AP.
|
|
||||||
00:20:30:40:50:60
|
|
||||||
00:ab:cd:ef:12:34
|
|
||||||
00:00:30:40:50:60
|
|
|
@ -1,91 +0,0 @@
|
||||||
# hostapd user database for integrated EAP server
|
|
||||||
|
|
||||||
# Each line must contain an identity, EAP method(s), and an optional password
|
|
||||||
# separated with whitespace (space or tab). The identity and password must be
|
|
||||||
# double quoted ("user"). Password can alternatively be stored as
|
|
||||||
# NtPasswordHash (16-byte MD4 hash of the unicode presentation of the password
|
|
||||||
# in unicode) if it is used for MSCHAP or MSCHAPv2 authentication. This means
|
|
||||||
# that the plaintext password does not need to be included in the user file.
|
|
||||||
# Password hash is stored as hash:<16-octets of hex data> without quotation
|
|
||||||
# marks.
|
|
||||||
|
|
||||||
# [2] flag in the end of the line can be used to mark users for tunneled phase
|
|
||||||
# 2 authentication (e.g., within EAP-PEAP). In these cases, an anonymous
|
|
||||||
# identity can be used in the unencrypted phase 1 and the real user identity
|
|
||||||
# is transmitted only within the encrypted tunnel in phase 2. If non-anonymous
|
|
||||||
# access is needed, two user entries is needed, one for phase 1 and another
|
|
||||||
# with the same username for phase 2.
|
|
||||||
#
|
|
||||||
# EAP-TLS, EAP-PEAP, EAP-TTLS, EAP-FAST, EAP-SIM, and EAP-AKA do not use
|
|
||||||
# password option.
|
|
||||||
# EAP-MD5, EAP-MSCHAPV2, EAP-GTC, EAP-PAX, EAP-PSK, and EAP-SAKE require a
|
|
||||||
# password.
|
|
||||||
# EAP-PEAP, EAP-TTLS, and EAP-FAST require Phase 2 configuration.
|
|
||||||
#
|
|
||||||
# * can be used as a wildcard to match any user identity. The main purposes for
|
|
||||||
# this are to set anonymous phase 1 identity for EAP-PEAP and EAP-TTLS and to
|
|
||||||
# avoid having to configure every certificate for EAP-TLS authentication. The
|
|
||||||
# first matching entry is selected, so * should be used as the last phase 1
|
|
||||||
# user entry.
|
|
||||||
#
|
|
||||||
# "prefix"* can be used to match the given prefix and anything after this. The
|
|
||||||
# main purpose for this is to be able to avoid EAP method negotiation when the
|
|
||||||
# method is using known prefix in identities (e.g., EAP-SIM and EAP-AKA). This
|
|
||||||
# is only allowed for phase 1 identities.
|
|
||||||
#
|
|
||||||
# Multiple methods can be configured to make the authenticator try them one by
|
|
||||||
# one until the peer accepts one. The method names are separated with a
|
|
||||||
# comma (,).
|
|
||||||
#
|
|
||||||
# [ver=0] and [ver=1] flags after EAP type PEAP can be used to force PEAP
|
|
||||||
# version based on the Phase 1 identity. Without this flag, the EAP
|
|
||||||
# authenticator advertises the highest supported version and select the version
|
|
||||||
# based on the first PEAP packet from the supplicant.
|
|
||||||
#
|
|
||||||
# EAP-TTLS supports both EAP and non-EAP authentication inside the tunnel.
|
|
||||||
# Tunneled EAP methods are configured with standard EAP method name and [2]
|
|
||||||
# flag. Non-EAP methods can be enabled by following method names: TTLS-PAP,
|
|
||||||
# TTLS-CHAP, TTLS-MSCHAP, TTLS-MSCHAPV2. TTLS-PAP and TTLS-CHAP require a
|
|
||||||
# plaintext password while TTLS-MSCHAP and TTLS-MSCHAPV2 can use NT password
|
|
||||||
# hash.
|
|
||||||
|
|
||||||
# Phase 1 users
|
|
||||||
"user" MD5 "password"
|
|
||||||
"test user" MD5 "secret"
|
|
||||||
"example user" TLS
|
|
||||||
"DOMAIN\user" MSCHAPV2 "password"
|
|
||||||
"gtc user" GTC "password"
|
|
||||||
"pax user" PAX "unknown"
|
|
||||||
"pax.user@example.com" PAX 0123456789abcdef0123456789abcdef
|
|
||||||
"psk user" PSK "unknown"
|
|
||||||
"psk.user@example.com" PSK 0123456789abcdef0123456789abcdef
|
|
||||||
"sake.user@example.com" SAKE 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
|
|
||||||
"ttls" TTLS
|
|
||||||
"not anonymous" PEAP
|
|
||||||
# Default to EAP-SIM and EAP-AKA based on fixed identity prefixes
|
|
||||||
"0"* AKA,TTLS,TLS,PEAP,SIM
|
|
||||||
"1"* SIM,TTLS,TLS,PEAP,AKA
|
|
||||||
"2"* AKA,TTLS,TLS,PEAP,SIM
|
|
||||||
"3"* SIM,TTLS,TLS,PEAP,AKA
|
|
||||||
"4"* AKA,TTLS,TLS,PEAP,SIM
|
|
||||||
"5"* SIM,TTLS,TLS,PEAP,AKA
|
|
||||||
|
|
||||||
# Wildcard for all other identities
|
|
||||||
* PEAP,TTLS,TLS,SIM,AKA
|
|
||||||
|
|
||||||
# Phase 2 (tunnelled within EAP-PEAP or EAP-TTLS) users
|
|
||||||
"t-md5" MD5 "password" [2]
|
|
||||||
"DOMAIN\t-mschapv2" MSCHAPV2 "password" [2]
|
|
||||||
"t-gtc" GTC "password" [2]
|
|
||||||
"not anonymous" MSCHAPV2 "password" [2]
|
|
||||||
"user" MD5,GTC,MSCHAPV2 "password" [2]
|
|
||||||
"test user" MSCHAPV2 hash:000102030405060708090a0b0c0d0e0f [2]
|
|
||||||
"ttls-user" TTLS-PAP,TTLS-CHAP,TTLS-MSCHAP,TTLS-MSCHAPV2 "password" [2]
|
|
||||||
|
|
||||||
# Default to EAP-SIM and EAP-AKA based on fixed identity prefixes in phase 2
|
|
||||||
"0"* AKA [2]
|
|
||||||
"1"* SIM [2]
|
|
||||||
"2"* AKA [2]
|
|
||||||
"3"* SIM [2]
|
|
||||||
"4"* AKA [2]
|
|
||||||
"5"* SIM [2]
|
|
|
@ -1,4 +0,0 @@
|
||||||
# RADIUS client configuration for the RADIUS server
|
|
||||||
10.1.2.3 secret passphrase
|
|
||||||
192.168.1.0/24 another very secret passphrase
|
|
||||||
0.0.0.0/0 radius
|
|
|
@ -1,9 +0,0 @@
|
||||||
# Example GSM authentication triplet file for EAP-SIM authenticator
|
|
||||||
# IMSI:Kc:SRES:RAND
|
|
||||||
# IMSI: ASCII string (numbers)
|
|
||||||
# Kc: hex, 8 octets
|
|
||||||
# SRES: hex, 4 octets
|
|
||||||
# RAND: hex, 16 octets
|
|
||||||
234567898765432:A0A1A2A3A4A5A6A7:D1D2D3D4:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
||||||
234567898765432:B0B1B2B3B4B5B6B7:E1E2E3E4:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
|
|
||||||
234567898765432:C0C1C2C3C4C5C6C7:F1F2F3F4:CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
|
|
|
@ -1,9 +0,0 @@
|
||||||
# VLAN ID to network interface mapping
|
|
||||||
1 vlan1
|
|
||||||
2 vlan2
|
|
||||||
3 vlan3
|
|
||||||
100 guest
|
|
||||||
# Optional wildcard entry matching all VLAN IDs. The first # in the interface
|
|
||||||
# name will be replaced with the VLAN ID. The network interfaces are created
|
|
||||||
# (and removed) dynamically based on the use.
|
|
||||||
* vlan#
|
|
|
@ -1,9 +0,0 @@
|
||||||
# List of WPA PSKs. Each line, except for empty lines and lines starting
|
|
||||||
# with #, must contain a MAC address and PSK separated with a space.
|
|
||||||
# Special MAC address 00:00:00:00:00:00 can be used to configure PSKs that
|
|
||||||
# anyone can use. PSK can be configured as an ASCII passphrase of 8..63
|
|
||||||
# characters or as a 256-bit hex PSK (64 hex digits).
|
|
||||||
00:00:00:00:00:00 secret passphrase
|
|
||||||
00:11:22:33:44:55 another passphrase
|
|
||||||
00:22:33:44:55:66 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
|
|
||||||
00:00:00:00:00:00 another passphrase for all STAs
|
|
|
@ -1,89 +0,0 @@
|
||||||
.TH HOSTAPD_CLI 1 "April 7, 2005" hostapd_cli "hostapd command-line interface"
|
|
||||||
.SH NAME
|
|
||||||
hostapd_cli \- hostapd command-line interface
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.B hostapd_cli
|
|
||||||
[\-p<path>] [\-i<ifname>] [\-a<path>] [\-hvB] [command..]
|
|
||||||
.SH DESCRIPTION
|
|
||||||
This manual page documents briefly the
|
|
||||||
.B hostapd_cli
|
|
||||||
utility.
|
|
||||||
.PP
|
|
||||||
.B hostapd_cli
|
|
||||||
is a command-line interface for the
|
|
||||||
.B hostapd
|
|
||||||
daemon.
|
|
||||||
|
|
||||||
.B hostapd
|
|
||||||
is a user space daemon for access point and authentication servers.
|
|
||||||
It implements IEEE 802.11 access point management, IEEE 802.1X/WPA/WPA2/EAP Authenticators and RADIUS authentication server.
|
|
||||||
For more information about
|
|
||||||
.B hostapd
|
|
||||||
refer to the
|
|
||||||
.BR hostapd (8)
|
|
||||||
man page.
|
|
||||||
.SH OPTIONS
|
|
||||||
A summary of options is included below.
|
|
||||||
For a complete description, run
|
|
||||||
.BR hostapd_cli
|
|
||||||
from the command line.
|
|
||||||
.TP
|
|
||||||
.B \-p<path>
|
|
||||||
Path to find control sockets.
|
|
||||||
|
|
||||||
Default: /var/run/hostapd
|
|
||||||
.TP
|
|
||||||
.B \-i<ifname>
|
|
||||||
Interface to listen on.
|
|
||||||
|
|
||||||
Default: first interface found in socket path.
|
|
||||||
.TP
|
|
||||||
.B \-a<path>
|
|
||||||
Run in daemon mode executing the action file based on events from hostapd.
|
|
||||||
.TP
|
|
||||||
.B \-B
|
|
||||||
Run a daemon in the background.
|
|
||||||
.TP
|
|
||||||
.B \-h
|
|
||||||
Show usage.
|
|
||||||
.TP
|
|
||||||
.B \-v
|
|
||||||
Show hostapd_cli version.
|
|
||||||
.SH COMMANDS
|
|
||||||
A summary of commands is included below.
|
|
||||||
For a complete description, run
|
|
||||||
.BR hostapd_cli
|
|
||||||
from the command line.
|
|
||||||
.TP
|
|
||||||
.B mib
|
|
||||||
Get MIB variables (dot1x, dot11, radius).
|
|
||||||
.TP
|
|
||||||
.B sta <addr>
|
|
||||||
Get MIB variables for one station.
|
|
||||||
.TP
|
|
||||||
.B all_sta
|
|
||||||
Get MIB variables for all stations.
|
|
||||||
.TP
|
|
||||||
.B help
|
|
||||||
Get usage help.
|
|
||||||
.TP
|
|
||||||
.B interface [ifname]
|
|
||||||
Show interfaces/select interface.
|
|
||||||
.TP
|
|
||||||
.B level <debug level>
|
|
||||||
Change debug level.
|
|
||||||
.TP
|
|
||||||
.B license
|
|
||||||
Show full
|
|
||||||
.B hostapd_cli
|
|
||||||
license.
|
|
||||||
.TP
|
|
||||||
.B quit
|
|
||||||
Exit hostapd_cli.
|
|
||||||
.SH SEE ALSO
|
|
||||||
.BR hostapd (8).
|
|
||||||
.SH AUTHOR
|
|
||||||
hostapd_cli was written by Jouni Malinen <j@w1.fi>.
|
|
||||||
.PP
|
|
||||||
This manual page was written by Faidon Liambotis <faidon@cube.gr>,
|
|
||||||
for the Debian project (but may be used by others).
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,9 +0,0 @@
|
||||||
Logwatch is a utility for analyzing system logs and provide a human
|
|
||||||
readable summary. This directory has a configuration file and a log
|
|
||||||
analyzer script for parsing hostapd system log entries for logwatch.
|
|
||||||
These files can be installed by copying them to following locations:
|
|
||||||
|
|
||||||
/etc/log.d/conf/services/hostapd.conf
|
|
||||||
/etc/log.d/scripts/services/hostapd
|
|
||||||
|
|
||||||
More information about logwatch is available from http://www.logwatch.org/
|
|
|
@ -1,65 +0,0 @@
|
||||||
#!/usr/bin/perl -w
|
|
||||||
#
|
|
||||||
# Logwatch script for hostapd
|
|
||||||
#
|
|
||||||
# Copyright 2005 Henrik Brix Andersen <brix@gentoo.org>
|
|
||||||
# Distributed under the terms of the GNU General Public License v2
|
|
||||||
# Alternatively, this file may be distributed under the terms of the BSD License
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
|
|
||||||
my $debug = $ENV{'LOGWATCH_DEBUG'} || 0;
|
|
||||||
my $detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0;
|
|
||||||
my $debugcounter = 1;
|
|
||||||
|
|
||||||
my %hostapd;
|
|
||||||
my @unmatched;
|
|
||||||
|
|
||||||
if ($debug >= 5) {
|
|
||||||
print STDERR "\n\nDEBUG: Inside HOSTAPD Filter\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
while (defined(my $line = <STDIN>)) {
|
|
||||||
if ($debug >= 5) {
|
|
||||||
print STDERR "DEBUG($debugcounter): $line";
|
|
||||||
$debugcounter++;
|
|
||||||
}
|
|
||||||
chomp($line);
|
|
||||||
|
|
||||||
if (my ($iface,$mac,$layer,$details) = ($line =~ /(.*?): STA (.*?) (.*?): (.*?)$/i)) {
|
|
||||||
unless ($detail == 10) {
|
|
||||||
# collapse association events
|
|
||||||
$details =~ s/^(associated) .*$/$1/i;
|
|
||||||
}
|
|
||||||
$hostapd{$iface}->{$mac}->{$layer}->{$details}++;
|
|
||||||
} else {
|
|
||||||
push @unmatched, "$line\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keys %hostapd) {
|
|
||||||
foreach my $iface (sort keys %hostapd) {
|
|
||||||
print "Interface $iface:\n";
|
|
||||||
foreach my $mac (sort keys %{$hostapd{$iface}}) {
|
|
||||||
print " Client MAC Address $mac:\n";
|
|
||||||
foreach my $layer (sort keys %{$hostapd{$iface}->{$mac}}) {
|
|
||||||
print " $layer:\n";
|
|
||||||
foreach my $details (sort keys %{$hostapd{$iface}->{$mac}->{$layer}}) {
|
|
||||||
print " $details";
|
|
||||||
my $count = $hostapd{$iface}->{$mac}->{$layer}->{$details};
|
|
||||||
if ($count > 1) {
|
|
||||||
print ": " . $count . " Times";
|
|
||||||
}
|
|
||||||
print "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($#unmatched >= 0) {
|
|
||||||
print "\n**Unmatched Entries**\n";
|
|
||||||
print @unmatched;
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(0);
|
|
|
@ -1,10 +0,0 @@
|
||||||
# Logwatch configuration for hostapd
|
|
||||||
#
|
|
||||||
# Copyright 2005 Henrik Brix Andersen <brix@gentoo.org>
|
|
||||||
# Distributed under the terms of the GNU General Public License v2
|
|
||||||
# Alternatively, this file may be distributed under the terms of the BSD License
|
|
||||||
|
|
||||||
Title = "hostapd"
|
|
||||||
LogFile = messages
|
|
||||||
*OnlyService = hostapd
|
|
||||||
*RemoveHeaders
|
|
|
@ -1,599 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / main()
|
|
||||||
* Copyright (c) 2002-2011, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "utils/includes.h"
|
|
||||||
#ifndef CONFIG_NATIVE_WINDOWS
|
|
||||||
#include <syslog.h>
|
|
||||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
|
||||||
#include "utils/eloop.h"
|
|
||||||
#include "crypto/random.h"
|
|
||||||
#include "crypto/tls.h"
|
|
||||||
#include "common/version.h"
|
|
||||||
#include "drivers/driver.h"
|
|
||||||
#include "eap_server/eap.h"
|
|
||||||
#include "eap_server/tncs.h"
|
|
||||||
#include "ap/hostapd.h"
|
|
||||||
#include "ap/ap_config.h"
|
|
||||||
#include "config_file.h"
|
|
||||||
#include "eap_register.h"
|
|
||||||
#include "dump_state.h"
|
|
||||||
#include "ctrl_iface.h"
|
|
||||||
|
|
||||||
|
|
||||||
extern int wpa_debug_level;
|
|
||||||
extern int wpa_debug_show_keys;
|
|
||||||
extern int wpa_debug_timestamp;
|
|
||||||
|
|
||||||
|
|
||||||
struct hapd_interfaces {
|
|
||||||
size_t count;
|
|
||||||
struct hostapd_iface **iface;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
|
|
||||||
int (*cb)(struct hostapd_iface *iface,
|
|
||||||
void *ctx), void *ctx)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
for (i = 0; i < interfaces->count; i++) {
|
|
||||||
ret = cb(interfaces->iface[i], ctx);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CONFIG_NO_HOSTAPD_LOGGER
|
|
||||||
static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
|
|
||||||
int level, const char *txt, size_t len)
|
|
||||||
{
|
|
||||||
struct hostapd_data *hapd = ctx;
|
|
||||||
char *format, *module_str;
|
|
||||||
int maxlen;
|
|
||||||
int conf_syslog_level, conf_stdout_level;
|
|
||||||
unsigned int conf_syslog, conf_stdout;
|
|
||||||
|
|
||||||
maxlen = len + 100;
|
|
||||||
format = os_malloc(maxlen);
|
|
||||||
if (!format)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (hapd && hapd->conf) {
|
|
||||||
conf_syslog_level = hapd->conf->logger_syslog_level;
|
|
||||||
conf_stdout_level = hapd->conf->logger_stdout_level;
|
|
||||||
conf_syslog = hapd->conf->logger_syslog;
|
|
||||||
conf_stdout = hapd->conf->logger_stdout;
|
|
||||||
} else {
|
|
||||||
conf_syslog_level = conf_stdout_level = 0;
|
|
||||||
conf_syslog = conf_stdout = (unsigned int) -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (module) {
|
|
||||||
case HOSTAPD_MODULE_IEEE80211:
|
|
||||||
module_str = "IEEE 802.11";
|
|
||||||
break;
|
|
||||||
case HOSTAPD_MODULE_IEEE8021X:
|
|
||||||
module_str = "IEEE 802.1X";
|
|
||||||
break;
|
|
||||||
case HOSTAPD_MODULE_RADIUS:
|
|
||||||
module_str = "RADIUS";
|
|
||||||
break;
|
|
||||||
case HOSTAPD_MODULE_WPA:
|
|
||||||
module_str = "WPA";
|
|
||||||
break;
|
|
||||||
case HOSTAPD_MODULE_DRIVER:
|
|
||||||
module_str = "DRIVER";
|
|
||||||
break;
|
|
||||||
case HOSTAPD_MODULE_IAPP:
|
|
||||||
module_str = "IAPP";
|
|
||||||
break;
|
|
||||||
case HOSTAPD_MODULE_MLME:
|
|
||||||
module_str = "MLME";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
module_str = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hapd && hapd->conf && addr)
|
|
||||||
os_snprintf(format, maxlen, "%s: STA " MACSTR "%s%s: %s",
|
|
||||||
hapd->conf->iface, MAC2STR(addr),
|
|
||||||
module_str ? " " : "", module_str, txt);
|
|
||||||
else if (hapd && hapd->conf)
|
|
||||||
os_snprintf(format, maxlen, "%s:%s%s %s",
|
|
||||||
hapd->conf->iface, module_str ? " " : "",
|
|
||||||
module_str, txt);
|
|
||||||
else if (addr)
|
|
||||||
os_snprintf(format, maxlen, "STA " MACSTR "%s%s: %s",
|
|
||||||
MAC2STR(addr), module_str ? " " : "",
|
|
||||||
module_str, txt);
|
|
||||||
else
|
|
||||||
os_snprintf(format, maxlen, "%s%s%s",
|
|
||||||
module_str, module_str ? ": " : "", txt);
|
|
||||||
|
|
||||||
if ((conf_stdout & module) && level >= conf_stdout_level) {
|
|
||||||
wpa_debug_print_timestamp();
|
|
||||||
printf("%s\n", format);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef CONFIG_NATIVE_WINDOWS
|
|
||||||
if ((conf_syslog & module) && level >= conf_syslog_level) {
|
|
||||||
int priority;
|
|
||||||
switch (level) {
|
|
||||||
case HOSTAPD_LEVEL_DEBUG_VERBOSE:
|
|
||||||
case HOSTAPD_LEVEL_DEBUG:
|
|
||||||
priority = LOG_DEBUG;
|
|
||||||
break;
|
|
||||||
case HOSTAPD_LEVEL_INFO:
|
|
||||||
priority = LOG_INFO;
|
|
||||||
break;
|
|
||||||
case HOSTAPD_LEVEL_NOTICE:
|
|
||||||
priority = LOG_NOTICE;
|
|
||||||
break;
|
|
||||||
case HOSTAPD_LEVEL_WARNING:
|
|
||||||
priority = LOG_WARNING;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
priority = LOG_INFO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
syslog(priority, "%s", format);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
|
||||||
|
|
||||||
os_free(format);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_NO_HOSTAPD_LOGGER */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hostapd_init - Allocate and initialize per-interface data
|
|
||||||
* @config_file: Path to the configuration file
|
|
||||||
* Returns: Pointer to the allocated interface data or %NULL on failure
|
|
||||||
*
|
|
||||||
* This function is used to allocate main data structures for per-interface
|
|
||||||
* data. The allocated data buffer will be freed by calling
|
|
||||||
* hostapd_cleanup_iface().
|
|
||||||
*/
|
|
||||||
static struct hostapd_iface * hostapd_init(const char *config_file)
|
|
||||||
{
|
|
||||||
struct hostapd_iface *hapd_iface = NULL;
|
|
||||||
struct hostapd_config *conf = NULL;
|
|
||||||
struct hostapd_data *hapd;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
hapd_iface = os_zalloc(sizeof(*hapd_iface));
|
|
||||||
if (hapd_iface == NULL)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
hapd_iface->reload_config = hostapd_reload_config;
|
|
||||||
hapd_iface->config_read_cb = hostapd_config_read;
|
|
||||||
hapd_iface->config_fname = os_strdup(config_file);
|
|
||||||
if (hapd_iface->config_fname == NULL)
|
|
||||||
goto fail;
|
|
||||||
hapd_iface->ctrl_iface_init = hostapd_ctrl_iface_init;
|
|
||||||
hapd_iface->ctrl_iface_deinit = hostapd_ctrl_iface_deinit;
|
|
||||||
hapd_iface->for_each_interface = hostapd_for_each_interface;
|
|
||||||
|
|
||||||
conf = hostapd_config_read(hapd_iface->config_fname);
|
|
||||||
if (conf == NULL)
|
|
||||||
goto fail;
|
|
||||||
hapd_iface->conf = conf;
|
|
||||||
|
|
||||||
hapd_iface->num_bss = conf->num_bss;
|
|
||||||
hapd_iface->bss = os_zalloc(conf->num_bss *
|
|
||||||
sizeof(struct hostapd_data *));
|
|
||||||
if (hapd_iface->bss == NULL)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
for (i = 0; i < conf->num_bss; i++) {
|
|
||||||
hapd = hapd_iface->bss[i] =
|
|
||||||
hostapd_alloc_bss_data(hapd_iface, conf,
|
|
||||||
&conf->bss[i]);
|
|
||||||
if (hapd == NULL)
|
|
||||||
goto fail;
|
|
||||||
hapd->msg_ctx = hapd;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hapd_iface;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
if (conf)
|
|
||||||
hostapd_config_free(conf);
|
|
||||||
if (hapd_iface) {
|
|
||||||
os_free(hapd_iface->config_fname);
|
|
||||||
os_free(hapd_iface->bss);
|
|
||||||
os_free(hapd_iface);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_driver_init(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
struct wpa_init_params params;
|
|
||||||
size_t i;
|
|
||||||
struct hostapd_data *hapd = iface->bss[0];
|
|
||||||
struct hostapd_bss_config *conf = hapd->conf;
|
|
||||||
u8 *b = conf->bssid;
|
|
||||||
struct wpa_driver_capa capa;
|
|
||||||
|
|
||||||
if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "No hostapd driver wrapper available");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the driver interface */
|
|
||||||
if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))
|
|
||||||
b = NULL;
|
|
||||||
|
|
||||||
os_memset(¶ms, 0, sizeof(params));
|
|
||||||
params.bssid = b;
|
|
||||||
params.ifname = hapd->conf->iface;
|
|
||||||
params.ssid = (const u8 *) hapd->conf->ssid.ssid;
|
|
||||||
params.ssid_len = hapd->conf->ssid.ssid_len;
|
|
||||||
params.test_socket = hapd->conf->test_socket;
|
|
||||||
params.use_pae_group_addr = hapd->conf->use_pae_group_addr;
|
|
||||||
|
|
||||||
params.num_bridge = hapd->iface->num_bss;
|
|
||||||
params.bridge = os_zalloc(hapd->iface->num_bss * sizeof(char *));
|
|
||||||
if (params.bridge == NULL)
|
|
||||||
return -1;
|
|
||||||
for (i = 0; i < hapd->iface->num_bss; i++) {
|
|
||||||
struct hostapd_data *bss = hapd->iface->bss[i];
|
|
||||||
if (bss->conf->bridge[0])
|
|
||||||
params.bridge[i] = bss->conf->bridge;
|
|
||||||
}
|
|
||||||
|
|
||||||
params.own_addr = hapd->own_addr;
|
|
||||||
|
|
||||||
hapd->drv_priv = hapd->driver->hapd_init(hapd, ¶ms);
|
|
||||||
os_free(params.bridge);
|
|
||||||
if (hapd->drv_priv == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "%s driver initialization failed.",
|
|
||||||
hapd->driver->name);
|
|
||||||
hapd->driver = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hapd->driver->get_capa &&
|
|
||||||
hapd->driver->get_capa(hapd->drv_priv, &capa) == 0)
|
|
||||||
iface->drv_flags = capa.flags;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_interface_deinit_free(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
const struct wpa_driver_ops *driver;
|
|
||||||
void *drv_priv;
|
|
||||||
if (iface == NULL)
|
|
||||||
return;
|
|
||||||
driver = iface->bss[0]->driver;
|
|
||||||
drv_priv = iface->bss[0]->drv_priv;
|
|
||||||
hostapd_interface_deinit(iface);
|
|
||||||
if (driver && driver->hapd_deinit)
|
|
||||||
driver->hapd_deinit(drv_priv);
|
|
||||||
hostapd_interface_free(iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct hostapd_iface *
|
|
||||||
hostapd_interface_init(struct hapd_interfaces *interfaces,
|
|
||||||
const char *config_fname, int debug)
|
|
||||||
{
|
|
||||||
struct hostapd_iface *iface;
|
|
||||||
int k;
|
|
||||||
|
|
||||||
wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname);
|
|
||||||
iface = hostapd_init(config_fname);
|
|
||||||
if (!iface)
|
|
||||||
return NULL;
|
|
||||||
iface->interfaces = interfaces;
|
|
||||||
|
|
||||||
for (k = 0; k < debug; k++) {
|
|
||||||
if (iface->bss[0]->conf->logger_stdout_level > 0)
|
|
||||||
iface->bss[0]->conf->logger_stdout_level--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hostapd_driver_init(iface) ||
|
|
||||||
hostapd_setup_interface(iface)) {
|
|
||||||
hostapd_interface_deinit_free(iface);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return iface;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* handle_term - SIGINT and SIGTERM handler to terminate hostapd process
|
|
||||||
*/
|
|
||||||
static void handle_term(int sig, void *signal_ctx)
|
|
||||||
{
|
|
||||||
wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig);
|
|
||||||
eloop_terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CONFIG_NATIVE_WINDOWS
|
|
||||||
|
|
||||||
static int handle_reload_iface(struct hostapd_iface *iface, void *ctx)
|
|
||||||
{
|
|
||||||
if (hostapd_reload_config(iface) < 0) {
|
|
||||||
wpa_printf(MSG_WARNING, "Failed to read new configuration "
|
|
||||||
"file - continuing with old.");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* handle_reload - SIGHUP handler to reload configuration
|
|
||||||
*/
|
|
||||||
static void handle_reload(int sig, void *signal_ctx)
|
|
||||||
{
|
|
||||||
struct hapd_interfaces *interfaces = signal_ctx;
|
|
||||||
wpa_printf(MSG_DEBUG, "Signal %d received - reloading configuration",
|
|
||||||
sig);
|
|
||||||
hostapd_for_each_interface(interfaces, handle_reload_iface, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void handle_dump_state(int sig, void *signal_ctx)
|
|
||||||
{
|
|
||||||
#ifdef HOSTAPD_DUMP_STATE
|
|
||||||
struct hapd_interfaces *interfaces = signal_ctx;
|
|
||||||
hostapd_for_each_interface(interfaces, handle_dump_state_iface, NULL);
|
|
||||||
#endif /* HOSTAPD_DUMP_STATE */
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_global_init(struct hapd_interfaces *interfaces)
|
|
||||||
{
|
|
||||||
hostapd_logger_register_cb(hostapd_logger_cb);
|
|
||||||
|
|
||||||
if (eap_server_register_methods()) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to register EAP methods");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eloop_init()) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to initialize event loop");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
random_init();
|
|
||||||
|
|
||||||
#ifndef CONFIG_NATIVE_WINDOWS
|
|
||||||
eloop_register_signal(SIGHUP, handle_reload, interfaces);
|
|
||||||
eloop_register_signal(SIGUSR1, handle_dump_state, interfaces);
|
|
||||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
|
||||||
eloop_register_signal_terminate(handle_term, interfaces);
|
|
||||||
|
|
||||||
#ifndef CONFIG_NATIVE_WINDOWS
|
|
||||||
openlog("hostapd", 0, LOG_DAEMON);
|
|
||||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_global_deinit(const char *pid_file)
|
|
||||||
{
|
|
||||||
#ifdef EAP_SERVER_TNC
|
|
||||||
tncs_global_deinit();
|
|
||||||
#endif /* EAP_SERVER_TNC */
|
|
||||||
|
|
||||||
random_deinit();
|
|
||||||
|
|
||||||
eloop_destroy();
|
|
||||||
|
|
||||||
#ifndef CONFIG_NATIVE_WINDOWS
|
|
||||||
closelog();
|
|
||||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
|
||||||
|
|
||||||
eap_server_unregister_methods();
|
|
||||||
|
|
||||||
os_daemonize_terminate(pid_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize,
|
|
||||||
const char *pid_file)
|
|
||||||
{
|
|
||||||
#ifdef EAP_SERVER_TNC
|
|
||||||
int tnc = 0;
|
|
||||||
size_t i, k;
|
|
||||||
|
|
||||||
for (i = 0; !tnc && i < ifaces->count; i++) {
|
|
||||||
for (k = 0; k < ifaces->iface[i]->num_bss; k++) {
|
|
||||||
if (ifaces->iface[i]->bss[0]->conf->tnc) {
|
|
||||||
tnc++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tnc && tncs_global_init() < 0) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to initialize TNCS");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif /* EAP_SERVER_TNC */
|
|
||||||
|
|
||||||
if (daemonize && os_daemonize(pid_file)) {
|
|
||||||
perror("daemon");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
eloop_run();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void show_version(void)
|
|
||||||
{
|
|
||||||
fprintf(stderr,
|
|
||||||
"hostapd v" VERSION_STR "\n"
|
|
||||||
"User space daemon for IEEE 802.11 AP management,\n"
|
|
||||||
"IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
|
|
||||||
"Copyright (c) 2002-2011, Jouni Malinen <j@w1.fi> "
|
|
||||||
"and contributors\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void usage(void)
|
|
||||||
{
|
|
||||||
show_version();
|
|
||||||
fprintf(stderr,
|
|
||||||
"\n"
|
|
||||||
"usage: hostapd [-hdBKtv] [-P <PID file>] "
|
|
||||||
"<configuration file(s)>\n"
|
|
||||||
"\n"
|
|
||||||
"options:\n"
|
|
||||||
" -h show this usage\n"
|
|
||||||
" -d show more debug messages (-dd for even more)\n"
|
|
||||||
" -B run daemon in the background\n"
|
|
||||||
" -P PID file\n"
|
|
||||||
" -K include key data in debug messages\n"
|
|
||||||
#ifdef CONFIG_DEBUG_FILE
|
|
||||||
" -f log output to debug file instead of stdout\n"
|
|
||||||
#endif /* CONFIG_DEBUG_FILE */
|
|
||||||
" -t include timestamps in some debug messages\n"
|
|
||||||
" -v show hostapd version\n");
|
|
||||||
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static const char * hostapd_msg_ifname_cb(void *ctx)
|
|
||||||
{
|
|
||||||
struct hostapd_data *hapd = ctx;
|
|
||||||
if (hapd && hapd->iconf && hapd->iconf->bss)
|
|
||||||
return hapd->iconf->bss->iface;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
struct hapd_interfaces interfaces;
|
|
||||||
int ret = 1;
|
|
||||||
size_t i;
|
|
||||||
int c, debug = 0, daemonize = 0;
|
|
||||||
char *pid_file = NULL;
|
|
||||||
const char *log_file = NULL;
|
|
||||||
|
|
||||||
if (os_program_init())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
c = getopt(argc, argv, "Bdf:hKP:tv");
|
|
||||||
if (c < 0)
|
|
||||||
break;
|
|
||||||
switch (c) {
|
|
||||||
case 'h':
|
|
||||||
usage();
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
debug++;
|
|
||||||
if (wpa_debug_level > 0)
|
|
||||||
wpa_debug_level--;
|
|
||||||
break;
|
|
||||||
case 'B':
|
|
||||||
daemonize++;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
log_file = optarg;
|
|
||||||
break;
|
|
||||||
case 'K':
|
|
||||||
wpa_debug_show_keys++;
|
|
||||||
break;
|
|
||||||
case 'P':
|
|
||||||
os_free(pid_file);
|
|
||||||
pid_file = os_rel2abs_path(optarg);
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
wpa_debug_timestamp++;
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
show_version();
|
|
||||||
exit(1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optind == argc)
|
|
||||||
usage();
|
|
||||||
|
|
||||||
wpa_msg_register_ifname_cb(hostapd_msg_ifname_cb);
|
|
||||||
|
|
||||||
if (log_file)
|
|
||||||
wpa_debug_open_file(log_file);
|
|
||||||
|
|
||||||
interfaces.count = argc - optind;
|
|
||||||
interfaces.iface = os_zalloc(interfaces.count *
|
|
||||||
sizeof(struct hostapd_iface *));
|
|
||||||
if (interfaces.iface == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "malloc failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hostapd_global_init(&interfaces))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* Initialize interfaces */
|
|
||||||
for (i = 0; i < interfaces.count; i++) {
|
|
||||||
interfaces.iface[i] = hostapd_interface_init(&interfaces,
|
|
||||||
argv[optind + i],
|
|
||||||
debug);
|
|
||||||
if (!interfaces.iface[i])
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hostapd_global_run(&interfaces, daemonize, pid_file))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
out:
|
|
||||||
/* Deinitialize all interfaces */
|
|
||||||
for (i = 0; i < interfaces.count; i++)
|
|
||||||
hostapd_interface_deinit_free(interfaces.iface[i]);
|
|
||||||
os_free(interfaces.iface);
|
|
||||||
|
|
||||||
hostapd_global_deinit(pid_file);
|
|
||||||
os_free(pid_file);
|
|
||||||
|
|
||||||
if (log_file)
|
|
||||||
wpa_debug_close_file();
|
|
||||||
|
|
||||||
os_program_deinit();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd - Plaintext password to NtPasswordHash
|
|
||||||
* Copyright (c) 2005, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "includes.h"
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "crypto/ms_funcs.h"
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
unsigned char password_hash[16];
|
|
||||||
size_t i;
|
|
||||||
char *password, buf[64], *pos;
|
|
||||||
|
|
||||||
if (argc > 1)
|
|
||||||
password = argv[1];
|
|
||||||
else {
|
|
||||||
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
|
||||||
printf("Failed to read password\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
buf[sizeof(buf) - 1] = '\0';
|
|
||||||
pos = buf;
|
|
||||||
while (*pos != '\0') {
|
|
||||||
if (*pos == '\r' || *pos == '\n') {
|
|
||||||
*pos = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
password = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nt_password_hash((u8 *) password, strlen(password), password_hash))
|
|
||||||
return -1;
|
|
||||||
for (i = 0; i < sizeof(password_hash); i++)
|
|
||||||
printf("%02x", password_hash[i]);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
##### hostapd configuration file ##############################################
|
|
||||||
# Empty lines and lines starting with # are ignored
|
|
||||||
|
|
||||||
# Example configuration file for wired authenticator. See hostapd.conf for
|
|
||||||
# more details.
|
|
||||||
|
|
||||||
interface=eth0
|
|
||||||
driver=wired
|
|
||||||
logger_stdout=-1
|
|
||||||
logger_stdout_level=1
|
|
||||||
debug=2
|
|
||||||
dump_file=/tmp/hostapd.dump
|
|
||||||
|
|
||||||
ieee8021x=1
|
|
||||||
eap_reauth_period=3600
|
|
||||||
|
|
||||||
use_pae_group_addr=1
|
|
||||||
|
|
||||||
|
|
||||||
##### RADIUS configuration ####################################################
|
|
||||||
# for IEEE 802.1X with external Authentication Server, IEEE 802.11
|
|
||||||
# authentication with external ACL for MAC addresses, and accounting
|
|
||||||
|
|
||||||
# The own IP address of the access point (used as NAS-IP-Address)
|
|
||||||
own_ip_addr=127.0.0.1
|
|
||||||
|
|
||||||
# Optional NAS-Identifier string for RADIUS messages. When used, this should be
|
|
||||||
# a unique to the NAS within the scope of the RADIUS server. For example, a
|
|
||||||
# fully qualified domain name can be used here.
|
|
||||||
nas_identifier=ap.example.com
|
|
||||||
|
|
||||||
# RADIUS authentication server
|
|
||||||
auth_server_addr=127.0.0.1
|
|
||||||
auth_server_port=1812
|
|
||||||
auth_server_shared_secret=radius
|
|
||||||
|
|
||||||
# RADIUS accounting server
|
|
||||||
acct_server_addr=127.0.0.1
|
|
||||||
acct_server_port=1813
|
|
||||||
acct_server_shared_secret=radius
|
|
|
@ -1,11 +0,0 @@
|
||||||
SUBDIRS=ap common crypto drivers eapol_auth eapol_supp eap_common eap_peer eap_server l2_packet p2p radius rsn_supp tls utils wps
|
|
||||||
|
|
||||||
all:
|
|
||||||
for d in $(SUBDIRS); do [ -d $$d ] && $(MAKE) -C $$d; done
|
|
||||||
|
|
||||||
clean:
|
|
||||||
for d in $(SUBDIRS); do [ -d $$d ] && $(MAKE) -C $$d clean; done
|
|
||||||
rm -f *~
|
|
||||||
|
|
||||||
install:
|
|
||||||
for d in $(SUBDIRS); do [ -d $$d ] && $(MAKE) -C $$d install; done
|
|
|
@ -1,8 +0,0 @@
|
||||||
all:
|
|
||||||
@echo Nothing to be made.
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *~ *.o *.d
|
|
||||||
|
|
||||||
install:
|
|
||||||
@echo Nothing to be made.
|
|
|
@ -1,505 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / RADIUS Accounting
|
|
||||||
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "utils/includes.h"
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
|
||||||
#include "utils/eloop.h"
|
|
||||||
#include "drivers/driver.h"
|
|
||||||
#include "radius/radius.h"
|
|
||||||
#include "radius/radius_client.h"
|
|
||||||
#include "hostapd.h"
|
|
||||||
#include "ieee802_1x.h"
|
|
||||||
#include "ap_config.h"
|
|
||||||
#include "sta_info.h"
|
|
||||||
#include "ap_drv_ops.h"
|
|
||||||
#include "accounting.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Default interval in seconds for polling TX/RX octets from the driver if
|
|
||||||
* STA is not using interim accounting. This detects wrap arounds for
|
|
||||||
* input/output octets and updates Acct-{Input,Output}-Gigawords. */
|
|
||||||
#define ACCT_DEFAULT_UPDATE_INTERVAL 300
|
|
||||||
|
|
||||||
static void accounting_sta_get_id(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta);
|
|
||||||
|
|
||||||
|
|
||||||
static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta,
|
|
||||||
int status_type)
|
|
||||||
{
|
|
||||||
struct radius_msg *msg;
|
|
||||||
char buf[128];
|
|
||||||
u8 *val;
|
|
||||||
size_t len;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
msg = radius_msg_new(RADIUS_CODE_ACCOUNTING_REQUEST,
|
|
||||||
radius_client_get_id(hapd->radius));
|
|
||||||
if (msg == NULL) {
|
|
||||||
printf("Could not create net RADIUS packet\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sta) {
|
|
||||||
radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta));
|
|
||||||
|
|
||||||
os_snprintf(buf, sizeof(buf), "%08X-%08X",
|
|
||||||
sta->acct_session_id_hi, sta->acct_session_id_lo);
|
|
||||||
if (!radius_msg_add_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID,
|
|
||||||
(u8 *) buf, os_strlen(buf))) {
|
|
||||||
printf("Could not add Acct-Session-Id\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
radius_msg_make_authenticator(msg, (u8 *) hapd, sizeof(*hapd));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_STATUS_TYPE,
|
|
||||||
status_type)) {
|
|
||||||
printf("Could not add Acct-Status-Type\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_AUTHENTIC,
|
|
||||||
hapd->conf->ieee802_1x ?
|
|
||||||
RADIUS_ACCT_AUTHENTIC_RADIUS :
|
|
||||||
RADIUS_ACCT_AUTHENTIC_LOCAL)) {
|
|
||||||
printf("Could not add Acct-Authentic\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sta) {
|
|
||||||
val = ieee802_1x_get_identity(sta->eapol_sm, &len);
|
|
||||||
if (!val) {
|
|
||||||
os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT,
|
|
||||||
MAC2STR(sta->addr));
|
|
||||||
val = (u8 *) buf;
|
|
||||||
len = os_strlen(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, val,
|
|
||||||
len)) {
|
|
||||||
printf("Could not add User-Name\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hapd->conf->own_ip_addr.af == AF_INET &&
|
|
||||||
!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
|
|
||||||
(u8 *) &hapd->conf->own_ip_addr.u.v4, 4)) {
|
|
||||||
printf("Could not add NAS-IP-Address\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_IPV6
|
|
||||||
if (hapd->conf->own_ip_addr.af == AF_INET6 &&
|
|
||||||
!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IPV6_ADDRESS,
|
|
||||||
(u8 *) &hapd->conf->own_ip_addr.u.v6, 16)) {
|
|
||||||
printf("Could not add NAS-IPv6-Address\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_IPV6 */
|
|
||||||
|
|
||||||
if (hapd->conf->nas_identifier &&
|
|
||||||
!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER,
|
|
||||||
(u8 *) hapd->conf->nas_identifier,
|
|
||||||
os_strlen(hapd->conf->nas_identifier))) {
|
|
||||||
printf("Could not add NAS-Identifier\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sta &&
|
|
||||||
!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT, sta->aid)) {
|
|
||||||
printf("Could not add NAS-Port\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":%s",
|
|
||||||
MAC2STR(hapd->own_addr), hapd->conf->ssid.ssid);
|
|
||||||
if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLED_STATION_ID,
|
|
||||||
(u8 *) buf, os_strlen(buf))) {
|
|
||||||
printf("Could not add Called-Station-Id\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sta) {
|
|
||||||
os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
|
|
||||||
MAC2STR(sta->addr));
|
|
||||||
if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
|
|
||||||
(u8 *) buf, os_strlen(buf))) {
|
|
||||||
printf("Could not add Calling-Station-Id\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!radius_msg_add_attr_int32(
|
|
||||||
msg, RADIUS_ATTR_NAS_PORT_TYPE,
|
|
||||||
RADIUS_NAS_PORT_TYPE_IEEE_802_11)) {
|
|
||||||
printf("Could not add NAS-Port-Type\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_snprintf(buf, sizeof(buf), "CONNECT %d%sMbps %s",
|
|
||||||
radius_sta_rate(hapd, sta) / 2,
|
|
||||||
(radius_sta_rate(hapd, sta) & 1) ? ".5" : "",
|
|
||||||
radius_mode_txt(hapd));
|
|
||||||
if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
|
|
||||||
(u8 *) buf, os_strlen(buf))) {
|
|
||||||
printf("Could not add Connect-Info\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; ; i++) {
|
|
||||||
val = ieee802_1x_get_radius_class(sta->eapol_sm, &len,
|
|
||||||
i);
|
|
||||||
if (val == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!radius_msg_add_attr(msg, RADIUS_ATTR_CLASS,
|
|
||||||
val, len)) {
|
|
||||||
printf("Could not add Class\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return msg;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
radius_msg_free(msg);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int accounting_sta_update_stats(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta,
|
|
||||||
struct hostap_sta_driver_data *data)
|
|
||||||
{
|
|
||||||
if (hostapd_drv_read_sta_data(hapd, data, sta->addr))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (sta->last_rx_bytes > data->rx_bytes)
|
|
||||||
sta->acct_input_gigawords++;
|
|
||||||
if (sta->last_tx_bytes > data->tx_bytes)
|
|
||||||
sta->acct_output_gigawords++;
|
|
||||||
sta->last_rx_bytes = data->rx_bytes;
|
|
||||||
sta->last_tx_bytes = data->tx_bytes;
|
|
||||||
|
|
||||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
|
|
||||||
HOSTAPD_LEVEL_DEBUG, "updated TX/RX stats: "
|
|
||||||
"Acct-Input-Octets=%lu Acct-Input-Gigawords=%u "
|
|
||||||
"Acct-Output-Octets=%lu Acct-Output-Gigawords=%u",
|
|
||||||
sta->last_rx_bytes, sta->acct_input_gigawords,
|
|
||||||
sta->last_tx_bytes, sta->acct_output_gigawords);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void accounting_interim_update(void *eloop_ctx, void *timeout_ctx)
|
|
||||||
{
|
|
||||||
struct hostapd_data *hapd = eloop_ctx;
|
|
||||||
struct sta_info *sta = timeout_ctx;
|
|
||||||
int interval;
|
|
||||||
|
|
||||||
if (sta->acct_interim_interval) {
|
|
||||||
accounting_sta_interim(hapd, sta);
|
|
||||||
interval = sta->acct_interim_interval;
|
|
||||||
} else {
|
|
||||||
struct hostap_sta_driver_data data;
|
|
||||||
accounting_sta_update_stats(hapd, sta, &data);
|
|
||||||
interval = ACCT_DEFAULT_UPDATE_INTERVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
eloop_register_timeout(interval, 0, accounting_interim_update,
|
|
||||||
hapd, sta);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* accounting_sta_start - Start STA accounting
|
|
||||||
* @hapd: hostapd BSS data
|
|
||||||
* @sta: The station
|
|
||||||
*/
|
|
||||||
void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta)
|
|
||||||
{
|
|
||||||
struct radius_msg *msg;
|
|
||||||
int interval;
|
|
||||||
|
|
||||||
if (sta->acct_session_started)
|
|
||||||
return;
|
|
||||||
|
|
||||||
accounting_sta_get_id(hapd, sta);
|
|
||||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
|
|
||||||
HOSTAPD_LEVEL_INFO,
|
|
||||||
"starting accounting session %08X-%08X",
|
|
||||||
sta->acct_session_id_hi, sta->acct_session_id_lo);
|
|
||||||
|
|
||||||
time(&sta->acct_session_start);
|
|
||||||
sta->last_rx_bytes = sta->last_tx_bytes = 0;
|
|
||||||
sta->acct_input_gigawords = sta->acct_output_gigawords = 0;
|
|
||||||
hostapd_drv_sta_clear_stats(hapd, sta->addr);
|
|
||||||
|
|
||||||
if (!hapd->conf->radius->acct_server)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (sta->acct_interim_interval)
|
|
||||||
interval = sta->acct_interim_interval;
|
|
||||||
else
|
|
||||||
interval = ACCT_DEFAULT_UPDATE_INTERVAL;
|
|
||||||
eloop_register_timeout(interval, 0, accounting_interim_update,
|
|
||||||
hapd, sta);
|
|
||||||
|
|
||||||
msg = accounting_msg(hapd, sta, RADIUS_ACCT_STATUS_TYPE_START);
|
|
||||||
if (msg)
|
|
||||||
radius_client_send(hapd->radius, msg, RADIUS_ACCT, sta->addr);
|
|
||||||
|
|
||||||
sta->acct_session_started = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void accounting_sta_report(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta, int stop)
|
|
||||||
{
|
|
||||||
struct radius_msg *msg;
|
|
||||||
int cause = sta->acct_terminate_cause;
|
|
||||||
struct hostap_sta_driver_data data;
|
|
||||||
struct os_time now;
|
|
||||||
u32 gigawords;
|
|
||||||
|
|
||||||
if (!hapd->conf->radius->acct_server)
|
|
||||||
return;
|
|
||||||
|
|
||||||
msg = accounting_msg(hapd, sta,
|
|
||||||
stop ? RADIUS_ACCT_STATUS_TYPE_STOP :
|
|
||||||
RADIUS_ACCT_STATUS_TYPE_INTERIM_UPDATE);
|
|
||||||
if (!msg) {
|
|
||||||
printf("Could not create RADIUS Accounting message\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_get_time(&now);
|
|
||||||
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_SESSION_TIME,
|
|
||||||
now.sec - sta->acct_session_start)) {
|
|
||||||
printf("Could not add Acct-Session-Time\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accounting_sta_update_stats(hapd, sta, &data) == 0) {
|
|
||||||
if (!radius_msg_add_attr_int32(msg,
|
|
||||||
RADIUS_ATTR_ACCT_INPUT_PACKETS,
|
|
||||||
data.rx_packets)) {
|
|
||||||
printf("Could not add Acct-Input-Packets\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (!radius_msg_add_attr_int32(msg,
|
|
||||||
RADIUS_ATTR_ACCT_OUTPUT_PACKETS,
|
|
||||||
data.tx_packets)) {
|
|
||||||
printf("Could not add Acct-Output-Packets\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (!radius_msg_add_attr_int32(msg,
|
|
||||||
RADIUS_ATTR_ACCT_INPUT_OCTETS,
|
|
||||||
data.rx_bytes)) {
|
|
||||||
printf("Could not add Acct-Input-Octets\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
gigawords = sta->acct_input_gigawords;
|
|
||||||
#if __WORDSIZE == 64
|
|
||||||
gigawords += data.rx_bytes >> 32;
|
|
||||||
#endif
|
|
||||||
if (gigawords &&
|
|
||||||
!radius_msg_add_attr_int32(
|
|
||||||
msg, RADIUS_ATTR_ACCT_INPUT_GIGAWORDS,
|
|
||||||
gigawords)) {
|
|
||||||
printf("Could not add Acct-Input-Gigawords\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (!radius_msg_add_attr_int32(msg,
|
|
||||||
RADIUS_ATTR_ACCT_OUTPUT_OCTETS,
|
|
||||||
data.tx_bytes)) {
|
|
||||||
printf("Could not add Acct-Output-Octets\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
gigawords = sta->acct_output_gigawords;
|
|
||||||
#if __WORDSIZE == 64
|
|
||||||
gigawords += data.tx_bytes >> 32;
|
|
||||||
#endif
|
|
||||||
if (gigawords &&
|
|
||||||
!radius_msg_add_attr_int32(
|
|
||||||
msg, RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS,
|
|
||||||
gigawords)) {
|
|
||||||
printf("Could not add Acct-Output-Gigawords\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_EVENT_TIMESTAMP,
|
|
||||||
now.sec)) {
|
|
||||||
printf("Could not add Event-Timestamp\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eloop_terminated())
|
|
||||||
cause = RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_REBOOT;
|
|
||||||
|
|
||||||
if (stop && cause &&
|
|
||||||
!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_TERMINATE_CAUSE,
|
|
||||||
cause)) {
|
|
||||||
printf("Could not add Acct-Terminate-Cause\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
radius_client_send(hapd->radius, msg,
|
|
||||||
stop ? RADIUS_ACCT : RADIUS_ACCT_INTERIM,
|
|
||||||
sta->addr);
|
|
||||||
return;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
radius_msg_free(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* accounting_sta_interim - Send a interim STA accounting report
|
|
||||||
* @hapd: hostapd BSS data
|
|
||||||
* @sta: The station
|
|
||||||
*/
|
|
||||||
void accounting_sta_interim(struct hostapd_data *hapd, struct sta_info *sta)
|
|
||||||
{
|
|
||||||
if (sta->acct_session_started)
|
|
||||||
accounting_sta_report(hapd, sta, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* accounting_sta_stop - Stop STA accounting
|
|
||||||
* @hapd: hostapd BSS data
|
|
||||||
* @sta: The station
|
|
||||||
*/
|
|
||||||
void accounting_sta_stop(struct hostapd_data *hapd, struct sta_info *sta)
|
|
||||||
{
|
|
||||||
if (sta->acct_session_started) {
|
|
||||||
accounting_sta_report(hapd, sta, 1);
|
|
||||||
eloop_cancel_timeout(accounting_interim_update, hapd, sta);
|
|
||||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
|
|
||||||
HOSTAPD_LEVEL_INFO,
|
|
||||||
"stopped accounting session %08X-%08X",
|
|
||||||
sta->acct_session_id_hi,
|
|
||||||
sta->acct_session_id_lo);
|
|
||||||
sta->acct_session_started = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void accounting_sta_get_id(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta)
|
|
||||||
{
|
|
||||||
sta->acct_session_id_lo = hapd->acct_session_id_lo++;
|
|
||||||
if (hapd->acct_session_id_lo == 0) {
|
|
||||||
hapd->acct_session_id_hi++;
|
|
||||||
}
|
|
||||||
sta->acct_session_id_hi = hapd->acct_session_id_hi;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* accounting_receive - Process the RADIUS frames from Accounting Server
|
|
||||||
* @msg: RADIUS response message
|
|
||||||
* @req: RADIUS request message
|
|
||||||
* @shared_secret: RADIUS shared secret
|
|
||||||
* @shared_secret_len: Length of shared_secret in octets
|
|
||||||
* @data: Context data (struct hostapd_data *)
|
|
||||||
* Returns: Processing status
|
|
||||||
*/
|
|
||||||
static RadiusRxResult
|
|
||||||
accounting_receive(struct radius_msg *msg, struct radius_msg *req,
|
|
||||||
const u8 *shared_secret, size_t shared_secret_len,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_RESPONSE) {
|
|
||||||
printf("Unknown RADIUS message code\n");
|
|
||||||
return RADIUS_RX_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (radius_msg_verify(msg, shared_secret, shared_secret_len, req, 0)) {
|
|
||||||
printf("Incoming RADIUS packet did not have correct "
|
|
||||||
"Authenticator - dropped\n");
|
|
||||||
return RADIUS_RX_INVALID_AUTHENTICATOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RADIUS_RX_PROCESSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void accounting_report_state(struct hostapd_data *hapd, int on)
|
|
||||||
{
|
|
||||||
struct radius_msg *msg;
|
|
||||||
|
|
||||||
if (!hapd->conf->radius->acct_server || hapd->radius == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Inform RADIUS server that accounting will start/stop so that the
|
|
||||||
* server can close old accounting sessions. */
|
|
||||||
msg = accounting_msg(hapd, NULL,
|
|
||||||
on ? RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_ON :
|
|
||||||
RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_OFF);
|
|
||||||
if (!msg)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_TERMINATE_CAUSE,
|
|
||||||
RADIUS_ACCT_TERMINATE_CAUSE_NAS_REBOOT))
|
|
||||||
{
|
|
||||||
printf("Could not add Acct-Terminate-Cause\n");
|
|
||||||
radius_msg_free(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
radius_client_send(hapd->radius, msg, RADIUS_ACCT, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* accounting_init: Initialize accounting
|
|
||||||
* @hapd: hostapd BSS data
|
|
||||||
* Returns: 0 on success, -1 on failure
|
|
||||||
*/
|
|
||||||
int accounting_init(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
struct os_time now;
|
|
||||||
|
|
||||||
/* Acct-Session-Id should be unique over reboots. If reliable clock is
|
|
||||||
* not available, this could be replaced with reboot counter, etc. */
|
|
||||||
os_get_time(&now);
|
|
||||||
hapd->acct_session_id_hi = now.sec;
|
|
||||||
|
|
||||||
if (radius_client_register(hapd->radius, RADIUS_ACCT,
|
|
||||||
accounting_receive, hapd))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
accounting_report_state(hapd, 1);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* accounting_deinit: Deinitilize accounting
|
|
||||||
* @hapd: hostapd BSS data
|
|
||||||
*/
|
|
||||||
void accounting_deinit(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
accounting_report_state(hapd, 0);
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / RADIUS Accounting
|
|
||||||
* Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ACCOUNTING_H
|
|
||||||
#define ACCOUNTING_H
|
|
||||||
|
|
||||||
void accounting_sta_interim(struct hostapd_data *hapd, struct sta_info *sta);
|
|
||||||
#ifdef CONFIG_NO_ACCOUNTING
|
|
||||||
static inline void accounting_sta_start(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void accounting_sta_stop(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int accounting_init(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void accounting_deinit(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#else /* CONFIG_NO_ACCOUNTING */
|
|
||||||
void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta);
|
|
||||||
void accounting_sta_stop(struct hostapd_data *hapd, struct sta_info *sta);
|
|
||||||
int accounting_init(struct hostapd_data *hapd);
|
|
||||||
void accounting_deinit(struct hostapd_data *hapd);
|
|
||||||
#endif /* CONFIG_NO_ACCOUNTING */
|
|
||||||
|
|
||||||
#endif /* ACCOUNTING_H */
|
|
|
@ -1,627 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / Configuration helper functions
|
|
||||||
* Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "utils/includes.h"
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
|
||||||
#include "crypto/sha1.h"
|
|
||||||
#include "radius/radius_client.h"
|
|
||||||
#include "common/ieee802_11_defs.h"
|
|
||||||
#include "common/eapol_common.h"
|
|
||||||
#include "eap_common/eap_wsc_common.h"
|
|
||||||
#include "eap_server/eap.h"
|
|
||||||
#include "wpa_auth.h"
|
|
||||||
#include "sta_info.h"
|
|
||||||
#include "ap_config.h"
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_config_free_vlan(struct hostapd_bss_config *bss)
|
|
||||||
{
|
|
||||||
struct hostapd_vlan *vlan, *prev;
|
|
||||||
|
|
||||||
vlan = bss->vlan;
|
|
||||||
prev = NULL;
|
|
||||||
while (vlan) {
|
|
||||||
prev = vlan;
|
|
||||||
vlan = vlan->next;
|
|
||||||
os_free(prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
bss->vlan = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
|
|
||||||
{
|
|
||||||
bss->logger_syslog_level = HOSTAPD_LEVEL_INFO;
|
|
||||||
bss->logger_stdout_level = HOSTAPD_LEVEL_INFO;
|
|
||||||
bss->logger_syslog = (unsigned int) -1;
|
|
||||||
bss->logger_stdout = (unsigned int) -1;
|
|
||||||
|
|
||||||
bss->auth_algs = WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED;
|
|
||||||
|
|
||||||
bss->wep_rekeying_period = 300;
|
|
||||||
/* use key0 in individual key and key1 in broadcast key */
|
|
||||||
bss->broadcast_key_idx_min = 1;
|
|
||||||
bss->broadcast_key_idx_max = 2;
|
|
||||||
bss->eap_reauth_period = 3600;
|
|
||||||
|
|
||||||
bss->wpa_group_rekey = 600;
|
|
||||||
bss->wpa_gmk_rekey = 86400;
|
|
||||||
bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
|
|
||||||
bss->wpa_pairwise = WPA_CIPHER_TKIP;
|
|
||||||
bss->wpa_group = WPA_CIPHER_TKIP;
|
|
||||||
bss->rsn_pairwise = 0;
|
|
||||||
|
|
||||||
bss->max_num_sta = MAX_STA_COUNT;
|
|
||||||
|
|
||||||
bss->dtim_period = 2;
|
|
||||||
|
|
||||||
bss->radius_server_auth_port = 1812;
|
|
||||||
bss->ap_max_inactivity = AP_MAX_INACTIVITY;
|
|
||||||
bss->eapol_version = EAPOL_VERSION;
|
|
||||||
|
|
||||||
bss->max_listen_interval = 65535;
|
|
||||||
|
|
||||||
bss->pwd_group = 19; /* ECC: GF(p=256) */
|
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211W
|
|
||||||
bss->assoc_sa_query_max_timeout = 1000;
|
|
||||||
bss->assoc_sa_query_retry_timeout = 201;
|
|
||||||
#endif /* CONFIG_IEEE80211W */
|
|
||||||
#ifdef EAP_SERVER_FAST
|
|
||||||
/* both anonymous and authenticated provisioning */
|
|
||||||
bss->eap_fast_prov = 3;
|
|
||||||
bss->pac_key_lifetime = 7 * 24 * 60 * 60;
|
|
||||||
bss->pac_key_refresh_time = 1 * 24 * 60 * 60;
|
|
||||||
#endif /* EAP_SERVER_FAST */
|
|
||||||
|
|
||||||
/* Set to -1 as defaults depends on HT in setup */
|
|
||||||
bss->wmm_enabled = -1;
|
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211R
|
|
||||||
bss->ft_over_ds = 1;
|
|
||||||
#endif /* CONFIG_IEEE80211R */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct hostapd_config * hostapd_config_defaults(void)
|
|
||||||
{
|
|
||||||
#define ecw2cw(ecw) ((1 << (ecw)) - 1)
|
|
||||||
|
|
||||||
struct hostapd_config *conf;
|
|
||||||
struct hostapd_bss_config *bss;
|
|
||||||
const int aCWmin = 4, aCWmax = 10;
|
|
||||||
const struct hostapd_wmm_ac_params ac_bk =
|
|
||||||
{ aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
|
|
||||||
const struct hostapd_wmm_ac_params ac_be =
|
|
||||||
{ aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
|
|
||||||
const struct hostapd_wmm_ac_params ac_vi = /* video traffic */
|
|
||||||
{ aCWmin - 1, aCWmin, 2, 3000 / 32, 1 };
|
|
||||||
const struct hostapd_wmm_ac_params ac_vo = /* voice traffic */
|
|
||||||
{ aCWmin - 2, aCWmin - 1, 2, 1500 / 32, 1 };
|
|
||||||
const struct hostapd_tx_queue_params txq_bk =
|
|
||||||
{ 7, ecw2cw(aCWmin), ecw2cw(aCWmax), 0 };
|
|
||||||
const struct hostapd_tx_queue_params txq_be =
|
|
||||||
{ 3, ecw2cw(aCWmin), 4 * (ecw2cw(aCWmin) + 1) - 1, 0};
|
|
||||||
const struct hostapd_tx_queue_params txq_vi =
|
|
||||||
{ 1, (ecw2cw(aCWmin) + 1) / 2 - 1, ecw2cw(aCWmin), 30};
|
|
||||||
const struct hostapd_tx_queue_params txq_vo =
|
|
||||||
{ 1, (ecw2cw(aCWmin) + 1) / 4 - 1,
|
|
||||||
(ecw2cw(aCWmin) + 1) / 2 - 1, 15};
|
|
||||||
|
|
||||||
#undef ecw2cw
|
|
||||||
|
|
||||||
conf = os_zalloc(sizeof(*conf));
|
|
||||||
bss = os_zalloc(sizeof(*bss));
|
|
||||||
if (conf == NULL || bss == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to allocate memory for "
|
|
||||||
"configuration data.");
|
|
||||||
os_free(conf);
|
|
||||||
os_free(bss);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bss->radius = os_zalloc(sizeof(*bss->radius));
|
|
||||||
if (bss->radius == NULL) {
|
|
||||||
os_free(conf);
|
|
||||||
os_free(bss);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hostapd_config_defaults_bss(bss);
|
|
||||||
|
|
||||||
conf->num_bss = 1;
|
|
||||||
conf->bss = bss;
|
|
||||||
|
|
||||||
conf->beacon_int = 100;
|
|
||||||
conf->rts_threshold = -1; /* use driver default: 2347 */
|
|
||||||
conf->fragm_threshold = -1; /* user driver default: 2346 */
|
|
||||||
conf->send_probe_response = 1;
|
|
||||||
|
|
||||||
conf->wmm_ac_params[0] = ac_be;
|
|
||||||
conf->wmm_ac_params[1] = ac_bk;
|
|
||||||
conf->wmm_ac_params[2] = ac_vi;
|
|
||||||
conf->wmm_ac_params[3] = ac_vo;
|
|
||||||
|
|
||||||
conf->tx_queue[0] = txq_vo;
|
|
||||||
conf->tx_queue[1] = txq_vi;
|
|
||||||
conf->tx_queue[2] = txq_be;
|
|
||||||
conf->tx_queue[3] = txq_bk;
|
|
||||||
|
|
||||||
conf->ht_capab = HT_CAP_INFO_SMPS_DISABLED;
|
|
||||||
|
|
||||||
return conf;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_mac_comp(const void *a, const void *b)
|
|
||||||
{
|
|
||||||
return os_memcmp(a, b, sizeof(macaddr));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_mac_comp_empty(const void *a)
|
|
||||||
{
|
|
||||||
macaddr empty = { 0 };
|
|
||||||
return os_memcmp(a, empty, sizeof(macaddr));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_config_read_wpa_psk(const char *fname,
|
|
||||||
struct hostapd_ssid *ssid)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
char buf[128], *pos;
|
|
||||||
int line = 0, ret = 0, len, ok;
|
|
||||||
u8 addr[ETH_ALEN];
|
|
||||||
struct hostapd_wpa_psk *psk;
|
|
||||||
|
|
||||||
if (!fname)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
f = fopen(fname, "r");
|
|
||||||
if (!f) {
|
|
||||||
wpa_printf(MSG_ERROR, "WPA PSK file '%s' not found.", fname);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (fgets(buf, sizeof(buf), f)) {
|
|
||||||
line++;
|
|
||||||
|
|
||||||
if (buf[0] == '#')
|
|
||||||
continue;
|
|
||||||
pos = buf;
|
|
||||||
while (*pos != '\0') {
|
|
||||||
if (*pos == '\n') {
|
|
||||||
*pos = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
if (buf[0] == '\0')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (hwaddr_aton(buf, addr)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Invalid MAC address '%s' on "
|
|
||||||
"line %d in '%s'", buf, line, fname);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
psk = os_zalloc(sizeof(*psk));
|
|
||||||
if (psk == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "WPA PSK allocation failed");
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (is_zero_ether_addr(addr))
|
|
||||||
psk->group = 1;
|
|
||||||
else
|
|
||||||
os_memcpy(psk->addr, addr, ETH_ALEN);
|
|
||||||
|
|
||||||
pos = buf + 17;
|
|
||||||
if (*pos == '\0') {
|
|
||||||
wpa_printf(MSG_ERROR, "No PSK on line %d in '%s'",
|
|
||||||
line, fname);
|
|
||||||
os_free(psk);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos++;
|
|
||||||
|
|
||||||
ok = 0;
|
|
||||||
len = os_strlen(pos);
|
|
||||||
if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0)
|
|
||||||
ok = 1;
|
|
||||||
else if (len >= 8 && len < 64) {
|
|
||||||
pbkdf2_sha1(pos, ssid->ssid, ssid->ssid_len,
|
|
||||||
4096, psk->psk, PMK_LEN);
|
|
||||||
ok = 1;
|
|
||||||
}
|
|
||||||
if (!ok) {
|
|
||||||
wpa_printf(MSG_ERROR, "Invalid PSK '%s' on line %d in "
|
|
||||||
"'%s'", pos, line, fname);
|
|
||||||
os_free(psk);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
psk->next = ssid->wpa_psk;
|
|
||||||
ssid->wpa_psk = psk;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_derive_psk(struct hostapd_ssid *ssid)
|
|
||||||
{
|
|
||||||
ssid->wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
|
|
||||||
if (ssid->wpa_psk == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "Unable to alloc space for PSK");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
wpa_hexdump_ascii(MSG_DEBUG, "SSID",
|
|
||||||
(u8 *) ssid->ssid, ssid->ssid_len);
|
|
||||||
wpa_hexdump_ascii_key(MSG_DEBUG, "PSK (ASCII passphrase)",
|
|
||||||
(u8 *) ssid->wpa_passphrase,
|
|
||||||
os_strlen(ssid->wpa_passphrase));
|
|
||||||
pbkdf2_sha1(ssid->wpa_passphrase,
|
|
||||||
ssid->ssid, ssid->ssid_len,
|
|
||||||
4096, ssid->wpa_psk->psk, PMK_LEN);
|
|
||||||
wpa_hexdump_key(MSG_DEBUG, "PSK (from passphrase)",
|
|
||||||
ssid->wpa_psk->psk, PMK_LEN);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf)
|
|
||||||
{
|
|
||||||
struct hostapd_ssid *ssid = &conf->ssid;
|
|
||||||
|
|
||||||
if (ssid->wpa_passphrase != NULL) {
|
|
||||||
if (ssid->wpa_psk != NULL) {
|
|
||||||
wpa_printf(MSG_DEBUG, "Using pre-configured WPA PSK "
|
|
||||||
"instead of passphrase");
|
|
||||||
} else {
|
|
||||||
wpa_printf(MSG_DEBUG, "Deriving WPA PSK based on "
|
|
||||||
"passphrase");
|
|
||||||
if (hostapd_derive_psk(ssid) < 0)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ssid->wpa_psk->group = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ssid->wpa_psk_file) {
|
|
||||||
if (hostapd_config_read_wpa_psk(ssid->wpa_psk_file,
|
|
||||||
&conf->ssid))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_wep_key_cmp(struct hostapd_wep_keys *a, struct hostapd_wep_keys *b)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (a->idx != b->idx || a->default_len != b->default_len)
|
|
||||||
return 1;
|
|
||||||
for (i = 0; i < NUM_WEP_KEYS; i++)
|
|
||||||
if (a->len[i] != b->len[i] ||
|
|
||||||
os_memcmp(a->key[i], b->key[i], a->len[i]) != 0)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_config_free_radius(struct hostapd_radius_server *servers,
|
|
||||||
int num_servers)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < num_servers; i++) {
|
|
||||||
os_free(servers[i].shared_secret);
|
|
||||||
}
|
|
||||||
os_free(servers);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
|
|
||||||
{
|
|
||||||
os_free(user->identity);
|
|
||||||
os_free(user->password);
|
|
||||||
os_free(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < NUM_WEP_KEYS; i++) {
|
|
||||||
os_free(keys->key[i]);
|
|
||||||
keys->key[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
|
|
||||||
{
|
|
||||||
struct hostapd_wpa_psk *psk, *prev;
|
|
||||||
struct hostapd_eap_user *user, *prev_user;
|
|
||||||
|
|
||||||
if (conf == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
psk = conf->ssid.wpa_psk;
|
|
||||||
while (psk) {
|
|
||||||
prev = psk;
|
|
||||||
psk = psk->next;
|
|
||||||
os_free(prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
os_free(conf->ssid.wpa_passphrase);
|
|
||||||
os_free(conf->ssid.wpa_psk_file);
|
|
||||||
hostapd_config_free_wep(&conf->ssid.wep);
|
|
||||||
#ifdef CONFIG_FULL_DYNAMIC_VLAN
|
|
||||||
os_free(conf->ssid.vlan_tagged_interface);
|
|
||||||
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
|
|
||||||
|
|
||||||
user = conf->eap_user;
|
|
||||||
while (user) {
|
|
||||||
prev_user = user;
|
|
||||||
user = user->next;
|
|
||||||
hostapd_config_free_eap_user(prev_user);
|
|
||||||
}
|
|
||||||
|
|
||||||
os_free(conf->dump_log_name);
|
|
||||||
os_free(conf->eap_req_id_text);
|
|
||||||
os_free(conf->accept_mac);
|
|
||||||
os_free(conf->deny_mac);
|
|
||||||
os_free(conf->nas_identifier);
|
|
||||||
hostapd_config_free_radius(conf->radius->auth_servers,
|
|
||||||
conf->radius->num_auth_servers);
|
|
||||||
hostapd_config_free_radius(conf->radius->acct_servers,
|
|
||||||
conf->radius->num_acct_servers);
|
|
||||||
os_free(conf->rsn_preauth_interfaces);
|
|
||||||
os_free(conf->ctrl_interface);
|
|
||||||
os_free(conf->ca_cert);
|
|
||||||
os_free(conf->server_cert);
|
|
||||||
os_free(conf->private_key);
|
|
||||||
os_free(conf->private_key_passwd);
|
|
||||||
os_free(conf->dh_file);
|
|
||||||
os_free(conf->pac_opaque_encr_key);
|
|
||||||
os_free(conf->eap_fast_a_id);
|
|
||||||
os_free(conf->eap_fast_a_id_info);
|
|
||||||
os_free(conf->eap_sim_db);
|
|
||||||
os_free(conf->radius_server_clients);
|
|
||||||
os_free(conf->test_socket);
|
|
||||||
os_free(conf->radius);
|
|
||||||
hostapd_config_free_vlan(conf);
|
|
||||||
if (conf->ssid.dyn_vlan_keys) {
|
|
||||||
struct hostapd_ssid *ssid = &conf->ssid;
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i <= ssid->max_dyn_vlan_keys; i++) {
|
|
||||||
if (ssid->dyn_vlan_keys[i] == NULL)
|
|
||||||
continue;
|
|
||||||
hostapd_config_free_wep(ssid->dyn_vlan_keys[i]);
|
|
||||||
os_free(ssid->dyn_vlan_keys[i]);
|
|
||||||
}
|
|
||||||
os_free(ssid->dyn_vlan_keys);
|
|
||||||
ssid->dyn_vlan_keys = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211R
|
|
||||||
{
|
|
||||||
struct ft_remote_r0kh *r0kh, *r0kh_prev;
|
|
||||||
struct ft_remote_r1kh *r1kh, *r1kh_prev;
|
|
||||||
|
|
||||||
r0kh = conf->r0kh_list;
|
|
||||||
conf->r0kh_list = NULL;
|
|
||||||
while (r0kh) {
|
|
||||||
r0kh_prev = r0kh;
|
|
||||||
r0kh = r0kh->next;
|
|
||||||
os_free(r0kh_prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
r1kh = conf->r1kh_list;
|
|
||||||
conf->r1kh_list = NULL;
|
|
||||||
while (r1kh) {
|
|
||||||
r1kh_prev = r1kh;
|
|
||||||
r1kh = r1kh->next;
|
|
||||||
os_free(r1kh_prev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_IEEE80211R */
|
|
||||||
|
|
||||||
#ifdef CONFIG_WPS
|
|
||||||
os_free(conf->wps_pin_requests);
|
|
||||||
os_free(conf->device_name);
|
|
||||||
os_free(conf->manufacturer);
|
|
||||||
os_free(conf->model_name);
|
|
||||||
os_free(conf->model_number);
|
|
||||||
os_free(conf->serial_number);
|
|
||||||
os_free(conf->config_methods);
|
|
||||||
os_free(conf->ap_pin);
|
|
||||||
os_free(conf->extra_cred);
|
|
||||||
os_free(conf->ap_settings);
|
|
||||||
os_free(conf->upnp_iface);
|
|
||||||
os_free(conf->friendly_name);
|
|
||||||
os_free(conf->manufacturer_url);
|
|
||||||
os_free(conf->model_description);
|
|
||||||
os_free(conf->model_url);
|
|
||||||
os_free(conf->upc);
|
|
||||||
#endif /* CONFIG_WPS */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hostapd_config_free - Free hostapd configuration
|
|
||||||
* @conf: Configuration data from hostapd_config_read().
|
|
||||||
*/
|
|
||||||
void hostapd_config_free(struct hostapd_config *conf)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (conf == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i < conf->num_bss; i++)
|
|
||||||
hostapd_config_free_bss(&conf->bss[i]);
|
|
||||||
os_free(conf->bss);
|
|
||||||
os_free(conf->supported_rates);
|
|
||||||
os_free(conf->basic_rates);
|
|
||||||
|
|
||||||
os_free(conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hostapd_maclist_found - Find a MAC address from a list
|
|
||||||
* @list: MAC address list
|
|
||||||
* @num_entries: Number of addresses in the list
|
|
||||||
* @addr: Address to search for
|
|
||||||
* @vlan_id: Buffer for returning VLAN ID or %NULL if not needed
|
|
||||||
* Returns: 1 if address is in the list or 0 if not.
|
|
||||||
*
|
|
||||||
* Perform a binary search for given MAC address from a pre-sorted list.
|
|
||||||
*/
|
|
||||||
int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries,
|
|
||||||
const u8 *addr, int *vlan_id)
|
|
||||||
{
|
|
||||||
int start, end, middle, res;
|
|
||||||
|
|
||||||
start = 0;
|
|
||||||
end = num_entries - 1;
|
|
||||||
|
|
||||||
while (start <= end) {
|
|
||||||
middle = (start + end) / 2;
|
|
||||||
res = os_memcmp(list[middle].addr, addr, ETH_ALEN);
|
|
||||||
if (res == 0) {
|
|
||||||
if (vlan_id)
|
|
||||||
*vlan_id = list[middle].vlan_id;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (res < 0)
|
|
||||||
start = middle + 1;
|
|
||||||
else
|
|
||||||
end = middle - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_rate_found(int *list, int rate)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (list == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = 0; list[i] >= 0; i++)
|
|
||||||
if (list[i] == rate)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan, int vlan_id)
|
|
||||||
{
|
|
||||||
struct hostapd_vlan *v = vlan;
|
|
||||||
while (v) {
|
|
||||||
if (v->vlan_id == vlan_id || v->vlan_id == VLAN_ID_WILDCARD)
|
|
||||||
return v->ifname;
|
|
||||||
v = v->next;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
|
|
||||||
const u8 *addr, const u8 *prev_psk)
|
|
||||||
{
|
|
||||||
struct hostapd_wpa_psk *psk;
|
|
||||||
int next_ok = prev_psk == NULL;
|
|
||||||
|
|
||||||
for (psk = conf->ssid.wpa_psk; psk != NULL; psk = psk->next) {
|
|
||||||
if (next_ok &&
|
|
||||||
(psk->group || os_memcmp(psk->addr, addr, ETH_ALEN) == 0))
|
|
||||||
return psk->psk;
|
|
||||||
|
|
||||||
if (psk->psk == prev_psk)
|
|
||||||
next_ok = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const struct hostapd_eap_user *
|
|
||||||
hostapd_get_eap_user(const struct hostapd_bss_config *conf, const u8 *identity,
|
|
||||||
size_t identity_len, int phase2)
|
|
||||||
{
|
|
||||||
struct hostapd_eap_user *user = conf->eap_user;
|
|
||||||
|
|
||||||
#ifdef CONFIG_WPS
|
|
||||||
if (conf->wps_state && identity_len == WSC_ID_ENROLLEE_LEN &&
|
|
||||||
os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) {
|
|
||||||
static struct hostapd_eap_user wsc_enrollee;
|
|
||||||
os_memset(&wsc_enrollee, 0, sizeof(wsc_enrollee));
|
|
||||||
wsc_enrollee.methods[0].method = eap_server_get_type(
|
|
||||||
"WSC", &wsc_enrollee.methods[0].vendor);
|
|
||||||
return &wsc_enrollee;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conf->wps_state && identity_len == WSC_ID_REGISTRAR_LEN &&
|
|
||||||
os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) {
|
|
||||||
static struct hostapd_eap_user wsc_registrar;
|
|
||||||
os_memset(&wsc_registrar, 0, sizeof(wsc_registrar));
|
|
||||||
wsc_registrar.methods[0].method = eap_server_get_type(
|
|
||||||
"WSC", &wsc_registrar.methods[0].vendor);
|
|
||||||
wsc_registrar.password = (u8 *) conf->ap_pin;
|
|
||||||
wsc_registrar.password_len = conf->ap_pin ?
|
|
||||||
os_strlen(conf->ap_pin) : 0;
|
|
||||||
return &wsc_registrar;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_WPS */
|
|
||||||
|
|
||||||
while (user) {
|
|
||||||
if (!phase2 && user->identity == NULL) {
|
|
||||||
/* Wildcard match */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user->phase2 == !!phase2 && user->wildcard_prefix &&
|
|
||||||
identity_len >= user->identity_len &&
|
|
||||||
os_memcmp(user->identity, identity, user->identity_len) ==
|
|
||||||
0) {
|
|
||||||
/* Wildcard prefix match */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user->phase2 == !!phase2 &&
|
|
||||||
user->identity_len == identity_len &&
|
|
||||||
os_memcmp(user->identity, identity, identity_len) == 0)
|
|
||||||
break;
|
|
||||||
user = user->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return user;
|
|
||||||
}
|
|
|
@ -1,417 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / Configuration definitions and helpers functions
|
|
||||||
* Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HOSTAPD_CONFIG_H
|
|
||||||
#define HOSTAPD_CONFIG_H
|
|
||||||
|
|
||||||
#include "common/defs.h"
|
|
||||||
#include "ip_addr.h"
|
|
||||||
#include "common/wpa_common.h"
|
|
||||||
#include "wps/wps.h"
|
|
||||||
|
|
||||||
#define MAX_STA_COUNT 2007
|
|
||||||
#define MAX_VLAN_ID 4094
|
|
||||||
|
|
||||||
typedef u8 macaddr[ETH_ALEN];
|
|
||||||
|
|
||||||
struct mac_acl_entry {
|
|
||||||
macaddr addr;
|
|
||||||
int vlan_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hostapd_radius_servers;
|
|
||||||
struct ft_remote_r0kh;
|
|
||||||
struct ft_remote_r1kh;
|
|
||||||
|
|
||||||
#define HOSTAPD_MAX_SSID_LEN 32
|
|
||||||
|
|
||||||
#define NUM_WEP_KEYS 4
|
|
||||||
struct hostapd_wep_keys {
|
|
||||||
u8 idx;
|
|
||||||
u8 *key[NUM_WEP_KEYS];
|
|
||||||
size_t len[NUM_WEP_KEYS];
|
|
||||||
int keys_set;
|
|
||||||
size_t default_len; /* key length used for dynamic key generation */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum hostap_security_policy {
|
|
||||||
SECURITY_PLAINTEXT = 0,
|
|
||||||
SECURITY_STATIC_WEP = 1,
|
|
||||||
SECURITY_IEEE_802_1X = 2,
|
|
||||||
SECURITY_WPA_PSK = 3,
|
|
||||||
SECURITY_WPA = 4
|
|
||||||
} secpolicy;
|
|
||||||
|
|
||||||
struct hostapd_ssid {
|
|
||||||
char ssid[HOSTAPD_MAX_SSID_LEN + 1];
|
|
||||||
size_t ssid_len;
|
|
||||||
int ssid_set;
|
|
||||||
|
|
||||||
char vlan[IFNAMSIZ + 1];
|
|
||||||
secpolicy security_policy;
|
|
||||||
|
|
||||||
struct hostapd_wpa_psk *wpa_psk;
|
|
||||||
char *wpa_passphrase;
|
|
||||||
char *wpa_psk_file;
|
|
||||||
|
|
||||||
struct hostapd_wep_keys wep;
|
|
||||||
|
|
||||||
#define DYNAMIC_VLAN_DISABLED 0
|
|
||||||
#define DYNAMIC_VLAN_OPTIONAL 1
|
|
||||||
#define DYNAMIC_VLAN_REQUIRED 2
|
|
||||||
int dynamic_vlan;
|
|
||||||
#ifdef CONFIG_FULL_DYNAMIC_VLAN
|
|
||||||
char *vlan_tagged_interface;
|
|
||||||
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
|
|
||||||
struct hostapd_wep_keys **dyn_vlan_keys;
|
|
||||||
size_t max_dyn_vlan_keys;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define VLAN_ID_WILDCARD -1
|
|
||||||
|
|
||||||
struct hostapd_vlan {
|
|
||||||
struct hostapd_vlan *next;
|
|
||||||
int vlan_id; /* VLAN ID or -1 (VLAN_ID_WILDCARD) for wildcard entry */
|
|
||||||
char ifname[IFNAMSIZ + 1];
|
|
||||||
int dynamic_vlan;
|
|
||||||
#ifdef CONFIG_FULL_DYNAMIC_VLAN
|
|
||||||
|
|
||||||
#define DVLAN_CLEAN_BR 0x1
|
|
||||||
#define DVLAN_CLEAN_VLAN 0x2
|
|
||||||
#define DVLAN_CLEAN_VLAN_PORT 0x4
|
|
||||||
#define DVLAN_CLEAN_WLAN_PORT 0x8
|
|
||||||
int clean;
|
|
||||||
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PMK_LEN 32
|
|
||||||
struct hostapd_wpa_psk {
|
|
||||||
struct hostapd_wpa_psk *next;
|
|
||||||
int group;
|
|
||||||
u8 psk[PMK_LEN];
|
|
||||||
u8 addr[ETH_ALEN];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define EAP_USER_MAX_METHODS 8
|
|
||||||
struct hostapd_eap_user {
|
|
||||||
struct hostapd_eap_user *next;
|
|
||||||
u8 *identity;
|
|
||||||
size_t identity_len;
|
|
||||||
struct {
|
|
||||||
int vendor;
|
|
||||||
u32 method;
|
|
||||||
} methods[EAP_USER_MAX_METHODS];
|
|
||||||
u8 *password;
|
|
||||||
size_t password_len;
|
|
||||||
int phase2;
|
|
||||||
int force_version;
|
|
||||||
unsigned int wildcard_prefix:1;
|
|
||||||
unsigned int password_hash:1; /* whether password is hashed with
|
|
||||||
* nt_password_hash() */
|
|
||||||
int ttls_auth; /* EAP_TTLS_AUTH_* bitfield */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define NUM_TX_QUEUES 4
|
|
||||||
|
|
||||||
struct hostapd_tx_queue_params {
|
|
||||||
int aifs;
|
|
||||||
int cwmin;
|
|
||||||
int cwmax;
|
|
||||||
int burst; /* maximum burst time in 0.1 ms, i.e., 10 = 1 ms */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hostapd_wmm_ac_params {
|
|
||||||
int cwmin;
|
|
||||||
int cwmax;
|
|
||||||
int aifs;
|
|
||||||
int txop_limit; /* in units of 32us */
|
|
||||||
int admission_control_mandatory;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct hostapd_bss_config - Per-BSS configuration
|
|
||||||
*/
|
|
||||||
struct hostapd_bss_config {
|
|
||||||
char iface[IFNAMSIZ + 1];
|
|
||||||
char bridge[IFNAMSIZ + 1];
|
|
||||||
char wds_bridge[IFNAMSIZ + 1];
|
|
||||||
|
|
||||||
enum hostapd_logger_level logger_syslog_level, logger_stdout_level;
|
|
||||||
|
|
||||||
unsigned int logger_syslog; /* module bitfield */
|
|
||||||
unsigned int logger_stdout; /* module bitfield */
|
|
||||||
|
|
||||||
char *dump_log_name; /* file name for state dump (SIGUSR1) */
|
|
||||||
|
|
||||||
int max_num_sta; /* maximum number of STAs in station table */
|
|
||||||
|
|
||||||
int dtim_period;
|
|
||||||
|
|
||||||
int ieee802_1x; /* use IEEE 802.1X */
|
|
||||||
int eapol_version;
|
|
||||||
int eap_server; /* Use internal EAP server instead of external
|
|
||||||
* RADIUS server */
|
|
||||||
struct hostapd_eap_user *eap_user;
|
|
||||||
char *eap_sim_db;
|
|
||||||
struct hostapd_ip_addr own_ip_addr;
|
|
||||||
char *nas_identifier;
|
|
||||||
struct hostapd_radius_servers *radius;
|
|
||||||
int acct_interim_interval;
|
|
||||||
|
|
||||||
struct hostapd_ssid ssid;
|
|
||||||
|
|
||||||
char *eap_req_id_text; /* optional displayable message sent with
|
|
||||||
* EAP Request-Identity */
|
|
||||||
size_t eap_req_id_text_len;
|
|
||||||
int eapol_key_index_workaround;
|
|
||||||
|
|
||||||
size_t default_wep_key_len;
|
|
||||||
int individual_wep_key_len;
|
|
||||||
int wep_rekeying_period;
|
|
||||||
int broadcast_key_idx_min, broadcast_key_idx_max;
|
|
||||||
int eap_reauth_period;
|
|
||||||
|
|
||||||
int ieee802_11f; /* use IEEE 802.11f (IAPP) */
|
|
||||||
char iapp_iface[IFNAMSIZ + 1]; /* interface used with IAPP broadcast
|
|
||||||
* frames */
|
|
||||||
|
|
||||||
enum {
|
|
||||||
ACCEPT_UNLESS_DENIED = 0,
|
|
||||||
DENY_UNLESS_ACCEPTED = 1,
|
|
||||||
USE_EXTERNAL_RADIUS_AUTH = 2
|
|
||||||
} macaddr_acl;
|
|
||||||
struct mac_acl_entry *accept_mac;
|
|
||||||
int num_accept_mac;
|
|
||||||
struct mac_acl_entry *deny_mac;
|
|
||||||
int num_deny_mac;
|
|
||||||
int wds_sta;
|
|
||||||
int isolate;
|
|
||||||
|
|
||||||
int auth_algs; /* bitfield of allowed IEEE 802.11 authentication
|
|
||||||
* algorithms, WPA_AUTH_ALG_{OPEN,SHARED,LEAP} */
|
|
||||||
|
|
||||||
int wpa; /* bitfield of WPA_PROTO_WPA, WPA_PROTO_RSN */
|
|
||||||
int wpa_key_mgmt;
|
|
||||||
#ifdef CONFIG_IEEE80211W
|
|
||||||
enum mfp_options ieee80211w;
|
|
||||||
/* dot11AssociationSAQueryMaximumTimeout (in TUs) */
|
|
||||||
unsigned int assoc_sa_query_max_timeout;
|
|
||||||
/* dot11AssociationSAQueryRetryTimeout (in TUs) */
|
|
||||||
int assoc_sa_query_retry_timeout;
|
|
||||||
#endif /* CONFIG_IEEE80211W */
|
|
||||||
int wpa_pairwise;
|
|
||||||
int wpa_group;
|
|
||||||
int wpa_group_rekey;
|
|
||||||
int wpa_strict_rekey;
|
|
||||||
int wpa_gmk_rekey;
|
|
||||||
int wpa_ptk_rekey;
|
|
||||||
int rsn_pairwise;
|
|
||||||
int rsn_preauth;
|
|
||||||
char *rsn_preauth_interfaces;
|
|
||||||
int peerkey;
|
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211R
|
|
||||||
/* IEEE 802.11r - Fast BSS Transition */
|
|
||||||
u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN];
|
|
||||||
u8 r1_key_holder[FT_R1KH_ID_LEN];
|
|
||||||
u32 r0_key_lifetime;
|
|
||||||
u32 reassociation_deadline;
|
|
||||||
struct ft_remote_r0kh *r0kh_list;
|
|
||||||
struct ft_remote_r1kh *r1kh_list;
|
|
||||||
int pmk_r1_push;
|
|
||||||
int ft_over_ds;
|
|
||||||
#endif /* CONFIG_IEEE80211R */
|
|
||||||
|
|
||||||
char *ctrl_interface; /* directory for UNIX domain sockets */
|
|
||||||
#ifndef CONFIG_NATIVE_WINDOWS
|
|
||||||
gid_t ctrl_interface_gid;
|
|
||||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
|
||||||
int ctrl_interface_gid_set;
|
|
||||||
|
|
||||||
char *ca_cert;
|
|
||||||
char *server_cert;
|
|
||||||
char *private_key;
|
|
||||||
char *private_key_passwd;
|
|
||||||
int check_crl;
|
|
||||||
char *dh_file;
|
|
||||||
u8 *pac_opaque_encr_key;
|
|
||||||
u8 *eap_fast_a_id;
|
|
||||||
size_t eap_fast_a_id_len;
|
|
||||||
char *eap_fast_a_id_info;
|
|
||||||
int eap_fast_prov;
|
|
||||||
int pac_key_lifetime;
|
|
||||||
int pac_key_refresh_time;
|
|
||||||
int eap_sim_aka_result_ind;
|
|
||||||
int tnc;
|
|
||||||
int fragment_size;
|
|
||||||
u16 pwd_group;
|
|
||||||
|
|
||||||
char *radius_server_clients;
|
|
||||||
int radius_server_auth_port;
|
|
||||||
int radius_server_ipv6;
|
|
||||||
|
|
||||||
char *test_socket; /* UNIX domain socket path for driver_test */
|
|
||||||
|
|
||||||
int use_pae_group_addr; /* Whether to send EAPOL frames to PAE group
|
|
||||||
* address instead of individual address
|
|
||||||
* (for driver_wired.c).
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ap_max_inactivity;
|
|
||||||
int ignore_broadcast_ssid;
|
|
||||||
|
|
||||||
int wmm_enabled;
|
|
||||||
int wmm_uapsd;
|
|
||||||
|
|
||||||
struct hostapd_vlan *vlan, *vlan_tail;
|
|
||||||
|
|
||||||
macaddr bssid;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Maximum listen interval that STAs can use when associating with this
|
|
||||||
* BSS. If a STA tries to use larger value, the association will be
|
|
||||||
* denied with status code 51.
|
|
||||||
*/
|
|
||||||
u16 max_listen_interval;
|
|
||||||
|
|
||||||
int okc; /* Opportunistic Key Caching */
|
|
||||||
|
|
||||||
int wps_state;
|
|
||||||
#ifdef CONFIG_WPS
|
|
||||||
int ap_setup_locked;
|
|
||||||
u8 uuid[16];
|
|
||||||
char *wps_pin_requests;
|
|
||||||
char *device_name;
|
|
||||||
char *manufacturer;
|
|
||||||
char *model_name;
|
|
||||||
char *model_number;
|
|
||||||
char *serial_number;
|
|
||||||
u8 device_type[WPS_DEV_TYPE_LEN];
|
|
||||||
char *config_methods;
|
|
||||||
u8 os_version[4];
|
|
||||||
char *ap_pin;
|
|
||||||
int skip_cred_build;
|
|
||||||
u8 *extra_cred;
|
|
||||||
size_t extra_cred_len;
|
|
||||||
int wps_cred_processing;
|
|
||||||
u8 *ap_settings;
|
|
||||||
size_t ap_settings_len;
|
|
||||||
char *upnp_iface;
|
|
||||||
char *friendly_name;
|
|
||||||
char *manufacturer_url;
|
|
||||||
char *model_description;
|
|
||||||
char *model_url;
|
|
||||||
char *upc;
|
|
||||||
struct wpabuf *wps_vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
|
|
||||||
#endif /* CONFIG_WPS */
|
|
||||||
|
|
||||||
#define P2P_ENABLED BIT(0)
|
|
||||||
#define P2P_GROUP_OWNER BIT(1)
|
|
||||||
#define P2P_GROUP_FORMATION BIT(2)
|
|
||||||
#define P2P_MANAGE BIT(3)
|
|
||||||
#define P2P_ALLOW_CROSS_CONNECTION BIT(4)
|
|
||||||
int p2p;
|
|
||||||
|
|
||||||
int disassoc_low_ack;
|
|
||||||
|
|
||||||
#define TDLS_PROHIBIT BIT(0)
|
|
||||||
#define TDLS_PROHIBIT_CHAN_SWITCH BIT(1)
|
|
||||||
int tdls;
|
|
||||||
int disable_11n;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct hostapd_config - Per-radio interface configuration
|
|
||||||
*/
|
|
||||||
struct hostapd_config {
|
|
||||||
struct hostapd_bss_config *bss, *last_bss;
|
|
||||||
size_t num_bss;
|
|
||||||
|
|
||||||
u16 beacon_int;
|
|
||||||
int rts_threshold;
|
|
||||||
int fragm_threshold;
|
|
||||||
u8 send_probe_response;
|
|
||||||
u8 channel;
|
|
||||||
enum hostapd_hw_mode hw_mode; /* HOSTAPD_MODE_IEEE80211A, .. */
|
|
||||||
enum {
|
|
||||||
LONG_PREAMBLE = 0,
|
|
||||||
SHORT_PREAMBLE = 1
|
|
||||||
} preamble;
|
|
||||||
enum {
|
|
||||||
CTS_PROTECTION_AUTOMATIC = 0,
|
|
||||||
CTS_PROTECTION_FORCE_ENABLED = 1,
|
|
||||||
CTS_PROTECTION_FORCE_DISABLED = 2,
|
|
||||||
CTS_PROTECTION_AUTOMATIC_NO_OLBC = 3,
|
|
||||||
} cts_protection_type;
|
|
||||||
|
|
||||||
int *supported_rates;
|
|
||||||
int *basic_rates;
|
|
||||||
|
|
||||||
const struct wpa_driver_ops *driver;
|
|
||||||
|
|
||||||
int ap_table_max_size;
|
|
||||||
int ap_table_expiration_time;
|
|
||||||
|
|
||||||
char country[3]; /* first two octets: country code as described in
|
|
||||||
* ISO/IEC 3166-1. Third octet:
|
|
||||||
* ' ' (ascii 32): all environments
|
|
||||||
* 'O': Outdoor environemnt only
|
|
||||||
* 'I': Indoor environment only
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ieee80211d;
|
|
||||||
|
|
||||||
struct hostapd_tx_queue_params tx_queue[NUM_TX_QUEUES];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* WMM AC parameters, in same order as 802.1D, i.e.
|
|
||||||
* 0 = BE (best effort)
|
|
||||||
* 1 = BK (background)
|
|
||||||
* 2 = VI (video)
|
|
||||||
* 3 = VO (voice)
|
|
||||||
*/
|
|
||||||
struct hostapd_wmm_ac_params wmm_ac_params[4];
|
|
||||||
|
|
||||||
int ht_op_mode_fixed;
|
|
||||||
u16 ht_capab;
|
|
||||||
int ieee80211n;
|
|
||||||
int secondary_channel;
|
|
||||||
int require_ht;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_mac_comp(const void *a, const void *b);
|
|
||||||
int hostapd_mac_comp_empty(const void *a);
|
|
||||||
struct hostapd_config * hostapd_config_defaults(void);
|
|
||||||
void hostapd_config_defaults_bss(struct hostapd_bss_config *bss);
|
|
||||||
void hostapd_config_free(struct hostapd_config *conf);
|
|
||||||
int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries,
|
|
||||||
const u8 *addr, int *vlan_id);
|
|
||||||
int hostapd_rate_found(int *list, int rate);
|
|
||||||
int hostapd_wep_key_cmp(struct hostapd_wep_keys *a,
|
|
||||||
struct hostapd_wep_keys *b);
|
|
||||||
const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
|
|
||||||
const u8 *addr, const u8 *prev_psk);
|
|
||||||
int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf);
|
|
||||||
const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan,
|
|
||||||
int vlan_id);
|
|
||||||
const struct hostapd_eap_user *
|
|
||||||
hostapd_get_eap_user(const struct hostapd_bss_config *conf, const u8 *identity,
|
|
||||||
size_t identity_len, int phase2);
|
|
||||||
|
|
||||||
#endif /* HOSTAPD_CONFIG_H */
|
|
|
@ -1,632 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd - Driver operations
|
|
||||||
* Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "utils/includes.h"
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
|
||||||
#include "drivers/driver.h"
|
|
||||||
#include "common/ieee802_11_defs.h"
|
|
||||||
#include "wps/wps.h"
|
|
||||||
#include "hostapd.h"
|
|
||||||
#include "ieee802_11.h"
|
|
||||||
#include "sta_info.h"
|
|
||||||
#include "ap_config.h"
|
|
||||||
#include "p2p_hostapd.h"
|
|
||||||
#include "ap_drv_ops.h"
|
|
||||||
|
|
||||||
|
|
||||||
u32 hostapd_sta_flags_to_drv(u32 flags)
|
|
||||||
{
|
|
||||||
int res = 0;
|
|
||||||
if (flags & WLAN_STA_AUTHORIZED)
|
|
||||||
res |= WPA_STA_AUTHORIZED;
|
|
||||||
if (flags & WLAN_STA_WMM)
|
|
||||||
res |= WPA_STA_WMM;
|
|
||||||
if (flags & WLAN_STA_SHORT_PREAMBLE)
|
|
||||||
res |= WPA_STA_SHORT_PREAMBLE;
|
|
||||||
if (flags & WLAN_STA_MFP)
|
|
||||||
res |= WPA_STA_MFP;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
struct wpabuf *beacon, *proberesp, *assocresp = NULL;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
beacon = hapd->wps_beacon_ie;
|
|
||||||
proberesp = hapd->wps_probe_resp_ie;
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
if (hapd->wps_beacon_ie == NULL && hapd->p2p_beacon_ie == NULL)
|
|
||||||
beacon = NULL;
|
|
||||||
else {
|
|
||||||
beacon = wpabuf_alloc((hapd->wps_beacon_ie ?
|
|
||||||
wpabuf_len(hapd->wps_beacon_ie) : 0) +
|
|
||||||
(hapd->p2p_beacon_ie ?
|
|
||||||
wpabuf_len(hapd->p2p_beacon_ie) : 0));
|
|
||||||
if (beacon == NULL)
|
|
||||||
return -1;
|
|
||||||
if (hapd->wps_beacon_ie)
|
|
||||||
wpabuf_put_buf(beacon, hapd->wps_beacon_ie);
|
|
||||||
if (hapd->p2p_beacon_ie)
|
|
||||||
wpabuf_put_buf(beacon, hapd->p2p_beacon_ie);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hapd->wps_probe_resp_ie == NULL && hapd->p2p_probe_resp_ie == NULL)
|
|
||||||
proberesp = NULL;
|
|
||||||
else {
|
|
||||||
proberesp = wpabuf_alloc(
|
|
||||||
(hapd->wps_probe_resp_ie ?
|
|
||||||
wpabuf_len(hapd->wps_probe_resp_ie) : 0) +
|
|
||||||
(hapd->p2p_probe_resp_ie ?
|
|
||||||
wpabuf_len(hapd->p2p_probe_resp_ie) : 0));
|
|
||||||
if (proberesp == NULL) {
|
|
||||||
wpabuf_free(beacon);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (hapd->wps_probe_resp_ie)
|
|
||||||
wpabuf_put_buf(proberesp, hapd->wps_probe_resp_ie);
|
|
||||||
if (hapd->p2p_probe_resp_ie)
|
|
||||||
wpabuf_put_buf(proberesp, hapd->p2p_probe_resp_ie);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P_MANAGER
|
|
||||||
if (hapd->conf->p2p & P2P_MANAGE) {
|
|
||||||
struct wpabuf *a;
|
|
||||||
|
|
||||||
a = wpabuf_alloc(100 + (beacon ? wpabuf_len(beacon) : 0));
|
|
||||||
if (a) {
|
|
||||||
u8 *start, *p;
|
|
||||||
if (beacon)
|
|
||||||
wpabuf_put_buf(a, beacon);
|
|
||||||
if (beacon != hapd->wps_beacon_ie)
|
|
||||||
wpabuf_free(beacon);
|
|
||||||
start = wpabuf_put(a, 0);
|
|
||||||
p = hostapd_eid_p2p_manage(hapd, start);
|
|
||||||
wpabuf_put(a, p - start);
|
|
||||||
beacon = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
a = wpabuf_alloc(100 + (proberesp ? wpabuf_len(proberesp) :
|
|
||||||
0));
|
|
||||||
if (a) {
|
|
||||||
u8 *start, *p;
|
|
||||||
if (proberesp)
|
|
||||||
wpabuf_put_buf(a, proberesp);
|
|
||||||
if (proberesp != hapd->wps_probe_resp_ie)
|
|
||||||
wpabuf_free(proberesp);
|
|
||||||
start = wpabuf_put(a, 0);
|
|
||||||
p = hostapd_eid_p2p_manage(hapd, start);
|
|
||||||
wpabuf_put(a, p - start);
|
|
||||||
proberesp = a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_P2P_MANAGER */
|
|
||||||
|
|
||||||
#ifdef CONFIG_WPS2
|
|
||||||
if (hapd->conf->wps_state)
|
|
||||||
assocresp = wps_build_assoc_resp_ie();
|
|
||||||
#endif /* CONFIG_WPS2 */
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P_MANAGER
|
|
||||||
if (hapd->conf->p2p & P2P_MANAGE) {
|
|
||||||
struct wpabuf *a;
|
|
||||||
a = wpabuf_alloc(100 + (assocresp ? wpabuf_len(assocresp) :
|
|
||||||
0));
|
|
||||||
if (a) {
|
|
||||||
u8 *start, *p;
|
|
||||||
start = wpabuf_put(a, 0);
|
|
||||||
p = hostapd_eid_p2p_manage(hapd, start);
|
|
||||||
wpabuf_put(a, p - start);
|
|
||||||
if (assocresp) {
|
|
||||||
wpabuf_put_buf(a, assocresp);
|
|
||||||
wpabuf_free(assocresp);
|
|
||||||
}
|
|
||||||
assocresp = a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_P2P_MANAGER */
|
|
||||||
|
|
||||||
ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
|
|
||||||
assocresp);
|
|
||||||
|
|
||||||
if (beacon != hapd->wps_beacon_ie)
|
|
||||||
wpabuf_free(beacon);
|
|
||||||
if (proberesp != hapd->wps_probe_resp_ie)
|
|
||||||
wpabuf_free(proberesp);
|
|
||||||
wpabuf_free(assocresp);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_authorized(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta, int authorized)
|
|
||||||
{
|
|
||||||
if (authorized) {
|
|
||||||
return hostapd_sta_set_flags(hapd, sta->addr,
|
|
||||||
hostapd_sta_flags_to_drv(
|
|
||||||
sta->flags),
|
|
||||||
WPA_STA_AUTHORIZED, ~0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hostapd_sta_set_flags(hapd, sta->addr,
|
|
||||||
hostapd_sta_flags_to_drv(sta->flags),
|
|
||||||
0, ~WPA_STA_AUTHORIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta)
|
|
||||||
{
|
|
||||||
int set_flags, total_flags, flags_and, flags_or;
|
|
||||||
total_flags = hostapd_sta_flags_to_drv(sta->flags);
|
|
||||||
set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP;
|
|
||||||
if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
|
|
||||||
sta->auth_alg == WLAN_AUTH_FT) &&
|
|
||||||
sta->flags & WLAN_STA_AUTHORIZED)
|
|
||||||
set_flags |= WPA_STA_AUTHORIZED;
|
|
||||||
flags_or = total_flags & set_flags;
|
|
||||||
flags_and = total_flags | ~set_flags;
|
|
||||||
return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
|
|
||||||
flags_or, flags_and);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
|
|
||||||
int enabled)
|
|
||||||
{
|
|
||||||
struct wpa_bss_params params;
|
|
||||||
os_memset(¶ms, 0, sizeof(params));
|
|
||||||
params.ifname = ifname;
|
|
||||||
params.enabled = enabled;
|
|
||||||
if (enabled) {
|
|
||||||
params.wpa = hapd->conf->wpa;
|
|
||||||
params.ieee802_1x = hapd->conf->ieee802_1x;
|
|
||||||
params.wpa_group = hapd->conf->wpa_group;
|
|
||||||
params.wpa_pairwise = hapd->conf->wpa_pairwise;
|
|
||||||
params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
|
|
||||||
params.rsn_preauth = hapd->conf->rsn_preauth;
|
|
||||||
#ifdef CONFIG_IEEE80211W
|
|
||||||
params.ieee80211w = hapd->conf->ieee80211w;
|
|
||||||
#endif /* CONFIG_IEEE80211W */
|
|
||||||
}
|
|
||||||
return hostapd_set_ieee8021x(hapd, ¶ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_set_ap_isolate(struct hostapd_data *hapd, int value)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_intra_bss == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_intra_bss(hapd->drv_priv, !value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_bss_params(struct hostapd_data *hapd, int use_protection)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
int preamble;
|
|
||||||
#ifdef CONFIG_IEEE80211N
|
|
||||||
u8 buf[60], *ht_capab, *ht_oper, *pos;
|
|
||||||
|
|
||||||
pos = buf;
|
|
||||||
ht_capab = pos;
|
|
||||||
pos = hostapd_eid_ht_capabilities(hapd, pos);
|
|
||||||
ht_oper = pos;
|
|
||||||
pos = hostapd_eid_ht_operation(hapd, pos);
|
|
||||||
if (pos > ht_oper && ht_oper > ht_capab &&
|
|
||||||
hostapd_set_ht_params(hapd, ht_capab + 2, ht_capab[1],
|
|
||||||
ht_oper + 2, ht_oper[1])) {
|
|
||||||
wpa_printf(MSG_ERROR, "Could not set HT capabilities "
|
|
||||||
"for kernel driver");
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_IEEE80211N */
|
|
||||||
|
|
||||||
if (hostapd_set_cts_protect(hapd, use_protection)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to set CTS protect in kernel "
|
|
||||||
"driver");
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hapd->iface->current_mode &&
|
|
||||||
hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
|
|
||||||
hostapd_set_short_slot_time(hapd,
|
|
||||||
hapd->iface->num_sta_no_short_slot_time
|
|
||||||
> 0 ? 0 : 1)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to set Short Slot Time option "
|
|
||||||
"in kernel driver");
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hapd->iface->num_sta_no_short_preamble == 0 &&
|
|
||||||
hapd->iconf->preamble == SHORT_PREAMBLE)
|
|
||||||
preamble = SHORT_PREAMBLE;
|
|
||||||
else
|
|
||||||
preamble = LONG_PREAMBLE;
|
|
||||||
if (hostapd_set_preamble(hapd, preamble)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Could not set preamble for kernel "
|
|
||||||
"driver");
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hostapd_set_ap_isolate(hapd, hapd->conf->isolate) &&
|
|
||||||
hapd->conf->isolate) {
|
|
||||||
wpa_printf(MSG_ERROR, "Could not enable AP isolation in "
|
|
||||||
"kernel driver");
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
|
|
||||||
{
|
|
||||||
char force_ifname[IFNAMSIZ];
|
|
||||||
u8 if_addr[ETH_ALEN];
|
|
||||||
return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr,
|
|
||||||
NULL, NULL, force_ifname, if_addr, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname)
|
|
||||||
{
|
|
||||||
return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_wds_sta(struct hostapd_data *hapd, const u8 *addr, int aid,
|
|
||||||
int val)
|
|
||||||
{
|
|
||||||
const char *bridge = NULL;
|
|
||||||
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
|
|
||||||
return 0;
|
|
||||||
if (hapd->conf->wds_bridge[0])
|
|
||||||
bridge = hapd->conf->wds_bridge;
|
|
||||||
else if (hapd->conf->bridge[0])
|
|
||||||
bridge = hapd->conf->bridge;
|
|
||||||
return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
|
|
||||||
bridge);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_sta_add(struct hostapd_data *hapd,
|
|
||||||
const u8 *addr, u16 aid, u16 capability,
|
|
||||||
const u8 *supp_rates, size_t supp_rates_len,
|
|
||||||
u16 listen_interval,
|
|
||||||
const struct ieee80211_ht_capabilities *ht_capab)
|
|
||||||
{
|
|
||||||
struct hostapd_sta_add_params params;
|
|
||||||
|
|
||||||
if (hapd->driver == NULL)
|
|
||||||
return 0;
|
|
||||||
if (hapd->driver->sta_add == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
os_memset(¶ms, 0, sizeof(params));
|
|
||||||
params.addr = addr;
|
|
||||||
params.aid = aid;
|
|
||||||
params.capability = capability;
|
|
||||||
params.supp_rates = supp_rates;
|
|
||||||
params.supp_rates_len = supp_rates_len;
|
|
||||||
params.listen_interval = listen_interval;
|
|
||||||
params.ht_capabilities = ht_capab;
|
|
||||||
return hapd->driver->sta_add(hapd->drv_priv, ¶ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_privacy(struct hostapd_data *hapd, int enabled)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_privacy == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_privacy(hapd->drv_priv, enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
|
|
||||||
size_t elem_len)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
|
||||||
const char *ifname, const u8 *addr, void *bss_ctx,
|
|
||||||
void **drv_priv, char *force_ifname, u8 *if_addr,
|
|
||||||
const char *bridge)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->if_add == NULL)
|
|
||||||
return -1;
|
|
||||||
return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr,
|
|
||||||
bss_ctx, drv_priv, force_ifname, if_addr,
|
|
||||||
bridge);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
|
||||||
const char *ifname)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->if_remove == NULL)
|
|
||||||
return -1;
|
|
||||||
return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_ieee8021x(struct hostapd_data *hapd,
|
|
||||||
struct wpa_bss_params *params)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_ieee8021x(hapd->drv_priv, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
|
|
||||||
const u8 *addr, int idx, u8 *seq)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx,
|
|
||||||
seq);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_flush(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->flush == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->flush(hapd->drv_priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_freq(struct hostapd_data *hapd, int mode, int freq,
|
|
||||||
int channel, int ht_enabled, int sec_channel_offset)
|
|
||||||
{
|
|
||||||
struct hostapd_freq_params data;
|
|
||||||
if (hapd->driver == NULL)
|
|
||||||
return 0;
|
|
||||||
if (hapd->driver->set_freq == NULL)
|
|
||||||
return 0;
|
|
||||||
os_memset(&data, 0, sizeof(data));
|
|
||||||
data.mode = mode;
|
|
||||||
data.freq = freq;
|
|
||||||
data.channel = channel;
|
|
||||||
data.ht_enabled = ht_enabled;
|
|
||||||
data.sec_channel_offset = sec_channel_offset;
|
|
||||||
return hapd->driver->set_freq(hapd->drv_priv, &data);
|
|
||||||
}
|
|
||||||
|
|
||||||
int hostapd_set_rts(struct hostapd_data *hapd, int rts)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_rts == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_rts(hapd->drv_priv, rts);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_frag(struct hostapd_data *hapd, int frag)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_frag == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_frag(hapd->drv_priv, frag);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
|
|
||||||
int total_flags, int flags_or, int flags_and)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
|
|
||||||
flags_or, flags_and);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_rate_sets(struct hostapd_data *hapd, int *supp_rates,
|
|
||||||
int *basic_rates, int mode)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_rate_sets == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_rate_sets(hapd->drv_priv, supp_rates,
|
|
||||||
basic_rates, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_country(struct hostapd_data *hapd, const char *country)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL ||
|
|
||||||
hapd->driver->set_country == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_country(hapd->drv_priv, country);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_cts_protect(struct hostapd_data *hapd, int value)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_cts_protect == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_cts_protect(hapd->drv_priv, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_preamble(struct hostapd_data *hapd, int value)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_preamble == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_preamble(hapd->drv_priv, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_short_slot_time(struct hostapd_data *hapd, int value)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_short_slot_time == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_short_slot_time(hapd->drv_priv, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
|
|
||||||
int cw_min, int cw_max, int burst_time)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs,
|
|
||||||
cw_min, cw_max, burst_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_valid_bss_mask(struct hostapd_data *hapd, const u8 *addr,
|
|
||||||
const u8 *mask)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->valid_bss_mask == NULL)
|
|
||||||
return 1;
|
|
||||||
return hapd->driver->valid_bss_mask(hapd->drv_priv, addr, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct hostapd_hw_modes *
|
|
||||||
hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
|
|
||||||
u16 *flags)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL ||
|
|
||||||
hapd->driver->get_hw_feature_data == NULL)
|
|
||||||
return NULL;
|
|
||||||
return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
|
|
||||||
flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_driver_commit(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->commit == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->commit(hapd->drv_priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_ht_params(struct hostapd_data *hapd,
|
|
||||||
const u8 *ht_capab, size_t ht_capab_len,
|
|
||||||
const u8 *ht_oper, size_t ht_oper_len)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_ht_params == NULL ||
|
|
||||||
ht_capab == NULL || ht_oper == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_ht_params(hapd->drv_priv,
|
|
||||||
ht_capab, ht_capab_len,
|
|
||||||
ht_oper, ht_oper_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_drv_none(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_driver_scan(struct hostapd_data *hapd,
|
|
||||||
struct wpa_driver_scan_params *params)
|
|
||||||
{
|
|
||||||
if (hapd->driver && hapd->driver->scan2)
|
|
||||||
return hapd->driver->scan2(hapd->drv_priv, params);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct wpa_scan_results * hostapd_driver_get_scan_results(
|
|
||||||
struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
if (hapd->driver && hapd->driver->get_scan_results2)
|
|
||||||
return hapd->driver->get_scan_results2(hapd->drv_priv);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
|
|
||||||
int duration)
|
|
||||||
{
|
|
||||||
if (hapd->driver && hapd->driver->set_noa)
|
|
||||||
return hapd->driver->set_noa(hapd->drv_priv, count, start,
|
|
||||||
duration);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
|
|
||||||
enum wpa_alg alg, const u8 *addr,
|
|
||||||
int key_idx, int set_tx,
|
|
||||||
const u8 *seq, size_t seq_len,
|
|
||||||
const u8 *key, size_t key_len)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_key == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
|
|
||||||
key_idx, set_tx, seq, seq_len, key,
|
|
||||||
key_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_drv_send_mlme(struct hostapd_data *hapd,
|
|
||||||
const void *msg, size_t len)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->send_mlme(hapd->drv_priv, msg, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
|
|
||||||
const u8 *addr, int reason)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
|
|
||||||
reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
|
|
||||||
const u8 *addr, int reason)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
|
|
||||||
reason);
|
|
||||||
}
|
|
|
@ -1,197 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd - Driver operations
|
|
||||||
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef AP_DRV_OPS
|
|
||||||
#define AP_DRV_OPS
|
|
||||||
|
|
||||||
enum wpa_driver_if_type;
|
|
||||||
struct wpa_bss_params;
|
|
||||||
struct wpa_driver_scan_params;
|
|
||||||
struct ieee80211_ht_capabilities;
|
|
||||||
|
|
||||||
u32 hostapd_sta_flags_to_drv(u32 flags);
|
|
||||||
int hostapd_set_ap_wps_ie(struct hostapd_data *hapd);
|
|
||||||
int hostapd_set_authorized(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta, int authorized);
|
|
||||||
int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta);
|
|
||||||
int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
|
|
||||||
int enabled);
|
|
||||||
int hostapd_set_bss_params(struct hostapd_data *hapd, int use_protection);
|
|
||||||
int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname);
|
|
||||||
int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname);
|
|
||||||
int hostapd_set_wds_sta(struct hostapd_data *hapd, const u8 *addr, int aid,
|
|
||||||
int val);
|
|
||||||
int hostapd_sta_add(struct hostapd_data *hapd,
|
|
||||||
const u8 *addr, u16 aid, u16 capability,
|
|
||||||
const u8 *supp_rates, size_t supp_rates_len,
|
|
||||||
u16 listen_interval,
|
|
||||||
const struct ieee80211_ht_capabilities *ht_capab);
|
|
||||||
int hostapd_set_privacy(struct hostapd_data *hapd, int enabled);
|
|
||||||
int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
|
|
||||||
size_t elem_len);
|
|
||||||
int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len);
|
|
||||||
int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len);
|
|
||||||
int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
|
||||||
const char *ifname, const u8 *addr, void *bss_ctx,
|
|
||||||
void **drv_priv, char *force_ifname, u8 *if_addr,
|
|
||||||
const char *bridge);
|
|
||||||
int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
|
||||||
const char *ifname);
|
|
||||||
int hostapd_set_ieee8021x(struct hostapd_data *hapd,
|
|
||||||
struct wpa_bss_params *params);
|
|
||||||
int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
|
|
||||||
const u8 *addr, int idx, u8 *seq);
|
|
||||||
int hostapd_flush(struct hostapd_data *hapd);
|
|
||||||
int hostapd_set_freq(struct hostapd_data *hapd, int mode, int freq,
|
|
||||||
int channel, int ht_enabled, int sec_channel_offset);
|
|
||||||
int hostapd_set_rts(struct hostapd_data *hapd, int rts);
|
|
||||||
int hostapd_set_frag(struct hostapd_data *hapd, int frag);
|
|
||||||
int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
|
|
||||||
int total_flags, int flags_or, int flags_and);
|
|
||||||
int hostapd_set_rate_sets(struct hostapd_data *hapd, int *supp_rates,
|
|
||||||
int *basic_rates, int mode);
|
|
||||||
int hostapd_set_country(struct hostapd_data *hapd, const char *country);
|
|
||||||
int hostapd_set_cts_protect(struct hostapd_data *hapd, int value);
|
|
||||||
int hostapd_set_preamble(struct hostapd_data *hapd, int value);
|
|
||||||
int hostapd_set_short_slot_time(struct hostapd_data *hapd, int value);
|
|
||||||
int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
|
|
||||||
int cw_min, int cw_max, int burst_time);
|
|
||||||
int hostapd_valid_bss_mask(struct hostapd_data *hapd, const u8 *addr,
|
|
||||||
const u8 *mask);
|
|
||||||
struct hostapd_hw_modes *
|
|
||||||
hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
|
|
||||||
u16 *flags);
|
|
||||||
int hostapd_driver_commit(struct hostapd_data *hapd);
|
|
||||||
int hostapd_set_ht_params(struct hostapd_data *hapd,
|
|
||||||
const u8 *ht_capab, size_t ht_capab_len,
|
|
||||||
const u8 *ht_oper, size_t ht_oper_len);
|
|
||||||
int hostapd_drv_none(struct hostapd_data *hapd);
|
|
||||||
int hostapd_driver_scan(struct hostapd_data *hapd,
|
|
||||||
struct wpa_driver_scan_params *params);
|
|
||||||
struct wpa_scan_results * hostapd_driver_get_scan_results(
|
|
||||||
struct hostapd_data *hapd);
|
|
||||||
int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
|
|
||||||
int duration);
|
|
||||||
int hostapd_drv_set_key(const char *ifname,
|
|
||||||
struct hostapd_data *hapd,
|
|
||||||
enum wpa_alg alg, const u8 *addr,
|
|
||||||
int key_idx, int set_tx,
|
|
||||||
const u8 *seq, size_t seq_len,
|
|
||||||
const u8 *key, size_t key_len);
|
|
||||||
int hostapd_drv_send_mlme(struct hostapd_data *hapd,
|
|
||||||
const void *msg, size_t len);
|
|
||||||
int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
|
|
||||||
const u8 *addr, int reason);
|
|
||||||
int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
|
|
||||||
const u8 *addr, int reason);
|
|
||||||
|
|
||||||
|
|
||||||
#include "drivers/driver.h"
|
|
||||||
|
|
||||||
static inline int hostapd_drv_set_countermeasures(struct hostapd_data *hapd,
|
|
||||||
int enabled)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL ||
|
|
||||||
hapd->driver->hapd_set_countermeasures == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->hapd_set_countermeasures(hapd->drv_priv, enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int hostapd_drv_set_sta_vlan(const char *ifname,
|
|
||||||
struct hostapd_data *hapd,
|
|
||||||
const u8 *addr, int vlan_id)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_sta_vlan == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_sta_vlan(hapd->drv_priv, addr, ifname,
|
|
||||||
vlan_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int hostapd_drv_get_inact_sec(struct hostapd_data *hapd,
|
|
||||||
const u8 *addr)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->get_inact_sec == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->get_inact_sec(hapd->drv_priv, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int hostapd_drv_sta_remove(struct hostapd_data *hapd,
|
|
||||||
const u8 *addr)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->sta_remove == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->sta_remove(hapd->drv_priv, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int hostapd_drv_hapd_send_eapol(struct hostapd_data *hapd,
|
|
||||||
const u8 *addr, const u8 *data,
|
|
||||||
size_t data_len, int encrypt,
|
|
||||||
u32 flags)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->hapd_send_eapol == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->hapd_send_eapol(hapd->drv_priv, addr, data,
|
|
||||||
data_len, encrypt,
|
|
||||||
hapd->own_addr, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int hostapd_drv_read_sta_data(
|
|
||||||
struct hostapd_data *hapd, struct hostap_sta_driver_data *data,
|
|
||||||
const u8 *addr)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->read_sta_data == NULL)
|
|
||||||
return -1;
|
|
||||||
return hapd->driver->read_sta_data(hapd->drv_priv, data, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int hostapd_drv_sta_clear_stats(struct hostapd_data *hapd,
|
|
||||||
const u8 *addr)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->sta_clear_stats == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->sta_clear_stats(hapd->drv_priv, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int hostapd_drv_set_beacon(struct hostapd_data *hapd,
|
|
||||||
const u8 *head, size_t head_len,
|
|
||||||
const u8 *tail, size_t tail_len,
|
|
||||||
int dtim_period, int beacon_int)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_beacon == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_beacon(hapd->drv_priv,
|
|
||||||
head, head_len, tail, tail_len,
|
|
||||||
dtim_period, beacon_int);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int hostapd_drv_set_radius_acl_auth(struct hostapd_data *hapd,
|
|
||||||
const u8 *mac, int accepted,
|
|
||||||
u32 session_timeout)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL || hapd->driver->set_radius_acl_auth == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_radius_acl_auth(hapd->drv_priv, mac, accepted,
|
|
||||||
session_timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int hostapd_drv_set_radius_acl_expire(struct hostapd_data *hapd,
|
|
||||||
const u8 *mac)
|
|
||||||
{
|
|
||||||
if (hapd->driver == NULL ||
|
|
||||||
hapd->driver->set_radius_acl_expire == NULL)
|
|
||||||
return 0;
|
|
||||||
return hapd->driver->set_radius_acl_expire(hapd->drv_priv, mac);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* AP_DRV_OPS */
|
|
|
@ -1,399 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / AP table
|
|
||||||
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
* Copyright (c) 2003-2004, Instant802 Networks, Inc.
|
|
||||||
* Copyright (c) 2006, Devicescape Software, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "utils/includes.h"
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
|
||||||
#include "utils/eloop.h"
|
|
||||||
#include "common/ieee802_11_defs.h"
|
|
||||||
#include "common/ieee802_11_common.h"
|
|
||||||
#include "drivers/driver.h"
|
|
||||||
#include "hostapd.h"
|
|
||||||
#include "ap_config.h"
|
|
||||||
#include "ieee802_11.h"
|
|
||||||
#include "sta_info.h"
|
|
||||||
#include "beacon.h"
|
|
||||||
#include "ap_list.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* AP list is a double linked list with head->prev pointing to the end of the
|
|
||||||
* list and tail->next = NULL. Entries are moved to the head of the list
|
|
||||||
* whenever a beacon has been received from the AP in question. The tail entry
|
|
||||||
* in this link will thus be the least recently used entry. */
|
|
||||||
|
|
||||||
|
|
||||||
static int ap_list_beacon_olbc(struct hostapd_iface *iface, struct ap_info *ap)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G ||
|
|
||||||
iface->conf->channel != ap->channel)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (ap->erp != -1 && (ap->erp & ERP_INFO_NON_ERP_PRESENT))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
for (i = 0; i < WLAN_SUPP_RATES_MAX; i++) {
|
|
||||||
int rate = (ap->supported_rates[i] & 0x7f) * 5;
|
|
||||||
if (rate == 60 || rate == 90 || rate > 110)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct ap_info * ap_get_ap(struct hostapd_iface *iface, const u8 *ap)
|
|
||||||
{
|
|
||||||
struct ap_info *s;
|
|
||||||
|
|
||||||
s = iface->ap_hash[STA_HASH(ap)];
|
|
||||||
while (s != NULL && os_memcmp(s->addr, ap, ETH_ALEN) != 0)
|
|
||||||
s = s->hnext;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ap_ap_list_add(struct hostapd_iface *iface, struct ap_info *ap)
|
|
||||||
{
|
|
||||||
if (iface->ap_list) {
|
|
||||||
ap->prev = iface->ap_list->prev;
|
|
||||||
iface->ap_list->prev = ap;
|
|
||||||
} else
|
|
||||||
ap->prev = ap;
|
|
||||||
ap->next = iface->ap_list;
|
|
||||||
iface->ap_list = ap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ap_ap_list_del(struct hostapd_iface *iface, struct ap_info *ap)
|
|
||||||
{
|
|
||||||
if (iface->ap_list == ap)
|
|
||||||
iface->ap_list = ap->next;
|
|
||||||
else
|
|
||||||
ap->prev->next = ap->next;
|
|
||||||
|
|
||||||
if (ap->next)
|
|
||||||
ap->next->prev = ap->prev;
|
|
||||||
else if (iface->ap_list)
|
|
||||||
iface->ap_list->prev = ap->prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ap_ap_iter_list_add(struct hostapd_iface *iface,
|
|
||||||
struct ap_info *ap)
|
|
||||||
{
|
|
||||||
if (iface->ap_iter_list) {
|
|
||||||
ap->iter_prev = iface->ap_iter_list->iter_prev;
|
|
||||||
iface->ap_iter_list->iter_prev = ap;
|
|
||||||
} else
|
|
||||||
ap->iter_prev = ap;
|
|
||||||
ap->iter_next = iface->ap_iter_list;
|
|
||||||
iface->ap_iter_list = ap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ap_ap_iter_list_del(struct hostapd_iface *iface,
|
|
||||||
struct ap_info *ap)
|
|
||||||
{
|
|
||||||
if (iface->ap_iter_list == ap)
|
|
||||||
iface->ap_iter_list = ap->iter_next;
|
|
||||||
else
|
|
||||||
ap->iter_prev->iter_next = ap->iter_next;
|
|
||||||
|
|
||||||
if (ap->iter_next)
|
|
||||||
ap->iter_next->iter_prev = ap->iter_prev;
|
|
||||||
else if (iface->ap_iter_list)
|
|
||||||
iface->ap_iter_list->iter_prev = ap->iter_prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ap_ap_hash_add(struct hostapd_iface *iface, struct ap_info *ap)
|
|
||||||
{
|
|
||||||
ap->hnext = iface->ap_hash[STA_HASH(ap->addr)];
|
|
||||||
iface->ap_hash[STA_HASH(ap->addr)] = ap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ap_ap_hash_del(struct hostapd_iface *iface, struct ap_info *ap)
|
|
||||||
{
|
|
||||||
struct ap_info *s;
|
|
||||||
|
|
||||||
s = iface->ap_hash[STA_HASH(ap->addr)];
|
|
||||||
if (s == NULL) return;
|
|
||||||
if (os_memcmp(s->addr, ap->addr, ETH_ALEN) == 0) {
|
|
||||||
iface->ap_hash[STA_HASH(ap->addr)] = s->hnext;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (s->hnext != NULL &&
|
|
||||||
os_memcmp(s->hnext->addr, ap->addr, ETH_ALEN) != 0)
|
|
||||||
s = s->hnext;
|
|
||||||
if (s->hnext != NULL)
|
|
||||||
s->hnext = s->hnext->hnext;
|
|
||||||
else
|
|
||||||
printf("AP: could not remove AP " MACSTR " from hash table\n",
|
|
||||||
MAC2STR(ap->addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ap_free_ap(struct hostapd_iface *iface, struct ap_info *ap)
|
|
||||||
{
|
|
||||||
ap_ap_hash_del(iface, ap);
|
|
||||||
ap_ap_list_del(iface, ap);
|
|
||||||
ap_ap_iter_list_del(iface, ap);
|
|
||||||
|
|
||||||
iface->num_ap--;
|
|
||||||
os_free(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_free_aps(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
struct ap_info *ap, *prev;
|
|
||||||
|
|
||||||
ap = iface->ap_list;
|
|
||||||
|
|
||||||
while (ap) {
|
|
||||||
prev = ap;
|
|
||||||
ap = ap->next;
|
|
||||||
ap_free_ap(iface, prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
iface->ap_list = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int ap_ap_for_each(struct hostapd_iface *iface,
|
|
||||||
int (*func)(struct ap_info *s, void *data), void *data)
|
|
||||||
{
|
|
||||||
struct ap_info *s;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
s = iface->ap_list;
|
|
||||||
|
|
||||||
while (s) {
|
|
||||||
ret = func(s, data);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
s = s->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct ap_info * ap_ap_add(struct hostapd_iface *iface, const u8 *addr)
|
|
||||||
{
|
|
||||||
struct ap_info *ap;
|
|
||||||
|
|
||||||
ap = os_zalloc(sizeof(struct ap_info));
|
|
||||||
if (ap == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* initialize AP info data */
|
|
||||||
os_memcpy(ap->addr, addr, ETH_ALEN);
|
|
||||||
ap_ap_list_add(iface, ap);
|
|
||||||
iface->num_ap++;
|
|
||||||
ap_ap_hash_add(iface, ap);
|
|
||||||
ap_ap_iter_list_add(iface, ap);
|
|
||||||
|
|
||||||
if (iface->num_ap > iface->conf->ap_table_max_size && ap != ap->prev) {
|
|
||||||
wpa_printf(MSG_DEBUG, "Removing the least recently used AP "
|
|
||||||
MACSTR " from AP table", MAC2STR(ap->prev->addr));
|
|
||||||
ap_free_ap(iface, ap->prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ap_list_process_beacon(struct hostapd_iface *iface,
|
|
||||||
const struct ieee80211_mgmt *mgmt,
|
|
||||||
struct ieee802_11_elems *elems,
|
|
||||||
struct hostapd_frame_info *fi)
|
|
||||||
{
|
|
||||||
struct ap_info *ap;
|
|
||||||
struct os_time now;
|
|
||||||
int new_ap = 0;
|
|
||||||
size_t len;
|
|
||||||
int set_beacon = 0;
|
|
||||||
|
|
||||||
if (iface->conf->ap_table_max_size < 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ap = ap_get_ap(iface, mgmt->bssid);
|
|
||||||
if (!ap) {
|
|
||||||
ap = ap_ap_add(iface, mgmt->bssid);
|
|
||||||
if (!ap) {
|
|
||||||
printf("Failed to allocate AP information entry\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
new_ap = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ap->beacon_int = le_to_host16(mgmt->u.beacon.beacon_int);
|
|
||||||
ap->capability = le_to_host16(mgmt->u.beacon.capab_info);
|
|
||||||
|
|
||||||
if (elems->ssid) {
|
|
||||||
len = elems->ssid_len;
|
|
||||||
if (len >= sizeof(ap->ssid))
|
|
||||||
len = sizeof(ap->ssid) - 1;
|
|
||||||
os_memcpy(ap->ssid, elems->ssid, len);
|
|
||||||
ap->ssid[len] = '\0';
|
|
||||||
ap->ssid_len = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_memset(ap->supported_rates, 0, WLAN_SUPP_RATES_MAX);
|
|
||||||
len = 0;
|
|
||||||
if (elems->supp_rates) {
|
|
||||||
len = elems->supp_rates_len;
|
|
||||||
if (len > WLAN_SUPP_RATES_MAX)
|
|
||||||
len = WLAN_SUPP_RATES_MAX;
|
|
||||||
os_memcpy(ap->supported_rates, elems->supp_rates, len);
|
|
||||||
}
|
|
||||||
if (elems->ext_supp_rates) {
|
|
||||||
int len2;
|
|
||||||
if (len + elems->ext_supp_rates_len > WLAN_SUPP_RATES_MAX)
|
|
||||||
len2 = WLAN_SUPP_RATES_MAX - len;
|
|
||||||
else
|
|
||||||
len2 = elems->ext_supp_rates_len;
|
|
||||||
os_memcpy(ap->supported_rates + len, elems->ext_supp_rates,
|
|
||||||
len2);
|
|
||||||
}
|
|
||||||
|
|
||||||
ap->wpa = elems->wpa_ie != NULL;
|
|
||||||
|
|
||||||
if (elems->erp_info && elems->erp_info_len == 1)
|
|
||||||
ap->erp = elems->erp_info[0];
|
|
||||||
else
|
|
||||||
ap->erp = -1;
|
|
||||||
|
|
||||||
if (elems->ds_params && elems->ds_params_len == 1)
|
|
||||||
ap->channel = elems->ds_params[0];
|
|
||||||
else if (fi)
|
|
||||||
ap->channel = fi->channel;
|
|
||||||
|
|
||||||
if (elems->ht_capabilities)
|
|
||||||
ap->ht_support = 1;
|
|
||||||
else
|
|
||||||
ap->ht_support = 0;
|
|
||||||
|
|
||||||
ap->num_beacons++;
|
|
||||||
os_get_time(&now);
|
|
||||||
ap->last_beacon = now.sec;
|
|
||||||
if (fi) {
|
|
||||||
ap->ssi_signal = fi->ssi_signal;
|
|
||||||
ap->datarate = fi->datarate;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!new_ap && ap != iface->ap_list) {
|
|
||||||
/* move AP entry into the beginning of the list so that the
|
|
||||||
* oldest entry is always in the end of the list */
|
|
||||||
ap_ap_list_del(iface, ap);
|
|
||||||
ap_ap_list_add(iface, ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!iface->olbc &&
|
|
||||||
ap_list_beacon_olbc(iface, ap)) {
|
|
||||||
iface->olbc = 1;
|
|
||||||
wpa_printf(MSG_DEBUG, "OLBC AP detected: " MACSTR " - enable "
|
|
||||||
"protection", MAC2STR(ap->addr));
|
|
||||||
set_beacon++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211N
|
|
||||||
if (!iface->olbc_ht && !ap->ht_support) {
|
|
||||||
iface->olbc_ht = 1;
|
|
||||||
hostapd_ht_operation_update(iface);
|
|
||||||
wpa_printf(MSG_DEBUG, "OLBC HT AP detected: " MACSTR
|
|
||||||
" - enable protection", MAC2STR(ap->addr));
|
|
||||||
set_beacon++;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_IEEE80211N */
|
|
||||||
|
|
||||||
if (set_beacon)
|
|
||||||
ieee802_11_set_beacons(iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ap_list_timer(void *eloop_ctx, void *timeout_ctx)
|
|
||||||
{
|
|
||||||
struct hostapd_iface *iface = eloop_ctx;
|
|
||||||
struct os_time now;
|
|
||||||
struct ap_info *ap;
|
|
||||||
int set_beacon = 0;
|
|
||||||
|
|
||||||
eloop_register_timeout(10, 0, ap_list_timer, iface, NULL);
|
|
||||||
|
|
||||||
if (!iface->ap_list)
|
|
||||||
return;
|
|
||||||
|
|
||||||
os_get_time(&now);
|
|
||||||
|
|
||||||
while (iface->ap_list) {
|
|
||||||
ap = iface->ap_list->prev;
|
|
||||||
if (ap->last_beacon + iface->conf->ap_table_expiration_time >=
|
|
||||||
now.sec)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ap_free_ap(iface, ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iface->olbc || iface->olbc_ht) {
|
|
||||||
int olbc = 0;
|
|
||||||
int olbc_ht = 0;
|
|
||||||
|
|
||||||
ap = iface->ap_list;
|
|
||||||
while (ap && (olbc == 0 || olbc_ht == 0)) {
|
|
||||||
if (ap_list_beacon_olbc(iface, ap))
|
|
||||||
olbc = 1;
|
|
||||||
if (!ap->ht_support)
|
|
||||||
olbc_ht = 1;
|
|
||||||
ap = ap->next;
|
|
||||||
}
|
|
||||||
if (!olbc && iface->olbc) {
|
|
||||||
wpa_printf(MSG_DEBUG, "OLBC not detected anymore");
|
|
||||||
iface->olbc = 0;
|
|
||||||
set_beacon++;
|
|
||||||
}
|
|
||||||
#ifdef CONFIG_IEEE80211N
|
|
||||||
if (!olbc_ht && iface->olbc_ht) {
|
|
||||||
wpa_printf(MSG_DEBUG, "OLBC HT not detected anymore");
|
|
||||||
iface->olbc_ht = 0;
|
|
||||||
hostapd_ht_operation_update(iface);
|
|
||||||
set_beacon++;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_IEEE80211N */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (set_beacon)
|
|
||||||
ieee802_11_set_beacons(iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int ap_list_init(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
eloop_register_timeout(10, 0, ap_list_timer, iface, NULL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ap_list_deinit(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
eloop_cancel_timeout(ap_list_timer, iface, NULL);
|
|
||||||
hostapd_free_aps(iface);
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / AP table
|
|
||||||
* Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
|
|
||||||
* Copyright (c) 2003-2004, Instant802 Networks, Inc.
|
|
||||||
* Copyright (c) 2006, Devicescape Software, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef AP_LIST_H
|
|
||||||
#define AP_LIST_H
|
|
||||||
|
|
||||||
struct ap_info {
|
|
||||||
/* Note: next/prev pointers are updated whenever a new beacon is
|
|
||||||
* received because these are used to find the least recently used
|
|
||||||
* entries. iter_next/iter_prev are updated only when adding new BSSes
|
|
||||||
* and when removing old ones. These should be used when iterating
|
|
||||||
* through the table in a manner that allows beacons to be received
|
|
||||||
* during the iteration. */
|
|
||||||
struct ap_info *next; /* next entry in AP list */
|
|
||||||
struct ap_info *prev; /* previous entry in AP list */
|
|
||||||
struct ap_info *hnext; /* next entry in hash table list */
|
|
||||||
struct ap_info *iter_next; /* next entry in AP iteration list */
|
|
||||||
struct ap_info *iter_prev; /* previous entry in AP iteration list */
|
|
||||||
u8 addr[6];
|
|
||||||
u16 beacon_int;
|
|
||||||
u16 capability;
|
|
||||||
u8 supported_rates[WLAN_SUPP_RATES_MAX];
|
|
||||||
u8 ssid[33];
|
|
||||||
size_t ssid_len;
|
|
||||||
int wpa;
|
|
||||||
int erp; /* ERP Info or -1 if ERP info element not present */
|
|
||||||
|
|
||||||
int channel;
|
|
||||||
int datarate; /* in 100 kbps */
|
|
||||||
int ssi_signal;
|
|
||||||
|
|
||||||
int ht_support;
|
|
||||||
|
|
||||||
unsigned int num_beacons; /* number of beacon frames received */
|
|
||||||
os_time_t last_beacon;
|
|
||||||
|
|
||||||
int already_seen; /* whether API call AP-NEW has already fetched
|
|
||||||
* information about this AP */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ieee802_11_elems;
|
|
||||||
struct hostapd_frame_info;
|
|
||||||
|
|
||||||
struct ap_info * ap_get_ap(struct hostapd_iface *iface, const u8 *sta);
|
|
||||||
int ap_ap_for_each(struct hostapd_iface *iface,
|
|
||||||
int (*func)(struct ap_info *s, void *data), void *data);
|
|
||||||
void ap_list_process_beacon(struct hostapd_iface *iface,
|
|
||||||
const struct ieee80211_mgmt *mgmt,
|
|
||||||
struct ieee802_11_elems *elems,
|
|
||||||
struct hostapd_frame_info *fi);
|
|
||||||
#ifdef NEED_AP_MLME
|
|
||||||
int ap_list_init(struct hostapd_iface *iface);
|
|
||||||
void ap_list_deinit(struct hostapd_iface *iface);
|
|
||||||
#else /* NEED_AP_MLME */
|
|
||||||
static inline int ap_list_init(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ap_list_deinit(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif /* NEED_AP_MLME */
|
|
||||||
|
|
||||||
#endif /* AP_LIST_H */
|
|
|
@ -1,184 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / IEEE 802.11 MLME
|
|
||||||
* Copyright 2003-2006, Jouni Malinen <j@w1.fi>
|
|
||||||
* Copyright 2003-2004, Instant802 Networks, Inc.
|
|
||||||
* Copyright 2005-2006, Devicescape Software, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "utils/includes.h"
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
|
||||||
#include "common/ieee802_11_defs.h"
|
|
||||||
#include "ieee802_11.h"
|
|
||||||
#include "wpa_auth.h"
|
|
||||||
#include "sta_info.h"
|
|
||||||
#include "ap_mlme.h"
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CONFIG_NO_HOSTAPD_LOGGER
|
|
||||||
static const char * mlme_auth_alg_str(int alg)
|
|
||||||
{
|
|
||||||
switch (alg) {
|
|
||||||
case WLAN_AUTH_OPEN:
|
|
||||||
return "OPEN_SYSTEM";
|
|
||||||
case WLAN_AUTH_SHARED_KEY:
|
|
||||||
return "SHARED_KEY";
|
|
||||||
case WLAN_AUTH_FT:
|
|
||||||
return "FT";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_NO_HOSTAPD_LOGGER */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mlme_authenticate_indication - Report the establishment of an authentication
|
|
||||||
* relationship with a specific peer MAC entity
|
|
||||||
* @hapd: BSS data
|
|
||||||
* @sta: peer STA data
|
|
||||||
*
|
|
||||||
* MLME calls this function as a result of the establishment of an
|
|
||||||
* authentication relationship with a specific peer MAC entity that
|
|
||||||
* resulted from an authentication procedure that was initiated by
|
|
||||||
* that specific peer MAC entity.
|
|
||||||
*
|
|
||||||
* PeerSTAAddress = sta->addr
|
|
||||||
* AuthenticationType = sta->auth_alg (WLAN_AUTH_OPEN / WLAN_AUTH_SHARED_KEY)
|
|
||||||
*/
|
|
||||||
void mlme_authenticate_indication(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta)
|
|
||||||
{
|
|
||||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME,
|
|
||||||
HOSTAPD_LEVEL_DEBUG,
|
|
||||||
"MLME-AUTHENTICATE.indication(" MACSTR ", %s)",
|
|
||||||
MAC2STR(sta->addr), mlme_auth_alg_str(sta->auth_alg));
|
|
||||||
if (sta->auth_alg != WLAN_AUTH_FT && !(sta->flags & WLAN_STA_MFP))
|
|
||||||
mlme_deletekeys_request(hapd, sta);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mlme_deauthenticate_indication - Report the invalidation of an
|
|
||||||
* authentication relationship with a specific peer MAC entity
|
|
||||||
* @hapd: BSS data
|
|
||||||
* @sta: Peer STA data
|
|
||||||
* @reason_code: ReasonCode from Deauthentication frame
|
|
||||||
*
|
|
||||||
* MLME calls this function as a result of the invalidation of an
|
|
||||||
* authentication relationship with a specific peer MAC entity.
|
|
||||||
*
|
|
||||||
* PeerSTAAddress = sta->addr
|
|
||||||
*/
|
|
||||||
void mlme_deauthenticate_indication(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta, u16 reason_code)
|
|
||||||
{
|
|
||||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME,
|
|
||||||
HOSTAPD_LEVEL_DEBUG,
|
|
||||||
"MLME-DEAUTHENTICATE.indication(" MACSTR ", %d)",
|
|
||||||
MAC2STR(sta->addr), reason_code);
|
|
||||||
mlme_deletekeys_request(hapd, sta);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mlme_associate_indication - Report the establishment of an association with
|
|
||||||
* a specific peer MAC entity
|
|
||||||
* @hapd: BSS data
|
|
||||||
* @sta: peer STA data
|
|
||||||
*
|
|
||||||
* MLME calls this function as a result of the establishment of an
|
|
||||||
* association with a specific peer MAC entity that resulted from an
|
|
||||||
* association procedure that was initiated by that specific peer MAC entity.
|
|
||||||
*
|
|
||||||
* PeerSTAAddress = sta->addr
|
|
||||||
*/
|
|
||||||
void mlme_associate_indication(struct hostapd_data *hapd, struct sta_info *sta)
|
|
||||||
{
|
|
||||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME,
|
|
||||||
HOSTAPD_LEVEL_DEBUG,
|
|
||||||
"MLME-ASSOCIATE.indication(" MACSTR ")",
|
|
||||||
MAC2STR(sta->addr));
|
|
||||||
if (sta->auth_alg != WLAN_AUTH_FT)
|
|
||||||
mlme_deletekeys_request(hapd, sta);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mlme_reassociate_indication - Report the establishment of an reassociation
|
|
||||||
* with a specific peer MAC entity
|
|
||||||
* @hapd: BSS data
|
|
||||||
* @sta: peer STA data
|
|
||||||
*
|
|
||||||
* MLME calls this function as a result of the establishment of an
|
|
||||||
* reassociation with a specific peer MAC entity that resulted from a
|
|
||||||
* reassociation procedure that was initiated by that specific peer MAC entity.
|
|
||||||
*
|
|
||||||
* PeerSTAAddress = sta->addr
|
|
||||||
*
|
|
||||||
* sta->previous_ap contains the "Current AP" information from ReassocReq.
|
|
||||||
*/
|
|
||||||
void mlme_reassociate_indication(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta)
|
|
||||||
{
|
|
||||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME,
|
|
||||||
HOSTAPD_LEVEL_DEBUG,
|
|
||||||
"MLME-REASSOCIATE.indication(" MACSTR ")",
|
|
||||||
MAC2STR(sta->addr));
|
|
||||||
if (sta->auth_alg != WLAN_AUTH_FT)
|
|
||||||
mlme_deletekeys_request(hapd, sta);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mlme_disassociate_indication - Report disassociation with a specific peer
|
|
||||||
* MAC entity
|
|
||||||
* @hapd: BSS data
|
|
||||||
* @sta: Peer STA data
|
|
||||||
* @reason_code: ReasonCode from Disassociation frame
|
|
||||||
*
|
|
||||||
* MLME calls this function as a result of the invalidation of an association
|
|
||||||
* relationship with a specific peer MAC entity.
|
|
||||||
*
|
|
||||||
* PeerSTAAddress = sta->addr
|
|
||||||
*/
|
|
||||||
void mlme_disassociate_indication(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta, u16 reason_code)
|
|
||||||
{
|
|
||||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME,
|
|
||||||
HOSTAPD_LEVEL_DEBUG,
|
|
||||||
"MLME-DISASSOCIATE.indication(" MACSTR ", %d)",
|
|
||||||
MAC2STR(sta->addr), reason_code);
|
|
||||||
mlme_deletekeys_request(hapd, sta);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void mlme_michaelmicfailure_indication(struct hostapd_data *hapd,
|
|
||||||
const u8 *addr)
|
|
||||||
{
|
|
||||||
hostapd_logger(hapd, addr, HOSTAPD_MODULE_MLME,
|
|
||||||
HOSTAPD_LEVEL_DEBUG,
|
|
||||||
"MLME-MichaelMICFailure.indication(" MACSTR ")",
|
|
||||||
MAC2STR(addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void mlme_deletekeys_request(struct hostapd_data *hapd, struct sta_info *sta)
|
|
||||||
{
|
|
||||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_MLME,
|
|
||||||
HOSTAPD_LEVEL_DEBUG,
|
|
||||||
"MLME-DELETEKEYS.request(" MACSTR ")",
|
|
||||||
MAC2STR(sta->addr));
|
|
||||||
|
|
||||||
if (sta->wpa_sm)
|
|
||||||
wpa_remove_ptk(sta->wpa_sm);
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / IEEE 802.11 MLME
|
|
||||||
* Copyright 2003, Jouni Malinen <j@w1.fi>
|
|
||||||
* Copyright 2003-2004, Instant802 Networks, Inc.
|
|
||||||
* Copyright 2005-2006, Devicescape Software, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MLME_H
|
|
||||||
#define MLME_H
|
|
||||||
|
|
||||||
void mlme_authenticate_indication(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta);
|
|
||||||
|
|
||||||
void mlme_deauthenticate_indication(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta, u16 reason_code);
|
|
||||||
|
|
||||||
void mlme_associate_indication(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta);
|
|
||||||
|
|
||||||
void mlme_reassociate_indication(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta);
|
|
||||||
|
|
||||||
void mlme_disassociate_indication(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta, u16 reason_code);
|
|
||||||
|
|
||||||
void mlme_michaelmicfailure_indication(struct hostapd_data *hapd,
|
|
||||||
const u8 *addr);
|
|
||||||
|
|
||||||
void mlme_deletekeys_request(struct hostapd_data *hapd, struct sta_info *sta);
|
|
||||||
|
|
||||||
#endif /* MLME_H */
|
|
|
@ -1,217 +0,0 @@
|
||||||
/*
|
|
||||||
* Authentication server setup
|
|
||||||
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "utils/includes.h"
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
|
||||||
#include "crypto/tls.h"
|
|
||||||
#include "eap_server/eap.h"
|
|
||||||
#include "eap_server/eap_sim_db.h"
|
|
||||||
#include "eapol_auth/eapol_auth_sm.h"
|
|
||||||
#include "radius/radius_server.h"
|
|
||||||
#include "hostapd.h"
|
|
||||||
#include "ap_config.h"
|
|
||||||
#include "sta_info.h"
|
|
||||||
#include "authsrv.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(EAP_SERVER_SIM) || defined(EAP_SERVER_AKA)
|
|
||||||
#define EAP_SIM_DB
|
|
||||||
#endif /* EAP_SERVER_SIM || EAP_SERVER_AKA */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef EAP_SIM_DB
|
|
||||||
static int hostapd_sim_db_cb_sta(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta, void *ctx)
|
|
||||||
{
|
|
||||||
if (eapol_auth_eap_pending_cb(sta->eapol_sm, ctx) == 0)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_sim_db_cb(void *ctx, void *session_ctx)
|
|
||||||
{
|
|
||||||
struct hostapd_data *hapd = ctx;
|
|
||||||
if (ap_for_each_sta(hapd, hostapd_sim_db_cb_sta, session_ctx) == 0) {
|
|
||||||
#ifdef RADIUS_SERVER
|
|
||||||
radius_server_eap_pending_cb(hapd->radius_srv, session_ctx);
|
|
||||||
#endif /* RADIUS_SERVER */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* EAP_SIM_DB */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef RADIUS_SERVER
|
|
||||||
|
|
||||||
static int hostapd_radius_get_eap_user(void *ctx, const u8 *identity,
|
|
||||||
size_t identity_len, int phase2,
|
|
||||||
struct eap_user *user)
|
|
||||||
{
|
|
||||||
const struct hostapd_eap_user *eap_user;
|
|
||||||
int i, count;
|
|
||||||
|
|
||||||
eap_user = hostapd_get_eap_user(ctx, identity, identity_len, phase2);
|
|
||||||
if (eap_user == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (user == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
os_memset(user, 0, sizeof(*user));
|
|
||||||
count = EAP_USER_MAX_METHODS;
|
|
||||||
if (count > EAP_MAX_METHODS)
|
|
||||||
count = EAP_MAX_METHODS;
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
user->methods[i].vendor = eap_user->methods[i].vendor;
|
|
||||||
user->methods[i].method = eap_user->methods[i].method;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eap_user->password) {
|
|
||||||
user->password = os_malloc(eap_user->password_len);
|
|
||||||
if (user->password == NULL)
|
|
||||||
return -1;
|
|
||||||
os_memcpy(user->password, eap_user->password,
|
|
||||||
eap_user->password_len);
|
|
||||||
user->password_len = eap_user->password_len;
|
|
||||||
user->password_hash = eap_user->password_hash;
|
|
||||||
}
|
|
||||||
user->force_version = eap_user->force_version;
|
|
||||||
user->ttls_auth = eap_user->ttls_auth;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_setup_radius_srv(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
struct radius_server_conf srv;
|
|
||||||
struct hostapd_bss_config *conf = hapd->conf;
|
|
||||||
os_memset(&srv, 0, sizeof(srv));
|
|
||||||
srv.client_file = conf->radius_server_clients;
|
|
||||||
srv.auth_port = conf->radius_server_auth_port;
|
|
||||||
srv.conf_ctx = conf;
|
|
||||||
srv.eap_sim_db_priv = hapd->eap_sim_db_priv;
|
|
||||||
srv.ssl_ctx = hapd->ssl_ctx;
|
|
||||||
srv.msg_ctx = hapd->msg_ctx;
|
|
||||||
srv.pac_opaque_encr_key = conf->pac_opaque_encr_key;
|
|
||||||
srv.eap_fast_a_id = conf->eap_fast_a_id;
|
|
||||||
srv.eap_fast_a_id_len = conf->eap_fast_a_id_len;
|
|
||||||
srv.eap_fast_a_id_info = conf->eap_fast_a_id_info;
|
|
||||||
srv.eap_fast_prov = conf->eap_fast_prov;
|
|
||||||
srv.pac_key_lifetime = conf->pac_key_lifetime;
|
|
||||||
srv.pac_key_refresh_time = conf->pac_key_refresh_time;
|
|
||||||
srv.eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
|
|
||||||
srv.tnc = conf->tnc;
|
|
||||||
srv.wps = hapd->wps;
|
|
||||||
srv.ipv6 = conf->radius_server_ipv6;
|
|
||||||
srv.get_eap_user = hostapd_radius_get_eap_user;
|
|
||||||
srv.eap_req_id_text = conf->eap_req_id_text;
|
|
||||||
srv.eap_req_id_text_len = conf->eap_req_id_text_len;
|
|
||||||
srv.pwd_group = conf->pwd_group;
|
|
||||||
|
|
||||||
hapd->radius_srv = radius_server_init(&srv);
|
|
||||||
if (hapd->radius_srv == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "RADIUS server initialization failed.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* RADIUS_SERVER */
|
|
||||||
|
|
||||||
|
|
||||||
int authsrv_init(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
#ifdef EAP_TLS_FUNCS
|
|
||||||
if (hapd->conf->eap_server &&
|
|
||||||
(hapd->conf->ca_cert || hapd->conf->server_cert ||
|
|
||||||
hapd->conf->dh_file)) {
|
|
||||||
struct tls_connection_params params;
|
|
||||||
|
|
||||||
hapd->ssl_ctx = tls_init(NULL);
|
|
||||||
if (hapd->ssl_ctx == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to initialize TLS");
|
|
||||||
authsrv_deinit(hapd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_memset(¶ms, 0, sizeof(params));
|
|
||||||
params.ca_cert = hapd->conf->ca_cert;
|
|
||||||
params.client_cert = hapd->conf->server_cert;
|
|
||||||
params.private_key = hapd->conf->private_key;
|
|
||||||
params.private_key_passwd = hapd->conf->private_key_passwd;
|
|
||||||
params.dh_file = hapd->conf->dh_file;
|
|
||||||
|
|
||||||
if (tls_global_set_params(hapd->ssl_ctx, ¶ms)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to set TLS parameters");
|
|
||||||
authsrv_deinit(hapd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tls_global_set_verify(hapd->ssl_ctx,
|
|
||||||
hapd->conf->check_crl)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to enable check_crl");
|
|
||||||
authsrv_deinit(hapd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* EAP_TLS_FUNCS */
|
|
||||||
|
|
||||||
#ifdef EAP_SIM_DB
|
|
||||||
if (hapd->conf->eap_sim_db) {
|
|
||||||
hapd->eap_sim_db_priv =
|
|
||||||
eap_sim_db_init(hapd->conf->eap_sim_db,
|
|
||||||
hostapd_sim_db_cb, hapd);
|
|
||||||
if (hapd->eap_sim_db_priv == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to initialize EAP-SIM "
|
|
||||||
"database interface");
|
|
||||||
authsrv_deinit(hapd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* EAP_SIM_DB */
|
|
||||||
|
|
||||||
#ifdef RADIUS_SERVER
|
|
||||||
if (hapd->conf->radius_server_clients &&
|
|
||||||
hostapd_setup_radius_srv(hapd))
|
|
||||||
return -1;
|
|
||||||
#endif /* RADIUS_SERVER */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void authsrv_deinit(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
#ifdef RADIUS_SERVER
|
|
||||||
radius_server_deinit(hapd->radius_srv);
|
|
||||||
hapd->radius_srv = NULL;
|
|
||||||
#endif /* RADIUS_SERVER */
|
|
||||||
|
|
||||||
#ifdef EAP_TLS_FUNCS
|
|
||||||
if (hapd->ssl_ctx) {
|
|
||||||
tls_deinit(hapd->ssl_ctx);
|
|
||||||
hapd->ssl_ctx = NULL;
|
|
||||||
}
|
|
||||||
#endif /* EAP_TLS_FUNCS */
|
|
||||||
|
|
||||||
#ifdef EAP_SIM_DB
|
|
||||||
if (hapd->eap_sim_db_priv) {
|
|
||||||
eap_sim_db_deinit(hapd->eap_sim_db_priv);
|
|
||||||
hapd->eap_sim_db_priv = NULL;
|
|
||||||
}
|
|
||||||
#endif /* EAP_SIM_DB */
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
/*
|
|
||||||
* Authentication server setup
|
|
||||||
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef AUTHSRV_H
|
|
||||||
#define AUTHSRV_H
|
|
||||||
|
|
||||||
int authsrv_init(struct hostapd_data *hapd);
|
|
||||||
void authsrv_deinit(struct hostapd_data *hapd);
|
|
||||||
|
|
||||||
#endif /* AUTHSRV_H */
|
|
|
@ -1,540 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / IEEE 802.11 Management: Beacon and Probe Request/Response
|
|
||||||
* Copyright (c) 2002-2004, Instant802 Networks, Inc.
|
|
||||||
* Copyright (c) 2005-2006, Devicescape Software, Inc.
|
|
||||||
* Copyright (c) 2008-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "utils/includes.h"
|
|
||||||
|
|
||||||
#ifndef CONFIG_NATIVE_WINDOWS
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
|
||||||
#include "common/ieee802_11_defs.h"
|
|
||||||
#include "common/ieee802_11_common.h"
|
|
||||||
#include "drivers/driver.h"
|
|
||||||
#include "wps/wps_defs.h"
|
|
||||||
#include "p2p/p2p.h"
|
|
||||||
#include "hostapd.h"
|
|
||||||
#include "ieee802_11.h"
|
|
||||||
#include "wpa_auth.h"
|
|
||||||
#include "wmm.h"
|
|
||||||
#include "ap_config.h"
|
|
||||||
#include "sta_info.h"
|
|
||||||
#include "p2p_hostapd.h"
|
|
||||||
#include "ap_drv_ops.h"
|
|
||||||
#include "beacon.h"
|
|
||||||
|
|
||||||
|
|
||||||
static u8 ieee802_11_erp_info(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
u8 erp = 0;
|
|
||||||
|
|
||||||
if (hapd->iface->current_mode == NULL ||
|
|
||||||
hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
switch (hapd->iconf->cts_protection_type) {
|
|
||||||
case CTS_PROTECTION_FORCE_ENABLED:
|
|
||||||
erp |= ERP_INFO_NON_ERP_PRESENT | ERP_INFO_USE_PROTECTION;
|
|
||||||
break;
|
|
||||||
case CTS_PROTECTION_FORCE_DISABLED:
|
|
||||||
erp = 0;
|
|
||||||
break;
|
|
||||||
case CTS_PROTECTION_AUTOMATIC:
|
|
||||||
if (hapd->iface->olbc)
|
|
||||||
erp |= ERP_INFO_USE_PROTECTION;
|
|
||||||
/* continue */
|
|
||||||
case CTS_PROTECTION_AUTOMATIC_NO_OLBC:
|
|
||||||
if (hapd->iface->num_sta_non_erp > 0) {
|
|
||||||
erp |= ERP_INFO_NON_ERP_PRESENT |
|
|
||||||
ERP_INFO_USE_PROTECTION;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (hapd->iface->num_sta_no_short_preamble > 0 ||
|
|
||||||
hapd->iconf->preamble == LONG_PREAMBLE)
|
|
||||||
erp |= ERP_INFO_BARKER_PREAMBLE_MODE;
|
|
||||||
|
|
||||||
return erp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static u8 * hostapd_eid_ds_params(struct hostapd_data *hapd, u8 *eid)
|
|
||||||
{
|
|
||||||
*eid++ = WLAN_EID_DS_PARAMS;
|
|
||||||
*eid++ = 1;
|
|
||||||
*eid++ = hapd->iconf->channel;
|
|
||||||
return eid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static u8 * hostapd_eid_erp_info(struct hostapd_data *hapd, u8 *eid)
|
|
||||||
{
|
|
||||||
if (hapd->iface->current_mode == NULL ||
|
|
||||||
hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
|
|
||||||
return eid;
|
|
||||||
|
|
||||||
/* Set NonERP_present and use_protection bits if there
|
|
||||||
* are any associated NonERP stations. */
|
|
||||||
/* TODO: use_protection bit can be set to zero even if
|
|
||||||
* there are NonERP stations present. This optimization
|
|
||||||
* might be useful if NonERP stations are "quiet".
|
|
||||||
* See 802.11g/D6 E-1 for recommended practice.
|
|
||||||
* In addition, Non ERP present might be set, if AP detects Non ERP
|
|
||||||
* operation on other APs. */
|
|
||||||
|
|
||||||
/* Add ERP Information element */
|
|
||||||
*eid++ = WLAN_EID_ERP_INFO;
|
|
||||||
*eid++ = 1;
|
|
||||||
*eid++ = ieee802_11_erp_info(hapd);
|
|
||||||
|
|
||||||
return eid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static u8 * hostapd_eid_country_add(u8 *pos, u8 *end, int chan_spacing,
|
|
||||||
struct hostapd_channel_data *start,
|
|
||||||
struct hostapd_channel_data *prev)
|
|
||||||
{
|
|
||||||
if (end - pos < 3)
|
|
||||||
return pos;
|
|
||||||
|
|
||||||
/* first channel number */
|
|
||||||
*pos++ = start->chan;
|
|
||||||
/* number of channels */
|
|
||||||
*pos++ = (prev->chan - start->chan) / chan_spacing + 1;
|
|
||||||
/* maximum transmit power level */
|
|
||||||
*pos++ = start->max_tx_power;
|
|
||||||
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
|
|
||||||
int max_len)
|
|
||||||
{
|
|
||||||
u8 *pos = eid;
|
|
||||||
u8 *end = eid + max_len;
|
|
||||||
int i;
|
|
||||||
struct hostapd_hw_modes *mode;
|
|
||||||
struct hostapd_channel_data *start, *prev;
|
|
||||||
int chan_spacing = 1;
|
|
||||||
|
|
||||||
if (!hapd->iconf->ieee80211d || max_len < 6 ||
|
|
||||||
hapd->iface->current_mode == NULL)
|
|
||||||
return eid;
|
|
||||||
|
|
||||||
*pos++ = WLAN_EID_COUNTRY;
|
|
||||||
pos++; /* length will be set later */
|
|
||||||
os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */
|
|
||||||
pos += 3;
|
|
||||||
|
|
||||||
mode = hapd->iface->current_mode;
|
|
||||||
if (mode->mode == HOSTAPD_MODE_IEEE80211A)
|
|
||||||
chan_spacing = 4;
|
|
||||||
|
|
||||||
start = prev = NULL;
|
|
||||||
for (i = 0; i < mode->num_channels; i++) {
|
|
||||||
struct hostapd_channel_data *chan = &mode->channels[i];
|
|
||||||
if (chan->flag & HOSTAPD_CHAN_DISABLED)
|
|
||||||
continue;
|
|
||||||
if (start && prev &&
|
|
||||||
prev->chan + chan_spacing == chan->chan &&
|
|
||||||
start->max_tx_power == chan->max_tx_power) {
|
|
||||||
prev = chan;
|
|
||||||
continue; /* can use same entry */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start) {
|
|
||||||
pos = hostapd_eid_country_add(pos, end, chan_spacing,
|
|
||||||
start, prev);
|
|
||||||
start = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Start new group */
|
|
||||||
start = prev = chan;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start) {
|
|
||||||
pos = hostapd_eid_country_add(pos, end, chan_spacing,
|
|
||||||
start, prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((pos - eid) & 1) {
|
|
||||||
if (end - pos < 1)
|
|
||||||
return eid;
|
|
||||||
*pos++ = 0; /* pad for 16-bit alignment */
|
|
||||||
}
|
|
||||||
|
|
||||||
eid[1] = (pos - eid) - 2;
|
|
||||||
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static u8 * hostapd_eid_wpa(struct hostapd_data *hapd, u8 *eid, size_t len,
|
|
||||||
struct sta_info *sta)
|
|
||||||
{
|
|
||||||
const u8 *ie;
|
|
||||||
size_t ielen;
|
|
||||||
|
|
||||||
ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ielen);
|
|
||||||
if (ie == NULL || ielen > len)
|
|
||||||
return eid;
|
|
||||||
|
|
||||||
os_memcpy(eid, ie, ielen);
|
|
||||||
return eid + ielen;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void handle_probe_req(struct hostapd_data *hapd,
|
|
||||||
const struct ieee80211_mgmt *mgmt, size_t len)
|
|
||||||
{
|
|
||||||
struct ieee80211_mgmt *resp;
|
|
||||||
struct ieee802_11_elems elems;
|
|
||||||
char *ssid;
|
|
||||||
u8 *pos, *epos;
|
|
||||||
const u8 *ie;
|
|
||||||
size_t ssid_len, ie_len;
|
|
||||||
struct sta_info *sta = NULL;
|
|
||||||
size_t buflen;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
ie = mgmt->u.probe_req.variable;
|
|
||||||
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
|
|
||||||
return;
|
|
||||||
ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
|
|
||||||
|
|
||||||
for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++)
|
|
||||||
if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
|
|
||||||
mgmt->sa, ie, ie_len) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!hapd->iconf->send_probe_response)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) {
|
|
||||||
wpa_printf(MSG_DEBUG, "Could not parse ProbeReq from " MACSTR,
|
|
||||||
MAC2STR(mgmt->sa));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssid = NULL;
|
|
||||||
ssid_len = 0;
|
|
||||||
|
|
||||||
if ((!elems.ssid || !elems.supp_rates)) {
|
|
||||||
wpa_printf(MSG_DEBUG, "STA " MACSTR " sent probe request "
|
|
||||||
"without SSID or supported rates element",
|
|
||||||
MAC2STR(mgmt->sa));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
if (hapd->p2p && elems.wps_ie) {
|
|
||||||
struct wpabuf *wps;
|
|
||||||
wps = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA);
|
|
||||||
if (wps && !p2p_group_match_dev_type(hapd->p2p_group, wps)) {
|
|
||||||
wpa_printf(MSG_MSGDUMP, "P2P: Ignore Probe Request "
|
|
||||||
"due to mismatch with Requested Device "
|
|
||||||
"Type");
|
|
||||||
wpabuf_free(wps);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wpabuf_free(wps);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
|
|
||||||
if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0) {
|
|
||||||
wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
|
|
||||||
"broadcast SSID ignored", MAC2STR(mgmt->sa));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sta = ap_get_sta(hapd, mgmt->sa);
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
if ((hapd->conf->p2p & P2P_GROUP_OWNER) &&
|
|
||||||
elems.ssid_len == P2P_WILDCARD_SSID_LEN &&
|
|
||||||
os_memcmp(elems.ssid, P2P_WILDCARD_SSID,
|
|
||||||
P2P_WILDCARD_SSID_LEN) == 0) {
|
|
||||||
/* Process P2P Wildcard SSID like Wildcard SSID */
|
|
||||||
elems.ssid_len = 0;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
|
|
||||||
if (elems.ssid_len == 0 ||
|
|
||||||
(elems.ssid_len == hapd->conf->ssid.ssid_len &&
|
|
||||||
os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) ==
|
|
||||||
0)) {
|
|
||||||
ssid = hapd->conf->ssid.ssid;
|
|
||||||
ssid_len = hapd->conf->ssid.ssid_len;
|
|
||||||
if (sta)
|
|
||||||
sta->ssid_probe = &hapd->conf->ssid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ssid) {
|
|
||||||
if (!(mgmt->da[0] & 0x01)) {
|
|
||||||
char ssid_txt[33];
|
|
||||||
ieee802_11_print_ssid(ssid_txt, elems.ssid,
|
|
||||||
elems.ssid_len);
|
|
||||||
wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
|
|
||||||
" for foreign SSID '%s' (DA " MACSTR ")",
|
|
||||||
MAC2STR(mgmt->sa), ssid_txt,
|
|
||||||
MAC2STR(mgmt->da));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: verify that supp_rates contains at least one matching rate
|
|
||||||
* with AP configuration */
|
|
||||||
#define MAX_PROBERESP_LEN 768
|
|
||||||
buflen = MAX_PROBERESP_LEN;
|
|
||||||
#ifdef CONFIG_WPS
|
|
||||||
if (hapd->wps_probe_resp_ie)
|
|
||||||
buflen += wpabuf_len(hapd->wps_probe_resp_ie);
|
|
||||||
#endif /* CONFIG_WPS */
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
if (hapd->p2p_probe_resp_ie)
|
|
||||||
buflen += wpabuf_len(hapd->p2p_probe_resp_ie);
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
resp = os_zalloc(buflen);
|
|
||||||
if (resp == NULL)
|
|
||||||
return;
|
|
||||||
epos = ((u8 *) resp) + MAX_PROBERESP_LEN;
|
|
||||||
|
|
||||||
resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
|
|
||||||
WLAN_FC_STYPE_PROBE_RESP);
|
|
||||||
os_memcpy(resp->da, mgmt->sa, ETH_ALEN);
|
|
||||||
os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
|
|
||||||
|
|
||||||
os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
|
|
||||||
resp->u.probe_resp.beacon_int =
|
|
||||||
host_to_le16(hapd->iconf->beacon_int);
|
|
||||||
|
|
||||||
/* hardware or low-level driver will setup seq_ctrl and timestamp */
|
|
||||||
resp->u.probe_resp.capab_info =
|
|
||||||
host_to_le16(hostapd_own_capab_info(hapd, sta, 1));
|
|
||||||
|
|
||||||
pos = resp->u.probe_resp.variable;
|
|
||||||
*pos++ = WLAN_EID_SSID;
|
|
||||||
*pos++ = ssid_len;
|
|
||||||
os_memcpy(pos, ssid, ssid_len);
|
|
||||||
pos += ssid_len;
|
|
||||||
|
|
||||||
/* Supported rates */
|
|
||||||
pos = hostapd_eid_supp_rates(hapd, pos);
|
|
||||||
|
|
||||||
/* DS Params */
|
|
||||||
pos = hostapd_eid_ds_params(hapd, pos);
|
|
||||||
|
|
||||||
pos = hostapd_eid_country(hapd, pos, epos - pos);
|
|
||||||
|
|
||||||
/* ERP Information element */
|
|
||||||
pos = hostapd_eid_erp_info(hapd, pos);
|
|
||||||
|
|
||||||
/* Extended supported rates */
|
|
||||||
pos = hostapd_eid_ext_supp_rates(hapd, pos);
|
|
||||||
|
|
||||||
/* RSN, MDIE, WPA */
|
|
||||||
pos = hostapd_eid_wpa(hapd, pos, epos - pos, sta);
|
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211N
|
|
||||||
pos = hostapd_eid_ht_capabilities(hapd, pos);
|
|
||||||
pos = hostapd_eid_ht_operation(hapd, pos);
|
|
||||||
#endif /* CONFIG_IEEE80211N */
|
|
||||||
|
|
||||||
pos = hostapd_eid_ext_capab(hapd, pos);
|
|
||||||
|
|
||||||
/* Wi-Fi Alliance WMM */
|
|
||||||
pos = hostapd_eid_wmm(hapd, pos);
|
|
||||||
|
|
||||||
#ifdef CONFIG_WPS
|
|
||||||
if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) {
|
|
||||||
os_memcpy(pos, wpabuf_head(hapd->wps_probe_resp_ie),
|
|
||||||
wpabuf_len(hapd->wps_probe_resp_ie));
|
|
||||||
pos += wpabuf_len(hapd->wps_probe_resp_ie);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_WPS */
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
if ((hapd->conf->p2p & P2P_ENABLED) && elems.p2p &&
|
|
||||||
hapd->p2p_probe_resp_ie) {
|
|
||||||
os_memcpy(pos, wpabuf_head(hapd->p2p_probe_resp_ie),
|
|
||||||
wpabuf_len(hapd->p2p_probe_resp_ie));
|
|
||||||
pos += wpabuf_len(hapd->p2p_probe_resp_ie);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
#ifdef CONFIG_P2P_MANAGER
|
|
||||||
if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) ==
|
|
||||||
P2P_MANAGE)
|
|
||||||
pos = hostapd_eid_p2p_manage(hapd, pos);
|
|
||||||
#endif /* CONFIG_P2P_MANAGER */
|
|
||||||
|
|
||||||
if (hostapd_drv_send_mlme(hapd, resp, pos - (u8 *) resp) < 0)
|
|
||||||
perror("handle_probe_req: send");
|
|
||||||
|
|
||||||
os_free(resp);
|
|
||||||
|
|
||||||
wpa_printf(MSG_EXCESSIVE, "STA " MACSTR " sent probe request for %s "
|
|
||||||
"SSID", MAC2STR(mgmt->sa),
|
|
||||||
elems.ssid_len == 0 ? "broadcast" : "our");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ieee802_11_set_beacon(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
struct ieee80211_mgmt *head;
|
|
||||||
u8 *pos, *tail, *tailpos;
|
|
||||||
u16 capab_info;
|
|
||||||
size_t head_len, tail_len;
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
if ((hapd->conf->p2p & (P2P_ENABLED | P2P_GROUP_OWNER)) == P2P_ENABLED)
|
|
||||||
goto no_beacon;
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
|
|
||||||
#define BEACON_HEAD_BUF_SIZE 256
|
|
||||||
#define BEACON_TAIL_BUF_SIZE 512
|
|
||||||
head = os_zalloc(BEACON_HEAD_BUF_SIZE);
|
|
||||||
tail_len = BEACON_TAIL_BUF_SIZE;
|
|
||||||
#ifdef CONFIG_WPS
|
|
||||||
if (hapd->conf->wps_state && hapd->wps_beacon_ie)
|
|
||||||
tail_len += wpabuf_len(hapd->wps_beacon_ie);
|
|
||||||
#endif /* CONFIG_WPS */
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
if (hapd->p2p_beacon_ie)
|
|
||||||
tail_len += wpabuf_len(hapd->p2p_beacon_ie);
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
tailpos = tail = os_malloc(tail_len);
|
|
||||||
if (head == NULL || tail == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to set beacon data");
|
|
||||||
os_free(head);
|
|
||||||
os_free(tail);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
|
|
||||||
WLAN_FC_STYPE_BEACON);
|
|
||||||
head->duration = host_to_le16(0);
|
|
||||||
os_memset(head->da, 0xff, ETH_ALEN);
|
|
||||||
|
|
||||||
os_memcpy(head->sa, hapd->own_addr, ETH_ALEN);
|
|
||||||
os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN);
|
|
||||||
head->u.beacon.beacon_int =
|
|
||||||
host_to_le16(hapd->iconf->beacon_int);
|
|
||||||
|
|
||||||
/* hardware or low-level driver will setup seq_ctrl and timestamp */
|
|
||||||
capab_info = hostapd_own_capab_info(hapd, NULL, 0);
|
|
||||||
head->u.beacon.capab_info = host_to_le16(capab_info);
|
|
||||||
pos = &head->u.beacon.variable[0];
|
|
||||||
|
|
||||||
/* SSID */
|
|
||||||
*pos++ = WLAN_EID_SSID;
|
|
||||||
if (hapd->conf->ignore_broadcast_ssid == 2) {
|
|
||||||
/* clear the data, but keep the correct length of the SSID */
|
|
||||||
*pos++ = hapd->conf->ssid.ssid_len;
|
|
||||||
os_memset(pos, 0, hapd->conf->ssid.ssid_len);
|
|
||||||
pos += hapd->conf->ssid.ssid_len;
|
|
||||||
} else if (hapd->conf->ignore_broadcast_ssid) {
|
|
||||||
*pos++ = 0; /* empty SSID */
|
|
||||||
} else {
|
|
||||||
*pos++ = hapd->conf->ssid.ssid_len;
|
|
||||||
os_memcpy(pos, hapd->conf->ssid.ssid,
|
|
||||||
hapd->conf->ssid.ssid_len);
|
|
||||||
pos += hapd->conf->ssid.ssid_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Supported rates */
|
|
||||||
pos = hostapd_eid_supp_rates(hapd, pos);
|
|
||||||
|
|
||||||
/* DS Params */
|
|
||||||
pos = hostapd_eid_ds_params(hapd, pos);
|
|
||||||
|
|
||||||
head_len = pos - (u8 *) head;
|
|
||||||
|
|
||||||
tailpos = hostapd_eid_country(hapd, tailpos,
|
|
||||||
tail + BEACON_TAIL_BUF_SIZE - tailpos);
|
|
||||||
|
|
||||||
/* ERP Information element */
|
|
||||||
tailpos = hostapd_eid_erp_info(hapd, tailpos);
|
|
||||||
|
|
||||||
/* Extended supported rates */
|
|
||||||
tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos);
|
|
||||||
|
|
||||||
/* RSN, MDIE, WPA */
|
|
||||||
tailpos = hostapd_eid_wpa(hapd, tailpos, tail + BEACON_TAIL_BUF_SIZE -
|
|
||||||
tailpos, NULL);
|
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211N
|
|
||||||
tailpos = hostapd_eid_ht_capabilities(hapd, tailpos);
|
|
||||||
tailpos = hostapd_eid_ht_operation(hapd, tailpos);
|
|
||||||
|
|
||||||
//DRIVER_RTW ADD
|
|
||||||
if(hapd->iconf->ieee80211n)
|
|
||||||
hapd->conf->wmm_enabled = 1;
|
|
||||||
|
|
||||||
#endif /* CONFIG_IEEE80211N */
|
|
||||||
|
|
||||||
tailpos = hostapd_eid_ext_capab(hapd, tailpos);
|
|
||||||
|
|
||||||
/* Wi-Fi Alliance WMM */
|
|
||||||
tailpos = hostapd_eid_wmm(hapd, tailpos);
|
|
||||||
|
|
||||||
#ifdef CONFIG_WPS
|
|
||||||
if (hapd->conf->wps_state && hapd->wps_beacon_ie) {
|
|
||||||
os_memcpy(tailpos, wpabuf_head(hapd->wps_beacon_ie),
|
|
||||||
wpabuf_len(hapd->wps_beacon_ie));
|
|
||||||
tailpos += wpabuf_len(hapd->wps_beacon_ie);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_WPS */
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_beacon_ie) {
|
|
||||||
os_memcpy(tailpos, wpabuf_head(hapd->p2p_beacon_ie),
|
|
||||||
wpabuf_len(hapd->p2p_beacon_ie));
|
|
||||||
tailpos += wpabuf_len(hapd->p2p_beacon_ie);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
#ifdef CONFIG_P2P_MANAGER
|
|
||||||
if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) ==
|
|
||||||
P2P_MANAGE)
|
|
||||||
tailpos = hostapd_eid_p2p_manage(hapd, tailpos);
|
|
||||||
#endif /* CONFIG_P2P_MANAGER */
|
|
||||||
|
|
||||||
tail_len = tailpos > tail ? tailpos - tail : 0;
|
|
||||||
|
|
||||||
if (hostapd_drv_set_beacon(hapd, (u8 *) head, head_len,
|
|
||||||
tail, tail_len, hapd->conf->dtim_period,
|
|
||||||
hapd->iconf->beacon_int))
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to set beacon head/tail or DTIM "
|
|
||||||
"period");
|
|
||||||
|
|
||||||
os_free(tail);
|
|
||||||
os_free(head);
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
no_beacon:
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
hostapd_set_bss_params(hapd, !!(ieee802_11_erp_info(hapd) &
|
|
||||||
ERP_INFO_USE_PROTECTION));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ieee802_11_set_beacons(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i < iface->num_bss; i++)
|
|
||||||
ieee802_11_set_beacon(iface->bss[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / IEEE 802.11 Management: Beacon and Probe Request/Response
|
|
||||||
* Copyright (c) 2002-2004, Instant802 Networks, Inc.
|
|
||||||
* Copyright (c) 2005-2006, Devicescape Software, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BEACON_H
|
|
||||||
#define BEACON_H
|
|
||||||
|
|
||||||
struct ieee80211_mgmt;
|
|
||||||
|
|
||||||
void handle_probe_req(struct hostapd_data *hapd,
|
|
||||||
const struct ieee80211_mgmt *mgmt, size_t len);
|
|
||||||
#ifdef NEED_AP_MLME
|
|
||||||
void ieee802_11_set_beacon(struct hostapd_data *hapd);
|
|
||||||
void ieee802_11_set_beacons(struct hostapd_iface *iface);
|
|
||||||
#else /* NEED_AP_MLME */
|
|
||||||
static inline void ieee802_11_set_beacon(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ieee802_11_set_beacons(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif /* NEED_AP_MLME */
|
|
||||||
|
|
||||||
#endif /* BEACON_H */
|
|
|
@ -1,108 +0,0 @@
|
||||||
/*
|
|
||||||
* Control interface for shared AP commands
|
|
||||||
* Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "utils/includes.h"
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
|
||||||
#include "hostapd.h"
|
|
||||||
#include "ieee802_1x.h"
|
|
||||||
#include "wpa_auth.h"
|
|
||||||
#include "ieee802_11.h"
|
|
||||||
#include "sta_info.h"
|
|
||||||
#include "wps_hostapd.h"
|
|
||||||
#include "p2p_hostapd.h"
|
|
||||||
#include "ctrl_iface_ap.h"
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta,
|
|
||||||
char *buf, size_t buflen)
|
|
||||||
{
|
|
||||||
int len, res, ret;
|
|
||||||
|
|
||||||
if (sta == NULL) {
|
|
||||||
ret = os_snprintf(buf, buflen, "FAIL\n");
|
|
||||||
if (ret < 0 || (size_t) ret >= buflen)
|
|
||||||
return 0;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = 0;
|
|
||||||
ret = os_snprintf(buf + len, buflen - len, MACSTR "\n",
|
|
||||||
MAC2STR(sta->addr));
|
|
||||||
if (ret < 0 || (size_t) ret >= buflen - len)
|
|
||||||
return len;
|
|
||||||
len += ret;
|
|
||||||
|
|
||||||
res = ieee802_11_get_mib_sta(hapd, sta, buf + len, buflen - len);
|
|
||||||
if (res >= 0)
|
|
||||||
len += res;
|
|
||||||
res = wpa_get_mib_sta(sta->wpa_sm, buf + len, buflen - len);
|
|
||||||
if (res >= 0)
|
|
||||||
len += res;
|
|
||||||
res = ieee802_1x_get_mib_sta(hapd, sta, buf + len, buflen - len);
|
|
||||||
if (res >= 0)
|
|
||||||
len += res;
|
|
||||||
res = hostapd_wps_get_mib_sta(hapd, sta->addr, buf + len,
|
|
||||||
buflen - len);
|
|
||||||
if (res >= 0)
|
|
||||||
len += res;
|
|
||||||
res = hostapd_p2p_get_mib_sta(hapd, sta, buf + len, buflen - len);
|
|
||||||
if (res >= 0)
|
|
||||||
len += res;
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_ctrl_iface_sta_first(struct hostapd_data *hapd,
|
|
||||||
char *buf, size_t buflen)
|
|
||||||
{
|
|
||||||
return hostapd_ctrl_iface_sta_mib(hapd, hapd->sta_list, buf, buflen);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_ctrl_iface_sta(struct hostapd_data *hapd, const char *txtaddr,
|
|
||||||
char *buf, size_t buflen)
|
|
||||||
{
|
|
||||||
u8 addr[ETH_ALEN];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (hwaddr_aton(txtaddr, addr)) {
|
|
||||||
ret = os_snprintf(buf, buflen, "FAIL\n");
|
|
||||||
if (ret < 0 || (size_t) ret >= buflen)
|
|
||||||
return 0;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return hostapd_ctrl_iface_sta_mib(hapd, ap_get_sta(hapd, addr),
|
|
||||||
buf, buflen);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd, const char *txtaddr,
|
|
||||||
char *buf, size_t buflen)
|
|
||||||
{
|
|
||||||
u8 addr[ETH_ALEN];
|
|
||||||
struct sta_info *sta;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (hwaddr_aton(txtaddr, addr) ||
|
|
||||||
(sta = ap_get_sta(hapd, addr)) == NULL) {
|
|
||||||
ret = os_snprintf(buf, buflen, "FAIL\n");
|
|
||||||
if (ret < 0 || (size_t) ret >= buflen)
|
|
||||||
return 0;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen);
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
* Control interface for shared AP commands
|
|
||||||
* Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CTRL_IFACE_AP_H
|
|
||||||
#define CTRL_IFACE_AP_H
|
|
||||||
|
|
||||||
int hostapd_ctrl_iface_sta_first(struct hostapd_data *hapd,
|
|
||||||
char *buf, size_t buflen);
|
|
||||||
int hostapd_ctrl_iface_sta(struct hostapd_data *hapd, const char *txtaddr,
|
|
||||||
char *buf, size_t buflen);
|
|
||||||
int hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd, const char *txtaddr,
|
|
||||||
char *buf, size_t buflen);
|
|
||||||
|
|
||||||
#endif /* CTRL_IFACE_AP_H */
|
|
|
@ -1,539 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / Callback functions for driver wrappers
|
|
||||||
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "utils/includes.h"
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
|
||||||
#include "radius/radius.h"
|
|
||||||
#include "drivers/driver.h"
|
|
||||||
#include "common/ieee802_11_defs.h"
|
|
||||||
#include "common/ieee802_11_common.h"
|
|
||||||
#include "common/wpa_ctrl.h"
|
|
||||||
#include "crypto/random.h"
|
|
||||||
#include "p2p/p2p.h"
|
|
||||||
#include "wps/wps.h"
|
|
||||||
#include "hostapd.h"
|
|
||||||
#include "ieee802_11.h"
|
|
||||||
#include "sta_info.h"
|
|
||||||
#include "accounting.h"
|
|
||||||
#include "tkip_countermeasures.h"
|
|
||||||
#include "iapp.h"
|
|
||||||
#include "ieee802_1x.h"
|
|
||||||
#include "wpa_auth.h"
|
|
||||||
#include "wmm.h"
|
|
||||||
#include "wps_hostapd.h"
|
|
||||||
#include "ap_drv_ops.h"
|
|
||||||
#include "ap_config.h"
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
|
|
||||||
const u8 *ie, size_t ielen, int reassoc)
|
|
||||||
{
|
|
||||||
struct sta_info *sta;
|
|
||||||
int new_assoc, res;
|
|
||||||
struct ieee802_11_elems elems;
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
const u8 *all_ies = ie;
|
|
||||||
size_t all_ies_len = ielen;
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
|
|
||||||
if (addr == NULL) {
|
|
||||||
/*
|
|
||||||
* This could potentially happen with unexpected event from the
|
|
||||||
* driver wrapper. This was seen at least in one case where the
|
|
||||||
* driver ended up being set to station mode while hostapd was
|
|
||||||
* running, so better make sure we stop processing such an
|
|
||||||
* event here.
|
|
||||||
*/
|
|
||||||
wpa_printf(MSG_DEBUG, "hostapd_notif_assoc: Skip event with "
|
|
||||||
"no address");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
random_add_randomness(addr, ETH_ALEN);
|
|
||||||
|
|
||||||
hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
|
|
||||||
HOSTAPD_LEVEL_INFO, "associated");
|
|
||||||
|
|
||||||
ieee802_11_parse_elems(ie, ielen, &elems, 0);
|
|
||||||
if (elems.wps_ie) {
|
|
||||||
ie = elems.wps_ie - 2;
|
|
||||||
ielen = elems.wps_ie_len + 2;
|
|
||||||
wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq");
|
|
||||||
} else if (elems.rsn_ie) {
|
|
||||||
ie = elems.rsn_ie - 2;
|
|
||||||
ielen = elems.rsn_ie_len + 2;
|
|
||||||
wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq");
|
|
||||||
} else if (elems.wpa_ie) {
|
|
||||||
ie = elems.wpa_ie - 2;
|
|
||||||
ielen = elems.wpa_ie_len + 2;
|
|
||||||
wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq");
|
|
||||||
} else {
|
|
||||||
ie = NULL;
|
|
||||||
ielen = 0;
|
|
||||||
wpa_printf(MSG_DEBUG, "STA did not include WPS/RSN/WPA IE in "
|
|
||||||
"(Re)AssocReq");
|
|
||||||
}
|
|
||||||
|
|
||||||
sta = ap_get_sta(hapd, addr);
|
|
||||||
if (sta) {
|
|
||||||
accounting_sta_stop(hapd, sta);
|
|
||||||
} else {
|
|
||||||
sta = ap_sta_add(hapd, addr);
|
|
||||||
if (sta == NULL)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
if (elems.p2p) {
|
|
||||||
wpabuf_free(sta->p2p_ie);
|
|
||||||
sta->p2p_ie = ieee802_11_vendor_ie_concat(all_ies, all_ies_len,
|
|
||||||
P2P_IE_VENDOR_TYPE);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
|
|
||||||
if (hapd->conf->wpa) {
|
|
||||||
if (ie == NULL || ielen == 0) {
|
|
||||||
if (hapd->conf->wps_state) {
|
|
||||||
wpa_printf(MSG_DEBUG, "STA did not include "
|
|
||||||
"WPA/RSN IE in (Re)Association "
|
|
||||||
"Request - possible WPS use");
|
|
||||||
sta->flags |= WLAN_STA_MAYBE_WPS;
|
|
||||||
goto skip_wpa_check;
|
|
||||||
}
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 &&
|
|
||||||
os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {
|
|
||||||
sta->flags |= WLAN_STA_WPS;
|
|
||||||
goto skip_wpa_check;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sta->wpa_sm == NULL)
|
|
||||||
sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
|
|
||||||
sta->addr);
|
|
||||||
if (sta->wpa_sm == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to initialize WPA state "
|
|
||||||
"machine");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
|
|
||||||
ie, ielen, NULL, 0);
|
|
||||||
if (res != WPA_IE_OK) {
|
|
||||||
int resp;
|
|
||||||
wpa_printf(MSG_DEBUG, "WPA/RSN information element "
|
|
||||||
"rejected? (res %u)", res);
|
|
||||||
wpa_hexdump(MSG_DEBUG, "IE", ie, ielen);
|
|
||||||
if (res == WPA_INVALID_GROUP)
|
|
||||||
resp = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
|
|
||||||
else if (res == WPA_INVALID_PAIRWISE)
|
|
||||||
resp = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID;
|
|
||||||
else if (res == WPA_INVALID_AKMP)
|
|
||||||
resp = WLAN_REASON_AKMP_NOT_VALID;
|
|
||||||
#ifdef CONFIG_IEEE80211W
|
|
||||||
else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION)
|
|
||||||
resp = WLAN_REASON_INVALID_IE;
|
|
||||||
else if (res == WPA_INVALID_MGMT_GROUP_CIPHER)
|
|
||||||
resp = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
|
|
||||||
#endif /* CONFIG_IEEE80211W */
|
|
||||||
else
|
|
||||||
resp = WLAN_REASON_INVALID_IE;
|
|
||||||
hostapd_drv_sta_disassoc(hapd, sta->addr, resp);
|
|
||||||
ap_free_sta(hapd, sta);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else if (hapd->conf->wps_state) {
|
|
||||||
#ifdef CONFIG_WPS_STRICT
|
|
||||||
if (ie) {
|
|
||||||
struct wpabuf *wps;
|
|
||||||
wps = ieee802_11_vendor_ie_concat(ie, ielen,
|
|
||||||
WPS_IE_VENDOR_TYPE);
|
|
||||||
if (wps && wps_validate_assoc_req(wps) < 0) {
|
|
||||||
hostapd_drv_sta_disassoc(
|
|
||||||
hapd, sta->addr,
|
|
||||||
WLAN_REASON_INVALID_IE);
|
|
||||||
ap_free_sta(hapd, sta);
|
|
||||||
wpabuf_free(wps);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
wpabuf_free(wps);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_WPS_STRICT */
|
|
||||||
if (ie && ielen > 4 && ie[0] == 0xdd && ie[1] >= 4 &&
|
|
||||||
os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {
|
|
||||||
sta->flags |= WLAN_STA_WPS;
|
|
||||||
} else
|
|
||||||
sta->flags |= WLAN_STA_MAYBE_WPS;
|
|
||||||
}
|
|
||||||
skip_wpa_check:
|
|
||||||
|
|
||||||
new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
|
|
||||||
sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
|
|
||||||
wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
|
|
||||||
|
|
||||||
hostapd_new_assoc_sta(hapd, sta, !new_assoc);
|
|
||||||
|
|
||||||
ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
p2p_group_notif_assoc(hapd->p2p_group, sta->addr,
|
|
||||||
all_ies, all_ies_len);
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
|
|
||||||
{
|
|
||||||
struct sta_info *sta;
|
|
||||||
|
|
||||||
if (addr == NULL) {
|
|
||||||
/*
|
|
||||||
* This could potentially happen with unexpected event from the
|
|
||||||
* driver wrapper. This was seen at least in one case where the
|
|
||||||
* driver ended up reporting a station mode event while hostapd
|
|
||||||
* was running, so better make sure we stop processing such an
|
|
||||||
* event here.
|
|
||||||
*/
|
|
||||||
wpa_printf(MSG_DEBUG, "hostapd_notif_disassoc: Skip event "
|
|
||||||
"with no address");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
|
|
||||||
HOSTAPD_LEVEL_INFO, "disassociated");
|
|
||||||
|
|
||||||
sta = ap_get_sta(hapd, addr);
|
|
||||||
if (sta == NULL) {
|
|
||||||
wpa_printf(MSG_DEBUG, "Disassociation notification for "
|
|
||||||
"unknown STA " MACSTR, MAC2STR(addr));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
|
|
||||||
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
|
|
||||||
MAC2STR(sta->addr));
|
|
||||||
wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
|
|
||||||
sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
|
|
||||||
ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
|
|
||||||
ap_free_sta(hapd, sta);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr)
|
|
||||||
{
|
|
||||||
struct sta_info *sta = ap_get_sta(hapd, addr);
|
|
||||||
|
|
||||||
if (!sta || !hapd->conf->disassoc_low_ack)
|
|
||||||
return;
|
|
||||||
|
|
||||||
hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
|
|
||||||
HOSTAPD_LEVEL_INFO, "disconnected due to excessive "
|
|
||||||
"missing ACKs");
|
|
||||||
hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK);
|
|
||||||
if (sta)
|
|
||||||
ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa,
|
|
||||||
const u8 *ie, size_t ie_len)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (sa == NULL || ie == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
random_add_randomness(sa, ETH_ALEN);
|
|
||||||
for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) {
|
|
||||||
if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
|
|
||||||
sa, ie, ie_len) > 0) {
|
|
||||||
ret = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HOSTAPD
|
|
||||||
|
|
||||||
#ifdef NEED_AP_MLME
|
|
||||||
|
|
||||||
static const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
|
|
||||||
{
|
|
||||||
u16 fc, type, stype;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PS-Poll frames are 16 bytes. All other frames are
|
|
||||||
* 24 bytes or longer.
|
|
||||||
*/
|
|
||||||
if (len < 16)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
fc = le_to_host16(hdr->frame_control);
|
|
||||||
type = WLAN_FC_GET_TYPE(fc);
|
|
||||||
stype = WLAN_FC_GET_STYPE(fc);
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case WLAN_FC_TYPE_DATA:
|
|
||||||
if (len < 24)
|
|
||||||
return NULL;
|
|
||||||
switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
|
|
||||||
case WLAN_FC_FROMDS | WLAN_FC_TODS:
|
|
||||||
case WLAN_FC_TODS:
|
|
||||||
return hdr->addr1;
|
|
||||||
case WLAN_FC_FROMDS:
|
|
||||||
return hdr->addr2;
|
|
||||||
default:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
case WLAN_FC_TYPE_CTRL:
|
|
||||||
if (stype != WLAN_FC_STYPE_PSPOLL)
|
|
||||||
return NULL;
|
|
||||||
return hdr->addr1;
|
|
||||||
case WLAN_FC_TYPE_MGMT:
|
|
||||||
return hdr->addr3;
|
|
||||||
default:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define HAPD_BROADCAST ((struct hostapd_data *) -1)
|
|
||||||
|
|
||||||
static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface,
|
|
||||||
const u8 *bssid)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (bssid == NULL)
|
|
||||||
return NULL;
|
|
||||||
if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff &&
|
|
||||||
bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff)
|
|
||||||
return HAPD_BROADCAST;
|
|
||||||
|
|
||||||
for (i = 0; i < iface->num_bss; i++) {
|
|
||||||
if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0)
|
|
||||||
return iface->bss[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd,
|
|
||||||
const u8 *frame, size_t len)
|
|
||||||
{
|
|
||||||
const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) frame;
|
|
||||||
u16 fc = le_to_host16(hdr->frame_control);
|
|
||||||
hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len));
|
|
||||||
if (hapd == NULL || hapd == HAPD_BROADCAST)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ieee802_11_rx_from_unknown(hapd, hdr->addr2,
|
|
||||||
(fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
|
|
||||||
(WLAN_FC_TODS | WLAN_FC_FROMDS));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
|
|
||||||
{
|
|
||||||
struct hostapd_iface *iface = hapd->iface;
|
|
||||||
const struct ieee80211_hdr *hdr;
|
|
||||||
const u8 *bssid;
|
|
||||||
struct hostapd_frame_info fi;
|
|
||||||
|
|
||||||
hdr = (const struct ieee80211_hdr *) rx_mgmt->frame;
|
|
||||||
bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len);
|
|
||||||
if (bssid == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
hapd = get_hapd_bssid(iface, bssid);
|
|
||||||
if (hapd == NULL) {
|
|
||||||
u16 fc;
|
|
||||||
fc = le_to_host16(hdr->frame_control);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Drop frames to unknown BSSIDs except for Beacon frames which
|
|
||||||
* could be used to update neighbor information.
|
|
||||||
*/
|
|
||||||
if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
|
|
||||||
WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
|
|
||||||
hapd = iface->bss[0];
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_memset(&fi, 0, sizeof(fi));
|
|
||||||
fi.datarate = rx_mgmt->datarate;
|
|
||||||
fi.ssi_signal = rx_mgmt->ssi_signal;
|
|
||||||
|
|
||||||
if (hapd == HAPD_BROADCAST) {
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i < iface->num_bss; i++)
|
|
||||||
ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame,
|
|
||||||
rx_mgmt->frame_len, &fi);
|
|
||||||
} else
|
|
||||||
ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len, &fi);
|
|
||||||
|
|
||||||
random_add_randomness(&fi, sizeof(fi));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
|
|
||||||
size_t len, u16 stype, int ok)
|
|
||||||
{
|
|
||||||
struct ieee80211_hdr *hdr;
|
|
||||||
hdr = (struct ieee80211_hdr *) buf;
|
|
||||||
hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len));
|
|
||||||
if (hapd == NULL || hapd == HAPD_BROADCAST)
|
|
||||||
return;
|
|
||||||
ieee802_11_mgmt_cb(hapd, buf, len, stype, ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* NEED_AP_MLME */
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
|
|
||||||
{
|
|
||||||
struct sta_info *sta = ap_get_sta(hapd, addr);
|
|
||||||
if (sta)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR
|
|
||||||
" - adding a new STA", MAC2STR(addr));
|
|
||||||
sta = ap_sta_add(hapd, addr);
|
|
||||||
if (sta) {
|
|
||||||
hostapd_new_assoc_sta(hapd, sta, 0);
|
|
||||||
} else {
|
|
||||||
wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR,
|
|
||||||
MAC2STR(addr));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
|
|
||||||
const u8 *data, size_t data_len)
|
|
||||||
{
|
|
||||||
struct hostapd_iface *iface = hapd->iface;
|
|
||||||
size_t j;
|
|
||||||
|
|
||||||
for (j = 0; j < iface->num_bss; j++) {
|
|
||||||
if (ap_get_sta(iface->bss[j], src)) {
|
|
||||||
hapd = iface->bss[j];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ieee802_1x_receive(hapd, src, data, data_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
|
||||||
union wpa_event_data *data)
|
|
||||||
{
|
|
||||||
struct hostapd_data *hapd = ctx;
|
|
||||||
|
|
||||||
switch (event) {
|
|
||||||
case EVENT_MICHAEL_MIC_FAILURE:
|
|
||||||
michael_mic_failure(hapd, data->michael_mic_failure.src, 1);
|
|
||||||
break;
|
|
||||||
case EVENT_SCAN_RESULTS:
|
|
||||||
if (hapd->iface->scan_cb)
|
|
||||||
hapd->iface->scan_cb(hapd->iface);
|
|
||||||
break;
|
|
||||||
#ifdef CONFIG_IEEE80211R
|
|
||||||
case EVENT_FT_RRB_RX:
|
|
||||||
wpa_ft_rrb_rx(hapd->wpa_auth, data->ft_rrb_rx.src,
|
|
||||||
data->ft_rrb_rx.data, data->ft_rrb_rx.data_len);
|
|
||||||
break;
|
|
||||||
#endif /* CONFIG_IEEE80211R */
|
|
||||||
case EVENT_WPS_BUTTON_PUSHED:
|
|
||||||
hostapd_wps_button_pushed(hapd, NULL);
|
|
||||||
break;
|
|
||||||
#ifdef NEED_AP_MLME
|
|
||||||
case EVENT_TX_STATUS:
|
|
||||||
switch (data->tx_status.type) {
|
|
||||||
case WLAN_FC_TYPE_MGMT:
|
|
||||||
hostapd_mgmt_tx_cb(hapd, data->tx_status.data,
|
|
||||||
data->tx_status.data_len,
|
|
||||||
data->tx_status.stype,
|
|
||||||
data->tx_status.ack);
|
|
||||||
break;
|
|
||||||
case WLAN_FC_TYPE_DATA:
|
|
||||||
hostapd_tx_status(hapd, data->tx_status.dst,
|
|
||||||
data->tx_status.data,
|
|
||||||
data->tx_status.data_len,
|
|
||||||
data->tx_status.ack);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EVENT_RX_FROM_UNKNOWN:
|
|
||||||
hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.frame,
|
|
||||||
data->rx_from_unknown.len);
|
|
||||||
break;
|
|
||||||
case EVENT_RX_MGMT:
|
|
||||||
hostapd_mgmt_rx(hapd, &data->rx_mgmt);
|
|
||||||
break;
|
|
||||||
#endif /* NEED_AP_MLME */
|
|
||||||
case EVENT_RX_PROBE_REQ:
|
|
||||||
if (data->rx_probe_req.sa == NULL ||
|
|
||||||
data->rx_probe_req.ie == NULL)
|
|
||||||
break;
|
|
||||||
hostapd_probe_req_rx(hapd, data->rx_probe_req.sa,
|
|
||||||
data->rx_probe_req.ie,
|
|
||||||
data->rx_probe_req.ie_len);
|
|
||||||
break;
|
|
||||||
case EVENT_NEW_STA:
|
|
||||||
hostapd_event_new_sta(hapd, data->new_sta.addr);
|
|
||||||
break;
|
|
||||||
case EVENT_EAPOL_RX:
|
|
||||||
hostapd_event_eapol_rx(hapd, data->eapol_rx.src,
|
|
||||||
data->eapol_rx.data,
|
|
||||||
data->eapol_rx.data_len);
|
|
||||||
break;
|
|
||||||
case EVENT_ASSOC:
|
|
||||||
hostapd_notif_assoc(hapd, data->assoc_info.addr,
|
|
||||||
data->assoc_info.req_ies,
|
|
||||||
data->assoc_info.req_ies_len,
|
|
||||||
data->assoc_info.reassoc);
|
|
||||||
break;
|
|
||||||
case EVENT_DISASSOC:
|
|
||||||
if (data)
|
|
||||||
hostapd_notif_disassoc(hapd, data->disassoc_info.addr);
|
|
||||||
break;
|
|
||||||
case EVENT_DEAUTH:
|
|
||||||
if (data)
|
|
||||||
hostapd_notif_disassoc(hapd, data->deauth_info.addr);
|
|
||||||
break;
|
|
||||||
case EVENT_STATION_LOW_ACK:
|
|
||||||
if (!data)
|
|
||||||
break;
|
|
||||||
hostapd_event_sta_low_ack(hapd, data->low_ack.addr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
wpa_printf(MSG_DEBUG, "Unknown event %d", event);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HOSTAPD */
|
|
|
@ -1,929 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / Initialization and configuration
|
|
||||||
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "utils/includes.h"
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
|
||||||
#include "utils/eloop.h"
|
|
||||||
#include "common/ieee802_11_defs.h"
|
|
||||||
#include "radius/radius_client.h"
|
|
||||||
#include "drivers/driver.h"
|
|
||||||
#include "hostapd.h"
|
|
||||||
#include "authsrv.h"
|
|
||||||
#include "sta_info.h"
|
|
||||||
#include "accounting.h"
|
|
||||||
#include "ap_list.h"
|
|
||||||
#include "beacon.h"
|
|
||||||
#include "iapp.h"
|
|
||||||
#include "ieee802_1x.h"
|
|
||||||
#include "ieee802_11_auth.h"
|
|
||||||
#include "vlan_init.h"
|
|
||||||
#include "wpa_auth.h"
|
|
||||||
#include "wps_hostapd.h"
|
|
||||||
#include "hw_features.h"
|
|
||||||
#include "wpa_auth_glue.h"
|
|
||||||
#include "ap_drv_ops.h"
|
|
||||||
#include "ap_config.h"
|
|
||||||
#include "p2p_hostapd.h"
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_flush_old_stations(struct hostapd_data *hapd);
|
|
||||||
static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd);
|
|
||||||
|
|
||||||
extern int wpa_debug_level;
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_reload_bss(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
#ifndef CONFIG_NO_RADIUS
|
|
||||||
radius_client_reconfig(hapd->radius, hapd->conf->radius);
|
|
||||||
#endif /* CONFIG_NO_RADIUS */
|
|
||||||
|
|
||||||
if (hostapd_setup_wpa_psk(hapd->conf)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK "
|
|
||||||
"after reloading configuration");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hapd->conf->ieee802_1x || hapd->conf->wpa)
|
|
||||||
hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1);
|
|
||||||
else
|
|
||||||
hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0);
|
|
||||||
|
|
||||||
if (hapd->conf->wpa && hapd->wpa_auth == NULL)
|
|
||||||
hostapd_setup_wpa(hapd);
|
|
||||||
else if (hapd->conf->wpa) {
|
|
||||||
const u8 *wpa_ie;
|
|
||||||
size_t wpa_ie_len;
|
|
||||||
hostapd_reconfig_wpa(hapd);
|
|
||||||
wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len);
|
|
||||||
if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len))
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to configure WPA IE for "
|
|
||||||
"the kernel driver.");
|
|
||||||
} else if (hapd->wpa_auth) {
|
|
||||||
wpa_deinit(hapd->wpa_auth);
|
|
||||||
hapd->wpa_auth = NULL;
|
|
||||||
hostapd_set_privacy(hapd, 0);
|
|
||||||
hostapd_setup_encryption(hapd->conf->iface, hapd);
|
|
||||||
hostapd_set_generic_elem(hapd, (u8 *) "", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ieee802_11_set_beacon(hapd);
|
|
||||||
hostapd_update_wps(hapd);
|
|
||||||
|
|
||||||
if (hapd->conf->ssid.ssid_set &&
|
|
||||||
hostapd_set_ssid(hapd, (u8 *) hapd->conf->ssid.ssid,
|
|
||||||
hapd->conf->ssid.ssid_len)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
|
|
||||||
/* try to continue */
|
|
||||||
}
|
|
||||||
wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_reload_config(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
struct hostapd_data *hapd = iface->bss[0];
|
|
||||||
struct hostapd_config *newconf, *oldconf;
|
|
||||||
size_t j;
|
|
||||||
|
|
||||||
if (iface->config_read_cb == NULL)
|
|
||||||
return -1;
|
|
||||||
newconf = iface->config_read_cb(iface->config_fname);
|
|
||||||
if (newconf == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Deauthenticate all stations since the new configuration may not
|
|
||||||
* allow them to use the BSS anymore.
|
|
||||||
*/
|
|
||||||
for (j = 0; j < iface->num_bss; j++) {
|
|
||||||
hostapd_flush_old_stations(iface->bss[j]);
|
|
||||||
|
|
||||||
#ifndef CONFIG_NO_RADIUS
|
|
||||||
/* TODO: update dynamic data based on changed configuration
|
|
||||||
* items (e.g., open/close sockets, etc.) */
|
|
||||||
radius_client_flush(iface->bss[j]->radius, 0);
|
|
||||||
#endif /* CONFIG_NO_RADIUS */
|
|
||||||
}
|
|
||||||
|
|
||||||
oldconf = hapd->iconf;
|
|
||||||
iface->conf = newconf;
|
|
||||||
|
|
||||||
for (j = 0; j < iface->num_bss; j++) {
|
|
||||||
hapd = iface->bss[j];
|
|
||||||
hapd->iconf = newconf;
|
|
||||||
hapd->conf = &newconf->bss[j];
|
|
||||||
hostapd_reload_bss(hapd);
|
|
||||||
}
|
|
||||||
|
|
||||||
hostapd_config_free(oldconf);
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
|
|
||||||
char *ifname)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_WEP_KEYS; i++) {
|
|
||||||
if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i,
|
|
||||||
0, NULL, 0, NULL, 0)) {
|
|
||||||
wpa_printf(MSG_DEBUG, "Failed to clear default "
|
|
||||||
"encryption keys (ifname=%s keyidx=%d)",
|
|
||||||
ifname, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef CONFIG_IEEE80211W
|
|
||||||
if (hapd->conf->ieee80211w) {
|
|
||||||
for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) {
|
|
||||||
if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE,
|
|
||||||
NULL, i, 0, NULL,
|
|
||||||
0, NULL, 0)) {
|
|
||||||
wpa_printf(MSG_DEBUG, "Failed to clear "
|
|
||||||
"default mgmt encryption keys "
|
|
||||||
"(ifname=%s keyidx=%d)", ifname, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_IEEE80211W */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
hostapd_broadcast_key_clear_iface(hapd, hapd->conf->iface);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
int errors = 0, idx;
|
|
||||||
struct hostapd_ssid *ssid = &hapd->conf->ssid;
|
|
||||||
|
|
||||||
idx = ssid->wep.idx;
|
|
||||||
if (ssid->wep.default_len &&
|
|
||||||
hostapd_drv_set_key(hapd->conf->iface,
|
|
||||||
hapd, WPA_ALG_WEP, broadcast_ether_addr, idx,
|
|
||||||
1, NULL, 0, ssid->wep.key[idx],
|
|
||||||
ssid->wep.len[idx])) {
|
|
||||||
wpa_printf(MSG_WARNING, "Could not set WEP encryption.");
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ssid->dyn_vlan_keys) {
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i <= ssid->max_dyn_vlan_keys; i++) {
|
|
||||||
const char *ifname;
|
|
||||||
struct hostapd_wep_keys *key = ssid->dyn_vlan_keys[i];
|
|
||||||
if (key == NULL)
|
|
||||||
continue;
|
|
||||||
ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan,
|
|
||||||
i);
|
|
||||||
if (ifname == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
idx = key->idx;
|
|
||||||
if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_WEP,
|
|
||||||
broadcast_ether_addr, idx, 1,
|
|
||||||
NULL, 0, key->key[idx],
|
|
||||||
key->len[idx])) {
|
|
||||||
wpa_printf(MSG_WARNING, "Could not set "
|
|
||||||
"dynamic VLAN WEP encryption.");
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hostapd_cleanup - Per-BSS cleanup (deinitialization)
|
|
||||||
* @hapd: Pointer to BSS data
|
|
||||||
*
|
|
||||||
* This function is used to free all per-BSS data structures and resources.
|
|
||||||
* This gets called in a loop for each BSS between calls to
|
|
||||||
* hostapd_cleanup_iface_pre() and hostapd_cleanup_iface() when an interface
|
|
||||||
* is deinitialized. Most of the modules that are initialized in
|
|
||||||
* hostapd_setup_bss() are deinitialized here.
|
|
||||||
*/
|
|
||||||
static void hostapd_cleanup(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
if (hapd->iface->ctrl_iface_deinit)
|
|
||||||
hapd->iface->ctrl_iface_deinit(hapd);
|
|
||||||
|
|
||||||
iapp_deinit(hapd->iapp);
|
|
||||||
hapd->iapp = NULL;
|
|
||||||
accounting_deinit(hapd);
|
|
||||||
hostapd_deinit_wpa(hapd);
|
|
||||||
vlan_deinit(hapd);
|
|
||||||
hostapd_acl_deinit(hapd);
|
|
||||||
#ifndef CONFIG_NO_RADIUS
|
|
||||||
radius_client_deinit(hapd->radius);
|
|
||||||
hapd->radius = NULL;
|
|
||||||
#endif /* CONFIG_NO_RADIUS */
|
|
||||||
|
|
||||||
hostapd_deinit_wps(hapd);
|
|
||||||
|
|
||||||
authsrv_deinit(hapd);
|
|
||||||
|
|
||||||
if (hapd->interface_added &&
|
|
||||||
hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) {
|
|
||||||
wpa_printf(MSG_WARNING, "Failed to remove BSS interface %s",
|
|
||||||
hapd->conf->iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
os_free(hapd->probereq_cb);
|
|
||||||
hapd->probereq_cb = NULL;
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
wpabuf_free(hapd->p2p_beacon_ie);
|
|
||||||
hapd->p2p_beacon_ie = NULL;
|
|
||||||
wpabuf_free(hapd->p2p_probe_resp_ie);
|
|
||||||
hapd->p2p_probe_resp_ie = NULL;
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hostapd_cleanup_iface_pre - Preliminary per-interface cleanup
|
|
||||||
* @iface: Pointer to interface data
|
|
||||||
*
|
|
||||||
* This function is called before per-BSS data structures are deinitialized
|
|
||||||
* with hostapd_cleanup().
|
|
||||||
*/
|
|
||||||
static void hostapd_cleanup_iface_pre(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hostapd_cleanup_iface - Complete per-interface cleanup
|
|
||||||
* @iface: Pointer to interface data
|
|
||||||
*
|
|
||||||
* This function is called after per-BSS data structures are deinitialized
|
|
||||||
* with hostapd_cleanup().
|
|
||||||
*/
|
|
||||||
static void hostapd_cleanup_iface(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
|
|
||||||
iface->hw_features = NULL;
|
|
||||||
os_free(iface->current_rates);
|
|
||||||
iface->current_rates = NULL;
|
|
||||||
ap_list_deinit(iface);
|
|
||||||
hostapd_config_free(iface->conf);
|
|
||||||
iface->conf = NULL;
|
|
||||||
|
|
||||||
os_free(iface->config_fname);
|
|
||||||
os_free(iface->bss);
|
|
||||||
os_free(iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
hostapd_broadcast_wep_set(hapd);
|
|
||||||
|
|
||||||
if (hapd->conf->ssid.wep.default_len) {
|
|
||||||
hostapd_set_privacy(hapd, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
if (hapd->conf->ssid.wep.key[i] &&
|
|
||||||
hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i,
|
|
||||||
i == hapd->conf->ssid.wep.idx, NULL, 0,
|
|
||||||
hapd->conf->ssid.wep.key[i],
|
|
||||||
hapd->conf->ssid.wep.len[i])) {
|
|
||||||
wpa_printf(MSG_WARNING, "Could not set WEP "
|
|
||||||
"encryption.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (hapd->conf->ssid.wep.key[i] &&
|
|
||||||
i == hapd->conf->ssid.wep.idx)
|
|
||||||
hostapd_set_privacy(hapd, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_flush_old_stations(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
u8 addr[ETH_ALEN];
|
|
||||||
|
|
||||||
if (hostapd_drv_none(hapd) || hapd->drv_priv == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "Flushing old station entries");
|
|
||||||
if (hostapd_flush(hapd)) {
|
|
||||||
wpa_printf(MSG_WARNING, "Could not connect to kernel driver.");
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
wpa_printf(MSG_DEBUG, "Deauthenticate all stations");
|
|
||||||
os_memset(addr, 0xff, ETH_ALEN);
|
|
||||||
hostapd_drv_sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
|
|
||||||
hostapd_free_stas(hapd);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hostapd_validate_bssid_configuration - Validate BSSID configuration
|
|
||||||
* @iface: Pointer to interface data
|
|
||||||
* Returns: 0 on success, -1 on failure
|
|
||||||
*
|
|
||||||
* This function is used to validate that the configured BSSIDs are valid.
|
|
||||||
*/
|
|
||||||
static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
u8 mask[ETH_ALEN] = { 0 };
|
|
||||||
struct hostapd_data *hapd = iface->bss[0];
|
|
||||||
unsigned int i = iface->conf->num_bss, bits = 0, j;
|
|
||||||
int res;
|
|
||||||
int auto_addr = 0;
|
|
||||||
|
|
||||||
if (hostapd_drv_none(hapd))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Generate BSSID mask that is large enough to cover the BSSIDs. */
|
|
||||||
|
|
||||||
/* Determine the bits necessary to cover the number of BSSIDs. */
|
|
||||||
for (i--; i; i >>= 1)
|
|
||||||
bits++;
|
|
||||||
|
|
||||||
/* Determine the bits necessary to any configured BSSIDs,
|
|
||||||
if they are higher than the number of BSSIDs. */
|
|
||||||
for (j = 0; j < iface->conf->num_bss; j++) {
|
|
||||||
if (hostapd_mac_comp_empty(iface->conf->bss[j].bssid) == 0) {
|
|
||||||
if (j)
|
|
||||||
auto_addr++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ETH_ALEN; i++) {
|
|
||||||
mask[i] |=
|
|
||||||
iface->conf->bss[j].bssid[i] ^
|
|
||||||
hapd->own_addr[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!auto_addr)
|
|
||||||
goto skip_mask_ext;
|
|
||||||
|
|
||||||
for (i = 0; i < ETH_ALEN && mask[i] == 0; i++)
|
|
||||||
;
|
|
||||||
j = 0;
|
|
||||||
if (i < ETH_ALEN) {
|
|
||||||
j = (5 - i) * 8;
|
|
||||||
|
|
||||||
while (mask[i] != 0) {
|
|
||||||
mask[i] >>= 1;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bits < j)
|
|
||||||
bits = j;
|
|
||||||
|
|
||||||
if (bits > 40) {
|
|
||||||
wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)",
|
|
||||||
bits);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_memset(mask, 0xff, ETH_ALEN);
|
|
||||||
j = bits / 8;
|
|
||||||
for (i = 5; i > 5 - j; i--)
|
|
||||||
mask[i] = 0;
|
|
||||||
j = bits % 8;
|
|
||||||
while (j--)
|
|
||||||
mask[i] <<= 1;
|
|
||||||
|
|
||||||
skip_mask_ext:
|
|
||||||
wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)",
|
|
||||||
(unsigned long) iface->conf->num_bss, MAC2STR(mask), bits);
|
|
||||||
|
|
||||||
res = hostapd_valid_bss_mask(hapd, hapd->own_addr, mask);
|
|
||||||
if (res == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (res < 0) {
|
|
||||||
wpa_printf(MSG_ERROR, "Driver did not accept BSSID mask "
|
|
||||||
MACSTR " for start address " MACSTR ".",
|
|
||||||
MAC2STR(mask), MAC2STR(hapd->own_addr));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!auto_addr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = 0; i < ETH_ALEN; i++) {
|
|
||||||
if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) {
|
|
||||||
wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR
|
|
||||||
" for start address " MACSTR ".",
|
|
||||||
MAC2STR(mask), MAC2STR(hapd->own_addr));
|
|
||||||
wpa_printf(MSG_ERROR, "Start address must be the "
|
|
||||||
"first address in the block (i.e., addr "
|
|
||||||
"AND mask == addr).");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int mac_in_conf(struct hostapd_config *conf, const void *a)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < conf->num_bss; i++) {
|
|
||||||
if (hostapd_mac_comp(conf->bss[i].bssid, a) == 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hostapd_setup_bss - Per-BSS setup (initialization)
|
|
||||||
* @hapd: Pointer to BSS data
|
|
||||||
* @first: Whether this BSS is the first BSS of an interface
|
|
||||||
*
|
|
||||||
* This function is used to initialize all per-BSS data structures and
|
|
||||||
* resources. This gets called in a loop for each BSS when an interface is
|
|
||||||
* initialized. Most of the modules that are initialized here will be
|
|
||||||
* deinitialized in hostapd_cleanup().
|
|
||||||
*/
|
|
||||||
static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
|
|
||||||
{
|
|
||||||
struct hostapd_bss_config *conf = hapd->conf;
|
|
||||||
u8 ssid[HOSTAPD_MAX_SSID_LEN + 1];
|
|
||||||
int ssid_len, set_ssid;
|
|
||||||
char force_ifname[IFNAMSIZ];
|
|
||||||
u8 if_addr[ETH_ALEN];
|
|
||||||
|
|
||||||
if (!first) {
|
|
||||||
if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) {
|
|
||||||
/* Allocate the next available BSSID. */
|
|
||||||
do {
|
|
||||||
inc_byte_array(hapd->own_addr, ETH_ALEN);
|
|
||||||
} while (mac_in_conf(hapd->iconf, hapd->own_addr));
|
|
||||||
} else {
|
|
||||||
/* Allocate the configured BSSID. */
|
|
||||||
os_memcpy(hapd->own_addr, hapd->conf->bssid, ETH_ALEN);
|
|
||||||
|
|
||||||
if (hostapd_mac_comp(hapd->own_addr,
|
|
||||||
hapd->iface->bss[0]->own_addr) ==
|
|
||||||
0) {
|
|
||||||
wpa_printf(MSG_ERROR, "BSS '%s' may not have "
|
|
||||||
"BSSID set to the MAC address of "
|
|
||||||
"the radio", hapd->conf->iface);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hapd->interface_added = 1;
|
|
||||||
if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS,
|
|
||||||
hapd->conf->iface, hapd->own_addr, hapd,
|
|
||||||
&hapd->drv_priv, force_ifname, if_addr,
|
|
||||||
hapd->conf->bridge[0] ? hapd->conf->bridge :
|
|
||||||
NULL)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID="
|
|
||||||
MACSTR ")", MAC2STR(hapd->own_addr));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conf->wmm_enabled < 0)
|
|
||||||
conf->wmm_enabled = hapd->iconf->ieee80211n;
|
|
||||||
|
|
||||||
hostapd_flush_old_stations(hapd);
|
|
||||||
hostapd_set_privacy(hapd, 0);
|
|
||||||
|
|
||||||
hostapd_broadcast_wep_clear(hapd);
|
|
||||||
if (hostapd_setup_encryption(hapd->conf->iface, hapd))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fetch the SSID from the system and use it or,
|
|
||||||
* if one was specified in the config file, verify they
|
|
||||||
* match.
|
|
||||||
*/
|
|
||||||
ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid));
|
|
||||||
if (ssid_len < 0) {
|
|
||||||
wpa_printf(MSG_ERROR, "Could not read SSID from system");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (conf->ssid.ssid_set) {
|
|
||||||
/*
|
|
||||||
* If SSID is specified in the config file and it differs
|
|
||||||
* from what is being used then force installation of the
|
|
||||||
* new SSID.
|
|
||||||
*/
|
|
||||||
set_ssid = (conf->ssid.ssid_len != (size_t) ssid_len ||
|
|
||||||
os_memcmp(conf->ssid.ssid, ssid, ssid_len) != 0);
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* No SSID in the config file; just use the one we got
|
|
||||||
* from the system.
|
|
||||||
*/
|
|
||||||
set_ssid = 0;
|
|
||||||
conf->ssid.ssid_len = ssid_len;
|
|
||||||
os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len);
|
|
||||||
conf->ssid.ssid[conf->ssid.ssid_len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hostapd_drv_none(hapd)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Using interface %s with hwaddr " MACSTR
|
|
||||||
" and ssid '%s'",
|
|
||||||
hapd->conf->iface, MAC2STR(hapd->own_addr),
|
|
||||||
hapd->conf->ssid.ssid);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hostapd_setup_wpa_psk(conf)) {
|
|
||||||
wpa_printf(MSG_ERROR, "WPA-PSK setup failed.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set SSID for the kernel driver (to be used in beacon and probe
|
|
||||||
* response frames) */
|
|
||||||
if (set_ssid && hostapd_set_ssid(hapd, (u8 *) conf->ssid.ssid,
|
|
||||||
conf->ssid.ssid_len)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wpa_debug_level == MSG_MSGDUMP)
|
|
||||||
conf->radius->msg_dumps = 1;
|
|
||||||
#ifndef CONFIG_NO_RADIUS
|
|
||||||
hapd->radius = radius_client_init(hapd, conf->radius);
|
|
||||||
if (hapd->radius == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "RADIUS client initialization failed.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_NO_RADIUS */
|
|
||||||
|
|
||||||
if (hostapd_acl_init(hapd)) {
|
|
||||||
wpa_printf(MSG_ERROR, "ACL initialization failed.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (hostapd_init_wps(hapd, conf))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (authsrv_init(hapd) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (ieee802_1x_init(hapd)) {
|
|
||||||
wpa_printf(MSG_ERROR, "IEEE 802.1X initialization failed.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hapd->conf->wpa && hostapd_setup_wpa(hapd))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (accounting_init(hapd)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Accounting initialization failed.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hapd->conf->ieee802_11f &&
|
|
||||||
(hapd->iapp = iapp_init(hapd, hapd->conf->iapp_iface)) == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "IEEE 802.11F (IAPP) initialization "
|
|
||||||
"failed.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hapd->iface->ctrl_iface_init &&
|
|
||||||
hapd->iface->ctrl_iface_init(hapd)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to setup control interface");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hostapd_drv_none(hapd) && vlan_init(hapd)) {
|
|
||||||
wpa_printf(MSG_ERROR, "VLAN initialization failed.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ieee802_11_set_beacon(hapd);
|
|
||||||
|
|
||||||
if (hapd->driver && hapd->driver->set_operstate)
|
|
||||||
hapd->driver->set_operstate(hapd->drv_priv, 1);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_tx_queue_params(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
struct hostapd_data *hapd = iface->bss[0];
|
|
||||||
int i;
|
|
||||||
struct hostapd_tx_queue_params *p;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_TX_QUEUES; i++) {
|
|
||||||
p = &iface->conf->tx_queue[i];
|
|
||||||
|
|
||||||
if (hostapd_set_tx_queue_params(hapd, i, p->aifs, p->cwmin,
|
|
||||||
p->cwmax, p->burst)) {
|
|
||||||
wpa_printf(MSG_DEBUG, "Failed to set TX queue "
|
|
||||||
"parameters for queue %d.", i);
|
|
||||||
/* Continue anyway */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int setup_interface(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
struct hostapd_data *hapd = iface->bss[0];
|
|
||||||
size_t i;
|
|
||||||
char country[4];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure that all BSSes get configured with a pointer to the same
|
|
||||||
* driver interface.
|
|
||||||
*/
|
|
||||||
for (i = 1; i < iface->num_bss; i++) {
|
|
||||||
iface->bss[i]->driver = hapd->driver;
|
|
||||||
iface->bss[i]->drv_priv = hapd->drv_priv;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hostapd_validate_bssid_configuration(iface))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (hapd->iconf->country[0] && hapd->iconf->country[1]) {
|
|
||||||
os_memcpy(country, hapd->iconf->country, 3);
|
|
||||||
country[3] = '\0';
|
|
||||||
if (hostapd_set_country(hapd, country) < 0) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to set country code");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hostapd_get_hw_features(iface)) {
|
|
||||||
/* Not all drivers support this yet, so continue without hw
|
|
||||||
* feature data. */
|
|
||||||
} else {
|
|
||||||
int ret = hostapd_select_hw_mode(iface);
|
|
||||||
if (ret < 0) {
|
|
||||||
wpa_printf(MSG_ERROR, "Could not select hw_mode and "
|
|
||||||
"channel. (%d)", ret);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ret = hostapd_check_ht_capab(iface);
|
|
||||||
if (ret < 0)
|
|
||||||
return -1;
|
|
||||||
if (ret == 1) {
|
|
||||||
wpa_printf(MSG_DEBUG, "Interface initialization will "
|
|
||||||
"be completed in a callback");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hostapd_setup_interface_complete(iface, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
|
|
||||||
{
|
|
||||||
struct hostapd_data *hapd = iface->bss[0];
|
|
||||||
size_t j;
|
|
||||||
u8 *prev_addr;
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
wpa_printf(MSG_ERROR, "Interface initialization failed");
|
|
||||||
eloop_terminate();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "Completing interface initialization");
|
|
||||||
if (hapd->iconf->channel) {
|
|
||||||
iface->freq = hostapd_hw_get_freq(hapd, hapd->iconf->channel);
|
|
||||||
wpa_printf(MSG_DEBUG, "Mode: %s Channel: %d "
|
|
||||||
"Frequency: %d MHz",
|
|
||||||
hostapd_hw_mode_txt(hapd->iconf->hw_mode),
|
|
||||||
hapd->iconf->channel, iface->freq);
|
|
||||||
|
|
||||||
if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq,
|
|
||||||
hapd->iconf->channel,
|
|
||||||
hapd->iconf->ieee80211n,
|
|
||||||
hapd->iconf->secondary_channel)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Could not set channel for "
|
|
||||||
"kernel driver");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iface->current_mode) {
|
|
||||||
if (hostapd_prepare_rates(hapd, iface->current_mode)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Failed to prepare rates "
|
|
||||||
"table.");
|
|
||||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
|
|
||||||
HOSTAPD_LEVEL_WARNING,
|
|
||||||
"Failed to prepare rates table.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hapd->iconf->rts_threshold > -1 &&
|
|
||||||
hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Could not set RTS threshold for "
|
|
||||||
"kernel driver");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hapd->iconf->fragm_threshold > -1 &&
|
|
||||||
hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) {
|
|
||||||
wpa_printf(MSG_ERROR, "Could not set fragmentation threshold "
|
|
||||||
"for kernel driver");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_addr = hapd->own_addr;
|
|
||||||
|
|
||||||
for (j = 0; j < iface->num_bss; j++) {
|
|
||||||
hapd = iface->bss[j];
|
|
||||||
if (j)
|
|
||||||
os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
|
|
||||||
if (hostapd_setup_bss(hapd, j == 0))
|
|
||||||
return -1;
|
|
||||||
if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0)
|
|
||||||
prev_addr = hapd->own_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
hostapd_tx_queue_params(iface);
|
|
||||||
|
|
||||||
ap_list_init(iface);
|
|
||||||
|
|
||||||
if (hostapd_driver_commit(hapd) < 0) {
|
|
||||||
wpa_printf(MSG_ERROR, "%s: Failed to commit driver "
|
|
||||||
"configuration", __func__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hapd->setup_complete_cb)
|
|
||||||
hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
|
|
||||||
iface->bss[0]->conf->iface);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hostapd_setup_interface - Setup of an interface
|
|
||||||
* @iface: Pointer to interface data.
|
|
||||||
* Returns: 0 on success, -1 on failure
|
|
||||||
*
|
|
||||||
* Initializes the driver interface, validates the configuration,
|
|
||||||
* and sets driver parameters based on the configuration.
|
|
||||||
* Flushes old stations, sets the channel, encryption,
|
|
||||||
* beacons, and WDS links based on the configuration.
|
|
||||||
*/
|
|
||||||
int hostapd_setup_interface(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = setup_interface(iface);
|
|
||||||
if (ret) {
|
|
||||||
wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
|
|
||||||
iface->bss[0]->conf->iface);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hostapd_alloc_bss_data - Allocate and initialize per-BSS data
|
|
||||||
* @hapd_iface: Pointer to interface data
|
|
||||||
* @conf: Pointer to per-interface configuration
|
|
||||||
* @bss: Pointer to per-BSS configuration for this BSS
|
|
||||||
* Returns: Pointer to allocated BSS data
|
|
||||||
*
|
|
||||||
* This function is used to allocate per-BSS data structure. This data will be
|
|
||||||
* freed after hostapd_cleanup() is called for it during interface
|
|
||||||
* deinitialization.
|
|
||||||
*/
|
|
||||||
struct hostapd_data *
|
|
||||||
hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
|
|
||||||
struct hostapd_config *conf,
|
|
||||||
struct hostapd_bss_config *bss)
|
|
||||||
{
|
|
||||||
struct hostapd_data *hapd;
|
|
||||||
|
|
||||||
hapd = os_zalloc(sizeof(*hapd));
|
|
||||||
if (hapd == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
hapd->new_assoc_sta_cb = hostapd_new_assoc_sta;
|
|
||||||
hapd->iconf = conf;
|
|
||||||
hapd->conf = bss;
|
|
||||||
hapd->iface = hapd_iface;
|
|
||||||
hapd->driver = hapd->iconf->driver;
|
|
||||||
|
|
||||||
return hapd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void hostapd_interface_deinit(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
size_t j;
|
|
||||||
|
|
||||||
if (iface == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
hostapd_cleanup_iface_pre(iface);
|
|
||||||
for (j = 0; j < iface->num_bss; j++) {
|
|
||||||
struct hostapd_data *hapd = iface->bss[j];
|
|
||||||
hostapd_free_stas(hapd);
|
|
||||||
hostapd_flush_old_stations(hapd);
|
|
||||||
hostapd_cleanup(hapd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void hostapd_interface_free(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
size_t j;
|
|
||||||
for (j = 0; j < iface->num_bss; j++)
|
|
||||||
os_free(iface->bss[j]);
|
|
||||||
hostapd_cleanup_iface(iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hostapd_new_assoc_sta - Notify that a new station associated with the AP
|
|
||||||
* @hapd: Pointer to BSS data
|
|
||||||
* @sta: Pointer to the associated STA data
|
|
||||||
* @reassoc: 1 to indicate this was a re-association; 0 = first association
|
|
||||||
*
|
|
||||||
* This function will be called whenever a station associates with the AP. It
|
|
||||||
* can be called from ieee802_11.c for drivers that export MLME to hostapd and
|
|
||||||
* from drv_callbacks.c based on driver events for drivers that take care of
|
|
||||||
* management frames (IEEE 802.11 authentication and association) internally.
|
|
||||||
*/
|
|
||||||
void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
|
|
||||||
int reassoc)
|
|
||||||
{
|
|
||||||
if (hapd->tkip_countermeasures) {
|
|
||||||
hostapd_drv_sta_deauth(hapd, sta->addr,
|
|
||||||
WLAN_REASON_MICHAEL_MIC_FAILURE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hostapd_prune_associations(hapd, sta->addr);
|
|
||||||
|
|
||||||
/* IEEE 802.11F (IAPP) */
|
|
||||||
if (hapd->conf->ieee802_11f)
|
|
||||||
iapp_new_station(hapd->iapp, sta);
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
if (sta->p2p_ie == NULL && !sta->no_p2p_set) {
|
|
||||||
sta->no_p2p_set = 1;
|
|
||||||
hapd->num_sta_no_p2p++;
|
|
||||||
if (hapd->num_sta_no_p2p == 1)
|
|
||||||
hostapd_p2p_non_p2p_sta_connected(hapd);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
|
|
||||||
/* Start accounting here, if IEEE 802.1X and WPA are not used.
|
|
||||||
* IEEE 802.1X/WPA code will start accounting after the station has
|
|
||||||
* been authorized. */
|
|
||||||
if (!hapd->conf->ieee802_1x && !hapd->conf->wpa)
|
|
||||||
accounting_sta_start(hapd, sta);
|
|
||||||
|
|
||||||
/* Start IEEE 802.1X authentication process for new stations */
|
|
||||||
ieee802_1x_new_station(hapd, sta);
|
|
||||||
if (reassoc) {
|
|
||||||
if (sta->auth_alg != WLAN_AUTH_FT &&
|
|
||||||
!(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)))
|
|
||||||
wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
|
|
||||||
} else
|
|
||||||
wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
|
|
||||||
}
|
|
|
@ -1,262 +0,0 @@
|
||||||
/*
|
|
||||||
* hostapd / Initialization and configuration
|
|
||||||
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* Alternatively, this software may be distributed under the terms of BSD
|
|
||||||
* license.
|
|
||||||
*
|
|
||||||
* See README and COPYING for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HOSTAPD_H
|
|
||||||
#define HOSTAPD_H
|
|
||||||
|
|
||||||
#include "common/defs.h"
|
|
||||||
|
|
||||||
struct wpa_driver_ops;
|
|
||||||
struct wpa_ctrl_dst;
|
|
||||||
struct radius_server_data;
|
|
||||||
struct upnp_wps_device_sm;
|
|
||||||
struct hapd_interfaces;
|
|
||||||
struct hostapd_data;
|
|
||||||
struct sta_info;
|
|
||||||
struct hostap_sta_driver_data;
|
|
||||||
struct ieee80211_ht_capabilities;
|
|
||||||
struct full_dynamic_vlan;
|
|
||||||
enum wps_event;
|
|
||||||
union wps_event_data;
|
|
||||||
|
|
||||||
struct hostapd_probereq_cb {
|
|
||||||
int (*cb)(void *ctx, const u8 *sa, const u8 *ie, size_t ie_len);
|
|
||||||
void *ctx;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define HOSTAPD_RATE_BASIC 0x00000001
|
|
||||||
|
|
||||||
struct hostapd_rate_data {
|
|
||||||
int rate; /* rate in 100 kbps */
|
|
||||||
int flags; /* HOSTAPD_RATE_ flags */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hostapd_frame_info {
|
|
||||||
u32 channel;
|
|
||||||
u32 datarate;
|
|
||||||
u32 ssi_signal;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct hostapd_data - hostapd per-BSS data structure
|
|
||||||
*/
|
|
||||||
struct hostapd_data {
|
|
||||||
struct hostapd_iface *iface;
|
|
||||||
struct hostapd_config *iconf;
|
|
||||||
struct hostapd_bss_config *conf;
|
|
||||||
int interface_added; /* virtual interface added for this BSS */
|
|
||||||
|
|
||||||
u8 own_addr[ETH_ALEN];
|
|
||||||
|
|
||||||
int num_sta; /* number of entries in sta_list */
|
|
||||||
struct sta_info *sta_list; /* STA info list head */
|
|
||||||
#define STA_HASH_SIZE 256
|
|
||||||
#define STA_HASH(sta) (sta[5])
|
|
||||||
struct sta_info *sta_hash[STA_HASH_SIZE];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bitfield for indicating which AIDs are allocated. Only AID values
|
|
||||||
* 1-2007 are used and as such, the bit at index 0 corresponds to AID
|
|
||||||
* 1.
|
|
||||||
*/
|
|
||||||
#define AID_WORDS ((2008 + 31) / 32)
|
|
||||||
u32 sta_aid[AID_WORDS];
|
|
||||||
|
|
||||||
const struct wpa_driver_ops *driver;
|
|
||||||
void *drv_priv;
|
|
||||||
|
|
||||||
void (*new_assoc_sta_cb)(struct hostapd_data *hapd,
|
|
||||||
struct sta_info *sta, int reassoc);
|
|
||||||
|
|
||||||
void *msg_ctx; /* ctx for wpa_msg() calls */
|
|
||||||
|
|
||||||
struct radius_client_data *radius;
|
|
||||||
u32 acct_session_id_hi, acct_session_id_lo;
|
|
||||||
|
|
||||||
struct iapp_data *iapp;
|
|
||||||
|
|
||||||
struct hostapd_cached_radius_acl *acl_cache;
|
|
||||||
struct hostapd_acl_query_data *acl_queries;
|
|
||||||
|
|
||||||
struct wpa_authenticator *wpa_auth;
|
|
||||||
struct eapol_authenticator *eapol_auth;
|
|
||||||
|
|
||||||
struct rsn_preauth_interface *preauth_iface;
|
|
||||||
time_t michael_mic_failure;
|
|
||||||
int michael_mic_failures;
|
|
||||||
int tkip_countermeasures;
|
|
||||||
|
|
||||||
int ctrl_sock;
|
|
||||||
struct wpa_ctrl_dst *ctrl_dst;
|
|
||||||
|
|
||||||
void *ssl_ctx;
|
|
||||||
void *eap_sim_db_priv;
|
|
||||||
struct radius_server_data *radius_srv;
|
|
||||||
|
|
||||||
int parameter_set_count;
|
|
||||||
|
|
||||||
#ifdef CONFIG_FULL_DYNAMIC_VLAN
|
|
||||||
struct full_dynamic_vlan *full_dynamic_vlan;
|
|
||||||
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
|
|
||||||
|
|
||||||
struct l2_packet_data *l2;
|
|
||||||
struct wps_context *wps;
|
|
||||||
|
|
||||||
struct wpabuf *wps_beacon_ie;
|
|
||||||
struct wpabuf *wps_probe_resp_ie;
|
|
||||||
#ifdef CONFIG_WPS
|
|
||||||
unsigned int ap_pin_failures;
|
|
||||||
struct upnp_wps_device_sm *wps_upnp;
|
|
||||||
unsigned int ap_pin_lockout_time;
|
|
||||||
#endif /* CONFIG_WPS */
|
|
||||||
|
|
||||||
struct hostapd_probereq_cb *probereq_cb;
|
|
||||||
size_t num_probereq_cb;
|
|
||||||
|
|
||||||
void (*public_action_cb)(void *ctx, const u8 *buf, size_t len,
|
|
||||||
int freq);
|
|
||||||
void *public_action_cb_ctx;
|
|
||||||
|
|
||||||
int (*vendor_action_cb)(void *ctx, const u8 *buf, size_t len,
|
|
||||||
int freq);
|
|
||||||
void *vendor_action_cb_ctx;
|
|
||||||
|
|
||||||
void (*wps_reg_success_cb)(void *ctx, const u8 *mac_addr,
|
|
||||||
const u8 *uuid_e);
|
|
||||||
void *wps_reg_success_cb_ctx;
|
|
||||||
|
|
||||||
void (*wps_event_cb)(void *ctx, enum wps_event event,
|
|
||||||
union wps_event_data *data);
|
|
||||||
void *wps_event_cb_ctx;
|
|
||||||
|
|
||||||
void (*sta_authorized_cb)(void *ctx, const u8 *mac_addr,
|
|
||||||
int authorized);
|
|
||||||
void *sta_authorized_cb_ctx;
|
|
||||||
|
|
||||||
void (*setup_complete_cb)(void *ctx);
|
|
||||||
void *setup_complete_cb_ctx;
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
struct p2p_data *p2p;
|
|
||||||
struct p2p_group *p2p_group;
|
|
||||||
struct wpabuf *p2p_beacon_ie;
|
|
||||||
struct wpabuf *p2p_probe_resp_ie;
|
|
||||||
|
|
||||||
/* Number of non-P2P association stations */
|
|
||||||
int num_sta_no_p2p;
|
|
||||||
|
|
||||||
/* Periodic NoA (used only when no non-P2P clients in the group) */
|
|
||||||
int noa_enabled;
|
|
||||||
int noa_start;
|
|
||||||
int noa_duration;
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct hostapd_iface - hostapd per-interface data structure
|
|
||||||
*/
|
|
||||||
struct hostapd_iface {
|
|
||||||
struct hapd_interfaces *interfaces;
|
|
||||||
void *owner;
|
|
||||||
int (*reload_config)(struct hostapd_iface *iface);
|
|
||||||
struct hostapd_config * (*config_read_cb)(const char *config_fname);
|
|
||||||
char *config_fname;
|
|
||||||
struct hostapd_config *conf;
|
|
||||||
|
|
||||||
size_t num_bss;
|
|
||||||
struct hostapd_data **bss;
|
|
||||||
|
|
||||||
int num_ap; /* number of entries in ap_list */
|
|
||||||
struct ap_info *ap_list; /* AP info list head */
|
|
||||||
struct ap_info *ap_hash[STA_HASH_SIZE];
|
|
||||||
struct ap_info *ap_iter_list;
|
|
||||||
|
|
||||||
unsigned int drv_flags;
|
|
||||||
struct hostapd_hw_modes *hw_features;
|
|
||||||
int num_hw_features;
|
|
||||||
struct hostapd_hw_modes *current_mode;
|
|
||||||
/* Rates that are currently used (i.e., filtered copy of
|
|
||||||
* current_mode->channels */
|
|
||||||
int num_rates;
|
|
||||||
struct hostapd_rate_data *current_rates;
|
|
||||||
int freq;
|
|
||||||
|
|
||||||
u16 hw_flags;
|
|
||||||
|
|
||||||
/* Number of associated Non-ERP stations (i.e., stations using 802.11b
|
|
||||||
* in 802.11g BSS) */
|
|
||||||
int num_sta_non_erp;
|
|
||||||
|
|
||||||
/* Number of associated stations that do not support Short Slot Time */
|
|
||||||
int num_sta_no_short_slot_time;
|
|
||||||
|
|
||||||
/* Number of associated stations that do not support Short Preamble */
|
|
||||||
int num_sta_no_short_preamble;
|
|
||||||
|
|
||||||
int olbc; /* Overlapping Legacy BSS Condition */
|
|
||||||
|
|
||||||
/* Number of HT associated stations that do not support greenfield */
|
|
||||||
int num_sta_ht_no_gf;
|
|
||||||
|
|
||||||
/* Number of associated non-HT stations */
|
|
||||||
int num_sta_no_ht;
|
|
||||||
|
|
||||||
/* Number of HT associated stations 20 MHz */
|
|
||||||
int num_sta_ht_20mhz;
|
|
||||||
|
|
||||||
/* Overlapping BSS information */
|
|
||||||
int olbc_ht;
|
|
||||||
|
|
||||||
u16 ht_op_mode;
|
|
||||||
void (*scan_cb)(struct hostapd_iface *iface);
|
|
||||||
|
|
||||||
int (*ctrl_iface_init)(struct hostapd_data *hapd);
|
|
||||||
void (*ctrl_iface_deinit)(struct hostapd_data *hapd);
|
|
||||||
|
|
||||||
int (*for_each_interface)(struct hapd_interfaces *interfaces,
|
|
||||||
int (*cb)(struct hostapd_iface *iface,
|
|
||||||
void *ctx), void *ctx);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* hostapd.c */
|
|
||||||
int hostapd_reload_config(struct hostapd_iface *iface);
|
|
||||||
struct hostapd_data *
|
|
||||||
hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
|
|
||||||
struct hostapd_config *conf,
|
|
||||||
struct hostapd_bss_config *bss);
|
|
||||||
int hostapd_setup_interface(struct hostapd_iface *iface);
|
|
||||||
int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
|
|
||||||
void hostapd_interface_deinit(struct hostapd_iface *iface);
|
|
||||||
void hostapd_interface_free(struct hostapd_iface *iface);
|
|
||||||
void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
|
|
||||||
int reassoc);
|
|
||||||
|
|
||||||
/* utils.c */
|
|
||||||
int hostapd_register_probereq_cb(struct hostapd_data *hapd,
|
|
||||||
int (*cb)(void *ctx, const u8 *sa,
|
|
||||||
const u8 *ie, size_t ie_len),
|
|
||||||
void *ctx);
|
|
||||||
void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr);
|
|
||||||
|
|
||||||
/* drv_callbacks.c (TODO: move to somewhere else?) */
|
|
||||||
int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
|
|
||||||
const u8 *ie, size_t ielen, int reassoc);
|
|
||||||
void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr);
|
|
||||||
void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr);
|
|
||||||
int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa,
|
|
||||||
const u8 *ie, size_t ie_len);
|
|
||||||
|
|
||||||
#endif /* HOSTAPD_H */
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue