[WireGuard] [PATCH] go test: add ICMP ping
Jonathan Rudenberg
jonathan at titanous.com
Thu Jul 7 04:57:08 CEST 2016
---
contrib/external-tests/go/main.go | 72 ++++++++++++++++++++++++++++++++++-----
1 file changed, 64 insertions(+), 8 deletions(-)
diff --git a/contrib/external-tests/go/main.go b/contrib/external-tests/go/main.go
index 16632bb..68447fe 100644
--- a/contrib/external-tests/go/main.go
+++ b/contrib/external-tests/go/main.go
@@ -12,6 +12,8 @@ import (
"github.com/dchest/blake2s"
"github.com/titanous/noise"
+ "golang.org/x/net/icmp"
+ "golang.org/x/net/ipv4"
)
func main() {
@@ -36,6 +38,7 @@ func main() {
}
defer conn.Close()
+ // write handshake initiation packet
now := time.Now()
tai64n := make([]byte, 12)
binary.BigEndian.PutUint64(tai64n[:], uint64(now.Unix()))
@@ -53,6 +56,7 @@ func main() {
log.Fatalf("error writing initiation packet: %s", err)
}
+ // read handshake response packet
responsePacket := make([]byte, 89)
n, err := conn.Read(responsePacket)
if err != nil {
@@ -69,7 +73,7 @@ func main() {
if ourIndex != 28 {
log.Fatalf("response packet index wrong: want %d, got %d", 28, ourIndex)
}
- payload, sendCipher, _, err := hs.ReadMessage(nil, responsePacket[9:57])
+ payload, sendCipher, receiveCipher, err := hs.ReadMessage(nil, responsePacket[9:57])
if err != nil {
log.Fatalf("error reading handshake message: %s", err)
}
@@ -77,12 +81,64 @@ func main() {
log.Fatalf("unexpected payload: %x", payload)
}
- keepalivePacket := make([]byte, 13)
- keepalivePacket[0] = 4 // Type: Data
- binary.LittleEndian.PutUint32(keepalivePacket[1:], theirIndex)
- binary.LittleEndian.PutUint64(keepalivePacket[5:], 0) // Nonce
- keepalivePacket = sendCipher.Encrypt(keepalivePacket, nil, nil)
- if _, err := conn.Write(keepalivePacket); err != nil {
- log.Fatalf("error writing keepalive packet: %s", err)
+ // write ICMP Echo packet
+ pingMessage, _ := (&icmp.Message{
+ Type: ipv4.ICMPTypeEcho,
+ Body: &icmp.Echo{
+ ID: 1,
+ Seq: 1,
+ Data: []byte("WireGuard"),
+ },
+ }).Marshal(nil)
+ pingHeader, err := (&ipv4.Header{
+ Version: ipv4.Version,
+ Len: ipv4.HeaderLen,
+ TotalLen: ipv4.HeaderLen + len(pingMessage),
+ Protocol: 1, // ICMP
+ TTL: 2,
+ Checksum: 0xa15b, // the packet is always the same, hard-code checksum
+ Src: net.IPv4(10, 189, 129, 2),
+ Dst: net.IPv4(10, 189, 129, 1),
+ }).Marshal()
+ binary.BigEndian.PutUint16(pingHeader[2:], uint16(ipv4.HeaderLen+len(pingMessage))) // fix the length endianness on BSDs
+ if err != nil {
+ panic(err)
+ }
+ pingPacket := make([]byte, 13)
+ pingPacket[0] = 4 // Type: Data
+ binary.LittleEndian.PutUint32(pingPacket[1:], theirIndex)
+ binary.LittleEndian.PutUint64(pingPacket[5:], 0) // Nonce
+ pingPacket = sendCipher.Encrypt(pingPacket, nil, append(pingHeader, pingMessage...))
+ if _, err := conn.Write(pingPacket); err != nil {
+ log.Fatalf("error writing ping message: %s", err)
+ }
+
+ // read ICMP Echo Reply packet
+ replyPacket := make([]byte, 128)
+ n, err = conn.Read(replyPacket)
+ if err != nil {
+ log.Fatalf("error reading ping reply message: %s", err)
+ }
+ replyPacket = replyPacket[:n]
+ if replyPacket[0] != 4 { // Type: Data
+ log.Fatalf("unexpected reply packet type: %d", replyPacket[0])
+ }
+ replyPacket, err = receiveCipher.Decrypt(nil, nil, replyPacket[13:])
+ if err != nil {
+ log.Fatalf("error decrypting reply packet: %s", err)
+ }
+ replyHeaderLen := int(replyPacket[0]&0x0f) << 2
+ replyLen := binary.BigEndian.Uint16(replyPacket[2:])
+ replyMessage, err := icmp.ParseMessage(1, replyPacket[replyHeaderLen:replyLen])
+ if err != nil {
+ log.Fatalf("error parsing echo: %s", err)
+ }
+ echo, ok := replyMessage.Body.(*icmp.Echo)
+ if !ok {
+ log.Fatalf("unexpected reply body type %T", replyMessage.Body)
+ }
+
+ if echo.ID != 1 || echo.Seq != 1 || string(echo.Data) != "WireGuard" {
+ log.Fatalf("incorrect echo response: %#v", echo)
}
}
--
2.9.0
More information about the WireGuard
mailing list