Sync: merge r214649 through r214894 from ^/head.
This commit is contained in:
commit
eef8b03ca0
@ -14,6 +14,11 @@
|
||||
# The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last.
|
||||
#
|
||||
|
||||
# 20101101: headers moved to machine/ to x86/
|
||||
.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386"
|
||||
OLD_FILES+=usr/include/machine/apicreg.h
|
||||
OLD_FILES+=usr/include/machine/mca.h
|
||||
.endif
|
||||
# 20101020: catch up with vm_page_sleep_if_busy rename
|
||||
OLD_FILES+=usr/share/man/man9/vm_page_sleep_busy.9.gz
|
||||
# 20101011: removed subblock.h from liblzma
|
||||
|
@ -69,6 +69,11 @@ __FBSDID("$FreeBSD$");
|
||||
#define EOFMARKLEN 79
|
||||
#define PROMPTLEN 128
|
||||
|
||||
/* values of checkkwd variable */
|
||||
#define CHKALIAS 0x1
|
||||
#define CHKKWD 0x2
|
||||
#define CHKNL 0x4
|
||||
|
||||
/* values returned by readtoken */
|
||||
#include "token.h"
|
||||
|
||||
@ -102,9 +107,6 @@ static int startlinno; /* line # where last token started */
|
||||
static int funclinno; /* line # where the current function started */
|
||||
static struct parser_temp *parser_temp;
|
||||
|
||||
/* XXX When 'noaliases' is set to one, no alias expansion takes place. */
|
||||
static int noaliases = 0;
|
||||
|
||||
|
||||
static union node *list(int, int);
|
||||
static union node *andor(void);
|
||||
@ -230,7 +232,7 @@ list(int nlflag, int erflag)
|
||||
union node *ntop, *n1, *n2, *n3;
|
||||
int tok;
|
||||
|
||||
checkkwd = 2;
|
||||
checkkwd = CHKNL | CHKKWD | CHKALIAS;
|
||||
if (!nlflag && !erflag && tokendlist[peektoken()])
|
||||
return NULL;
|
||||
ntop = n1 = NULL;
|
||||
@ -283,7 +285,7 @@ list(int nlflag, int erflag)
|
||||
} else {
|
||||
tokpushback++;
|
||||
}
|
||||
checkkwd = 2;
|
||||
checkkwd = CHKNL | CHKKWD | CHKALIAS;
|
||||
if (!nlflag && !erflag && tokendlist[peektoken()])
|
||||
return ntop;
|
||||
break;
|
||||
@ -339,7 +341,7 @@ pipeline(void)
|
||||
int negate, t;
|
||||
|
||||
negate = 0;
|
||||
checkkwd = 2;
|
||||
checkkwd = CHKNL | CHKKWD | CHKALIAS;
|
||||
TRACE(("pipeline: entered\n"));
|
||||
while (readtoken() == TNOT)
|
||||
negate = !negate;
|
||||
@ -355,7 +357,7 @@ pipeline(void)
|
||||
do {
|
||||
prev = lp;
|
||||
lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
|
||||
checkkwd = 2;
|
||||
checkkwd = CHKNL | CHKKWD | CHKALIAS;
|
||||
t = readtoken();
|
||||
tokpushback++;
|
||||
if (t == TNOT)
|
||||
@ -388,7 +390,7 @@ command(void)
|
||||
union node *redir, **rpp;
|
||||
int t;
|
||||
|
||||
checkkwd = 2;
|
||||
checkkwd = CHKNL | CHKKWD | CHKALIAS;
|
||||
redir = NULL;
|
||||
n1 = NULL;
|
||||
rpp = &redir;
|
||||
@ -429,7 +431,7 @@ command(void)
|
||||
}
|
||||
if (readtoken() != TFI)
|
||||
synexpect(TFI);
|
||||
checkkwd = 1;
|
||||
checkkwd = CHKKWD | CHKALIAS;
|
||||
break;
|
||||
case TWHILE:
|
||||
case TUNTIL: {
|
||||
@ -445,7 +447,7 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
|
||||
n1->nbinary.ch2 = list(0, 0);
|
||||
if (readtoken() != TDONE)
|
||||
synexpect(TDONE);
|
||||
checkkwd = 1;
|
||||
checkkwd = CHKKWD | CHKALIAS;
|
||||
break;
|
||||
}
|
||||
case TFOR:
|
||||
@ -487,7 +489,7 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
|
||||
if (lasttoken != TNL && lasttoken != TSEMI)
|
||||
tokpushback++;
|
||||
}
|
||||
checkkwd = 2;
|
||||
checkkwd = CHKNL | CHKKWD | CHKALIAS;
|
||||
if ((t = readtoken()) == TDO)
|
||||
t = TDONE;
|
||||
else if (t == TBEGIN)
|
||||
@ -497,7 +499,7 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
|
||||
n1->nfor.body = list(0, 0);
|
||||
if (readtoken() != t)
|
||||
synexpect(t);
|
||||
checkkwd = 1;
|
||||
checkkwd = CHKKWD | CHKALIAS;
|
||||
break;
|
||||
case TCASE:
|
||||
n1 = (union node *)stalloc(sizeof (struct ncase));
|
||||
@ -513,8 +515,7 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
|
||||
if (lasttoken != TWORD || ! equal(wordtext, "in"))
|
||||
synerror("expecting \"in\"");
|
||||
cpp = &n1->ncase.cases;
|
||||
noaliases = 1; /* turn off alias expansion */
|
||||
checkkwd = 2, readtoken();
|
||||
checkkwd = CHKNL | CHKKWD, readtoken();
|
||||
while (lasttoken != TESAC) {
|
||||
*cpp = cp = (union node *)stalloc(sizeof (struct nclist));
|
||||
cp->type = NCLIST;
|
||||
@ -526,28 +527,28 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
|
||||
ap->type = NARG;
|
||||
ap->narg.text = wordtext;
|
||||
ap->narg.backquote = backquotelist;
|
||||
if (checkkwd = 2, readtoken() != TPIPE)
|
||||
checkkwd = CHKNL | CHKKWD;
|
||||
if (readtoken() != TPIPE)
|
||||
break;
|
||||
app = &ap->narg.next;
|
||||
readtoken();
|
||||
}
|
||||
ap->narg.next = NULL;
|
||||
if (lasttoken != TRP)
|
||||
noaliases = 0, synexpect(TRP);
|
||||
synexpect(TRP);
|
||||
cp->nclist.body = list(0, 0);
|
||||
|
||||
checkkwd = 2;
|
||||
checkkwd = CHKNL | CHKKWD | CHKALIAS;
|
||||
if ((t = readtoken()) != TESAC) {
|
||||
if (t != TENDCASE)
|
||||
noaliases = 0, synexpect(TENDCASE);
|
||||
synexpect(TENDCASE);
|
||||
else
|
||||
checkkwd = 2, readtoken();
|
||||
checkkwd = CHKNL | CHKKWD, readtoken();
|
||||
}
|
||||
cpp = &cp->nclist.next;
|
||||
}
|
||||
noaliases = 0; /* reset alias expansion */
|
||||
*cpp = NULL;
|
||||
checkkwd = 1;
|
||||
checkkwd = CHKKWD | CHKALIAS;
|
||||
break;
|
||||
case TLP:
|
||||
n1 = (union node *)stalloc(sizeof (struct nredir));
|
||||
@ -556,13 +557,13 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
|
||||
n1->nredir.redirect = NULL;
|
||||
if (readtoken() != TRP)
|
||||
synexpect(TRP);
|
||||
checkkwd = 1;
|
||||
checkkwd = CHKKWD | CHKALIAS;
|
||||
break;
|
||||
case TBEGIN:
|
||||
n1 = list(0, 0);
|
||||
if (readtoken() != TEND)
|
||||
synexpect(TEND);
|
||||
checkkwd = 1;
|
||||
checkkwd = CHKKWD | CHKALIAS;
|
||||
break;
|
||||
/* Handle an empty command like other simple commands. */
|
||||
case TBACKGND:
|
||||
@ -796,7 +797,6 @@ static int
|
||||
readtoken(void)
|
||||
{
|
||||
int t;
|
||||
int savecheckkwd = checkkwd;
|
||||
struct alias *ap;
|
||||
#ifdef DEBUG
|
||||
int alreadyseen = tokpushback;
|
||||
@ -805,25 +805,24 @@ readtoken(void)
|
||||
top:
|
||||
t = xxreadtoken();
|
||||
|
||||
if (checkkwd) {
|
||||
/*
|
||||
* eat newlines
|
||||
*/
|
||||
if (checkkwd == 2) {
|
||||
checkkwd = 0;
|
||||
while (t == TNL) {
|
||||
parseheredoc();
|
||||
t = xxreadtoken();
|
||||
}
|
||||
} else
|
||||
checkkwd = 0;
|
||||
/*
|
||||
* check for keywords and aliases
|
||||
*/
|
||||
if (t == TWORD && !quoteflag)
|
||||
{
|
||||
const char * const *pp;
|
||||
/*
|
||||
* eat newlines
|
||||
*/
|
||||
if (checkkwd & CHKNL) {
|
||||
while (t == TNL) {
|
||||
parseheredoc();
|
||||
t = xxreadtoken();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check for keywords and aliases
|
||||
*/
|
||||
if (t == TWORD && !quoteflag)
|
||||
{
|
||||
const char * const *pp;
|
||||
|
||||
if (checkkwd & CHKKWD)
|
||||
for (pp = parsekwd; *pp; pp++) {
|
||||
if (**pp == *wordtext && equal(*pp, wordtext))
|
||||
{
|
||||
@ -832,16 +831,16 @@ readtoken(void)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (noaliases == 0 &&
|
||||
(ap = lookupalias(wordtext, 1)) != NULL) {
|
||||
pushstring(ap->val, strlen(ap->val), ap);
|
||||
checkkwd = savecheckkwd;
|
||||
goto top;
|
||||
}
|
||||
if (checkkwd & CHKALIAS &&
|
||||
(ap = lookupalias(wordtext, 1)) != NULL) {
|
||||
pushstring(ap->val, strlen(ap->val), ap);
|
||||
goto top;
|
||||
}
|
||||
out:
|
||||
checkkwd = (t == TNOT) ? savecheckkwd : 0;
|
||||
}
|
||||
out:
|
||||
if (t != TNOT)
|
||||
checkkwd = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!alreadyseen)
|
||||
TRACE(("token %s %s\n", tokname[t], t == TWORD ? wordtext : ""));
|
||||
|
@ -257,14 +257,15 @@ f_rows(struct info *ip)
|
||||
void
|
||||
f_sane(struct info *ip)
|
||||
{
|
||||
struct termios def;
|
||||
|
||||
ip->t.c_cflag = TTYDEF_CFLAG | (ip->t.c_cflag & CLOCAL);
|
||||
ip->t.c_iflag = TTYDEF_IFLAG;
|
||||
ip->t.c_iflag |= ICRNL;
|
||||
cfmakesane(&def);
|
||||
ip->t.c_cflag = def.c_cflag | (ip->t.c_cflag & CLOCAL);
|
||||
ip->t.c_iflag = def.c_iflag;
|
||||
/* preserve user-preference flags in lflag */
|
||||
#define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH)
|
||||
ip->t.c_lflag = TTYDEF_LFLAG | (ip->t.c_lflag & LKEEP);
|
||||
ip->t.c_oflag = TTYDEF_OFLAG;
|
||||
ip->t.c_lflag = def.c_lflag | (ip->t.c_lflag & LKEEP);
|
||||
ip->t.c_oflag = def.c_oflag;
|
||||
ip->set = 1;
|
||||
}
|
||||
|
||||
|
@ -5178,7 +5178,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
|
||||
line_ptr = dwarf_line_buffer + offset;
|
||||
|
||||
/* read in the header */
|
||||
lh->total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read);
|
||||
lh->total_length = read_initial_length (abfd, line_ptr, &cu->header, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
if (line_ptr + lh->total_length > dwarf_line_buffer + dwarf_line_size)
|
||||
{
|
||||
|
@ -187,6 +187,14 @@ static struct core_fns mipsfbsd_core_fns =
|
||||
NULL /* next */
|
||||
};
|
||||
|
||||
static struct core_fns mipsfbsd_elfcore_fns =
|
||||
{
|
||||
bfd_target_elf_flavour, /* core_flavour */
|
||||
default_check_format, /* check_format */
|
||||
default_core_sniffer, /* core_sniffer */
|
||||
fetch_elfcore_registers, /* core_read_registers */
|
||||
NULL /* next */
|
||||
};
|
||||
|
||||
/*
|
||||
* MIPSFBSD Offsets
|
||||
@ -576,4 +584,6 @@ _initialize_mipsfbsd_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_FREEBSD_ELF,
|
||||
mipsfbsd_init_abi);
|
||||
add_core_fns (&mipsfbsd_core_fns);
|
||||
add_core_fns (&mipsfbsd_elfcore_fns);
|
||||
}
|
||||
|
@ -694,7 +694,7 @@ char *text;
|
||||
int width;
|
||||
|
||||
s = NULL;
|
||||
width = display_width;
|
||||
width = screen_width;
|
||||
header_length = strlen(text);
|
||||
if (header_length >= width) {
|
||||
s = malloc((width + 1) * sizeof(char));
|
||||
@ -702,6 +702,14 @@ char *text;
|
||||
return (NULL);
|
||||
strncpy(s, text, width);
|
||||
s[width] = '\0';
|
||||
} else {
|
||||
s = malloc((width + 1) * sizeof(char));
|
||||
if (s == NULL)
|
||||
return (NULL);
|
||||
strncpy(s, text, width);
|
||||
while (screen_width > header_length)
|
||||
s[header_length++] = ' ';
|
||||
s[width] = '\0';
|
||||
}
|
||||
return (s);
|
||||
}
|
||||
@ -726,7 +734,7 @@ char *text;
|
||||
if (header_status == ON)
|
||||
{
|
||||
putchar('\n');
|
||||
fputs(text, stdout);
|
||||
standout(text, stdout);
|
||||
lastline++;
|
||||
}
|
||||
else if (header_status == ERASE)
|
||||
|
@ -14,7 +14,7 @@
|
||||
extern int Header_lines; /* 7 */
|
||||
|
||||
/* Maximum number of columns allowed for display */
|
||||
#define MAX_COLS 128
|
||||
#define MAX_COLS 512
|
||||
|
||||
/* Log base 2 of 1024 is 10 (2^10 == 1024) */
|
||||
#define LOG1024 10
|
||||
|
@ -1,5 +1,5 @@
|
||||
# <pre>
|
||||
# @(#)australasia 8.18
|
||||
# @(#)australasia 8.20
|
||||
# This file is in the public domain, so clarified as of
|
||||
# 2009-05-17 by Arthur David Olson.
|
||||
|
||||
@ -284,13 +284,26 @@ Zone Indian/Cocos 6:27:40 - LMT 1900
|
||||
# http://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html
|
||||
# </a>
|
||||
|
||||
# From Alexander Krivenyshev (2010-10-24):
|
||||
# According to Radio Fiji and Fiji Times online, Fiji will end DST 3
|
||||
# weeks earlier than expected - on March 6, 2011, not March 27, 2011...
|
||||
# Here is confirmation from Government of the Republic of the Fiji Islands,
|
||||
# Ministry of Information (fiji.gov.fj) web site:
|
||||
# <a href="http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=2608:daylight-savings&catid=71:press-releases&Itemid=155">
|
||||
# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=2608:daylight-savings&catid=71:press-releases&Itemid=155
|
||||
# </a>
|
||||
# or
|
||||
# <a href="http://www.worldtimezone.com/dst_news/dst_news_fiji04.html">
|
||||
# http://www.worldtimezone.com/dst_news/dst_news_fiji04.html
|
||||
# </a>
|
||||
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
Rule Fiji 1998 1999 - Nov Sun>=1 2:00 1:00 S
|
||||
Rule Fiji 1999 2000 - Feb lastSun 3:00 0 -
|
||||
Rule Fiji 2009 only - Nov 29 2:00 1:00 S
|
||||
Rule Fiji 2010 only - Mar lastSun 3:00 0 -
|
||||
Rule Fiji 2010 only - Oct 24 2:00 1:00 S
|
||||
Rule Fiji 2011 only - Mar lastSun 3:00 0 -
|
||||
Rule Fiji 2011 only - Mar Sun>=1 3:00 0 -
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Pacific/Fiji 11:53:40 - LMT 1915 Oct 26 # Suva
|
||||
12:00 Fiji FJ%sT # Fiji Time
|
||||
@ -487,11 +500,21 @@ Zone Pacific/Pago_Pago 12:37:12 - LMT 1879 Jul 5
|
||||
# http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf
|
||||
# </a>
|
||||
|
||||
# From Raymond Hughes (2010-10-07):
|
||||
# Please see
|
||||
# <a href="http://www.mcil.gov.ws">
|
||||
# http://www.mcil.gov.ws
|
||||
# </a>,
|
||||
# the Ministry of Commerce, Industry and Labour (sideframe) "Last Sunday
|
||||
# September 2010 (26/09/10) - adjust clocks forward from 12:00 midnight
|
||||
# to 01:00am and First Sunday April 2011 (03/04/11) - adjust clocks
|
||||
# backwards from 1:00am to 12:00am"
|
||||
|
||||
Zone Pacific/Apia 12:33:04 - LMT 1879 Jul 5
|
||||
-11:26:56 - LMT 1911
|
||||
-11:30 - SAMT 1950 # Samoa Time
|
||||
-11:00 - WST 2010 Sep 26
|
||||
-11:00 1:00 WSDT 2011 Apr 3
|
||||
-11:00 1:00 WSDT 2011 Apr 3 1:00
|
||||
-11:00 - WST
|
||||
|
||||
# Solomon Is
|
||||
|
7
contrib/wpa/hostapd/.gitignore
vendored
Normal file
7
contrib/wpa/hostapd/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
*.d
|
||||
.config
|
||||
driver_conf.c
|
||||
hostapd
|
||||
hostapd_cli
|
||||
hlr_auc_gw
|
||||
nt_password_hash
|
@ -1,42 +1,108 @@
|
||||
ChangeLog for hostapd
|
||||
|
||||
2010-01-12 - v0.6.10
|
||||
* 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]
|
||||
* fixed WPS selected registrar expiration for internal PIN registrar
|
||||
* disable PMTU discovery for RADIUS packets
|
||||
* fixed WPS UPnP SSDP on 32-bit targets
|
||||
* fixed WPS AP reconfiguration with drivers that do not use hostapd
|
||||
MLME
|
||||
* fixed RSN parameter setting for multi-BSS case
|
||||
* added WPS workarounds for known interoperability issues with broken,
|
||||
deployed implementation
|
||||
* update IEEE 802.11w implementation to match with the published
|
||||
standard
|
||||
* fixed OpCode when proxying WSC_ACK or WSC_NACK from WPS ER
|
||||
* fixed proxying of WSC_NACK to WPS ER
|
||||
* fixed compilation with newer GnuTLS versions
|
||||
* added support for defining timeout for WPS PINs
|
||||
2010-09-07 - v0.7.3
|
||||
* fixed re-association after WPS not initializing WPA state machine in
|
||||
some cases
|
||||
* fixed WPS IE update on reconfiguration
|
||||
* fixed WPS code not to proxy Probe Request frames for foreign SSIDs
|
||||
* added WPS workaround for open networks and some known interop issues
|
||||
* fixed WPS Diffie-Hellman derivation to use correct public key length
|
||||
* fixed FT RRB messages on big endian CPUs
|
||||
* changed WPS protection for brute force AP PIN attacks to disable AP
|
||||
PIN only temporarily (but with increasing time) to avoid usability
|
||||
issues on Label-only devices
|
||||
* added wps_ap_pin command for more secure handling of AP PIN
|
||||
operations (e.g., to generate a random AP PIN and only use it for
|
||||
short amount of time)
|
||||
* fixed HT STBC negotiation
|
||||
|
||||
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-03-23 - v0.6.9
|
||||
* driver_nl80211: fixed STA accounting data collection (TX/RX bytes
|
||||
reported correctly; TX/RX packets not yet available from kernel)
|
||||
* fixed EAPOL/EAP reauthentication when using an external RADIUS
|
||||
authentication server
|
||||
* driver_prism54: fixed segmentation fault on initialization
|
||||
* 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]
|
||||
|
||||
2009-02-15 - v0.6.8
|
||||
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)
|
||||
|
@ -6,14 +6,8 @@ ifndef CFLAGS
|
||||
CFLAGS = -MMD -O2 -Wall -g
|
||||
endif
|
||||
|
||||
# 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
|
||||
|
||||
CFLAGS += -I../src
|
||||
CFLAGS += -I../src/crypto
|
||||
CFLAGS += -I../src/utils
|
||||
CFLAGS += -I../src/common
|
||||
|
||||
# Uncomment following line and set the path to your kernel tree include
|
||||
# directory if your C library does not include all header files.
|
||||
@ -38,12 +32,45 @@ CFLAGS += -DCONFIG_NATIVE_WINDOWS
|
||||
LIBS += -lws2_32
|
||||
endif
|
||||
|
||||
OBJS = hostapd.o ieee802_1x.o eapol_sm.o \
|
||||
ieee802_11.o config.o ieee802_11_auth.o accounting.o \
|
||||
sta_info.o wpa.o ctrl_iface.o \
|
||||
drivers.o preauth.o pmksa_cache.o beacon.o \
|
||||
hw_features.o wme.o ap_list.o \
|
||||
mlme.o vlan_init.o wpa_auth_ie.o
|
||||
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
|
||||
LDFLAGS += -rdynamic
|
||||
CFLAGS += -funwind-tables
|
||||
ifdef CONFIG_WPA_TRACE_BFD
|
||||
CFLAGS += -DWPA_TRACE_BFD
|
||||
LIBS += -lbfd
|
||||
LIBS_c += -lbfd
|
||||
endif
|
||||
endif
|
||||
|
||||
OBJS += ../src/utils/eloop.o
|
||||
OBJS += ../src/utils/common.o
|
||||
@ -55,24 +82,51 @@ 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
|
||||
OBJS += ../src/crypto/rc4.o
|
||||
OBJS += ../src/crypto/md4.o
|
||||
OBJS += ../src/crypto/sha1.o
|
||||
OBJS += ../src/crypto/des.o
|
||||
OBJS += ../src/crypto/aes_wrap.o
|
||||
OBJS += ../src/crypto/aes.o
|
||||
|
||||
HOBJS=../src/hlr_auc_gw/hlr_auc_gw.o ../src/utils/common.o ../src/utils/wpa_debug.o ../src/utils/os_$(CONFIG_OS).o ../src/hlr_auc_gw/milenage.o ../src/crypto/aes_wrap.o ../src/crypto/aes.o
|
||||
|
||||
CFLAGS += -DCONFIG_CTRL_IFACE -DCONFIG_CTRL_IFACE_UNIX
|
||||
|
||||
ifdef CONFIG_IAPP
|
||||
CFLAGS += -DCONFIG_IAPP
|
||||
OBJS += iapp.o
|
||||
OBJS += ../src/ap/iapp.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_RSN_PREAUTH
|
||||
@ -82,78 +136,32 @@ endif
|
||||
|
||||
ifdef CONFIG_PEERKEY
|
||||
CFLAGS += -DCONFIG_PEERKEY
|
||||
OBJS += peerkey.o
|
||||
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 += wpa_ft.o
|
||||
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
|
||||
|
||||
ifdef CONFIG_DRIVER_HOSTAP
|
||||
CFLAGS += -DCONFIG_DRIVER_HOSTAP
|
||||
OBJS += driver_hostap.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRIVER_WIRED
|
||||
CFLAGS += -DCONFIG_DRIVER_WIRED
|
||||
OBJS += driver_wired.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRIVER_MADWIFI
|
||||
CFLAGS += -DCONFIG_DRIVER_MADWIFI
|
||||
OBJS += driver_madwifi.o
|
||||
CONFIG_L2_PACKET=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRIVER_ATHEROS
|
||||
CFLAGS += -DCONFIG_DRIVER_ATHEROS
|
||||
OBJS += driver_atheros.o
|
||||
CONFIG_L2_PACKET=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRIVER_PRISM54
|
||||
CFLAGS += -DCONFIG_DRIVER_PRISM54
|
||||
OBJS += driver_prism54.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRIVER_NL80211
|
||||
CFLAGS += -DCONFIG_DRIVER_NL80211
|
||||
OBJS += driver_nl80211.o radiotap.o
|
||||
LIBS += -lnl
|
||||
ifdef CONFIG_LIBNL20
|
||||
LIBS += -lnl-genl
|
||||
CFLAGS += -DCONFIG_LIBNL20
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRIVER_BSD
|
||||
CFLAGS += -DCONFIG_DRIVER_BSD
|
||||
OBJS += driver_bsd.o
|
||||
CONFIG_L2_PACKET=y
|
||||
CONFIG_DNET_PCAP=y
|
||||
CONFIG_L2_FREEBSD=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRIVER_TEST
|
||||
CFLAGS += -DCONFIG_DRIVER_TEST
|
||||
OBJS += driver_test.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRIVER_NONE
|
||||
CFLAGS += -DCONFIG_DRIVER_NONE
|
||||
OBJS += driver_none.o
|
||||
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
|
||||
@ -173,58 +181,60 @@ endif
|
||||
|
||||
|
||||
ifdef CONFIG_EAP_MD5
|
||||
CFLAGS += -DEAP_MD5
|
||||
OBJS += ../src/eap_server/eap_md5.o
|
||||
CFLAGS += -DEAP_SERVER_MD5
|
||||
OBJS += ../src/eap_server/eap_server_md5.o
|
||||
CHAP=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_EAP_TLS
|
||||
CFLAGS += -DEAP_TLS
|
||||
OBJS += ../src/eap_server/eap_tls.o
|
||||
CFLAGS += -DEAP_SERVER_TLS
|
||||
OBJS += ../src/eap_server/eap_server_tls.o
|
||||
TLS_FUNCS=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_EAP_PEAP
|
||||
CFLAGS += -DEAP_PEAP
|
||||
OBJS += ../src/eap_server/eap_peap.o
|
||||
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_TTLS
|
||||
OBJS += ../src/eap_server/eap_ttls.o
|
||||
CFLAGS += -DEAP_SERVER_TTLS
|
||||
OBJS += ../src/eap_server/eap_server_ttls.o
|
||||
TLS_FUNCS=y
|
||||
CHAP=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_EAP_MSCHAPV2
|
||||
CFLAGS += -DEAP_MSCHAPv2
|
||||
OBJS += ../src/eap_server/eap_mschapv2.o
|
||||
CFLAGS += -DEAP_SERVER_MSCHAPV2
|
||||
OBJS += ../src/eap_server/eap_server_mschapv2.o
|
||||
MS_FUNCS=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_EAP_GTC
|
||||
CFLAGS += -DEAP_GTC
|
||||
OBJS += ../src/eap_server/eap_gtc.o
|
||||
CFLAGS += -DEAP_SERVER_GTC
|
||||
OBJS += ../src/eap_server/eap_server_gtc.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_EAP_SIM
|
||||
CFLAGS += -DEAP_SIM
|
||||
OBJS += ../src/eap_server/eap_sim.o
|
||||
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_AKA
|
||||
OBJS += ../src/eap_server/eap_aka.o
|
||||
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_AKA_PRIME
|
||||
CFLAGS += -DEAP_SERVER_AKA_PRIME
|
||||
endif
|
||||
|
||||
ifdef CONFIG_EAP_SIM_COMMON
|
||||
@ -237,47 +247,52 @@ NEED_FIPS186_2_PRF=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_EAP_PAX
|
||||
CFLAGS += -DEAP_PAX
|
||||
OBJS += ../src/eap_server/eap_pax.o ../src/eap_common/eap_pax_common.o
|
||||
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_PSK
|
||||
OBJS += ../src/eap_server/eap_psk.o ../src/eap_common/eap_psk_common.o
|
||||
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_SAKE
|
||||
OBJS += ../src/eap_server/eap_sake.o ../src/eap_common/eap_sake_common.o
|
||||
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_GPSK
|
||||
OBJS += ../src/eap_server/eap_gpsk.o ../src/eap_common/eap_gpsk_common.o
|
||||
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_GPSK_SHA256
|
||||
CFLAGS += -DEAP_SERVER_GPSK_SHA256
|
||||
endif
|
||||
NEED_SHA256=y
|
||||
NEED_AES_OMAC1=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_EAP_VENDOR_TEST
|
||||
CFLAGS += -DEAP_VENDOR_TEST
|
||||
OBJS += ../src/eap_server/eap_vendor_test.o
|
||||
CFLAGS += -DEAP_SERVER_VENDOR_TEST
|
||||
OBJS += ../src/eap_server/eap_server_vendor_test.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_EAP_FAST
|
||||
CFLAGS += -DEAP_FAST
|
||||
OBJS += ../src/eap_server/eap_fast.o
|
||||
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
|
||||
CFLAGS += -DCONFIG_WPS -DEAP_WSC
|
||||
CFLAGS += -DCONFIG_WPS -DEAP_SERVER_WSC
|
||||
OBJS += ../src/utils/uuid.o
|
||||
OBJS += wps_hostapd.o
|
||||
OBJS += ../src/eap_server/eap_wsc.o ../src/eap_common/eap_wsc_common.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
|
||||
@ -288,8 +303,35 @@ OBJS += ../src/wps/wps_enrollee.o
|
||||
OBJS += ../src/wps/wps_registrar.o
|
||||
NEED_DH_GROUPS=y
|
||||
NEED_SHA256=y
|
||||
NEED_CRYPTO=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
|
||||
@ -297,22 +339,28 @@ 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
|
||||
|
||||
endif
|
||||
|
||||
ifdef CONFIG_EAP_IKEV2
|
||||
CFLAGS += -DEAP_IKEV2
|
||||
OBJS += ../src/eap_server/eap_ikev2.o ../src/eap_server/ikev2.o
|
||||
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_TNC
|
||||
OBJS += ../src/eap_server/eap_tnc.o
|
||||
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
|
||||
@ -321,135 +369,150 @@ endif
|
||||
endif
|
||||
|
||||
# Basic EAP functionality is needed for EAPOL
|
||||
OBJS += ../src/eap_server/eap.o
|
||||
OBJS += eap_register.o
|
||||
OBJS += ../src/eap_server/eap_server.o
|
||||
OBJS += ../src/eap_common/eap_common.o
|
||||
OBJS += ../src/eap_server/eap_methods.o
|
||||
OBJS += ../src/eap_server/eap_identity.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
|
||||
|
||||
ifndef CONFIG_TLS
|
||||
CONFIG_TLS=openssl
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_TLS), internal)
|
||||
ifndef CONFIG_CRYPTO
|
||||
CONFIG_CRYPTO=internal
|
||||
endif
|
||||
endif
|
||||
ifeq ($(CONFIG_CRYPTO), libtomcrypt)
|
||||
CFLAGS += -DCONFIG_INTERNAL_X509
|
||||
endif
|
||||
ifeq ($(CONFIG_CRYPTO), internal)
|
||||
CFLAGS += -DCONFIG_INTERNAL_X509
|
||||
endif
|
||||
|
||||
|
||||
ifdef TLS_FUNCS
|
||||
# Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS)
|
||||
CFLAGS += -DEAP_TLS_FUNCS
|
||||
OBJS += ../src/eap_server/eap_tls_common.o
|
||||
NEED_TLS_PRF=y
|
||||
ifeq ($(CONFIG_TLS), openssl)
|
||||
OBJS += ../src/crypto/tls_openssl.o
|
||||
LIBS += -lssl -lcrypto
|
||||
LIBS_p += -lcrypto
|
||||
LIBS_h += -lcrypto
|
||||
endif
|
||||
ifeq ($(CONFIG_TLS), gnutls)
|
||||
OBJS += ../src/crypto/tls_gnutls.o
|
||||
LIBS += -lgnutls -lgcrypt -lgpg-error
|
||||
LIBS_p += -lgcrypt
|
||||
LIBS_h += -lgcrypt
|
||||
endif
|
||||
ifdef CONFIG_GNUTLS_EXTRA
|
||||
CFLAGS += -DCONFIG_GNUTLS_EXTRA
|
||||
LIBS += -lgnutls-extra
|
||||
endif
|
||||
ifeq ($(CONFIG_TLS), internal)
|
||||
OBJS += ../src/crypto/tls_internal.o
|
||||
OBJS += ../src/tls/tlsv1_common.o ../src/tls/tlsv1_record.o
|
||||
OBJS += ../src/tls/tlsv1_cred.o ../src/tls/tlsv1_server.o
|
||||
OBJS += ../src/tls/tlsv1_server_write.o ../src/tls/tlsv1_server_read.o
|
||||
OBJS += ../src/tls/asn1.o ../src/tls/x509v3.o
|
||||
OBJS_p += ../src/tls/asn1.o
|
||||
OBJS_p += ../src/crypto/rc4.o ../src/crypto/aes_wrap.o ../src/crypto/aes.o
|
||||
NEED_BASE64=y
|
||||
CFLAGS += -DCONFIG_TLS_INTERNAL
|
||||
CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER
|
||||
ifeq ($(CONFIG_CRYPTO), internal)
|
||||
ifdef CONFIG_INTERNAL_LIBTOMMATH
|
||||
CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH
|
||||
else
|
||||
LIBS += -ltommath
|
||||
LIBS_p += -ltommath
|
||||
endif
|
||||
endif
|
||||
ifeq ($(CONFIG_CRYPTO), libtomcrypt)
|
||||
LIBS += -ltomcrypt -ltfm
|
||||
LIBS_p += -ltomcrypt -ltfm
|
||||
endif
|
||||
endif
|
||||
NEED_CRYPTO=y
|
||||
else
|
||||
OBJS += ../src/crypto/tls_none.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_PKCS12
|
||||
CFLAGS += -DPKCS12_FUNCS
|
||||
endif
|
||||
|
||||
ifdef MS_FUNCS
|
||||
OBJS += ../src/crypto/ms_funcs.o
|
||||
NEED_CRYPTO=y
|
||||
NEED_DES=y
|
||||
NEED_MD4=y
|
||||
endif
|
||||
|
||||
ifdef CHAP
|
||||
OBJS += ../src/eap_common/chap.o
|
||||
endif
|
||||
|
||||
ifdef NEED_CRYPTO
|
||||
ifndef TLS_FUNCS
|
||||
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_p += -lcrypto
|
||||
LIBS_h += -lcrypto
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_TLS), gnutls)
|
||||
LIBS += -lgcrypt
|
||||
LIBS_p += -lgcrypt
|
||||
LIBS_h += -lgcrypt
|
||||
endif
|
||||
ifeq ($(CONFIG_TLS), internal)
|
||||
ifeq ($(CONFIG_CRYPTO), libtomcrypt)
|
||||
LIBS += -ltomcrypt -ltfm
|
||||
LIBS_p += -ltomcrypt -ltfm
|
||||
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
|
||||
endif
|
||||
ifeq ($(CONFIG_TLS), openssl)
|
||||
OBJS += ../src/crypto/crypto_openssl.o
|
||||
OBJS_p += ../src/crypto/crypto_openssl.o
|
||||
HOBJS += ../src/crypto/crypto_openssl.o
|
||||
CONFIG_INTERNAL_SHA256=y
|
||||
endif
|
||||
ifeq ($(CONFIG_TLS), gnutls)
|
||||
OBJS += ../src/crypto/crypto_gnutls.o
|
||||
OBJS_p += ../src/crypto/crypto_gnutls.o
|
||||
HOBJS += ../src/crypto/crypto_gnutls.o
|
||||
CONFIG_INTERNAL_SHA256=y
|
||||
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
|
||||
OBJS_p += ../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 ../src/tls/rsa.o ../src/tls/bignum.o
|
||||
OBJS_p += ../src/crypto/crypto_internal.o ../src/tls/rsa.o ../src/tls/bignum.o
|
||||
OBJS += ../src/crypto/crypto_internal.o
|
||||
NEED_AES_DEC=y
|
||||
CFLAGS += -DCONFIG_CRYPTO_INTERNAL
|
||||
ifdef CONFIG_INTERNAL_LIBTOMMATH
|
||||
CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH
|
||||
@ -458,7 +521,7 @@ CFLAGS += -DLTM_FAST
|
||||
endif
|
||||
else
|
||||
LIBS += -ltommath
|
||||
LIBS_p += -ltommath
|
||||
LIBS_h += -ltommath
|
||||
endif
|
||||
CONFIG_INTERNAL_AES=y
|
||||
CONFIG_INTERNAL_DES=y
|
||||
@ -466,55 +529,140 @@ 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
|
||||
else
|
||||
|
||||
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
|
||||
CFLAGS += -DINTERNAL_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
|
||||
CFLAGS += -DINTERNAL_SHA1
|
||||
SHA1OBJS += ../src/crypto/sha1-internal.o
|
||||
ifdef NEED_FIPS186_2_PRF
|
||||
SHA1OBJS += ../src/crypto/fips_prf_internal.o
|
||||
endif
|
||||
ifdef CONFIG_INTERNAL_SHA256
|
||||
CFLAGS += -DINTERNAL_SHA256
|
||||
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
|
||||
CFLAGS += -DINTERNAL_MD5
|
||||
OBJS += ../src/crypto/md5-internal.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef NEED_MD4
|
||||
ifdef CONFIG_INTERNAL_MD4
|
||||
CFLAGS += -DINTERNAL_MD4
|
||||
OBJS += ../src/crypto/md4-internal.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef NEED_DES
|
||||
ifdef CONFIG_INTERNAL_DES
|
||||
CFLAGS += -DINTERNAL_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
|
||||
|
||||
ifndef NEED_FIPS186_2_PRF
|
||||
CFLAGS += -DCONFIG_NO_FIPS186_2_PRF
|
||||
endif
|
||||
|
||||
ifndef NEED_T_PRF
|
||||
CFLAGS += -DCONFIG_NO_T_PRF
|
||||
endif
|
||||
|
||||
ifndef NEED_TLS_PRF
|
||||
CFLAGS += -DCONFIG_NO_TLS_PRF
|
||||
endif
|
||||
|
||||
ifdef CONFIG_RADIUS_SERVER
|
||||
@ -540,16 +688,20 @@ ifdef NEED_BASE64
|
||||
OBJS += ../src/utils/base64.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_NO_STDOUT_DEBUG
|
||||
CFLAGS += -DCONFIG_NO_STDOUT_DEBUG
|
||||
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_NO_AES_EXTRAS
|
||||
CFLAGS += -DCONFIG_NO_AES_UNWRAP
|
||||
CFLAGS += -DCONFIG_NO_AES_CTR -DCONFIG_NO_AES_OMAC1
|
||||
CFLAGS += -DCONFIG_NO_AES_EAX -DCONFIG_NO_AES_CBC
|
||||
CFLAGS += -DCONFIG_NO_AES_DECRYPT
|
||||
CFLAGS += -DCONFIG_NO_AES_ENCRYPT_BLOCK
|
||||
ifdef CONFIG_NO_STDOUT_DEBUG
|
||||
CFLAGS += -DCONFIG_NO_STDOUT_DEBUG
|
||||
endif
|
||||
|
||||
ALL=hostapd hostapd_cli
|
||||
@ -577,59 +729,63 @@ verify_config:
|
||||
fi
|
||||
|
||||
install: all
|
||||
for i in $(ALL); do cp $$i /usr/local/bin/$$i; done
|
||||
for i in $(ALL); do cp -f $$i /usr/local/bin/$$i; done
|
||||
|
||||
hostapd: $(OBJS)
|
||||
$(CC) -o hostapd $(OBJS) $(LIBS)
|
||||
../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)
|
||||
$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS)
|
||||
|
||||
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)
|
||||
$(CC) -o hostapd_cli $(OBJS_c)
|
||||
$(CC) $(LDFLAGS) -o hostapd_cli $(OBJS_c) $(LIBS_c)
|
||||
|
||||
NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o ../src/crypto/sha1.o ../src/crypto/rc4.o ../src/crypto/md5.o
|
||||
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)
|
||||
$(CC) -o nt_password_hash $(NOBJS) $(LIBS_n)
|
||||
$(CC) $(LDFLAGS) -o nt_password_hash $(NOBJS) $(LIBS_n)
|
||||
|
||||
hlr_auc_gw: $(HOBJS)
|
||||
$(CC) -o hlr_auc_gw $(HOBJS) $(LIBS_h)
|
||||
$(CC) $(LDFLAGS) -o hlr_auc_gw $(HOBJS) $(LIBS_h)
|
||||
|
||||
clean:
|
||||
$(MAKE) -C ../src clean
|
||||
rm -f core *~ *.o hostapd hostapd_cli nt_password_hash hlr_auc_gw
|
||||
rm -f *.d
|
||||
|
||||
%.eps: %.fig
|
||||
fig2dev -L eps $*.fig $*.eps
|
||||
|
||||
%.png: %.fig
|
||||
fig2dev -L png -m 3 $*.fig | pngtopnm | pnmscale 0.4 | pnmtopng \
|
||||
> $*.png
|
||||
|
||||
docs-pics: doc/hostapd.png doc/hostapd.eps
|
||||
|
||||
docs: docs-pics
|
||||
(cd ..; doxygen hostapd/doc/doxygen.full; cd hostapd)
|
||||
$(MAKE) -C doc/latex
|
||||
cp doc/latex/refman.pdf hostapd-devel.pdf
|
||||
|
||||
docs-fast: docs-pics
|
||||
(cd ..; doxygen hostapd/doc/doxygen.fast; cd hostapd)
|
||||
|
||||
clean-docs:
|
||||
rm -rf doc/latex doc/html
|
||||
rm -f doc/hostapd.{eps,png} hostapd-devel.pdf
|
||||
|
||||
TEST_SRC_MILENAGE = ../src/hlr_auc_gw/milenage.c ../src/crypto/aes_wrap.c ../src/crypto/aes.c ../src/utils/common.c ../src/utils/wpa_debug.o ../src/utils/os_$(CONFIG_OS).c
|
||||
test-milenage: $(TEST_SRC_MILENAGE)
|
||||
$(CC) -o test-milenage -Wall -Werror $(TEST_SRC_MILENAGE) \
|
||||
-DTEST_MAIN_MILENAGE -I. -DINTERNAL_AES \
|
||||
-I../src/crypto -I../src/utils
|
||||
./test-milenage
|
||||
rm test-milenage
|
||||
|
||||
-include $(OBJS:%.o=%.d)
|
||||
|
@ -2,7 +2,7 @@ hostapd - user space IEEE 802.11 AP and IEEE 802.1X/WPA/WPA2/EAP
|
||||
Authenticator and RADIUS authentication server
|
||||
================================================================
|
||||
|
||||
Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> and contributors
|
||||
Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi> and contributors
|
||||
All Rights Reserved.
|
||||
|
||||
This program is dual-licensed under both the GPL version 2 and BSD
|
||||
@ -95,9 +95,6 @@ Current hardware/software requirements:
|
||||
madwifi driver root directory in .config (see defconfig file for
|
||||
an example: CFLAGS += -I<path>)
|
||||
|
||||
Prism54 driver for Intersil/Conexant Prism GT/Duette/Indigo
|
||||
(http://www.prism54.org/)
|
||||
|
||||
mac80211-based drivers that support AP mode (with driver=nl80211).
|
||||
This includes drivers for Atheros (ath9k) and Broadcom (b43)
|
||||
chipsets.
|
||||
|
@ -62,7 +62,6 @@ includes WPS support and uses madwifi driver interface:
|
||||
|
||||
CONFIG_DRIVER_MADWIFI=y
|
||||
CFLAGS += -I/usr/src/madwifi-0.9.3
|
||||
CONFIG_EAP=y
|
||||
CONFIG_WPS=y
|
||||
CONFIG_WPS_UPNP=y
|
||||
|
||||
@ -196,6 +195,33 @@ 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
|
||||
|
||||
|
||||
Credential generation and configuration changes
|
||||
-----------------------------------------------
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
20
contrib/wpa/hostapd/config_file.h
Normal file
20
contrib/wpa/hostapd/config_file.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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 */
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / UNIX domain socket -based control interface
|
||||
* Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
|
||||
* 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
|
||||
@ -12,7 +12,7 @@
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "utils/includes.h"
|
||||
|
||||
#ifndef CONFIG_NATIVE_WINDOWS
|
||||
|
||||
@ -20,17 +20,21 @@
|
||||
#include <sys/stat.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "hostapd.h"
|
||||
#include "eloop.h"
|
||||
#include "config.h"
|
||||
#include "ieee802_1x.h"
|
||||
#include "wpa.h"
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "drivers/driver.h"
|
||||
#include "radius/radius_client.h"
|
||||
#include "ieee802_11.h"
|
||||
#include "ap/hostapd.h"
|
||||
#include "ap/ap_config.h"
|
||||
#include "ap/ieee802_1x.h"
|
||||
#include "ap/wpa_auth.h"
|
||||
#include "ap/ieee802_11.h"
|
||||
#include "ap/sta_info.h"
|
||||
#include "ap/accounting.h"
|
||||
#include "ap/wps_hostapd.h"
|
||||
#include "ap/ctrl_iface_ap.h"
|
||||
#include "ctrl_iface.h"
|
||||
#include "sta_info.h"
|
||||
#include "accounting.h"
|
||||
#include "wps_hostapd.h"
|
||||
|
||||
|
||||
struct wpa_ctrl_dst {
|
||||
@ -125,84 +129,6 @@ static int hostapd_ctrl_iface_level(struct hostapd_data *hapd,
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd,
|
||||
const char *txtaddr)
|
||||
{
|
||||
@ -229,7 +155,100 @@ static int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd,
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd,
|
||||
const char *txtaddr)
|
||||
{
|
||||
u8 addr[ETH_ALEN];
|
||||
struct sta_info *sta;
|
||||
const char *pos;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE DEAUTHENTICATE %s", txtaddr);
|
||||
|
||||
if (hwaddr_aton(txtaddr, addr))
|
||||
return -1;
|
||||
|
||||
pos = os_strstr(txtaddr, " test=");
|
||||
if (pos) {
|
||||
struct ieee80211_mgmt mgmt;
|
||||
int encrypt;
|
||||
if (hapd->driver->send_frame == NULL)
|
||||
return -1;
|
||||
pos += 6;
|
||||
encrypt = atoi(pos);
|
||||
os_memset(&mgmt, 0, sizeof(mgmt));
|
||||
mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
|
||||
WLAN_FC_STYPE_DEAUTH);
|
||||
os_memcpy(mgmt.da, addr, ETH_ALEN);
|
||||
os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
|
||||
os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
|
||||
mgmt.u.deauth.reason_code =
|
||||
host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt,
|
||||
IEEE80211_HDRLEN +
|
||||
sizeof(mgmt.u.deauth),
|
||||
encrypt) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
hapd->drv.sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
sta = ap_get_sta(hapd, addr);
|
||||
if (sta)
|
||||
ap_sta_deauthenticate(hapd, sta,
|
||||
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
|
||||
const char *txtaddr)
|
||||
{
|
||||
u8 addr[ETH_ALEN];
|
||||
struct sta_info *sta;
|
||||
const char *pos;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE DISASSOCIATE %s", txtaddr);
|
||||
|
||||
if (hwaddr_aton(txtaddr, addr))
|
||||
return -1;
|
||||
|
||||
pos = os_strstr(txtaddr, " test=");
|
||||
if (pos) {
|
||||
struct ieee80211_mgmt mgmt;
|
||||
int encrypt;
|
||||
if (hapd->driver->send_frame == NULL)
|
||||
return -1;
|
||||
pos += 6;
|
||||
encrypt = atoi(pos);
|
||||
os_memset(&mgmt, 0, sizeof(mgmt));
|
||||
mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
|
||||
WLAN_FC_STYPE_DISASSOC);
|
||||
os_memcpy(mgmt.da, addr, ETH_ALEN);
|
||||
os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
|
||||
os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
|
||||
mgmt.u.disassoc.reason_code =
|
||||
host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt,
|
||||
IEEE80211_HDRLEN +
|
||||
sizeof(mgmt.u.deauth),
|
||||
encrypt) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
hapd->drv.sta_disassoc(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
sta = ap_get_sta(hapd, addr);
|
||||
if (sta)
|
||||
ap_sta_disassociate(hapd, sta,
|
||||
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
#ifdef NEED_AP_MLME
|
||||
static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd,
|
||||
const char *txtaddr)
|
||||
{
|
||||
@ -238,14 +257,15 @@ static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd,
|
||||
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE SA_QUERY %s", txtaddr);
|
||||
|
||||
if (hwaddr_aton(txtaddr, addr))
|
||||
if (hwaddr_aton(txtaddr, addr) ||
|
||||
os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN) < 0)
|
||||
return -1;
|
||||
|
||||
os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN);
|
||||
ieee802_11_send_sa_query_req(hapd, addr, trans_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* NEED_AP_MLME */
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
|
||||
|
||||
@ -269,6 +289,83 @@ static int hostapd_ctrl_iface_wps_pin(struct hostapd_data *hapd, char *txt)
|
||||
|
||||
return hostapd_wps_add_pin(hapd, txt, pin, timeout);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_WPS_OOB
|
||||
static int hostapd_ctrl_iface_wps_oob(struct hostapd_data *hapd, char *txt)
|
||||
{
|
||||
char *path, *method, *name;
|
||||
|
||||
path = os_strchr(txt, ' ');
|
||||
if (path == NULL)
|
||||
return -1;
|
||||
*path++ = '\0';
|
||||
|
||||
method = os_strchr(path, ' ');
|
||||
if (method == NULL)
|
||||
return -1;
|
||||
*method++ = '\0';
|
||||
|
||||
name = os_strchr(method, ' ');
|
||||
if (name != NULL)
|
||||
*name++ = '\0';
|
||||
|
||||
return hostapd_wps_start_oob(hapd, txt, path, method, name);
|
||||
}
|
||||
#endif /* CONFIG_WPS_OOB */
|
||||
|
||||
|
||||
static int hostapd_ctrl_iface_wps_ap_pin(struct hostapd_data *hapd, char *txt,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
int timeout = 300;
|
||||
char *pos;
|
||||
const char *pin_txt;
|
||||
|
||||
pos = os_strchr(txt, ' ');
|
||||
if (pos)
|
||||
*pos++ = '\0';
|
||||
|
||||
if (os_strcmp(txt, "disable") == 0) {
|
||||
hostapd_wps_ap_pin_disable(hapd);
|
||||
return os_snprintf(buf, buflen, "OK\n");
|
||||
}
|
||||
|
||||
if (os_strcmp(txt, "random") == 0) {
|
||||
if (pos)
|
||||
timeout = atoi(pos);
|
||||
pin_txt = hostapd_wps_ap_pin_random(hapd, timeout);
|
||||
if (pin_txt == NULL)
|
||||
return -1;
|
||||
return os_snprintf(buf, buflen, "%s", pin_txt);
|
||||
}
|
||||
|
||||
if (os_strcmp(txt, "get") == 0) {
|
||||
pin_txt = hostapd_wps_ap_pin_get(hapd);
|
||||
if (pin_txt == NULL)
|
||||
return -1;
|
||||
return os_snprintf(buf, buflen, "%s", pin_txt);
|
||||
}
|
||||
|
||||
if (os_strcmp(txt, "set") == 0) {
|
||||
char *pin;
|
||||
if (pos == NULL)
|
||||
return -1;
|
||||
pin = pos;
|
||||
pos = os_strchr(pos, ' ');
|
||||
if (pos) {
|
||||
*pos++ = '\0';
|
||||
timeout = atoi(pos);
|
||||
}
|
||||
if (os_strlen(pin) > buflen)
|
||||
return -1;
|
||||
if (hostapd_wps_ap_pin_set(hapd, pin, timeout) < 0)
|
||||
return -1;
|
||||
return os_snprintf(buf, buflen, "%s", pin);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif /* CONFIG_WPS */
|
||||
|
||||
|
||||
@ -324,6 +421,7 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
|
||||
else
|
||||
reply_len += res;
|
||||
}
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
if (reply_len >= 0) {
|
||||
res = radius_client_get_mib(hapd->radius,
|
||||
reply + reply_len,
|
||||
@ -333,6 +431,7 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
|
||||
else
|
||||
reply_len += res;
|
||||
}
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
} else if (os_strcmp(buf, "STA-FIRST") == 0) {
|
||||
reply_len = hostapd_ctrl_iface_sta_first(hapd, reply,
|
||||
reply_size);
|
||||
@ -355,10 +454,18 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
|
||||
} else if (os_strncmp(buf, "NEW_STA ", 8) == 0) {
|
||||
if (hostapd_ctrl_iface_new_sta(hapd, buf + 8))
|
||||
reply_len = -1;
|
||||
} else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) {
|
||||
if (hostapd_ctrl_iface_deauthenticate(hapd, buf + 15))
|
||||
reply_len = -1;
|
||||
} else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) {
|
||||
if (hostapd_ctrl_iface_disassociate(hapd, buf + 13))
|
||||
reply_len = -1;
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
#ifdef NEED_AP_MLME
|
||||
} else if (os_strncmp(buf, "SA_QUERY ", 9) == 0) {
|
||||
if (hostapd_ctrl_iface_sa_query(hapd, buf + 9))
|
||||
reply_len = -1;
|
||||
#endif /* NEED_AP_MLME */
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
#ifdef CONFIG_WPS
|
||||
} else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
|
||||
@ -367,6 +474,14 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
|
||||
} else if (os_strcmp(buf, "WPS_PBC") == 0) {
|
||||
if (hostapd_wps_button_pushed(hapd))
|
||||
reply_len = -1;
|
||||
#ifdef CONFIG_WPS_OOB
|
||||
} else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) {
|
||||
if (hostapd_ctrl_iface_wps_oob(hapd, buf + 8))
|
||||
reply_len = -1;
|
||||
#endif /* CONFIG_WPS_OOB */
|
||||
} else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) {
|
||||
reply_len = hostapd_ctrl_iface_wps_ap_pin(hapd, buf + 11,
|
||||
reply, reply_size);
|
||||
#endif /* CONFIG_WPS */
|
||||
} else {
|
||||
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
|
||||
@ -507,6 +622,7 @@ int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
|
||||
hapd->ctrl_sock = s;
|
||||
eloop_register_read_sock(s, hostapd_ctrl_iface_receive, hapd,
|
||||
NULL);
|
||||
hapd->msg_ctx = hapd;
|
||||
wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb);
|
||||
|
||||
return 0;
|
||||
|
@ -15,7 +15,18 @@
|
||||
#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 */
|
||||
|
@ -19,9 +19,6 @@ CONFIG_DRIVER_HOSTAP=y
|
||||
#CONFIG_DRIVER_MADWIFI=y
|
||||
#CFLAGS += -I../../madwifi # change to the madwifi source directory
|
||||
|
||||
# Driver interface for Prism54 driver
|
||||
#CONFIG_DRIVER_PRISM54=y
|
||||
|
||||
# Driver interface for drivers using the nl80211 kernel interface
|
||||
#CONFIG_DRIVER_NL80211=y
|
||||
# driver_nl80211.c requires a rather new libnl (version 1.1) which may not be
|
||||
@ -35,6 +32,8 @@ CONFIG_DRIVER_HOSTAP=y
|
||||
#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
|
||||
@ -142,3 +141,35 @@ CONFIG_IPV6=y
|
||||
# This can be used to reduce the size of the hostapd considerably if debugging
|
||||
# code is not needed.
|
||||
#CONFIG_NO_STDOUT_DEBUG=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
|
||||
|
||||
# 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
|
||||
|
@ -1,5 +0,0 @@
|
||||
/**
|
||||
\page code_structure Structure of the source code
|
||||
|
||||
|
||||
*/
|
@ -1,66 +0,0 @@
|
||||
/**
|
||||
\page ctrl_iface_page Control interface
|
||||
|
||||
hostapd implements a control interface that can be used by
|
||||
external programs to control the operations of the hostapd
|
||||
daemon and to get status information and event notifications. There is
|
||||
a small C library, in a form of a single C file, wpa_ctrl.c, that
|
||||
provides helper functions to facilitate the use of the control
|
||||
interface. External programs can link this file into them and then use
|
||||
the library functions documented in wpa_ctrl.h to interact with
|
||||
%wpa_supplicant. This library can also be used with C++. hostapd_cli.c
|
||||
is an example program using this library.
|
||||
|
||||
There are multiple mechanisms for inter-process communication. For
|
||||
example, Linux version of hostapd is using UNIX domain sockets for the
|
||||
control interface. The use of the functions defined in wpa_ctrl.h can
|
||||
be used to hide the details of the used IPC from external programs.
|
||||
|
||||
|
||||
\section using_ctrl_iface Using the control interface
|
||||
|
||||
External programs, e.g., a GUI or a configuration utility, that need to
|
||||
communicate with hostapd should link in wpa_ctrl.c. This
|
||||
allows them to use helper functions to open connection to the control
|
||||
interface with wpa_ctrl_open() and to send commands with
|
||||
wpa_ctrl_request().
|
||||
|
||||
hostapd uses the control interface for two types of communication:
|
||||
commands and unsolicited event messages. Commands are a pair of
|
||||
messages, a request from the external program and a response from
|
||||
hostapd. These can be executed using wpa_ctrl_request().
|
||||
Unsolicited event messages are sent by hostapd to the control
|
||||
interface connection without specific request from the external program
|
||||
for receiving each message. However, the external program needs to
|
||||
attach to the control interface with wpa_ctrl_attach() to receive these
|
||||
unsolicited messages.
|
||||
|
||||
If the control interface connection is used both for commands and
|
||||
unsolicited event messages, there is potential for receiving an
|
||||
unsolicited message between the command request and response.
|
||||
wpa_ctrl_request() caller will need to supply a callback, msg_cb,
|
||||
for processing these messages. Often it is easier to open two
|
||||
control interface connections by calling wpa_ctrl_open() twice and
|
||||
then use one of the connections for commands and the other one for
|
||||
unsolicited messages. This way command request/response pairs will
|
||||
not be broken by unsolicited messages. wpa_cli is an example of how
|
||||
to use only one connection for both purposes and wpa_gui demonstrates
|
||||
how to use two separate connections.
|
||||
|
||||
Once the control interface connection is not needed anymore, it should
|
||||
be closed by calling wpa_ctrl_close(). If the connection was used for
|
||||
unsolicited event messages, it should be first detached by calling
|
||||
wpa_ctrl_detach().
|
||||
|
||||
|
||||
\section ctrl_iface_cmds Control interface commands
|
||||
|
||||
Following commands can be used with wpa_ctrl_request():
|
||||
|
||||
\subsection ctrl_iface_PING PING
|
||||
|
||||
This command can be used to test whether hostapd is replying
|
||||
to the control interface commands. The expected reply is \c PONG if the
|
||||
connection is open and hostapd is processing commands.
|
||||
|
||||
*/
|
@ -1,238 +0,0 @@
|
||||
# Doxyfile 1.4.4
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = hostapd
|
||||
PROJECT_NUMBER = 0.6.x
|
||||
OUTPUT_DIRECTORY = hostapd/doc
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF = "The $name class" \
|
||||
"The $name widget" \
|
||||
"The $name file" \
|
||||
is \
|
||||
provides \
|
||||
specifies \
|
||||
contains \
|
||||
represents \
|
||||
a \
|
||||
an \
|
||||
the
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = YES
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
DETAILS_AT_TOP = NO
|
||||
INHERIT_DOCS = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 8
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
SUBGROUPING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = NO
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = YES
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = hostapd \
|
||||
src/common \
|
||||
src/crypto \
|
||||
src/eap_common \
|
||||
src/eap_server \
|
||||
src/l2_packet \
|
||||
src/radius \
|
||||
src/rsn_supp \
|
||||
src/tls \
|
||||
src/utils \
|
||||
src/wps
|
||||
FILE_PATTERNS = *.c *.h *.doxygen
|
||||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS = *
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH = hostapd/doc
|
||||
INPUT_FILTER = kerneldoc2doxygen.pl
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = YES
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = NO
|
||||
REFERENCES_RELATION = NO
|
||||
VERBATIM_HEADERS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 3
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
XML_PROGRAMLISTING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED = RADIUS_SERVER EAP_SERVER EAP_SIM
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = NO
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = NO
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = YES
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = NO
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_DEPTH = 1000
|
||||
DOT_TRANSPARENT = NO
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
@ -1,238 +0,0 @@
|
||||
# Doxyfile 1.4.4
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = hostapd
|
||||
PROJECT_NUMBER = 0.6.x
|
||||
OUTPUT_DIRECTORY = hostapd/doc
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF = "The $name class" \
|
||||
"The $name widget" \
|
||||
"The $name file" \
|
||||
is \
|
||||
provides \
|
||||
specifies \
|
||||
contains \
|
||||
represents \
|
||||
a \
|
||||
an \
|
||||
the
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = YES
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
DETAILS_AT_TOP = NO
|
||||
INHERIT_DOCS = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 8
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
SUBGROUPING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = NO
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = YES
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = hostapd \
|
||||
src/common \
|
||||
src/crypto \
|
||||
src/eap_common \
|
||||
src/eap_server \
|
||||
src/l2_packet \
|
||||
src/radius \
|
||||
src/rsn_supp \
|
||||
src/tls \
|
||||
src/utils \
|
||||
src/wps
|
||||
FILE_PATTERNS = *.c *.h *.doxygen
|
||||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS = *
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH = hostapd/doc
|
||||
INPUT_FILTER = kerneldoc2doxygen.pl
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = YES
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = NO
|
||||
REFERENCES_RELATION = NO
|
||||
VERBATIM_HEADERS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 3
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = YES
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
XML_PROGRAMLISTING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED = RADIUS_SERVER EAP_SERVER EAP_SIM
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = NO
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = YES
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = YES
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = NO
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_DEPTH = 1000
|
||||
DOT_TRANSPARENT = NO
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = YES
|
@ -1,20 +0,0 @@
|
||||
/**
|
||||
\page driver_wrapper Driver wrapper implementation (driver.h, drivers.c)
|
||||
|
||||
All hardware and driver dependent functionality is in separate C files
|
||||
that implement defined wrapper functions. Other parts
|
||||
of the hostapd are designed to be hardware, driver, and operating
|
||||
system independent.
|
||||
|
||||
Driver wrappers need to implement whatever calls are used in the
|
||||
target operating system/driver for controlling wireless LAN
|
||||
devices. As an example, in case of Linux, these are mostly some glue
|
||||
code and ioctl() calls and netlink message parsing for Linux Wireless
|
||||
Extensions (WE). Since features required for WPA were added only recently to
|
||||
Linux Wireless Extensions (in version 18), some driver specific code is used
|
||||
in number of driver interface implementations. These driver dependent parts
|
||||
can be replaced with generic code in driver_wext.c once the target driver
|
||||
includes full support for WE-18. After that, all Linux drivers, at
|
||||
least in theory, could use the same driver wrapper code.
|
||||
|
||||
*/
|
@ -1,56 +0,0 @@
|
||||
/**
|
||||
\page eap_module EAP server implementation
|
||||
|
||||
Extensible Authentication Protocol (EAP) is an authentication framework
|
||||
defined in RFC 3748. hostapd uses a separate code module for EAP server
|
||||
implementation. This module was designed to use only a minimal set of
|
||||
direct function calls (mainly, to debug/event functions) in order for
|
||||
it to be usable in other programs. The design of the EAP
|
||||
implementation is based loosely on RFC 4137. The state machine is
|
||||
defined in this RFC and so is the interface between the server state
|
||||
machine and methods. As such, this RFC provides useful information for
|
||||
understanding the EAP server implementation in hostapd.
|
||||
|
||||
Some of the terminology used in EAP state machine is referring to
|
||||
EAPOL (IEEE 802.1X), but there is no strict requirement on the lower
|
||||
layer being IEEE 802.1X if EAP module is built for other programs than
|
||||
%wpa_supplicant. These terms should be understood to refer to the
|
||||
lower layer as defined in RFC 4137.
|
||||
|
||||
|
||||
\section adding_eap_methods Adding EAP methods
|
||||
|
||||
Each EAP method is implemented as a separate module, usually as one C
|
||||
file named eap_<name of the method>.c, e.g., eap_md5.c. All EAP
|
||||
methods use the same interface between the server state machine and
|
||||
method specific functions. This allows new EAP methods to be added
|
||||
without modifying the core EAP state machine implementation.
|
||||
|
||||
New EAP methods need to be registered by adding them into the build
|
||||
(Makefile) and the EAP method registration list in the
|
||||
eap_server_register_methods() function of eap_methods.c. Each EAP
|
||||
method should use a build-time configuration option, e.g., EAP_TLS, in
|
||||
order to make it possible to select which of the methods are included
|
||||
in the build.
|
||||
|
||||
EAP methods must implement the interface defined in eap_i.h. struct
|
||||
eap_method defines the needed function pointers that each EAP method
|
||||
must provide. In addition, the EAP type and name are registered using
|
||||
this structure. This interface is based on section 4.4 of RFC 4137.
|
||||
|
||||
It is recommended that the EAP methods would use generic helper
|
||||
functions, eap_msg_alloc() and eap_hdr_validate() when processing
|
||||
messages. This allows code sharing and can avoid missing some of the
|
||||
needed validation steps for received packets. In addition, these
|
||||
functions make it easier to change between expanded and legacy EAP
|
||||
header, if needed.
|
||||
|
||||
When adding an EAP method that uses a vendor specific EAP type
|
||||
(Expanded Type as defined in RFC 3748, Chapter 5.7), the new method
|
||||
must be registered by passing vendor id instead of EAP_VENDOR_IETF to
|
||||
eap_server_method_alloc(). These methods must not try to emulate
|
||||
expanded types by registering a legacy EAP method for type 254. See
|
||||
eap_vendor_test.c for an example of an EAP method implementation that
|
||||
is implemented as an expanded type.
|
||||
|
||||
*/
|
@ -1,264 +0,0 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 1875 4050 2925 4350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1875 4050 2925 4050 2925 4350 1875 4350 1875 4050
|
||||
4 0 0 50 -1 0 12 0.0000 4 180 735 2025 4275 l2_packet\001
|
||||
-6
|
||||
6 4725 1200 5925 1500
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4725 1200 5925 1200 5925 1500 4725 1500 4725 1200
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 1005 4800 1425 GUI frontend\001
|
||||
-6
|
||||
6 6000 2700 7200 3225
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6000 2700 7200 2700 7200 3225 6000 3225 6000 2700
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 975 6075 2925 WPA/WPA2\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 1065 6075 3150 state machine\001
|
||||
-6
|
||||
6 6000 4950 7200 5475
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6000 4950 7200 4950 7200 5475 6000 5475 6000 4950
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 360 6075 5175 EAP\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 1065 6075 5400 state machine\001
|
||||
-6
|
||||
6 4350 3900 5025 4425
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4350 3900 5025 3900 5025 4425 4350 4425 4350 3900
|
||||
4 0 0 50 -1 0 12 0.0000 4 105 420 4500 4125 event\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 180 315 4500 4350 loop\001
|
||||
-6
|
||||
6 4275 2550 5100 2850
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4275 2550 5100 2550 5100 2850 4275 2850 4275 2550
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 450 4425 2775 ctrl i/f\001
|
||||
-6
|
||||
6 6000 3900 7200 4425
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6000 3900 7200 3900 7200 4425 6000 4425 6000 3900
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 600 6075 4125 EAPOL\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 1065 6075 4350 state machine\001
|
||||
-6
|
||||
6 2775 3150 4050 3450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2775 3150 4050 3150 4050 3450 2775 3450 2775 3150
|
||||
4 0 0 50 -1 0 12 0.0000 4 180 990 2925 3375 configuration\001
|
||||
-6
|
||||
6 3450 1200 4575 1500
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3450 1200 4575 1200 4575 1500 3450 1500 3450 1200
|
||||
4 0 0 50 -1 0 12 0.0000 4 180 870 3600 1425 hostapd_cli\001
|
||||
-6
|
||||
6 3525 7800 5775 8100
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3525 7800 5775 7800 5775 8100 3525 8100 3525 7800
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 2145 3600 8025 kernel network device driver\001
|
||||
-6
|
||||
6 4275 6000 5100 6300
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4275 6000 5100 6000 5100 6300 4275 6300 4275 6000
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 630 4350 6225 driver i/f\001
|
||||
-6
|
||||
6 8175 4725 9225 5025
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8175 4725 9225 4725 9225 5025 8175 5025 8175 4725
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 735 8250 4950 EAP-TLS\001
|
||||
-6
|
||||
6 9300 4725 10350 5025
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
9300 4725 10350 4725 10350 5025 9300 5025 9300 4725
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 810 9375 4950 EAP-MD5\001
|
||||
-6
|
||||
6 8175 5100 9225 5400
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8175 5100 9225 5100 9225 5400 8175 5400 8175 5100
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 885 8250 5325 EAP-PEAP\001
|
||||
-6
|
||||
6 9300 5100 10350 5400
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
9300 5100 10350 5100 10350 5400 9300 5400 9300 5100
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 840 9375 5325 EAP-TTLS\001
|
||||
-6
|
||||
6 8175 5475 9225 5775
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8175 5475 9225 5475 9225 5775 8175 5775 8175 5475
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 780 8250 5700 EAP-GTC\001
|
||||
-6
|
||||
6 8175 5850 9225 6150
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8175 5850 9225 5850 9225 6150 8175 6150 8175 5850
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 750 8250 6075 EAP-SIM\001
|
||||
-6
|
||||
6 8175 6225 9225 6525
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8175 6225 9225 6225 9225 6525 8175 6525 8175 6225
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 765 8250 6450 EAP-PSK\001
|
||||
-6
|
||||
6 9300 5850 10350 6150
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
9300 5850 10350 5850 10350 6150 9300 6150 9300 5850
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 825 9375 6075 EAP-AKA\001
|
||||
-6
|
||||
6 9300 5475 10350 5775
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
9300 5475 10350 5475 10350 5775 9300 5775 9300 5475
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 795 9375 5700 EAP-PAX\001
|
||||
-6
|
||||
6 8175 6600 9675 6900
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8175 6600 9675 6600 9675 6900 8175 6900 8175 6600
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 1365 8250 6825 EAP-MSCHAPv2\001
|
||||
-6
|
||||
6 8700 3450 9375 3750
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8700 3450 9375 3450 9375 3750 8700 3750 8700 3450
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 480 8775 3675 crypto\001
|
||||
-6
|
||||
6 9600 3450 10275 3750
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
9600 3450 10275 3450 10275 3750 9600 3750 9600 3450
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 315 9750 3675 TLS\001
|
||||
-6
|
||||
6 6000 5775 7200 6300
|
||||
6 6000 5775 7200 6300
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6000 5775 7200 5775 7200 6300 6000 6300 6000 5775
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 690 6075 6000 RADIUS\001
|
||||
-6
|
||||
4 0 0 50 -1 0 12 0.0000 4 90 480 6075 6225 server\001
|
||||
-6
|
||||
6 8100 2250 8925 2775
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8100 2250 8925 2250 8925 2775 8100 2775 8100 2250
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 690 8175 2475 RADIUS\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 420 8175 2700 client\001
|
||||
-6
|
||||
6 3150 5475 4425 5775
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3150 5475 4425 5475 4425 5775 3150 5775 3150 5475
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 990 3300 5700 driver events\001
|
||||
-6
|
||||
6 1950 5550 2625 6075
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1950 5550 2625 5550 2625 6075 1950 6075 1950 5550
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 540 2025 5775 Station\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 375 2025 6000 table\001
|
||||
-6
|
||||
6 1875 4725 2925 5250
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1875 4725 2925 4725 2925 5250 1875 5250 1875 4725
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 960 1950 4950 IEEE 802.11\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 555 1950 5175 MLME\001
|
||||
-6
|
||||
2 1 1 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2
|
||||
1275 4200 1875 4200
|
||||
2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
4500 2550 3900 1500
|
||||
2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
4800 2550 5400 1500
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
2925 4200 4350 4200
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5025 3900 6000 3000
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5025 4200 6000 4200
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4650 6000 4650 4425
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6600 4425 6600 4950
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6600 3225 6600 3900
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7200 5250 8100 5250
|
||||
2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
9075 4425 9075 3750
|
||||
2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7200 3000 8700 3525
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4650 3900 4650 2850
|
||||
2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7200 4125 8700 3675
|
||||
2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6000 4350 5025 6000
|
||||
2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6000 3150 4875 6000
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1500 2100 10800 2100 10800 7500 1500 7500 1500 2100
|
||||
2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
9900 4425 9900 3750
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 1
|
||||
4350 3900
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4350 3900 4050 3450
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4350 4425 4050 5475
|
||||
2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
2250 7200 4200 7800
|
||||
2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
7200 7200 5100 7800
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2775 6900 3675 6900 3675 7200 2775 7200 2775 6900
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3750 6900 4650 6900 4650 7200 3750 7200 3750 6900
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
|
||||
2250 6900 2250 6600 7200 6600 7200 6900
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3225 6900 3225 6600
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4200 6900 4200 6600
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5175 6900 5175 6600
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6150 6900 6150 6600
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4650 6600 4650 6300
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1800 6900 2700 6900 2700 7200 1800 7200 1800 6900
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4725 6900 5625 6900 5625 7200 4725 7200 4725 6900
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5700 6900 6600 6900 6600 7200 5700 7200 5700 6900
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6675 6900 7800 6900 7800 7200 6675 7200 6675 6900
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8100 6975 10425 6975 10425 4425 8100 4425 8100 6975
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6600 5475 6600 5775
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5025 4425 6000 5775
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
4800 3900 5925 2550 8100 2550
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7200 3900 8475 2775
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
9450 2250 10425 2250 10425 2775 9450 2775 9450 2250
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
8925 2475 9450 2475
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
2325 5550 2325 5250
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
2925 4950 4350 4275
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
2850 4725 5775 2400 8100 2400
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 915 375 3975 EAPOL and\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 180 630 375 4200 pre-auth\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 180 810 375 4425 ethertypes\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 1050 375 4650 from/to kernel\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 1920 3675 1875 frontend control interface\001
|
||||
4 0 0 50 -1 2 14 0.0000 4 195 720 1637 2371 hostapd\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 180 600 3825 7125 prism54\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 180 510 1875 7125 hostap\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 600 2850 7125 madwifi\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 270 4800 7125 bsd\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 105 300 6750 7125 test\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 420 5775 7125 wired\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 1050 8700 4650 EAP methods\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 135 690 9525 2475 RADIUS\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 180 825 9525 2700 accounting\001
|
@ -1,129 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
##########################################################################
|
||||
# Convert kernel-doc style comments to Doxygen comments.
|
||||
##########################################################################
|
||||
#
|
||||
# This script reads a C source file from stdin, and writes
|
||||
# to stdout. Normal usage:
|
||||
#
|
||||
# $ mv file.c file.c.gtkdoc
|
||||
# $ kerneldoc2doxygen.pl <file.c.gtkdoc >file.c
|
||||
#
|
||||
# Or to do the same thing with multiple files:
|
||||
# $ perl -i.gtkdoc kerneldoc2doxygen.pl *.c *.h
|
||||
#
|
||||
# This script may also be suitable for use as a Doxygen input filter,
|
||||
# but that has not been tested.
|
||||
#
|
||||
# Back up your source files before using this script!!
|
||||
#
|
||||
##########################################################################
|
||||
# Copyright (C) 2003 Jonathan Foster <jon@jon-foster.co.uk>
|
||||
# Copyright (C) 2005 Jouni Malinen <j@w1.fi>
|
||||
# (modified for kerneldoc format used in wpa_supplicant)
|
||||
#
|
||||
# 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
|
||||
# or look at http://www.gnu.org/licenses/gpl.html
|
||||
##########################################################################
|
||||
|
||||
|
||||
##########################################################################
|
||||
#
|
||||
# This function converts a single comment from gtk-doc to Doxygen format.
|
||||
# The parameter does not include the opening or closing lines
|
||||
# (i.e. given a comment like this:
|
||||
# "/**\n"
|
||||
# " * FunctionName:\n"
|
||||
# " * @foo: This describes the foo parameter\n"
|
||||
# " * @bar: This describes the bar parameter\n"
|
||||
# " * @Returns: This describes the return value\n"
|
||||
# " *\n"
|
||||
# " * This describes the function.\n"
|
||||
# " */\n"
|
||||
# This function gets:
|
||||
# " * FunctionName:\n"
|
||||
# " * @foo: This describes the foo parameter\n"
|
||||
# " * @bar: This describes the bar parameter\n"
|
||||
# " * @Returns: This describes the return value\n"
|
||||
# " *\n"
|
||||
# " * This describes the function.\n"
|
||||
# And it returns:
|
||||
# " * This describes the function.\n"
|
||||
# " *\n"
|
||||
# " * @param foo This describes the foo parameter\n"
|
||||
# " * @param bar This describes the bar parameter\n"
|
||||
# " * @return This describes the return value\n"
|
||||
# )
|
||||
#
|
||||
sub fixcomment {
|
||||
$t = $_[0];
|
||||
|
||||
# " * func: foo" --> "\brief foo\n"
|
||||
# " * struct bar: foo" --> "\brief foo\n"
|
||||
# If this fails, not a kernel-doc comment ==> return unmodified.
|
||||
($t =~ s/^[\t ]*\*[\t ]*(struct )?([^ \t\n]*) - ([^\n]*)/\\brief $3\n/s)
|
||||
or return $t;
|
||||
|
||||
# " * Returns: foo" --> "\return foo"
|
||||
$t =~ s/\n[\t ]*\*[\t ]*Returns:/\n\\return/sig;
|
||||
|
||||
# " * @foo: bar" --> "\param foo bar"
|
||||
# Handle two common typos: No ":", or "," instead of ":".
|
||||
$t =~ s/\n[\t ]*\*[\t ]*\@([^ :,]*)[:,]?[\t ]*/\n\\param $1 /sg;
|
||||
|
||||
return $t;
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Start of main code
|
||||
|
||||
# Read entire stdin into memory - one multi-line string.
|
||||
$_ = do { local $/; <> };
|
||||
|
||||
s{^/\*\n \*}{/\*\* \\file\n\\brief};
|
||||
s{ \* Copyright}{\\par Copyright\nCopyright};
|
||||
|
||||
# Fix any comments like "/*************" so they don't match.
|
||||
# "/***" ===> "/* *"
|
||||
s{/\*\*\*}{/\* \*}gs;
|
||||
|
||||
# The main comment-detection code.
|
||||
s{
|
||||
( # $1 = Open comment
|
||||
/\*\* # Open comment
|
||||
(?!\*) # Do not match /*** (redundant due to fixup above).
|
||||
[\t ]*\n? # If 1st line is whitespace, match the lot (including the newline).
|
||||
)
|
||||
(.*?) # $2 = Body of comment (multi-line)
|
||||
( # $3 = Close comment
|
||||
( # If possible, match the whitespace before the close-comment
|
||||
(?<=\n) # This part only matches after a newline
|
||||
[\t ]* # Eat whitespace
|
||||
)?
|
||||
\*/ # Close comment
|
||||
)
|
||||
}
|
||||
{
|
||||
$1 . fixcomment($2) . $3
|
||||
}gesx;
|
||||
# ^^^^ Modes: g - Global, match all occurances.
|
||||
# e - Evaluate the replacement as an expression.
|
||||
# s - Single-line - allows the pattern to match across newlines.
|
||||
# x - eXtended pattern, ignore embedded whitespace
|
||||
# and allow comments.
|
||||
|
||||
# Write results to stdout
|
||||
print $_;
|
||||
|
@ -1,52 +0,0 @@
|
||||
/**
|
||||
\mainpage Developers' documentation for hostapd
|
||||
|
||||
hostapd includes IEEE 802.11 access point management (authentication /
|
||||
association), IEEE 802.1X/WPA/WPA2 Authenticator, EAP server, and
|
||||
RADIUS authentication server functionality. It can be build with
|
||||
various configuration option, e.g., a standalone AP management
|
||||
solution or a RADIUS authentication server with support for number of
|
||||
EAP methods.
|
||||
|
||||
The goal of this documentation and comments in the source code is to
|
||||
give enough information for other developers to understand how hostapd
|
||||
has been implemented, how it can be modified, how new drivers can be
|
||||
supported, and how hostapd can be ported to other operating
|
||||
systems. If any information is missing, feel free to contact Jouni
|
||||
Malinen <j@w1.fi> for more information. Contributions as
|
||||
patch files are also very welcome at the same address. Please note
|
||||
that hostapd is licensed under dual license, GPLv2 or BSD at user's
|
||||
choice. All contributions to hostapd are expected to use compatible
|
||||
licensing terms.
|
||||
|
||||
The source code and read-only access to hostapd CVS repository
|
||||
is available from the project home page at
|
||||
http://hostap.epitest.fi/hostapd/. This developers' documentation
|
||||
is also available as a PDF file from
|
||||
http://hostap.epitest.fi/hostapd/hostapd-devel.pdf .
|
||||
|
||||
The design goal for hostapd was to use hardware, driver, and
|
||||
OS independent, portable C code for all WPA functionality. The source
|
||||
code is divided into separate C files as shown on the \ref
|
||||
code_structure "code structure page". All hardware/driver specific
|
||||
functionality is in separate files that implement a \ref
|
||||
driver_wrapper "well-defined driver API". Information about porting
|
||||
to different target boards and operating systems is available on
|
||||
the \ref porting "porting page".
|
||||
|
||||
EAPOL (IEEE 802.1X) state machines are implemented as a separate
|
||||
module that interacts with \ref eap_module "EAP server implementation".
|
||||
Similarly, RADIUS authentication server is in its own separate module.
|
||||
Both IEEE 802.1X and RADIUS authentication server can use EAP server
|
||||
functionality.
|
||||
|
||||
hostapd implements a \ref ctrl_iface_page "control interface" that can
|
||||
be used by external programs to control the operations of the hostapdt
|
||||
daemon and to get status information and event notifications. There is
|
||||
a small C library that provides helper functions to facilitate the use
|
||||
of the control interface. This library can also be used with C++.
|
||||
|
||||
\image html hostapd.png "hostapd modules"
|
||||
\image latex hostapd.eps "hostapd modules" width=15cm
|
||||
|
||||
*/
|
@ -1,5 +0,0 @@
|
||||
/**
|
||||
\page porting Porting to different target boards and operating systems
|
||||
|
||||
|
||||
*/
|
@ -1,798 +0,0 @@
|
||||
/*
|
||||
* hostapd - driver interface definition
|
||||
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2007-2008, Intel Corporation
|
||||
*
|
||||
* 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 DRIVER_H
|
||||
#define DRIVER_H
|
||||
|
||||
struct hostapd_sta_add_params {
|
||||
const u8 *addr;
|
||||
u16 aid;
|
||||
u16 capability;
|
||||
const u8 *supp_rates;
|
||||
size_t supp_rates_len;
|
||||
int flags;
|
||||
u16 listen_interval;
|
||||
const struct ht_cap_ie *ht_capabilities;
|
||||
};
|
||||
|
||||
struct hostapd_freq_params {
|
||||
int mode;
|
||||
int freq;
|
||||
int ht_enabled;
|
||||
int sec_channel_offset; /* 0 = HT40 disabled, -1 = HT40 enabled,
|
||||
* secondary channel below primary, 1 = HT40
|
||||
* enabled, secondary channel above primary */
|
||||
};
|
||||
|
||||
enum hostapd_driver_if_type {
|
||||
HOSTAPD_IF_VLAN, HOSTAPD_IF_WDS
|
||||
};
|
||||
|
||||
struct wpa_driver_ops {
|
||||
const char *name; /* as appears in the config file */
|
||||
|
||||
void * (*init)(struct hostapd_data *hapd);
|
||||
void * (*init_bssid)(struct hostapd_data *hapd, const u8 *bssid);
|
||||
void (*deinit)(void *priv);
|
||||
|
||||
int (*wireless_event_init)(void *priv);
|
||||
void (*wireless_event_deinit)(void *priv);
|
||||
|
||||
/**
|
||||
* set_8021x - enable/disable IEEE 802.1X support
|
||||
* @ifname: Interface name (for multi-SSID/VLAN support)
|
||||
* @priv: driver private data
|
||||
* @enabled: 1 = enable, 0 = disable
|
||||
*
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* Configure the kernel driver to enable/disable 802.1X support.
|
||||
* This may be an empty function if 802.1X support is always enabled.
|
||||
*/
|
||||
int (*set_ieee8021x)(const char *ifname, void *priv, int enabled);
|
||||
|
||||
/**
|
||||
* set_privacy - enable/disable privacy
|
||||
* @priv: driver private data
|
||||
* @enabled: 1 = privacy enabled, 0 = disabled
|
||||
*
|
||||
* Return: 0 on success, -1 on failure
|
||||
*
|
||||
* Configure privacy.
|
||||
*/
|
||||
int (*set_privacy)(const char *ifname, void *priv, int enabled);
|
||||
|
||||
int (*set_encryption)(const char *ifname, void *priv, const char *alg,
|
||||
const u8 *addr, int idx,
|
||||
const u8 *key, size_t key_len, int txkey);
|
||||
int (*get_seqnum)(const char *ifname, void *priv, const u8 *addr,
|
||||
int idx, u8 *seq);
|
||||
int (*get_seqnum_igtk)(const char *ifname, void *priv, const u8 *addr,
|
||||
int idx, u8 *seq);
|
||||
int (*flush)(void *priv);
|
||||
int (*set_generic_elem)(const char *ifname, void *priv, const u8 *elem,
|
||||
size_t elem_len);
|
||||
|
||||
int (*read_sta_data)(void *priv, struct hostap_sta_driver_data *data,
|
||||
const u8 *addr);
|
||||
int (*send_eapol)(void *priv, const u8 *addr, const u8 *data,
|
||||
size_t data_len, int encrypt, const u8 *own_addr);
|
||||
int (*sta_deauth)(void *priv, const u8 *addr, int reason);
|
||||
int (*sta_disassoc)(void *priv, const u8 *addr, int reason);
|
||||
int (*sta_remove)(void *priv, const u8 *addr);
|
||||
int (*get_ssid)(const char *ifname, void *priv, u8 *buf, int len);
|
||||
int (*set_ssid)(const char *ifname, void *priv, const u8 *buf,
|
||||
int len);
|
||||
int (*set_countermeasures)(void *priv, int enabled);
|
||||
int (*send_mgmt_frame)(void *priv, const void *msg, size_t len,
|
||||
int flags);
|
||||
int (*set_assoc_ap)(void *priv, const u8 *addr);
|
||||
/* note: sta_add() is deprecated; use sta_add2() instead */
|
||||
int (*sta_add)(const char *ifname, void *priv, const u8 *addr, u16 aid,
|
||||
u16 capability, u8 *supp_rates, size_t supp_rates_len,
|
||||
int flags, u16 listen_interval);
|
||||
int (*sta_add2)(const char *ifname, void *priv,
|
||||
struct hostapd_sta_add_params *params);
|
||||
int (*get_inact_sec)(void *priv, const u8 *addr);
|
||||
int (*sta_clear_stats)(void *priv, const u8 *addr);
|
||||
|
||||
/* note: set_freq() is deprecated; use set_freq2() instead */
|
||||
int (*set_freq)(void *priv, int mode, int freq);
|
||||
int (*set_freq2)(void *priv, struct hostapd_freq_params *freq);
|
||||
int (*set_rts)(void *priv, int rts);
|
||||
int (*get_rts)(void *priv, int *rts);
|
||||
int (*set_frag)(void *priv, int frag);
|
||||
int (*get_frag)(void *priv, int *frag);
|
||||
int (*set_retry)(void *priv, int short_retry, int long_retry);
|
||||
int (*get_retry)(void *priv, int *short_retry, int *long_retry);
|
||||
|
||||
int (*sta_set_flags)(void *priv, const u8 *addr,
|
||||
int total_flags, int flags_or, int flags_and);
|
||||
int (*set_rate_sets)(void *priv, int *supp_rates, int *basic_rates,
|
||||
int mode);
|
||||
int (*set_regulatory_domain)(void *priv, unsigned int rd);
|
||||
int (*set_country)(void *priv, const char *country);
|
||||
int (*set_ieee80211d)(void *priv, int enabled);
|
||||
int (*set_beacon)(const char *ifname, void *priv,
|
||||
u8 *head, size_t head_len,
|
||||
u8 *tail, size_t tail_len);
|
||||
|
||||
/* Configure internal bridge:
|
||||
* 0 = disabled, i.e., client separation is enabled (no bridging of
|
||||
* packets between associated STAs
|
||||
* 1 = enabled, i.e., bridge packets between associated STAs (default)
|
||||
*/
|
||||
int (*set_internal_bridge)(void *priv, int value);
|
||||
int (*set_beacon_int)(void *priv, int value);
|
||||
int (*set_dtim_period)(const char *ifname, void *priv, int value);
|
||||
/* Configure broadcast SSID mode:
|
||||
* 0 = include SSID in Beacon frames and reply to Probe Request frames
|
||||
* that use broadcast SSID
|
||||
* 1 = hide SSID from Beacon frames and ignore Probe Request frames for
|
||||
* broadcast SSID
|
||||
*/
|
||||
int (*set_broadcast_ssid)(void *priv, int value);
|
||||
int (*set_cts_protect)(void *priv, int value);
|
||||
int (*set_key_tx_rx_threshold)(void *priv, int value);
|
||||
int (*set_preamble)(void *priv, int value);
|
||||
int (*set_short_slot_time)(void *priv, int value);
|
||||
int (*set_tx_queue_params)(void *priv, int queue, int aifs, int cw_min,
|
||||
int cw_max, int burst_time);
|
||||
int (*bss_add)(void *priv, const char *ifname, const u8 *bssid);
|
||||
int (*bss_remove)(void *priv, const char *ifname);
|
||||
int (*valid_bss_mask)(void *priv, const u8 *addr, const u8 *mask);
|
||||
int (*passive_scan)(void *priv, int now, int our_mode_only,
|
||||
int interval, int _listen, int *channel,
|
||||
int *last_rx);
|
||||
struct hostapd_hw_modes * (*get_hw_feature_data)(void *priv,
|
||||
u16 *num_modes,
|
||||
u16 *flags);
|
||||
int (*if_add)(const char *iface, void *priv,
|
||||
enum hostapd_driver_if_type type, char *ifname,
|
||||
const u8 *addr);
|
||||
int (*if_update)(void *priv, enum hostapd_driver_if_type type,
|
||||
char *ifname, const u8 *addr);
|
||||
int (*if_remove)(void *priv, enum hostapd_driver_if_type type,
|
||||
const char *ifname, const u8 *addr);
|
||||
int (*set_sta_vlan)(void *priv, const u8 *addr, const char *ifname,
|
||||
int vlan_id);
|
||||
/**
|
||||
* commit - Optional commit changes handler
|
||||
* @priv: driver private data
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This optional handler function can be registered if the driver
|
||||
* interface implementation needs to commit changes (e.g., by setting
|
||||
* network interface up) at the end of initial configuration. If set,
|
||||
* this handler will be called after initial setup has been completed.
|
||||
*/
|
||||
int (*commit)(void *priv);
|
||||
|
||||
int (*send_ether)(void *priv, const u8 *dst, const u8 *src, u16 proto,
|
||||
const u8 *data, size_t data_len);
|
||||
|
||||
int (*set_radius_acl_auth)(void *priv, const u8 *mac, int accepted,
|
||||
u32 session_timeout);
|
||||
int (*set_radius_acl_expire)(void *priv, const u8 *mac);
|
||||
|
||||
int (*set_ht_params)(const char *ifname, void *priv,
|
||||
const u8 *ht_capab, size_t ht_capab_len,
|
||||
const u8 *ht_oper, size_t ht_oper_len);
|
||||
|
||||
int (*set_wps_beacon_ie)(const char *ifname, void *priv,
|
||||
const u8 *ie, size_t len);
|
||||
int (*set_wps_probe_resp_ie)(const char *ifname, void *priv,
|
||||
const u8 *ie, size_t len);
|
||||
};
|
||||
|
||||
static inline void *
|
||||
hostapd_driver_init(struct hostapd_data *hapd)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->init == NULL)
|
||||
return NULL;
|
||||
return hapd->driver->init(hapd);
|
||||
}
|
||||
|
||||
static inline void *
|
||||
hostapd_driver_init_bssid(struct hostapd_data *hapd, const u8 *bssid)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->init_bssid == NULL)
|
||||
return NULL;
|
||||
return hapd->driver->init_bssid(hapd, bssid);
|
||||
}
|
||||
|
||||
static inline void
|
||||
hostapd_driver_deinit(struct hostapd_data *hapd)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->deinit == NULL)
|
||||
return;
|
||||
hapd->driver->deinit(hapd->drv_priv);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_wireless_event_init(struct hostapd_data *hapd)
|
||||
{
|
||||
if (hapd->driver == NULL ||
|
||||
hapd->driver->wireless_event_init == NULL)
|
||||
return 0;
|
||||
return hapd->driver->wireless_event_init(hapd->drv_priv);
|
||||
}
|
||||
|
||||
static inline void
|
||||
hostapd_wireless_event_deinit(struct hostapd_data *hapd)
|
||||
{
|
||||
if (hapd->driver == NULL ||
|
||||
hapd->driver->wireless_event_deinit == NULL)
|
||||
return;
|
||||
hapd->driver->wireless_event_deinit(hapd->drv_priv);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_ieee8021x(const char *ifname, struct hostapd_data *hapd,
|
||||
int enabled)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_ieee8021x(ifname, hapd->drv_priv, enabled);
|
||||
}
|
||||
|
||||
static inline 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->conf->iface, hapd->drv_priv,
|
||||
enabled);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_encryption(const char *ifname, struct hostapd_data *hapd,
|
||||
const char *alg, const u8 *addr, int idx,
|
||||
u8 *key, size_t key_len, int txkey)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_encryption == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_encryption(ifname, hapd->drv_priv, alg, addr,
|
||||
idx, key, key_len, txkey);
|
||||
}
|
||||
|
||||
static inline 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);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_get_seqnum_igtk(const char *ifname, struct hostapd_data *hapd,
|
||||
const u8 *addr, int idx, u8 *seq)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->get_seqnum_igtk == NULL)
|
||||
return -1;
|
||||
return hapd->driver->get_seqnum_igtk(ifname, hapd->drv_priv, addr, idx,
|
||||
seq);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_flush(struct hostapd_data *hapd)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->flush == NULL)
|
||||
return 0;
|
||||
return hapd->driver->flush(hapd->drv_priv);
|
||||
}
|
||||
|
||||
static inline 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->conf->iface,
|
||||
hapd->drv_priv, elem, elem_len);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_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_send_eapol(struct hostapd_data *hapd, const u8 *addr, const u8 *data,
|
||||
size_t data_len, int encrypt)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->send_eapol == NULL)
|
||||
return 0;
|
||||
return hapd->driver->send_eapol(hapd->drv_priv, addr, data, data_len,
|
||||
encrypt, hapd->own_addr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_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, addr, reason);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_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, addr, reason);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_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_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->get_ssid == NULL)
|
||||
return 0;
|
||||
return hapd->driver->get_ssid(hapd->conf->iface, hapd->drv_priv, buf,
|
||||
len);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_ssid == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_ssid(hapd->conf->iface, hapd->drv_priv, buf,
|
||||
len);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_send_mgmt_frame(struct hostapd_data *hapd, const void *msg, size_t len,
|
||||
int flags)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->send_mgmt_frame == NULL)
|
||||
return 0;
|
||||
return hapd->driver->send_mgmt_frame(hapd->drv_priv, msg, len, flags);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_assoc_ap(struct hostapd_data *hapd, const u8 *addr)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_assoc_ap == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_assoc_ap(hapd->drv_priv, addr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_countermeasures(struct hostapd_data *hapd, int enabled)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_countermeasures == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_countermeasures(hapd->drv_priv, enabled);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_sta_add(const char *ifname, struct hostapd_data *hapd, const u8 *addr,
|
||||
u16 aid, u16 capability, const u8 *supp_rates,
|
||||
size_t supp_rates_len, int flags, u16 listen_interval,
|
||||
const struct ht_cap_ie *ht_capabilities)
|
||||
{
|
||||
if (hapd->driver == NULL)
|
||||
return 0;
|
||||
|
||||
if (hapd->driver->sta_add2) {
|
||||
struct hostapd_sta_add_params params;
|
||||
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.flags = flags;
|
||||
params.listen_interval = listen_interval;
|
||||
params.ht_capabilities = ht_capabilities;
|
||||
return hapd->driver->sta_add2(ifname, hapd->drv_priv, ¶ms);
|
||||
}
|
||||
|
||||
if (hapd->driver->sta_add == NULL)
|
||||
return 0;
|
||||
return hapd->driver->sta_add(ifname, hapd->drv_priv, addr, aid,
|
||||
capability, (u8 *) supp_rates,
|
||||
supp_rates_len,
|
||||
flags, listen_interval);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_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_set_freq(struct hostapd_data *hapd, int mode, int freq, int ht_enabled,
|
||||
int sec_channel_offset)
|
||||
{
|
||||
if (hapd->driver == NULL)
|
||||
return 0;
|
||||
if (hapd->driver->set_freq2) {
|
||||
struct hostapd_freq_params data;
|
||||
os_memset(&data, 0, sizeof(data));
|
||||
data.mode = mode;
|
||||
data.freq = freq;
|
||||
data.ht_enabled = ht_enabled;
|
||||
data.sec_channel_offset = sec_channel_offset;
|
||||
return hapd->driver->set_freq2(hapd->drv_priv, &data);
|
||||
}
|
||||
|
||||
if (hapd->driver->set_freq == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_freq(hapd->drv_priv, mode, freq);
|
||||
}
|
||||
|
||||
static inline 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);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_get_rts(struct hostapd_data *hapd, int *rts)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->get_rts == NULL)
|
||||
return 0;
|
||||
return hapd->driver->get_rts(hapd->drv_priv, rts);
|
||||
}
|
||||
|
||||
static inline 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);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_get_frag(struct hostapd_data *hapd, int *frag)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->get_frag == NULL)
|
||||
return 0;
|
||||
return hapd->driver->get_frag(hapd->drv_priv, frag);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_retry(struct hostapd_data *hapd, int short_retry, int long_retry)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_retry == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_retry(hapd->drv_priv, short_retry,
|
||||
long_retry);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_get_retry(struct hostapd_data *hapd, int *short_retry, int *long_retry)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->get_retry == NULL)
|
||||
return 0;
|
||||
return hapd->driver->get_retry(hapd->drv_priv, short_retry,
|
||||
long_retry);
|
||||
}
|
||||
|
||||
static inline 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);
|
||||
}
|
||||
|
||||
static inline 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);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_regulatory_domain(struct hostapd_data *hapd, unsigned int rd)
|
||||
{
|
||||
if (hapd->driver == NULL ||
|
||||
hapd->driver->set_regulatory_domain == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_regulatory_domain(hapd->drv_priv, rd);
|
||||
}
|
||||
|
||||
static inline 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);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_ieee80211d(struct hostapd_data *hapd, int enabled)
|
||||
{
|
||||
if (hapd->driver == NULL ||
|
||||
hapd->driver->set_ieee80211d == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_ieee80211d(hapd->drv_priv, enabled);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_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_set_beacon(const char *ifname, struct hostapd_data *hapd,
|
||||
u8 *head, size_t head_len,
|
||||
u8 *tail, size_t tail_len)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_beacon == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_beacon(ifname, hapd->drv_priv, head, head_len,
|
||||
tail, tail_len);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_internal_bridge(struct hostapd_data *hapd, int value)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_internal_bridge == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_internal_bridge(hapd->drv_priv, value);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_beacon_int(struct hostapd_data *hapd, int value)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_beacon_int == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_beacon_int(hapd->drv_priv, value);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_dtim_period(struct hostapd_data *hapd, int value)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_dtim_period == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_dtim_period(hapd->conf->iface, hapd->drv_priv,
|
||||
value);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_broadcast_ssid(struct hostapd_data *hapd, int value)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_broadcast_ssid == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_broadcast_ssid(hapd->drv_priv, value);
|
||||
}
|
||||
|
||||
static inline 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);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_key_tx_rx_threshold(struct hostapd_data *hapd, int value)
|
||||
{
|
||||
if (hapd->driver == NULL ||
|
||||
hapd->driver->set_key_tx_rx_threshold == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_key_tx_rx_threshold(hapd->drv_priv, value);
|
||||
}
|
||||
|
||||
static inline 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);
|
||||
}
|
||||
|
||||
static inline 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);
|
||||
}
|
||||
|
||||
static inline 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);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_bss_add(struct hostapd_data *hapd, const char *ifname, const u8 *bssid)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->bss_add == NULL)
|
||||
return 0;
|
||||
return hapd->driver->bss_add(hapd->drv_priv, ifname, bssid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_bss_remove(struct hostapd_data *hapd, const char *ifname)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->bss_remove == NULL)
|
||||
return 0;
|
||||
return hapd->driver->bss_remove(hapd->drv_priv, ifname);
|
||||
}
|
||||
|
||||
static inline 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);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_if_add(struct hostapd_data *hapd, enum hostapd_driver_if_type type,
|
||||
char *ifname, const u8 *addr)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->if_add == NULL)
|
||||
return -1;
|
||||
return hapd->driver->if_add(hapd->conf->iface, hapd->drv_priv, type,
|
||||
ifname, addr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_if_update(struct hostapd_data *hapd, enum hostapd_driver_if_type type,
|
||||
char *ifname, const u8 *addr)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->if_update == NULL)
|
||||
return -1;
|
||||
return hapd->driver->if_update(hapd->drv_priv, type, ifname, addr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_if_remove(struct hostapd_data *hapd, enum hostapd_driver_if_type type,
|
||||
char *ifname, const u8 *addr)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->if_remove == NULL)
|
||||
return -1;
|
||||
return hapd->driver->if_remove(hapd->drv_priv, type, ifname, addr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_passive_scan(struct hostapd_data *hapd, int now, int our_mode_only,
|
||||
int interval, int _listen, int *channel,
|
||||
int *last_rx)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->passive_scan == NULL)
|
||||
return -1;
|
||||
return hapd->driver->passive_scan(hapd->drv_priv, now, our_mode_only,
|
||||
interval, _listen, channel, last_rx);
|
||||
}
|
||||
|
||||
static inline 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);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_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_driver_commit(struct hostapd_data *hapd)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->commit == NULL)
|
||||
return 0;
|
||||
return hapd->driver->commit(hapd->drv_priv);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_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_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);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
static inline int
|
||||
hostapd_set_ht_params(const char *ifname, 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(
|
||||
ifname, hapd->drv_priv, ht_capab, ht_capab_len,
|
||||
ht_oper, ht_oper_len);
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
|
||||
static inline int
|
||||
hostapd_drv_none(struct hostapd_data *hapd)
|
||||
{
|
||||
return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_wps_beacon_ie(struct hostapd_data *hapd, const u8 *ie, size_t len)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_wps_beacon_ie == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_wps_beacon_ie(hapd->conf->iface,
|
||||
hapd->drv_priv, ie, len);
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_wps_probe_resp_ie(struct hostapd_data *hapd, const u8 *ie,
|
||||
size_t len)
|
||||
{
|
||||
if (hapd->driver == NULL ||
|
||||
hapd->driver->set_wps_probe_resp_ie == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_wps_probe_resp_ie(hapd->conf->iface,
|
||||
hapd->drv_priv, ie, len);
|
||||
}
|
||||
|
||||
#endif /* DRIVER_H */
|
@ -1,839 +0,0 @@
|
||||
/*
|
||||
* hostapd / Driver interaction with BSD net80211 layer
|
||||
* Copyright (c) 2004, Sam Leffler <sam@errno.com>
|
||||
* Copyright (c) 2004, 2Wire, 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 "includes.h"
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <net80211/ieee80211.h>
|
||||
#include <net80211/ieee80211_crypto.h>
|
||||
#include <net80211/ieee80211_ioctl.h>
|
||||
|
||||
/*
|
||||
* Avoid conflicts with hostapd definitions by undefining couple of defines
|
||||
* from net80211 header files.
|
||||
*/
|
||||
#undef RSN_VERSION
|
||||
#undef WPA_VERSION
|
||||
#undef WPA_OUI_TYPE
|
||||
#undef WME_OUI_TYPE
|
||||
|
||||
#include "hostapd.h"
|
||||
#include "driver.h"
|
||||
#include "ieee802_1x.h"
|
||||
#include "eloop.h"
|
||||
#include "sta_info.h"
|
||||
#include "l2_packet/l2_packet.h"
|
||||
|
||||
#include "eapol_sm.h"
|
||||
#include "wpa.h"
|
||||
#include "radius/radius.h"
|
||||
#include "ieee802_11.h"
|
||||
#include "common.h"
|
||||
|
||||
struct bsd_driver_data {
|
||||
struct hostapd_data *hapd; /* back pointer */
|
||||
|
||||
char iface[IFNAMSIZ + 1];
|
||||
struct l2_packet_data *sock_xmit; /* raw packet xmit socket */
|
||||
int ioctl_sock; /* socket for ioctl() use */
|
||||
int wext_sock; /* socket for wireless events */
|
||||
};
|
||||
|
||||
static int bsd_sta_deauth(void *priv, const u8 *addr, int reason_code);
|
||||
|
||||
static int
|
||||
set80211var(struct bsd_driver_data *drv, int op, const void *arg, int arg_len)
|
||||
{
|
||||
struct ieee80211req ireq;
|
||||
|
||||
memset(&ireq, 0, sizeof(ireq));
|
||||
os_strlcpy(ireq.i_name, drv->iface, IFNAMSIZ);
|
||||
ireq.i_type = op;
|
||||
ireq.i_len = arg_len;
|
||||
ireq.i_data = (void *) arg;
|
||||
|
||||
if (ioctl(drv->ioctl_sock, SIOCS80211, &ireq) < 0) {
|
||||
perror("ioctl[SIOCS80211]");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
get80211var(struct bsd_driver_data *drv, int op, void *arg, int arg_len)
|
||||
{
|
||||
struct ieee80211req ireq;
|
||||
|
||||
memset(&ireq, 0, sizeof(ireq));
|
||||
os_strlcpy(ireq.i_name, drv->iface, IFNAMSIZ);
|
||||
ireq.i_type = op;
|
||||
ireq.i_len = arg_len;
|
||||
ireq.i_data = arg;
|
||||
|
||||
if (ioctl(drv->ioctl_sock, SIOCG80211, &ireq) < 0) {
|
||||
perror("ioctl[SIOCG80211]");
|
||||
return -1;
|
||||
}
|
||||
return ireq.i_len;
|
||||
}
|
||||
|
||||
static int
|
||||
set80211param(struct bsd_driver_data *drv, int op, int arg)
|
||||
{
|
||||
struct ieee80211req ireq;
|
||||
|
||||
memset(&ireq, 0, sizeof(ireq));
|
||||
os_strlcpy(ireq.i_name, drv->iface, IFNAMSIZ);
|
||||
ireq.i_type = op;
|
||||
ireq.i_val = arg;
|
||||
|
||||
if (ioctl(drv->ioctl_sock, SIOCS80211, &ireq) < 0) {
|
||||
perror("ioctl[SIOCS80211]");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *
|
||||
ether_sprintf(const u8 *addr)
|
||||
{
|
||||
static char buf[sizeof(MACSTR)];
|
||||
|
||||
if (addr != NULL)
|
||||
snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
|
||||
else
|
||||
snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure WPA parameters.
|
||||
*/
|
||||
static int
|
||||
bsd_configure_wpa(struct bsd_driver_data *drv)
|
||||
{
|
||||
static const char *ciphernames[] =
|
||||
{ "WEP", "TKIP", "AES-OCB", "AES-CCM", "CKIP", "NONE" };
|
||||
struct hostapd_data *hapd = drv->hapd;
|
||||
struct hostapd_bss_config *conf = hapd->conf;
|
||||
int v;
|
||||
|
||||
switch (conf->wpa_group) {
|
||||
case WPA_CIPHER_CCMP:
|
||||
v = IEEE80211_CIPHER_AES_CCM;
|
||||
break;
|
||||
case WPA_CIPHER_TKIP:
|
||||
v = IEEE80211_CIPHER_TKIP;
|
||||
break;
|
||||
case WPA_CIPHER_WEP104:
|
||||
v = IEEE80211_CIPHER_WEP;
|
||||
break;
|
||||
case WPA_CIPHER_WEP40:
|
||||
v = IEEE80211_CIPHER_WEP;
|
||||
break;
|
||||
case WPA_CIPHER_NONE:
|
||||
v = IEEE80211_CIPHER_NONE;
|
||||
break;
|
||||
default:
|
||||
printf("Unknown group key cipher %u\n",
|
||||
conf->wpa_group);
|
||||
return -1;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "%s: group key cipher=%s (%u)",
|
||||
__func__, ciphernames[v], v);
|
||||
if (set80211param(drv, IEEE80211_IOC_MCASTCIPHER, v)) {
|
||||
printf("Unable to set group key cipher to %u (%s)\n",
|
||||
v, ciphernames[v]);
|
||||
return -1;
|
||||
}
|
||||
if (v == IEEE80211_CIPHER_WEP) {
|
||||
/* key length is done only for specific ciphers */
|
||||
v = (conf->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5);
|
||||
if (set80211param(drv, IEEE80211_IOC_MCASTKEYLEN, v)) {
|
||||
printf("Unable to set group key length to %u\n", v);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
v = 0;
|
||||
if (conf->wpa_pairwise & WPA_CIPHER_CCMP)
|
||||
v |= 1<<IEEE80211_CIPHER_AES_CCM;
|
||||
if (conf->wpa_pairwise & WPA_CIPHER_TKIP)
|
||||
v |= 1<<IEEE80211_CIPHER_TKIP;
|
||||
if (conf->wpa_pairwise & WPA_CIPHER_NONE)
|
||||
v |= 1<<IEEE80211_CIPHER_NONE;
|
||||
wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v);
|
||||
if (set80211param(drv, IEEE80211_IOC_UCASTCIPHERS, v)) {
|
||||
printf("Unable to set pairwise key ciphers to 0x%x\n", v);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x",
|
||||
__func__, conf->wpa_key_mgmt);
|
||||
if (set80211param(drv, IEEE80211_IOC_KEYMGTALGS, conf->wpa_key_mgmt)) {
|
||||
printf("Unable to set key management algorithms to 0x%x\n",
|
||||
conf->wpa_key_mgmt);
|
||||
return -1;
|
||||
}
|
||||
|
||||
v = 0;
|
||||
if (conf->rsn_preauth)
|
||||
v |= BIT(0);
|
||||
wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x",
|
||||
__func__, conf->rsn_preauth);
|
||||
if (set80211param(drv, IEEE80211_IOC_RSNCAPS, v)) {
|
||||
printf("Unable to set RSN capabilities to 0x%x\n", v);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: enable WPA= 0x%x", __func__, conf->wpa);
|
||||
if (set80211param(drv, IEEE80211_IOC_WPA, conf->wpa)) {
|
||||
printf("Unable to set WPA to %u\n", conf->wpa);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
bsd_set_iface_flags(void *priv, int dev_up)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
struct ifreq ifr;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: dev_up=%d", __func__, dev_up);
|
||||
|
||||
if (drv->ioctl_sock < 0)
|
||||
return -1;
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_name, drv->iface, IFNAMSIZ);
|
||||
|
||||
if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
|
||||
perror("ioctl[SIOCGIFFLAGS]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dev_up)
|
||||
ifr.ifr_flags |= IFF_UP;
|
||||
else
|
||||
ifr.ifr_flags &= ~IFF_UP;
|
||||
|
||||
if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) {
|
||||
perror("ioctl[SIOCSIFFLAGS]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dev_up) {
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_name, drv->iface, IFNAMSIZ);
|
||||
ifr.ifr_mtu = HOSTAPD_MTU;
|
||||
if (ioctl(drv->ioctl_sock, SIOCSIFMTU, &ifr) != 0) {
|
||||
perror("ioctl[SIOCSIFMTU]");
|
||||
printf("Setting MTU failed - trying to survive with "
|
||||
"current value\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_set_ieee8021x(const char *ifname, void *priv, int enabled)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
struct hostapd_data *hapd = drv->hapd;
|
||||
struct hostapd_bss_config *conf = hapd->conf;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
|
||||
|
||||
if (!enabled) {
|
||||
/* XXX restore state */
|
||||
return set80211param(priv, IEEE80211_IOC_AUTHMODE,
|
||||
IEEE80211_AUTH_AUTO);
|
||||
}
|
||||
if (!conf->wpa && !conf->ieee802_1x) {
|
||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
|
||||
HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!");
|
||||
return -1;
|
||||
}
|
||||
if (conf->wpa && bsd_configure_wpa(drv) != 0) {
|
||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
|
||||
HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!");
|
||||
return -1;
|
||||
}
|
||||
if (set80211param(priv, IEEE80211_IOC_AUTHMODE,
|
||||
(conf->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
|
||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
|
||||
HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!");
|
||||
return -1;
|
||||
}
|
||||
return bsd_set_iface_flags(priv, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_set_privacy(const char *ifname, void *priv, int enabled)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
|
||||
|
||||
return set80211param(drv, IEEE80211_IOC_PRIVACY, enabled);
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_set_sta_authorized(void *priv, const u8 *addr, int authorized)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
struct ieee80211req_mlme mlme;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d",
|
||||
__func__, ether_sprintf(addr), authorized);
|
||||
|
||||
if (authorized)
|
||||
mlme.im_op = IEEE80211_MLME_AUTHORIZE;
|
||||
else
|
||||
mlme.im_op = IEEE80211_MLME_UNAUTHORIZE;
|
||||
mlme.im_reason = 0;
|
||||
memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
|
||||
return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_sta_set_flags(void *priv, const u8 *addr, int total_flags, int flags_or,
|
||||
int flags_and)
|
||||
{
|
||||
/* For now, only support setting Authorized flag */
|
||||
if (flags_or & WLAN_STA_AUTHORIZED)
|
||||
return bsd_set_sta_authorized(priv, addr, 1);
|
||||
if (!(flags_and & WLAN_STA_AUTHORIZED))
|
||||
return bsd_set_sta_authorized(priv, addr, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_del_key(void *priv, const u8 *addr, int key_idx)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
struct ieee80211req_del_key wk;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d",
|
||||
__func__, ether_sprintf(addr), key_idx);
|
||||
|
||||
memset(&wk, 0, sizeof(wk));
|
||||
if (addr != NULL) {
|
||||
memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
|
||||
wk.idk_keyix = (u_int8_t) IEEE80211_KEYIX_NONE; /* XXX */
|
||||
} else {
|
||||
wk.idk_keyix = key_idx;
|
||||
}
|
||||
|
||||
return set80211var(drv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk));
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_set_key(const char *ifname, void *priv, const char *alg,
|
||||
const u8 *addr, int key_idx,
|
||||
const u8 *key, size_t key_len, int txkey)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
struct ieee80211req_key wk;
|
||||
u_int8_t cipher;
|
||||
|
||||
if (strcmp(alg, "none") == 0)
|
||||
return bsd_del_key(drv, addr, key_idx);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: alg=%s addr=%s key_idx=%d",
|
||||
__func__, alg, ether_sprintf(addr), key_idx);
|
||||
|
||||
if (strcmp(alg, "WEP") == 0)
|
||||
cipher = IEEE80211_CIPHER_WEP;
|
||||
else if (strcmp(alg, "TKIP") == 0)
|
||||
cipher = IEEE80211_CIPHER_TKIP;
|
||||
else if (strcmp(alg, "CCMP") == 0)
|
||||
cipher = IEEE80211_CIPHER_AES_CCM;
|
||||
else {
|
||||
printf("%s: unknown/unsupported algorithm %s\n",
|
||||
__func__, alg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (key_len > sizeof(wk.ik_keydata)) {
|
||||
printf("%s: key length %d too big\n", __func__, key_len);
|
||||
return -3;
|
||||
}
|
||||
|
||||
memset(&wk, 0, sizeof(wk));
|
||||
wk.ik_type = cipher;
|
||||
wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT;
|
||||
if (addr == NULL) {
|
||||
memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
|
||||
wk.ik_keyix = key_idx;
|
||||
wk.ik_flags |= IEEE80211_KEY_DEFAULT;
|
||||
} else {
|
||||
memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
|
||||
wk.ik_keyix = IEEE80211_KEYIX_NONE;
|
||||
}
|
||||
wk.ik_keylen = key_len;
|
||||
memcpy(wk.ik_keydata, key, key_len);
|
||||
|
||||
return set80211var(drv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
bsd_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
|
||||
u8 *seq)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
struct ieee80211req_key wk;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d",
|
||||
__func__, ether_sprintf(addr), idx);
|
||||
|
||||
memset(&wk, 0, sizeof(wk));
|
||||
if (addr == NULL)
|
||||
memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
|
||||
else
|
||||
memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
|
||||
wk.ik_keyix = idx;
|
||||
|
||||
if (get80211var(drv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)) < 0) {
|
||||
printf("Failed to get encryption.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
{
|
||||
/*
|
||||
* wk.ik_keytsc is in host byte order (big endian), need to
|
||||
* swap it to match with the byte order used in WPA.
|
||||
*/
|
||||
int i;
|
||||
u8 tmp[WPA_KEY_RSC_LEN];
|
||||
memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
|
||||
for (i = 0; i < WPA_KEY_RSC_LEN; i++) {
|
||||
seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1];
|
||||
}
|
||||
}
|
||||
#else /* WORDS_BIGENDIAN */
|
||||
memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
|
||||
#endif /* WORDS_BIGENDIAN */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
bsd_flush(void *priv)
|
||||
{
|
||||
u8 allsta[IEEE80211_ADDR_LEN];
|
||||
|
||||
memset(allsta, 0xff, IEEE80211_ADDR_LEN);
|
||||
return bsd_sta_deauth(priv, allsta, IEEE80211_REASON_AUTH_LEAVE);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
bsd_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data,
|
||||
const u8 *addr)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
struct ieee80211req_sta_stats stats;
|
||||
|
||||
memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);
|
||||
if (get80211var(drv, IEEE80211_IOC_STA_STATS, &stats, sizeof(stats)) > 0) {
|
||||
/* XXX? do packets counts include non-data frames? */
|
||||
data->rx_packets = stats.is_stats.ns_rx_data;
|
||||
data->rx_bytes = stats.is_stats.ns_rx_bytes;
|
||||
data->tx_packets = stats.is_stats.ns_tx_data;
|
||||
data->tx_bytes = stats.is_stats.ns_tx_bytes;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_set_opt_ie(const char *ifname, void *priv, const u8 *ie, size_t ie_len)
|
||||
{
|
||||
/*
|
||||
* Do nothing; we setup parameters at startup that define the
|
||||
* contents of the beacon information element.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_sta_deauth(void *priv, const u8 *addr, int reason_code)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
struct ieee80211req_mlme mlme;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
|
||||
__func__, ether_sprintf(addr), reason_code);
|
||||
|
||||
mlme.im_op = IEEE80211_MLME_DEAUTH;
|
||||
mlme.im_reason = reason_code;
|
||||
memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
|
||||
return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_sta_disassoc(void *priv, const u8 *addr, int reason_code)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
struct ieee80211req_mlme mlme;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
|
||||
__func__, ether_sprintf(addr), reason_code);
|
||||
|
||||
mlme.im_op = IEEE80211_MLME_DISASSOC;
|
||||
mlme.im_reason = reason_code;
|
||||
memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
|
||||
return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_del_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
|
||||
{
|
||||
struct hostapd_data *hapd = drv->hapd;
|
||||
struct hostapd_bss_config *conf = hapd->conf;
|
||||
struct sta_info *sta;
|
||||
|
||||
hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_INFO, "deassociated");
|
||||
|
||||
sta = ap_get_sta(hapd, addr);
|
||||
if (sta != NULL) {
|
||||
sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
|
||||
if (conf->wpa)
|
||||
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);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_new_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
|
||||
{
|
||||
struct hostapd_data *hapd = drv->hapd;
|
||||
struct hostapd_bss_config *conf = hapd->conf;
|
||||
struct sta_info *sta;
|
||||
struct ieee80211req_wpaie ie;
|
||||
int new_assoc, ielen, res;
|
||||
|
||||
hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_INFO, "associated");
|
||||
|
||||
sta = ap_sta_add(hapd, addr);
|
||||
if (sta == NULL)
|
||||
return -1;
|
||||
/*
|
||||
* Fetch and validate any negotiated WPA/RSN parameters.
|
||||
*/
|
||||
if (conf->wpa) {
|
||||
memset(&ie, 0, sizeof(ie));
|
||||
memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
|
||||
if (get80211var(drv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) {
|
||||
printf("Failed to get WPA/RSN information element.\n");
|
||||
return -1; /* XXX not right */
|
||||
}
|
||||
ielen = ie.wpa_ie[1];
|
||||
if (ielen == 0) {
|
||||
printf("No WPA/RSN information element for station!\n");
|
||||
return -1; /* XXX not right */
|
||||
}
|
||||
ielen += 2;
|
||||
if (sta->wpa_sm == NULL)
|
||||
sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
|
||||
sta->addr);
|
||||
if (sta->wpa_sm == NULL) {
|
||||
printf("Failed to initialize WPA state machine\n");
|
||||
return -1;
|
||||
}
|
||||
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
|
||||
ie.wpa_ie, ielen, NULL, 0);
|
||||
if (res != WPA_IE_OK) {
|
||||
printf("WPA/RSN information element rejected? "
|
||||
"(res %u)\n", res);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that the internal station state is setup
|
||||
* kick the authenticator into action.
|
||||
*/
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <net/route.h>
|
||||
#include <net80211/ieee80211_freebsd.h>
|
||||
|
||||
static void
|
||||
bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
|
||||
{
|
||||
struct bsd_driver_data *drv = ctx;
|
||||
struct hostapd_data *hapd = drv->hapd;
|
||||
char buf[2048];
|
||||
struct if_announcemsghdr *ifan;
|
||||
struct rt_msghdr *rtm;
|
||||
struct ieee80211_michael_event *mic;
|
||||
struct ieee80211_join_event *join;
|
||||
struct ieee80211_leave_event *leave;
|
||||
int n;
|
||||
|
||||
n = read(sock, buf, sizeof(buf));
|
||||
if (n < 0) {
|
||||
if (errno != EINTR && errno != EAGAIN)
|
||||
perror("read(PF_ROUTE)");
|
||||
return;
|
||||
}
|
||||
|
||||
rtm = (struct rt_msghdr *) buf;
|
||||
if (rtm->rtm_version != RTM_VERSION) {
|
||||
wpa_printf(MSG_DEBUG, "Routing message version %d not "
|
||||
"understood\n", rtm->rtm_version);
|
||||
return;
|
||||
}
|
||||
ifan = (struct if_announcemsghdr *) rtm;
|
||||
switch (rtm->rtm_type) {
|
||||
case RTM_IEEE80211:
|
||||
switch (ifan->ifan_what) {
|
||||
case RTM_IEEE80211_ASSOC:
|
||||
case RTM_IEEE80211_REASSOC:
|
||||
case RTM_IEEE80211_DISASSOC:
|
||||
case RTM_IEEE80211_SCAN:
|
||||
break;
|
||||
case RTM_IEEE80211_LEAVE:
|
||||
leave = (struct ieee80211_leave_event *) &ifan[1];
|
||||
bsd_del_sta(drv, leave->iev_addr);
|
||||
break;
|
||||
case RTM_IEEE80211_JOIN:
|
||||
#ifdef RTM_IEEE80211_REJOIN
|
||||
case RTM_IEEE80211_REJOIN:
|
||||
#endif
|
||||
join = (struct ieee80211_join_event *) &ifan[1];
|
||||
bsd_new_sta(drv, join->iev_addr);
|
||||
break;
|
||||
case RTM_IEEE80211_REPLAY:
|
||||
/* ignore */
|
||||
break;
|
||||
case RTM_IEEE80211_MICHAEL:
|
||||
mic = (struct ieee80211_michael_event *) &ifan[1];
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"Michael MIC failure wireless event: "
|
||||
"keyix=%u src_addr=" MACSTR, mic->iev_keyix,
|
||||
MAC2STR(mic->iev_src));
|
||||
ieee80211_michael_mic_failure(hapd, mic->iev_src, 1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_wireless_event_init(void *priv)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
int s;
|
||||
|
||||
drv->wext_sock = -1;
|
||||
|
||||
s = socket(PF_ROUTE, SOCK_RAW, 0);
|
||||
if (s < 0) {
|
||||
perror("socket(PF_ROUTE,SOCK_RAW)");
|
||||
return -1;
|
||||
}
|
||||
eloop_register_read_sock(s, bsd_wireless_event_receive, drv, NULL);
|
||||
drv->wext_sock = s;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
bsd_wireless_event_deinit(void *priv)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
|
||||
if (drv != NULL) {
|
||||
if (drv->wext_sock < 0)
|
||||
return;
|
||||
eloop_unregister_read_sock(drv->wext_sock);
|
||||
close(drv->wext_sock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
bsd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
|
||||
int encrypt, const u8 *own_addr)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
unsigned char buf[3000];
|
||||
unsigned char *bp = buf;
|
||||
struct l2_ethhdr *eth;
|
||||
size_t len;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Prepend the Etherent header. If the caller left us
|
||||
* space at the front we could just insert it but since
|
||||
* we don't know we copy to a local buffer. Given the frequency
|
||||
* and size of frames this probably doesn't matter.
|
||||
*/
|
||||
len = data_len + sizeof(struct l2_ethhdr);
|
||||
if (len > sizeof(buf)) {
|
||||
bp = malloc(len);
|
||||
if (bp == NULL) {
|
||||
printf("EAPOL frame discarded, cannot malloc temp "
|
||||
"buffer of size %u!\n", len);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
eth = (struct l2_ethhdr *) bp;
|
||||
memcpy(eth->h_dest, addr, ETH_ALEN);
|
||||
memcpy(eth->h_source, own_addr, ETH_ALEN);
|
||||
eth->h_proto = htons(ETH_P_EAPOL);
|
||||
memcpy(eth+1, data, data_len);
|
||||
|
||||
wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len);
|
||||
|
||||
status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len);
|
||||
|
||||
if (bp != buf)
|
||||
free(bp);
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
|
||||
{
|
||||
struct bsd_driver_data *drv = ctx;
|
||||
struct hostapd_data *hapd = drv->hapd;
|
||||
struct sta_info *sta;
|
||||
|
||||
sta = ap_get_sta(hapd, src_addr);
|
||||
if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {
|
||||
printf("Data frame from not associated STA %s\n",
|
||||
ether_sprintf(src_addr));
|
||||
/* XXX cannot happen */
|
||||
return;
|
||||
}
|
||||
ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr),
|
||||
len - sizeof(struct l2_ethhdr));
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_get_ssid(const char *ifname, void *priv, u8 *buf, int len)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
int ssid_len = get80211var(drv, IEEE80211_IOC_SSID, buf, len);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: ssid=\"%.*s\"", __func__, ssid_len, buf);
|
||||
|
||||
return ssid_len;
|
||||
}
|
||||
|
||||
static int
|
||||
bsd_set_ssid(const char *ifname, void *priv, const u8 *buf, int len)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: ssid=\"%.*s\"", __func__, len, buf);
|
||||
|
||||
return set80211var(drv, IEEE80211_IOC_SSID, buf, len);
|
||||
}
|
||||
|
||||
static void *
|
||||
bsd_init(struct hostapd_data *hapd)
|
||||
{
|
||||
struct bsd_driver_data *drv;
|
||||
|
||||
drv = os_zalloc(sizeof(struct bsd_driver_data));
|
||||
if (drv == NULL) {
|
||||
printf("Could not allocate memory for bsd driver data\n");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
drv->hapd = hapd;
|
||||
drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (drv->ioctl_sock < 0) {
|
||||
perror("socket[PF_INET,SOCK_DGRAM]");
|
||||
goto bad;
|
||||
}
|
||||
memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface));
|
||||
|
||||
drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
|
||||
handle_read, drv, 1);
|
||||
if (drv->sock_xmit == NULL)
|
||||
goto bad;
|
||||
if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr))
|
||||
goto bad;
|
||||
|
||||
bsd_set_iface_flags(drv, 0); /* mark down during setup */
|
||||
|
||||
return drv;
|
||||
bad:
|
||||
if (drv->sock_xmit != NULL)
|
||||
l2_packet_deinit(drv->sock_xmit);
|
||||
if (drv->ioctl_sock >= 0)
|
||||
close(drv->ioctl_sock);
|
||||
if (drv != NULL)
|
||||
free(drv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
bsd_deinit(void *priv)
|
||||
{
|
||||
struct bsd_driver_data *drv = priv;
|
||||
|
||||
(void) bsd_set_iface_flags(drv, 0);
|
||||
if (drv->ioctl_sock >= 0)
|
||||
close(drv->ioctl_sock);
|
||||
if (drv->sock_xmit != NULL)
|
||||
l2_packet_deinit(drv->sock_xmit);
|
||||
free(drv);
|
||||
}
|
||||
|
||||
const struct wpa_driver_ops wpa_driver_bsd_ops = {
|
||||
.name = "bsd",
|
||||
.init = bsd_init,
|
||||
.deinit = bsd_deinit,
|
||||
.set_ieee8021x = bsd_set_ieee8021x,
|
||||
.set_privacy = bsd_set_privacy,
|
||||
.set_encryption = bsd_set_key,
|
||||
.get_seqnum = bsd_get_seqnum,
|
||||
.flush = bsd_flush,
|
||||
.set_generic_elem = bsd_set_opt_ie,
|
||||
.wireless_event_init = bsd_wireless_event_init,
|
||||
.wireless_event_deinit = bsd_wireless_event_deinit,
|
||||
.sta_set_flags = bsd_sta_set_flags,
|
||||
.read_sta_data = bsd_read_sta_driver_data,
|
||||
.send_eapol = bsd_send_eapol,
|
||||
.sta_disassoc = bsd_sta_disassoc,
|
||||
.sta_deauth = bsd_sta_deauth,
|
||||
.set_ssid = bsd_set_ssid,
|
||||
.get_ssid = bsd_get_ssid,
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -1,372 +0,0 @@
|
||||
/*
|
||||
* hostapd / Kernel driver communication for wired (Ethernet) drivers
|
||||
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004, Gunter Burchardt <tira@isx.de>
|
||||
*
|
||||
* 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 <sys/ioctl.h>
|
||||
|
||||
#ifdef USE_KERNEL_HEADERS
|
||||
#include <asm/types.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <linux/if_ether.h> /* The L2 protocols */
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/if.h>
|
||||
#else /* USE_KERNEL_HEADERS */
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if.h>
|
||||
#include <netpacket/packet.h>
|
||||
#endif /* USE_KERNEL_HEADERS */
|
||||
|
||||
#include "hostapd.h"
|
||||
#include "ieee802_1x.h"
|
||||
#include "eloop.h"
|
||||
#include "sta_info.h"
|
||||
#include "driver.h"
|
||||
#include "accounting.h"
|
||||
|
||||
|
||||
struct wired_driver_data {
|
||||
struct hostapd_data *hapd;
|
||||
|
||||
int sock; /* raw packet socket for driver access */
|
||||
int dhcp_sock; /* socket for dhcp packets */
|
||||
int use_pae_group_addr;
|
||||
};
|
||||
|
||||
|
||||
#define WIRED_EAPOL_MULTICAST_GROUP {0x01,0x80,0xc2,0x00,0x00,0x03}
|
||||
|
||||
|
||||
/* TODO: detecting new devices should eventually be changed from using DHCP
|
||||
* snooping to trigger on any packet from a new layer 2 MAC address, e.g.,
|
||||
* based on ebtables, etc. */
|
||||
|
||||
struct dhcp_message {
|
||||
u_int8_t op;
|
||||
u_int8_t htype;
|
||||
u_int8_t hlen;
|
||||
u_int8_t hops;
|
||||
u_int32_t xid;
|
||||
u_int16_t secs;
|
||||
u_int16_t flags;
|
||||
u_int32_t ciaddr;
|
||||
u_int32_t yiaddr;
|
||||
u_int32_t siaddr;
|
||||
u_int32_t giaddr;
|
||||
u_int8_t chaddr[16];
|
||||
u_int8_t sname[64];
|
||||
u_int8_t file[128];
|
||||
u_int32_t cookie;
|
||||
u_int8_t options[308]; /* 312 - cookie */
|
||||
};
|
||||
|
||||
|
||||
static void wired_possible_new_sta(struct hostapd_data *hapd, u8 *addr)
|
||||
{
|
||||
struct sta_info *sta;
|
||||
|
||||
sta = ap_get_sta(hapd, addr);
|
||||
if (sta)
|
||||
return;
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void handle_data(struct hostapd_data *hapd, unsigned char *buf,
|
||||
size_t len)
|
||||
{
|
||||
struct ieee8023_hdr *hdr;
|
||||
u8 *pos, *sa;
|
||||
size_t left;
|
||||
|
||||
/* must contain at least ieee8023_hdr 6 byte source, 6 byte dest,
|
||||
* 2 byte ethertype */
|
||||
if (len < 14) {
|
||||
wpa_printf(MSG_MSGDUMP, "handle_data: too short (%lu)",
|
||||
(unsigned long) len);
|
||||
return;
|
||||
}
|
||||
|
||||
hdr = (struct ieee8023_hdr *) buf;
|
||||
|
||||
switch (ntohs(hdr->ethertype)) {
|
||||
case ETH_P_PAE:
|
||||
wpa_printf(MSG_MSGDUMP, "Received EAPOL packet");
|
||||
sa = hdr->src;
|
||||
wired_possible_new_sta(hapd, sa);
|
||||
|
||||
pos = (u8 *) (hdr + 1);
|
||||
left = len - sizeof(*hdr);
|
||||
|
||||
ieee802_1x_receive(hapd, sa, pos, left);
|
||||
break;
|
||||
|
||||
default:
|
||||
wpa_printf(MSG_DEBUG, "Unknown ethertype 0x%04x in data frame",
|
||||
ntohs(hdr->ethertype));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void handle_read(int sock, void *eloop_ctx, void *sock_ctx)
|
||||
{
|
||||
struct hostapd_data *hapd = (struct hostapd_data *) eloop_ctx;
|
||||
int len;
|
||||
unsigned char buf[3000];
|
||||
|
||||
len = recv(sock, buf, sizeof(buf), 0);
|
||||
if (len < 0) {
|
||||
perror("recv");
|
||||
return;
|
||||
}
|
||||
|
||||
handle_data(hapd, buf, len);
|
||||
}
|
||||
|
||||
|
||||
static void handle_dhcp(int sock, void *eloop_ctx, void *sock_ctx)
|
||||
{
|
||||
struct hostapd_data *hapd = (struct hostapd_data *) eloop_ctx;
|
||||
int len;
|
||||
unsigned char buf[3000];
|
||||
struct dhcp_message *msg;
|
||||
u8 *mac_address;
|
||||
|
||||
len = recv(sock, buf, sizeof(buf), 0);
|
||||
if (len < 0) {
|
||||
perror("recv");
|
||||
return;
|
||||
}
|
||||
|
||||
/* must contain at least dhcp_message->chaddr */
|
||||
if (len < 44) {
|
||||
wpa_printf(MSG_MSGDUMP, "handle_dhcp: too short (%d)", len);
|
||||
return;
|
||||
}
|
||||
|
||||
msg = (struct dhcp_message *) buf;
|
||||
mac_address = (u8 *) &(msg->chaddr);
|
||||
|
||||
wpa_printf(MSG_MSGDUMP, "Got DHCP broadcast packet from " MACSTR,
|
||||
MAC2STR(mac_address));
|
||||
|
||||
wired_possible_new_sta(hapd, mac_address);
|
||||
}
|
||||
|
||||
|
||||
static int wired_init_sockets(struct wired_driver_data *drv)
|
||||
{
|
||||
struct hostapd_data *hapd = drv->hapd;
|
||||
struct ifreq ifr;
|
||||
struct sockaddr_ll addr;
|
||||
struct sockaddr_in addr2;
|
||||
struct packet_mreq mreq;
|
||||
u8 multicastgroup_eapol[6] = WIRED_EAPOL_MULTICAST_GROUP;
|
||||
int n = 1;
|
||||
|
||||
drv->sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_PAE));
|
||||
if (drv->sock < 0) {
|
||||
perror("socket[PF_PACKET,SOCK_RAW]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (eloop_register_read_sock(drv->sock, handle_read, hapd, NULL)) {
|
||||
printf("Could not register read socket\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_name, hapd->conf->iface, sizeof(ifr.ifr_name));
|
||||
if (ioctl(drv->sock, SIOCGIFINDEX, &ifr) != 0) {
|
||||
perror("ioctl(SIOCGIFINDEX)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sll_family = AF_PACKET;
|
||||
addr.sll_ifindex = ifr.ifr_ifindex;
|
||||
wpa_printf(MSG_DEBUG, "Opening raw packet socket for ifindex %d",
|
||||
addr.sll_ifindex);
|
||||
|
||||
if (bind(drv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
perror("bind");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* filter multicast address */
|
||||
memset(&mreq, 0, sizeof(mreq));
|
||||
mreq.mr_ifindex = ifr.ifr_ifindex;
|
||||
mreq.mr_type = PACKET_MR_MULTICAST;
|
||||
mreq.mr_alen = 6;
|
||||
memcpy(mreq.mr_address, multicastgroup_eapol, mreq.mr_alen);
|
||||
|
||||
if (setsockopt(drv->sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq,
|
||||
sizeof(mreq)) < 0) {
|
||||
perror("setsockopt[SOL_SOCKET,PACKET_ADD_MEMBERSHIP]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_name, hapd->conf->iface, sizeof(ifr.ifr_name));
|
||||
if (ioctl(drv->sock, SIOCGIFHWADDR, &ifr) != 0) {
|
||||
perror("ioctl(SIOCGIFHWADDR)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
|
||||
printf("Invalid HW-addr family 0x%04x\n",
|
||||
ifr.ifr_hwaddr.sa_family);
|
||||
return -1;
|
||||
}
|
||||
memcpy(hapd->own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
|
||||
|
||||
/* setup dhcp listen socket for sta detection */
|
||||
if ((drv->dhcp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
|
||||
perror("socket call failed for dhcp");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (eloop_register_read_sock(drv->dhcp_sock, handle_dhcp, hapd, NULL))
|
||||
{
|
||||
printf("Could not register read socket\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&addr2, 0, sizeof(addr2));
|
||||
addr2.sin_family = AF_INET;
|
||||
addr2.sin_port = htons(67);
|
||||
addr2.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if (setsockopt(drv->dhcp_sock, SOL_SOCKET, SO_REUSEADDR, (char *) &n,
|
||||
sizeof(n)) == -1) {
|
||||
perror("setsockopt[SOL_SOCKET,SO_REUSEADDR]");
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(drv->dhcp_sock, SOL_SOCKET, SO_BROADCAST, (char *) &n,
|
||||
sizeof(n)) == -1) {
|
||||
perror("setsockopt[SOL_SOCKET,SO_BROADCAST]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_ifrn.ifrn_name, hapd->conf->iface, IFNAMSIZ);
|
||||
if (setsockopt(drv->dhcp_sock, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
(char *) &ifr, sizeof(ifr)) < 0) {
|
||||
perror("setsockopt[SOL_SOCKET,SO_BINDTODEVICE]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bind(drv->dhcp_sock, (struct sockaddr *) &addr2,
|
||||
sizeof(struct sockaddr)) == -1) {
|
||||
perror("bind");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int wired_send_eapol(void *priv, const u8 *addr,
|
||||
const u8 *data, size_t data_len, int encrypt,
|
||||
const u8 *own_addr)
|
||||
{
|
||||
struct wired_driver_data *drv = priv;
|
||||
u8 pae_group_addr[ETH_ALEN] = WIRED_EAPOL_MULTICAST_GROUP;
|
||||
struct ieee8023_hdr *hdr;
|
||||
size_t len;
|
||||
u8 *pos;
|
||||
int res;
|
||||
|
||||
len = sizeof(*hdr) + data_len;
|
||||
hdr = os_zalloc(len);
|
||||
if (hdr == NULL) {
|
||||
printf("malloc() failed for wired_send_eapol(len=%lu)\n",
|
||||
(unsigned long) len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(hdr->dest, drv->use_pae_group_addr ? pae_group_addr : addr,
|
||||
ETH_ALEN);
|
||||
memcpy(hdr->src, own_addr, ETH_ALEN);
|
||||
hdr->ethertype = htons(ETH_P_PAE);
|
||||
|
||||
pos = (u8 *) (hdr + 1);
|
||||
memcpy(pos, data, data_len);
|
||||
|
||||
res = send(drv->sock, (u8 *) hdr, len, 0);
|
||||
free(hdr);
|
||||
|
||||
if (res < 0) {
|
||||
perror("wired_send_eapol: send");
|
||||
printf("wired_send_eapol - packet len: %lu - failed\n",
|
||||
(unsigned long) len);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static void * wired_driver_init(struct hostapd_data *hapd)
|
||||
{
|
||||
struct wired_driver_data *drv;
|
||||
|
||||
drv = os_zalloc(sizeof(struct wired_driver_data));
|
||||
if (drv == NULL) {
|
||||
printf("Could not allocate memory for wired driver data\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
drv->hapd = hapd;
|
||||
drv->use_pae_group_addr = hapd->conf->use_pae_group_addr;
|
||||
|
||||
if (wired_init_sockets(drv)) {
|
||||
free(drv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return drv;
|
||||
}
|
||||
|
||||
|
||||
static void wired_driver_deinit(void *priv)
|
||||
{
|
||||
struct wired_driver_data *drv = priv;
|
||||
|
||||
if (drv->sock >= 0)
|
||||
close(drv->sock);
|
||||
|
||||
if (drv->dhcp_sock >= 0)
|
||||
close(drv->dhcp_sock);
|
||||
|
||||
free(drv);
|
||||
}
|
||||
|
||||
|
||||
const struct wpa_driver_ops wpa_driver_wired_ops = {
|
||||
.name = "wired",
|
||||
.init = wired_driver_init,
|
||||
.deinit = wired_driver_deinit,
|
||||
.send_eapol = wired_send_eapol,
|
||||
};
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* hostapd / driver interface list
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_DRIVER_HOSTAP
|
||||
extern struct wpa_driver_ops wpa_driver_hostap_ops; /* driver_hostap.c */
|
||||
#endif /* CONFIG_DRIVER_HOSTAP */
|
||||
#ifdef CONFIG_DRIVER_NL80211
|
||||
extern struct wpa_driver_ops wpa_driver_nl80211_ops; /* driver_nl80211.c */
|
||||
#endif /* CONFIG_DRIVER_NL80211 */
|
||||
#ifdef CONFIG_DRIVER_PRISM54
|
||||
extern struct wpa_driver_ops wpa_driver_prism54_ops; /* driver_prism54.c */
|
||||
#endif /* CONFIG_DRIVER_PRISM54 */
|
||||
#ifdef CONFIG_DRIVER_MADWIFI
|
||||
extern struct wpa_driver_ops wpa_driver_madwifi_ops; /* driver_madwifi.c */
|
||||
#endif /* CONFIG_DRIVER_MADWIFI */
|
||||
#ifdef CONFIG_DRIVER_ATHEROS
|
||||
extern struct wpa_driver_ops wpa_driver_atheros_ops; /* driver_atheros.c */
|
||||
#endif /* CONFIG_DRIVER_ATHEROS */
|
||||
#ifdef CONFIG_DRIVER_BSD
|
||||
extern struct wpa_driver_ops wpa_driver_bsd_ops; /* driver_bsd.c */
|
||||
#endif /* CONFIG_DRIVER_BSD */
|
||||
#ifdef CONFIG_DRIVER_WIRED
|
||||
extern struct wpa_driver_ops wpa_driver_wired_ops; /* driver_wired.c */
|
||||
#endif /* CONFIG_DRIVER_WIRED */
|
||||
#ifdef CONFIG_DRIVER_TEST
|
||||
extern struct wpa_driver_ops wpa_driver_test_ops; /* driver_test.c */
|
||||
#endif /* CONFIG_DRIVER_TEST */
|
||||
#ifdef CONFIG_DRIVER_NONE
|
||||
extern struct wpa_driver_ops wpa_driver_none_ops; /* driver_none.c */
|
||||
#endif /* CONFIG_DRIVER_NONE */
|
||||
|
||||
|
||||
struct wpa_driver_ops *hostapd_drivers[] =
|
||||
{
|
||||
#ifdef CONFIG_DRIVER_HOSTAP
|
||||
&wpa_driver_hostap_ops,
|
||||
#endif /* CONFIG_DRIVER_HOSTAP */
|
||||
#ifdef CONFIG_DRIVER_NL80211
|
||||
&wpa_driver_nl80211_ops,
|
||||
#endif /* CONFIG_DRIVER_NL80211 */
|
||||
#ifdef CONFIG_DRIVER_PRISM54
|
||||
&wpa_driver_prism54_ops,
|
||||
#endif /* CONFIG_DRIVER_PRISM54 */
|
||||
#ifdef CONFIG_DRIVER_MADWIFI
|
||||
&wpa_driver_madwifi_ops,
|
||||
#endif /* CONFIG_DRIVER_MADWIFI */
|
||||
#ifdef CONFIG_DRIVER_ATHEROS
|
||||
&wpa_driver_atheros_ops,
|
||||
#endif /* CONFIG_DRIVER_ATHEROS */
|
||||
#ifdef CONFIG_DRIVER_BSD
|
||||
&wpa_driver_bsd_ops,
|
||||
#endif /* CONFIG_DRIVER_BSD */
|
||||
#ifdef CONFIG_DRIVER_WIRED
|
||||
&wpa_driver_wired_ops,
|
||||
#endif /* CONFIG_DRIVER_WIRED */
|
||||
#ifdef CONFIG_DRIVER_TEST
|
||||
&wpa_driver_test_ops,
|
||||
#endif /* CONFIG_DRIVER_TEST */
|
||||
#ifdef CONFIG_DRIVER_NONE
|
||||
&wpa_driver_none_ops,
|
||||
#endif /* CONFIG_DRIVER_NONE */
|
||||
NULL
|
||||
};
|
184
contrib/wpa/hostapd/dump_state.c
Normal file
184
contrib/wpa/hostapd/dump_state.c
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 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]" : ""),
|
||||
(sta->flags & WLAN_STA_AUTHORIZED ? "[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;
|
||||
}
|
20
contrib/wpa/hostapd/dump_state.h
Normal file
20
contrib/wpa/hostapd/dump_state.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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 */
|
134
contrib/wpa/hostapd/eap_register.c
Normal file
134
contrib/wpa/hostapd/eap_register.c
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* RC4 stream cipher
|
||||
* Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
|
||||
* 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
|
||||
@ -12,10 +12,9 @@
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#ifndef RC4_H
|
||||
#define RC4_H
|
||||
#ifndef EAP_REGISTER_H
|
||||
#define EAP_REGISTER_H
|
||||
|
||||
void rc4_skip(const u8 *key, size_t keylen, size_t skip,
|
||||
u8 *data, size_t data_len);
|
||||
int eap_server_register_methods(void);
|
||||
|
||||
#endif /* RC4_H */
|
||||
#endif /* EAP_REGISTER_H */
|
@ -47,7 +47,7 @@
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "milenage.h"
|
||||
#include "crypto/milenage.h"
|
||||
|
||||
static const char *default_socket_path = "/tmp/hlr_auc_gw.sock";
|
||||
static const char *socket_path;
|
@ -1,216 +0,0 @@
|
||||
/*
|
||||
* hostapd / Kernel driver communication with Linux Host AP driver
|
||||
* Copyright (c) 2002-2006, 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 HOSTAP_COMMON_H
|
||||
#define HOSTAP_COMMON_H
|
||||
|
||||
/* netdevice private ioctls (used, e.g., with iwpriv from user space) */
|
||||
|
||||
/* New wireless extensions API - SET/GET convention (even ioctl numbers are
|
||||
* root only)
|
||||
*/
|
||||
#define PRISM2_IOCTL_PRISM2_PARAM (SIOCIWFIRSTPRIV + 0)
|
||||
#define PRISM2_IOCTL_GET_PRISM2_PARAM (SIOCIWFIRSTPRIV + 1)
|
||||
#define PRISM2_IOCTL_WRITEMIF (SIOCIWFIRSTPRIV + 2)
|
||||
#define PRISM2_IOCTL_READMIF (SIOCIWFIRSTPRIV + 3)
|
||||
#define PRISM2_IOCTL_MONITOR (SIOCIWFIRSTPRIV + 4)
|
||||
#define PRISM2_IOCTL_RESET (SIOCIWFIRSTPRIV + 6)
|
||||
#define PRISM2_IOCTL_INQUIRE (SIOCIWFIRSTPRIV + 8)
|
||||
#define PRISM2_IOCTL_WDS_ADD (SIOCIWFIRSTPRIV + 10)
|
||||
#define PRISM2_IOCTL_WDS_DEL (SIOCIWFIRSTPRIV + 12)
|
||||
#define PRISM2_IOCTL_SET_RID_WORD (SIOCIWFIRSTPRIV + 14)
|
||||
#define PRISM2_IOCTL_MACCMD (SIOCIWFIRSTPRIV + 16)
|
||||
#define PRISM2_IOCTL_ADDMAC (SIOCIWFIRSTPRIV + 18)
|
||||
#define PRISM2_IOCTL_DELMAC (SIOCIWFIRSTPRIV + 20)
|
||||
#define PRISM2_IOCTL_KICKMAC (SIOCIWFIRSTPRIV + 22)
|
||||
|
||||
/* following are not in SIOCGIWPRIV list; check permission in the driver code
|
||||
*/
|
||||
#define PRISM2_IOCTL_DOWNLOAD (SIOCDEVPRIVATE + 13)
|
||||
#define PRISM2_IOCTL_HOSTAPD (SIOCDEVPRIVATE + 14)
|
||||
|
||||
|
||||
/* PRISM2_IOCTL_PRISM2_PARAM ioctl() subtypes: */
|
||||
enum {
|
||||
/* PRISM2_PARAM_PTYPE = 1, */ /* REMOVED 2003-10-22 */
|
||||
PRISM2_PARAM_TXRATECTRL = 2,
|
||||
PRISM2_PARAM_BEACON_INT = 3,
|
||||
PRISM2_PARAM_PSEUDO_IBSS = 4,
|
||||
PRISM2_PARAM_ALC = 5,
|
||||
/* PRISM2_PARAM_TXPOWER = 6, */ /* REMOVED 2003-10-22 */
|
||||
PRISM2_PARAM_DUMP = 7,
|
||||
PRISM2_PARAM_OTHER_AP_POLICY = 8,
|
||||
PRISM2_PARAM_AP_MAX_INACTIVITY = 9,
|
||||
PRISM2_PARAM_AP_BRIDGE_PACKETS = 10,
|
||||
PRISM2_PARAM_DTIM_PERIOD = 11,
|
||||
PRISM2_PARAM_AP_NULLFUNC_ACK = 12,
|
||||
PRISM2_PARAM_MAX_WDS = 13,
|
||||
PRISM2_PARAM_AP_AUTOM_AP_WDS = 14,
|
||||
PRISM2_PARAM_AP_AUTH_ALGS = 15,
|
||||
PRISM2_PARAM_MONITOR_ALLOW_FCSERR = 16,
|
||||
PRISM2_PARAM_HOST_ENCRYPT = 17,
|
||||
PRISM2_PARAM_HOST_DECRYPT = 18,
|
||||
PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX = 19,
|
||||
PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX = 20,
|
||||
PRISM2_PARAM_HOST_ROAMING = 21,
|
||||
PRISM2_PARAM_BCRX_STA_KEY = 22,
|
||||
PRISM2_PARAM_IEEE_802_1X = 23,
|
||||
PRISM2_PARAM_ANTSEL_TX = 24,
|
||||
PRISM2_PARAM_ANTSEL_RX = 25,
|
||||
PRISM2_PARAM_MONITOR_TYPE = 26,
|
||||
PRISM2_PARAM_WDS_TYPE = 27,
|
||||
PRISM2_PARAM_HOSTSCAN = 28,
|
||||
PRISM2_PARAM_AP_SCAN = 29,
|
||||
PRISM2_PARAM_ENH_SEC = 30,
|
||||
PRISM2_PARAM_IO_DEBUG = 31,
|
||||
PRISM2_PARAM_BASIC_RATES = 32,
|
||||
PRISM2_PARAM_OPER_RATES = 33,
|
||||
PRISM2_PARAM_HOSTAPD = 34,
|
||||
PRISM2_PARAM_HOSTAPD_STA = 35,
|
||||
PRISM2_PARAM_WPA = 36,
|
||||
PRISM2_PARAM_PRIVACY_INVOKED = 37,
|
||||
PRISM2_PARAM_TKIP_COUNTERMEASURES = 38,
|
||||
PRISM2_PARAM_DROP_UNENCRYPTED = 39,
|
||||
PRISM2_PARAM_SCAN_CHANNEL_MASK = 40,
|
||||
};
|
||||
|
||||
enum { HOSTAP_ANTSEL_DO_NOT_TOUCH = 0, HOSTAP_ANTSEL_DIVERSITY = 1,
|
||||
HOSTAP_ANTSEL_LOW = 2, HOSTAP_ANTSEL_HIGH = 3 };
|
||||
|
||||
|
||||
/* PRISM2_IOCTL_MACCMD ioctl() subcommands: */
|
||||
enum { AP_MAC_CMD_POLICY_OPEN = 0, AP_MAC_CMD_POLICY_ALLOW = 1,
|
||||
AP_MAC_CMD_POLICY_DENY = 2, AP_MAC_CMD_FLUSH = 3,
|
||||
AP_MAC_CMD_KICKALL = 4 };
|
||||
|
||||
|
||||
/* PRISM2_IOCTL_DOWNLOAD ioctl() dl_cmd: */
|
||||
enum {
|
||||
PRISM2_DOWNLOAD_VOLATILE = 1 /* RAM */,
|
||||
/* Note! Old versions of prism2_srec have a fatal error in CRC-16
|
||||
* calculation, which will corrupt all non-volatile downloads.
|
||||
* PRISM2_DOWNLOAD_NON_VOLATILE used to be 2, but it is now 3 to
|
||||
* prevent use of old versions of prism2_srec for non-volatile
|
||||
* download. */
|
||||
PRISM2_DOWNLOAD_NON_VOLATILE = 3 /* FLASH */,
|
||||
PRISM2_DOWNLOAD_VOLATILE_GENESIS = 4 /* RAM in Genesis mode */,
|
||||
/* Persistent versions of volatile download commands (keep firmware
|
||||
* data in memory and automatically re-download after hw_reset */
|
||||
PRISM2_DOWNLOAD_VOLATILE_PERSISTENT = 5,
|
||||
PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT = 6,
|
||||
};
|
||||
|
||||
struct prism2_download_param {
|
||||
u32 dl_cmd;
|
||||
u32 start_addr;
|
||||
u32 num_areas;
|
||||
struct prism2_download_area {
|
||||
u32 addr; /* wlan card address */
|
||||
u32 len;
|
||||
caddr_t ptr; /* pointer to data in user space */
|
||||
} data[0];
|
||||
};
|
||||
|
||||
#define PRISM2_MAX_DOWNLOAD_AREA_LEN 131072
|
||||
#define PRISM2_MAX_DOWNLOAD_LEN 262144
|
||||
|
||||
|
||||
/* PRISM2_IOCTL_HOSTAPD ioctl() cmd: */
|
||||
enum {
|
||||
PRISM2_HOSTAPD_FLUSH = 1,
|
||||
PRISM2_HOSTAPD_ADD_STA = 2,
|
||||
PRISM2_HOSTAPD_REMOVE_STA = 3,
|
||||
PRISM2_HOSTAPD_GET_INFO_STA = 4,
|
||||
/* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */
|
||||
PRISM2_SET_ENCRYPTION = 6,
|
||||
PRISM2_GET_ENCRYPTION = 7,
|
||||
PRISM2_HOSTAPD_SET_FLAGS_STA = 8,
|
||||
PRISM2_HOSTAPD_GET_RID = 9,
|
||||
PRISM2_HOSTAPD_SET_RID = 10,
|
||||
PRISM2_HOSTAPD_SET_ASSOC_AP_ADDR = 11,
|
||||
PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12,
|
||||
PRISM2_HOSTAPD_MLME = 13,
|
||||
PRISM2_HOSTAPD_SCAN_REQ = 14,
|
||||
PRISM2_HOSTAPD_STA_CLEAR_STATS = 15,
|
||||
};
|
||||
|
||||
#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
|
||||
#define PRISM2_HOSTAPD_RID_HDR_LEN \
|
||||
((size_t) (&((struct prism2_hostapd_param *) 0)->u.rid.data))
|
||||
#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
|
||||
((size_t) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
|
||||
|
||||
/* Maximum length for algorithm names (-1 for nul termination) used in ioctl()
|
||||
*/
|
||||
#define HOSTAP_CRYPT_ALG_NAME_LEN 16
|
||||
|
||||
|
||||
struct prism2_hostapd_param {
|
||||
u32 cmd;
|
||||
u8 sta_addr[ETH_ALEN];
|
||||
union {
|
||||
struct {
|
||||
u16 aid;
|
||||
u16 capability;
|
||||
u8 tx_supp_rates;
|
||||
} add_sta;
|
||||
struct {
|
||||
u32 inactive_sec;
|
||||
} get_info_sta;
|
||||
struct {
|
||||
u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN];
|
||||
u32 flags;
|
||||
u32 err;
|
||||
u8 idx;
|
||||
u8 seq[8]; /* sequence counter (set: RX, get: TX) */
|
||||
u16 key_len;
|
||||
u8 key[0];
|
||||
} crypt;
|
||||
struct {
|
||||
u32 flags_and;
|
||||
u32 flags_or;
|
||||
} set_flags_sta;
|
||||
struct {
|
||||
u16 rid;
|
||||
u16 len;
|
||||
u8 data[0];
|
||||
} rid;
|
||||
struct {
|
||||
u8 len;
|
||||
u8 data[0];
|
||||
} generic_elem;
|
||||
struct {
|
||||
#define MLME_STA_DEAUTH 0
|
||||
#define MLME_STA_DISASSOC 1
|
||||
u16 cmd;
|
||||
u16 reason_code;
|
||||
} mlme;
|
||||
struct {
|
||||
u8 ssid_len;
|
||||
u8 ssid[32];
|
||||
} scan_req;
|
||||
} u;
|
||||
};
|
||||
|
||||
#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT(0)
|
||||
#define HOSTAP_CRYPT_FLAG_PERMANENT BIT(1)
|
||||
|
||||
#define HOSTAP_CRYPT_ERR_UNKNOWN_ALG 2
|
||||
#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3
|
||||
#define HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED 4
|
||||
#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5
|
||||
#define HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED 6
|
||||
#define HOSTAP_CRYPT_ERR_CARD_CONF_FAILED 7
|
||||
|
||||
#endif /* HOSTAP_COMMON_H */
|
@ -12,7 +12,7 @@ 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.
|
||||
The current version supports Linux (Host AP, madwifi, Prism54 drivers) and FreeBSD (net80211).
|
||||
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.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,12 +5,20 @@
|
||||
# management frames); ath0 for madwifi
|
||||
interface=wlan0
|
||||
|
||||
# In case of madwifi and nl80211 driver interfaces, an additional configuration
|
||||
# parameter, bridge, must be used to notify hostapd if the interface is
|
||||
# included in a bridge. This parameter is not used with Host AP driver.
|
||||
# In case of madwifi, atheros, and nl80211 driver interfaces, an additional
|
||||
# configuration parameter, bridge, may be used to notify hostapd if the
|
||||
# interface is included in a bridge. This parameter is not used with Host AP
|
||||
# driver. If the bridge parameter is not set, the drivers will automatically
|
||||
# figure out the bridge interface (assuming sysfs is enabled and mounted to
|
||||
# /sys) and this parameter may not be needed.
|
||||
#
|
||||
# For nl80211, this parameter can be used to request the AP interface to be
|
||||
# added to the bridge automatically (brctl may refuse to do this before hostapd
|
||||
# has been started to change the interface mode). If needed, the bridge
|
||||
# interface is also created.
|
||||
#bridge=br0
|
||||
|
||||
# Driver interface type (hostap/wired/madwifi/prism54/test/none/nl80211/bsd);
|
||||
# Driver interface type (hostap/wired/madwifi/test/none/nl80211/bsd);
|
||||
# default: hostap). nl80211 is used with all Linux mac80211 drivers.
|
||||
# Use driver=none if building hostapd as a standalone RADIUS server that does
|
||||
# not control any wireless/wired driver.
|
||||
@ -275,6 +283,10 @@ ignore_broadcast_ssid=0
|
||||
#
|
||||
wmm_enabled=1
|
||||
#
|
||||
# WMM-PS Unscheduled Automatic Power Save Delivery [U-APSD]
|
||||
# Enable this flag if U-APSD supported outside hostapd (eg., Firmware/driver)
|
||||
#uapsd_advertisement_enabled=1
|
||||
#
|
||||
# Low priority / AC_BK = background
|
||||
wmm_ac_bk_cwmin=4
|
||||
wmm_ac_bk_cwmax=10
|
||||
@ -342,34 +354,16 @@ wmm_ac_vo_acm=0
|
||||
# default: 300 (i.e., 5 minutes)
|
||||
#ap_max_inactivity=300
|
||||
|
||||
# Enable/disable internal bridge for packets between associated stations.
|
||||
#
|
||||
# When IEEE 802.11 is used in managed mode, packets are usually send through
|
||||
# the AP even if they are from a wireless station to another wireless station.
|
||||
# This functionality requires that the AP has a bridge functionality that sends
|
||||
# frames back to the same interface if their destination is another associated
|
||||
# station. In addition, broadcast/multicast frames from wireless stations will
|
||||
# be sent both to the host system net stack (e.g., to eventually wired network)
|
||||
# and back to the wireless interface.
|
||||
#
|
||||
# The internal bridge is implemented within the wireless kernel module and it
|
||||
# bypasses kernel filtering (netfilter/iptables/ebtables). If direct
|
||||
# communication between the stations needs to be prevented, the internal
|
||||
# bridge can be disabled by setting bridge_packets=0.
|
||||
#
|
||||
# Note: If this variable is not included in hostapd.conf, hostapd does not
|
||||
# change the configuration and iwpriv can be used to set the value with
|
||||
# 'iwpriv wlan# param 10 0' command. If the variable is in hostapd.conf,
|
||||
# hostapd will override possible iwpriv configuration whenever configuration
|
||||
# file is reloaded.
|
||||
#
|
||||
# default: do not control from hostapd (80211.o defaults to 1=enabled)
|
||||
#bridge_packets=1
|
||||
|
||||
# Maximum allowed Listen Interval (how many Beacon periods STAs are allowed to
|
||||
# remain asleep). Default: 65535 (no limit apart from field size)
|
||||
#max_listen_interval=100
|
||||
|
||||
# WDS (4-address frame) mode with per-station virtual interfaces
|
||||
# (only supported with driver=nl80211)
|
||||
# This mode allows associated stations to use 4-address frames to allow layer 2
|
||||
# bridging to be used.
|
||||
#wds_sta=1
|
||||
|
||||
##### IEEE 802.11n related configuration ######################################
|
||||
|
||||
# ieee80211n: Whether IEEE 802.11n (HT) is enabled
|
||||
@ -392,6 +386,10 @@ wmm_ac_vo_acm=0
|
||||
# 5 GHz 40,48,56,64 36,44,52,60
|
||||
# (depending on the location, not all of these channels may be available
|
||||
# for use)
|
||||
# Please note that 40 MHz channels may switch their primary and secondary
|
||||
# channels if needed or creation of 40 MHz channel maybe rejected based
|
||||
# on overlapping BSSes. These changes are done automatically when hostapd
|
||||
# is setting up the 40 MHz channel.
|
||||
# Spatial Multiplexing (SM) Power Save: [SMPS-STATIC] or [SMPS-DYNAMIC]
|
||||
# (SMPS disabled if neither is set)
|
||||
# HT-greenfield: [GF] (disabled if not set)
|
||||
@ -522,9 +520,9 @@ eap_server=0
|
||||
# EAP-FAST authority identity (A-ID)
|
||||
# A-ID indicates the identity of the authority that issues PACs. The A-ID
|
||||
# should be unique across all issuing servers. In theory, this is a variable
|
||||
# length field, but due to some existing implementations required A-ID to be
|
||||
# length field, but due to some existing implementations requiring A-ID to be
|
||||
# 16 octets in length, it is strongly recommended to use that length for the
|
||||
# field to provided interoperability with deployed peer implementation. This
|
||||
# field to provid interoperability with deployed peer implementations. This
|
||||
# field is configured in hex format.
|
||||
#eap_fast_a_id=101112131415161718191a1b1c1d1e1f
|
||||
|
||||
@ -808,7 +806,7 @@ own_ip_addr=127.0.0.1
|
||||
# And so on.. One line per R0KH.
|
||||
|
||||
# List of R1KHs in the same Mobility Domain
|
||||
# format: <MAC address> <R0KH-ID> <128-bit key as hex string>
|
||||
# format: <MAC address> <R1KH-ID> <128-bit key as hex string>
|
||||
# This list is used to map R1KH-ID to a destination MAC address when sending
|
||||
# PMK-R1 key from the R0KH. This is also the list of authorized R1KHs in the MD
|
||||
# that can request PMK-R1 keys.
|
||||
@ -821,27 +819,11 @@ own_ip_addr=127.0.0.1
|
||||
# 1 = push PMK-R1 to all configured R1KHs whenever a new PMK-R0 is derived
|
||||
#pmk_r1_push=1
|
||||
|
||||
##### Passive scanning ########################################################
|
||||
# Scan different channels every N seconds. 0 = disable passive scanning.
|
||||
#passive_scan_interval=60
|
||||
|
||||
# Listen N usecs on each channel when doing passive scanning.
|
||||
# This value plus the time needed for changing channels should be less than
|
||||
# 32 milliseconds (i.e. 32000 usec) to avoid interruptions to normal
|
||||
# operations. Time needed for channel changing varies based on the used wlan
|
||||
# hardware.
|
||||
# default: disabled (0)
|
||||
#passive_scan_listen=10000
|
||||
|
||||
# Passive scanning mode:
|
||||
# 0 = scan all supported modes (802.11a/b/g/Turbo) (default)
|
||||
# 1 = scan only the mode that is currently used for normal operations
|
||||
#passive_scan_mode=1
|
||||
|
||||
# Maximum number of entries kept in AP table (either for passive scanning or
|
||||
# for detecting Overlapping Legacy BSS Condition). The oldest entry will be
|
||||
##### Neighbor table ##########################################################
|
||||
# Maximum number of entries kept in AP table (either for neigbor table or for
|
||||
# detecting Overlapping Legacy BSS Condition). The oldest entry will be
|
||||
# removed when adding a new entry that would make the list grow over this
|
||||
# limit. Note! Wi-Fi certification for IEEE 802.11g requires that OLBC is
|
||||
# limit. Note! WFA certification for IEEE 802.11g requires that OLBC is
|
||||
# enabled, so this field should not be set to 0 when using IEEE 802.11g.
|
||||
# default: 255
|
||||
#ap_table_max_size=255
|
||||
@ -927,11 +909,17 @@ own_ip_addr=127.0.0.1
|
||||
|
||||
# Config Methods
|
||||
# List of the supported configuration methods
|
||||
# Available methods: usba ethernet label display ext_nfc_token int_nfc_token
|
||||
# nfc_interface push_button keypad
|
||||
#config_methods=label display push_button keypad
|
||||
|
||||
# Access point PIN for initial configuration and adding Registrars
|
||||
# Static access point PIN for initial configuration and adding Registrars
|
||||
# If not set, hostapd will not allow external WPS Registrars to control the
|
||||
# access point.
|
||||
# access point. The AP PIN can also be set at runtime with hostapd_cli
|
||||
# wps_ap_pin command. Use of temporary (enabled by user action) and random
|
||||
# AP PIN is much more secure than configuring a static AP PIN here. As such,
|
||||
# use of the ap_pin parameter is not recommended if the AP device has means for
|
||||
# displaying a random PIN.
|
||||
#ap_pin=12345670
|
||||
|
||||
# Skip building of automatic WPS credential
|
||||
@ -1002,7 +990,10 @@ own_ip_addr=127.0.0.1
|
||||
# hostapd will generate BSSID mask based on the BSSIDs that are
|
||||
# configured. hostapd will verify that dev_addr & MASK == dev_addr. If this is
|
||||
# not the case, the MAC address of the radio must be changed before starting
|
||||
# hostapd (ifconfig wlan0 hw ether <MAC addr>).
|
||||
# hostapd (ifconfig wlan0 hw ether <MAC addr>). If a BSSID is configured for
|
||||
# every secondary BSS, this limitation is not applied at hostapd and other
|
||||
# masks may be used if the driver supports them (e.g., swap the locally
|
||||
# administered bit)
|
||||
#
|
||||
# BSSIDs are assigned in order to each BSS, unless an explicit BSSID is
|
||||
# specified using the 'bssid' parameter.
|
||||
|
@ -1,238 +0,0 @@
|
||||
/*
|
||||
* hostapd / Initialization and configuration
|
||||
* Host AP kernel driver
|
||||
* Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2007-2008, Intel Corporation
|
||||
*
|
||||
* 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.h"
|
||||
#include "ap.h"
|
||||
|
||||
#ifndef ETH_ALEN
|
||||
#define ETH_ALEN 6
|
||||
#endif
|
||||
#ifndef IFNAMSIZ
|
||||
#define IFNAMSIZ 16
|
||||
#endif
|
||||
#ifndef ETH_P_ALL
|
||||
#define ETH_P_ALL 0x0003
|
||||
#endif
|
||||
#ifndef ETH_P_PAE
|
||||
#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
|
||||
#endif /* ETH_P_PAE */
|
||||
#ifndef ETH_P_EAPOL
|
||||
#define ETH_P_EAPOL ETH_P_PAE
|
||||
#endif /* ETH_P_EAPOL */
|
||||
|
||||
#ifndef ETH_P_RRB
|
||||
#define ETH_P_RRB 0x890D
|
||||
#endif /* ETH_P_RRB */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, 1)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#define MAX_VLAN_ID 4094
|
||||
|
||||
struct ieee8023_hdr {
|
||||
u8 dest[6];
|
||||
u8 src[6];
|
||||
u16 ethertype;
|
||||
} STRUCT_PACKED;
|
||||
|
||||
|
||||
struct ieee80211_hdr {
|
||||
le16 frame_control;
|
||||
le16 duration_id;
|
||||
u8 addr1[6];
|
||||
u8 addr2[6];
|
||||
u8 addr3[6];
|
||||
le16 seq_ctrl;
|
||||
/* followed by 'u8 addr4[6];' if ToDS and FromDS is set in data frame
|
||||
*/
|
||||
} STRUCT_PACKED;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#define IEEE80211_DA_FROMDS addr1
|
||||
#define IEEE80211_BSSID_FROMDS addr2
|
||||
#define IEEE80211_SA_FROMDS addr3
|
||||
|
||||
#define IEEE80211_HDRLEN (sizeof(struct ieee80211_hdr))
|
||||
|
||||
#define IEEE80211_FC(type, stype) host_to_le16((type << 2) | (stype << 4))
|
||||
|
||||
/* MTU to be set for the wlan#ap device; this is mainly needed for IEEE 802.1X
|
||||
* frames that might be longer than normal default MTU and they are not
|
||||
* fragmented */
|
||||
#define HOSTAPD_MTU 2290
|
||||
|
||||
extern unsigned char rfc1042_header[6];
|
||||
|
||||
struct hostap_sta_driver_data {
|
||||
unsigned long rx_packets, tx_packets, rx_bytes, tx_bytes;
|
||||
unsigned long current_tx_rate;
|
||||
unsigned long inactive_msec;
|
||||
unsigned long flags;
|
||||
unsigned long num_ps_buf_frames;
|
||||
unsigned long tx_retry_failed;
|
||||
unsigned long tx_retry_count;
|
||||
int last_rssi;
|
||||
int last_ack_rssi;
|
||||
};
|
||||
|
||||
struct wpa_driver_ops;
|
||||
struct wpa_ctrl_dst;
|
||||
struct radius_server_data;
|
||||
struct upnp_wps_device_sm;
|
||||
|
||||
#ifdef CONFIG_FULL_DYNAMIC_VLAN
|
||||
struct full_dynamic_vlan;
|
||||
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
struct sta_info *sta_hash[STA_HASH_SIZE];
|
||||
|
||||
/* pointers to STA info; based on allocated AID or NULL if AID free
|
||||
* AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1
|
||||
* and so on
|
||||
*/
|
||||
struct sta_info *sta_aid[MAX_AID_TABLE_SIZE];
|
||||
|
||||
const struct wpa_driver_ops *driver;
|
||||
void *drv_priv;
|
||||
|
||||
u8 *default_wep_key;
|
||||
u8 default_wep_key_idx;
|
||||
|
||||
struct radius_client_data *radius;
|
||||
int radius_client_reconfigured;
|
||||
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;
|
||||
|
||||
#ifdef CONFIG_WPS
|
||||
u8 *wps_beacon_ie;
|
||||
size_t wps_beacon_ie_len;
|
||||
u8 *wps_probe_resp_ie;
|
||||
size_t wps_probe_resp_ie_len;
|
||||
unsigned int ap_pin_failures;
|
||||
struct upnp_wps_device_sm *wps_upnp;
|
||||
#endif /* CONFIG_WPS */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct hostapd_iface - hostapd per-interface data structure
|
||||
*/
|
||||
struct hostapd_iface {
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
u16 ht_op_mode;
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
};
|
||||
|
||||
void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
int reassoc);
|
||||
int hostapd_reload_config(struct hostapd_iface *iface);
|
||||
|
||||
#endif /* HOSTAPD_H */
|
@ -3,7 +3,7 @@
|
||||
hostapd_cli \- hostapd command-line interface
|
||||
.SH SYNOPSIS
|
||||
.B hostapd_cli
|
||||
[\-p<path>] [\-i<ifname>] [\-hv] [command..]
|
||||
[\-p<path>] [\-i<ifname>] [\-a<path>] [\-hvB] [command..]
|
||||
.SH DESCRIPTION
|
||||
This manual page documents briefly the
|
||||
.B hostapd_cli
|
||||
@ -38,6 +38,12 @@ 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
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd - command line interface for hostapd daemon
|
||||
* Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-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
|
||||
@ -15,14 +15,14 @@
|
||||
#include "includes.h"
|
||||
#include <dirent.h>
|
||||
|
||||
#include "wpa_ctrl.h"
|
||||
#include "common/wpa_ctrl.h"
|
||||
#include "common.h"
|
||||
#include "version.h"
|
||||
#include "common/version.h"
|
||||
|
||||
|
||||
static const char *hostapd_cli_version =
|
||||
"hostapd_cli v" VERSION_STR "\n"
|
||||
"Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> and contributors";
|
||||
"Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
|
||||
|
||||
|
||||
static const char *hostapd_cli_license =
|
||||
@ -83,12 +83,18 @@ static const char *commands_help =
|
||||
" sta <addr> get MIB variables for one station\n"
|
||||
" all_sta get MIB variables for all stations\n"
|
||||
" new_sta <addr> add a new station\n"
|
||||
" deauthenticate <addr> deauthenticate a station\n"
|
||||
" disassociate <addr> disassociate a station\n"
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
" sa_query <addr> send SA Query to a station\n"
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
#ifdef CONFIG_WPS
|
||||
" wps_pin <uuid> <pin> [timeout] add WPS Enrollee PIN (Device Password)\n"
|
||||
" wps_pbc indicate button pushed to initiate PBC\n"
|
||||
#ifdef CONFIG_WPS_OOB
|
||||
" wps_oob <type> <path> <method> use WPS with out-of-band (UFD)\n"
|
||||
#endif /* CONFIG_WPS_OOB */
|
||||
" wps_ap_pin <cmd> [params..] enable/disable AP PIN\n"
|
||||
#endif /* CONFIG_WPS */
|
||||
" help show this usage help\n"
|
||||
" interface [ifname] show interfaces/select interface\n"
|
||||
@ -101,23 +107,29 @@ static int hostapd_cli_quit = 0;
|
||||
static int hostapd_cli_attached = 0;
|
||||
static const char *ctrl_iface_dir = "/var/run/hostapd";
|
||||
static char *ctrl_ifname = NULL;
|
||||
static const char *pid_file = NULL;
|
||||
static const char *action_file = NULL;
|
||||
static int ping_interval = 5;
|
||||
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
fprintf(stderr, "%s\n", hostapd_cli_version);
|
||||
fprintf(stderr,
|
||||
"\n"
|
||||
"usage: hostapd_cli [-p<path>] [-i<ifname>] [-hv] "
|
||||
"[-G<ping interval>] \\\n"
|
||||
" [command..]\n"
|
||||
fprintf(stderr,
|
||||
"\n"
|
||||
"usage: hostapd_cli [-p<path>] [-i<ifname>] [-hvB] "
|
||||
"[-a<path>] \\\n"
|
||||
" [-G<ping interval>] [command..]\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -h help (show this usage text)\n"
|
||||
" -v shown version information\n"
|
||||
" -p<path> path to find control sockets (default: "
|
||||
"/var/run/hostapd)\n"
|
||||
" -a<file> run in daemon mode executing the action file "
|
||||
"based on events\n"
|
||||
" from hostapd\n"
|
||||
" -B run a daemon in the background\n"
|
||||
" -i<ifname> Interface to listen on (default: first "
|
||||
"interface found in the\n"
|
||||
" socket path)\n\n"
|
||||
@ -212,6 +224,51 @@ static int hostapd_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_cli_exec(const char *program, const char *arg1,
|
||||
const char *arg2)
|
||||
{
|
||||
char *cmd;
|
||||
size_t len;
|
||||
int res;
|
||||
int ret = 0;
|
||||
|
||||
len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
|
||||
cmd = os_malloc(len);
|
||||
if (cmd == NULL)
|
||||
return -1;
|
||||
res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
|
||||
if (res < 0 || (size_t) res >= len) {
|
||||
os_free(cmd);
|
||||
return -1;
|
||||
}
|
||||
cmd[len - 1] = '\0';
|
||||
#ifndef _WIN32_WCE
|
||||
if (system(cmd) < 0)
|
||||
ret = -1;
|
||||
#endif /* _WIN32_WCE */
|
||||
os_free(cmd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_cli_action_process(char *msg, size_t len)
|
||||
{
|
||||
const char *pos;
|
||||
|
||||
pos = msg;
|
||||
if (*pos == '<') {
|
||||
pos = os_strchr(pos, '>');
|
||||
if (pos)
|
||||
pos++;
|
||||
else
|
||||
pos = msg;
|
||||
}
|
||||
|
||||
hostapd_cli_exec(action_file, ctrl_ifname, pos);
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||
{
|
||||
char buf[64];
|
||||
@ -239,6 +296,42 @@ static int hostapd_cli_cmd_new_sta(struct wpa_ctrl *ctrl, int argc,
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
char buf[64];
|
||||
if (argc < 1) {
|
||||
printf("Invalid 'deauthenticate' command - exactly one "
|
||||
"argument, STA address, is required.\n");
|
||||
return -1;
|
||||
}
|
||||
if (argc > 1)
|
||||
os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s %s",
|
||||
argv[0], argv[1]);
|
||||
else
|
||||
os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s", argv[0]);
|
||||
return wpa_ctrl_command(ctrl, buf);
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
char buf[64];
|
||||
if (argc < 1) {
|
||||
printf("Invalid 'disassociate' command - exactly one "
|
||||
"argument, STA address, is required.\n");
|
||||
return -1;
|
||||
}
|
||||
if (argc > 1)
|
||||
os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s %s",
|
||||
argv[0], argv[1]);
|
||||
else
|
||||
os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s", argv[0]);
|
||||
return wpa_ctrl_command(ctrl, buf);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
@ -279,6 +372,61 @@ static int hostapd_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc,
|
||||
{
|
||||
return wpa_ctrl_command(ctrl, "WPS_PBC");
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_WPS_OOB
|
||||
static int hostapd_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
char cmd[256];
|
||||
int res;
|
||||
|
||||
if (argc != 3 && argc != 4) {
|
||||
printf("Invalid WPS_OOB command: need three or four "
|
||||
"arguments:\n"
|
||||
"- DEV_TYPE: use 'ufd' or 'nfc'\n"
|
||||
"- PATH: path of OOB device like '/mnt'\n"
|
||||
"- METHOD: OOB method 'pin-e' or 'pin-r', "
|
||||
"'cred'\n"
|
||||
"- DEV_NAME: (only for NFC) device name like "
|
||||
"'pn531'\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (argc == 3)
|
||||
res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
|
||||
argv[0], argv[1], argv[2]);
|
||||
else
|
||||
res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
|
||||
argv[0], argv[1], argv[2], argv[3]);
|
||||
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
|
||||
printf("Too long WPS_OOB command.\n");
|
||||
return -1;
|
||||
}
|
||||
return wpa_ctrl_command(ctrl, cmd);
|
||||
}
|
||||
#endif /* CONFIG_WPS_OOB */
|
||||
|
||||
|
||||
static int hostapd_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
char buf[64];
|
||||
if (argc < 1) {
|
||||
printf("Invalid 'wps_ap_pin' command - at least one argument "
|
||||
"is required.\n");
|
||||
return -1;
|
||||
}
|
||||
if (argc > 2)
|
||||
snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s %s",
|
||||
argv[0], argv[1], argv[2]);
|
||||
else if (argc > 1)
|
||||
snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s",
|
||||
argv[0], argv[1]);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "WPS_AP_PIN %s", argv[0]);
|
||||
return wpa_ctrl_command(ctrl, buf);
|
||||
}
|
||||
#endif /* CONFIG_WPS */
|
||||
|
||||
|
||||
@ -430,12 +578,18 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = {
|
||||
{ "sta", hostapd_cli_cmd_sta },
|
||||
{ "all_sta", hostapd_cli_cmd_all_sta },
|
||||
{ "new_sta", hostapd_cli_cmd_new_sta },
|
||||
{ "deauthenticate", hostapd_cli_cmd_deauthenticate },
|
||||
{ "disassociate", hostapd_cli_cmd_disassociate },
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
{ "sa_query", hostapd_cli_cmd_sa_query },
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
#ifdef CONFIG_WPS
|
||||
{ "wps_pin", hostapd_cli_cmd_wps_pin },
|
||||
{ "wps_pbc", hostapd_cli_cmd_wps_pbc },
|
||||
#ifdef CONFIG_WPS_OOB
|
||||
{ "wps_oob", hostapd_cli_cmd_wps_oob },
|
||||
#endif /* CONFIG_WPS_OOB */
|
||||
{ "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
|
||||
#endif /* CONFIG_WPS */
|
||||
{ "help", hostapd_cli_cmd_help },
|
||||
{ "interface", hostapd_cli_cmd_interface },
|
||||
@ -480,7 +634,8 @@ static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read)
|
||||
static void hostapd_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
|
||||
int action_monitor)
|
||||
{
|
||||
int first = 1;
|
||||
if (ctrl_conn == NULL)
|
||||
@ -490,10 +645,14 @@ static void hostapd_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read)
|
||||
size_t len = sizeof(buf) - 1;
|
||||
if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
|
||||
buf[len] = '\0';
|
||||
if (in_read && first)
|
||||
printf("\n");
|
||||
first = 0;
|
||||
printf("%s\n", buf);
|
||||
if (action_monitor)
|
||||
hostapd_cli_action_process(buf, len);
|
||||
else {
|
||||
if (in_read && first)
|
||||
printf("\n");
|
||||
first = 0;
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
} else {
|
||||
printf("Could not read pending message.\n");
|
||||
break;
|
||||
@ -511,7 +670,7 @@ static void hostapd_cli_interactive(void)
|
||||
printf("\nInteractive mode\n\n");
|
||||
|
||||
do {
|
||||
hostapd_cli_recv_pending(ctrl_conn, 0);
|
||||
hostapd_cli_recv_pending(ctrl_conn, 0, 0);
|
||||
printf("> ");
|
||||
alarm(ping_interval);
|
||||
res = fgets(cmd, sizeof(cmd), stdin);
|
||||
@ -548,9 +707,19 @@ static void hostapd_cli_interactive(void)
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_cli_terminate(int sig)
|
||||
static void hostapd_cli_cleanup(void)
|
||||
{
|
||||
hostapd_cli_close_connection();
|
||||
if (pid_file)
|
||||
os_daemonize_terminate(pid_file);
|
||||
|
||||
os_program_deinit();
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_cli_terminate(int sig)
|
||||
{
|
||||
hostapd_cli_cleanup();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -574,22 +743,69 @@ static void hostapd_cli_alarm(int sig)
|
||||
}
|
||||
}
|
||||
if (ctrl_conn)
|
||||
hostapd_cli_recv_pending(ctrl_conn, 1);
|
||||
hostapd_cli_recv_pending(ctrl_conn, 1, 0);
|
||||
alarm(ping_interval);
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_cli_action(struct wpa_ctrl *ctrl)
|
||||
{
|
||||
fd_set rfds;
|
||||
int fd, res;
|
||||
struct timeval tv;
|
||||
char buf[256];
|
||||
size_t len;
|
||||
|
||||
fd = wpa_ctrl_get_fd(ctrl);
|
||||
|
||||
while (!hostapd_cli_quit) {
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
tv.tv_sec = ping_interval;
|
||||
tv.tv_usec = 0;
|
||||
res = select(fd + 1, &rfds, NULL, NULL, &tv);
|
||||
if (res < 0 && errno != EINTR) {
|
||||
perror("select");
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET(fd, &rfds))
|
||||
hostapd_cli_recv_pending(ctrl, 0, 1);
|
||||
else {
|
||||
len = sizeof(buf) - 1;
|
||||
if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
|
||||
hostapd_cli_action_process) < 0 ||
|
||||
len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
|
||||
printf("hostapd did not reply to PING "
|
||||
"command - exiting\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int interactive;
|
||||
int warning_displayed = 0;
|
||||
int c;
|
||||
int daemonize = 0;
|
||||
|
||||
if (os_program_init())
|
||||
return -1;
|
||||
|
||||
for (;;) {
|
||||
c = getopt(argc, argv, "hG:i:p:v");
|
||||
c = getopt(argc, argv, "a:BhG:i:p:v");
|
||||
if (c < 0)
|
||||
break;
|
||||
switch (c) {
|
||||
case 'a':
|
||||
action_file = optarg;
|
||||
break;
|
||||
case 'B':
|
||||
daemonize = 1;
|
||||
break;
|
||||
case 'G':
|
||||
ping_interval = atoi(optarg);
|
||||
break;
|
||||
@ -600,8 +816,8 @@ int main(int argc, char *argv[])
|
||||
printf("%s\n", hostapd_cli_version);
|
||||
return 0;
|
||||
case 'i':
|
||||
free(ctrl_ifname);
|
||||
ctrl_ifname = strdup(optarg);
|
||||
os_free(ctrl_ifname);
|
||||
ctrl_ifname = os_strdup(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
ctrl_iface_dir = optarg;
|
||||
@ -612,7 +828,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
interactive = argc == optind;
|
||||
interactive = (argc == optind) && (action_file == NULL);
|
||||
|
||||
if (interactive) {
|
||||
printf("%s\n\n%s\n\n", hostapd_cli_version,
|
||||
@ -625,12 +841,13 @@ int main(int argc, char *argv[])
|
||||
DIR *dir = opendir(ctrl_iface_dir);
|
||||
if (dir) {
|
||||
while ((dent = readdir(dir))) {
|
||||
if (strcmp(dent->d_name, ".") == 0 ||
|
||||
strcmp(dent->d_name, "..") == 0)
|
||||
if (os_strcmp(dent->d_name, ".") == 0
|
||||
||
|
||||
os_strcmp(dent->d_name, "..") == 0)
|
||||
continue;
|
||||
printf("Selected interface '%s'\n",
|
||||
dent->d_name);
|
||||
ctrl_ifname = strdup(dent->d_name);
|
||||
ctrl_ifname = os_strdup(dent->d_name);
|
||||
break;
|
||||
}
|
||||
closedir(dir);
|
||||
@ -653,7 +870,7 @@ int main(int argc, char *argv[])
|
||||
printf("Could not connect to hostapd - re-trying\n");
|
||||
warning_displayed = 1;
|
||||
}
|
||||
sleep(1);
|
||||
os_sleep(1, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -661,17 +878,27 @@ int main(int argc, char *argv[])
|
||||
signal(SIGTERM, hostapd_cli_terminate);
|
||||
signal(SIGALRM, hostapd_cli_alarm);
|
||||
|
||||
if (interactive) {
|
||||
if (interactive || action_file) {
|
||||
if (wpa_ctrl_attach(ctrl_conn) == 0) {
|
||||
hostapd_cli_attached = 1;
|
||||
} else {
|
||||
printf("Warning: Failed to attach to hostapd.\n");
|
||||
if (action_file)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (daemonize && os_daemonize(pid_file))
|
||||
return -1;
|
||||
|
||||
if (interactive)
|
||||
hostapd_cli_interactive();
|
||||
} else
|
||||
else if (action_file)
|
||||
hostapd_cli_action(ctrl_conn);
|
||||
else
|
||||
wpa_request(ctrl_conn, argc - optind, &argv[optind]);
|
||||
|
||||
free(ctrl_ifname);
|
||||
hostapd_cli_close_connection();
|
||||
os_free(ctrl_ifname);
|
||||
hostapd_cli_cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
565
contrib/wpa/hostapd/main.c
Normal file
565
contrib/wpa/hostapd/main.c
Normal file
@ -0,0 +1,565 @@
|
||||
/*
|
||||
* hostapd / main()
|
||||
* Copyright (c) 2002-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"
|
||||
#ifndef CONFIG_NATIVE_WINDOWS
|
||||
#include <syslog.h>
|
||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#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 */
|
||||
|
||||
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-2010, 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"
|
||||
" -t include timestamps in some debug messages\n"
|
||||
" -v show hostapd version\n");
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
if (os_program_init())
|
||||
return -1;
|
||||
|
||||
for (;;) {
|
||||
c = getopt(argc, argv, "BdhKP: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 '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();
|
||||
|
||||
interfaces.count = argc - optind;
|
||||
interfaces.iface = os_malloc(interfaces.count *
|
||||
sizeof(struct hostapd_iface *));
|
||||
if (interfaces.iface == NULL) {
|
||||
wpa_printf(MSG_ERROR, "malloc failed\n");
|
||||
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);
|
||||
|
||||
os_program_deinit();
|
||||
|
||||
return ret;
|
||||
}
|
@ -15,7 +15,7 @@
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "ms_funcs.h"
|
||||
#include "crypto/ms_funcs.h"
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -43,7 +43,8 @@ int main(int argc, char *argv[])
|
||||
password = buf;
|
||||
}
|
||||
|
||||
nt_password_hash((u8 *) password, strlen(password), password_hash);
|
||||
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");
|
||||
|
@ -1,242 +0,0 @@
|
||||
/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
|
||||
/* $NetBSD: ieee80211_radiotap.h,v 1.11 2005/06/22 06:16:02 dyoung Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004 David Young. All rights reserved.
|
||||
*
|
||||
* 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. The name of David Young may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``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 DAVID
|
||||
* YOUNG 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modifications to fit into the linux IEEE 802.11 stack,
|
||||
* Mike Kershaw (dragorn@kismetwireless.net)
|
||||
*/
|
||||
|
||||
#ifndef IEEE80211RADIOTAP_H
|
||||
#define IEEE80211RADIOTAP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Base version of the radiotap packet header data */
|
||||
#define PKTHDR_RADIOTAP_VERSION 0
|
||||
|
||||
/* A generic radio capture format is desirable. There is one for
|
||||
* Linux, but it is neither rigidly defined (there were not even
|
||||
* units given for some fields) nor easily extensible.
|
||||
*
|
||||
* I suggest the following extensible radio capture format. It is
|
||||
* based on a bitmap indicating which fields are present.
|
||||
*
|
||||
* I am trying to describe precisely what the application programmer
|
||||
* should expect in the following, and for that reason I tell the
|
||||
* units and origin of each measurement (where it applies), or else I
|
||||
* use sufficiently weaselly language ("is a monotonically nondecreasing
|
||||
* function of...") that I cannot set false expectations for lawyerly
|
||||
* readers.
|
||||
*/
|
||||
|
||||
/* The radio capture header precedes the 802.11 header.
|
||||
* All data in the header is little endian on all platforms.
|
||||
*/
|
||||
struct ieee80211_radiotap_header {
|
||||
uint8_t it_version; /* Version 0. Only increases
|
||||
* for drastic changes,
|
||||
* introduction of compatible
|
||||
* new fields does not count.
|
||||
*/
|
||||
uint8_t it_pad;
|
||||
uint16_t it_len; /* length of the whole
|
||||
* header in bytes, including
|
||||
* it_version, it_pad,
|
||||
* it_len, and data fields.
|
||||
*/
|
||||
uint32_t it_present; /* A bitmap telling which
|
||||
* fields are present. Set bit 31
|
||||
* (0x80000000) to extend the
|
||||
* bitmap by another 32 bits.
|
||||
* Additional extensions are made
|
||||
* by setting bit 31.
|
||||
*/
|
||||
};
|
||||
|
||||
/* Name Data type Units
|
||||
* ---- --------- -----
|
||||
*
|
||||
* IEEE80211_RADIOTAP_TSFT __le64 microseconds
|
||||
*
|
||||
* Value in microseconds of the MAC's 64-bit 802.11 Time
|
||||
* Synchronization Function timer when the first bit of the
|
||||
* MPDU arrived at the MAC. For received frames, only.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_CHANNEL 2 x uint16_t MHz, bitmap
|
||||
*
|
||||
* Tx/Rx frequency in MHz, followed by flags (see below).
|
||||
*
|
||||
* IEEE80211_RADIOTAP_FHSS uint16_t see below
|
||||
*
|
||||
* For frequency-hopping radios, the hop set (first byte)
|
||||
* and pattern (second byte).
|
||||
*
|
||||
* IEEE80211_RADIOTAP_RATE u8 500kb/s
|
||||
*
|
||||
* Tx/Rx data rate
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from
|
||||
* one milliwatt (dBm)
|
||||
*
|
||||
* RF signal power at the antenna, decibel difference from
|
||||
* one milliwatt.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from
|
||||
* one milliwatt (dBm)
|
||||
*
|
||||
* RF noise power at the antenna, decibel difference from one
|
||||
* milliwatt.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB)
|
||||
*
|
||||
* RF signal power at the antenna, decibel difference from an
|
||||
* arbitrary, fixed reference.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB)
|
||||
*
|
||||
* RF noise power at the antenna, decibel difference from an
|
||||
* arbitrary, fixed reference point.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_LOCK_QUALITY uint16_t unitless
|
||||
*
|
||||
* Quality of Barker code lock. Unitless. Monotonically
|
||||
* nondecreasing with "better" lock strength. Called "Signal
|
||||
* Quality" in datasheets. (Is there a standard way to measure
|
||||
* this?)
|
||||
*
|
||||
* IEEE80211_RADIOTAP_TX_ATTENUATION uint16_t unitless
|
||||
*
|
||||
* Transmit power expressed as unitless distance from max
|
||||
* power set at factory calibration. 0 is max power.
|
||||
* Monotonically nondecreasing with lower power levels.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t decibels (dB)
|
||||
*
|
||||
* Transmit power expressed as decibel distance from max power
|
||||
* set at factory calibration. 0 is max power. Monotonically
|
||||
* nondecreasing with lower power levels.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from
|
||||
* one milliwatt (dBm)
|
||||
*
|
||||
* Transmit power expressed as dBm (decibels from a 1 milliwatt
|
||||
* reference). This is the absolute power level measured at
|
||||
* the antenna port.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_FLAGS u8 bitmap
|
||||
*
|
||||
* Properties of transmitted and received frames. See flags
|
||||
* defined below.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_ANTENNA u8 antenna index
|
||||
*
|
||||
* Unitless indication of the Rx/Tx antenna for this packet.
|
||||
* The first antenna is antenna 0.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_RX_FLAGS uint16_t bitmap
|
||||
*
|
||||
* Properties of received frames. See flags defined below.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_TX_FLAGS uint16_t bitmap
|
||||
*
|
||||
* Properties of transmitted frames. See flags defined below.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_RTS_RETRIES u8 data
|
||||
*
|
||||
* Number of rts retries a transmitted frame used.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DATA_RETRIES u8 data
|
||||
*
|
||||
* Number of unicast retries a transmitted frame used.
|
||||
*
|
||||
*/
|
||||
enum ieee80211_radiotap_type {
|
||||
IEEE80211_RADIOTAP_TSFT = 0,
|
||||
IEEE80211_RADIOTAP_FLAGS = 1,
|
||||
IEEE80211_RADIOTAP_RATE = 2,
|
||||
IEEE80211_RADIOTAP_CHANNEL = 3,
|
||||
IEEE80211_RADIOTAP_FHSS = 4,
|
||||
IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
|
||||
IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
|
||||
IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
|
||||
IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
|
||||
IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
|
||||
IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
|
||||
IEEE80211_RADIOTAP_ANTENNA = 11,
|
||||
IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
|
||||
IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
|
||||
IEEE80211_RADIOTAP_RX_FLAGS = 14,
|
||||
IEEE80211_RADIOTAP_TX_FLAGS = 15,
|
||||
IEEE80211_RADIOTAP_RTS_RETRIES = 16,
|
||||
IEEE80211_RADIOTAP_DATA_RETRIES = 17,
|
||||
IEEE80211_RADIOTAP_EXT = 31
|
||||
};
|
||||
|
||||
/* Channel flags. */
|
||||
#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */
|
||||
#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */
|
||||
#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */
|
||||
#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
|
||||
#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
|
||||
#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
|
||||
#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */
|
||||
#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */
|
||||
|
||||
/* For IEEE80211_RADIOTAP_FLAGS */
|
||||
#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
|
||||
* during CFP
|
||||
*/
|
||||
#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
|
||||
* with short
|
||||
* preamble
|
||||
*/
|
||||
#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
|
||||
* with WEP encryption
|
||||
*/
|
||||
#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
|
||||
* with fragmentation
|
||||
*/
|
||||
#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */
|
||||
#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between
|
||||
* 802.11 header and payload
|
||||
* (to 32-bit boundary)
|
||||
*/
|
||||
/* For IEEE80211_RADIOTAP_RX_FLAGS */
|
||||
#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */
|
||||
|
||||
/* For IEEE80211_RADIOTAP_TX_FLAGS */
|
||||
#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive
|
||||
* retries */
|
||||
#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */
|
||||
#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */
|
||||
|
||||
#endif /* IEEE80211_RADIOTAP_H */
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* hostapd / Station table
|
||||
* Copyright (c) 2002-2008, 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 STA_INFO_H
|
||||
#define STA_INFO_H
|
||||
|
||||
int ap_for_each_sta(struct hostapd_data *hapd,
|
||||
int (*cb)(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
void *ctx),
|
||||
void *ctx);
|
||||
struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta);
|
||||
void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void hostapd_free_stas(struct hostapd_data *hapd);
|
||||
void ap_handle_timer(void *eloop_ctx, void *timeout_ctx);
|
||||
void ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
u32 session_timeout);
|
||||
void ap_sta_no_session_timeout(struct hostapd_data *hapd,
|
||||
struct sta_info *sta);
|
||||
struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr);
|
||||
void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
u16 reason);
|
||||
void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
u16 reason);
|
||||
int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
int old_vlanid);
|
||||
void ap_sta_start_sa_query(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void ap_sta_stop_sa_query(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
|
||||
#endif /* STA_INFO_H */
|
@ -1,135 +0,0 @@
|
||||
/*
|
||||
* hostapd / WMM (Wi-Fi Multimedia)
|
||||
* Copyright 2002-2003, 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 WME_H
|
||||
#define WME_H
|
||||
|
||||
/*
|
||||
* WMM Information Element (used in (Re)Association Request frames; may also be
|
||||
* used in Beacon frames)
|
||||
*/
|
||||
struct wmm_information_element {
|
||||
/* Element ID: 221 (0xdd); Length: 7 */
|
||||
/* required fields for WMM version 1 */
|
||||
u8 oui[3]; /* 00:50:f2 */
|
||||
u8 oui_type; /* 2 */
|
||||
u8 oui_subtype; /* 0 */
|
||||
u8 version; /* 1 for WMM version 1.0 */
|
||||
u8 qos_info; /* AP/STA specific QoS info */
|
||||
};
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
|
||||
#include <sys/types.h>
|
||||
#include <sys/endian.h>
|
||||
#endif /* defined(__FreeBSD__) || defined(__NetBSD__) ||
|
||||
* defined(__DragonFly__) */
|
||||
|
||||
|
||||
static inline u16 tsinfo(int tag1d, int contention_based, int direction)
|
||||
{
|
||||
return (tag1d << 11) | (contention_based << 7) | (direction << 5) |
|
||||
(tag1d << 1);
|
||||
}
|
||||
|
||||
|
||||
struct wme_information_element {
|
||||
/* required fields for WME version 1 */
|
||||
u8 oui[3];
|
||||
u8 oui_type;
|
||||
u8 oui_subtype;
|
||||
u8 version;
|
||||
u8 acInfo;
|
||||
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define WMM_AC_AIFSN_MASK 0x0f
|
||||
#define WMM_AC_AIFNS_SHIFT 0
|
||||
#define WMM_AC_ACM 0x10
|
||||
#define WMM_AC_ACI_MASK 0x60
|
||||
#define WMM_AC_ACI_SHIFT 5
|
||||
|
||||
#define WMM_AC_ECWMIN_MASK 0x0f
|
||||
#define WMM_AC_ECWMIN_SHIFT 0
|
||||
#define WMM_AC_ECWMAX_MASK 0xf0
|
||||
#define WMM_AC_ECWMAX_SHIFT 4
|
||||
|
||||
struct wmm_ac_parameter {
|
||||
u8 aci_aifsn; /* AIFSN, ACM, ACI */
|
||||
u8 cw; /* ECWmin, ECWmax (CW = 2^ECW - 1) */
|
||||
le16 txop_limit;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* WMM Parameter Element (used in Beacon, Probe Response, and (Re)Association
|
||||
* Response frmaes)
|
||||
*/
|
||||
struct wmm_parameter_element {
|
||||
/* Element ID: 221 (0xdd); Length: 24 */
|
||||
/* required fields for WMM version 1 */
|
||||
u8 oui[3]; /* 00:50:f2 */
|
||||
u8 oui_type; /* 2 */
|
||||
u8 oui_subtype; /* 1 */
|
||||
u8 version; /* 1 for WMM version 1.0 */
|
||||
u8 qos_info; /* AP/STA specif QoS info */
|
||||
u8 reserved; /* 0 */
|
||||
struct wmm_ac_parameter ac[4]; /* AC_BE, AC_BK, AC_VI, AC_VO */
|
||||
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* WMM TSPEC Element */
|
||||
struct wmm_tspec_element {
|
||||
u8 eid; /* 221 = 0xdd */
|
||||
u8 length; /* 6 + 55 = 61 */
|
||||
u8 oui[3]; /* 00:50:f2 */
|
||||
u8 oui_type; /* 2 */
|
||||
u8 oui_subtype; /* 2 */
|
||||
u8 version; /* 1 */
|
||||
/* WMM TSPEC body (55 octets): */
|
||||
u8 ts_info[3];
|
||||
le16 nominal_msdu_size;
|
||||
le16 maximum_msdu_size;
|
||||
le32 minimum_service_interval;
|
||||
le32 maximum_service_interval;
|
||||
le32 inactivity_interval;
|
||||
le32 suspension_interval;
|
||||
le32 service_start_time;
|
||||
le32 minimum_data_rate;
|
||||
le32 mean_data_rate;
|
||||
le32 peak_data_rate;
|
||||
le32 maximum_burst_size;
|
||||
le32 delay_bound;
|
||||
le32 minimum_phy_rate;
|
||||
le16 surplus_bandwidth_allowance;
|
||||
le16 medium_time;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* Access Categories / ACI to AC coding */
|
||||
enum {
|
||||
WMM_AC_BE = 0 /* Best Effort */,
|
||||
WMM_AC_BK = 1 /* Background */,
|
||||
WMM_AC_VI = 2 /* Video */,
|
||||
WMM_AC_VO = 3 /* Voice */
|
||||
};
|
||||
|
||||
struct ieee80211_mgmt;
|
||||
|
||||
u8 * hostapd_eid_wmm(struct hostapd_data *hapd, u8 *eid);
|
||||
int hostapd_eid_wmm_valid(struct hostapd_data *hapd, u8 *eid, size_t len);
|
||||
int hostapd_wmm_sta_config(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void hostapd_wmm_action(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
|
||||
size_t len);
|
||||
|
||||
#endif /* WME_H */
|
429
contrib/wpa/patches/openssl-0.9.8-tls-extensions.patch
Normal file
429
contrib/wpa/patches/openssl-0.9.8-tls-extensions.patch
Normal file
@ -0,0 +1,429 @@
|
||||
This patch is adding support for TLS hello extensions and externally
|
||||
generated pre-shared key material to OpenSSL 0.9.8. This is
|
||||
based on the patch from Alexey Kobozev <akobozev@cisco.com>
|
||||
(sent to openssl-dev mailing list on Tue, 07 Jun 2005 15:40:58 +0300).
|
||||
|
||||
|
||||
|
||||
diff -uprN openssl-0.9.8.orig/include/openssl/ssl.h openssl-0.9.8/include/openssl/ssl.h
|
||||
--- openssl-0.9.8.orig/include/openssl/ssl.h 2005-06-10 12:51:16.000000000 -0700
|
||||
+++ openssl-0.9.8/include/openssl/ssl.h 2005-07-19 20:02:15.000000000 -0700
|
||||
@@ -340,6 +340,7 @@ extern "C" {
|
||||
* 'struct ssl_st *' function parameters used to prototype callbacks
|
||||
* in SSL_CTX. */
|
||||
typedef struct ssl_st *ssl_crock_st;
|
||||
+typedef struct tls_extension_st TLS_EXTENSION;
|
||||
|
||||
/* used to hold info on the particular ciphers used */
|
||||
typedef struct ssl_cipher_st
|
||||
@@ -361,6 +362,8 @@ DECLARE_STACK_OF(SSL_CIPHER)
|
||||
typedef struct ssl_st SSL;
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
|
||||
+typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
|
||||
+
|
||||
/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
|
||||
typedef struct ssl_method_st
|
||||
{
|
||||
@@ -968,6 +971,15 @@ struct ssl_st
|
||||
int first_packet;
|
||||
int client_version; /* what was passed, used for
|
||||
* SSLv3/TLS rollback check */
|
||||
+
|
||||
+ /* TLS externsions */
|
||||
+ TLS_EXTENSION *tls_extension;
|
||||
+ int (*tls_extension_cb)(SSL *s, TLS_EXTENSION *tls_ext, void *arg);
|
||||
+ void *tls_extension_cb_arg;
|
||||
+
|
||||
+ /* TLS pre-shared secret session resumption */
|
||||
+ tls_session_secret_cb_fn tls_session_secret_cb;
|
||||
+ void *tls_session_secret_cb_arg;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -1533,6 +1545,13 @@ void *SSL_COMP_get_compression_methods(v
|
||||
int SSL_COMP_add_compression_method(int id,void *cm);
|
||||
#endif
|
||||
|
||||
+/* TLS extensions functions */
|
||||
+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len);
|
||||
+int SSL_set_hello_extension_cb(SSL *s, int (*cb)(SSL *, TLS_EXTENSION *, void *), void *arg);
|
||||
+
|
||||
+/* Pre-shared secret session resumption functions */
|
||||
+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
|
||||
+
|
||||
/* BEGIN ERROR CODES */
|
||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||
* made after this point may be overwritten when the script is next run.
|
||||
@@ -1714,6 +1733,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_TLS1_ENC 210
|
||||
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211
|
||||
#define SSL_F_WRITE_PENDING 212
|
||||
+#define SSL_F_SSL_SET_HELLO_EXTENSION 213
|
||||
|
||||
/* Reason codes. */
|
||||
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
|
||||
diff -uprN openssl-0.9.8.orig/include/openssl/tls1.h openssl-0.9.8/include/openssl/tls1.h
|
||||
--- openssl-0.9.8.orig/include/openssl/tls1.h 2003-07-22 05:34:21.000000000 -0700
|
||||
+++ openssl-0.9.8/include/openssl/tls1.h 2005-07-19 20:02:15.000000000 -0700
|
||||
@@ -282,6 +282,14 @@ extern "C" {
|
||||
#define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/
|
||||
#endif
|
||||
|
||||
+/* TLS extension struct */
|
||||
+struct tls_extension_st
|
||||
+{
|
||||
+ unsigned short type;
|
||||
+ unsigned short length;
|
||||
+ void *data;
|
||||
+};
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff -uprN openssl-0.9.8.orig/ssl/Makefile openssl-0.9.8/ssl/Makefile
|
||||
--- openssl-0.9.8.orig/ssl/Makefile 2005-05-30 16:20:30.000000000 -0700
|
||||
+++ openssl-0.9.8/ssl/Makefile 2005-07-19 20:02:15.000000000 -0700
|
||||
@@ -24,7 +24,7 @@ LIBSRC= \
|
||||
s2_meth.c s2_srvr.c s2_clnt.c s2_lib.c s2_enc.c s2_pkt.c \
|
||||
s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c \
|
||||
s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c s23_pkt.c \
|
||||
- t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c \
|
||||
+ t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c t1_ext.c \
|
||||
d1_meth.c d1_srvr.c d1_clnt.c d1_lib.c d1_pkt.c \
|
||||
d1_both.c d1_enc.c \
|
||||
ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
|
||||
@@ -35,7 +35,7 @@ LIBOBJ= \
|
||||
s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \
|
||||
s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \
|
||||
s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o s23_pkt.o \
|
||||
- t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o \
|
||||
+ t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o t1_ext.o \
|
||||
d1_meth.o d1_srvr.o d1_clnt.o d1_lib.o d1_pkt.o \
|
||||
d1_both.o d1_enc.o \
|
||||
ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
|
||||
@@ -968,3 +968,4 @@ t1_srvr.o: ../include/openssl/ssl23.h ..
|
||||
t1_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
|
||||
t1_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
|
||||
t1_srvr.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_srvr.c
|
||||
+t1_ext.o: t1_ext.c ssl_locl.h
|
||||
diff -uprN openssl-0.9.8.orig/ssl/s3_clnt.c openssl-0.9.8/ssl/s3_clnt.c
|
||||
--- openssl-0.9.8.orig/ssl/s3_clnt.c 2005-05-16 03:11:03.000000000 -0700
|
||||
+++ openssl-0.9.8/ssl/s3_clnt.c 2005-07-19 20:02:15.000000000 -0700
|
||||
@@ -606,6 +606,20 @@ int ssl3_client_hello(SSL *s)
|
||||
}
|
||||
*(p++)=0; /* Add the NULL method */
|
||||
|
||||
+ /* send client hello extensions if any */
|
||||
+ if (s->version >= TLS1_VERSION && s->tls_extension)
|
||||
+ {
|
||||
+ // set the total extensions length
|
||||
+ s2n(s->tls_extension->length + 4, p);
|
||||
+
|
||||
+ // put the extensions with type and length
|
||||
+ s2n(s->tls_extension->type, p);
|
||||
+ s2n(s->tls_extension->length, p);
|
||||
+
|
||||
+ memcpy(p, s->tls_extension->data, s->tls_extension->length);
|
||||
+ p+=s->tls_extension->length;
|
||||
+ }
|
||||
+
|
||||
l=(p-d);
|
||||
d=buf;
|
||||
*(d++)=SSL3_MT_CLIENT_HELLO;
|
||||
@@ -628,7 +642,7 @@ int ssl3_get_server_hello(SSL *s)
|
||||
STACK_OF(SSL_CIPHER) *sk;
|
||||
SSL_CIPHER *c;
|
||||
unsigned char *p,*d;
|
||||
- int i,al,ok;
|
||||
+ int i,al,ok,pre_shared;
|
||||
unsigned int j;
|
||||
long n;
|
||||
SSL_COMP *comp;
|
||||
@@ -693,7 +707,24 @@ int ssl3_get_server_hello(SSL *s)
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
- if (j != 0 && j == s->session->session_id_length
|
||||
+ /* check if we want to resume the session based on external pre-shared secret */
|
||||
+ pre_shared = 0;
|
||||
+ if (s->version >= TLS1_VERSION && s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ SSL_CIPHER *pref_cipher=NULL;
|
||||
+ s->session->master_key_length=sizeof(s->session->master_key);
|
||||
+ if (s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
|
||||
+ NULL, &pref_cipher, s->tls_session_secret_cb_arg))
|
||||
+ {
|
||||
+ s->hit=1;
|
||||
+ s->session->cipher=pref_cipher ? pref_cipher : ssl_get_cipher_by_char(s,p+j);
|
||||
+ s->session->session_id_length = j;
|
||||
+ memcpy(s->session->session_id, p, j);
|
||||
+ pre_shared = 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ((pre_shared || j != 0) && j == s->session->session_id_length
|
||||
&& memcmp(p,s->session->session_id,j) == 0)
|
||||
{
|
||||
if(s->sid_ctx_length != s->session->sid_ctx_length
|
||||
diff -uprN openssl-0.9.8.orig/ssl/s3_srvr.c openssl-0.9.8/ssl/s3_srvr.c
|
||||
--- openssl-0.9.8.orig/ssl/s3_srvr.c 2005-05-22 17:32:55.000000000 -0700
|
||||
+++ openssl-0.9.8/ssl/s3_srvr.c 2005-07-19 20:02:15.000000000 -0700
|
||||
@@ -955,6 +955,75 @@ int ssl3_get_client_hello(SSL *s)
|
||||
}
|
||||
#endif
|
||||
|
||||
+ /* Check for TLS client hello extension here */
|
||||
+ if (p < (d+n) && s->version >= TLS1_VERSION)
|
||||
+ {
|
||||
+ if (s->tls_extension_cb)
|
||||
+ {
|
||||
+ TLS_EXTENSION tls_ext;
|
||||
+ unsigned short ext_total_len;
|
||||
+
|
||||
+ n2s(p, ext_total_len);
|
||||
+ n2s(p, tls_ext.type);
|
||||
+ n2s(p, tls_ext.length);
|
||||
+
|
||||
+ // sanity check in TLS extension len
|
||||
+ if (tls_ext.length > (d+n) - p)
|
||||
+ {
|
||||
+ // just cut the lenth to packet border
|
||||
+ tls_ext.length = (d+n) - p;
|
||||
+ }
|
||||
+
|
||||
+ tls_ext.data = p;
|
||||
+
|
||||
+ // returns an alert code or 0
|
||||
+ al = s->tls_extension_cb(s, &tls_ext, s->tls_extension_cb_arg);
|
||||
+ if (al != 0)
|
||||
+ {
|
||||
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PEER_ERROR);
|
||||
+ goto f_err;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Check if we want to use external pre-shared secret for this handshake */
|
||||
+ /* for not reused session only */
|
||||
+ if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ SSL_CIPHER *pref_cipher=NULL;
|
||||
+
|
||||
+ s->session->master_key_length=sizeof(s->session->master_key);
|
||||
+ if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
|
||||
+ ciphers, &pref_cipher, s->tls_session_secret_cb_arg))
|
||||
+ {
|
||||
+ s->hit=1;
|
||||
+ s->session->ciphers=ciphers;
|
||||
+ s->session->verify_result=X509_V_OK;
|
||||
+
|
||||
+ ciphers=NULL;
|
||||
+
|
||||
+ /* check if some cipher was preferred by call back */
|
||||
+ pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
|
||||
+ if (pref_cipher == NULL)
|
||||
+ {
|
||||
+ al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
|
||||
+ goto f_err;
|
||||
+ }
|
||||
+
|
||||
+ s->session->cipher=pref_cipher;
|
||||
+
|
||||
+ if (s->cipher_list)
|
||||
+ sk_SSL_CIPHER_free(s->cipher_list);
|
||||
+
|
||||
+ if (s->cipher_list_by_id)
|
||||
+ sk_SSL_CIPHER_free(s->cipher_list_by_id);
|
||||
+
|
||||
+ s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
+ s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Given s->session->ciphers and SSL_get_ciphers, we must
|
||||
* pick a cipher */
|
||||
|
||||
diff -uprN openssl-0.9.8.orig/ssl/ssl_err.c openssl-0.9.8/ssl/ssl_err.c
|
||||
--- openssl-0.9.8.orig/ssl/ssl_err.c 2005-06-10 12:51:16.000000000 -0700
|
||||
+++ openssl-0.9.8/ssl/ssl_err.c 2005-07-19 20:02:15.000000000 -0700
|
||||
@@ -242,6 +242,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"},
|
||||
{ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"},
|
||||
{ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"},
|
||||
+{ERR_FUNC(SSL_F_SSL_SET_HELLO_EXTENSION), "SSL_set_hello_extension"},
|
||||
{0,NULL}
|
||||
};
|
||||
|
||||
diff -uprN openssl-0.9.8.orig/ssl/ssl.h openssl-0.9.8/ssl/ssl.h
|
||||
--- openssl-0.9.8.orig/ssl/ssl.h 2005-06-10 12:51:16.000000000 -0700
|
||||
+++ openssl-0.9.8/ssl/ssl.h 2005-07-19 20:02:15.000000000 -0700
|
||||
@@ -340,6 +340,7 @@ extern "C" {
|
||||
* 'struct ssl_st *' function parameters used to prototype callbacks
|
||||
* in SSL_CTX. */
|
||||
typedef struct ssl_st *ssl_crock_st;
|
||||
+typedef struct tls_extension_st TLS_EXTENSION;
|
||||
|
||||
/* used to hold info on the particular ciphers used */
|
||||
typedef struct ssl_cipher_st
|
||||
@@ -361,6 +362,8 @@ DECLARE_STACK_OF(SSL_CIPHER)
|
||||
typedef struct ssl_st SSL;
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
|
||||
+typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
|
||||
+
|
||||
/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
|
||||
typedef struct ssl_method_st
|
||||
{
|
||||
@@ -968,6 +971,15 @@ struct ssl_st
|
||||
int first_packet;
|
||||
int client_version; /* what was passed, used for
|
||||
* SSLv3/TLS rollback check */
|
||||
+
|
||||
+ /* TLS externsions */
|
||||
+ TLS_EXTENSION *tls_extension;
|
||||
+ int (*tls_extension_cb)(SSL *s, TLS_EXTENSION *tls_ext, void *arg);
|
||||
+ void *tls_extension_cb_arg;
|
||||
+
|
||||
+ /* TLS pre-shared secret session resumption */
|
||||
+ tls_session_secret_cb_fn tls_session_secret_cb;
|
||||
+ void *tls_session_secret_cb_arg;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -1533,6 +1545,13 @@ void *SSL_COMP_get_compression_methods(v
|
||||
int SSL_COMP_add_compression_method(int id,void *cm);
|
||||
#endif
|
||||
|
||||
+/* TLS extensions functions */
|
||||
+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len);
|
||||
+int SSL_set_hello_extension_cb(SSL *s, int (*cb)(SSL *, TLS_EXTENSION *, void *), void *arg);
|
||||
+
|
||||
+/* Pre-shared secret session resumption functions */
|
||||
+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
|
||||
+
|
||||
/* BEGIN ERROR CODES */
|
||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||
* made after this point may be overwritten when the script is next run.
|
||||
@@ -1714,6 +1733,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_TLS1_ENC 210
|
||||
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211
|
||||
#define SSL_F_WRITE_PENDING 212
|
||||
+#define SSL_F_SSL_SET_HELLO_EXTENSION 213
|
||||
|
||||
/* Reason codes. */
|
||||
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
|
||||
diff -uprN openssl-0.9.8.orig/ssl/ssl_sess.c openssl-0.9.8/ssl/ssl_sess.c
|
||||
--- openssl-0.9.8.orig/ssl/ssl_sess.c 2005-04-29 13:10:06.000000000 -0700
|
||||
+++ openssl-0.9.8/ssl/ssl_sess.c 2005-07-19 20:02:15.000000000 -0700
|
||||
@@ -656,6 +656,15 @@ long SSL_CTX_get_timeout(const SSL_CTX *
|
||||
return(s->session_timeout);
|
||||
}
|
||||
|
||||
+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len,
|
||||
+ STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg)
|
||||
+{
|
||||
+ if (s == NULL) return(0);
|
||||
+ s->tls_session_secret_cb = tls_session_secret_cb;
|
||||
+ s->tls_session_secret_cb_arg = arg;
|
||||
+ return(1);
|
||||
+}
|
||||
+
|
||||
typedef struct timeout_param_st
|
||||
{
|
||||
SSL_CTX *ctx;
|
||||
diff -uprN openssl-0.9.8.orig/ssl/t1_ext.c openssl-0.9.8/ssl/t1_ext.c
|
||||
--- openssl-0.9.8.orig/ssl/t1_ext.c 1969-12-31 16:00:00.000000000 -0800
|
||||
+++ openssl-0.9.8/ssl/t1_ext.c 2005-07-19 20:03:29.000000000 -0700
|
||||
@@ -0,0 +1,48 @@
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include "ssl_locl.h"
|
||||
+
|
||||
+
|
||||
+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len)
|
||||
+{
|
||||
+ if(s->version >= TLS1_VERSION)
|
||||
+ {
|
||||
+ if(s->tls_extension)
|
||||
+ {
|
||||
+ OPENSSL_free(s->tls_extension);
|
||||
+ s->tls_extension = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if(ext_data)
|
||||
+ {
|
||||
+ s->tls_extension = OPENSSL_malloc(sizeof(TLS_EXTENSION) + ext_len);
|
||||
+ if(!s->tls_extension)
|
||||
+ {
|
||||
+ SSLerr(SSL_F_SSL_SET_HELLO_EXTENSION, ERR_R_MALLOC_FAILURE);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ s->tls_extension->type = ext_type;
|
||||
+ s->tls_extension->length = ext_len;
|
||||
+ s->tls_extension->data = s->tls_extension + 1;
|
||||
+ memcpy(s->tls_extension->data, ext_data, ext_len);
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int SSL_set_hello_extension_cb(SSL *s, int (*cb)(SSL *, TLS_EXTENSION *, void *), void *arg)
|
||||
+{
|
||||
+ if(s->version >= TLS1_VERSION)
|
||||
+ {
|
||||
+ s->tls_extension_cb = cb;
|
||||
+ s->tls_extension_cb_arg = arg;
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff -uprN openssl-0.9.8.orig/ssl/t1_lib.c openssl-0.9.8/ssl/t1_lib.c
|
||||
--- openssl-0.9.8.orig/ssl/t1_lib.c 2005-04-26 09:02:40.000000000 -0700
|
||||
+++ openssl-0.9.8/ssl/t1_lib.c 2005-07-19 20:02:15.000000000 -0700
|
||||
@@ -131,6 +131,10 @@ int tls1_new(SSL *s)
|
||||
|
||||
void tls1_free(SSL *s)
|
||||
{
|
||||
+ if(s->tls_extension)
|
||||
+ {
|
||||
+ OPENSSL_free(s->tls_extension);
|
||||
+ }
|
||||
ssl3_free(s);
|
||||
}
|
||||
|
||||
diff -uprN openssl-0.9.8.orig/ssl/tls1.h openssl-0.9.8/ssl/tls1.h
|
||||
--- openssl-0.9.8.orig/ssl/tls1.h 2003-07-22 05:34:21.000000000 -0700
|
||||
+++ openssl-0.9.8/ssl/tls1.h 2005-07-19 20:02:15.000000000 -0700
|
||||
@@ -282,6 +282,14 @@ extern "C" {
|
||||
#define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/
|
||||
#endif
|
||||
|
||||
+/* TLS extension struct */
|
||||
+struct tls_extension_st
|
||||
+{
|
||||
+ unsigned short type;
|
||||
+ unsigned short length;
|
||||
+ void *data;
|
||||
+};
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff -uprN openssl-0.9.8.orig/util/ssleay.num openssl-0.9.8/util/ssleay.num
|
||||
--- openssl-0.9.8.orig/util/ssleay.num 2005-05-08 17:22:02.000000000 -0700
|
||||
+++ openssl-0.9.8/util/ssleay.num 2005-07-19 20:02:15.000000000 -0700
|
||||
@@ -226,3 +226,6 @@ DTLSv1_server_method
|
||||
SSL_COMP_get_compression_methods 276 EXIST:!VMS:FUNCTION:COMP
|
||||
SSL_COMP_get_compress_methods 276 EXIST:VMS:FUNCTION:COMP
|
||||
SSL_SESSION_get_id 277 EXIST::FUNCTION:
|
||||
+SSL_set_hello_extension 278 EXIST::FUNCTION:
|
||||
+SSL_set_hello_extension_cb 279 EXIST::FUNCTION:
|
||||
+SSL_set_session_secret_cb 280 EXIST::FUNCTION:
|
429
contrib/wpa/patches/openssl-0.9.8d-tls-extensions.patch
Normal file
429
contrib/wpa/patches/openssl-0.9.8d-tls-extensions.patch
Normal file
@ -0,0 +1,429 @@
|
||||
This patch is adding support for TLS hello extensions and externally
|
||||
generated pre-shared key material to OpenSSL 0.9.8d. This is
|
||||
based on the patch from Alexey Kobozev <akobozev@cisco.com>
|
||||
(sent to openssl-dev mailing list on Tue, 07 Jun 2005 15:40:58 +0300).
|
||||
|
||||
|
||||
|
||||
diff -uprN openssl-0.9.8d.orig/include/openssl/ssl.h openssl-0.9.8d/include/openssl/ssl.h
|
||||
--- openssl-0.9.8d.orig/include/openssl/ssl.h 2006-06-14 06:52:49.000000000 -0700
|
||||
+++ openssl-0.9.8d/include/openssl/ssl.h 2006-12-10 08:20:02.000000000 -0800
|
||||
@@ -345,6 +345,7 @@ extern "C" {
|
||||
* 'struct ssl_st *' function parameters used to prototype callbacks
|
||||
* in SSL_CTX. */
|
||||
typedef struct ssl_st *ssl_crock_st;
|
||||
+typedef struct tls_extension_st TLS_EXTENSION;
|
||||
|
||||
/* used to hold info on the particular ciphers used */
|
||||
typedef struct ssl_cipher_st
|
||||
@@ -366,6 +367,8 @@ DECLARE_STACK_OF(SSL_CIPHER)
|
||||
typedef struct ssl_st SSL;
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
|
||||
+typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
|
||||
+
|
||||
/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
|
||||
typedef struct ssl_method_st
|
||||
{
|
||||
@@ -973,6 +976,15 @@ struct ssl_st
|
||||
int first_packet;
|
||||
int client_version; /* what was passed, used for
|
||||
* SSLv3/TLS rollback check */
|
||||
+
|
||||
+ /* TLS externsions */
|
||||
+ TLS_EXTENSION *tls_extension;
|
||||
+ int (*tls_extension_cb)(SSL *s, TLS_EXTENSION *tls_ext, void *arg);
|
||||
+ void *tls_extension_cb_arg;
|
||||
+
|
||||
+ /* TLS pre-shared secret session resumption */
|
||||
+ tls_session_secret_cb_fn tls_session_secret_cb;
|
||||
+ void *tls_session_secret_cb_arg;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -1538,6 +1550,13 @@ void *SSL_COMP_get_compression_methods(v
|
||||
int SSL_COMP_add_compression_method(int id,void *cm);
|
||||
#endif
|
||||
|
||||
+/* TLS extensions functions */
|
||||
+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len);
|
||||
+int SSL_set_hello_extension_cb(SSL *s, int (*cb)(SSL *, TLS_EXTENSION *, void *), void *arg);
|
||||
+
|
||||
+/* Pre-shared secret session resumption functions */
|
||||
+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
|
||||
+
|
||||
/* BEGIN ERROR CODES */
|
||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||
* made after this point may be overwritten when the script is next run.
|
||||
@@ -1719,6 +1738,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_TLS1_ENC 210
|
||||
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211
|
||||
#define SSL_F_WRITE_PENDING 212
|
||||
+#define SSL_F_SSL_SET_HELLO_EXTENSION 213
|
||||
|
||||
/* Reason codes. */
|
||||
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
|
||||
diff -uprN openssl-0.9.8d.orig/include/openssl/tls1.h openssl-0.9.8d/include/openssl/tls1.h
|
||||
--- openssl-0.9.8d.orig/include/openssl/tls1.h 2006-06-14 10:52:01.000000000 -0700
|
||||
+++ openssl-0.9.8d/include/openssl/tls1.h 2006-12-10 08:20:02.000000000 -0800
|
||||
@@ -296,6 +296,14 @@ extern "C" {
|
||||
#define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/
|
||||
#endif
|
||||
|
||||
+/* TLS extension struct */
|
||||
+struct tls_extension_st
|
||||
+{
|
||||
+ unsigned short type;
|
||||
+ unsigned short length;
|
||||
+ void *data;
|
||||
+};
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff -uprN openssl-0.9.8d.orig/ssl/Makefile openssl-0.9.8d/ssl/Makefile
|
||||
--- openssl-0.9.8d.orig/ssl/Makefile 2006-02-03 17:49:35.000000000 -0800
|
||||
+++ openssl-0.9.8d/ssl/Makefile 2006-12-10 08:20:02.000000000 -0800
|
||||
@@ -24,7 +24,7 @@ LIBSRC= \
|
||||
s2_meth.c s2_srvr.c s2_clnt.c s2_lib.c s2_enc.c s2_pkt.c \
|
||||
s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c \
|
||||
s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c s23_pkt.c \
|
||||
- t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c \
|
||||
+ t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c t1_ext.c \
|
||||
d1_meth.c d1_srvr.c d1_clnt.c d1_lib.c d1_pkt.c \
|
||||
d1_both.c d1_enc.c \
|
||||
ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
|
||||
@@ -35,7 +35,7 @@ LIBOBJ= \
|
||||
s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \
|
||||
s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \
|
||||
s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o s23_pkt.o \
|
||||
- t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o \
|
||||
+ t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o t1_ext.o \
|
||||
d1_meth.o d1_srvr.o d1_clnt.o d1_lib.o d1_pkt.o \
|
||||
d1_both.o d1_enc.o \
|
||||
ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
|
||||
@@ -968,3 +968,4 @@ t1_srvr.o: ../include/openssl/ssl23.h ..
|
||||
t1_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
|
||||
t1_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
|
||||
t1_srvr.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_srvr.c
|
||||
+t1_ext.o: t1_ext.c ssl_locl.h
|
||||
diff -uprN openssl-0.9.8d.orig/ssl/s3_clnt.c openssl-0.9.8d/ssl/s3_clnt.c
|
||||
--- openssl-0.9.8d.orig/ssl/s3_clnt.c 2005-12-12 23:41:46.000000000 -0800
|
||||
+++ openssl-0.9.8d/ssl/s3_clnt.c 2006-12-10 08:20:02.000000000 -0800
|
||||
@@ -601,6 +601,20 @@ int ssl3_client_hello(SSL *s)
|
||||
#endif
|
||||
*(p++)=0; /* Add the NULL method */
|
||||
|
||||
+ /* send client hello extensions if any */
|
||||
+ if (s->version >= TLS1_VERSION && s->tls_extension)
|
||||
+ {
|
||||
+ // set the total extensions length
|
||||
+ s2n(s->tls_extension->length + 4, p);
|
||||
+
|
||||
+ // put the extensions with type and length
|
||||
+ s2n(s->tls_extension->type, p);
|
||||
+ s2n(s->tls_extension->length, p);
|
||||
+
|
||||
+ memcpy(p, s->tls_extension->data, s->tls_extension->length);
|
||||
+ p+=s->tls_extension->length;
|
||||
+ }
|
||||
+
|
||||
l=(p-d);
|
||||
d=buf;
|
||||
*(d++)=SSL3_MT_CLIENT_HELLO;
|
||||
@@ -623,7 +637,7 @@ int ssl3_get_server_hello(SSL *s)
|
||||
STACK_OF(SSL_CIPHER) *sk;
|
||||
SSL_CIPHER *c;
|
||||
unsigned char *p,*d;
|
||||
- int i,al,ok;
|
||||
+ int i,al,ok,pre_shared;
|
||||
unsigned int j;
|
||||
long n;
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
@@ -690,7 +704,24 @@ int ssl3_get_server_hello(SSL *s)
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
- if (j != 0 && j == s->session->session_id_length
|
||||
+ /* check if we want to resume the session based on external pre-shared secret */
|
||||
+ pre_shared = 0;
|
||||
+ if (s->version >= TLS1_VERSION && s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ SSL_CIPHER *pref_cipher=NULL;
|
||||
+ s->session->master_key_length=sizeof(s->session->master_key);
|
||||
+ if (s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
|
||||
+ NULL, &pref_cipher, s->tls_session_secret_cb_arg))
|
||||
+ {
|
||||
+ s->hit=1;
|
||||
+ s->session->cipher=pref_cipher ? pref_cipher : ssl_get_cipher_by_char(s,p+j);
|
||||
+ s->session->session_id_length = j;
|
||||
+ memcpy(s->session->session_id, p, j);
|
||||
+ pre_shared = 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ((pre_shared || j != 0) && j == s->session->session_id_length
|
||||
&& memcmp(p,s->session->session_id,j) == 0)
|
||||
{
|
||||
if(s->sid_ctx_length != s->session->sid_ctx_length
|
||||
diff -uprN openssl-0.9.8d.orig/ssl/s3_srvr.c openssl-0.9.8d/ssl/s3_srvr.c
|
||||
--- openssl-0.9.8d.orig/ssl/s3_srvr.c 2006-09-28 04:29:03.000000000 -0700
|
||||
+++ openssl-0.9.8d/ssl/s3_srvr.c 2006-12-10 08:20:02.000000000 -0800
|
||||
@@ -943,6 +943,75 @@ int ssl3_get_client_hello(SSL *s)
|
||||
}
|
||||
#endif
|
||||
|
||||
+ /* Check for TLS client hello extension here */
|
||||
+ if (p < (d+n) && s->version >= TLS1_VERSION)
|
||||
+ {
|
||||
+ if (s->tls_extension_cb)
|
||||
+ {
|
||||
+ TLS_EXTENSION tls_ext;
|
||||
+ unsigned short ext_total_len;
|
||||
+
|
||||
+ n2s(p, ext_total_len);
|
||||
+ n2s(p, tls_ext.type);
|
||||
+ n2s(p, tls_ext.length);
|
||||
+
|
||||
+ // sanity check in TLS extension len
|
||||
+ if (tls_ext.length > (d+n) - p)
|
||||
+ {
|
||||
+ // just cut the lenth to packet border
|
||||
+ tls_ext.length = (d+n) - p;
|
||||
+ }
|
||||
+
|
||||
+ tls_ext.data = p;
|
||||
+
|
||||
+ // returns an alert code or 0
|
||||
+ al = s->tls_extension_cb(s, &tls_ext, s->tls_extension_cb_arg);
|
||||
+ if (al != 0)
|
||||
+ {
|
||||
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PEER_ERROR);
|
||||
+ goto f_err;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Check if we want to use external pre-shared secret for this handshake */
|
||||
+ /* for not reused session only */
|
||||
+ if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ SSL_CIPHER *pref_cipher=NULL;
|
||||
+
|
||||
+ s->session->master_key_length=sizeof(s->session->master_key);
|
||||
+ if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
|
||||
+ ciphers, &pref_cipher, s->tls_session_secret_cb_arg))
|
||||
+ {
|
||||
+ s->hit=1;
|
||||
+ s->session->ciphers=ciphers;
|
||||
+ s->session->verify_result=X509_V_OK;
|
||||
+
|
||||
+ ciphers=NULL;
|
||||
+
|
||||
+ /* check if some cipher was preferred by call back */
|
||||
+ pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
|
||||
+ if (pref_cipher == NULL)
|
||||
+ {
|
||||
+ al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
|
||||
+ goto f_err;
|
||||
+ }
|
||||
+
|
||||
+ s->session->cipher=pref_cipher;
|
||||
+
|
||||
+ if (s->cipher_list)
|
||||
+ sk_SSL_CIPHER_free(s->cipher_list);
|
||||
+
|
||||
+ if (s->cipher_list_by_id)
|
||||
+ sk_SSL_CIPHER_free(s->cipher_list_by_id);
|
||||
+
|
||||
+ s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
+ s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Given s->session->ciphers and SSL_get_ciphers, we must
|
||||
* pick a cipher */
|
||||
|
||||
diff -uprN openssl-0.9.8d.orig/ssl/ssl.h openssl-0.9.8d/ssl/ssl.h
|
||||
--- openssl-0.9.8d.orig/ssl/ssl.h 2006-06-14 06:52:49.000000000 -0700
|
||||
+++ openssl-0.9.8d/ssl/ssl.h 2006-12-10 08:20:02.000000000 -0800
|
||||
@@ -345,6 +345,7 @@ extern "C" {
|
||||
* 'struct ssl_st *' function parameters used to prototype callbacks
|
||||
* in SSL_CTX. */
|
||||
typedef struct ssl_st *ssl_crock_st;
|
||||
+typedef struct tls_extension_st TLS_EXTENSION;
|
||||
|
||||
/* used to hold info on the particular ciphers used */
|
||||
typedef struct ssl_cipher_st
|
||||
@@ -366,6 +367,8 @@ DECLARE_STACK_OF(SSL_CIPHER)
|
||||
typedef struct ssl_st SSL;
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
|
||||
+typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
|
||||
+
|
||||
/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
|
||||
typedef struct ssl_method_st
|
||||
{
|
||||
@@ -973,6 +976,15 @@ struct ssl_st
|
||||
int first_packet;
|
||||
int client_version; /* what was passed, used for
|
||||
* SSLv3/TLS rollback check */
|
||||
+
|
||||
+ /* TLS externsions */
|
||||
+ TLS_EXTENSION *tls_extension;
|
||||
+ int (*tls_extension_cb)(SSL *s, TLS_EXTENSION *tls_ext, void *arg);
|
||||
+ void *tls_extension_cb_arg;
|
||||
+
|
||||
+ /* TLS pre-shared secret session resumption */
|
||||
+ tls_session_secret_cb_fn tls_session_secret_cb;
|
||||
+ void *tls_session_secret_cb_arg;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -1538,6 +1550,13 @@ void *SSL_COMP_get_compression_methods(v
|
||||
int SSL_COMP_add_compression_method(int id,void *cm);
|
||||
#endif
|
||||
|
||||
+/* TLS extensions functions */
|
||||
+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len);
|
||||
+int SSL_set_hello_extension_cb(SSL *s, int (*cb)(SSL *, TLS_EXTENSION *, void *), void *arg);
|
||||
+
|
||||
+/* Pre-shared secret session resumption functions */
|
||||
+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
|
||||
+
|
||||
/* BEGIN ERROR CODES */
|
||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||
* made after this point may be overwritten when the script is next run.
|
||||
@@ -1719,6 +1738,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_TLS1_ENC 210
|
||||
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211
|
||||
#define SSL_F_WRITE_PENDING 212
|
||||
+#define SSL_F_SSL_SET_HELLO_EXTENSION 213
|
||||
|
||||
/* Reason codes. */
|
||||
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
|
||||
diff -uprN openssl-0.9.8d.orig/ssl/ssl_err.c openssl-0.9.8d/ssl/ssl_err.c
|
||||
--- openssl-0.9.8d.orig/ssl/ssl_err.c 2006-01-08 13:52:46.000000000 -0800
|
||||
+++ openssl-0.9.8d/ssl/ssl_err.c 2006-12-10 08:20:02.000000000 -0800
|
||||
@@ -242,6 +242,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"},
|
||||
{ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"},
|
||||
{ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"},
|
||||
+{ERR_FUNC(SSL_F_SSL_SET_HELLO_EXTENSION), "SSL_set_hello_extension"},
|
||||
{0,NULL}
|
||||
};
|
||||
|
||||
diff -uprN openssl-0.9.8d.orig/ssl/ssl_sess.c openssl-0.9.8d/ssl/ssl_sess.c
|
||||
--- openssl-0.9.8d.orig/ssl/ssl_sess.c 2005-12-30 15:51:57.000000000 -0800
|
||||
+++ openssl-0.9.8d/ssl/ssl_sess.c 2006-12-10 08:20:02.000000000 -0800
|
||||
@@ -656,6 +656,15 @@ long SSL_CTX_get_timeout(const SSL_CTX *
|
||||
return(s->session_timeout);
|
||||
}
|
||||
|
||||
+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len,
|
||||
+ STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg)
|
||||
+{
|
||||
+ if (s == NULL) return(0);
|
||||
+ s->tls_session_secret_cb = tls_session_secret_cb;
|
||||
+ s->tls_session_secret_cb_arg = arg;
|
||||
+ return(1);
|
||||
+}
|
||||
+
|
||||
typedef struct timeout_param_st
|
||||
{
|
||||
SSL_CTX *ctx;
|
||||
diff -uprN openssl-0.9.8d.orig/ssl/t1_ext.c openssl-0.9.8d/ssl/t1_ext.c
|
||||
--- openssl-0.9.8d.orig/ssl/t1_ext.c 1969-12-31 16:00:00.000000000 -0800
|
||||
+++ openssl-0.9.8d/ssl/t1_ext.c 2006-12-10 08:20:02.000000000 -0800
|
||||
@@ -0,0 +1,48 @@
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include "ssl_locl.h"
|
||||
+
|
||||
+
|
||||
+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len)
|
||||
+{
|
||||
+ if(s->version >= TLS1_VERSION)
|
||||
+ {
|
||||
+ if(s->tls_extension)
|
||||
+ {
|
||||
+ OPENSSL_free(s->tls_extension);
|
||||
+ s->tls_extension = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if(ext_data)
|
||||
+ {
|
||||
+ s->tls_extension = OPENSSL_malloc(sizeof(TLS_EXTENSION) + ext_len);
|
||||
+ if(!s->tls_extension)
|
||||
+ {
|
||||
+ SSLerr(SSL_F_SSL_SET_HELLO_EXTENSION, ERR_R_MALLOC_FAILURE);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ s->tls_extension->type = ext_type;
|
||||
+ s->tls_extension->length = ext_len;
|
||||
+ s->tls_extension->data = s->tls_extension + 1;
|
||||
+ memcpy(s->tls_extension->data, ext_data, ext_len);
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int SSL_set_hello_extension_cb(SSL *s, int (*cb)(SSL *, TLS_EXTENSION *, void *), void *arg)
|
||||
+{
|
||||
+ if(s->version >= TLS1_VERSION)
|
||||
+ {
|
||||
+ s->tls_extension_cb = cb;
|
||||
+ s->tls_extension_cb_arg = arg;
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff -uprN openssl-0.9.8d.orig/ssl/t1_lib.c openssl-0.9.8d/ssl/t1_lib.c
|
||||
--- openssl-0.9.8d.orig/ssl/t1_lib.c 2005-08-05 16:52:07.000000000 -0700
|
||||
+++ openssl-0.9.8d/ssl/t1_lib.c 2006-12-10 08:20:02.000000000 -0800
|
||||
@@ -97,6 +97,10 @@ int tls1_new(SSL *s)
|
||||
|
||||
void tls1_free(SSL *s)
|
||||
{
|
||||
+ if(s->tls_extension)
|
||||
+ {
|
||||
+ OPENSSL_free(s->tls_extension);
|
||||
+ }
|
||||
ssl3_free(s);
|
||||
}
|
||||
|
||||
diff -uprN openssl-0.9.8d.orig/ssl/tls1.h openssl-0.9.8d/ssl/tls1.h
|
||||
--- openssl-0.9.8d.orig/ssl/tls1.h 2006-06-14 10:52:01.000000000 -0700
|
||||
+++ openssl-0.9.8d/ssl/tls1.h 2006-12-10 08:20:02.000000000 -0800
|
||||
@@ -296,6 +296,14 @@ extern "C" {
|
||||
#define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/
|
||||
#endif
|
||||
|
||||
+/* TLS extension struct */
|
||||
+struct tls_extension_st
|
||||
+{
|
||||
+ unsigned short type;
|
||||
+ unsigned short length;
|
||||
+ void *data;
|
||||
+};
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff -uprN openssl-0.9.8d.orig/util/ssleay.num openssl-0.9.8d/util/ssleay.num
|
||||
--- openssl-0.9.8d.orig/util/ssleay.num 2005-05-08 17:22:02.000000000 -0700
|
||||
+++ openssl-0.9.8d/util/ssleay.num 2006-12-10 08:20:02.000000000 -0800
|
||||
@@ -226,3 +226,6 @@ DTLSv1_server_method
|
||||
SSL_COMP_get_compression_methods 276 EXIST:!VMS:FUNCTION:COMP
|
||||
SSL_COMP_get_compress_methods 276 EXIST:VMS:FUNCTION:COMP
|
||||
SSL_SESSION_get_id 277 EXIST::FUNCTION:
|
||||
+SSL_set_hello_extension 278 EXIST::FUNCTION:
|
||||
+SSL_set_hello_extension_cb 279 EXIST::FUNCTION:
|
||||
+SSL_set_session_secret_cb 280 EXIST::FUNCTION:
|
353
contrib/wpa/patches/openssl-0.9.8e-tls-extensions.patch
Normal file
353
contrib/wpa/patches/openssl-0.9.8e-tls-extensions.patch
Normal file
@ -0,0 +1,353 @@
|
||||
This patch is adding support for TLS hello extensions and externally
|
||||
generated pre-shared key material to OpenSSL 0.9.8e. This is
|
||||
based on the patch from Alexey Kobozev <akobozev@cisco.com>
|
||||
(sent to openssl-dev mailing list on Tue, 07 Jun 2005 15:40:58 +0300).
|
||||
|
||||
|
||||
|
||||
diff -uprN openssl-0.9.8e.orig/ssl/Makefile openssl-0.9.8e/ssl/Makefile
|
||||
--- openssl-0.9.8e.orig/ssl/Makefile 2006-02-03 17:49:35.000000000 -0800
|
||||
+++ openssl-0.9.8e/ssl/Makefile 2007-03-22 20:23:19.000000000 -0700
|
||||
@@ -24,7 +24,7 @@ LIBSRC= \
|
||||
s2_meth.c s2_srvr.c s2_clnt.c s2_lib.c s2_enc.c s2_pkt.c \
|
||||
s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c \
|
||||
s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c s23_pkt.c \
|
||||
- t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c \
|
||||
+ t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c t1_ext.c \
|
||||
d1_meth.c d1_srvr.c d1_clnt.c d1_lib.c d1_pkt.c \
|
||||
d1_both.c d1_enc.c \
|
||||
ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
|
||||
@@ -35,7 +35,7 @@ LIBOBJ= \
|
||||
s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \
|
||||
s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \
|
||||
s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o s23_pkt.o \
|
||||
- t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o \
|
||||
+ t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o t1_ext.o \
|
||||
d1_meth.o d1_srvr.o d1_clnt.o d1_lib.o d1_pkt.o \
|
||||
d1_both.o d1_enc.o \
|
||||
ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
|
||||
@@ -968,3 +968,4 @@ t1_srvr.o: ../include/openssl/ssl23.h ..
|
||||
t1_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
|
||||
t1_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
|
||||
t1_srvr.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_srvr.c
|
||||
+t1_ext.o: t1_ext.c ssl_locl.h
|
||||
diff -uprN openssl-0.9.8e.orig/ssl/s3_clnt.c openssl-0.9.8e/ssl/s3_clnt.c
|
||||
--- openssl-0.9.8e.orig/ssl/s3_clnt.c 2006-09-28 05:23:15.000000000 -0700
|
||||
+++ openssl-0.9.8e/ssl/s3_clnt.c 2007-03-22 20:23:19.000000000 -0700
|
||||
@@ -601,6 +601,20 @@ int ssl3_client_hello(SSL *s)
|
||||
#endif
|
||||
*(p++)=0; /* Add the NULL method */
|
||||
|
||||
+ /* send client hello extensions if any */
|
||||
+ if (s->version >= TLS1_VERSION && s->tls_extension)
|
||||
+ {
|
||||
+ // set the total extensions length
|
||||
+ s2n(s->tls_extension->length + 4, p);
|
||||
+
|
||||
+ // put the extensions with type and length
|
||||
+ s2n(s->tls_extension->type, p);
|
||||
+ s2n(s->tls_extension->length, p);
|
||||
+
|
||||
+ memcpy(p, s->tls_extension->data, s->tls_extension->length);
|
||||
+ p+=s->tls_extension->length;
|
||||
+ }
|
||||
+
|
||||
l=(p-d);
|
||||
d=buf;
|
||||
*(d++)=SSL3_MT_CLIENT_HELLO;
|
||||
@@ -623,7 +637,7 @@ int ssl3_get_server_hello(SSL *s)
|
||||
STACK_OF(SSL_CIPHER) *sk;
|
||||
SSL_CIPHER *c;
|
||||
unsigned char *p,*d;
|
||||
- int i,al,ok;
|
||||
+ int i,al,ok,pre_shared;
|
||||
unsigned int j;
|
||||
long n;
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
@@ -690,7 +704,24 @@ int ssl3_get_server_hello(SSL *s)
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
- if (j != 0 && j == s->session->session_id_length
|
||||
+ /* check if we want to resume the session based on external pre-shared secret */
|
||||
+ pre_shared = 0;
|
||||
+ if (s->version >= TLS1_VERSION && s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ SSL_CIPHER *pref_cipher=NULL;
|
||||
+ s->session->master_key_length=sizeof(s->session->master_key);
|
||||
+ if (s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
|
||||
+ NULL, &pref_cipher, s->tls_session_secret_cb_arg))
|
||||
+ {
|
||||
+ s->hit=1;
|
||||
+ s->session->cipher=pref_cipher ? pref_cipher : ssl_get_cipher_by_char(s,p+j);
|
||||
+ s->session->session_id_length = j;
|
||||
+ memcpy(s->session->session_id, p, j);
|
||||
+ pre_shared = 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ((pre_shared || j != 0) && j == s->session->session_id_length
|
||||
&& memcmp(p,s->session->session_id,j) == 0)
|
||||
{
|
||||
if(s->sid_ctx_length != s->session->sid_ctx_length
|
||||
diff -uprN openssl-0.9.8e.orig/ssl/s3_srvr.c openssl-0.9.8e/ssl/s3_srvr.c
|
||||
--- openssl-0.9.8e.orig/ssl/s3_srvr.c 2007-02-07 12:36:40.000000000 -0800
|
||||
+++ openssl-0.9.8e/ssl/s3_srvr.c 2007-03-22 20:23:19.000000000 -0700
|
||||
@@ -945,6 +945,75 @@ int ssl3_get_client_hello(SSL *s)
|
||||
}
|
||||
#endif
|
||||
|
||||
+ /* Check for TLS client hello extension here */
|
||||
+ if (p < (d+n) && s->version >= TLS1_VERSION)
|
||||
+ {
|
||||
+ if (s->tls_extension_cb)
|
||||
+ {
|
||||
+ TLS_EXTENSION tls_ext;
|
||||
+ unsigned short ext_total_len;
|
||||
+
|
||||
+ n2s(p, ext_total_len);
|
||||
+ n2s(p, tls_ext.type);
|
||||
+ n2s(p, tls_ext.length);
|
||||
+
|
||||
+ // sanity check in TLS extension len
|
||||
+ if (tls_ext.length > (d+n) - p)
|
||||
+ {
|
||||
+ // just cut the lenth to packet border
|
||||
+ tls_ext.length = (d+n) - p;
|
||||
+ }
|
||||
+
|
||||
+ tls_ext.data = p;
|
||||
+
|
||||
+ // returns an alert code or 0
|
||||
+ al = s->tls_extension_cb(s, &tls_ext, s->tls_extension_cb_arg);
|
||||
+ if (al != 0)
|
||||
+ {
|
||||
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PEER_ERROR);
|
||||
+ goto f_err;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Check if we want to use external pre-shared secret for this handshake */
|
||||
+ /* for not reused session only */
|
||||
+ if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ SSL_CIPHER *pref_cipher=NULL;
|
||||
+
|
||||
+ s->session->master_key_length=sizeof(s->session->master_key);
|
||||
+ if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
|
||||
+ ciphers, &pref_cipher, s->tls_session_secret_cb_arg))
|
||||
+ {
|
||||
+ s->hit=1;
|
||||
+ s->session->ciphers=ciphers;
|
||||
+ s->session->verify_result=X509_V_OK;
|
||||
+
|
||||
+ ciphers=NULL;
|
||||
+
|
||||
+ /* check if some cipher was preferred by call back */
|
||||
+ pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
|
||||
+ if (pref_cipher == NULL)
|
||||
+ {
|
||||
+ al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
|
||||
+ goto f_err;
|
||||
+ }
|
||||
+
|
||||
+ s->session->cipher=pref_cipher;
|
||||
+
|
||||
+ if (s->cipher_list)
|
||||
+ sk_SSL_CIPHER_free(s->cipher_list);
|
||||
+
|
||||
+ if (s->cipher_list_by_id)
|
||||
+ sk_SSL_CIPHER_free(s->cipher_list_by_id);
|
||||
+
|
||||
+ s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
+ s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Given s->session->ciphers and SSL_get_ciphers, we must
|
||||
* pick a cipher */
|
||||
|
||||
diff -uprN openssl-0.9.8e.orig/ssl/ssl.h openssl-0.9.8e/ssl/ssl.h
|
||||
--- openssl-0.9.8e.orig/ssl/ssl.h 2007-02-19 09:55:07.000000000 -0800
|
||||
+++ openssl-0.9.8e/ssl/ssl.h 2007-03-22 20:23:19.000000000 -0700
|
||||
@@ -345,6 +345,7 @@ extern "C" {
|
||||
* 'struct ssl_st *' function parameters used to prototype callbacks
|
||||
* in SSL_CTX. */
|
||||
typedef struct ssl_st *ssl_crock_st;
|
||||
+typedef struct tls_extension_st TLS_EXTENSION;
|
||||
|
||||
/* used to hold info on the particular ciphers used */
|
||||
typedef struct ssl_cipher_st
|
||||
@@ -366,6 +367,8 @@ DECLARE_STACK_OF(SSL_CIPHER)
|
||||
typedef struct ssl_st SSL;
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
|
||||
+typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
|
||||
+
|
||||
/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
|
||||
typedef struct ssl_method_st
|
||||
{
|
||||
@@ -973,6 +976,15 @@ struct ssl_st
|
||||
int first_packet;
|
||||
int client_version; /* what was passed, used for
|
||||
* SSLv3/TLS rollback check */
|
||||
+
|
||||
+ /* TLS externsions */
|
||||
+ TLS_EXTENSION *tls_extension;
|
||||
+ int (*tls_extension_cb)(SSL *s, TLS_EXTENSION *tls_ext, void *arg);
|
||||
+ void *tls_extension_cb_arg;
|
||||
+
|
||||
+ /* TLS pre-shared secret session resumption */
|
||||
+ tls_session_secret_cb_fn tls_session_secret_cb;
|
||||
+ void *tls_session_secret_cb_arg;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -1538,6 +1550,13 @@ void *SSL_COMP_get_compression_methods(v
|
||||
int SSL_COMP_add_compression_method(int id,void *cm);
|
||||
#endif
|
||||
|
||||
+/* TLS extensions functions */
|
||||
+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len);
|
||||
+int SSL_set_hello_extension_cb(SSL *s, int (*cb)(SSL *, TLS_EXTENSION *, void *), void *arg);
|
||||
+
|
||||
+/* Pre-shared secret session resumption functions */
|
||||
+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
|
||||
+
|
||||
/* BEGIN ERROR CODES */
|
||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||
* made after this point may be overwritten when the script is next run.
|
||||
@@ -1719,6 +1738,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_TLS1_ENC 210
|
||||
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211
|
||||
#define SSL_F_WRITE_PENDING 212
|
||||
+#define SSL_F_SSL_SET_HELLO_EXTENSION 213
|
||||
|
||||
/* Reason codes. */
|
||||
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
|
||||
diff -uprN openssl-0.9.8e.orig/ssl/ssl_err.c openssl-0.9.8e/ssl/ssl_err.c
|
||||
--- openssl-0.9.8e.orig/ssl/ssl_err.c 2006-11-21 12:14:46.000000000 -0800
|
||||
+++ openssl-0.9.8e/ssl/ssl_err.c 2007-03-22 20:23:19.000000000 -0700
|
||||
@@ -242,6 +242,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"},
|
||||
{ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"},
|
||||
{ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"},
|
||||
+{ERR_FUNC(SSL_F_SSL_SET_HELLO_EXTENSION), "SSL_set_hello_extension"},
|
||||
{0,NULL}
|
||||
};
|
||||
|
||||
diff -uprN openssl-0.9.8e.orig/ssl/ssl_sess.c openssl-0.9.8e/ssl/ssl_sess.c
|
||||
--- openssl-0.9.8e.orig/ssl/ssl_sess.c 2007-02-10 02:40:24.000000000 -0800
|
||||
+++ openssl-0.9.8e/ssl/ssl_sess.c 2007-03-22 20:23:19.000000000 -0700
|
||||
@@ -656,6 +656,15 @@ long SSL_CTX_get_timeout(const SSL_CTX *
|
||||
return(s->session_timeout);
|
||||
}
|
||||
|
||||
+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len,
|
||||
+ STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg)
|
||||
+{
|
||||
+ if (s == NULL) return(0);
|
||||
+ s->tls_session_secret_cb = tls_session_secret_cb;
|
||||
+ s->tls_session_secret_cb_arg = arg;
|
||||
+ return(1);
|
||||
+}
|
||||
+
|
||||
typedef struct timeout_param_st
|
||||
{
|
||||
SSL_CTX *ctx;
|
||||
diff -uprN openssl-0.9.8e.orig/ssl/t1_ext.c openssl-0.9.8e/ssl/t1_ext.c
|
||||
--- openssl-0.9.8e.orig/ssl/t1_ext.c 1969-12-31 16:00:00.000000000 -0800
|
||||
+++ openssl-0.9.8e/ssl/t1_ext.c 2007-03-22 20:23:19.000000000 -0700
|
||||
@@ -0,0 +1,48 @@
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include "ssl_locl.h"
|
||||
+
|
||||
+
|
||||
+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len)
|
||||
+{
|
||||
+ if(s->version >= TLS1_VERSION)
|
||||
+ {
|
||||
+ if(s->tls_extension)
|
||||
+ {
|
||||
+ OPENSSL_free(s->tls_extension);
|
||||
+ s->tls_extension = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if(ext_data)
|
||||
+ {
|
||||
+ s->tls_extension = OPENSSL_malloc(sizeof(TLS_EXTENSION) + ext_len);
|
||||
+ if(!s->tls_extension)
|
||||
+ {
|
||||
+ SSLerr(SSL_F_SSL_SET_HELLO_EXTENSION, ERR_R_MALLOC_FAILURE);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ s->tls_extension->type = ext_type;
|
||||
+ s->tls_extension->length = ext_len;
|
||||
+ s->tls_extension->data = s->tls_extension + 1;
|
||||
+ memcpy(s->tls_extension->data, ext_data, ext_len);
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int SSL_set_hello_extension_cb(SSL *s, int (*cb)(SSL *, TLS_EXTENSION *, void *), void *arg)
|
||||
+{
|
||||
+ if(s->version >= TLS1_VERSION)
|
||||
+ {
|
||||
+ s->tls_extension_cb = cb;
|
||||
+ s->tls_extension_cb_arg = arg;
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff -uprN openssl-0.9.8e.orig/ssl/t1_lib.c openssl-0.9.8e/ssl/t1_lib.c
|
||||
--- openssl-0.9.8e.orig/ssl/t1_lib.c 2007-01-21 08:07:25.000000000 -0800
|
||||
+++ openssl-0.9.8e/ssl/t1_lib.c 2007-03-22 20:23:19.000000000 -0700
|
||||
@@ -97,6 +97,10 @@ int tls1_new(SSL *s)
|
||||
|
||||
void tls1_free(SSL *s)
|
||||
{
|
||||
+ if(s->tls_extension)
|
||||
+ {
|
||||
+ OPENSSL_free(s->tls_extension);
|
||||
+ }
|
||||
ssl3_free(s);
|
||||
}
|
||||
|
||||
diff -uprN openssl-0.9.8e.orig/ssl/tls1.h openssl-0.9.8e/ssl/tls1.h
|
||||
--- openssl-0.9.8e.orig/ssl/tls1.h 2006-06-14 10:52:01.000000000 -0700
|
||||
+++ openssl-0.9.8e/ssl/tls1.h 2007-03-22 20:23:19.000000000 -0700
|
||||
@@ -296,6 +296,14 @@ extern "C" {
|
||||
#define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/
|
||||
#endif
|
||||
|
||||
+/* TLS extension struct */
|
||||
+struct tls_extension_st
|
||||
+{
|
||||
+ unsigned short type;
|
||||
+ unsigned short length;
|
||||
+ void *data;
|
||||
+};
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff -uprN openssl-0.9.8e.orig/util/ssleay.num openssl-0.9.8e/util/ssleay.num
|
||||
--- openssl-0.9.8e.orig/util/ssleay.num 2006-11-30 05:04:43.000000000 -0800
|
||||
+++ openssl-0.9.8e/util/ssleay.num 2007-03-22 20:24:07.000000000 -0700
|
||||
@@ -238,3 +238,6 @@ SSL_CTX_set_info_callback
|
||||
SSL_CTX_sess_get_new_cb 287 EXIST::FUNCTION:
|
||||
SSL_CTX_get_client_cert_cb 288 EXIST::FUNCTION:
|
||||
SSL_CTX_sess_get_remove_cb 289 EXIST::FUNCTION:
|
||||
+SSL_set_hello_extension 290 EXIST::FUNCTION:
|
||||
+SSL_set_hello_extension_cb 291 EXIST::FUNCTION:
|
||||
+SSL_set_session_secret_cb 292 EXIST::FUNCTION:
|
330
contrib/wpa/patches/openssl-0.9.8g-tls-extensions.patch
Normal file
330
contrib/wpa/patches/openssl-0.9.8g-tls-extensions.patch
Normal file
@ -0,0 +1,330 @@
|
||||
This patch adds support for TLS SessionTicket extension (RFC 5077) for
|
||||
the parts used by EAP-FAST (RFC 4851).
|
||||
|
||||
This is based on the patch from Alexey Kobozev <akobozev@cisco.com>
|
||||
(sent to openssl-dev mailing list on Tue, 07 Jun 2005 15:40:58 +0300).
|
||||
|
||||
OpenSSL 0.9.8g does not enable TLS extension support by default, so it
|
||||
will need to be enabled by adding enable-tlsext to config script
|
||||
command line.
|
||||
|
||||
|
||||
diff -upr openssl-0.9.8g.orig/ssl/s3_clnt.c openssl-0.9.8g/ssl/s3_clnt.c
|
||||
--- openssl-0.9.8g.orig/ssl/s3_clnt.c 2007-08-31 03:28:51.000000000 +0300
|
||||
+++ openssl-0.9.8g/ssl/s3_clnt.c 2008-04-15 17:11:46.000000000 +0300
|
||||
@@ -727,6 +727,20 @@ int ssl3_get_server_hello(SSL *s)
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
+#ifndef OPENSSL_NO_TLSEXT
|
||||
+ /* check if we want to resume the session based on external pre-shared secret */
|
||||
+ if (s->version >= TLS1_VERSION && s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ SSL_CIPHER *pref_cipher=NULL;
|
||||
+ s->session->master_key_length=sizeof(s->session->master_key);
|
||||
+ if (s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
|
||||
+ NULL, &pref_cipher, s->tls_session_secret_cb_arg))
|
||||
+ {
|
||||
+ s->session->cipher=pref_cipher ? pref_cipher : ssl_get_cipher_by_char(s,p+j);
|
||||
+ }
|
||||
+ }
|
||||
+#endif /* OPENSSL_NO_TLSEXT */
|
||||
+
|
||||
if (j != 0 && j == s->session->session_id_length
|
||||
&& memcmp(p,s->session->session_id,j) == 0)
|
||||
{
|
||||
diff -upr openssl-0.9.8g.orig/ssl/s3_srvr.c openssl-0.9.8g/ssl/s3_srvr.c
|
||||
--- openssl-0.9.8g.orig/ssl/s3_srvr.c 2007-09-30 21:55:59.000000000 +0300
|
||||
+++ openssl-0.9.8g/ssl/s3_srvr.c 2008-04-15 17:10:37.000000000 +0300
|
||||
@@ -928,6 +928,59 @@ int ssl3_get_client_hello(SSL *s)
|
||||
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
|
||||
goto err;
|
||||
}
|
||||
+
|
||||
+ /* Check if we want to use external pre-shared secret for this
|
||||
+ * handshake for not reused session only. We need to generate
|
||||
+ * server_random before calling tls_session_secret_cb in order to allow
|
||||
+ * SessionTicket processing to use it in key derivation. */
|
||||
+ {
|
||||
+ unsigned long Time;
|
||||
+ unsigned char *pos;
|
||||
+ Time=(unsigned long)time(NULL); /* Time */
|
||||
+ pos=s->s3->server_random;
|
||||
+ l2n(Time,pos);
|
||||
+ if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0)
|
||||
+ {
|
||||
+ al=SSL_AD_INTERNAL_ERROR;
|
||||
+ goto f_err;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ SSL_CIPHER *pref_cipher=NULL;
|
||||
+
|
||||
+ s->session->master_key_length=sizeof(s->session->master_key);
|
||||
+ if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
|
||||
+ ciphers, &pref_cipher, s->tls_session_secret_cb_arg))
|
||||
+ {
|
||||
+ s->hit=1;
|
||||
+ s->session->ciphers=ciphers;
|
||||
+ s->session->verify_result=X509_V_OK;
|
||||
+
|
||||
+ ciphers=NULL;
|
||||
+
|
||||
+ /* check if some cipher was preferred by call back */
|
||||
+ pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
|
||||
+ if (pref_cipher == NULL)
|
||||
+ {
|
||||
+ al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
|
||||
+ goto f_err;
|
||||
+ }
|
||||
+
|
||||
+ s->session->cipher=pref_cipher;
|
||||
+
|
||||
+ if (s->cipher_list)
|
||||
+ sk_SSL_CIPHER_free(s->cipher_list);
|
||||
+
|
||||
+ if (s->cipher_list_by_id)
|
||||
+ sk_SSL_CIPHER_free(s->cipher_list_by_id);
|
||||
+
|
||||
+ s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
+ s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
+ }
|
||||
+ }
|
||||
#endif
|
||||
/* Worst case, we will use the NULL compression, but if we have other
|
||||
* options, we will now look for them. We have i-1 compression
|
||||
@@ -1066,16 +1119,22 @@ int ssl3_send_server_hello(SSL *s)
|
||||
unsigned char *buf;
|
||||
unsigned char *p,*d;
|
||||
int i,sl;
|
||||
- unsigned long l,Time;
|
||||
+ unsigned long l;
|
||||
+#ifdef OPENSSL_NO_TLSEXT
|
||||
+ unsigned long Time;
|
||||
+#endif
|
||||
|
||||
if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
|
||||
{
|
||||
buf=(unsigned char *)s->init_buf->data;
|
||||
+#ifdef OPENSSL_NO_TLSEXT
|
||||
p=s->s3->server_random;
|
||||
+ /* Generate server_random if it was not needed previously */
|
||||
Time=(unsigned long)time(NULL); /* Time */
|
||||
l2n(Time,p);
|
||||
if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
|
||||
return -1;
|
||||
+#endif
|
||||
/* Do the message type and length last */
|
||||
d=p= &(buf[4]);
|
||||
|
||||
diff -upr openssl-0.9.8g.orig/ssl/ssl.h openssl-0.9.8g/ssl/ssl.h
|
||||
--- openssl-0.9.8g.orig/ssl/ssl.h 2007-10-19 10:42:38.000000000 +0300
|
||||
+++ openssl-0.9.8g/ssl/ssl.h 2008-04-15 17:10:37.000000000 +0300
|
||||
@@ -342,6 +342,7 @@ extern "C" {
|
||||
* 'struct ssl_st *' function parameters used to prototype callbacks
|
||||
* in SSL_CTX. */
|
||||
typedef struct ssl_st *ssl_crock_st;
|
||||
+typedef struct tls_extension_st TLS_EXTENSION;
|
||||
|
||||
/* used to hold info on the particular ciphers used */
|
||||
typedef struct ssl_cipher_st
|
||||
@@ -363,6 +364,8 @@ DECLARE_STACK_OF(SSL_CIPHER)
|
||||
typedef struct ssl_st SSL;
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
|
||||
+typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
|
||||
+
|
||||
/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
|
||||
typedef struct ssl_method_st
|
||||
{
|
||||
@@ -1004,6 +1007,14 @@ struct ssl_st
|
||||
*/
|
||||
/* RFC4507 session ticket expected to be received or sent */
|
||||
int tlsext_ticket_expected;
|
||||
+
|
||||
+ /* TLS extensions */
|
||||
+ TLS_EXTENSION *tls_extension;
|
||||
+
|
||||
+ /* TLS pre-shared secret session resumption */
|
||||
+ tls_session_secret_cb_fn tls_session_secret_cb;
|
||||
+ void *tls_session_secret_cb_arg;
|
||||
+
|
||||
SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
|
||||
#define session_ctx initial_ctx
|
||||
#else
|
||||
@@ -1589,6 +1600,12 @@ void *SSL_COMP_get_compression_methods(v
|
||||
int SSL_COMP_add_compression_method(int id,void *cm);
|
||||
#endif
|
||||
|
||||
+/* TLS extensions functions */
|
||||
+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len);
|
||||
+
|
||||
+/* Pre-shared secret session resumption functions */
|
||||
+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
|
||||
+
|
||||
/* BEGIN ERROR CODES */
|
||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||
* made after this point may be overwritten when the script is next run.
|
||||
@@ -1778,6 +1795,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_TLS1_ENC 210
|
||||
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211
|
||||
#define SSL_F_WRITE_PENDING 212
|
||||
+#define SSL_F_SSL_SET_HELLO_EXTENSION 213
|
||||
|
||||
/* Reason codes. */
|
||||
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
|
||||
diff -upr openssl-0.9.8g.orig/ssl/ssl_err.c openssl-0.9.8g/ssl/ssl_err.c
|
||||
--- openssl-0.9.8g.orig/ssl/ssl_err.c 2007-10-11 17:36:59.000000000 +0300
|
||||
+++ openssl-0.9.8g/ssl/ssl_err.c 2008-04-15 17:10:37.000000000 +0300
|
||||
@@ -250,6 +250,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"},
|
||||
{ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"},
|
||||
{ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"},
|
||||
+{ERR_FUNC(SSL_F_SSL_SET_HELLO_EXTENSION), "SSL_set_hello_extension"},
|
||||
{0,NULL}
|
||||
};
|
||||
|
||||
diff -upr openssl-0.9.8g.orig/ssl/ssl_sess.c openssl-0.9.8g/ssl/ssl_sess.c
|
||||
--- openssl-0.9.8g.orig/ssl/ssl_sess.c 2007-10-19 10:36:34.000000000 +0300
|
||||
+++ openssl-0.9.8g/ssl/ssl_sess.c 2008-04-15 17:10:37.000000000 +0300
|
||||
@@ -704,6 +704,52 @@ long SSL_CTX_get_timeout(const SSL_CTX *
|
||||
return(s->session_timeout);
|
||||
}
|
||||
|
||||
+#ifndef OPENSSL_NO_TLSEXT
|
||||
+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len,
|
||||
+ STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg)
|
||||
+{
|
||||
+ if (s == NULL) return(0);
|
||||
+ s->tls_session_secret_cb = tls_session_secret_cb;
|
||||
+ s->tls_session_secret_cb_arg = arg;
|
||||
+ return(1);
|
||||
+}
|
||||
+
|
||||
+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len)
|
||||
+{
|
||||
+ if(s->version >= TLS1_VERSION)
|
||||
+ {
|
||||
+ if(s->tls_extension)
|
||||
+ {
|
||||
+ OPENSSL_free(s->tls_extension);
|
||||
+ s->tls_extension = NULL;
|
||||
+ }
|
||||
+
|
||||
+ s->tls_extension = OPENSSL_malloc(sizeof(TLS_EXTENSION) + ext_len);
|
||||
+ if(!s->tls_extension)
|
||||
+ {
|
||||
+ SSLerr(SSL_F_SSL_SET_HELLO_EXTENSION, ERR_R_MALLOC_FAILURE);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ s->tls_extension->type = ext_type;
|
||||
+
|
||||
+ if(ext_data)
|
||||
+ {
|
||||
+ s->tls_extension->length = ext_len;
|
||||
+ s->tls_extension->data = s->tls_extension + 1;
|
||||
+ memcpy(s->tls_extension->data, ext_data, ext_len);
|
||||
+ } else {
|
||||
+ s->tls_extension->length = 0;
|
||||
+ s->tls_extension->data = NULL;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif /* OPENSSL_NO_TLSEXT */
|
||||
+
|
||||
typedef struct timeout_param_st
|
||||
{
|
||||
SSL_CTX *ctx;
|
||||
diff -upr openssl-0.9.8g.orig/ssl/t1_lib.c openssl-0.9.8g/ssl/t1_lib.c
|
||||
--- openssl-0.9.8g.orig/ssl/t1_lib.c 2007-10-19 10:44:10.000000000 +0300
|
||||
+++ openssl-0.9.8g/ssl/t1_lib.c 2008-04-15 17:10:37.000000000 +0300
|
||||
@@ -105,6 +105,12 @@ int tls1_new(SSL *s)
|
||||
|
||||
void tls1_free(SSL *s)
|
||||
{
|
||||
+#ifndef OPENSSL_NO_TLSEXT
|
||||
+ if(s->tls_extension)
|
||||
+ {
|
||||
+ OPENSSL_free(s->tls_extension);
|
||||
+ }
|
||||
+#endif
|
||||
ssl3_free(s);
|
||||
}
|
||||
|
||||
@@ -174,8 +180,24 @@ unsigned char *ssl_add_clienthello_tlsex
|
||||
int ticklen;
|
||||
if (s->session && s->session->tlsext_tick)
|
||||
ticklen = s->session->tlsext_ticklen;
|
||||
+ else if (s->session && s->tls_extension &&
|
||||
+ s->tls_extension->type == TLSEXT_TYPE_session_ticket &&
|
||||
+ s->tls_extension->data)
|
||||
+ {
|
||||
+ ticklen = s->tls_extension->length;
|
||||
+ s->session->tlsext_tick = OPENSSL_malloc(ticklen);
|
||||
+ if (!s->session->tlsext_tick)
|
||||
+ return NULL;
|
||||
+ memcpy(s->session->tlsext_tick, s->tls_extension->data,
|
||||
+ ticklen);
|
||||
+ s->session->tlsext_ticklen = ticklen;
|
||||
+ }
|
||||
else
|
||||
ticklen = 0;
|
||||
+ if (ticklen == 0 && s->tls_extension &&
|
||||
+ s->tls_extension->type == TLSEXT_TYPE_session_ticket &&
|
||||
+ s->tls_extension->data == NULL)
|
||||
+ goto skip_ext;
|
||||
/* Check for enough room 2 for extension type, 2 for len
|
||||
* rest for ticket
|
||||
*/
|
||||
@@ -189,6 +211,7 @@ unsigned char *ssl_add_clienthello_tlsex
|
||||
ret += ticklen;
|
||||
}
|
||||
}
|
||||
+ skip_ext:
|
||||
|
||||
if ((extdatalen = ret-p-2)== 0)
|
||||
return p;
|
||||
@@ -543,6 +566,8 @@ int tls1_process_ticket(SSL *s, unsigned
|
||||
s->tlsext_ticket_expected = 1;
|
||||
return 0; /* Cache miss */
|
||||
}
|
||||
+ if (s->tls_session_secret_cb)
|
||||
+ return 0;
|
||||
return tls_decrypt_ticket(s, p, size, session_id, len,
|
||||
ret);
|
||||
}
|
||||
diff -upr openssl-0.9.8g.orig/ssl/tls1.h openssl-0.9.8g/ssl/tls1.h
|
||||
--- openssl-0.9.8g.orig/ssl/tls1.h 2007-08-28 04:12:44.000000000 +0300
|
||||
+++ openssl-0.9.8g/ssl/tls1.h 2008-04-15 17:10:37.000000000 +0300
|
||||
@@ -365,6 +365,14 @@ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SER
|
||||
#define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/
|
||||
#endif
|
||||
|
||||
+/* TLS extension struct */
|
||||
+struct tls_extension_st
|
||||
+{
|
||||
+ unsigned short type;
|
||||
+ unsigned short length;
|
||||
+ void *data;
|
||||
+};
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff -upr openssl-0.9.8g.orig/util/ssleay.num openssl-0.9.8g/util/ssleay.num
|
||||
--- openssl-0.9.8g.orig/util/ssleay.num 2007-08-13 01:31:16.000000000 +0300
|
||||
+++ openssl-0.9.8g/util/ssleay.num 2008-04-15 17:10:37.000000000 +0300
|
||||
@@ -241,3 +241,5 @@ SSL_CTX_sess_get_remove_cb
|
||||
SSL_set_SSL_CTX 290 EXIST::FUNCTION:
|
||||
SSL_get_servername 291 EXIST::FUNCTION:TLSEXT
|
||||
SSL_get_servername_type 292 EXIST::FUNCTION:TLSEXT
|
||||
+SSL_set_hello_extension 305 EXIST::FUNCTION:TLSEXT
|
||||
+SSL_set_session_secret_cb 306 EXIST::FUNCTION:TLSEXT
|
344
contrib/wpa/patches/openssl-0.9.8h-tls-extensions.patch
Normal file
344
contrib/wpa/patches/openssl-0.9.8h-tls-extensions.patch
Normal file
@ -0,0 +1,344 @@
|
||||
This patch adds support for TLS SessionTicket extension (RFC 5077) for
|
||||
the parts used by EAP-FAST (RFC 4851).
|
||||
|
||||
This is based on the patch from Alexey Kobozev <akobozev@cisco.com>
|
||||
(sent to openssl-dev mailing list on Tue, 07 Jun 2005 15:40:58 +0300).
|
||||
|
||||
OpenSSL 0.9.8h does not enable TLS extension support by default, so it
|
||||
will need to be enabled by adding enable-tlsext to config script
|
||||
command line.
|
||||
|
||||
|
||||
diff -upr openssl-0.9.8h.orig/ssl/s3_clnt.c openssl-0.9.8h/ssl/s3_clnt.c
|
||||
--- openssl-0.9.8h.orig/ssl/s3_clnt.c 2008-05-28 10:29:27.000000000 +0300
|
||||
+++ openssl-0.9.8h/ssl/s3_clnt.c 2008-05-29 10:44:25.000000000 +0300
|
||||
@@ -752,6 +752,20 @@ int ssl3_get_server_hello(SSL *s)
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
+#ifndef OPENSSL_NO_TLSEXT
|
||||
+ /* check if we want to resume the session based on external pre-shared secret */
|
||||
+ if (s->version >= TLS1_VERSION && s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ SSL_CIPHER *pref_cipher=NULL;
|
||||
+ s->session->master_key_length=sizeof(s->session->master_key);
|
||||
+ if (s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
|
||||
+ NULL, &pref_cipher, s->tls_session_secret_cb_arg))
|
||||
+ {
|
||||
+ s->session->cipher=pref_cipher ? pref_cipher : ssl_get_cipher_by_char(s,p+j);
|
||||
+ }
|
||||
+ }
|
||||
+#endif /* OPENSSL_NO_TLSEXT */
|
||||
+
|
||||
if (j != 0 && j == s->session->session_id_length
|
||||
&& memcmp(p,s->session->session_id,j) == 0)
|
||||
{
|
||||
@@ -2693,11 +2707,8 @@ static int ssl3_check_finished(SSL *s)
|
||||
{
|
||||
int ok;
|
||||
long n;
|
||||
- /* If we have no ticket or session ID is non-zero length (a match of
|
||||
- * a non-zero session length would never reach here) it cannot be a
|
||||
- * resumed session.
|
||||
- */
|
||||
- if (!s->session->tlsext_tick || s->session->session_id_length)
|
||||
+ /* If we have no ticket it cannot be a resumed session. */
|
||||
+ if (!s->session->tlsext_tick)
|
||||
return 1;
|
||||
/* this function is called when we really expect a Certificate
|
||||
* message, so permit appropriate message length */
|
||||
diff -upr openssl-0.9.8h.orig/ssl/s3_srvr.c openssl-0.9.8h/ssl/s3_srvr.c
|
||||
--- openssl-0.9.8h.orig/ssl/s3_srvr.c 2008-04-30 19:11:32.000000000 +0300
|
||||
+++ openssl-0.9.8h/ssl/s3_srvr.c 2008-05-28 18:49:34.000000000 +0300
|
||||
@@ -959,6 +959,59 @@ int ssl3_get_client_hello(SSL *s)
|
||||
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
|
||||
goto err;
|
||||
}
|
||||
+
|
||||
+ /* Check if we want to use external pre-shared secret for this
|
||||
+ * handshake for not reused session only. We need to generate
|
||||
+ * server_random before calling tls_session_secret_cb in order to allow
|
||||
+ * SessionTicket processing to use it in key derivation. */
|
||||
+ {
|
||||
+ unsigned long Time;
|
||||
+ unsigned char *pos;
|
||||
+ Time=(unsigned long)time(NULL); /* Time */
|
||||
+ pos=s->s3->server_random;
|
||||
+ l2n(Time,pos);
|
||||
+ if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0)
|
||||
+ {
|
||||
+ al=SSL_AD_INTERNAL_ERROR;
|
||||
+ goto f_err;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ SSL_CIPHER *pref_cipher=NULL;
|
||||
+
|
||||
+ s->session->master_key_length=sizeof(s->session->master_key);
|
||||
+ if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
|
||||
+ ciphers, &pref_cipher, s->tls_session_secret_cb_arg))
|
||||
+ {
|
||||
+ s->hit=1;
|
||||
+ s->session->ciphers=ciphers;
|
||||
+ s->session->verify_result=X509_V_OK;
|
||||
+
|
||||
+ ciphers=NULL;
|
||||
+
|
||||
+ /* check if some cipher was preferred by call back */
|
||||
+ pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
|
||||
+ if (pref_cipher == NULL)
|
||||
+ {
|
||||
+ al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
|
||||
+ goto f_err;
|
||||
+ }
|
||||
+
|
||||
+ s->session->cipher=pref_cipher;
|
||||
+
|
||||
+ if (s->cipher_list)
|
||||
+ sk_SSL_CIPHER_free(s->cipher_list);
|
||||
+
|
||||
+ if (s->cipher_list_by_id)
|
||||
+ sk_SSL_CIPHER_free(s->cipher_list_by_id);
|
||||
+
|
||||
+ s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
+ s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
+ }
|
||||
+ }
|
||||
#endif
|
||||
/* Worst case, we will use the NULL compression, but if we have other
|
||||
* options, we will now look for them. We have i-1 compression
|
||||
@@ -1097,16 +1150,22 @@ int ssl3_send_server_hello(SSL *s)
|
||||
unsigned char *buf;
|
||||
unsigned char *p,*d;
|
||||
int i,sl;
|
||||
- unsigned long l,Time;
|
||||
+ unsigned long l;
|
||||
+#ifdef OPENSSL_NO_TLSEXT
|
||||
+ unsigned long Time;
|
||||
+#endif
|
||||
|
||||
if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
|
||||
{
|
||||
buf=(unsigned char *)s->init_buf->data;
|
||||
+#ifdef OPENSSL_NO_TLSEXT
|
||||
p=s->s3->server_random;
|
||||
+ /* Generate server_random if it was not needed previously */
|
||||
Time=(unsigned long)time(NULL); /* Time */
|
||||
l2n(Time,p);
|
||||
if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
|
||||
return -1;
|
||||
+#endif
|
||||
/* Do the message type and length last */
|
||||
d=p= &(buf[4]);
|
||||
|
||||
diff -upr openssl-0.9.8h.orig/ssl/ssl.h openssl-0.9.8h/ssl/ssl.h
|
||||
--- openssl-0.9.8h.orig/ssl/ssl.h 2008-04-30 19:11:32.000000000 +0300
|
||||
+++ openssl-0.9.8h/ssl/ssl.h 2008-05-28 18:49:34.000000000 +0300
|
||||
@@ -343,6 +343,7 @@ extern "C" {
|
||||
* 'struct ssl_st *' function parameters used to prototype callbacks
|
||||
* in SSL_CTX. */
|
||||
typedef struct ssl_st *ssl_crock_st;
|
||||
+typedef struct tls_extension_st TLS_EXTENSION;
|
||||
|
||||
/* used to hold info on the particular ciphers used */
|
||||
typedef struct ssl_cipher_st
|
||||
@@ -364,6 +365,8 @@ DECLARE_STACK_OF(SSL_CIPHER)
|
||||
typedef struct ssl_st SSL;
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
|
||||
+typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
|
||||
+
|
||||
/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
|
||||
typedef struct ssl_method_st
|
||||
{
|
||||
@@ -1027,6 +1030,14 @@ struct ssl_st
|
||||
|
||||
/* RFC4507 session ticket expected to be received or sent */
|
||||
int tlsext_ticket_expected;
|
||||
+
|
||||
+ /* TLS extensions */
|
||||
+ TLS_EXTENSION *tls_extension;
|
||||
+
|
||||
+ /* TLS pre-shared secret session resumption */
|
||||
+ tls_session_secret_cb_fn tls_session_secret_cb;
|
||||
+ void *tls_session_secret_cb_arg;
|
||||
+
|
||||
SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
|
||||
#define session_ctx initial_ctx
|
||||
#else
|
||||
@@ -1625,6 +1636,12 @@ void *SSL_COMP_get_compression_methods(v
|
||||
int SSL_COMP_add_compression_method(int id,void *cm);
|
||||
#endif
|
||||
|
||||
+/* TLS extensions functions */
|
||||
+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len);
|
||||
+
|
||||
+/* Pre-shared secret session resumption functions */
|
||||
+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
|
||||
+
|
||||
/* BEGIN ERROR CODES */
|
||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||
* made after this point may be overwritten when the script is next run.
|
||||
@@ -1815,6 +1832,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_TLS1_ENC 210
|
||||
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211
|
||||
#define SSL_F_WRITE_PENDING 212
|
||||
+#define SSL_F_SSL_SET_HELLO_EXTENSION 213
|
||||
|
||||
/* Reason codes. */
|
||||
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
|
||||
diff -upr openssl-0.9.8h.orig/ssl/ssl_err.c openssl-0.9.8h/ssl/ssl_err.c
|
||||
--- openssl-0.9.8h.orig/ssl/ssl_err.c 2007-10-12 03:00:30.000000000 +0300
|
||||
+++ openssl-0.9.8h/ssl/ssl_err.c 2008-05-28 18:49:34.000000000 +0300
|
||||
@@ -251,6 +251,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"},
|
||||
{ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"},
|
||||
{ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"},
|
||||
+{ERR_FUNC(SSL_F_SSL_SET_HELLO_EXTENSION), "SSL_set_hello_extension"},
|
||||
{0,NULL}
|
||||
};
|
||||
|
||||
diff -upr openssl-0.9.8h.orig/ssl/ssl_sess.c openssl-0.9.8h/ssl/ssl_sess.c
|
||||
--- openssl-0.9.8h.orig/ssl/ssl_sess.c 2007-10-17 20:30:15.000000000 +0300
|
||||
+++ openssl-0.9.8h/ssl/ssl_sess.c 2008-05-28 18:49:34.000000000 +0300
|
||||
@@ -704,6 +704,52 @@ long SSL_CTX_get_timeout(const SSL_CTX *
|
||||
return(s->session_timeout);
|
||||
}
|
||||
|
||||
+#ifndef OPENSSL_NO_TLSEXT
|
||||
+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len,
|
||||
+ STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg)
|
||||
+{
|
||||
+ if (s == NULL) return(0);
|
||||
+ s->tls_session_secret_cb = tls_session_secret_cb;
|
||||
+ s->tls_session_secret_cb_arg = arg;
|
||||
+ return(1);
|
||||
+}
|
||||
+
|
||||
+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len)
|
||||
+{
|
||||
+ if(s->version >= TLS1_VERSION)
|
||||
+ {
|
||||
+ if(s->tls_extension)
|
||||
+ {
|
||||
+ OPENSSL_free(s->tls_extension);
|
||||
+ s->tls_extension = NULL;
|
||||
+ }
|
||||
+
|
||||
+ s->tls_extension = OPENSSL_malloc(sizeof(TLS_EXTENSION) + ext_len);
|
||||
+ if(!s->tls_extension)
|
||||
+ {
|
||||
+ SSLerr(SSL_F_SSL_SET_HELLO_EXTENSION, ERR_R_MALLOC_FAILURE);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ s->tls_extension->type = ext_type;
|
||||
+
|
||||
+ if(ext_data)
|
||||
+ {
|
||||
+ s->tls_extension->length = ext_len;
|
||||
+ s->tls_extension->data = s->tls_extension + 1;
|
||||
+ memcpy(s->tls_extension->data, ext_data, ext_len);
|
||||
+ } else {
|
||||
+ s->tls_extension->length = 0;
|
||||
+ s->tls_extension->data = NULL;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif /* OPENSSL_NO_TLSEXT */
|
||||
+
|
||||
typedef struct timeout_param_st
|
||||
{
|
||||
SSL_CTX *ctx;
|
||||
diff -upr openssl-0.9.8h.orig/ssl/t1_lib.c openssl-0.9.8h/ssl/t1_lib.c
|
||||
--- openssl-0.9.8h.orig/ssl/t1_lib.c 2008-05-28 10:26:33.000000000 +0300
|
||||
+++ openssl-0.9.8h/ssl/t1_lib.c 2008-05-28 18:49:34.000000000 +0300
|
||||
@@ -106,6 +106,12 @@ int tls1_new(SSL *s)
|
||||
|
||||
void tls1_free(SSL *s)
|
||||
{
|
||||
+#ifndef OPENSSL_NO_TLSEXT
|
||||
+ if(s->tls_extension)
|
||||
+ {
|
||||
+ OPENSSL_free(s->tls_extension);
|
||||
+ }
|
||||
+#endif
|
||||
ssl3_free(s);
|
||||
}
|
||||
|
||||
@@ -175,8 +181,24 @@ unsigned char *ssl_add_clienthello_tlsex
|
||||
int ticklen;
|
||||
if (s->session && s->session->tlsext_tick)
|
||||
ticklen = s->session->tlsext_ticklen;
|
||||
+ else if (s->session && s->tls_extension &&
|
||||
+ s->tls_extension->type == TLSEXT_TYPE_session_ticket &&
|
||||
+ s->tls_extension->data)
|
||||
+ {
|
||||
+ ticklen = s->tls_extension->length;
|
||||
+ s->session->tlsext_tick = OPENSSL_malloc(ticklen);
|
||||
+ if (!s->session->tlsext_tick)
|
||||
+ return NULL;
|
||||
+ memcpy(s->session->tlsext_tick, s->tls_extension->data,
|
||||
+ ticklen);
|
||||
+ s->session->tlsext_ticklen = ticklen;
|
||||
+ }
|
||||
else
|
||||
ticklen = 0;
|
||||
+ if (ticklen == 0 && s->tls_extension &&
|
||||
+ s->tls_extension->type == TLSEXT_TYPE_session_ticket &&
|
||||
+ s->tls_extension->data == NULL)
|
||||
+ goto skip_ext;
|
||||
/* Check for enough room 2 for extension type, 2 for len
|
||||
* rest for ticket
|
||||
*/
|
||||
@@ -190,6 +212,7 @@ unsigned char *ssl_add_clienthello_tlsex
|
||||
ret += ticklen;
|
||||
}
|
||||
}
|
||||
+ skip_ext:
|
||||
|
||||
if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
|
||||
{
|
||||
@@ -774,6 +797,8 @@ int tls1_process_ticket(SSL *s, unsigned
|
||||
s->tlsext_ticket_expected = 1;
|
||||
return 0; /* Cache miss */
|
||||
}
|
||||
+ if (s->tls_session_secret_cb)
|
||||
+ return 0;
|
||||
return tls_decrypt_ticket(s, p, size, session_id, len,
|
||||
ret);
|
||||
}
|
||||
diff -upr openssl-0.9.8h.orig/ssl/tls1.h openssl-0.9.8h/ssl/tls1.h
|
||||
--- openssl-0.9.8h.orig/ssl/tls1.h 2008-04-30 19:11:33.000000000 +0300
|
||||
+++ openssl-0.9.8h/ssl/tls1.h 2008-05-28 18:49:34.000000000 +0300
|
||||
@@ -398,6 +398,14 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_T
|
||||
#define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/
|
||||
#endif
|
||||
|
||||
+/* TLS extension struct */
|
||||
+struct tls_extension_st
|
||||
+{
|
||||
+ unsigned short type;
|
||||
+ unsigned short length;
|
||||
+ void *data;
|
||||
+};
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff -upr openssl-0.9.8h.orig/util/ssleay.num openssl-0.9.8h/util/ssleay.num
|
||||
--- openssl-0.9.8h.orig/util/ssleay.num 2007-08-13 01:31:16.000000000 +0300
|
||||
+++ openssl-0.9.8h/util/ssleay.num 2008-05-28 18:49:34.000000000 +0300
|
||||
@@ -241,3 +241,5 @@ SSL_CTX_sess_get_remove_cb
|
||||
SSL_set_SSL_CTX 290 EXIST::FUNCTION:
|
||||
SSL_get_servername 291 EXIST::FUNCTION:TLSEXT
|
||||
SSL_get_servername_type 292 EXIST::FUNCTION:TLSEXT
|
||||
+SSL_set_hello_extension 305 EXIST::FUNCTION:TLSEXT
|
||||
+SSL_set_session_secret_cb 306 EXIST::FUNCTION:TLSEXT
|
404
contrib/wpa/patches/openssl-0.9.8i-tls-extensions.patch
Normal file
404
contrib/wpa/patches/openssl-0.9.8i-tls-extensions.patch
Normal file
@ -0,0 +1,404 @@
|
||||
This patch adds support for TLS SessionTicket extension (RFC 5077) for
|
||||
the parts used by EAP-FAST (RFC 4851).
|
||||
|
||||
This is based on the patch from Alexey Kobozev <akobozev@cisco.com>
|
||||
(sent to openssl-dev mailing list on Tue, 07 Jun 2005 15:40:58 +0300).
|
||||
|
||||
OpenSSL 0.9.8i does not enable TLS extension support by default, so it
|
||||
will need to be enabled by adding enable-tlsext to config script
|
||||
command line.
|
||||
|
||||
|
||||
Index: openssl-0.9.8i/ssl/s3_clnt.c
|
||||
===================================================================
|
||||
--- openssl-0.9.8i.orig/ssl/s3_clnt.c 2008-06-16 19:56:41.000000000 +0300
|
||||
+++ openssl-0.9.8i/ssl/s3_clnt.c 2008-11-23 20:39:40.000000000 +0200
|
||||
@@ -759,6 +759,21 @@
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
+#ifndef OPENSSL_NO_TLSEXT
|
||||
+ /* check if we want to resume the session based on external pre-shared secret */
|
||||
+ if (s->version >= TLS1_VERSION && s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ SSL_CIPHER *pref_cipher=NULL;
|
||||
+ s->session->master_key_length=sizeof(s->session->master_key);
|
||||
+ if (s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
|
||||
+ NULL, &pref_cipher, s->tls_session_secret_cb_arg))
|
||||
+ {
|
||||
+ s->session->cipher=pref_cipher ?
|
||||
+ pref_cipher : ssl_get_cipher_by_char(s,p+j);
|
||||
+ }
|
||||
+ }
|
||||
+#endif /* OPENSSL_NO_TLSEXT */
|
||||
+
|
||||
if (j != 0 && j == s->session->session_id_length
|
||||
&& memcmp(p,s->session->session_id,j) == 0)
|
||||
{
|
||||
@@ -2701,11 +2716,8 @@
|
||||
{
|
||||
int ok;
|
||||
long n;
|
||||
- /* If we have no ticket or session ID is non-zero length (a match of
|
||||
- * a non-zero session length would never reach here) it cannot be a
|
||||
- * resumed session.
|
||||
- */
|
||||
- if (!s->session->tlsext_tick || s->session->session_id_length)
|
||||
+ /* If we have no ticket it cannot be a resumed session. */
|
||||
+ if (!s->session->tlsext_tick)
|
||||
return 1;
|
||||
/* this function is called when we really expect a Certificate
|
||||
* message, so permit appropriate message length */
|
||||
Index: openssl-0.9.8i/ssl/s3_srvr.c
|
||||
===================================================================
|
||||
--- openssl-0.9.8i.orig/ssl/s3_srvr.c 2008-09-14 21:16:09.000000000 +0300
|
||||
+++ openssl-0.9.8i/ssl/s3_srvr.c 2008-11-23 20:37:40.000000000 +0200
|
||||
@@ -959,6 +959,59 @@
|
||||
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
|
||||
goto err;
|
||||
}
|
||||
+
|
||||
+ /* Check if we want to use external pre-shared secret for this
|
||||
+ * handshake for not reused session only. We need to generate
|
||||
+ * server_random before calling tls_session_secret_cb in order to allow
|
||||
+ * SessionTicket processing to use it in key derivation. */
|
||||
+ {
|
||||
+ unsigned long Time;
|
||||
+ unsigned char *pos;
|
||||
+ Time=(unsigned long)time(NULL); /* Time */
|
||||
+ pos=s->s3->server_random;
|
||||
+ l2n(Time,pos);
|
||||
+ if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0)
|
||||
+ {
|
||||
+ al=SSL_AD_INTERNAL_ERROR;
|
||||
+ goto f_err;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ SSL_CIPHER *pref_cipher=NULL;
|
||||
+
|
||||
+ s->session->master_key_length=sizeof(s->session->master_key);
|
||||
+ if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
|
||||
+ ciphers, &pref_cipher, s->tls_session_secret_cb_arg))
|
||||
+ {
|
||||
+ s->hit=1;
|
||||
+ s->session->ciphers=ciphers;
|
||||
+ s->session->verify_result=X509_V_OK;
|
||||
+
|
||||
+ ciphers=NULL;
|
||||
+
|
||||
+ /* check if some cipher was preferred by call back */
|
||||
+ pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
|
||||
+ if (pref_cipher == NULL)
|
||||
+ {
|
||||
+ al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
|
||||
+ goto f_err;
|
||||
+ }
|
||||
+
|
||||
+ s->session->cipher=pref_cipher;
|
||||
+
|
||||
+ if (s->cipher_list)
|
||||
+ sk_SSL_CIPHER_free(s->cipher_list);
|
||||
+
|
||||
+ if (s->cipher_list_by_id)
|
||||
+ sk_SSL_CIPHER_free(s->cipher_list_by_id);
|
||||
+
|
||||
+ s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
+ s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
+ }
|
||||
+ }
|
||||
#endif
|
||||
/* Worst case, we will use the NULL compression, but if we have other
|
||||
* options, we will now look for them. We have i-1 compression
|
||||
@@ -1097,16 +1150,22 @@
|
||||
unsigned char *buf;
|
||||
unsigned char *p,*d;
|
||||
int i,sl;
|
||||
- unsigned long l,Time;
|
||||
+ unsigned long l;
|
||||
+#ifdef OPENSSL_NO_TLSEXT
|
||||
+ unsigned long Time;
|
||||
+#endif
|
||||
|
||||
if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
|
||||
{
|
||||
buf=(unsigned char *)s->init_buf->data;
|
||||
+#ifdef OPENSSL_NO_TLSEXT
|
||||
p=s->s3->server_random;
|
||||
+ /* Generate server_random if it was not needed previously */
|
||||
Time=(unsigned long)time(NULL); /* Time */
|
||||
l2n(Time,p);
|
||||
if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
|
||||
return -1;
|
||||
+#endif
|
||||
/* Do the message type and length last */
|
||||
d=p= &(buf[4]);
|
||||
|
||||
Index: openssl-0.9.8i/ssl/ssl_err.c
|
||||
===================================================================
|
||||
--- openssl-0.9.8i.orig/ssl/ssl_err.c 2008-08-13 22:44:44.000000000 +0300
|
||||
+++ openssl-0.9.8i/ssl/ssl_err.c 2008-11-23 20:33:43.000000000 +0200
|
||||
@@ -253,6 +253,7 @@
|
||||
{ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"},
|
||||
{ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"},
|
||||
{ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"},
|
||||
+{ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT), "SSL_set_session_ticket_ext"},
|
||||
{0,NULL}
|
||||
};
|
||||
|
||||
Index: openssl-0.9.8i/ssl/ssl.h
|
||||
===================================================================
|
||||
--- openssl-0.9.8i.orig/ssl/ssl.h 2008-08-13 22:44:44.000000000 +0300
|
||||
+++ openssl-0.9.8i/ssl/ssl.h 2008-11-23 20:35:41.000000000 +0200
|
||||
@@ -344,6 +344,7 @@
|
||||
* 'struct ssl_st *' function parameters used to prototype callbacks
|
||||
* in SSL_CTX. */
|
||||
typedef struct ssl_st *ssl_crock_st;
|
||||
+typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT;
|
||||
|
||||
/* used to hold info on the particular ciphers used */
|
||||
typedef struct ssl_cipher_st
|
||||
@@ -362,6 +363,9 @@
|
||||
|
||||
DECLARE_STACK_OF(SSL_CIPHER)
|
||||
|
||||
+typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, int len, void *arg);
|
||||
+typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
|
||||
+
|
||||
/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
|
||||
typedef struct ssl_method_st
|
||||
{
|
||||
@@ -1034,6 +1038,18 @@
|
||||
|
||||
/* RFC4507 session ticket expected to be received or sent */
|
||||
int tlsext_ticket_expected;
|
||||
+
|
||||
+ /* TLS Session Ticket extension override */
|
||||
+ TLS_SESSION_TICKET_EXT *tlsext_session_ticket;
|
||||
+
|
||||
+ /* TLS Session Ticket extension callback */
|
||||
+ tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb;
|
||||
+ void *tls_session_ticket_ext_cb_arg;
|
||||
+
|
||||
+ /* TLS pre-shared secret session resumption */
|
||||
+ tls_session_secret_cb_fn tls_session_secret_cb;
|
||||
+ void *tls_session_secret_cb_arg;
|
||||
+
|
||||
SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
|
||||
#define session_ctx initial_ctx
|
||||
#else
|
||||
@@ -1632,6 +1648,15 @@
|
||||
int SSL_COMP_add_compression_method(int id,void *cm);
|
||||
#endif
|
||||
|
||||
+/* TLS extensions functions */
|
||||
+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);
|
||||
+
|
||||
+int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
|
||||
+ void *arg);
|
||||
+
|
||||
+/* Pre-shared secret session resumption functions */
|
||||
+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
|
||||
+
|
||||
/* BEGIN ERROR CODES */
|
||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||
* made after this point may be overwritten when the script is next run.
|
||||
@@ -1824,6 +1849,7 @@
|
||||
#define SSL_F_TLS1_ENC 210
|
||||
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211
|
||||
#define SSL_F_WRITE_PENDING 212
|
||||
+#define SSL_F_SSL_SET_SESSION_TICKET_EXT 213
|
||||
|
||||
/* Reason codes. */
|
||||
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
|
||||
Index: openssl-0.9.8i/ssl/ssl_sess.c
|
||||
===================================================================
|
||||
--- openssl-0.9.8i.orig/ssl/ssl_sess.c 2008-06-04 21:35:27.000000000 +0300
|
||||
+++ openssl-0.9.8i/ssl/ssl_sess.c 2008-11-23 20:32:24.000000000 +0200
|
||||
@@ -707,6 +707,61 @@
|
||||
return(s->session_timeout);
|
||||
}
|
||||
|
||||
+#ifndef OPENSSL_NO_TLSEXT
|
||||
+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len,
|
||||
+ STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg)
|
||||
+ {
|
||||
+ if (s == NULL) return(0);
|
||||
+ s->tls_session_secret_cb = tls_session_secret_cb;
|
||||
+ s->tls_session_secret_cb_arg = arg;
|
||||
+ return(1);
|
||||
+ }
|
||||
+
|
||||
+int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
|
||||
+ void *arg)
|
||||
+ {
|
||||
+ if (s == NULL) return(0);
|
||||
+ s->tls_session_ticket_ext_cb = cb;
|
||||
+ s->tls_session_ticket_ext_cb_arg = arg;
|
||||
+ return(1);
|
||||
+ }
|
||||
+
|
||||
+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len)
|
||||
+ {
|
||||
+ if (s->version >= TLS1_VERSION)
|
||||
+ {
|
||||
+ if (s->tlsext_session_ticket)
|
||||
+ {
|
||||
+ OPENSSL_free(s->tlsext_session_ticket);
|
||||
+ s->tlsext_session_ticket = NULL;
|
||||
+ }
|
||||
+
|
||||
+ s->tlsext_session_ticket = OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len);
|
||||
+ if (!s->tlsext_session_ticket)
|
||||
+ {
|
||||
+ SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (ext_data)
|
||||
+ {
|
||||
+ s->tlsext_session_ticket->length = ext_len;
|
||||
+ s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1;
|
||||
+ memcpy(s->tlsext_session_ticket->data, ext_data, ext_len);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ s->tlsext_session_ticket->length = 0;
|
||||
+ s->tlsext_session_ticket->data = NULL;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+ }
|
||||
+#endif /* OPENSSL_NO_TLSEXT */
|
||||
+
|
||||
typedef struct timeout_param_st
|
||||
{
|
||||
SSL_CTX *ctx;
|
||||
Index: openssl-0.9.8i/ssl/t1_lib.c
|
||||
===================================================================
|
||||
--- openssl-0.9.8i.orig/ssl/t1_lib.c 2008-09-04 01:13:04.000000000 +0300
|
||||
+++ openssl-0.9.8i/ssl/t1_lib.c 2008-11-23 20:31:20.000000000 +0200
|
||||
@@ -106,6 +106,12 @@
|
||||
|
||||
void tls1_free(SSL *s)
|
||||
{
|
||||
+#ifndef OPENSSL_NO_TLSEXT
|
||||
+ if (s->tlsext_session_ticket)
|
||||
+ {
|
||||
+ OPENSSL_free(s->tlsext_session_ticket);
|
||||
+ }
|
||||
+#endif
|
||||
ssl3_free(s);
|
||||
}
|
||||
|
||||
@@ -175,8 +181,23 @@
|
||||
int ticklen;
|
||||
if (s->session && s->session->tlsext_tick)
|
||||
ticklen = s->session->tlsext_ticklen;
|
||||
+ else if (s->session && s->tlsext_session_ticket &&
|
||||
+ s->tlsext_session_ticket->data)
|
||||
+ {
|
||||
+ ticklen = s->tlsext_session_ticket->length;
|
||||
+ s->session->tlsext_tick = OPENSSL_malloc(ticklen);
|
||||
+ if (!s->session->tlsext_tick)
|
||||
+ return NULL;
|
||||
+ memcpy(s->session->tlsext_tick,
|
||||
+ s->tlsext_session_ticket->data,
|
||||
+ ticklen);
|
||||
+ s->session->tlsext_ticklen = ticklen;
|
||||
+ }
|
||||
else
|
||||
ticklen = 0;
|
||||
+ if (ticklen == 0 && s->tlsext_session_ticket &&
|
||||
+ s->tlsext_session_ticket->data == NULL)
|
||||
+ goto skip_ext;
|
||||
/* Check for enough room 2 for extension type, 2 for len
|
||||
* rest for ticket
|
||||
*/
|
||||
@@ -190,6 +211,7 @@
|
||||
ret += ticklen;
|
||||
}
|
||||
}
|
||||
+ skip_ext:
|
||||
|
||||
if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
|
||||
{
|
||||
@@ -407,6 +429,15 @@
|
||||
}
|
||||
|
||||
}
|
||||
+ else if (type == TLSEXT_TYPE_session_ticket)
|
||||
+ {
|
||||
+ if (s->tls_session_ticket_ext_cb &&
|
||||
+ !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg))
|
||||
+ {
|
||||
+ *al = TLS1_AD_INTERNAL_ERROR;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
else if (type == TLSEXT_TYPE_status_request
|
||||
&& s->ctx->tlsext_status_cb)
|
||||
{
|
||||
@@ -553,6 +584,12 @@
|
||||
}
|
||||
else if (type == TLSEXT_TYPE_session_ticket)
|
||||
{
|
||||
+ if (s->tls_session_ticket_ext_cb &&
|
||||
+ !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg))
|
||||
+ {
|
||||
+ *al = TLS1_AD_INTERNAL_ERROR;
|
||||
+ return 0;
|
||||
+ }
|
||||
if ((SSL_get_options(s) & SSL_OP_NO_TICKET)
|
||||
|| (size > 0))
|
||||
{
|
||||
@@ -776,6 +813,15 @@
|
||||
s->tlsext_ticket_expected = 1;
|
||||
return 0; /* Cache miss */
|
||||
}
|
||||
+ if (s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ /* Indicate cache miss here and instead of
|
||||
+ * generating the session from ticket now,
|
||||
+ * trigger abbreviated handshake based on
|
||||
+ * external mechanism to calculate the master
|
||||
+ * secret later. */
|
||||
+ return 0;
|
||||
+ }
|
||||
return tls_decrypt_ticket(s, p, size, session_id, len,
|
||||
ret);
|
||||
}
|
||||
Index: openssl-0.9.8i/ssl/tls1.h
|
||||
===================================================================
|
||||
--- openssl-0.9.8i.orig/ssl/tls1.h 2008-04-30 19:11:33.000000000 +0300
|
||||
+++ openssl-0.9.8i/ssl/tls1.h 2008-11-23 20:22:38.000000000 +0200
|
||||
@@ -398,6 +398,13 @@
|
||||
#define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/
|
||||
#endif
|
||||
|
||||
+/* TLS extension struct */
|
||||
+struct tls_session_ticket_ext_st
|
||||
+ {
|
||||
+ unsigned short length;
|
||||
+ void *data;
|
||||
+ };
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Index: openssl-0.9.8i/util/ssleay.num
|
||||
===================================================================
|
||||
--- openssl-0.9.8i.orig/util/ssleay.num 2008-06-05 13:57:21.000000000 +0300
|
||||
+++ openssl-0.9.8i/util/ssleay.num 2008-11-23 20:22:05.000000000 +0200
|
||||
@@ -242,3 +242,5 @@
|
||||
SSL_get_servername 291 EXIST::FUNCTION:TLSEXT
|
||||
SSL_get_servername_type 292 EXIST::FUNCTION:TLSEXT
|
||||
SSL_CTX_set_client_cert_engine 293 EXIST::FUNCTION:ENGINE
|
||||
+SSL_set_session_ticket_ext 306 EXIST::FUNCTION:TLSEXT
|
||||
+SSL_set_session_secret_cb 307 EXIST::FUNCTION:TLSEXT
|
374
contrib/wpa/patches/openssl-0.9.9-session-ticket.patch
Normal file
374
contrib/wpa/patches/openssl-0.9.9-session-ticket.patch
Normal file
@ -0,0 +1,374 @@
|
||||
This patch adds support for TLS SessionTicket extension (RFC 5077) for
|
||||
the parts used by EAP-FAST (RFC 4851).
|
||||
|
||||
This is based on the patch from Alexey Kobozev <akobozev@cisco.com>
|
||||
(sent to openssl-dev mailing list on Tue, 07 Jun 2005 15:40:58 +0300).
|
||||
|
||||
NOTE: This patch (without SSL_set_hello_extension() wrapper) was
|
||||
merged into the upstream OpenSSL 0.9.9 tree and as such, an external
|
||||
patch for EAP-FAST support is not needed anymore.
|
||||
|
||||
|
||||
|
||||
Index: openssl-SNAP-20081111/ssl/s3_clnt.c
|
||||
===================================================================
|
||||
--- openssl-SNAP-20081111.orig/ssl/s3_clnt.c
|
||||
+++ openssl-SNAP-20081111/ssl/s3_clnt.c
|
||||
@@ -788,6 +788,23 @@ int ssl3_get_server_hello(SSL *s)
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
+#ifndef OPENSSL_NO_TLSEXT
|
||||
+ /* check if we want to resume the session based on external pre-shared secret */
|
||||
+ if (s->version >= TLS1_VERSION && s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ SSL_CIPHER *pref_cipher=NULL;
|
||||
+ s->session->master_key_length=sizeof(s->session->master_key);
|
||||
+ if (s->tls_session_secret_cb(s, s->session->master_key,
|
||||
+ &s->session->master_key_length,
|
||||
+ NULL, &pref_cipher,
|
||||
+ s->tls_session_secret_cb_arg))
|
||||
+ {
|
||||
+ s->session->cipher = pref_cipher ?
|
||||
+ pref_cipher : ssl_get_cipher_by_char(s, p+j);
|
||||
+ }
|
||||
+ }
|
||||
+#endif /* OPENSSL_NO_TLSEXT */
|
||||
+
|
||||
if (j != 0 && j == s->session->session_id_length
|
||||
&& memcmp(p,s->session->session_id,j) == 0)
|
||||
{
|
||||
@@ -2927,11 +2944,8 @@ static int ssl3_check_finished(SSL *s)
|
||||
{
|
||||
int ok;
|
||||
long n;
|
||||
- /* If we have no ticket or session ID is non-zero length (a match of
|
||||
- * a non-zero session length would never reach here) it cannot be a
|
||||
- * resumed session.
|
||||
- */
|
||||
- if (!s->session->tlsext_tick || s->session->session_id_length)
|
||||
+ /* If we have no ticket it cannot be a resumed session. */
|
||||
+ if (!s->session->tlsext_tick)
|
||||
return 1;
|
||||
/* this function is called when we really expect a Certificate
|
||||
* message, so permit appropriate message length */
|
||||
Index: openssl-SNAP-20081111/ssl/s3_srvr.c
|
||||
===================================================================
|
||||
--- openssl-SNAP-20081111.orig/ssl/s3_srvr.c
|
||||
+++ openssl-SNAP-20081111/ssl/s3_srvr.c
|
||||
@@ -1010,6 +1010,59 @@ int ssl3_get_client_hello(SSL *s)
|
||||
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
|
||||
goto err;
|
||||
}
|
||||
+
|
||||
+ /* Check if we want to use external pre-shared secret for this
|
||||
+ * handshake for not reused session only. We need to generate
|
||||
+ * server_random before calling tls_session_secret_cb in order to allow
|
||||
+ * SessionTicket processing to use it in key derivation. */
|
||||
+ {
|
||||
+ unsigned long Time;
|
||||
+ unsigned char *pos;
|
||||
+ Time=(unsigned long)time(NULL); /* Time */
|
||||
+ pos=s->s3->server_random;
|
||||
+ l2n(Time,pos);
|
||||
+ if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0)
|
||||
+ {
|
||||
+ al=SSL_AD_INTERNAL_ERROR;
|
||||
+ goto f_err;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ SSL_CIPHER *pref_cipher=NULL;
|
||||
+
|
||||
+ s->session->master_key_length=sizeof(s->session->master_key);
|
||||
+ if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
|
||||
+ ciphers, &pref_cipher, s->tls_session_secret_cb_arg))
|
||||
+ {
|
||||
+ s->hit=1;
|
||||
+ s->session->ciphers=ciphers;
|
||||
+ s->session->verify_result=X509_V_OK;
|
||||
+
|
||||
+ ciphers=NULL;
|
||||
+
|
||||
+ /* check if some cipher was preferred by call back */
|
||||
+ pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
|
||||
+ if (pref_cipher == NULL)
|
||||
+ {
|
||||
+ al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
|
||||
+ goto f_err;
|
||||
+ }
|
||||
+
|
||||
+ s->session->cipher=pref_cipher;
|
||||
+
|
||||
+ if (s->cipher_list)
|
||||
+ sk_SSL_CIPHER_free(s->cipher_list);
|
||||
+
|
||||
+ if (s->cipher_list_by_id)
|
||||
+ sk_SSL_CIPHER_free(s->cipher_list_by_id);
|
||||
+
|
||||
+ s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
+ s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
|
||||
+ }
|
||||
+ }
|
||||
#endif
|
||||
|
||||
/* Worst case, we will use the NULL compression, but if we have other
|
||||
@@ -1134,16 +1187,22 @@ int ssl3_send_server_hello(SSL *s)
|
||||
unsigned char *buf;
|
||||
unsigned char *p,*d;
|
||||
int i,sl;
|
||||
- unsigned long l,Time;
|
||||
+ unsigned long l;
|
||||
+#ifdef OPENSSL_NO_TLSEXT
|
||||
+ unsigned long Time;
|
||||
+#endif
|
||||
|
||||
if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
|
||||
{
|
||||
buf=(unsigned char *)s->init_buf->data;
|
||||
+#ifdef OPENSSL_NO_TLSEXT
|
||||
p=s->s3->server_random;
|
||||
+ /* Generate server_random if it was not needed previously */
|
||||
Time=(unsigned long)time(NULL); /* Time */
|
||||
l2n(Time,p);
|
||||
if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
|
||||
return -1;
|
||||
+#endif
|
||||
/* Do the message type and length last */
|
||||
d=p= &(buf[4]);
|
||||
|
||||
Index: openssl-SNAP-20081111/ssl/ssl_err.c
|
||||
===================================================================
|
||||
--- openssl-SNAP-20081111.orig/ssl/ssl_err.c
|
||||
+++ openssl-SNAP-20081111/ssl/ssl_err.c
|
||||
@@ -263,6 +263,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"},
|
||||
{ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"},
|
||||
{ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"},
|
||||
+{ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT), "SSL_set_session_ticket_ext"},
|
||||
{0,NULL}
|
||||
};
|
||||
|
||||
Index: openssl-SNAP-20081111/ssl/ssl.h
|
||||
===================================================================
|
||||
--- openssl-SNAP-20081111.orig/ssl/ssl.h
|
||||
+++ openssl-SNAP-20081111/ssl/ssl.h
|
||||
@@ -355,6 +355,7 @@ extern "C" {
|
||||
* 'struct ssl_st *' function parameters used to prototype callbacks
|
||||
* in SSL_CTX. */
|
||||
typedef struct ssl_st *ssl_crock_st;
|
||||
+typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT;
|
||||
|
||||
/* used to hold info on the particular ciphers used */
|
||||
typedef struct ssl_cipher_st
|
||||
@@ -378,6 +379,8 @@ typedef struct ssl_cipher_st
|
||||
|
||||
DECLARE_STACK_OF(SSL_CIPHER)
|
||||
|
||||
+typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
|
||||
+
|
||||
/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
|
||||
typedef struct ssl_method_st
|
||||
{
|
||||
@@ -1145,6 +1148,13 @@ struct ssl_st
|
||||
void *tlsext_opaque_prf_input;
|
||||
size_t tlsext_opaque_prf_input_len;
|
||||
|
||||
+ /* TLS Session Ticket extension override */
|
||||
+ TLS_SESSION_TICKET_EXT *tlsext_session_ticket;
|
||||
+
|
||||
+ /* TLS pre-shared secret session resumption */
|
||||
+ tls_session_secret_cb_fn tls_session_secret_cb;
|
||||
+ void *tls_session_secret_cb_arg;
|
||||
+
|
||||
SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
|
||||
#define session_ctx initial_ctx
|
||||
#else
|
||||
@@ -1746,6 +1756,16 @@ void *SSL_COMP_get_compression_methods(v
|
||||
int SSL_COMP_add_compression_method(int id,void *cm);
|
||||
#endif
|
||||
|
||||
+/* NOTE: This function will be removed; it is only here for backwards
|
||||
+ * compatibility for the API during testing. */
|
||||
+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len);
|
||||
+
|
||||
+/* TLS extensions functions */
|
||||
+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);
|
||||
+
|
||||
+/* Pre-shared secret session resumption functions */
|
||||
+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
|
||||
+
|
||||
/* BEGIN ERROR CODES */
|
||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||
* made after this point may be overwritten when the script is next run.
|
||||
@@ -1948,6 +1968,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_TLS1_PRF 284
|
||||
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211
|
||||
#define SSL_F_WRITE_PENDING 212
|
||||
+#define SSL_F_SSL_SET_SESSION_TICKET_EXT 213
|
||||
|
||||
/* Reason codes. */
|
||||
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
|
||||
Index: openssl-SNAP-20081111/ssl/ssl_sess.c
|
||||
===================================================================
|
||||
--- openssl-SNAP-20081111.orig/ssl/ssl_sess.c
|
||||
+++ openssl-SNAP-20081111/ssl/ssl_sess.c
|
||||
@@ -834,6 +834,62 @@ long SSL_CTX_get_timeout(const SSL_CTX *
|
||||
return(s->session_timeout);
|
||||
}
|
||||
|
||||
+#ifndef OPENSSL_NO_TLSEXT
|
||||
+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len,
|
||||
+ STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg)
|
||||
+ {
|
||||
+ if (s == NULL) return(0);
|
||||
+ s->tls_session_secret_cb = tls_session_secret_cb;
|
||||
+ s->tls_session_secret_cb_arg = arg;
|
||||
+ return(1);
|
||||
+ }
|
||||
+
|
||||
+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len)
|
||||
+ {
|
||||
+ if (s->version >= TLS1_VERSION)
|
||||
+ {
|
||||
+ if (s->tlsext_session_ticket)
|
||||
+ {
|
||||
+ OPENSSL_free(s->tlsext_session_ticket);
|
||||
+ s->tlsext_session_ticket = NULL;
|
||||
+ }
|
||||
+
|
||||
+ s->tlsext_session_ticket = OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len);
|
||||
+ if (!s->tlsext_session_ticket)
|
||||
+ {
|
||||
+ SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (ext_data)
|
||||
+ {
|
||||
+ s->tlsext_session_ticket->length = ext_len;
|
||||
+ s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1;
|
||||
+ memcpy(s->tlsext_session_ticket->data, ext_data, ext_len);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ s->tlsext_session_ticket->length = 0;
|
||||
+ s->tlsext_session_ticket->data = NULL;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+/* NOTE: This function will be removed; it is only here for backwards
|
||||
+ * compatibility for the API during testing. */
|
||||
+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len)
|
||||
+ {
|
||||
+ if (ext_type != TLSEXT_TYPE_session_ticket)
|
||||
+ return 0;
|
||||
+
|
||||
+ return SSL_set_session_ticket_ext(s, ext_data, ext_len);
|
||||
+ }
|
||||
+#endif /* OPENSSL_NO_TLSEXT */
|
||||
+
|
||||
typedef struct timeout_param_st
|
||||
{
|
||||
SSL_CTX *ctx;
|
||||
Index: openssl-SNAP-20081111/ssl/t1_lib.c
|
||||
===================================================================
|
||||
--- openssl-SNAP-20081111.orig/ssl/t1_lib.c
|
||||
+++ openssl-SNAP-20081111/ssl/t1_lib.c
|
||||
@@ -154,6 +154,12 @@ int tls1_new(SSL *s)
|
||||
|
||||
void tls1_free(SSL *s)
|
||||
{
|
||||
+#ifndef OPENSSL_NO_TLSEXT
|
||||
+ if (s->tlsext_session_ticket)
|
||||
+ {
|
||||
+ OPENSSL_free(s->tlsext_session_ticket);
|
||||
+ }
|
||||
+#endif /* OPENSSL_NO_TLSEXT */
|
||||
ssl3_free(s);
|
||||
}
|
||||
|
||||
@@ -357,8 +363,23 @@ unsigned char *ssl_add_clienthello_tlsex
|
||||
int ticklen;
|
||||
if (s->session && s->session->tlsext_tick)
|
||||
ticklen = s->session->tlsext_ticklen;
|
||||
+ else if (s->session && s->tlsext_session_ticket &&
|
||||
+ s->tlsext_session_ticket->data)
|
||||
+ {
|
||||
+ ticklen = s->tlsext_session_ticket->length;
|
||||
+ s->session->tlsext_tick = OPENSSL_malloc(ticklen);
|
||||
+ if (!s->session->tlsext_tick)
|
||||
+ return NULL;
|
||||
+ memcpy(s->session->tlsext_tick,
|
||||
+ s->tlsext_session_ticket->data,
|
||||
+ ticklen);
|
||||
+ s->session->tlsext_ticklen = ticklen;
|
||||
+ }
|
||||
else
|
||||
ticklen = 0;
|
||||
+ if (ticklen == 0 && s->tlsext_session_ticket &&
|
||||
+ s->tlsext_session_ticket->data == NULL)
|
||||
+ goto skip_ext;
|
||||
/* Check for enough room 2 for extension type, 2 for len
|
||||
* rest for ticket
|
||||
*/
|
||||
@@ -371,6 +392,7 @@ unsigned char *ssl_add_clienthello_tlsex
|
||||
ret += ticklen;
|
||||
}
|
||||
}
|
||||
+ skip_ext:
|
||||
|
||||
#ifdef TLSEXT_TYPE_opaque_prf_input
|
||||
if (s->s3->client_opaque_prf_input != NULL)
|
||||
@@ -1435,6 +1457,15 @@ int tls1_process_ticket(SSL *s, unsigned
|
||||
s->tlsext_ticket_expected = 1;
|
||||
return 0; /* Cache miss */
|
||||
}
|
||||
+ if (s->tls_session_secret_cb)
|
||||
+ {
|
||||
+ /* Indicate cache miss here and instead of
|
||||
+ * generating the session from ticket now,
|
||||
+ * trigger abbreviated handshake based on
|
||||
+ * external mechanism to calculate the master
|
||||
+ * secret later. */
|
||||
+ return 0;
|
||||
+ }
|
||||
return tls_decrypt_ticket(s, p, size, session_id, len,
|
||||
ret);
|
||||
}
|
||||
Index: openssl-SNAP-20081111/ssl/tls1.h
|
||||
===================================================================
|
||||
--- openssl-SNAP-20081111.orig/ssl/tls1.h
|
||||
+++ openssl-SNAP-20081111/ssl/tls1.h
|
||||
@@ -512,6 +512,13 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_T
|
||||
#define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/
|
||||
#endif
|
||||
|
||||
+/* TLS Session Ticket extension struct */
|
||||
+struct tls_session_ticket_ext_st
|
||||
+ {
|
||||
+ unsigned short length;
|
||||
+ void *data;
|
||||
+ };
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Index: openssl-SNAP-20081111/util/ssleay.num
|
||||
===================================================================
|
||||
--- openssl-SNAP-20081111.orig/util/ssleay.num
|
||||
+++ openssl-SNAP-20081111/util/ssleay.num
|
||||
@@ -254,3 +254,5 @@ PEM_read_bio_SSL_SESSION
|
||||
SSL_CTX_set_psk_server_callback 303 EXIST::FUNCTION:PSK
|
||||
SSL_get_psk_identity 304 EXIST::FUNCTION:PSK
|
||||
PEM_write_SSL_SESSION 305 EXIST:!WIN16:FUNCTION:
|
||||
+SSL_set_session_ticket_ext 306 EXIST::FUNCTION:TLSEXT
|
||||
+SSL_set_session_secret_cb 307 EXIST::FUNCTION:TLSEXT
|
@ -1,7 +1,7 @@
|
||||
SUBDIRS=common crypto drivers hlr_auc_gw eapol_supp eap_common eap_peer eap_server l2_packet radius rsn_supp tls utils wps
|
||||
SUBDIRS=ap common crypto drivers eapol_auth eapol_supp eap_common eap_peer eap_server l2_packet radius rsn_supp tls utils wps
|
||||
|
||||
all:
|
||||
@echo Nothing to be made.
|
||||
for d in $(SUBDIRS); do [ -d $$d ] && $(MAKE) -C $$d; done
|
||||
|
||||
clean:
|
||||
for d in $(SUBDIRS); do [ -d $$d ] && $(MAKE) -C $$d clean; done
|
||||
|
@ -2,7 +2,6 @@ all:
|
||||
@echo Nothing to be made.
|
||||
|
||||
clean:
|
||||
for d in $(SUBDIRS); do make -C $$d clean; done
|
||||
rm -f *~ *.o *.d
|
||||
|
||||
install:
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / RADIUS Accounting
|
||||
* Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
|
||||
* 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
|
||||
@ -12,15 +12,18 @@
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "hostapd.h"
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "drivers/driver.h"
|
||||
#include "radius/radius.h"
|
||||
#include "radius/radius_client.h"
|
||||
#include "eloop.h"
|
||||
#include "accounting.h"
|
||||
#include "hostapd.h"
|
||||
#include "ieee802_1x.h"
|
||||
#include "driver.h"
|
||||
#include "ap_config.h"
|
||||
#include "sta_info.h"
|
||||
#include "accounting.h"
|
||||
|
||||
|
||||
/* Default interval in seconds for polling TX/RX octets from the driver if
|
||||
@ -175,7 +178,6 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
|
||||
|
||||
fail:
|
||||
radius_msg_free(msg);
|
||||
os_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -184,7 +186,7 @@ static int accounting_sta_update_stats(struct hostapd_data *hapd,
|
||||
struct sta_info *sta,
|
||||
struct hostap_sta_driver_data *data)
|
||||
{
|
||||
if (hostapd_read_sta_data(hapd, data, sta->addr))
|
||||
if (hapd->drv.read_sta_data(hapd, data, sta->addr))
|
||||
return -1;
|
||||
|
||||
if (sta->last_rx_bytes > data->rx_bytes)
|
||||
@ -247,7 +249,7 @@ void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
time(&sta->acct_session_start);
|
||||
sta->last_rx_bytes = sta->last_tx_bytes = 0;
|
||||
sta->acct_input_gigawords = sta->acct_output_gigawords = 0;
|
||||
hostapd_sta_clear_stats(hapd, sta->addr);
|
||||
hapd->drv.sta_clear_stats(hapd, sta->addr);
|
||||
|
||||
if (!hapd->conf->radius->acct_server)
|
||||
return;
|
||||
@ -364,7 +366,6 @@ static void accounting_sta_report(struct hostapd_data *hapd,
|
||||
|
||||
fail:
|
||||
radius_msg_free(msg);
|
||||
os_free(msg);
|
||||
}
|
||||
|
||||
|
||||
@ -425,7 +426,7 @@ accounting_receive(struct radius_msg *msg, struct radius_msg *req,
|
||||
const u8 *shared_secret, size_t shared_secret_len,
|
||||
void *data)
|
||||
{
|
||||
if (msg->hdr->code != RADIUS_CODE_ACCOUNTING_RESPONSE) {
|
||||
if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_RESPONSE) {
|
||||
printf("Unknown RADIUS message code\n");
|
||||
return RADIUS_RX_UNKNOWN;
|
||||
}
|
||||
@ -460,7 +461,6 @@ static void accounting_report_state(struct hostapd_data *hapd, int on)
|
||||
{
|
||||
printf("Could not add Acct-Terminate-Cause\n");
|
||||
radius_msg_free(msg);
|
||||
os_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -497,14 +497,3 @@ void accounting_deinit(struct hostapd_data *hapd)
|
||||
{
|
||||
accounting_report_state(hapd, 0);
|
||||
}
|
||||
|
||||
|
||||
int accounting_reconfig(struct hostapd_data *hapd,
|
||||
struct hostapd_config *oldconf)
|
||||
{
|
||||
if (!hapd->radius_client_reconfigured)
|
||||
return 0;
|
||||
|
||||
accounting_deinit(hapd);
|
||||
return accounting_init(hapd);
|
||||
}
|
@ -15,12 +15,31 @@
|
||||
#ifndef ACCOUNTING_H
|
||||
#define ACCOUNTING_H
|
||||
|
||||
void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
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);
|
||||
int accounting_reconfig(struct hostapd_data *hapd,
|
||||
struct hostapd_config *oldconf);
|
||||
#endif /* CONFIG_NO_ACCOUNTING */
|
||||
|
||||
#endif /* ACCOUNTING_H */
|
605
contrib/wpa/src/ap/ap_config.c
Normal file
605
contrib/wpa/src/ap/ap_config.c
Normal file
@ -0,0 +1,605 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
#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 */
|
||||
}
|
||||
|
||||
|
||||
struct hostapd_config * hostapd_config_defaults(void)
|
||||
{
|
||||
struct hostapd_config *conf;
|
||||
struct hostapd_bss_config *bss;
|
||||
int i;
|
||||
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 };
|
||||
|
||||
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;
|
||||
|
||||
for (i = 0; i < NUM_TX_QUEUES; i++)
|
||||
conf->tx_queue[i].aifs = -1; /* use hw default */
|
||||
|
||||
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->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->device_type);
|
||||
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,7 +1,6 @@
|
||||
/*
|
||||
* hostapd / Configuration file
|
||||
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2007-2008, Intel Corporation
|
||||
* 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
|
||||
@ -13,16 +12,15 @@
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
#ifndef HOSTAPD_CONFIG_H
|
||||
#define HOSTAPD_CONFIG_H
|
||||
|
||||
#include "defs.h"
|
||||
#include "common/defs.h"
|
||||
#include "ip_addr.h"
|
||||
#include "wpa_common.h"
|
||||
#include "common/wpa_common.h"
|
||||
|
||||
#ifndef IFNAMSIZ
|
||||
#define IFNAMSIZ 16
|
||||
#endif
|
||||
#define MAX_STA_COUNT 2007
|
||||
#define MAX_VLAN_ID 4094
|
||||
|
||||
typedef u8 macaddr[ETH_ALEN];
|
||||
|
||||
@ -171,6 +169,7 @@ struct hostapd_bss_config {
|
||||
struct hostapd_ip_addr own_ip_addr;
|
||||
char *nas_identifier;
|
||||
struct hostapd_radius_servers *radius;
|
||||
int acct_interim_interval;
|
||||
|
||||
struct hostapd_ssid ssid;
|
||||
|
||||
@ -198,6 +197,7 @@ struct hostapd_bss_config {
|
||||
int num_accept_mac;
|
||||
struct mac_acl_entry *deny_mac;
|
||||
int num_deny_mac;
|
||||
int wds_sta;
|
||||
|
||||
int auth_algs; /* bitfield of allowed IEEE 802.11 authentication
|
||||
* algorithms, WPA_AUTH_ALG_{OPEN,SHARED,LEAP} */
|
||||
@ -205,11 +205,7 @@ struct hostapd_bss_config {
|
||||
int wpa; /* bitfield of WPA_PROTO_WPA, WPA_PROTO_RSN */
|
||||
int wpa_key_mgmt;
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
enum {
|
||||
NO_IEEE80211W = 0,
|
||||
IEEE80211W_OPTIONAL = 1,
|
||||
IEEE80211W_REQUIRED = 2
|
||||
} ieee80211w;
|
||||
enum mfp_options ieee80211w;
|
||||
/* dot11AssociationSAQueryMaximumTimeout (in TUs) */
|
||||
unsigned int assoc_sa_query_max_timeout;
|
||||
/* dot11AssociationSAQueryRetryTimeout (in TUs) */
|
||||
@ -238,7 +234,9 @@ struct hostapd_bss_config {
|
||||
#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;
|
||||
@ -272,6 +270,7 @@ struct hostapd_bss_config {
|
||||
int ignore_broadcast_ssid;
|
||||
|
||||
int wmm_enabled;
|
||||
int wmm_uapsd;
|
||||
|
||||
struct hostapd_vlan *vlan, *vlan_tail;
|
||||
|
||||
@ -316,14 +315,6 @@ struct hostapd_bss_config {
|
||||
};
|
||||
|
||||
|
||||
typedef enum {
|
||||
HOSTAPD_MODE_IEEE80211B,
|
||||
HOSTAPD_MODE_IEEE80211G,
|
||||
HOSTAPD_MODE_IEEE80211A,
|
||||
NUM_HOSTAPD_MODES
|
||||
} hostapd_hw_mode;
|
||||
|
||||
|
||||
/**
|
||||
* struct hostapd_config - Per-radio interface configuration
|
||||
*/
|
||||
@ -336,7 +327,7 @@ struct hostapd_config {
|
||||
int fragm_threshold;
|
||||
u8 send_probe_response;
|
||||
u8 channel;
|
||||
hostapd_hw_mode hw_mode; /* HOSTAPD_MODE_IEEE80211A, .. */
|
||||
enum hostapd_hw_mode hw_mode; /* HOSTAPD_MODE_IEEE80211A, .. */
|
||||
enum {
|
||||
LONG_PREAMBLE = 0,
|
||||
SHORT_PREAMBLE = 1
|
||||
@ -353,9 +344,6 @@ struct hostapd_config {
|
||||
|
||||
const struct wpa_driver_ops *driver;
|
||||
|
||||
int passive_scan_interval; /* seconds, 0 = disabled */
|
||||
int passive_scan_listen; /* usec */
|
||||
int passive_scan_mode;
|
||||
int ap_table_max_size;
|
||||
int ap_table_expiration_time;
|
||||
|
||||
@ -379,16 +367,8 @@ struct hostapd_config {
|
||||
*/
|
||||
struct hostapd_wmm_ac_params wmm_ac_params[4];
|
||||
|
||||
enum {
|
||||
INTERNAL_BRIDGE_DO_NOT_CONTROL = -1,
|
||||
INTERNAL_BRIDGE_DISABLED = 0,
|
||||
INTERNAL_BRIDGE_ENABLED = 1
|
||||
} bridge_packets;
|
||||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
int ht_op_mode_fixed;
|
||||
u16 ht_capab;
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
int ieee80211n;
|
||||
int secondary_channel;
|
||||
};
|
||||
@ -396,7 +376,8 @@ struct hostapd_config {
|
||||
|
||||
int hostapd_mac_comp(const void *a, const void *b);
|
||||
int hostapd_mac_comp_empty(const void *a);
|
||||
struct hostapd_config * hostapd_config_read(const char *fname);
|
||||
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);
|
||||
@ -412,4 +393,4 @@ 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 /* CONFIG_H */
|
||||
#endif /* HOSTAPD_CONFIG_H */
|
621
contrib/wpa/src/ap/ap_drv_ops.c
Normal file
621
contrib/wpa/src/ap/ap_drv_ops.c
Normal file
@ -0,0 +1,621 @@
|
||||
/*
|
||||
* 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 "hostapd.h"
|
||||
#include "ieee802_11.h"
|
||||
#include "sta_info.h"
|
||||
#include "ap_config.h"
|
||||
#include "ap_drv_ops.h"
|
||||
|
||||
|
||||
static int hostapd_sta_flags_to_drv(int 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;
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
|
||||
{
|
||||
struct wpabuf *beacon, *proberesp;
|
||||
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;
|
||||
|
||||
ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_send_mgmt_frame(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);
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_send_eapol(struct hostapd_data *hapd, const u8 *addr,
|
||||
const u8 *data, size_t data_len, int encrypt)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_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);
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_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 int hostapd_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 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);
|
||||
}
|
||||
|
||||
|
||||
static 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;
|
||||
}
|
||||
return hostapd_set_ieee8021x(hapd, ¶ms);
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_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 int hostapd_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);
|
||||
}
|
||||
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_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 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, NULL, NULL, NULL,
|
||||
force_ifname, if_addr);
|
||||
}
|
||||
|
||||
static int hostapd_vlan_if_remove(struct hostapd_data *hapd,
|
||||
const char *ifname)
|
||||
{
|
||||
return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_set_wds_sta(struct hostapd_data *hapd, const u8 *addr,
|
||||
int aid, int val)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val);
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_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 int hostapd_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 int hostapd_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);
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_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);
|
||||
}
|
||||
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_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 int hostapd_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);
|
||||
}
|
||||
|
||||
|
||||
void hostapd_set_driver_ops(struct hostapd_driver_ops *ops)
|
||||
{
|
||||
ops->set_ap_wps_ie = hostapd_set_ap_wps_ie;
|
||||
ops->send_mgmt_frame = hostapd_send_mgmt_frame;
|
||||
ops->send_eapol = hostapd_send_eapol;
|
||||
ops->set_authorized = hostapd_set_authorized;
|
||||
ops->set_key = hostapd_set_key;
|
||||
ops->read_sta_data = hostapd_read_sta_data;
|
||||
ops->sta_clear_stats = hostapd_sta_clear_stats;
|
||||
ops->set_sta_flags = hostapd_set_sta_flags;
|
||||
ops->set_drv_ieee8021x = hostapd_set_drv_ieee8021x;
|
||||
ops->set_radius_acl_auth = hostapd_set_radius_acl_auth;
|
||||
ops->set_radius_acl_expire = hostapd_set_radius_acl_expire;
|
||||
ops->set_bss_params = hostapd_set_bss_params;
|
||||
ops->set_beacon = hostapd_set_beacon;
|
||||
ops->vlan_if_add = hostapd_vlan_if_add;
|
||||
ops->vlan_if_remove = hostapd_vlan_if_remove;
|
||||
ops->set_wds_sta = hostapd_set_wds_sta;
|
||||
ops->set_sta_vlan = hostapd_set_sta_vlan;
|
||||
ops->get_inact_sec = hostapd_get_inact_sec;
|
||||
ops->sta_deauth = hostapd_sta_deauth;
|
||||
ops->sta_disassoc = hostapd_sta_disassoc;
|
||||
ops->sta_add = hostapd_sta_add;
|
||||
ops->sta_remove = hostapd_sta_remove;
|
||||
ops->set_countermeasures = hostapd_set_countermeasures;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
67
contrib/wpa/src/ap/ap_drv_ops.h
Normal file
67
contrib/wpa/src/ap/ap_drv_ops.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
void hostapd_set_driver_ops(struct hostapd_driver_ops *ops);
|
||||
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);
|
||||
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);
|
||||
|
||||
#endif /* AP_DRV_OPS */
|
@ -1,9 +1,8 @@
|
||||
/*
|
||||
* hostapd / AP table
|
||||
* Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2003-2004, Instant802 Networks, Inc.
|
||||
* Copyright (c) 2006, Devicescape Software, Inc.
|
||||
* Copyright (c) 2007-2008, Intel Corporation
|
||||
*
|
||||
* 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
|
||||
@ -15,52 +14,19 @@
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#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 "eloop.h"
|
||||
#include "ap_list.h"
|
||||
#include "hw_features.h"
|
||||
#include "sta_info.h"
|
||||
#include "beacon.h"
|
||||
|
||||
|
||||
struct ieee80211_frame_info {
|
||||
u32 version;
|
||||
u32 length;
|
||||
u64 mactime;
|
||||
u64 hosttime;
|
||||
u32 phytype;
|
||||
u32 channel;
|
||||
u32 datarate;
|
||||
u32 antenna;
|
||||
u32 priority;
|
||||
u32 ssi_type;
|
||||
u32 ssi_signal;
|
||||
u32 ssi_noise;
|
||||
u32 preamble;
|
||||
u32 encoding;
|
||||
|
||||
/* Note: this structure is otherwise identical to capture format used
|
||||
* in linux-wlan-ng, but this additional field is used to provide meta
|
||||
* data about the frame to hostapd. This was the easiest method for
|
||||
* providing this information, but this might change in the future. */
|
||||
u32 msg_type;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
enum ieee80211_phytype {
|
||||
ieee80211_phytype_fhss_dot11_97 = 1,
|
||||
ieee80211_phytype_dsss_dot11_97 = 2,
|
||||
ieee80211_phytype_irbaseband = 3,
|
||||
ieee80211_phytype_dsss_dot11_b = 4,
|
||||
ieee80211_phytype_pbcc_dot11_b = 5,
|
||||
ieee80211_phytype_ofdm_dot11_g = 6,
|
||||
ieee80211_phytype_pbcc_dot11_g = 7,
|
||||
ieee80211_phytype_ofdm_dot11_a = 8,
|
||||
ieee80211_phytype_dsss_dot11_turbog = 255,
|
||||
ieee80211_phytype_dsss_dot11_turbo = 256,
|
||||
};
|
||||
#include "ap_list.h"
|
||||
|
||||
|
||||
/* AP list is a double linked list with head->prev pointing to the end of the
|
||||
@ -69,29 +35,11 @@ enum ieee80211_phytype {
|
||||
* in this link will thus be the least recently used entry. */
|
||||
|
||||
|
||||
static void ap_list_new_ap(struct hostapd_iface *iface, struct ap_info *ap)
|
||||
{
|
||||
wpa_printf(MSG_DEBUG, "New AP detected: " MACSTR, MAC2STR(ap->addr));
|
||||
|
||||
/* TODO: could send a notification message to an external program that
|
||||
* would then determine whether a rogue AP has been detected */
|
||||
}
|
||||
|
||||
|
||||
static void ap_list_expired_ap(struct hostapd_iface *iface, struct ap_info *ap)
|
||||
{
|
||||
wpa_printf(MSG_DEBUG, "AP info expired: " MACSTR, MAC2STR(ap->addr));
|
||||
|
||||
/* TODO: could send a notification message to an external program */
|
||||
}
|
||||
|
||||
|
||||
static int ap_list_beacon_olbc(struct hostapd_iface *iface, struct ap_info *ap)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G ||
|
||||
ap->phytype != ieee80211_phytype_pbcc_dot11_g ||
|
||||
iface->conf->channel != ap->channel)
|
||||
return 0;
|
||||
|
||||
@ -108,16 +56,7 @@ static int ap_list_beacon_olbc(struct hostapd_iface *iface, struct ap_info *ap)
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
static int ap_list_beacon_olbc_ht(struct hostapd_iface *iface,
|
||||
struct ap_info *ap)
|
||||
{
|
||||
return !ap->ht_support;
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
|
||||
|
||||
struct ap_info * ap_get_ap(struct hostapd_iface *iface, u8 *ap)
|
||||
struct ap_info * ap_get_ap(struct hostapd_iface *iface, const u8 *ap)
|
||||
{
|
||||
struct ap_info *s;
|
||||
|
||||
@ -257,7 +196,7 @@ int ap_ap_for_each(struct hostapd_iface *iface,
|
||||
}
|
||||
|
||||
|
||||
static struct ap_info * ap_ap_add(struct hostapd_iface *iface, u8 *addr)
|
||||
static struct ap_info * ap_ap_add(struct hostapd_iface *iface, const u8 *addr)
|
||||
{
|
||||
struct ap_info *ap;
|
||||
|
||||
@ -275,8 +214,6 @@ static struct ap_info * ap_ap_add(struct hostapd_iface *iface, u8 *addr)
|
||||
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));
|
||||
if (iface->conf->passive_scan_interval > 0)
|
||||
ap_list_expired_ap(iface, ap->prev);
|
||||
ap_free_ap(iface, ap->prev);
|
||||
}
|
||||
|
||||
@ -285,7 +222,7 @@ static struct ap_info * ap_ap_add(struct hostapd_iface *iface, u8 *addr)
|
||||
|
||||
|
||||
void ap_list_process_beacon(struct hostapd_iface *iface,
|
||||
struct ieee80211_mgmt *mgmt,
|
||||
const struct ieee80211_mgmt *mgmt,
|
||||
struct ieee802_11_elems *elems,
|
||||
struct hostapd_frame_info *fi)
|
||||
{
|
||||
@ -357,15 +294,11 @@ void ap_list_process_beacon(struct hostapd_iface *iface,
|
||||
ap->num_beacons++;
|
||||
time(&ap->last_beacon);
|
||||
if (fi) {
|
||||
ap->phytype = fi->phytype;
|
||||
ap->ssi_signal = fi->ssi_signal;
|
||||
ap->datarate = fi->datarate;
|
||||
}
|
||||
|
||||
if (new_ap) {
|
||||
if (iface->conf->passive_scan_interval > 0)
|
||||
ap_list_new_ap(iface, ap);
|
||||
} else if (ap != iface->ap_list) {
|
||||
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);
|
||||
@ -381,7 +314,7 @@ void ap_list_process_beacon(struct hostapd_iface *iface,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
if (!iface->olbc_ht && ap_list_beacon_olbc_ht(iface, ap)) {
|
||||
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
|
||||
@ -409,18 +342,12 @@ static void ap_list_timer(void *eloop_ctx, void *timeout_ctx)
|
||||
|
||||
time(&now);
|
||||
|
||||
/* FIX: it looks like jkm-Purina ended up in busy loop in this
|
||||
* function. Apparently, something can still cause a loop in the AP
|
||||
* list.. */
|
||||
|
||||
while (iface->ap_list) {
|
||||
ap = iface->ap_list->prev;
|
||||
if (ap->last_beacon + iface->conf->ap_table_expiration_time >=
|
||||
now)
|
||||
break;
|
||||
|
||||
if (iface->conf->passive_scan_interval > 0)
|
||||
ap_list_expired_ap(iface, ap);
|
||||
ap_free_ap(iface, ap);
|
||||
}
|
||||
|
||||
@ -432,10 +359,8 @@ static void ap_list_timer(void *eloop_ctx, void *timeout_ctx)
|
||||
while (ap && (olbc == 0 || olbc_ht == 0)) {
|
||||
if (ap_list_beacon_olbc(iface, ap))
|
||||
olbc = 1;
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
if (ap_list_beacon_olbc_ht(iface, ap))
|
||||
if (!ap->ht_support)
|
||||
olbc_ht = 1;
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
ap = ap->next;
|
||||
}
|
||||
if (!olbc && iface->olbc) {
|
||||
@ -470,32 +395,3 @@ void ap_list_deinit(struct hostapd_iface *iface)
|
||||
eloop_cancel_timeout(ap_list_timer, iface, NULL);
|
||||
hostapd_free_aps(iface);
|
||||
}
|
||||
|
||||
|
||||
int ap_list_reconfig(struct hostapd_iface *iface,
|
||||
struct hostapd_config *oldconf)
|
||||
{
|
||||
time_t now;
|
||||
struct ap_info *ap;
|
||||
|
||||
if (iface->conf->ap_table_max_size == oldconf->ap_table_max_size &&
|
||||
iface->conf->ap_table_expiration_time ==
|
||||
oldconf->ap_table_expiration_time)
|
||||
return 0;
|
||||
|
||||
time(&now);
|
||||
|
||||
while (iface->ap_list) {
|
||||
ap = iface->ap_list->prev;
|
||||
if (iface->num_ap <= iface->conf->ap_table_max_size &&
|
||||
ap->last_beacon + iface->conf->ap_table_expiration_time >=
|
||||
now)
|
||||
break;
|
||||
|
||||
if (iface->conf->passive_scan_interval > 0)
|
||||
ap_list_expired_ap(iface, iface->ap_list->prev);
|
||||
ap_free_ap(iface, iface->ap_list->prev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -3,7 +3,6 @@
|
||||
* Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2003-2004, Instant802 Networks, Inc.
|
||||
* Copyright (c) 2006, Devicescape Software, Inc.
|
||||
* Copyright (c) 2007-2008, Intel Corporation
|
||||
*
|
||||
* 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
|
||||
@ -39,7 +38,6 @@ struct ap_info {
|
||||
int wpa;
|
||||
int erp; /* ERP Info or -1 if ERP info element not present */
|
||||
|
||||
int phytype; /* .11a / .11b / .11g / Atheros Turbo */
|
||||
int channel;
|
||||
int datarate; /* in 100 kbps */
|
||||
int ssi_signal;
|
||||
@ -56,16 +54,25 @@ struct ap_info {
|
||||
struct ieee802_11_elems;
|
||||
struct hostapd_frame_info;
|
||||
|
||||
struct ap_info * ap_get_ap(struct hostapd_iface *iface, u8 *sta);
|
||||
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,
|
||||
struct ieee80211_mgmt *mgmt,
|
||||
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);
|
||||
int ap_list_reconfig(struct hostapd_iface *iface,
|
||||
struct hostapd_config *oldconf);
|
||||
#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 */
|
@ -14,14 +14,17 @@
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "hostapd.h"
|
||||
#include "utils/common.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "ieee802_11.h"
|
||||
#include "wpa.h"
|
||||
#include "mlme.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) {
|
||||
@ -35,6 +38,7 @@ static const char * mlme_auth_alg_str(int alg)
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
#endif /* CONFIG_NO_HOSTAPD_LOGGER */
|
||||
|
||||
|
||||
/**
|
216
contrib/wpa/src/ap/authsrv.c
Normal file
216
contrib/wpa/src/ap/authsrv.c
Normal file
@ -0,0 +1,216 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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 */
|
||||
}
|
21
contrib/wpa/src/ap/authsrv.h
Normal file
21
contrib/wpa/src/ap/authsrv.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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 */
|
@ -2,8 +2,7 @@
|
||||
* 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, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2007-2008, Intel Corporation
|
||||
* 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
|
||||
@ -15,19 +14,21 @@
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#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 "hostapd.h"
|
||||
#include "ieee802_11.h"
|
||||
#include "wpa.h"
|
||||
#include "wme.h"
|
||||
#include "beacon.h"
|
||||
#include "hw_features.h"
|
||||
#include "driver.h"
|
||||
#include "wpa_auth.h"
|
||||
#include "wmm.h"
|
||||
#include "ap_config.h"
|
||||
#include "sta_info.h"
|
||||
#include "wps_hostapd.h"
|
||||
#include "beacon.h"
|
||||
|
||||
|
||||
static u8 ieee802_11_erp_info(struct hostapd_data *hapd)
|
||||
@ -56,7 +57,8 @@ static u8 ieee802_11_erp_info(struct hostapd_data *hapd)
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (hapd->iface->num_sta_no_short_preamble > 0)
|
||||
if (hapd->iface->num_sta_no_short_preamble > 0 ||
|
||||
hapd->iconf->preamble == LONG_PREAMBLE)
|
||||
erp |= ERP_INFO_BARKER_PREAMBLE_MODE;
|
||||
|
||||
return erp;
|
||||
@ -191,20 +193,26 @@ static u8 * hostapd_eid_wpa(struct hostapd_data *hapd, u8 *eid, size_t len,
|
||||
}
|
||||
|
||||
|
||||
void handle_probe_req(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
|
||||
size_t len)
|
||||
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, *ie;
|
||||
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;
|
||||
ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
|
||||
|
||||
hostapd_wps_probe_req_rx(hapd, mgmt->sa, ie, ie_len);
|
||||
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;
|
||||
@ -258,7 +266,12 @@ void handle_probe_req(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
|
||||
/* TODO: verify that supp_rates contains at least one matching rate
|
||||
* with AP configuration */
|
||||
#define MAX_PROBERESP_LEN 768
|
||||
resp = os_zalloc(MAX_PROBERESP_LEN);
|
||||
buflen = MAX_PROBERESP_LEN;
|
||||
#ifdef CONFIG_WPS
|
||||
if (hapd->wps_probe_resp_ie)
|
||||
buflen += wpabuf_len(hapd->wps_probe_resp_ie);
|
||||
#endif /* CONFIG_WPS */
|
||||
resp = os_zalloc(buflen);
|
||||
if (resp == NULL)
|
||||
return;
|
||||
epos = ((u8 *) resp) + MAX_PROBERESP_LEN;
|
||||
@ -296,23 +309,26 @@ void handle_probe_req(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
|
||||
/* 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 */
|
||||
|
||||
/* Wi-Fi Alliance WMM */
|
||||
pos = hostapd_eid_wmm(hapd, pos);
|
||||
|
||||
pos = hostapd_eid_ht_capabilities_info(hapd, pos);
|
||||
pos = hostapd_eid_ht_operation(hapd, pos);
|
||||
|
||||
#ifdef CONFIG_WPS
|
||||
if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) {
|
||||
os_memcpy(pos, hapd->wps_probe_resp_ie,
|
||||
hapd->wps_probe_resp_ie_len);
|
||||
pos += hapd->wps_probe_resp_ie_len;
|
||||
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 */
|
||||
|
||||
if (hostapd_send_mgmt_frame(hapd, resp, pos - (u8 *) resp, 0) < 0)
|
||||
if (hapd->drv.send_mgmt_frame(hapd, resp, pos - (u8 *) resp) < 0)
|
||||
perror("handle_probe_req: send");
|
||||
|
||||
os_free(resp);
|
||||
@ -327,16 +343,18 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
|
||||
{
|
||||
struct ieee80211_mgmt *head;
|
||||
u8 *pos, *tail, *tailpos;
|
||||
int preamble;
|
||||
u16 capab_info;
|
||||
size_t head_len, tail_len;
|
||||
int cts_protection = ((ieee802_11_erp_info(hapd) &
|
||||
ERP_INFO_USE_PROTECTION) ? 1 : 0);
|
||||
|
||||
#define BEACON_HEAD_BUF_SIZE 256
|
||||
#define BEACON_TAIL_BUF_SIZE 512
|
||||
head = os_zalloc(BEACON_HEAD_BUF_SIZE);
|
||||
tailpos = tail = os_malloc(BEACON_TAIL_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 */
|
||||
tailpos = tail = os_malloc(tail_len);
|
||||
if (head == NULL || tail == NULL) {
|
||||
wpa_printf(MSG_ERROR, "Failed to set beacon data");
|
||||
os_free(head);
|
||||
@ -392,68 +410,39 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
|
||||
/* 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);
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
|
||||
/* Wi-Fi Alliance WMM */
|
||||
tailpos = hostapd_eid_wmm(hapd, tailpos);
|
||||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
if (hapd->iconf->ieee80211n) {
|
||||
u8 *ht_capab, *ht_oper;
|
||||
ht_capab = tailpos;
|
||||
tailpos = hostapd_eid_ht_capabilities_info(hapd, tailpos);
|
||||
|
||||
ht_oper = tailpos;
|
||||
tailpos = hostapd_eid_ht_operation(hapd, tailpos);
|
||||
|
||||
if (tailpos > ht_oper && ht_oper > ht_capab &&
|
||||
hostapd_set_ht_params(hapd->conf->iface, 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");
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
|
||||
#ifdef CONFIG_WPS
|
||||
if (hapd->conf->wps_state && hapd->wps_beacon_ie) {
|
||||
os_memcpy(tailpos, hapd->wps_beacon_ie,
|
||||
hapd->wps_beacon_ie_len);
|
||||
tailpos += hapd->wps_beacon_ie_len;
|
||||
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 */
|
||||
|
||||
tail_len = tailpos > tail ? tailpos - tail : 0;
|
||||
|
||||
if (hostapd_set_beacon(hapd->conf->iface, hapd, (u8 *) head, head_len,
|
||||
tail, tail_len))
|
||||
wpa_printf(MSG_ERROR, "Failed to set beacon head/tail");
|
||||
if (hapd->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);
|
||||
|
||||
if (hostapd_set_cts_protect(hapd, cts_protection))
|
||||
wpa_printf(MSG_ERROR, "Failed to set CTS protect in kernel "
|
||||
"driver");
|
||||
|
||||
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");
|
||||
|
||||
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");
|
||||
hapd->drv.set_bss_params(hapd, !!(ieee802_11_erp_info(hapd) &
|
||||
ERP_INFO_USE_PROTECTION));
|
||||
}
|
||||
|
||||
|
@ -16,9 +16,21 @@
|
||||
#ifndef BEACON_H
|
||||
#define BEACON_H
|
||||
|
||||
void handle_probe_req(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
|
||||
size_t len);
|
||||
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 */
|
104
contrib/wpa/src/ap/ctrl_iface_ap.c
Normal file
104
contrib/wpa/src/ap/ctrl_iface_ap.c
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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 "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;
|
||||
|
||||
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);
|
||||
}
|
25
contrib/wpa/src/ap/ctrl_iface_ap.h
Normal file
25
contrib/wpa/src/ap/ctrl_iface_ap.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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 */
|
457
contrib/wpa/src/ap/drv_callbacks.c
Normal file
457
contrib/wpa/src/ap/drv_callbacks.c
Normal file
@ -0,0 +1,457 @@
|
||||
/*
|
||||
* 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 "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_config.h"
|
||||
|
||||
|
||||
int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
|
||||
const u8 *ie, size_t ielen)
|
||||
{
|
||||
struct sta_info *sta;
|
||||
int new_assoc, res;
|
||||
struct ieee802_11_elems elems;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
hapd->drv.sta_disassoc(hapd, sta->addr, resp);
|
||||
ap_free_sta(hapd, sta);
|
||||
return -1;
|
||||
}
|
||||
} else if (hapd->conf->wps_state) {
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
|
||||
{
|
||||
struct sta_info *sta;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
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_probe_req_rx(struct hostapd_data *hapd, const u8 *sa,
|
||||
const u8 *ie, size_t ie_len)
|
||||
{
|
||||
size_t i;
|
||||
int ret = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
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:
|
||||
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);
|
||||
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;
|
||||
default:
|
||||
wpa_printf(MSG_DEBUG, "Unknown event %d", event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HOSTAPD */
|
887
contrib/wpa/src/ap/hostapd.c
Normal file
887
contrib/wpa/src/ap/hostapd.c
Normal file
@ -0,0 +1,887 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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(hapd->radius, 0);
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
|
||||
oldconf = hapd->iconf;
|
||||
hapd->iconf = newconf;
|
||||
hapd->conf = &newconf->bss[0];
|
||||
iface->conf = newconf;
|
||||
|
||||
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)
|
||||
hapd->drv.set_drv_ieee8021x(hapd, hapd->conf->iface, 1);
|
||||
else
|
||||
hapd->drv.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 */
|
||||
}
|
||||
|
||||
hostapd_config_free(oldconf);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface);
|
||||
|
||||
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 (hapd->drv.set_key(ifname, hapd, WPA_ALG_NONE, NULL, i,
|
||||
i == 0 ? 1 : 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 (hapd->drv.set_key(ifname, hapd, WPA_ALG_NONE, NULL,
|
||||
i, i == 0 ? 1 : 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 &&
|
||||
hapd->drv.set_key(hapd->conf->iface,
|
||||
hapd, WPA_ALG_WEP, NULL, idx,
|
||||
idx == ssid->wep.idx,
|
||||
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 (hapd->drv.set_key(ifname, hapd, WPA_ALG_WEP, NULL,
|
||||
idx, idx == key->idx, 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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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] &&
|
||||
hapd->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;
|
||||
|
||||
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");
|
||||
|
||||
/* New Prism2.5/3 STA firmware versions seem to have issues with this
|
||||
* broadcast deauth frame. This gets the firmware in odd state where
|
||||
* nothing works correctly, so let's skip sending this for the hostap
|
||||
* driver. */
|
||||
if (hapd->driver && os_strcmp(hapd->driver->name, "hostap") != 0) {
|
||||
u8 addr[ETH_ALEN];
|
||||
os_memset(addr, 0xff, ETH_ALEN);
|
||||
hapd->drv.sta_deauth(hapd, addr,
|
||||
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
}
|
||||
|
||||
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)) {
|
||||
wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID="
|
||||
MACSTR ")", MAC2STR(hapd->own_addr));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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 (!p->configured)
|
||||
continue;
|
||||
|
||||
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 (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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
hostapd_set_driver_ops(&hapd->drv);
|
||||
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) {
|
||||
hapd->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);
|
||||
|
||||
/* 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);
|
||||
}
|
276
contrib/wpa/src/ap/hostapd.h
Normal file
276
contrib/wpa/src/ap/hostapd.h
Normal file
@ -0,0 +1,276 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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_driver_ops {
|
||||
int (*set_ap_wps_ie)(struct hostapd_data *hapd);
|
||||
int (*send_mgmt_frame)(struct hostapd_data *hapd, const void *msg,
|
||||
size_t len);
|
||||
int (*send_eapol)(struct hostapd_data *hapd, const u8 *addr,
|
||||
const u8 *data, size_t data_len, int encrypt);
|
||||
int (*set_authorized)(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
int authorized);
|
||||
int (*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 (*read_sta_data)(struct hostapd_data *hapd,
|
||||
struct hostap_sta_driver_data *data,
|
||||
const u8 *addr);
|
||||
int (*sta_clear_stats)(struct hostapd_data *hapd, const u8 *addr);
|
||||
int (*set_sta_flags)(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
int (*set_drv_ieee8021x)(struct hostapd_data *hapd, const char *ifname,
|
||||
int enabled);
|
||||
int (*set_radius_acl_auth)(struct hostapd_data *hapd,
|
||||
const u8 *mac, int accepted,
|
||||
u32 session_timeout);
|
||||
int (*set_radius_acl_expire)(struct hostapd_data *hapd,
|
||||
const u8 *mac);
|
||||
int (*set_bss_params)(struct hostapd_data *hapd, int use_protection);
|
||||
int (*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);
|
||||
int (*vlan_if_add)(struct hostapd_data *hapd, const char *ifname);
|
||||
int (*vlan_if_remove)(struct hostapd_data *hapd, const char *ifname);
|
||||
int (*set_wds_sta)(struct hostapd_data *hapd, const u8 *addr, int aid,
|
||||
int val);
|
||||
int (*set_sta_vlan)(const char *ifname, struct hostapd_data *hapd,
|
||||
const u8 *addr, int vlan_id);
|
||||
int (*get_inact_sec)(struct hostapd_data *hapd, const u8 *addr);
|
||||
int (*sta_deauth)(struct hostapd_data *hapd, const u8 *addr,
|
||||
int reason);
|
||||
int (*sta_disassoc)(struct hostapd_data *hapd, const u8 *addr,
|
||||
int reason);
|
||||
int (*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 (*sta_remove)(struct hostapd_data *hapd, const u8 *addr);
|
||||
int (*set_countermeasures)(struct hostapd_data *hapd, int enabled);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
struct hostapd_driver_ops drv;
|
||||
|
||||
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;
|
||||
|
||||
void (*wps_reg_success_cb)(void *ctx, const u8 *mac_addr,
|
||||
const u8 *uuid_e);
|
||||
void *wps_reg_success_cb_ctx;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
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);
|
||||
void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr);
|
||||
|
||||
#endif /* HOSTAPD_H */
|
@ -2,7 +2,7 @@
|
||||
* hostapd / Hardware feature query and different modes
|
||||
* Copyright 2002-2003, Instant802 Networks, Inc.
|
||||
* Copyright 2005-2006, Devicescape Software, Inc.
|
||||
* Copyright (c) 2008, Jouni Malinen <j@w1.fi>
|
||||
* 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
|
||||
@ -14,12 +14,17 @@
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#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 "ap_drv_ops.h"
|
||||
#include "hw_features.h"
|
||||
#include "driver.h"
|
||||
#include "config.h"
|
||||
|
||||
|
||||
void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
|
||||
@ -131,7 +136,7 @@ static int hostapd_prepare_rates(struct hostapd_data *hapd,
|
||||
hapd->iface->num_rates = 0;
|
||||
|
||||
hapd->iface->current_rates =
|
||||
os_malloc(mode->num_rates * sizeof(struct hostapd_rate_data));
|
||||
os_zalloc(mode->num_rates * sizeof(struct hostapd_rate_data));
|
||||
if (!hapd->iface->current_rates) {
|
||||
wpa_printf(MSG_ERROR, "Failed to allocate memory for rate "
|
||||
"table.");
|
||||
@ -143,17 +148,15 @@ static int hostapd_prepare_rates(struct hostapd_data *hapd,
|
||||
|
||||
if (hapd->iconf->supported_rates &&
|
||||
!hostapd_rate_found(hapd->iconf->supported_rates,
|
||||
mode->rates[i].rate))
|
||||
mode->rates[i]))
|
||||
continue;
|
||||
|
||||
rate = &hapd->iface->current_rates[hapd->iface->num_rates];
|
||||
os_memcpy(rate, &mode->rates[i],
|
||||
sizeof(struct hostapd_rate_data));
|
||||
rate->rate = mode->rates[i];
|
||||
if (hostapd_rate_found(basic_rates, rate->rate)) {
|
||||
rate->flags |= HOSTAPD_RATE_BASIC;
|
||||
num_basic_rates++;
|
||||
} else
|
||||
rate->flags &= ~HOSTAPD_RATE_BASIC;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "RATE[%d] rate=%d flags=0x%x",
|
||||
hapd->iface->num_rates, rate->rate, rate->flags);
|
||||
hapd->iface->num_rates++;
|
||||
@ -236,6 +239,245 @@ static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface *iface)
|
||||
}
|
||||
|
||||
|
||||
static void ieee80211n_switch_pri_sec(struct hostapd_iface *iface)
|
||||
{
|
||||
if (iface->conf->secondary_channel > 0) {
|
||||
iface->conf->channel += 4;
|
||||
iface->conf->secondary_channel = -1;
|
||||
} else {
|
||||
iface->conf->channel -= 4;
|
||||
iface->conf->secondary_channel = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ieee80211n_get_pri_sec_chan(struct wpa_scan_res *bss,
|
||||
int *pri_chan, int *sec_chan)
|
||||
{
|
||||
struct ieee80211_ht_operation *oper;
|
||||
struct ieee802_11_elems elems;
|
||||
|
||||
*pri_chan = *sec_chan = 0;
|
||||
|
||||
ieee802_11_parse_elems((u8 *) (bss + 1), bss->ie_len, &elems, 0);
|
||||
if (elems.ht_operation &&
|
||||
elems.ht_operation_len >= sizeof(*oper)) {
|
||||
oper = (struct ieee80211_ht_operation *) elems.ht_operation;
|
||||
*pri_chan = oper->control_chan;
|
||||
if (oper->ht_param & HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH) {
|
||||
if (oper->ht_param &
|
||||
HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
|
||||
*sec_chan = *pri_chan + 4;
|
||||
else if (oper->ht_param &
|
||||
HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW)
|
||||
*sec_chan = *pri_chan - 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211n_check_40mhz_5g(struct hostapd_iface *iface,
|
||||
struct wpa_scan_results *scan_res)
|
||||
{
|
||||
int pri_chan, sec_chan, pri_freq, sec_freq, pri_bss, sec_bss;
|
||||
int bss_pri_chan, bss_sec_chan;
|
||||
size_t i;
|
||||
int match;
|
||||
|
||||
pri_chan = iface->conf->channel;
|
||||
sec_chan = iface->conf->secondary_channel * 4;
|
||||
pri_freq = hostapd_hw_get_freq(iface->bss[0], pri_chan);
|
||||
if (iface->conf->secondary_channel > 0)
|
||||
sec_freq = pri_freq + 20;
|
||||
else
|
||||
sec_freq = pri_freq - 20;
|
||||
|
||||
/*
|
||||
* Switch PRI/SEC channels if Beacons were detected on selected SEC
|
||||
* channel, but not on selected PRI channel.
|
||||
*/
|
||||
pri_bss = sec_bss = 0;
|
||||
for (i = 0; i < scan_res->num; i++) {
|
||||
struct wpa_scan_res *bss = scan_res->res[i];
|
||||
if (bss->freq == pri_freq)
|
||||
pri_bss++;
|
||||
else if (bss->freq == sec_freq)
|
||||
sec_bss++;
|
||||
}
|
||||
if (sec_bss && !pri_bss) {
|
||||
wpa_printf(MSG_INFO, "Switch own primary and secondary "
|
||||
"channel to get secondary channel with no Beacons "
|
||||
"from other BSSes");
|
||||
ieee80211n_switch_pri_sec(iface);
|
||||
}
|
||||
|
||||
/*
|
||||
* Match PRI/SEC channel with any existing HT40 BSS on the same
|
||||
* channels that we are about to use (if already mixed order in
|
||||
* existing BSSes, use own preference).
|
||||
*/
|
||||
match = 0;
|
||||
for (i = 0; i < scan_res->num; i++) {
|
||||
struct wpa_scan_res *bss = scan_res->res[i];
|
||||
ieee80211n_get_pri_sec_chan(bss, &bss_pri_chan, &bss_sec_chan);
|
||||
if (pri_chan == bss_pri_chan &&
|
||||
sec_chan == bss_sec_chan) {
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match) {
|
||||
for (i = 0; i < scan_res->num; i++) {
|
||||
struct wpa_scan_res *bss = scan_res->res[i];
|
||||
ieee80211n_get_pri_sec_chan(bss, &bss_pri_chan,
|
||||
&bss_sec_chan);
|
||||
if (pri_chan == bss_sec_chan &&
|
||||
sec_chan == bss_pri_chan) {
|
||||
wpa_printf(MSG_INFO, "Switch own primary and "
|
||||
"secondary channel due to BSS "
|
||||
"overlap with " MACSTR,
|
||||
MAC2STR(bss->bssid));
|
||||
ieee80211n_switch_pri_sec(iface);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211n_check_40mhz_2g4(struct hostapd_iface *iface,
|
||||
struct wpa_scan_results *scan_res)
|
||||
{
|
||||
int pri_freq, sec_freq;
|
||||
int affected_start, affected_end;
|
||||
size_t i;
|
||||
|
||||
pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
|
||||
if (iface->conf->secondary_channel > 0)
|
||||
sec_freq = pri_freq + 20;
|
||||
else
|
||||
sec_freq = pri_freq - 20;
|
||||
affected_start = (pri_freq + sec_freq) / 2 - 25;
|
||||
affected_end = (pri_freq + sec_freq) / 2 + 25;
|
||||
wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
|
||||
affected_start, affected_end);
|
||||
for (i = 0; i < scan_res->num; i++) {
|
||||
struct wpa_scan_res *bss = scan_res->res[i];
|
||||
int pri = bss->freq;
|
||||
int sec = pri;
|
||||
int sec_chan, pri_chan;
|
||||
|
||||
ieee80211n_get_pri_sec_chan(bss, &pri_chan, &sec_chan);
|
||||
|
||||
if (sec_chan) {
|
||||
if (sec_chan < pri_chan)
|
||||
sec = pri - 20;
|
||||
else
|
||||
sec = pri + 20;
|
||||
}
|
||||
|
||||
if ((pri < affected_start || pri > affected_end) &&
|
||||
(sec < affected_start || sec > affected_end))
|
||||
continue; /* not within affected channel range */
|
||||
|
||||
wpa_printf(MSG_DEBUG, "Neighboring BSS: " MACSTR
|
||||
" freq=%d pri=%d sec=%d",
|
||||
MAC2STR(bss->bssid), bss->freq, pri_chan, sec_chan);
|
||||
|
||||
if (sec_chan) {
|
||||
if (pri_freq != pri || sec_freq != sec) {
|
||||
wpa_printf(MSG_DEBUG, "40 MHz pri/sec "
|
||||
"mismatch with BSS " MACSTR
|
||||
" <%d,%d> (chan=%d%c) vs. <%d,%d>",
|
||||
MAC2STR(bss->bssid),
|
||||
pri, sec, pri_chan,
|
||||
sec > pri ? '+' : '-',
|
||||
pri_freq, sec_freq);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: 40 MHz intolerant */
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void wpa_scan_results_free(struct wpa_scan_results *res)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (res == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < res->num; i++)
|
||||
os_free(res->res[i]);
|
||||
os_free(res->res);
|
||||
os_free(res);
|
||||
}
|
||||
|
||||
|
||||
static void ieee80211n_check_scan(struct hostapd_iface *iface)
|
||||
{
|
||||
struct wpa_scan_results *scan_res;
|
||||
int oper40;
|
||||
|
||||
/* Check list of neighboring BSSes (from scan) to see whether 40 MHz is
|
||||
* allowed per IEEE 802.11n/D7.0, 11.14.3.2 */
|
||||
|
||||
iface->scan_cb = NULL;
|
||||
|
||||
scan_res = hostapd_driver_get_scan_results(iface->bss[0]);
|
||||
if (scan_res == NULL) {
|
||||
hostapd_setup_interface_complete(iface, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A)
|
||||
oper40 = ieee80211n_check_40mhz_5g(iface, scan_res);
|
||||
else
|
||||
oper40 = ieee80211n_check_40mhz_2g4(iface, scan_res);
|
||||
wpa_scan_results_free(scan_res);
|
||||
|
||||
if (!oper40) {
|
||||
wpa_printf(MSG_INFO, "20/40 MHz operation not permitted on "
|
||||
"channel pri=%d sec=%d based on overlapping BSSes",
|
||||
iface->conf->channel,
|
||||
iface->conf->channel +
|
||||
iface->conf->secondary_channel * 4);
|
||||
iface->conf->secondary_channel = 0;
|
||||
iface->conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
|
||||
}
|
||||
|
||||
hostapd_setup_interface_complete(iface, 0);
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211n_check_40mhz(struct hostapd_iface *iface)
|
||||
{
|
||||
struct wpa_driver_scan_params params;
|
||||
|
||||
if (!iface->conf->secondary_channel)
|
||||
return 0; /* HT40 not used */
|
||||
|
||||
wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling "
|
||||
"40 MHz channel");
|
||||
os_memset(¶ms, 0, sizeof(params));
|
||||
/* TODO: scan only the needed frequency */
|
||||
if (hostapd_driver_scan(iface->bss[0], ¶ms) < 0) {
|
||||
wpa_printf(MSG_ERROR, "Failed to request a scan of "
|
||||
"neighboring BSSes");
|
||||
return -1;
|
||||
}
|
||||
|
||||
iface->scan_cb = ieee80211n_check_scan;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211n_supported_ht_capab(struct hostapd_iface *iface)
|
||||
{
|
||||
u16 hw = iface->current_mode->ht_capab;
|
||||
@ -335,9 +577,27 @@ static int ieee80211n_supported_ht_capab(struct hostapd_iface *iface)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
|
||||
|
||||
int hostapd_check_ht_capab(struct hostapd_iface *iface)
|
||||
{
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
int ret;
|
||||
ret = ieee80211n_check_40mhz(iface);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!ieee80211n_allowed_ht40_channel_pair(iface))
|
||||
return -1;
|
||||
if (!ieee80211n_supported_ht_capab(iface))
|
||||
return -1;
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hostapd_select_hw_mode - Select the hardware mode
|
||||
* @iface: Pointer to interface data.
|
||||
@ -348,7 +608,7 @@ static int ieee80211n_supported_ht_capab(struct hostapd_iface *iface)
|
||||
*/
|
||||
int hostapd_select_hw_mode(struct hostapd_iface *iface)
|
||||
{
|
||||
int i, j, ok, ret;
|
||||
int i, j, ok;
|
||||
|
||||
if (iface->num_hw_features < 1)
|
||||
return -1;
|
||||
@ -356,7 +616,7 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface)
|
||||
iface->current_mode = NULL;
|
||||
for (i = 0; i < iface->num_hw_features; i++) {
|
||||
struct hostapd_hw_modes *mode = &iface->hw_features[i];
|
||||
if (mode->mode == (int) iface->conf->hw_mode) {
|
||||
if (mode->mode == iface->conf->hw_mode) {
|
||||
iface->current_mode = mode;
|
||||
break;
|
||||
}
|
||||
@ -408,13 +668,6 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
if (!ieee80211n_allowed_ht40_channel_pair(iface))
|
||||
return -1;
|
||||
if (!ieee80211n_supported_ht_capab(iface))
|
||||
return -1;
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
|
||||
if (hostapd_prepare_rates(iface->bss[0], iface->current_mode)) {
|
||||
wpa_printf(MSG_ERROR, "Failed to prepare rates table.");
|
||||
hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
|
||||
@ -423,23 +676,7 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = hostapd_passive_scan(iface->bss[0], 0,
|
||||
iface->conf->passive_scan_mode,
|
||||
iface->conf->passive_scan_interval,
|
||||
iface->conf->passive_scan_listen,
|
||||
NULL, NULL);
|
||||
if (ret) {
|
||||
if (ret == -1) {
|
||||
wpa_printf(MSG_DEBUG, "Passive scanning not "
|
||||
"supported");
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "Could not set passive "
|
||||
"scanning: %s", strerror(ret));
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -16,41 +16,7 @@
|
||||
#ifndef HW_FEATURES_H
|
||||
#define HW_FEATURES_H
|
||||
|
||||
#define HOSTAPD_CHAN_DISABLED 0x00000001
|
||||
#define HOSTAPD_CHAN_PASSIVE_SCAN 0x00000002
|
||||
#define HOSTAPD_CHAN_NO_IBSS 0x00000004
|
||||
#define HOSTAPD_CHAN_RADAR 0x00000008
|
||||
|
||||
struct hostapd_channel_data {
|
||||
short chan; /* channel number (IEEE 802.11) */
|
||||
short freq; /* frequency in MHz */
|
||||
int flag; /* flag for hostapd use (HOSTAPD_CHAN_*) */
|
||||
u8 max_tx_power; /* maximum transmit power in dBm */
|
||||
};
|
||||
|
||||
#define HOSTAPD_RATE_ERP 0x00000001
|
||||
#define HOSTAPD_RATE_BASIC 0x00000002
|
||||
#define HOSTAPD_RATE_PREAMBLE2 0x00000004
|
||||
#define HOSTAPD_RATE_SUPPORTED 0x00000010
|
||||
#define HOSTAPD_RATE_OFDM 0x00000020
|
||||
#define HOSTAPD_RATE_CCK 0x00000040
|
||||
#define HOSTAPD_RATE_MANDATORY 0x00000100
|
||||
|
||||
struct hostapd_rate_data {
|
||||
int rate; /* rate in 100 kbps */
|
||||
int flags; /* HOSTAPD_RATE_ flags */
|
||||
};
|
||||
|
||||
struct hostapd_hw_modes {
|
||||
int mode;
|
||||
int num_channels;
|
||||
struct hostapd_channel_data *channels;
|
||||
int num_rates;
|
||||
struct hostapd_rate_data *rates;
|
||||
u16 ht_capab;
|
||||
};
|
||||
|
||||
|
||||
#ifdef NEED_AP_MLME
|
||||
void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
|
||||
size_t num_hw_features);
|
||||
int hostapd_get_hw_features(struct hostapd_iface *iface);
|
||||
@ -58,5 +24,39 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface);
|
||||
const char * hostapd_hw_mode_txt(int mode);
|
||||
int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan);
|
||||
int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq);
|
||||
int hostapd_check_ht_capab(struct hostapd_iface *iface);
|
||||
#else /* NEED_AP_MLME */
|
||||
static inline void
|
||||
hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
|
||||
size_t num_hw_features)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int hostapd_get_hw_features(struct hostapd_iface *iface)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int hostapd_select_hw_mode(struct hostapd_iface *iface)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline const char * hostapd_hw_mode_txt(int mode)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int hostapd_check_ht_capab(struct hostapd_iface *iface)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* NEED_AP_MLME */
|
||||
|
||||
#endif /* HW_FEATURES_H */
|
@ -37,7 +37,7 @@
|
||||
* - IEEE 802.11 context transfer
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "utils/includes.h"
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#ifdef USE_KERNEL_HEADERS
|
||||
@ -46,11 +46,14 @@
|
||||
#include <netpacket/packet.h>
|
||||
#endif /* USE_KERNEL_HEADERS */
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "hostapd.h"
|
||||
#include "ap_config.h"
|
||||
#include "ieee802_11.h"
|
||||
#include "iapp.h"
|
||||
#include "eloop.h"
|
||||
#include "sta_info.h"
|
||||
#include "iapp.h"
|
||||
|
||||
|
||||
#define IAPP_MULTICAST "224.0.1.178"
|
||||
@ -304,10 +307,7 @@ static void iapp_process_add_notify(struct iapp_data *iapp,
|
||||
hostapd_logger(iapp->hapd, add->mac_addr, HOSTAPD_MODULE_IAPP,
|
||||
HOSTAPD_LEVEL_DEBUG,
|
||||
"Removing STA due to IAPP ADD-notify");
|
||||
sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_AUTHORIZED);
|
||||
eloop_cancel_timeout(ap_handle_timer, iapp->hapd, sta);
|
||||
eloop_register_timeout(0, 0, ap_handle_timer, iapp->hapd, sta);
|
||||
sta->timeout_next = STA_REMOVE;
|
||||
ap_sta_disconnect(iapp->hapd, sta, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -533,21 +533,3 @@ void iapp_deinit(struct iapp_data *iapp)
|
||||
}
|
||||
os_free(iapp);
|
||||
}
|
||||
|
||||
int iapp_reconfig(struct hostapd_data *hapd, struct hostapd_config *oldconf,
|
||||
struct hostapd_bss_config *oldbss)
|
||||
{
|
||||
if (hapd->conf->ieee802_11f != oldbss->ieee802_11f ||
|
||||
os_strcmp(hapd->conf->iapp_iface, oldbss->iapp_iface) != 0) {
|
||||
iapp_deinit(hapd->iapp);
|
||||
hapd->iapp = NULL;
|
||||
|
||||
if (hapd->conf->ieee802_11f) {
|
||||
hapd->iapp = iapp_init(hapd, hapd->conf->iapp_iface);
|
||||
if (hapd->iapp == NULL)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -22,8 +22,6 @@ struct iapp_data;
|
||||
void iapp_new_station(struct iapp_data *iapp, struct sta_info *sta);
|
||||
struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface);
|
||||
void iapp_deinit(struct iapp_data *iapp);
|
||||
int iapp_reconfig(struct hostapd_data *hapd, struct hostapd_config *oldconf,
|
||||
struct hostapd_bss_config *oldbss);
|
||||
|
||||
#else /* CONFIG_IAPP */
|
||||
|
||||
@ -42,13 +40,6 @@ static inline void iapp_deinit(struct iapp_data *iapp)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int
|
||||
iapp_reconfig(struct hostapd_data *hapd, struct hostapd_config *oldconf,
|
||||
struct hostapd_bss_config *oldbss)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IAPP */
|
||||
|
||||
#endif /* IAPP_H */
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* hostapd / IEEE 802.11 Management
|
||||
* Copyright (c) 2002-2006, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2007-2008, Intel Corporation
|
||||
* 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
|
||||
@ -16,41 +15,53 @@
|
||||
#ifndef IEEE802_11_H
|
||||
#define IEEE802_11_H
|
||||
|
||||
#include "ieee802_11_defs.h"
|
||||
#include "ieee802_11_common.h"
|
||||
|
||||
struct hostapd_frame_info {
|
||||
u32 phytype;
|
||||
u32 channel;
|
||||
u32 datarate;
|
||||
u32 ssi_signal;
|
||||
|
||||
unsigned int passive_scan:1;
|
||||
};
|
||||
|
||||
struct hostapd_iface;
|
||||
struct hostapd_data;
|
||||
struct sta_info;
|
||||
struct hostapd_frame_info;
|
||||
struct ieee80211_ht_capabilities;
|
||||
|
||||
void ieee802_11_send_deauth(struct hostapd_data *hapd, u8 *addr, u16 reason);
|
||||
void ieee802_11_mgmt(struct hostapd_data *hapd, u8 *buf, size_t len,
|
||||
u16 stype, struct hostapd_frame_info *fi);
|
||||
void ieee802_11_mgmt_cb(struct hostapd_data *hapd, u8 *buf, size_t len,
|
||||
void ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
|
||||
struct hostapd_frame_info *fi);
|
||||
void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,
|
||||
u16 stype, int ok);
|
||||
void ieee802_11_print_ssid(char *buf, const u8 *ssid, u8 len);
|
||||
void ieee80211_michael_mic_failure(struct hostapd_data *hapd, const u8 *addr,
|
||||
int local);
|
||||
#ifdef NEED_AP_MLME
|
||||
int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen);
|
||||
int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
char *buf, size_t buflen);
|
||||
#else /* NEED_AP_MLME */
|
||||
static inline int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ieee802_11_get_mib_sta(struct hostapd_data *hapd,
|
||||
struct sta_info *sta,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* NEED_AP_MLME */
|
||||
u16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
int probe);
|
||||
u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_ht_capabilities_info(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid);
|
||||
int hostapd_ht_operation_update(struct hostapd_iface *iface);
|
||||
void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
|
||||
const u8 *addr, const u8 *trans_id);
|
||||
void hostapd_get_ht_capab(struct hostapd_data *hapd,
|
||||
struct ieee80211_ht_capabilities *ht_cap,
|
||||
struct ieee80211_ht_capabilities *neg_ht_cap);
|
||||
u16 copy_sta_ht_capab(struct sta_info *sta, const u8 *ht_capab,
|
||||
size_t ht_capab_len);
|
||||
void update_ht_state(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
|
||||
const u8 *buf, size_t len, int ack);
|
||||
void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
|
||||
int wds);
|
||||
|
||||
#endif /* IEEE802_11_H */
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / IEEE 802.11 authentication (ACL)
|
||||
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
|
||||
* 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
|
||||
@ -17,17 +17,16 @@
|
||||
* authentication frame processing.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "utils/includes.h"
|
||||
|
||||
#ifndef CONFIG_NATIVE_WINDOWS
|
||||
|
||||
#include "hostapd.h"
|
||||
#include "ieee802_11.h"
|
||||
#include "ieee802_11_auth.h"
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "radius/radius.h"
|
||||
#include "radius/radius_client.h"
|
||||
#include "eloop.h"
|
||||
#include "driver.h"
|
||||
#include "hostapd.h"
|
||||
#include "ap_config.h"
|
||||
#include "ieee802_11.h"
|
||||
#include "ieee802_11_auth.h"
|
||||
|
||||
#define RADIUS_ACL_TIMEOUT 30
|
||||
|
||||
@ -53,6 +52,7 @@ struct hostapd_acl_query_data {
|
||||
};
|
||||
|
||||
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
static void hostapd_acl_cache_free(struct hostapd_cached_radius_acl *acl_cache)
|
||||
{
|
||||
struct hostapd_cached_radius_acl *prev;
|
||||
@ -96,6 +96,7 @@ static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr,
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
|
||||
|
||||
static void hostapd_acl_query_free(struct hostapd_acl_query_data *query)
|
||||
@ -107,6 +108,7 @@ static void hostapd_acl_query_free(struct hostapd_acl_query_data *query)
|
||||
}
|
||||
|
||||
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
|
||||
struct hostapd_acl_query_data *query)
|
||||
{
|
||||
@ -193,9 +195,9 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
|
||||
|
||||
fail:
|
||||
radius_msg_free(msg);
|
||||
os_free(msg);
|
||||
return -1;
|
||||
}
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
|
||||
|
||||
/**
|
||||
@ -234,6 +236,9 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
|
||||
return HOSTAPD_ACL_REJECT;
|
||||
|
||||
if (hapd->conf->macaddr_acl == USE_EXTERNAL_RADIUS_AUTH) {
|
||||
#ifdef CONFIG_NO_RADIUS
|
||||
return HOSTAPD_ACL_REJECT;
|
||||
#else /* CONFIG_NO_RADIUS */
|
||||
struct hostapd_acl_query_data *query;
|
||||
|
||||
/* Check whether ACL cache has an entry for this station */
|
||||
@ -289,12 +294,14 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
|
||||
/* Queued data will be processed in hostapd_acl_recv_radius()
|
||||
* when RADIUS server replies to the sent Access-Request. */
|
||||
return HOSTAPD_ACL_PENDING;
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
}
|
||||
|
||||
return HOSTAPD_ACL_REJECT;
|
||||
}
|
||||
|
||||
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
static void hostapd_acl_expire_cache(struct hostapd_data *hapd, time_t now)
|
||||
{
|
||||
struct hostapd_cached_radius_acl *prev, *entry, *tmp;
|
||||
@ -311,7 +318,7 @@ static void hostapd_acl_expire_cache(struct hostapd_data *hapd, time_t now)
|
||||
else
|
||||
hapd->acl_cache = entry->next;
|
||||
#ifdef CONFIG_DRIVER_RADIUS_ACL
|
||||
hostapd_set_radius_acl_expire(hapd, entry->addr);
|
||||
hapd->drv.set_radius_acl_expire(hapd, entry->addr);
|
||||
#endif /* CONFIG_DRIVER_RADIUS_ACL */
|
||||
tmp = entry;
|
||||
entry = entry->next;
|
||||
@ -389,11 +396,12 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
|
||||
struct hostapd_data *hapd = data;
|
||||
struct hostapd_acl_query_data *query, *prev;
|
||||
struct hostapd_cached_radius_acl *cache;
|
||||
struct radius_hdr *hdr = radius_msg_get_hdr(msg);
|
||||
|
||||
query = hapd->acl_queries;
|
||||
prev = NULL;
|
||||
while (query) {
|
||||
if (query->radius_id == msg->hdr->identifier)
|
||||
if (query->radius_id == hdr->identifier)
|
||||
break;
|
||||
prev = query;
|
||||
query = query->next;
|
||||
@ -410,10 +418,10 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
|
||||
return RADIUS_RX_INVALID_AUTHENTICATOR;
|
||||
}
|
||||
|
||||
if (msg->hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
|
||||
msg->hdr->code != RADIUS_CODE_ACCESS_REJECT) {
|
||||
if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
|
||||
hdr->code != RADIUS_CODE_ACCESS_REJECT) {
|
||||
wpa_printf(MSG_DEBUG, "Unknown RADIUS message code %d to ACL "
|
||||
"query", msg->hdr->code);
|
||||
"query", hdr->code);
|
||||
return RADIUS_RX_UNKNOWN;
|
||||
}
|
||||
|
||||
@ -425,7 +433,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
|
||||
}
|
||||
time(&cache->timestamp);
|
||||
os_memcpy(cache->addr, query->addr, sizeof(cache->addr));
|
||||
if (msg->hdr->code == RADIUS_CODE_ACCESS_ACCEPT) {
|
||||
if (hdr->code == RADIUS_CODE_ACCESS_ACCEPT) {
|
||||
if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT,
|
||||
&cache->session_timeout) == 0)
|
||||
cache->accepted = HOSTAPD_ACL_ACCEPT_TIMEOUT;
|
||||
@ -450,14 +458,15 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
|
||||
hapd->acl_cache = cache;
|
||||
|
||||
#ifdef CONFIG_DRIVER_RADIUS_ACL
|
||||
hostapd_set_radius_acl_auth(hapd, query->addr, cache->accepted,
|
||||
cache->session_timeout);
|
||||
hapd->drv.set_radius_acl_auth(hapd, query->addr, cache->accepted,
|
||||
cache->session_timeout);
|
||||
#else /* CONFIG_DRIVER_RADIUS_ACL */
|
||||
#ifdef NEED_AP_MLME
|
||||
/* Re-send original authentication frame for 802.11 processing */
|
||||
wpa_printf(MSG_DEBUG, "Re-sending authentication frame after "
|
||||
"successful RADIUS ACL query");
|
||||
ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len,
|
||||
WLAN_FC_STYPE_AUTH, NULL);
|
||||
ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len, NULL);
|
||||
#endif /* NEED_AP_MLME */
|
||||
#endif /* CONFIG_DRIVER_RADIUS_ACL */
|
||||
|
||||
done:
|
||||
@ -470,6 +479,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
|
||||
|
||||
return RADIUS_RX_PROCESSED;
|
||||
}
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
|
||||
|
||||
/**
|
||||
@ -479,11 +489,13 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
|
||||
*/
|
||||
int hostapd_acl_init(struct hostapd_data *hapd)
|
||||
{
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
if (radius_client_register(hapd->radius, RADIUS_AUTH,
|
||||
hostapd_acl_recv_radius, hapd))
|
||||
return -1;
|
||||
|
||||
eloop_register_timeout(10, 0, hostapd_acl_expire, hapd, NULL);
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -497,9 +509,11 @@ void hostapd_acl_deinit(struct hostapd_data *hapd)
|
||||
{
|
||||
struct hostapd_acl_query_data *query, *prev;
|
||||
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
eloop_cancel_timeout(hostapd_acl_expire, hapd, NULL);
|
||||
|
||||
hostapd_acl_cache_free(hapd->acl_cache);
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
|
||||
query = hapd->acl_queries;
|
||||
while (query) {
|
||||
@ -508,16 +522,3 @@ void hostapd_acl_deinit(struct hostapd_data *hapd)
|
||||
hostapd_acl_query_free(prev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int hostapd_acl_reconfig(struct hostapd_data *hapd,
|
||||
struct hostapd_config *oldconf)
|
||||
{
|
||||
if (!hapd->radius_client_reconfigured)
|
||||
return 0;
|
||||
|
||||
hostapd_acl_deinit(hapd);
|
||||
return hostapd_acl_init(hapd);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
@ -27,7 +27,5 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
|
||||
u32 *acct_interim_interval, int *vlan_id);
|
||||
int hostapd_acl_init(struct hostapd_data *hapd);
|
||||
void hostapd_acl_deinit(struct hostapd_data *hapd);
|
||||
int hostapd_acl_reconfig(struct hostapd_data *hapd,
|
||||
struct hostapd_config *oldconf);
|
||||
|
||||
#endif /* IEEE802_11_AUTH_H */
|
270
contrib/wpa/src/ap/ieee802_11_ht.c
Normal file
270
contrib/wpa/src/ap/ieee802_11_ht.c
Normal file
@ -0,0 +1,270 @@
|
||||
/*
|
||||
* hostapd / IEEE 802.11n HT
|
||||
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2007-2008, Intel Corporation
|
||||
*
|
||||
* 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 "drivers/driver.h"
|
||||
#include "hostapd.h"
|
||||
#include "ap_config.h"
|
||||
#include "sta_info.h"
|
||||
#include "beacon.h"
|
||||
#include "ieee802_11.h"
|
||||
|
||||
|
||||
u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
struct ieee80211_ht_capabilities *cap;
|
||||
u8 *pos = eid;
|
||||
|
||||
if (!hapd->iconf->ieee80211n || !hapd->iface->current_mode)
|
||||
return eid;
|
||||
|
||||
*pos++ = WLAN_EID_HT_CAP;
|
||||
*pos++ = sizeof(*cap);
|
||||
|
||||
cap = (struct ieee80211_ht_capabilities *) pos;
|
||||
os_memset(cap, 0, sizeof(*cap));
|
||||
cap->ht_capabilities_info = host_to_le16(hapd->iconf->ht_capab);
|
||||
cap->a_mpdu_params = hapd->iface->current_mode->a_mpdu_params;
|
||||
os_memcpy(cap->supported_mcs_set, hapd->iface->current_mode->mcs_set,
|
||||
16);
|
||||
|
||||
/* TODO: ht_extended_capabilities (now fully disabled) */
|
||||
/* TODO: tx_bf_capability_info (now fully disabled) */
|
||||
/* TODO: asel_capabilities (now fully disabled) */
|
||||
|
||||
pos += sizeof(*cap);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
struct ieee80211_ht_operation *oper;
|
||||
u8 *pos = eid;
|
||||
|
||||
if (!hapd->iconf->ieee80211n)
|
||||
return eid;
|
||||
|
||||
*pos++ = WLAN_EID_HT_OPERATION;
|
||||
*pos++ = sizeof(*oper);
|
||||
|
||||
oper = (struct ieee80211_ht_operation *) pos;
|
||||
os_memset(oper, 0, sizeof(*oper));
|
||||
|
||||
oper->control_chan = hapd->iconf->channel;
|
||||
oper->operation_mode = host_to_le16(hapd->iface->ht_op_mode);
|
||||
if (hapd->iconf->secondary_channel == 1)
|
||||
oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE |
|
||||
HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;
|
||||
if (hapd->iconf->secondary_channel == -1)
|
||||
oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW |
|
||||
HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;
|
||||
|
||||
pos += sizeof(*oper);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
op_mode
|
||||
Set to 0 (HT pure) under the followign conditions
|
||||
- all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
|
||||
- all STAs in the BSS are 20 MHz HT in 20 MHz BSS
|
||||
Set to 1 (HT non-member protection) if there may be non-HT STAs
|
||||
in both the primary and the secondary channel
|
||||
Set to 2 if only HT STAs are associated in BSS,
|
||||
however and at least one 20 MHz HT STA is associated
|
||||
Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
|
||||
(currently non-GF HT station is considered as non-HT STA also)
|
||||
*/
|
||||
int hostapd_ht_operation_update(struct hostapd_iface *iface)
|
||||
{
|
||||
u16 cur_op_mode, new_op_mode;
|
||||
int op_mode_changes = 0;
|
||||
|
||||
if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed)
|
||||
return 0;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s current operation mode=0x%X",
|
||||
__func__, iface->ht_op_mode);
|
||||
|
||||
if (!(iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)
|
||||
&& iface->num_sta_ht_no_gf) {
|
||||
iface->ht_op_mode |=
|
||||
HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
|
||||
op_mode_changes++;
|
||||
} else if ((iface->ht_op_mode &
|
||||
HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
|
||||
iface->num_sta_ht_no_gf == 0) {
|
||||
iface->ht_op_mode &=
|
||||
~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
|
||||
op_mode_changes++;
|
||||
}
|
||||
|
||||
if (!(iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
|
||||
(iface->num_sta_no_ht || iface->olbc_ht)) {
|
||||
iface->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
|
||||
op_mode_changes++;
|
||||
} else if ((iface->ht_op_mode &
|
||||
HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
|
||||
(iface->num_sta_no_ht == 0 && !iface->olbc_ht)) {
|
||||
iface->ht_op_mode &=
|
||||
~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
|
||||
op_mode_changes++;
|
||||
}
|
||||
|
||||
/* Note: currently we switch to the MIXED op mode if HT non-greenfield
|
||||
* station is associated. Probably it's a theoretical case, since
|
||||
* it looks like all known HT STAs support greenfield.
|
||||
*/
|
||||
new_op_mode = 0;
|
||||
if (iface->num_sta_no_ht ||
|
||||
(iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
|
||||
new_op_mode = OP_MODE_MIXED;
|
||||
else if ((iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
|
||||
&& iface->num_sta_ht_20mhz)
|
||||
new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
|
||||
else if (iface->olbc_ht)
|
||||
new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
|
||||
else
|
||||
new_op_mode = OP_MODE_PURE;
|
||||
|
||||
cur_op_mode = iface->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
|
||||
if (cur_op_mode != new_op_mode) {
|
||||
iface->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
|
||||
iface->ht_op_mode |= new_op_mode;
|
||||
op_mode_changes++;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s new operation mode=0x%X changes=%d",
|
||||
__func__, iface->ht_op_mode, op_mode_changes);
|
||||
|
||||
return op_mode_changes;
|
||||
}
|
||||
|
||||
|
||||
u16 copy_sta_ht_capab(struct sta_info *sta, const u8 *ht_capab,
|
||||
size_t ht_capab_len)
|
||||
{
|
||||
if (!ht_capab ||
|
||||
ht_capab_len < sizeof(struct ieee80211_ht_capabilities)) {
|
||||
sta->flags &= ~WLAN_STA_HT;
|
||||
os_free(sta->ht_capabilities);
|
||||
sta->ht_capabilities = NULL;
|
||||
return WLAN_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (sta->ht_capabilities == NULL) {
|
||||
sta->ht_capabilities =
|
||||
os_zalloc(sizeof(struct ieee80211_ht_capabilities));
|
||||
if (sta->ht_capabilities == NULL)
|
||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
}
|
||||
|
||||
sta->flags |= WLAN_STA_HT;
|
||||
os_memcpy(sta->ht_capabilities, ht_capab,
|
||||
sizeof(struct ieee80211_ht_capabilities));
|
||||
|
||||
return WLAN_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static void update_sta_ht(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
{
|
||||
u16 ht_capab;
|
||||
|
||||
ht_capab = le_to_host16(sta->ht_capabilities->ht_capabilities_info);
|
||||
wpa_printf(MSG_DEBUG, "HT: STA " MACSTR " HT Capabilities Info: "
|
||||
"0x%04x", MAC2STR(sta->addr), ht_capab);
|
||||
if ((ht_capab & HT_CAP_INFO_GREEN_FIELD) == 0) {
|
||||
if (!sta->no_ht_gf_set) {
|
||||
sta->no_ht_gf_set = 1;
|
||||
hapd->iface->num_sta_ht_no_gf++;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "%s STA " MACSTR " - no greenfield, num "
|
||||
"of non-gf stations %d",
|
||||
__func__, MAC2STR(sta->addr),
|
||||
hapd->iface->num_sta_ht_no_gf);
|
||||
}
|
||||
if ((ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) == 0) {
|
||||
if (!sta->ht_20mhz_set) {
|
||||
sta->ht_20mhz_set = 1;
|
||||
hapd->iface->num_sta_ht_20mhz++;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "%s STA " MACSTR " - 20 MHz HT, num of "
|
||||
"20MHz HT STAs %d",
|
||||
__func__, MAC2STR(sta->addr),
|
||||
hapd->iface->num_sta_ht_20mhz);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void update_sta_no_ht(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
{
|
||||
if (!sta->no_ht_set) {
|
||||
sta->no_ht_set = 1;
|
||||
hapd->iface->num_sta_no_ht++;
|
||||
}
|
||||
if (hapd->iconf->ieee80211n) {
|
||||
wpa_printf(MSG_DEBUG, "%s STA " MACSTR " - no HT, num of "
|
||||
"non-HT stations %d",
|
||||
__func__, MAC2STR(sta->addr),
|
||||
hapd->iface->num_sta_no_ht);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void update_ht_state(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
{
|
||||
if ((sta->flags & WLAN_STA_HT) && sta->ht_capabilities)
|
||||
update_sta_ht(hapd, sta);
|
||||
else
|
||||
update_sta_no_ht(hapd, sta);
|
||||
|
||||
if (hostapd_ht_operation_update(hapd->iface) > 0)
|
||||
ieee802_11_set_beacons(hapd->iface);
|
||||
}
|
||||
|
||||
|
||||
void hostapd_get_ht_capab(struct hostapd_data *hapd,
|
||||
struct ieee80211_ht_capabilities *ht_cap,
|
||||
struct ieee80211_ht_capabilities *neg_ht_cap)
|
||||
{
|
||||
u16 cap;
|
||||
|
||||
if (ht_cap == NULL)
|
||||
return;
|
||||
os_memcpy(neg_ht_cap, ht_cap, sizeof(*neg_ht_cap));
|
||||
cap = le_to_host16(neg_ht_cap->ht_capabilities_info);
|
||||
cap &= hapd->iconf->ht_capab;
|
||||
cap |= (hapd->iconf->ht_capab & HT_CAP_INFO_SMPS_DISABLED);
|
||||
|
||||
/*
|
||||
* STBC needs to be handled specially
|
||||
* if we don't support RX STBC, mask out TX STBC in the STA's HT caps
|
||||
* if we don't support TX STBC, mask out RX STBC in the STA's HT caps
|
||||
*/
|
||||
if (!(hapd->iconf->ht_capab & HT_CAP_INFO_RX_STBC_MASK))
|
||||
cap &= ~HT_CAP_INFO_TX_STBC;
|
||||
if (!(hapd->iconf->ht_capab & HT_CAP_INFO_TX_STBC))
|
||||
cap &= ~HT_CAP_INFO_RX_STBC_MASK;
|
||||
|
||||
neg_ht_cap->ht_capabilities_info = host_to_le16(cap);
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / IEEE 802.1X-2004 Authenticator
|
||||
* Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
|
||||
* 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
|
||||
@ -12,25 +12,28 @@
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "hostapd.h"
|
||||
#include "ieee802_1x.h"
|
||||
#include "accounting.h"
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "crypto/md5.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/wpa_ctrl.h"
|
||||
#include "radius/radius.h"
|
||||
#include "radius/radius_client.h"
|
||||
#include "eapol_sm.h"
|
||||
#include "md5.h"
|
||||
#include "rc4.h"
|
||||
#include "eloop.h"
|
||||
#include "sta_info.h"
|
||||
#include "wpa.h"
|
||||
#include "preauth.h"
|
||||
#include "pmksa_cache.h"
|
||||
#include "driver.h"
|
||||
#include "hw_features.h"
|
||||
#include "eap_server/eap.h"
|
||||
#include "ieee802_11_defs.h"
|
||||
#include "eap_common/eap_wsc_common.h"
|
||||
#include "eapol_auth/eapol_auth_sm.h"
|
||||
#include "eapol_auth/eapol_auth_sm_i.h"
|
||||
#include "hostapd.h"
|
||||
#include "accounting.h"
|
||||
#include "sta_info.h"
|
||||
#include "wpa_auth.h"
|
||||
#include "preauth_auth.h"
|
||||
#include "pmksa_cache_auth.h"
|
||||
#include "ap_config.h"
|
||||
#include "ieee802_1x.h"
|
||||
|
||||
|
||||
static void ieee802_1x_finished(struct hostapd_data *hapd,
|
||||
@ -67,7 +70,7 @@ static void ieee802_1x_send(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
if (sta->flags & WLAN_STA_PREAUTH) {
|
||||
rsn_preauth_send(hapd, sta, buf, len);
|
||||
} else {
|
||||
hostapd_send_eapol(hapd, sta->addr, buf, len, encrypt);
|
||||
hapd->drv.send_eapol(hapd, sta->addr, buf, len, encrypt);
|
||||
}
|
||||
|
||||
os_free(buf);
|
||||
@ -83,15 +86,21 @@ void ieee802_1x_set_sta_authorized(struct hostapd_data *hapd,
|
||||
return;
|
||||
|
||||
if (authorized) {
|
||||
if (!(sta->flags & WLAN_STA_AUTHORIZED))
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO,
|
||||
AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr));
|
||||
sta->flags |= WLAN_STA_AUTHORIZED;
|
||||
res = hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
|
||||
WLAN_STA_AUTHORIZED, ~0);
|
||||
res = hapd->drv.set_authorized(hapd, sta, 1);
|
||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
|
||||
HOSTAPD_LEVEL_DEBUG, "authorizing port");
|
||||
} else {
|
||||
if ((sta->flags & (WLAN_STA_AUTHORIZED | WLAN_STA_ASSOC)) ==
|
||||
(WLAN_STA_AUTHORIZED | WLAN_STA_ASSOC))
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO,
|
||||
AP_STA_DISCONNECTED MACSTR,
|
||||
MAC2STR(sta->addr));
|
||||
sta->flags &= ~WLAN_STA_AUTHORIZED;
|
||||
res = hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
|
||||
0, ~WLAN_STA_AUTHORIZED);
|
||||
res = hapd->drv.set_authorized(hapd, sta, 0);
|
||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
|
||||
HOSTAPD_LEVEL_DEBUG, "unauthorizing port");
|
||||
}
|
||||
@ -185,6 +194,7 @@ static void ieee802_1x_tx_key_one(struct hostapd_data *hapd,
|
||||
}
|
||||
|
||||
|
||||
#ifndef CONFIG_NO_VLAN
|
||||
static struct hostapd_wep_keys *
|
||||
ieee802_1x_group_alloc(struct hostapd_data *hapd, const char *ifname)
|
||||
{
|
||||
@ -219,11 +229,11 @@ ieee802_1x_group_alloc(struct hostapd_data *hapd, const char *ifname)
|
||||
wpa_hexdump_key(MSG_DEBUG, "Default WEP key (dynamic VLAN)",
|
||||
key->key[key->idx], key->len[key->idx]);
|
||||
|
||||
if (hostapd_set_encryption(ifname, hapd, "WEP", NULL, key->idx,
|
||||
key->key[key->idx], key->len[key->idx], 1))
|
||||
if (hapd->drv.set_key(ifname, hapd, WPA_ALG_WEP, NULL, key->idx, 1,
|
||||
NULL, 0, key->key[key->idx], key->len[key->idx]))
|
||||
printf("Could not set dynamic VLAN WEP encryption key.\n");
|
||||
|
||||
hostapd_set_ieee8021x(ifname, hapd, 1);
|
||||
hapd->drv.set_drv_ieee8021x(hapd, ifname, 1);
|
||||
|
||||
return key;
|
||||
}
|
||||
@ -279,13 +289,17 @@ ieee802_1x_get_group(struct hostapd_data *hapd, struct hostapd_ssid *ssid,
|
||||
|
||||
return ssid->dyn_vlan_keys[vlan_id];
|
||||
}
|
||||
#endif /* CONFIG_NO_VLAN */
|
||||
|
||||
|
||||
void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
{
|
||||
struct hostapd_wep_keys *key = NULL;
|
||||
struct eapol_authenticator *eapol = hapd->eapol_auth;
|
||||
struct eapol_state_machine *sm = sta->eapol_sm;
|
||||
#ifndef CONFIG_NO_VLAN
|
||||
struct hostapd_wep_keys *key = NULL;
|
||||
int vlan_id;
|
||||
#endif /* CONFIG_NO_VLAN */
|
||||
|
||||
if (sm == NULL || !sm->eap_if->eapKeyData)
|
||||
return;
|
||||
@ -293,6 +307,7 @@ void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
wpa_printf(MSG_DEBUG, "IEEE 802.1X: Sending EAPOL-Key(s) to " MACSTR,
|
||||
MAC2STR(sta->addr));
|
||||
|
||||
#ifndef CONFIG_NO_VLAN
|
||||
vlan_id = sta->vlan_id;
|
||||
if (vlan_id < 0 || vlan_id > MAX_VLAN_ID)
|
||||
vlan_id = 0;
|
||||
@ -303,9 +318,11 @@ void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
ieee802_1x_tx_key_one(hapd, sta, key->idx, 1,
|
||||
key->key[key->idx],
|
||||
key->len[key->idx]);
|
||||
} else if (hapd->default_wep_key) {
|
||||
ieee802_1x_tx_key_one(hapd, sta, hapd->default_wep_key_idx, 1,
|
||||
hapd->default_wep_key,
|
||||
} else
|
||||
#endif /* CONFIG_NO_VLAN */
|
||||
if (eapol->default_wep_key) {
|
||||
ieee802_1x_tx_key_one(hapd, sta, eapol->default_wep_key_idx, 1,
|
||||
eapol->default_wep_key,
|
||||
hapd->conf->default_wep_key_len);
|
||||
}
|
||||
|
||||
@ -328,10 +345,9 @@ void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
|
||||
/* TODO: set encryption in TX callback, i.e., only after STA
|
||||
* has ACKed EAPOL-Key frame */
|
||||
if (hostapd_set_encryption(hapd->conf->iface, hapd, "WEP",
|
||||
sta->addr, 0, ikey,
|
||||
hapd->conf->individual_wep_key_len,
|
||||
1)) {
|
||||
if (hapd->drv.set_key(hapd->conf->iface, hapd, WPA_ALG_WEP,
|
||||
sta->addr, 0, 1, NULL, 0, ikey,
|
||||
hapd->conf->individual_wep_key_len)) {
|
||||
wpa_printf(MSG_ERROR, "Could not set individual WEP "
|
||||
"encryption.");
|
||||
}
|
||||
@ -343,10 +359,7 @@ void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
|
||||
const char *radius_mode_txt(struct hostapd_data *hapd)
|
||||
{
|
||||
if (hapd->iface->current_mode == NULL)
|
||||
return "802.11";
|
||||
|
||||
switch (hapd->iface->current_mode->mode) {
|
||||
switch (hapd->iface->conf->hw_mode) {
|
||||
case HOSTAPD_MODE_IEEE80211A:
|
||||
return "802.11a";
|
||||
case HOSTAPD_MODE_IEEE80211G:
|
||||
@ -371,6 +384,7 @@ int radius_sta_rate(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
}
|
||||
|
||||
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
static void ieee802_1x_learn_identity(struct hostapd_data *hapd,
|
||||
struct eapol_state_machine *sm,
|
||||
const u8 *eap, size_t len)
|
||||
@ -520,7 +534,8 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
|
||||
|
||||
/* State attribute must be copied if and only if this packet is
|
||||
* Access-Request reply to the previous Access-Challenge */
|
||||
if (sm->last_recv_radius && sm->last_recv_radius->hdr->code ==
|
||||
if (sm->last_recv_radius &&
|
||||
radius_msg_get_hdr(sm->last_recv_radius)->code ==
|
||||
RADIUS_CODE_ACCESS_CHALLENGE) {
|
||||
int res = radius_msg_copy_attr(msg, sm->last_recv_radius,
|
||||
RADIUS_ATTR_STATE);
|
||||
@ -539,30 +554,8 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
|
||||
|
||||
fail:
|
||||
radius_msg_free(msg);
|
||||
os_free(msg);
|
||||
}
|
||||
|
||||
|
||||
char *eap_type_text(u8 type)
|
||||
{
|
||||
switch (type) {
|
||||
case EAP_TYPE_IDENTITY: return "Identity";
|
||||
case EAP_TYPE_NOTIFICATION: return "Notification";
|
||||
case EAP_TYPE_NAK: return "Nak";
|
||||
case EAP_TYPE_MD5: return "MD5-Challenge";
|
||||
case EAP_TYPE_OTP: return "One-Time Password";
|
||||
case EAP_TYPE_GTC: return "Generic Token Card";
|
||||
case EAP_TYPE_TLS: return "TLS";
|
||||
case EAP_TYPE_TTLS: return "TTLS";
|
||||
case EAP_TYPE_PEAP: return "PEAP";
|
||||
case EAP_TYPE_SIM: return "SIM";
|
||||
case EAP_TYPE_FAST: return "FAST";
|
||||
case EAP_TYPE_SAKE: return "SAKE";
|
||||
case EAP_TYPE_PSK: return "PSK";
|
||||
case EAP_TYPE_PAX: return "PAX";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
|
||||
|
||||
static void handle_eap_response(struct hostapd_data *hapd,
|
||||
@ -587,7 +580,7 @@ static void handle_eap_response(struct hostapd_data *hapd,
|
||||
HOSTAPD_LEVEL_DEBUG, "received EAP packet (code=%d "
|
||||
"id=%d len=%d) from STA: EAP Response-%s (%d)",
|
||||
eap->code, eap->identifier, be_to_host16(eap->length),
|
||||
eap_type_text(type), type);
|
||||
eap_server_get_name(0, type), type);
|
||||
|
||||
sm->dot1xAuthEapolRespFramesRx++;
|
||||
|
||||
@ -647,6 +640,22 @@ static void handle_eap(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
}
|
||||
|
||||
|
||||
static struct eapol_state_machine *
|
||||
ieee802_1x_alloc_eapol_sm(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
{
|
||||
int flags = 0;
|
||||
if (sta->flags & WLAN_STA_PREAUTH)
|
||||
flags |= EAPOL_SM_PREAUTH;
|
||||
if (sta->wpa_sm) {
|
||||
flags |= EAPOL_SM_USES_WPA;
|
||||
if (wpa_auth_sta_get_pmksa(sta->wpa_sm))
|
||||
flags |= EAPOL_SM_FROM_PMKSA_CACHE;
|
||||
}
|
||||
return eapol_auth_alloc(hapd->eapol_auth, sta->addr, flags,
|
||||
sta->wps_ie, sta);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ieee802_1x_receive - Process the EAPOL frames from the Supplicant
|
||||
* @hapd: hostapd BSS data
|
||||
@ -672,8 +681,9 @@ void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
|
||||
wpa_printf(MSG_DEBUG, "IEEE 802.1X: %lu bytes from " MACSTR,
|
||||
(unsigned long) len, MAC2STR(sa));
|
||||
sta = ap_get_sta(hapd, sa);
|
||||
if (!sta) {
|
||||
printf(" no station information available\n");
|
||||
if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {
|
||||
wpa_printf(MSG_DEBUG, "IEEE 802.1X data frame from not "
|
||||
"associated STA");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -720,9 +730,7 @@ void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
|
||||
return;
|
||||
|
||||
if (!sta->eapol_sm) {
|
||||
sta->eapol_sm = eapol_auth_alloc(hapd->eapol_auth, sta->addr,
|
||||
sta->flags & WLAN_STA_PREAUTH,
|
||||
sta);
|
||||
sta->eapol_sm = ieee802_1x_alloc_eapol_sm(hapd, sta);
|
||||
if (!sta->eapol_sm)
|
||||
return;
|
||||
|
||||
@ -839,9 +847,7 @@ void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
if (sta->eapol_sm == NULL) {
|
||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
|
||||
HOSTAPD_LEVEL_DEBUG, "start authentication");
|
||||
sta->eapol_sm = eapol_auth_alloc(hapd->eapol_auth, sta->addr,
|
||||
sta->flags & WLAN_STA_PREAUTH,
|
||||
sta);
|
||||
sta->eapol_sm = ieee802_1x_alloc_eapol_sm(hapd, sta);
|
||||
if (sta->eapol_sm == NULL) {
|
||||
hostapd_logger(hapd, sta->addr,
|
||||
HOSTAPD_MODULE_IEEE8021X,
|
||||
@ -900,47 +906,6 @@ void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
}
|
||||
|
||||
|
||||
void ieee802_1x_free_radius_class(struct radius_class_data *class)
|
||||
{
|
||||
size_t i;
|
||||
if (class == NULL)
|
||||
return;
|
||||
for (i = 0; i < class->count; i++)
|
||||
os_free(class->attr[i].data);
|
||||
os_free(class->attr);
|
||||
class->attr = NULL;
|
||||
class->count = 0;
|
||||
}
|
||||
|
||||
|
||||
int ieee802_1x_copy_radius_class(struct radius_class_data *dst,
|
||||
const struct radius_class_data *src)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (src->attr == NULL)
|
||||
return 0;
|
||||
|
||||
dst->attr = os_zalloc(src->count * sizeof(struct radius_attr_data));
|
||||
if (dst->attr == NULL)
|
||||
return -1;
|
||||
|
||||
dst->count = 0;
|
||||
|
||||
for (i = 0; i < src->count; i++) {
|
||||
dst->attr[i].data = os_malloc(src->attr[i].len);
|
||||
if (dst->attr[i].data == NULL)
|
||||
break;
|
||||
dst->count++;
|
||||
os_memcpy(dst->attr[i].data, src->attr[i].data,
|
||||
src->attr[i].len);
|
||||
dst->attr[i].len = src->attr[i].len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ieee802_1x_free_station(struct sta_info *sta)
|
||||
{
|
||||
struct eapol_state_machine *sm = sta->eapol_sm;
|
||||
@ -950,17 +915,17 @@ void ieee802_1x_free_station(struct sta_info *sta)
|
||||
|
||||
sta->eapol_sm = NULL;
|
||||
|
||||
if (sm->last_recv_radius) {
|
||||
radius_msg_free(sm->last_recv_radius);
|
||||
os_free(sm->last_recv_radius);
|
||||
}
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
radius_msg_free(sm->last_recv_radius);
|
||||
radius_free_class(&sm->radius_class);
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
|
||||
os_free(sm->identity);
|
||||
ieee802_1x_free_radius_class(&sm->radius_class);
|
||||
eapol_auth_free(sm);
|
||||
}
|
||||
|
||||
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
@ -1010,12 +975,14 @@ static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,
|
||||
if (eap_type >= 0)
|
||||
sm->eap_type_authsrv = eap_type;
|
||||
os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)",
|
||||
eap_type >= 0 ? eap_type_text(eap_type) : "??",
|
||||
eap_type >= 0 ? eap_server_get_name(0, eap_type) :
|
||||
"??",
|
||||
eap_type);
|
||||
break;
|
||||
case EAP_CODE_RESPONSE:
|
||||
os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)",
|
||||
eap_type >= 0 ? eap_type_text(eap_type) : "??",
|
||||
eap_type >= 0 ? eap_server_get_name(0, eap_type) :
|
||||
"??",
|
||||
eap_type);
|
||||
break;
|
||||
case EAP_CODE_SUCCESS:
|
||||
@ -1097,7 +1064,7 @@ static void ieee802_1x_store_radius_class(struct hostapd_data *hapd,
|
||||
sm == NULL)
|
||||
return;
|
||||
|
||||
ieee802_1x_free_radius_class(&sm->radius_class);
|
||||
radius_free_class(&sm->radius_class);
|
||||
count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1);
|
||||
if (count <= 0)
|
||||
return;
|
||||
@ -1225,8 +1192,9 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
|
||||
int session_timeout_set, old_vlanid = 0;
|
||||
struct eapol_state_machine *sm;
|
||||
int override_eapReq = 0;
|
||||
struct radius_hdr *hdr = radius_msg_get_hdr(msg);
|
||||
|
||||
sm = ieee802_1x_search_radius_identifier(hapd, msg->hdr->identifier);
|
||||
sm = ieee802_1x_search_radius_identifier(hapd, hdr->identifier);
|
||||
if (sm == NULL) {
|
||||
wpa_printf(MSG_DEBUG, "IEEE 802.1X: Could not find matching "
|
||||
"station for this RADIUS message");
|
||||
@ -1236,7 +1204,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
|
||||
|
||||
/* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be
|
||||
* present when packet contains an EAP-Message attribute */
|
||||
if (msg->hdr->code == RADIUS_CODE_ACCESS_REJECT &&
|
||||
if (hdr->code == RADIUS_CODE_ACCESS_REJECT &&
|
||||
radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL,
|
||||
0) < 0 &&
|
||||
radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) {
|
||||
@ -1250,9 +1218,9 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
|
||||
return RADIUS_RX_INVALID_AUTHENTICATOR;
|
||||
}
|
||||
|
||||
if (msg->hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
|
||||
msg->hdr->code != RADIUS_CODE_ACCESS_REJECT &&
|
||||
msg->hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) {
|
||||
if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
|
||||
hdr->code != RADIUS_CODE_ACCESS_REJECT &&
|
||||
hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) {
|
||||
printf("Unknown RADIUS message code\n");
|
||||
return RADIUS_RX_UNKNOWN;
|
||||
}
|
||||
@ -1261,11 +1229,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
|
||||
wpa_printf(MSG_DEBUG, "RADIUS packet matching with station " MACSTR,
|
||||
MAC2STR(sta->addr));
|
||||
|
||||
if (sm->last_recv_radius) {
|
||||
radius_msg_free(sm->last_recv_radius);
|
||||
os_free(sm->last_recv_radius);
|
||||
}
|
||||
|
||||
radius_msg_free(sm->last_recv_radius);
|
||||
sm->last_recv_radius = msg;
|
||||
|
||||
session_timeout_set =
|
||||
@ -1275,8 +1239,8 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
|
||||
&termination_action))
|
||||
termination_action = RADIUS_TERMINATION_ACTION_DEFAULT;
|
||||
|
||||
if (hapd->conf->radius->acct_interim_interval == 0 &&
|
||||
msg->hdr->code == RADIUS_CODE_ACCESS_ACCEPT &&
|
||||
if (hapd->conf->acct_interim_interval == 0 &&
|
||||
hdr->code == RADIUS_CODE_ACCESS_ACCEPT &&
|
||||
radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL,
|
||||
&acct_interim_interval) == 0) {
|
||||
if (acct_interim_interval < 60) {
|
||||
@ -1291,10 +1255,11 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
|
||||
}
|
||||
|
||||
|
||||
switch (msg->hdr->code) {
|
||||
switch (hdr->code) {
|
||||
case RADIUS_CODE_ACCESS_ACCEPT:
|
||||
if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)
|
||||
sta->vlan_id = 0;
|
||||
#ifndef CONFIG_NO_VLAN
|
||||
else {
|
||||
old_vlanid = sta->vlan_id;
|
||||
sta->vlan_id = radius_msg_get_vlanid(msg);
|
||||
@ -1315,8 +1280,10 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
|
||||
"ID in Access-Accept");
|
||||
break;
|
||||
}
|
||||
#endif /* CONFIG_NO_VLAN */
|
||||
|
||||
ap_sta_bind_vlan(hapd, sta, old_vlanid);
|
||||
if (ap_sta_bind_vlan(hapd, sta, old_vlanid) < 0)
|
||||
break;
|
||||
|
||||
/* RFC 3580, Ch. 3.17 */
|
||||
if (session_timeout_set && termination_action ==
|
||||
@ -1373,6 +1340,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
|
||||
|
||||
return RADIUS_RX_QUEUED;
|
||||
}
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
|
||||
|
||||
void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
@ -1384,11 +1352,10 @@ void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
|
||||
HOSTAPD_LEVEL_DEBUG, "aborting authentication");
|
||||
|
||||
if (sm->last_recv_radius) {
|
||||
radius_msg_free(sm->last_recv_radius);
|
||||
os_free(sm->last_recv_radius);
|
||||
sm->last_recv_radius = NULL;
|
||||
}
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
radius_msg_free(sm->last_recv_radius);
|
||||
sm->last_recv_radius = NULL;
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
|
||||
if (sm->eap_if->eapTimeout) {
|
||||
/*
|
||||
@ -1397,74 +1364,32 @@ void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
* could only be sent if the EAP peer actually replied).
|
||||
*/
|
||||
sm->eap_if->portEnabled = FALSE;
|
||||
hostapd_sta_deauth(hapd, sta->addr,
|
||||
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
|
||||
WLAN_STA_AUTHORIZED);
|
||||
eloop_cancel_timeout(ap_handle_timer, hapd, sta);
|
||||
eloop_register_timeout(0, 0, ap_handle_timer, hapd, sta);
|
||||
sta->timeout_next = STA_REMOVE;
|
||||
ap_sta_disconnect(hapd, sta, sta->addr,
|
||||
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef HOSTAPD_DUMP_STATE
|
||||
static void fprint_char(FILE *f, char c)
|
||||
{
|
||||
if (c >= 32 && c < 127)
|
||||
fprintf(f, "%c", c);
|
||||
else
|
||||
fprintf(f, "<%02x>", c);
|
||||
}
|
||||
|
||||
|
||||
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_type_text(sm->eap_type_authsrv),
|
||||
sm->eap_type_supp, eap_type_text(sm->eap_type_supp));
|
||||
|
||||
fprintf(f, "%scached_packets=%s\n", prefix,
|
||||
sm->last_recv_radius ? "[RX RADIUS]" : "");
|
||||
|
||||
eapol_auth_dump_state(f, prefix, sm);
|
||||
}
|
||||
#endif /* HOSTAPD_DUMP_STATE */
|
||||
|
||||
|
||||
static int ieee802_1x_rekey_broadcast(struct hostapd_data *hapd)
|
||||
{
|
||||
struct eapol_authenticator *eapol = hapd->eapol_auth;
|
||||
|
||||
if (hapd->conf->default_wep_key_len < 1)
|
||||
return 0;
|
||||
|
||||
os_free(hapd->default_wep_key);
|
||||
hapd->default_wep_key = os_malloc(hapd->conf->default_wep_key_len);
|
||||
if (hapd->default_wep_key == NULL ||
|
||||
os_get_random(hapd->default_wep_key,
|
||||
os_free(eapol->default_wep_key);
|
||||
eapol->default_wep_key = os_malloc(hapd->conf->default_wep_key_len);
|
||||
if (eapol->default_wep_key == NULL ||
|
||||
os_get_random(eapol->default_wep_key,
|
||||
hapd->conf->default_wep_key_len)) {
|
||||
printf("Could not generate random WEP key.\n");
|
||||
os_free(hapd->default_wep_key);
|
||||
hapd->default_wep_key = NULL;
|
||||
os_free(eapol->default_wep_key);
|
||||
eapol->default_wep_key = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_hexdump_key(MSG_DEBUG, "IEEE 802.1X: New default WEP key",
|
||||
hapd->default_wep_key,
|
||||
eapol->default_wep_key,
|
||||
hapd->conf->default_wep_key_len);
|
||||
|
||||
return 0;
|
||||
@ -1485,36 +1410,37 @@ static int ieee802_1x_sta_key_available(struct hostapd_data *hapd,
|
||||
static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx)
|
||||
{
|
||||
struct hostapd_data *hapd = eloop_ctx;
|
||||
struct eapol_authenticator *eapol = hapd->eapol_auth;
|
||||
|
||||
if (hapd->default_wep_key_idx >= 3)
|
||||
hapd->default_wep_key_idx =
|
||||
if (eapol->default_wep_key_idx >= 3)
|
||||
eapol->default_wep_key_idx =
|
||||
hapd->conf->individual_wep_key_len > 0 ? 1 : 0;
|
||||
else
|
||||
hapd->default_wep_key_idx++;
|
||||
eapol->default_wep_key_idx++;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "IEEE 802.1X: New default WEP key index %d",
|
||||
hapd->default_wep_key_idx);
|
||||
eapol->default_wep_key_idx);
|
||||
|
||||
if (ieee802_1x_rekey_broadcast(hapd)) {
|
||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X,
|
||||
HOSTAPD_LEVEL_WARNING, "failed to generate a "
|
||||
"new broadcast key");
|
||||
os_free(hapd->default_wep_key);
|
||||
hapd->default_wep_key = NULL;
|
||||
os_free(eapol->default_wep_key);
|
||||
eapol->default_wep_key = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: Could setup key for RX here, but change default TX keyid only
|
||||
* after new broadcast key has been sent to all stations. */
|
||||
if (hostapd_set_encryption(hapd->conf->iface, hapd, "WEP", NULL,
|
||||
hapd->default_wep_key_idx,
|
||||
hapd->default_wep_key,
|
||||
hapd->conf->default_wep_key_len, 1)) {
|
||||
if (hapd->drv.set_key(hapd->conf->iface, hapd, WPA_ALG_WEP, NULL,
|
||||
eapol->default_wep_key_idx, 1, NULL, 0,
|
||||
eapol->default_wep_key,
|
||||
hapd->conf->default_wep_key_len)) {
|
||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X,
|
||||
HOSTAPD_LEVEL_WARNING, "failed to configure a "
|
||||
"new broadcast key");
|
||||
os_free(hapd->default_wep_key);
|
||||
hapd->default_wep_key = NULL;
|
||||
os_free(eapol->default_wep_key);
|
||||
eapol->default_wep_key = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1530,6 +1456,30 @@ static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx)
|
||||
static void ieee802_1x_eapol_send(void *ctx, void *sta_ctx, u8 type,
|
||||
const u8 *data, size_t datalen)
|
||||
{
|
||||
#ifdef CONFIG_WPS
|
||||
struct sta_info *sta = sta_ctx;
|
||||
|
||||
if ((sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)) ==
|
||||
WLAN_STA_MAYBE_WPS) {
|
||||
const u8 *identity;
|
||||
size_t identity_len;
|
||||
struct eapol_state_machine *sm = sta->eapol_sm;
|
||||
|
||||
identity = eap_get_identity(sm->eap, &identity_len);
|
||||
if (identity &&
|
||||
((identity_len == WSC_ID_ENROLLEE_LEN &&
|
||||
os_memcmp(identity, WSC_ID_ENROLLEE,
|
||||
WSC_ID_ENROLLEE_LEN) == 0) ||
|
||||
(identity_len == WSC_ID_REGISTRAR_LEN &&
|
||||
os_memcmp(identity, WSC_ID_REGISTRAR,
|
||||
WSC_ID_REGISTRAR_LEN) == 0))) {
|
||||
wpa_printf(MSG_DEBUG, "WPS: WLAN_STA_MAYBE_WPS -> "
|
||||
"WLAN_STA_WPS");
|
||||
sta->flags |= WLAN_STA_WPS;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_WPS */
|
||||
|
||||
ieee802_1x_send(ctx, sta_ctx, type, data, datalen);
|
||||
}
|
||||
|
||||
@ -1537,10 +1487,12 @@ static void ieee802_1x_eapol_send(void *ctx, void *sta_ctx, u8 type,
|
||||
static void ieee802_1x_aaa_send(void *ctx, void *sta_ctx,
|
||||
const u8 *data, size_t datalen)
|
||||
{
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
struct hostapd_data *hapd = ctx;
|
||||
struct sta_info *sta = sta_ctx;
|
||||
|
||||
ieee802_1x_encapsulate_radius(hapd, sta, data, datalen);
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
}
|
||||
|
||||
|
||||
@ -1608,6 +1560,7 @@ static int ieee802_1x_sta_entry_alive(void *ctx, const u8 *addr)
|
||||
static void ieee802_1x_logger(void *ctx, const u8 *addr,
|
||||
eapol_logger_level level, const char *txt)
|
||||
{
|
||||
#ifndef CONFIG_NO_HOSTAPD_LOGGER
|
||||
struct hostapd_data *hapd = ctx;
|
||||
int hlevel;
|
||||
|
||||
@ -1626,6 +1579,7 @@ static void ieee802_1x_logger(void *ctx, const u8 *addr,
|
||||
|
||||
hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE8021X, hlevel, "%s",
|
||||
txt);
|
||||
#endif /* CONFIG_NO_HOSTAPD_LOGGER */
|
||||
}
|
||||
|
||||
|
||||
@ -1654,6 +1608,22 @@ static void _ieee802_1x_tx_key(void *ctx, void *sta_ctx)
|
||||
}
|
||||
|
||||
|
||||
static void ieee802_1x_eapol_event(void *ctx, void *sta_ctx,
|
||||
enum eapol_event type)
|
||||
{
|
||||
/* struct hostapd_data *hapd = ctx; */
|
||||
struct sta_info *sta = sta_ctx;
|
||||
switch (type) {
|
||||
case EAPOL_AUTH_SM_CHANGE:
|
||||
wpa_auth_sm_notify(sta->wpa_sm);
|
||||
break;
|
||||
case EAPOL_AUTH_REAUTHENTICATE:
|
||||
wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH_EAPOL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int ieee802_1x_init(struct hostapd_data *hapd)
|
||||
{
|
||||
int i;
|
||||
@ -1661,12 +1631,13 @@ int ieee802_1x_init(struct hostapd_data *hapd)
|
||||
struct eapol_auth_cb cb;
|
||||
|
||||
os_memset(&conf, 0, sizeof(conf));
|
||||
conf.hapd = hapd;
|
||||
conf.ctx = hapd;
|
||||
conf.eap_reauth_period = hapd->conf->eap_reauth_period;
|
||||
conf.wpa = hapd->conf->wpa;
|
||||
conf.individual_wep_key_len = hapd->conf->individual_wep_key_len;
|
||||
conf.eap_server = hapd->conf->eap_server;
|
||||
conf.ssl_ctx = hapd->ssl_ctx;
|
||||
conf.msg_ctx = hapd->msg_ctx;
|
||||
conf.eap_sim_db_priv = hapd->eap_sim_db_priv;
|
||||
conf.eap_req_id_text = hapd->conf->eap_req_id_text;
|
||||
conf.eap_req_id_text_len = hapd->conf->eap_req_id_text_len;
|
||||
@ -1691,29 +1662,31 @@ int ieee802_1x_init(struct hostapd_data *hapd)
|
||||
cb.set_port_authorized = ieee802_1x_set_port_authorized;
|
||||
cb.abort_auth = _ieee802_1x_abort_auth;
|
||||
cb.tx_key = _ieee802_1x_tx_key;
|
||||
cb.eapol_event = ieee802_1x_eapol_event;
|
||||
|
||||
hapd->eapol_auth = eapol_auth_init(&conf, &cb);
|
||||
if (hapd->eapol_auth == NULL)
|
||||
return -1;
|
||||
|
||||
if ((hapd->conf->ieee802_1x || hapd->conf->wpa) &&
|
||||
hostapd_set_ieee8021x(hapd->conf->iface, hapd, 1))
|
||||
hapd->drv.set_drv_ieee8021x(hapd, hapd->conf->iface, 1))
|
||||
return -1;
|
||||
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
if (radius_client_register(hapd->radius, RADIUS_AUTH,
|
||||
ieee802_1x_receive_auth, hapd))
|
||||
return -1;
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
|
||||
if (hapd->conf->default_wep_key_len) {
|
||||
hostapd_set_privacy(hapd, 1);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
hostapd_set_encryption(hapd->conf->iface, hapd,
|
||||
"none", NULL, i, NULL, 0, 0);
|
||||
hapd->drv.set_key(hapd->conf->iface, hapd,
|
||||
WPA_ALG_NONE, NULL, i, 0, NULL, 0,
|
||||
NULL, 0);
|
||||
|
||||
ieee802_1x_rekey(hapd, NULL);
|
||||
|
||||
if (hapd->default_wep_key == NULL)
|
||||
if (hapd->eapol_auth->default_wep_key == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1727,24 +1700,15 @@ void ieee802_1x_deinit(struct hostapd_data *hapd)
|
||||
|
||||
if (hapd->driver != NULL &&
|
||||
(hapd->conf->ieee802_1x || hapd->conf->wpa))
|
||||
hostapd_set_ieee8021x(hapd->conf->iface, hapd, 0);
|
||||
hapd->drv.set_drv_ieee8021x(hapd, hapd->conf->iface, 0);
|
||||
|
||||
eapol_auth_deinit(hapd->eapol_auth);
|
||||
hapd->eapol_auth = NULL;
|
||||
}
|
||||
|
||||
|
||||
int ieee802_1x_reconfig(struct hostapd_data *hapd,
|
||||
struct hostapd_config *oldconf,
|
||||
struct hostapd_bss_config *oldbss)
|
||||
{
|
||||
ieee802_1x_deinit(hapd);
|
||||
return ieee802_1x_init(hapd);
|
||||
}
|
||||
|
||||
|
||||
int ieee802_1x_tx_status(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
u8 *buf, size_t len, int ack)
|
||||
const u8 *buf, size_t len, int ack)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct ieee802_1x_hdr *xhdr;
|
||||
@ -2039,4 +2003,23 @@ static void ieee802_1x_finished(struct hostapd_data *hapd,
|
||||
HOSTAPD_LEVEL_DEBUG,
|
||||
"Added PMKSA cache entry (IEEE 802.1X)");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_WPS
|
||||
if (!success && (sta->flags & WLAN_STA_WPS)) {
|
||||
/*
|
||||
* Many devices require deauthentication after WPS provisioning
|
||||
* and some may not be be able to do that themselves, so
|
||||
* disconnect the client here.
|
||||
*/
|
||||
wpa_printf(MSG_DEBUG, "WPS: Force disconnection after "
|
||||
"EAP-Failure");
|
||||
/* Add a small sleep to increase likelihood of previously
|
||||
* requested EAP-Failure TX getting out before this should the
|
||||
* driver reorder operations.
|
||||
*/
|
||||
os_sleep(0, 10000);
|
||||
ap_sta_disconnect(hapd, sta, sta->addr,
|
||||
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
}
|
||||
#endif /* CONFIG_WPS */
|
||||
}
|
@ -21,6 +21,10 @@ struct eapol_state_machine;
|
||||
struct hostapd_config;
|
||||
struct hostapd_bss_config;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, 1)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/* RFC 3580, 4. RC4 EAPOL-Key Frame */
|
||||
|
||||
struct ieee802_1x_eapol_key {
|
||||
@ -43,7 +47,11 @@ struct ieee802_1x_eapol_key {
|
||||
* represents the number of least significant octets from
|
||||
* MS-MPPE-Send-Key attribute to be used as the keying material;
|
||||
* RC4 key used in encryption = Key-IV + MS-MPPE-Recv-Key */
|
||||
} __attribute__ ((packed));
|
||||
} STRUCT_PACKED;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
|
||||
void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
|
||||
@ -58,11 +66,8 @@ void ieee802_1x_set_sta_authorized(struct hostapd_data *hapd,
|
||||
void ieee802_1x_dump_state(FILE *f, const char *prefix, struct sta_info *sta);
|
||||
int ieee802_1x_init(struct hostapd_data *hapd);
|
||||
void ieee802_1x_deinit(struct hostapd_data *hapd);
|
||||
int ieee802_1x_reconfig(struct hostapd_data *hapd,
|
||||
struct hostapd_config *oldconf,
|
||||
struct hostapd_bss_config *oldbss);
|
||||
int ieee802_1x_tx_status(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
u8 *buf, size_t len, int ack);
|
||||
const u8 *buf, size_t len, int ack);
|
||||
u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len);
|
||||
u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len,
|
||||
int idx);
|
||||
@ -78,12 +83,6 @@ int ieee802_1x_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
void hostapd_get_ntp_timestamp(u8 *buf);
|
||||
char *eap_type_text(u8 type);
|
||||
|
||||
struct radius_class_data;
|
||||
|
||||
void ieee802_1x_free_radius_class(struct radius_class_data *class);
|
||||
int ieee802_1x_copy_radius_class(struct radius_class_data *dst,
|
||||
const struct radius_class_data *src);
|
||||
|
||||
const char *radius_mode_txt(struct hostapd_data *hapd);
|
||||
int radius_sta_rate(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd - PeerKey for Direct Link Setup (DLS)
|
||||
* Copyright (c) 2006-2008, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2006-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
|
||||
@ -12,14 +12,13 @@
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "eloop.h"
|
||||
#include "sha1.h"
|
||||
#include "sha256.h"
|
||||
#include "wpa.h"
|
||||
#include "defs.h"
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "crypto/sha1.h"
|
||||
#include "crypto/sha256.h"
|
||||
#include "wpa_auth.h"
|
||||
#include "wpa_auth_i.h"
|
||||
#include "wpa_auth_ie.h"
|
||||
|
@ -12,18 +12,15 @@
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "ap.h"
|
||||
#include "config.h"
|
||||
#include "common.h"
|
||||
#include "eloop.h"
|
||||
#include "sha1.h"
|
||||
#include "sha256.h"
|
||||
#include "ieee802_1x.h"
|
||||
#include "eapol_sm.h"
|
||||
#include "pmksa_cache.h"
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "eapol_auth/eapol_auth_sm.h"
|
||||
#include "eapol_auth/eapol_auth_sm_i.h"
|
||||
#include "sta_info.h"
|
||||
#include "ap_config.h"
|
||||
#include "pmksa_cache_auth.h"
|
||||
|
||||
|
||||
static const int pmksa_cache_max_entries = 1024;
|
||||
@ -41,40 +38,6 @@ struct rsn_pmksa_cache {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* rsn_pmkid - Calculate PMK identifier
|
||||
* @pmk: Pairwise master key
|
||||
* @pmk_len: Length of pmk in bytes
|
||||
* @aa: Authenticator address
|
||||
* @spa: Supplicant address
|
||||
* @pmkid: Buffer for PMKID
|
||||
* @use_sha256: Whether to use SHA256-based KDF
|
||||
*
|
||||
* IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
|
||||
* PMKID = HMAC-SHA1-128(PMK, "PMK Name" || AA || SPA)
|
||||
*/
|
||||
void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
|
||||
u8 *pmkid, int use_sha256)
|
||||
{
|
||||
char *title = "PMK Name";
|
||||
const u8 *addr[3];
|
||||
const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
|
||||
unsigned char hash[SHA256_MAC_LEN];
|
||||
|
||||
addr[0] = (u8 *) title;
|
||||
addr[1] = aa;
|
||||
addr[2] = spa;
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
if (use_sha256)
|
||||
hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
|
||||
else
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
|
||||
os_memcpy(pmkid, hash, PMKID_LEN);
|
||||
}
|
||||
|
||||
|
||||
static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa);
|
||||
|
||||
|
||||
@ -83,7 +46,9 @@ static void _pmksa_cache_free_entry(struct rsn_pmksa_cache_entry *entry)
|
||||
if (entry == NULL)
|
||||
return;
|
||||
os_free(entry->identity);
|
||||
ieee802_1x_free_radius_class(&entry->radius_class);
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
radius_free_class(&entry->radius_class);
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
os_free(entry);
|
||||
}
|
||||
|
||||
@ -177,11 +142,12 @@ static void pmksa_cache_from_eapol_data(struct rsn_pmksa_cache_entry *entry,
|
||||
}
|
||||
}
|
||||
|
||||
ieee802_1x_copy_radius_class(&entry->radius_class,
|
||||
&eapol->radius_class);
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
radius_copy_class(&entry->radius_class, &eapol->radius_class);
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
|
||||
entry->eap_type_authsrv = eapol->eap_type_authsrv;
|
||||
entry->vlan_id = eapol->sta->vlan_id;
|
||||
entry->vlan_id = ((struct sta_info *) eapol->sta)->vlan_id;
|
||||
}
|
||||
|
||||
|
||||
@ -203,16 +169,17 @@ void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache_entry *entry,
|
||||
eapol->identity, eapol->identity_len);
|
||||
}
|
||||
|
||||
ieee802_1x_free_radius_class(&eapol->radius_class);
|
||||
ieee802_1x_copy_radius_class(&eapol->radius_class,
|
||||
&entry->radius_class);
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
radius_free_class(&eapol->radius_class);
|
||||
radius_copy_class(&eapol->radius_class, &entry->radius_class);
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
if (eapol->radius_class.attr) {
|
||||
wpa_printf(MSG_DEBUG, "Copied %lu Class attribute(s) from "
|
||||
"PMKSA", (unsigned long) eapol->radius_class.count);
|
||||
}
|
||||
|
||||
eapol->eap_type_authsrv = entry->eap_type_authsrv;
|
||||
eapol->sta->vlan_id = entry->vlan_id;
|
||||
((struct sta_info *) eapol->sta)->vlan_id = entry->vlan_id;
|
||||
}
|
||||
|
||||
|
||||
@ -248,8 +215,8 @@ static void pmksa_cache_link_entry(struct rsn_pmksa_cache *pmksa,
|
||||
|
||||
|
||||
/**
|
||||
* pmksa_cache_add - Add a PMKSA cache entry
|
||||
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_init()
|
||||
* pmksa_cache_auth_add - Add a PMKSA cache entry
|
||||
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_auth_init()
|
||||
* @pmk: The new pairwise master key
|
||||
* @pmk_len: PMK length in bytes, usually PMK_LEN (32)
|
||||
* @aa: Authenticator address
|
||||
@ -265,7 +232,8 @@ static void pmksa_cache_link_entry(struct rsn_pmksa_cache *pmksa,
|
||||
* based on the PMK.
|
||||
*/
|
||||
struct rsn_pmksa_cache_entry *
|
||||
pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
|
||||
pmksa_cache_auth_add(struct rsn_pmksa_cache *pmksa,
|
||||
const u8 *pmk, size_t pmk_len,
|
||||
const u8 *aa, const u8 *spa, int session_timeout,
|
||||
struct eapol_state_machine *eapol, int akmp)
|
||||
{
|
||||
@ -294,7 +262,7 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
|
||||
|
||||
/* Replace an old entry for the same STA (if found) with the new entry
|
||||
*/
|
||||
pos = pmksa_cache_get(pmksa, spa, NULL);
|
||||
pos = pmksa_cache_auth_get(pmksa, spa, NULL);
|
||||
if (pos)
|
||||
pmksa_cache_free_entry(pmksa, pos);
|
||||
|
||||
@ -337,8 +305,9 @@ pmksa_cache_add_okc(struct rsn_pmksa_cache *pmksa,
|
||||
old_entry->identity_len);
|
||||
}
|
||||
}
|
||||
ieee802_1x_copy_radius_class(&entry->radius_class,
|
||||
&old_entry->radius_class);
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
radius_copy_class(&entry->radius_class, &old_entry->radius_class);
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
entry->eap_type_authsrv = old_entry->eap_type_authsrv;
|
||||
entry->vlan_id = old_entry->vlan_id;
|
||||
entry->opportunistic = 1;
|
||||
@ -350,10 +319,10 @@ pmksa_cache_add_okc(struct rsn_pmksa_cache *pmksa,
|
||||
|
||||
|
||||
/**
|
||||
* pmksa_cache_deinit - Free all entries in PMKSA cache
|
||||
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_init()
|
||||
* pmksa_cache_auth_deinit - Free all entries in PMKSA cache
|
||||
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_auth_init()
|
||||
*/
|
||||
void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa)
|
||||
void pmksa_cache_auth_deinit(struct rsn_pmksa_cache *pmksa)
|
||||
{
|
||||
struct rsn_pmksa_cache_entry *entry, *prev;
|
||||
int i;
|
||||
@ -375,14 +344,15 @@ void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa)
|
||||
|
||||
|
||||
/**
|
||||
* pmksa_cache_get - Fetch a PMKSA cache entry
|
||||
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_init()
|
||||
* pmksa_cache_auth_get - Fetch a PMKSA cache entry
|
||||
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_auth_init()
|
||||
* @spa: Supplicant address or %NULL to match any
|
||||
* @pmkid: PMKID or %NULL to match any
|
||||
* Returns: Pointer to PMKSA cache entry or %NULL if no match was found
|
||||
*/
|
||||
struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
|
||||
const u8 *spa, const u8 *pmkid)
|
||||
struct rsn_pmksa_cache_entry *
|
||||
pmksa_cache_auth_get(struct rsn_pmksa_cache *pmksa,
|
||||
const u8 *spa, const u8 *pmkid)
|
||||
{
|
||||
struct rsn_pmksa_cache_entry *entry;
|
||||
|
||||
@ -404,7 +374,7 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
|
||||
|
||||
/**
|
||||
* pmksa_cache_get_okc - Fetch a PMKSA cache entry using OKC
|
||||
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_init()
|
||||
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_auth_init()
|
||||
* @aa: Authenticator address
|
||||
* @spa: Supplicant address
|
||||
* @pmkid: PMKID
|
||||
@ -434,14 +404,14 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get_okc(
|
||||
|
||||
|
||||
/**
|
||||
* pmksa_cache_init - Initialize PMKSA cache
|
||||
* pmksa_cache_auth_init - Initialize PMKSA cache
|
||||
* @free_cb: Callback function to be called when a PMKSA cache entry is freed
|
||||
* @ctx: Context pointer for free_cb function
|
||||
* Returns: Pointer to PMKSA cache data or %NULL on failure
|
||||
*/
|
||||
struct rsn_pmksa_cache *
|
||||
pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
|
||||
void *ctx), void *ctx)
|
||||
pmksa_cache_auth_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
|
||||
void *ctx), void *ctx)
|
||||
{
|
||||
struct rsn_pmksa_cache *pmksa;
|
||||
|
@ -15,6 +15,8 @@
|
||||
#ifndef PMKSA_CACHE_H
|
||||
#define PMKSA_CACHE_H
|
||||
|
||||
#include "radius/radius.h"
|
||||
|
||||
/**
|
||||
* struct rsn_pmksa_cache_entry - PMKSA cache entry
|
||||
*/
|
||||
@ -38,25 +40,25 @@ struct rsn_pmksa_cache_entry {
|
||||
struct rsn_pmksa_cache;
|
||||
|
||||
struct rsn_pmksa_cache *
|
||||
pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
|
||||
void *ctx), void *ctx);
|
||||
void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa);
|
||||
struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
|
||||
const u8 *spa, const u8 *pmkid);
|
||||
pmksa_cache_auth_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
|
||||
void *ctx), void *ctx);
|
||||
void pmksa_cache_auth_deinit(struct rsn_pmksa_cache *pmksa);
|
||||
struct rsn_pmksa_cache_entry *
|
||||
pmksa_cache_auth_get(struct rsn_pmksa_cache *pmksa,
|
||||
const u8 *spa, const u8 *pmkid);
|
||||
struct rsn_pmksa_cache_entry * pmksa_cache_get_okc(
|
||||
struct rsn_pmksa_cache *pmksa, const u8 *spa, const u8 *aa,
|
||||
const u8 *pmkid);
|
||||
struct rsn_pmksa_cache_entry *
|
||||
pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
|
||||
const u8 *aa, const u8 *spa, int session_timeout,
|
||||
struct eapol_state_machine *eapol, int akmp);
|
||||
pmksa_cache_auth_add(struct rsn_pmksa_cache *pmksa,
|
||||
const u8 *pmk, size_t pmk_len,
|
||||
const u8 *aa, const u8 *spa, int session_timeout,
|
||||
struct eapol_state_machine *eapol, int akmp);
|
||||
struct rsn_pmksa_cache_entry *
|
||||
pmksa_cache_add_okc(struct rsn_pmksa_cache *pmksa,
|
||||
const struct rsn_pmksa_cache_entry *old_entry,
|
||||
const u8 *aa, const u8 *pmkid);
|
||||
void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache_entry *entry,
|
||||
struct eapol_state_machine *eapol);
|
||||
void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
|
||||
u8 *pmkid, int use_sha256);
|
||||
|
||||
#endif /* PMKSA_CACHE_H */
|
@ -12,19 +12,22 @@
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "utils/includes.h"
|
||||
|
||||
#ifdef CONFIG_RSN_PREAUTH
|
||||
|
||||
#include "hostapd.h"
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "l2_packet/l2_packet.h"
|
||||
#include "common/wpa_common.h"
|
||||
#include "eapol_auth/eapol_auth_sm.h"
|
||||
#include "eapol_auth/eapol_auth_sm_i.h"
|
||||
#include "hostapd.h"
|
||||
#include "ap_config.h"
|
||||
#include "ieee802_1x.h"
|
||||
#include "eloop.h"
|
||||
#include "sta_info.h"
|
||||
#include "wpa_common.h"
|
||||
#include "eapol_sm.h"
|
||||
#include "wpa.h"
|
||||
#include "preauth.h"
|
||||
#include "wpa_auth.h"
|
||||
#include "preauth_auth.h"
|
||||
|
||||
#ifndef ETH_P_PREAUTH
|
||||
#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
|
||||
@ -256,7 +259,7 @@ void rsn_preauth_send(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
|
||||
os_memcpy(ethhdr->h_dest, sta->addr, ETH_ALEN);
|
||||
os_memcpy(ethhdr->h_source, hapd->own_addr, ETH_ALEN);
|
||||
ethhdr->h_proto = htons(ETH_P_PREAUTH);
|
||||
ethhdr->h_proto = host_to_be16(ETH_P_PREAUTH);
|
||||
os_memcpy(ethhdr + 1, buf, len);
|
||||
|
||||
if (l2_packet_send(piface->l2, sta->addr, ETH_P_PREAUTH, (u8 *) ethhdr,
|
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* hostapd / Station table
|
||||
* Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2007-2008, Intel Corporation
|
||||
* 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
|
||||
@ -13,26 +12,28 @@
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "radius/radius.h"
|
||||
#include "radius/radius_client.h"
|
||||
#include "drivers/driver.h"
|
||||
#include "hostapd.h"
|
||||
#include "sta_info.h"
|
||||
#include "eloop.h"
|
||||
#include "accounting.h"
|
||||
#include "ieee802_1x.h"
|
||||
#include "ieee802_11.h"
|
||||
#include "radius/radius.h"
|
||||
#include "wpa.h"
|
||||
#include "preauth.h"
|
||||
#include "radius/radius_client.h"
|
||||
#include "driver.h"
|
||||
#include "wpa_auth.h"
|
||||
#include "preauth_auth.h"
|
||||
#include "ap_config.h"
|
||||
#include "beacon.h"
|
||||
#include "hw_features.h"
|
||||
#include "mlme.h"
|
||||
#include "ap_mlme.h"
|
||||
#include "vlan_init.h"
|
||||
#include "sta_info.h"
|
||||
|
||||
static int ap_sta_in_other_bss(struct hostapd_data *hapd,
|
||||
struct sta_info *sta, u32 flags);
|
||||
static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd,
|
||||
struct sta_info *sta);
|
||||
static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx);
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx);
|
||||
@ -120,15 +121,18 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
|
||||
accounting_sta_stop(hapd, sta);
|
||||
|
||||
if (!ap_sta_in_other_bss(hapd, sta, WLAN_STA_ASSOC) &&
|
||||
!(sta->flags & WLAN_STA_PREAUTH))
|
||||
hostapd_sta_remove(hapd, sta->addr);
|
||||
if (sta->flags & WLAN_STA_WDS)
|
||||
hapd->drv.set_wds_sta(hapd, sta->addr, sta->aid, 0);
|
||||
|
||||
if (!(sta->flags & WLAN_STA_PREAUTH))
|
||||
hapd->drv.sta_remove(hapd, sta->addr);
|
||||
|
||||
ap_sta_hash_del(hapd, sta);
|
||||
ap_sta_list_del(hapd, sta);
|
||||
|
||||
if (sta->aid > 0)
|
||||
hapd->sta_aid[sta->aid - 1] = NULL;
|
||||
hapd->sta_aid[(sta->aid - 1) / 32] &=
|
||||
~BIT((sta->aid - 1) % 32);
|
||||
|
||||
hapd->num_sta--;
|
||||
if (sta->nonerp_set) {
|
||||
@ -154,7 +158,6 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
set_beacon++;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
if (sta->no_ht_gf_set) {
|
||||
sta->no_ht_gf_set = 0;
|
||||
hapd->iface->num_sta_ht_no_gf--;
|
||||
@ -170,9 +173,10 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
hapd->iface->num_sta_ht_20mhz--;
|
||||
}
|
||||
|
||||
#if defined(NEED_AP_MLME) && defined(CONFIG_IEEE80211N)
|
||||
if (hostapd_ht_operation_update(hapd->iface) > 0)
|
||||
set_beacon++;
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
#endif /* NEED_AP_MLME && CONFIG_IEEE80211N */
|
||||
|
||||
if (set_beacon)
|
||||
ieee802_11_set_beacons(hapd->iface);
|
||||
@ -183,7 +187,9 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
ieee802_1x_free_station(sta);
|
||||
wpa_auth_sta_deinit(sta->wpa_sm);
|
||||
rsn_preauth_free_station(hapd, sta);
|
||||
#ifndef CONFIG_NO_RADIUS
|
||||
radius_client_flush_auth(hapd->radius, sta->addr);
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
|
||||
os_free(sta->last_assoc_req);
|
||||
os_free(sta->challenge);
|
||||
@ -195,6 +201,8 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
|
||||
wpabuf_free(sta->wps_ie);
|
||||
|
||||
os_free(sta->ht_capabilities);
|
||||
|
||||
os_free(sta);
|
||||
}
|
||||
|
||||
@ -247,7 +255,7 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
|
||||
int inactive_sec;
|
||||
wpa_printf(MSG_DEBUG, "Checking STA " MACSTR " inactivity:",
|
||||
MAC2STR(sta->addr));
|
||||
inactive_sec = hostapd_get_inact_sec(hapd, sta->addr);
|
||||
inactive_sec = hapd->drv.get_inact_sec(hapd, sta->addr);
|
||||
if (inactive_sec == -1) {
|
||||
wpa_printf(MSG_DEBUG, "Could not get station info "
|
||||
"from kernel driver for " MACSTR ".",
|
||||
@ -280,6 +288,7 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
|
||||
|
||||
if (sta->timeout_next == STA_NULLFUNC &&
|
||||
(sta->flags & WLAN_STA_ASSOC)) {
|
||||
#ifndef CONFIG_NATIVE_WINDOWS
|
||||
/* send data frame to poll STA and check whether this frame
|
||||
* is ACKed */
|
||||
struct ieee80211_hdr hdr;
|
||||
@ -287,7 +296,6 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
|
||||
wpa_printf(MSG_DEBUG, " Polling STA with data frame");
|
||||
sta->flags |= WLAN_STA_PENDING_POLL;
|
||||
|
||||
#ifndef CONFIG_NATIVE_WINDOWS
|
||||
os_memset(&hdr, 0, sizeof(hdr));
|
||||
if (hapd->driver &&
|
||||
os_strcmp(hapd->driver->name, "hostap") == 0) {
|
||||
@ -311,7 +319,7 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
|
||||
ETH_ALEN);
|
||||
os_memcpy(hdr.IEEE80211_SA_FROMDS, hapd->own_addr, ETH_ALEN);
|
||||
|
||||
if (hostapd_send_mgmt_frame(hapd, &hdr, sizeof(hdr), 0) < 0)
|
||||
if (hapd->drv.send_mgmt_frame(hapd, &hdr, sizeof(hdr)) < 0)
|
||||
perror("ap_handle_timer: send");
|
||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||
} else if (sta->timeout_next != STA_REMOVE) {
|
||||
@ -322,10 +330,10 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
|
||||
MAC2STR(sta->addr));
|
||||
|
||||
if (deauth) {
|
||||
hostapd_sta_deauth(hapd, sta->addr,
|
||||
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
hapd->drv.sta_deauth(hapd, sta->addr,
|
||||
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
} else {
|
||||
hostapd_sta_disassoc(
|
||||
hapd->drv.sta_disassoc(
|
||||
hapd, sta->addr,
|
||||
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
|
||||
}
|
||||
@ -389,7 +397,7 @@ static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx)
|
||||
RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT;
|
||||
os_memcpy(addr, sta->addr, ETH_ALEN);
|
||||
ap_free_sta(hapd, sta);
|
||||
hostapd_sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
hapd->drv.sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
}
|
||||
|
||||
|
||||
@ -432,7 +440,7 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
|
||||
wpa_printf(MSG_ERROR, "malloc failed");
|
||||
return NULL;
|
||||
}
|
||||
sta->acct_interim_interval = hapd->conf->radius->acct_interim_interval;
|
||||
sta->acct_interim_interval = hapd->conf->acct_interim_interval;
|
||||
|
||||
/* initialize STA info data */
|
||||
eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
|
||||
@ -443,6 +451,7 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
|
||||
hapd->num_sta++;
|
||||
ap_sta_hash_add(hapd, sta);
|
||||
sta->ssid = &hapd->conf->ssid;
|
||||
ap_sta_remove_in_other_bss(hapd, sta);
|
||||
|
||||
return sta;
|
||||
}
|
||||
@ -454,7 +463,7 @@ static int ap_sta_remove(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
|
||||
wpa_printf(MSG_DEBUG, "Removing STA " MACSTR " from kernel driver",
|
||||
MAC2STR(sta->addr));
|
||||
if (hostapd_sta_remove(hapd, sta->addr) &&
|
||||
if (hapd->drv.sta_remove(hapd, sta->addr) &&
|
||||
sta->flags & WLAN_STA_ASSOC) {
|
||||
wpa_printf(MSG_DEBUG, "Could not remove station " MACSTR
|
||||
" from kernel driver.", MAC2STR(sta->addr));
|
||||
@ -464,8 +473,8 @@ static int ap_sta_remove(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
}
|
||||
|
||||
|
||||
static int ap_sta_in_other_bss(struct hostapd_data *hapd,
|
||||
struct sta_info *sta, u32 flags)
|
||||
static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
struct hostapd_iface *iface = hapd->iface;
|
||||
size_t i;
|
||||
@ -480,11 +489,12 @@ static int ap_sta_in_other_bss(struct hostapd_data *hapd,
|
||||
if (bss == hapd || bss == NULL)
|
||||
continue;
|
||||
sta2 = ap_get_sta(bss, sta->addr);
|
||||
if (sta2 && ((sta2->flags & flags) == flags))
|
||||
return 1;
|
||||
}
|
||||
if (!sta2)
|
||||
continue;
|
||||
|
||||
return 0;
|
||||
ap_sta_disconnect(bss, sta2, sta2->addr,
|
||||
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -494,8 +504,7 @@ void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
wpa_printf(MSG_DEBUG, "%s: disassociate STA " MACSTR,
|
||||
hapd->conf->iface, MAC2STR(sta->addr));
|
||||
sta->flags &= ~WLAN_STA_ASSOC;
|
||||
if (!ap_sta_in_other_bss(hapd, sta, WLAN_STA_ASSOC))
|
||||
ap_sta_remove(hapd, sta);
|
||||
ap_sta_remove(hapd, sta);
|
||||
sta->timeout_next = STA_DEAUTH;
|
||||
eloop_cancel_timeout(ap_handle_timer, hapd, sta);
|
||||
eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DISASSOC, 0,
|
||||
@ -513,8 +522,7 @@ void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
wpa_printf(MSG_DEBUG, "%s: deauthenticate STA " MACSTR,
|
||||
hapd->conf->iface, MAC2STR(sta->addr));
|
||||
sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
|
||||
if (!ap_sta_in_other_bss(hapd, sta, WLAN_STA_ASSOC))
|
||||
ap_sta_remove(hapd, sta);
|
||||
ap_sta_remove(hapd, sta);
|
||||
sta->timeout_next = STA_REMOVE;
|
||||
eloop_cancel_timeout(ap_handle_timer, hapd, sta);
|
||||
eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0,
|
||||
@ -529,8 +537,10 @@ void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
int old_vlanid)
|
||||
{
|
||||
#ifndef CONFIG_NO_VLAN
|
||||
const char *iface;
|
||||
struct hostapd_vlan *vlan = NULL;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Do not proceed furthur if the vlan id remains same. We do not want
|
||||
@ -626,7 +636,16 @@ int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
if (wpa_auth_sta_set_vlan(sta->wpa_sm, sta->vlan_id) < 0)
|
||||
wpa_printf(MSG_INFO, "Failed to update VLAN-ID for WPA");
|
||||
|
||||
return hostapd_set_sta_vlan(iface, hapd, sta->addr, sta->vlan_id);
|
||||
ret = hapd->drv.set_sta_vlan(iface, hapd, sta->addr, sta->vlan_id);
|
||||
if (ret < 0) {
|
||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_DEBUG, "could not bind the STA "
|
||||
"entry to vlan_id=%d", sta->vlan_id);
|
||||
}
|
||||
return ret;
|
||||
#else /* CONFIG_NO_VLAN */
|
||||
return 0;
|
||||
#endif /* CONFIG_NO_VLAN */
|
||||
}
|
||||
|
||||
|
||||
@ -690,7 +709,9 @@ static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx)
|
||||
HOSTAPD_LEVEL_DEBUG,
|
||||
"association SA Query attempt %d", sta->sa_query_count);
|
||||
|
||||
#ifdef NEED_AP_MLME
|
||||
ieee802_11_send_sa_query_req(hapd, sta->addr, trans_id);
|
||||
#endif /* NEED_AP_MLME */
|
||||
}
|
||||
|
||||
|
||||
@ -709,3 +730,22 @@ void ap_sta_stop_sa_query(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
|
||||
|
||||
void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
const u8 *addr, u16 reason)
|
||||
{
|
||||
|
||||
if (sta == NULL && addr)
|
||||
sta = ap_get_sta(hapd, addr);
|
||||
|
||||
if (addr)
|
||||
hapd->drv.sta_deauth(hapd, addr, reason);
|
||||
|
||||
if (sta == NULL)
|
||||
return;
|
||||
sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_AUTHORIZED);
|
||||
eloop_cancel_timeout(ap_handle_timer, hapd, sta);
|
||||
eloop_register_timeout(0, 0, ap_handle_timer, hapd, sta);
|
||||
sta->timeout_next = STA_REMOVE;
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* hostapd / Station table data structures
|
||||
* Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2007-2008, Intel Corporation
|
||||
* hostapd / Station table
|
||||
* 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
|
||||
@ -13,12 +12,8 @@
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#ifndef AP_H
|
||||
#define AP_H
|
||||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
#include "ieee802_11_defs.h"
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
#ifndef STA_INFO_H
|
||||
#define STA_INFO_H
|
||||
|
||||
/* STA flags */
|
||||
#define WLAN_STA_AUTH BIT(0)
|
||||
@ -35,6 +30,7 @@
|
||||
#define WLAN_STA_HT BIT(11)
|
||||
#define WLAN_STA_WPS BIT(12)
|
||||
#define WLAN_STA_MAYBE_WPS BIT(13)
|
||||
#define WLAN_STA_WDS BIT(14)
|
||||
#define WLAN_STA_NONERP BIT(31)
|
||||
|
||||
/* Maximum number of supported rates (from both Supported Rates and Extended
|
||||
@ -47,7 +43,7 @@ struct sta_info {
|
||||
struct sta_info *hnext; /* next entry in hash table list */
|
||||
u8 addr[6];
|
||||
u16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */
|
||||
u32 flags;
|
||||
u32 flags; /* Bitfield of WLAN_STA_* */
|
||||
u16 capability;
|
||||
u16 listen_interval; /* or beacon_int for APs */
|
||||
u8 supported_rates[WLAN_SUPP_RATES_MAX];
|
||||
@ -95,9 +91,7 @@ struct sta_info {
|
||||
|
||||
int vlan_id;
|
||||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
struct ht_cap_ie ht_capabilities; /* IEEE 802.11n capabilities */
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
struct ieee80211_ht_capabilities *ht_capabilities;
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
int sa_query_count; /* number of pending SA Query requests;
|
||||
@ -113,14 +107,6 @@ struct sta_info {
|
||||
};
|
||||
|
||||
|
||||
/* Maximum number of AIDs to use for STAs; must be 2007 or lower
|
||||
* (8802.11 limitation) */
|
||||
#define MAX_AID_TABLE_SIZE 128
|
||||
|
||||
#define STA_HASH_SIZE 256
|
||||
#define STA_HASH(sta) (sta[5])
|
||||
|
||||
|
||||
/* Default value for maximum station inactivity. After AP_MAX_INACTIVITY has
|
||||
* passed since last received frame from the station, a nullfunc data frame is
|
||||
* sent to the station. If this frame is not acknowledged and no other frames
|
||||
@ -136,4 +122,34 @@ struct sta_info {
|
||||
/* Number of seconds to keep STA entry after it has been deauthenticated. */
|
||||
#define AP_MAX_INACTIVITY_AFTER_DEAUTH (1 * 5)
|
||||
|
||||
#endif /* AP_H */
|
||||
|
||||
struct hostapd_data;
|
||||
|
||||
int ap_for_each_sta(struct hostapd_data *hapd,
|
||||
int (*cb)(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
void *ctx),
|
||||
void *ctx);
|
||||
struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta);
|
||||
void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void hostapd_free_stas(struct hostapd_data *hapd);
|
||||
void ap_handle_timer(void *eloop_ctx, void *timeout_ctx);
|
||||
void ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
u32 session_timeout);
|
||||
void ap_sta_no_session_timeout(struct hostapd_data *hapd,
|
||||
struct sta_info *sta);
|
||||
struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr);
|
||||
void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
u16 reason);
|
||||
void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
u16 reason);
|
||||
int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
int old_vlanid);
|
||||
void ap_sta_start_sa_query(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void ap_sta_stop_sa_query(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
const u8 *addr, u16 reason);
|
||||
|
||||
#endif /* STA_INFO_H */
|
93
contrib/wpa/src/ap/tkip_countermeasures.c
Normal file
93
contrib/wpa/src/ap/tkip_countermeasures.c
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* hostapd / TKIP countermeasures
|
||||
* 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 "hostapd.h"
|
||||
#include "sta_info.h"
|
||||
#include "ap_mlme.h"
|
||||
#include "wpa_auth.h"
|
||||
#include "tkip_countermeasures.h"
|
||||
|
||||
|
||||
static void ieee80211_tkip_countermeasures_stop(void *eloop_ctx,
|
||||
void *timeout_ctx)
|
||||
{
|
||||
struct hostapd_data *hapd = eloop_ctx;
|
||||
hapd->tkip_countermeasures = 0;
|
||||
hapd->drv.set_countermeasures(hapd, 0);
|
||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_INFO, "TKIP countermeasures ended");
|
||||
}
|
||||
|
||||
|
||||
static void ieee80211_tkip_countermeasures_start(struct hostapd_data *hapd)
|
||||
{
|
||||
struct sta_info *sta;
|
||||
|
||||
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_INFO, "TKIP countermeasures initiated");
|
||||
|
||||
wpa_auth_countermeasures_start(hapd->wpa_auth);
|
||||
hapd->tkip_countermeasures = 1;
|
||||
hapd->drv.set_countermeasures(hapd, 1);
|
||||
wpa_gtk_rekey(hapd->wpa_auth);
|
||||
eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL);
|
||||
eloop_register_timeout(60, 0, ieee80211_tkip_countermeasures_stop,
|
||||
hapd, NULL);
|
||||
for (sta = hapd->sta_list; sta != NULL; sta = sta->next) {
|
||||
hapd->drv.sta_deauth(hapd, sta->addr,
|
||||
WLAN_REASON_MICHAEL_MIC_FAILURE);
|
||||
sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
|
||||
WLAN_STA_AUTHORIZED);
|
||||
hapd->drv.sta_remove(hapd, sta->addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local)
|
||||
{
|
||||
time_t now;
|
||||
|
||||
if (addr && local) {
|
||||
struct sta_info *sta = ap_get_sta(hapd, addr);
|
||||
if (sta != NULL) {
|
||||
wpa_auth_sta_local_mic_failure_report(sta->wpa_sm);
|
||||
hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_INFO,
|
||||
"Michael MIC failure detected in "
|
||||
"received frame");
|
||||
mlme_michaelmicfailure_indication(hapd, addr);
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"MLME-MICHAELMICFAILURE.indication "
|
||||
"for not associated STA (" MACSTR
|
||||
") ignored", MAC2STR(addr));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
time(&now);
|
||||
if (now > hapd->michael_mic_failure + 60) {
|
||||
hapd->michael_mic_failures = 1;
|
||||
} else {
|
||||
hapd->michael_mic_failures++;
|
||||
if (hapd->michael_mic_failures > 1)
|
||||
ieee80211_tkip_countermeasures_start(hapd);
|
||||
}
|
||||
hapd->michael_mic_failure = now;
|
||||
}
|
20
contrib/wpa/src/ap/tkip_countermeasures.h
Normal file
20
contrib/wpa/src/ap/tkip_countermeasures.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* hostapd / TKIP countermeasures
|
||||
* 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 TKIP_COUNTERMEASURES_H
|
||||
#define TKIP_COUNTERMEASURES_H
|
||||
|
||||
void michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local);
|
||||
|
||||
#endif /* TKIP_COUNTERMEASURES_H */
|
88
contrib/wpa/src/ap/utils.c
Normal file
88
contrib/wpa/src/ap/utils.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* AP mode helper functions
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "sta_info.h"
|
||||
#include "hostapd.h"
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
struct hostapd_probereq_cb *n;
|
||||
|
||||
n = os_realloc(hapd->probereq_cb, (hapd->num_probereq_cb + 1) *
|
||||
sizeof(struct hostapd_probereq_cb));
|
||||
if (n == NULL)
|
||||
return -1;
|
||||
|
||||
hapd->probereq_cb = n;
|
||||
n = &hapd->probereq_cb[hapd->num_probereq_cb];
|
||||
hapd->num_probereq_cb++;
|
||||
|
||||
n->cb = cb;
|
||||
n->ctx = ctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct prune_data {
|
||||
struct hostapd_data *hapd;
|
||||
const u8 *addr;
|
||||
};
|
||||
|
||||
static int prune_associations(struct hostapd_iface *iface, void *ctx)
|
||||
{
|
||||
struct prune_data *data = ctx;
|
||||
struct sta_info *osta;
|
||||
struct hostapd_data *ohapd;
|
||||
size_t j;
|
||||
|
||||
for (j = 0; j < iface->num_bss; j++) {
|
||||
ohapd = iface->bss[j];
|
||||
if (ohapd == data->hapd)
|
||||
continue;
|
||||
osta = ap_get_sta(ohapd, data->addr);
|
||||
if (!osta)
|
||||
continue;
|
||||
|
||||
ap_sta_disassociate(ohapd, osta, WLAN_REASON_UNSPECIFIED);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hostapd_prune_associations - Remove extraneous associations
|
||||
* @hapd: Pointer to BSS data for the most recent association
|
||||
* @addr: Associated STA address
|
||||
*
|
||||
* This function looks through all radios and BSS's for previous
|
||||
* (stale) associations of STA. If any are found they are removed.
|
||||
*/
|
||||
void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr)
|
||||
{
|
||||
struct prune_data data;
|
||||
data.hapd = hapd;
|
||||
data.addr = addr;
|
||||
if (hapd->iface->for_each_interface)
|
||||
hapd->iface->for_each_interface(hapd->iface->interfaces,
|
||||
prune_associations, &data);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user