mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-30 04:33:00 +02:00
utils: ixll: Add link-local wrappers for ping/ssh/scp
This commit is contained in:
committed by
Joachim Wiberg
parent
0c917ab37e
commit
36716dab42
Executable
+92
@@ -0,0 +1,92 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
. $(dirname $(readlink -f "$0"))/libll.sh
|
||||
|
||||
usage()
|
||||
{
|
||||
local me="$(basename $0)"
|
||||
|
||||
cat <<EOF
|
||||
usage: $me [-A] <command> [<args>]
|
||||
|
||||
Wrap various existing network facilities such that an interface name
|
||||
may be supplied in places where a hostname is otherwise expected.
|
||||
|
||||
Options:
|
||||
|
||||
-A
|
||||
For commands requiring authentication, use password
|
||||
authentication with username "admin" and password "admin".
|
||||
|
||||
Commands:
|
||||
|
||||
peer <iface>
|
||||
Return the address of the first IPv6 neighbor to respond on
|
||||
<iface>'s local LAN.
|
||||
|
||||
ping <iface>
|
||||
Send ping to all-hosts group, with link-local scope, on <iface>,
|
||||
suppressing loopbacked packets.
|
||||
|
||||
ssh <iface> [<ssh-arguments>]
|
||||
ssh(1) to the neighboring host on <iface>.
|
||||
|
||||
scp <src> <dst>
|
||||
scp(1) from <src> to <dst>, but any host specified in either
|
||||
<src> or <dst> is assumed to be an interface name, which is
|
||||
expanded to a neighboring host on that interface.
|
||||
|
||||
${0} help
|
||||
Display this message.
|
||||
|
||||
Examples:
|
||||
|
||||
Start interactive ssh(1) session to the neighbor to eth0
|
||||
$me ssh eth0
|
||||
|
||||
Copy /etc/hostname from the neighbor to eth0, using admin/admin
|
||||
$me -A scp eth0:/etc/hostname /tmp/hostname
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
while getopts "A" opt; do
|
||||
case ${opt} in
|
||||
A)
|
||||
LLSSH_USER=admin
|
||||
LLSSH_PASS=admin
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
usage && exit 1
|
||||
fi
|
||||
|
||||
cmd="$1"
|
||||
shift
|
||||
|
||||
case "$cmd" in
|
||||
help)
|
||||
usage && exit 0
|
||||
;;
|
||||
peer)
|
||||
llpeer "$@"
|
||||
;;
|
||||
ping)
|
||||
llping "$@"
|
||||
;;
|
||||
scp)
|
||||
llscp "$@"
|
||||
;;
|
||||
ssh)
|
||||
llssh "$@"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown command \"$cmd\"" >2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
# Utility functions for communicating with IPv6 neighbors on the local
|
||||
# LAN
|
||||
|
||||
# Usage: llping <iface>
|
||||
#
|
||||
# Send ping to all-hosts group, with link-local scope, on <iface>,
|
||||
# suppressing loopbacked packets.
|
||||
llping()
|
||||
{
|
||||
local iface="$1"
|
||||
shift
|
||||
ping -L ff02::1%$iface "$@"
|
||||
}
|
||||
|
||||
|
||||
# Usage: llpeer <iface>
|
||||
#
|
||||
# Return the address of the first IPv6 neighbor to respond on
|
||||
# <iface>'s local LAN. It is thus typically only useful in scenarios
|
||||
# where only one neighbor exists
|
||||
llpeer()
|
||||
{
|
||||
local iface="$1"
|
||||
shift
|
||||
llping $iface -c1 "$@" | \
|
||||
awk '/bytes from/ { sub(/:$/, "", $4); print($4); exit(0); }'
|
||||
}
|
||||
|
||||
llssh_expand()
|
||||
{
|
||||
local old_ifs="$IFS"
|
||||
|
||||
local orig="$1"
|
||||
local fmt="$2"
|
||||
|
||||
local peer=
|
||||
local user=
|
||||
local iface=
|
||||
|
||||
IFS=@
|
||||
set $1
|
||||
IFS="$old_ifs"
|
||||
case $# in
|
||||
1)
|
||||
user="$LLSSH_USER"
|
||||
iface="$1"
|
||||
;;
|
||||
2)
|
||||
user="$1"
|
||||
iface="$2"
|
||||
;;
|
||||
*)
|
||||
echo "Error: Invalid peer \"$orig1\"" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -d "/sys/class/net/$iface" ]; then
|
||||
peer="$(llpeer $iface -w3)"
|
||||
else
|
||||
peer="$iface"
|
||||
fi
|
||||
|
||||
if [ ! "$peer" ]; then
|
||||
echo "Error: No peer responded on $iface" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
case "$fmt" in
|
||||
ssh)
|
||||
;;
|
||||
scp)
|
||||
peer="[$peer]"
|
||||
;;
|
||||
*)
|
||||
echo "Internal error: Invalid format \"$fmt\"" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
[ "$user" ] && peer="$user@$peer"
|
||||
echo $peer
|
||||
}
|
||||
|
||||
# Usage: llssh <destination> [<ssh-args>]
|
||||
#
|
||||
# ssh(1) to <destination>, but if the host matches an existing
|
||||
# interface name, expand it to a neighboring host on that interface.
|
||||
llssh()
|
||||
{
|
||||
local remote="$1"
|
||||
shift
|
||||
|
||||
local peer="$(llssh_expand $remote ssh)"
|
||||
[ "$peer" ] || return 1
|
||||
|
||||
local sshpasscmd=
|
||||
[ "$LLSSH_PASS" ] && sshpasscmd="sshpass -p$LLSSH_PASS $LLSSHPASS_OPTS"
|
||||
|
||||
$sshpasscmd ssh $LLSSH_OPTS $peer "$@"
|
||||
}
|
||||
|
||||
llscp_expand()
|
||||
{
|
||||
local orig="$1"
|
||||
local old_ifs="$IFS"
|
||||
|
||||
local peer=
|
||||
|
||||
IFS=:
|
||||
set $@
|
||||
IFS="$old_ifs"
|
||||
case $# in
|
||||
1)
|
||||
echo "$1"
|
||||
;;
|
||||
2)
|
||||
peer="$(llssh_expand $1 scp)"
|
||||
[ "$peer" ] || return 1
|
||||
|
||||
echo "$peer:$2"
|
||||
;;
|
||||
*)
|
||||
echo "Error: Invalid location \"$orig1\"" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Usage: llscp <src> <dst>
|
||||
#
|
||||
# scp(1) from <src> to <dst>, but expand any host specified in either
|
||||
# <src> or <dst>, which matches an existing interface name, to a
|
||||
# neighboring host on that interface.
|
||||
llscp()
|
||||
{
|
||||
local src="$(llscp_expand $1)"
|
||||
local dst="$(llscp_expand $2)"
|
||||
[ "$src" -a "$dst" ] || return 1
|
||||
shift 2
|
||||
|
||||
local sshpasscmd=
|
||||
[ "$LLSSH_PASS" ] && sshpasscmd="sshpass -p$LLSSH_PASS $LLSSHPASS_OPTS"
|
||||
|
||||
$sshpasscmd scp $LLSCP_OPTS "$src" "$dst"
|
||||
}
|
||||
Reference in New Issue
Block a user