iPXE
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.
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.
static void net80211_rx_frag (struct net80211_device *dev, struct io_buffer *iob, int signal)
 Handle receipt of 802.11 fragment.

Detailed Description

Function Documentation

◆ net80211_free_frags()

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}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
struct net80211_frag_cache frags[NET80211_NR_CONCURRENT_FRAGS]
Fragment reassembly state.
Definition net80211.h:994
Structure tracking received fragments for a packet.
Definition net80211.h:534
u32 start_ticks
Timestamp from point at which first fragment was collected.
Definition net80211.h:542
u8 in_use
Whether this cache entry is in use.
Definition net80211.h:536
u16 seqnr
Sequence number of this MSDU (packet)
Definition net80211.h:539
struct io_buffer * iob[16]
Buffers for each fragment.
Definition net80211.h:545

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

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;
2586
2587 return niob;
2588}
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
ring len
Length.
Definition dwmac.h:226
#define IEEE80211_FC_MORE_FRAG
802.11 Frame Control field: More Fragments flag
Definition ieee80211.h:240
#define IEEE80211_TYP_FRAME_HEADER_LEN
Frame header length for frames we might work with.
Definition ieee80211.h:60
uint16_t size
Buffer size.
Definition dwmac.h:3
void * memcpy(void *dest, const void *src, size_t len) __nonnull
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
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
An 802.11 data or management frame without QoS or WDS header fields.
Definition ieee80211.h:301
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53

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

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}
void timeout(int)
#define DBGC(...)
Definition compiler.h:505
#define IEEE80211_SEQNR(seq)
Extract sequence number from 802.11 Sequence Control field.
Definition ieee80211.h:280
#define IEEE80211_FRAG(seq)
Extract fragment number from 802.11 Sequence Control field.
Definition ieee80211.h:283
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
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
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 TICKS_PER_SEC
Number of ticks per second.
Definition timer.h:16
#define NET80211_NR_CONCURRENT_FRAGS
The number of fragments we can receive at once.
Definition net80211.h:284
#define NET80211_FRAG_TIMEOUT
Seconds we'll wait to get all fragments of a packet.
Definition net80211.h:278
unsigned long currticks(void)
Get current system time in ticks.
Definition timer.c:43
#define u32
Definition vga.h:21

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, timeout(), and u32.

Referenced by net80211_rx().