iPXE
Functions
802.11 association handling functions

Functions

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

Detailed Description

Function Documentation

◆ net80211_step_associate()

static void net80211_step_associate ( struct net80211_device dev)
static

Step 802.11 association process.

Parameters
dev802.11 device

Definition at line 1646 of file net80211.c.

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

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()

static 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 2227 of file net80211.c.

2229 {
2230  struct ieee80211_frame *hdr = iob->data;
2231  struct ieee80211_auth *auth =
2232  ( struct ieee80211_auth * ) hdr->data;
2233 
2234  if ( auth->tx_seq & 1 ) {
2235  DBGC ( dev, "802.11 %p authentication received improperly "
2236  "directed frame (seq. %d)\n", dev, auth->tx_seq );
2239  return;
2240  }
2241 
2242  if ( auth->status != IEEE80211_STATUS_SUCCESS ) {
2243  DBGC ( dev, "802.11 %p authentication failed: status %d\n",
2244  dev, auth->status );
2246  auth->status );
2247  return;
2248  }
2249 
2250  if ( auth->algorithm == IEEE80211_AUTH_SHARED_KEY && ! dev->crypto ) {
2251  DBGC ( dev, "802.11 %p can't perform shared-key authentication "
2252  "without a cryptosystem\n", dev );
2255  return;
2256  }
2257 
2258  if ( auth->algorithm == IEEE80211_AUTH_SHARED_KEY &&
2259  auth->tx_seq == 2 ) {
2260  /* Since the iob we got is going to be freed as soon
2261  as we return, we can do some in-place
2262  modification. */
2263  auth->tx_seq = 3;
2264  auth->status = 0;
2265 
2266  memcpy ( hdr->addr2, hdr->addr1, ETH_ALEN );
2267  memcpy ( hdr->addr1, hdr->addr3, ETH_ALEN );
2268 
2269  netdev_tx ( dev->netdev,
2270  dev->crypto->encrypt ( dev->crypto, iob ) );
2271  return;
2272  }
2273 
2276 
2277  return;
2278 }
#define IEEE80211_STATUS_FAILURE
Definition: ieee80211.h:453
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
#define IEEE80211_AUTH_SHARED_KEY
Shared Key authentication algorithm.
Definition: ieee80211.h:1157
#define DBGC(...)
Definition: compiler.h:505
An 802.11 data or management frame without QoS or WDS header fields.
Definition: ieee80211.h:300
static void void * auth
Definition: crypto.h:264
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct net80211_crypto * crypto
802.11 cryptosystem for our current network
Definition: net80211.h:940
#define IEEE80211_STATUS_SUCCESS
Definition: ieee80211.h:452
#define NET80211_WAITING
Whether the auto-association task is waiting for a reply from the AP.
Definition: net80211.h:215
int netdev_tx(struct net_device *netdev, struct io_buffer *iobuf)
Transmit raw packet via network device.
Definition: netdevice.c:334
#define ETH_ALEN
Definition: if_ether.h:8
struct net_device * netdev
The net_device that wraps us.
Definition: net80211.h:789
#define NET80211_AUTHENTICATED
Whether we have successfully authenticated with the network.
Definition: net80211.h:198
Authentication frame data.
Definition: ieee80211.h:1138
static void net80211_set_state(struct net80211_device *dev, short clear, short set, u16 status)
Set state of 802.11 device.
Definition: net80211.c:866
void * data
Start of data.
Definition: iobuf.h:48
struct io_buffer *(* encrypt)(struct net80211_crypto *crypto, struct io_buffer *iob)
Encrypt a frame using the cryptosystem.
Definition: net80211.h:733
if(natsemi->flags &NATSEMI_64BIT) return 1

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

Referenced by net80211_handle_mgmt().

◆ net80211_handle_assoc_reply()

static 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 2326 of file net80211.c.

2328 {
2329  struct ieee80211_frame *hdr = iob->data;
2330  struct ieee80211_assoc_resp *assoc =
2331  ( struct ieee80211_assoc_resp * ) hdr->data;
2332 
2333  net80211_process_capab ( dev, assoc->capability );
2334  net80211_process_ie ( dev, assoc->info_element, iob->tail );
2335 
2336  if ( assoc->status != IEEE80211_STATUS_SUCCESS ) {
2337  DBGC ( dev, "802.11 %p association failed: status %d\n",
2338  dev, assoc->status );
2340  assoc->status );
2341  return;
2342  }
2343 
2344  /* ESSID was filled before the association request was sent */
2345  memcpy ( dev->bssid, hdr->addr3, ETH_ALEN );
2346  dev->aid = assoc->aid;
2347 
2350 }
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
#define DBGC(...)
Definition: compiler.h:505
An 802.11 data or management frame without QoS or WDS header fields.
Definition: ieee80211.h:300
u16 aid
Association ID given to us by the AP.
Definition: net80211.h:965
void * tail
End of data.
Definition: iobuf.h:50
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define IEEE80211_STATUS_SUCCESS
Definition: ieee80211.h:452
#define NET80211_WAITING
Whether the auto-association task is waiting for a reply from the AP.
Definition: net80211.h:215
#define NET80211_ASSOCIATED
Whether we have successfully associated with the network.
Definition: net80211.h:201
static int net80211_process_capab(struct net80211_device *dev, u16 capab)
Update 802.11 device state to reflect received capabilities field.
Definition: net80211.c:1010
#define ETH_ALEN
Definition: if_ether.h:8
#define ieee80211_assoc_resp
Definition: ieee80211.h:1111
static void net80211_set_state(struct net80211_device *dev, short clear, short set, u16 status)
Set state of 802.11 device.
Definition: net80211.c:866
void * data
Start of data.
Definition: iobuf.h:48
u8 bssid[ETH_ALEN]
MAC address of the access point most recently associated.
Definition: net80211.h:954
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:1044

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()

static 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 2361 of file net80211.c.

2363 {
2364  struct io_buffer *iob = alloc_iob ( 64 );
2365  struct ieee80211_disassoc *disassoc;
2366 
2367  if ( ! ( dev->state & NET80211_ASSOCIATED ) )
2368  return -EINVAL;
2369 
2370  net80211_set_state ( dev, NET80211_ASSOCIATED, 0, 0 );
2372  disassoc = iob_put ( iob, sizeof ( *disassoc ) );
2373  disassoc->reason = reason;
2374 
2375  return net80211_tx_mgmt ( dev, deauth ? IEEE80211_STYPE_DEAUTH :
2376  IEEE80211_STYPE_DISASSOC, dev->bssid, iob );
2377 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define iob_put(iobuf, len)
Definition: iobuf.h:120
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:129
#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 NET80211_ASSOCIATED
Whether we have successfully associated with the network.
Definition: net80211.h:201
#define IEEE80211_STYPE_DISASSOC
Subtype value for disassociation management frames.
Definition: ieee80211.h:178
#define iob_reserve(iobuf, len)
Definition: iobuf.h:67
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:706
static void net80211_set_state(struct net80211_device *dev, short clear, short set, u16 status)
Set state of 802.11 device.
Definition: net80211.c:866
#define ieee80211_disassoc
Definition: ieee80211.h:1079
uint16_t reason
Rejection reason.
Definition: ib_mad.h:20
u8 bssid[ETH_ALEN]
MAC address of the access point most recently associated.
Definition: net80211.h:954
u16 state
State of our association to the network.
Definition: net80211.h:921
A persistent I/O buffer.
Definition: iobuf.h:33

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()

static 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 2438 of file net80211.c.

2440 {
2441  struct ieee80211_frame *hdr = iob->data;
2442  struct ieee80211_disassoc *disassoc;
2443  u16 stype = hdr->fc & IEEE80211_FC_SUBTYPE;
2444  int keep = 0;
2445  int is_deauth = ( stype == IEEE80211_STYPE_DEAUTH );
2446 
2447  if ( ( hdr->fc & IEEE80211_FC_TYPE ) != IEEE80211_TYPE_MGMT ) {
2448  free_iob ( iob );
2449  return; /* only handle management frames */
2450  }
2451 
2452  switch ( stype ) {
2453  /* We reconnect on deauthentication and disassociation. */
2456  disassoc = ( struct ieee80211_disassoc * ) hdr->data;
2457  net80211_set_state ( dev, is_deauth ? NET80211_AUTHENTICATED :
2459  NET80211_IS_REASON | disassoc->reason );
2460  DBGC ( dev, "802.11 %p %s: reason %d\n",
2461  dev, is_deauth ? "deauthenticated" : "disassociated",
2462  disassoc->reason );
2463 
2464  /* Try to reassociate, in case it's transient. */
2465  net80211_autoassociate ( dev );
2466 
2467  break;
2468 
2469  /* We handle authentication and association. */
2470  case IEEE80211_STYPE_AUTH:
2471  if ( ! ( dev->state & NET80211_AUTHENTICATED ) )
2472  net80211_handle_auth ( dev, iob );
2473  break;
2474 
2477  if ( ! ( dev->state & NET80211_ASSOCIATED ) )
2478  net80211_handle_assoc_reply ( dev, iob );
2479  break;
2480 
2481  /* We pass probes and beacons onto network scanning
2482  code. Pass actions for future extensibility. */
2484  net80211_update_link_quality ( dev, iob );
2485  /* fall through */
2488  if ( dev->keep_mgmt ) {
2489  struct net80211_rx_info *rxinf;
2490  rxinf = zalloc ( sizeof ( *rxinf ) );
2491  if ( ! rxinf ) {
2492  DBGC ( dev, "802.11 %p out of memory\n", dev );
2493  break;
2494  }
2495  rxinf->signal = signal;
2496  list_add_tail ( &iob->list, &dev->mgmt_queue );
2497  list_add_tail ( &rxinf->list, &dev->mgmt_info_queue );
2498  keep = 1;
2499  }
2500  break;
2501 
2503  /* Some nodes send these broadcast. Ignore them. */
2504  break;
2505 
2508  /* We should never receive these, only send them. */
2509  DBGC ( dev, "802.11 %p received strange management request "
2510  "(%04x)\n", dev, stype );
2511  break;
2512 
2513  default:
2514  DBGC ( dev, "802.11 %p received unimplemented management "
2515  "packet (%04x)\n", dev, stype );
2516  break;
2517  }
2518 
2519  if ( ! keep )
2520  free_iob ( iob );
2521 }
uint16_t u16
Definition: stdint.h:21
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
#define IEEE80211_STYPE_ASSOC_RESP
Subtype value for association-response management frames.
Definition: ieee80211.h:125
struct list_head mgmt_info_queue
RX management packet info queue.
Definition: net80211.h:1034
#define DBGC(...)
Definition: compiler.h:505
An 802.11 data or management frame without QoS or WDS header fields.
Definition: ieee80211.h:300
struct list_head mgmt_queue
RX management packet queue.
Definition: net80211.h:1021
#define IEEE80211_STYPE_AUTH
Subtype value for authentication management frames.
Definition: ieee80211.h:188
#define NET80211_IS_REASON
Whether the error code provided is a "reason" code, not a "status" code.
Definition: net80211.h:188
#define IEEE80211_FC_SUBTYPE
802.11 Frame Control field, Frame Subtype bitmask
Definition: ieee80211.h:110
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:2326
#define IEEE80211_STYPE_DEAUTH
Subtype value for deauthentication management frames.
Definition: ieee80211.h:198
#define IEEE80211_STYPE_REASSOC_RESP
Subtype value for reassociation-response management frames.
Definition: ieee80211.h:141
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
Information associated with a received management packet.
Definition: net80211.c:57
int keep_mgmt
Whether to store management packets.
Definition: net80211.h:1046
static void net80211_handle_auth(struct net80211_device *dev, struct io_buffer *iob)
Handle receipt of 802.11 authentication frame.
Definition: net80211.c:2227
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
#define IEEE80211_FC_TYPE
802.11 Frame Control field, Frame Type bitmask
Definition: ieee80211.h:97
#define NET80211_ASSOCIATED
Whether we have successfully associated with the network.
Definition: net80211.h:201
void net80211_autoassociate(struct net80211_device *dev)
Start 802.11 association process.
Definition: net80211.c:1929
struct list_head list
Definition: net80211.c:59
#define IEEE80211_STYPE_ASSOC_REQ
Subtype value for association-request management frames.
Definition: ieee80211.h:118
#define IEEE80211_STYPE_PROBE_RESP
Subtype value for probe-response management frames.
Definition: ieee80211.h:157
#define NET80211_AUTHENTICATED
Whether we have successfully authenticated with the network.
Definition: net80211.h:198
#define IEEE80211_STYPE_DISASSOC
Subtype value for disassociation management frames.
Definition: ieee80211.h:178
#define IEEE80211_STYPE_REASSOC_REQ
Subtype value for reassociation-request management frames.
Definition: ieee80211.h:133
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
static void net80211_set_state(struct net80211_device *dev, short clear, short set, u16 status)
Set state of 802.11 device.
Definition: net80211.c:866
void * data
Start of data.
Definition: iobuf.h:48
#define IEEE80211_STYPE_ACTION
Subtype value for action management frames.
Definition: ieee80211.h:205
#define ieee80211_disassoc
Definition: ieee80211.h:1079
u16 state
State of our association to the network.
Definition: net80211.h:921
#define IEEE80211_STYPE_BEACON
Subtype value for beacon management frames.
Definition: ieee80211.h:168
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:2410
#define IEEE80211_STYPE_PROBE_REQ
Subtype value for probe-request management frames.
Definition: ieee80211.h:150
#define IEEE80211_TYPE_MGMT
Type value for management (layer-2) frames.
Definition: ieee80211.h:100

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, net80211_rx_info::list, io_buffer::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, and zalloc().

Referenced by net80211_rx().