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

2535 {
2536  int j;
2537  struct net80211_frag_cache *frag = &dev->frags[fcid];
2538 
2539  for ( j = 0; j < 16; j++ ) {
2540  if ( frag->iob[j] ) {
2541  free_iob ( frag->iob[j] );
2542  frag->iob[j] = NULL;
2543  }
2544  }
2545 
2546  frag->seqnr = 0;
2547  frag->start_ticks = 0;
2548  frag->in_use = 0;
2549 }
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:153
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:322

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

2564 {
2565  struct net80211_frag_cache *frag = &dev->frags[fcid];
2566  int hdrsize = IEEE80211_TYP_FRAME_HEADER_LEN;
2567  int nsize = size - hdrsize * ( nfrags - 1 );
2568  int i;
2569 
2570  struct io_buffer *niob = alloc_iob ( nsize );
2571  struct ieee80211_frame *hdr;
2572 
2573  /* Add the header from the first one... */
2574  memcpy ( iob_put ( niob, hdrsize ), frag->iob[0]->data, hdrsize );
2575 
2576  /* ... and all the data from all of them. */
2577  for ( i = 0; i < nfrags; i++ ) {
2578  int len = iob_len ( frag->iob[i] ) - hdrsize;
2579  memcpy ( iob_put ( niob, len ),
2580  frag->iob[i]->data + hdrsize, len );
2581  }
2582 
2583  /* Turn off the fragment bit. */
2584  hdr = niob->data;
2585  hdr->fc &= ~IEEE80211_FC_MORE_FRAG;
2586 
2587  return niob;
2588 }
struct net80211_frag_cache frags[NET80211_NR_CONCURRENT_FRAGS]
Fragment reassembly state.
Definition: net80211.h:994
#define iob_put(iobuf, len)
Definition: iobuf.h:125
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
uint16_t size
Buffer size.
Definition: dwmac.h:14
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:131
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
ring len
Length.
Definition: dwmac.h:231
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:160
#define IEEE80211_FC_MORE_FRAG
802.11 Frame Control field: More Fragments flag
Definition: ieee80211.h:240
void * data
Start of data.
Definition: iobuf.h:53
A persistent I/O buffer.
Definition: iobuf.h:38

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

2599 {
2600  struct ieee80211_frame *hdr = iob->data;
2601  int fragnr = IEEE80211_FRAG ( hdr->seq );
2602 
2603  if ( fragnr == 0 && ( hdr->fc & IEEE80211_FC_MORE_FRAG ) ) {
2604  /* start a frag cache entry */
2605  int i, newest = -1;
2606  u32 curr_ticks = currticks(), newest_ticks = 0;
2608 
2609  for ( i = 0; i < NET80211_NR_CONCURRENT_FRAGS; i++ ) {
2610  if ( dev->frags[i].in_use == 0 )
2611  break;
2612 
2613  if ( dev->frags[i].start_ticks + timeout >=
2614  curr_ticks ) {
2615  net80211_free_frags ( dev, i );
2616  break;
2617  }
2618 
2619  if ( dev->frags[i].start_ticks > newest_ticks ) {
2620  newest = i;
2621  newest_ticks = dev->frags[i].start_ticks;
2622  }
2623  }
2624 
2625  /* If we're being sent more concurrent fragmented
2626  packets than we can handle, drop the newest so the
2627  older ones have time to complete. */
2628  if ( i == NET80211_NR_CONCURRENT_FRAGS ) {
2629  i = newest;
2630  net80211_free_frags ( dev, i );
2631  }
2632 
2633  dev->frags[i].in_use = 1;
2634  dev->frags[i].seqnr = IEEE80211_SEQNR ( hdr->seq );
2635  dev->frags[i].start_ticks = currticks();
2636  dev->frags[i].iob[0] = iob;
2637  return;
2638  } else {
2639  int i;
2640  for ( i = 0; i < NET80211_NR_CONCURRENT_FRAGS; i++ ) {
2641  if ( dev->frags[i].in_use && dev->frags[i].seqnr ==
2642  IEEE80211_SEQNR ( hdr->seq ) )
2643  break;
2644  }
2645  if ( i == NET80211_NR_CONCURRENT_FRAGS ) {
2646  /* Drop non-first not-in-cache fragments */
2647  DBGC ( dev, "802.11 %p dropped fragment fc=%04x "
2648  "seq=%04x\n", dev, hdr->fc, hdr->seq );
2649  free_iob ( iob );
2650  return;
2651  }
2652 
2653  dev->frags[i].iob[fragnr] = iob;
2654 
2655  if ( ! ( hdr->fc & IEEE80211_FC_MORE_FRAG ) ) {
2656  int j, size = 0;
2657  for ( j = 0; j < fragnr; j++ ) {
2658  size += iob_len ( dev->frags[i].iob[j] );
2659  if ( dev->frags[i].iob[j] == NULL )
2660  break;
2661  }
2662  if ( j == fragnr ) {
2663  /* We've got everything */
2664  struct io_buffer *niob =
2665  net80211_accum_frags ( dev, i, fragnr,
2666  size );
2667  net80211_free_frags ( dev, i );
2668  net80211_rx ( dev, niob, signal, 0 );
2669  } else {
2670  DBGC ( dev, "802.11 %p dropping fragmented "
2671  "packet due to out-of-order arrival, "
2672  "fc=%04x seq=%04x\n", dev, hdr->fc,
2673  hdr->seq );
2674  net80211_free_frags ( dev, i );
2675  }
2676  }
2677  }
2678 }
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:16
u8 in_use
Whether this cache entry is in use.
Definition: net80211.h:536
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:153
void net80211_rx(struct net80211_device *dev, struct io_buffer *iob, int signal, u16 rate)
Handle receipt of 802.11 frame.
Definition: net80211.c:2690
uint16_t size
Buffer size.
Definition: dwmac.h:14
#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:160
static void net80211_free_frags(struct net80211_device *dev, int fcid)
Free buffers used by 802.11 fragment cache entry.
Definition: net80211.c:2534
#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:2562
void * data
Start of data.
Definition: iobuf.h:53
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:43
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define NET80211_NR_CONCURRENT_FRAGS
The number of fragments we can receive at once.
Definition: net80211.h:284
uint32_t u32
Definition: stdint.h:24
A persistent I/O buffer.
Definition: iobuf.h:38

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