go test: add ICMP ping
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
		
							parent
							
								
									1f349aa101
								
							
						
					
					
						commit
						35a61c32fa
					
				@ -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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user