802.11 link-layer protocol functions


static int net80211_ll_push (struct net_device *netdev, struct io_buffer *iobuf, const void *ll_dest, const void *ll_source, uint16_t net_proto)
 Add 802.11 link-layer header.
static int net80211_ll_pull (struct net_device *netdev, struct io_buffer *iobuf, const void **ll_dest, const void **ll_source, uint16_t *net_proto, unsigned int *flags)

Function Documentation

static int net80211_ll_push ( struct net_device netdev,
struct io_buffer iobuf,
const void *  ll_dest,
const void *  ll_source,
uint16_t  net_proto 
) [static]

Add 802.11 link-layer header.

netdevWrapping network device
iobufI/O buffer
ll_destLink-layer destination address
ll_sourceLink-layer source address
net_protoNetwork-layer protocol, in network byte order
Return values:
rcReturn status code

This adds both the 802.11 frame header and the 802.2 LLC/SNAP header used on data packets.

We also check here for state of the link that would make it invalid to send a data packet; every data packet must pass through here, and no non-data packet (e.g. management frame) should.

Definition at line 483 of file net80211.c.

References ieee80211_frame::addr1, ieee80211_frame::addr2, ieee80211_frame::addr3, net80211_device::assoc_rc, net80211_device::bssid, ieee80211_llc_snap_header::ctrl, ieee80211_llc_snap_header::dsap, ieee80211_frame::duration, ENETUNREACH, ETH_ALEN, ieee80211_llc_snap_header::ethertype, ieee80211_frame::fc, hdr, IEEE80211_FC_TODS, IEEE80211_LLC_CTRL, IEEE80211_LLC_DSAP, IEEE80211_LLC_HEADER_LEN, IEEE80211_LLC_SSAP, IEEE80211_MAKESEQ, IEEE80211_STYPE_DATA, IEEE80211_THIS_VERSION, IEEE80211_TYP_FRAME_HEADER_LEN, IEEE80211_TYPE_DATA, iob_push, net80211_device::last_tx_seqnr, memcpy(), memset(), NET80211_ASSOCIATED, net80211_duration(), net_proto, ieee80211_llc_snap_header::oui, net_device::priv, net80211_device::rate, net80211_device::rates, ieee80211_frame::seq, ieee80211_llc_snap_header::ssap, and net80211_device::state.

        struct net80211_device *dev = netdev->priv;
        struct ieee80211_frame *hdr = iob_push ( iobuf,
                                                 IEEE80211_LLC_HEADER_LEN +
                                                 IEEE80211_TYP_FRAME_HEADER_LEN );
        struct ieee80211_llc_snap_header *lhdr =
                ( void * ) hdr + IEEE80211_TYP_FRAME_HEADER_LEN;

        /* We can't send data packets if we're not associated. */
        if ( ! ( dev->state & NET80211_ASSOCIATED ) ) {
                if ( dev->assoc_rc )
                        return dev->assoc_rc;
                return -ENETUNREACH;

        hdr->fc = IEEE80211_THIS_VERSION | IEEE80211_TYPE_DATA |
            IEEE80211_STYPE_DATA | IEEE80211_FC_TODS;

        /* We don't send fragmented frames, so duration is the time
           for an SIFS + 10-byte ACK. */
        hdr->duration = net80211_duration ( dev, 10, dev->rates[dev->rate] );

        memcpy ( hdr->addr1, dev->bssid, ETH_ALEN );
        memcpy ( hdr->addr2, ll_source, ETH_ALEN );
        memcpy ( hdr->addr3, ll_dest, ETH_ALEN );

        hdr->seq = IEEE80211_MAKESEQ ( ++dev->last_tx_seqnr, 0 );

        lhdr->dsap = IEEE80211_LLC_DSAP;
        lhdr->ssap = IEEE80211_LLC_SSAP;
        lhdr->ctrl = IEEE80211_LLC_CTRL;
        memset ( lhdr->oui, 0x00, 3 );
        lhdr->ethertype = net_proto;

        return 0;
static int net80211_ll_pull ( struct net_device netdev,
struct io_buffer iobuf,
const void **  ll_dest,
const void **  ll_source,
uint16_t net_proto,
unsigned int *  flags 
) [static]