aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/golang.org/x/net/icmp
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/net/icmp')
-rw-r--r--vendor/golang.org/x/net/icmp/diag_test.go274
-rw-r--r--vendor/golang.org/x/net/icmp/dstunreach.go8
-rw-r--r--vendor/golang.org/x/net/icmp/echo.go114
-rw-r--r--vendor/golang.org/x/net/icmp/endpoint.go13
-rw-r--r--vendor/golang.org/x/net/icmp/extension.go43
-rw-r--r--vendor/golang.org/x/net/icmp/extension_test.go508
-rw-r--r--vendor/golang.org/x/net/icmp/interface.go100
-rw-r--r--vendor/golang.org/x/net/icmp/ipv4_test.go118
-rw-r--r--vendor/golang.org/x/net/icmp/listen_stub.go2
-rw-r--r--vendor/golang.org/x/net/icmp/message.go25
-rw-r--r--vendor/golang.org/x/net/icmp/message_test.go245
-rw-r--r--vendor/golang.org/x/net/icmp/mpls.go4
-rw-r--r--vendor/golang.org/x/net/icmp/multipart.go38
-rw-r--r--vendor/golang.org/x/net/icmp/multipart_test.go807
-rw-r--r--vendor/golang.org/x/net/icmp/packettoobig.go2
-rw-r--r--vendor/golang.org/x/net/icmp/paramprob.go8
-rw-r--r--vendor/golang.org/x/net/icmp/ping_test.go200
-rw-r--r--vendor/golang.org/x/net/icmp/timeexceeded.go8
18 files changed, 1522 insertions, 995 deletions
diff --git a/vendor/golang.org/x/net/icmp/diag_test.go b/vendor/golang.org/x/net/icmp/diag_test.go
new file mode 100644
index 0000000..2ecd465
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/diag_test.go
@@ -0,0 +1,274 @@
+// Copyright 2014 The Go 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 icmp_test
+
+import (
+ "errors"
+ "fmt"
+ "net"
+ "os"
+ "runtime"
+ "sync"
+ "testing"
+ "time"
+
+ "golang.org/x/net/icmp"
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/nettest"
+ "golang.org/x/net/ipv4"
+ "golang.org/x/net/ipv6"
+)
+
+type diagTest struct {
+ network, address string
+ protocol int
+ m icmp.Message
+}
+
+func TestDiag(t *testing.T) {
+ if testing.Short() {
+ t.Skip("avoid external network")
+ }
+
+ t.Run("Ping/NonPrivileged", func(t *testing.T) {
+ switch runtime.GOOS {
+ case "darwin":
+ case "linux":
+ t.Log("you may need to adjust the net.ipv4.ping_group_range kernel state")
+ default:
+ t.Logf("not supported on %s", runtime.GOOS)
+ return
+ }
+ for i, dt := range []diagTest{
+ {
+ "udp4", "0.0.0.0", iana.ProtocolICMP,
+ icmp.Message{
+ Type: ipv4.ICMPTypeEcho, Code: 0,
+ Body: &icmp.Echo{
+ ID: os.Getpid() & 0xffff,
+ Data: []byte("HELLO-R-U-THERE"),
+ },
+ },
+ },
+
+ {
+ "udp6", "::", iana.ProtocolIPv6ICMP,
+ icmp.Message{
+ Type: ipv6.ICMPTypeEchoRequest, Code: 0,
+ Body: &icmp.Echo{
+ ID: os.Getpid() & 0xffff,
+ Data: []byte("HELLO-R-U-THERE"),
+ },
+ },
+ },
+ } {
+ if err := doDiag(dt, i); err != nil {
+ t.Error(err)
+ }
+ }
+ })
+ t.Run("Ping/Privileged", func(t *testing.T) {
+ if m, ok := nettest.SupportsRawIPSocket(); !ok {
+ t.Skip(m)
+ }
+ for i, dt := range []diagTest{
+ {
+ "ip4:icmp", "0.0.0.0", iana.ProtocolICMP,
+ icmp.Message{
+ Type: ipv4.ICMPTypeEcho, Code: 0,
+ Body: &icmp.Echo{
+ ID: os.Getpid() & 0xffff,
+ Data: []byte("HELLO-R-U-THERE"),
+ },
+ },
+ },
+
+ {
+ "ip6:ipv6-icmp", "::", iana.ProtocolIPv6ICMP,
+ icmp.Message{
+ Type: ipv6.ICMPTypeEchoRequest, Code: 0,
+ Body: &icmp.Echo{
+ ID: os.Getpid() & 0xffff,
+ Data: []byte("HELLO-R-U-THERE"),
+ },
+ },
+ },
+ } {
+ if err := doDiag(dt, i); err != nil {
+ t.Error(err)
+ }
+ }
+ })
+ t.Run("Probe/Privileged", func(t *testing.T) {
+ if m, ok := nettest.SupportsRawIPSocket(); !ok {
+ t.Skip(m)
+ }
+ for i, dt := range []diagTest{
+ {
+ "ip4:icmp", "0.0.0.0", iana.ProtocolICMP,
+ icmp.Message{
+ Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: os.Getpid() & 0xffff,
+ Local: true,
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Class: 3, Type: 1,
+ Name: "doesnotexist",
+ },
+ },
+ },
+ },
+ },
+
+ {
+ "ip6:ipv6-icmp", "::", iana.ProtocolIPv6ICMP,
+ icmp.Message{
+ Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: os.Getpid() & 0xffff,
+ Local: true,
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Class: 3, Type: 1,
+ Name: "doesnotexist",
+ },
+ },
+ },
+ },
+ },
+ } {
+ if err := doDiag(dt, i); err != nil {
+ t.Error(err)
+ }
+ }
+ })
+}
+
+func doDiag(dt diagTest, seq int) error {
+ c, err := icmp.ListenPacket(dt.network, dt.address)
+ if err != nil {
+ return err
+ }
+ defer c.Close()
+
+ dst, err := googleAddr(c, dt.protocol)
+ if err != nil {
+ return err
+ }
+
+ if dt.network != "udp6" && dt.protocol == iana.ProtocolIPv6ICMP {
+ var f ipv6.ICMPFilter
+ f.SetAll(true)
+ f.Accept(ipv6.ICMPTypeDestinationUnreachable)
+ f.Accept(ipv6.ICMPTypePacketTooBig)
+ f.Accept(ipv6.ICMPTypeTimeExceeded)
+ f.Accept(ipv6.ICMPTypeParameterProblem)
+ f.Accept(ipv6.ICMPTypeEchoReply)
+ f.Accept(ipv6.ICMPTypeExtendedEchoReply)
+ if err := c.IPv6PacketConn().SetICMPFilter(&f); err != nil {
+ return err
+ }
+ }
+
+ switch m := dt.m.Body.(type) {
+ case *icmp.Echo:
+ m.Seq = 1 << uint(seq)
+ case *icmp.ExtendedEchoRequest:
+ m.Seq = 1 << uint(seq)
+ }
+ wb, err := dt.m.Marshal(nil)
+ if err != nil {
+ return err
+ }
+ if n, err := c.WriteTo(wb, dst); err != nil {
+ return err
+ } else if n != len(wb) {
+ return fmt.Errorf("got %v; want %v", n, len(wb))
+ }
+
+ rb := make([]byte, 1500)
+ if err := c.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
+ return err
+ }
+ n, peer, err := c.ReadFrom(rb)
+ if err != nil {
+ return err
+ }
+ rm, err := icmp.ParseMessage(dt.protocol, rb[:n])
+ if err != nil {
+ return err
+ }
+ switch {
+ case dt.m.Type == ipv4.ICMPTypeEcho && rm.Type == ipv4.ICMPTypeEchoReply:
+ fallthrough
+ case dt.m.Type == ipv6.ICMPTypeEchoRequest && rm.Type == ipv6.ICMPTypeEchoReply:
+ fallthrough
+ case dt.m.Type == ipv4.ICMPTypeExtendedEchoRequest && rm.Type == ipv4.ICMPTypeExtendedEchoReply:
+ fallthrough
+ case dt.m.Type == ipv6.ICMPTypeExtendedEchoRequest && rm.Type == ipv6.ICMPTypeExtendedEchoReply:
+ return nil
+ default:
+ return fmt.Errorf("got %+v from %v; want echo reply or extended echo reply", rm, peer)
+ }
+}
+
+func googleAddr(c *icmp.PacketConn, protocol int) (net.Addr, error) {
+ host := "ipv4.google.com"
+ if protocol == iana.ProtocolIPv6ICMP {
+ host = "ipv6.google.com"
+ }
+ ips, err := net.LookupIP(host)
+ if err != nil {
+ return nil, err
+ }
+ netaddr := func(ip net.IP) (net.Addr, error) {
+ switch c.LocalAddr().(type) {
+ case *net.UDPAddr:
+ return &net.UDPAddr{IP: ip}, nil
+ case *net.IPAddr:
+ return &net.IPAddr{IP: ip}, nil
+ default:
+ return nil, errors.New("neither UDPAddr nor IPAddr")
+ }
+ }
+ if len(ips) > 0 {
+ return netaddr(ips[0])
+ }
+ return nil, errors.New("no A or AAAA record")
+}
+
+func TestConcurrentNonPrivilegedListenPacket(t *testing.T) {
+ if testing.Short() {
+ t.Skip("avoid external network")
+ }
+ switch runtime.GOOS {
+ case "darwin":
+ case "linux":
+ t.Log("you may need to adjust the net.ipv4.ping_group_range kernel state")
+ default:
+ t.Skipf("not supported on %s", runtime.GOOS)
+ }
+
+ network, address := "udp4", "127.0.0.1"
+ if !nettest.SupportsIPv4() {
+ network, address = "udp6", "::1"
+ }
+ const N = 1000
+ var wg sync.WaitGroup
+ wg.Add(N)
+ for i := 0; i < N; i++ {
+ go func() {
+ defer wg.Done()
+ c, err := icmp.ListenPacket(network, address)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ c.Close()
+ }()
+ }
+ wg.Wait()
+}
diff --git a/vendor/golang.org/x/net/icmp/dstunreach.go b/vendor/golang.org/x/net/icmp/dstunreach.go
index 75db991..7464bf7 100644
--- a/vendor/golang.org/x/net/icmp/dstunreach.go
+++ b/vendor/golang.org/x/net/icmp/dstunreach.go
@@ -16,24 +16,24 @@ func (p *DstUnreach) Len(proto int) int {
if p == nil {
return 0
}
- l, _ := multipartMessageBodyDataLen(proto, p.Data, p.Extensions)
+ l, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions)
return 4 + l
}
// Marshal implements the Marshal method of MessageBody interface.
func (p *DstUnreach) Marshal(proto int) ([]byte, error) {
- return marshalMultipartMessageBody(proto, p.Data, p.Extensions)
+ return marshalMultipartMessageBody(proto, true, p.Data, p.Extensions)
}
// parseDstUnreach parses b as an ICMP destination unreachable message
// body.
-func parseDstUnreach(proto int, b []byte) (MessageBody, error) {
+func parseDstUnreach(proto int, typ Type, b []byte) (MessageBody, error) {
if len(b) < 4 {
return nil, errMessageTooShort
}
p := &DstUnreach{}
var err error
- p.Data, p.Extensions, err = parseMultipartMessageBody(proto, b)
+ p.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b)
if err != nil {
return nil, err
}
diff --git a/vendor/golang.org/x/net/icmp/echo.go b/vendor/golang.org/x/net/icmp/echo.go
index e6f15ef..c611f65 100644
--- a/vendor/golang.org/x/net/icmp/echo.go
+++ b/vendor/golang.org/x/net/icmp/echo.go
@@ -31,7 +31,7 @@ func (p *Echo) Marshal(proto int) ([]byte, error) {
}
// parseEcho parses b as an ICMP echo request or reply message body.
-func parseEcho(proto int, b []byte) (MessageBody, error) {
+func parseEcho(proto int, _ Type, b []byte) (MessageBody, error) {
bodyLen := len(b)
if bodyLen < 4 {
return nil, errMessageTooShort
@@ -43,3 +43,115 @@ func parseEcho(proto int, b []byte) (MessageBody, error) {
}
return p, nil
}
+
+// An ExtendedEchoRequest represents an ICMP extended echo request
+// message body.
+type ExtendedEchoRequest struct {
+ ID int // identifier
+ Seq int // sequence number
+ Local bool // must be true when identifying by name or index
+ Extensions []Extension // extensions
+}
+
+// Len implements the Len method of MessageBody interface.
+func (p *ExtendedEchoRequest) Len(proto int) int {
+ if p == nil {
+ return 0
+ }
+ l, _ := multipartMessageBodyDataLen(proto, false, nil, p.Extensions)
+ return 4 + l
+}
+
+// Marshal implements the Marshal method of MessageBody interface.
+func (p *ExtendedEchoRequest) Marshal(proto int) ([]byte, error) {
+ b, err := marshalMultipartMessageBody(proto, false, nil, p.Extensions)
+ if err != nil {
+ return nil, err
+ }
+ bb := make([]byte, 4)
+ binary.BigEndian.PutUint16(bb[:2], uint16(p.ID))
+ bb[2] = byte(p.Seq)
+ if p.Local {
+ bb[3] |= 0x01
+ }
+ bb = append(bb, b...)
+ return bb, nil
+}
+
+// parseExtendedEchoRequest parses b as an ICMP extended echo request
+// message body.
+func parseExtendedEchoRequest(proto int, typ Type, b []byte) (MessageBody, error) {
+ if len(b) < 4+4 {
+ return nil, errMessageTooShort
+ }
+ p := &ExtendedEchoRequest{ID: int(binary.BigEndian.Uint16(b[:2])), Seq: int(b[2])}
+ if b[3]&0x01 != 0 {
+ p.Local = true
+ }
+ var err error
+ _, p.Extensions, err = parseMultipartMessageBody(proto, typ, b[4:])
+ if err != nil {
+ return nil, err
+ }
+ return p, nil
+}
+
+// An ExtendedEchoReply represents an ICMP extended echo reply message
+// body.
+type ExtendedEchoReply struct {
+ ID int // identifier
+ Seq int // sequence number
+ State int // 3-bit state working together with Message.Code
+ Active bool // probed interface is active
+ IPv4 bool // probed interface runs IPv4
+ IPv6 bool // probed interface runs IPv6
+}
+
+// Len implements the Len method of MessageBody interface.
+func (p *ExtendedEchoReply) Len(proto int) int {
+ if p == nil {
+ return 0
+ }
+ return 4
+}
+
+// Marshal implements the Marshal method of MessageBody interface.
+func (p *ExtendedEchoReply) Marshal(proto int) ([]byte, error) {
+ b := make([]byte, 4)
+ binary.BigEndian.PutUint16(b[:2], uint16(p.ID))
+ b[2] = byte(p.Seq)
+ b[3] = byte(p.State<<5) & 0xe0
+ if p.Active {
+ b[3] |= 0x04
+ }
+ if p.IPv4 {
+ b[3] |= 0x02
+ }
+ if p.IPv6 {
+ b[3] |= 0x01
+ }
+ return b, nil
+}
+
+// parseExtendedEchoReply parses b as an ICMP extended echo reply
+// message body.
+func parseExtendedEchoReply(proto int, _ Type, b []byte) (MessageBody, error) {
+ if len(b) < 4 {
+ return nil, errMessageTooShort
+ }
+ p := &ExtendedEchoReply{
+ ID: int(binary.BigEndian.Uint16(b[:2])),
+ Seq: int(b[2]),
+ State: int(b[3]) >> 5,
+ }
+ if b[3]&0x04 != 0 {
+ p.Active = true
+ }
+ if b[3]&0x02 != 0 {
+ p.IPv4 = true
+ }
+ if b[3]&0x01 != 0 {
+ p.IPv6 = true
+ }
+ return p, nil
+}
diff --git a/vendor/golang.org/x/net/icmp/endpoint.go b/vendor/golang.org/x/net/icmp/endpoint.go
index a68bfb0..7640a8c5 100644
--- a/vendor/golang.org/x/net/icmp/endpoint.go
+++ b/vendor/golang.org/x/net/icmp/endpoint.go
@@ -7,7 +7,6 @@ package icmp
import (
"net"
"runtime"
- "syscall"
"time"
"golang.org/x/net/ipv4"
@@ -47,7 +46,7 @@ func (c *PacketConn) IPv6PacketConn() *ipv6.PacketConn {
// ReadFrom reads an ICMP message from the connection.
func (c *PacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
if !c.ok() {
- return 0, nil, syscall.EINVAL
+ return 0, nil, errInvalidConn
}
// Please be informed that ipv4.NewPacketConn enables
// IP_STRIPHDR option by default on Darwin.
@@ -64,7 +63,7 @@ func (c *PacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
// datagram-oriented ICMP endpoint. Otherwise it must be net.IPAddr.
func (c *PacketConn) WriteTo(b []byte, dst net.Addr) (int, error) {
if !c.ok() {
- return 0, syscall.EINVAL
+ return 0, errInvalidConn
}
return c.c.WriteTo(b, dst)
}
@@ -72,7 +71,7 @@ func (c *PacketConn) WriteTo(b []byte, dst net.Addr) (int, error) {
// Close closes the endpoint.
func (c *PacketConn) Close() error {
if !c.ok() {
- return syscall.EINVAL
+ return errInvalidConn
}
return c.c.Close()
}
@@ -89,7 +88,7 @@ func (c *PacketConn) LocalAddr() net.Addr {
// endpoint.
func (c *PacketConn) SetDeadline(t time.Time) error {
if !c.ok() {
- return syscall.EINVAL
+ return errInvalidConn
}
return c.c.SetDeadline(t)
}
@@ -98,7 +97,7 @@ func (c *PacketConn) SetDeadline(t time.Time) error {
// endpoint.
func (c *PacketConn) SetReadDeadline(t time.Time) error {
if !c.ok() {
- return syscall.EINVAL
+ return errInvalidConn
}
return c.c.SetReadDeadline(t)
}
@@ -107,7 +106,7 @@ func (c *PacketConn) SetReadDeadline(t time.Time) error {
// endpoint.
func (c *PacketConn) SetWriteDeadline(t time.Time) error {
if !c.ok() {
- return syscall.EINVAL
+ return errInvalidConn
}
return c.c.SetWriteDeadline(t)
}
diff --git a/vendor/golang.org/x/net/icmp/extension.go b/vendor/golang.org/x/net/icmp/extension.go
index 402a751..2005068 100644
--- a/vendor/golang.org/x/net/icmp/extension.go
+++ b/vendor/golang.org/x/net/icmp/extension.go
@@ -4,7 +4,12 @@
package icmp
-import "encoding/binary"
+import (
+ "encoding/binary"
+
+ "golang.org/x/net/ipv4"
+ "golang.org/x/net/ipv6"
+)
// An Extension represents an ICMP extension.
type Extension interface {
@@ -38,7 +43,7 @@ func validExtensionHeader(b []byte) bool {
// It will return a list of ICMP extensions and an adjusted length
// attribute that represents the length of the padded original
// datagram field. Otherwise, it returns an error.
-func parseExtensions(b []byte, l int) ([]Extension, int, error) {
+func parseExtensions(typ Type, b []byte, l int) ([]Extension, int, error) {
// Still a lot of non-RFC 4884 compliant implementations are
// out there. Set the length attribute l to 128 when it looks
// inappropriate for backwards compatibility.
@@ -48,20 +53,28 @@ func parseExtensions(b []byte, l int) ([]Extension, int, error) {
// header.
//
// See RFC 4884 for further information.
- if 128 > l || l+8 > len(b) {
- l = 128
- }
- if l+8 > len(b) {
- return nil, -1, errNoExtension
- }
- if !validExtensionHeader(b[l:]) {
- if l == 128 {
+ switch typ {
+ case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
+ if len(b) < 8 || !validExtensionHeader(b) {
return nil, -1, errNoExtension
}
- l = 128
- if !validExtensionHeader(b[l:]) {
+ l = 0
+ default:
+ if 128 > l || l+8 > len(b) {
+ l = 128
+ }
+ if l+8 > len(b) {
return nil, -1, errNoExtension
}
+ if !validExtensionHeader(b[l:]) {
+ if l == 128 {
+ return nil, -1, errNoExtension
+ }
+ l = 128
+ if !validExtensionHeader(b[l:]) {
+ return nil, -1, errNoExtension
+ }
+ }
}
var exts []Extension
for b = b[l+4:]; len(b) >= 4; {
@@ -82,6 +95,12 @@ func parseExtensions(b []byte, l int) ([]Extension, int, error) {
return nil, -1, err
}
exts = append(exts, ext)
+ case classInterfaceIdent:
+ ext, err := parseInterfaceIdent(b[:ol])
+ if err != nil {
+ return nil, -1, err
+ }
+ exts = append(exts, ext)
}
b = b[ol:]
}
diff --git a/vendor/golang.org/x/net/icmp/extension_test.go b/vendor/golang.org/x/net/icmp/extension_test.go
index 0b3f7b9..a7669da 100644
--- a/vendor/golang.org/x/net/icmp/extension_test.go
+++ b/vendor/golang.org/x/net/icmp/extension_test.go
@@ -5,253 +5,327 @@
package icmp
import (
+ "fmt"
"net"
"reflect"
"testing"
"golang.org/x/net/internal/iana"
+ "golang.org/x/net/ipv4"
+ "golang.org/x/net/ipv6"
)
-var marshalAndParseExtensionTests = []struct {
- proto int
- hdr []byte
- obj []byte
- exts []Extension
-}{
- // MPLS label stack with no label
- {
- proto: iana.ProtocolICMP,
- hdr: []byte{
- 0x20, 0x00, 0x00, 0x00,
- },
- obj: []byte{
- 0x00, 0x04, 0x01, 0x01,
- },
- exts: []Extension{
- &MPLSLabelStack{
- Class: classMPLSLabelStack,
- Type: typeIncomingMPLSLabelStack,
+func TestMarshalAndParseExtension(t *testing.T) {
+ fn := func(t *testing.T, proto int, typ Type, hdr, obj []byte, te Extension) error {
+ b, err := te.Marshal(proto)
+ if err != nil {
+ return err
+ }
+ if !reflect.DeepEqual(b, obj) {
+ return fmt.Errorf("got %#v; want %#v", b, obj)
+ }
+ switch typ {
+ case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
+ exts, l, err := parseExtensions(typ, append(hdr, obj...), 0)
+ if err != nil {
+ return err
+ }
+ if l != 0 {
+ return fmt.Errorf("got %d; want 0", l)
+ }
+ if !reflect.DeepEqual(exts, []Extension{te}) {
+ return fmt.Errorf("got %#v; want %#v", exts[0], te)
+ }
+ default:
+ for i, wire := range []struct {
+ data []byte // original datagram
+ inlattr int // length of padded original datagram, a hint
+ outlattr int // length of padded original datagram, a want
+ err error
+ }{
+ {nil, 0, -1, errNoExtension},
+ {make([]byte, 127), 128, -1, errNoExtension},
+
+ {make([]byte, 128), 127, -1, errNoExtension},
+ {make([]byte, 128), 128, -1, errNoExtension},
+ {make([]byte, 128), 129, -1, errNoExtension},
+
+ {append(make([]byte, 128), append(hdr, obj...)...), 127, 128, nil},
+ {append(make([]byte, 128), append(hdr, obj...)...), 128, 128, nil},
+ {append(make([]byte, 128), append(hdr, obj...)...), 129, 128, nil},
+
+ {append(make([]byte, 512), append(hdr, obj...)...), 511, -1, errNoExtension},
+ {append(make([]byte, 512), append(hdr, obj...)...), 512, 512, nil},
+ {append(make([]byte, 512), append(hdr, obj...)...), 513, -1, errNoExtension},
+ } {
+ exts, l, err := parseExtensions(typ, wire.data, wire.inlattr)
+ if err != wire.err {
+ return fmt.Errorf("#%d: got %v; want %v", i, err, wire.err)
+ }
+ if wire.err != nil {
+ continue
+ }
+ if l != wire.outlattr {
+ return fmt.Errorf("#%d: got %d; want %d", i, l, wire.outlattr)
+ }
+ if !reflect.DeepEqual(exts, []Extension{te}) {
+ return fmt.Errorf("#%d: got %#v; want %#v", i, exts[0], te)
+ }
+ }
+ }
+ return nil
+ }
+
+ t.Run("MPLSLabelStack", func(t *testing.T) {
+ for _, et := range []struct {
+ proto int
+ typ Type
+ hdr []byte
+ obj []byte
+ ext Extension
+ }{
+ // MPLS label stack with no label
+ {
+ proto: iana.ProtocolICMP,
+ typ: ipv4.ICMPTypeDestinationUnreachable,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x04, 0x01, 0x01,
+ },
+ ext: &MPLSLabelStack{
+ Class: classMPLSLabelStack,
+ Type: typeIncomingMPLSLabelStack,
+ },
},
- },
- },
- // MPLS label stack with a single label
- {
- proto: iana.ProtocolIPv6ICMP,
- hdr: []byte{
- 0x20, 0x00, 0x00, 0x00,
- },
- obj: []byte{
- 0x00, 0x08, 0x01, 0x01,
- 0x03, 0xe8, 0xe9, 0xff,
- },
- exts: []Extension{
- &MPLSLabelStack{
- Class: classMPLSLabelStack,
- Type: typeIncomingMPLSLabelStack,
- Labels: []MPLSLabel{
- {
- Label: 16014,
- TC: 0x4,
- S: true,
- TTL: 255,
+ // MPLS label stack with a single label
+ {
+ proto: iana.ProtocolIPv6ICMP,
+ typ: ipv6.ICMPTypeDestinationUnreachable,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x08, 0x01, 0x01,
+ 0x03, 0xe8, 0xe9, 0xff,
+ },
+ ext: &MPLSLabelStack{
+ Class: classMPLSLabelStack,
+ Type: typeIncomingMPLSLabelStack,
+ Labels: []MPLSLabel{
+ {
+ Label: 16014,
+ TC: 0x4,
+ S: true,
+ TTL: 255,
+ },
},
},
},
- },
- },
- // MPLS label stack with multiple labels
- {
- proto: iana.ProtocolICMP,
- hdr: []byte{
- 0x20, 0x00, 0x00, 0x00,
- },
- obj: []byte{
- 0x00, 0x0c, 0x01, 0x01,
- 0x03, 0xe8, 0xde, 0xfe,
- 0x03, 0xe8, 0xe1, 0xff,
- },
- exts: []Extension{
- &MPLSLabelStack{
- Class: classMPLSLabelStack,
- Type: typeIncomingMPLSLabelStack,
- Labels: []MPLSLabel{
- {
- Label: 16013,
- TC: 0x7,
- S: false,
- TTL: 254,
- },
- {
- Label: 16014,
- TC: 0,
- S: true,
- TTL: 255,
+ // MPLS label stack with multiple labels
+ {
+ proto: iana.ProtocolICMP,
+ typ: ipv4.ICMPTypeDestinationUnreachable,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x0c, 0x01, 0x01,
+ 0x03, 0xe8, 0xde, 0xfe,
+ 0x03, 0xe8, 0xe1, 0xff,
+ },
+ ext: &MPLSLabelStack{
+ Class: classMPLSLabelStack,
+ Type: typeIncomingMPLSLabelStack,
+ Labels: []MPLSLabel{
+ {
+ Label: 16013,
+ TC: 0x7,
+ S: false,
+ TTL: 254,
+ },
+ {
+ Label: 16014,
+ TC: 0,
+ S: true,
+ TTL: 255,
+ },
},
},
},
- },
- },
- // Interface information with no attribute
- {
- proto: iana.ProtocolICMP,
- hdr: []byte{
- 0x20, 0x00, 0x00, 0x00,
- },
- obj: []byte{
- 0x00, 0x04, 0x02, 0x00,
- },
- exts: []Extension{
- &InterfaceInfo{
- Class: classInterfaceInfo,
+ } {
+ if err := fn(t, et.proto, et.typ, et.hdr, et.obj, et.ext); err != nil {
+ t.Error(err)
+ }
+ }
+ })
+ t.Run("InterfaceInfo", func(t *testing.T) {
+ for _, et := range []struct {
+ proto int
+ typ Type
+ hdr []byte
+ obj []byte
+ ext Extension
+ }{
+ // Interface information with no attribute
+ {
+ proto: iana.ProtocolICMP,
+ typ: ipv4.ICMPTypeDestinationUnreachable,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x04, 0x02, 0x00,
+ },
+ ext: &InterfaceInfo{
+ Class: classInterfaceInfo,
+ },
},
- },
- },
- // Interface information with ifIndex and name
- {
- proto: iana.ProtocolICMP,
- hdr: []byte{
- 0x20, 0x00, 0x00, 0x00,
- },
- obj: []byte{
- 0x00, 0x10, 0x02, 0x0a,
- 0x00, 0x00, 0x00, 0x10,
- 0x08, byte('e'), byte('n'), byte('1'),
- byte('0'), byte('1'), 0x00, 0x00,
- },
- exts: []Extension{
- &InterfaceInfo{
- Class: classInterfaceInfo,
- Type: 0x0a,
- Interface: &net.Interface{
- Index: 16,
- Name: "en101",
+ // Interface information with ifIndex and name
+ {
+ proto: iana.ProtocolICMP,
+ typ: ipv4.ICMPTypeDestinationUnreachable,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x10, 0x02, 0x0a,
+ 0x00, 0x00, 0x00, 0x10,
+ 0x08, byte('e'), byte('n'), byte('1'),
+ byte('0'), byte('1'), 0x00, 0x00,
+ },
+ ext: &InterfaceInfo{
+ Class: classInterfaceInfo,
+ Type: 0x0a,
+ Interface: &net.Interface{
+ Index: 16,
+ Name: "en101",
+ },
},
},
- },
- },
- // Interface information with ifIndex, IPAddr, name and MTU
- {
- proto: iana.ProtocolIPv6ICMP,
- hdr: []byte{
- 0x20, 0x00, 0x00, 0x00,
- },
- obj: []byte{
- 0x00, 0x28, 0x02, 0x0f,
- 0x00, 0x00, 0x00, 0x0f,
- 0x00, 0x02, 0x00, 0x00,
- 0xfe, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01,
- 0x08, byte('e'), byte('n'), byte('1'),
- byte('0'), byte('1'), 0x00, 0x00,
- 0x00, 0x00, 0x20, 0x00,
- },
- exts: []Extension{
- &InterfaceInfo{
- Class: classInterfaceInfo,
- Type: 0x0f,
- Interface: &net.Interface{
- Index: 15,
- Name: "en101",
- MTU: 8192,
+ // Interface information with ifIndex, IPAddr, name and MTU
+ {
+ proto: iana.ProtocolIPv6ICMP,
+ typ: ipv6.ICMPTypeDestinationUnreachable,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
},
- Addr: &net.IPAddr{
- IP: net.ParseIP("fe80::1"),
- Zone: "en101",
+ obj: []byte{
+ 0x00, 0x28, 0x02, 0x0f,
+ 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x02, 0x00, 0x00,
+ 0xfe, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x08, byte('e'), byte('n'), byte('1'),
+ byte('0'), byte('1'), 0x00, 0x00,
+ 0x00, 0x00, 0x20, 0x00,
+ },
+ ext: &InterfaceInfo{
+ Class: classInterfaceInfo,
+ Type: 0x0f,
+ Interface: &net.Interface{
+ Index: 15,
+ Name: "en101",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.ParseIP("fe80::1"),
+ Zone: "en101",
+ },
},
},
- },
- },
-}
-
-func TestMarshalAndParseExtension(t *testing.T) {
- for i, tt := range marshalAndParseExtensionTests {
- for j, ext := range tt.exts {
- var err error
- var b []byte
- switch ext := ext.(type) {
- case *MPLSLabelStack:
- b, err = ext.Marshal(tt.proto)
- if err != nil {
- t.Errorf("#%v/%v: %v", i, j, err)
- continue
- }
- case *InterfaceInfo:
- b, err = ext.Marshal(tt.proto)
- if err != nil {
- t.Errorf("#%v/%v: %v", i, j, err)
- continue
- }
- }
- if !reflect.DeepEqual(b, tt.obj) {
- t.Errorf("#%v/%v: got %#v; want %#v", i, j, b, tt.obj)
- continue
+ } {
+ if err := fn(t, et.proto, et.typ, et.hdr, et.obj, et.ext); err != nil {
+ t.Error(err)
}
}
-
- for j, wire := range []struct {
- data []byte // original datagram
- inlattr int // length of padded original datagram, a hint
- outlattr int // length of padded original datagram, a want
- err error
+ })
+ t.Run("InterfaceIdent", func(t *testing.T) {
+ for _, et := range []struct {
+ proto int
+ typ Type
+ hdr []byte
+ obj []byte
+ ext Extension
}{
- {nil, 0, -1, errNoExtension},
- {make([]byte, 127), 128, -1, errNoExtension},
-
- {make([]byte, 128), 127, -1, errNoExtension},
- {make([]byte, 128), 128, -1, errNoExtension},
- {make([]byte, 128), 129, -1, errNoExtension},
-
- {append(make([]byte, 128), append(tt.hdr, tt.obj...)...), 127, 128, nil},
- {append(make([]byte, 128), append(tt.hdr, tt.obj...)...), 128, 128, nil},
- {append(make([]byte, 128), append(tt.hdr, tt.obj...)...), 129, 128, nil},
-
- {append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 511, -1, errNoExtension},
- {append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 512, 512, nil},
- {append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 513, -1, errNoExtension},
+ // Interface identification by name
+ {
+ proto: iana.ProtocolICMP,
+ typ: ipv4.ICMPTypeExtendedEchoRequest,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x0c, 0x03, 0x01,
+ byte('e'), byte('n'), byte('1'), byte('0'),
+ byte('1'), 0x00, 0x00, 0x00,
+ },
+ ext: &InterfaceIdent{
+ Class: classInterfaceIdent,
+ Type: typeInterfaceByName,
+ Name: "en101",
+ },
+ },
+ // Interface identification by index
+ {
+ proto: iana.ProtocolIPv6ICMP,
+ typ: ipv6.ICMPTypeExtendedEchoRequest,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x0c, 0x03, 0x02,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x8f,
+ },
+ ext: &InterfaceIdent{
+ Class: classInterfaceIdent,
+ Type: typeInterfaceByIndex,
+ Index: 911,
+ },
+ },
+ // Interface identification by address
+ {
+ proto: iana.ProtocolICMP,
+ typ: ipv4.ICMPTypeExtendedEchoRequest,
+ hdr: []byte{
+ 0x20, 0x00, 0x00, 0x00,
+ },
+ obj: []byte{
+ 0x00, 0x10, 0x03, 0x03,
+ byte(iana.AddrFamily48bitMAC >> 8), byte(iana.AddrFamily48bitMAC & 0x0f), 0x06, 0x00,
+ 0x01, 0x23, 0x45, 0x67,
+ 0x89, 0xab, 0x00, 0x00,
+ },
+ ext: &InterfaceIdent{
+ Class: classInterfaceIdent,
+ Type: typeInterfaceByAddress,
+ AFI: iana.AddrFamily48bitMAC,
+ Addr: []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab},
+ },
+ },
} {
- exts, l, err := parseExtensions(wire.data, wire.inlattr)
- if err != wire.err {
- t.Errorf("#%v/%v: got %v; want %v", i, j, err, wire.err)
- continue
- }
- if wire.err != nil {
- continue
- }
- if l != wire.outlattr {
- t.Errorf("#%v/%v: got %v; want %v", i, j, l, wire.outlattr)
- }
- if !reflect.DeepEqual(exts, tt.exts) {
- for j, ext := range exts {
- switch ext := ext.(type) {
- case *MPLSLabelStack:
- want := tt.exts[j].(*MPLSLabelStack)
- t.Errorf("#%v/%v: got %#v; want %#v", i, j, ext, want)
- case *InterfaceInfo:
- want := tt.exts[j].(*InterfaceInfo)
- t.Errorf("#%v/%v: got %#v; want %#v", i, j, ext, want)
- }
- }
- continue
+ if err := fn(t, et.proto, et.typ, et.hdr, et.obj, et.ext); err != nil {
+ t.Error(err)
}
}
- }
-}
-
-var parseInterfaceNameTests = []struct {
- b []byte
- error
-}{
- {[]byte{0, 'e', 'n', '0'}, errInvalidExtension},
- {[]byte{4, 'e', 'n', '0'}, nil},
- {[]byte{7, 'e', 'n', '0', 0xff, 0xff, 0xff, 0xff}, errInvalidExtension},
- {[]byte{8, 'e', 'n', '0', 0xff, 0xff, 0xff}, errMessageTooShort},
+ })
}
func TestParseInterfaceName(t *testing.T) {
ifi := InterfaceInfo{Interface: &net.Interface{}}
- for i, tt := range parseInterfaceNameTests {
+ for i, tt := range []struct {
+ b []byte
+ error
+ }{
+ {[]byte{0, 'e', 'n', '0'}, errInvalidExtension},
+ {[]byte{4, 'e', 'n', '0'}, nil},
+ {[]byte{7, 'e', 'n', '0', 0xff, 0xff, 0xff, 0xff}, errInvalidExtension},
+ {[]byte{8, 'e', 'n', '0', 0xff, 0xff, 0xff}, errMessageTooShort},
+ } {
if _, err := ifi.parseName(tt.b); err != tt.error {
t.Errorf("#%d: got %v; want %v", i, err, tt.error)
}
diff --git a/vendor/golang.org/x/net/icmp/interface.go b/vendor/golang.org/x/net/icmp/interface.go
index 78b5b98..617f757 100644
--- a/vendor/golang.org/x/net/icmp/interface.go
+++ b/vendor/golang.org/x/net/icmp/interface.go
@@ -14,9 +14,6 @@ import (
const (
classInterfaceInfo = 2
-
- afiIPv4 = 1
- afiIPv6 = 2
)
const (
@@ -127,11 +124,11 @@ func (ifi *InterfaceInfo) parseIfIndex(b []byte) ([]byte, error) {
func (ifi *InterfaceInfo) marshalIPAddr(proto int, b []byte) []byte {
switch proto {
case iana.ProtocolICMP:
- binary.BigEndian.PutUint16(b[:2], uint16(afiIPv4))
+ binary.BigEndian.PutUint16(b[:2], uint16(iana.AddrFamilyIPv4))
copy(b[4:4+net.IPv4len], ifi.Addr.IP.To4())
b = b[4+net.IPv4len:]
case iana.ProtocolIPv6ICMP:
- binary.BigEndian.PutUint16(b[:2], uint16(afiIPv6))
+ binary.BigEndian.PutUint16(b[:2], uint16(iana.AddrFamilyIPv6))
copy(b[4:4+net.IPv6len], ifi.Addr.IP.To16())
b = b[4+net.IPv6len:]
}
@@ -145,14 +142,14 @@ func (ifi *InterfaceInfo) parseIPAddr(b []byte) ([]byte, error) {
afi := int(binary.BigEndian.Uint16(b[:2]))
b = b[4:]
switch afi {
- case afiIPv4:
+ case iana.AddrFamilyIPv4:
if len(b) < net.IPv4len {
return nil, errMessageTooShort
}
ifi.Addr.IP = make(net.IP, net.IPv4len)
copy(ifi.Addr.IP, b[:net.IPv4len])
b = b[net.IPv4len:]
- case afiIPv6:
+ case iana.AddrFamilyIPv6:
if len(b) < net.IPv6len {
return nil, errMessageTooShort
}
@@ -234,3 +231,92 @@ func parseInterfaceInfo(b []byte) (Extension, error) {
}
return ifi, nil
}
+
+const (
+ classInterfaceIdent = 3
+ typeInterfaceByName = 1
+ typeInterfaceByIndex = 2
+ typeInterfaceByAddress = 3
+)
+
+// An InterfaceIdent represents interface identification.
+type InterfaceIdent struct {
+ Class int // extension object class number
+ Type int // extension object sub-type
+ Name string // interface name
+ Index int // interface index
+ AFI int // address family identifier; see address family numbers in IANA registry
+ Addr []byte // address
+}
+
+// Len implements the Len method of Extension interface.
+func (ifi *InterfaceIdent) Len(_ int) int {
+ switch ifi.Type {
+ case typeInterfaceByName:
+ l := len(ifi.Name)
+ if l > 255 {
+ l = 255
+ }
+ return 4 + (l+3)&^3
+ case typeInterfaceByIndex:
+ return 4 + 8
+ case typeInterfaceByAddress:
+ return 4 + 4 + (len(ifi.Addr)+3)&^3
+ default:
+ return 4
+ }
+}
+
+// Marshal implements the Marshal method of Extension interface.
+func (ifi *InterfaceIdent) Marshal(proto int) ([]byte, error) {
+ b := make([]byte, ifi.Len(proto))
+ if err := ifi.marshal(proto, b); err != nil {
+ return nil, err
+ }
+ return b, nil
+}
+
+func (ifi *InterfaceIdent) marshal(proto int, b []byte) error {
+ l := ifi.Len(proto)
+ binary.BigEndian.PutUint16(b[:2], uint16(l))
+ b[2], b[3] = classInterfaceIdent, byte(ifi.Type)
+ switch ifi.Type {
+ case typeInterfaceByName:
+ copy(b[4:], ifi.Name)
+ case typeInterfaceByIndex:
+ binary.BigEndian.PutUint64(b[4:4+8], uint64(ifi.Index))
+ case typeInterfaceByAddress:
+ binary.BigEndian.PutUint16(b[4:4+2], uint16(ifi.AFI))
+ b[4+2] = byte(len(ifi.Addr))
+ copy(b[4+4:], ifi.Addr)
+ }
+ return nil
+}
+
+func parseInterfaceIdent(b []byte) (Extension, error) {
+ ifi := &InterfaceIdent{
+ Class: int(b[2]),
+ Type: int(b[3]),
+ }
+ switch ifi.Type {
+ case typeInterfaceByName:
+ ifi.Name = strings.Trim(string(b[4:]), string(0))
+ case typeInterfaceByIndex:
+ if len(b[4:]) < 8 {
+ return nil, errInvalidExtension
+ }
+ ifi.Index = int(binary.BigEndian.Uint64(b[4 : 4+8]))
+ case typeInterfaceByAddress:
+ if len(b[4:]) < 4 {
+ return nil, errInvalidExtension
+ }
+ ifi.AFI = int(binary.BigEndian.Uint16(b[4 : 4+2]))
+ l := int(b[4+2])
+ if len(b[4+4:]) < l {
+ return nil, errInvalidExtension
+ }
+ ifi.Addr = make([]byte, l)
+ copy(ifi.Addr, b[4+4:])
+ }
+ return ifi, nil
+}
diff --git a/vendor/golang.org/x/net/icmp/ipv4_test.go b/vendor/golang.org/x/net/icmp/ipv4_test.go
index 058953f..3fdee83 100644
--- a/vendor/golang.org/x/net/icmp/ipv4_test.go
+++ b/vendor/golang.org/x/net/icmp/ipv4_test.go
@@ -15,69 +15,61 @@ import (
"golang.org/x/net/ipv4"
)
-type ipv4HeaderTest struct {
- wireHeaderFromKernel [ipv4.HeaderLen]byte
- wireHeaderFromTradBSDKernel [ipv4.HeaderLen]byte
- Header *ipv4.Header
-}
-
-var ipv4HeaderLittleEndianTest = ipv4HeaderTest{
- // TODO(mikio): Add platform dependent wire header formats when
- // we support new platforms.
- wireHeaderFromKernel: [ipv4.HeaderLen]byte{
- 0x45, 0x01, 0xbe, 0xef,
- 0xca, 0xfe, 0x45, 0xdc,
- 0xff, 0x01, 0xde, 0xad,
- 172, 16, 254, 254,
- 192, 168, 0, 1,
- },
- wireHeaderFromTradBSDKernel: [ipv4.HeaderLen]byte{
- 0x45, 0x01, 0xef, 0xbe,
- 0xca, 0xfe, 0x45, 0xdc,
- 0xff, 0x01, 0xde, 0xad,
- 172, 16, 254, 254,
- 192, 168, 0, 1,
- },
- Header: &ipv4.Header{
- Version: ipv4.Version,
- Len: ipv4.HeaderLen,
- TOS: 1,
- TotalLen: 0xbeef,
- ID: 0xcafe,
- Flags: ipv4.DontFragment,
- FragOff: 1500,
- TTL: 255,
- Protocol: 1,
- Checksum: 0xdead,
- Src: net.IPv4(172, 16, 254, 254),
- Dst: net.IPv4(192, 168, 0, 1),
- },
-}
-
func TestParseIPv4Header(t *testing.T) {
- tt := &ipv4HeaderLittleEndianTest
- if socket.NativeEndian != binary.LittleEndian {
- t.Skip("no test for non-little endian machine yet")
- }
-
- var wh []byte
- switch runtime.GOOS {
- case "darwin":
- wh = tt.wireHeaderFromTradBSDKernel[:]
- case "freebsd":
- if freebsdVersion >= 1000000 {
- wh = tt.wireHeaderFromKernel[:]
- } else {
- wh = tt.wireHeaderFromTradBSDKernel[:]
- }
- default:
- wh = tt.wireHeaderFromKernel[:]
- }
- h, err := ParseIPv4Header(wh)
- if err != nil {
- t.Fatal(err)
- }
- if !reflect.DeepEqual(h, tt.Header) {
- t.Fatalf("got %#v; want %#v", h, tt.Header)
+ switch socket.NativeEndian {
+ case binary.LittleEndian:
+ t.Run("LittleEndian", func(t *testing.T) {
+ // TODO(mikio): Add platform dependent wire
+ // header formats when we support new
+ // platforms.
+ wireHeaderFromKernel := [ipv4.HeaderLen]byte{
+ 0x45, 0x01, 0xbe, 0xef,
+ 0xca, 0xfe, 0x45, 0xdc,
+ 0xff, 0x01, 0xde, 0xad,
+ 172, 16, 254, 254,
+ 192, 168, 0, 1,
+ }
+ wireHeaderFromTradBSDKernel := [ipv4.HeaderLen]byte{
+ 0x45, 0x01, 0xef, 0xbe,
+ 0xca, 0xfe, 0x45, 0xdc,
+ 0xff, 0x01, 0xde, 0xad,
+ 172, 16, 254, 254,
+ 192, 168, 0, 1,
+ }
+ th := &ipv4.Header{
+ Version: ipv4.Version,
+ Len: ipv4.HeaderLen,
+ TOS: 1,
+ TotalLen: 0xbeef,
+ ID: 0xcafe,
+ Flags: ipv4.DontFragment,
+ FragOff: 1500,
+ TTL: 255,
+ Protocol: 1,
+ Checksum: 0xdead,
+ Src: net.IPv4(172, 16, 254, 254),
+ Dst: net.IPv4(192, 168, 0, 1),
+ }
+ var wh []byte
+ switch runtime.GOOS {
+ case "darwin":
+ wh = wireHeaderFromTradBSDKernel[:]
+ case "freebsd":
+ if freebsdVersion >= 1000000 {
+ wh = wireHeaderFromKernel[:]
+ } else {
+ wh = wireHeaderFromTradBSDKernel[:]
+ }
+ default:
+ wh = wireHeaderFromKernel[:]
+ }
+ h, err := ParseIPv4Header(wh)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !reflect.DeepEqual(h, th) {
+ t.Fatalf("got %#v; want %#v", h, th)
+ }
+ })
}
}
diff --git a/vendor/golang.org/x/net/icmp/listen_stub.go b/vendor/golang.org/x/net/icmp/listen_stub.go
index 668728d..14beb0e 100644
--- a/vendor/golang.org/x/net/icmp/listen_stub.go
+++ b/vendor/golang.org/x/net/icmp/listen_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build nacl plan9
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
package icmp
diff --git a/vendor/golang.org/x/net/icmp/message.go b/vendor/golang.org/x/net/icmp/message.go
index 81140b0..4a78017 100644
--- a/vendor/golang.org/x/net/icmp/message.go
+++ b/vendor/golang.org/x/net/icmp/message.go
@@ -11,22 +11,23 @@
// ICMP extensions for MPLS are defined in RFC 4950.
// ICMP extensions for interface and next-hop identification are
// defined in RFC 5837.
+// PROBE: A utility for probing interfaces is defined in RFC 8335.
package icmp // import "golang.org/x/net/icmp"
import (
"encoding/binary"
"errors"
"net"
- "syscall"
"golang.org/x/net/internal/iana"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
)
-// BUG(mikio): This package is not implemented on NaCl and Plan 9.
+// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9.
var (
+ errInvalidConn = errors.New("invalid connection")
errMessageTooShort = errors.New("message too short")
errHeaderTooShort = errors.New("header too short")
errBufferTooShort = errors.New("buffer too short")
@@ -79,7 +80,7 @@ func (m *Message) Marshal(psh []byte) ([]byte, error) {
case ipv6.ICMPType:
mtype = int(typ)
default:
- return nil, syscall.EINVAL
+ return nil, errInvalidConn
}
b := []byte{byte(mtype), byte(m.Code), 0, 0}
if m.Type.Protocol() == iana.ProtocolIPv6ICMP && psh != nil {
@@ -107,21 +108,25 @@ func (m *Message) Marshal(psh []byte) ([]byte, error) {
return b[len(psh):], nil
}
-var parseFns = map[Type]func(int, []byte) (MessageBody, error){
+var parseFns = map[Type]func(int, Type, []byte) (MessageBody, error){
ipv4.ICMPTypeDestinationUnreachable: parseDstUnreach,
ipv4.ICMPTypeTimeExceeded: parseTimeExceeded,
ipv4.ICMPTypeParameterProblem: parseParamProb,
- ipv4.ICMPTypeEcho: parseEcho,
- ipv4.ICMPTypeEchoReply: parseEcho,
+ ipv4.ICMPTypeEcho: parseEcho,
+ ipv4.ICMPTypeEchoReply: parseEcho,
+ ipv4.ICMPTypeExtendedEchoRequest: parseExtendedEchoRequest,
+ ipv4.ICMPTypeExtendedEchoReply: parseExtendedEchoReply,
ipv6.ICMPTypeDestinationUnreachable: parseDstUnreach,
ipv6.ICMPTypePacketTooBig: parsePacketTooBig,
ipv6.ICMPTypeTimeExceeded: parseTimeExceeded,
ipv6.ICMPTypeParameterProblem: parseParamProb,
- ipv6.ICMPTypeEchoRequest: parseEcho,
- ipv6.ICMPTypeEchoReply: parseEcho,
+ ipv6.ICMPTypeEchoRequest: parseEcho,
+ ipv6.ICMPTypeEchoReply: parseEcho,
+ ipv6.ICMPTypeExtendedEchoRequest: parseExtendedEchoRequest,
+ ipv6.ICMPTypeExtendedEchoReply: parseExtendedEchoReply,
}
// ParseMessage parses b as an ICMP message.
@@ -138,12 +143,12 @@ func ParseMessage(proto int, b []byte) (*Message, error) {
case iana.ProtocolIPv6ICMP:
m.Type = ipv6.ICMPType(b[0])
default:
- return nil, syscall.EINVAL
+ return nil, errInvalidConn
}
if fn, ok := parseFns[m.Type]; !ok {
m.Body, err = parseDefaultMessageBody(proto, b[4:])
} else {
- m.Body, err = fn(proto, b[4:])
+ m.Body, err = fn(proto, m.Type, b[4:])
}
if err != nil {
return nil, err
diff --git a/vendor/golang.org/x/net/icmp/message_test.go b/vendor/golang.org/x/net/icmp/message_test.go
index 5d2605f..c278b8b 100644
--- a/vendor/golang.org/x/net/icmp/message_test.go
+++ b/vendor/golang.org/x/net/icmp/message_test.go
@@ -15,120 +15,141 @@ import (
"golang.org/x/net/ipv6"
)
-var marshalAndParseMessageForIPv4Tests = []icmp.Message{
- {
- Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15,
- Body: &icmp.DstUnreach{
- Data: []byte("ERROR-INVOKING-PACKET"),
- },
- },
- {
- Type: ipv4.ICMPTypeTimeExceeded, Code: 1,
- Body: &icmp.TimeExceeded{
- Data: []byte("ERROR-INVOKING-PACKET"),
- },
- },
- {
- Type: ipv4.ICMPTypeParameterProblem, Code: 2,
- Body: &icmp.ParamProb{
- Pointer: 8,
- Data: []byte("ERROR-INVOKING-PACKET"),
- },
- },
- {
- Type: ipv4.ICMPTypeEcho, Code: 0,
- Body: &icmp.Echo{
- ID: 1, Seq: 2,
- Data: []byte("HELLO-R-U-THERE"),
- },
- },
- {
- Type: ipv4.ICMPTypePhoturis,
- Body: &icmp.DefaultMessageBody{
- Data: []byte{0x80, 0x40, 0x20, 0x10},
- },
- },
-}
-
-func TestMarshalAndParseMessageForIPv4(t *testing.T) {
- for i, tt := range marshalAndParseMessageForIPv4Tests {
- b, err := tt.Marshal(nil)
- if err != nil {
- t.Fatal(err)
- }
- m, err := icmp.ParseMessage(iana.ProtocolICMP, b)
- if err != nil {
- t.Fatal(err)
- }
- if m.Type != tt.Type || m.Code != tt.Code {
- t.Errorf("#%v: got %v; want %v", i, m, &tt)
- }
- if !reflect.DeepEqual(m.Body, tt.Body) {
- t.Errorf("#%v: got %v; want %v", i, m.Body, tt.Body)
- }
- }
-}
-
-var marshalAndParseMessageForIPv6Tests = []icmp.Message{
- {
- Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6,
- Body: &icmp.DstUnreach{
- Data: []byte("ERROR-INVOKING-PACKET"),
- },
- },
- {
- Type: ipv6.ICMPTypePacketTooBig, Code: 0,
- Body: &icmp.PacketTooBig{
- MTU: 1<<16 - 1,
- Data: []byte("ERROR-INVOKING-PACKET"),
- },
- },
- {
- Type: ipv6.ICMPTypeTimeExceeded, Code: 1,
- Body: &icmp.TimeExceeded{
- Data: []byte("ERROR-INVOKING-PACKET"),
- },
- },
- {
- Type: ipv6.ICMPTypeParameterProblem, Code: 2,
- Body: &icmp.ParamProb{
- Pointer: 8,
- Data: []byte("ERROR-INVOKING-PACKET"),
- },
- },
- {
- Type: ipv6.ICMPTypeEchoRequest, Code: 0,
- Body: &icmp.Echo{
- ID: 1, Seq: 2,
- Data: []byte("HELLO-R-U-THERE"),
- },
- },
- {
- Type: ipv6.ICMPTypeDuplicateAddressConfirmation,
- Body: &icmp.DefaultMessageBody{
- Data: []byte{0x80, 0x40, 0x20, 0x10},
- },
- },
-}
-
-func TestMarshalAndParseMessageForIPv6(t *testing.T) {
- pshicmp := icmp.IPv6PseudoHeader(net.ParseIP("fe80::1"), net.ParseIP("ff02::1"))
- for i, tt := range marshalAndParseMessageForIPv6Tests {
- for _, psh := range [][]byte{pshicmp, nil} {
- b, err := tt.Marshal(psh)
- if err != nil {
- t.Fatal(err)
- }
- m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, b)
- if err != nil {
- t.Fatal(err)
+func TestMarshalAndParseMessage(t *testing.T) {
+ fn := func(t *testing.T, proto int, tms []icmp.Message) {
+ var pshs [][]byte
+ switch proto {
+ case iana.ProtocolICMP:
+ pshs = [][]byte{nil}
+ case iana.ProtocolIPv6ICMP:
+ pshs = [][]byte{
+ icmp.IPv6PseudoHeader(net.ParseIP("fe80::1"), net.ParseIP("ff02::1")),
+ nil,
}
- if m.Type != tt.Type || m.Code != tt.Code {
- t.Errorf("#%v: got %v; want %v", i, m, &tt)
- }
- if !reflect.DeepEqual(m.Body, tt.Body) {
- t.Errorf("#%v: got %v; want %v", i, m.Body, tt.Body)
+ }
+ for i, tm := range tms {
+ for _, psh := range pshs {
+ b, err := tm.Marshal(psh)
+ if err != nil {
+ t.Fatal(err)
+ }
+ m, err := icmp.ParseMessage(proto, b)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if m.Type != tm.Type || m.Code != tm.Code {
+ t.Errorf("#%d: got %#v; want %#v", i, m, &tm)
+ }
+ if !reflect.DeepEqual(m.Body, tm.Body) {
+ t.Errorf("#%d: got %#v; want %#v", i, m.Body, tm.Body)
+ }
}
}
}
+
+ t.Run("IPv4", func(t *testing.T) {
+ fn(t, iana.ProtocolICMP,
+ []icmp.Message{
+ {
+ Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15,
+ Body: &icmp.DstUnreach{
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ },
+ },
+ {
+ Type: ipv4.ICMPTypeTimeExceeded, Code: 1,
+ Body: &icmp.TimeExceeded{
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ },
+ },
+ {
+ Type: ipv4.ICMPTypeParameterProblem, Code: 2,
+ Body: &icmp.ParamProb{
+ Pointer: 8,
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ },
+ },
+ {
+ Type: ipv4.ICMPTypeEcho, Code: 0,
+ Body: &icmp.Echo{
+ ID: 1, Seq: 2,
+ Data: []byte("HELLO-R-U-THERE"),
+ },
+ },
+ {
+ Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: 1, Seq: 2,
+ },
+ },
+ {
+ Type: ipv4.ICMPTypeExtendedEchoReply, Code: 0,
+ Body: &icmp.ExtendedEchoReply{
+ State: 4 /* Delay */, Active: true, IPv4: true,
+ },
+ },
+ {
+ Type: ipv4.ICMPTypePhoturis,
+ Body: &icmp.DefaultMessageBody{
+ Data: []byte{0x80, 0x40, 0x20, 0x10},
+ },
+ },
+ })
+ })
+ t.Run("IPv6", func(t *testing.T) {
+ fn(t, iana.ProtocolIPv6ICMP,
+ []icmp.Message{
+ {
+ Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6,
+ Body: &icmp.DstUnreach{
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ },
+ },
+ {
+ Type: ipv6.ICMPTypePacketTooBig, Code: 0,
+ Body: &icmp.PacketTooBig{
+ MTU: 1<<16 - 1,
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ },
+ },
+ {
+ Type: ipv6.ICMPTypeTimeExceeded, Code: 1,
+ Body: &icmp.TimeExceeded{
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ },
+ },
+ {
+ Type: ipv6.ICMPTypeParameterProblem, Code: 2,
+ Body: &icmp.ParamProb{
+ Pointer: 8,
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ },
+ },
+ {
+ Type: ipv6.ICMPTypeEchoRequest, Code: 0,
+ Body: &icmp.Echo{
+ ID: 1, Seq: 2,
+ Data: []byte("HELLO-R-U-THERE"),
+ },
+ },
+ {
+ Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: 1, Seq: 2,
+ },
+ },
+ {
+ Type: ipv6.ICMPTypeExtendedEchoReply, Code: 0,
+ Body: &icmp.ExtendedEchoReply{
+ State: 5 /* Probe */, Active: true, IPv6: true,
+ },
+ },
+ {
+ Type: ipv6.ICMPTypeDuplicateAddressConfirmation,
+ Body: &icmp.DefaultMessageBody{
+ Data: []byte{0x80, 0x40, 0x20, 0x10},
+ },
+ },
+ })
+ })
}
diff --git a/vendor/golang.org/x/net/icmp/mpls.go b/vendor/golang.org/x/net/icmp/mpls.go
index c314917..f9f4841 100644
--- a/vendor/golang.org/x/net/icmp/mpls.go
+++ b/vendor/golang.org/x/net/icmp/mpls.go
@@ -6,7 +6,7 @@ package icmp
import "encoding/binary"
-// A MPLSLabel represents a MPLS label stack entry.
+// MPLSLabel represents an MPLS label stack entry.
type MPLSLabel struct {
Label int // label value
TC int // traffic class; formerly experimental use
@@ -19,7 +19,7 @@ const (
typeIncomingMPLSLabelStack = 1
)
-// A MPLSLabelStack represents a MPLS label stack.
+// MPLSLabelStack represents an MPLS label stack.
type MPLSLabelStack struct {
Class int // extension object class number
Type int // extension object sub-type
diff --git a/vendor/golang.org/x/net/icmp/multipart.go b/vendor/golang.org/x/net/icmp/multipart.go
index f271356..9ebbbaf 100644
--- a/vendor/golang.org/x/net/icmp/multipart.go
+++ b/vendor/golang.org/x/net/icmp/multipart.go
@@ -10,12 +10,14 @@ import "golang.org/x/net/internal/iana"
// exts as extensions, and returns a required length for message body
// and a required length for a padded original datagram in wire
// format.
-func multipartMessageBodyDataLen(proto int, b []byte, exts []Extension) (bodyLen, dataLen int) {
+func multipartMessageBodyDataLen(proto int, withOrigDgram bool, b []byte, exts []Extension) (bodyLen, dataLen int) {
for _, ext := range exts {
bodyLen += ext.Len(proto)
}
if bodyLen > 0 {
- dataLen = multipartMessageOrigDatagramLen(proto, b)
+ if withOrigDgram {
+ dataLen = multipartMessageOrigDatagramLen(proto, b)
+ }
bodyLen += 4 // length of extension header
} else {
dataLen = len(b)
@@ -50,8 +52,8 @@ func multipartMessageOrigDatagramLen(proto int, b []byte) int {
// marshalMultipartMessageBody takes data as an original datagram and
// exts as extesnsions, and returns a binary encoding of message body.
// It can be used for non-multipart message bodies when exts is nil.
-func marshalMultipartMessageBody(proto int, data []byte, exts []Extension) ([]byte, error) {
- bodyLen, dataLen := multipartMessageBodyDataLen(proto, data, exts)
+func marshalMultipartMessageBody(proto int, withOrigDgram bool, data []byte, exts []Extension) ([]byte, error) {
+ bodyLen, dataLen := multipartMessageBodyDataLen(proto, withOrigDgram, data, exts)
b := make([]byte, 4+bodyLen)
copy(b[4:], data)
off := dataLen + 4
@@ -71,16 +73,23 @@ func marshalMultipartMessageBody(proto int, data []byte, exts []Extension) ([]by
return nil, err
}
off += ext.Len(proto)
+ case *InterfaceIdent:
+ if err := ext.marshal(proto, b[off:]); err != nil {
+ return nil, err
+ }
+ off += ext.Len(proto)
}
}
s := checksum(b[dataLen+4:])
b[dataLen+4+2] ^= byte(s)
b[dataLen+4+3] ^= byte(s >> 8)
- switch proto {
- case iana.ProtocolICMP:
- b[1] = byte(dataLen / 4)
- case iana.ProtocolIPv6ICMP:
- b[0] = byte(dataLen / 8)
+ if withOrigDgram {
+ switch proto {
+ case iana.ProtocolICMP:
+ b[1] = byte(dataLen / 4)
+ case iana.ProtocolIPv6ICMP:
+ b[0] = byte(dataLen / 8)
+ }
}
}
return b, nil
@@ -88,7 +97,7 @@ func marshalMultipartMessageBody(proto int, data []byte, exts []Extension) ([]by
// parseMultipartMessageBody parses b as either a non-multipart
// message body or a multipart message body.
-func parseMultipartMessageBody(proto int, b []byte) ([]byte, []Extension, error) {
+func parseMultipartMessageBody(proto int, typ Type, b []byte) ([]byte, []Extension, error) {
var l int
switch proto {
case iana.ProtocolICMP:
@@ -99,11 +108,14 @@ func parseMultipartMessageBody(proto int, b []byte) ([]byte, []Extension, error)
if len(b) == 4 {
return nil, nil, nil
}
- exts, l, err := parseExtensions(b[4:], l)
+ exts, l, err := parseExtensions(typ, b[4:], l)
if err != nil {
l = len(b) - 4
}
- data := make([]byte, l)
- copy(data, b[4:])
+ var data []byte
+ if l > 0 {
+ data = make([]byte, l)
+ copy(data, b[4:])
+ }
return data, exts, nil
}
diff --git a/vendor/golang.org/x/net/icmp/multipart_test.go b/vendor/golang.org/x/net/icmp/multipart_test.go
index 966ccb8..7440882 100644
--- a/vendor/golang.org/x/net/icmp/multipart_test.go
+++ b/vendor/golang.org/x/net/icmp/multipart_test.go
@@ -5,6 +5,7 @@
package icmp_test
import (
+ "errors"
"fmt"
"net"
"reflect"
@@ -16,425 +17,557 @@ import (
"golang.org/x/net/ipv6"
)
-var marshalAndParseMultipartMessageForIPv4Tests = []icmp.Message{
- {
- Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15,
- Body: &icmp.DstUnreach{
- Data: []byte("ERROR-INVOKING-PACKET"),
- Extensions: []icmp.Extension{
- &icmp.MPLSLabelStack{
- Class: 1,
- Type: 1,
- Labels: []icmp.MPLSLabel{
- {
- Label: 16014,
- TC: 0x4,
- S: true,
- TTL: 255,
- },
- },
- },
- &icmp.InterfaceInfo{
- Class: 2,
- Type: 0x0f,
- Interface: &net.Interface{
- Index: 15,
- Name: "en101",
- MTU: 8192,
- },
- Addr: &net.IPAddr{
- IP: net.IPv4(192, 168, 0, 1).To4(),
- },
- },
- },
- },
- },
- {
- Type: ipv4.ICMPTypeTimeExceeded, Code: 1,
- Body: &icmp.TimeExceeded{
- Data: []byte("ERROR-INVOKING-PACKET"),
- Extensions: []icmp.Extension{
- &icmp.InterfaceInfo{
- Class: 2,
- Type: 0x0f,
- Interface: &net.Interface{
- Index: 15,
- Name: "en101",
- MTU: 8192,
- },
- Addr: &net.IPAddr{
- IP: net.IPv4(192, 168, 0, 1).To4(),
- },
- },
- &icmp.MPLSLabelStack{
- Class: 1,
- Type: 1,
- Labels: []icmp.MPLSLabel{
- {
- Label: 16014,
- TC: 0x4,
- S: true,
- TTL: 255,
- },
- },
- },
- },
- },
- },
- {
- Type: ipv4.ICMPTypeParameterProblem, Code: 2,
- Body: &icmp.ParamProb{
- Pointer: 8,
- Data: []byte("ERROR-INVOKING-PACKET"),
- Extensions: []icmp.Extension{
- &icmp.MPLSLabelStack{
- Class: 1,
- Type: 1,
- Labels: []icmp.MPLSLabel{
- {
- Label: 16014,
- TC: 0x4,
- S: true,
- TTL: 255,
- },
- },
- },
- &icmp.InterfaceInfo{
- Class: 2,
- Type: 0x0f,
- Interface: &net.Interface{
- Index: 15,
- Name: "en101",
- MTU: 8192,
- },
- Addr: &net.IPAddr{
- IP: net.IPv4(192, 168, 0, 1).To4(),
- },
- },
- &icmp.InterfaceInfo{
- Class: 2,
- Type: 0x2f,
- Interface: &net.Interface{
- Index: 16,
- Name: "en102",
- MTU: 8192,
- },
- Addr: &net.IPAddr{
- IP: net.IPv4(192, 168, 0, 2).To4(),
- },
- },
- },
- },
- },
-}
-
-func TestMarshalAndParseMultipartMessageForIPv4(t *testing.T) {
- for i, tt := range marshalAndParseMultipartMessageForIPv4Tests {
- b, err := tt.Marshal(nil)
+func TestMarshalAndParseMultipartMessage(t *testing.T) {
+ fn := func(t *testing.T, proto int, tm icmp.Message) error {
+ b, err := tm.Marshal(nil)
if err != nil {
- t.Fatal(err)
+ return err
}
- if b[5] != 32 {
- t.Errorf("#%v: got %v; want 32", i, b[5])
+ switch tm.Type {
+ case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
+ default:
+ switch proto {
+ case iana.ProtocolICMP:
+ if b[5] != 32 {
+ return fmt.Errorf("got %d; want 32", b[5])
+ }
+ case iana.ProtocolIPv6ICMP:
+ if b[4] != 16 {
+ return fmt.Errorf("got %d; want 16", b[4])
+ }
+ default:
+ return fmt.Errorf("unknown protocol: %d", proto)
+ }
}
- m, err := icmp.ParseMessage(iana.ProtocolICMP, b)
+ m, err := icmp.ParseMessage(proto, b)
if err != nil {
- t.Fatal(err)
+ return err
}
- if m.Type != tt.Type || m.Code != tt.Code {
- t.Errorf("#%v: got %v; want %v", i, m, &tt)
+ if m.Type != tm.Type || m.Code != tm.Code {
+ return fmt.Errorf("got %v; want %v", m, &tm)
}
switch m.Type {
+ case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
+ got, want := m.Body.(*icmp.ExtendedEchoRequest), tm.Body.(*icmp.ExtendedEchoRequest)
+ if !reflect.DeepEqual(got.Extensions, want.Extensions) {
+ return errors.New(dumpExtensions(got.Extensions, want.Extensions))
+ }
case ipv4.ICMPTypeDestinationUnreachable:
- got, want := m.Body.(*icmp.DstUnreach), tt.Body.(*icmp.DstUnreach)
+ got, want := m.Body.(*icmp.DstUnreach), tm.Body.(*icmp.DstUnreach)
if !reflect.DeepEqual(got.Extensions, want.Extensions) {
- t.Error(dumpExtensions(i, got.Extensions, want.Extensions))
+ return errors.New(dumpExtensions(got.Extensions, want.Extensions))
}
if len(got.Data) != 128 {
- t.Errorf("#%v: got %v; want 128", i, len(got.Data))
+ return fmt.Errorf("got %d; want 128", len(got.Data))
}
case ipv4.ICMPTypeTimeExceeded:
- got, want := m.Body.(*icmp.TimeExceeded), tt.Body.(*icmp.TimeExceeded)
+ got, want := m.Body.(*icmp.TimeExceeded), tm.Body.(*icmp.TimeExceeded)
if !reflect.DeepEqual(got.Extensions, want.Extensions) {
- t.Error(dumpExtensions(i, got.Extensions, want.Extensions))
+ return errors.New(dumpExtensions(got.Extensions, want.Extensions))
}
if len(got.Data) != 128 {
- t.Errorf("#%v: got %v; want 128", i, len(got.Data))
+ return fmt.Errorf("got %d; want 128", len(got.Data))
}
case ipv4.ICMPTypeParameterProblem:
- got, want := m.Body.(*icmp.ParamProb), tt.Body.(*icmp.ParamProb)
+ got, want := m.Body.(*icmp.ParamProb), tm.Body.(*icmp.ParamProb)
+ if !reflect.DeepEqual(got.Extensions, want.Extensions) {
+ return errors.New(dumpExtensions(got.Extensions, want.Extensions))
+ }
+ if len(got.Data) != 128 {
+ return fmt.Errorf("got %d; want 128", len(got.Data))
+ }
+ case ipv6.ICMPTypeDestinationUnreachable:
+ got, want := m.Body.(*icmp.DstUnreach), tm.Body.(*icmp.DstUnreach)
if !reflect.DeepEqual(got.Extensions, want.Extensions) {
- t.Error(dumpExtensions(i, got.Extensions, want.Extensions))
+ return errors.New(dumpExtensions(got.Extensions, want.Extensions))
}
if len(got.Data) != 128 {
- t.Errorf("#%v: got %v; want 128", i, len(got.Data))
+ return fmt.Errorf("got %d; want 128", len(got.Data))
}
+ case ipv6.ICMPTypeTimeExceeded:
+ got, want := m.Body.(*icmp.TimeExceeded), tm.Body.(*icmp.TimeExceeded)
+ if !reflect.DeepEqual(got.Extensions, want.Extensions) {
+ return errors.New(dumpExtensions(got.Extensions, want.Extensions))
+ }
+ if len(got.Data) != 128 {
+ return fmt.Errorf("got %d; want 128", len(got.Data))
+ }
+ default:
+ return fmt.Errorf("unknown message type: %v", m.Type)
}
+ return nil
}
-}
-var marshalAndParseMultipartMessageForIPv6Tests = []icmp.Message{
- {
- Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6,
- Body: &icmp.DstUnreach{
- Data: []byte("ERROR-INVOKING-PACKET"),
- Extensions: []icmp.Extension{
- &icmp.MPLSLabelStack{
- Class: 1,
- Type: 1,
- Labels: []icmp.MPLSLabel{
- {
- Label: 16014,
- TC: 0x4,
- S: true,
- TTL: 255,
+ t.Run("IPv4", func(t *testing.T) {
+ for i, tm := range []icmp.Message{
+ {
+ Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15,
+ Body: &icmp.DstUnreach{
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{
+ Class: 1,
+ Type: 1,
+ Labels: []icmp.MPLSLabel{
+ {
+ Label: 16014,
+ TC: 0x4,
+ S: true,
+ TTL: 255,
+ },
+ },
+ },
+ &icmp.InterfaceInfo{
+ Class: 2,
+ Type: 0x0f,
+ Interface: &net.Interface{
+ Index: 15,
+ Name: "en101",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.IPv4(192, 168, 0, 1).To4(),
+ },
},
},
},
- &icmp.InterfaceInfo{
- Class: 2,
- Type: 0x0f,
- Interface: &net.Interface{
- Index: 15,
- Name: "en101",
- MTU: 8192,
+ },
+ {
+ Type: ipv4.ICMPTypeTimeExceeded, Code: 1,
+ Body: &icmp.TimeExceeded{
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceInfo{
+ Class: 2,
+ Type: 0x0f,
+ Interface: &net.Interface{
+ Index: 15,
+ Name: "en101",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.IPv4(192, 168, 0, 1).To4(),
+ },
+ },
+ &icmp.MPLSLabelStack{
+ Class: 1,
+ Type: 1,
+ Labels: []icmp.MPLSLabel{
+ {
+ Label: 16014,
+ TC: 0x4,
+ S: true,
+ TTL: 255,
+ },
+ },
+ },
},
- Addr: &net.IPAddr{
- IP: net.ParseIP("fe80::1"),
- Zone: "en101",
+ },
+ },
+ {
+ Type: ipv4.ICMPTypeParameterProblem, Code: 2,
+ Body: &icmp.ParamProb{
+ Pointer: 8,
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{
+ Class: 1,
+ Type: 1,
+ Labels: []icmp.MPLSLabel{
+ {
+ Label: 16014,
+ TC: 0x4,
+ S: true,
+ TTL: 255,
+ },
+ },
+ },
+ &icmp.InterfaceInfo{
+ Class: 2,
+ Type: 0x0f,
+ Interface: &net.Interface{
+ Index: 15,
+ Name: "en101",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.IPv4(192, 168, 0, 1).To4(),
+ },
+ },
+ &icmp.InterfaceInfo{
+ Class: 2,
+ Type: 0x2f,
+ Interface: &net.Interface{
+ Index: 16,
+ Name: "en102",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.IPv4(192, 168, 0, 2).To4(),
+ },
+ },
},
},
},
- },
- },
- {
- Type: ipv6.ICMPTypeTimeExceeded, Code: 1,
- Body: &icmp.TimeExceeded{
- Data: []byte("ERROR-INVOKING-PACKET"),
- Extensions: []icmp.Extension{
- &icmp.InterfaceInfo{
- Class: 2,
- Type: 0x0f,
- Interface: &net.Interface{
- Index: 15,
- Name: "en101",
- MTU: 8192,
+ {
+ Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: 1, Seq: 2, Local: true,
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 1,
+ Name: "en101",
+ },
},
- Addr: &net.IPAddr{
- IP: net.ParseIP("fe80::1"),
- Zone: "en101",
+ },
+ },
+ {
+ Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: 1, Seq: 2, Local: true,
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 2,
+ Index: 911,
+ },
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 1,
+ Name: "en101",
+ },
},
},
- &icmp.MPLSLabelStack{
- Class: 1,
- Type: 1,
- Labels: []icmp.MPLSLabel{
- {
- Label: 16014,
- TC: 0x4,
- S: true,
- TTL: 255,
+ },
+ {
+ Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: 1, Seq: 2,
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 3,
+ AFI: iana.AddrFamily48bitMAC,
+ Addr: []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab},
},
},
},
- &icmp.InterfaceInfo{
- Class: 2,
- Type: 0x2f,
- Interface: &net.Interface{
- Index: 16,
- Name: "en102",
- MTU: 8192,
+ },
+ } {
+ if err := fn(t, iana.ProtocolICMP, tm); err != nil {
+ t.Errorf("#%d: %v", i, err)
+ }
+ }
+ })
+ t.Run("IPv6", func(t *testing.T) {
+ for i, tm := range []icmp.Message{
+ {
+ Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6,
+ Body: &icmp.DstUnreach{
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{
+ Class: 1,
+ Type: 1,
+ Labels: []icmp.MPLSLabel{
+ {
+ Label: 16014,
+ TC: 0x4,
+ S: true,
+ TTL: 255,
+ },
+ },
+ },
+ &icmp.InterfaceInfo{
+ Class: 2,
+ Type: 0x0f,
+ Interface: &net.Interface{
+ Index: 15,
+ Name: "en101",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.ParseIP("fe80::1"),
+ Zone: "en101",
+ },
+ },
},
- Addr: &net.IPAddr{
- IP: net.ParseIP("fe80::1"),
- Zone: "en102",
+ },
+ },
+ {
+ Type: ipv6.ICMPTypeTimeExceeded, Code: 1,
+ Body: &icmp.TimeExceeded{
+ Data: []byte("ERROR-INVOKING-PACKET"),
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceInfo{
+ Class: 2,
+ Type: 0x0f,
+ Interface: &net.Interface{
+ Index: 15,
+ Name: "en101",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.ParseIP("fe80::1"),
+ Zone: "en101",
+ },
+ },
+ &icmp.MPLSLabelStack{
+ Class: 1,
+ Type: 1,
+ Labels: []icmp.MPLSLabel{
+ {
+ Label: 16014,
+ TC: 0x4,
+ S: true,
+ TTL: 255,
+ },
+ },
+ },
+ &icmp.InterfaceInfo{
+ Class: 2,
+ Type: 0x2f,
+ Interface: &net.Interface{
+ Index: 16,
+ Name: "en102",
+ MTU: 8192,
+ },
+ Addr: &net.IPAddr{
+ IP: net.ParseIP("fe80::1"),
+ Zone: "en102",
+ },
+ },
},
},
},
- },
- },
-}
-
-func TestMarshalAndParseMultipartMessageForIPv6(t *testing.T) {
- pshicmp := icmp.IPv6PseudoHeader(net.ParseIP("fe80::1"), net.ParseIP("ff02::1"))
- for i, tt := range marshalAndParseMultipartMessageForIPv6Tests {
- for _, psh := range [][]byte{pshicmp, nil} {
- b, err := tt.Marshal(psh)
- if err != nil {
- t.Fatal(err)
- }
- if b[4] != 16 {
- t.Errorf("#%v: got %v; want 16", i, b[4])
- }
- m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, b)
- if err != nil {
- t.Fatal(err)
- }
- if m.Type != tt.Type || m.Code != tt.Code {
- t.Errorf("#%v: got %v; want %v", i, m, &tt)
- }
- switch m.Type {
- case ipv6.ICMPTypeDestinationUnreachable:
- got, want := m.Body.(*icmp.DstUnreach), tt.Body.(*icmp.DstUnreach)
- if !reflect.DeepEqual(got.Extensions, want.Extensions) {
- t.Error(dumpExtensions(i, got.Extensions, want.Extensions))
- }
- if len(got.Data) != 128 {
- t.Errorf("#%v: got %v; want 128", i, len(got.Data))
- }
- case ipv6.ICMPTypeTimeExceeded:
- got, want := m.Body.(*icmp.TimeExceeded), tt.Body.(*icmp.TimeExceeded)
- if !reflect.DeepEqual(got.Extensions, want.Extensions) {
- t.Error(dumpExtensions(i, got.Extensions, want.Extensions))
- }
- if len(got.Data) != 128 {
- t.Errorf("#%v: got %v; want 128", i, len(got.Data))
- }
+ {
+ Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: 1, Seq: 2, Local: true,
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 1,
+ Name: "en101",
+ },
+ },
+ },
+ },
+ {
+ Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: 1, Seq: 2, Local: true,
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 1,
+ Name: "en101",
+ },
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 2,
+ Index: 911,
+ },
+ },
+ },
+ },
+ {
+ Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
+ Body: &icmp.ExtendedEchoRequest{
+ ID: 1, Seq: 2,
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Class: 3,
+ Type: 3,
+ AFI: iana.AddrFamilyIPv4,
+ Addr: []byte{192, 0, 2, 1},
+ },
+ },
+ },
+ },
+ } {
+ if err := fn(t, iana.ProtocolIPv6ICMP, tm); err != nil {
+ t.Errorf("#%d: %v", i, err)
}
}
- }
+ })
}
-func dumpExtensions(i int, gotExts, wantExts []icmp.Extension) string {
+func dumpExtensions(gotExts, wantExts []icmp.Extension) string {
var s string
- for j, got := range gotExts {
+ for i, got := range gotExts {
switch got := got.(type) {
case *icmp.MPLSLabelStack:
- want := wantExts[j].(*icmp.MPLSLabelStack)
+ want := wantExts[i].(*icmp.MPLSLabelStack)
if !reflect.DeepEqual(got, want) {
- s += fmt.Sprintf("#%v/%v: got %#v; want %#v\n", i, j, got, want)
+ s += fmt.Sprintf("#%d: got %#v; want %#v\n", i, got, want)
}
case *icmp.InterfaceInfo:
- want := wantExts[j].(*icmp.InterfaceInfo)
+ want := wantExts[i].(*icmp.InterfaceInfo)
+ if !reflect.DeepEqual(got, want) {
+ s += fmt.Sprintf("#%d: got %#v, %#v, %#v; want %#v, %#v, %#v\n", i, got, got.Interface, got.Addr, want, want.Interface, want.Addr)
+ }
+ case *icmp.InterfaceIdent:
+ want := wantExts[i].(*icmp.InterfaceIdent)
if !reflect.DeepEqual(got, want) {
- s += fmt.Sprintf("#%v/%v: got %#v, %#v, %#v; want %#v, %#v, %#v\n", i, j, got, got.Interface, got.Addr, want, want.Interface, want.Addr)
+ s += fmt.Sprintf("#%d: got %#v; want %#v\n", i, got, want)
}
}
}
+ if len(s) == 0 {
+ return "<nil>"
+ }
return s[:len(s)-1]
}
-var multipartMessageBodyLenTests = []struct {
- proto int
- in icmp.MessageBody
- out int
-}{
- {
- iana.ProtocolICMP,
- &icmp.DstUnreach{
- Data: make([]byte, ipv4.HeaderLen),
+func TestMultipartMessageBodyLen(t *testing.T) {
+ for i, tt := range []struct {
+ proto int
+ in icmp.MessageBody
+ out int
+ }{
+ {
+ iana.ProtocolICMP,
+ &icmp.DstUnreach{
+ Data: make([]byte, ipv4.HeaderLen),
+ },
+ 4 + ipv4.HeaderLen, // unused and original datagram
},
- 4 + ipv4.HeaderLen, // unused and original datagram
- },
- {
- iana.ProtocolICMP,
- &icmp.TimeExceeded{
- Data: make([]byte, ipv4.HeaderLen),
+ {
+ iana.ProtocolICMP,
+ &icmp.TimeExceeded{
+ Data: make([]byte, ipv4.HeaderLen),
+ },
+ 4 + ipv4.HeaderLen, // unused and original datagram
},
- 4 + ipv4.HeaderLen, // unused and original datagram
- },
- {
- iana.ProtocolICMP,
- &icmp.ParamProb{
- Data: make([]byte, ipv4.HeaderLen),
+ {
+ iana.ProtocolICMP,
+ &icmp.ParamProb{
+ Data: make([]byte, ipv4.HeaderLen),
+ },
+ 4 + ipv4.HeaderLen, // [pointer, unused] and original datagram
},
- 4 + ipv4.HeaderLen, // [pointer, unused] and original datagram
- },
- {
- iana.ProtocolICMP,
- &icmp.ParamProb{
- Data: make([]byte, ipv4.HeaderLen),
- Extensions: []icmp.Extension{
- &icmp.MPLSLabelStack{},
+ {
+ iana.ProtocolICMP,
+ &icmp.ParamProb{
+ Data: make([]byte, ipv4.HeaderLen),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{},
+ },
},
+ 4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload, original datagram
},
- 4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload, original datagram
- },
- {
- iana.ProtocolICMP,
- &icmp.ParamProb{
- Data: make([]byte, 128),
- Extensions: []icmp.Extension{
- &icmp.MPLSLabelStack{},
+ {
+ iana.ProtocolICMP,
+ &icmp.ParamProb{
+ Data: make([]byte, 128),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{},
+ },
},
+ 4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload and original datagram
},
- 4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload and original datagram
- },
- {
- iana.ProtocolICMP,
- &icmp.ParamProb{
- Data: make([]byte, 129),
- Extensions: []icmp.Extension{
- &icmp.MPLSLabelStack{},
+ {
+ iana.ProtocolICMP,
+ &icmp.ParamProb{
+ Data: make([]byte, 129),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{},
+ },
},
+ 4 + 4 + 4 + 0 + 132, // [pointer, length, unused], extension header, object header, object payload and original datagram
},
- 4 + 4 + 4 + 0 + 132, // [pointer, length, unused], extension header, object header, object payload and original datagram
- },
- {
- iana.ProtocolIPv6ICMP,
- &icmp.DstUnreach{
- Data: make([]byte, ipv6.HeaderLen),
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.DstUnreach{
+ Data: make([]byte, ipv6.HeaderLen),
+ },
+ 4 + ipv6.HeaderLen, // unused and original datagram
},
- 4 + ipv6.HeaderLen, // unused and original datagram
- },
- {
- iana.ProtocolIPv6ICMP,
- &icmp.PacketTooBig{
- Data: make([]byte, ipv6.HeaderLen),
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.PacketTooBig{
+ Data: make([]byte, ipv6.HeaderLen),
+ },
+ 4 + ipv6.HeaderLen, // mtu and original datagram
},
- 4 + ipv6.HeaderLen, // mtu and original datagram
- },
- {
- iana.ProtocolIPv6ICMP,
- &icmp.TimeExceeded{
- Data: make([]byte, ipv6.HeaderLen),
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.TimeExceeded{
+ Data: make([]byte, ipv6.HeaderLen),
+ },
+ 4 + ipv6.HeaderLen, // unused and original datagram
},
- 4 + ipv6.HeaderLen, // unused and original datagram
- },
- {
- iana.ProtocolIPv6ICMP,
- &icmp.ParamProb{
- Data: make([]byte, ipv6.HeaderLen),
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.ParamProb{
+ Data: make([]byte, ipv6.HeaderLen),
+ },
+ 4 + ipv6.HeaderLen, // pointer and original datagram
},
- 4 + ipv6.HeaderLen, // pointer and original datagram
- },
- {
- iana.ProtocolIPv6ICMP,
- &icmp.DstUnreach{
- Data: make([]byte, 127),
- Extensions: []icmp.Extension{
- &icmp.MPLSLabelStack{},
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.DstUnreach{
+ Data: make([]byte, 127),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{},
+ },
},
+ 4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram
},
- 4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram
- },
- {
- iana.ProtocolIPv6ICMP,
- &icmp.DstUnreach{
- Data: make([]byte, 128),
- Extensions: []icmp.Extension{
- &icmp.MPLSLabelStack{},
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.DstUnreach{
+ Data: make([]byte, 128),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{},
+ },
},
+ 4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram
},
- 4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram
- },
- {
- iana.ProtocolIPv6ICMP,
- &icmp.DstUnreach{
- Data: make([]byte, 129),
- Extensions: []icmp.Extension{
- &icmp.MPLSLabelStack{},
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.DstUnreach{
+ Data: make([]byte, 129),
+ Extensions: []icmp.Extension{
+ &icmp.MPLSLabelStack{},
+ },
},
+ 4 + 4 + 4 + 0 + 136, // [length, unused], extension header, object header, object payload and original datagram
},
- 4 + 4 + 4 + 0 + 136, // [length, unused], extension header, object header, object payload and original datagram
- },
-}
-func TestMultipartMessageBodyLen(t *testing.T) {
- for i, tt := range multipartMessageBodyLenTests {
+ {
+ iana.ProtocolICMP,
+ &icmp.ExtendedEchoRequest{},
+ 4, // [id, seq, l-bit]
+ },
+ {
+ iana.ProtocolICMP,
+ &icmp.ExtendedEchoRequest{
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{},
+ },
+ },
+ 4 + 4 + 4, // [id, seq, l-bit], extension header, object header
+ },
+ {
+ iana.ProtocolIPv6ICMP,
+ &icmp.ExtendedEchoRequest{
+ Extensions: []icmp.Extension{
+ &icmp.InterfaceIdent{
+ Type: 3,
+ AFI: iana.AddrFamilyNSAP,
+ Addr: []byte{0x49, 0x00, 0x01, 0xaa, 0xaa, 0xbb, 0xbb, 0xcc, 0xcc, 0x00},
+ },
+ },
+ },
+ 4 + 4 + 4 + 16, // [id, seq, l-bit], extension header, object header, object payload
+ },
+ } {
if out := tt.in.Len(tt.proto); out != tt.out {
t.Errorf("#%d: got %d; want %d", i, out, tt.out)
}
diff --git a/vendor/golang.org/x/net/icmp/packettoobig.go b/vendor/golang.org/x/net/icmp/packettoobig.go
index a1c9df7..afbf24f 100644
--- a/vendor/golang.org/x/net/icmp/packettoobig.go
+++ b/vendor/golang.org/x/net/icmp/packettoobig.go
@@ -29,7 +29,7 @@ func (p *PacketTooBig) Marshal(proto int) ([]byte, error) {
}
// parsePacketTooBig parses b as an ICMP packet too big message body.
-func parsePacketTooBig(proto int, b []byte) (MessageBody, error) {
+func parsePacketTooBig(proto int, _ Type, b []byte) (MessageBody, error) {
bodyLen := len(b)
if bodyLen < 4 {
return nil, errMessageTooShort
diff --git a/vendor/golang.org/x/net/icmp/paramprob.go b/vendor/golang.org/x/net/icmp/paramprob.go
index 0a2548d..8587255 100644
--- a/vendor/golang.org/x/net/icmp/paramprob.go
+++ b/vendor/golang.org/x/net/icmp/paramprob.go
@@ -21,7 +21,7 @@ func (p *ParamProb) Len(proto int) int {
if p == nil {
return 0
}
- l, _ := multipartMessageBodyDataLen(proto, p.Data, p.Extensions)
+ l, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions)
return 4 + l
}
@@ -33,7 +33,7 @@ func (p *ParamProb) Marshal(proto int) ([]byte, error) {
copy(b[4:], p.Data)
return b, nil
}
- b, err := marshalMultipartMessageBody(proto, p.Data, p.Extensions)
+ b, err := marshalMultipartMessageBody(proto, true, p.Data, p.Extensions)
if err != nil {
return nil, err
}
@@ -42,7 +42,7 @@ func (p *ParamProb) Marshal(proto int) ([]byte, error) {
}
// parseParamProb parses b as an ICMP parameter problem message body.
-func parseParamProb(proto int, b []byte) (MessageBody, error) {
+func parseParamProb(proto int, typ Type, b []byte) (MessageBody, error) {
if len(b) < 4 {
return nil, errMessageTooShort
}
@@ -55,7 +55,7 @@ func parseParamProb(proto int, b []byte) (MessageBody, error) {
}
p.Pointer = uintptr(b[0])
var err error
- p.Data, p.Extensions, err = parseMultipartMessageBody(proto, b)
+ p.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b)
if err != nil {
return nil, err
}
diff --git a/vendor/golang.org/x/net/icmp/ping_test.go b/vendor/golang.org/x/net/icmp/ping_test.go
deleted file mode 100644
index 3171dad..0000000
--- a/vendor/golang.org/x/net/icmp/ping_test.go
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2014 The Go 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 icmp_test
-
-import (
- "errors"
- "fmt"
- "net"
- "os"
- "runtime"
- "sync"
- "testing"
- "time"
-
- "golang.org/x/net/icmp"
- "golang.org/x/net/internal/iana"
- "golang.org/x/net/internal/nettest"
- "golang.org/x/net/ipv4"
- "golang.org/x/net/ipv6"
-)
-
-func googleAddr(c *icmp.PacketConn, protocol int) (net.Addr, error) {
- const host = "www.google.com"
- ips, err := net.LookupIP(host)
- if err != nil {
- return nil, err
- }
- netaddr := func(ip net.IP) (net.Addr, error) {
- switch c.LocalAddr().(type) {
- case *net.UDPAddr:
- return &net.UDPAddr{IP: ip}, nil
- case *net.IPAddr:
- return &net.IPAddr{IP: ip}, nil
- default:
- return nil, errors.New("neither UDPAddr nor IPAddr")
- }
- }
- for _, ip := range ips {
- switch protocol {
- case iana.ProtocolICMP:
- if ip.To4() != nil {
- return netaddr(ip)
- }
- case iana.ProtocolIPv6ICMP:
- if ip.To16() != nil && ip.To4() == nil {
- return netaddr(ip)
- }
- }
- }
- return nil, errors.New("no A or AAAA record")
-}
-
-type pingTest struct {
- network, address string
- protocol int
- mtype icmp.Type
-}
-
-var nonPrivilegedPingTests = []pingTest{
- {"udp4", "0.0.0.0", iana.ProtocolICMP, ipv4.ICMPTypeEcho},
-
- {"udp6", "::", iana.ProtocolIPv6ICMP, ipv6.ICMPTypeEchoRequest},
-}
-
-func TestNonPrivilegedPing(t *testing.T) {
- if testing.Short() {
- t.Skip("avoid external network")
- }
- switch runtime.GOOS {
- case "darwin":
- case "linux":
- t.Log("you may need to adjust the net.ipv4.ping_group_range kernel state")
- default:
- t.Skipf("not supported on %s", runtime.GOOS)
- }
-
- for i, tt := range nonPrivilegedPingTests {
- if err := doPing(tt, i); err != nil {
- t.Error(err)
- }
- }
-}
-
-var privilegedPingTests = []pingTest{
- {"ip4:icmp", "0.0.0.0", iana.ProtocolICMP, ipv4.ICMPTypeEcho},
-
- {"ip6:ipv6-icmp", "::", iana.ProtocolIPv6ICMP, ipv6.ICMPTypeEchoRequest},
-}
-
-func TestPrivilegedPing(t *testing.T) {
- if testing.Short() {
- t.Skip("avoid external network")
- }
- if m, ok := nettest.SupportsRawIPSocket(); !ok {
- t.Skip(m)
- }
-
- for i, tt := range privilegedPingTests {
- if err := doPing(tt, i); err != nil {
- t.Error(err)
- }
- }
-}
-
-func doPing(tt pingTest, seq int) error {
- c, err := icmp.ListenPacket(tt.network, tt.address)
- if err != nil {
- return err
- }
- defer c.Close()
-
- dst, err := googleAddr(c, tt.protocol)
- if err != nil {
- return err
- }
-
- if tt.network != "udp6" && tt.protocol == iana.ProtocolIPv6ICMP {
- var f ipv6.ICMPFilter
- f.SetAll(true)
- f.Accept(ipv6.ICMPTypeDestinationUnreachable)
- f.Accept(ipv6.ICMPTypePacketTooBig)
- f.Accept(ipv6.ICMPTypeTimeExceeded)
- f.Accept(ipv6.ICMPTypeParameterProblem)
- f.Accept(ipv6.ICMPTypeEchoReply)
- if err := c.IPv6PacketConn().SetICMPFilter(&f); err != nil {
- return err
- }
- }
-
- wm := icmp.Message{
- Type: tt.mtype, Code: 0,
- Body: &icmp.Echo{
- ID: os.Getpid() & 0xffff, Seq: 1 << uint(seq),
- Data: []byte("HELLO-R-U-THERE"),
- },
- }
- wb, err := wm.Marshal(nil)
- if err != nil {
- return err
- }
- if n, err := c.WriteTo(wb, dst); err != nil {
- return err
- } else if n != len(wb) {
- return fmt.Errorf("got %v; want %v", n, len(wb))
- }
-
- rb := make([]byte, 1500)
- if err := c.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
- return err
- }
- n, peer, err := c.ReadFrom(rb)
- if err != nil {
- return err
- }
- rm, err := icmp.ParseMessage(tt.protocol, rb[:n])
- if err != nil {
- return err
- }
- switch rm.Type {
- case ipv4.ICMPTypeEchoReply, ipv6.ICMPTypeEchoReply:
- return nil
- default:
- return fmt.Errorf("got %+v from %v; want echo reply", rm, peer)
- }
-}
-
-func TestConcurrentNonPrivilegedListenPacket(t *testing.T) {
- if testing.Short() {
- t.Skip("avoid external network")
- }
- switch runtime.GOOS {
- case "darwin":
- case "linux":
- t.Log("you may need to adjust the net.ipv4.ping_group_range kernel state")
- default:
- t.Skipf("not supported on %s", runtime.GOOS)
- }
-
- network, address := "udp4", "127.0.0.1"
- if !nettest.SupportsIPv4() {
- network, address = "udp6", "::1"
- }
- const N = 1000
- var wg sync.WaitGroup
- wg.Add(N)
- for i := 0; i < N; i++ {
- go func() {
- defer wg.Done()
- c, err := icmp.ListenPacket(network, address)
- if err != nil {
- t.Error(err)
- return
- }
- c.Close()
- }()
- }
- wg.Wait()
-}
diff --git a/vendor/golang.org/x/net/icmp/timeexceeded.go b/vendor/golang.org/x/net/icmp/timeexceeded.go
index 344e158..14e9e23 100644
--- a/vendor/golang.org/x/net/icmp/timeexceeded.go
+++ b/vendor/golang.org/x/net/icmp/timeexceeded.go
@@ -15,23 +15,23 @@ func (p *TimeExceeded) Len(proto int) int {
if p == nil {
return 0
}
- l, _ := multipartMessageBodyDataLen(proto, p.Data, p.Extensions)
+ l, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions)
return 4 + l
}
// Marshal implements the Marshal method of MessageBody interface.
func (p *TimeExceeded) Marshal(proto int) ([]byte, error) {
- return marshalMultipartMessageBody(proto, p.Data, p.Extensions)
+ return marshalMultipartMessageBody(proto, true, p.Data, p.Extensions)
}
// parseTimeExceeded parses b as an ICMP time exceeded message body.
-func parseTimeExceeded(proto int, b []byte) (MessageBody, error) {
+func parseTimeExceeded(proto int, typ Type, b []byte) (MessageBody, error) {
if len(b) < 4 {
return nil, errMessageTooShort
}
p := &TimeExceeded{}
var err error
- p.Data, p.Extensions, err = parseMultipartMessageBody(proto, b)
+ p.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b)
if err != nil {
return nil, err
}