Moved to google.golang.org/genproto/googleapis/api/annotations
Fixes #52
This commit is contained in:
		
							
								
								
									
										41
									
								
								vendor/golang.org/x/net/icmp/dstunreach.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								vendor/golang.org/x/net/icmp/dstunreach.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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, 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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseDstUnreach parses b as an ICMP destination unreachable message
 | 
			
		||||
// body.
 | 
			
		||||
func parseDstUnreach(proto int, b []byte) (MessageBody, error) {
 | 
			
		||||
	if len(b) < 4 {
 | 
			
		||||
		return nil, errMessageTooShort
 | 
			
		||||
	}
 | 
			
		||||
	p := &DstUnreach{}
 | 
			
		||||
	var err error
 | 
			
		||||
	p.Data, p.Extensions, err = parseMultipartMessageBody(proto, b)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return p, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								vendor/golang.org/x/net/icmp/echo.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								vendor/golang.org/x/net/icmp/echo.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
// 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, 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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										113
									
								
								vendor/golang.org/x/net/icmp/endpoint.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								vendor/golang.org/x/net/icmp/endpoint.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								vendor/golang.org/x/net/icmp/example_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								vendor/golang.org/x/net/icmp/example_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"log"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/net/icmp"
 | 
			
		||||
	"golang.org/x/net/ipv6"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func ExamplePacketConn_nonPrivilegedPing() {
 | 
			
		||||
	switch runtime.GOOS {
 | 
			
		||||
	case "darwin":
 | 
			
		||||
	case "linux":
 | 
			
		||||
		log.Println("you may need to adjust the net.ipv4.ping_group_range kernel state")
 | 
			
		||||
	default:
 | 
			
		||||
		log.Println("not supported on", runtime.GOOS)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c, err := icmp.ListenPacket("udp6", "fe80::1%en0")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	defer c.Close()
 | 
			
		||||
 | 
			
		||||
	wm := icmp.Message{
 | 
			
		||||
		Type: ipv6.ICMPTypeEchoRequest, Code: 0,
 | 
			
		||||
		Body: &icmp.Echo{
 | 
			
		||||
			ID: os.Getpid() & 0xffff, Seq: 1,
 | 
			
		||||
			Data: []byte("HELLO-R-U-THERE"),
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	wb, err := wm.Marshal(nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	if _, err := c.WriteTo(wb, &net.UDPAddr{IP: net.ParseIP("ff02::1"), Zone: "en0"}); err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rb := make([]byte, 1500)
 | 
			
		||||
	n, peer, err := c.ReadFrom(rb)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	rm, err := icmp.ParseMessage(58, rb[:n])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	switch rm.Type {
 | 
			
		||||
	case ipv6.ICMPTypeEchoReply:
 | 
			
		||||
		log.Printf("got reflection from %v", peer)
 | 
			
		||||
	default:
 | 
			
		||||
		log.Printf("got %+v; want echo reply", rm)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										89
									
								
								vendor/golang.org/x/net/icmp/extension.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								vendor/golang.org/x/net/icmp/extension.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
			
		||||
// 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"
 | 
			
		||||
 | 
			
		||||
// 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(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.
 | 
			
		||||
	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)
 | 
			
		||||
		}
 | 
			
		||||
		b = b[ol:]
 | 
			
		||||
	}
 | 
			
		||||
	return exts, l, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										259
									
								
								vendor/golang.org/x/net/icmp/extension_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										259
									
								
								vendor/golang.org/x/net/icmp/extension_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,259 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"net"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/net/internal/iana"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	// 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 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,
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	// 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,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	// 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, 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,
 | 
			
		||||
				},
 | 
			
		||||
				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
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		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
 | 
			
		||||
		}{
 | 
			
		||||
			{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},
 | 
			
		||||
		} {
 | 
			
		||||
			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
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
		if _, err := ifi.parseName(tt.b); err != tt.error {
 | 
			
		||||
			t.Errorf("#%d: got %v; want %v", i, err, tt.error)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								vendor/golang.org/x/net/icmp/helper.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/golang.org/x/net/icmp/helper.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
// Copyright 2016 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"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
 | 
			
		||||
	freebsdVersion uint32
 | 
			
		||||
 | 
			
		||||
	nativeEndian binary.ByteOrder
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	i := uint32(1)
 | 
			
		||||
	b := (*[4]byte)(unsafe.Pointer(&i))
 | 
			
		||||
	if b[0] == 1 {
 | 
			
		||||
		nativeEndian = binary.LittleEndian
 | 
			
		||||
	} else {
 | 
			
		||||
		nativeEndian = binary.BigEndian
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										75
									
								
								vendor/golang.org/x/net/icmp/helper_posix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								vendor/golang.org/x/net/icmp/helper_posix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										236
									
								
								vendor/golang.org/x/net/icmp/interface.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								vendor/golang.org/x/net/icmp/interface.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,236 @@
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
	afiIPv4 = 1
 | 
			
		||||
	afiIPv6 = 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(afiIPv4))
 | 
			
		||||
		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))
 | 
			
		||||
		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 afiIPv4:
 | 
			
		||||
		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:
 | 
			
		||||
		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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										56
									
								
								vendor/golang.org/x/net/icmp/ipv4.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								vendor/golang.org/x/net/icmp/ipv4.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
// 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/ipv4"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 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(nativeEndian.Uint16(b[2:4]))
 | 
			
		||||
	case "freebsd":
 | 
			
		||||
		if freebsdVersion >= 1000000 {
 | 
			
		||||
			h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
 | 
			
		||||
		} else {
 | 
			
		||||
			h.TotalLen = int(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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										82
									
								
								vendor/golang.org/x/net/icmp/ipv4_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								vendor/golang.org/x/net/icmp/ipv4_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
// 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"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"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 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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								vendor/golang.org/x/net/icmp/ipv6.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/golang.org/x/net/icmp/ipv6.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										100
									
								
								vendor/golang.org/x/net/icmp/listen_posix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								vendor/golang.org/x/net/icmp/listen_posix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								vendor/golang.org/x/net/icmp/listen_stub.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								vendor/golang.org/x/net/icmp/listen_stub.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										152
									
								
								vendor/golang.org/x/net/icmp/message.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								vendor/golang.org/x/net/icmp/message.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,152 @@
 | 
			
		||||
// 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.
 | 
			
		||||
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, []byte) (MessageBody, error){
 | 
			
		||||
	ipv4.ICMPTypeDestinationUnreachable: parseDstUnreach,
 | 
			
		||||
	ipv4.ICMPTypeTimeExceeded:           parseTimeExceeded,
 | 
			
		||||
	ipv4.ICMPTypeParameterProblem:       parseParamProb,
 | 
			
		||||
 | 
			
		||||
	ipv4.ICMPTypeEcho:      parseEcho,
 | 
			
		||||
	ipv4.ICMPTypeEchoReply: parseEcho,
 | 
			
		||||
 | 
			
		||||
	ipv6.ICMPTypeDestinationUnreachable: parseDstUnreach,
 | 
			
		||||
	ipv6.ICMPTypePacketTooBig:           parsePacketTooBig,
 | 
			
		||||
	ipv6.ICMPTypeTimeExceeded:           parseTimeExceeded,
 | 
			
		||||
	ipv6.ICMPTypeParameterProblem:       parseParamProb,
 | 
			
		||||
 | 
			
		||||
	ipv6.ICMPTypeEchoRequest: parseEcho,
 | 
			
		||||
	ipv6.ICMPTypeEchoReply:   parseEcho,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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, b[4:])
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return m, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										134
									
								
								vendor/golang.org/x/net/icmp/message_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								vendor/golang.org/x/net/icmp/message_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"net"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/net/icmp"
 | 
			
		||||
	"golang.org/x/net/internal/iana"
 | 
			
		||||
	"golang.org/x/net/ipv4"
 | 
			
		||||
	"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)
 | 
			
		||||
			}
 | 
			
		||||
			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)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								vendor/golang.org/x/net/icmp/messagebody.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								vendor/golang.org/x/net/icmp/messagebody.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										77
									
								
								vendor/golang.org/x/net/icmp/mpls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								vendor/golang.org/x/net/icmp/mpls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										109
									
								
								vendor/golang.org/x/net/icmp/multipart.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								vendor/golang.org/x/net/icmp/multipart.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
			
		||||
// 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, b []byte, exts []Extension) (bodyLen, dataLen int) {
 | 
			
		||||
	for _, ext := range exts {
 | 
			
		||||
		bodyLen += ext.Len(proto)
 | 
			
		||||
	}
 | 
			
		||||
	if bodyLen > 0 {
 | 
			
		||||
		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, data []byte, exts []Extension) ([]byte, error) {
 | 
			
		||||
	bodyLen, dataLen := multipartMessageBodyDataLen(proto, 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)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		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)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return b, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseMultipartMessageBody parses b as either a non-multipart
 | 
			
		||||
// message body or a multipart message body.
 | 
			
		||||
func parseMultipartMessageBody(proto int, 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(b[4:], l)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		l = len(b) - 4
 | 
			
		||||
	}
 | 
			
		||||
	data := make([]byte, l)
 | 
			
		||||
	copy(data, b[4:])
 | 
			
		||||
	return data, exts, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										442
									
								
								vendor/golang.org/x/net/icmp/multipart_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										442
									
								
								vendor/golang.org/x/net/icmp/multipart_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,442 @@
 | 
			
		||||
// 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_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/net/icmp"
 | 
			
		||||
	"golang.org/x/net/internal/iana"
 | 
			
		||||
	"golang.org/x/net/ipv4"
 | 
			
		||||
	"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)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			t.Fatal(err)
 | 
			
		||||
		}
 | 
			
		||||
		if b[5] != 32 {
 | 
			
		||||
			t.Errorf("#%v: got %v; want 32", i, b[5])
 | 
			
		||||
		}
 | 
			
		||||
		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)
 | 
			
		||||
		}
 | 
			
		||||
		switch m.Type {
 | 
			
		||||
		case ipv4.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 ipv4.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))
 | 
			
		||||
			}
 | 
			
		||||
		case ipv4.ICMPTypeParameterProblem:
 | 
			
		||||
			got, want := m.Body.(*icmp.ParamProb), tt.Body.(*icmp.ParamProb)
 | 
			
		||||
			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))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				&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",
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		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))
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dumpExtensions(i int, gotExts, wantExts []icmp.Extension) string {
 | 
			
		||||
	var s string
 | 
			
		||||
	for j, got := range gotExts {
 | 
			
		||||
		switch got := got.(type) {
 | 
			
		||||
		case *icmp.MPLSLabelStack:
 | 
			
		||||
			want := wantExts[j].(*icmp.MPLSLabelStack)
 | 
			
		||||
			if !reflect.DeepEqual(got, want) {
 | 
			
		||||
				s += fmt.Sprintf("#%v/%v: got %#v; want %#v\n", i, j, got, want)
 | 
			
		||||
			}
 | 
			
		||||
		case *icmp.InterfaceInfo:
 | 
			
		||||
			want := wantExts[j].(*icmp.InterfaceInfo)
 | 
			
		||||
			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)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return s[:len(s)-1]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var multipartMessageBodyLenTests = []struct {
 | 
			
		||||
	proto int
 | 
			
		||||
	in    icmp.MessageBody
 | 
			
		||||
	out   int
 | 
			
		||||
}{
 | 
			
		||||
	{
 | 
			
		||||
		iana.ProtocolICMP,
 | 
			
		||||
		&icmp.DstUnreach{
 | 
			
		||||
			Data: make([]byte, ipv4.HeaderLen),
 | 
			
		||||
		},
 | 
			
		||||
		4 + ipv4.HeaderLen, // unused and original datagram
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		iana.ProtocolICMP,
 | 
			
		||||
		&icmp.TimeExceeded{
 | 
			
		||||
			Data: make([]byte, ipv4.HeaderLen),
 | 
			
		||||
		},
 | 
			
		||||
		4 + ipv4.HeaderLen, // unused and original datagram
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		iana.ProtocolICMP,
 | 
			
		||||
		&icmp.ParamProb{
 | 
			
		||||
			Data: make([]byte, ipv4.HeaderLen),
 | 
			
		||||
		},
 | 
			
		||||
		4 + ipv4.HeaderLen, // [pointer, unused] and original datagram
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		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
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		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
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		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
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		iana.ProtocolIPv6ICMP,
 | 
			
		||||
		&icmp.DstUnreach{
 | 
			
		||||
			Data: make([]byte, ipv6.HeaderLen),
 | 
			
		||||
		},
 | 
			
		||||
		4 + ipv6.HeaderLen, // unused and original datagram
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		iana.ProtocolIPv6ICMP,
 | 
			
		||||
		&icmp.PacketTooBig{
 | 
			
		||||
			Data: make([]byte, ipv6.HeaderLen),
 | 
			
		||||
		},
 | 
			
		||||
		4 + ipv6.HeaderLen, // mtu and original datagram
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		iana.ProtocolIPv6ICMP,
 | 
			
		||||
		&icmp.TimeExceeded{
 | 
			
		||||
			Data: make([]byte, ipv6.HeaderLen),
 | 
			
		||||
		},
 | 
			
		||||
		4 + ipv6.HeaderLen, // unused and original datagram
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		iana.ProtocolIPv6ICMP,
 | 
			
		||||
		&icmp.ParamProb{
 | 
			
		||||
			Data: make([]byte, ipv6.HeaderLen),
 | 
			
		||||
		},
 | 
			
		||||
		4 + ipv6.HeaderLen, // pointer and original datagram
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		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
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		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
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		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
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestMultipartMessageBodyLen(t *testing.T) {
 | 
			
		||||
	for i, tt := range multipartMessageBodyLenTests {
 | 
			
		||||
		if out := tt.in.Len(tt.proto); out != tt.out {
 | 
			
		||||
			t.Errorf("#%d: got %d; want %d", i, out, tt.out)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								vendor/golang.org/x/net/icmp/packettoobig.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								vendor/golang.org/x/net/icmp/packettoobig.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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, 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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								vendor/golang.org/x/net/icmp/paramprob.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								vendor/golang.org/x/net/icmp/paramprob.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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, 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, 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, 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, b)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return p, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										200
									
								
								vendor/golang.org/x/net/icmp/ping_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								vendor/golang.org/x/net/icmp/ping_test.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,200 @@
 | 
			
		||||
// 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()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								vendor/golang.org/x/net/icmp/sys_freebsd.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/golang.org/x/net/icmp/sys_freebsd.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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")
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								vendor/golang.org/x/net/icmp/timeexceeded.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								vendor/golang.org/x/net/icmp/timeexceeded.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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, 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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseTimeExceeded parses b as an ICMP time exceeded message body.
 | 
			
		||||
func parseTimeExceeded(proto int, b []byte) (MessageBody, error) {
 | 
			
		||||
	if len(b) < 4 {
 | 
			
		||||
		return nil, errMessageTooShort
 | 
			
		||||
	}
 | 
			
		||||
	p := &TimeExceeded{}
 | 
			
		||||
	var err error
 | 
			
		||||
	p.Data, p.Extensions, err = parseMultipartMessageBody(proto, b)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return p, nil
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user