mirror of
https://git.disroot.org/pranav/pybatmesh.git
synced 2024-11-09 15:02:21 +05:30
Merge pull request 'Set gateway mode automatically' (#18) from gateway into master
Reviewed-on: https://git.disroot.org/pranav/naxalnet/pulls/18
This commit is contained in:
commit
a6f5b07310
23
CHANGELOG.md
23
CHANGELOG.md
@ -1,23 +1,28 @@
|
||||
# Changelog
|
||||
|
||||
## [Unreleased][] - 2021-09-21
|
||||
## [Unreleased][] - 2021-10-08
|
||||
|
||||
- Better error messages
|
||||
- Sets gateway mode automatically (to choose the best available
|
||||
connection). **This might cause problems with nodes running previous
|
||||
version of naxalnet** (#15)
|
||||
- Cleanup before exit
|
||||
- Closed #19
|
||||
|
||||
## [v0.4.0][] - 2021-09-20
|
||||
|
||||
- naxalnet is now a daemon! naxalnet will reconfigure the WiFi network
|
||||
every time a WiFi adapter is plugged in or removed
|
||||
every time a WiFi adapter is plugged in or removed (#14)
|
||||
- **Logging**: logs to systemd journal when run from systemd, stderr
|
||||
otherwise
|
||||
otherwise (#13)
|
||||
- New dependency `python-systemd`
|
||||
- Fixed dependency order in systemd service
|
||||
- Added `--verbose` argument
|
||||
|
||||
## [v0.3.0][] - 2021-08-19
|
||||
|
||||
- Support for arguments
|
||||
- Configuration file support with fallback values
|
||||
- Support for arguments (#11)
|
||||
- Configuration file support with fallback values (#11)
|
||||
- Made messages more readable
|
||||
- Improved documentation in docstrings
|
||||
- Changed default name of mesh network. **This will make naxalnet
|
||||
@ -26,15 +31,17 @@
|
||||
|
||||
## [v0.2.0][] - 2021-07-26
|
||||
|
||||
- rfkill support
|
||||
- rewrite into python module
|
||||
- rfkill support (#9)
|
||||
- rewrite into python module (#5)
|
||||
|
||||
## [v0.1.0][] - 2021-06-19
|
||||
|
||||
Initial python version. At first, this was a shell script. Than it was
|
||||
Rewrite to python. At first, this was a shell script. Then 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.
|
||||
|
||||
- Closed #1 and #3
|
||||
|
||||
[unreleased]: https://git.disroot.org/pranav/naxalnet/compare/v0.4.0...HEAD
|
||||
[v0.4.0]: https://git.disroot.org/pranav/naxalnet/compare/v0.3.0...v0.4.0
|
||||
[v0.3.0]: https://git.disroot.org/pranav/naxalnet/compare/v0.2.0...v0.3.0
|
||||
|
@ -5,13 +5,12 @@ Everyone can [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.
|
||||
<https://git.disroot.org/pranav/naxalnet/issues>
|
||||
|
||||
## Improving documentation
|
||||
|
||||
The README and HACKING.md needs to be more beginner friendly.
|
||||
See section below.
|
||||
See #20.
|
||||
|
||||
## Contribute code
|
||||
|
||||
@ -26,6 +25,6 @@ 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.
|
||||
post a message to issue #6.
|
||||
|
||||
[hack]: https://catb.org/jargon/html/H/hack.html
|
||||
|
@ -1,5 +0,0 @@
|
||||
include LICENSE
|
||||
include README.md
|
||||
include naxalnet.service
|
||||
include naxalnet.conf.example
|
||||
recursive-include systemd-networkd *
|
24
Makefile
24
Makefile
@ -1,27 +1,37 @@
|
||||
# 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.
|
||||
# This makefile uses setup.py under the hood. In debian, and therefore
|
||||
# ubuntu, and in fedora, 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
|
||||
|
||||
# This can be changed when creating a package for your POSIX distribution
|
||||
DESTDIR:= /
|
||||
|
||||
all: build
|
||||
|
||||
# Build only when naxalnet/__init__.py changes. We assume here that anyone
|
||||
# creating a new commit will first update the __version__ in
|
||||
# naxalnet/__init__.py
|
||||
build: naxalnet/__init__.py
|
||||
$(PYTHON) setup.py build
|
||||
|
||||
install: build
|
||||
install:
|
||||
$(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
|
||||
@echo "The directory /etc/naxalnet was not removed." && \
|
||||
@echo "make uninstall will not remove anything in /etc/naxalnet" && \
|
||||
echo "Do 'sudo make purge' to remove it."
|
||||
|
||||
# remove config files, like apt purge
|
||||
rpm:
|
||||
$(PYTHON) setup.py bdist_rpm --requires python3-dasbus,python3-systemd,iwd,systemd-networkd
|
||||
|
||||
# Remove config files, like apt purge. Purge should first do what
|
||||
# uninstall does, so we add uninstall as a dependency to this rule.
|
||||
purge: uninstall
|
||||
rm -rf /etc/naxalnet
|
||||
|
||||
clean:
|
||||
rm -rf build naxalnet.egg-info **/__pycache__
|
||||
rm -rf build *.egg-info **/__pycache__ dist
|
||||
|
156
README.md
156
README.md
@ -1,18 +1,15 @@
|
||||
# naxalnet
|
||||
|
||||
**naxalnet** is a program to create a wireless mesh network for
|
||||
communicating with each other. It can be useful during an
|
||||
[internet shutdown](#internet-shutdown), or to join
|
||||
[online classes](#online-class) 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.
|
||||
communicating with each other. It can be useful during an [internet
|
||||
shutdown](#internet-shutdown), or to join [online classes](#online-class)
|
||||
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
|
||||
network.
|
||||
**WARNING**: 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
|
||||
|
||||
@ -27,23 +24,24 @@ well-being if you get arrested under a draconian national security law.
|
||||
-->
|
||||
<!-- UNCOMMENT WHEN NECESSARY
|
||||
|
||||
**Disclaimer**:
|
||||
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 human rights groups designated as "terrorist" groups in India.
|
||||
**Disclaimer**: 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 human rights defenders or with anyone currently at
|
||||
risk of death in overcrowded prisons.
|
||||
|
||||
Using the name naxal does not imply any form of connection
|
||||
with anyone currently at risk of death in overcrowded prisons.
|
||||
Using the name naxal in a program will not shake the foundations of
|
||||
democracy nor affect the soverignty, unity or integrity of any
|
||||
nation-state. .
|
||||
|
||||
-->
|
||||
|
||||
## Requirements
|
||||
|
||||
- [systemd-networkd v248 or more][batman-systemd]
|
||||
- Linux kernel with batman-adv module
|
||||
- [systemd-networkd v248 or greater][batman-systemd]
|
||||
- Linux kernel with [batman-adv v2021.0][batman-systemd] or greater
|
||||
- [iwd][] for controlling the WiFi adapter
|
||||
- python3
|
||||
- python3-setuptools, for building and installing naxalnet
|
||||
- python (tested only on 3.9)
|
||||
- python setuptools, for building and installing naxalnet
|
||||
- [python-systemd][], for logging to systemd journal
|
||||
- [dasbus][], for communicating with iwd
|
||||
- two or more machines with a WiFi adapter having ibss support, called
|
||||
@ -53,8 +51,8 @@ with anyone currently at risk of death in overcrowded prisons.
|
||||
|
||||
## Installing
|
||||
|
||||
This program is available in the AUR for Arch users. Building
|
||||
manually for other distributions may not always work.
|
||||
This program is available in the AUR for Arch users. Users of other
|
||||
distributions will have to build manually.
|
||||
|
||||
### Arch Linux
|
||||
|
||||
@ -65,21 +63,17 @@ development version) from the AUR with your favourite helper:
|
||||
yay -S naxalnet
|
||||
```
|
||||
|
||||
Optionally, [setup systemd-resolved][arch-resolved] for DNS if any
|
||||
of the nodes have internet access. [Start naxalnet][startnx] when
|
||||
you need it.
|
||||
Optionally, [setup systemd-resolved][arch-resolved] for DNS. [Start
|
||||
naxalnet][startnx] when you need it.
|
||||
|
||||
### Ubuntu
|
||||
### Debian or Ubuntu
|
||||
|
||||
naxalnet is not packaged for Ubuntu, so you will have to build
|
||||
and install it manually.
|
||||
Currently, only the **unreleased 21.10** comes with the
|
||||
required version of systemd. Therefore, naxalnet **won't work on Ubuntu
|
||||
21.04 or older**.
|
||||
naxalnet is not packaged for Debian or Ubuntu, so you will have to build
|
||||
and install it manually. Currently, only Debian experimental and Ubuntu
|
||||
21.10 comes with the required version of systemd. Therefore, naxalnet
|
||||
requires **Debian experimental** or **Ubuntu 21.10 or greater** to work.
|
||||
|
||||
<!-- TODO: remove this message if systemd 248 arrives in 21.04 -->
|
||||
|
||||
Install the requirements from the Ubuntu repositories:
|
||||
Install the requirements from the repositories:
|
||||
|
||||
```sh
|
||||
# batctl is optional
|
||||
@ -93,20 +87,47 @@ Now follow the instructions in the
|
||||
|
||||
### 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:
|
||||
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**. python-setuptools support building rpms, which are the
|
||||
preferred way of installing software in Fedora. Follow the steps to
|
||||
install naxalnet on Fedora:
|
||||
|
||||
```sh
|
||||
# systemd-resolved may be required for rawhide
|
||||
sudo dnf install systemd-networkd iwd python3-dasbus python3-setuptools python3-systemd
|
||||
```
|
||||
# Install the build requirements
|
||||
sudo dnf install python3-setuptools make git
|
||||
|
||||
Now head over to the [next section][install-manual] to install naxalnet.
|
||||
# Clone the repo
|
||||
git clone https://git.disroot.org/pranav/naxalnet.git
|
||||
cd naxalnet
|
||||
|
||||
# Create an installable rpm from the source code
|
||||
make rpm
|
||||
|
||||
# Now install it. This will also install the requirements
|
||||
sudo dnf install dist/naxalnet-$(python3 -m setup --version)-1.noarch.rpm
|
||||
```
|
||||
|
||||
### Manually
|
||||
|
||||
Install the [requirements][requirements].
|
||||
Verify that the [requirements][] are of required versions.
|
||||
|
||||
```sh
|
||||
# Should be greater than or equal to 2021.0
|
||||
batctl -v
|
||||
|
||||
# 248 or greater
|
||||
systemctl --version
|
||||
|
||||
# Atleast 4.4
|
||||
uname -r
|
||||
|
||||
# >= 3.6
|
||||
python3 --version
|
||||
|
||||
# Check for IBSS (ad-hoc) support in your WiFi firmware or driver
|
||||
iw phy | grep -iq ibss && echo "IBSS is supported" || echo "IBSS not supported"
|
||||
```
|
||||
|
||||
Clone the naxalnet repo and cd into it.
|
||||
|
||||
@ -135,7 +156,8 @@ To upgrade, clean the build files, update the repo and reinstall:
|
||||
make clean
|
||||
git pull
|
||||
make
|
||||
sudo make uninstall install
|
||||
sudo make uninstall
|
||||
sudo make install
|
||||
```
|
||||
|
||||
This will keep the configuration files.
|
||||
@ -154,15 +176,16 @@ To start naxalnet, do the command on all the nodes:
|
||||
sudo systemctl start naxalnet.service
|
||||
```
|
||||
|
||||
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. Press
|
||||
Ctrl+C to stop `batctl`.
|
||||
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. Press Ctrl+C to stop `batctl`.
|
||||
|
||||
### Getting internet access
|
||||
|
||||
Connect an ethernet cable from a router to any of the nodes and
|
||||
renew the DHCP connection of all peers. To do this, type
|
||||
Connect an ethernet cable from a router to any of the nodes. Now restart
|
||||
naxalnet on the node to set `gateway_mode` to `server`. Other nodes will
|
||||
take a minute or more to renew DHCP. You can optionally do this manually
|
||||
if you don't want the delay. To do this, type
|
||||
`sudo networkctl renew bridge0` on all nodes.
|
||||
|
||||
### Tethering via WiFi AP
|
||||
@ -186,12 +209,26 @@ sudo systemctl enable naxalnet.service
|
||||
```
|
||||
|
||||
Now naxalnet will start a mesh on every boot.
|
||||
Disable the service to stop running at boot:
|
||||
|
||||
If you have NetworkManager enabled, which is the default in Ubuntu and
|
||||
Fedora, it should be disabled:
|
||||
|
||||
```sh
|
||||
sudo systemctl disable NetworkManager.service
|
||||
```
|
||||
|
||||
To stop running at boot, you should disable `naxalnet.service`:
|
||||
|
||||
```sh
|
||||
sudo systemctl disable naxalnet.service
|
||||
```
|
||||
|
||||
If you had disabled `NetworkManager` before, enable it:
|
||||
|
||||
```sh
|
||||
sudo systemctl enable NetworkManager.service
|
||||
```
|
||||
|
||||
### Stopping the service
|
||||
|
||||
```sh
|
||||
@ -224,6 +261,10 @@ arguments:
|
||||
naxalnet --help
|
||||
```
|
||||
|
||||
## Contributing or reporting bugs
|
||||
|
||||
See [HACKING.md](HACKING.md)
|
||||
|
||||
## How it works
|
||||
|
||||
There are three modes commonly supported by WiFi adapters - `ap` (WiFi
|
||||
@ -262,10 +303,11 @@ Withheld due to national security reasons.
|
||||
|
||||
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].
|
||||
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] and use the installed
|
||||
software to communicate with anyone within range.
|
||||
|
||||
## Uninstalling
|
||||
|
||||
@ -279,10 +321,6 @@ sudo make uninstall
|
||||
sudo make purge
|
||||
```
|
||||
|
||||
## Contributing or reporting bugs
|
||||
|
||||
See [HACKING.md](HACKING.md)
|
||||
|
||||
## Similar projects
|
||||
|
||||
Many projects make setting up B.A.T.M.A.N. Advanced mesh networks with
|
||||
|
@ -11,6 +11,19 @@ confdir = /usr/share/naxalnet/networkd
|
||||
# See man:systemd.network(5)
|
||||
runtimedir = /run/systemd/network
|
||||
|
||||
[device]
|
||||
# These are better left this way
|
||||
# Changing this won't do you any good, unless you have
|
||||
# other network configs that would mess things up.
|
||||
batman=bat0
|
||||
bridge=bridge0
|
||||
|
||||
[gateway]
|
||||
# This helps users choose the best network when multiple machines
|
||||
# offer an internet connection, or to be more precise, a DHCP server
|
||||
# Allowed values: auto, server, client or off
|
||||
mode=auto
|
||||
|
||||
[adhoc]
|
||||
# All your nodes should have the same name
|
||||
name = NxMesh
|
||||
@ -20,4 +33,3 @@ name = NxMesh
|
||||
ssid = MeshWiFi
|
||||
# Note the spelling. It's passwd, not password.
|
||||
passwd = naxalnet256
|
||||
|
||||
|
@ -21,16 +21,8 @@ Type=notify
|
||||
NotifyAccess=all
|
||||
Restart=on-failure
|
||||
RestartSec=2sec
|
||||
ExecStart=/usr/bin/naxalnet --systemd
|
||||
# Reload systemd-networkd after naxalnet signals it is ready
|
||||
ExecStartPost=/usr/bin/networkctl reload
|
||||
# When naxalnet exits, delete all files starting
|
||||
# with mesh.* in /run/systemd/network
|
||||
ExecStopPost=/usr/bin/find /run/systemd/network -type f -delete -name "mesh.*"
|
||||
# Then delete the two interfaces created...
|
||||
ExecStopPost=/usr/bin/networkctl delete bridge0 bat0
|
||||
# ... and reload the configuration files.
|
||||
ExecStopPost=/usr/bin/networkctl reload
|
||||
ExecStart=naxalnet --systemd
|
||||
KillSignal=SIGINT
|
||||
# naxalnet already logs to systemd journal so we don't need
|
||||
# stdout and stderr.
|
||||
StandardOutput=null
|
||||
|
@ -1,25 +1,32 @@
|
||||
# This file is part of naxalnet.
|
||||
# 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 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.
|
||||
# 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/>.
|
||||
# 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
|
||||
========
|
||||
|
||||
Create mesh networks with batman-adv, systemd-networkd and iwd.
|
||||
See README.md for documentation.
|
||||
|
||||
See README.md and the docstrings for documentation. You can read
|
||||
documentaion in the python interpretor using something like the example
|
||||
given below.
|
||||
|
||||
>>> help("naxalnet")
|
||||
>>> help("naxalnet.config")
|
||||
|
||||
"""
|
||||
|
||||
# GUIDE FOR CHANGING __version__
|
||||
@ -35,4 +42,4 @@ See README.md for documentation.
|
||||
#
|
||||
# In case you forgot to change the version, skip the number
|
||||
# and put the next number in the next commit.
|
||||
__version__ = "0.4.0a1"
|
||||
__version__ = "0.4.0a6"
|
||||
|
@ -16,9 +16,16 @@
|
||||
|
||||
|
||||
"""
|
||||
__main__.py
|
||||
-----------
|
||||
|
||||
If called as python -m naxalnet, this file makes naxalnet run like
|
||||
it was called from the commandline. Try:
|
||||
python -m naxalnet --help
|
||||
|
||||
WARNING: Using naxalnet might threaten the soverignity and integrity of
|
||||
your nation-state. The authors are not responsible for any damage caused
|
||||
while using this software.
|
||||
"""
|
||||
|
||||
from naxalnet.scripts import main
|
||||
|
@ -1,59 +1,56 @@
|
||||
# This file is part of naxalnet.
|
||||
# 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 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.
|
||||
# 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/>.
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
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.
|
||||
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:
|
||||
Some parts of naxalnet can be configured by configuration files and
|
||||
arguments in a specific order. 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.
|
||||
|
||||
- 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.
|
||||
- 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
|
||||
@ -158,6 +155,24 @@ def parse_args() -> Namespace:
|
||||
help="send log messages to systemd journal",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--batman-device",
|
||||
default=config["device"]["batman"],
|
||||
help="name of interface used by batman-adv",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--bridge-device",
|
||||
default=config["device"]["bridge"],
|
||||
help="name of bridge interface",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--gateway-mode",
|
||||
default=config["gateway"]["mode"],
|
||||
help="auto, server, client, or off",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--version",
|
||||
"-V",
|
||||
@ -170,8 +185,10 @@ def parse_args() -> Namespace:
|
||||
"-v", "--verbose", action="count", default=0, help="increase output verbosity"
|
||||
)
|
||||
|
||||
# logger.debug("Parsing arguments")
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
# This is defined here because log.py needs some arguments to determine
|
||||
# the loglevel and where to send the log message to. If you know a better
|
||||
# way of implementing it, create an issue
|
||||
args = parse_args()
|
||||
|
@ -1,24 +1,25 @@
|
||||
# This file is part of naxalnet.
|
||||
# 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 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.
|
||||
# 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/>.
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
daemon.py
|
||||
---------
|
||||
|
||||
The daemon part. This is currently under construction.
|
||||
The daemon part. This is used to perform some work when a new wifi adapter
|
||||
is plugged in, or it is removed.
|
||||
"""
|
||||
|
||||
from dasbus.loop import EventLoop
|
||||
@ -32,13 +33,14 @@ class Daemon:
|
||||
def __init__(self):
|
||||
self.loop = EventLoop()
|
||||
self.iwd = IWD()
|
||||
self.callback = None
|
||||
|
||||
def on_device_add(self, path, data):
|
||||
"""
|
||||
this function will be run every time a device is added
|
||||
"""
|
||||
if IWD_DEVICE_INTERFACE in data:
|
||||
logger.debug("New device %s found", str(data[IWD_DEVICE_INTERFACE]["Name"]))
|
||||
logger.debug("New device %s found", data[IWD_DEVICE_INTERFACE]["Name"])
|
||||
logger.info("Reloading")
|
||||
self.callback()
|
||||
|
||||
|
@ -1,29 +1,28 @@
|
||||
# This file is part of naxalnet.
|
||||
# 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 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.
|
||||
# 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/>.
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
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.
|
||||
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 = {
|
||||
@ -31,13 +30,17 @@ CONFIG = {
|
||||
"confdir": "/usr/share/naxalnet/networkd",
|
||||
"runtimedir": "/run/systemd/network",
|
||||
},
|
||||
"device": {"batman": "bat0", "bridge": "bridge0"},
|
||||
"adhoc": {"name": "NxMesh"},
|
||||
"ap": {"ssid": "MeshWiFi", "passwd": "naxalnet256"},
|
||||
"gateway": {"mode": "auto"},
|
||||
}
|
||||
|
||||
# glob
|
||||
CONFIG_FILES = ["naxalnet.conf", "naxalnet.conf.d/*.conf"]
|
||||
CONFIG_DIRS = ["/usr/share/naxalnet", "/usr/local/share/naxalnet", "/etc/naxalnet"]
|
||||
MESH_GLOB = "mesh.*"
|
||||
TMP_NET_GLOB = "tmp.*"
|
||||
|
||||
ISSUE_URL = "https://git.disroot.org/pranav/naxalnet/issues"
|
||||
REPORT_BUG_INFO = "If you think this is a bug, report it to " + ISSUE_URL
|
||||
|
109
naxalnet/iwd.py
109
naxalnet/iwd.py
@ -1,60 +1,54 @@
|
||||
# This file is part of naxalnet.
|
||||
# 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 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.
|
||||
# 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/>.
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
iwd.py
|
||||
------
|
||||
|
||||
This file contains methods to communicate with iwd via
|
||||
its D-Bus API and control WiFi adapters.
|
||||
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:
|
||||
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.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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
|
||||
- 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.
|
||||
- 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.
|
||||
- node: a machine that runs naxalnet and is therefore connected to the
|
||||
mesh.
|
||||
"""
|
||||
|
||||
from dasbus.connection import SystemMessageBus
|
||||
@ -74,7 +68,7 @@ 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 and self._proxy are meant for use only in this submodule
|
||||
self._bus = bus
|
||||
self.reload()
|
||||
|
||||
@ -95,9 +89,9 @@ class IWD:
|
||||
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
|
||||
# See comment in the function below
|
||||
path = i
|
||||
return path
|
||||
|
||||
def get_adapter_path_from_name(self, name: str) -> str:
|
||||
"""returns path of adapter as str"""
|
||||
@ -105,9 +99,10 @@ class IWD:
|
||||
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
|
||||
# We could have just used return here, but shutting up
|
||||
# pylint has a greter priority at the moment
|
||||
path = i
|
||||
return path
|
||||
|
||||
def get_all_device_paths(self) -> list:
|
||||
"""returns list of paths of all devices"""
|
||||
@ -132,7 +127,8 @@ class IWD:
|
||||
|
||||
def get_devices(self) -> list:
|
||||
"""
|
||||
returns list of device names as str
|
||||
returns list of all device names as str
|
||||
|
||||
example: ["wlan0", "wlan1"]
|
||||
"""
|
||||
devices = []
|
||||
@ -146,6 +142,7 @@ class IWD:
|
||||
def get_adapters(self) -> list:
|
||||
"""
|
||||
returns list of adapters
|
||||
|
||||
example: ["phy0","phy1"]
|
||||
"""
|
||||
adapters = []
|
||||
@ -160,6 +157,7 @@ class IWD:
|
||||
class Device:
|
||||
"""
|
||||
control devices with iwd
|
||||
|
||||
name: name of device (str)
|
||||
adapter: name of adapter (str)
|
||||
"""
|
||||
@ -190,7 +188,10 @@ class Device:
|
||||
self.reload()
|
||||
|
||||
def reload(self):
|
||||
"""reload the proxy after changing mode"""
|
||||
"""
|
||||
Reload the proxy. Used liberally by other
|
||||
members to work around errors
|
||||
"""
|
||||
self._proxy = self._bus.get_proxy(IWD_BUS, self._path)
|
||||
self.name = self._proxy.Name
|
||||
adapter_path = self._proxy.Adapter
|
||||
@ -235,16 +236,15 @@ class Device:
|
||||
if it isn't already on ad-hoc and power onn the device
|
||||
if it is off
|
||||
"""
|
||||
print("Starting adhoc", name)
|
||||
# Stop adhoc if already started
|
||||
self.stop_adhoc()
|
||||
|
||||
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()
|
||||
|
||||
logger.debug("Starting ad-hoc on %s", self.name)
|
||||
self._proxy.StartOpen(name)
|
||||
|
||||
@ -261,15 +261,16 @@ class Device:
|
||||
if it isn't already on ap and turning
|
||||
on the device if it is off
|
||||
"""
|
||||
|
||||
# Stop ap if already started
|
||||
self.stop_ap()
|
||||
|
||||
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()
|
||||
|
||||
logger.debug("Starting ap on %s with ssid %s", self.name, ssid)
|
||||
self._proxy.Start(ssid, passwd)
|
||||
|
||||
|
@ -18,8 +18,9 @@
|
||||
log.py
|
||||
------
|
||||
|
||||
Initialise the logger for other submodules to import. Do not
|
||||
import any submodules here except for naxallnet.config
|
||||
Initialise the logger for other submodules to import. Do not import any
|
||||
submodules here other than naxallnet.config, which is needed to set the
|
||||
loglevel and to add the systemd journal handler
|
||||
"""
|
||||
import logging
|
||||
from systemd.journal import JournalHandler
|
||||
|
120
naxalnet/network.py
Normal file
120
naxalnet/network.py
Normal file
@ -0,0 +1,120 @@
|
||||
# This file is part of naxalnet.
|
||||
# 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/>.
|
||||
|
||||
"""
|
||||
network.py
|
||||
----------
|
||||
|
||||
This submodule manages the systemd-networkd configuration. This is used to
|
||||
add configuration files to the systemd-networkd runtime directory.
|
||||
|
||||
Some configuration files have variables which should be substituted by
|
||||
str.format() in python. The values for these variables can be set using
|
||||
NetworkD.set_vars(). See files in the systemd-networkd directory for
|
||||
examples.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from dasbus.connection import SystemMessageBus
|
||||
|
||||
|
||||
NETWORKD_BUS = "org.freedesktop.network1"
|
||||
NETWORKD_PATH = "/org/freedesktop/network1"
|
||||
|
||||
|
||||
class NetworkD:
|
||||
"""
|
||||
Control systemd-networkd using configuration files. Since these
|
||||
were made for use by naxalnet only, the class is not suitable for
|
||||
importing outside naxalnet.
|
||||
"""
|
||||
|
||||
def __init__(self, runtime_dir="/run/systemd/network", bus=SystemMessageBus()):
|
||||
self._bus = bus
|
||||
self.proxy_reload()
|
||||
|
||||
self.variables = {}
|
||||
self.runtime_path = Path(runtime_dir)
|
||||
# Create the runtime directory if it doesn't exist
|
||||
self.runtime_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def set_vars(self, **variables):
|
||||
"""set the variables to replace with str.format"""
|
||||
self.variables = variables
|
||||
|
||||
def proxy_reload(self) -> None:
|
||||
"""reload the proxy"""
|
||||
self.proxy = self._bus.get_proxy(NETWORKD_BUS, NETWORKD_PATH)
|
||||
|
||||
def reload(self) -> None:
|
||||
"""
|
||||
Reload the systemd-networkd configuration. This is used by many
|
||||
class methods after doing their job.
|
||||
"""
|
||||
self.proxy.Reload()
|
||||
|
||||
def add_config(self, name: str) -> None:
|
||||
"""add config file to runtime directory and reload networkd"""
|
||||
source = Path(name)
|
||||
destination = self.runtime_path / source.name
|
||||
|
||||
# Substitute variables in the config
|
||||
text = source.read_text(encoding="utf-8").format(**self.variables)
|
||||
# now write it to a runtime config of the same name
|
||||
destination.write_text(text, encoding="utf-8")
|
||||
self.reload()
|
||||
|
||||
def is_routable(self) -> bool:
|
||||
"""returns true if any interface is routable"""
|
||||
return self.proxy.AddressState == "routable"
|
||||
|
||||
def delete_interface(self, name: str) -> None:
|
||||
"""delete the given interface"""
|
||||
# If anyone knows a better way of doing this, create
|
||||
# an issue and get things done
|
||||
subprocess.run(["networkctl", "delete", name], check=True)
|
||||
# This is probably not required. This is mainly to shut up
|
||||
# pylint's messages
|
||||
self.reload()
|
||||
|
||||
def disable_config(self, name: str) -> None:
|
||||
"""
|
||||
Disable or mask the config of the same name. This can only be
|
||||
used for configs in /usr/lib/systemd/network and
|
||||
/usr/local/lib/systemd/network. It works on the same principle
|
||||
used by systemctl mask, that is, it created a symlink of the same
|
||||
name in the runtime directory and links it to /dev/null.
|
||||
"""
|
||||
path = self.runtime_path / name
|
||||
path.symlink_to("/dev/null")
|
||||
self.reload()
|
||||
|
||||
def remove_config(self, name: str) -> None:
|
||||
"""
|
||||
remove the file called 'name' from the runtime dir and reload
|
||||
"""
|
||||
path = self.runtime_path / name
|
||||
path.unlink()
|
||||
self.reload()
|
||||
|
||||
def remove_all_configs(self) -> None:
|
||||
"""
|
||||
Remove all configs in runtime_path. This will remove all files
|
||||
in runtime_path without checking who put them there.
|
||||
"""
|
||||
for i in self.runtime_path.iterdir():
|
||||
self.remove_config(i.name)
|
@ -27,39 +27,80 @@ When run from the commandline, the function main() is called.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
from shutil import copy
|
||||
from dasbus.error import DBusError
|
||||
from systemd.daemon import notify
|
||||
from naxalnet import __version__
|
||||
from naxalnet.default import REPORT_BUG_INFO
|
||||
from naxalnet.default import REPORT_BUG_INFO, MESH_GLOB, TMP_NET_GLOB
|
||||
from naxalnet.log import logger
|
||||
from naxalnet.iwd import Adapter, Device, IWD
|
||||
from naxalnet.config import args
|
||||
from naxalnet.daemon import Daemon
|
||||
from naxalnet.network import NetworkD
|
||||
|
||||
|
||||
def copy_files():
|
||||
def get_sorted_glob(directory: str, glob: str) -> list:
|
||||
"""return sorted list of filenames matching glob"""
|
||||
path = Path(directory)
|
||||
glob_list = path.glob(glob)
|
||||
sorted_list = []
|
||||
for i in glob_list:
|
||||
# g is a list of PosixPath objects.
|
||||
# So we add their absolute path as str.
|
||||
sorted_list.append(str(i))
|
||||
# sorted_list is not sorted, so we sort them here
|
||||
sorted_list.sort()
|
||||
return sorted_list
|
||||
|
||||
|
||||
def any_interface_is_routable():
|
||||
"""returns true if any of the interfaces is routable"""
|
||||
networkd = NetworkD(runtime_dir=args.networkd_runtime_dir)
|
||||
|
||||
# First, add the temporary configs to networkd.
|
||||
for i in get_sorted_glob(args.networkd_config_dir, TMP_NET_GLOB):
|
||||
logger.debug("Adding temporary config %s", i)
|
||||
networkd.add_config(i)
|
||||
# Then, wait for some time to setup the network.
|
||||
# This can probably be replaced by a d-bus wait-for-signal
|
||||
# function that timeouts after 10 seconds.
|
||||
time.sleep(10)
|
||||
routable = networkd.is_routable()
|
||||
networkd.remove_all_configs()
|
||||
|
||||
return routable
|
||||
|
||||
|
||||
def setup_mesh(gateway_mode: str = "off"):
|
||||
"""
|
||||
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)
|
||||
configure networkd to setup the mesh
|
||||
|
||||
gateway_mode can be client, server, or off
|
||||
"""
|
||||
try:
|
||||
notify("STATUS=Configuring the network...")
|
||||
logger.info("Copying network config files")
|
||||
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)
|
||||
networkd = NetworkD(runtime_dir=args.networkd_runtime_dir)
|
||||
networkd.set_vars(
|
||||
batdev=args.batman_device,
|
||||
bridgedev=args.bridge_device,
|
||||
gateway_mode=gateway_mode,
|
||||
)
|
||||
|
||||
# Copy all files in src to dest
|
||||
for i in src.iterdir():
|
||||
copy(i, dest)
|
||||
# Fix for issue #19. There should be a switch to disable this
|
||||
# humanitarian intervention. We don't want to adopt the U.S.
|
||||
# foreign policy here.
|
||||
networkd.disable_config("80-wifi-adhoc.network")
|
||||
|
||||
for i in get_sorted_glob(args.networkd_config_dir, MESH_GLOB):
|
||||
logger.debug("Adding network config %s", i)
|
||||
networkd.add_config(i)
|
||||
except PermissionError:
|
||||
logger.exception("A PermissionError occured while copying files")
|
||||
logger.exception(
|
||||
"A PermissionError occured while copying files. Make sure you are root."
|
||||
)
|
||||
logger.error(REPORT_BUG_INFO)
|
||||
sys.exit(3)
|
||||
except:
|
||||
@ -111,8 +152,10 @@ def setup_devices():
|
||||
if not adhoc_adapter.is_powered_on():
|
||||
logger.debug("Adapter %s is off. Turning on", adhoc_adapter.name)
|
||||
adhoc_adapter.power_on()
|
||||
|
||||
logger.info("Starting mesh on %s", adhoc_device.name)
|
||||
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:
|
||||
@ -138,11 +181,30 @@ def setup_devices():
|
||||
logger.error(REPORT_BUG_INFO)
|
||||
sys.exit(4)
|
||||
except:
|
||||
logger.exception("An unknow error occured while setting up the mesh")
|
||||
logger.exception("An unknown error occured while setting up the mesh")
|
||||
logger.error(REPORT_BUG_INFO)
|
||||
sys.exit(4)
|
||||
|
||||
|
||||
def cleanup():
|
||||
"""
|
||||
Remove all network config, poweroff used wireless devices and
|
||||
exit with 0.
|
||||
"""
|
||||
networkd = NetworkD(runtime_dir=args.networkd_runtime_dir)
|
||||
logger.info("Exiting gracefully")
|
||||
networkd.remove_all_configs()
|
||||
for i in IWD().get_devices():
|
||||
logger.debug("Turning off %s", i)
|
||||
device = Device(i)
|
||||
# device.set_mode("station")
|
||||
device.power_off()
|
||||
logger.debug("Deleting interface %s", args.batman_device)
|
||||
networkd.delete_interface(args.batman_device)
|
||||
logger.debug("Deleting interface %s", args.bridge_device)
|
||||
networkd.delete_interface(args.bridge_device)
|
||||
|
||||
|
||||
def print_wifi():
|
||||
"""
|
||||
Prints the name and password of the adhoc, and ap
|
||||
@ -171,20 +233,40 @@ def main():
|
||||
elif args.version:
|
||||
print_version()
|
||||
sys.exit(0)
|
||||
copy_files()
|
||||
|
||||
setup_devices()
|
||||
# Notify systemd that naxalnet is ready.
|
||||
# see man:sd_notify(3)
|
||||
notify("READY=1")
|
||||
|
||||
# Start the daemon so that setup_devices() is called every
|
||||
# time a device is connected or removed.
|
||||
daemon = Daemon()
|
||||
daemon.add_callback(setup_devices)
|
||||
# Gateway mode comes in handy when many nodes have a DHCP server and
|
||||
# you want to prevent conflicts. It defaults to "auto" in naxalnet.
|
||||
# https://www.open-mesh.org/projects/batman-adv/wiki/Gateways
|
||||
if args.gateway_mode == "auto":
|
||||
logger.info("Checking for internet connection")
|
||||
notify("STATUS=Checking for internet")
|
||||
# If any interface is routable, set gateway mode to server
|
||||
if any_interface_is_routable():
|
||||
gateway_mode = "server"
|
||||
else:
|
||||
gateway_mode = "client"
|
||||
logger.info("gateway_mode set to %s", gateway_mode)
|
||||
elif args.gateway_mode in ["server", "client", "off"]:
|
||||
gateway_mode = args.gateway_mode
|
||||
else:
|
||||
logger.error("gateway-mode has an illegal value")
|
||||
sys.exit(5)
|
||||
|
||||
notify("STATUS=Waiting for changes")
|
||||
daemon.start()
|
||||
try:
|
||||
setup_devices()
|
||||
setup_mesh(gateway_mode=gateway_mode)
|
||||
|
||||
# naxalnet prints Bye while exiting.
|
||||
logger.info("Bye")
|
||||
# Start the daemon so that setup_devices() is called every
|
||||
# time a device is connected or removed.
|
||||
daemon = Daemon()
|
||||
daemon.add_callback(setup_devices)
|
||||
|
||||
notify("STATUS=Waiting for changes")
|
||||
daemon.start()
|
||||
# systemd uses SIGINT to kill this program
|
||||
except KeyboardInterrupt:
|
||||
cleanup()
|
||||
|
@ -1,3 +1,4 @@
|
||||
# This program is not meant to be distributed through PyPi
|
||||
[metadata]
|
||||
name = naxalnet
|
||||
version = attr: naxalnet.__version__
|
||||
@ -34,7 +35,7 @@ console_scripts =
|
||||
lib/systemd/system =
|
||||
naxalnet.service
|
||||
# If installing with pip, this file will be copied to some other place.
|
||||
# This is the reason we use setup.py instead of pip.
|
||||
# This is the reason we use setup.py instead of pip in the Makefile.
|
||||
/etc/naxalnet =
|
||||
naxalnet.conf.example
|
||||
share/naxalnet/networkd =
|
||||
@ -45,3 +46,4 @@ share/naxalnet/networkd =
|
||||
systemd-networkd/mesh.05-wireless-ap.network
|
||||
systemd-networkd/mesh.06-eth.network
|
||||
systemd-networkd/mesh.07-bridge.network
|
||||
systemd-networkd/tmp.01-eth.network
|
||||
|
@ -1,10 +1,13 @@
|
||||
# Create the BATMAN interface
|
||||
# See 04-batman.network for configuration details
|
||||
# See mesh.04-batman.network for configuration details
|
||||
[NetDev]
|
||||
Name=bat0
|
||||
Name={batdev}
|
||||
Description=BATMAN interface
|
||||
Kind=batadv
|
||||
|
||||
# Use default settings. Uncomment to change
|
||||
# see man:systemd.netdev(5) § [BATMANADVANCED] SECTION OPTIONS
|
||||
#[BatmanAdvanced]
|
||||
# See man:systemd.netdev(5) § [BATMANADVANCED] SECTION OPTIONS
|
||||
[BatmanAdvanced]
|
||||
# This helps choose the best network when many nodes have a DHCP
|
||||
# server. See the B.A.T.M.A.N. documentation at
|
||||
# https://www.open-mesh.org/projects/batman-adv/wiki/Gateways
|
||||
GatewayMode={gateway_mode}
|
||||
|
@ -1,8 +1,8 @@
|
||||
# Create a bridge interface
|
||||
# The batman interface be will later linked to this bridge.
|
||||
# See 07-bridge.network to see how this bridge is configured
|
||||
# See mesh.07-bridge.network to see how this bridge is configured
|
||||
[NetDev]
|
||||
Name=bridge0
|
||||
Name={bridgedev}
|
||||
Description=Bridge
|
||||
Kind=bridge
|
||||
|
||||
|
@ -10,7 +10,7 @@ MTUBytes=1560
|
||||
|
||||
[Network]
|
||||
Description=ad-hoc network connecting to other nodes
|
||||
BatmanAdvanced=bat0
|
||||
BatmanAdvanced={batdev}
|
||||
# This interface should not have any IP addresses assigned.
|
||||
# IP will be given later to the bridge
|
||||
DHCP=no
|
||||
|
@ -1,11 +1,11 @@
|
||||
[Match]
|
||||
Name=bat0
|
||||
Name={batdev}
|
||||
|
||||
[Network]
|
||||
Description=The BATMAN interface
|
||||
Bridge=bridge0
|
||||
Description=Configuration for the BATMAN interface
|
||||
Bridge={bridgedev}
|
||||
|
||||
# like in 03-wireless-ad-hoc.network, this interface
|
||||
# like in mesh.03-wireless-ad-hoc.network, this interface
|
||||
# also shouldn't have IP address the address will
|
||||
# be assigned to the bridge
|
||||
DHCP=no
|
||||
|
@ -8,10 +8,10 @@
|
||||
WLANInterfaceType=ap
|
||||
|
||||
[Network]
|
||||
Description=Wireless AP
|
||||
Description=Configuration for Wireless AP
|
||||
|
||||
# link the interface to the bridge
|
||||
Bridge=bridge0
|
||||
Bridge={bridgedev}
|
||||
|
||||
# Like in the ad-hoc network and bat0, this interface
|
||||
# should not have any ip address assigned to it.
|
||||
|
@ -1,8 +1,9 @@
|
||||
# This file bridges any ethernet device found
|
||||
# to the bridge made in 02-bridge.netdev
|
||||
# to the bridge made in mesh.02-bridge.netdev
|
||||
[Match]
|
||||
Name=en*
|
||||
Name=eth*
|
||||
|
||||
[Network]
|
||||
Bridge=bridge0
|
||||
Description=Connect ethernet to the bridge
|
||||
Bridge={bridgedev}
|
||||
|
@ -3,13 +3,15 @@
|
||||
# communicate with others devices
|
||||
|
||||
[Match]
|
||||
Name=bridge0
|
||||
Name={bridgedev}
|
||||
|
||||
[Network]
|
||||
# use DHCP to assign an IP
|
||||
Description=bridge to link non-batman machines
|
||||
# Use DHCP to assign an IP
|
||||
DHCP=yes
|
||||
|
||||
# if DHCP fails, assign a random address
|
||||
# If DHCP fails, assign a random address. This is probably the default,
|
||||
# but we are specifying it anyway.
|
||||
LinkLocalAddressing=yes
|
||||
|
||||
# LLMNR and MulticastDNS are used for hostname discovery
|
||||
|
10
systemd-networkd/tmp.01-eth.network
Normal file
10
systemd-networkd/tmp.01-eth.network
Normal file
@ -0,0 +1,10 @@
|
||||
# This is used to check if any ethernet or USB ethernet ports
|
||||
# is connected to a router or some other device with a DHCP server.
|
||||
# After checking, this file is no longer needed.
|
||||
[Match]
|
||||
Name=eth*
|
||||
Name=en*
|
||||
|
||||
[Network]
|
||||
Description=Check for ethernet connection
|
||||
DHCP=yes
|
Loading…
Reference in New Issue
Block a user