Merge branch 'wifi-ap'

This commit is contained in:
Pranav Jerry 2021-06-15 14:28:08 +05:30
commit 55a54440f7
No known key found for this signature in database
GPG Key ID: F1DCDC4FED0A0C5B
3 changed files with 116 additions and 83 deletions

View File

@ -15,20 +15,20 @@ West Bengal.
<!-- UNCOMMENT WHEN NECESSARY
**Disclaimer**:
In case you are either 1) a complete idiot; or 2) a member of parliament;
or 3) both, please be aware that this project is not affiliated with
any groups designated as "terrorist" groups in India.
In case you are either 1) a complete idiot; or 2) a member of the saffron
brigade; or 3) both, please be aware that this project is not affiliated
with any groups designated as "terrorist" groups in India.
Using the name Naxal does not imply any form of connection
with anyone the government collectively calles Urban Naxals (human rights
activists, lawyers, poets, writers, journalists or anyone else
advocating the constitutional rights).
with anyone the government of India collectively calles Urban
Naxals (human rights activists, lawyers, poets, writers, journalists
or anyone else advocating for their rights).
-->
## Requirements
- systemd v248 or more (for batman support)
- systemd{,-networkd} v248 or more (for batman support)
- Linux kernel with batman-adv module (if `modinfo batman-adv` shows
no error then you already have it)
- iwd (for starting ad-hoc network)
@ -36,17 +36,22 @@ advocating the constitutional rights).
- [python-dasbus][]
- wifi adapter with ad-hoc support
- two or more computers with wifi adapter
- systemd-resolved (optional, for DNS)
- batctl (optional, for debugging)
## Installing
### Arch Linux
Install [naxalnet-git][] from the AUR:
Install [naxalnet-git][] from the AUR with your favourite helper:
```sh
yay -S naxalnet-git
```
Optionally, [setup systemd-resolved][arch-resolved] if any of the
computers have internet access.
### Manually
Clone the repo and cd into it.
@ -61,15 +66,41 @@ without rebooting:
sudo systemctl daemon-reload
```
## Running the program
## How to use
You need more than one computer running for the connection to work.
Start the naxalnet service:
### Communicate between peers
Connect a wifi adapter to all the computers you intend to run
naxalnet.
Start the naxalnet service on all of them:
```sh
sudo systemctl start naxalnet.service
```
To test if it works, run `ip addr` to find out your address.
Note the `inet` or `inet6` address of `bridge0`. Ping the address
from another computer (example: `ping 169.254.62.90`) to find out
if it is online. Press Ctrl-C to stop.
### Getting internet access
Connect an ethernet to any of the peers and start naxalnet.
Now all the peers should be able to connect after renewing
their DHCP connection (`sudo networkctl renew bridge0`).
### Tethering via WiFi AP
Connect two wifi adapters on a device and start naxalnet.
Now an ap will be created on one of the devices with
SSID `NaxalNet` and password `naxalnet256`.
If you had set up internet access on one of the peers, internet
can be accessed from the AP.
### Running at boot
Starting the service will stop `NetworkManager.service` and
`wpa_supplicant.service` if it is running. If you start either of these
services after naxalnet is started, systemd will stop naxalnet.
@ -125,3 +156,4 @@ This project is in alpha stage. Documentation is incomplete.
[ssb]: https://scuttlebutt.nz
[python-dasbus]: https://github.com/rhinstaller/dasbus
[naxalnet-git]: https://aur.archlinux.org/packages/naxalnet-git
[arch-resolved]: https://wiki.archlinux.org/title/Systemd-resolved#DNS

124
naxalnet
View File

@ -22,7 +22,6 @@ with systemd-networkd and iwd
import sys
import time
from pathlib import Path
from shutil import copy
from dasbus.connection import SystemMessageBus
@ -30,12 +29,13 @@ from dasbus.error import DBusError
NETWORKD_CONFIGS = "/usr/share/naxalnet/networkd"
NETWORKD_VOLATILE_DIR = "/run/systemd/network"
RESOLVED_STUB_RESOLVE = "/run/systemd/resolve/stub-resolv.conf"
RESOLV_CONF = "/etc/resolv.conf"
ADHOC_SSID = "HelloWorld"
AP_SSID = "NaxalNet"
AP_PASSWD = "naxalnet256"
# Copy networkd configs to volatile dir.
# See man:systemd.networkm(5)
# The D-Bus API does not support creating new interfaces
# or linking to bridges. So we use config files.
# See man:systemd.network(5)
try:
print("Copying network config files")
dest = Path(NETWORKD_VOLATILE_DIR)
@ -51,36 +51,6 @@ except PermissionError as error:
print(error)
sys.exit("Make sure you are root")
# Symlink resolvd.conf to systemd's stub-resolvd.conf
# This is needed for DNS resolution to work.
# see https://wiki.archlinux.org/title/Systemd-resolved#DNS
try:
print("Checking resolv.conf")
r = Path(RESOLV_CONF)
if r.is_symlink():
# Naxalnet will be started before resolved, so the destination
# is unlikely to exist at the time
# If r is linked to resolved's resolv.conf, dont change it
if r.samefile(RESOLVED_STUB_RESOLVE):
print(r, "is already linked to stub-resolv.conf. Not changing")
# Else if the destination exists
elif r.exists():
print(r, "is a symlink that exists. Not removing")
else:
print(r, "is a symlink to a destination that doesn't exist. Removing")
r.unlink()
elif r.exists():
print(r, "is not a symlink")
x = r.rename(RESOLV_CONF + ".naxalnet-bkp")
print(r, "was moved to", x)
print("Linking resolv.conf")
r.symlink_to(RESOLVED_STUB_RESOLVE)
except PermissionError as error:
print(error)
sys.exit("An error occured while linking resolv.conf")
# Now, the iwd part
try:
# connect to the System bus
@ -90,17 +60,35 @@ try:
# Get list of all devices
print("Finding connected devices")
objects = iwd.GetManagedObjects()
devices = []
for name, obj in objects.items():
# devices that support ad-hoc
adhoc_devices = []
# devices that support ap
ap_devices = []
for path, obj in objects.items():
if "net.connman.iwd.Device" in obj:
# add all devices to the list
print("Found device:", obj["net.connman.iwd.Device"]["Name"])
devices.append(name)
name = obj["net.connman.iwd.Device"]["Name"]
print("Found device", name)
adapter_path = obj["net.connman.iwd.Device"]["Adapter"].get_string()
adapter = objects[adapter_path]["net.connman.iwd.Adapter"]
if "ad-hoc" in adapter["SupportedModes"]:
print(name, "supports ad-hoc")
adhoc_devices.append(path)
if "ap" in adapter["SupportedModes"]:
print(name, "supports ap")
ap_devices.append(path)
# Start ad-hoc on first device
devpath = devices.pop()
print("Working on first device", devpath)
dev1 = bus.get_proxy("net.connman.iwd", devpath)
if len(adhoc_devices) != 0:
# Start ad-hoc on first device supporting ad-hoc
dev1path = adhoc_devices.pop()
# The same device is likely to have ap support too.
# But we can't start ad-hoc and ap on the same interface.
# Remove dev1 from ap_devices if it exists there
if dev1path in ap_devices:
ap_devices.remove(dev1path)
print("Working on ad-hoc")
dev1 = bus.get_proxy("net.connman.iwd", dev1path)
print("Starting ad-hoc on", dev1.Name)
if not dev1.Powered:
print("Device is off. Turning on")
dev1.Powered = True
@ -108,29 +96,39 @@ try:
print("Device is in", dev1.Mode)
print("Switching to ad-hoc")
dev1.Mode = "ad-hoc"
# Changing Mode requires connecting to the proxy again
dev1 = bus.get_proxy("net.connman.iwd", devpath)
# Changing Mode needs connecting to the proxy again
dev1 = bus.get_proxy("net.connman.iwd", dev1path)
# If already connected to ad-hoc, stop it
if dev1.Started is True:
print("Already connected to ad-hoc. Stopping")
dev1.Stop()
# Reconnect to proxy or StartOpen won't work
dev1 = bus.get_proxy("net.connman.iwd", dev1path)
print("Starting ad-hoc network")
dev1.StartOpen(ADHOC_SSID)
# TODO: If there is a second device, start AP
# in it
# Start Access point if ap_device is not empty,
# ie, we have more devices
if len(ap_devices) != 0:
print("Working on AP")
dev2path = ap_devices.pop()
dev2 = bus.get_proxy("net.connman.iwd", dev2path)
if not dev1.Powered:
print("Device is off. Turning on")
dev1.Powered = True
if dev2.Mode != "ap":
print(dev2.Name, "is in", dev2.Mode)
print("Switching to ap")
dev2.Mode = "ap"
dev2 = bus.get_proxy("net.connman.iwd", dev2path)
if dev2.Started is True:
print("An AP is already started on", dev2.Name)
print("Stopping")
dev2.Stop()
dev2 = bus.get_proxy("net.connman.iwd", dev2path)
print("Starting AP on", dev2.Name)
dev2.Start(AP_SSID, AP_PASSWD)
except DBusError:
sys.exit("An error occured while communicating with iwd")
# Sleep my little baby-oh
# Sleep until you waken
# When you wake you'll see the world
# If I'm not mistaken...
#
# Kiss a lover
# Dance a measure,
# Find your name
# And buried treasure...
#
# Face your life
# Its pain,
# Its pleasure,
# Leave no path untaken.
#
# -- Neil Gaiman, The Graveyard Book
print("Bye")

View File

@ -15,9 +15,12 @@ After=wpa_supplicant.service
[Service]
Type=oneshot
RemainAfterExit=yes
# Temporary (maybe permanent) fix to aborting after changing to ad-hoc
Restart=on-failure
RestartSec=5sec
# IWD takes some time to find devices.
# Without the sleep 5, naxalnet could not detect the second
# device while testing.
ExecStartPre=/usr/bin/sleep 5
ExecStart=/usr/bin/naxalnet
[Install]