ping: check IPv6 is actually usable, and split ping4 per platform
The ping wrapper only asked whether the *target* had an AAAA record, never whether this machine could reach over IPv6, so `ping ya.ru` ran ping6 and died with "No route to host" while IPv4 worked fine. Checking for a default v6 route is not sufficient either: this Mac has one while holding only ::1 and fe80:: link-locals. So require a global unicast address (2000::/3) as well as the route, which is the condition that actually fails here. ping4 is now platform-split rather than branching internally, since macOS ping rejects -4: macOS ~/.local/bin/ping (wrapper) and ~/.local/bin/ping4 -> /sbin/ping Linux a fish function running `ping -4` .chezmoiignore gates each side so neither lands where it cannot work.
This commit is contained in:
parent
0f758cb668
commit
af05b9e245
@ -3,6 +3,14 @@ Library
|
|||||||
.terminfo
|
.terminfo
|
||||||
.1password
|
.1password
|
||||||
.config/karabiner
|
.config/karabiner
|
||||||
|
# macOS-only: the ping wrapper drives /sbin/ping6 and dscacheutil, and ping4
|
||||||
|
# is a symlink to /sbin/ping. Linux ping picks a family itself and takes -4.
|
||||||
|
.local/bin/ping
|
||||||
|
.local/bin/ping4
|
||||||
|
{{- end }}
|
||||||
|
{{- if eq .chezmoi.os "darwin" }}
|
||||||
|
# Linux-only: macOS ping rejects -4, so there ping4 is ~/.local/bin/ping4.
|
||||||
|
.config/fish/functions/ping4.fish
|
||||||
{{- end }}
|
{{- end }}
|
||||||
.config/karabiner/automatic_backups
|
.config/karabiner/automatic_backups
|
||||||
.config/scripts/__pycache__
|
.config/scripts/__pycache__
|
||||||
|
|||||||
5
private_dot_config/private_fish/functions/ping4.fish
Normal file
5
private_dot_config/private_fish/functions/ping4.fish
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
function ping4 --description 'Ping over IPv4'
|
||||||
|
# Linux only -- .chezmoiignore keeps this off macOS, where ping has no -4
|
||||||
|
# flag and ~/.local/bin/ping4 points at /sbin/ping instead.
|
||||||
|
command ping -4 $argv
|
||||||
|
end
|
||||||
48
private_dot_local/bin/executable_ping
Normal file
48
private_dot_local/bin/executable_ping
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Unified ping, native output preserved.
|
||||||
|
#
|
||||||
|
# macOS still ships separate ping/ping6 binaries, so this picks one the way
|
||||||
|
# Linux's ping does: IPv6 when the target has an AAAA record *and* this machine
|
||||||
|
# can actually reach over IPv6, IPv4 otherwise.
|
||||||
|
|
||||||
|
v6_usable() {
|
||||||
|
# A default route on its own is not enough. A Mac with IPv6 switched off
|
||||||
|
# can still show a default v6 route while holding only ::1 and fe80::
|
||||||
|
# link-local addresses, and ping6 then dies with "No route to host".
|
||||||
|
# Global unicast is 2000::/3, so require an address starting with 2 or 3.
|
||||||
|
route -n get -inet6 default >/dev/null 2>&1 || return 1
|
||||||
|
ifconfig 2>/dev/null | awk '/inet6 /{ print $2 }' | grep -qE '^[23]'
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
-6)
|
||||||
|
shift
|
||||||
|
exec /sbin/ping6 "$@"
|
||||||
|
;;
|
||||||
|
-4)
|
||||||
|
shift
|
||||||
|
exec /sbin/ping "$@"
|
||||||
|
;;
|
||||||
|
*:*)
|
||||||
|
# An explicit IPv6 literal: honour it and let ping6 report any problem.
|
||||||
|
exec /sbin/ping6 "$@"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# First non-option argument is the target.
|
||||||
|
for a in "$@"; do
|
||||||
|
case "$a" in
|
||||||
|
-*) ;;
|
||||||
|
*)
|
||||||
|
t="$a"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$t" ] && v6_usable &&
|
||||||
|
dscacheutil -q host -a name "$t" 2>/dev/null | grep -q ipv6_address; then
|
||||||
|
exec /sbin/ping6 "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec /sbin/ping "$@"
|
||||||
1
private_dot_local/bin/symlink_ping4
Normal file
1
private_dot_local/bin/symlink_ping4
Normal file
@ -0,0 +1 @@
|
|||||||
|
/sbin/ping
|
||||||
Loading…
Reference in New Issue
Block a user