root/drivers/staging/rtl8188eu/os_dep/mon.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. unprotect_frame
  2. mon_recv_decrypted
  3. mon_recv_encrypted
  4. rtl88eu_mon_recv_hook
  5. rtl88eu_mon_xmit_hook
  6. mon_xmit
  7. mon_setup
  8. rtl88eu_mon_init
  9. rtl88eu_mon_deinit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * RTL8188EU monitor interface
   4  *
   5  * Copyright (C) 2015 Jakub Sitnicki
   6  */
   7 
   8 #include <linux/ieee80211.h>
   9 #include <linux/netdevice.h>
  10 #include <net/cfg80211.h>
  11 
  12 #include <drv_types.h>
  13 #include <rtw_recv.h>
  14 #include <rtw_xmit.h>
  15 #include <mon.h>
  16 
  17 /**
  18  * unprotect_frame() - unset Protected flag and strip off IV and ICV/MIC
  19  */
  20 static void unprotect_frame(struct sk_buff *skb, int iv_len, int icv_len)
  21 {
  22         struct ieee80211_hdr *hdr;
  23         int hdr_len;
  24 
  25         hdr = (struct ieee80211_hdr *)skb->data;
  26         hdr_len = ieee80211_hdrlen(hdr->frame_control);
  27 
  28         if (skb->len < hdr_len + iv_len + icv_len)
  29                 return;
  30         if (!ieee80211_has_protected(hdr->frame_control))
  31                 return;
  32 
  33         hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_PROTECTED);
  34 
  35         memmove(skb->data + iv_len, skb->data, hdr_len);
  36         skb_pull(skb, iv_len);
  37         skb_trim(skb, skb->len - icv_len);
  38 }
  39 
  40 static void mon_recv_decrypted(struct net_device *dev, const u8 *data,
  41                                int data_len, int iv_len, int icv_len)
  42 {
  43         struct sk_buff *skb;
  44 
  45         skb = netdev_alloc_skb(dev, data_len);
  46         if (!skb)
  47                 return;
  48         skb_put_data(skb, data, data_len);
  49 
  50         /*
  51          * Frame data is not encrypted. Strip off protection so
  52          * userspace doesn't think that it is.
  53          */
  54         unprotect_frame(skb, iv_len, icv_len);
  55 
  56         skb->ip_summed = CHECKSUM_UNNECESSARY;
  57         skb->protocol = eth_type_trans(skb, dev);
  58         netif_rx(skb);
  59 }
  60 
  61 static void mon_recv_encrypted(struct net_device *dev, const u8 *data,
  62                                int data_len)
  63 {
  64         if (net_ratelimit())
  65                 netdev_info(dev, "Encrypted packets are not supported");
  66 }
  67 
  68 /**
  69  * rtl88eu_mon_recv_hook() - forward received frame to the monitor interface
  70  *
  71  * Assumes that the frame contains an IV and an ICV/MIC, and that
  72  * encrypt field in frame->attrib have been set accordingly.
  73  */
  74 void rtl88eu_mon_recv_hook(struct net_device *dev, struct recv_frame *frame)
  75 {
  76         struct rx_pkt_attrib *attr;
  77         int iv_len, icv_len;
  78         int data_len;
  79         u8 *data;
  80 
  81         if (!dev || !frame)
  82                 return;
  83         if (!netif_running(dev))
  84                 return;
  85 
  86         attr = &frame->attrib;
  87         data = frame->pkt->data;
  88         data_len = frame->pkt->len;
  89 
  90         /* Broadcast and multicast frames don't have attr->{iv,icv}_len set */
  91         SET_ICE_IV_LEN(iv_len, icv_len, attr->encrypt);
  92 
  93         if (attr->bdecrypted)
  94                 mon_recv_decrypted(dev, data, data_len, iv_len, icv_len);
  95         else
  96                 mon_recv_encrypted(dev, data, data_len);
  97 }
  98 
  99 /**
 100  * rtl88eu_mon_xmit_hook() - forward trasmitted frame to the monitor interface
 101  *
 102  * Assumes that:
 103  * - frame header contains an IV and frame->attrib.iv_len is set accordingly,
 104  * - data is not encrypted and ICV/MIC has not been appended yet.
 105  */
 106 void rtl88eu_mon_xmit_hook(struct net_device *dev, struct xmit_frame *frame,
 107                            uint frag_len)
 108 {
 109         struct pkt_attrib *attr;
 110         u8 *data;
 111         int i, offset;
 112 
 113         if (!dev || !frame)
 114                 return;
 115         if (!netif_running(dev))
 116                 return;
 117 
 118         attr = &frame->attrib;
 119 
 120         offset = TXDESC_SIZE + frame->pkt_offset * PACKET_OFFSET_SZ;
 121         data = frame->buf_addr + offset;
 122 
 123         for (i = 0; i < attr->nr_frags - 1; i++) {
 124                 mon_recv_decrypted(dev, data, frag_len, attr->iv_len, 0);
 125                 data += frag_len;
 126                 data = (u8 *)round_up((size_t)data, 4);
 127         }
 128         /* Last fragment has different length */
 129         mon_recv_decrypted(dev, data, attr->last_txcmdsz, attr->iv_len, 0);
 130 }
 131 
 132 static netdev_tx_t mon_xmit(struct sk_buff *skb, struct net_device *dev)
 133 {
 134         dev_kfree_skb(skb);
 135         return NETDEV_TX_OK;
 136 }
 137 
 138 static const struct net_device_ops mon_netdev_ops = {
 139         .ndo_start_xmit         = mon_xmit,
 140         .ndo_set_mac_address    = eth_mac_addr,
 141         .ndo_validate_addr      = eth_validate_addr,
 142 };
 143 
 144 static void mon_setup(struct net_device *dev)
 145 {
 146         dev->netdev_ops = &mon_netdev_ops;
 147         dev->needs_free_netdev = true;
 148         ether_setup(dev);
 149         dev->priv_flags |= IFF_NO_QUEUE;
 150         dev->type = ARPHRD_IEEE80211;
 151         /*
 152          * Use a locally administered address (IEEE 802)
 153          * XXX: Copied from mac80211_hwsim driver. Revisit.
 154          */
 155         eth_zero_addr(dev->dev_addr);
 156         dev->dev_addr[0] = 0x12;
 157 }
 158 
 159 struct net_device *rtl88eu_mon_init(void)
 160 {
 161         struct net_device *dev;
 162         int err;
 163 
 164         dev = alloc_netdev(0, "mon%d", NET_NAME_UNKNOWN, mon_setup);
 165         if (!dev)
 166                 goto fail;
 167 
 168         err = register_netdev(dev);
 169         if (err < 0)
 170                 goto fail_free_dev;
 171 
 172         return dev;
 173 
 174 fail_free_dev:
 175         free_netdev(dev);
 176 fail:
 177         return NULL;
 178 }
 179 
 180 void rtl88eu_mon_deinit(struct net_device *dev)
 181 {
 182         if (!dev)
 183                 return;
 184 
 185         unregister_netdev(dev);
 186 }

/* [<][>][^][v][top][bottom][index][help] */