A simple ping implementation in Go, written as a "Hello World" project.
This imlementation supports both IPv4 and IPv6 on both Linux and Windows,
as well as several command-line switches like -t
(to set the TTL), -s
to set the payload size,
-W
to set the socket timeout, and others.
It's here as a reference for others, there's no good reason to actually use it. You have a perfectly good ping implementation in your OS, use that one.
-
In hidnsight, not a great choice for a first project in Go. I've spent way too much time on dealing with different syscalls, and too little time on Go.
-
Windows support was especially hard since golang.org/x/sys simply didn't implement the necessary syscalls (
recvfrom
,sendto
), so I implemented them myself (Pull Request #1, Pull Request #2). Even some of the standard constants likeIPPROTO_ICMP
were missing and had to be added (Pull Request #3, Pull Request #4) -
golang.org/x/sys/windows still lacks a lot of basic syscalls. Some just don't exist while others return
syscall.EWINDOWS
, which meansnot supported by windows
. -
IPv6 Raw sockets behave differently than IPv4 sockets. Most relevantly, an IPv6 raw socket doesn't allow the application to send or receive the IPv6 header itself (See RFC 3542). This means that to print the TTL (Hop Limit) field, one needs to use ancillary data, which is avaiable only using the
recvmsg
syscall. Unsurprisingly,recvmsg
and its send counterpartsendmsg
aren't implemented in Windows, so that might be something more to do in the future. The current implementation usesrecvfrom
, so when pinging an IPv6 address, a TTL of 0 will be printed.