// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package packet type ICMPType uint8 const ( ICMPEchoReply ICMPType = 0x00 ICMPEchoRequest ICMPType = 0x08 ICMPUnreachable ICMPType = 0x03 ICMPTimeExceeded ICMPType = 0x0b ) func (t ICMPType) String() string { switch t { case ICMPEchoReply: return "EchoReply" case ICMPEchoRequest: return "EchoRequest" case ICMPUnreachable: return "Unreachable" case ICMPTimeExceeded: return "TimeExceeded" default: return "Unknown" } } type ICMPCode uint8 const ( ICMPNoCode ICMPCode = 0 ) // ICMPHeader represents an ICMP packet header. type ICMPHeader struct { IPHeader Type ICMPType Code ICMPCode } const ( icmpHeaderLength = 4 // icmpTotalHeaderLength is the length of all headers in a ICMP packet. icmpAllHeadersLength = ipHeaderLength + icmpHeaderLength ) func (ICMPHeader) Len() int { return icmpAllHeadersLength } func (h ICMPHeader) Marshal(buf []byte) error { if len(buf) < icmpAllHeadersLength { return errSmallBuffer } if len(buf) > maxPacketLength { return errLargePacket } // The caller does not need to set this. h.IPProto = ICMP buf[20] = uint8(h.Type) buf[21] = uint8(h.Code) h.IPHeader.Marshal(buf) put16(buf[22:24], ipChecksum(buf)) return nil } func (h *ICMPHeader) ToResponse() { h.Type = ICMPEchoReply h.Code = ICMPNoCode h.IPHeader.ToResponse() }