aboutsummaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/net/icmp
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2018-04-25 09:28:54 +0200
committerDimitri Sokolyuk <demon@dim13.org>2018-04-25 09:28:54 +0200
commite1e8d058a33f7566f9c565d04b0d8b56f9645c35 (patch)
treeddd8a705efdc02cc8968eac7410aa8fd045e2a28 /vendor/golang.org/x/net/icmp
parent45109e77b62e40bb973b68412b94017bd7130754 (diff)
add vendor
Diffstat (limited to 'vendor/golang.org/x/net/icmp')
-rw-r--r--vendor/golang.org/x/net/icmp/dstunreach.go41
-rw-r--r--vendor/golang.org/x/net/icmp/echo.go157
-rw-r--r--vendor/golang.org/x/net/icmp/endpoint.go113
-rw-r--r--vendor/golang.org/x/net/icmp/extension.go108
-rw-r--r--vendor/golang.org/x/net/icmp/helper_posix.go75
-rw-r--r--vendor/golang.org/x/net/icmp/interface.go322
-rw-r--r--vendor/golang.org/x/net/icmp/ipv4.go61
-rw-r--r--vendor/golang.org/x/net/icmp/ipv6.go23
-rw-r--r--vendor/golang.org/x/net/icmp/listen_posix.go100
-rw-r--r--vendor/golang.org/x/net/icmp/listen_stub.go33
-rw-r--r--vendor/golang.org/x/net/icmp/message.go157
-rw-r--r--vendor/golang.org/x/net/icmp/messagebody.go41
-rw-r--r--vendor/golang.org/x/net/icmp/mpls.go77
-rw-r--r--vendor/golang.org/x/net/icmp/multipart.go121
-rw-r--r--vendor/golang.org/x/net/icmp/packettoobig.go43
-rw-r--r--vendor/golang.org/x/net/icmp/paramprob.go63
-rw-r--r--vendor/golang.org/x/net/icmp/sys_freebsd.go11
-rw-r--r--vendor/golang.org/x/net/icmp/timeexceeded.go39
18 files changed, 1585 insertions, 0 deletions
diff --git a/vendor/golang.org/x/net/icmp/dstunreach.go b/vendor/golang.org/x/net/icmp/dstunreach.go
new file mode 100644
index 0000000..7464bf7
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/dstunreach.go
@@ -0,0 +1,41 @@
+// 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
+
+// A DstUnreach represents an ICMP destination unreachable message
+// body.
+type DstUnreach struct {
+ Data []byte // data, known as original datagram field
+ Extensions []Extension // extensions
+}
+
+// Len implements the Len method of MessageBody interface.
+func (p *DstUnreach) Len(proto int) int {
+ if p == nil {
+ return 0
+ }
+ 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, true, p.Data, p.Extensions)
+}
+
+// parseDstUnreach parses b as an ICMP destination unreachable message
+// body.
+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, typ, b)
+ if err != nil {
+ return nil, err
+ }
+ return p, nil
+}
diff --git a/vendor/golang.org/x/net/icmp/echo.go b/vendor/golang.org/x/net/icmp/echo.go
new file mode 100644
index 0000000..c611f65
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/echo.go
@@ -0,0 +1,157 @@
+// Copyright 2012 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
+
+import "encoding/binary"
+
+// An Echo represents an ICMP echo request or reply message body.
+type Echo struct {
+ ID int // identifier
+ Seq int // sequence number
+ Data []byte // data
+}
+
+// Len implements the Len method of MessageBody interface.
+func (p *Echo) Len(proto int) int {
+ if p == nil {
+ return 0
+ }
+ return 4 + len(p.Data)
+}
+
+// Marshal implements the Marshal method of MessageBody interface.
+func (p *Echo) Marshal(proto int) ([]byte, error) {
+ b := make([]byte, 4+len(p.Data))
+ binary.BigEndian.PutUint16(b[:2], uint16(p.ID))
+ binary.BigEndian.PutUint16(b[2:4], uint16(p.Seq))
+ copy(b[4:], p.Data)
+ return b, nil
+}
+
+// parseEcho parses b as an ICMP echo request or reply message body.
+func parseEcho(proto int, _ Type, b []byte) (MessageBody, error) {
+ bodyLen := len(b)
+ if bodyLen < 4 {
+ return nil, errMessageTooShort
+ }
+ p := &Echo{ID: int(binary.BigEndian.Uint16(b[:2])), Seq: int(binary.BigEndian.Uint16(b[2:4]))}
+ if bodyLen > 4 {
+ p.Data = make([]byte, bodyLen-4)
+ copy(p.Data, b[4:])
+ }
+ 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
new file mode 100644
index 0000000..a68bfb0
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/endpoint.go
@@ -0,0 +1,113 @@
+// 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
+
+import (
+ "net"
+ "runtime"
+ "syscall"
+ "time"
+
+ "golang.org/x/net/ipv4"
+ "golang.org/x/net/ipv6"
+)
+
+var _ net.PacketConn = &PacketConn{}
+
+// A PacketConn represents a packet network endpoint that uses either
+// ICMPv4 or ICMPv6.
+type PacketConn struct {
+ c net.PacketConn
+ p4 *ipv4.PacketConn
+ p6 *ipv6.PacketConn
+}
+
+func (c *PacketConn) ok() bool { return c != nil && c.c != nil }
+
+// IPv4PacketConn returns the ipv4.PacketConn of c.
+// It returns nil when c is not created as the endpoint for ICMPv4.
+func (c *PacketConn) IPv4PacketConn() *ipv4.PacketConn {
+ if !c.ok() {
+ return nil
+ }
+ return c.p4
+}
+
+// IPv6PacketConn returns the ipv6.PacketConn of c.
+// It returns nil when c is not created as the endpoint for ICMPv6.
+func (c *PacketConn) IPv6PacketConn() *ipv6.PacketConn {
+ if !c.ok() {
+ return nil
+ }
+ return c.p6
+}
+
+// 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
+ }
+ // Please be informed that ipv4.NewPacketConn enables
+ // IP_STRIPHDR option by default on Darwin.
+ // See golang.org/issue/9395 for further information.
+ if runtime.GOOS == "darwin" && c.p4 != nil {
+ n, _, peer, err := c.p4.ReadFrom(b)
+ return n, peer, err
+ }
+ return c.c.ReadFrom(b)
+}
+
+// WriteTo writes the ICMP message b to dst.
+// Dst must be net.UDPAddr when c is a non-privileged
+// 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 c.c.WriteTo(b, dst)
+}
+
+// Close closes the endpoint.
+func (c *PacketConn) Close() error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ return c.c.Close()
+}
+
+// LocalAddr returns the local network address.
+func (c *PacketConn) LocalAddr() net.Addr {
+ if !c.ok() {
+ return nil
+ }
+ return c.c.LocalAddr()
+}
+
+// SetDeadline sets the read and write deadlines associated with the
+// endpoint.
+func (c *PacketConn) SetDeadline(t time.Time) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ return c.c.SetDeadline(t)
+}
+
+// SetReadDeadline sets the read deadline associated with the
+// endpoint.
+func (c *PacketConn) SetReadDeadline(t time.Time) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ return c.c.SetReadDeadline(t)
+}
+
+// SetWriteDeadline sets the write deadline associated with the
+// endpoint.
+func (c *PacketConn) SetWriteDeadline(t time.Time) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ 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
new file mode 100644
index 0000000..2005068
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/extension.go
@@ -0,0 +1,108 @@
+// Copyright 2015 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
+
+import (
+ "encoding/binary"
+
+ "golang.org/x/net/ipv4"
+ "golang.org/x/net/ipv6"
+)
+
+// An Extension represents an ICMP extension.
+type Extension interface {
+ // Len returns the length of ICMP extension.
+ // Proto must be either the ICMPv4 or ICMPv6 protocol number.
+ Len(proto int) int
+
+ // Marshal returns the binary encoding of ICMP extension.
+ // Proto must be either the ICMPv4 or ICMPv6 protocol number.
+ Marshal(proto int) ([]byte, error)
+}
+
+const extensionVersion = 2
+
+func validExtensionHeader(b []byte) bool {
+ v := int(b[0]&0xf0) >> 4
+ s := binary.BigEndian.Uint16(b[2:4])
+ if s != 0 {
+ s = checksum(b)
+ }
+ if v != extensionVersion || s != 0 {
+ return false
+ }
+ return true
+}
+
+// parseExtensions parses b as a list of ICMP extensions.
+// The length attribute l must be the length attribute field in
+// received icmp messages.
+//
+// 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(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.
+ //
+ // A minimal extension at least requires 8 octets; 4 octets
+ // for an extension header, and 4 octets for a single object
+ // header.
+ //
+ // See RFC 4884 for further information.
+ switch typ {
+ case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
+ if len(b) < 8 || !validExtensionHeader(b) {
+ return nil, -1, errNoExtension
+ }
+ 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; {
+ ol := int(binary.BigEndian.Uint16(b[:2]))
+ if 4 > ol || ol > len(b) {
+ break
+ }
+ switch b[2] {
+ case classMPLSLabelStack:
+ ext, err := parseMPLSLabelStack(b[:ol])
+ if err != nil {
+ return nil, -1, err
+ }
+ exts = append(exts, ext)
+ case classInterfaceInfo:
+ ext, err := parseInterfaceInfo(b[:ol])
+ if err != nil {
+ 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:]
+ }
+ return exts, l, nil
+}
diff --git a/vendor/golang.org/x/net/icmp/helper_posix.go b/vendor/golang.org/x/net/icmp/helper_posix.go
new file mode 100644
index 0000000..398fd38
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/helper_posix.go
@@ -0,0 +1,75 @@
+// 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.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
+
+package icmp
+
+import (
+ "net"
+ "strconv"
+ "syscall"
+)
+
+func sockaddr(family int, address string) (syscall.Sockaddr, error) {
+ switch family {
+ case syscall.AF_INET:
+ a, err := net.ResolveIPAddr("ip4", address)
+ if err != nil {
+ return nil, err
+ }
+ if len(a.IP) == 0 {
+ a.IP = net.IPv4zero
+ }
+ if a.IP = a.IP.To4(); a.IP == nil {
+ return nil, net.InvalidAddrError("non-ipv4 address")
+ }
+ sa := &syscall.SockaddrInet4{}
+ copy(sa.Addr[:], a.IP)
+ return sa, nil
+ case syscall.AF_INET6:
+ a, err := net.ResolveIPAddr("ip6", address)
+ if err != nil {
+ return nil, err
+ }
+ if len(a.IP) == 0 {
+ a.IP = net.IPv6unspecified
+ }
+ if a.IP.Equal(net.IPv4zero) {
+ a.IP = net.IPv6unspecified
+ }
+ if a.IP = a.IP.To16(); a.IP == nil || a.IP.To4() != nil {
+ return nil, net.InvalidAddrError("non-ipv6 address")
+ }
+ sa := &syscall.SockaddrInet6{ZoneId: zoneToUint32(a.Zone)}
+ copy(sa.Addr[:], a.IP)
+ return sa, nil
+ default:
+ return nil, net.InvalidAddrError("unexpected family")
+ }
+}
+
+func zoneToUint32(zone string) uint32 {
+ if zone == "" {
+ return 0
+ }
+ if ifi, err := net.InterfaceByName(zone); err == nil {
+ return uint32(ifi.Index)
+ }
+ n, err := strconv.Atoi(zone)
+ if err != nil {
+ return 0
+ }
+ return uint32(n)
+}
+
+func last(s string, b byte) int {
+ i := len(s)
+ for i--; i >= 0; i-- {
+ if s[i] == b {
+ break
+ }
+ }
+ return i
+}
diff --git a/vendor/golang.org/x/net/icmp/interface.go b/vendor/golang.org/x/net/icmp/interface.go
new file mode 100644
index 0000000..617f757
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/interface.go
@@ -0,0 +1,322 @@
+// Copyright 2015 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
+
+import (
+ "encoding/binary"
+ "net"
+ "strings"
+
+ "golang.org/x/net/internal/iana"
+)
+
+const (
+ classInterfaceInfo = 2
+)
+
+const (
+ attrMTU = 1 << iota
+ attrName
+ attrIPAddr
+ attrIfIndex
+)
+
+// An InterfaceInfo represents interface and next-hop identification.
+type InterfaceInfo struct {
+ Class int // extension object class number
+ Type int // extension object sub-type
+ Interface *net.Interface
+ Addr *net.IPAddr
+}
+
+func (ifi *InterfaceInfo) nameLen() int {
+ if len(ifi.Interface.Name) > 63 {
+ return 64
+ }
+ l := 1 + len(ifi.Interface.Name)
+ return (l + 3) &^ 3
+}
+
+func (ifi *InterfaceInfo) attrsAndLen(proto int) (attrs, l int) {
+ l = 4
+ if ifi.Interface != nil && ifi.Interface.Index > 0 {
+ attrs |= attrIfIndex
+ l += 4
+ if len(ifi.Interface.Name) > 0 {
+ attrs |= attrName
+ l += ifi.nameLen()
+ }
+ if ifi.Interface.MTU > 0 {
+ attrs |= attrMTU
+ l += 4
+ }
+ }
+ if ifi.Addr != nil {
+ switch proto {
+ case iana.ProtocolICMP:
+ if ifi.Addr.IP.To4() != nil {
+ attrs |= attrIPAddr
+ l += 4 + net.IPv4len
+ }
+ case iana.ProtocolIPv6ICMP:
+ if ifi.Addr.IP.To16() != nil && ifi.Addr.IP.To4() == nil {
+ attrs |= attrIPAddr
+ l += 4 + net.IPv6len
+ }
+ }
+ }
+ return
+}
+
+// Len implements the Len method of Extension interface.
+func (ifi *InterfaceInfo) Len(proto int) int {
+ _, l := ifi.attrsAndLen(proto)
+ return l
+}
+
+// Marshal implements the Marshal method of Extension interface.
+func (ifi *InterfaceInfo) Marshal(proto int) ([]byte, error) {
+ attrs, l := ifi.attrsAndLen(proto)
+ b := make([]byte, l)
+ if err := ifi.marshal(proto, b, attrs, l); err != nil {
+ return nil, err
+ }
+ return b, nil
+}
+
+func (ifi *InterfaceInfo) marshal(proto int, b []byte, attrs, l int) error {
+ binary.BigEndian.PutUint16(b[:2], uint16(l))
+ b[2], b[3] = classInterfaceInfo, byte(ifi.Type)
+ for b = b[4:]; len(b) > 0 && attrs != 0; {
+ switch {
+ case attrs&attrIfIndex != 0:
+ b = ifi.marshalIfIndex(proto, b)
+ attrs &^= attrIfIndex
+ case attrs&attrIPAddr != 0:
+ b = ifi.marshalIPAddr(proto, b)
+ attrs &^= attrIPAddr
+ case attrs&attrName != 0:
+ b = ifi.marshalName(proto, b)
+ attrs &^= attrName
+ case attrs&attrMTU != 0:
+ b = ifi.marshalMTU(proto, b)
+ attrs &^= attrMTU
+ }
+ }
+ return nil
+}
+
+func (ifi *InterfaceInfo) marshalIfIndex(proto int, b []byte) []byte {
+ binary.BigEndian.PutUint32(b[:4], uint32(ifi.Interface.Index))
+ return b[4:]
+}
+
+func (ifi *InterfaceInfo) parseIfIndex(b []byte) ([]byte, error) {
+ if len(b) < 4 {
+ return nil, errMessageTooShort
+ }
+ ifi.Interface.Index = int(binary.BigEndian.Uint32(b[:4]))
+ return b[4:], nil
+}
+
+func (ifi *InterfaceInfo) marshalIPAddr(proto int, b []byte) []byte {
+ switch proto {
+ case iana.ProtocolICMP:
+ 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(iana.AddrFamilyIPv6))
+ copy(b[4:4+net.IPv6len], ifi.Addr.IP.To16())
+ b = b[4+net.IPv6len:]
+ }
+ return b
+}
+
+func (ifi *InterfaceInfo) parseIPAddr(b []byte) ([]byte, error) {
+ if len(b) < 4 {
+ return nil, errMessageTooShort
+ }
+ afi := int(binary.BigEndian.Uint16(b[:2]))
+ b = b[4:]
+ switch afi {
+ 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 iana.AddrFamilyIPv6:
+ if len(b) < net.IPv6len {
+ return nil, errMessageTooShort
+ }
+ ifi.Addr.IP = make(net.IP, net.IPv6len)
+ copy(ifi.Addr.IP, b[:net.IPv6len])
+ b = b[net.IPv6len:]
+ }
+ return b, nil
+}
+
+func (ifi *InterfaceInfo) marshalName(proto int, b []byte) []byte {
+ l := byte(ifi.nameLen())
+ b[0] = l
+ copy(b[1:], []byte(ifi.Interface.Name))
+ return b[l:]
+}
+
+func (ifi *InterfaceInfo) parseName(b []byte) ([]byte, error) {
+ if 4 > len(b) || len(b) < int(b[0]) {
+ return nil, errMessageTooShort
+ }
+ l := int(b[0])
+ if l%4 != 0 || 4 > l || l > 64 {
+ return nil, errInvalidExtension
+ }
+ var name [63]byte
+ copy(name[:], b[1:l])
+ ifi.Interface.Name = strings.Trim(string(name[:]), "\000")
+ return b[l:], nil
+}
+
+func (ifi *InterfaceInfo) marshalMTU(proto int, b []byte) []byte {
+ binary.BigEndian.PutUint32(b[:4], uint32(ifi.Interface.MTU))
+ return b[4:]
+}
+
+func (ifi *InterfaceInfo) parseMTU(b []byte) ([]byte, error) {
+ if len(b) < 4 {
+ return nil, errMessageTooShort
+ }
+ ifi.Interface.MTU = int(binary.BigEndian.Uint32(b[:4]))
+ return b[4:], nil
+}
+
+func parseInterfaceInfo(b []byte) (Extension, error) {
+ ifi := &InterfaceInfo{
+ Class: int(b[2]),
+ Type: int(b[3]),
+ }
+ if ifi.Type&(attrIfIndex|attrName|attrMTU) != 0 {
+ ifi.Interface = &net.Interface{}
+ }
+ if ifi.Type&attrIPAddr != 0 {
+ ifi.Addr = &net.IPAddr{}
+ }
+ attrs := ifi.Type & (attrIfIndex | attrIPAddr | attrName | attrMTU)
+ for b = b[4:]; len(b) > 0 && attrs != 0; {
+ var err error
+ switch {
+ case attrs&attrIfIndex != 0:
+ b, err = ifi.parseIfIndex(b)
+ attrs &^= attrIfIndex
+ case attrs&attrIPAddr != 0:
+ b, err = ifi.parseIPAddr(b)
+ attrs &^= attrIPAddr
+ case attrs&attrName != 0:
+ b, err = ifi.parseName(b)
+ attrs &^= attrName
+ case attrs&attrMTU != 0:
+ b, err = ifi.parseMTU(b)
+ attrs &^= attrMTU
+ }
+ if err != nil {
+ return nil, err
+ }
+ }
+ if ifi.Interface != nil && ifi.Interface.Name != "" && ifi.Addr != nil && ifi.Addr.IP.To16() != nil && ifi.Addr.IP.To4() == nil {
+ ifi.Addr.Zone = ifi.Interface.Name
+ }
+ 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.go b/vendor/golang.org/x/net/icmp/ipv4.go
new file mode 100644
index 0000000..ffc66ed
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/ipv4.go
@@ -0,0 +1,61 @@
+// 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
+
+import (
+ "encoding/binary"
+ "net"
+ "runtime"
+
+ "golang.org/x/net/internal/socket"
+ "golang.org/x/net/ipv4"
+)
+
+// freebsdVersion is set in sys_freebsd.go.
+// See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
+var freebsdVersion uint32
+
+// ParseIPv4Header parses b as an IPv4 header of ICMP error message
+// invoking packet, which is contained in ICMP error message.
+func ParseIPv4Header(b []byte) (*ipv4.Header, error) {
+ if len(b) < ipv4.HeaderLen {
+ return nil, errHeaderTooShort
+ }
+ hdrlen := int(b[0]&0x0f) << 2
+ if hdrlen > len(b) {
+ return nil, errBufferTooShort
+ }
+ h := &ipv4.Header{
+ Version: int(b[0] >> 4),
+ Len: hdrlen,
+ TOS: int(b[1]),
+ ID: int(binary.BigEndian.Uint16(b[4:6])),
+ FragOff: int(binary.BigEndian.Uint16(b[6:8])),
+ TTL: int(b[8]),
+ Protocol: int(b[9]),
+ Checksum: int(binary.BigEndian.Uint16(b[10:12])),
+ Src: net.IPv4(b[12], b[13], b[14], b[15]),
+ Dst: net.IPv4(b[16], b[17], b[18], b[19]),
+ }
+ switch runtime.GOOS {
+ case "darwin":
+ h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))
+ case "freebsd":
+ if freebsdVersion >= 1000000 {
+ h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
+ } else {
+ h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))
+ }
+ default:
+ h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
+ }
+ h.Flags = ipv4.HeaderFlags(h.FragOff&0xe000) >> 13
+ h.FragOff = h.FragOff & 0x1fff
+ if hdrlen-ipv4.HeaderLen > 0 {
+ h.Options = make([]byte, hdrlen-ipv4.HeaderLen)
+ copy(h.Options, b[ipv4.HeaderLen:])
+ }
+ return h, nil
+}
diff --git a/vendor/golang.org/x/net/icmp/ipv6.go b/vendor/golang.org/x/net/icmp/ipv6.go
new file mode 100644
index 0000000..2e8cfeb
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/ipv6.go
@@ -0,0 +1,23 @@
+// Copyright 2013 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
+
+import (
+ "net"
+
+ "golang.org/x/net/internal/iana"
+)
+
+const ipv6PseudoHeaderLen = 2*net.IPv6len + 8
+
+// IPv6PseudoHeader returns an IPv6 pseudo header for checksum
+// calculation.
+func IPv6PseudoHeader(src, dst net.IP) []byte {
+ b := make([]byte, ipv6PseudoHeaderLen)
+ copy(b, src.To16())
+ copy(b[net.IPv6len:], dst.To16())
+ b[len(b)-1] = byte(iana.ProtocolIPv6ICMP)
+ return b
+}
diff --git a/vendor/golang.org/x/net/icmp/listen_posix.go b/vendor/golang.org/x/net/icmp/listen_posix.go
new file mode 100644
index 0000000..7fac4f9
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/listen_posix.go
@@ -0,0 +1,100 @@
+// 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.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
+
+package icmp
+
+import (
+ "net"
+ "os"
+ "runtime"
+ "syscall"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/ipv4"
+ "golang.org/x/net/ipv6"
+)
+
+const sysIP_STRIPHDR = 0x17 // for now only darwin supports this option
+
+// ListenPacket listens for incoming ICMP packets addressed to
+// address. See net.Dial for the syntax of address.
+//
+// For non-privileged datagram-oriented ICMP endpoints, network must
+// be "udp4" or "udp6". The endpoint allows to read, write a few
+// limited ICMP messages such as echo request and echo reply.
+// Currently only Darwin and Linux support this.
+//
+// Examples:
+// ListenPacket("udp4", "192.168.0.1")
+// ListenPacket("udp4", "0.0.0.0")
+// ListenPacket("udp6", "fe80::1%en0")
+// ListenPacket("udp6", "::")
+//
+// For privileged raw ICMP endpoints, network must be "ip4" or "ip6"
+// followed by a colon and an ICMP protocol number or name.
+//
+// Examples:
+// ListenPacket("ip4:icmp", "192.168.0.1")
+// ListenPacket("ip4:1", "0.0.0.0")
+// ListenPacket("ip6:ipv6-icmp", "fe80::1%en0")
+// ListenPacket("ip6:58", "::")
+func ListenPacket(network, address string) (*PacketConn, error) {
+ var family, proto int
+ switch network {
+ case "udp4":
+ family, proto = syscall.AF_INET, iana.ProtocolICMP
+ case "udp6":
+ family, proto = syscall.AF_INET6, iana.ProtocolIPv6ICMP
+ default:
+ i := last(network, ':')
+ switch network[:i] {
+ case "ip4":
+ proto = iana.ProtocolICMP
+ case "ip6":
+ proto = iana.ProtocolIPv6ICMP
+ }
+ }
+ var cerr error
+ var c net.PacketConn
+ switch family {
+ case syscall.AF_INET, syscall.AF_INET6:
+ s, err := syscall.Socket(family, syscall.SOCK_DGRAM, proto)
+ if err != nil {
+ return nil, os.NewSyscallError("socket", err)
+ }
+ if runtime.GOOS == "darwin" && family == syscall.AF_INET {
+ if err := syscall.SetsockoptInt(s, iana.ProtocolIP, sysIP_STRIPHDR, 1); err != nil {
+ syscall.Close(s)
+ return nil, os.NewSyscallError("setsockopt", err)
+ }
+ }
+ sa, err := sockaddr(family, address)
+ if err != nil {
+ syscall.Close(s)
+ return nil, err
+ }
+ if err := syscall.Bind(s, sa); err != nil {
+ syscall.Close(s)
+ return nil, os.NewSyscallError("bind", err)
+ }
+ f := os.NewFile(uintptr(s), "datagram-oriented icmp")
+ c, cerr = net.FilePacketConn(f)
+ f.Close()
+ default:
+ c, cerr = net.ListenPacket(network, address)
+ }
+ if cerr != nil {
+ return nil, cerr
+ }
+ switch proto {
+ case iana.ProtocolICMP:
+ return &PacketConn{c: c, p4: ipv4.NewPacketConn(c)}, nil
+ case iana.ProtocolIPv6ICMP:
+ return &PacketConn{c: c, p6: ipv6.NewPacketConn(c)}, nil
+ default:
+ return &PacketConn{c: c}, nil
+ }
+}
diff --git a/vendor/golang.org/x/net/icmp/listen_stub.go b/vendor/golang.org/x/net/icmp/listen_stub.go
new file mode 100644
index 0000000..668728d
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/listen_stub.go
@@ -0,0 +1,33 @@
+// 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.
+
+// +build nacl plan9
+
+package icmp
+
+// ListenPacket listens for incoming ICMP packets addressed to
+// address. See net.Dial for the syntax of address.
+//
+// For non-privileged datagram-oriented ICMP endpoints, network must
+// be "udp4" or "udp6". The endpoint allows to read, write a few
+// limited ICMP messages such as echo request and echo reply.
+// Currently only Darwin and Linux support this.
+//
+// Examples:
+// ListenPacket("udp4", "192.168.0.1")
+// ListenPacket("udp4", "0.0.0.0")
+// ListenPacket("udp6", "fe80::1%en0")
+// ListenPacket("udp6", "::")
+//
+// For privileged raw ICMP endpoints, network must be "ip4" or "ip6"
+// followed by a colon and an ICMP protocol number or name.
+//
+// Examples:
+// ListenPacket("ip4:icmp", "192.168.0.1")
+// ListenPacket("ip4:1", "0.0.0.0")
+// ListenPacket("ip6:ipv6-icmp", "fe80::1%en0")
+// ListenPacket("ip6:58", "::")
+func ListenPacket(network, address string) (*PacketConn, error) {
+ return nil, errOpNoSupport
+}
diff --git a/vendor/golang.org/x/net/icmp/message.go b/vendor/golang.org/x/net/icmp/message.go
new file mode 100644
index 0000000..46fe95a
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/message.go
@@ -0,0 +1,157 @@
+// Copyright 2012 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 provides basic functions for the manipulation of
+// messages used in the Internet Control Message Protocols,
+// ICMPv4 and ICMPv6.
+//
+// ICMPv4 and ICMPv6 are defined in RFC 792 and RFC 4443.
+// Multi-part message support for ICMP is defined in RFC 4884.
+// 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.
+
+var (
+ errMessageTooShort = errors.New("message too short")
+ errHeaderTooShort = errors.New("header too short")
+ errBufferTooShort = errors.New("buffer too short")
+ errOpNoSupport = errors.New("operation not supported")
+ errNoExtension = errors.New("no extension")
+ errInvalidExtension = errors.New("invalid extension")
+)
+
+func checksum(b []byte) uint16 {
+ csumcv := len(b) - 1 // checksum coverage
+ s := uint32(0)
+ for i := 0; i < csumcv; i += 2 {
+ s += uint32(b[i+1])<<8 | uint32(b[i])
+ }
+ if csumcv&1 == 0 {
+ s += uint32(b[csumcv])
+ }
+ s = s>>16 + s&0xffff
+ s = s + s>>16
+ return ^uint16(s)
+}
+
+// A Type represents an ICMP message type.
+type Type interface {
+ Protocol() int
+}
+
+// A Message represents an ICMP message.
+type Message struct {
+ Type Type // type, either ipv4.ICMPType or ipv6.ICMPType
+ Code int // code
+ Checksum int // checksum
+ Body MessageBody // body
+}
+
+// Marshal returns the binary encoding of the ICMP message m.
+//
+// For an ICMPv4 message, the returned message always contains the
+// calculated checksum field.
+//
+// For an ICMPv6 message, the returned message contains the calculated
+// checksum field when psh is not nil, otherwise the kernel will
+// compute the checksum field during the message transmission.
+// When psh is not nil, it must be the pseudo header for IPv6.
+func (m *Message) Marshal(psh []byte) ([]byte, error) {
+ var mtype int
+ switch typ := m.Type.(type) {
+ case ipv4.ICMPType:
+ mtype = int(typ)
+ case ipv6.ICMPType:
+ mtype = int(typ)
+ default:
+ return nil, syscall.EINVAL
+ }
+ b := []byte{byte(mtype), byte(m.Code), 0, 0}
+ if m.Type.Protocol() == iana.ProtocolIPv6ICMP && psh != nil {
+ b = append(psh, b...)
+ }
+ if m.Body != nil && m.Body.Len(m.Type.Protocol()) != 0 {
+ mb, err := m.Body.Marshal(m.Type.Protocol())
+ if err != nil {
+ return nil, err
+ }
+ b = append(b, mb...)
+ }
+ if m.Type.Protocol() == iana.ProtocolIPv6ICMP {
+ if psh == nil { // cannot calculate checksum here
+ return b, nil
+ }
+ off, l := 2*net.IPv6len, len(b)-len(psh)
+ binary.BigEndian.PutUint32(b[off:off+4], uint32(l))
+ }
+ s := checksum(b)
+ // Place checksum back in header; using ^= avoids the
+ // assumption the checksum bytes are zero.
+ b[len(psh)+2] ^= byte(s)
+ b[len(psh)+3] ^= byte(s >> 8)
+ return b[len(psh):], nil
+}
+
+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.ICMPTypeExtendedEchoRequest: parseExtendedEchoRequest,
+ ipv4.ICMPTypeExtendedEchoReply: parseExtendedEchoReply,
+
+ ipv6.ICMPTypeDestinationUnreachable: parseDstUnreach,
+ ipv6.ICMPTypePacketTooBig: parsePacketTooBig,
+ ipv6.ICMPTypeTimeExceeded: parseTimeExceeded,
+ ipv6.ICMPTypeParameterProblem: parseParamProb,
+
+ ipv6.ICMPTypeEchoRequest: parseEcho,
+ ipv6.ICMPTypeEchoReply: parseEcho,
+ ipv6.ICMPTypeExtendedEchoRequest: parseExtendedEchoRequest,
+ ipv6.ICMPTypeExtendedEchoReply: parseExtendedEchoReply,
+}
+
+// ParseMessage parses b as an ICMP message.
+// Proto must be either the ICMPv4 or ICMPv6 protocol number.
+func ParseMessage(proto int, b []byte) (*Message, error) {
+ if len(b) < 4 {
+ return nil, errMessageTooShort
+ }
+ var err error
+ m := &Message{Code: int(b[1]), Checksum: int(binary.BigEndian.Uint16(b[2:4]))}
+ switch proto {
+ case iana.ProtocolICMP:
+ m.Type = ipv4.ICMPType(b[0])
+ case iana.ProtocolIPv6ICMP:
+ m.Type = ipv6.ICMPType(b[0])
+ default:
+ return nil, syscall.EINVAL
+ }
+ if fn, ok := parseFns[m.Type]; !ok {
+ m.Body, err = parseDefaultMessageBody(proto, b[4:])
+ } else {
+ m.Body, err = fn(proto, m.Type, b[4:])
+ }
+ if err != nil {
+ return nil, err
+ }
+ return m, nil
+}
diff --git a/vendor/golang.org/x/net/icmp/messagebody.go b/vendor/golang.org/x/net/icmp/messagebody.go
new file mode 100644
index 0000000..2463730
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/messagebody.go
@@ -0,0 +1,41 @@
+// Copyright 2012 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
+
+// A MessageBody represents an ICMP message body.
+type MessageBody interface {
+ // Len returns the length of ICMP message body.
+ // Proto must be either the ICMPv4 or ICMPv6 protocol number.
+ Len(proto int) int
+
+ // Marshal returns the binary encoding of ICMP message body.
+ // Proto must be either the ICMPv4 or ICMPv6 protocol number.
+ Marshal(proto int) ([]byte, error)
+}
+
+// A DefaultMessageBody represents the default message body.
+type DefaultMessageBody struct {
+ Data []byte // data
+}
+
+// Len implements the Len method of MessageBody interface.
+func (p *DefaultMessageBody) Len(proto int) int {
+ if p == nil {
+ return 0
+ }
+ return len(p.Data)
+}
+
+// Marshal implements the Marshal method of MessageBody interface.
+func (p *DefaultMessageBody) Marshal(proto int) ([]byte, error) {
+ return p.Data, nil
+}
+
+// parseDefaultMessageBody parses b as an ICMP message body.
+func parseDefaultMessageBody(proto int, b []byte) (MessageBody, error) {
+ p := &DefaultMessageBody{Data: make([]byte, len(b))}
+ copy(p.Data, b)
+ return p, nil
+}
diff --git a/vendor/golang.org/x/net/icmp/mpls.go b/vendor/golang.org/x/net/icmp/mpls.go
new file mode 100644
index 0000000..c314917
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/mpls.go
@@ -0,0 +1,77 @@
+// Copyright 2015 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
+
+import "encoding/binary"
+
+// A MPLSLabel represents a MPLS label stack entry.
+type MPLSLabel struct {
+ Label int // label value
+ TC int // traffic class; formerly experimental use
+ S bool // bottom of stack
+ TTL int // time to live
+}
+
+const (
+ classMPLSLabelStack = 1
+ typeIncomingMPLSLabelStack = 1
+)
+
+// A MPLSLabelStack represents a MPLS label stack.
+type MPLSLabelStack struct {
+ Class int // extension object class number
+ Type int // extension object sub-type
+ Labels []MPLSLabel
+}
+
+// Len implements the Len method of Extension interface.
+func (ls *MPLSLabelStack) Len(proto int) int {
+ return 4 + (4 * len(ls.Labels))
+}
+
+// Marshal implements the Marshal method of Extension interface.
+func (ls *MPLSLabelStack) Marshal(proto int) ([]byte, error) {
+ b := make([]byte, ls.Len(proto))
+ if err := ls.marshal(proto, b); err != nil {
+ return nil, err
+ }
+ return b, nil
+}
+
+func (ls *MPLSLabelStack) marshal(proto int, b []byte) error {
+ l := ls.Len(proto)
+ binary.BigEndian.PutUint16(b[:2], uint16(l))
+ b[2], b[3] = classMPLSLabelStack, typeIncomingMPLSLabelStack
+ off := 4
+ for _, ll := range ls.Labels {
+ b[off], b[off+1], b[off+2] = byte(ll.Label>>12), byte(ll.Label>>4&0xff), byte(ll.Label<<4&0xf0)
+ b[off+2] |= byte(ll.TC << 1 & 0x0e)
+ if ll.S {
+ b[off+2] |= 0x1
+ }
+ b[off+3] = byte(ll.TTL)
+ off += 4
+ }
+ return nil
+}
+
+func parseMPLSLabelStack(b []byte) (Extension, error) {
+ ls := &MPLSLabelStack{
+ Class: int(b[2]),
+ Type: int(b[3]),
+ }
+ for b = b[4:]; len(b) >= 4; b = b[4:] {
+ ll := MPLSLabel{
+ Label: int(b[0])<<12 | int(b[1])<<4 | int(b[2])>>4,
+ TC: int(b[2]&0x0e) >> 1,
+ TTL: int(b[3]),
+ }
+ if b[2]&0x1 != 0 {
+ ll.S = true
+ }
+ ls.Labels = append(ls.Labels, ll)
+ }
+ return ls, nil
+}
diff --git a/vendor/golang.org/x/net/icmp/multipart.go b/vendor/golang.org/x/net/icmp/multipart.go
new file mode 100644
index 0000000..9ebbbaf
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/multipart.go
@@ -0,0 +1,121 @@
+// Copyright 2015 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
+
+import "golang.org/x/net/internal/iana"
+
+// multipartMessageBodyDataLen takes b as an original datagram and
+// 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, withOrigDgram bool, b []byte, exts []Extension) (bodyLen, dataLen int) {
+ for _, ext := range exts {
+ bodyLen += ext.Len(proto)
+ }
+ if bodyLen > 0 {
+ if withOrigDgram {
+ dataLen = multipartMessageOrigDatagramLen(proto, b)
+ }
+ bodyLen += 4 // length of extension header
+ } else {
+ dataLen = len(b)
+ }
+ bodyLen += dataLen
+ return bodyLen, dataLen
+}
+
+// multipartMessageOrigDatagramLen takes b as an original datagram,
+// and returns a required length for a padded orignal datagram in wire
+// format.
+func multipartMessageOrigDatagramLen(proto int, b []byte) int {
+ roundup := func(b []byte, align int) int {
+ // According to RFC 4884, the padded original datagram
+ // field must contain at least 128 octets.
+ if len(b) < 128 {
+ return 128
+ }
+ r := len(b)
+ return (r + align - 1) & ^(align - 1)
+ }
+ switch proto {
+ case iana.ProtocolICMP:
+ return roundup(b, 4)
+ case iana.ProtocolIPv6ICMP:
+ return roundup(b, 8)
+ default:
+ return len(b)
+ }
+}
+
+// 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, 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
+ if len(exts) > 0 {
+ b[dataLen+4] = byte(extensionVersion << 4)
+ off += 4 // length of object header
+ for _, ext := range exts {
+ switch ext := ext.(type) {
+ case *MPLSLabelStack:
+ if err := ext.marshal(proto, b[off:]); err != nil {
+ return nil, err
+ }
+ off += ext.Len(proto)
+ case *InterfaceInfo:
+ attrs, l := ext.attrsAndLen(proto)
+ if err := ext.marshal(proto, b[off:], attrs, l); err != nil {
+ 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)
+ if withOrigDgram {
+ switch proto {
+ case iana.ProtocolICMP:
+ b[1] = byte(dataLen / 4)
+ case iana.ProtocolIPv6ICMP:
+ b[0] = byte(dataLen / 8)
+ }
+ }
+ }
+ return b, nil
+}
+
+// parseMultipartMessageBody parses b as either a non-multipart
+// message body or a multipart message body.
+func parseMultipartMessageBody(proto int, typ Type, b []byte) ([]byte, []Extension, error) {
+ var l int
+ switch proto {
+ case iana.ProtocolICMP:
+ l = 4 * int(b[1])
+ case iana.ProtocolIPv6ICMP:
+ l = 8 * int(b[0])
+ }
+ if len(b) == 4 {
+ return nil, nil, nil
+ }
+ exts, l, err := parseExtensions(typ, b[4:], l)
+ if err != nil {
+ l = len(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/packettoobig.go b/vendor/golang.org/x/net/icmp/packettoobig.go
new file mode 100644
index 0000000..afbf24f
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/packettoobig.go
@@ -0,0 +1,43 @@
+// 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
+
+import "encoding/binary"
+
+// A PacketTooBig represents an ICMP packet too big message body.
+type PacketTooBig struct {
+ MTU int // maximum transmission unit of the nexthop link
+ Data []byte // data, known as original datagram field
+}
+
+// Len implements the Len method of MessageBody interface.
+func (p *PacketTooBig) Len(proto int) int {
+ if p == nil {
+ return 0
+ }
+ return 4 + len(p.Data)
+}
+
+// Marshal implements the Marshal method of MessageBody interface.
+func (p *PacketTooBig) Marshal(proto int) ([]byte, error) {
+ b := make([]byte, 4+len(p.Data))
+ binary.BigEndian.PutUint32(b[:4], uint32(p.MTU))
+ copy(b[4:], p.Data)
+ return b, nil
+}
+
+// parsePacketTooBig parses b as an ICMP packet too big message body.
+func parsePacketTooBig(proto int, _ Type, b []byte) (MessageBody, error) {
+ bodyLen := len(b)
+ if bodyLen < 4 {
+ return nil, errMessageTooShort
+ }
+ p := &PacketTooBig{MTU: int(binary.BigEndian.Uint32(b[:4]))}
+ if bodyLen > 4 {
+ p.Data = make([]byte, bodyLen-4)
+ copy(p.Data, b[4:])
+ }
+ return p, nil
+}
diff --git a/vendor/golang.org/x/net/icmp/paramprob.go b/vendor/golang.org/x/net/icmp/paramprob.go
new file mode 100644
index 0000000..8587255
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/paramprob.go
@@ -0,0 +1,63 @@
+// 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
+
+import (
+ "encoding/binary"
+ "golang.org/x/net/internal/iana"
+)
+
+// A ParamProb represents an ICMP parameter problem message body.
+type ParamProb struct {
+ Pointer uintptr // offset within the data where the error was detected
+ Data []byte // data, known as original datagram field
+ Extensions []Extension // extensions
+}
+
+// Len implements the Len method of MessageBody interface.
+func (p *ParamProb) Len(proto int) int {
+ if p == nil {
+ return 0
+ }
+ l, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions)
+ return 4 + l
+}
+
+// Marshal implements the Marshal method of MessageBody interface.
+func (p *ParamProb) Marshal(proto int) ([]byte, error) {
+ if proto == iana.ProtocolIPv6ICMP {
+ b := make([]byte, p.Len(proto))
+ binary.BigEndian.PutUint32(b[:4], uint32(p.Pointer))
+ copy(b[4:], p.Data)
+ return b, nil
+ }
+ b, err := marshalMultipartMessageBody(proto, true, p.Data, p.Extensions)
+ if err != nil {
+ return nil, err
+ }
+ b[0] = byte(p.Pointer)
+ return b, nil
+}
+
+// parseParamProb parses b as an ICMP parameter problem message body.
+func parseParamProb(proto int, typ Type, b []byte) (MessageBody, error) {
+ if len(b) < 4 {
+ return nil, errMessageTooShort
+ }
+ p := &ParamProb{}
+ if proto == iana.ProtocolIPv6ICMP {
+ p.Pointer = uintptr(binary.BigEndian.Uint32(b[:4]))
+ p.Data = make([]byte, len(b)-4)
+ copy(p.Data, b[4:])
+ return p, nil
+ }
+ p.Pointer = uintptr(b[0])
+ var err error
+ p.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b)
+ if err != nil {
+ return nil, err
+ }
+ return p, nil
+}
diff --git a/vendor/golang.org/x/net/icmp/sys_freebsd.go b/vendor/golang.org/x/net/icmp/sys_freebsd.go
new file mode 100644
index 0000000..c75f3dd
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/sys_freebsd.go
@@ -0,0 +1,11 @@
+// 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
+
+import "syscall"
+
+func init() {
+ freebsdVersion, _ = syscall.SysctlUint32("kern.osreldate")
+}
diff --git a/vendor/golang.org/x/net/icmp/timeexceeded.go b/vendor/golang.org/x/net/icmp/timeexceeded.go
new file mode 100644
index 0000000..14e9e23
--- /dev/null
+++ b/vendor/golang.org/x/net/icmp/timeexceeded.go
@@ -0,0 +1,39 @@
+// 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
+
+// A TimeExceeded represents an ICMP time exceeded message body.
+type TimeExceeded struct {
+ Data []byte // data, known as original datagram field
+ Extensions []Extension // extensions
+}
+
+// Len implements the Len method of MessageBody interface.
+func (p *TimeExceeded) Len(proto int) int {
+ if p == nil {
+ return 0
+ }
+ 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, true, p.Data, p.Extensions)
+}
+
+// parseTimeExceeded parses b as an ICMP time exceeded message body.
+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, typ, b)
+ if err != nil {
+ return nil, err
+ }
+ return p, nil
+}