mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-28 00:59:58 +00:00
TUN-6666: Define packet package
This package defines IP and ICMP packet, decoders, encoder and flow
This commit is contained in:
3
vendor/golang.org/x/net/AUTHORS
generated
vendored
3
vendor/golang.org/x/net/AUTHORS
generated
vendored
@@ -1,3 +0,0 @@
|
||||
# This source code refers to The Go Authors for copyright purposes.
|
||||
# The master list of authors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/AUTHORS.
|
3
vendor/golang.org/x/net/CONTRIBUTORS
generated
vendored
3
vendor/golang.org/x/net/CONTRIBUTORS
generated
vendored
@@ -1,3 +0,0 @@
|
||||
# This source code was written by the Go contributors.
|
||||
# The master list of contributors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/CONTRIBUTORS.
|
22
vendor/golang.org/x/net/http2/frame.go
generated
vendored
22
vendor/golang.org/x/net/http2/frame.go
generated
vendored
@@ -23,7 +23,7 @@ const frameHeaderLen = 9
|
||||
var padZeros = make([]byte, 255) // zeros for padding
|
||||
|
||||
// A FrameType is a registered frame type as defined in
|
||||
// http://http2.github.io/http2-spec/#rfc.section.11.2
|
||||
// https://httpwg.org/specs/rfc7540.html#rfc.section.11.2
|
||||
type FrameType uint8
|
||||
|
||||
const (
|
||||
@@ -146,7 +146,7 @@ func typeFrameParser(t FrameType) frameParser {
|
||||
|
||||
// A FrameHeader is the 9 byte header of all HTTP/2 frames.
|
||||
//
|
||||
// See http://http2.github.io/http2-spec/#FrameHeader
|
||||
// See https://httpwg.org/specs/rfc7540.html#FrameHeader
|
||||
type FrameHeader struct {
|
||||
valid bool // caller can access []byte fields in the Frame
|
||||
|
||||
@@ -575,7 +575,7 @@ func (fr *Framer) checkFrameOrder(f Frame) error {
|
||||
|
||||
// A DataFrame conveys arbitrary, variable-length sequences of octets
|
||||
// associated with a stream.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.1
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1
|
||||
type DataFrame struct {
|
||||
FrameHeader
|
||||
data []byte
|
||||
@@ -698,7 +698,7 @@ func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []by
|
||||
// endpoints communicate, such as preferences and constraints on peer
|
||||
// behavior.
|
||||
//
|
||||
// See http://http2.github.io/http2-spec/#SETTINGS
|
||||
// See https://httpwg.org/specs/rfc7540.html#SETTINGS
|
||||
type SettingsFrame struct {
|
||||
FrameHeader
|
||||
p []byte
|
||||
@@ -837,7 +837,7 @@ func (f *Framer) WriteSettingsAck() error {
|
||||
// A PingFrame is a mechanism for measuring a minimal round trip time
|
||||
// from the sender, as well as determining whether an idle connection
|
||||
// is still functional.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.7
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7
|
||||
type PingFrame struct {
|
||||
FrameHeader
|
||||
Data [8]byte
|
||||
@@ -870,7 +870,7 @@ func (f *Framer) WritePing(ack bool, data [8]byte) error {
|
||||
}
|
||||
|
||||
// A GoAwayFrame informs the remote peer to stop creating streams on this connection.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.8
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8
|
||||
type GoAwayFrame struct {
|
||||
FrameHeader
|
||||
LastStreamID uint32
|
||||
@@ -934,7 +934,7 @@ func parseUnknownFrame(_ *frameCache, fh FrameHeader, countError func(string), p
|
||||
}
|
||||
|
||||
// A WindowUpdateFrame is used to implement flow control.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.9
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9
|
||||
type WindowUpdateFrame struct {
|
||||
FrameHeader
|
||||
Increment uint32 // never read with high bit set
|
||||
@@ -1123,7 +1123,7 @@ func (f *Framer) WriteHeaders(p HeadersFrameParam) error {
|
||||
}
|
||||
|
||||
// A PriorityFrame specifies the sender-advised priority of a stream.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.3
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3
|
||||
type PriorityFrame struct {
|
||||
FrameHeader
|
||||
PriorityParam
|
||||
@@ -1193,7 +1193,7 @@ func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error {
|
||||
}
|
||||
|
||||
// A RSTStreamFrame allows for abnormal termination of a stream.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.4
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4
|
||||
type RSTStreamFrame struct {
|
||||
FrameHeader
|
||||
ErrCode ErrCode
|
||||
@@ -1225,7 +1225,7 @@ func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error {
|
||||
}
|
||||
|
||||
// A ContinuationFrame is used to continue a sequence of header block fragments.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.10
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10
|
||||
type ContinuationFrame struct {
|
||||
FrameHeader
|
||||
headerFragBuf []byte
|
||||
@@ -1266,7 +1266,7 @@ func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlock
|
||||
}
|
||||
|
||||
// A PushPromiseFrame is used to initiate a server stream.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.6
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6
|
||||
type PushPromiseFrame struct {
|
||||
FrameHeader
|
||||
PromiseID uint32
|
||||
|
2
vendor/golang.org/x/net/http2/hpack/encode.go
generated
vendored
2
vendor/golang.org/x/net/http2/hpack/encode.go
generated
vendored
@@ -191,7 +191,7 @@ func appendTableSize(dst []byte, v uint32) []byte {
|
||||
// bit prefix, to dst and returns the extended buffer.
|
||||
//
|
||||
// See
|
||||
// http://http2.github.io/http2-spec/compression.html#integer.representation
|
||||
// https://httpwg.org/specs/rfc7541.html#integer.representation
|
||||
func appendVarInt(dst []byte, n byte, i uint64) []byte {
|
||||
k := uint64((1 << n) - 1)
|
||||
if i < k {
|
||||
|
16
vendor/golang.org/x/net/http2/hpack/hpack.go
generated
vendored
16
vendor/golang.org/x/net/http2/hpack/hpack.go
generated
vendored
@@ -59,7 +59,7 @@ func (hf HeaderField) String() string {
|
||||
|
||||
// Size returns the size of an entry per RFC 7541 section 4.1.
|
||||
func (hf HeaderField) Size() uint32 {
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.4.1
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.4.1
|
||||
// "The size of the dynamic table is the sum of the size of
|
||||
// its entries. The size of an entry is the sum of its name's
|
||||
// length in octets (as defined in Section 5.2), its value's
|
||||
@@ -158,7 +158,7 @@ func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) {
|
||||
}
|
||||
|
||||
type dynamicTable struct {
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.2.3.2
|
||||
table headerFieldTable
|
||||
size uint32 // in bytes
|
||||
maxSize uint32 // current maxSize
|
||||
@@ -307,27 +307,27 @@ func (d *Decoder) parseHeaderFieldRepr() error {
|
||||
case b&128 != 0:
|
||||
// Indexed representation.
|
||||
// High bit set?
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.6.1
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.1
|
||||
return d.parseFieldIndexed()
|
||||
case b&192 == 64:
|
||||
// 6.2.1 Literal Header Field with Incremental Indexing
|
||||
// 0b10xxxxxx: top two bits are 10
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.1
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1
|
||||
return d.parseFieldLiteral(6, indexedTrue)
|
||||
case b&240 == 0:
|
||||
// 6.2.2 Literal Header Field without Indexing
|
||||
// 0b0000xxxx: top four bits are 0000
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.2
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2
|
||||
return d.parseFieldLiteral(4, indexedFalse)
|
||||
case b&240 == 16:
|
||||
// 6.2.3 Literal Header Field never Indexed
|
||||
// 0b0001xxxx: top four bits are 0001
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.3
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3
|
||||
return d.parseFieldLiteral(4, indexedNever)
|
||||
case b&224 == 32:
|
||||
// 6.3 Dynamic Table Size Update
|
||||
// Top three bits are '001'.
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.6.3
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.3
|
||||
return d.parseDynamicTableSizeUpdate()
|
||||
}
|
||||
|
||||
@@ -420,7 +420,7 @@ var errVarintOverflow = DecodingError{errors.New("varint integer overflow")}
|
||||
|
||||
// readVarInt reads an unsigned variable length integer off the
|
||||
// beginning of p. n is the parameter as described in
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.5.1.
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.5.1.
|
||||
//
|
||||
// n must always be between 1 and 8.
|
||||
//
|
||||
|
8
vendor/golang.org/x/net/http2/http2.go
generated
vendored
8
vendor/golang.org/x/net/http2/http2.go
generated
vendored
@@ -55,14 +55,14 @@ const (
|
||||
ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
|
||||
|
||||
// SETTINGS_MAX_FRAME_SIZE default
|
||||
// http://http2.github.io/http2-spec/#rfc.section.6.5.2
|
||||
// https://httpwg.org/specs/rfc7540.html#rfc.section.6.5.2
|
||||
initialMaxFrameSize = 16384
|
||||
|
||||
// NextProtoTLS is the NPN/ALPN protocol negotiated during
|
||||
// HTTP/2's TLS setup.
|
||||
NextProtoTLS = "h2"
|
||||
|
||||
// http://http2.github.io/http2-spec/#SettingValues
|
||||
// https://httpwg.org/specs/rfc7540.html#SettingValues
|
||||
initialHeaderTableSize = 4096
|
||||
|
||||
initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size
|
||||
@@ -111,7 +111,7 @@ func (st streamState) String() string {
|
||||
// Setting is a setting parameter: which setting it is, and its value.
|
||||
type Setting struct {
|
||||
// ID is which setting is being set.
|
||||
// See http://http2.github.io/http2-spec/#SettingValues
|
||||
// See https://httpwg.org/specs/rfc7540.html#SettingFormat
|
||||
ID SettingID
|
||||
|
||||
// Val is the value.
|
||||
@@ -143,7 +143,7 @@ func (s Setting) Valid() error {
|
||||
}
|
||||
|
||||
// A SettingID is an HTTP/2 setting as defined in
|
||||
// http://http2.github.io/http2-spec/#iana-settings
|
||||
// https://httpwg.org/specs/rfc7540.html#iana-settings
|
||||
type SettingID uint16
|
||||
|
||||
const (
|
||||
|
9
vendor/golang.org/x/net/http2/server.go
generated
vendored
9
vendor/golang.org/x/net/http2/server.go
generated
vendored
@@ -1747,6 +1747,12 @@ func (sc *serverConn) processData(f *DataFrame) error {
|
||||
|
||||
// Sender sending more than they'd declared?
|
||||
if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
|
||||
if sc.inflow.available() < int32(f.Length) {
|
||||
return sc.countError("data_flow", streamError(id, ErrCodeFlowControl))
|
||||
}
|
||||
sc.inflow.take(int32(f.Length))
|
||||
sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
|
||||
|
||||
st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
|
||||
// RFC 7540, sec 8.1.2.6: A request or response is also malformed if the
|
||||
// value of a content-length header field does not equal the sum of the
|
||||
@@ -2223,6 +2229,9 @@ func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler
|
||||
didPanic := true
|
||||
defer func() {
|
||||
rw.rws.stream.cancelCtx()
|
||||
if req.MultipartForm != nil {
|
||||
req.MultipartForm.RemoveAll()
|
||||
}
|
||||
if didPanic {
|
||||
e := recover()
|
||||
sc.writeFrameFromHandler(FrameWriteRequest{
|
||||
|
51
vendor/golang.org/x/net/http2/transport.go
generated
vendored
51
vendor/golang.org/x/net/http2/transport.go
generated
vendored
@@ -67,13 +67,23 @@ const (
|
||||
// A Transport internally caches connections to servers. It is safe
|
||||
// for concurrent use by multiple goroutines.
|
||||
type Transport struct {
|
||||
// DialTLS specifies an optional dial function for creating
|
||||
// TLS connections for requests.
|
||||
// DialTLSContext specifies an optional dial function with context for
|
||||
// creating TLS connections for requests.
|
||||
//
|
||||
// If DialTLS is nil, tls.Dial is used.
|
||||
// If DialTLSContext and DialTLS is nil, tls.Dial is used.
|
||||
//
|
||||
// If the returned net.Conn has a ConnectionState method like tls.Conn,
|
||||
// it will be used to set http.Response.TLS.
|
||||
DialTLSContext func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error)
|
||||
|
||||
// DialTLS specifies an optional dial function for creating
|
||||
// TLS connections for requests.
|
||||
//
|
||||
// If DialTLSContext and DialTLS is nil, tls.Dial is used.
|
||||
//
|
||||
// Deprecated: Use DialTLSContext instead, which allows the transport
|
||||
// to cancel dials as soon as they are no longer needed.
|
||||
// If both are set, DialTLSContext takes priority.
|
||||
DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error)
|
||||
|
||||
// TLSClientConfig specifies the TLS configuration to use with
|
||||
@@ -592,7 +602,7 @@ func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse b
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tconn, err := t.dialTLS(ctx)("tcp", addr, t.newTLSConfig(host))
|
||||
tconn, err := t.dialTLS(ctx, "tcp", addr, t.newTLSConfig(host))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -613,24 +623,25 @@ func (t *Transport) newTLSConfig(host string) *tls.Config {
|
||||
return cfg
|
||||
}
|
||||
|
||||
func (t *Transport) dialTLS(ctx context.Context) func(string, string, *tls.Config) (net.Conn, error) {
|
||||
if t.DialTLS != nil {
|
||||
return t.DialTLS
|
||||
func (t *Transport) dialTLS(ctx context.Context, network, addr string, tlsCfg *tls.Config) (net.Conn, error) {
|
||||
if t.DialTLSContext != nil {
|
||||
return t.DialTLSContext(ctx, network, addr, tlsCfg)
|
||||
} else if t.DialTLS != nil {
|
||||
return t.DialTLS(network, addr, tlsCfg)
|
||||
}
|
||||
return func(network, addr string, cfg *tls.Config) (net.Conn, error) {
|
||||
tlsCn, err := t.dialTLSWithContext(ctx, network, addr, cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
state := tlsCn.ConnectionState()
|
||||
if p := state.NegotiatedProtocol; p != NextProtoTLS {
|
||||
return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, NextProtoTLS)
|
||||
}
|
||||
if !state.NegotiatedProtocolIsMutual {
|
||||
return nil, errors.New("http2: could not negotiate protocol mutually")
|
||||
}
|
||||
return tlsCn, nil
|
||||
|
||||
tlsCn, err := t.dialTLSWithContext(ctx, network, addr, tlsCfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
state := tlsCn.ConnectionState()
|
||||
if p := state.NegotiatedProtocol; p != NextProtoTLS {
|
||||
return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, NextProtoTLS)
|
||||
}
|
||||
if !state.NegotiatedProtocolIsMutual {
|
||||
return nil, errors.New("http2: could not negotiate protocol mutually")
|
||||
}
|
||||
return tlsCn, nil
|
||||
}
|
||||
|
||||
// disableKeepAlives reports whether connections should be closed as
|
||||
|
59
vendor/golang.org/x/net/icmp/dstunreach.go
generated
vendored
Normal file
59
vendor/golang.org/x/net/icmp/dstunreach.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// 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 (
|
||||
"golang.org/x/net/internal/iana"
|
||||
"golang.org/x/net/ipv4"
|
||||
"golang.org/x/net/ipv6"
|
||||
)
|
||||
|
||||
// A DstUnreach represents an ICMP destination unreachable message
|
||||
// body.
|
||||
type DstUnreach struct {
|
||||
Data []byte // data, known as original datagram field
|
||||
Extensions []Extension // extensions
|
||||
}
|
||||
|
||||
// Len implements the Len method of MessageBody interface.
|
||||
func (p *DstUnreach) Len(proto int) int {
|
||||
if p == nil {
|
||||
return 0
|
||||
}
|
||||
l, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions)
|
||||
return l
|
||||
}
|
||||
|
||||
// Marshal implements the Marshal method of MessageBody interface.
|
||||
func (p *DstUnreach) Marshal(proto int) ([]byte, error) {
|
||||
var typ Type
|
||||
switch proto {
|
||||
case iana.ProtocolICMP:
|
||||
typ = ipv4.ICMPTypeDestinationUnreachable
|
||||
case iana.ProtocolIPv6ICMP:
|
||||
typ = ipv6.ICMPTypeDestinationUnreachable
|
||||
default:
|
||||
return nil, errInvalidProtocol
|
||||
}
|
||||
if !validExtensions(typ, p.Extensions) {
|
||||
return nil, errInvalidExtension
|
||||
}
|
||||
return marshalMultipartMessageBody(proto, true, p.Data, p.Extensions)
|
||||
}
|
||||
|
||||
// parseDstUnreach parses b as an ICMP destination unreachable message
|
||||
// body.
|
||||
func parseDstUnreach(proto int, typ Type, b []byte) (MessageBody, error) {
|
||||
if len(b) < 4 {
|
||||
return nil, errMessageTooShort
|
||||
}
|
||||
p := &DstUnreach{}
|
||||
var err error
|
||||
p.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
173
vendor/golang.org/x/net/icmp/echo.go
generated
vendored
Normal file
173
vendor/golang.org/x/net/icmp/echo.go
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
// 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"
|
||||
|
||||
"golang.org/x/net/internal/iana"
|
||||
"golang.org/x/net/ipv4"
|
||||
"golang.org/x/net/ipv6"
|
||||
)
|
||||
|
||||
// An Echo represents an ICMP echo request or reply message body.
|
||||
type Echo struct {
|
||||
ID int // identifier
|
||||
Seq int // sequence number
|
||||
Data []byte // data
|
||||
}
|
||||
|
||||
// Len implements the Len method of MessageBody interface.
|
||||
func (p *Echo) Len(proto int) int {
|
||||
if p == nil {
|
||||
return 0
|
||||
}
|
||||
return 4 + len(p.Data)
|
||||
}
|
||||
|
||||
// Marshal implements the Marshal method of MessageBody interface.
|
||||
func (p *Echo) Marshal(proto int) ([]byte, error) {
|
||||
b := make([]byte, 4+len(p.Data))
|
||||
binary.BigEndian.PutUint16(b[:2], uint16(p.ID))
|
||||
binary.BigEndian.PutUint16(b[2:4], uint16(p.Seq))
|
||||
copy(b[4:], p.Data)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// parseEcho parses b as an ICMP echo request or reply message body.
|
||||
func parseEcho(proto int, _ Type, b []byte) (MessageBody, error) {
|
||||
bodyLen := len(b)
|
||||
if bodyLen < 4 {
|
||||
return nil, errMessageTooShort
|
||||
}
|
||||
p := &Echo{ID: int(binary.BigEndian.Uint16(b[:2])), Seq: int(binary.BigEndian.Uint16(b[2:4]))}
|
||||
if bodyLen > 4 {
|
||||
p.Data = make([]byte, bodyLen-4)
|
||||
copy(p.Data, b[4:])
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// An ExtendedEchoRequest represents an ICMP extended echo request
|
||||
// message body.
|
||||
type ExtendedEchoRequest struct {
|
||||
ID int // identifier
|
||||
Seq int // sequence number
|
||||
Local bool // must be true when identifying by name or index
|
||||
Extensions []Extension // extensions
|
||||
}
|
||||
|
||||
// Len implements the Len method of MessageBody interface.
|
||||
func (p *ExtendedEchoRequest) Len(proto int) int {
|
||||
if p == nil {
|
||||
return 0
|
||||
}
|
||||
l, _ := multipartMessageBodyDataLen(proto, false, nil, p.Extensions)
|
||||
return l
|
||||
}
|
||||
|
||||
// Marshal implements the Marshal method of MessageBody interface.
|
||||
func (p *ExtendedEchoRequest) Marshal(proto int) ([]byte, error) {
|
||||
var typ Type
|
||||
switch proto {
|
||||
case iana.ProtocolICMP:
|
||||
typ = ipv4.ICMPTypeExtendedEchoRequest
|
||||
case iana.ProtocolIPv6ICMP:
|
||||
typ = ipv6.ICMPTypeExtendedEchoRequest
|
||||
default:
|
||||
return nil, errInvalidProtocol
|
||||
}
|
||||
if !validExtensions(typ, p.Extensions) {
|
||||
return nil, errInvalidExtension
|
||||
}
|
||||
b, err := marshalMultipartMessageBody(proto, false, nil, p.Extensions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
binary.BigEndian.PutUint16(b[:2], uint16(p.ID))
|
||||
b[2] = byte(p.Seq)
|
||||
if p.Local {
|
||||
b[3] |= 0x01
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// parseExtendedEchoRequest parses b as an ICMP extended echo request
|
||||
// message body.
|
||||
func parseExtendedEchoRequest(proto int, typ Type, b []byte) (MessageBody, error) {
|
||||
if len(b) < 4 {
|
||||
return nil, errMessageTooShort
|
||||
}
|
||||
p := &ExtendedEchoRequest{ID: int(binary.BigEndian.Uint16(b[:2])), Seq: int(b[2])}
|
||||
if b[3]&0x01 != 0 {
|
||||
p.Local = true
|
||||
}
|
||||
var err error
|
||||
_, p.Extensions, err = parseMultipartMessageBody(proto, typ, b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// An ExtendedEchoReply represents an ICMP extended echo reply message
|
||||
// body.
|
||||
type ExtendedEchoReply struct {
|
||||
ID int // identifier
|
||||
Seq int // sequence number
|
||||
State int // 3-bit state working together with Message.Code
|
||||
Active bool // probed interface is active
|
||||
IPv4 bool // probed interface runs IPv4
|
||||
IPv6 bool // probed interface runs IPv6
|
||||
}
|
||||
|
||||
// Len implements the Len method of MessageBody interface.
|
||||
func (p *ExtendedEchoReply) Len(proto int) int {
|
||||
if p == nil {
|
||||
return 0
|
||||
}
|
||||
return 4
|
||||
}
|
||||
|
||||
// Marshal implements the Marshal method of MessageBody interface.
|
||||
func (p *ExtendedEchoReply) Marshal(proto int) ([]byte, error) {
|
||||
b := make([]byte, 4)
|
||||
binary.BigEndian.PutUint16(b[:2], uint16(p.ID))
|
||||
b[2] = byte(p.Seq)
|
||||
b[3] = byte(p.State<<5) & 0xe0
|
||||
if p.Active {
|
||||
b[3] |= 0x04
|
||||
}
|
||||
if p.IPv4 {
|
||||
b[3] |= 0x02
|
||||
}
|
||||
if p.IPv6 {
|
||||
b[3] |= 0x01
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// parseExtendedEchoReply parses b as an ICMP extended echo reply
|
||||
// message body.
|
||||
func parseExtendedEchoReply(proto int, _ Type, b []byte) (MessageBody, error) {
|
||||
if len(b) < 4 {
|
||||
return nil, errMessageTooShort
|
||||
}
|
||||
p := &ExtendedEchoReply{
|
||||
ID: int(binary.BigEndian.Uint16(b[:2])),
|
||||
Seq: int(b[2]),
|
||||
State: int(b[3]) >> 5,
|
||||
}
|
||||
if b[3]&0x04 != 0 {
|
||||
p.Active = true
|
||||
}
|
||||
if b[3]&0x02 != 0 {
|
||||
p.IPv4 = true
|
||||
}
|
||||
if b[3]&0x01 != 0 {
|
||||
p.IPv6 = true
|
||||
}
|
||||
return p, nil
|
||||
}
|
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"
|
||||
"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, errInvalidConn
|
||||
}
|
||||
// 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" || runtime.GOOS == "ios") && 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.
|
||||
// The provided 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, errInvalidConn
|
||||
}
|
||||
return c.c.WriteTo(b, dst)
|
||||
}
|
||||
|
||||
// Close closes the endpoint.
|
||||
func (c *PacketConn) Close() error {
|
||||
if !c.ok() {
|
||||
return errInvalidConn
|
||||
}
|
||||
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 errInvalidConn
|
||||
}
|
||||
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 errInvalidConn
|
||||
}
|
||||
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 errInvalidConn
|
||||
}
|
||||
return c.c.SetWriteDeadline(t)
|
||||
}
|
170
vendor/golang.org/x/net/icmp/extension.go
generated
vendored
Normal file
170
vendor/golang.org/x/net/icmp/extension.go
generated
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package icmp
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"golang.org/x/net/ipv4"
|
||||
"golang.org/x/net/ipv6"
|
||||
)
|
||||
|
||||
// An Extension represents an ICMP extension.
|
||||
type Extension interface {
|
||||
// Len returns the length of ICMP extension.
|
||||
// The provided proto must be either the ICMPv4 or ICMPv6
|
||||
// protocol number.
|
||||
Len(proto int) int
|
||||
|
||||
// Marshal returns the binary encoding of ICMP extension.
|
||||
// The provided proto must be either the ICMPv4 or ICMPv6
|
||||
// protocol number.
|
||||
Marshal(proto int) ([]byte, error)
|
||||
}
|
||||
|
||||
const extensionVersion = 2
|
||||
|
||||
func validExtensionHeader(b []byte) bool {
|
||||
v := int(b[0]&0xf0) >> 4
|
||||
s := binary.BigEndian.Uint16(b[2:4])
|
||||
if s != 0 {
|
||||
s = checksum(b)
|
||||
}
|
||||
if v != extensionVersion || s != 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// parseExtensions parses b as a list of ICMP extensions.
|
||||
// The length attribute l must be the length attribute field in
|
||||
// received icmp messages.
|
||||
//
|
||||
// It will return a list of ICMP extensions and an adjusted length
|
||||
// attribute that represents the length of the padded original
|
||||
// datagram field. Otherwise, it returns an error.
|
||||
func parseExtensions(typ Type, b []byte, l int) ([]Extension, int, error) {
|
||||
// Still a lot of non-RFC 4884 compliant implementations are
|
||||
// out there. Set the length attribute l to 128 when it looks
|
||||
// inappropriate for backwards compatibility.
|
||||
//
|
||||
// A minimal extension at least requires 8 octets; 4 octets
|
||||
// for an extension header, and 4 octets for a single object
|
||||
// header.
|
||||
//
|
||||
// See RFC 4884 for further information.
|
||||
switch typ {
|
||||
case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
|
||||
if len(b) < 8 || !validExtensionHeader(b) {
|
||||
return nil, -1, errNoExtension
|
||||
}
|
||||
l = 0
|
||||
default:
|
||||
if 128 > l || l+8 > len(b) {
|
||||
l = 128
|
||||
}
|
||||
if l+8 > len(b) {
|
||||
return nil, -1, errNoExtension
|
||||
}
|
||||
if !validExtensionHeader(b[l:]) {
|
||||
if l == 128 {
|
||||
return nil, -1, errNoExtension
|
||||
}
|
||||
l = 128
|
||||
if !validExtensionHeader(b[l:]) {
|
||||
return nil, -1, errNoExtension
|
||||
}
|
||||
}
|
||||
}
|
||||
var exts []Extension
|
||||
for b = b[l+4:]; len(b) >= 4; {
|
||||
ol := int(binary.BigEndian.Uint16(b[:2]))
|
||||
if 4 > ol || ol > len(b) {
|
||||
break
|
||||
}
|
||||
switch b[2] {
|
||||
case classMPLSLabelStack:
|
||||
ext, err := parseMPLSLabelStack(b[:ol])
|
||||
if err != nil {
|
||||
return nil, -1, err
|
||||
}
|
||||
exts = append(exts, ext)
|
||||
case classInterfaceInfo:
|
||||
ext, err := parseInterfaceInfo(b[:ol])
|
||||
if err != nil {
|
||||
return nil, -1, err
|
||||
}
|
||||
exts = append(exts, ext)
|
||||
case classInterfaceIdent:
|
||||
ext, err := parseInterfaceIdent(b[:ol])
|
||||
if err != nil {
|
||||
return nil, -1, err
|
||||
}
|
||||
exts = append(exts, ext)
|
||||
default:
|
||||
ext := &RawExtension{Data: make([]byte, ol)}
|
||||
copy(ext.Data, b[:ol])
|
||||
exts = append(exts, ext)
|
||||
}
|
||||
b = b[ol:]
|
||||
}
|
||||
return exts, l, nil
|
||||
}
|
||||
|
||||
func validExtensions(typ Type, exts []Extension) bool {
|
||||
switch typ {
|
||||
case ipv4.ICMPTypeDestinationUnreachable, ipv4.ICMPTypeTimeExceeded, ipv4.ICMPTypeParameterProblem,
|
||||
ipv6.ICMPTypeDestinationUnreachable, ipv6.ICMPTypeTimeExceeded:
|
||||
for i := range exts {
|
||||
switch exts[i].(type) {
|
||||
case *MPLSLabelStack, *InterfaceInfo, *RawExtension:
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
|
||||
var n int
|
||||
for i := range exts {
|
||||
switch exts[i].(type) {
|
||||
case *InterfaceIdent:
|
||||
n++
|
||||
case *RawExtension:
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
// Not a single InterfaceIdent object or a combo of
|
||||
// RawExtension and InterfaceIdent objects is not
|
||||
// allowed.
|
||||
if n == 1 && len(exts) > 1 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// A RawExtension represents a raw extension.
|
||||
//
|
||||
// A raw extension is excluded from message processing and can be used
|
||||
// to construct applications such as protocol conformance testing.
|
||||
type RawExtension struct {
|
||||
Data []byte // data
|
||||
}
|
||||
|
||||
// Len implements the Len method of Extension interface.
|
||||
func (p *RawExtension) Len(proto int) int {
|
||||
if p == nil {
|
||||
return 0
|
||||
}
|
||||
return len(p.Data)
|
||||
}
|
||||
|
||||
// Marshal implements the Marshal method of Extension interface.
|
||||
func (p *RawExtension) Marshal(proto int) ([]byte, error) {
|
||||
return p.Data, nil
|
||||
}
|
76
vendor/golang.org/x/net/icmp/helper_posix.go
generated
vendored
Normal file
76
vendor/golang.org/x/net/icmp/helper_posix.go
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
// 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.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
|
||||
// +build aix 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
|
||||
}
|
322
vendor/golang.org/x/net/icmp/interface.go
generated
vendored
Normal file
322
vendor/golang.org/x/net/icmp/interface.go
generated
vendored
Normal file
@@ -0,0 +1,322 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package icmp
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/internal/iana"
|
||||
)
|
||||
|
||||
const (
|
||||
classInterfaceInfo = 2
|
||||
)
|
||||
|
||||
const (
|
||||
attrMTU = 1 << iota
|
||||
attrName
|
||||
attrIPAddr
|
||||
attrIfIndex
|
||||
)
|
||||
|
||||
// An InterfaceInfo represents interface and next-hop identification.
|
||||
type InterfaceInfo struct {
|
||||
Class int // extension object class number
|
||||
Type int // extension object sub-type
|
||||
Interface *net.Interface
|
||||
Addr *net.IPAddr
|
||||
}
|
||||
|
||||
func (ifi *InterfaceInfo) nameLen() int {
|
||||
if len(ifi.Interface.Name) > 63 {
|
||||
return 64
|
||||
}
|
||||
l := 1 + len(ifi.Interface.Name)
|
||||
return (l + 3) &^ 3
|
||||
}
|
||||
|
||||
func (ifi *InterfaceInfo) attrsAndLen(proto int) (attrs, l int) {
|
||||
l = 4
|
||||
if ifi.Interface != nil && ifi.Interface.Index > 0 {
|
||||
attrs |= attrIfIndex
|
||||
l += 4
|
||||
if len(ifi.Interface.Name) > 0 {
|
||||
attrs |= attrName
|
||||
l += ifi.nameLen()
|
||||
}
|
||||
if ifi.Interface.MTU > 0 {
|
||||
attrs |= attrMTU
|
||||
l += 4
|
||||
}
|
||||
}
|
||||
if ifi.Addr != nil {
|
||||
switch proto {
|
||||
case iana.ProtocolICMP:
|
||||
if ifi.Addr.IP.To4() != nil {
|
||||
attrs |= attrIPAddr
|
||||
l += 4 + net.IPv4len
|
||||
}
|
||||
case iana.ProtocolIPv6ICMP:
|
||||
if ifi.Addr.IP.To16() != nil && ifi.Addr.IP.To4() == nil {
|
||||
attrs |= attrIPAddr
|
||||
l += 4 + net.IPv6len
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Len implements the Len method of Extension interface.
|
||||
func (ifi *InterfaceInfo) Len(proto int) int {
|
||||
_, l := ifi.attrsAndLen(proto)
|
||||
return l
|
||||
}
|
||||
|
||||
// Marshal implements the Marshal method of Extension interface.
|
||||
func (ifi *InterfaceInfo) Marshal(proto int) ([]byte, error) {
|
||||
attrs, l := ifi.attrsAndLen(proto)
|
||||
b := make([]byte, l)
|
||||
if err := ifi.marshal(proto, b, attrs, l); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (ifi *InterfaceInfo) marshal(proto int, b []byte, attrs, l int) error {
|
||||
binary.BigEndian.PutUint16(b[:2], uint16(l))
|
||||
b[2], b[3] = classInterfaceInfo, byte(ifi.Type)
|
||||
for b = b[4:]; len(b) > 0 && attrs != 0; {
|
||||
switch {
|
||||
case attrs&attrIfIndex != 0:
|
||||
b = ifi.marshalIfIndex(proto, b)
|
||||
attrs &^= attrIfIndex
|
||||
case attrs&attrIPAddr != 0:
|
||||
b = ifi.marshalIPAddr(proto, b)
|
||||
attrs &^= attrIPAddr
|
||||
case attrs&attrName != 0:
|
||||
b = ifi.marshalName(proto, b)
|
||||
attrs &^= attrName
|
||||
case attrs&attrMTU != 0:
|
||||
b = ifi.marshalMTU(proto, b)
|
||||
attrs &^= attrMTU
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ifi *InterfaceInfo) marshalIfIndex(proto int, b []byte) []byte {
|
||||
binary.BigEndian.PutUint32(b[:4], uint32(ifi.Interface.Index))
|
||||
return b[4:]
|
||||
}
|
||||
|
||||
func (ifi *InterfaceInfo) parseIfIndex(b []byte) ([]byte, error) {
|
||||
if len(b) < 4 {
|
||||
return nil, errMessageTooShort
|
||||
}
|
||||
ifi.Interface.Index = int(binary.BigEndian.Uint32(b[:4]))
|
||||
return b[4:], nil
|
||||
}
|
||||
|
||||
func (ifi *InterfaceInfo) marshalIPAddr(proto int, b []byte) []byte {
|
||||
switch proto {
|
||||
case iana.ProtocolICMP:
|
||||
binary.BigEndian.PutUint16(b[:2], uint16(iana.AddrFamilyIPv4))
|
||||
copy(b[4:4+net.IPv4len], ifi.Addr.IP.To4())
|
||||
b = b[4+net.IPv4len:]
|
||||
case iana.ProtocolIPv6ICMP:
|
||||
binary.BigEndian.PutUint16(b[:2], uint16(iana.AddrFamilyIPv6))
|
||||
copy(b[4:4+net.IPv6len], ifi.Addr.IP.To16())
|
||||
b = b[4+net.IPv6len:]
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func (ifi *InterfaceInfo) parseIPAddr(b []byte) ([]byte, error) {
|
||||
if len(b) < 4 {
|
||||
return nil, errMessageTooShort
|
||||
}
|
||||
afi := int(binary.BigEndian.Uint16(b[:2]))
|
||||
b = b[4:]
|
||||
switch afi {
|
||||
case iana.AddrFamilyIPv4:
|
||||
if len(b) < net.IPv4len {
|
||||
return nil, errMessageTooShort
|
||||
}
|
||||
ifi.Addr.IP = make(net.IP, net.IPv4len)
|
||||
copy(ifi.Addr.IP, b[:net.IPv4len])
|
||||
b = b[net.IPv4len:]
|
||||
case iana.AddrFamilyIPv6:
|
||||
if len(b) < net.IPv6len {
|
||||
return nil, errMessageTooShort
|
||||
}
|
||||
ifi.Addr.IP = make(net.IP, net.IPv6len)
|
||||
copy(ifi.Addr.IP, b[:net.IPv6len])
|
||||
b = b[net.IPv6len:]
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (ifi *InterfaceInfo) marshalName(proto int, b []byte) []byte {
|
||||
l := byte(ifi.nameLen())
|
||||
b[0] = l
|
||||
copy(b[1:], []byte(ifi.Interface.Name))
|
||||
return b[l:]
|
||||
}
|
||||
|
||||
func (ifi *InterfaceInfo) parseName(b []byte) ([]byte, error) {
|
||||
if 4 > len(b) || len(b) < int(b[0]) {
|
||||
return nil, errMessageTooShort
|
||||
}
|
||||
l := int(b[0])
|
||||
if l%4 != 0 || 4 > l || l > 64 {
|
||||
return nil, errInvalidExtension
|
||||
}
|
||||
var name [63]byte
|
||||
copy(name[:], b[1:l])
|
||||
ifi.Interface.Name = strings.Trim(string(name[:]), "\000")
|
||||
return b[l:], nil
|
||||
}
|
||||
|
||||
func (ifi *InterfaceInfo) marshalMTU(proto int, b []byte) []byte {
|
||||
binary.BigEndian.PutUint32(b[:4], uint32(ifi.Interface.MTU))
|
||||
return b[4:]
|
||||
}
|
||||
|
||||
func (ifi *InterfaceInfo) parseMTU(b []byte) ([]byte, error) {
|
||||
if len(b) < 4 {
|
||||
return nil, errMessageTooShort
|
||||
}
|
||||
ifi.Interface.MTU = int(binary.BigEndian.Uint32(b[:4]))
|
||||
return b[4:], nil
|
||||
}
|
||||
|
||||
func parseInterfaceInfo(b []byte) (Extension, error) {
|
||||
ifi := &InterfaceInfo{
|
||||
Class: int(b[2]),
|
||||
Type: int(b[3]),
|
||||
}
|
||||
if ifi.Type&(attrIfIndex|attrName|attrMTU) != 0 {
|
||||
ifi.Interface = &net.Interface{}
|
||||
}
|
||||
if ifi.Type&attrIPAddr != 0 {
|
||||
ifi.Addr = &net.IPAddr{}
|
||||
}
|
||||
attrs := ifi.Type & (attrIfIndex | attrIPAddr | attrName | attrMTU)
|
||||
for b = b[4:]; len(b) > 0 && attrs != 0; {
|
||||
var err error
|
||||
switch {
|
||||
case attrs&attrIfIndex != 0:
|
||||
b, err = ifi.parseIfIndex(b)
|
||||
attrs &^= attrIfIndex
|
||||
case attrs&attrIPAddr != 0:
|
||||
b, err = ifi.parseIPAddr(b)
|
||||
attrs &^= attrIPAddr
|
||||
case attrs&attrName != 0:
|
||||
b, err = ifi.parseName(b)
|
||||
attrs &^= attrName
|
||||
case attrs&attrMTU != 0:
|
||||
b, err = ifi.parseMTU(b)
|
||||
attrs &^= attrMTU
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if ifi.Interface != nil && ifi.Interface.Name != "" && ifi.Addr != nil && ifi.Addr.IP.To16() != nil && ifi.Addr.IP.To4() == nil {
|
||||
ifi.Addr.Zone = ifi.Interface.Name
|
||||
}
|
||||
return ifi, nil
|
||||
}
|
||||
|
||||
const (
|
||||
classInterfaceIdent = 3
|
||||
typeInterfaceByName = 1
|
||||
typeInterfaceByIndex = 2
|
||||
typeInterfaceByAddress = 3
|
||||
)
|
||||
|
||||
// An InterfaceIdent represents interface identification.
|
||||
type InterfaceIdent struct {
|
||||
Class int // extension object class number
|
||||
Type int // extension object sub-type
|
||||
Name string // interface name
|
||||
Index int // interface index
|
||||
AFI int // address family identifier; see address family numbers in IANA registry
|
||||
Addr []byte // address
|
||||
}
|
||||
|
||||
// Len implements the Len method of Extension interface.
|
||||
func (ifi *InterfaceIdent) Len(_ int) int {
|
||||
switch ifi.Type {
|
||||
case typeInterfaceByName:
|
||||
l := len(ifi.Name)
|
||||
if l > 255 {
|
||||
l = 255
|
||||
}
|
||||
return 4 + (l+3)&^3
|
||||
case typeInterfaceByIndex:
|
||||
return 4 + 4
|
||||
case typeInterfaceByAddress:
|
||||
return 4 + 4 + (len(ifi.Addr)+3)&^3
|
||||
default:
|
||||
return 4
|
||||
}
|
||||
}
|
||||
|
||||
// Marshal implements the Marshal method of Extension interface.
|
||||
func (ifi *InterfaceIdent) Marshal(proto int) ([]byte, error) {
|
||||
b := make([]byte, ifi.Len(proto))
|
||||
if err := ifi.marshal(proto, b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (ifi *InterfaceIdent) marshal(proto int, b []byte) error {
|
||||
l := ifi.Len(proto)
|
||||
binary.BigEndian.PutUint16(b[:2], uint16(l))
|
||||
b[2], b[3] = classInterfaceIdent, byte(ifi.Type)
|
||||
switch ifi.Type {
|
||||
case typeInterfaceByName:
|
||||
copy(b[4:], ifi.Name)
|
||||
case typeInterfaceByIndex:
|
||||
binary.BigEndian.PutUint32(b[4:4+4], uint32(ifi.Index))
|
||||
case typeInterfaceByAddress:
|
||||
binary.BigEndian.PutUint16(b[4:4+2], uint16(ifi.AFI))
|
||||
b[4+2] = byte(len(ifi.Addr))
|
||||
copy(b[4+4:], ifi.Addr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseInterfaceIdent(b []byte) (Extension, error) {
|
||||
ifi := &InterfaceIdent{
|
||||
Class: int(b[2]),
|
||||
Type: int(b[3]),
|
||||
}
|
||||
switch ifi.Type {
|
||||
case typeInterfaceByName:
|
||||
ifi.Name = strings.Trim(string(b[4:]), "\x00")
|
||||
case typeInterfaceByIndex:
|
||||
if len(b[4:]) < 4 {
|
||||
return nil, errInvalidExtension
|
||||
}
|
||||
ifi.Index = int(binary.BigEndian.Uint32(b[4 : 4+4]))
|
||||
case typeInterfaceByAddress:
|
||||
if len(b[4:]) < 4 {
|
||||
return nil, errInvalidExtension
|
||||
}
|
||||
ifi.AFI = int(binary.BigEndian.Uint16(b[4 : 4+2]))
|
||||
l := int(b[4+2])
|
||||
if len(b[4+4:]) < l {
|
||||
return nil, errInvalidExtension
|
||||
}
|
||||
ifi.Addr = make([]byte, l)
|
||||
copy(ifi.Addr, b[4+4:])
|
||||
}
|
||||
return ifi, nil
|
||||
}
|
69
vendor/golang.org/x/net/icmp/ipv4.go
generated
vendored
Normal file
69
vendor/golang.org/x/net/icmp/ipv4.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package icmp
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"net"
|
||||
"runtime"
|
||||
|
||||
"golang.org/x/net/internal/socket"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
// freebsdVersion is set in sys_freebsd.go.
|
||||
// See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
|
||||
var freebsdVersion uint32
|
||||
|
||||
// ParseIPv4Header returns the IPv4 header of the IPv4 packet that
|
||||
// triggered an ICMP error message.
|
||||
// This is found in the Data field of the ICMP error message body.
|
||||
//
|
||||
// The provided b must be in the format used by a raw ICMP socket on
|
||||
// the local system.
|
||||
// This may differ from the wire format, and the format used by a raw
|
||||
// IP socket, depending on the system.
|
||||
//
|
||||
// To parse an IPv6 header, use ipv6.ParseHeader.
|
||||
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", "ios":
|
||||
h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))
|
||||
case "freebsd":
|
||||
if freebsdVersion >= 1000000 {
|
||||
h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
|
||||
} else {
|
||||
h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))
|
||||
}
|
||||
default:
|
||||
h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
|
||||
}
|
||||
h.Flags = ipv4.HeaderFlags(h.FragOff&0xe000) >> 13
|
||||
h.FragOff = h.FragOff & 0x1fff
|
||||
if hdrlen-ipv4.HeaderLen > 0 {
|
||||
h.Options = make([]byte, hdrlen-ipv4.HeaderLen)
|
||||
copy(h.Options, b[ipv4.HeaderLen:])
|
||||
}
|
||||
return h, nil
|
||||
}
|
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
|
||||
}
|
106
vendor/golang.org/x/net/icmp/listen_posix.go
generated
vendored
Normal file
106
vendor/golang.org/x/net/icmp/listen_posix.go
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
// 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.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
|
||||
// +build aix 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, ':')
|
||||
if i < 0 {
|
||||
i = len(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" || runtime.GOOS == "ios") && 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
|
||||
}
|
||||
}
|
36
vendor/golang.org/x/net/icmp/listen_stub.go
generated
vendored
Normal file
36
vendor/golang.org/x/net/icmp/listen_stub.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// 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.
|
||||
|
||||
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows
|
||||
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
|
||||
|
||||
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, errNotImplemented
|
||||
}
|
162
vendor/golang.org/x/net/icmp/message.go
generated
vendored
Normal file
162
vendor/golang.org/x/net/icmp/message.go
generated
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package icmp provides basic functions for the manipulation of
|
||||
// messages used in the Internet Control Message Protocols,
|
||||
// ICMPv4 and ICMPv6.
|
||||
//
|
||||
// ICMPv4 and ICMPv6 are defined in RFC 792 and RFC 4443.
|
||||
// Multi-part message support for ICMP is defined in RFC 4884.
|
||||
// ICMP extensions for MPLS are defined in RFC 4950.
|
||||
// ICMP extensions for interface and next-hop identification are
|
||||
// defined in RFC 5837.
|
||||
// PROBE: A utility for probing interfaces is defined in RFC 8335.
|
||||
package icmp // import "golang.org/x/net/icmp"
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"net"
|
||||
"runtime"
|
||||
|
||||
"golang.org/x/net/internal/iana"
|
||||
"golang.org/x/net/ipv4"
|
||||
"golang.org/x/net/ipv6"
|
||||
)
|
||||
|
||||
// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9.
|
||||
|
||||
var (
|
||||
errInvalidConn = errors.New("invalid connection")
|
||||
errInvalidProtocol = errors.New("invalid protocol")
|
||||
errMessageTooShort = errors.New("message too short")
|
||||
errHeaderTooShort = errors.New("header too short")
|
||||
errBufferTooShort = errors.New("buffer too short")
|
||||
errInvalidBody = errors.New("invalid body")
|
||||
errNoExtension = errors.New("no extension")
|
||||
errInvalidExtension = errors.New("invalid extension")
|
||||
errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
|
||||
)
|
||||
|
||||
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 byte
|
||||
switch typ := m.Type.(type) {
|
||||
case ipv4.ICMPType:
|
||||
mtype = byte(typ)
|
||||
case ipv6.ICMPType:
|
||||
mtype = byte(typ)
|
||||
default:
|
||||
return nil, errInvalidProtocol
|
||||
}
|
||||
b := []byte{mtype, byte(m.Code), 0, 0}
|
||||
proto := m.Type.Protocol()
|
||||
if proto == iana.ProtocolIPv6ICMP && psh != nil {
|
||||
b = append(psh, b...)
|
||||
}
|
||||
if m.Body != nil && m.Body.Len(proto) != 0 {
|
||||
mb, err := m.Body.Marshal(proto)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = append(b, mb...)
|
||||
}
|
||||
if proto == iana.ProtocolIPv6ICMP {
|
||||
if psh == nil { // cannot calculate checksum here
|
||||
return b, nil
|
||||
}
|
||||
off, l := 2*net.IPv6len, len(b)-len(psh)
|
||||
binary.BigEndian.PutUint32(b[off:off+4], uint32(l))
|
||||
}
|
||||
s := checksum(b)
|
||||
// Place checksum back in header; using ^= avoids the
|
||||
// assumption the checksum bytes are zero.
|
||||
b[len(psh)+2] ^= byte(s)
|
||||
b[len(psh)+3] ^= byte(s >> 8)
|
||||
return b[len(psh):], nil
|
||||
}
|
||||
|
||||
var parseFns = map[Type]func(int, Type, []byte) (MessageBody, error){
|
||||
ipv4.ICMPTypeDestinationUnreachable: parseDstUnreach,
|
||||
ipv4.ICMPTypeTimeExceeded: parseTimeExceeded,
|
||||
ipv4.ICMPTypeParameterProblem: parseParamProb,
|
||||
|
||||
ipv4.ICMPTypeEcho: parseEcho,
|
||||
ipv4.ICMPTypeEchoReply: parseEcho,
|
||||
ipv4.ICMPTypeExtendedEchoRequest: parseExtendedEchoRequest,
|
||||
ipv4.ICMPTypeExtendedEchoReply: parseExtendedEchoReply,
|
||||
|
||||
ipv6.ICMPTypeDestinationUnreachable: parseDstUnreach,
|
||||
ipv6.ICMPTypePacketTooBig: parsePacketTooBig,
|
||||
ipv6.ICMPTypeTimeExceeded: parseTimeExceeded,
|
||||
ipv6.ICMPTypeParameterProblem: parseParamProb,
|
||||
|
||||
ipv6.ICMPTypeEchoRequest: parseEcho,
|
||||
ipv6.ICMPTypeEchoReply: parseEcho,
|
||||
ipv6.ICMPTypeExtendedEchoRequest: parseExtendedEchoRequest,
|
||||
ipv6.ICMPTypeExtendedEchoReply: parseExtendedEchoReply,
|
||||
}
|
||||
|
||||
// ParseMessage parses b as an ICMP message.
|
||||
// The provided 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, errInvalidProtocol
|
||||
}
|
||||
if fn, ok := parseFns[m.Type]; !ok {
|
||||
m.Body, err = parseRawBody(proto, b[4:])
|
||||
} else {
|
||||
m.Body, err = fn(proto, m.Type, b[4:])
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
52
vendor/golang.org/x/net/icmp/messagebody.go
generated
vendored
Normal file
52
vendor/golang.org/x/net/icmp/messagebody.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
// 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.
|
||||
// The provided proto must be either the ICMPv4 or ICMPv6
|
||||
// protocol number.
|
||||
Len(proto int) int
|
||||
|
||||
// Marshal returns the binary encoding of ICMP message body.
|
||||
// The provided proto must be either the ICMPv4 or ICMPv6
|
||||
// protocol number.
|
||||
Marshal(proto int) ([]byte, error)
|
||||
}
|
||||
|
||||
// A RawBody represents a raw message body.
|
||||
//
|
||||
// A raw message body is excluded from message processing and can be
|
||||
// used to construct applications such as protocol conformance
|
||||
// testing.
|
||||
type RawBody struct {
|
||||
Data []byte // data
|
||||
}
|
||||
|
||||
// Len implements the Len method of MessageBody interface.
|
||||
func (p *RawBody) Len(proto int) int {
|
||||
if p == nil {
|
||||
return 0
|
||||
}
|
||||
return len(p.Data)
|
||||
}
|
||||
|
||||
// Marshal implements the Marshal method of MessageBody interface.
|
||||
func (p *RawBody) Marshal(proto int) ([]byte, error) {
|
||||
return p.Data, nil
|
||||
}
|
||||
|
||||
// parseRawBody parses b as an ICMP message body.
|
||||
func parseRawBody(proto int, b []byte) (MessageBody, error) {
|
||||
p := &RawBody{Data: make([]byte, len(b))}
|
||||
copy(p.Data, b)
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// A DefaultMessageBody represents the default message body.
|
||||
//
|
||||
// Deprecated: Use RawBody instead.
|
||||
type DefaultMessageBody = RawBody
|
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"
|
||||
|
||||
// MPLSLabel represents an 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
|
||||
)
|
||||
|
||||
// MPLSLabelStack represents an 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
|
||||
}
|
129
vendor/golang.org/x/net/icmp/multipart.go
generated
vendored
Normal file
129
vendor/golang.org/x/net/icmp/multipart.go
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package icmp
|
||||
|
||||
import "golang.org/x/net/internal/iana"
|
||||
|
||||
// multipartMessageBodyDataLen takes b as an original datagram and
|
||||
// exts as extensions, and returns a required length for message body
|
||||
// and a required length for a padded original datagram in wire
|
||||
// format.
|
||||
func multipartMessageBodyDataLen(proto int, withOrigDgram bool, b []byte, exts []Extension) (bodyLen, dataLen int) {
|
||||
bodyLen = 4 // length of leading octets
|
||||
var extLen int
|
||||
var rawExt bool // raw extension may contain an empty object
|
||||
for _, ext := range exts {
|
||||
extLen += ext.Len(proto)
|
||||
if _, ok := ext.(*RawExtension); ok {
|
||||
rawExt = true
|
||||
}
|
||||
}
|
||||
if extLen > 0 && withOrigDgram {
|
||||
dataLen = multipartMessageOrigDatagramLen(proto, b)
|
||||
} else {
|
||||
dataLen = len(b)
|
||||
}
|
||||
if extLen > 0 || rawExt {
|
||||
bodyLen += 4 // length of extension header
|
||||
}
|
||||
bodyLen += dataLen + extLen
|
||||
return bodyLen, dataLen
|
||||
}
|
||||
|
||||
// multipartMessageOrigDatagramLen takes b as an original datagram,
|
||||
// and returns a required length for a padded orignal datagram in wire
|
||||
// format.
|
||||
func multipartMessageOrigDatagramLen(proto int, b []byte) int {
|
||||
roundup := func(b []byte, align int) int {
|
||||
// According to RFC 4884, the padded original datagram
|
||||
// field must contain at least 128 octets.
|
||||
if len(b) < 128 {
|
||||
return 128
|
||||
}
|
||||
r := len(b)
|
||||
return (r + align - 1) &^ (align - 1)
|
||||
}
|
||||
switch proto {
|
||||
case iana.ProtocolICMP:
|
||||
return roundup(b, 4)
|
||||
case iana.ProtocolIPv6ICMP:
|
||||
return roundup(b, 8)
|
||||
default:
|
||||
return len(b)
|
||||
}
|
||||
}
|
||||
|
||||
// marshalMultipartMessageBody takes data as an original datagram and
|
||||
// exts as extesnsions, and returns a binary encoding of message body.
|
||||
// It can be used for non-multipart message bodies when exts is nil.
|
||||
func marshalMultipartMessageBody(proto int, withOrigDgram bool, data []byte, exts []Extension) ([]byte, error) {
|
||||
bodyLen, dataLen := multipartMessageBodyDataLen(proto, withOrigDgram, data, exts)
|
||||
b := make([]byte, bodyLen)
|
||||
copy(b[4:], data)
|
||||
if len(exts) > 0 {
|
||||
b[4+dataLen] = byte(extensionVersion << 4)
|
||||
off := 4 + dataLen + 4 // leading octets, data, extension header
|
||||
for _, ext := range exts {
|
||||
switch ext := ext.(type) {
|
||||
case *MPLSLabelStack:
|
||||
if err := ext.marshal(proto, b[off:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
off += ext.Len(proto)
|
||||
case *InterfaceInfo:
|
||||
attrs, l := ext.attrsAndLen(proto)
|
||||
if err := ext.marshal(proto, b[off:], attrs, l); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
off += ext.Len(proto)
|
||||
case *InterfaceIdent:
|
||||
if err := ext.marshal(proto, b[off:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
off += ext.Len(proto)
|
||||
case *RawExtension:
|
||||
copy(b[off:], ext.Data)
|
||||
off += ext.Len(proto)
|
||||
}
|
||||
}
|
||||
s := checksum(b[4+dataLen:])
|
||||
b[4+dataLen+2] ^= byte(s)
|
||||
b[4+dataLen+3] ^= byte(s >> 8)
|
||||
if withOrigDgram {
|
||||
switch proto {
|
||||
case iana.ProtocolICMP:
|
||||
b[1] = byte(dataLen / 4)
|
||||
case iana.ProtocolIPv6ICMP:
|
||||
b[0] = byte(dataLen / 8)
|
||||
}
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// parseMultipartMessageBody parses b as either a non-multipart
|
||||
// message body or a multipart message body.
|
||||
func parseMultipartMessageBody(proto int, typ Type, b []byte) ([]byte, []Extension, error) {
|
||||
var l int
|
||||
switch proto {
|
||||
case iana.ProtocolICMP:
|
||||
l = 4 * int(b[1])
|
||||
case iana.ProtocolIPv6ICMP:
|
||||
l = 8 * int(b[0])
|
||||
}
|
||||
if len(b) == 4 {
|
||||
return nil, nil, nil
|
||||
}
|
||||
exts, l, err := parseExtensions(typ, b[4:], l)
|
||||
if err != nil {
|
||||
l = len(b) - 4
|
||||
}
|
||||
var data []byte
|
||||
if l > 0 {
|
||||
data = make([]byte, l)
|
||||
copy(data, b[4:])
|
||||
}
|
||||
return data, exts, nil
|
||||
}
|
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, _ Type, b []byte) (MessageBody, error) {
|
||||
bodyLen := len(b)
|
||||
if bodyLen < 4 {
|
||||
return nil, errMessageTooShort
|
||||
}
|
||||
p := &PacketTooBig{MTU: int(binary.BigEndian.Uint32(b[:4]))}
|
||||
if bodyLen > 4 {
|
||||
p.Data = make([]byte, bodyLen-4)
|
||||
copy(p.Data, b[4:])
|
||||
}
|
||||
return p, nil
|
||||
}
|
72
vendor/golang.org/x/net/icmp/paramprob.go
generated
vendored
Normal file
72
vendor/golang.org/x/net/icmp/paramprob.go
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// 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"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
// A ParamProb represents an ICMP parameter problem message body.
|
||||
type ParamProb struct {
|
||||
Pointer uintptr // offset within the data where the error was detected
|
||||
Data []byte // data, known as original datagram field
|
||||
Extensions []Extension // extensions
|
||||
}
|
||||
|
||||
// Len implements the Len method of MessageBody interface.
|
||||
func (p *ParamProb) Len(proto int) int {
|
||||
if p == nil {
|
||||
return 0
|
||||
}
|
||||
l, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions)
|
||||
return l
|
||||
}
|
||||
|
||||
// Marshal implements the Marshal method of MessageBody interface.
|
||||
func (p *ParamProb) Marshal(proto int) ([]byte, error) {
|
||||
switch proto {
|
||||
case iana.ProtocolICMP:
|
||||
if !validExtensions(ipv4.ICMPTypeParameterProblem, p.Extensions) {
|
||||
return nil, errInvalidExtension
|
||||
}
|
||||
b, err := marshalMultipartMessageBody(proto, true, p.Data, p.Extensions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b[0] = byte(p.Pointer)
|
||||
return b, nil
|
||||
case iana.ProtocolIPv6ICMP:
|
||||
b := make([]byte, p.Len(proto))
|
||||
binary.BigEndian.PutUint32(b[:4], uint32(p.Pointer))
|
||||
copy(b[4:], p.Data)
|
||||
return b, nil
|
||||
default:
|
||||
return nil, errInvalidProtocol
|
||||
}
|
||||
}
|
||||
|
||||
// parseParamProb parses b as an ICMP parameter problem message body.
|
||||
func parseParamProb(proto int, typ Type, b []byte) (MessageBody, error) {
|
||||
if len(b) < 4 {
|
||||
return nil, errMessageTooShort
|
||||
}
|
||||
p := &ParamProb{}
|
||||
if proto == iana.ProtocolIPv6ICMP {
|
||||
p.Pointer = uintptr(binary.BigEndian.Uint32(b[:4]))
|
||||
p.Data = make([]byte, len(b)-4)
|
||||
copy(p.Data, b[4:])
|
||||
return p, nil
|
||||
}
|
||||
p.Pointer = uintptr(b[0])
|
||||
var err error
|
||||
p.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
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")
|
||||
}
|
57
vendor/golang.org/x/net/icmp/timeexceeded.go
generated
vendored
Normal file
57
vendor/golang.org/x/net/icmp/timeexceeded.go
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
// 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 (
|
||||
"golang.org/x/net/internal/iana"
|
||||
"golang.org/x/net/ipv4"
|
||||
"golang.org/x/net/ipv6"
|
||||
)
|
||||
|
||||
// A TimeExceeded represents an ICMP time exceeded message body.
|
||||
type TimeExceeded struct {
|
||||
Data []byte // data, known as original datagram field
|
||||
Extensions []Extension // extensions
|
||||
}
|
||||
|
||||
// Len implements the Len method of MessageBody interface.
|
||||
func (p *TimeExceeded) Len(proto int) int {
|
||||
if p == nil {
|
||||
return 0
|
||||
}
|
||||
l, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions)
|
||||
return l
|
||||
}
|
||||
|
||||
// Marshal implements the Marshal method of MessageBody interface.
|
||||
func (p *TimeExceeded) Marshal(proto int) ([]byte, error) {
|
||||
var typ Type
|
||||
switch proto {
|
||||
case iana.ProtocolICMP:
|
||||
typ = ipv4.ICMPTypeTimeExceeded
|
||||
case iana.ProtocolIPv6ICMP:
|
||||
typ = ipv6.ICMPTypeTimeExceeded
|
||||
default:
|
||||
return nil, errInvalidProtocol
|
||||
}
|
||||
if !validExtensions(typ, p.Extensions) {
|
||||
return nil, errInvalidExtension
|
||||
}
|
||||
return marshalMultipartMessageBody(proto, true, p.Data, p.Extensions)
|
||||
}
|
||||
|
||||
// parseTimeExceeded parses b as an ICMP time exceeded message body.
|
||||
func parseTimeExceeded(proto int, typ Type, b []byte) (MessageBody, error) {
|
||||
if len(b) < 4 {
|
||||
return nil, errMessageTooShort
|
||||
}
|
||||
p := &TimeExceeded{}
|
||||
var err error
|
||||
p.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
48
vendor/golang.org/x/net/internal/socket/rawconn_msg.go
generated
vendored
48
vendor/golang.org/x/net/internal/socket/rawconn_msg.go
generated
vendored
@@ -8,22 +8,21 @@
|
||||
package socket
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
)
|
||||
|
||||
func (c *Conn) recvMsg(m *Message, flags int) error {
|
||||
m.raceWrite()
|
||||
var h msghdr
|
||||
vs := make([]iovec, len(m.Buffers))
|
||||
var sa []byte
|
||||
if c.network != "tcp" {
|
||||
sa = make([]byte, sizeofSockaddrInet6)
|
||||
}
|
||||
h.pack(vs, m.Buffers, m.OOB, sa)
|
||||
var operr error
|
||||
var n int
|
||||
var (
|
||||
operr error
|
||||
n int
|
||||
oobn int
|
||||
recvflags int
|
||||
from net.Addr
|
||||
)
|
||||
fn := func(s uintptr) bool {
|
||||
n, operr = recvmsg(s, &h, flags)
|
||||
n, oobn, recvflags, from, operr = recvmsg(s, m.Buffers, m.OOB, flags, c.network)
|
||||
return ioComplete(flags, operr)
|
||||
}
|
||||
if err := c.c.Read(fn); err != nil {
|
||||
@@ -32,34 +31,21 @@ func (c *Conn) recvMsg(m *Message, flags int) error {
|
||||
if operr != nil {
|
||||
return os.NewSyscallError("recvmsg", operr)
|
||||
}
|
||||
if c.network != "tcp" {
|
||||
var err error
|
||||
m.Addr, err = parseInetAddr(sa[:], c.network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
m.Addr = from
|
||||
m.N = n
|
||||
m.NN = h.controllen()
|
||||
m.Flags = h.flags()
|
||||
m.NN = oobn
|
||||
m.Flags = recvflags
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Conn) sendMsg(m *Message, flags int) error {
|
||||
m.raceRead()
|
||||
var h msghdr
|
||||
vs := make([]iovec, len(m.Buffers))
|
||||
var sa []byte
|
||||
if m.Addr != nil {
|
||||
var a [sizeofSockaddrInet6]byte
|
||||
n := marshalInetAddr(m.Addr, a[:])
|
||||
sa = a[:n]
|
||||
}
|
||||
h.pack(vs, m.Buffers, m.OOB, sa)
|
||||
var operr error
|
||||
var n int
|
||||
var (
|
||||
operr error
|
||||
n int
|
||||
)
|
||||
fn := func(s uintptr) bool {
|
||||
n, operr = sendmsg(s, &h, flags)
|
||||
n, operr = sendmsg(s, m.Buffers, m.OOB, m.Addr, flags)
|
||||
return ioComplete(flags, operr)
|
||||
}
|
||||
if err := c.c.Write(fn); err != nil {
|
||||
|
6
vendor/golang.org/x/net/internal/socket/sys_stub.go
generated
vendored
6
vendor/golang.org/x/net/internal/socket/sys_stub.go
generated
vendored
@@ -36,11 +36,11 @@ func setsockopt(s uintptr, level, name int, b []byte) error {
|
||||
return errNotImplemented
|
||||
}
|
||||
|
||||
func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
|
||||
return 0, 0, 0, nil, errNotImplemented
|
||||
}
|
||||
|
||||
func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
|
||||
func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
}
|
||||
|
||||
|
101
vendor/golang.org/x/net/internal/socket/sys_unix.go
generated
vendored
101
vendor/golang.org/x/net/internal/socket/sys_unix.go
generated
vendored
@@ -8,8 +8,10 @@
|
||||
package socket
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"net"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
//go:linkname syscall_getsockopt syscall.getsockopt
|
||||
@@ -18,12 +20,6 @@ func syscall_getsockopt(s, level, name int, val unsafe.Pointer, vallen *uint32)
|
||||
//go:linkname syscall_setsockopt syscall.setsockopt
|
||||
func syscall_setsockopt(s, level, name int, val unsafe.Pointer, vallen uintptr) error
|
||||
|
||||
//go:linkname syscall_recvmsg syscall.recvmsg
|
||||
func syscall_recvmsg(s int, msg *syscall.Msghdr, flags int) (int, error)
|
||||
|
||||
//go:linkname syscall_sendmsg syscall.sendmsg
|
||||
func syscall_sendmsg(s int, msg *syscall.Msghdr, flags int) (int, error)
|
||||
|
||||
func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
|
||||
l := uint32(len(b))
|
||||
err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l)
|
||||
@@ -34,10 +30,93 @@ func setsockopt(s uintptr, level, name int, b []byte) error {
|
||||
return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b)))
|
||||
}
|
||||
|
||||
func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
|
||||
return syscall_recvmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags)
|
||||
func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
|
||||
var unixFrom unix.Sockaddr
|
||||
n, oobn, recvflags, unixFrom, err = unix.RecvmsgBuffers(int(s), buffers, oob, flags)
|
||||
if unixFrom != nil {
|
||||
from = sockaddrToAddr(unixFrom, network)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
|
||||
return syscall_sendmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags)
|
||||
func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
|
||||
var unixTo unix.Sockaddr
|
||||
if to != nil {
|
||||
unixTo = addrToSockaddr(to)
|
||||
}
|
||||
return unix.SendmsgBuffers(int(s), buffers, oob, unixTo, flags)
|
||||
}
|
||||
|
||||
// addrToSockaddr converts a net.Addr to a unix.Sockaddr.
|
||||
func addrToSockaddr(a net.Addr) unix.Sockaddr {
|
||||
var (
|
||||
ip net.IP
|
||||
port int
|
||||
zone string
|
||||
)
|
||||
switch a := a.(type) {
|
||||
case *net.TCPAddr:
|
||||
ip = a.IP
|
||||
port = a.Port
|
||||
zone = a.Zone
|
||||
case *net.UDPAddr:
|
||||
ip = a.IP
|
||||
port = a.Port
|
||||
zone = a.Zone
|
||||
case *net.IPAddr:
|
||||
ip = a.IP
|
||||
zone = a.Zone
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
sa := unix.SockaddrInet4{Port: port}
|
||||
copy(sa.Addr[:], ip4)
|
||||
return &sa
|
||||
}
|
||||
|
||||
if ip6 := ip.To16(); ip6 != nil && ip.To4() == nil {
|
||||
sa := unix.SockaddrInet6{Port: port}
|
||||
copy(sa.Addr[:], ip6)
|
||||
if zone != "" {
|
||||
sa.ZoneId = uint32(zoneCache.index(zone))
|
||||
}
|
||||
return &sa
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// sockaddrToAddr converts a unix.Sockaddr to a net.Addr.
|
||||
func sockaddrToAddr(sa unix.Sockaddr, network string) net.Addr {
|
||||
var (
|
||||
ip net.IP
|
||||
port int
|
||||
zone string
|
||||
)
|
||||
switch sa := sa.(type) {
|
||||
case *unix.SockaddrInet4:
|
||||
ip = make(net.IP, net.IPv4len)
|
||||
copy(ip, sa.Addr[:])
|
||||
port = sa.Port
|
||||
case *unix.SockaddrInet6:
|
||||
ip = make(net.IP, net.IPv6len)
|
||||
copy(ip, sa.Addr[:])
|
||||
port = sa.Port
|
||||
if sa.ZoneId > 0 {
|
||||
zone = zoneCache.name(int(sa.ZoneId))
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
switch network {
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
return &net.TCPAddr{IP: ip, Port: port, Zone: zone}
|
||||
case "udp", "udp4", "udp6":
|
||||
return &net.UDPAddr{IP: ip, Port: port, Zone: zone}
|
||||
default:
|
||||
return &net.IPAddr{IP: ip, Zone: zone}
|
||||
}
|
||||
}
|
||||
|
7
vendor/golang.org/x/net/internal/socket/sys_windows.go
generated
vendored
7
vendor/golang.org/x/net/internal/socket/sys_windows.go
generated
vendored
@@ -5,6 +5,7 @@
|
||||
package socket
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
@@ -37,11 +38,11 @@ func setsockopt(s uintptr, level, name int, b []byte) error {
|
||||
return syscall.Setsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(unsafe.Pointer(&b[0])), int32(len(b)))
|
||||
}
|
||||
|
||||
func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
|
||||
return 0, 0, 0, nil, errNotImplemented
|
||||
}
|
||||
|
||||
func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
|
||||
func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
}
|
||||
|
||||
|
37
vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go
generated
vendored
37
vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go
generated
vendored
@@ -27,12 +27,39 @@ func setsockopt(s uintptr, level, name int, b []byte) error {
|
||||
return errnoErr(errno)
|
||||
}
|
||||
|
||||
func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
|
||||
n, _, errno := syscall_syscall(syscall.SYS___RECVMSG_A, s, uintptr(unsafe.Pointer(h)), uintptr(flags))
|
||||
return int(n), errnoErr(errno)
|
||||
func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
|
||||
var h msghdr
|
||||
vs := make([]iovec, len(buffers))
|
||||
var sa []byte
|
||||
if network != "tcp" {
|
||||
sa = make([]byte, sizeofSockaddrInet6)
|
||||
}
|
||||
h.pack(vs, buffers, oob, sa)
|
||||
sn, _, errno := syscall_syscall(syscall.SYS___RECVMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags))
|
||||
n = int(sn)
|
||||
oobn = h.controllen()
|
||||
recvflags = h.flags()
|
||||
err = errnoErr(errno)
|
||||
if network != "tcp" {
|
||||
var err2 error
|
||||
from, err2 = parseInetAddr(sa, network)
|
||||
if err2 != nil && err == nil {
|
||||
err = err2
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
|
||||
n, _, errno := syscall_syscall(syscall.SYS___SENDMSG_A, s, uintptr(unsafe.Pointer(h)), uintptr(flags))
|
||||
func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
|
||||
var h msghdr
|
||||
vs := make([]iovec, len(buffers))
|
||||
var sa []byte
|
||||
if to != nil {
|
||||
var a [sizeofSockaddrInet6]byte
|
||||
n := marshalInetAddr(to, a[:])
|
||||
sa = a[:n]
|
||||
}
|
||||
h.pack(vs, buffers, oob, sa)
|
||||
n, _, errno := syscall_syscall(syscall.SYS___SENDMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags))
|
||||
return int(n), errnoErr(errno)
|
||||
}
|
||||
|
30
vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go
generated
vendored
30
vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go
generated
vendored
@@ -1,30 +0,0 @@
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_darwin.go
|
||||
|
||||
package socket
|
||||
|
||||
type iovec struct {
|
||||
Base *byte
|
||||
Len uint32
|
||||
}
|
||||
|
||||
type msghdr struct {
|
||||
Name *byte
|
||||
Namelen uint32
|
||||
Iov *iovec
|
||||
Iovlen int32
|
||||
Control *byte
|
||||
Controllen uint32
|
||||
Flags int32
|
||||
}
|
||||
|
||||
type cmsghdr struct {
|
||||
Len uint32
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
const (
|
||||
sizeofIovec = 0x8
|
||||
sizeofMsghdr = 0x1c
|
||||
)
|
@@ -1,11 +1,11 @@
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_darwin.go
|
||||
// cgo -godefs defs_freebsd.go
|
||||
|
||||
package socket
|
||||
|
||||
type iovec struct {
|
||||
Base *byte
|
||||
Len uint32
|
||||
Len uint64
|
||||
}
|
||||
|
||||
type msghdr struct {
|
||||
@@ -25,6 +25,6 @@ type cmsghdr struct {
|
||||
}
|
||||
|
||||
const (
|
||||
sizeofIovec = 0x8
|
||||
sizeofMsghdr = 0x1c
|
||||
sizeofIovec = 0x10
|
||||
sizeofMsghdr = 0x30
|
||||
)
|
52
vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go
generated
vendored
Normal file
52
vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_freebsd.go
|
||||
|
||||
package ipv4
|
||||
|
||||
const (
|
||||
sizeofSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet = 0x10
|
||||
|
||||
sizeofIPMreq = 0x8
|
||||
sizeofIPMreqSource = 0xc
|
||||
sizeofGroupReq = 0x88
|
||||
sizeofGroupSourceReq = 0x108
|
||||
)
|
||||
|
||||
type sockaddrStorage struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
X__ss_pad1 [6]uint8
|
||||
X__ss_align int64
|
||||
X__ss_pad2 [112]uint8
|
||||
}
|
||||
|
||||
type sockaddrInet struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
Port uint16
|
||||
Addr [4]byte /* in_addr */
|
||||
Zero [8]uint8
|
||||
}
|
||||
|
||||
type ipMreq struct {
|
||||
Multiaddr [4]byte /* in_addr */
|
||||
Interface [4]byte /* in_addr */
|
||||
}
|
||||
|
||||
type ipMreqSource struct {
|
||||
Multiaddr [4]byte /* in_addr */
|
||||
Sourceaddr [4]byte /* in_addr */
|
||||
Interface [4]byte /* in_addr */
|
||||
}
|
||||
|
||||
type groupReq struct {
|
||||
Interface uint32
|
||||
Group sockaddrStorage
|
||||
}
|
||||
|
||||
type groupSourceReq struct {
|
||||
Interface uint32
|
||||
Group sockaddrStorage
|
||||
Source sockaddrStorage
|
||||
}
|
64
vendor/golang.org/x/net/ipv6/zsys_freebsd_riscv64.go
generated
vendored
Normal file
64
vendor/golang.org/x/net/ipv6/zsys_freebsd_riscv64.go
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_freebsd.go
|
||||
|
||||
package ipv6
|
||||
|
||||
const (
|
||||
sizeofSockaddrStorage = 0x80
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
sizeofIPv6Mtuinfo = 0x20
|
||||
|
||||
sizeofIPv6Mreq = 0x14
|
||||
sizeofGroupReq = 0x88
|
||||
sizeofGroupSourceReq = 0x108
|
||||
|
||||
sizeofICMPv6Filter = 0x20
|
||||
)
|
||||
|
||||
type sockaddrStorage struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
X__ss_pad1 [6]uint8
|
||||
X__ss_align int64
|
||||
X__ss_pad2 [112]uint8
|
||||
}
|
||||
|
||||
type sockaddrInet6 struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
Port uint16
|
||||
Flowinfo uint32
|
||||
Addr [16]byte /* in6_addr */
|
||||
Scope_id uint32
|
||||
}
|
||||
|
||||
type inet6Pktinfo struct {
|
||||
Addr [16]byte /* in6_addr */
|
||||
Ifindex uint32
|
||||
}
|
||||
|
||||
type ipv6Mtuinfo struct {
|
||||
Addr sockaddrInet6
|
||||
Mtu uint32
|
||||
}
|
||||
|
||||
type ipv6Mreq struct {
|
||||
Multiaddr [16]byte /* in6_addr */
|
||||
Interface uint32
|
||||
}
|
||||
|
||||
type groupReq struct {
|
||||
Interface uint32
|
||||
Group sockaddrStorage
|
||||
}
|
||||
|
||||
type groupSourceReq struct {
|
||||
Interface uint32
|
||||
Group sockaddrStorage
|
||||
Source sockaddrStorage
|
||||
}
|
||||
|
||||
type icmpv6Filter struct {
|
||||
Filt [8]uint32
|
||||
}
|
Reference in New Issue
Block a user