1 // SPDX-License-Identifier: GPL-2.0
3 * RTL8188EU monitor interface
5 * Copyright (C) 2015 Jakub Sitnicki
8 #include <linux/ieee80211.h>
9 #include <linux/netdevice.h>
10 #include <net/cfg80211.h>
12 #include <drv_types.h>
18 * unprotect_frame() - unset Protected flag and strip off IV and ICV/MIC
20 static void unprotect_frame(struct sk_buff *skb, int iv_len, int icv_len)
22 struct ieee80211_hdr *hdr;
25 hdr = (struct ieee80211_hdr *)skb->data;
26 hdr_len = ieee80211_hdrlen(hdr->frame_control);
28 if (skb->len < hdr_len + iv_len + icv_len)
30 if (!ieee80211_has_protected(hdr->frame_control))
33 hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_PROTECTED);
35 memmove(skb->data + iv_len, skb->data, hdr_len);
36 skb_pull(skb, iv_len);
37 skb_trim(skb, skb->len - icv_len);
40 static void mon_recv_decrypted(struct net_device *dev, const u8 *data,
41 int data_len, int iv_len, int icv_len)
45 skb = netdev_alloc_skb(dev, data_len);
48 skb_put_data(skb, data, data_len);
51 * Frame data is not encrypted. Strip off protection so
52 * userspace doesn't think that it is.
54 unprotect_frame(skb, iv_len, icv_len);
56 skb->ip_summed = CHECKSUM_UNNECESSARY;
57 skb->protocol = eth_type_trans(skb, dev);
61 static void mon_recv_encrypted(struct net_device *dev, const u8 *data,
65 netdev_info(dev, "Encrypted packets are not supported");
69 * rtl88eu_mon_recv_hook() - forward received frame to the monitor interface
71 * Assumes that the frame contains an IV and an ICV/MIC, and that
72 * encrypt field in frame->attrib have been set accordingly.
74 void rtl88eu_mon_recv_hook(struct net_device *dev, struct recv_frame *frame)
76 struct rx_pkt_attrib *attr;
83 if (!netif_running(dev))
86 attr = &frame->attrib;
87 data = frame->pkt->data;
88 data_len = frame->pkt->len;
90 /* Broadcast and multicast frames don't have attr->{iv,icv}_len set */
91 SET_ICE_IV_LEN(iv_len, icv_len, attr->encrypt);
94 mon_recv_decrypted(dev, data, data_len, iv_len, icv_len);
96 mon_recv_encrypted(dev, data, data_len);
100 * rtl88eu_mon_xmit_hook() - forward trasmitted frame to the monitor interface
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.
106 void rtl88eu_mon_xmit_hook(struct net_device *dev, struct xmit_frame *frame,
109 struct pkt_attrib *attr;
115 if (!netif_running(dev))
118 attr = &frame->attrib;
120 offset = TXDESC_SIZE + frame->pkt_offset * PACKET_OFFSET_SZ;
121 data = frame->buf_addr + offset;
123 for (i = 0; i < attr->nr_frags - 1; i++) {
124 mon_recv_decrypted(dev, data, frag_len, attr->iv_len, 0);
126 data = (u8 *)round_up((size_t)data, 4);
128 /* Last fragment has different length */
129 mon_recv_decrypted(dev, data, attr->last_txcmdsz, attr->iv_len, 0);
132 static netdev_tx_t mon_xmit(struct sk_buff *skb, struct net_device *dev)
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,
144 static void mon_setup(struct net_device *dev)
146 dev->netdev_ops = &mon_netdev_ops;
147 dev->needs_free_netdev = true;
149 dev->priv_flags |= IFF_NO_QUEUE;
150 dev->type = ARPHRD_IEEE80211;
152 * Use a locally administered address (IEEE 802)
153 * XXX: Copied from mac80211_hwsim driver. Revisit.
155 eth_zero_addr(dev->dev_addr);
156 dev->dev_addr[0] = 0x12;
159 struct net_device *rtl88eu_mon_init(void)
161 struct net_device *dev;
164 dev = alloc_netdev(0, "mon%d", NET_NAME_UNKNOWN, mon_setup);
168 err = register_netdev(dev);
180 void rtl88eu_mon_deinit(struct net_device *dev)
185 unregister_netdev(dev);