#!/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 . """ Setup a working BATMAN Advanced network with systemd-networkd and iwd """ import sys from pathlib import Path from shutil import copy from dasbus.connection import SystemMessageBus from dasbus.error import DBusError NETWORKD_CONFIGS = "/usr/share/naxalnet/networkd" NETWORKD_VOLATILE_DIR = "/run/systemd/network" ADHOC_SSID = "HelloWorld" AP_SSID = "NaxalNet" AP_PASSWD = "naxalnet256" # Copy networkd configs to volatile dir. # The D-Bus API does not support creating new interfaces # or linking to bridges. So we use config files. # See man:systemd.network(5) try: print("Copying network config files") dest = Path(NETWORKD_VOLATILE_DIR) src = Path(NETWORKD_CONFIGS) # Create the volatile directory if it doesn't exist dest.mkdir(parents=True, exist_ok=True) # Copy all files in src to dest for i in src.iterdir(): copy(i, dest) except PermissionError as error: print(error) sys.exit("Make sure you are root") # Now, the iwd part try: # connect to the System bus bus = SystemMessageBus() # iwd proxy iwd = bus.get_proxy("net.connman.iwd", "/") # Get list of all devices print("Finding connected devices") objects = iwd.GetManagedObjects() # devices that support ad-hoc adhoc_devices = [] # devices that support ap ap_devices = [] for path, obj in objects.items(): if "net.connman.iwd.Device" in obj: # add all devices to the list name = obj["net.connman.iwd.Device"]["Name"] print("Found device", name) adapter_path = obj["net.connman.iwd.Device"]["Adapter"].get_string() adapter = objects[adapter_path]["net.connman.iwd.Adapter"] if "ad-hoc" in adapter["SupportedModes"]: print(name, "supports ad-hoc") adhoc_devices.append(path) if "ap" in adapter["SupportedModes"]: print(name, "supports ap") ap_devices.append(path) if len(adhoc_devices) != 0: # Start ad-hoc on first device supporting ad-hoc dev1path = adhoc_devices.pop() # The same device is likely to have ap support too. # But we can't start ad-hoc and ap on the same interface. # Remove dev1 from ap_devices if it exists there if dev1path in ap_devices: ap_devices.remove(dev1path) print("Working on ad-hoc") dev1 = bus.get_proxy("net.connman.iwd", dev1path) print("Starting ad-hoc on", dev1.Name) if not dev1.Powered: print("Device is off. Turning on") dev1.Powered = True if dev1.Mode != "ad-hoc": print("Device is in", dev1.Mode) print("Switching to ad-hoc") dev1.Mode = "ad-hoc" # Changing Mode needs connecting to the proxy again dev1 = bus.get_proxy("net.connman.iwd", dev1path) # If already connected to ad-hoc, stop it if dev1.Started is True: print("Already connected to ad-hoc. Stopping") dev1.Stop() # Reconnect to proxy or StartOpen won't work dev1 = bus.get_proxy("net.connman.iwd", dev1path) print("Starting ad-hoc network") dev1.StartOpen(ADHOC_SSID) # Start Access point if ap_device is not empty, # ie, we have more devices if len(ap_devices) != 0: print("Working on AP") dev2path = ap_devices.pop() dev2 = bus.get_proxy("net.connman.iwd", dev2path) if not dev1.Powered: print("Device is off. Turning on") dev1.Powered = True if dev2.Mode != "ap": print(dev2.Name, "is in", dev2.Mode) print("Switching to ap") dev2.Mode = "ap" dev2 = bus.get_proxy("net.connman.iwd", dev2path) if dev2.Started is True: print("An AP is already started on", dev2.Name) print("Stopping") dev2.Stop() dev2 = bus.get_proxy("net.connman.iwd", dev2path) print("Starting AP on", dev2.Name) dev2.Start(AP_SSID, AP_PASSWD) except DBusError: sys.exit("An error occured while communicating with iwd") print("Bye")