iPXE
802.11 association handling functions

Functions

static void net80211_step_associate (struct net80211_device *dev)
 Step 802.11 association process.
static void net80211_handle_auth (struct net80211_device *dev, struct io_buffer *iob)
 Handle receipt of 802.11 authentication frame.
static void net80211_handle_assoc_reply (struct net80211_device *dev, struct io_buffer *iob)
 Handle receipt of 802.11 association reply frame.
static int net80211_send_disassoc (struct net80211_device *dev, int reason, int deauth)
 Send 802.11 disassociation frame.
static void net80211_handle_mgmt (struct net80211_device *dev, struct io_buffer *iob, int signal)
 Handle receipt of 802.11 management frame.

Detailed Description

Function Documentation

◆ net80211_step_associate()

void net80211_step_associate ( struct net80211_device * dev)
static

Step 802.11 association process.

Parameters
dev802.11 device

Definition at line 1647 of file net80211.c.

1648{
1649 int rc = 0;
1650 int status = dev->state & NET80211_STATUS_MASK;
1651
1652 /*
1653 * We use a sort of state machine implemented using bits in
1654 * the dev->state variable. At each call, we take the
1655 * logically first step that has not yet succeeded; either it
1656 * has not been tried yet, it's being retried, or it failed.
1657 * If it failed, we return an error indication; otherwise we
1658 * perform the step. If it succeeds, RX handling code will set
1659 * the appropriate status bit for us.
1660 *
1661 * Probe works a bit differently, since we have to step it
1662 * on every call instead of waiting for a packet to arrive
1663 * that will set the completion bit for us.
1664 */
1665
1666 /* If we're waiting for a reply, check for timeout condition */
1667 if ( dev->state & NET80211_WAITING ) {
1668 /* Sanity check */
1669 if ( ! dev->associating )
1670 return;
1671
1672 if ( currticks() - dev->ctx.assoc->last_packet > ASSOC_TIMEOUT ) {
1673 /* Timed out - fail if too many retries, or retry */
1674 dev->ctx.assoc->times_tried++;
1675 if ( ++dev->ctx.assoc->times_tried > ASSOC_RETRIES ) {
1676 rc = -ETIMEDOUT;
1677 goto fail;
1678 }
1679 } else {
1680 /* Didn't time out - let it keep going */
1681 return;
1682 }
1683 } else {
1684 if ( dev->state & NET80211_PROBED )
1685 dev->ctx.assoc->times_tried = 0;
1686 }
1687
1688 if ( ! ( dev->state & NET80211_PROBED ) ) {
1689 /* state: probe */
1690
1691 if ( ! dev->ctx.probe ) {
1692 /* start probe */
1693 int active = fetch_intz_setting ( NULL,
1694 &net80211_active_setting );
1695 int band = dev->hw->bands;
1696
1697 if ( active )
1699
1700 rc = net80211_prepare_probe ( dev, band, active );
1701 if ( rc )
1702 goto fail;
1703
1704 dev->ctx.probe = net80211_probe_start ( dev, dev->essid,
1705 active );
1706 if ( ! dev->ctx.probe ) {
1707 dev->assoc_rc = -ENOMEM;
1708 goto fail;
1709 }
1710 }
1711
1712 rc = net80211_probe_step ( dev->ctx.probe );
1713 if ( ! rc ) {
1714 return; /* still going */
1715 }
1716
1718 dev->ctx.probe = NULL;
1719 if ( ! dev->associating ) {
1720 if ( rc > 0 ) /* "successful" probe found nothing */
1721 rc = -ETIMEDOUT;
1722 goto fail;
1723 }
1724
1725 /* If we probed using a broadcast SSID, record that
1726 fact for the settings applicator before we clobber
1727 it with the specific SSID we've chosen. */
1728 if ( ! dev->essid[0] )
1729 dev->state |= NET80211_AUTO_SSID;
1730
1731 DBGC ( dev, "802.11 %p found network %s (%s)\n", dev,
1732 dev->associating->essid,
1733 eth_ntoa ( dev->associating->bssid ) );
1734
1735 dev->ctx.assoc = zalloc ( sizeof ( *dev->ctx.assoc ) );
1736 if ( ! dev->ctx.assoc ) {
1737 rc = -ENOMEM;
1738 goto fail;
1739 }
1740
1741 dev->state |= NET80211_PROBED;
1743
1744 return;
1745 }
1746
1747 /* Record time of sending the packet we're about to send, for timeout */
1748 dev->ctx.assoc->last_packet = currticks();
1749
1750 if ( ! ( dev->state & NET80211_AUTHENTICATED ) ) {
1751 /* state: prepare and authenticate */
1752
1754 /* we tried authenticating already, but failed */
1755 int method = dev->ctx.assoc->method;
1756
1760 /* Maybe this network uses Shared Key? */
1761 dev->ctx.assoc->method =
1763 } else {
1764 goto fail;
1765 }
1766 }
1767
1768 DBGC ( dev, "802.11 %p authenticating with method %d\n", dev,
1769 dev->ctx.assoc->method );
1770
1771 rc = net80211_prepare_assoc ( dev, dev->associating );
1772 if ( rc )
1773 goto fail;
1774
1775 rc = net80211_send_auth ( dev, dev->associating,
1776 dev->ctx.assoc->method );
1777 if ( rc )
1778 goto fail;
1779
1780 return;
1781 }
1782
1783 if ( ! ( dev->state & NET80211_ASSOCIATED ) ) {
1784 /* state: associate */
1785
1787 goto fail;
1788
1789 DBGC ( dev, "802.11 %p associating\n", dev );
1790
1791 if ( dev->handshaker && dev->handshaker->start &&
1792 ! dev->handshaker->started ) {
1793 rc = dev->handshaker->start ( dev );
1794 if ( rc < 0 )
1795 goto fail;
1796 dev->handshaker->started = 1;
1797 }
1798
1799 rc = net80211_send_assoc ( dev, dev->associating );
1800 if ( rc )
1801 goto fail;
1802
1803 return;
1804 }
1805
1806 if ( ! ( dev->state & NET80211_CRYPTO_SYNCED ) ) {
1807 /* state: crypto sync */
1808 DBGC ( dev, "802.11 %p security handshaking\n", dev );
1809
1810 if ( ! dev->handshaker || ! dev->handshaker->step ) {
1812 return;
1813 }
1814
1815 rc = dev->handshaker->step ( dev );
1816
1817 if ( rc < 0 ) {
1818 /* Only record the returned error if we're
1819 still marked as associated, because an
1820 asynchronous error will have already been
1821 reported to net80211_deauthenticate() and
1822 assoc_rc thereby set. */
1823 if ( dev->state & NET80211_ASSOCIATED )
1824 dev->assoc_rc = rc;
1825 rc = 0;
1826 goto fail;
1827 }
1828
1829 if ( rc > 0 ) {
1830 dev->assoc_rc = 0;
1832 }
1833 return;
1834 }
1835
1836 /* state: done! */
1837 netdev_link_up ( dev->netdev );
1838 dev->assoc_rc = 0;
1839 dev->state &= ~NET80211_WORKING;
1840
1841 free ( dev->ctx.assoc );
1842 dev->ctx.assoc = NULL;
1843
1845 dev->associating = NULL;
1846
1847 dev->rctl = rc80211_init ( dev );
1848
1849 process_del ( &dev->proc_assoc );
1850
1851 DBGC ( dev, "802.11 %p associated with %s (%s)\n", dev,
1852 dev->essid, eth_ntoa ( dev->bssid ) );
1853
1854 return;
1855
1856 fail:
1858 if ( rc )
1859 dev->assoc_rc = rc;
1860
1861 netdev_link_err ( dev->netdev, dev->assoc_rc );
1862
1863 /* We never reach here from the middle of a probe, so we don't
1864 need to worry about freeing dev->ctx.probe. */
1865
1866 if ( dev->state & NET80211_PROBED ) {
1867 free ( dev->ctx.assoc );
1868 dev->ctx.assoc = NULL;
1869 }
1870
1872 dev->associating = NULL;
1873
1874 process_del ( &dev->proc_assoc );
1875
1876 DBGC ( dev, "802.11 %p association failed (state=%04x): "
1877 "%s\n", dev, dev->state, strerror ( dev->assoc_rc ) );
1878
1879 /* Try it again: */
1880 net80211_autoassociate ( dev );
1881}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
uint8_t status
Status.
Definition ena.h:5
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition ethernet.c:176
#define DBGC(...)
Definition compiler.h:505
#define IEEE80211_AUTH_SHARED_KEY
Shared Key authentication algorithm.
Definition ieee80211.h:1157
#define IEEE80211_AUTH_OPEN_SYSTEM
Open System authentication algorithm.
Definition ieee80211.h:1154
#define IEEE80211_STATUS_AUTH_ALGO_UNSUPP
Definition ieee80211.h:457
#define IEEE80211_STATUS_SUCCESS
Definition ieee80211.h:452
#define IEEE80211_STATUS_AUTH_CHALL_INVALID
Definition ieee80211.h:459
int net80211_prepare_assoc(struct net80211_device *dev, struct net80211_wlan *wlan)
Prepare 802.11 device channel and rate set for communication.
Definition net80211.c:2106
int net80211_send_auth(struct net80211_device *dev, struct net80211_wlan *wlan, int method)
Send 802.11 initial authentication frame.
Definition net80211.c:2201
int net80211_send_assoc(struct net80211_device *dev, struct net80211_wlan *wlan)
Send 802.11 association frame.
Definition net80211.c:2288
#define NET80211_BAND_BIT_5GHZ
Bitmask for the 5GHz band.
Definition net80211.h:54
void net80211_autoassociate(struct net80211_device *dev)
Start 802.11 association process.
Definition net80211.c:1930
struct net80211_wlan * net80211_probe_finish_best(struct net80211_probe_ctx *ctx)
Finish probe of 802.11 networks, returning best-signal network found.
Definition net80211.c:1545
void net80211_free_wlan(struct net80211_wlan *wlan)
Free WLAN structure.
Definition net80211.c:1606
int net80211_prepare_probe(struct net80211_device *dev, int band, int active)
Prepare 802.11 device channel and rate set for scanning.
Definition net80211.c:2052
struct net80211_probe_ctx * net80211_probe_start(struct net80211_device *dev, const char *essid, int active)
Begin probe of 802.11 networks.
Definition net80211.c:1291
int net80211_probe_step(struct net80211_probe_ctx *ctx)
Continue probe of 802.11 networks.
Definition net80211.c:1364
#define NET80211_PROBED
Whether we have found the network we will be associating with.
Definition net80211.h:191
#define NET80211_WORKING
Whether the auto-association task is running.
Definition net80211.h:212
#define NET80211_AUTHENTICATED
Whether we have successfully authenticated with the network.
Definition net80211.h:198
#define NET80211_CRYPTO_SYNCED
Whether we have completed security handshaking with the network.
Definition net80211.h:209
#define NET80211_WAITING
Whether the auto-association task is waiting for a reply from the AP.
Definition net80211.h:215
#define NET80211_AUTO_SSID
Whether this association was performed using a broadcast SSID.
Definition net80211.h:234
#define NET80211_STATUS_MASK
An error code indicating the failure mode, or 0 if successful.
Definition net80211.h:185
#define NET80211_ASSOCIATED
Whether we have successfully associated with the network.
Definition net80211.h:201
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
#define ENOMEM
Not enough space.
Definition errno.h:535
uint8_t method
Definition ib_mad.h:3
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
#define ASSOC_RETRIES
Number of times to try sending a particular association management frame.
Definition net80211.c:1640
#define ASSOC_TIMEOUT
Number of ticks to wait for replies to association management frames.
Definition net80211.c:1637
void netdev_link_err(struct net_device *netdev, int rc)
Mark network device as having a specific link state.
Definition netdevice.c:208
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition netdevice.h:789
void process_del(struct process *process)
Remove process from process list.
Definition process.c:80
struct rc80211_ctx * rc80211_init(struct net80211_device *dev __unused)
Initialize rate-control algorithm.
Definition rc80211.c:155
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
long fetch_intz_setting(struct settings *settings, const struct setting *setting)
Fetch value of signed integer setting, or zero.
Definition settings.c:1054
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int method
Next authentication method to try using.
Definition net80211.c:99
int last_packet
Time (in ticks) of the last sent association-related packet.
Definition net80211.c:102
int times_tried
Number of times we have tried sending it.
Definition net80211.c:105
struct net_device * netdev
The net_device that wraps us.
Definition net80211.h:789
char essid[IEEE80211_MAX_SSID_LEN+1]
SSID of the access point we are or will be associated with.
Definition net80211.h:962
union net80211_device::@067175076122124030020270151142244371222356023347 ctx
Context for the association process.
int assoc_rc
Return status code associated with state.
Definition net80211.h:924
u16 state
State of our association to the network.
Definition net80211.h:921
struct rc80211_ctx * rctl
Rate control state.
Definition net80211.h:989
struct net80211_handshaker * handshaker
Security handshaker being used.
Definition net80211.h:879
struct net80211_wlan * associating
Network with which we are associating.
Definition net80211.h:866
u8 bssid[ETH_ALEN]
MAC address of the access point most recently associated.
Definition net80211.h:954
struct net80211_assoc_ctx * assoc
Definition net80211.h:875
struct net80211_probe_ctx * probe
Definition net80211.h:874
struct process proc_assoc
The asynchronous association process.
Definition net80211.h:858
struct net80211_hw_info * hw
Information about the hardware, provided to net80211_register()
Definition net80211.h:801
int started
Whether start has been called.
Definition net80211.h:665
int(* start)(struct net80211_device *dev)
Start handshaking.
Definition net80211.h:598
int(* step)(struct net80211_device *dev)
Process handshaking state.
Definition net80211.h:616
int bands
A bitwise OR of the bands on which this device can communicate.
Definition net80211.h:453
u8 bssid[ETH_ALEN]
MAC address of the strongest-signal access point for this ESSID.
Definition net80211.h:1067
char essid[IEEE80211_MAX_SSID_LEN+1]
The human-readable ESSID (network name)
Definition net80211.h:1064
unsigned long currticks(void)
Get current system time in ticks.
Definition timer.c:43

References net80211_device::assoc, net80211_device::assoc_rc, ASSOC_RETRIES, ASSOC_TIMEOUT, net80211_device::associating, net80211_hw_info::bands, net80211_device::bssid, net80211_wlan::bssid, net80211_device::ctx, currticks(), DBGC, ENOMEM, net80211_device::essid, net80211_wlan::essid, eth_ntoa(), ETIMEDOUT, fetch_intz_setting(), free, net80211_device::handshaker, net80211_device::hw, IEEE80211_AUTH_OPEN_SYSTEM, IEEE80211_AUTH_SHARED_KEY, IEEE80211_STATUS_AUTH_ALGO_UNSUPP, IEEE80211_STATUS_AUTH_CHALL_INVALID, IEEE80211_STATUS_SUCCESS, net80211_assoc_ctx::last_packet, method, net80211_assoc_ctx::method, NET80211_ASSOCIATED, NET80211_AUTHENTICATED, NET80211_AUTO_SSID, net80211_autoassociate(), NET80211_BAND_BIT_5GHZ, NET80211_CRYPTO_SYNCED, net80211_free_wlan(), net80211_prepare_assoc(), net80211_prepare_probe(), net80211_probe_finish_best(), net80211_probe_start(), net80211_probe_step(), NET80211_PROBED, net80211_send_assoc(), net80211_send_auth(), NET80211_STATUS_MASK, NET80211_WAITING, NET80211_WORKING, net80211_device::netdev, netdev_link_err(), netdev_link_up(), NULL, net80211_device::probe, net80211_device::proc_assoc, process_del(), rc, rc80211_init(), net80211_device::rctl, net80211_handshaker::start, net80211_handshaker::started, net80211_device::state, status, net80211_handshaker::step, strerror(), net80211_assoc_ctx::times_tried, and zalloc().

◆ net80211_handle_auth()

void net80211_handle_auth ( struct net80211_device * dev,
struct io_buffer * iob )
static

Handle receipt of 802.11 authentication frame.

Parameters
dev802.11 device
iobI/O buffer

If the authentication method being used is Shared Key, and the frame that was received included challenge text, the frame is encrypted using the cryptosystem currently in effect and sent back to the AP to complete the authentication.

Definition at line 2228 of file net80211.c.

2230{
2231 struct ieee80211_frame *hdr = iob->data;
2232 struct ieee80211_auth *auth =
2233 ( struct ieee80211_auth * ) hdr->data;
2234
2235 if ( auth->tx_seq & 1 ) {
2236 DBGC ( dev, "802.11 %p authentication received improperly "
2237 "directed frame (seq. %d)\n", dev, auth->tx_seq );
2240 return;
2241 }
2242
2243 if ( auth->status != IEEE80211_STATUS_SUCCESS ) {
2244 DBGC ( dev, "802.11 %p authentication failed: status %d\n",
2245 dev, auth->status );
2247 auth->status );
2248 return;
2249 }
2250
2251 if ( auth->algorithm == IEEE80211_AUTH_SHARED_KEY && ! dev->crypto ) {
2252 DBGC ( dev, "802.11 %p can't perform shared-key authentication "
2253 "without a cryptosystem\n", dev );
2256 return;
2257 }
2258
2259 if ( auth->algorithm == IEEE80211_AUTH_SHARED_KEY &&
2260 auth->tx_seq == 2 ) {
2261 /* Since the iob we got is going to be freed as soon
2262 as we return, we can do some in-place
2263 modification. */
2264 auth->tx_seq = 3;
2265 auth->status = 0;
2266
2267 memcpy ( hdr->addr2, hdr->addr1, ETH_ALEN );
2268 memcpy ( hdr->addr1, hdr->addr3, ETH_ALEN );
2269
2270 netdev_tx ( dev->netdev,
2271 dev->crypto->encrypt ( dev->crypto, iob ) );
2272 return;
2273 }
2274
2277
2278 return;
2279}
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
#define IEEE80211_STATUS_FAILURE
Definition ieee80211.h:453
#define ETH_ALEN
Definition if_ether.h:9
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void net80211_set_state(struct net80211_device *dev, short clear, short set, u16 status)
Set state of 802.11 device.
Definition net80211.c:867
int netdev_tx(struct net_device *netdev, struct io_buffer *iobuf)
Transmit raw packet via network device.
Definition netdevice.c:335
Authentication frame data.
Definition ieee80211.h:1139
An 802.11 data or management frame without QoS or WDS header fields.
Definition ieee80211.h:301
void * data
Start of data.
Definition iobuf.h:53
struct io_buffer *(* encrypt)(struct net80211_crypto *crypto, struct io_buffer *iob)
Encrypt a frame using the cryptosystem.
Definition net80211.h:733
struct net80211_crypto * crypto
802.11 cryptosystem for our current network
Definition net80211.h:940

References ieee80211_auth::algorithm, net80211_device::crypto, io_buffer::data, DBGC, net80211_crypto::encrypt, ETH_ALEN, hdr, IEEE80211_AUTH_SHARED_KEY, IEEE80211_STATUS_FAILURE, IEEE80211_STATUS_SUCCESS, memcpy(), NET80211_AUTHENTICATED, net80211_set_state(), NET80211_WAITING, net80211_device::netdev, netdev_tx(), ieee80211_auth::status, and ieee80211_auth::tx_seq.

Referenced by net80211_handle_mgmt().

◆ net80211_handle_assoc_reply()

void net80211_handle_assoc_reply ( struct net80211_device * dev,
struct io_buffer * iob )
static

Handle receipt of 802.11 association reply frame.

Parameters
dev802.11 device
iobI/O buffer

Definition at line 2327 of file net80211.c.

2329{
2330 struct ieee80211_frame *hdr = iob->data;
2331 struct ieee80211_assoc_resp *assoc =
2332 ( struct ieee80211_assoc_resp * ) hdr->data;
2333
2334 net80211_process_capab ( dev, assoc->capability );
2335 net80211_process_ie ( dev, assoc->info_element, iob->tail );
2336
2337 if ( assoc->status != IEEE80211_STATUS_SUCCESS ) {
2338 DBGC ( dev, "802.11 %p association failed: status %d\n",
2339 dev, assoc->status );
2341 assoc->status );
2342 return;
2343 }
2344
2345 /* ESSID was filled before the association request was sent */
2346 memcpy ( dev->bssid, hdr->addr3, ETH_ALEN );
2347 dev->aid = assoc->aid;
2348
2351}
#define ieee80211_assoc_resp
Definition ieee80211.h:1111
static int net80211_process_capab(struct net80211_device *dev, u16 capab)
Update 802.11 device state to reflect received capabilities field.
Definition net80211.c:1011
static int net80211_process_ie(struct net80211_device *dev, union ieee80211_ie *ie, void *ie_end)
Update 802.11 device state to reflect received information elements.
Definition net80211.c:1045
void * tail
End of data.
Definition iobuf.h:55
u16 aid
Association ID given to us by the AP.
Definition net80211.h:965

References net80211_device::aid, net80211_device::bssid, io_buffer::data, DBGC, ETH_ALEN, hdr, ieee80211_assoc_resp, IEEE80211_STATUS_SUCCESS, memcpy(), NET80211_ASSOCIATED, net80211_process_capab(), net80211_process_ie(), net80211_set_state(), NET80211_WAITING, and io_buffer::tail.

Referenced by net80211_handle_mgmt().

◆ net80211_send_disassoc()

int net80211_send_disassoc ( struct net80211_device * dev,
int reason,
int deauth )
static

Send 802.11 disassociation frame.

Parameters
dev802.11 device
reasonReason for disassociation
deauthIf TRUE, send deauthentication instead of disassociation
Return values
rcReturn status code

Definition at line 2362 of file net80211.c.

2364{
2365 struct io_buffer *iob = alloc_iob ( 64 );
2366 struct ieee80211_disassoc *disassoc;
2367
2368 if ( ! ( dev->state & NET80211_ASSOCIATED ) )
2369 return -EINVAL;
2370
2373 disassoc = iob_put ( iob, sizeof ( *disassoc ) );
2374 disassoc->reason = reason;
2375
2376 return net80211_tx_mgmt ( dev, deauth ? IEEE80211_STYPE_DEAUTH :
2377 IEEE80211_STYPE_DISASSOC, dev->bssid, iob );
2378}
#define IEEE80211_STYPE_DISASSOC
Subtype value for disassociation management frames.
Definition ieee80211.h:178
#define IEEE80211_STYPE_DEAUTH
Subtype value for deauthentication management frames.
Definition ieee80211.h:198
#define IEEE80211_TYP_FRAME_HEADER_LEN
Frame header length for frames we might work with.
Definition ieee80211.h:60
#define ieee80211_disassoc
Definition ieee80211.h:1079
#define EINVAL
Invalid argument.
Definition errno.h:429
uint16_t reason
Rejection reason.
Definition ib_mad.h:9
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_put(iobuf, len)
Definition iobuf.h:125
#define iob_reserve(iobuf, len)
Definition iobuf.h:72
int net80211_tx_mgmt(struct net80211_device *dev, u16 fc, u8 dest[6], struct io_buffer *iob)
Transmit 802.11 management frame.
Definition net80211.c:707
A persistent I/O buffer.
Definition iobuf.h:38

References alloc_iob(), net80211_device::bssid, EINVAL, ieee80211_disassoc, IEEE80211_STYPE_DEAUTH, IEEE80211_STYPE_DISASSOC, IEEE80211_TYP_FRAME_HEADER_LEN, iob_put, iob_reserve, NET80211_ASSOCIATED, net80211_set_state(), net80211_tx_mgmt(), reason, and net80211_device::state.

Referenced by net80211_deauthenticate(), and net80211_netdev_close().

◆ net80211_handle_mgmt()

void net80211_handle_mgmt ( struct net80211_device * dev,
struct io_buffer * iob,
int signal )
static

Handle receipt of 802.11 management frame.

Parameters
dev802.11 device
iobI/O buffer
signalSignal strength of received frame

Definition at line 2439 of file net80211.c.

2441{
2442 struct ieee80211_frame *hdr = iob->data;
2443 struct ieee80211_disassoc *disassoc;
2444 u16 stype = hdr->fc & IEEE80211_FC_SUBTYPE;
2445 int keep = 0;
2446 int is_deauth = ( stype == IEEE80211_STYPE_DEAUTH );
2447
2448 if ( ( hdr->fc & IEEE80211_FC_TYPE ) != IEEE80211_TYPE_MGMT ) {
2449 free_iob ( iob );
2450 return; /* only handle management frames */
2451 }
2452
2453 switch ( stype ) {
2454 /* We reconnect on deauthentication and disassociation. */
2457 disassoc = ( struct ieee80211_disassoc * ) hdr->data;
2458 net80211_set_state ( dev, is_deauth ? NET80211_AUTHENTICATED :
2460 NET80211_IS_REASON | disassoc->reason );
2461 DBGC ( dev, "802.11 %p %s: reason %d\n",
2462 dev, is_deauth ? "deauthenticated" : "disassociated",
2463 disassoc->reason );
2464
2465 /* Try to reassociate, in case it's transient. */
2466 net80211_autoassociate ( dev );
2467
2468 break;
2469
2470 /* We handle authentication and association. */
2472 if ( ! ( dev->state & NET80211_AUTHENTICATED ) )
2473 net80211_handle_auth ( dev, iob );
2474 break;
2475
2478 if ( ! ( dev->state & NET80211_ASSOCIATED ) )
2479 net80211_handle_assoc_reply ( dev, iob );
2480 break;
2481
2482 /* We pass probes and beacons onto network scanning
2483 code. Pass actions for future extensibility. */
2485 net80211_update_link_quality ( dev, iob );
2486 /* fall through */
2489 if ( dev->keep_mgmt ) {
2490 struct net80211_rx_info *rxinf;
2491 rxinf = zalloc ( sizeof ( *rxinf ) );
2492 if ( ! rxinf ) {
2493 DBGC ( dev, "802.11 %p out of memory\n", dev );
2494 break;
2495 }
2496 rxinf->signal = signal;
2497 list_add_tail ( &iob->list, &dev->mgmt_queue );
2498 list_add_tail ( &rxinf->list, &dev->mgmt_info_queue );
2499 keep = 1;
2500 }
2501 break;
2502
2504 /* Some nodes send these broadcast. Ignore them. */
2505 break;
2506
2509 /* We should never receive these, only send them. */
2510 DBGC ( dev, "802.11 %p received strange management request "
2511 "(%04x)\n", dev, stype );
2512 break;
2513
2514 default:
2515 DBGC ( dev, "802.11 %p received unimplemented management "
2516 "packet (%04x)\n", dev, stype );
2517 break;
2518 }
2519
2520 if ( ! keep )
2521 free_iob ( iob );
2522}
#define IEEE80211_STYPE_ASSOC_REQ
Subtype value for association-request management frames.
Definition ieee80211.h:118
#define IEEE80211_STYPE_ASSOC_RESP
Subtype value for association-response management frames.
Definition ieee80211.h:125
#define IEEE80211_FC_SUBTYPE
802.11 Frame Control field, Frame Subtype bitmask
Definition ieee80211.h:110
#define IEEE80211_TYPE_MGMT
Type value for management (layer-2) frames.
Definition ieee80211.h:100
#define IEEE80211_STYPE_PROBE_RESP
Subtype value for probe-response management frames.
Definition ieee80211.h:157
#define IEEE80211_STYPE_ACTION
Subtype value for action management frames.
Definition ieee80211.h:205
#define IEEE80211_FC_TYPE
802.11 Frame Control field, Frame Type bitmask
Definition ieee80211.h:97
#define IEEE80211_STYPE_BEACON
Subtype value for beacon management frames.
Definition ieee80211.h:168
#define IEEE80211_STYPE_REASSOC_REQ
Subtype value for reassociation-request management frames.
Definition ieee80211.h:133
#define IEEE80211_STYPE_AUTH
Subtype value for authentication management frames.
Definition ieee80211.h:188
#define IEEE80211_STYPE_PROBE_REQ
Subtype value for probe-request management frames.
Definition ieee80211.h:150
#define IEEE80211_STYPE_REASSOC_RESP
Subtype value for reassociation-response management frames.
Definition ieee80211.h:141
static void net80211_handle_assoc_reply(struct net80211_device *dev, struct io_buffer *iob)
Handle receipt of 802.11 association reply frame.
Definition net80211.c:2327
static void net80211_handle_auth(struct net80211_device *dev, struct io_buffer *iob)
Handle receipt of 802.11 authentication frame.
Definition net80211.c:2228
#define NET80211_IS_REASON
Whether the error code provided is a "reason" code, not a "status" code.
Definition net80211.h:188
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
static void net80211_update_link_quality(struct net80211_device *dev, struct io_buffer *iob)
Update link quality information based on received beacon.
Definition net80211.c:2411
struct list_head list
List of which this buffer is a member.
Definition iobuf.h:45
int keep_mgmt
Whether to store management packets.
Definition net80211.h:1046
struct list_head mgmt_queue
RX management packet queue.
Definition net80211.h:1021
struct list_head mgmt_info_queue
RX management packet info queue.
Definition net80211.h:1034
Information associated with a received management packet.
Definition net80211.c:58
struct list_head list
Definition net80211.c:60
#define u16
Definition vga.h:20

References io_buffer::data, DBGC, free_iob(), hdr, ieee80211_disassoc, IEEE80211_FC_SUBTYPE, IEEE80211_FC_TYPE, IEEE80211_STYPE_ACTION, IEEE80211_STYPE_ASSOC_REQ, IEEE80211_STYPE_ASSOC_RESP, IEEE80211_STYPE_AUTH, IEEE80211_STYPE_BEACON, IEEE80211_STYPE_DEAUTH, IEEE80211_STYPE_DISASSOC, IEEE80211_STYPE_PROBE_REQ, IEEE80211_STYPE_PROBE_RESP, IEEE80211_STYPE_REASSOC_REQ, IEEE80211_STYPE_REASSOC_RESP, IEEE80211_TYPE_MGMT, net80211_device::keep_mgmt, io_buffer::list, net80211_rx_info::list, list_add_tail, net80211_device::mgmt_info_queue, net80211_device::mgmt_queue, NET80211_ASSOCIATED, NET80211_AUTHENTICATED, net80211_autoassociate(), net80211_handle_assoc_reply(), net80211_handle_auth(), NET80211_IS_REASON, net80211_set_state(), net80211_update_link_quality(), net80211_rx_info::signal, net80211_device::state, u16, and zalloc().

Referenced by net80211_rx().