BUILD A VIRTUAL WIFI DRIVER FOR LINUX - VWIFI
By:吳恩緯 (EN-WEI WU)
Self Introduction
What is vwifi
What can vwifi do
Why not mac80211_hwsim, why vwifi
Why not mac80211_hwsim, why vwifi
Probe request /
Probe response
Why not mac80211_hwsim, why vwifi
802.11 authentication
Why not mac80211_hwsim, why vwifi
Association request /
Association response
Why not mac80211_hwsim, why vwifi
802.1X authentication
Why not mac80211_hwsim, why vwifi
Just find AP and connect to it !
Lightweight !!
Fewer code
Fewer cost
Outline
TX = transmit�RX = receive
What to implement
Implementation
DATA FRAME FLOW AND HOOKS
Data frame workflow (like Ethernet)
hooks
struct net_device
Register callbacks for net_device
static struct net_device_ops owl_ndev_ops = {
.ndo_open = owl_ndo_open,
.ndo_stop = owl_ndo_stop,
.ndo_start_xmit = owl_ndo_start_xmit,
.ndo_get_stats = owl_ndo_get_stats,
};
TX
WIRELESS STACK AND HOOKS
Different NIC category
FullMAC
SoftMAC
= MLME in hardware
= MLME in software
802.11 Management workflow
註: NL = netlink
hooks
Register callbacks for cfg80211
static struct cfg80211_ops owl_cfg_ops = {
.scan = owl_scan,
.connect = owl_connect,
.disconnect = owl_disconnect,
�.change_virtual_intf = owl_change_iface,
.start_ap = owl_start_ap,
.stop_ap = owl_stop_ap,
� .get_station = owl_get_station,
};
STA mode
AP mode
IMPLEMENTATION OF �STA MODE OPS
cfg80211 scan
static int owl_scan(struct wiphy *wiphy,
struct cfg80211_scan_request *request)
{
list_for_each_entry (ap, &owl->ap_list, ap_list) {
struct cfg80211_inform_bss data = {
.chan = /* ... */
.scan_width = NL80211_BSS_CHAN_WIDTH_20,
.signal = /* ... */
};
�u8 *ie = kmalloc(ap->ssid_len + 2, GFP_KERNEL);
ie[0] = WLAN_EID_SSID;
ie[1] = ap->ssid_len;
memcpy(ie + 2, ap->ssid, ap->ssid_len);
�bss = cfg80211_inform_bss_data(
vif->wdev.wiphy, &data, CFG80211_BSS_FTYPE_UNKNOWN, ap->bssid, tsf,
WLAN_CAPABILITY_ESS, 100, ie, ap->ssid_len + 2, GFP_KERNEL);
}
cfg80211_scan_done(vif->scan_request, &info);
}
cfg80211 connect
kernel of connection successful or not
註: vif = virtual interface
static int owl_connect(struct wiphy *wiphy,
struct net_device *dev,
struct cfg80211_connect_params *sme)
{
list_for_each_entry (ap, &owl->ap_list, ap_list) {
if (!memcmp(ap->ssid, vif->req_ssid, ap->ssid_len)) {
cfg80211_connect_result(vif->ndev, NULL,
NULL, 0, NULL, 0,
WLAN_STATUS_SUCCESS, GFP_KERNEL);
memcpy(vif->ssid, ap->ssid, ap->ssid_len);
memcpy(vif->bssid, ap->bssid, ETH_ALEN);
vif->sme_state = SME_CONNECTED;
vif->conn_time = jiffies;
vif->ap = ap;
�list_add_tail(&vif->bss_list, &ap->bss_list);
return;
}
}
}
IMPLEMENTATION OF HOSTAP MODE TX/RX
TX on AP mode (may be relay)
3. Call owl_rx() on destination vif to simulate RX interrupt
AP TX
AP RX
RX on AP mode (may need to relay)
relay
relay
Packet is for us
Packet is for us
RX on AP mode
struct sk_buff *skb, *skb1 = NULL;
PS: skb represents packet
WELCOME TO CONTRIBUTE VWIFI
TODO List