Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ad hoc network #70

Merged
merged 1 commit into from
Jul 14, 2024
Merged

Support ad hoc network #70

merged 1 commit into from
Jul 14, 2024

Conversation

jychen0611
Copy link
Collaborator

@jychen0611 jychen0611 commented Jun 10, 2024

In this update, an ad-hoc (IBSS) mode has been added. Users can switch their device to IBSS mode using the following command : iw dev [interface] set type ibss

To join a specific IBSS cell and configure other settings, users can use the command :

iw dev [interface] ibss join [SSID] [freq in MHz] [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz] [fixed-freq] [] [beacon-interval ]
[basic-rates <rate in Mbps,rate2,…>] [mcast-rate ] [key d:0:abcde]

eg.
iw dev vw3 ibss join Elian 2412 NOHT fixed-freq 00:76:77:33:00:00 beacon-interval 200
This command signifies that the device vw3 will either join an existing Ad-Hoc network named Elian or create one if it doesn't exist. The device will use the 2412 MHz frequency, not utilize High Throughput mode (802.11n), and maintain a fixed frequency without changes due to other devices. The BSSID (Basic Service Set Identifier) for the IBSS will be set as 00:76:77:33:00:00, and the beacon interval, which is the time between two consecutive beacons, will be set to 200 Time Units (TUs).

To leave the current Ad-Hoc network, users can use command : iw dev [interface] ibss leave

Additionally, ad-hoc related test items have been added, and the IBSS devices are scannable.

ping test

$ sudo ip netns exec ns3 ping -c 1 10.0.0.5    
================================================================================
Ping Test: IBSS vw3 (10.0.0.4) (in Elian) <--> IBSS vw4 (10.0.0.5) (in Elian)

(should success)
(be patient, it will take some time to route...)
================================================================================
PING 10.0.0.5 (10.0.0.5) 56(84) bytes of data.
64 bytes from 10.0.0.5: icmp_seq=1 ttl=64 time=0.098 ms

--- 10.0.0.5 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.098/0.098/0.098/0.000 ms
$ sudo ip netns exec ns3 ping -c 1 10.0.0.6
================================================================================
Ping Test: IBSS vw3 (10.0.0.4) (in Elian) <--> IBSS vw5 (10.0.0.6) (in Ricky)

(should fail)
(be patient, it will take some time to route...)
================================================================================
PING 10.0.0.6 (10.0.0.6) 56(84) bytes of data.
From 10.0.0.4 icmp_seq=1 Destination Host Unreachable

--- 10.0.0.6 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
$ sudo ip netns exec ns3 ping -c 1 10.0.0.3
================================================================================
Ping Test: IBSS vw3 (10.0.0.4) (in Elian) <--> STA vw2 (10.0.0.3)

(should fail)
(be patient, it will take some time to route...)
================================================================================
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
From 10.0.0.4 icmp_seq=1 Destination Host Unreachable

--- 10.0.0.3 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

scan result

BSS 00:76:77:30:00:00(on vw1)
	TSF: 4320753904 usec (0d, 01:12:00)
	freq: 2437
	beacon interval: 100 TUs
	capability: ESS Privacy (0x0011)
	signal: -43.00 dBm
	last seen: 0 ms ago
	SSID: test
	Supported rates: 1.0* 2.0* 5.5 11.0 
	DS Parameter set: channel 6
	RSN:	 * Version: 1
		 * Group cipher: CCMP
		 * Pairwise ciphers: CCMP
		 * Authentication suites: PSK
		 * Capabilities: 1-PTKSA-RC 1-GTKSA-RC (0x0000)
	Extended capabilities:
		 * SSID List
BSS 00:76:77:33:00:00(on vw1)
	TSF: 4320753917 usec (0d, 01:12:00)
	freq: 2412
	beacon interval: 200 TUs
	capability: IBSS (0x0002)
	signal: -45.00 dBm
	last seen: 0 ms ago
BSS 00:76:77:35:00:00(on vw1)
	TSF: 4320753921 usec (0d, 01:12:00)
	freq: 2412
	beacon interval: 300 TUs
	capability: IBSS (0x0002)
	signal: -45.00 dBm
	last seen: 0 ms ago


kernel messages

[ 4320.753585] vwifi: vw1 performs scan, found vw0 (SSID: test, BSSID: 00:76:77:30:00:00)
[ 4320.753594] cap = 17, beacon_ie_len = 43
[ 4320.753601] vwifi: vw1 performs scan, found vw3 (SSID: elian, BSSID: 00:76:77:33:00:00)
[ 4320.753604] cap = 2, beacon_ie_len = 0
[ 4320.753607] vwifi: vw1 performs scan, found vw4 (SSID: elian, BSSID: 00:76:77:33:00:00)
[ 4320.753609] cap = 2, beacon_ie_len = 0
[ 4320.753611] vwifi: vw1 performs scan, found vw5 (SSID: ricky, BSSID: 00:76:77:35:00:00)
[ 4320.753612] cap = 2, beacon_ie_len = 0

vwifi.c Outdated Show resolved Hide resolved
scripts/verify.sh Outdated Show resolved Hide resolved
Copy link
Collaborator

@rickywu0421 rickywu0421 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest that the commit message should contain what you have done (e.g. implement cfg80211_ops->join_ibss()) rather than the tutorial on how to setup the environment. However, the tutorial can be moved to README.md.

vwifi.c Outdated Show resolved Hide resolved
Comment on lines +965 to +976
/* Don't send packet to device with different SSID. */
if (strcmp(vif->ssid, dest_vif->ssid))
continue;
/* Don't send packet to device with different BSSID. */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: move the packet filtering part on netif_rx(). Receivers with promiscuous mode on should expose the packets to kernel (via BPF) even if the packets are not for itself.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean that I should rewrite netif_rx() separately, or perform packet filtering in vwifi_rx()?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MAC address here refers to the MAC address of the IBSS network itself, rather than the MAC address of any individual device within the IBSS network.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mistakenly wrote the netif_rx() rather than vwifi_rx(). It should be vwifi_rx().

The MAC address here refers to the MAC address of the IBSS network itself, rather than the MAC address of any individual device within the IBSS network.

What I mention is both for the randomized IBSS MAC address and the receiver's MAC address. A wireless interface in promiscuous mode should let the sniffer see all the frames in the wireless medium.

But we should defer the implementation of RX filtering to the next PR.

Comment on lines +983 to +994
/* Don't send packet to device with different SSID. */
if (strcmp(vif->ssid, dest_vif->ssid))
continue;
/* Don't send packet to device with different BSSID. */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: move the packet filtering part on netif_rx(). Receivers with promiscuous mode on should expose the packets to kernel (via BPF) even if the packets are not for itself.

The same.

@rickywu0421
Copy link
Collaborator

rickywu0421 commented Jun 12, 2024

Have you tried vwifi with WPA/RSN support in IBSS mode?

@jserv jserv changed the title Support AD-HOC mode Support ad hoc network Jun 13, 2024
@jserv jserv requested a review from rickywu0421 June 15, 2024 03:45
@jychen0611
Copy link
Collaborator Author

jychen0611 commented Jun 15, 2024

Have you tried vwifi with WPA/RSN support in IBSS mode?

I tried using the following file, and it worked.

network={
    ssid="ibss1"
    mode=1
    frequency=2412
    key_mgmt=WPA-PSK
    proto=RSN
    pairwise=CCMP
    group=CCMP
    psk="12345678"
}

Test Scenario 1

Using the command wpa_supplicant, configure vw3 and vw4 to join ibss1:

$ wpa_supplicant -i vw3 -B -c scripts/wpa_supplicant_ibss.conf    

Successfully initialized wpa_supplicant

$ wpa_supplicant -i vw4 -B -c scripts/wpa_supplicant_ibss.conf    

Successfully initialized wpa_supplicant

Observing the interface information confirms both successfully joined ibss1:

Interface vw3
	ifindex 12
	wdev 0x900000001
	addr 00:76:77:33:00:00
	ssid ibss1
	type IBSS
	wiphy 9
	txpower 14.00 dBm
Interface vw4
	ifindex 13
	wdev 0xa00000001
	addr 00:76:77:34:00:00
	ssid ibss1
	type IBSS
	wiphy 10
	txpower 15.00 dBm

The kernel messages shows that initially ibss1 did not exist, so vw3 created it. vw4, through scanning, discovered the existence of ibss1 and joined it:

[  205.578356] vwifi : vw3 start acting in IBSS mode.
[  205.578720] vwifi : vw3 join ibss1.
[  205.639498] vwifi: vw4 performs scan, found vw3 (SSID: ibss1, BSSID: 00:00:00:00:00:00)
[  205.639506] cap = 18, beacon_ie_len = 35
[  205.640141] vwifi : vw4 start acting in IBSS mode.
[  205.640475] vwifi : vw4 join ibss1.

It's noteworthy that when creating an IBSS network with WPA, the BSSID is automatically generated by the system. This ensures each IBSS network is unique.

Attempting to ping from vw3 to vw4 results in successful packet delivery:

$ sudo ip netns exec ns3 ping -c 1 10.0.0.5
================================================================================
Ping Test: IBSS vw3 (10.0.0.4) (in ibss1) <--> IBSS vw4 (10.0.0.5) (in ibss1)

(should success)
(be patient, it will take some time to route...)
================================================================================
PING 10.0.0.5 (10.0.0.5) 56(84) bytes of data.
64 bytes from 10.0.0.5: icmp_seq=1 ttl=64 time=1031 ms

--- 10.0.0.5 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1031.052/1031.052/1031.052/0.000 ms

Test Scenario 2

vw5 manually creates and joins ibss2, while vw3 and vw4 join ibss1 using WPA:

sudo ip netns exec ns5 iw dev vw5 set type ibss
$ sudo ip netns exec ns5 iw dev vw5 ibss join ibss2 2412 NOHT fixed-freq 00:76:77:35:00:00 beacon-interval 300 

$ sudo ip netns exec ns3 ip addr add 10.0.0.4/24 dev vw3
$ sudo ip netns exec ns4 ip addr add 10.0.0.5/24 dev vw4
$ sudo ip netns exec ns5 ip addr add 10.0.0.6/24 dev vw5
    
$ sudo ip netns exec ns3 wpa_supplicant -i vw3 -B -c scripts/wpa_supplicant_ibss.conf
$ sudo ip netns exec ns4 wpa_supplicant -i vw4 -B -c scripts/wpa_supplicant_ibss.conf

Observing kernel messages shows that vw5 initially creates ibss2, so when vw3 attempts to join using WPA, it scans and finds ibss2 but creates ibss1 instead. vw4, upon scanning, discovers both ibss1 and ibss2, and chooses to join ibss1:

[  961.600176] vwifi : vw5 start acting in IBSS mode.
[  961.613599] vwifi : vw5 join ibss2.
[  962.020891] vwifi: vw3 performs scan, found vw5 (SSID: ibss2, BSSID: 00:76:77:35:00:00)
[  962.020897] cap = 2, beacon_ie_len = 0
[  962.021099] vwifi : vw3 start acting in IBSS mode.
[  962.021256] vwifi : vw3 join ibss1.
[  962.159989] vwifi: vw4 performs scan, found vw5 (SSID: ibss2, BSSID: 00:76:77:35:00:00)
[  962.159998] cap = 2, beacon_ie_len = 0
[  962.160004] vwifi: vw4 performs scan, found vw3 (SSID: ibss1, BSSID: 00:00:00:00:00:00)
[  962.160006] cap = 18, beacon_ie_len = 35
[  962.160645] vwifi : vw4 start acting in IBSS mode.
[  962.160989] vwifi : vw4 join ibss1.

Attempting to ping from vw3 to vw5 fails to deliver packets:

$ sudo ip netns exec ns3 ping -c 1 10.0.0.6
================================================================================
Ping Test: IBSS vw3 (10.0.0.4) (in ibss1) <--> IBSS vw5 (10.0.0.6) (in ibss2)

(should fail)
(be patient, it will take some time to route...)
================================================================================
PING 10.0.0.6 (10.0.0.6) 56(84) bytes of data.
From 10.0.0.4 icmp_seq=1 Destination Host Unreachable

--- 10.0.0.6 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

@jychen0611
Copy link
Collaborator Author

jychen0611 commented Jun 29, 2024

I suggest that the commit message should contain what you have done (e.g. implement cfg80211_ops->join_ibss()) rather than the tutorial on how to setup the environment. However, the tutorial can be moved to README.md.

The adjustments have been completed.

@jychen0611
Copy link
Collaborator Author

The WPA-related tests and explanations have been updated.
@rickywu0421

Copy link
Contributor

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the background color of ibss.png. Either transparent or white is fine.

README.md Outdated Show resolved Hide resolved
@jserv
Copy link
Contributor

jserv commented Jul 9, 2024

I defer to @rickywu0421 for confirmation.

Comment on lines +965 to +976
/* Don't send packet to device with different SSID. */
if (strcmp(vif->ssid, dest_vif->ssid))
continue;
/* Don't send packet to device with different BSSID. */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mistakenly wrote the netif_rx() rather than vwifi_rx(). It should be vwifi_rx().

The MAC address here refers to the MAC address of the IBSS network itself, rather than the MAC address of any individual device within the IBSS network.

What I mention is both for the randomized IBSS MAC address and the receiver's MAC address. A wireless interface in promiscuous mode should let the sniffer see all the frames in the wireless medium.

But we should defer the implementation of RX filtering to the next PR.


/* It is possible to use cfg80211_inform_bss() instead. */
bss = cfg80211_inform_bss_data(
vif->wdev.wiphy, &data, CFG80211_BSS_FTYPE_UNKNOWN, ibss->bssid,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the ibss->bssid is generated by the system (randomized BSSID)? I'm writing because I didn't see the code assigning this member (if the "if condition" in vwifi:2079 fails).

Copy link
Collaborator Author

@jychen0611 jychen0611 Jul 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spot on, generating a BSSID should be implemented by the driver. Perhaps we need a global structure to manage the BSSID.

@jychen0611 jychen0611 force-pushed the ad-hoc branch 2 times, most recently from 29b0c27 to c2eb670 Compare July 13, 2024 08:00
vwifi.c Outdated
memcpy(vif->bssid, ndev->dev_addr, ETH_ALEN);
struct vwifi_vif *ibss_vif = NULL;
list_for_each_entry (ibss_vif, &vwifi->ibss_list, ibss_list) {
if (!memcmp(ibss_vif->ssid, vif->ssid, vif->ssid_len) &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should check if these two SSID's lengths are matched first. Otherwise the unexpected result might happen:
ibss_vif->ssid = "test2", vif->ssid = "test", vif->ssid_len = 4

In this update, an ad hoc (IBSS) mode has been added.

Add the 'NL80211_IFTYPE_ADHOC' interface type to wiphy, enabling
it to switch to ad hoc (IBSS) mode through the 'vwifi_change_iface'
operation.

Implement 'vwifi_join_ibss' and 'vwifi_leave_ibss' based on the
'cfg80211_ops' structure to enable IBSS devices to join a specific
IBSS cell and frequency band.

In the global structure 'vwifi_context', add 'ibss_list' to
facilitate finding IBSS devices. When a device joins, it will be
added to the 'ibss_list', and when a device leaves, it will be
removed.

Implement the IBSS mode packet forwarding mechanism.

Additionally, ad-hoc related test items have been added, and the
IBSS devices are scannable.

Update the README file to include information about IBSS mode.

Additionally, WPA support for IBSS mode has been added.
The 'wpa_supplicant_ibss.conf' is used to configure the IBSS
network. Since using WPA to construct an IBSS network results
in the BSSID being automatically generated by the system, the
'vwifi_join_ibss' function does not receive the BSSID parameter.
Thus, adopt the following method to assign its BSSID:

Search the IBSS list for a network with matching WPA settings
(compare the SSID and the frequency band). If found, use its
BSSID. If not, use the device's MAC address as the BSSID.

Check the lengths of the two SSIDs first before using 'memcmp'.
Otherwise, unexpected results might occur.
> In C99 standard : "The 'memcmp' function compares the first n
characters of the object pointed to by s1 to the first n
characters of the object pointed to by s2."
@jserv jserv merged commit 0dfa5f7 into sysprog21:main Jul 14, 2024
4 checks passed
@jserv
Copy link
Contributor

jserv commented Jul 14, 2024

Thank @jychen0611 for contributing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants