mirror of
https://git.disroot.org/pranav/pybatmesh.git
synced 2025-01-14 18:52:08 +05:30
Merge branch 'args-and-config'
See CHANGELOG.md for details
This commit is contained in:
commit
1a6dbc4bcb
26
CHANGELOG.md
Normal file
26
CHANGELOG.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Changelog
|
||||
|
||||
## [Unreleased][] - 2021-08-19
|
||||
|
||||
- Support for arguments
|
||||
- Configuration file support with fallback values
|
||||
- Made messages more readable
|
||||
- Improved documentation in docstrings
|
||||
- Changed default name of mesh network. **This will make naxalnet
|
||||
incompatible with nodes running previous versions.**
|
||||
- New versioning scheme that conforms to PEP 440
|
||||
|
||||
## [v0.2.0][] - 2021-07-26
|
||||
|
||||
- rfkill support
|
||||
- rewrite into python module
|
||||
|
||||
## [v0.1.0][] - 2021-06-19
|
||||
|
||||
Initial version. At first, this was a shell script. Than it was converted
|
||||
into a single python file that did just what the shell script used to do.
|
||||
The shell script was not given a version.
|
||||
|
||||
[unreleased]: https://git.disroot.org/pranav/naxalnet/compare/v0.2.0...HEAD
|
||||
[v0.2.0]: https://git.disroot.org/pranav/naxalnet/compare/v0.1.0...v0.2.0
|
||||
[v0.1.0]: https://git.disroot.org/pranav/naxalnet/releases/tag/v0.1.0
|
16
HACKING.md
16
HACKING.md
@ -1,7 +1,6 @@
|
||||
# Hacking
|
||||
|
||||
Everyone <!-- including anti-nationals and urban naxals are -->
|
||||
is welcome to [hack][] naxalnet. See below for how to hack.
|
||||
Everyone can [hack][] naxalnet. See below for how to hack.
|
||||
|
||||
## Reporting issues and suggesting ideas
|
||||
|
||||
@ -9,14 +8,23 @@ To report a bug or suggest an idea, create a new issue at
|
||||
<https://git.disroot.org/pranav/naxalnet/issues> with a
|
||||
relevant label.
|
||||
|
||||
## Improving documentation
|
||||
|
||||
The README and HACKING.md needs to be more beginner friendly.
|
||||
See section below.
|
||||
|
||||
## Contribute code
|
||||
|
||||
To push to this repo, you need your username to be in the
|
||||
contributors list. See issue #8.
|
||||
contributors list. Add your username to issue #8 to add you
|
||||
as a contributor. Before each commit, update the CHANGELOG.md
|
||||
and `__version__` in `naxalnet/__init__.py`
|
||||
|
||||
## Packaging
|
||||
|
||||
naxalnet needs distro packages in Debian, Fedora, openSUSE,
|
||||
Currently this program is only packaged for Arch Linux.
|
||||
naxalnet needs packages in GNU+Linux+systemd
|
||||
distributions such as Debian, Fedora, openSUSE,
|
||||
and nixos. If you know/like to package it in your distro,
|
||||
post to issue #6.
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
include LICENSE
|
||||
include README.md
|
||||
include naxalnet.service
|
||||
include systemd-networkd/*
|
||||
include naxalnet.conf.example
|
||||
recursive-include systemd-networkd *
|
||||
|
24
Makefile
24
Makefile
@ -1,11 +1,27 @@
|
||||
# This makefile uses setup.py under the hood
|
||||
# This makefile uses setup.py under the hood.
|
||||
# In ubuntu, python and pip are symlinks to python2 and pip2, not
|
||||
# python3. So we have to specify python as python3 by default.
|
||||
PYTHON := python3
|
||||
PIP := pip3
|
||||
DESTDIR:= /
|
||||
|
||||
all: build
|
||||
|
||||
build:
|
||||
python3 setup.py build
|
||||
$(PYTHON) setup.py build
|
||||
|
||||
install: build
|
||||
python3 setup.py install --root="$(DESTDIR)/" --optimize=1 --skip-build
|
||||
$(PYTHON) setup.py install --root="$(DESTDIR)" --optimize=1 --skip-build
|
||||
|
||||
uninstall:
|
||||
$(PIP) uninstall -y naxalnet
|
||||
rm -rf /usr/share/naxalnet /usr/lib/systemd/system/naxalnet.service
|
||||
@-test -d /etc/naxalnet && echo "The directory /etc/naxalnet was not removed." && \
|
||||
echo "Do 'sudo make purge' to remove it."
|
||||
|
||||
# remove config files, like apt purge
|
||||
purge: uninstall
|
||||
rm -rf /etc/naxalnet
|
||||
|
||||
clean:
|
||||
rm -rf build naxalnet.egg-info
|
||||
rm -rf build naxalnet.egg-info **/__pycache__
|
||||
|
241
README.md
241
README.md
@ -1,32 +1,32 @@
|
||||
# naxalnet
|
||||
|
||||
**naxalnet** is a program to create a wireless mesh network for
|
||||
communicating with each other. It can be useful during an internet
|
||||
shutdown, or to join online classes with a group of laptops.
|
||||
It uses [B.A.T.M.A.N. Advanced][batman-adv],an implementation
|
||||
communicating with each other. It can be useful during an
|
||||
[internet shutdown](#internet-shutdown), or to join
|
||||
[online classes](#online-class-in-remote-areas) with a group
|
||||
of laptops.
|
||||
It uses [B.A.T.M.A.N. Advanced][batman-adv], an implementation
|
||||
of the B.A.T.M.A.N. routing protocol to communicate with peers.
|
||||
The name naxal comes from Naxalbari, a village in Darjeeling,
|
||||
West Bengal.
|
||||
|
||||
WARNING:
|
||||
This program uses an unencrypted network. This means,
|
||||
you do not get any more privacy or security than with an open wifi
|
||||
This program uses an **unencrypted** network. This means
|
||||
you do not get any more privacy or security than with an open WiFi
|
||||
network.
|
||||
|
||||
<!-- NOTE TO ACTIVISTS
|
||||
|
||||
Running this program in the world's largest partly free democracy
|
||||
Running this program in the world's largest partly-free democracy
|
||||
may result in you getting arrested under the UAPA, and not
|
||||
getting bail because of false evidence planted in your phone by
|
||||
Pegasus, or by a forensic lab in Gujarat.
|
||||
|
||||
The author, not unlike the Government of India, does not wish
|
||||
The author, much like the Government of India, does not wish
|
||||
to take responsibility in your well-being if you get arrested under
|
||||
a draconian national security law, which was once used to arrest
|
||||
a person involved in the freedom struggle against British Raj.
|
||||
a draconian national security law.
|
||||
|
||||
-->
|
||||
|
||||
The name naxal comes from Naxalbari, a village in Darjeeling,
|
||||
West Bengal.
|
||||
|
||||
<!-- UNCOMMENT WHEN NECESSARY
|
||||
|
||||
**Disclaimer**:
|
||||
@ -34,7 +34,7 @@ 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
|
||||
Using the name naxal does not imply any form of connection
|
||||
with anyone currently at risk of death in overcrowded prisons.
|
||||
|
||||
-->
|
||||
@ -44,16 +44,19 @@ with anyone currently at risk of death in overcrowded prisons.
|
||||
- [systemd v248 or more][batman-systemd]
|
||||
- Linux kernel with batman-adv module
|
||||
- [iwd][]
|
||||
- python3
|
||||
- python-setuptools (for building)
|
||||
- [python-dasbus][]
|
||||
- wifi adapter with ad-hoc support
|
||||
- two or more computers, or laptops with wifi adapter, called nodes
|
||||
- systemd-resolved (optional, for DNS)
|
||||
- python
|
||||
- python-setuptools (for building and installing)
|
||||
- [dasbus][]
|
||||
- WiFi adapter with ad-hoc support
|
||||
- two or more computers, or laptops with WiFi adapter, called nodes
|
||||
- batctl (optional, for debugging)
|
||||
- python pip (optional, for uninstalling)
|
||||
|
||||
## Installing
|
||||
|
||||
This program is available in the AUR for Arch users. Building
|
||||
manually for other distributions may not always work.
|
||||
|
||||
### Arch Linux
|
||||
|
||||
Install [naxalnet][aur] (or [naxalnet-git][aur-devel] for the
|
||||
@ -64,28 +67,69 @@ yay -S naxalnet
|
||||
```
|
||||
|
||||
Optionally, [setup systemd-resolved][arch-resolved] for DNS if any
|
||||
of the nodes have internet access.
|
||||
of the nodes have internet access. [Start naxalnet][startnx] when
|
||||
you need it.
|
||||
|
||||
### Ubuntu
|
||||
|
||||
naxalnet is not packaged for Ubuntu, so you will have to build
|
||||
and install it manually.
|
||||
Currently, only the [unreleased 21.10][ubuntu-systemd] comes with the
|
||||
required version of systemd. Therefore, naxalnet won't work on Ubuntu
|
||||
21.04 or older.
|
||||
|
||||
<!-- TODO: remove this message when systemd 248 arrives in 21.04 -->
|
||||
|
||||
Install the requirements from the Ubuntu repositories:
|
||||
|
||||
```sh
|
||||
# batctl is optional
|
||||
sudo apt install systemd python3-pip iwd batctl build-essential
|
||||
# Now, install dasbus with pip
|
||||
sudo pip3 install dasbus
|
||||
```
|
||||
|
||||
Now follow the instructions in the
|
||||
[manual installation section][install-manual]
|
||||
|
||||
### Fedora
|
||||
|
||||
naxalnet is not packaged for Fedora, so it should be installed
|
||||
manually. naxalnet requires atleast systemd v248 which is only
|
||||
available on Fedora 34 and above. Install the dependencies:
|
||||
|
||||
```sh
|
||||
# systemd-resolved may be required for rawhide
|
||||
sudo dnf install systemd-networkd iwd python3-dasbus python3-setuptools
|
||||
```
|
||||
|
||||
Now head over to the [next section][install-manual] to install naxalnet.
|
||||
|
||||
### Manually
|
||||
|
||||
Clone the repo and cd into it.
|
||||
Install the [requirements][requirements].
|
||||
|
||||
Clone the naxalnet 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:
|
||||
Or, if you have an [IPFS client][ipfs] running, try this instead:
|
||||
|
||||
```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`.
|
||||
Now, install naxalnet:
|
||||
|
||||
After installing, reload systemd so that you can enable `naxalnet.service`
|
||||
without rebooting:
|
||||
```sh
|
||||
sudo make install
|
||||
```
|
||||
|
||||
After installing, reload systemd so that it detects the new
|
||||
service files:
|
||||
|
||||
```sh
|
||||
sudo systemctl daemon-reload
|
||||
@ -93,53 +137,50 @@ sudo systemctl daemon-reload
|
||||
|
||||
## How to use
|
||||
|
||||
You need more than one computer running for the connection to work.
|
||||
You need more than one machine running naxalnet for the connection to work.
|
||||
|
||||
### Start naxalnet
|
||||
|
||||
Though naxalnet can run from the commandline, it was designed to be
|
||||
run as a systemd service.
|
||||
To start naxalnet, do the command on all the nodes:
|
||||
|
||||
```sh
|
||||
sudo systemctl start naxalnet.service
|
||||
```
|
||||
|
||||
To test if it works, run `ip -c addr` to find out your address.
|
||||
Note the `inet` address of `bridge0`. If there isn't one, try again
|
||||
after a few seconds. If the address starts with 169.254, it has
|
||||
got a link-local address. Otherwise, it has got an IP address
|
||||
from DHCP.
|
||||
This will start a mesh network and connect to all nodes.
|
||||
To test if it works, run `sudo batctl n -w` and check for
|
||||
nodes. If there are any nodes, your network is up.
|
||||
|
||||
### Getting internet access
|
||||
|
||||
Connect an ethernet cable to any of the peers and
|
||||
[start naxalnet][startnx]. Now all the peers should
|
||||
be able to connect after renewing their DHCP connection
|
||||
(`sudo networkctl renew bridge0`).
|
||||
Connect an ethernet cable from a router to any of the peers and
|
||||
[start naxalnet][startnx]. If it was already started, you should
|
||||
renew the DHCP connection of all peers. To do this, type
|
||||
`sudo networkctl renew bridge0` on all peers.
|
||||
|
||||
### Tethering via WiFi AP
|
||||
|
||||
If there are two adapters in a peer, naxalnet will start a
|
||||
wifi ap (wifi hotspot) on one of them.
|
||||
WiFi ap (also called WiFi hotspot) on one of them.
|
||||
|
||||
Connect two WiFi adapters on a device and [start naxalnet][startnx].
|
||||
Now an ap will be started on one of the adapters.
|
||||
Type `naxalnet --print-WiFi` to get the WiFi SSID and password.
|
||||
|
||||
Connect two wifi adapters on a device and [start naxalnet][startnx].
|
||||
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.
|
||||
|
||||
### 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 was started, systemd will stop naxalnet.
|
||||
|
||||
To run naxalnet at boot, enable the service on all the nodes:
|
||||
|
||||
```sh
|
||||
sudo systemctl enable naxalnet.service
|
||||
```
|
||||
|
||||
Now naxalnet will configure a batman interface on every boot.
|
||||
Now naxalnet will start a mesh on every boot.
|
||||
Disable the service to stop running at boot:
|
||||
|
||||
```sh
|
||||
@ -149,10 +190,7 @@ 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
|
||||
sudo systemctl stop naxalnet iwd systemd-networkd systemd-resolved
|
||||
```
|
||||
|
||||
If your distribution uses NetworkManager, starting `naxalnet.service`
|
||||
@ -162,61 +200,112 @@ will have stopped it. Start NetworkManager again:
|
||||
sudo systemctl start NetworkManager.service
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
naxalnet comes with a sample configuration file
|
||||
`/etc/naxalnet/naxalnet.conf.example`. To change how the program
|
||||
behaves, copy it to /etc/naxalnet/naxalnet.conf and edit it:
|
||||
|
||||
```sh
|
||||
sudo cp /etc/naxalnet/naxalnet.conf{.example,}
|
||||
# Now edit the file with your favourite editor as root
|
||||
gedit admin:/etc/naxalnet/naxalnet.conf
|
||||
```
|
||||
|
||||
Also, you can change its behaviour every time you run it using
|
||||
arguments:
|
||||
|
||||
```sh
|
||||
naxalnet --help
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
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 use
|
||||
services like [IPFS][], [Jami][], [Secure Scuttlebutt][ssb]
|
||||
There are three modes commonly supported by WiFi adapters -
|
||||
`ap` (WiFi hotspot), `station` (for joining WiFi networks) and `ad-hoc`
|
||||
(for decentralised networks). There are some other modes too,
|
||||
like `p2p` (WiFi direct), but we won't go into the details.
|
||||
|
||||
naxalnet uses two modes - `ad-hoc` and `ap`, for connecting to the
|
||||
mesh. naxalnet uses iwd to start an `ad-hoc` network and configures
|
||||
systemd-networkd to setup a BATMAN Advanced network.
|
||||
If there are two WiFi adapters connected to the machine,
|
||||
naxalnet starts an ad-hoc on one of them and an ap on the other.
|
||||
You can use the ap for connecting mobile phones and other devices
|
||||
to the mesh network.
|
||||
|
||||
Read the code to learn the details.
|
||||
See [systemd-networkd](systemd-networkd) to see how
|
||||
systemd-networkd configures the network.
|
||||
|
||||
## Use cases
|
||||
|
||||
### Online class in remote areas
|
||||
|
||||
naxalnet can be used to share connections in remote areas.
|
||||
You need at least one device with internet access.
|
||||
|
||||
### Internet shutdown
|
||||
|
||||
You can communicate with neighbouring devices running naxalnet,
|
||||
using services like [IPFS][], [Jami][], [Secure Scuttlebutt][ssb]
|
||||
and others which can work on an intranet.
|
||||
They should be installed on your machine _before_ your friendly
|
||||
democratic government announces an [internet shutdown][], since you
|
||||
cannot download and install them during a shutdown.
|
||||
When a shutdown occurs, [enable naxalnet][enablenx]
|
||||
|
||||
## Uninstalling
|
||||
|
||||
If you installed naxalnet manually, there is no way to uninstall
|
||||
than manually removing the files:
|
||||
If you installed naxalnet manually, use make uninstall to remove
|
||||
naxalnet and its data files. This requires python pip to be installed.
|
||||
|
||||
```sh
|
||||
sudo pip uninstall naxalnet
|
||||
sudo rm -rf /usr/share/naxalnet* /usr/lib/systemd/system/naxalnet.service
|
||||
# Uninstall the program, keeping the config files
|
||||
sudo make uninstall
|
||||
# Or, to uninstall and remove config files
|
||||
sudo make purge
|
||||
```
|
||||
|
||||
## Contributing
|
||||
## Contributing or reporting bugs
|
||||
|
||||
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
|
||||
to be used in a machine 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
|
||||
- [LibreMesh][]: framework for OpenWrt-based firmwares
|
||||
- [disaster.radio][]: solar-powered communications network
|
||||
|
||||
## License
|
||||
|
||||
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.
|
||||
naxalnet is [free/libre/swatantra][free-sw] and open source 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,
|
||||
eitherversion 3 of the License, or (at your option) any later version.
|
||||
|
||||
See [LICENSE](LICENSE) for the complete version of the
|
||||
license.
|
||||
See [LICENSE](LICENSE) for the complete version of the license.
|
||||
|
||||
[batman-adv]: https://www.open-mesh.org/projects/batman-adv/wiki
|
||||
[ipfs]: https://ipfs.io
|
||||
[internet shutdown]: https://internetshutdowns.in
|
||||
[ipfs]: https://ipfs.io "InterPlanetary File System"
|
||||
[jami]: https://jami.net "Peer to peer video calls"
|
||||
[ssb]: https://scuttlebutt.nz "Secure Scuttlebutt"
|
||||
[python-dasbus]: https://github.com/rhinstaller/dasbus "Python D-Bus library"
|
||||
[dasbus]: https://github.com/rhinstaller/dasbus "A python D-Bus library"
|
||||
[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
|
||||
[arch-resolved]: https://wiki.archlinux.org/title/Systemd-resolved#DNS "systemd-resolved on ArchWiki"
|
||||
[batman-systemd]: https://www.open-mesh.org/news/101 "systemd v248 brings support for batman advanced"
|
||||
[libremesh]: https://libremesh.org
|
||||
[disaster.radio]: https://disaster.radio/
|
||||
[disaster.radio]: https://disaster.radio
|
||||
[startnx]: #start-naxalnet
|
||||
[iwd]: https://iwd.wiki.kernel.org "wifi daemon"
|
||||
[iwd]: https://iwd.wiki.kernel.org "WiFi daemon"
|
||||
[free-sw]: https://gnu.org/philosophy/free-sw.html "What is free software?"
|
||||
[enablenx]: #running-at-boot
|
||||
[ubuntu-systemd]: https://packages.ubuntu.com/impish/systemd
|
||||
[requirements]: #requirements
|
||||
[install-manual]: #manually
|
||||
|
22
naxalnet.conf.example
Normal file
22
naxalnet.conf.example
Normal file
@ -0,0 +1,22 @@
|
||||
# This configuration file is part of naxalnet.
|
||||
# To configure this program, rename this file
|
||||
# to naxalnet.conf and edit it.
|
||||
# The values given here are defaults.
|
||||
|
||||
[networkd]
|
||||
# systemd-networkd configuration files bundled with naxalnet.
|
||||
# THese will be copied to runtimedir at runtime.
|
||||
confdir = /usr/share/naxalnet/networkd
|
||||
# systemd-networkd runtime configuration directory.
|
||||
# See man:systemd.network(5)
|
||||
runtimedir = /run/systemd/network
|
||||
|
||||
[adhoc]
|
||||
# All your nodes should have the same name
|
||||
name = NxMesh
|
||||
|
||||
[ap]
|
||||
# An AP is started if your machine has more than one WiFi adapter.
|
||||
ssid = MeshWiFi
|
||||
passwd = naxalnet256
|
||||
|
@ -1,18 +1,16 @@
|
||||
# naxalnet systemd service
|
||||
# The naxalnet systemd service
|
||||
# See man:systemd.service(5) and man:systemd.unit(5)
|
||||
# before editing this file.
|
||||
[Unit]
|
||||
Description=Naxalnet
|
||||
Description=Setup mesh networks
|
||||
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
|
||||
# This stops networkmanager and wpa_supplicant when naxalnet is enabled
|
||||
After=NetworkManager.service
|
||||
After=wpa_supplicant.service
|
||||
|
||||
@ -20,13 +18,30 @@ After=wpa_supplicant.service
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
Restart=on-failure
|
||||
# Probably not needed now
|
||||
RestartSec=2sec
|
||||
# IWD takes some time to find devices.
|
||||
# Without the delay, naxalnet could not detect the second
|
||||
# device while testing.
|
||||
# If naxalnet is run before iwd finds devices,
|
||||
# naxalnet cannot start a mesh network but exits without errors.
|
||||
# So, we give a 2s delay.
|
||||
ExecStartPre=/usr/bin/sleep 2
|
||||
ExecStart=/usr/bin/naxalnet
|
||||
# Reload systemd-networkd after naxalnet exits
|
||||
ExecStartPost=/usr/bin/networkctl reload
|
||||
# Delete all files in /run/systemd/network
|
||||
ExecStop=/usr/bin/find /run/systemd/network -type f -delete
|
||||
# Delete the interfaces created...
|
||||
ExecStopPost=/usr/bin/networkctl delete bridge0 bat0
|
||||
# ... and reload the configuration files.
|
||||
ExecStopPost=/usr/bin/networkctl reload
|
||||
# Make python flush messages instead of buffering.
|
||||
# When reading the systemd journal, we need to see the messages
|
||||
# in the exact order. There will suddenly be a lot of messages
|
||||
# from naxalnet, networkd, iwd and resolved. When buffering is on,
|
||||
# we won't see the messages from naxalnet in the order they were
|
||||
# printed. This, among other problems, make it hard while debugging.
|
||||
# This will no longer be needed when naxalnet sends its messages
|
||||
# directly to the systtemd journal instead of stdout.
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
@ -15,5 +15,25 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
naxalnet
|
||||
========
|
||||
|
||||
__version__ = "0.2.0a"
|
||||
Create mesh networks with batman-adv, systemd-networkd and iwd.
|
||||
See README.md for documentation.
|
||||
"""
|
||||
|
||||
# GUIDE FOR CHANGING __version__
|
||||
#
|
||||
# All commits in master should have the version as
|
||||
# {last published version tag}.a{1,2,3,...}
|
||||
# example: 0.2.0a3 should mean 3 commits after tag v0.2.0
|
||||
#
|
||||
# All commits in other branches should
|
||||
# have {version in master}.dev{1,2,...}
|
||||
# example: 0.2.0a3.dev1 should mean 1 commit in the new
|
||||
# branch after the commit in master.
|
||||
#
|
||||
# In case you forgot to change the version, skip the number
|
||||
# and put the next number in the next commit.
|
||||
__version__ = "0.2.0a4"
|
||||
|
@ -15,6 +15,11 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
If called as python -m naxalnet, this file makes naxalnet run like
|
||||
it was called from the commandline. Try:
|
||||
python -m naxalnet --help
|
||||
"""
|
||||
|
||||
from naxalnet.scripts import here_be_dragons
|
||||
|
||||
|
144
naxalnet/config.py
Normal file
144
naxalnet/config.py
Normal file
@ -0,0 +1,144 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
config.py
|
||||
---------
|
||||
|
||||
This file contains functions to parse configuration files
|
||||
and arguments. Most of these functions are meant to be used
|
||||
by parse_args() internally, so only parse_args() should
|
||||
be imported outside this file.
|
||||
|
||||
Some parts of naxalnet can be configured by configuration
|
||||
files and arguments. First, the default values from
|
||||
default.py is taken. Then, key-value pairs from the
|
||||
configuration files are read, if they exist, in the
|
||||
following order:
|
||||
|
||||
- First it reads /usr/share/naxalnet/naxalnet.conf
|
||||
and then from /usr/share/naxalnet/naxalnet.conf.d/*.conf
|
||||
where *.conf means any file with the name ending with
|
||||
".conf". The files in this directory are intended
|
||||
to be used by distribution and package maintainers.
|
||||
- Next, it does the same with /usr/local/share/naxalnet
|
||||
- Then, it looks for the files naxalnet.conf and
|
||||
naxalnet.conf.d/*.conf from the directory
|
||||
/etc/naxalnet, like it did up above. This directory is where
|
||||
the user creates and stores the config file.
|
||||
- Then it parses the arguments from the commandline,
|
||||
storing the values in the files parsed until now
|
||||
as fallback. Finally you get an argpase.Namespace object
|
||||
from parse_args().
|
||||
Because of the way this is implemented, all key-value
|
||||
pairs in the configuration should have an argument
|
||||
too, or they won't be parsed.
|
||||
|
||||
All the key-value pairs are replaced successively if they exist
|
||||
by each new configuration file parsed, similar
|
||||
to how systemd parses configuration and service files.
|
||||
If any of the files checked does not exist, then they are
|
||||
ignored and the next combination is checked. If none of
|
||||
the config files exist and no arguments are given, the
|
||||
fallback data from default.py is used.
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from configparser import ConfigParser
|
||||
from argparse import ArgumentParser, Namespace
|
||||
from naxalnet.default import CONFIG, CONFIG_FILES, CONFIG_DIRS
|
||||
|
||||
|
||||
def get_config_files():
|
||||
"""
|
||||
Read list of configuration files and return a list
|
||||
of files that exists as pathlib.Path objects
|
||||
"""
|
||||
config_files = []
|
||||
for directory in CONFIG_DIRS:
|
||||
path = Path(directory)
|
||||
if path.exists():
|
||||
for i in CONFIG_FILES:
|
||||
glob = path.glob(i)
|
||||
config_files.extend(glob)
|
||||
return config_files
|
||||
|
||||
|
||||
def parse_config():
|
||||
"""
|
||||
Parse all configuration files, with the values in
|
||||
default.py as fallback
|
||||
"""
|
||||
parser = ConfigParser()
|
||||
# encoded defaults
|
||||
parser.read_dict(CONFIG)
|
||||
# read config files
|
||||
files = get_config_files()
|
||||
for i in files:
|
||||
parser.read_file(i.open())
|
||||
return parser
|
||||
|
||||
|
||||
def parse_args() -> Namespace:
|
||||
"""
|
||||
Parse all arguments and return ArgumentParser.parse_args(),
|
||||
with values in config files as fallback. Ideally, only this
|
||||
function should be used by naxalnet to get arguments and
|
||||
configuration.
|
||||
"""
|
||||
config = parse_config()
|
||||
parser = ArgumentParser(
|
||||
description="setup batman-adv networks with systemd and iwd"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ap-ssid",
|
||||
"-n",
|
||||
type=str,
|
||||
help="SSID of the WiFi AP",
|
||||
default=config["ap"]["ssid"],
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ap-passwd",
|
||||
"-p",
|
||||
"--ap-password",
|
||||
type=str,
|
||||
help="password of the WiFi AP",
|
||||
default=config["ap"]["passwd"],
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--adhoc-name",
|
||||
"-a",
|
||||
type=str,
|
||||
default=config["adhoc"]["name"],
|
||||
help="name of adhoc network",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--print-wifi",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="prints the ssid and password of the WiFi network and exit",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--networkd-config-dir",
|
||||
type=str,
|
||||
default=config["networkd"]["confdir"],
|
||||
help="the directory where systemd-networkd configuration files are stored",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--networkd-runtime-dir",
|
||||
type=str,
|
||||
default=config["networkd"]["runtimedir"],
|
||||
help="volatile directory where configuration files of systemd-networkd should be copied",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--version",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="prints the version and exit",
|
||||
)
|
||||
|
||||
return parser.parse_args()
|
26
naxalnet/default.py
Normal file
26
naxalnet/default.py
Normal file
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
default.py
|
||||
----------
|
||||
|
||||
This file contains default values for configuration.
|
||||
This is taken as fallback data by config.py if no
|
||||
configuration files were found, or if a key-value pair
|
||||
was not present in the config file. The data will be
|
||||
further changed by arguments if naxalnet is called
|
||||
from the commandline. See config.py for more info.
|
||||
"""
|
||||
|
||||
CONFIG = {
|
||||
"networkd": {
|
||||
"confdir": "/usr/share/naxalnet/networkd",
|
||||
"runtimedir": "/run/systemd/network",
|
||||
},
|
||||
"adhoc": {"name": "NxMesh"},
|
||||
"ap": {"ssid": "MeshWiFi", "passwd": "naxalnet256"},
|
||||
}
|
||||
|
||||
# glob
|
||||
CONFIG_FILES = ["naxalnet.conf", "naxalnet.conf.d/*.conf"]
|
||||
CONFIG_DIRS = ["/usr/share/naxalnet", "/usr/local/share/naxalnet", "/etc/naxalnet"]
|
@ -16,7 +16,48 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
"""Manage wifi adapter via iwd D-Bus api"""
|
||||
"""
|
||||
iwd.py
|
||||
------
|
||||
|
||||
This file contains methods to communicate with iwd via
|
||||
its D-Bus API and control WiFi adapters.
|
||||
|
||||
Some terms used here, such as device and adapter might
|
||||
confuse you if you haven't used iwctl before.
|
||||
Just as a quick reference, here is a list of terms
|
||||
and what they mean:
|
||||
|
||||
- ad-hoc: a mode supported by some WiFi adapters to
|
||||
start a decentralised network, where there
|
||||
is no central point of failure.
|
||||
|
||||
- ap: a mode used to start a central access point
|
||||
so that other machines without naxalnet can
|
||||
connect to the mesh. AP is also known as
|
||||
WiFi hotspot.
|
||||
|
||||
- station: this is the mode most WiFi adapters use
|
||||
by default. This mode is used to connect to
|
||||
an ap. naxalnet DOES NOT use this mode.
|
||||
|
||||
- adapter: a physical WiFi chip or something similar
|
||||
that is present inside most laptops and phones
|
||||
or can be connected via USB to a machine.
|
||||
|
||||
- device: an interface provided by the kernel to control
|
||||
an adapter. Some adapters can have multiple
|
||||
devices so that you can start an ap on one device
|
||||
and an ad-hoc on the other. By default, iwd starts
|
||||
only one device each for one adapter.
|
||||
|
||||
- machine: Since iwd uses the term device for a
|
||||
WiFi interface, we use the word machine to
|
||||
refer to a computer, or a laptop, or a phone.
|
||||
|
||||
- node: a machine that runs naxalnet and is therefore
|
||||
connected to the mesh.
|
||||
"""
|
||||
|
||||
from dasbus.connection import SystemMessageBus
|
||||
|
||||
@ -27,7 +68,7 @@ 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
|
||||
# And try out iwctl to understand iwd's bus objects.
|
||||
|
||||
|
||||
class IWD:
|
||||
@ -155,23 +196,24 @@ class Device:
|
||||
# name of adapter ('phy0' for example)
|
||||
self.adapter = self._iwd.get_name_from_path(adapter_path)
|
||||
|
||||
def is_adhoc_started(self):
|
||||
def is_adhoc_started(self) -> bool:
|
||||
"""
|
||||
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.
|
||||
Returns False if the network is in staring stage, 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
|
||||
# If above condition is not true, return False
|
||||
return False
|
||||
|
||||
def is_ap_started(self):
|
||||
def is_ap_started(self) -> bool:
|
||||
"""
|
||||
Same as is_adhoc_started(), but for ap
|
||||
"""
|
||||
if self.is_powered_on() and self.get_mode() == "ap":
|
||||
return self._proxy.Started
|
||||
return None
|
||||
return False
|
||||
|
||||
def get_mode(self) -> str:
|
||||
"""
|
||||
@ -250,8 +292,6 @@ class Adapter:
|
||||
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"""
|
||||
|
@ -16,24 +16,27 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
Setup a working BATMAN Advanced network
|
||||
with systemd-networkd and iwd
|
||||
scripts.py
|
||||
----------
|
||||
|
||||
The functions in this file is used for reading configs, args
|
||||
and doing the things this program is supposed to do.
|
||||
This file is named scripts.py because the original developer
|
||||
of this program could not think of a better name that suits this file.
|
||||
If you want to hack naxalnet, this is the right place to start.
|
||||
When run from the commandline, the function here_be_dragons() is called.
|
||||
"""
|
||||
|
||||
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"
|
||||
from naxalnet import __version__
|
||||
from naxalnet.iwd import Adapter, Device, IWD
|
||||
from naxalnet.config import parse_args
|
||||
|
||||
|
||||
def copy_files():
|
||||
def copy_files(args):
|
||||
"""
|
||||
Copy networkd configs to volatile dir.
|
||||
The D-Bus API does not support creating new interfaces
|
||||
@ -42,8 +45,8 @@ def copy_files():
|
||||
"""
|
||||
|
||||
print("Copying network config files")
|
||||
dest = Path(NETWORKD_VOLATILE_DIR)
|
||||
src = Path(NETWORKD_CONFIGS)
|
||||
dest = Path(args.networkd_runtime_dir)
|
||||
src = Path(args.networkd_config_dir)
|
||||
|
||||
# Create the volatile directory if it doesn't exist
|
||||
dest.mkdir(parents=True, exist_ok=True)
|
||||
@ -53,60 +56,99 @@ def copy_files():
|
||||
copy(i, dest)
|
||||
|
||||
|
||||
def setup_devices(args):
|
||||
"""
|
||||
Setup wifi interfaces using iwd
|
||||
This function should be called every time an interface
|
||||
is connected or removed.
|
||||
args should be what parse_args() returns
|
||||
"""
|
||||
iwd = IWD()
|
||||
devices = iwd.get_devices()
|
||||
adhoc_devices = []
|
||||
ap_devices = []
|
||||
|
||||
# Find devices supporting ad-hoc and ap
|
||||
for i in devices:
|
||||
# For each device, check if its adapter supports
|
||||
# ad-hoc or ap. Many adapters will support both,
|
||||
# so we will prioritise ad-hoc over ap.
|
||||
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.
|
||||
# So we will remove adhoc_device from ap_devices if it exists there
|
||||
if adhoc_device.name in ap_devices:
|
||||
ap_devices.remove(adhoc_device.name)
|
||||
print("Starting mesh on", adhoc_device.name)
|
||||
# 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(args.adhoc_name)
|
||||
# Start Access point if ap_device is not empty,
|
||||
# ie, we have more devices
|
||||
if len(ap_devices) != 0:
|
||||
ap_device = Device(ap_devices.pop())
|
||||
print("Starting WiFi Access point on", ap_device.name)
|
||||
print('Use "naxalnet --print-wifi" to get password')
|
||||
# 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(args.ap_ssid, args.ap_passwd)
|
||||
|
||||
|
||||
def print_wifi(args):
|
||||
"""
|
||||
Prints the name and password of the adhoc, and ap
|
||||
from the arguments
|
||||
"""
|
||||
print("Mesh name:", args.adhoc_name)
|
||||
print("SSID:", args.ap_ssid)
|
||||
print("Password:", args.ap_passwd)
|
||||
|
||||
|
||||
def print_version():
|
||||
"""Just does what the name suggests"""
|
||||
print(__version__)
|
||||
|
||||
|
||||
def here_be_dragons():
|
||||
"""
|
||||
This is where the magic happens!
|
||||
This function is run every time you
|
||||
execute naxalnet from commandline
|
||||
execute naxalnet from the commandline
|
||||
"""
|
||||
args = parse_args()
|
||||
|
||||
if args.print_wifi:
|
||||
print_wifi(args)
|
||||
sys.exit(0)
|
||||
elif args.version:
|
||||
print_version()
|
||||
sys.exit(0)
|
||||
|
||||
try:
|
||||
copy_files()
|
||||
copy_files(args)
|
||||
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)
|
||||
setup_devices(args)
|
||||
except DBusError as error:
|
||||
print(error)
|
||||
sys.exit("An error occured while communicating with iwd")
|
||||
|
12
setup.cfg
12
setup.cfg
@ -2,11 +2,12 @@
|
||||
name = naxalnet
|
||||
version = attr: naxalnet.__version__
|
||||
description = create mesh networks with batman-adv and systemd
|
||||
long_description = file: README.md, LICENSE
|
||||
long_description = file: README.md
|
||||
url = https://git.disroot.org/pranav/naxalnet
|
||||
author = Pranav Jerry
|
||||
author_email = libreinator@disroot.org
|
||||
license = GPLv3
|
||||
license_files = LICENSE
|
||||
classifiers =
|
||||
License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
||||
Operating System :: POSIX :: Linux
|
||||
@ -18,15 +19,20 @@ packages = find:
|
||||
python_requires = >=3.6
|
||||
install_requires =
|
||||
dasbus
|
||||
configparser
|
||||
pathlib
|
||||
argparse
|
||||
|
||||
[options.entry_points]
|
||||
console_scripts =
|
||||
naxalnet = naxalnet.scripts:here_be_dragons
|
||||
|
||||
[options.data_files]
|
||||
/usr/lib/systemd/system =
|
||||
lib/systemd/system =
|
||||
naxalnet.service
|
||||
/usr/share/naxalnet/networkd =
|
||||
/etc/naxalnet =
|
||||
naxalnet.conf.example
|
||||
share/naxalnet/networkd =
|
||||
systemd-networkd/01-batman.netdev
|
||||
systemd-networkd/02-bridge.netdev
|
||||
systemd-networkd/03-wireless-ad-hoc.network
|
||||
|
Loading…
x
Reference in New Issue
Block a user