Skip to content

Instantly share code, notes, and snippets.

@maurerle
Last active August 24, 2024 00:20
Show Gist options
  • Save maurerle/3586f2b8d825a69df0f523f60b731efa to your computer and use it in GitHub Desktop.
Save maurerle/3586f2b8d825a69df0f523f60b731efa to your computer and use it in GitHub Desktop.
update-bat-hosts - get the list of neighbours from the meshviewer to see in batctlcd
#!/usr/bin/lua
-- SPDX-FileCopyrightText: Florian Maurer
-- SPDX-License-Identifier: MIT
local jsonc = require("jsonc")
local function truncate_hostname(hostname, max_length)
-- If the hostname is already within the maximum length, return it as is
if #hostname <= max_length then
return hostname
end
-- Define the number of characters to keep at the start and end
local keep_start = math.floor((max_length - 3) / 2)
local keep_end = max_length - 3 - keep_start
-- Concatenate the start, ellipses, and end of the hostname
return hostname:sub(1, keep_start) .. "..." .. hostname:sub(-keep_end)
end
-- Function to fetch JSON data using wget
local function fetch_json_from_url(url)
local tmpfile = "/tmp/nodes.json" -- Temporary file to store the downloaded JSON data
local success = os.execute("wget -q -O " .. tmpfile .. " " .. url)
if success > 0 then
error("Failed to download JSON file from" .. url)
end
local file = io.open(tmpfile, "r")
if not file then
error("Failed to open the downloaded JSON file")
end
local json_data = file:read("*all")
file:close()
return json_data
end
-- Function to parse the JSON data and output MAC addresses with hostnames
local function parse_and_print_mac_addresses(json_data, gateway_only)
gateway_only = gateway_only or true
local data = jsonc.parse(json_data)
if not data then
error("Failed to parse JSON data")
end
local seen_hostnames = {} -- Table to keep track of seen hostnames
local file = io.open("/tmp/bat-hosts", "w")
if not file then
error("Failed to open /tmp/bat-hosts")
end
-- Iterate over nodes and extract MAC addresses with corresponding hostnames
for _, node in ipairs(data.nodes) do
local hostname = truncate_hostname(node.nodeinfo.hostname:gsub("%s", "-"), 30)
local mesh = node.nodeinfo.network.mesh
-- only parse if gateway filter is off or is gateway
-- and if mesh info exists and host was not seen yet (otherwise this would give warnings)
if (not gateway_only or node.flags.gateway) and mesh and not seen_hostnames[hostname] then
seen_hostnames[hostname] = true
for _, mesh_interface in pairs(mesh) do
local interfaces = mesh_interface.interfaces
-- Loop through wireless, other, and tunnel interfaces
for iface, mac_list in pairs(interfaces) do
for idx, mac in ipairs(mac_list) do
file:write(mac .. " " .. hostname .. "-" .. iface .. "" .. idx .. "\n")
end
end
end
end
end
end
local url = arg[1]
local json_data = fetch_json_from_url(url)
parse_and_print_mac_addresses(json_data)
os.execute("ln -s /tmp/bat-hosts /etc/bat-hosts")
@maurerle
Copy link
Author

One can install it using:

wget https://gist.githubusercontent.com/maurerle/3586f2b8d825a69df0f523f60b731efa/raw/23b68babcc73d2054d3cb0df95e9b6f9d239abcd/update-bat-hosts.lua
chmod +x update-bat-hosts.lua

One can then call it using you communities nodes.json:
update-bat-hosts "https://map.aachen.freifunk.net/data/nodes.json"

Though this takes quite a few seconds on router cpus but is decent on x86.

Few notes:

  • batctl hostnames have to be unique so I added the iface and an index to the name
  • batctl has a host length limit of 50 - adding iface and idx and other chars, i used 30 real chars as maximum
  • batctl gives warnings if hosts are duplicated, so duplicates are removed (as some people just name their device "Freifunk")

Also see freifunk-gluon/community-packages#129

@herbetom
Copy link

Cool script to test /etc/bat-hosts. Didn't know about that one.

I noticed two things:

If run again the symlink creation fails: ln: /etc/bat-hosts: File exists

Also it could be good not to get a traceback if the url is ommited but some more helpfull error message.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment