2 * RTL8188EU monitor interface
4 * Copyright (C) 2015 Jakub Sitnicki
6 * This program is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License version 2 as published by the
8 * Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 #include <linux/ieee80211.h>
17 #include <linux/netdevice.h>
18 #include <net/cfg80211.h>
20 #include <drv_types.h>
26 * unprotect_frame() - unset Protected flag and strip off IV and ICV/MIC
28 static void unprotect_frame(struct sk_buff
*skb
, int iv_len
, int icv_len
)
30 struct ieee80211_hdr
*hdr
;
33 hdr
= (struct ieee80211_hdr
*)skb
->data
;
34 hdr_len
= ieee80211_hdrlen(hdr
->frame_control
);
36 if (skb
->len
< hdr_len
+ iv_len
+ icv_len
)
38 if (!ieee80211_has_protected(hdr
->frame_control
))
41 hdr
->frame_control
&= ~cpu_to_le16(IEEE80211_FCTL_PROTECTED
);
43 memmove(skb
->data
+ iv_len
, skb
->data
, hdr_len
);
44 skb_pull(skb
, iv_len
);
45 skb_trim(skb
, skb
->len
- icv_len
);
48 static void mon_recv_decrypted(struct net_device
*dev
, const u8
*data
,
49 int data_len
, int iv_len
, int icv_len
)
53 skb
= netdev_alloc_skb(dev
, data_len
);
56 memcpy(skb_put(skb
, data_len
), data
, data_len
);
59 * Frame data is not encrypted. Strip off protection so
60 * userspace doesn't think that it is.
62 unprotect_frame(skb
, iv_len
, icv_len
);
64 skb
->ip_summed
= CHECKSUM_UNNECESSARY
;
65 skb
->protocol
= eth_type_trans(skb
, dev
);
69 static void mon_recv_encrypted(struct net_device
*dev
, const u8
*data
,
73 netdev_info(dev
, "Encrypted packets are not supported");
77 * rtl88eu_mon_recv_hook() - forward received frame to the monitor interface
79 * Assumes that the frame contains an IV and an ICV/MIC, and that
80 * encrypt field in frame->attrib have been set accordingly.
82 void rtl88eu_mon_recv_hook(struct net_device
*dev
, struct recv_frame
*frame
)
84 struct rx_pkt_attrib
*attr
;
91 if (!netif_running(dev
))
94 attr
= &frame
->attrib
;
95 data
= frame
->pkt
->data
;
96 data_len
= frame
->pkt
->len
;
98 /* Broadcast and multicast frames don't have attr->{iv,icv}_len set */
99 SET_ICE_IV_LEN(iv_len
, icv_len
, attr
->encrypt
);
101 if (attr
->bdecrypted
)
102 mon_recv_decrypted(dev
, data
, data_len
, iv_len
, icv_len
);
104 mon_recv_encrypted(dev
, data
, data_len
);
108 * rtl88eu_mon_xmit_hook() - forward trasmitted frame to the monitor interface
111 * - frame header contains an IV and frame->attrib.iv_len is set accordingly,
112 * - data is not encrypted and ICV/MIC has not been appended yet.
114 void rtl88eu_mon_xmit_hook(struct net_device
*dev
, struct xmit_frame
*frame
,
117 struct pkt_attrib
*attr
;
123 if (!netif_running(dev
))
126 attr
= &frame
->attrib
;
128 offset
= TXDESC_SIZE
+ frame
->pkt_offset
* PACKET_OFFSET_SZ
;
129 data
= frame
->buf_addr
+ offset
;
131 for (i
= 0; i
< attr
->nr_frags
- 1; i
++) {
132 mon_recv_decrypted(dev
, data
, frag_len
, attr
->iv_len
, 0);
134 data
= (u8
*)round_up((size_t)data
, 4);
136 /* Last fragment has different length */
137 mon_recv_decrypted(dev
, data
, attr
->last_txcmdsz
, attr
->iv_len
, 0);
140 static netdev_tx_t
mon_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
146 static const struct net_device_ops mon_netdev_ops
= {
147 .ndo_start_xmit
= mon_xmit
,
148 .ndo_set_mac_address
= eth_mac_addr
,
149 .ndo_validate_addr
= eth_validate_addr
,
152 static void mon_setup(struct net_device
*dev
)
154 dev
->netdev_ops
= &mon_netdev_ops
;
155 dev
->destructor
= free_netdev
;
157 dev
->priv_flags
|= IFF_NO_QUEUE
;
158 dev
->type
= ARPHRD_IEEE80211
;
160 * Use a locally administered address (IEEE 802)
161 * XXX: Copied from mac80211_hwsim driver. Revisit.
163 eth_zero_addr(dev
->dev_addr
);
164 dev
->dev_addr
[0] = 0x12;
167 struct net_device
*rtl88eu_mon_init(void)
169 struct net_device
*dev
;
172 dev
= alloc_netdev(0, "mon%d", NET_NAME_UNKNOWN
, mon_setup
);
176 err
= register_netdev(dev
);
188 void rtl88eu_mon_deinit(struct net_device
*dev
)
193 unregister_netdev(dev
);