Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to set static IPs, gateway, DNS to wired/wireless networks #5

Open
wants to merge 26 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0ca6a42
Removed logic to disable ethernet
nikeflight Jan 16, 2025
79a1f9a
Add support for wireless:
nikeflight Jan 16, 2025
f437299
Added support for wired networks: setting static ip, gateway, netmask…
nikeflight Jan 17, 2025
afeb7b9
remove dhcpd in piaware_config.py
nikeflight Jan 20, 2025
531a9d0
Add start-network.service, start_network.py to up the connections aft…
nikeflight Jan 20, 2025
a07dffa
Merge pull request #6 from flightaware/wifi-reboot-fix
nikeflight Jan 20, 2025
9ca90ee
Revert network-manager to dhcp in wireless/wired-type
nikeflight Jan 21, 2025
e821e38
Add test commands to README
nikeflight Jan 21, 2025
c0140e6
Add in logic to `ip addr show` then | to `grep`. Makes parsing for br…
nikeflight Jan 22, 2025
885d14a
manually upping wireless connections is not needed. Because we create…
nikeflight Jan 22, 2025
3d3f25a
Change network manager back to dhcp in debian-bookworm/piaware-config…
nikeflight Jan 22, 2025
4d7474c
Merge branch 'wired-network-change' of https://github.com/flightaware…
nikeflight Jan 22, 2025
9bff625
Add an ignore_list field to MetadataSetting. Adding a file to this li…
nikeflight Jan 22, 2025
4b14afe
updated .gitignore
nikeflight Jan 22, 2025
5ca30df
Addressing PR comments
nikeflight Jan 23, 2025
ccda2fa
PR comments
nikeflight Jan 23, 2025
5389a40
Merge branch 'wired-network-change' of https://github.com/flightaware…
nikeflight Jan 23, 2025
b7e6b0a
PR comments
nikeflight Jan 23, 2025
69ecfef
Add shebang to generate_network_config_bookworm.py
nikeflight Jan 23, 2025
a930fbd
Merge pull request #7 from flightaware/verify-brd-address
nikeflight Jan 24, 2025
9d5f156
PR comments
nikeflight Jan 24, 2025
41cebad
drop .py extension from generate_network_config_bookworm
nikeflight Jan 27, 2025
eb6fdf5
Change ignore_list to deprecated field
nikeflight Jan 27, 2025
2a566ab
Clean up dict init
nikeflight Jan 27, 2025
12512bb
Chnage netmask to be dotted decimal format
nikeflight Jan 27, 2025
1c13391
Add in default netmask for class A,B,C static IPs
nikeflight Jan 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@
pkgIndex.tcl
splashscreen/fa-logo.png
splashscreen/rpi-logo.png

.coverage
.DS_Store
/scripts/__pycache__
/tests/__pycache__
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,11 @@ sdcard image:
* initramfs support
* Management of /boot/config.txt when kernels or initramfs are updated
* Warns about default passwords when ssh is enabled

## Tests

`pip install pytest`
`pip install coverage`
run `python3 -m pytest`
run `coverage run -m pytest`
run `coverage html`
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@

[Unit]
Description=Generate network configuration
Before=network-pre.target
Wants=network-pre.target
After=config-ready.target set-rfkill.service NetworkManager.service
Wants=config-ready.target
DefaultDependencies=no
Before=NetworkManager.service

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /usr/lib/piaware-support/generate-network-config-bookworm.py
ExecStart=/usr/lib/piaware-support/generate_network_config_bookworm

[Install]
WantedBy=network.target
2 changes: 1 addition & 1 deletion debian-bookworm/piaware-support.install
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package/*.tcl usr/lib/piaware-support/
scripts/generate-network-config-bookworm.py usr/lib/piaware-support/
scripts/generate_network_config_bookworm usr/lib/piaware-support/
scripts/generate-receiver-config usr/lib/piaware-support/
scripts/piaware_config.py usr/lib/piaware-support/
scripts/set-rfkill usr/lib/piaware-support/
Expand Down
67 changes: 0 additions & 67 deletions scripts/generate-network-config-bookworm.py

This file was deleted.

200 changes: 200 additions & 0 deletions scripts/generate_network_config_bookworm
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
#!/usr/bin/env python3

from piaware_config import get_standard_config_group, ConfigGroup
from uuid import uuid4
import subprocess
import os
import stat
import ipaddress

SYS_CON_DIR = "/etc/NetworkManager/system-connections"

def netmask_to_cidr(netmask) -> int:
return ipaddress.IPv4Network('0.0.0.0/' + netmask).prefixlen

# We're calculating broadcast address for an ipv4 address.
# Hence the magic number 32. Ipv4 addresses are 32 bits.
def calculate_brd_by_hand(addr: str, nm: int) -> str:
values = addr.split(".")
binaries = [f"{int(v):08b}" for v in values]
full_bin = list("".join(binaries))
for i in range(32 - nm):
full_bin[i + nm] = "1"

cur = ""
base_10_val = []
for index, i in enumerate(full_bin):
cur += i

if (index + 1) % 8 == 0 and index > 0:
base_10_val.append(f"{(int(cur, 2))}")
cur = ""

ba = ".".join(base_10_val)
return ba

def verify_broadcast_address(network: str,config: ConfigGroup) -> bool:
assigned_ba = config.get(f"{network}-broadcast")
if not assigned_ba:
return

print("Verifying broadcast address")
addr = config.get(f"{network}-address")
nm = config.get(f"{network}-netmask")

if addr is None or nm is None:
print(f"Addr: {addr}, Netmask: {nm}")
return

if nm > 32:
print("Netmask cannot be greater than 32. Stopping brd verification...")
return

calculated_ba = calculate_brd_by_hand(addr, nm)

if assigned_ba != calculated_ba:
print(f"Warning: the brd address that we've calculated: {calculated_ba} is different than the one you've assigned: {assigned_ba}")

def format_dns(dns_string: str) -> str:
names = dns_string.split()
formatted = ";".join(names) + ";"
return formatted

def check_address(network_type: str, config: ConfigGroup):
address = config.get(f"{network_type}-address")
if address is None:
raise ValueError(f"{network_type}-type was set to static but {network_type}-address was not set")
address = ipaddress.ip_address(address)

if address.version != 4:
raise ValueError(f"{network_type}-address needs an ipv4 address")

def get_netmask(network_type: str, config: ConfigGroup) -> str:
netmask = config.get(f"{network_type}-netmask")
if netmask is None:
address = config.get(f"{network_type}-address")
address = ipaddress.ip_address(address)
address = '{:#b}'.format(address)
address = address[2:]
match address[0:3]:
case "000":
return "255.0.0.0"
case "100":
return "255.255.0.0"
case "110":
return "255.255.255.0"
else:
return netmask

def configure_static_network(network_type: str, config: ConfigGroup) -> str:
check_address(network_type, config)
nm = get_netmask(network_type, config)
cidr = str(netmask_to_cidr(nm))
ip = ""
static_ip = config.get(f"{network_type}-address") + "/" + cidr
gateway = config.get(f"{network_type}-gateway")
if gateway is not None:
static_ip += f",{gateway}"
ip += f"address1={static_ip}\n"

name_servers = config.get(f"{network_type}-nameservers")
if name_servers is not None:
ip += f"dns={format_dns(name_servers)}\n"
return ip

def get_wired_conn_file(config: ConfigGroup):
new_uuid = uuid4()
connect = "true" if config.get("wired-network") else "false"

file = f"""
[connection]
id=wired
uuid={new_uuid}
type=ethernet
autoconnect-priority=999
interface-name=eth0
autoconnect={connect}

[ethernet]
"""
ipv4 = """
[ipv4]
"""
if config.get("wired-type") == "static":
ipv4 += configure_static_network("wired", config)
ipv4 += "method=manual\n"
else:
ipv4 += "method=auto\n"
file += ipv4
file += """
[ipv6]
addr-gen-mode=default
method=auto

[proxy]
"""

return file

def get_wireless_conn_file(config: ConfigGroup):
new_uuid = uuid4()
ssid = config.get("wireless-ssid")
psk = config.get("wireless-password")
connect = "true" if config.get("wireless-network") else "false"

file = f"""
[connection]
id=wireless
uuid={new_uuid}
type=wifi
autoconnect={connect}

[wifi]
mode=infrastructure
ssid={ssid}

[wifi-security]
key-mgmt=wpa-psk
psk={psk}
"""

ipv4 = """
[ipv4]
"""
if config.get("wireless-type") == "static":
ipv4 += configure_static_network("wireless", config)
ipv4 += f"method=manual\n"
else:
ipv4 += "method=auto\n"

ipv4 += """
[ipv6]
addr-gen-mode=default
method=auto

[proxy]
"""
file += ipv4
return file

def generate_wired_network_config(config: ConfigGroup):
with open(f"{SYS_CON_DIR}/wired.nmconnection", "w") as conn_file:
conn_file.write(get_wired_conn_file(config))

os.chmod(f"{SYS_CON_DIR}/wired.nmconnection", stat.S_IRUSR | stat.S_IWUSR)

def generate_wireless_network_config(config: ConfigGroup):
with open(f"{SYS_CON_DIR}/wireless.nmconnection", "w") as conn_file:
conn_file.write(get_wireless_conn_file(config))

os.chmod(f"{SYS_CON_DIR}/wireless.nmconnection", stat.S_IRUSR | stat.S_IWUSR)

def main(dryrun=False, extra_file_path: str = None):
config_group = get_standard_config_group(extra_file_path)
generate_wired_network_config(config_group)
generate_wireless_network_config(config_group)
verify_broadcast_address("wireless", config_group)
verify_broadcast_address("wired", config_group)

if __name__ == "__main__":
main()
Loading