iPXE
Functions
802.11 fragment handling functions

Functions

static void net80211_free_frags (struct net80211_device *dev, int fcid)
 Free buffers used by 802.11 fragment cache entry. More...
 
static struct io_buffernet80211_accum_frags (struct net80211_device *dev, int fcid, int nfrags, int size)
 Accumulate 802.11 fragments into one I/O buffer. More...
 
static void net80211_rx_frag (struct net80211_device *dev, struct io_buffer *iob, int signal)
 Handle receipt of 802.11 fragment. More...
 

Detailed Description

Function Documentation

◆ net80211_free_frags()

static void net80211_free_frags ( struct net80211_device dev,
int  fcid 
)
static

Free buffers used by 802.11 fragment cache entry.

Parameters
dev802.11 device
fcidFragment cache entry index

After this function, the referenced entry will be marked unused.

Definition at line 2533 of file net80211.c.

2534 {
2535  int j;
2536  struct net80211_frag_cache *frag = &dev->frags[fcid];
2537 
2538  for ( j = 0; j < 16; j++ ) {
2539  if ( frag->iob[j] ) {
2540  free_iob ( frag->iob[j] );
2541  frag->iob[j] = NULL;
2542  }
2543  }
2544 
2545  frag->seqnr = 0;
2546  frag->start_ticks = 0;
2547  frag->in_use = 0;
2548 }
struct net80211_frag_cache frags[NET80211_NR_CONCURRENT_FRAGS]
Fragment reassembly state.
Definition: net80211.h:994
u8 in_use
Whether this cache entry is in use.
Definition: net80211.h:536
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
Structure tracking received fragments for a packet.
Definition: net80211.h:533
struct io_buffer * iob[16]
Buffers for each fragment.
Definition: net80211.h:545
u32 start_ticks
Timestamp from point at which first fragment was collected.
Definition: net80211.h:542
u16 seqnr
Sequence number of this MSDU (packet)
Definition: net80211.h:539
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References net80211_device::frags, free_iob(), net80211_frag_cache::in_use, net80211_frag_cache::iob, NULL, net80211_frag_cache::seqnr, and net80211_frag_cache::start_ticks.

Referenced by net80211_rx_frag().

◆ net80211_accum_frags()

static struct io_buffer * net80211_accum_frags ( struct net80211_device dev,
int  fcid,
int  nfrags,
int  size 
)
static

Accumulate 802.11 fragments into one I/O buffer.

Parameters
dev802.11 device
fcidFragment cache entry index
nfragsNumber of fragments received
sizeSum of sizes of all fragments, including headers
Return values
iobI/O buffer containing reassembled packet

This function does not free the fragment buffers.

Definition at line 2561 of file net80211.c.

2563 {
2564  struct net80211_frag_cache *frag = &dev->frags[fcid];
2565  int hdrsize = IEEE80211_TYP_FRAME_HEADER_LEN;
2566  int nsize = size - hdrsize * ( nfrags - 1 );
2567  int i;
2568 
2569  struct io_buffer *niob = alloc_iob ( nsize );
2570  struct ieee80211_frame *hdr;
2571 
2572  /* Add the header from the first one... */
2573  memcpy ( iob_put ( niob, hdrsize ), frag->iob[0]->data, hdrsize );
2574 
2575  /* ... and all the data from all of them. */
2576  for ( i = 0; i < nfrags; i++ ) {
2577  int len = iob_len ( frag->iob[i] ) - hdrsize;
2578  memcpy ( iob_put ( niob, len ),
2579  frag->iob[i]->data + hdrsize, len );
2580  }
2581 
2582  /* Turn off the fragment bit. */
2583  hdr = niob->data;
2584  hdr->fc &= ~IEEE80211_FC_MORE_FRAG;
2585 
2586  return niob;
2587 }
struct net80211_frag_cache frags[NET80211_NR_CONCURRENT_FRAGS]
Fragment reassembly state.
Definition: net80211.h:994
#define iob_put(iobuf, len)
Definition: iobuf.h:116
An 802.11 data or management frame without QoS or WDS header fields.
Definition: ieee80211.h:300
Structure tracking received fragments for a packet.
Definition: net80211.h:533
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:128
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define IEEE80211_TYP_FRAME_HEADER_LEN
Frame header length for frames we might work with.
Definition: ieee80211.h:60
struct io_buffer * iob[16]
Buffers for each fragment.
Definition: net80211.h:545
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
uint32_t hdr
Message header.
Definition: intelvf.h:12
#define IEEE80211_FC_MORE_FRAG
802.11 Frame Control field: More Fragments flag
Definition: ieee80211.h:240
uint32_t len
Length.
Definition: ena.h:14
void * data
Start of data.
Definition: iobuf.h:44
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
A persistent I/O buffer.
Definition: iobuf.h:32

References alloc_iob(), io_buffer::data, net80211_device::frags, hdr, IEEE80211_FC_MORE_FRAG, IEEE80211_TYP_FRAME_HEADER_LEN, net80211_frag_cache::iob, iob_len(), iob_put, len, memcpy(), and size.

Referenced by net80211_rx_frag().

◆ net80211_rx_frag()

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

Handle receipt of 802.11 fragment.

Parameters
dev802.11 device
iobI/O buffer containing fragment
signalSignal strength with which fragment was received

Definition at line 2596 of file net80211.c.

2598 {
2599  struct ieee80211_frame *hdr = iob->data;
2600  int fragnr = IEEE80211_FRAG ( hdr->seq );
2601 
2602  if ( fragnr == 0 && ( hdr->fc & IEEE80211_FC_MORE_FRAG ) ) {
2603  /* start a frag cache entry */
2604  int i, newest = -1;
2605  u32 curr_ticks = currticks(), newest_ticks = 0;
2607 
2608  for ( i = 0; i < NET80211_NR_CONCURRENT_FRAGS; i++ ) {
2609  if ( dev->frags[i].in_use == 0 )
2610  break;
2611 
2612  if ( dev->frags[i].start_ticks + timeout >=
2613  curr_ticks ) {
2614  net80211_free_frags ( dev, i );
2615  break;
2616  }
2617 
2618  if ( dev->frags[i].start_ticks > newest_ticks ) {
2619  newest = i;
2620  newest_ticks = dev->frags[i].start_ticks;
2621  }
2622  }
2623 
2624  /* If we're being sent more concurrent fragmented
2625  packets than we can handle, drop the newest so the
2626  older ones have time to complete. */
2627  if ( i == NET80211_NR_CONCURRENT_FRAGS ) {
2628  i = newest;
2629  net80211_free_frags ( dev, i );
2630  }
2631 
2632  dev->frags[i].in_use = 1;
2633  dev->frags[i].seqnr = IEEE80211_SEQNR ( hdr->seq );
2634  dev->frags[i].start_ticks = currticks();
2635  dev->frags[i].iob[0] = iob;
2636  return;
2637  } else {
2638  int i;
2639  for ( i = 0; i < NET80211_NR_CONCURRENT_FRAGS; i++ ) {
2640  if ( dev->frags[i].in_use && dev->frags[i].seqnr ==
2641  IEEE80211_SEQNR ( hdr->seq ) )
2642  break;
2643  }
2644  if ( i == NET80211_NR_CONCURRENT_FRAGS ) {
2645  /* Drop non-first not-in-cache fragments */
2646  DBGC ( dev, "802.11 %p dropped fragment fc=%04x "
2647  "seq=%04x\n", dev, hdr->fc, hdr->seq );
2648  free_iob ( iob );
2649  return;
2650  }
2651 
2652  dev->frags[i].iob[fragnr] = iob;
2653 
2654  if ( ! ( hdr->fc & IEEE80211_FC_MORE_FRAG ) ) {
2655  int j, size = 0;
2656  for ( j = 0; j < fragnr; j++ ) {
2657  size += iob_len ( dev->frags[i].iob[j] );
2658  if ( dev->frags[i].iob[j] == NULL )
2659  break;
2660  }
2661  if ( j == fragnr ) {
2662  /* We've got everything */
2663  struct io_buffer *niob =
2664  net80211_accum_frags ( dev, i, fragnr,
2665  size );
2666  net80211_free_frags ( dev, i );
2667  net80211_rx ( dev, niob, signal, 0 );
2668  } else {
2669  DBGC ( dev, "802.11 %p dropping fragmented "
2670  "packet due to out-of-order arrival, "
2671  "fc=%04x seq=%04x\n", dev, hdr->fc,
2672  hdr->seq );
2673  net80211_free_frags ( dev, i );
2674  }
2675  }
2676  }
2677 }
struct net80211_frag_cache frags[NET80211_NR_CONCURRENT_FRAGS]
Fragment reassembly state.
Definition: net80211.h:994
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
u8 in_use
Whether this cache entry is in use.
Definition: net80211.h:536
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
void net80211_rx(struct net80211_device *dev, struct io_buffer *iob, int signal, u16 rate)
Handle receipt of 802.11 frame.
Definition: net80211.c:2689
#define DBGC(...)
Definition: compiler.h:505
An 802.11 data or management frame without QoS or WDS header fields.
Definition: ieee80211.h:300
#define NET80211_FRAG_TIMEOUT
Seconds we'll wait to get all fragments of a packet.
Definition: net80211.h:278
struct io_buffer * iob[16]
Buffers for each fragment.
Definition: net80211.h:545
u32 start_ticks
Timestamp from point at which first fragment was collected.
Definition: net80211.h:542
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
uint32_t hdr
Message header.
Definition: intelvf.h:12
static void net80211_free_frags(struct net80211_device *dev, int fcid)
Free buffers used by 802.11 fragment cache entry.
Definition: net80211.c:2533
#define IEEE80211_FC_MORE_FRAG
802.11 Frame Control field: More Fragments flag
Definition: ieee80211.h:240
#define IEEE80211_FRAG(seq)
Extract fragment number from 802.11 Sequence Control field.
Definition: ieee80211.h:283
#define IEEE80211_SEQNR(seq)
Extract sequence number from 802.11 Sequence Control field.
Definition: ieee80211.h:280
static struct io_buffer * net80211_accum_frags(struct net80211_device *dev, int fcid, int nfrags, int size)
Accumulate 802.11 fragments into one I/O buffer.
Definition: net80211.c:2561
void * data
Start of data.
Definition: iobuf.h:44
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
void timeout(int)
u16 seqnr
Sequence number of this MSDU (packet)
Definition: net80211.h:539
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define NET80211_NR_CONCURRENT_FRAGS
The number of fragments we can receive at once.
Definition: net80211.h:284
uint32_t u32
Definition: stdint.h:23
A persistent I/O buffer.
Definition: iobuf.h:32

References currticks(), io_buffer::data, DBGC, net80211_device::frags, free_iob(), hdr, IEEE80211_FC_MORE_FRAG, IEEE80211_FRAG, IEEE80211_SEQNR, net80211_frag_cache::in_use, net80211_frag_cache::iob, iob_len(), net80211_accum_frags(), NET80211_FRAG_TIMEOUT, net80211_free_frags(), NET80211_NR_CONCURRENT_FRAGS, net80211_rx(), NULL, net80211_frag_cache::seqnr, size, net80211_frag_cache::start_ticks, TICKS_PER_SEC, and timeout().

Referenced by net80211_rx().