mirror of
https://git.disroot.org/pranav/pybatmesh.git
synced 2025-04-19 09:29:11 +05:30
Compare commits
121 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
566f562d33 | ||
1106945732 | |||
|
d45ac72442 | ||
3354584045 | |||
0c6bdea4a8 | |||
|
9123224de0 | ||
396fe9af7e | |||
72dda12d7b | |||
38d0aa8ab5 | |||
fad2591b9f | |||
|
05b91e7721 | ||
4d4e5e15d7 | |||
6bca6149b7 | |||
710da18af9 | |||
888fdf3856 | |||
fc1f3d4216 | |||
5e58df0b71 | |||
d7a84d8ccc | |||
183ce16eca | |||
caeb042612 | |||
f657146eb3 | |||
cd44357496 | |||
fbf518e14c | |||
28de9570b5 | |||
009f6364cd | |||
a09ababd06 | |||
9749cf0c00 | |||
|
542347eac7 | ||
a5ba99ca2a | |||
|
0d5d3c5cc6 | ||
26a907d907 | |||
704fe646f8 | |||
aa079c7c29 | |||
295fde3f0b | |||
270db3cf90 | |||
6fbebc51bb | |||
1f8be50dd6 | |||
c4933378ff | |||
0a85c465ee | |||
5dd90d349e | |||
|
a6f5b07310 | ||
de63113098 | |||
e56ff40495 | |||
3b3644e107 | |||
65e1906753 | |||
6acd7084f2 | |||
61a96ea3b3 | |||
a7304a986b | |||
32e9559e6e | |||
a061852a59 | |||
5bde1faeba | |||
87612fac2c | |||
2e4c3a70a4 | |||
d0389e5638 | |||
8ba8d6af6c | |||
761618aff4 | |||
798cd3e988 | |||
a81449b898 | |||
ab3252683a | |||
8f905ed970 | |||
25ac54dfad | |||
25a5bdee30 | |||
9171b942db | |||
ea283a3247 | |||
8137b5067b | |||
5f7c59d4b8 | |||
c8f032a3d0 | |||
|
74a061507f | ||
5eb55c19a2 | |||
2a8930ce00 | |||
f9c969d233 | |||
c638de4c9c | |||
ca1e721c9e | |||
68b53ccad1 | |||
6fff558405 | |||
0bcd31b6e3 | |||
2d9aee4d3a | |||
a3e9b45050 | |||
|
33156e6a8d | ||
4d9de4d3c3 | |||
97b1f46535 | |||
ee341d6967 | |||
3774076e03 | |||
87c5d48144 | |||
e4a7fa5d3f | |||
4db6d9457f | |||
4ea53e5a35 | |||
09ea47e609 | |||
d8dcf10b76 | |||
feb362b149 | |||
1a6dbc4bcb | |||
9f8a5b3d0d | |||
fdbbca686d | |||
be8de69b73 | |||
7e0fe5ef4c | |||
274f08cded | |||
d1ec77dc69 | |||
cf54edf9b9 | |||
e99b3222e1 | |||
d18160c46c | |||
397269823d | |||
d7a9edc1e8 | |||
fe146b7a0d | |||
b50d0e3656 | |||
550529e3d0 | |||
dfd521f9b9 | |||
90464f0304 | |||
e24ff03e0c | |||
2f97bab5cf | |||
a798ac8051 | |||
fb4b11b9fd | |||
ebc7e39d76 | |||
2e4149d943 | |||
df73f94018 | |||
3d63ddd2d2 | |||
5db3d1dc09 | |||
f55fc74ad4 | |||
16dff8bb49 | |||
946d20a72c | |||
7b7ce8044b | |||
f6a5a8556b |
151
.gitignore
vendored
151
.gitignore
vendored
@ -1,10 +1,145 @@
|
|||||||
.DS_Store
|
|
||||||
.idea
|
|
||||||
*.log
|
|
||||||
tmp/
|
|
||||||
|
|
||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/python
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=python
|
||||||
|
|
||||||
|
### Python ###
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
*.egg*
|
*$py.class
|
||||||
build
|
|
||||||
htmlcov
|
# C extensions
|
||||||
__pycache__
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/python
|
||||||
|
77
CHANGELOG.md
Normal file
77
CHANGELOG.md
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## [v0.5.3][] - 2022-08-03
|
||||||
|
|
||||||
|
- Renamed to pybatmesh, to be more clear what the program does
|
||||||
|
- code cleanup
|
||||||
|
|
||||||
|
To update via the repo, do the following:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git remote set-url origin git@git.disroot.org:pranav/pybatmesh.git
|
||||||
|
# or
|
||||||
|
git remote set-url origin https://git.disroot.org/pranav/pybatmesh.git
|
||||||
|
# remove naxlnet and install pybatmesh
|
||||||
|
git pull && git checkout 38d0aa8ab5dd60f2febffda335df6df1ea143ab3 && make clean && sudo make purge && git checkout main && make && sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
## [v0.5.2][] - 2021-12-10
|
||||||
|
|
||||||
|
- Optimised auto gateway mode selection (#25)
|
||||||
|
|
||||||
|
## [v0.5.1][] - 2021-10-22
|
||||||
|
|
||||||
|
- Fixed stopping at boot when GNOME starts location service (#21)
|
||||||
|
- Changes in directory structure
|
||||||
|
|
||||||
|
## [v0.5.0][] - 2021-10-10
|
||||||
|
|
||||||
|
- 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 (#14)
|
||||||
|
- **Logging**: logs to systemd journal when run from systemd, stderr
|
||||||
|
otherwise (#13)
|
||||||
|
- New dependency `python-systemd`
|
||||||
|
- Fixed dependency order in systemd service
|
||||||
|
- Added `--verbose` argument
|
||||||
|
|
||||||
|
## [v0.3.0][] - 2021-08-19
|
||||||
|
|
||||||
|
- 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
|
||||||
|
incompatible with nodes running previous versions.**
|
||||||
|
- New versioning scheme that conforms to PEP 440
|
||||||
|
|
||||||
|
## [v0.2.0][] - 2021-07-26
|
||||||
|
|
||||||
|
- rfkill support (#9)
|
||||||
|
- rewrite into python module (#5)
|
||||||
|
|
||||||
|
## [v0.1.0][] - 2021-06-19
|
||||||
|
|
||||||
|
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/pybatmesh/compare/v0.5.3...HEAD
|
||||||
|
[v0.5.3]: https://git.disroot.org/pranav/pybatmesh/compare/v0.5.2...v0.5.3
|
||||||
|
[v0.5.2]: https://git.disroot.org/pranav/pybatmesh/compare/v0.5.1...v0.5.2
|
||||||
|
[v0.5.1]: https://git.disroot.org/pranav/pybatmesh/compare/v0.5.0...v0.5.1
|
||||||
|
[v0.5.0]: https://git.disroot.org/pranav/pybatmesh/compare/v0.4.0...v0.5.0
|
||||||
|
[v0.4.0]: https://git.disroot.org/pranav/pybatmesh/compare/v0.3.0...v0.4.0
|
||||||
|
[v0.3.0]: https://git.disroot.org/pranav/pybatmesh/compare/v0.2.0...v0.3.0
|
||||||
|
[v0.2.0]: https://git.disroot.org/pranav/pybatmesh/compare/v0.1.0...v0.2.0
|
||||||
|
[v0.1.0]: https://git.disroot.org/pranav/pybatmesh/releases/tag/v0.1.0
|
28
HACKING.md
28
HACKING.md
@ -1,23 +1,33 @@
|
|||||||
# Hacking
|
# Hacking
|
||||||
|
|
||||||
Everyone <!-- including anti-nationals and urban naxals are -->
|
Everyone can [hack][] pybatmesh. See below for how to hack.
|
||||||
is welcome to [hack][] naxalnet. See below for how to hack.
|
|
||||||
|
|
||||||
## Reporting issues and suggesting ideas
|
## Reporting issues and suggesting ideas
|
||||||
|
|
||||||
To report a bug or suggest an idea, create a new issue at
|
To report a bug or suggest an idea, create a new issue at
|
||||||
<https://git.disroot.org/pranav/naxalnet/issues> with a
|
<https://git.disroot.org/pranav/pybatmesh/issues>
|
||||||
relevant label.
|
|
||||||
|
While reporting a bug, you can add the debug messages to provide more
|
||||||
|
data. Run `journalctl -fu pybatmesh` on a terminal emulator (this could
|
||||||
|
take some time on some machines). Now on another one, type `sudo systemctl start pybatmesh.service` or whatever caused the error. Now copy the error
|
||||||
|
messages and paste it in the issue body along with the description.
|
||||||
|
|
||||||
|
## Improving documentation
|
||||||
|
|
||||||
|
The README and HACKING.md needs to be more beginner friendly. See #20.
|
||||||
|
|
||||||
## Contribute code
|
## Contribute code
|
||||||
|
|
||||||
To push to this repo, you need your username to be in the
|
To push to this repo, you need your username to be in the contributors
|
||||||
contributors list. See issue #8.
|
list. Add your username to issue #8 to add you as a contributor. Before
|
||||||
|
each commit, update the CHANGELOG.md and `__version__` in
|
||||||
|
`pybatmesh/__init__.py`
|
||||||
|
|
||||||
## Packaging
|
## Packaging
|
||||||
|
|
||||||
naxalnet needs distro packages in Debian, Fedora, openSUSE,
|
Currently this program is only packaged for Arch Linux. pybatmesh needs
|
||||||
and nixos. If you know/like to package it in your distro,
|
packages in GNU+Linux+systemd distributions such as Debian, Fedora,
|
||||||
post to issue #6.
|
openSUSE, and nixos. If you know/like to package it in your distro, post a
|
||||||
|
message to issue #6.
|
||||||
|
|
||||||
[hack]: https://catb.org/jargon/html/H/hack.html
|
[hack]: https://catb.org/jargon/html/H/hack.html
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
include LICENSE
|
|
||||||
include README.md
|
|
||||||
include naxalnet.service
|
|
||||||
include systemd-networkd/*
|
|
38
Makefile
38
Makefile
@ -1,11 +1,37 @@
|
|||||||
# This makefile uses setup.py under the hood
|
# 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
|
all: build
|
||||||
|
|
||||||
build:
|
# Build only when pybatmesh/__init__.py changes. We assume here that anyone
|
||||||
python setup.py build
|
# creating a new commit will first update the __version__ in
|
||||||
|
# pybatmesh/__init__.py
|
||||||
|
build: pybatmesh/__init__.py
|
||||||
|
$(PYTHON) setup.py build
|
||||||
|
|
||||||
install: build
|
install:
|
||||||
python setup.py install --root="$(DESTDIR)/" --optimize=1 --skip-build
|
$(PYTHON) setup.py install --root="$(DESTDIR)" --optimize=1 --skip-build
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
$(PIP) uninstall -y pybatmesh
|
||||||
|
rm -rf /usr/share/pybatmesh /usr/lib/systemd/system/pybatmesh.service
|
||||||
|
@echo "make uninstall will not remove anything in /etc/pybatmesh" && \
|
||||||
|
echo "Do 'sudo make purge' to remove it."
|
||||||
|
|
||||||
|
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/pybatmesh
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf build naxalnet.egg-info
|
rm -rf build *.egg-info **/__pycache__ dist
|
||||||
|
374
README.md
374
README.md
@ -1,205 +1,343 @@
|
|||||||
# naxalnet
|
# pybatmesh
|
||||||
|
|
||||||
**naxalnet** is an experiment to create a wireless mesh network for
|
**pybatmesh** is a program to create a wireless mesh network for
|
||||||
communicating with each other during an internet shutdown, using
|
communicating with each other. It can be useful during an [internet
|
||||||
existing software and tech as much as possible. Currently
|
shutdown](#internet-shutdown), or to join [online classes](#online-class)
|
||||||
you can only communicate with other peers running naxalnet or
|
with a group of laptops. It uses [B.A.T.M.A.N. Advanced][batman-adv], an
|
||||||
using the same network as naxalnet. It uses
|
implementation of the B.A.T.M.A.N. routing protocol to communicate with
|
||||||
[B.A.T.M.A.N. Advanced][batman-adv],
|
peers.
|
||||||
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,
|
**WARNING**: This program uses an **unencrypted** network. This means you do
|
||||||
West Bengal.
|
not get any more privacy or security than with an open WiFi network.
|
||||||
|
|
||||||
<!-- UNCOMMENT WHEN NECESSARY
|
## Features
|
||||||
|
|
||||||
**Disclaimer**:
|
- Select best network when multiple nodes have internet access (gateway
|
||||||
In case you are either 1) a complete idiot; or 2) a member of the saffron
|
mode)
|
||||||
brigade; or 3) both, please be aware that this project is not affiliated
|
- Detect insertion and removal of wifi adapters and reconfigure them
|
||||||
with any groups designated as "terrorist" groups in India.
|
- Readable logs
|
||||||
|
- Supports rfkill
|
||||||
Using the name Naxal does not imply any form of connection
|
|
||||||
with anyone the government of India collectively calles Urban
|
|
||||||
Naxals (human rights activists, lawyers, poets, writers, journalists
|
|
||||||
or anyone else advocating for their rights).
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- systemd{,-networkd} v248 or more (for [batman support][batman-systemd])
|
- [systemd-networkd v248 or greater][batman-systemd]
|
||||||
- Linux kernel with batman-adv module (if `modinfo batman-adv` shows
|
- Linux kernel with [batman-adv v2021.0][batman-systemd] or greater
|
||||||
no error then you already have it)
|
- [iwd][] for controlling the WiFi adapter
|
||||||
- iwd (for starting ad-hoc network)
|
- python (tested on 3.9 and 3.10)
|
||||||
- python3
|
- python setuptools, for building and installing pybatmesh
|
||||||
- python-setuptools (for building)
|
- [python-systemd][], for logging to systemd journal
|
||||||
- [python-dasbus][]
|
- [dasbus][], for communicating with iwd
|
||||||
- wifi adapter with ad-hoc support
|
- two or more machines with a WiFi adapter having ibss support, called
|
||||||
- two or more computers with wifi adapter, called nodes
|
nodes or peers
|
||||||
- systemd-resolved (optional, for DNS)
|
|
||||||
- batctl (optional, for debugging)
|
- batctl (optional, for debugging)
|
||||||
|
- python3-pip (for installing dasbus on Debian-based distributions)
|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
|
|
||||||
|
This program is available in the AUR for Arch users. Users of other
|
||||||
|
distributions will have to build manually.
|
||||||
|
|
||||||
### Arch Linux
|
### Arch Linux
|
||||||
|
|
||||||
Install [naxalnet][aur] (or [naxalnet-git][aur-devel] for the
|
Install [pybatmesh][aur] (or [pybatmesh-git][aur-devel] for the
|
||||||
development version) from the AUR with your favourite helper:
|
development version) from the AUR with your favourite helper:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
yay -S naxalnet
|
yay -S pybatmesh
|
||||||
```
|
```
|
||||||
|
|
||||||
Optionally, [setup systemd-resolved][arch-resolved] for DNS if any
|
Optionally, [setup systemd-resolved][arch-resolved] for DNS. [Start
|
||||||
of the nodes have internet access.
|
pybatmesh][startnx] when you need it.
|
||||||
|
|
||||||
|
### Debian or Ubuntu
|
||||||
|
|
||||||
|
pybatmesh is not packaged for Debian or Ubuntu, so you will have to build
|
||||||
|
and install it manually. Currently, only Debian bookworm (testing) and
|
||||||
|
Ubuntu 21.10 comes with the required version of systemd. Therefore,
|
||||||
|
pybatmesh requires **Debian testing** or **Ubuntu 21.10 or greater** to
|
||||||
|
work.
|
||||||
|
|
||||||
|
Install the requirements from the repositories:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# batctl is optional
|
||||||
|
sudo apt install python3-pip python3-systemd python3-dasbus iwd batctl
|
||||||
|
```
|
||||||
|
|
||||||
|
Now follow the instructions in the
|
||||||
|
[manual installation section][install-manual]
|
||||||
|
|
||||||
|
### Fedora
|
||||||
|
|
||||||
|
pybatmesh is not packaged for Fedora, so it should be installed manually.
|
||||||
|
pybatmesh requires at least 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 pybatmesh on Fedora:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Install the build requirements
|
||||||
|
sudo dnf install python3-setuptools make git
|
||||||
|
|
||||||
|
# Clone the repo
|
||||||
|
git clone https://git.disroot.org/pranav/pybatmesh.git
|
||||||
|
cd pybatmesh
|
||||||
|
|
||||||
|
# Create an installable rpm from the source code
|
||||||
|
make rpm
|
||||||
|
|
||||||
|
# Now install it. This will also install the requirements
|
||||||
|
sudo dnf install dist/pybatmesh-$(python3 -m setup --version)-1.noarch.rpm
|
||||||
|
```
|
||||||
|
|
||||||
### Manually
|
### Manually
|
||||||
|
|
||||||
Clone the repo and cd into it.
|
Verify that the [requirements][] are of required versions.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://git.disroot.org/pranav/naxalnet.git
|
# Should be greater than or equal to 2021.0
|
||||||
cd naxalnet
|
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 -q join_ibss && echo "IBSS is supported" || echo "IBSS not supported"
|
||||||
```
|
```
|
||||||
|
|
||||||
Or, if you have an [IPFS client][ipfs] running, try:
|
Clone the pybatmesh repo and cd into it.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone http://k51qzi5uqu5dlye74be0n9iihwk6sm54vexo7bf7pdr4w811y6mmrcp25djozv.ipns.localhost:8080/naxalnet.git
|
git clone https://git.disroot.org/pranav/pybatmesh.git
|
||||||
|
cd pybatmesh
|
||||||
```
|
```
|
||||||
|
|
||||||
Run `sudo make install` to install naxalnet. This will install naxalnet in
|
Now, build and install pybatmesh:
|
||||||
`/usr/bin/naxalnet`.
|
|
||||||
|
|
||||||
After installing, reload systemd so that you can enable `naxalnet.service`
|
```sh
|
||||||
without rebooting:
|
make
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
After installing, reload systemd so that it detects the new
|
||||||
|
service files:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo systemctl daemon-reload
|
sudo systemctl daemon-reload
|
||||||
```
|
```
|
||||||
|
|
||||||
## How to use
|
To upgrade, clean the build files, update the repo and reinstall:
|
||||||
|
|
||||||
You need more than one computer running for the connection to work.
|
|
||||||
|
|
||||||
### Communicate between peers
|
|
||||||
|
|
||||||
Connect a wifi adapter to all the computers you intend to run
|
|
||||||
naxalnet.
|
|
||||||
Start the naxalnet service on all of them:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo systemctl start naxalnet.service
|
make clean
|
||||||
|
git pull
|
||||||
|
make
|
||||||
|
sudo make uninstall
|
||||||
|
sudo make install
|
||||||
```
|
```
|
||||||
|
|
||||||
To test if it works, run `ip addr` to find out your address.
|
This will keep the configuration files.
|
||||||
Note the `inet` or `inet6` address of `bridge0`. Ping the address
|
|
||||||
from another computer (example: `ping 169.254.62.90`) to find out
|
## How to use
|
||||||
if it is online. Press Ctrl-C to stop.
|
|
||||||
|
You need more than one machine running pybatmesh for the connection to work.
|
||||||
|
|
||||||
|
### Start pybatmesh
|
||||||
|
|
||||||
|
Though pybatmesh can run from the command line, it was designed to be
|
||||||
|
run as a systemd service.
|
||||||
|
To start pybatmesh, do the command on all the nodes:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo systemctl start pybatmesh.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`.
|
||||||
|
|
||||||
### Getting internet access
|
### Getting internet access
|
||||||
|
|
||||||
Connect an ethernet to any of the peers and start naxalnet.
|
Connect an ethernet cable from a router to any of the nodes. Now restart
|
||||||
Now all the peers should be able to connect after renewing
|
pybatmesh on the node to set `gateway_mode` to `server`. Other nodes will
|
||||||
their DHCP connection (`sudo networkctl renew bridge0`).
|
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
|
### Tethering via WiFi AP
|
||||||
|
|
||||||
Connect two wifi adapters on a device and start naxalnet.
|
If there are two adapters in a peer, pybatmesh will start a
|
||||||
Now an ap will be created on one of the adapters with
|
WiFi ap (also called WiFi hotspot) on one of them.
|
||||||
SSID `NaxalNet` and password `naxalnet256`.
|
|
||||||
If you had set up internet access on one of the peers, internet
|
Connect two WiFi adapters on a node.
|
||||||
|
Now an AP will be started on one of the adapters.
|
||||||
|
Type `pybatmesh --print-wifi` to get the WiFi SSID and password.
|
||||||
|
|
||||||
|
If you had set up internet access on one of the nodes, internet
|
||||||
can be accessed from the AP.
|
can be accessed from the AP.
|
||||||
|
|
||||||
### Running at boot
|
### Running at boot
|
||||||
|
|
||||||
Starting the service will stop `NetworkManager.service` and
|
To run pybatmesh at boot, enable the service on all the nodes:
|
||||||
`wpa_supplicant.service` if it is running. If you start either of these
|
|
||||||
services after naxalnet is started, systemd will stop naxalnet.
|
|
||||||
|
|
||||||
To run naxalnet at boot, enable the service:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo systemctl enable naxalnet.service
|
sudo systemctl enable pybatmesh.service
|
||||||
```
|
```
|
||||||
|
|
||||||
Now naxalnet will configure a batman interface on every boot.
|
Now pybatmesh 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
|
```sh
|
||||||
sudo systemctl disable naxalnet.service
|
sudo systemctl disable NetworkManager.service
|
||||||
|
```
|
||||||
|
|
||||||
|
To stop running at boot, you should disable `pybatmesh.service`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo systemctl disable pybatmesh.service
|
||||||
|
```
|
||||||
|
|
||||||
|
If you had disabled `NetworkManager` before, enable it:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo systemctl enable NetworkManager.service
|
||||||
```
|
```
|
||||||
|
|
||||||
### Stopping the service
|
### Stopping the service
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Stop the services
|
sudo systemctl stop pybatmesh iwd systemd-networkd systemd-resolved
|
||||||
sudo systemctl stop naxalnet systemd-networkd systemd-resolved iwd
|
|
||||||
# Delete the virtual interfaces created by naxalnet
|
|
||||||
sudo networkctl delete bat0 bridge0
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If your distribution uses NetworkManager, starting `naxalnet.service`
|
If your distribution uses NetworkManager, starting `pybatmesh.service`
|
||||||
will have stopped it. Start NetworkManager again:
|
will have stopped it. Start NetworkManager again:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo systemctl start NetworkManager.service
|
sudo systemctl start NetworkManager.service
|
||||||
```
|
```
|
||||||
|
|
||||||
## How it works
|
### Configuration
|
||||||
|
|
||||||
The program naxalnet copies some `systemd-networkd` configuration files
|
pybatmesh comes with a sample configuration file
|
||||||
into networkd's runtime configuration directory. It uses iwd to start
|
`/etc/pybatmesh/pybatmesh.conf.example`. To change how the program
|
||||||
an ad-hoc network named "HelloWorld". See the
|
behaves, copy it to /etc/pybatmesh/pybatmesh.conf and edit it:
|
||||||
[systemd-networkd](systemd-networkd) directory
|
|
||||||
to see how systemd-networkd configures the network. You can use
|
|
||||||
services like [IPFS][], [Jami][], [Secure Scuttlebutt][ssb]
|
|
||||||
and others which can work on an intranet.
|
|
||||||
|
|
||||||
## Uninstalling
|
|
||||||
|
|
||||||
If you installed naxalnet manually, there is no way to uninstall
|
|
||||||
than manually removing the files:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo pip uninstall naxalnet
|
sudo cp /etc/pybatmesh/pybatmesh.conf{.example,}
|
||||||
sudo rm -rf /usr/share/naxalnet* /usr/lib/systemd/system/naxalnet.service
|
# Now edit the file with your favourite editor as root
|
||||||
|
gedit admin:/etc/pybatmesh/pybatmesh.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
## Contributing
|
Also, you can change its behaviour every time you run it using
|
||||||
|
arguments:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pybatmesh --help
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributing or reporting bugs
|
||||||
|
|
||||||
See [HACKING.md](HACKING.md)
|
See [HACKING.md](HACKING.md)
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
There are three modes commonly supported by WiFi adapters - `ap` (WiFi
|
||||||
|
hotspot), `station` (for joining WiFi networks) and `ad-hoc` (or ibss, for
|
||||||
|
decentralised networks). There are other modes supported by some WiFi
|
||||||
|
adapters too, like `p2p` (WiFi direct), but this program doesn't use them.
|
||||||
|
|
||||||
|
pybatmesh uses two modes - `ad-hoc` and `ap`, for connecting to the
|
||||||
|
mesh. pybatmesh 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,
|
||||||
|
pybatmesh 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 and the documentation in the code to learn the details.
|
||||||
|
See the directory [network](network) to see how
|
||||||
|
systemd-networkd configures the network.
|
||||||
|
|
||||||
|
## Use cases
|
||||||
|
|
||||||
|
### Online class
|
||||||
|
|
||||||
|
pybatmesh can be used to share connections to join online classes. You need
|
||||||
|
at least one device with internet access if you are not using a program
|
||||||
|
like [Jami][] (see below).
|
||||||
|
|
||||||
|
### Internet shutdown
|
||||||
|
|
||||||
|
You can communicate with neighbouring devices running pybatmesh, using
|
||||||
|
services like [IPFS][], [Jami][], [Briar][] [Secure Scuttlebutt][ssb] or
|
||||||
|
similar software 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 pybatmesh][enable-pybatmesh] and use the
|
||||||
|
installed software to communicate with anyone within range.
|
||||||
|
|
||||||
|
## Uninstalling
|
||||||
|
|
||||||
|
If you installed pybatmesh manually, use make uninstall to remove
|
||||||
|
pybatmesh and its data files. This requires python pip to be installed.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Uninstall the program, keeping the config files
|
||||||
|
sudo make uninstall
|
||||||
|
# Or, to uninstall and remove config files
|
||||||
|
sudo make purge
|
||||||
|
```
|
||||||
|
|
||||||
## Similar projects
|
## Similar projects
|
||||||
|
|
||||||
The following projects are similar to naxalnet, but are not designed
|
Many projects make setting up B.A.T.M.A.N. Advanced mesh networks with
|
||||||
to be used in a laptop or computer with wifi adapter. If you live in
|
WiFi routers easier. They are easier to setup and are more
|
||||||
an area where the materials required for any of them are easily
|
configurable. But pybatmesh is different from them. It simplifies
|
||||||
available, consider using them instead of naxalnet.
|
setting up mesh networks with _laptops or computers_, and was not
|
||||||
|
made to work with routers.
|
||||||
|
|
||||||
- [LibreMesh][libremesh]: framework for OpenWrt-based
|
The following projects does something similar to pybatmesh, but
|
||||||
firmwares
|
requires special devices or routers to work. If you live in an area
|
||||||
|
where the materials are easily available, consider using them instead
|
||||||
|
of pybatmesh.
|
||||||
|
|
||||||
|
- [LibreMesh][]: framework for OpenWrt-based firmwares
|
||||||
- [disaster.radio][]: solar-powered communications network
|
- [disaster.radio][]: solar-powered communications network
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
pybatmesh is [free/libre/swatantra][free-sw] and open source software;
|
||||||
it under the terms of the GNU General Public License as published by
|
you can redistribute it and/or modify it under the terms of the GNU
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
General Public License as published by the Free Software Foundation,
|
||||||
(at your option) any later version.
|
either version 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
See [LICENSE](LICENSE) for the complete version of the
|
See [LICENSE](LICENSE) for the complete version of the license.
|
||||||
license.
|
|
||||||
|
|
||||||
[batman-adv]: https://www.open-mesh.org/projects/batman-adv/wiki
|
[batman-adv]: https://www.open-mesh.org/projects/batman-adv/wiki
|
||||||
[ipfs]: https://ipfs.io
|
[internet shutdown]: https://internetshutdowns.in
|
||||||
[jami]: https://jami.net
|
[ipfs]: https://ipfs.io "InterPlanetary File System"
|
||||||
[ssb]: https://scuttlebutt.nz
|
[jami]: https://jami.net "Peer to peer video calls"
|
||||||
[python-dasbus]: https://github.com/rhinstaller/dasbus
|
[ssb]: https://scuttlebutt.nz "Secure Scuttlebutt"
|
||||||
[aur]: https://aur.archlinux.org/packages/naxalnet
|
[briar]: https://briarproject.org/
|
||||||
[aur-devel]: https://aur.archlinux.org/packages/naxalnet-git
|
[dasbus]: https://github.com/rhinstaller/dasbus "A python D-Bus library"
|
||||||
[arch-resolved]: https://wiki.archlinux.org/title/Systemd-resolved#DNS
|
[aur]: https://aur.archlinux.org/packages/pybatmesh
|
||||||
[batman-systemd]: https://www.open-mesh.org/news/101
|
[aur-devel]: https://aur.archlinux.org/packages/pybatmesh-git
|
||||||
|
[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
|
[libremesh]: https://libremesh.org
|
||||||
[disaster.radio]: https://disaster.radio/
|
[disaster.radio]: https://disaster.radio
|
||||||
|
[startnx]: #start-pybatmesh
|
||||||
|
[iwd]: https://iwd.wiki.kernel.org "WiFi daemon"
|
||||||
|
[free-sw]: https://gnu.org/philosophy/free-sw.html "What is free software?"
|
||||||
|
[enable-pybatmesh]: #running-at-boot
|
||||||
|
[requirements]: #requirements
|
||||||
|
[install-manual]: #manually
|
||||||
|
[python-systemd]: https://github.com/systemd/python-systemd
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
# naxalnet systemd service
|
|
||||||
# See man:systemd.service(5) and man:systemd.unit(5)
|
|
||||||
# before editing this file.
|
|
||||||
[Unit]
|
|
||||||
Description=Naxalnet
|
|
||||||
Requires=systemd-networkd.service
|
|
||||||
Requires=iwd.service
|
|
||||||
Wants=systemd-resolved.service
|
|
||||||
# naxalnet does not reload networkd, so networkd
|
|
||||||
# should be started only afer naxalnet exits
|
|
||||||
Before=systemd-networkd.service
|
|
||||||
After=iwd.service
|
|
||||||
# Stops NetworkManager and wpa_supplicant if already running
|
|
||||||
Conflicts=NetworkManager.service
|
|
||||||
Conflicts=wpa_supplicant.service
|
|
||||||
After=NetworkManager.service
|
|
||||||
After=wpa_supplicant.service
|
|
||||||
|
|
||||||
[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.
|
|
||||||
ExecStartPre=/usr/bin/sleep 2
|
|
||||||
ExecStart=/usr/bin/naxalnet
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
@ -1,19 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# Copyright (C) 2021 The naxalnet Authors
|
|
||||||
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
__version__ = "0.1.0a"
|
|
@ -1,115 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# Copyright (C) 2021 The naxalnet Authors
|
|
||||||
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
"""
|
|
||||||
Setup a working BATMAN Advanced network
|
|
||||||
with systemd-networkd and iwd
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
from shutil import copy
|
|
||||||
from dasbus.error import DBusError
|
|
||||||
from naxalnet.iwd import IWD, Device, Adapter
|
|
||||||
|
|
||||||
NETWORKD_CONFIGS = "/usr/share/naxalnet/networkd"
|
|
||||||
NETWORKD_VOLATILE_DIR = "/run/systemd/network"
|
|
||||||
ADHOC_SSID = "HelloWorld"
|
|
||||||
AP_SSID = "NaxalNet"
|
|
||||||
AP_PASSWD = "naxalnet256"
|
|
||||||
|
|
||||||
|
|
||||||
def copy_files():
|
|
||||||
"""
|
|
||||||
Copy networkd configs to volatile dir.
|
|
||||||
The D-Bus API does not support creating new interfaces
|
|
||||||
or linking to bridges. So we use config files.
|
|
||||||
See man:systemd.network(5)
|
|
||||||
"""
|
|
||||||
|
|
||||||
print("Copying network config files")
|
|
||||||
dest = Path(NETWORKD_VOLATILE_DIR)
|
|
||||||
src = Path(NETWORKD_CONFIGS)
|
|
||||||
|
|
||||||
# Create the volatile directory if it doesn't exist
|
|
||||||
dest.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
# Copy all files in src to dest
|
|
||||||
for i in src.iterdir():
|
|
||||||
copy(i, dest)
|
|
||||||
|
|
||||||
|
|
||||||
def here_be_dragons():
|
|
||||||
"""
|
|
||||||
This function is run every time you
|
|
||||||
execute naxalnet from commandline
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
copy_files()
|
|
||||||
except PermissionError as error:
|
|
||||||
print(error)
|
|
||||||
sys.exit("Make sure you are root")
|
|
||||||
|
|
||||||
# Now, the iwd part
|
|
||||||
try:
|
|
||||||
iwd = IWD()
|
|
||||||
devices = iwd.get_devices()
|
|
||||||
adhoc_devices = []
|
|
||||||
ap_devices = []
|
|
||||||
|
|
||||||
for i in devices:
|
|
||||||
device = Device(i)
|
|
||||||
adapter = Adapter(device.adapter)
|
|
||||||
if adapter.supports_mode("ad-hoc"):
|
|
||||||
adhoc_devices.append(i)
|
|
||||||
if adapter.supports_mode("ap"):
|
|
||||||
ap_devices.append(i)
|
|
||||||
|
|
||||||
if len(adhoc_devices) != 0:
|
|
||||||
# Start ad-hoc on first device supporting ad-hoc
|
|
||||||
adhoc_device = Device(adhoc_devices.pop())
|
|
||||||
# The same device is likely to have ap support too.
|
|
||||||
# But we can't start ad-hoc and ap on the same interface.
|
|
||||||
# Remove adhoc_device from ap_devices if it exists there
|
|
||||||
if adhoc_device.name in ap_devices:
|
|
||||||
ap_devices.remove(adhoc_device.name)
|
|
||||||
print("Working on ad-hoc")
|
|
||||||
# Turn on adapter if it is off
|
|
||||||
# See issue #9
|
|
||||||
adhoc_adapter = Adapter(adhoc_device.adapter)
|
|
||||||
if not adhoc_adapter.is_powered_on():
|
|
||||||
adhoc_adapter.power_on()
|
|
||||||
adhoc_device.reload()
|
|
||||||
adhoc_device.start_adhoc_open(ADHOC_SSID)
|
|
||||||
# Start Access point if ap_device is not empty,
|
|
||||||
# ie, we have more devices
|
|
||||||
if len(ap_devices) != 0:
|
|
||||||
print("Working on AP")
|
|
||||||
ap_device = Device(ap_devices.pop())
|
|
||||||
# Turn on adapter if it is off
|
|
||||||
# See issue #9
|
|
||||||
ap_adapter = Adapter(ap_device.adapter)
|
|
||||||
if not ap_adapter.is_powered_on():
|
|
||||||
ap_adapter.power_on()
|
|
||||||
ap_adapter.reload()
|
|
||||||
ap_device.start_ap(AP_SSID, AP_PASSWD)
|
|
||||||
except DBusError as error:
|
|
||||||
print(error)
|
|
||||||
sys.exit("An error occured while communicating with iwd")
|
|
||||||
|
|
||||||
# naxalnet will print Bye if no errors occured
|
|
||||||
print("Bye")
|
|
13
network/mesh.01-batman.netdev
Normal file
13
network/mesh.01-batman.netdev
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Create the BATMAN interface
|
||||||
|
# See mesh.04-batman.network for configuration details
|
||||||
|
[NetDev]
|
||||||
|
Name={batdev}
|
||||||
|
Description=BATMAN interface
|
||||||
|
Kind=batadv
|
||||||
|
|
||||||
|
# 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
|
# Create a bridge interface
|
||||||
# The batman interface be will later linked to this bridge.
|
# 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]
|
[NetDev]
|
||||||
Name=bridge0
|
Name={bridgedev}
|
||||||
Description=Bridge
|
Description=Bridge
|
||||||
Kind=bridge
|
Kind=bridge
|
||||||
|
|
@ -10,7 +10,7 @@ MTUBytes=1560
|
|||||||
|
|
||||||
[Network]
|
[Network]
|
||||||
Description=ad-hoc network connecting to other nodes
|
Description=ad-hoc network connecting to other nodes
|
||||||
BatmanAdvanced=bat0
|
BatmanAdvanced={batdev}
|
||||||
# This interface should not have any IP addresses assigned.
|
# This interface should not have any IP addresses assigned.
|
||||||
# IP will be given later to the bridge
|
# IP will be given later to the bridge
|
||||||
DHCP=no
|
DHCP=no
|
@ -1,11 +1,11 @@
|
|||||||
[Match]
|
[Match]
|
||||||
Name=bat0
|
Name={batdev}
|
||||||
|
|
||||||
[Network]
|
[Network]
|
||||||
Description=The BATMAN interface
|
Description=Configuration for the BATMAN interface
|
||||||
Bridge=bridge0
|
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
|
# also shouldn't have IP address the address will
|
||||||
# be assigned to the bridge
|
# be assigned to the bridge
|
||||||
DHCP=no
|
DHCP=no
|
@ -1,17 +1,17 @@
|
|||||||
# This file links any interface in ap mode
|
# This file links any interface in ap mode
|
||||||
# to the bridge we created earlier.
|
# to the bridge we created earlier.
|
||||||
# To start an AP, connect two adapters to the computer
|
# To start an AP, connect two adapters to the computer
|
||||||
# before starting naxalnet.service
|
# before starting pybatmesh.service
|
||||||
# This file won't do anything if an ap interface is not found.
|
# This file won't do anything if an ap interface is not found.
|
||||||
|
|
||||||
[Match]
|
[Match]
|
||||||
WLANInterfaceType=ap
|
WLANInterfaceType=ap
|
||||||
|
|
||||||
[Network]
|
[Network]
|
||||||
Description=Wireless AP
|
Description=Configuration for Wireless AP
|
||||||
|
|
||||||
# link the interface to the bridge
|
# link the interface to the bridge
|
||||||
Bridge=bridge0
|
Bridge={bridgedev}
|
||||||
|
|
||||||
# Like in the ad-hoc network and bat0, this interface
|
# Like in the ad-hoc network and bat0, this interface
|
||||||
# should not have any ip address assigned to it.
|
# should not have any ip address assigned to it.
|
9
network/mesh.06-eth.network
Normal file
9
network/mesh.06-eth.network
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# This file bridges any ethernet device found
|
||||||
|
# to the bridge made in mesh.02-bridge.netdev
|
||||||
|
[Match]
|
||||||
|
Name=en*
|
||||||
|
Name=eth*
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
Description=Connect ethernet to the bridge
|
||||||
|
Bridge={bridgedev}
|
@ -3,13 +3,15 @@
|
|||||||
# communicate with others devices
|
# communicate with others devices
|
||||||
|
|
||||||
[Match]
|
[Match]
|
||||||
Name=bridge0
|
Name={bridgedev}
|
||||||
|
|
||||||
[Network]
|
[Network]
|
||||||
# use DHCP to assign an IP
|
Description=bridge to link non-batman machines
|
||||||
|
# Use DHCP to assign an IP
|
||||||
DHCP=yes
|
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
|
LinkLocalAddressing=yes
|
||||||
|
|
||||||
# LLMNR and MulticastDNS are used for hostname discovery
|
# LLMNR and MulticastDNS are used for hostname discovery
|
10
network/tmp.01-eth.network
Normal file
10
network/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
|
35
pybatmesh.conf.example
Normal file
35
pybatmesh.conf.example
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# This configuration file is part of pybatmesh.
|
||||||
|
# To configure this program, rename this file
|
||||||
|
# to pybatmesh.conf and edit it.
|
||||||
|
# The values given here are defaults.
|
||||||
|
|
||||||
|
[networkd]
|
||||||
|
# systemd-networkd configuration files bundled with pybatmesh.
|
||||||
|
# THese will be copied to runtimedir at runtime.
|
||||||
|
confdir = /usr/share/pybatmesh/networkd
|
||||||
|
# systemd-networkd runtime configuration directory.
|
||||||
|
# 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 = pybatmesh
|
||||||
|
|
||||||
|
[ap]
|
||||||
|
# An AP is started if your machine has more than one WiFi adapter.
|
||||||
|
ssid = BatWiFi
|
||||||
|
# Note the spelling. It's passwd, not password.
|
||||||
|
passwd = pybatmesh256
|
30
pybatmesh.service
Normal file
30
pybatmesh.service
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# The pybatmesh systemd service
|
||||||
|
# See man:systemd.service(5) and man:systemd.unit(5)
|
||||||
|
# before editing this file.
|
||||||
|
[Unit]
|
||||||
|
Description=Setup mesh networks
|
||||||
|
Requires=systemd-networkd.service
|
||||||
|
Requires=iwd.service
|
||||||
|
Wants=systemd-resolved.service
|
||||||
|
After=iwd.service
|
||||||
|
After=systemd-networkd.service
|
||||||
|
After=systemd-resolved.service
|
||||||
|
# Stops NetworkManager if already running
|
||||||
|
Conflicts=NetworkManager.service
|
||||||
|
# This stops NetworkManager when pybatmesh is enabled
|
||||||
|
After=NetworkManager.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
NotifyAccess=all
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=2sec
|
||||||
|
ExecStart=pybatmesh --systemd
|
||||||
|
KillSignal=SIGINT
|
||||||
|
# pybatmesh already logs to systemd journal so we don't need
|
||||||
|
# stdout and stderr.
|
||||||
|
StandardOutput=null
|
||||||
|
StandardError=null
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
45
pybatmesh/__init__.py
Normal file
45
pybatmesh/__init__.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# This file is part of pybatmesh.
|
||||||
|
# Copyright (C) 2021 The pybatmesh 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/>.
|
||||||
|
|
||||||
|
"""
|
||||||
|
pybatmesh
|
||||||
|
========
|
||||||
|
|
||||||
|
Create mesh networks with batman-adv, systemd-networkd and iwd.
|
||||||
|
|
||||||
|
See README.md and the docstrings for documentation. You can read
|
||||||
|
documentaion in the python interpretor using something like the example
|
||||||
|
given below.
|
||||||
|
|
||||||
|
>>> help("pybatmesh")
|
||||||
|
>>> help("pybatmesh.config")
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 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.5.3"
|
@ -1,6 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
# This file is part of pybatmesh.
|
||||||
|
# Copyright (C) 2021 The pybatmesh Authors
|
||||||
# Copyright (C) 2021 The naxalnet Authors
|
|
||||||
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -16,7 +15,16 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
from naxalnet.scripts import here_be_dragons
|
"""
|
||||||
|
__main__.py
|
||||||
|
-----------
|
||||||
|
|
||||||
|
If called as python -m pybatmesh, this file makes pybatmesh run like
|
||||||
|
it was called from the commandline. Try:
|
||||||
|
python -m pybatmesh --help
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pybatmesh.scripts import main
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
here_be_dragons()
|
main()
|
194
pybatmesh/config.py
Normal file
194
pybatmesh/config.py
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
# This file is part of pybatmesh.
|
||||||
|
# Copyright (C) 2021 The pybatmesh 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/>.
|
||||||
|
|
||||||
|
"""
|
||||||
|
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 pybatmesh 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/pybatmesh/pybatmesh.conf and then from
|
||||||
|
/usr/share/pybatmesh/pybatmesh.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/pybatmesh
|
||||||
|
|
||||||
|
- Then, it looks for the files pybatmesh.conf and pybatmesh.conf.d/*.conf
|
||||||
|
from the directory /etc/pybatmesh, 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 pybatmesh.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
|
||||||
|
"""
|
||||||
|
# logger.debug("Parsing config files")
|
||||||
|
parser = ConfigParser()
|
||||||
|
# encoded defaults
|
||||||
|
parser.read_dict(CONFIG)
|
||||||
|
# read config files
|
||||||
|
files = get_config_files()
|
||||||
|
for i in files:
|
||||||
|
# logger.debug("Reading config file %s", str(i))
|
||||||
|
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 pybatmesh 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(
|
||||||
|
"--systemd",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
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",
|
||||||
|
default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="prints the version and exit",
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"-v", "--verbose", action="count", default=0, help="increase output verbosity"
|
||||||
|
)
|
||||||
|
|
||||||
|
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()
|
71
pybatmesh/daemon.py
Normal file
71
pybatmesh/daemon.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# This file is part of pybatmesh.
|
||||||
|
# Copyright (C) 2021 The pybatmesh 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/>.
|
||||||
|
|
||||||
|
"""
|
||||||
|
daemon.py
|
||||||
|
---------
|
||||||
|
|
||||||
|
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
|
||||||
|
from pybatmesh.iwd import IWD, IWD_DEVICE_INTERFACE
|
||||||
|
from pybatmesh.log import logger
|
||||||
|
|
||||||
|
|
||||||
|
class Daemon:
|
||||||
|
"""implements the daemon part"""
|
||||||
|
|
||||||
|
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", data[IWD_DEVICE_INTERFACE]["Name"])
|
||||||
|
logger.info("Reloading")
|
||||||
|
self.callback()
|
||||||
|
|
||||||
|
def on_device_remove(self, path, data):
|
||||||
|
"""
|
||||||
|
this function will be run every time a device is removed
|
||||||
|
"""
|
||||||
|
if IWD_DEVICE_INTERFACE in data:
|
||||||
|
logger.debug("A device was removed")
|
||||||
|
logger.info("Reloading")
|
||||||
|
self.callback()
|
||||||
|
|
||||||
|
def add_callback(self, callback):
|
||||||
|
"""
|
||||||
|
register the callback with D-Bus so that callback is
|
||||||
|
run every time a device is added or removed
|
||||||
|
"""
|
||||||
|
self.callback = callback
|
||||||
|
proxy = self.iwd._proxy
|
||||||
|
proxy.InterfacesAdded.connect(self.on_device_add)
|
||||||
|
proxy.InterfacesRemoved.connect(self.on_device_remove)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""
|
||||||
|
start the daemon
|
||||||
|
"""
|
||||||
|
logger.debug("Starting daemon")
|
||||||
|
self.loop.run()
|
50
pybatmesh/default.py
Normal file
50
pybatmesh/default.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# This file is part of pybatmesh.
|
||||||
|
# Copyright (C) 2021 The pybatmesh 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/>.
|
||||||
|
|
||||||
|
"""
|
||||||
|
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 pybatmesh is called from the commandline.
|
||||||
|
See config.py for more info.
|
||||||
|
"""
|
||||||
|
|
||||||
|
CONFIG = {
|
||||||
|
"networkd": {
|
||||||
|
"confdir": "/usr/share/pybatmesh/networkd",
|
||||||
|
"runtimedir": "/run/systemd/network",
|
||||||
|
},
|
||||||
|
"device": {"batman": "bat0", "bridge": "bridge0"},
|
||||||
|
"adhoc": {"name": "pybatmesh"},
|
||||||
|
"ap": {"ssid": "BatWiFi", "passwd": "pybatmesh256"},
|
||||||
|
"gateway": {"mode": "auto"},
|
||||||
|
}
|
||||||
|
|
||||||
|
# glob
|
||||||
|
CONFIG_FILES = ["pybatmesh.conf", "pybatmesh.conf.d/*.conf"]
|
||||||
|
CONFIG_DIRS = ["/usr/share/pybatmesh", "/usr/local/share/pybatmesh", "/etc/pybatmesh"]
|
||||||
|
MESH_GLOB = "mesh.*"
|
||||||
|
TMP_NET_GLOB = "tmp.*"
|
||||||
|
|
||||||
|
ISSUE_URL = "https://git.disroot.org/pranav/pybatmesh/issues"
|
||||||
|
REPORT_BUG_INFO = "If you think this is a bug, report it to " + ISSUE_URL
|
||||||
|
|
||||||
|
# Changing this constant will alter not just the behaviour of pybatmesh,
|
||||||
|
# but affect the meaning of Life, the Universe and Everthing
|
||||||
|
ANSWER = 42
|
@ -1,24 +1,58 @@
|
|||||||
#!/usr/bin/env python3
|
# This file is part of pybatmesh.
|
||||||
|
# Copyright (C) 2021 The pybatmesh Authors
|
||||||
|
|
||||||
# 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
|
# This program is distributed in the hope that it will be useful, but
|
||||||
# it under the terms of the GNU General Public License as published by
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
# (at your option) any later version.
|
# Public License for more details.
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
# You should have received a copy of the GNU General Public License along
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
# 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/>.
|
iwd.py
|
||||||
|
------
|
||||||
|
|
||||||
|
This file contains methods to communicate with iwd via its D-Bus API and
|
||||||
|
control WiFi adapters.
|
||||||
|
|
||||||
"""Manage wifi adapter via iwd D-Bus api"""
|
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 pybatmesh 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. pybatmesh 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 pybatmesh and is therefore connected to the
|
||||||
|
mesh.
|
||||||
|
"""
|
||||||
|
|
||||||
from dasbus.connection import SystemMessageBus
|
from dasbus.connection import SystemMessageBus
|
||||||
|
from pybatmesh.log import logger
|
||||||
|
|
||||||
IWD_BUS = "net.connman.iwd"
|
IWD_BUS = "net.connman.iwd"
|
||||||
IWD_ROOT_PATH = "/"
|
IWD_ROOT_PATH = "/"
|
||||||
@ -27,14 +61,14 @@ IWD_ADAPTER_INTERFACE = "net.connman.iwd.Adapter"
|
|||||||
|
|
||||||
# If you are new to D-Bus, you might want to use a program
|
# 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.
|
# 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:
|
class IWD:
|
||||||
"""Manage iwd via dbus"""
|
"""Manage iwd via dbus"""
|
||||||
|
|
||||||
def __init__(self, bus=SystemMessageBus()):
|
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._bus = bus
|
||||||
self.reload()
|
self.reload()
|
||||||
|
|
||||||
@ -55,9 +89,9 @@ class IWD:
|
|||||||
for i in device_paths:
|
for i in device_paths:
|
||||||
proxy = self._bus.get_proxy(IWD_BUS, i)
|
proxy = self._bus.get_proxy(IWD_BUS, i)
|
||||||
if proxy.Name == name:
|
if proxy.Name == name:
|
||||||
return i
|
# See comment in the function below
|
||||||
# If no devices were found, return None
|
path = i
|
||||||
return None
|
return path
|
||||||
|
|
||||||
def get_adapter_path_from_name(self, name: str) -> str:
|
def get_adapter_path_from_name(self, name: str) -> str:
|
||||||
"""returns path of adapter as str"""
|
"""returns path of adapter as str"""
|
||||||
@ -65,9 +99,10 @@ class IWD:
|
|||||||
for i in adapter_paths:
|
for i in adapter_paths:
|
||||||
proxy = self._bus.get_proxy(IWD_BUS, i)
|
proxy = self._bus.get_proxy(IWD_BUS, i)
|
||||||
if proxy.Name == name:
|
if proxy.Name == name:
|
||||||
return i
|
# We could have just used return here, but shutting up
|
||||||
# If no adapters were found
|
# pylint has a greter priority at the moment
|
||||||
return None
|
path = i
|
||||||
|
return path
|
||||||
|
|
||||||
def get_all_device_paths(self) -> list:
|
def get_all_device_paths(self) -> list:
|
||||||
"""returns list of paths of all devices"""
|
"""returns list of paths of all devices"""
|
||||||
@ -92,7 +127,8 @@ class IWD:
|
|||||||
|
|
||||||
def get_devices(self) -> list:
|
def get_devices(self) -> list:
|
||||||
"""
|
"""
|
||||||
returns list of device names as str
|
returns list of all device names as str
|
||||||
|
|
||||||
example: ["wlan0", "wlan1"]
|
example: ["wlan0", "wlan1"]
|
||||||
"""
|
"""
|
||||||
devices = []
|
devices = []
|
||||||
@ -106,6 +142,7 @@ class IWD:
|
|||||||
def get_adapters(self) -> list:
|
def get_adapters(self) -> list:
|
||||||
"""
|
"""
|
||||||
returns list of adapters
|
returns list of adapters
|
||||||
|
|
||||||
example: ["phy0","phy1"]
|
example: ["phy0","phy1"]
|
||||||
"""
|
"""
|
||||||
adapters = []
|
adapters = []
|
||||||
@ -120,12 +157,13 @@ class IWD:
|
|||||||
class Device:
|
class Device:
|
||||||
"""
|
"""
|
||||||
control devices with iwd
|
control devices with iwd
|
||||||
|
|
||||||
name: name of device (str)
|
name: name of device (str)
|
||||||
adapter: name of adapter (str)
|
adapter: name of adapter (str)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str, bus=SystemMessageBus()):
|
def __init__(self, name: str):
|
||||||
self._iwd = IWD(bus)
|
self._iwd = IWD()
|
||||||
self._bus = self._iwd._bus
|
self._bus = self._iwd._bus
|
||||||
self._path = self._iwd.get_device_path_from_name(name)
|
self._path = self._iwd.get_device_path_from_name(name)
|
||||||
self.reload()
|
self.reload()
|
||||||
@ -140,38 +178,44 @@ class Device:
|
|||||||
def power_on(self):
|
def power_on(self):
|
||||||
"""Turn on the device and reload the proxy"""
|
"""Turn on the device and reload the proxy"""
|
||||||
self._proxy.Powered = True
|
self._proxy.Powered = True
|
||||||
|
logger.debug("Powered on %s", self.name)
|
||||||
self.reload()
|
self.reload()
|
||||||
|
|
||||||
def power_off(self):
|
def power_off(self):
|
||||||
"""Turn off the device and reload the proxy"""
|
"""Turn off the device and reload the proxy"""
|
||||||
self._proxy.Powered = False
|
self._proxy.Powered = False
|
||||||
|
logger.debug("Powered off %s", self.name)
|
||||||
self.reload()
|
self.reload()
|
||||||
|
|
||||||
def reload(self):
|
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._proxy = self._bus.get_proxy(IWD_BUS, self._path)
|
||||||
self.name = self._proxy.Name
|
self.name = self._proxy.Name
|
||||||
adapter_path = self._proxy.Adapter
|
adapter_path = self._proxy.Adapter
|
||||||
# name of adapter ('phy0' for example)
|
# name of adapter ('phy0' for example)
|
||||||
self.adapter = self._iwd.get_name_from_path(adapter_path)
|
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 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":
|
if self.is_powered_on() and self.get_mode() == "ad-hoc":
|
||||||
return self._proxy.Started
|
return self._proxy.Started
|
||||||
# If above condition is not true, return None
|
# If above condition is not true, return False
|
||||||
return None
|
return False
|
||||||
|
|
||||||
def is_ap_started(self):
|
def is_ap_started(self) -> bool:
|
||||||
"""
|
"""
|
||||||
Same as is_adhoc_started(), but for ap
|
Same as is_adhoc_started(), but for ap
|
||||||
"""
|
"""
|
||||||
if self.is_powered_on() and self.get_mode() == "ap":
|
if self.is_powered_on() and self.get_mode() == "ap":
|
||||||
return self._proxy.Started
|
return self._proxy.Started
|
||||||
return None
|
return False
|
||||||
|
|
||||||
def get_mode(self) -> str:
|
def get_mode(self) -> str:
|
||||||
"""
|
"""
|
||||||
@ -183,6 +227,7 @@ class Device:
|
|||||||
def set_mode(self, mode: str):
|
def set_mode(self, mode: str):
|
||||||
"""change the device mode to mode"""
|
"""change the device mode to mode"""
|
||||||
self._proxy.Mode = mode
|
self._proxy.Mode = mode
|
||||||
|
logger.debug("Set mode on %s to %s", self.name, mode)
|
||||||
self.reload()
|
self.reload()
|
||||||
|
|
||||||
def start_adhoc_open(self, name: str):
|
def start_adhoc_open(self, name: str):
|
||||||
@ -191,20 +236,22 @@ class Device:
|
|||||||
if it isn't already on ad-hoc and power onn the device
|
if it isn't already on ad-hoc and power onn the device
|
||||||
if it is off
|
if it is off
|
||||||
"""
|
"""
|
||||||
|
# Stop adhoc if already started
|
||||||
|
self.stop_adhoc()
|
||||||
|
|
||||||
if self.get_mode() != "ad-hoc":
|
if self.get_mode() != "ad-hoc":
|
||||||
self.set_mode("ad-hoc")
|
self.set_mode("ad-hoc")
|
||||||
|
|
||||||
if not self.is_powered_on():
|
if not self.is_powered_on():
|
||||||
self.power_on()
|
self.power_on()
|
||||||
|
|
||||||
# Stop adhoc if already started
|
logger.debug("Starting ad-hoc on %s", self.name)
|
||||||
self.stop_adhoc()
|
|
||||||
|
|
||||||
self._proxy.StartOpen(name)
|
self._proxy.StartOpen(name)
|
||||||
|
|
||||||
def stop_adhoc(self):
|
def stop_adhoc(self):
|
||||||
"""stop adhoc if adhoc is started"""
|
"""stop adhoc if adhoc is started"""
|
||||||
if self.is_adhoc_started():
|
if self.is_adhoc_started():
|
||||||
|
logger.debug("Stopping ad-hoc on %s", self.name)
|
||||||
self._proxy.Stop()
|
self._proxy.Stop()
|
||||||
self.reload()
|
self.reload()
|
||||||
|
|
||||||
@ -214,20 +261,23 @@ class Device:
|
|||||||
if it isn't already on ap and turning
|
if it isn't already on ap and turning
|
||||||
on the device if it is off
|
on the device if it is off
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Stop ap if already started
|
||||||
|
self.stop_ap()
|
||||||
|
|
||||||
if self.get_mode() != "ap":
|
if self.get_mode() != "ap":
|
||||||
self.set_mode("ap")
|
self.set_mode("ap")
|
||||||
|
|
||||||
if not self.is_powered_on():
|
if not self.is_powered_on():
|
||||||
self.power_on()
|
self.power_on()
|
||||||
|
|
||||||
# Stop ap if already started
|
logger.debug("Starting ap on %s with ssid %s", self.name, ssid)
|
||||||
self.stop_ap()
|
|
||||||
|
|
||||||
self._proxy.Start(ssid, passwd)
|
self._proxy.Start(ssid, passwd)
|
||||||
|
|
||||||
def stop_ap(self):
|
def stop_ap(self):
|
||||||
"""stop ap if an ap is started"""
|
"""stop ap if an ap is started"""
|
||||||
if self.is_ap_started():
|
if self.is_ap_started():
|
||||||
|
logger.debug("Stopping ap on %s", self.name)
|
||||||
self._proxy.Stop()
|
self._proxy.Stop()
|
||||||
self.reload()
|
self.reload()
|
||||||
|
|
||||||
@ -235,8 +285,8 @@ class Device:
|
|||||||
class Adapter:
|
class Adapter:
|
||||||
"""represents an adapter as a python object"""
|
"""represents an adapter as a python object"""
|
||||||
|
|
||||||
def __init__(self, name: str, bus=SystemMessageBus()):
|
def __init__(self, name: str):
|
||||||
self._iwd = IWD(bus)
|
self._iwd = IWD()
|
||||||
self._bus = self._iwd._bus
|
self._bus = self._iwd._bus
|
||||||
self._path = self._iwd.get_adapter_path_from_name(name)
|
self._path = self._iwd.get_adapter_path_from_name(name)
|
||||||
# Initialise self._proxy
|
# Initialise self._proxy
|
||||||
@ -250,8 +300,6 @@ class Adapter:
|
|||||||
self._proxy = self._bus.get_proxy(IWD_BUS, self._path)
|
self._proxy = self._bus.get_proxy(IWD_BUS, self._path)
|
||||||
self.name = self._proxy.Name
|
self.name = self._proxy.Name
|
||||||
self.supported_modes = self._proxy.SupportedModes
|
self.supported_modes = self._proxy.SupportedModes
|
||||||
self.model = self._proxy.Model
|
|
||||||
self.vendor = self._proxy.Vendor
|
|
||||||
|
|
||||||
def is_powered_on(self) -> bool:
|
def is_powered_on(self) -> bool:
|
||||||
"""returns True if adapter is powered on, False otherwise"""
|
"""returns True if adapter is powered on, False otherwise"""
|
||||||
@ -260,10 +308,14 @@ class Adapter:
|
|||||||
def power_on(self):
|
def power_on(self):
|
||||||
"""power on the adapter"""
|
"""power on the adapter"""
|
||||||
self._proxy.Powered = True
|
self._proxy.Powered = True
|
||||||
|
logger.debug("Powered on adapter %s", self.name)
|
||||||
|
self.reload()
|
||||||
|
|
||||||
def power_off(self):
|
def power_off(self):
|
||||||
"""power off the adapter"""
|
"""power off the adapter"""
|
||||||
self._proxy.Powered = False
|
self._proxy.Powered = False
|
||||||
|
logger.debug("Powered off adapter %s", self.name)
|
||||||
|
self.reload()
|
||||||
|
|
||||||
def supports_mode(self, mode: str) -> bool:
|
def supports_mode(self, mode: str) -> bool:
|
||||||
"""
|
"""
|
55
pybatmesh/log.py
Normal file
55
pybatmesh/log.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# This file is part of pybatmesh.
|
||||||
|
# Copyright (C) 2021 The pybatmesh 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/>.
|
||||||
|
|
||||||
|
"""
|
||||||
|
log.py
|
||||||
|
------
|
||||||
|
|
||||||
|
Initialise the logger for other submodules to import. Do not import any
|
||||||
|
submodules here other than pybatmesh.config, which is needed to set the
|
||||||
|
loglevel and to add the systemd journal handler
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
from systemd.journal import JournalHandler
|
||||||
|
from pybatmesh.config import args
|
||||||
|
|
||||||
|
|
||||||
|
def get_logger():
|
||||||
|
"""
|
||||||
|
Initialise the logger and return it.
|
||||||
|
This function is meant to be used only by pybatmesh.log.
|
||||||
|
If you want to import the logger, use:
|
||||||
|
from pybatmesh.log import logger
|
||||||
|
"""
|
||||||
|
log = logging.getLogger("pybatmesh")
|
||||||
|
# --verbose
|
||||||
|
if args.verbose >= 2:
|
||||||
|
loglevel = logging.DEBUG
|
||||||
|
elif args.verbose == 1:
|
||||||
|
loglevel = logging.INFO
|
||||||
|
else:
|
||||||
|
loglevel = logging.WARNING
|
||||||
|
|
||||||
|
# if --systemd is given, log to systemd journal
|
||||||
|
if args.systemd:
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
log.addHandler(JournalHandler())
|
||||||
|
else:
|
||||||
|
logging.basicConfig(level=loglevel)
|
||||||
|
return log
|
||||||
|
|
||||||
|
|
||||||
|
logger = get_logger()
|
187
pybatmesh/network.py
Normal file
187
pybatmesh/network.py
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
# This file is part of pybatmesh.
|
||||||
|
# Copyright (C) 2021 The pybatmesh 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
|
||||||
|
from dasbus.loop import EventLoop, GLib
|
||||||
|
|
||||||
|
|
||||||
|
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 pybatmesh only, the class is not suitable for
|
||||||
|
importing outside pybatmesh.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, runtime_dir="/run/systemd/network", bus=SystemMessageBus()):
|
||||||
|
print("NetworkD init")
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkLoop(NetworkD):
|
||||||
|
"""Used to wait until a condition is met
|
||||||
|
|
||||||
|
Available methods:
|
||||||
|
|
||||||
|
NetworkLoop.wait_until_routable(timeout=0):
|
||||||
|
return true when the network is routable, or false when timed out
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
# first, initialise the parent object
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.waitfor = None
|
||||||
|
self.wait_function = None
|
||||||
|
self.loop = EventLoop()
|
||||||
|
|
||||||
|
def start_loop(self):
|
||||||
|
"""start the dasbus loop"""
|
||||||
|
self.proxy.PropertiesChanged.connect(self.on_properties_changed)
|
||||||
|
self.loop.run()
|
||||||
|
|
||||||
|
def wait_until_routable(self, timeout=0):
|
||||||
|
"""
|
||||||
|
Wait until timeout in milliseconds and returns True when any
|
||||||
|
network interface is shown routable by networkd. Does not wait
|
||||||
|
for timeout if timeout==0
|
||||||
|
"""
|
||||||
|
self.setup_timeout(timeout)
|
||||||
|
self.wait_for_change("AddressState", self.on_addressstate_change)
|
||||||
|
|
||||||
|
return self.is_routable()
|
||||||
|
|
||||||
|
def wait_for_change(self, name, function):
|
||||||
|
"""
|
||||||
|
Wait until the given property is changed and stop. If setup_timeout()
|
||||||
|
is called before calling this function, the loop stops after the timeout
|
||||||
|
or after the property is changed, whichever occurs first.
|
||||||
|
"""
|
||||||
|
self.waitfor = name
|
||||||
|
self.wait_function = function
|
||||||
|
self.start_loop()
|
||||||
|
|
||||||
|
def on_addressstate_change(self):
|
||||||
|
"""quit the loop if the network is routable"""
|
||||||
|
if self.is_routable():
|
||||||
|
self.loop.quit()
|
||||||
|
|
||||||
|
def on_properties_changed(self, bus_interface, data, blah):
|
||||||
|
"""called by dasbus everytime the configured property is changed"""
|
||||||
|
if self.waitfor in data:
|
||||||
|
return self.wait_function()
|
||||||
|
# Just to shut up pylint
|
||||||
|
return None
|
||||||
|
|
||||||
|
def setup_timeout(self, timeout):
|
||||||
|
"""setup a timeout"""
|
||||||
|
if timeout != 0:
|
||||||
|
GLib.timeout_add(timeout, self.on_timeout)
|
||||||
|
|
||||||
|
def on_timeout(self):
|
||||||
|
"""called by dasbus when a timeout occurs"""
|
||||||
|
self.loop.quit()
|
271
pybatmesh/scripts.py
Normal file
271
pybatmesh/scripts.py
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
# This file is part of pybatmesh.
|
||||||
|
# Copyright (C) 2021 The pybatmesh 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/>.
|
||||||
|
|
||||||
|
"""
|
||||||
|
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 pybatmesh, this is the right place to start.
|
||||||
|
When run from the commandline, the function main() is called.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
from dasbus.error import DBusError
|
||||||
|
from systemd.daemon import notify
|
||||||
|
from pybatmesh import __version__
|
||||||
|
from pybatmesh.default import REPORT_BUG_INFO, MESH_GLOB, TMP_NET_GLOB
|
||||||
|
from pybatmesh.log import logger
|
||||||
|
from pybatmesh.iwd import Adapter, Device, IWD
|
||||||
|
from pybatmesh.config import args
|
||||||
|
from pybatmesh.daemon import Daemon
|
||||||
|
from pybatmesh.network import NetworkD, NetworkLoop
|
||||||
|
|
||||||
|
|
||||||
|
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 = NetworkLoop(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)
|
||||||
|
|
||||||
|
# timeout = 10 seconds
|
||||||
|
routable = networkd.wait_until_routable(10 * 1000)
|
||||||
|
networkd.remove_all_configs()
|
||||||
|
|
||||||
|
return routable
|
||||||
|
|
||||||
|
|
||||||
|
def setup_mesh(gateway_mode: str = "off"):
|
||||||
|
"""
|
||||||
|
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")
|
||||||
|
|
||||||
|
networkd = NetworkD(runtime_dir=args.networkd_runtime_dir)
|
||||||
|
networkd.set_vars(
|
||||||
|
batdev=args.batman_device,
|
||||||
|
bridgedev=args.bridge_device,
|
||||||
|
gateway_mode=gateway_mode,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 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. Make sure you are root."
|
||||||
|
)
|
||||||
|
logger.error(REPORT_BUG_INFO)
|
||||||
|
sys.exit(3)
|
||||||
|
except:
|
||||||
|
logger.exception("An unknown error occured while copying files")
|
||||||
|
logger.error(REPORT_BUG_INFO)
|
||||||
|
sys.exit(3)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_devices():
|
||||||
|
"""
|
||||||
|
Setup wifi interfaces using iwd
|
||||||
|
This function should be called every time an interface
|
||||||
|
is connected or removed.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
notify("STATUS=Setting up mesh...")
|
||||||
|
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)
|
||||||
|
logger.debug("Found device %s", device.name)
|
||||||
|
adapter = Adapter(device.adapter)
|
||||||
|
if adapter.supports_mode("ad-hoc"):
|
||||||
|
logger.debug("The device %s can be used for ad-hoc", device.name)
|
||||||
|
adhoc_devices.append(i)
|
||||||
|
if adapter.supports_mode("ap"):
|
||||||
|
logger.debug("The device %s can be used for ap", device.name)
|
||||||
|
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)
|
||||||
|
|
||||||
|
# Turn on adapter if it is off
|
||||||
|
# See issue #9
|
||||||
|
adhoc_adapter = Adapter(adhoc_device.adapter)
|
||||||
|
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:
|
||||||
|
ap_device = Device(ap_devices.pop())
|
||||||
|
logger.info("Starting WiFi Access Point on %s", ap_device.name)
|
||||||
|
logger.info("Use pybatmesh --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():
|
||||||
|
logger.debug("Adapter %s is off. Turning on", ap_adapter.name)
|
||||||
|
ap_adapter.power_on()
|
||||||
|
ap_device.start_ap(args.ap_ssid, args.ap_passwd)
|
||||||
|
else:
|
||||||
|
logger.warning("Not setting up WiFi AP.")
|
||||||
|
else:
|
||||||
|
logger.warning(
|
||||||
|
"No device found to setup mesh. Make sure a WiFi adapter is connected"
|
||||||
|
)
|
||||||
|
|
||||||
|
except DBusError:
|
||||||
|
logger.exception("Error while communicating with iwd")
|
||||||
|
logger.error(REPORT_BUG_INFO)
|
||||||
|
sys.exit(4)
|
||||||
|
except:
|
||||||
|
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
|
||||||
|
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 main():
|
||||||
|
"""
|
||||||
|
This is where the magic happens!
|
||||||
|
This function is run every time you
|
||||||
|
execute pybatmesh from the commandline
|
||||||
|
"""
|
||||||
|
|
||||||
|
if args.print_wifi:
|
||||||
|
print_wifi()
|
||||||
|
sys.exit(0)
|
||||||
|
elif args.version:
|
||||||
|
print_version()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# Notify systemd that pybatmesh is ready.
|
||||||
|
# see man:sd_notify(3)
|
||||||
|
notify("READY=1")
|
||||||
|
|
||||||
|
# Gateway mode comes in handy when many nodes have a DHCP server and
|
||||||
|
# you want to prevent conflicts. It defaults to "auto" in pybatmesh.
|
||||||
|
# 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():
|
||||||
|
logger.info("Network is routable. Setting gw_mode to server")
|
||||||
|
gateway_mode = "server"
|
||||||
|
else:
|
||||||
|
logger.info("Network is not routable. Setting gw_mode to client")
|
||||||
|
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)
|
||||||
|
|
||||||
|
try:
|
||||||
|
setup_devices()
|
||||||
|
setup_mesh(gateway_mode=gateway_mode)
|
||||||
|
|
||||||
|
# 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()
|
4
pyproject.toml
Normal file
4
pyproject.toml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[build-system]
|
||||||
|
# I don't know what this means, I just copied it from some setuptools tutorial
|
||||||
|
requires = ["setuptools", "wheel"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
46
setup.cfg
46
setup.cfg
@ -1,12 +1,17 @@
|
|||||||
|
# This file is loosely based on the setup.cfg used in django.
|
||||||
|
# pybatmesh is not meant to be distributed through PyPi. This program uses
|
||||||
|
# a systemd service, and some other files whose path is hardcoded into the
|
||||||
|
# module.
|
||||||
[metadata]
|
[metadata]
|
||||||
name = naxalnet
|
name = pybatmesh
|
||||||
version = attr: naxalnet.__version__
|
version = attr: pybatmesh.__version__
|
||||||
description = create mesh networks with batman-adv and systemd
|
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
|
url = https://git.disroot.org/pranav/pybatmesh
|
||||||
author = Pranav Jerry
|
author = Pranav Jerry
|
||||||
author_email = libreinator@disroot.org
|
author_email = libreinator@disroot.org
|
||||||
license = GPLv3
|
license = GPLv3
|
||||||
|
license_files = LICENSE
|
||||||
classifiers =
|
classifiers =
|
||||||
License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
||||||
Operating System :: POSIX :: Linux
|
Operating System :: POSIX :: Linux
|
||||||
@ -18,19 +23,30 @@ packages = find:
|
|||||||
python_requires = >=3.6
|
python_requires = >=3.6
|
||||||
install_requires =
|
install_requires =
|
||||||
dasbus
|
dasbus
|
||||||
|
# pathlib, configparser and argparse are already
|
||||||
|
# in the standard library
|
||||||
|
configparser
|
||||||
|
pathlib
|
||||||
|
argparse
|
||||||
|
systemd
|
||||||
|
|
||||||
[options.entry_points]
|
[options.entry_points]
|
||||||
console_scripts =
|
console_scripts =
|
||||||
naxalnet = naxalnet.scripts:here_be_dragons
|
pybatmesh = pybatmesh.scripts:main
|
||||||
|
|
||||||
[options.data_files]
|
[options.data_files]
|
||||||
/usr/lib/systemd/system =
|
lib/systemd/system =
|
||||||
naxalnet.service
|
pybatmesh.service
|
||||||
/usr/share/naxalnet/networkd =
|
# If installing with pip, this file will be copied to some other place.
|
||||||
systemd-networkd/01-batman.netdev
|
# This is the reason we use setup.py instead of pip in the Makefile.
|
||||||
systemd-networkd/02-bridge.netdev
|
/etc/pybatmesh =
|
||||||
systemd-networkd/03-wireless-ad-hoc.network
|
pybatmesh.conf.example
|
||||||
systemd-networkd/04-batman.network
|
share/pybatmesh/networkd =
|
||||||
systemd-networkd/05-wireless-ap.network
|
network/mesh.01-batman.netdev
|
||||||
systemd-networkd/06-eth.network
|
network/mesh.02-bridge.netdev
|
||||||
systemd-networkd/07-bridge.network
|
network/mesh.03-wireless-ad-hoc.network
|
||||||
|
network/mesh.04-batman.network
|
||||||
|
network/mesh.05-wireless-ap.network
|
||||||
|
network/mesh.06-eth.network
|
||||||
|
network/mesh.07-bridge.network
|
||||||
|
network/tmp.01-eth.network
|
||||||
|
4
setup.py
4
setup.py
@ -1,5 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
See setup.py --help for usage
|
||||||
|
"""
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
setup()
|
setup()
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
# Create the BATMAN interface
|
|
||||||
# See 04-batman.network for configuration details
|
|
||||||
[NetDev]
|
|
||||||
Name=bat0
|
|
||||||
Description=BATMAN interface
|
|
||||||
Kind=batadv
|
|
||||||
|
|
||||||
# Use default settings. Uncomment to change
|
|
||||||
# see man:systemd.netdev(5) § [BATMANADVANCED] SECTION OPTIONS
|
|
||||||
#[BatmanAdvanced]
|
|
@ -1,8 +0,0 @@
|
|||||||
# This file bridges any ethernet device found
|
|
||||||
# to the bridge made in 02-bridge.netdev
|
|
||||||
[Match]
|
|
||||||
Name=en*
|
|
||||||
Name=eth*
|
|
||||||
|
|
||||||
[Network]
|
|
||||||
Bridge=bridge0
|
|
Loading…
x
Reference in New Issue
Block a user