Compare commits

...

29 Commits

Author SHA1 Message Date
Pranav Jerry 5068250ad6
added link to HACKING.md in README.md 2021-07-26 16:08:36 +05:30
Pranav Jerry 19137faab3
reduced 5s delay in the systemd service to 2s 2021-07-26 15:58:50 +05:30
Pranav Jerry b3710633cc
Merge branch 'fix-rfkill'
Added rfkill support, among other things.
See pull request #10 for more info.
2021-07-26 15:47:38 +05:30
Pranav Jerry 86042b9852
uncommented IPNS address 2021-07-26 12:48:45 +05:30
Pranav Jerry 1500f486ef
added clean in Makefile 2021-07-26 12:44:24 +05:30
Pranav Jerry 9c6081ea87
added rfkill support
Updated HACKING.md and added license disclaimer to all python files.
And tidied up scripts.py
2021-07-25 14:06:17 +05:30
Pranav Jerry c8e98b2c4f
Merge branch 'python-module'
The pypackage version is ready for use by non-nerds
2021-07-23 21:43:00 +05:30
Pranav Jerry adb8c62407
Removed alpha stage disclaimer
naxalnet doesn't seem to fit into the alpha stage anymore, although it
is probably unstable according to debian standards
2021-07-23 21:39:46 +05:30
Pranav Jerry e0d2602552
Updated README.md
Removed IPFS git link and updated .gitignore
And fixed a tiny mistake in uninstalling section in README.md
2021-07-23 21:35:11 +05:30
Pranav Jerry c2fba89816
Made python package!
Finally, the python package is ready to use!
2021-07-21 15:36:11 +05:30
Pranav Jerry b2f30bad62
added AP support in naxalnet.py and iwd.py 2021-07-21 14:36:23 +05:30
Pranav Jerry af5fc0e285
Added ipns git clone url
Probably wont work properly
2021-07-19 19:02:25 +05:30
Pranav Jerry f0689016ce
ad-hoc part done
Check out naxalnet/naxalnet.py
2021-07-19 14:11:43 +05:30
Pranav Jerry b9592696f2
Fixed another typo in HACKING.md 2021-07-18 20:05:39 +05:30
Pranav Jerry 809c09afe0
Added class Adapter in iwd.py
Initial implementation. No useful public methods yet
2021-07-18 14:24:27 +05:30
Pranav Jerry 3c22fa63f4
Fixed typo in HACKING.md 2021-07-18 14:11:36 +05:30
Pranav Jerry 91be0b0189
Added main.py
This file at the moment contains debugging code.
Changed HACKING.md
2021-07-18 14:07:16 +05:30
Pranav Jerry b1d970a0f6
fixed bug in iwd.py
And fixed a typo in README.md
2021-07-17 13:34:06 +05:30
Pranav Jerry 7b7c3f0b2e
added license to iwd.py 2021-07-12 20:20:50 +05:30
Pranav Jerry 8bf05ba334
added new functions 2021-07-12 20:17:33 +05:30
Pranav Jerry 0e7a69be53
Updated HACKING.md and naxalnet/iwd.py
Added Device.reload() to reload the proxy every time the device mode is
changed. Added Device.set_mode() and partial implementation of
Device.start_adhoc_open().

Added link to meaning of hack in HACKING.md
2021-07-07 14:08:05 +05:30
Pranav Jerry d4e6b929d2
added HACKING.md 2021-07-02 09:30:28 +05:30
Pranav Jerry e4fd0ff04d
basic implementaion of class Device and IWD
When work is finished, we can use them to start adhoc or ap
2021-07-01 12:18:44 +05:30
Pranav Jerry f4a490210d added prototype functions in naxalnet/iwd.py
They won't work yet but when they do we can use the classes in iwd.py
instead of using dasbus directly. Also added a Name to Match in
systemd-networkd/06-eth.network
2021-06-30 21:50:39 +05:30
Pranav Jerry ba2425f008
initial implementation of iwd api
iwd.py is used to communicate with iwd via d-bus
2021-06-27 14:25:36 +05:30
Pranav Jerry 8bdeddf08e
Renamed naxalnet into naxalnet/naxalnet.py 2021-06-27 13:59:42 +05:30
Pranav Jerry d57c92588f
Added AUR package
Now there are two AUR packages - naxalnet and naxalnet-git
2021-06-24 17:04:31 +05:30
Pranav Jerry 47f2324604
Improved README.md
Added how to stop the systemd service and improved the similar projects section.
2021-06-23 13:48:05 +05:30
Pranav Jerry af98a57b0e
Updated README.md
Added shell code to clone git repo. Not everyone knows how to clone a
repo and cd into it 😁
2021-06-19 15:53:16 +05:30
15 changed files with 579 additions and 166 deletions

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
.DS_Store
.idea
*.log
tmp/
*.py[cod]
*.egg*
build
htmlcov
__pycache__

23
HACKING.md Normal file
View File

@ -0,0 +1,23 @@
# Hacking
Everyone <!-- including anti-nationals and urban naxals are -->
is welcome to [hack][] naxalnet. See below for how to hack.
## Reporting issues and suggesting ideas
To report a bug or suggest an idea, create a new issue at
<https://git.disroot.org/pranav/naxalnet/issues> with a
relevant label.
## Contribute code
To push to this repo, you need your username to be in the
contributors list. See issue #8.
## Packaging
naxalnet needs distro packages in Debian, Fedora, openSUSE,
and nixos. If you know/like to package it in your distro,
post to issue #6.
[hack]: https://catb.org/jargon/html/H/hack.html

4
MANIFEST.in Normal file
View File

@ -0,0 +1,4 @@
include LICENSE
include README.md
include naxalnet.service
include systemd-networkd/*

View File

@ -1,16 +1,11 @@
PREFIX := /usr
# This makefile uses setup.py under the hood
all: build
install: naxalnet
install -d $(DESTDIR)$(PREFIX)/bin
install -d $(DESTDIR)$(PREFIX)/lib/systemd/system/
install -m644 naxalnet.service $(DESTDIR)$(PREFIX)/lib/systemd/system/
install naxalnet $(DESTDIR)$(PREFIX)/bin/
install -d $(DESTDIR)$(PREFIX)/share/naxalnet/networkd
install -m644 systemd-networkd/* $(DESTDIR)$(PREFIX)/share/naxalnet/networkd
build:
python setup.py build
testdeps:
@for i in networkctl systemctl python3; do \
echo "Checking for $$i"; \
which $$i > /dev/null && echo " $$i found" || \
(echo " $$i not found"; exit 1); \
done
install: build
python setup.py install --root="$(DESTDIR)/" --optimize=1 --skip-build
clean:
rm -rf build naxalnet.egg-info

View File

@ -33,6 +33,7 @@ or anyone else advocating for their rights).
no error then you already have it)
- iwd (for starting ad-hoc network)
- python3
- python-setuptools (for building)
- [python-dasbus][]
- wifi adapter with ad-hoc support
- two or more computers with wifi adapter, called nodes
@ -43,10 +44,11 @@ or anyone else advocating for their rights).
### Arch Linux
Install [naxalnet-git][] from the AUR with your favourite helper:
Install [naxalnet][aur] (or [naxalnet-git][aur-devel] for the
development version) from the AUR with your favourite helper:
```sh
yay -S naxalnet-git
yay -S naxalnet
```
Optionally, [setup systemd-resolved][arch-resolved] for DNS if any
@ -56,6 +58,17 @@ of the nodes have internet access.
Clone the repo and cd into it.
```sh
git clone https://git.disroot.org/pranav/naxalnet.git
cd naxalnet
```
Or, if you have an [IPFS client][ipfs] running, try:
```sh
git clone http://k51qzi5uqu5dlye74be0n9iihwk6sm54vexo7bf7pdr4w811y6mmrcp25djozv.ipns.localhost:8080/naxalnet.git
```
Run `sudo make install` to install naxalnet. This will install naxalnet in
`/usr/bin/naxalnet`.
@ -94,7 +107,7 @@ 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
Now an ap will be created on one of the adapters 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.
@ -118,28 +131,53 @@ Disable the service to stop running at boot:
sudo systemctl disable naxalnet.service
```
### Stopping the service
```sh
# Stop the services
sudo systemctl stop naxalnet systemd-networkd systemd-resolved iwd
# Delete the virtual interfaces created by naxalnet
sudo networkctl delete bat0 bridge0
```
If your distribution uses NetworkManager, starting `naxalnet.service`
will have stopped it. Start NetworkManager again:
```sh
sudo systemctl start NetworkManager.service
```
## How it works
The program naxalnet copies predefined systemd-networkd configuration
The program naxalnet copies some `systemd-networkd` configuration files
into networkd's runtime configuration directory. It uses iwd to start
an ad-hoc network named "HelloWorld". See the
[systemd-networkd](systemd-networkd) directory
to see how systemd-networkd configures the network. You can now use
to see how systemd-networkd configures the network. You can use
services like [IPFS][], [Jami][], [Secure Scuttlebutt][ssb]
and others which can work without internet access.
and others which can work on an intranet.
## Uninstalling
Currently there is now way to uninstall naxalnet than manually removing
the files:
If you installed naxalnet manually, there is no way to uninstall
than manually removing the files:
```sh
sudo rm -rf /usr/{bin,share}/naxalnet \
/usr/lib/systemd/system/naxalnet.service
sudo pip uninstall naxalnet
sudo rm -rf /usr/share/naxalnet* /usr/lib/systemd/system/naxalnet.service
```
## Contributing
See [HACKING.md](HACKING.md)
## Similar projects
The following projects are similar to naxalnet, but are not designed
to be used in a laptop or computer with wifi adapter. If you live in
an area where the materials required for any of them are easily
available, consider using them instead of naxalnet.
- [LibreMesh][libremesh]: framework for OpenWrt-based
firmwares
- [disaster.radio][]: solar-powered communications network
@ -154,14 +192,13 @@ the Free Software Foundation, either version 3 of the License, or
See [LICENSE](LICENSE) for the complete version of the
license.
This project is in alpha stage. Documentation is incomplete.
[batman-adv]: https://www.open-mesh.org/projects/batman-adv/wiki
[ipfs]: https://ipfs.io
[jami]: https://jami.net
[ssb]: https://scuttlebutt.nz
[python-dasbus]: https://github.com/rhinstaller/dasbus
[naxalnet-git]: https://aur.archlinux.org/packages/naxalnet-git
[aur]: https://aur.archlinux.org/packages/naxalnet
[aur-devel]: https://aur.archlinux.org/packages/naxalnet-git
[arch-resolved]: https://wiki.archlinux.org/title/Systemd-resolved#DNS
[batman-systemd]: https://www.open-mesh.org/news/101
[libremesh]: https://libremesh.org

134
naxalnet
View File

@ -1,134 +0,0 @@
#!/usr/bin/env python3
"""
Setup a working BATMAN Advanced network
with systemd-networkd and iwd
"""
# Copyright (C) 2021 The Authors
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
from pathlib import Path
from shutil import copy
from dasbus.connection import SystemMessageBus
from dasbus.error import DBusError
NETWORKD_CONFIGS = "/usr/share/naxalnet/networkd"
NETWORKD_VOLATILE_DIR = "/run/systemd/network"
ADHOC_SSID = "HelloWorld"
AP_SSID = "NaxalNet"
AP_PASSWD = "naxalnet256"
# Copy networkd configs to volatile dir.
# 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)
src = Path(NETWORKD_CONFIGS)
# Create the volatile directory if it doesn't exist
dest.mkdir(parents=True, exist_ok=True)
# Copy all files in src to dest
for i in src.iterdir():
copy(i, dest)
except PermissionError as error:
print(error)
sys.exit("Make sure you are root")
# Now, the iwd part
try:
# connect to the System bus
bus = SystemMessageBus()
# iwd proxy
iwd = bus.get_proxy("net.connman.iwd", "/")
# Get list of all devices
print("Finding connected devices")
objects = iwd.GetManagedObjects()
# 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
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)
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
if dev1.Mode != "ad-hoc":
print("Device is in", dev1.Mode)
print("Switching to ad-hoc")
dev1.Mode = "ad-hoc"
# 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)
# 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")
print("Bye")

View File

@ -1,11 +1,15 @@
# naxalnet systemd service
# See man:systemd.service(5) and man:systemd.unit(5)
# before editing this file.
[Unit]
Description=Naxalnet
Requires=systemd-networkd.service
Requires=iwd.service
Wants=systemd-resolved.service
# naxalnet does not reload networkd, so networkd
# should be started only afer naxalnet exits
Before=systemd-networkd.service
After=iwd.service
# Stops NetworkManager and wpa_supplicant if already running
Conflicts=NetworkManager.service
Conflicts=wpa_supplicant.service
@ -16,11 +20,12 @@ After=wpa_supplicant.service
Type=oneshot
RemainAfterExit=yes
Restart=on-failure
RestartSec=5sec
# Probably not needed now
RestartSec=2sec
# IWD takes some time to find devices.
# Without the sleep 5, naxalnet could not detect the second
# Without the delay, naxalnet could not detect the second
# device while testing.
ExecStartPre=/usr/bin/sleep 5
ExecStartPre=/usr/bin/sleep 2
ExecStart=/usr/bin/naxalnet
[Install]

19
naxalnet/__init__.py Normal file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env python3
# Copyright (C) 2021 The naxalnet Authors
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
__version__ = "0.1.0a"

22
naxalnet/__main__.py Normal file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env python3
# Copyright (C) 2021 The naxalnet Authors
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from naxalnet.scripts import here_be_dragons
if __name__ == "__main__":
here_be_dragons()

273
naxalnet/iwd.py Normal file
View File

@ -0,0 +1,273 @@
#!/usr/bin/env python3
# Copyright (C) 2021 The naxalnet Authors
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Manage wifi adapter via iwd D-Bus api"""
from dasbus.connection import SystemMessageBus
IWD_BUS = "net.connman.iwd"
IWD_ROOT_PATH = "/"
IWD_DEVICE_INTERFACE = "net.connman.iwd.Device"
IWD_ADAPTER_INTERFACE = "net.connman.iwd.Adapter"
# If you are new to D-Bus, you might want to use a program
# such as D-Feet (https://wiki.gnome.org/Apps/DFeet) for reference.
# And try out iwctl to understand iwd's bus objects
class IWD:
"""Manage iwd via dbus"""
def __init__(self, bus=SystemMessageBus()):
# self._bus and self._proxy are meant for use only in this file
self._bus = bus
self.reload()
def reload(self):
"""reload the proxy"""
self._proxy = self._bus.get_proxy(IWD_BUS, IWD_ROOT_PATH)
def get_name_from_path(self, path: str) -> str:
"""
returns device or adapter name when d-bus path is given as arg
"""
proxy = self._bus.get_proxy(IWD_BUS, path)
return proxy.Name
def get_device_path_from_name(self, name: str) -> str:
"""returns path of device as str"""
device_paths = self.get_all_device_paths()
for i in device_paths:
proxy = self._bus.get_proxy(IWD_BUS, i)
if proxy.Name == name:
return i
# If no devices were found, return None
return None
def get_adapter_path_from_name(self, name: str) -> str:
"""returns path of adapter as str"""
adapter_paths = self.get_all_adapter_paths()
for i in adapter_paths:
proxy = self._bus.get_proxy(IWD_BUS, i)
if proxy.Name == name:
return i
# If no adapters were found
return None
def get_all_device_paths(self) -> list:
"""returns list of paths of all devices"""
objects = self._proxy.GetManagedObjects()
paths = []
for key, value in objects.items():
# if value is a device, add its path to paths
if IWD_DEVICE_INTERFACE in value:
paths.append(key)
return paths
def get_all_adapter_paths(self) -> list:
"""returns list of paths of all adapters"""
objects = self._proxy.GetManagedObjects()
paths = []
for key, value in objects.items():
# if value is an adapter, add its path to paths
if IWD_ADAPTER_INTERFACE in value:
paths.append(key)
return paths
def get_devices(self) -> list:
"""
returns list of device names as str
example: ["wlan0", "wlan1"]
"""
devices = []
device_paths = self.get_all_device_paths()
for i in device_paths:
name = self.get_name_from_path(i)
devices.append(name)
return devices
def get_adapters(self) -> list:
"""
returns list of adapters
example: ["phy0","phy1"]
"""
adapters = []
adapter_paths = self.get_all_adapter_paths()
for i in adapter_paths:
name = self.get_name_from_path(i)
adapters.append(name)
return adapters
class Device:
"""
control devices with iwd
name: name of device (str)
adapter: name of adapter (str)
"""
def __init__(self, name: str, bus=SystemMessageBus()):
self._iwd = IWD(bus)
self._bus = self._iwd._bus
self._path = self._iwd.get_device_path_from_name(name)
self.reload()
def __str__(self):
return self.name
def is_powered_on(self) -> bool:
"""returns True if devie is powered on"""
return self._proxy.Powered
def power_on(self):
"""Turn on the device and reload the proxy"""
self._proxy.Powered = True
self.reload()
def power_off(self):
"""Turn off the device and reload the proxy"""
self._proxy.Powered = False
self.reload()
def reload(self):
"""reload the proxy after changing mode"""
self._proxy = self._bus.get_proxy(IWD_BUS, self._path)
self.name = self._proxy.Name
adapter_path = self._proxy.Adapter
# name of adapter ('phy0' for example)
self.adapter = self._iwd.get_name_from_path(adapter_path)
def is_adhoc_started(self):
"""
Returns True if an adhoc network is started on this device.
Returns None if device is not powered on or not in ad-hoc mode.
"""
if self.is_powered_on() and self.get_mode() == "ad-hoc":
return self._proxy.Started
# If above condition is not true, return None
return None
def is_ap_started(self):
"""
Same as is_adhoc_started(), but for ap
"""
if self.is_powered_on() and self.get_mode() == "ap":
return self._proxy.Started
return None
def get_mode(self) -> str:
"""
returns the mode in which the device is in
example: "ap"
"""
return self._proxy.Mode
def set_mode(self, mode: str):
"""change the device mode to mode"""
self._proxy.Mode = mode
self.reload()
def start_adhoc_open(self, name: str):
"""
Create ad-hoc network with name, changing mode to ad-hoc
if it isn't already on ad-hoc and power onn the device
if it is off
"""
if self.get_mode() != "ad-hoc":
self.set_mode("ad-hoc")
if not self.is_powered_on():
self.power_on()
# Stop adhoc if already started
self.stop_adhoc()
self._proxy.StartOpen(name)
def stop_adhoc(self):
"""stop adhoc if adhoc is started"""
if self.is_adhoc_started():
self._proxy.Stop()
self.reload()
def start_ap(self, ssid, passwd):
"""
Create ap network, changing mode to ap
if it isn't already on ap and turning
on the device if it is off
"""
if self.get_mode() != "ap":
self.set_mode("ap")
if not self.is_powered_on():
self.power_on()
# Stop ap if already started
self.stop_ap()
self._proxy.Start(ssid, passwd)
def stop_ap(self):
"""stop ap if an ap is started"""
if self.is_ap_started():
self._proxy.Stop()
self.reload()
class Adapter:
"""represents an adapter as a python object"""
def __init__(self, name: str, bus=SystemMessageBus()):
self._iwd = IWD(bus)
self._bus = self._iwd._bus
self._path = self._iwd.get_adapter_path_from_name(name)
# Initialise self._proxy
self.reload()
def __str__(self):
return self.name
def reload(self):
"""reload the proxy after changing mode"""
self._proxy = self._bus.get_proxy(IWD_BUS, self._path)
self.name = self._proxy.Name
self.supported_modes = self._proxy.SupportedModes
self.model = self._proxy.Model
self.vendor = self._proxy.Vendor
def is_powered_on(self) -> bool:
"""returns True if adapter is powered on, False otherwise"""
return self._proxy.Powered
def power_on(self):
"""power on the adapter"""
self._proxy.Powered = True
def power_off(self):
"""power off the adapter"""
self._proxy.Powered = False
def supports_mode(self, mode: str) -> bool:
"""
Returns True if the adapter supports the mode.
mode can be "ad-hoc", "ap" or "station"
"""
return mode in self.supported_modes

115
naxalnet/scripts.py Normal file
View File

@ -0,0 +1,115 @@
#!/usr/bin/env python3
# Copyright (C) 2021 The naxalnet Authors
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Setup a working BATMAN Advanced network
with systemd-networkd and iwd
"""
import sys
from pathlib import Path
from shutil import copy
from dasbus.error import DBusError
from naxalnet.iwd import IWD, Device, Adapter
NETWORKD_CONFIGS = "/usr/share/naxalnet/networkd"
NETWORKD_VOLATILE_DIR = "/run/systemd/network"
ADHOC_SSID = "HelloWorld"
AP_SSID = "NaxalNet"
AP_PASSWD = "naxalnet256"
def copy_files():
"""
Copy networkd configs to volatile dir.
The D-Bus API does not support creating new interfaces
or linking to bridges. So we use config files.
See man:systemd.network(5)
"""
print("Copying network config files")
dest = Path(NETWORKD_VOLATILE_DIR)
src = Path(NETWORKD_CONFIGS)
# Create the volatile directory if it doesn't exist
dest.mkdir(parents=True, exist_ok=True)
# Copy all files in src to dest
for i in src.iterdir():
copy(i, dest)
def here_be_dragons():
"""
This function is run every time you
execute naxalnet from commandline
"""
try:
copy_files()
except PermissionError as error:
print(error)
sys.exit("Make sure you are root")
# Now, the iwd part
try:
iwd = IWD()
devices = iwd.get_devices()
adhoc_devices = []
ap_devices = []
for i in devices:
device = Device(i)
adapter = Adapter(device.adapter)
if adapter.supports_mode("ad-hoc"):
adhoc_devices.append(i)
if adapter.supports_mode("ap"):
ap_devices.append(i)
if len(adhoc_devices) != 0:
# Start ad-hoc on first device supporting ad-hoc
adhoc_device = Device(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 adhoc_device from ap_devices if it exists there
if adhoc_device.name in ap_devices:
ap_devices.remove(adhoc_device.name)
print("Working on ad-hoc")
# Turn on adapter if it is off
# See issue #9
adhoc_adapter = Adapter(adhoc_device.adapter)
if not adhoc_adapter.is_powered_on():
adhoc_adapter.power_on()
adhoc_device.reload()
adhoc_device.start_adhoc_open(ADHOC_SSID)
# Start Access point if ap_device is not empty,
# ie, we have more devices
if len(ap_devices) != 0:
print("Working on AP")
ap_device = Device(ap_devices.pop())
# Turn on adapter if it is off
# See issue #9
ap_adapter = Adapter(ap_device.adapter)
if not ap_adapter.is_powered_on():
ap_adapter.power_on()
ap_adapter.reload()
ap_device.start_ap(AP_SSID, AP_PASSWD)
except DBusError as error:
print(error)
sys.exit("An error occured while communicating with iwd")
# naxalnet will print Bye if no errors occured
print("Bye")

36
setup.cfg Normal file
View File

@ -0,0 +1,36 @@
[metadata]
name = naxalnet
version = attr: naxalnet.__version__
description = create mesh networks with batman-adv and systemd
long_description = file: README.md, LICENSE
url = https://git.disroot.org/pranav/naxalnet
author = Pranav Jerry
author_email = libreinator@disroot.org
license = GPLv3
classifiers =
License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Operating System :: POSIX :: Linux
Programming Language :: Python :: 3 :: Only
[options]
include_package_data = true
packages = find:
python_requires = >=3.6
install_requires =
dasbus
[options.entry_points]
console_scripts =
naxalnet = naxalnet.scripts:here_be_dragons
[options.data_files]
/usr/lib/systemd/system =
naxalnet.service
/usr/share/naxalnet/networkd =
systemd-networkd/01-batman.netdev
systemd-networkd/02-bridge.netdev
systemd-networkd/03-wireless-ad-hoc.network
systemd-networkd/04-batman.network
systemd-networkd/05-wireless-ap.network
systemd-networkd/06-eth.network
systemd-networkd/07-bridge.network

5
setup.py Executable file
View File

@ -0,0 +1,5 @@
#!/usr/bin/env python3
from setuptools import setup
setup()

View File

@ -1,5 +1,7 @@
# This file links any interface in ap mode
# to the bridge we created earlier
# to the bridge we created earlier.
# To start an AP, connect two adapters to the computer
# before starting naxalnet.service
# This file won't do anything if an ap interface is not found.
[Match]

View File

@ -2,6 +2,7 @@
# to the bridge made in 02-bridge.netdev
[Match]
Name=en*
Name=eth*
[Network]
Bridge=bridge0