mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
utils: add 'scan' feature to ixll
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -22,6 +22,12 @@ may be supplied in places where a hostname is otherwise expected.
|
||||
|
||||
Commands:
|
||||
|
||||
scan [-a] [<iface>]
|
||||
Discover Infix devices on the LAN using mDNS-SD (avahi-browse).
|
||||
Use -a to show all mDNS devices, not just Infix. Falls back to
|
||||
IPv6 link-local multicast ping if avahi-browse is not installed
|
||||
and <iface> is specified.
|
||||
|
||||
peer <iface>
|
||||
Return the address of the first IPv6 neighbor to respond on
|
||||
<iface>'s local LAN.
|
||||
@@ -75,6 +81,9 @@ case "$cmd" in
|
||||
help)
|
||||
usage && exit 0
|
||||
;;
|
||||
scan)
|
||||
llscan "$@"
|
||||
;;
|
||||
peer)
|
||||
llpeer "$@"
|
||||
;;
|
||||
|
||||
+152
@@ -144,3 +144,155 @@ llscp()
|
||||
|
||||
$sshpasscmd scp $LLSCP_OPTS "$src" "$dst"
|
||||
}
|
||||
|
||||
# Usage: llscan [-a] [<iface>]
|
||||
#
|
||||
# Discover Infix devices (or all mDNS devices with -a) on the LAN.
|
||||
# Prefers mDNS-SD via avahi-browse; falls back to IPv6 link-local
|
||||
# multicast ping if avahi-browse is not available and an interface
|
||||
# is specified.
|
||||
llscan()
|
||||
{
|
||||
local all=0
|
||||
local iface=
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-a)
|
||||
all=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
iface="$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$iface" ] && [ ! -d "/sys/class/net/$iface" ]; then
|
||||
echo "Error: Interface \"$iface\" does not exist." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if command -v avahi-browse >/dev/null 2>&1; then
|
||||
llscan_mdns "$all"
|
||||
elif [ "$iface" ]; then
|
||||
echo "Note: avahi-browse not found, falling back to link-local scan." >&2
|
||||
llscan_ll "$iface"
|
||||
else
|
||||
cat >&2 <<-EOF
|
||||
Error: avahi-browse not found.
|
||||
|
||||
Install avahi-utils to scan for Infix devices via mDNS:
|
||||
sudo apt install avahi-utils
|
||||
|
||||
Or specify an interface to use IPv6 link-local fallback:
|
||||
$(basename $0) scan <iface>
|
||||
EOF
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
llscan_mdns()
|
||||
{
|
||||
local all="$1"
|
||||
local flags="-tarp"
|
||||
|
||||
if avahi-browse --help 2>&1 | grep -q -- '-k'; then
|
||||
flags="-tarpk"
|
||||
fi
|
||||
|
||||
avahi-browse $flags | awk -F';' -v show_all="$all" '
|
||||
$1 == "=" {
|
||||
host = $7
|
||||
proto = $3
|
||||
addr = $8
|
||||
txt = $10
|
||||
|
||||
on = ""; ov = ""; product = ""; serial = ""; devid = ""
|
||||
n = split(txt, parts, "\" \"")
|
||||
for (i = 1; i <= n; i++) {
|
||||
gsub(/"/, "", parts[i])
|
||||
if (parts[i] ~ /^on=/) { split(parts[i], kv, "="); on = kv[2] }
|
||||
else if (parts[i] ~ /^ov=/) { split(parts[i], kv, "="); ov = kv[2] }
|
||||
else if (parts[i] ~ /^product=/) { split(parts[i], kv, "="); product = kv[2] }
|
||||
else if (parts[i] ~ /^serial=/) { split(parts[i], kv, "="); serial = kv[2] }
|
||||
else if (parts[i] ~ /^deviceid=/) { split(parts[i], kv, "="); devid = kv[2] }
|
||||
}
|
||||
|
||||
if (!show_all && on != "Infix") next
|
||||
|
||||
# Use deviceid (MAC) as unique key; fall back to hostname
|
||||
key = devid ? devid : host
|
||||
|
||||
if (!product) product = on ? on : "-"
|
||||
if (!ov) ov = "-"
|
||||
if (!serial || serial == "null") serial = "-"
|
||||
|
||||
# Prefer IPv4 for display address
|
||||
if (proto == "IPv4") {
|
||||
ipv4[key] = addr
|
||||
} else if (proto == "IPv6" && !ipv6[key]) {
|
||||
ipv6[key] = addr
|
||||
}
|
||||
|
||||
if (!seen[key]++) {
|
||||
keys[++ndevs] = key
|
||||
hosts[key] = host
|
||||
products[key] = product
|
||||
versions[key] = ov
|
||||
serials[key] = serial
|
||||
} else if (length(host) > length(hosts[key])) {
|
||||
# Prefer the unique hostname (e.g., infix-c0-ff-ee.local)
|
||||
# over the generic one (e.g., infix.local)
|
||||
hosts[key] = host
|
||||
}
|
||||
}
|
||||
|
||||
END {
|
||||
if (ndevs == 0) {
|
||||
if (show_all)
|
||||
print "No mDNS devices found." | "cat >&2"
|
||||
else
|
||||
print "No Infix devices found. Use -a to show all mDNS devices." | "cat >&2"
|
||||
exit 1
|
||||
}
|
||||
|
||||
fmt = "%-26s %-18s %-24s %-22s %s\n"
|
||||
hdr = sprintf(fmt, "HOSTNAME", "ADDRESS", "PRODUCT", "VERSION", "SERIAL")
|
||||
sub(/\n$/, "", hdr)
|
||||
printf "\033[7m%s\033[0m\n", hdr
|
||||
|
||||
for (i = 1; i <= ndevs; i++) {
|
||||
k = keys[i]
|
||||
a = (ipv4[k] ? ipv4[k] : (ipv6[k] ? ipv6[k] : "-"))
|
||||
p = products[k]; if (length(p) > 23) p = substr(p, 1, 22) "~"
|
||||
v = versions[k]; if (length(v) > 21) v = substr(v, 1, 20) "~"
|
||||
printf fmt, hosts[k], a, p, v, serials[k]
|
||||
}
|
||||
|
||||
printf "\n%d device(s) found.\n", ndevs
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
llscan_ll()
|
||||
{
|
||||
local iface="$1"
|
||||
|
||||
printf "Scanning %s for IPv6 link-local neighbors ...\n\n" "$iface"
|
||||
printf "\033[7m%-6s %s\033[0m\n" "#" "ADDRESS"
|
||||
|
||||
llping "$iface" -c3 -w3 2>/dev/null | awk '
|
||||
/bytes from/ {
|
||||
sub(/:$/, "", $4)
|
||||
addr = $4
|
||||
if (!seen[addr]++) {
|
||||
printf "%-6d %s\n", ++n, addr
|
||||
}
|
||||
}
|
||||
END {
|
||||
printf "\n%d neighbor(s) found on '"$iface"'.\n", n+0
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user