Skip to content

Commit

Permalink
Merge pull request #70 from jychen0611/ad-hoc
Browse files Browse the repository at this point in the history
Support ad hoc network
  • Loading branch information
jserv authored Jul 14, 2024
2 parents db7245e + a5fc5f0 commit 0dfa5f7
Show file tree
Hide file tree
Showing 6 changed files with 652 additions and 30 deletions.
231 changes: 213 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ $ pip3 install numpy matplotlib
```

## Testing environment (non-virtio)
To test the network environment effectively, we utilize **Linux network namespaces**. These namespaces isolate network environments from the host system, providing distinct instances of network stacks with independent routes, firewall rules, and network devices.

Without network namespaces, virtual interfaces created within the same namespace use the loopback device for packet transmission between them, as the kernel recognizes them as residing on the same host.

In our testing setup, all interfaces created by `vwifi` are placed within an isolated network namespace. This approach ensures that each virtual interface operates independently, facilitating comprehensive testing of networking functionalities without interference from the host's network configuration.

Below, we will conduct two separate tests: Infrastructure BSS and Independent BSS.
### Infrastructure BSS
<p align="center"><img src="assets/vwifi.png" alt="logo image" width=60%></p>

The testing environment consists of **one AP and two STAs**.
Expand All @@ -48,15 +56,12 @@ The AP then performs the following actions based on the packet type:
2. Broadcast: The AP forwards the packet to all other STAs in the network, except for the source STA, and then passes it to the protocol stack.
3. Multicast: The AP treats multicast packets the same way as broadcast packets.

To test the network environment, we can utilize the **Linux network namespace**.
Linux network namespace allows us to isolate a network environment from the host system, providing its own routes, firewall rules, and network devices.
Essentially, it creates a separate instance of the network stack.
### Independent BSS
<p align="center"><img src="assets/ibss.png" alt="logo image" width=75%></p>

Without network namespace, when virtual interfaces are created that share the same network namespace and start transmitting/receiving packets between them,
the kernel will use the loopback device for packet transmission/reception. This behavior occurs because the kernel identifies that the sender and receiver are on the same host.

In conclusion, all the interfaces created by `vwifi` in the testing environment will be added to an isolated network namespace.
The testing environment consists of **two IBSS devices**.

The testing environment operates in IEEE 802.11 independent BSS. IBSS devices can communicate with any device in the same IBSS network **without the need to establish a connection beforehand**. However, devices in different IBSS networks cannot communicate with each other.
## Build and Run (non-virtio)

To build the kernel module, execute the following command:
Expand All @@ -72,7 +77,7 @@ $ sudo modprobe cfg80211
Insert the `vwifi` driver.
This will create three interfaces (the "station" parameter can be modified according to preference):
```shell
$ sudo insmod vwifi.ko station=3
$ sudo insmod vwifi.ko station=5
```

Please note that interfaces can only be created in station mode during the initialization phase.
Expand All @@ -85,7 +90,7 @@ To check the network interfaces, run the following command:
$ ip link
```

There should be entries starting with `vw0`, `vw1`, and `vw2`, which correspond to the interfaces created by `vwifi`.
There should be entries starting with `vw0`, `vw1`, `vw2`, `vw3`, and `vw4`, which correspond to the interfaces created by `vwifi`.

To view the available wireless interfaces, execute the following command:
```shell
Expand All @@ -94,24 +99,41 @@ $ sudo iw dev

You should see something similar to the following output:
```
phy#2
phy#5
Interface vw4
ifindex 7
wdev 0x500000001
addr 00:76:77:34:00:00
type managed
txpower 0.00 dBm
phy#4
Interface vw3
ifindex 6
wdev 0x400000001
addr 00:76:77:33:00:00
type managed
txpower 0.00 dBm
phy#3
Interface vw2
ifindex 5
wdev 0x200000001
addr 00:6f:77:6c:32:00
wdev 0x300000001
addr 00:76:77:32:00:00
type managed
phy#1
txpower 0.00 dBm
phy#2
Interface vw1
ifindex 4
wdev 0x100000001
addr 00:6f:77:6c:31:00
wdev 0x200000001
addr 00:76:77:31:00:00
type managed
phy#0
txpower 0.00 dBm
phy#1
Interface vw0
ifindex 3
wdev 0x1
addr 00:6f:77:6c:30:00
wdev 0x100000001
addr 00:76:77:30:00:00
type managed
txpower 0.00 dBm
```

As observed, each interface has its own phy (`struct wiphy`), allowing them to be placed into separate network namespaces.
Expand All @@ -125,6 +147,10 @@ $ sudo iw list

Reference output:
```
Wiphy vw_phy4
(... omit)
Wiphy vw_phy3
(... omit)
Wiphy vw_phy2
(... omit)
Wiphy vw_phy1
Expand Down Expand Up @@ -366,6 +392,175 @@ PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
4 packets transmitted, 4 received, 0% packet loss, time 3058ms
rtt min/avg/max/mdev = 0.054/0.141/0.342/0.117 ms
```
### IBSS mode

#### Creating Network Namespaces
Create three network namespaces using the following commands:
```shell
$ sudo ip netns add ns3
$ sudo ip netns add ns4
```
Find the `wiphy` name for the two interfaces.
The index number for the `wiphy` name postfix might be different each time.
Please use the following command for the ease of memorizing different index number everytime.
```shell
$ vw3_phy=$(sudo iw dev vw3 info | grep wiphy | awk '{print $2}')
$ vw3_phy=$(sudo iw list | grep "wiphy index: $vw3_phy" -B 1 | grep Wiphy | awk '{print $2}')
$ vw4_phy=$(sudo iw dev vw4 info | grep wiphy | awk '{print $2}')
$ vw4_phy=$(sudo iw list | grep "wiphy index: $vw4_phy" -B 1 | grep Wiphy | awk '{print $2}')
```
Check whether the name of each `wiphy` is the same as the name listing under the command `sudo iw list`
```shell
$ echo $vw3_phy
vw_phy3
$ echo $vw4_phy
vw_phy4
```
Assign the two interfaces to separate network namespaces.
Please note that the `wiphy` is placed within the network namespace, and the interface associated with that wiphy will be contained within it.
```shell
$ sudo iw phy vw_phy3 set netns name ns3
$ sudo iw phy vw_phy4 set netns name ns4
```
#### Assigning IP Addresses to Each Interface

Now, assign an IP address to both interfaces using the following commands:
```shell
$ 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
```
There are two methods to configure an IBSS network: manual configuration or using WPA.
#### Option1 : Manual configuration
##### Switch to IBSS mode
Switch device to IBSS mode using the following command :

***iw dev [interface] set type ibss***

The following commands switch `vw3` and `vw4` to IBSS mode.
```shell
$ sudo ip netns exec ns3 iw dev vw3 set type ibss
$ sudo ip netns exec ns4 iw dev vw4 set type ibss
```
Check the information of `vw3`.
```shell
$ sudo ip netns exec ns3 iw dev vw3 info
```
You should see output similar to the following:
```
Interface vw3
ifindex 6
wdev 0x400000001
addr 00:76:77:33:00:00
type IBSS
wiphy 4
txpower 0.00 dBm
```
##### Join IBSS network
```shell
$ sudo ip netns exec ns3 ip link set vw3 up
$ sudo ip netns exec ns4 ip link set vw4 up
```
Users can join a specific IBSS cell and configure additional settings using the command :

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

If the IBSS cell does not already exist, it will be created.

The following command makes `vw3` and `vw4` join the same IBSS cell with the SSID `ibss1` and specifies the frequency as 2412 MHz:
```shell
$ sudo ip netns exec ns3 iw dev vw3 ibss join ibss1 2412 NOHT fixed-freq 00:76:77:33:00:00 beacon-interval 200
$ sudo ip netns exec ns4 iw dev vw4 ibss join ibss1 2412 NOHT fixed-freq 00:76:77:33:00:00 beacon-interval 200
```
Check the information of `vw3`.
```shell
$ sudo ip netns exec ns3 iw dev vw3 info
```
You should see output similar to the following:
```
Interface vw3
ifindex 6
wdev 0x400000001
addr 00:76:77:33:00:00
ssid ibss1
type IBSS
wiphy 4
txpower 0.00 dBm
```
#### Option2 : Using WPA
```shell
$ sudo ip netns exec ns3 ip link set vw3 up
$ sudo ip netns exec ns4 ip link set vw4 up
```
Prepare the following script `wpa_supplicant_ibss.conf` (you can modify the script based on your needs):
```shell
network={
ssid="ibss1"
mode=1
frequency=2412
key_mgmt=WPA-PSK
proto=RSN
pairwise=CCMP
group=CCMP
psk="12345678"
}
```
Using the command **wpa_supplicant**, configure `vw3` and `vw4` to join `ibss1`.
```shell
$ 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
```
Check the information of `vw3`.
```shell
$ sudo ip netns exec ns3 iw dev vw3 info
```
You should see output similar to the following:
```
Interface vw3
ifindex 6
wdev 0x400000001
addr 00:76:77:33:00:00
ssid ibss1
type IBSS
wiphy 4
txpower 0.00 dBm
```
#### Transmission/Receivement test
To perform a ping test between two IBSS devices (`vw3` and `vw4`) in the same ibss cell (`ibss1`), use the following command:
```shell
$ sudo ip netns exec ns3 ping -c 1 10.0.0.5
```
You should see output similar to the following:
```
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.093 ms
--- 10.0.0.5 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.093/0.093/0.093/0.000 ms
```
#### Leave IBSS network
To leave the current IBSS cell, use ***iw dev [interface] ibss leave***.

The following command makes `vw3` and `vw4` leave `ibss1`:
```shell
$ sudo ip netns exec ns3 iw dev vw3 ibss leave
$ sudo ip netns exec ns4 iw dev vw4 ibss leave
```
Check the information of `vw3`.
```shell
$ sudo ip netns exec ns3 iw dev vw3 info
```
You should see output similar to the following:
```
Interface vw3
ifindex 6
wdev 0x400000001
addr 00:76:77:33:00:00
type IBSS
wiphy 4
txpower 0.00 dBm
```

### vwifi-tool
A userspace tool which supports more user-specific utilization for vwifi.
Aiming to provide more flexibility and customization for users of vwifi.
Expand Down
98 changes: 98 additions & 0 deletions assets/ibss.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<mxfile host="app.diagrams.net" modified="2024-07-07T06:17:01.630Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" etag="-HEaOgMibt1UBT4tSmFY" version="24.5.4" type="device">
<diagram id="yF4yq0laEPX1mU6WioKN" name="Page-1">
<mxGraphModel dx="1715" dy="574" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" background="#FFFFFF" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="5jAbq0H1r1dMHXJugziX-10" value="" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;fillStyle=solid;gradientDirection=radial;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="-70" y="221" width="870" height="330" as="geometry" />
</mxCell>
<mxCell id="1VKriumNMIqOGRltyLQd-10" value="" style="shape=mxgraph.arrows2.wedgeArrowDashed2;html=1;bendable=0;startWidth=150;stepSize=15;rounded=0;strokeColor=#006633;elbow=vertical;sketch=1;curveFitting=1;jiggle=2;shadow=0;flowAnimation=1;fillColor=#e51400;" parent="1" edge="1">
<mxGeometry width="100" height="100" relative="1" as="geometry">
<mxPoint x="270" y="340" as="sourcePoint" />
<mxPoint x="318.1258741258739" y="311" as="targetPoint" />
<Array as="points">
<mxPoint x="430.05" y="230" />
<mxPoint x="420.05" y="190" />
<mxPoint x="279.99999999999994" y="253" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="1VKriumNMIqOGRltyLQd-3" value="" style="shape=mxgraph.arrows2.wedgeArrowDashed2;html=1;bendable=0;startWidth=150;stepSize=15;rounded=0;strokeColor=#006633;elbow=vertical;sketch=1;curveFitting=1;jiggle=2;shadow=0;flowAnimation=1;entryX=0.75;entryY=1;entryDx=0;entryDy=0;fillColor=#e51400;" parent="1" edge="1">
<mxGeometry width="100" height="100" relative="1" as="geometry">
<mxPoint x="470" y="280" as="sourcePoint" />
<mxPoint x="432.5" y="306" as="targetPoint" />
<Array as="points">
<mxPoint x="638.61" y="177" />
<mxPoint x="628.61" y="137" />
<mxPoint x="488.55999999999995" y="200" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="RjUjesMydYoAQQ34KLtV-6" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#000000;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="80" y="340" width="170" height="80" as="geometry" />
</mxCell>
<mxCell id="RjUjesMydYoAQQ34KLtV-7" value="&lt;font color=&quot;#ffffff&quot;&gt;netns: ns3&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=18;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="110" y="343" width="110" height="30" as="geometry" />
</mxCell>
<mxCell id="RjUjesMydYoAQQ34KLtV-9" value="vw3&lt;div&gt;(IBSS mode)&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=18;fillColor=#006633;strokeColor=#006633;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="105" y="400" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="RjUjesMydYoAQQ34KLtV-10" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#000000;fontColor=#ffffff;strokeColor=#006EAF;" parent="1" vertex="1">
<mxGeometry x="505" y="340" width="170" height="80" as="geometry" />
</mxCell>
<mxCell id="RjUjesMydYoAQQ34KLtV-11" value="&lt;font color=&quot;#ffffff&quot;&gt;netns: ns4&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=18;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="535" y="343" width="110" height="30" as="geometry" />
</mxCell>
<mxCell id="RjUjesMydYoAQQ34KLtV-13" value="vw4&lt;br&gt;(IBSS mode)" style="rounded=1;whiteSpace=wrap;html=1;fontSize=18;fillColor=#006633;strokeColor=#006633;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="530" y="400" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="RjUjesMydYoAQQ34KLtV-22" value="&lt;font color=&quot;#ffffff&quot;&gt;IP address: 10.0.0.4&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;" parent="1" vertex="1">
<mxGeometry x="92" y="371" width="150" height="30" as="geometry" />
</mxCell>
<mxCell id="RjUjesMydYoAQQ34KLtV-24" value="&lt;font color=&quot;#ffffff&quot;&gt;IP address: 10.0.0.5&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;" parent="1" vertex="1">
<mxGeometry x="515" y="368" width="150" height="30" as="geometry" />
</mxCell>
<mxCell id="5jAbq0H1r1dMHXJugziX-4" value="" style="endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.75;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;dashed=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="529" y="425" as="sourcePoint" />
<mxPoint x="224" y="425" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="5jAbq0H1r1dMHXJugziX-5" value="ARP Reply" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" parent="5jAbq0H1r1dMHXJugziX-4" connectable="0" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="5jAbq0H1r1dMHXJugziX-6" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;dashed=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="225" y="438.5" as="sourcePoint" />
<mxPoint x="530" y="438.5" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="5jAbq0H1r1dMHXJugziX-7" value="Ping Request" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" parent="5jAbq0H1r1dMHXJugziX-6" connectable="0" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="5jAbq0H1r1dMHXJugziX-8" value="" style="endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.75;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;dashed=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="528" y="453" as="sourcePoint" />
<mxPoint x="223" y="453" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="5jAbq0H1r1dMHXJugziX-9" value="Ping Reply" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" parent="5jAbq0H1r1dMHXJugziX-8" connectable="0" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="5jAbq0H1r1dMHXJugziX-11" value="&lt;font style=&quot;font-size: 26px;&quot;&gt;ad hoc network&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=18;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="310" y="299" width="130" height="27" as="geometry" />
</mxCell>
<mxCell id="1VKriumNMIqOGRltyLQd-8" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;dashed=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="226" y="409.5" as="sourcePoint" />
<mxPoint x="531" y="409.5" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="1VKriumNMIqOGRltyLQd-9" value="ARP Request" style="edgeLabel;resizable=0;html=1;;align=center;verticalAlign=middle;" parent="1VKriumNMIqOGRltyLQd-8" connectable="0" vertex="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
Binary file added assets/ibss.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 0dfa5f7

Please sign in to comment.