summaryrefslogtreecommitdiff
path: root/libgo/go/golang_org/x/net
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/golang_org/x/net')
-rw-r--r--libgo/go/golang_org/x/net/http2/hpack/encode.go251
-rw-r--r--libgo/go/golang_org/x/net/http2/hpack/encode_test.go330
-rw-r--r--libgo/go/golang_org/x/net/http2/hpack/hpack.go542
-rw-r--r--libgo/go/golang_org/x/net/http2/hpack/hpack_test.go854
-rw-r--r--libgo/go/golang_org/x/net/http2/hpack/huffman.go212
-rw-r--r--libgo/go/golang_org/x/net/http2/hpack/tables.go352
-rw-r--r--libgo/go/golang_org/x/net/lex/httplex/httplex.go312
-rw-r--r--libgo/go/golang_org/x/net/lex/httplex/httplex_test.go101
-rw-r--r--libgo/go/golang_org/x/net/route/address.go269
-rw-r--r--libgo/go/golang_org/x/net/route/address_darwin_test.go63
-rw-r--r--libgo/go/golang_org/x/net/route/address_test.go103
-rw-r--r--libgo/go/golang_org/x/net/route/binary.go90
-rw-r--r--libgo/go/golang_org/x/net/route/defs_darwin.go106
-rw-r--r--libgo/go/golang_org/x/net/route/defs_dragonfly.go105
-rw-r--r--libgo/go/golang_org/x/net/route/defs_freebsd.go329
-rw-r--r--libgo/go/golang_org/x/net/route/defs_netbsd.go104
-rw-r--r--libgo/go/golang_org/x/net/route/defs_openbsd.go93
-rw-r--r--libgo/go/golang_org/x/net/route/interface.go64
-rw-r--r--libgo/go/golang_org/x/net/route/interface_announce.go32
-rw-r--r--libgo/go/golang_org/x/net/route/interface_classic.go66
-rw-r--r--libgo/go/golang_org/x/net/route/interface_freebsd.go78
-rw-r--r--libgo/go/golang_org/x/net/route/interface_multicast.go30
-rw-r--r--libgo/go/golang_org/x/net/route/interface_openbsd.go83
-rw-r--r--libgo/go/golang_org/x/net/route/message.go70
-rw-r--r--libgo/go/golang_org/x/net/route/message_darwin_test.go27
-rw-r--r--libgo/go/golang_org/x/net/route/message_freebsd_test.go106
-rw-r--r--libgo/go/golang_org/x/net/route/message_test.go95
-rw-r--r--libgo/go/golang_org/x/net/route/route.go74
-rw-r--r--libgo/go/golang_org/x/net/route/route_classic.go31
-rw-r--r--libgo/go/golang_org/x/net/route/route_openbsd.go28
-rw-r--r--libgo/go/golang_org/x/net/route/route_test.go385
-rw-r--r--libgo/go/golang_org/x/net/route/sys.go40
-rw-r--r--libgo/go/golang_org/x/net/route/sys_darwin.go80
-rw-r--r--libgo/go/golang_org/x/net/route/sys_dragonfly.go71
-rw-r--r--libgo/go/golang_org/x/net/route/sys_freebsd.go150
-rw-r--r--libgo/go/golang_org/x/net/route/sys_netbsd.go67
-rw-r--r--libgo/go/golang_org/x/net/route/sys_openbsd.go72
-rw-r--r--libgo/go/golang_org/x/net/route/syscall.go33
-rw-r--r--libgo/go/golang_org/x/net/route/zsys_darwin.go93
-rw-r--r--libgo/go/golang_org/x/net/route/zsys_dragonfly.go92
-rw-r--r--libgo/go/golang_org/x/net/route/zsys_freebsd_386.go120
-rw-r--r--libgo/go/golang_org/x/net/route/zsys_freebsd_amd64.go117
-rw-r--r--libgo/go/golang_org/x/net/route/zsys_freebsd_arm.go117
-rw-r--r--libgo/go/golang_org/x/net/route/zsys_netbsd.go91
-rw-r--r--libgo/go/golang_org/x/net/route/zsys_openbsd.go80
45 files changed, 6608 insertions, 0 deletions
diff --git a/libgo/go/golang_org/x/net/http2/hpack/encode.go b/libgo/go/golang_org/x/net/http2/hpack/encode.go
new file mode 100644
index 00000000000..f9bb0339848
--- /dev/null
+++ b/libgo/go/golang_org/x/net/http2/hpack/encode.go
@@ -0,0 +1,251 @@
+// 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 hpack
+
+import (
+ "io"
+)
+
+const (
+ uint32Max = ^uint32(0)
+ initialHeaderTableSize = 4096
+)
+
+type Encoder struct {
+ dynTab dynamicTable
+ // minSize is the minimum table size set by
+ // SetMaxDynamicTableSize after the previous Header Table Size
+ // Update.
+ minSize uint32
+ // maxSizeLimit is the maximum table size this encoder
+ // supports. This will protect the encoder from too large
+ // size.
+ maxSizeLimit uint32
+ // tableSizeUpdate indicates whether "Header Table Size
+ // Update" is required.
+ tableSizeUpdate bool
+ w io.Writer
+ buf []byte
+}
+
+// NewEncoder returns a new Encoder which performs HPACK encoding. An
+// encoded data is written to w.
+func NewEncoder(w io.Writer) *Encoder {
+ e := &Encoder{
+ minSize: uint32Max,
+ maxSizeLimit: initialHeaderTableSize,
+ tableSizeUpdate: false,
+ w: w,
+ }
+ e.dynTab.setMaxSize(initialHeaderTableSize)
+ return e
+}
+
+// WriteField encodes f into a single Write to e's underlying Writer.
+// This function may also produce bytes for "Header Table Size Update"
+// if necessary. If produced, it is done before encoding f.
+func (e *Encoder) WriteField(f HeaderField) error {
+ e.buf = e.buf[:0]
+
+ if e.tableSizeUpdate {
+ e.tableSizeUpdate = false
+ if e.minSize < e.dynTab.maxSize {
+ e.buf = appendTableSize(e.buf, e.minSize)
+ }
+ e.minSize = uint32Max
+ e.buf = appendTableSize(e.buf, e.dynTab.maxSize)
+ }
+
+ idx, nameValueMatch := e.searchTable(f)
+ if nameValueMatch {
+ e.buf = appendIndexed(e.buf, idx)
+ } else {
+ indexing := e.shouldIndex(f)
+ if indexing {
+ e.dynTab.add(f)
+ }
+
+ if idx == 0 {
+ e.buf = appendNewName(e.buf, f, indexing)
+ } else {
+ e.buf = appendIndexedName(e.buf, f, idx, indexing)
+ }
+ }
+ n, err := e.w.Write(e.buf)
+ if err == nil && n != len(e.buf) {
+ err = io.ErrShortWrite
+ }
+ return err
+}
+
+// searchTable searches f in both stable and dynamic header tables.
+// The static header table is searched first. Only when there is no
+// exact match for both name and value, the dynamic header table is
+// then searched. If there is no match, i is 0. If both name and value
+// match, i is the matched index and nameValueMatch becomes true. If
+// only name matches, i points to that index and nameValueMatch
+// becomes false.
+func (e *Encoder) searchTable(f HeaderField) (i uint64, nameValueMatch bool) {
+ for idx, hf := range staticTable {
+ if !constantTimeStringCompare(hf.Name, f.Name) {
+ continue
+ }
+ if i == 0 {
+ i = uint64(idx + 1)
+ }
+ if f.Sensitive {
+ continue
+ }
+ if !constantTimeStringCompare(hf.Value, f.Value) {
+ continue
+ }
+ i = uint64(idx + 1)
+ nameValueMatch = true
+ return
+ }
+
+ j, nameValueMatch := e.dynTab.search(f)
+ if nameValueMatch || (i == 0 && j != 0) {
+ i = j + uint64(len(staticTable))
+ }
+ return
+}
+
+// SetMaxDynamicTableSize changes the dynamic header table size to v.
+// The actual size is bounded by the value passed to
+// SetMaxDynamicTableSizeLimit.
+func (e *Encoder) SetMaxDynamicTableSize(v uint32) {
+ if v > e.maxSizeLimit {
+ v = e.maxSizeLimit
+ }
+ if v < e.minSize {
+ e.minSize = v
+ }
+ e.tableSizeUpdate = true
+ e.dynTab.setMaxSize(v)
+}
+
+// SetMaxDynamicTableSizeLimit changes the maximum value that can be
+// specified in SetMaxDynamicTableSize to v. By default, it is set to
+// 4096, which is the same size of the default dynamic header table
+// size described in HPACK specification. If the current maximum
+// dynamic header table size is strictly greater than v, "Header Table
+// Size Update" will be done in the next WriteField call and the
+// maximum dynamic header table size is truncated to v.
+func (e *Encoder) SetMaxDynamicTableSizeLimit(v uint32) {
+ e.maxSizeLimit = v
+ if e.dynTab.maxSize > v {
+ e.tableSizeUpdate = true
+ e.dynTab.setMaxSize(v)
+ }
+}
+
+// shouldIndex reports whether f should be indexed.
+func (e *Encoder) shouldIndex(f HeaderField) bool {
+ return !f.Sensitive && f.Size() <= e.dynTab.maxSize
+}
+
+// appendIndexed appends index i, as encoded in "Indexed Header Field"
+// representation, to dst and returns the extended buffer.
+func appendIndexed(dst []byte, i uint64) []byte {
+ first := len(dst)
+ dst = appendVarInt(dst, 7, i)
+ dst[first] |= 0x80
+ return dst
+}
+
+// appendNewName appends f, as encoded in one of "Literal Header field
+// - New Name" representation variants, to dst and returns the
+// extended buffer.
+//
+// If f.Sensitive is true, "Never Indexed" representation is used. If
+// f.Sensitive is false and indexing is true, "Inremental Indexing"
+// representation is used.
+func appendNewName(dst []byte, f HeaderField, indexing bool) []byte {
+ dst = append(dst, encodeTypeByte(indexing, f.Sensitive))
+ dst = appendHpackString(dst, f.Name)
+ return appendHpackString(dst, f.Value)
+}
+
+// appendIndexedName appends f and index i referring indexed name
+// entry, as encoded in one of "Literal Header field - Indexed Name"
+// representation variants, to dst and returns the extended buffer.
+//
+// If f.Sensitive is true, "Never Indexed" representation is used. If
+// f.Sensitive is false and indexing is true, "Incremental Indexing"
+// representation is used.
+func appendIndexedName(dst []byte, f HeaderField, i uint64, indexing bool) []byte {
+ first := len(dst)
+ var n byte
+ if indexing {
+ n = 6
+ } else {
+ n = 4
+ }
+ dst = appendVarInt(dst, n, i)
+ dst[first] |= encodeTypeByte(indexing, f.Sensitive)
+ return appendHpackString(dst, f.Value)
+}
+
+// appendTableSize appends v, as encoded in "Header Table Size Update"
+// representation, to dst and returns the extended buffer.
+func appendTableSize(dst []byte, v uint32) []byte {
+ first := len(dst)
+ dst = appendVarInt(dst, 5, uint64(v))
+ dst[first] |= 0x20
+ return dst
+}
+
+// appendVarInt appends i, as encoded in variable integer form using n
+// bit prefix, to dst and returns the extended buffer.
+//
+// See
+// http://http2.github.io/http2-spec/compression.html#integer.representation
+func appendVarInt(dst []byte, n byte, i uint64) []byte {
+ k := uint64((1 << n) - 1)
+ if i < k {
+ return append(dst, byte(i))
+ }
+ dst = append(dst, byte(k))
+ i -= k
+ for ; i >= 128; i >>= 7 {
+ dst = append(dst, byte(0x80|(i&0x7f)))
+ }
+ return append(dst, byte(i))
+}
+
+// appendHpackString appends s, as encoded in "String Literal"
+// representation, to dst and returns the the extended buffer.
+//
+// s will be encoded in Huffman codes only when it produces strictly
+// shorter byte string.
+func appendHpackString(dst []byte, s string) []byte {
+ huffmanLength := HuffmanEncodeLength(s)
+ if huffmanLength < uint64(len(s)) {
+ first := len(dst)
+ dst = appendVarInt(dst, 7, huffmanLength)
+ dst = AppendHuffmanString(dst, s)
+ dst[first] |= 0x80
+ } else {
+ dst = appendVarInt(dst, 7, uint64(len(s)))
+ dst = append(dst, s...)
+ }
+ return dst
+}
+
+// encodeTypeByte returns type byte. If sensitive is true, type byte
+// for "Never Indexed" representation is returned. If sensitive is
+// false and indexing is true, type byte for "Incremental Indexing"
+// representation is returned. Otherwise, type byte for "Without
+// Indexing" is returned.
+func encodeTypeByte(indexing, sensitive bool) byte {
+ if sensitive {
+ return 0x10
+ }
+ if indexing {
+ return 0x40
+ }
+ return 0
+}
diff --git a/libgo/go/golang_org/x/net/http2/hpack/encode_test.go b/libgo/go/golang_org/x/net/http2/hpack/encode_test.go
new file mode 100644
index 00000000000..92286f3bad1
--- /dev/null
+++ b/libgo/go/golang_org/x/net/http2/hpack/encode_test.go
@@ -0,0 +1,330 @@
+// 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 hpack
+
+import (
+ "bytes"
+ "encoding/hex"
+ "reflect"
+ "strings"
+ "testing"
+)
+
+func TestEncoderTableSizeUpdate(t *testing.T) {
+ tests := []struct {
+ size1, size2 uint32
+ wantHex string
+ }{
+ // Should emit 2 table size updates (2048 and 4096)
+ {2048, 4096, "3fe10f 3fe11f 82"},
+
+ // Should emit 1 table size update (2048)
+ {16384, 2048, "3fe10f 82"},
+ }
+ for _, tt := range tests {
+ var buf bytes.Buffer
+ e := NewEncoder(&buf)
+ e.SetMaxDynamicTableSize(tt.size1)
+ e.SetMaxDynamicTableSize(tt.size2)
+ if err := e.WriteField(pair(":method", "GET")); err != nil {
+ t.Fatal(err)
+ }
+ want := removeSpace(tt.wantHex)
+ if got := hex.EncodeToString(buf.Bytes()); got != want {
+ t.Errorf("e.SetDynamicTableSize %v, %v = %q; want %q", tt.size1, tt.size2, got, want)
+ }
+ }
+}
+
+func TestEncoderWriteField(t *testing.T) {
+ var buf bytes.Buffer
+ e := NewEncoder(&buf)
+ var got []HeaderField
+ d := NewDecoder(4<<10, func(f HeaderField) {
+ got = append(got, f)
+ })
+
+ tests := []struct {
+ hdrs []HeaderField
+ }{
+ {[]HeaderField{
+ pair(":method", "GET"),
+ pair(":scheme", "http"),
+ pair(":path", "/"),
+ pair(":authority", "www.example.com"),
+ }},
+ {[]HeaderField{
+ pair(":method", "GET"),
+ pair(":scheme", "http"),
+ pair(":path", "/"),
+ pair(":authority", "www.example.com"),
+ pair("cache-control", "no-cache"),
+ }},
+ {[]HeaderField{
+ pair(":method", "GET"),
+ pair(":scheme", "https"),
+ pair(":path", "/index.html"),
+ pair(":authority", "www.example.com"),
+ pair("custom-key", "custom-value"),
+ }},
+ }
+ for i, tt := range tests {
+ buf.Reset()
+ got = got[:0]
+ for _, hf := range tt.hdrs {
+ if err := e.WriteField(hf); err != nil {
+ t.Fatal(err)
+ }
+ }
+ _, err := d.Write(buf.Bytes())
+ if err != nil {
+ t.Errorf("%d. Decoder Write = %v", i, err)
+ }
+ if !reflect.DeepEqual(got, tt.hdrs) {
+ t.Errorf("%d. Decoded %+v; want %+v", i, got, tt.hdrs)
+ }
+ }
+}
+
+func TestEncoderSearchTable(t *testing.T) {
+ e := NewEncoder(nil)
+
+ e.dynTab.add(pair("foo", "bar"))
+ e.dynTab.add(pair("blake", "miz"))
+ e.dynTab.add(pair(":method", "GET"))
+
+ tests := []struct {
+ hf HeaderField
+ wantI uint64
+ wantMatch bool
+ }{
+ // Name and Value match
+ {pair("foo", "bar"), uint64(len(staticTable) + 3), true},
+ {pair("blake", "miz"), uint64(len(staticTable) + 2), true},
+ {pair(":method", "GET"), 2, true},
+
+ // Only name match because Sensitive == true
+ {HeaderField{":method", "GET", true}, 2, false},
+
+ // Only Name matches
+ {pair("foo", "..."), uint64(len(staticTable) + 3), false},
+ {pair("blake", "..."), uint64(len(staticTable) + 2), false},
+ {pair(":method", "..."), 2, false},
+
+ // None match
+ {pair("foo-", "bar"), 0, false},
+ }
+ for _, tt := range tests {
+ if gotI, gotMatch := e.searchTable(tt.hf); gotI != tt.wantI || gotMatch != tt.wantMatch {
+ t.Errorf("d.search(%+v) = %v, %v; want %v, %v", tt.hf, gotI, gotMatch, tt.wantI, tt.wantMatch)
+ }
+ }
+}
+
+func TestAppendVarInt(t *testing.T) {
+ tests := []struct {
+ n byte
+ i uint64
+ want []byte
+ }{
+ // Fits in a byte:
+ {1, 0, []byte{0}},
+ {2, 2, []byte{2}},
+ {3, 6, []byte{6}},
+ {4, 14, []byte{14}},
+ {5, 30, []byte{30}},
+ {6, 62, []byte{62}},
+ {7, 126, []byte{126}},
+ {8, 254, []byte{254}},
+
+ // Multiple bytes:
+ {5, 1337, []byte{31, 154, 10}},
+ }
+ for _, tt := range tests {
+ got := appendVarInt(nil, tt.n, tt.i)
+ if !bytes.Equal(got, tt.want) {
+ t.Errorf("appendVarInt(nil, %v, %v) = %v; want %v", tt.n, tt.i, got, tt.want)
+ }
+ }
+}
+
+func TestAppendHpackString(t *testing.T) {
+ tests := []struct {
+ s, wantHex string
+ }{
+ // Huffman encoded
+ {"www.example.com", "8c f1e3 c2e5 f23a 6ba0 ab90 f4ff"},
+
+ // Not Huffman encoded
+ {"a", "01 61"},
+
+ // zero length
+ {"", "00"},
+ }
+ for _, tt := range tests {
+ want := removeSpace(tt.wantHex)
+ buf := appendHpackString(nil, tt.s)
+ if got := hex.EncodeToString(buf); want != got {
+ t.Errorf("appendHpackString(nil, %q) = %q; want %q", tt.s, got, want)
+ }
+ }
+}
+
+func TestAppendIndexed(t *testing.T) {
+ tests := []struct {
+ i uint64
+ wantHex string
+ }{
+ // 1 byte
+ {1, "81"},
+ {126, "fe"},
+
+ // 2 bytes
+ {127, "ff00"},
+ {128, "ff01"},
+ }
+ for _, tt := range tests {
+ want := removeSpace(tt.wantHex)
+ buf := appendIndexed(nil, tt.i)
+ if got := hex.EncodeToString(buf); want != got {
+ t.Errorf("appendIndex(nil, %v) = %q; want %q", tt.i, got, want)
+ }
+ }
+}
+
+func TestAppendNewName(t *testing.T) {
+ tests := []struct {
+ f HeaderField
+ indexing bool
+ wantHex string
+ }{
+ // Incremental indexing
+ {HeaderField{"custom-key", "custom-value", false}, true, "40 88 25a8 49e9 5ba9 7d7f 89 25a8 49e9 5bb8 e8b4 bf"},
+
+ // Without indexing
+ {HeaderField{"custom-key", "custom-value", false}, false, "00 88 25a8 49e9 5ba9 7d7f 89 25a8 49e9 5bb8 e8b4 bf"},
+
+ // Never indexed
+ {HeaderField{"custom-key", "custom-value", true}, true, "10 88 25a8 49e9 5ba9 7d7f 89 25a8 49e9 5bb8 e8b4 bf"},
+ {HeaderField{"custom-key", "custom-value", true}, false, "10 88 25a8 49e9 5ba9 7d7f 89 25a8 49e9 5bb8 e8b4 bf"},
+ }
+ for _, tt := range tests {
+ want := removeSpace(tt.wantHex)
+ buf := appendNewName(nil, tt.f, tt.indexing)
+ if got := hex.EncodeToString(buf); want != got {
+ t.Errorf("appendNewName(nil, %+v, %v) = %q; want %q", tt.f, tt.indexing, got, want)
+ }
+ }
+}
+
+func TestAppendIndexedName(t *testing.T) {
+ tests := []struct {
+ f HeaderField
+ i uint64
+ indexing bool
+ wantHex string
+ }{
+ // Incremental indexing
+ {HeaderField{":status", "302", false}, 8, true, "48 82 6402"},
+
+ // Without indexing
+ {HeaderField{":status", "302", false}, 8, false, "08 82 6402"},
+
+ // Never indexed
+ {HeaderField{":status", "302", true}, 8, true, "18 82 6402"},
+ {HeaderField{":status", "302", true}, 8, false, "18 82 6402"},
+ }
+ for _, tt := range tests {
+ want := removeSpace(tt.wantHex)
+ buf := appendIndexedName(nil, tt.f, tt.i, tt.indexing)
+ if got := hex.EncodeToString(buf); want != got {
+ t.Errorf("appendIndexedName(nil, %+v, %v) = %q; want %q", tt.f, tt.indexing, got, want)
+ }
+ }
+}
+
+func TestAppendTableSize(t *testing.T) {
+ tests := []struct {
+ i uint32
+ wantHex string
+ }{
+ // Fits into 1 byte
+ {30, "3e"},
+
+ // Extra byte
+ {31, "3f00"},
+ {32, "3f01"},
+ }
+ for _, tt := range tests {
+ want := removeSpace(tt.wantHex)
+ buf := appendTableSize(nil, tt.i)
+ if got := hex.EncodeToString(buf); want != got {
+ t.Errorf("appendTableSize(nil, %v) = %q; want %q", tt.i, got, want)
+ }
+ }
+}
+
+func TestEncoderSetMaxDynamicTableSize(t *testing.T) {
+ var buf bytes.Buffer
+ e := NewEncoder(&buf)
+ tests := []struct {
+ v uint32
+ wantUpdate bool
+ wantMinSize uint32
+ wantMaxSize uint32
+ }{
+ // Set new table size to 2048
+ {2048, true, 2048, 2048},
+
+ // Set new table size to 16384, but still limited to
+ // 4096
+ {16384, true, 2048, 4096},
+ }
+ for _, tt := range tests {
+ e.SetMaxDynamicTableSize(tt.v)
+ if got := e.tableSizeUpdate; tt.wantUpdate != got {
+ t.Errorf("e.tableSizeUpdate = %v; want %v", got, tt.wantUpdate)
+ }
+ if got := e.minSize; tt.wantMinSize != got {
+ t.Errorf("e.minSize = %v; want %v", got, tt.wantMinSize)
+ }
+ if got := e.dynTab.maxSize; tt.wantMaxSize != got {
+ t.Errorf("e.maxSize = %v; want %v", got, tt.wantMaxSize)
+ }
+ }
+}
+
+func TestEncoderSetMaxDynamicTableSizeLimit(t *testing.T) {
+ e := NewEncoder(nil)
+ // 4095 < initialHeaderTableSize means maxSize is truncated to
+ // 4095.
+ e.SetMaxDynamicTableSizeLimit(4095)
+ if got, want := e.dynTab.maxSize, uint32(4095); got != want {
+ t.Errorf("e.dynTab.maxSize = %v; want %v", got, want)
+ }
+ if got, want := e.maxSizeLimit, uint32(4095); got != want {
+ t.Errorf("e.maxSizeLimit = %v; want %v", got, want)
+ }
+ if got, want := e.tableSizeUpdate, true; got != want {
+ t.Errorf("e.tableSizeUpdate = %v; want %v", got, want)
+ }
+ // maxSize will be truncated to maxSizeLimit
+ e.SetMaxDynamicTableSize(16384)
+ if got, want := e.dynTab.maxSize, uint32(4095); got != want {
+ t.Errorf("e.dynTab.maxSize = %v; want %v", got, want)
+ }
+ // 8192 > current maxSizeLimit, so maxSize does not change.
+ e.SetMaxDynamicTableSizeLimit(8192)
+ if got, want := e.dynTab.maxSize, uint32(4095); got != want {
+ t.Errorf("e.dynTab.maxSize = %v; want %v", got, want)
+ }
+ if got, want := e.maxSizeLimit, uint32(8192); got != want {
+ t.Errorf("e.maxSizeLimit = %v; want %v", got, want)
+ }
+}
+
+func removeSpace(s string) string {
+ return strings.Replace(s, " ", "", -1)
+}
diff --git a/libgo/go/golang_org/x/net/http2/hpack/hpack.go b/libgo/go/golang_org/x/net/http2/hpack/hpack.go
new file mode 100644
index 00000000000..8aa197ad678
--- /dev/null
+++ b/libgo/go/golang_org/x/net/http2/hpack/hpack.go
@@ -0,0 +1,542 @@
+// 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 hpack implements HPACK, a compression format for
+// efficiently representing HTTP header fields in the context of HTTP/2.
+//
+// See http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09
+package hpack
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+)
+
+// A DecodingError is something the spec defines as a decoding error.
+type DecodingError struct {
+ Err error
+}
+
+func (de DecodingError) Error() string {
+ return fmt.Sprintf("decoding error: %v", de.Err)
+}
+
+// An InvalidIndexError is returned when an encoder references a table
+// entry before the static table or after the end of the dynamic table.
+type InvalidIndexError int
+
+func (e InvalidIndexError) Error() string {
+ return fmt.Sprintf("invalid indexed representation index %d", int(e))
+}
+
+// A HeaderField is a name-value pair. Both the name and value are
+// treated as opaque sequences of octets.
+type HeaderField struct {
+ Name, Value string
+
+ // Sensitive means that this header field should never be
+ // indexed.
+ Sensitive bool
+}
+
+// IsPseudo reports whether the header field is an http2 pseudo header.
+// That is, it reports whether it starts with a colon.
+// It is not otherwise guaranteed to be a valid pseudo header field,
+// though.
+func (hf HeaderField) IsPseudo() bool {
+ return len(hf.Name) != 0 && hf.Name[0] == ':'
+}
+
+func (hf HeaderField) String() string {
+ var suffix string
+ if hf.Sensitive {
+ suffix = " (sensitive)"
+ }
+ return fmt.Sprintf("header field %q = %q%s", hf.Name, hf.Value, suffix)
+}
+
+// Size returns the size of an entry per RFC 7540 section 5.2.
+func (hf HeaderField) Size() uint32 {
+ // http://http2.github.io/http2-spec/compression.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
+ // length in octets (see Section 5.2), plus 32. The size of
+ // an entry is calculated using the length of the name and
+ // value without any Huffman encoding applied."
+
+ // This can overflow if somebody makes a large HeaderField
+ // Name and/or Value by hand, but we don't care, because that
+ // won't happen on the wire because the encoding doesn't allow
+ // it.
+ return uint32(len(hf.Name) + len(hf.Value) + 32)
+}
+
+// A Decoder is the decoding context for incremental processing of
+// header blocks.
+type Decoder struct {
+ dynTab dynamicTable
+ emit func(f HeaderField)
+
+ emitEnabled bool // whether calls to emit are enabled
+ maxStrLen int // 0 means unlimited
+
+ // buf is the unparsed buffer. It's only written to
+ // saveBuf if it was truncated in the middle of a header
+ // block. Because it's usually not owned, we can only
+ // process it under Write.
+ buf []byte // not owned; only valid during Write
+
+ // saveBuf is previous data passed to Write which we weren't able
+ // to fully parse before. Unlike buf, we own this data.
+ saveBuf bytes.Buffer
+}
+
+// NewDecoder returns a new decoder with the provided maximum dynamic
+// table size. The emitFunc will be called for each valid field
+// parsed, in the same goroutine as calls to Write, before Write returns.
+func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decoder {
+ d := &Decoder{
+ emit: emitFunc,
+ emitEnabled: true,
+ }
+ d.dynTab.allowedMaxSize = maxDynamicTableSize
+ d.dynTab.setMaxSize(maxDynamicTableSize)
+ return d
+}
+
+// ErrStringLength is returned by Decoder.Write when the max string length
+// (as configured by Decoder.SetMaxStringLength) would be violated.
+var ErrStringLength = errors.New("hpack: string too long")
+
+// SetMaxStringLength sets the maximum size of a HeaderField name or
+// value string. If a string exceeds this length (even after any
+// decompression), Write will return ErrStringLength.
+// A value of 0 means unlimited and is the default from NewDecoder.
+func (d *Decoder) SetMaxStringLength(n int) {
+ d.maxStrLen = n
+}
+
+// SetEmitFunc changes the callback used when new header fields
+// are decoded.
+// It must be non-nil. It does not affect EmitEnabled.
+func (d *Decoder) SetEmitFunc(emitFunc func(f HeaderField)) {
+ d.emit = emitFunc
+}
+
+// SetEmitEnabled controls whether the emitFunc provided to NewDecoder
+// should be called. The default is true.
+//
+// This facility exists to let servers enforce MAX_HEADER_LIST_SIZE
+// while still decoding and keeping in-sync with decoder state, but
+// without doing unnecessary decompression or generating unnecessary
+// garbage for header fields past the limit.
+func (d *Decoder) SetEmitEnabled(v bool) { d.emitEnabled = v }
+
+// EmitEnabled reports whether calls to the emitFunc provided to NewDecoder
+// are currently enabled. The default is true.
+func (d *Decoder) EmitEnabled() bool { return d.emitEnabled }
+
+// TODO: add method *Decoder.Reset(maxSize, emitFunc) to let callers re-use Decoders and their
+// underlying buffers for garbage reasons.
+
+func (d *Decoder) SetMaxDynamicTableSize(v uint32) {
+ d.dynTab.setMaxSize(v)
+}
+
+// SetAllowedMaxDynamicTableSize sets the upper bound that the encoded
+// stream (via dynamic table size updates) may set the maximum size
+// to.
+func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) {
+ d.dynTab.allowedMaxSize = v
+}
+
+type dynamicTable struct {
+ // ents is the FIFO described at
+ // http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2
+ // The newest (low index) is append at the end, and items are
+ // evicted from the front.
+ ents []HeaderField
+ size uint32
+ maxSize uint32 // current maxSize
+ allowedMaxSize uint32 // maxSize may go up to this, inclusive
+}
+
+func (dt *dynamicTable) setMaxSize(v uint32) {
+ dt.maxSize = v
+ dt.evict()
+}
+
+// TODO: change dynamicTable to be a struct with a slice and a size int field,
+// per http://http2.github.io/http2-spec/compression.html#rfc.section.4.1:
+//
+//
+// Then make add increment the size. maybe the max size should move from Decoder to
+// dynamicTable and add should return an ok bool if there was enough space.
+//
+// Later we'll need a remove operation on dynamicTable.
+
+func (dt *dynamicTable) add(f HeaderField) {
+ dt.ents = append(dt.ents, f)
+ dt.size += f.Size()
+ dt.evict()
+}
+
+// If we're too big, evict old stuff (front of the slice)
+func (dt *dynamicTable) evict() {
+ base := dt.ents // keep base pointer of slice
+ for dt.size > dt.maxSize {
+ dt.size -= dt.ents[0].Size()
+ dt.ents = dt.ents[1:]
+ }
+
+ // Shift slice contents down if we evicted things.
+ if len(dt.ents) != len(base) {
+ copy(base, dt.ents)
+ dt.ents = base[:len(dt.ents)]
+ }
+}
+
+// constantTimeStringCompare compares string a and b in a constant
+// time manner.
+func constantTimeStringCompare(a, b string) bool {
+ if len(a) != len(b) {
+ return false
+ }
+
+ c := byte(0)
+
+ for i := 0; i < len(a); i++ {
+ c |= a[i] ^ b[i]
+ }
+
+ return c == 0
+}
+
+// Search searches f in the table. The return value i is 0 if there is
+// no name match. If there is name match or name/value match, i is the
+// index of that entry (1-based). If both name and value match,
+// nameValueMatch becomes true.
+func (dt *dynamicTable) search(f HeaderField) (i uint64, nameValueMatch bool) {
+ l := len(dt.ents)
+ for j := l - 1; j >= 0; j-- {
+ ent := dt.ents[j]
+ if !constantTimeStringCompare(ent.Name, f.Name) {
+ continue
+ }
+ if i == 0 {
+ i = uint64(l - j)
+ }
+ if f.Sensitive {
+ continue
+ }
+ if !constantTimeStringCompare(ent.Value, f.Value) {
+ continue
+ }
+ i = uint64(l - j)
+ nameValueMatch = true
+ return
+ }
+ return
+}
+
+func (d *Decoder) maxTableIndex() int {
+ return len(d.dynTab.ents) + len(staticTable)
+}
+
+func (d *Decoder) at(i uint64) (hf HeaderField, ok bool) {
+ if i < 1 {
+ return
+ }
+ if i > uint64(d.maxTableIndex()) {
+ return
+ }
+ if i <= uint64(len(staticTable)) {
+ return staticTable[i-1], true
+ }
+ dents := d.dynTab.ents
+ return dents[len(dents)-(int(i)-len(staticTable))], true
+}
+
+// Decode decodes an entire block.
+//
+// TODO: remove this method and make it incremental later? This is
+// easier for debugging now.
+func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) {
+ var hf []HeaderField
+ saveFunc := d.emit
+ defer func() { d.emit = saveFunc }()
+ d.emit = func(f HeaderField) { hf = append(hf, f) }
+ if _, err := d.Write(p); err != nil {
+ return nil, err
+ }
+ if err := d.Close(); err != nil {
+ return nil, err
+ }
+ return hf, nil
+}
+
+func (d *Decoder) Close() error {
+ if d.saveBuf.Len() > 0 {
+ d.saveBuf.Reset()
+ return DecodingError{errors.New("truncated headers")}
+ }
+ return nil
+}
+
+func (d *Decoder) Write(p []byte) (n int, err error) {
+ if len(p) == 0 {
+ // Prevent state machine CPU attacks (making us redo
+ // work up to the point of finding out we don't have
+ // enough data)
+ return
+ }
+ // Only copy the data if we have to. Optimistically assume
+ // that p will contain a complete header block.
+ if d.saveBuf.Len() == 0 {
+ d.buf = p
+ } else {
+ d.saveBuf.Write(p)
+ d.buf = d.saveBuf.Bytes()
+ d.saveBuf.Reset()
+ }
+
+ for len(d.buf) > 0 {
+ err = d.parseHeaderFieldRepr()
+ if err == errNeedMore {
+ // Extra paranoia, making sure saveBuf won't
+ // get too large. All the varint and string
+ // reading code earlier should already catch
+ // overlong things and return ErrStringLength,
+ // but keep this as a last resort.
+ const varIntOverhead = 8 // conservative
+ if d.maxStrLen != 0 && int64(len(d.buf)) > 2*(int64(d.maxStrLen)+varIntOverhead) {
+ return 0, ErrStringLength
+ }
+ d.saveBuf.Write(d.buf)
+ return len(p), nil
+ }
+ if err != nil {
+ break
+ }
+ }
+ return len(p), err
+}
+
+// errNeedMore is an internal sentinel error value that means the
+// buffer is truncated and we need to read more data before we can
+// continue parsing.
+var errNeedMore = errors.New("need more data")
+
+type indexType int
+
+const (
+ indexedTrue indexType = iota
+ indexedFalse
+ indexedNever
+)
+
+func (v indexType) indexed() bool { return v == indexedTrue }
+func (v indexType) sensitive() bool { return v == indexedNever }
+
+// returns errNeedMore if there isn't enough data available.
+// any other error is fatal.
+// consumes d.buf iff it returns nil.
+// precondition: must be called with len(d.buf) > 0
+func (d *Decoder) parseHeaderFieldRepr() error {
+ b := d.buf[0]
+ switch {
+ case b&128 != 0:
+ // Indexed representation.
+ // High bit set?
+ // http://http2.github.io/http2-spec/compression.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
+ 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
+ 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
+ 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
+ return d.parseDynamicTableSizeUpdate()
+ }
+
+ return DecodingError{errors.New("invalid encoding")}
+}
+
+// (same invariants and behavior as parseHeaderFieldRepr)
+func (d *Decoder) parseFieldIndexed() error {
+ buf := d.buf
+ idx, buf, err := readVarInt(7, buf)
+ if err != nil {
+ return err
+ }
+ hf, ok := d.at(idx)
+ if !ok {
+ return DecodingError{InvalidIndexError(idx)}
+ }
+ d.buf = buf
+ return d.callEmit(HeaderField{Name: hf.Name, Value: hf.Value})
+}
+
+// (same invariants and behavior as parseHeaderFieldRepr)
+func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {
+ buf := d.buf
+ nameIdx, buf, err := readVarInt(n, buf)
+ if err != nil {
+ return err
+ }
+
+ var hf HeaderField
+ wantStr := d.emitEnabled || it.indexed()
+ if nameIdx > 0 {
+ ihf, ok := d.at(nameIdx)
+ if !ok {
+ return DecodingError{InvalidIndexError(nameIdx)}
+ }
+ hf.Name = ihf.Name
+ } else {
+ hf.Name, buf, err = d.readString(buf, wantStr)
+ if err != nil {
+ return err
+ }
+ }
+ hf.Value, buf, err = d.readString(buf, wantStr)
+ if err != nil {
+ return err
+ }
+ d.buf = buf
+ if it.indexed() {
+ d.dynTab.add(hf)
+ }
+ hf.Sensitive = it.sensitive()
+ return d.callEmit(hf)
+}
+
+func (d *Decoder) callEmit(hf HeaderField) error {
+ if d.maxStrLen != 0 {
+ if len(hf.Name) > d.maxStrLen || len(hf.Value) > d.maxStrLen {
+ return ErrStringLength
+ }
+ }
+ if d.emitEnabled {
+ d.emit(hf)
+ }
+ return nil
+}
+
+// (same invariants and behavior as parseHeaderFieldRepr)
+func (d *Decoder) parseDynamicTableSizeUpdate() error {
+ buf := d.buf
+ size, buf, err := readVarInt(5, buf)
+ if err != nil {
+ return err
+ }
+ if size > uint64(d.dynTab.allowedMaxSize) {
+ return DecodingError{errors.New("dynamic table size update too large")}
+ }
+ d.dynTab.setMaxSize(uint32(size))
+ d.buf = buf
+ return nil
+}
+
+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.
+//
+// n must always be between 1 and 8.
+//
+// The returned remain buffer is either a smaller suffix of p, or err != nil.
+// The error is errNeedMore if p doesn't contain a complete integer.
+func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) {
+ if n < 1 || n > 8 {
+ panic("bad n")
+ }
+ if len(p) == 0 {
+ return 0, p, errNeedMore
+ }
+ i = uint64(p[0])
+ if n < 8 {
+ i &= (1 << uint64(n)) - 1
+ }
+ if i < (1<<uint64(n))-1 {
+ return i, p[1:], nil
+ }
+
+ origP := p
+ p = p[1:]
+ var m uint64
+ for len(p) > 0 {
+ b := p[0]
+ p = p[1:]
+ i += uint64(b&127) << m
+ if b&128 == 0 {
+ return i, p, nil
+ }
+ m += 7
+ if m >= 63 { // TODO: proper overflow check. making this up.
+ return 0, origP, errVarintOverflow
+ }
+ }
+ return 0, origP, errNeedMore
+}
+
+// readString decodes an hpack string from p.
+//
+// wantStr is whether s will be used. If false, decompression and
+// []byte->string garbage are skipped if s will be ignored
+// anyway. This does mean that huffman decoding errors for non-indexed
+// strings past the MAX_HEADER_LIST_SIZE are ignored, but the server
+// is returning an error anyway, and because they're not indexed, the error
+// won't affect the decoding state.
+func (d *Decoder) readString(p []byte, wantStr bool) (s string, remain []byte, err error) {
+ if len(p) == 0 {
+ return "", p, errNeedMore
+ }
+ isHuff := p[0]&128 != 0
+ strLen, p, err := readVarInt(7, p)
+ if err != nil {
+ return "", p, err
+ }
+ if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) {
+ return "", nil, ErrStringLength
+ }
+ if uint64(len(p)) < strLen {
+ return "", p, errNeedMore
+ }
+ if !isHuff {
+ if wantStr {
+ s = string(p[:strLen])
+ }
+ return s, p[strLen:], nil
+ }
+
+ if wantStr {
+ buf := bufPool.Get().(*bytes.Buffer)
+ buf.Reset() // don't trust others
+ defer bufPool.Put(buf)
+ if err := huffmanDecode(buf, d.maxStrLen, p[:strLen]); err != nil {
+ buf.Reset()
+ return "", nil, err
+ }
+ s = buf.String()
+ buf.Reset() // be nice to GC
+ }
+ return s, p[strLen:], nil
+}
diff --git a/libgo/go/golang_org/x/net/http2/hpack/hpack_test.go b/libgo/go/golang_org/x/net/http2/hpack/hpack_test.go
new file mode 100644
index 00000000000..4c7b17bfb14
--- /dev/null
+++ b/libgo/go/golang_org/x/net/http2/hpack/hpack_test.go
@@ -0,0 +1,854 @@
+// 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 hpack
+
+import (
+ "bufio"
+ "bytes"
+ "encoding/hex"
+ "fmt"
+ "math/rand"
+ "reflect"
+ "regexp"
+ "strconv"
+ "strings"
+ "testing"
+ "time"
+)
+
+func TestStaticTable(t *testing.T) {
+ fromSpec := `
+ +-------+-----------------------------+---------------+
+ | 1 | :authority | |
+ | 2 | :method | GET |
+ | 3 | :method | POST |
+ | 4 | :path | / |
+ | 5 | :path | /index.html |
+ | 6 | :scheme | http |
+ | 7 | :scheme | https |
+ | 8 | :status | 200 |
+ | 9 | :status | 204 |
+ | 10 | :status | 206 |
+ | 11 | :status | 304 |
+ | 12 | :status | 400 |
+ | 13 | :status | 404 |
+ | 14 | :status | 500 |
+ | 15 | accept-charset | |
+ | 16 | accept-encoding | gzip, deflate |
+ | 17 | accept-language | |
+ | 18 | accept-ranges | |
+ | 19 | accept | |
+ | 20 | access-control-allow-origin | |
+ | 21 | age | |
+ | 22 | allow | |
+ | 23 | authorization | |
+ | 24 | cache-control | |
+ | 25 | content-disposition | |
+ | 26 | content-encoding | |
+ | 27 | content-language | |
+ | 28 | content-length | |
+ | 29 | content-location | |
+ | 30 | content-range | |
+ | 31 | content-type | |
+ | 32 | cookie | |
+ | 33 | date | |
+ | 34 | etag | |
+ | 35 | expect | |
+ | 36 | expires | |
+ | 37 | from | |
+ | 38 | host | |
+ | 39 | if-match | |
+ | 40 | if-modified-since | |
+ | 41 | if-none-match | |
+ | 42 | if-range | |
+ | 43 | if-unmodified-since | |
+ | 44 | last-modified | |
+ | 45 | link | |
+ | 46 | location | |
+ | 47 | max-forwards | |
+ | 48 | proxy-authenticate | |
+ | 49 | proxy-authorization | |
+ | 50 | range | |
+ | 51 | referer | |
+ | 52 | refresh | |
+ | 53 | retry-after | |
+ | 54 | server | |
+ | 55 | set-cookie | |
+ | 56 | strict-transport-security | |
+ | 57 | transfer-encoding | |
+ | 58 | user-agent | |
+ | 59 | vary | |
+ | 60 | via | |
+ | 61 | www-authenticate | |
+ +-------+-----------------------------+---------------+
+`
+ bs := bufio.NewScanner(strings.NewReader(fromSpec))
+ re := regexp.MustCompile(`\| (\d+)\s+\| (\S+)\s*\| (\S(.*\S)?)?\s+\|`)
+ for bs.Scan() {
+ l := bs.Text()
+ if !strings.Contains(l, "|") {
+ continue
+ }
+ m := re.FindStringSubmatch(l)
+ if m == nil {
+ continue
+ }
+ i, err := strconv.Atoi(m[1])
+ if err != nil {
+ t.Errorf("Bogus integer on line %q", l)
+ continue
+ }
+ if i < 1 || i > len(staticTable) {
+ t.Errorf("Bogus index %d on line %q", i, l)
+ continue
+ }
+ if got, want := staticTable[i-1].Name, m[2]; got != want {
+ t.Errorf("header index %d name = %q; want %q", i, got, want)
+ }
+ if got, want := staticTable[i-1].Value, m[3]; got != want {
+ t.Errorf("header index %d value = %q; want %q", i, got, want)
+ }
+ }
+ if err := bs.Err(); err != nil {
+ t.Error(err)
+ }
+}
+
+func (d *Decoder) mustAt(idx int) HeaderField {
+ if hf, ok := d.at(uint64(idx)); !ok {
+ panic(fmt.Sprintf("bogus index %d", idx))
+ } else {
+ return hf
+ }
+}
+
+func TestDynamicTableAt(t *testing.T) {
+ d := NewDecoder(4096, nil)
+ at := d.mustAt
+ if got, want := at(2), (pair(":method", "GET")); got != want {
+ t.Errorf("at(2) = %v; want %v", got, want)
+ }
+ d.dynTab.add(pair("foo", "bar"))
+ d.dynTab.add(pair("blake", "miz"))
+ if got, want := at(len(staticTable)+1), (pair("blake", "miz")); got != want {
+ t.Errorf("at(dyn 1) = %v; want %v", got, want)
+ }
+ if got, want := at(len(staticTable)+2), (pair("foo", "bar")); got != want {
+ t.Errorf("at(dyn 2) = %v; want %v", got, want)
+ }
+ if got, want := at(3), (pair(":method", "POST")); got != want {
+ t.Errorf("at(3) = %v; want %v", got, want)
+ }
+}
+
+func TestDynamicTableSearch(t *testing.T) {
+ dt := dynamicTable{}
+ dt.setMaxSize(4096)
+
+ dt.add(pair("foo", "bar"))
+ dt.add(pair("blake", "miz"))
+ dt.add(pair(":method", "GET"))
+
+ tests := []struct {
+ hf HeaderField
+ wantI uint64
+ wantMatch bool
+ }{
+ // Name and Value match
+ {pair("foo", "bar"), 3, true},
+ {pair(":method", "GET"), 1, true},
+
+ // Only name match because of Sensitive == true
+ {HeaderField{"blake", "miz", true}, 2, false},
+
+ // Only Name matches
+ {pair("foo", "..."), 3, false},
+ {pair("blake", "..."), 2, false},
+ {pair(":method", "..."), 1, false},
+
+ // None match
+ {pair("foo-", "bar"), 0, false},
+ }
+ for _, tt := range tests {
+ if gotI, gotMatch := dt.search(tt.hf); gotI != tt.wantI || gotMatch != tt.wantMatch {
+ t.Errorf("d.search(%+v) = %v, %v; want %v, %v", tt.hf, gotI, gotMatch, tt.wantI, tt.wantMatch)
+ }
+ }
+}
+
+func TestDynamicTableSizeEvict(t *testing.T) {
+ d := NewDecoder(4096, nil)
+ if want := uint32(0); d.dynTab.size != want {
+ t.Fatalf("size = %d; want %d", d.dynTab.size, want)
+ }
+ add := d.dynTab.add
+ add(pair("blake", "eats pizza"))
+ if want := uint32(15 + 32); d.dynTab.size != want {
+ t.Fatalf("after pizza, size = %d; want %d", d.dynTab.size, want)
+ }
+ add(pair("foo", "bar"))
+ if want := uint32(15 + 32 + 6 + 32); d.dynTab.size != want {
+ t.Fatalf("after foo bar, size = %d; want %d", d.dynTab.size, want)
+ }
+ d.dynTab.setMaxSize(15 + 32 + 1 /* slop */)
+ if want := uint32(6 + 32); d.dynTab.size != want {
+ t.Fatalf("after setMaxSize, size = %d; want %d", d.dynTab.size, want)
+ }
+ if got, want := d.mustAt(len(staticTable)+1), (pair("foo", "bar")); got != want {
+ t.Errorf("at(dyn 1) = %v; want %v", got, want)
+ }
+ add(pair("long", strings.Repeat("x", 500)))
+ if want := uint32(0); d.dynTab.size != want {
+ t.Fatalf("after big one, size = %d; want %d", d.dynTab.size, want)
+ }
+}
+
+func TestDecoderDecode(t *testing.T) {
+ tests := []struct {
+ name string
+ in []byte
+ want []HeaderField
+ wantDynTab []HeaderField // newest entry first
+ }{
+ // C.2.1 Literal Header Field with Indexing
+ // http://http2.github.io/http2-spec/compression.html#rfc.section.C.2.1
+ {"C.2.1", dehex("400a 6375 7374 6f6d 2d6b 6579 0d63 7573 746f 6d2d 6865 6164 6572"),
+ []HeaderField{pair("custom-key", "custom-header")},
+ []HeaderField{pair("custom-key", "custom-header")},
+ },
+
+ // C.2.2 Literal Header Field without Indexing
+ // http://http2.github.io/http2-spec/compression.html#rfc.section.C.2.2
+ {"C.2.2", dehex("040c 2f73 616d 706c 652f 7061 7468"),
+ []HeaderField{pair(":path", "/sample/path")},
+ []HeaderField{}},
+
+ // C.2.3 Literal Header Field never Indexed
+ // http://http2.github.io/http2-spec/compression.html#rfc.section.C.2.3
+ {"C.2.3", dehex("1008 7061 7373 776f 7264 0673 6563 7265 74"),
+ []HeaderField{{"password", "secret", true}},
+ []HeaderField{}},
+
+ // C.2.4 Indexed Header Field
+ // http://http2.github.io/http2-spec/compression.html#rfc.section.C.2.4
+ {"C.2.4", []byte("\x82"),
+ []HeaderField{pair(":method", "GET")},
+ []HeaderField{}},
+ }
+ for _, tt := range tests {
+ d := NewDecoder(4096, nil)
+ hf, err := d.DecodeFull(tt.in)
+ if err != nil {
+ t.Errorf("%s: %v", tt.name, err)
+ continue
+ }
+ if !reflect.DeepEqual(hf, tt.want) {
+ t.Errorf("%s: Got %v; want %v", tt.name, hf, tt.want)
+ }
+ gotDynTab := d.dynTab.reverseCopy()
+ if !reflect.DeepEqual(gotDynTab, tt.wantDynTab) {
+ t.Errorf("%s: dynamic table after = %v; want %v", tt.name, gotDynTab, tt.wantDynTab)
+ }
+ }
+}
+
+func (dt *dynamicTable) reverseCopy() (hf []HeaderField) {
+ hf = make([]HeaderField, len(dt.ents))
+ for i := range hf {
+ hf[i] = dt.ents[len(dt.ents)-1-i]
+ }
+ return
+}
+
+type encAndWant struct {
+ enc []byte
+ want []HeaderField
+ wantDynTab []HeaderField
+ wantDynSize uint32
+}
+
+// C.3 Request Examples without Huffman Coding
+// http://http2.github.io/http2-spec/compression.html#rfc.section.C.3
+func TestDecodeC3_NoHuffman(t *testing.T) {
+ testDecodeSeries(t, 4096, []encAndWant{
+ {dehex("8286 8441 0f77 7777 2e65 7861 6d70 6c65 2e63 6f6d"),
+ []HeaderField{
+ pair(":method", "GET"),
+ pair(":scheme", "http"),
+ pair(":path", "/"),
+ pair(":authority", "www.example.com"),
+ },
+ []HeaderField{
+ pair(":authority", "www.example.com"),
+ },
+ 57,
+ },
+ {dehex("8286 84be 5808 6e6f 2d63 6163 6865"),
+ []HeaderField{
+ pair(":method", "GET"),
+ pair(":scheme", "http"),
+ pair(":path", "/"),
+ pair(":authority", "www.example.com"),
+ pair("cache-control", "no-cache"),
+ },
+ []HeaderField{
+ pair("cache-control", "no-cache"),
+ pair(":authority", "www.example.com"),
+ },
+ 110,
+ },
+ {dehex("8287 85bf 400a 6375 7374 6f6d 2d6b 6579 0c63 7573 746f 6d2d 7661 6c75 65"),
+ []HeaderField{
+ pair(":method", "GET"),
+ pair(":scheme", "https"),
+ pair(":path", "/index.html"),
+ pair(":authority", "www.example.com"),
+ pair("custom-key", "custom-value"),
+ },
+ []HeaderField{
+ pair("custom-key", "custom-value"),
+ pair("cache-control", "no-cache"),
+ pair(":authority", "www.example.com"),
+ },
+ 164,
+ },
+ })
+}
+
+// C.4 Request Examples with Huffman Coding
+// http://http2.github.io/http2-spec/compression.html#rfc.section.C.4
+func TestDecodeC4_Huffman(t *testing.T) {
+ testDecodeSeries(t, 4096, []encAndWant{
+ {dehex("8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4 ff"),
+ []HeaderField{
+ pair(":method", "GET"),
+ pair(":scheme", "http"),
+ pair(":path", "/"),
+ pair(":authority", "www.example.com"),
+ },
+ []HeaderField{
+ pair(":authority", "www.example.com"),
+ },
+ 57,
+ },
+ {dehex("8286 84be 5886 a8eb 1064 9cbf"),
+ []HeaderField{
+ pair(":method", "GET"),
+ pair(":scheme", "http"),
+ pair(":path", "/"),
+ pair(":authority", "www.example.com"),
+ pair("cache-control", "no-cache"),
+ },
+ []HeaderField{
+ pair("cache-control", "no-cache"),
+ pair(":authority", "www.example.com"),
+ },
+ 110,
+ },
+ {dehex("8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925 a849 e95b b8e8 b4bf"),
+ []HeaderField{
+ pair(":method", "GET"),
+ pair(":scheme", "https"),
+ pair(":path", "/index.html"),
+ pair(":authority", "www.example.com"),
+ pair("custom-key", "custom-value"),
+ },
+ []HeaderField{
+ pair("custom-key", "custom-value"),
+ pair("cache-control", "no-cache"),
+ pair(":authority", "www.example.com"),
+ },
+ 164,
+ },
+ })
+}
+
+// http://http2.github.io/http2-spec/compression.html#rfc.section.C.5
+// "This section shows several consecutive header lists, corresponding
+// to HTTP responses, on the same connection. The HTTP/2 setting
+// parameter SETTINGS_HEADER_TABLE_SIZE is set to the value of 256
+// octets, causing some evictions to occur."
+func TestDecodeC5_ResponsesNoHuff(t *testing.T) {
+ testDecodeSeries(t, 256, []encAndWant{
+ {dehex(`
+4803 3330 3258 0770 7269 7661 7465 611d
+4d6f 6e2c 2032 3120 4f63 7420 3230 3133
+2032 303a 3133 3a32 3120 474d 546e 1768
+7474 7073 3a2f 2f77 7777 2e65 7861 6d70
+6c65 2e63 6f6d
+`),
+ []HeaderField{
+ pair(":status", "302"),
+ pair("cache-control", "private"),
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
+ pair("location", "https://www.example.com"),
+ },
+ []HeaderField{
+ pair("location", "https://www.example.com"),
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
+ pair("cache-control", "private"),
+ pair(":status", "302"),
+ },
+ 222,
+ },
+ {dehex("4803 3330 37c1 c0bf"),
+ []HeaderField{
+ pair(":status", "307"),
+ pair("cache-control", "private"),
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
+ pair("location", "https://www.example.com"),
+ },
+ []HeaderField{
+ pair(":status", "307"),
+ pair("location", "https://www.example.com"),
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
+ pair("cache-control", "private"),
+ },
+ 222,
+ },
+ {dehex(`
+88c1 611d 4d6f 6e2c 2032 3120 4f63 7420
+3230 3133 2032 303a 3133 3a32 3220 474d
+54c0 5a04 677a 6970 7738 666f 6f3d 4153
+444a 4b48 514b 425a 584f 5157 454f 5049
+5541 5851 5745 4f49 553b 206d 6178 2d61
+6765 3d33 3630 303b 2076 6572 7369 6f6e
+3d31
+`),
+ []HeaderField{
+ pair(":status", "200"),
+ pair("cache-control", "private"),
+ pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
+ pair("location", "https://www.example.com"),
+ pair("content-encoding", "gzip"),
+ pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
+ },
+ []HeaderField{
+ pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
+ pair("content-encoding", "gzip"),
+ pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
+ },
+ 215,
+ },
+ })
+}
+
+// http://http2.github.io/http2-spec/compression.html#rfc.section.C.6
+// "This section shows the same examples as the previous section, but
+// using Huffman encoding for the literal values. The HTTP/2 setting
+// parameter SETTINGS_HEADER_TABLE_SIZE is set to the value of 256
+// octets, causing some evictions to occur. The eviction mechanism
+// uses the length of the decoded literal values, so the same
+// evictions occurs as in the previous section."
+func TestDecodeC6_ResponsesHuffman(t *testing.T) {
+ testDecodeSeries(t, 256, []encAndWant{
+ {dehex(`
+4882 6402 5885 aec3 771a 4b61 96d0 7abe
+9410 54d4 44a8 2005 9504 0b81 66e0 82a6
+2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8
+e9ae 82ae 43d3
+`),
+ []HeaderField{
+ pair(":status", "302"),
+ pair("cache-control", "private"),
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
+ pair("location", "https://www.example.com"),
+ },
+ []HeaderField{
+ pair("location", "https://www.example.com"),
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
+ pair("cache-control", "private"),
+ pair(":status", "302"),
+ },
+ 222,
+ },
+ {dehex("4883 640e ffc1 c0bf"),
+ []HeaderField{
+ pair(":status", "307"),
+ pair("cache-control", "private"),
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
+ pair("location", "https://www.example.com"),
+ },
+ []HeaderField{
+ pair(":status", "307"),
+ pair("location", "https://www.example.com"),
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
+ pair("cache-control", "private"),
+ },
+ 222,
+ },
+ {dehex(`
+88c1 6196 d07a be94 1054 d444 a820 0595
+040b 8166 e084 a62d 1bff c05a 839b d9ab
+77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b
+3960 d5af 2708 7f36 72c1 ab27 0fb5 291f
+9587 3160 65c0 03ed 4ee5 b106 3d50 07
+`),
+ []HeaderField{
+ pair(":status", "200"),
+ pair("cache-control", "private"),
+ pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
+ pair("location", "https://www.example.com"),
+ pair("content-encoding", "gzip"),
+ pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
+ },
+ []HeaderField{
+ pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
+ pair("content-encoding", "gzip"),
+ pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
+ },
+ 215,
+ },
+ })
+}
+
+func testDecodeSeries(t *testing.T, size uint32, steps []encAndWant) {
+ d := NewDecoder(size, nil)
+ for i, step := range steps {
+ hf, err := d.DecodeFull(step.enc)
+ if err != nil {
+ t.Fatalf("Error at step index %d: %v", i, err)
+ }
+ if !reflect.DeepEqual(hf, step.want) {
+ t.Fatalf("At step index %d: Got headers %v; want %v", i, hf, step.want)
+ }
+ gotDynTab := d.dynTab.reverseCopy()
+ if !reflect.DeepEqual(gotDynTab, step.wantDynTab) {
+ t.Errorf("After step index %d, dynamic table = %v; want %v", i, gotDynTab, step.wantDynTab)
+ }
+ if d.dynTab.size != step.wantDynSize {
+ t.Errorf("After step index %d, dynamic table size = %v; want %v", i, d.dynTab.size, step.wantDynSize)
+ }
+ }
+}
+
+func TestHuffmanDecodeExcessPadding(t *testing.T) {
+ tests := [][]byte{
+ {0xff}, // Padding Exceeds 7 bits
+ {0x1f, 0xff}, // {"a", 1 byte excess padding}
+ {0x1f, 0xff, 0xff}, // {"a", 2 byte excess padding}
+ {0x1f, 0xff, 0xff, 0xff}, // {"a", 3 byte excess padding}
+ {0xff, 0x9f, 0xff, 0xff, 0xff}, // {"a", 29 bit excess padding}
+ {'R', 0xbc, '0', 0xff, 0xff, 0xff, 0xff}, // Padding ends on partial symbol.
+ }
+ for i, in := range tests {
+ var buf bytes.Buffer
+ if _, err := HuffmanDecode(&buf, in); err != ErrInvalidHuffman {
+ t.Errorf("test-%d: decode(%q) = %v; want ErrInvalidHuffman", i, in, err)
+ }
+ }
+}
+
+func TestHuffmanDecodeEOS(t *testing.T) {
+ in := []byte{0xff, 0xff, 0xff, 0xff, 0xfc} // {EOS, "?"}
+ var buf bytes.Buffer
+ if _, err := HuffmanDecode(&buf, in); err != ErrInvalidHuffman {
+ t.Errorf("error = %v; want ErrInvalidHuffman", err)
+ }
+}
+
+func TestHuffmanDecodeMaxLengthOnTrailingByte(t *testing.T) {
+ in := []byte{0x00, 0x01} // {"0", "0", "0"}
+ var buf bytes.Buffer
+ if err := huffmanDecode(&buf, 2, in); err != ErrStringLength {
+ t.Errorf("error = %v; want ErrStringLength", err)
+ }
+}
+
+func TestHuffmanDecodeCorruptPadding(t *testing.T) {
+ in := []byte{0x00}
+ var buf bytes.Buffer
+ if _, err := HuffmanDecode(&buf, in); err != ErrInvalidHuffman {
+ t.Errorf("error = %v; want ErrInvalidHuffman", err)
+ }
+}
+
+func TestHuffmanDecode(t *testing.T) {
+ tests := []struct {
+ inHex, want string
+ }{
+ {"f1e3 c2e5 f23a 6ba0 ab90 f4ff", "www.example.com"},
+ {"a8eb 1064 9cbf", "no-cache"},
+ {"25a8 49e9 5ba9 7d7f", "custom-key"},
+ {"25a8 49e9 5bb8 e8b4 bf", "custom-value"},
+ {"6402", "302"},
+ {"aec3 771a 4b", "private"},
+ {"d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff", "Mon, 21 Oct 2013 20:13:21 GMT"},
+ {"9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3", "https://www.example.com"},
+ {"9bd9 ab", "gzip"},
+ {"94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 3160 65c0 03ed 4ee5 b106 3d50 07",
+ "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"},
+ }
+ for i, tt := range tests {
+ var buf bytes.Buffer
+ in, err := hex.DecodeString(strings.Replace(tt.inHex, " ", "", -1))
+ if err != nil {
+ t.Errorf("%d. hex input error: %v", i, err)
+ continue
+ }
+ if _, err := HuffmanDecode(&buf, in); err != nil {
+ t.Errorf("%d. decode error: %v", i, err)
+ continue
+ }
+ if got := buf.String(); tt.want != got {
+ t.Errorf("%d. decode = %q; want %q", i, got, tt.want)
+ }
+ }
+}
+
+func TestAppendHuffmanString(t *testing.T) {
+ tests := []struct {
+ in, want string
+ }{
+ {"www.example.com", "f1e3 c2e5 f23a 6ba0 ab90 f4ff"},
+ {"no-cache", "a8eb 1064 9cbf"},
+ {"custom-key", "25a8 49e9 5ba9 7d7f"},
+ {"custom-value", "25a8 49e9 5bb8 e8b4 bf"},
+ {"302", "6402"},
+ {"private", "aec3 771a 4b"},
+ {"Mon, 21 Oct 2013 20:13:21 GMT", "d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff"},
+ {"https://www.example.com", "9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3"},
+ {"gzip", "9bd9 ab"},
+ {"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
+ "94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 3160 65c0 03ed 4ee5 b106 3d50 07"},
+ }
+ for i, tt := range tests {
+ buf := []byte{}
+ want := strings.Replace(tt.want, " ", "", -1)
+ buf = AppendHuffmanString(buf, tt.in)
+ if got := hex.EncodeToString(buf); want != got {
+ t.Errorf("%d. encode = %q; want %q", i, got, want)
+ }
+ }
+}
+
+func TestHuffmanMaxStrLen(t *testing.T) {
+ const msg = "Some string"
+ huff := AppendHuffmanString(nil, msg)
+
+ testGood := func(max int) {
+ var out bytes.Buffer
+ if err := huffmanDecode(&out, max, huff); err != nil {
+ t.Errorf("For maxLen=%d, unexpected error: %v", max, err)
+ }
+ if out.String() != msg {
+ t.Errorf("For maxLen=%d, out = %q; want %q", max, out.String(), msg)
+ }
+ }
+ testGood(0)
+ testGood(len(msg))
+ testGood(len(msg) + 1)
+
+ var out bytes.Buffer
+ if err := huffmanDecode(&out, len(msg)-1, huff); err != ErrStringLength {
+ t.Errorf("err = %v; want ErrStringLength", err)
+ }
+}
+
+func TestHuffmanRoundtripStress(t *testing.T) {
+ const Len = 50 // of uncompressed string
+ input := make([]byte, Len)
+ var output bytes.Buffer
+ var huff []byte
+
+ n := 5000
+ if testing.Short() {
+ n = 100
+ }
+ seed := time.Now().UnixNano()
+ t.Logf("Seed = %v", seed)
+ src := rand.New(rand.NewSource(seed))
+ var encSize int64
+ for i := 0; i < n; i++ {
+ for l := range input {
+ input[l] = byte(src.Intn(256))
+ }
+ huff = AppendHuffmanString(huff[:0], string(input))
+ encSize += int64(len(huff))
+ output.Reset()
+ if err := huffmanDecode(&output, 0, huff); err != nil {
+ t.Errorf("Failed to decode %q -> %q -> error %v", input, huff, err)
+ continue
+ }
+ if !bytes.Equal(output.Bytes(), input) {
+ t.Errorf("Roundtrip failure on %q -> %q -> %q", input, huff, output.Bytes())
+ }
+ }
+ t.Logf("Compressed size of original: %0.02f%% (%v -> %v)", 100*(float64(encSize)/(Len*float64(n))), Len*n, encSize)
+}
+
+func TestHuffmanDecodeFuzz(t *testing.T) {
+ const Len = 50 // of compressed
+ var buf, zbuf bytes.Buffer
+
+ n := 5000
+ if testing.Short() {
+ n = 100
+ }
+ seed := time.Now().UnixNano()
+ t.Logf("Seed = %v", seed)
+ src := rand.New(rand.NewSource(seed))
+ numFail := 0
+ for i := 0; i < n; i++ {
+ zbuf.Reset()
+ if i == 0 {
+ // Start with at least one invalid one.
+ zbuf.WriteString("00\x91\xff\xff\xff\xff\xc8")
+ } else {
+ for l := 0; l < Len; l++ {
+ zbuf.WriteByte(byte(src.Intn(256)))
+ }
+ }
+
+ buf.Reset()
+ if err := huffmanDecode(&buf, 0, zbuf.Bytes()); err != nil {
+ if err == ErrInvalidHuffman {
+ numFail++
+ continue
+ }
+ t.Errorf("Failed to decode %q: %v", zbuf.Bytes(), err)
+ continue
+ }
+ }
+ t.Logf("%0.02f%% are invalid (%d / %d)", 100*float64(numFail)/float64(n), numFail, n)
+ if numFail < 1 {
+ t.Error("expected at least one invalid huffman encoding (test starts with one)")
+ }
+}
+
+func TestReadVarInt(t *testing.T) {
+ type res struct {
+ i uint64
+ consumed int
+ err error
+ }
+ tests := []struct {
+ n byte
+ p []byte
+ want res
+ }{
+ // Fits in a byte:
+ {1, []byte{0}, res{0, 1, nil}},
+ {2, []byte{2}, res{2, 1, nil}},
+ {3, []byte{6}, res{6, 1, nil}},
+ {4, []byte{14}, res{14, 1, nil}},
+ {5, []byte{30}, res{30, 1, nil}},
+ {6, []byte{62}, res{62, 1, nil}},
+ {7, []byte{126}, res{126, 1, nil}},
+ {8, []byte{254}, res{254, 1, nil}},
+
+ // Doesn't fit in a byte:
+ {1, []byte{1}, res{0, 0, errNeedMore}},
+ {2, []byte{3}, res{0, 0, errNeedMore}},
+ {3, []byte{7}, res{0, 0, errNeedMore}},
+ {4, []byte{15}, res{0, 0, errNeedMore}},
+ {5, []byte{31}, res{0, 0, errNeedMore}},
+ {6, []byte{63}, res{0, 0, errNeedMore}},
+ {7, []byte{127}, res{0, 0, errNeedMore}},
+ {8, []byte{255}, res{0, 0, errNeedMore}},
+
+ // Ignoring top bits:
+ {5, []byte{255, 154, 10}, res{1337, 3, nil}}, // high dummy three bits: 111
+ {5, []byte{159, 154, 10}, res{1337, 3, nil}}, // high dummy three bits: 100
+ {5, []byte{191, 154, 10}, res{1337, 3, nil}}, // high dummy three bits: 101
+
+ // Extra byte:
+ {5, []byte{191, 154, 10, 2}, res{1337, 3, nil}}, // extra byte
+
+ // Short a byte:
+ {5, []byte{191, 154}, res{0, 0, errNeedMore}},
+
+ // integer overflow:
+ {1, []byte{255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, res{0, 0, errVarintOverflow}},
+ }
+ for _, tt := range tests {
+ i, remain, err := readVarInt(tt.n, tt.p)
+ consumed := len(tt.p) - len(remain)
+ got := res{i, consumed, err}
+ if got != tt.want {
+ t.Errorf("readVarInt(%d, %v ~ %x) = %+v; want %+v", tt.n, tt.p, tt.p, got, tt.want)
+ }
+ }
+}
+
+// Fuzz crash, originally reported at https://github.com/bradfitz/http2/issues/56
+func TestHuffmanFuzzCrash(t *testing.T) {
+ got, err := HuffmanDecodeToString([]byte("00\x91\xff\xff\xff\xff\xc8"))
+ if got != "" {
+ t.Errorf("Got %q; want empty string", got)
+ }
+ if err != ErrInvalidHuffman {
+ t.Errorf("Err = %v; want ErrInvalidHuffman", err)
+ }
+}
+
+func dehex(s string) []byte {
+ s = strings.Replace(s, " ", "", -1)
+ s = strings.Replace(s, "\n", "", -1)
+ b, err := hex.DecodeString(s)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
+
+func TestEmitEnabled(t *testing.T) {
+ var buf bytes.Buffer
+ enc := NewEncoder(&buf)
+ enc.WriteField(HeaderField{Name: "foo", Value: "bar"})
+ enc.WriteField(HeaderField{Name: "foo", Value: "bar"})
+
+ numCallback := 0
+ var dec *Decoder
+ dec = NewDecoder(8<<20, func(HeaderField) {
+ numCallback++
+ dec.SetEmitEnabled(false)
+ })
+ if !dec.EmitEnabled() {
+ t.Errorf("initial emit enabled = false; want true")
+ }
+ if _, err := dec.Write(buf.Bytes()); err != nil {
+ t.Error(err)
+ }
+ if numCallback != 1 {
+ t.Errorf("num callbacks = %d; want 1", numCallback)
+ }
+ if dec.EmitEnabled() {
+ t.Errorf("emit enabled = true; want false")
+ }
+}
+
+func TestSaveBufLimit(t *testing.T) {
+ const maxStr = 1 << 10
+ var got []HeaderField
+ dec := NewDecoder(initialHeaderTableSize, func(hf HeaderField) {
+ got = append(got, hf)
+ })
+ dec.SetMaxStringLength(maxStr)
+ var frag []byte
+ frag = append(frag[:0], encodeTypeByte(false, false))
+ frag = appendVarInt(frag, 7, 3)
+ frag = append(frag, "foo"...)
+ frag = appendVarInt(frag, 7, 3)
+ frag = append(frag, "bar"...)
+
+ if _, err := dec.Write(frag); err != nil {
+ t.Fatal(err)
+ }
+
+ want := []HeaderField{{Name: "foo", Value: "bar"}}
+ if !reflect.DeepEqual(got, want) {
+ t.Errorf("After small writes, got %v; want %v", got, want)
+ }
+
+ frag = append(frag[:0], encodeTypeByte(false, false))
+ frag = appendVarInt(frag, 7, maxStr*3)
+ frag = append(frag, make([]byte, maxStr*3)...)
+
+ _, err := dec.Write(frag)
+ if err != ErrStringLength {
+ t.Fatalf("Write error = %v; want ErrStringLength", err)
+ }
+}
diff --git a/libgo/go/golang_org/x/net/http2/hpack/huffman.go b/libgo/go/golang_org/x/net/http2/hpack/huffman.go
new file mode 100644
index 00000000000..8850e394677
--- /dev/null
+++ b/libgo/go/golang_org/x/net/http2/hpack/huffman.go
@@ -0,0 +1,212 @@
+// 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 hpack
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "sync"
+)
+
+var bufPool = sync.Pool{
+ New: func() interface{} { return new(bytes.Buffer) },
+}
+
+// HuffmanDecode decodes the string in v and writes the expanded
+// result to w, returning the number of bytes written to w and the
+// Write call's return value. At most one Write call is made.
+func HuffmanDecode(w io.Writer, v []byte) (int, error) {
+ buf := bufPool.Get().(*bytes.Buffer)
+ buf.Reset()
+ defer bufPool.Put(buf)
+ if err := huffmanDecode(buf, 0, v); err != nil {
+ return 0, err
+ }
+ return w.Write(buf.Bytes())
+}
+
+// HuffmanDecodeToString decodes the string in v.
+func HuffmanDecodeToString(v []byte) (string, error) {
+ buf := bufPool.Get().(*bytes.Buffer)
+ buf.Reset()
+ defer bufPool.Put(buf)
+ if err := huffmanDecode(buf, 0, v); err != nil {
+ return "", err
+ }
+ return buf.String(), nil
+}
+
+// ErrInvalidHuffman is returned for errors found decoding
+// Huffman-encoded strings.
+var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data")
+
+// huffmanDecode decodes v to buf.
+// If maxLen is greater than 0, attempts to write more to buf than
+// maxLen bytes will return ErrStringLength.
+func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
+ n := rootHuffmanNode
+ // cur is the bit buffer that has not been fed into n.
+ // cbits is the number of low order bits in cur that are valid.
+ // sbits is the number of bits of the symbol prefix being decoded.
+ cur, cbits, sbits := uint(0), uint8(0), uint8(0)
+ for _, b := range v {
+ cur = cur<<8 | uint(b)
+ cbits += 8
+ sbits += 8
+ for cbits >= 8 {
+ idx := byte(cur >> (cbits - 8))
+ n = n.children[idx]
+ if n == nil {
+ return ErrInvalidHuffman
+ }
+ if n.children == nil {
+ if maxLen != 0 && buf.Len() == maxLen {
+ return ErrStringLength
+ }
+ buf.WriteByte(n.sym)
+ cbits -= n.codeLen
+ n = rootHuffmanNode
+ sbits = cbits
+ } else {
+ cbits -= 8
+ }
+ }
+ }
+ for cbits > 0 {
+ n = n.children[byte(cur<<(8-cbits))]
+ if n == nil {
+ return ErrInvalidHuffman
+ }
+ if n.children != nil || n.codeLen > cbits {
+ break
+ }
+ if maxLen != 0 && buf.Len() == maxLen {
+ return ErrStringLength
+ }
+ buf.WriteByte(n.sym)
+ cbits -= n.codeLen
+ n = rootHuffmanNode
+ sbits = cbits
+ }
+ if sbits > 7 {
+ // Either there was an incomplete symbol, or overlong padding.
+ // Both are decoding errors per RFC 7541 section 5.2.
+ return ErrInvalidHuffman
+ }
+ if mask := uint(1<<cbits - 1); cur&mask != mask {
+ // Trailing bits must be a prefix of EOS per RFC 7541 section 5.2.
+ return ErrInvalidHuffman
+ }
+
+ return nil
+}
+
+type node struct {
+ // children is non-nil for internal nodes
+ children []*node
+
+ // The following are only valid if children is nil:
+ codeLen uint8 // number of bits that led to the output of sym
+ sym byte // output symbol
+}
+
+func newInternalNode() *node {
+ return &node{children: make([]*node, 256)}
+}
+
+var rootHuffmanNode = newInternalNode()
+
+func init() {
+ if len(huffmanCodes) != 256 {
+ panic("unexpected size")
+ }
+ for i, code := range huffmanCodes {
+ addDecoderNode(byte(i), code, huffmanCodeLen[i])
+ }
+}
+
+func addDecoderNode(sym byte, code uint32, codeLen uint8) {
+ cur := rootHuffmanNode
+ for codeLen > 8 {
+ codeLen -= 8
+ i := uint8(code >> codeLen)
+ if cur.children[i] == nil {
+ cur.children[i] = newInternalNode()
+ }
+ cur = cur.children[i]
+ }
+ shift := 8 - codeLen
+ start, end := int(uint8(code<<shift)), int(1<<shift)
+ for i := start; i < start+end; i++ {
+ cur.children[i] = &node{sym: sym, codeLen: codeLen}
+ }
+}
+
+// AppendHuffmanString appends s, as encoded in Huffman codes, to dst
+// and returns the extended buffer.
+func AppendHuffmanString(dst []byte, s string) []byte {
+ rembits := uint8(8)
+
+ for i := 0; i < len(s); i++ {
+ if rembits == 8 {
+ dst = append(dst, 0)
+ }
+ dst, rembits = appendByteToHuffmanCode(dst, rembits, s[i])
+ }
+
+ if rembits < 8 {
+ // special EOS symbol
+ code := uint32(0x3fffffff)
+ nbits := uint8(30)
+
+ t := uint8(code >> (nbits - rembits))
+ dst[len(dst)-1] |= t
+ }
+
+ return dst
+}
+
+// HuffmanEncodeLength returns the number of bytes required to encode
+// s in Huffman codes. The result is round up to byte boundary.
+func HuffmanEncodeLength(s string) uint64 {
+ n := uint64(0)
+ for i := 0; i < len(s); i++ {
+ n += uint64(huffmanCodeLen[s[i]])
+ }
+ return (n + 7) / 8
+}
+
+// appendByteToHuffmanCode appends Huffman code for c to dst and
+// returns the extended buffer and the remaining bits in the last
+// element. The appending is not byte aligned and the remaining bits
+// in the last element of dst is given in rembits.
+func appendByteToHuffmanCode(dst []byte, rembits uint8, c byte) ([]byte, uint8) {
+ code := huffmanCodes[c]
+ nbits := huffmanCodeLen[c]
+
+ for {
+ if rembits > nbits {
+ t := uint8(code << (rembits - nbits))
+ dst[len(dst)-1] |= t
+ rembits -= nbits
+ break
+ }
+
+ t := uint8(code >> (nbits - rembits))
+ dst[len(dst)-1] |= t
+
+ nbits -= rembits
+ rembits = 8
+
+ if nbits == 0 {
+ break
+ }
+
+ dst = append(dst, 0)
+ }
+
+ return dst, rembits
+}
diff --git a/libgo/go/golang_org/x/net/http2/hpack/tables.go b/libgo/go/golang_org/x/net/http2/hpack/tables.go
new file mode 100644
index 00000000000..b9283a02330
--- /dev/null
+++ b/libgo/go/golang_org/x/net/http2/hpack/tables.go
@@ -0,0 +1,352 @@
+// 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 hpack
+
+func pair(name, value string) HeaderField {
+ return HeaderField{Name: name, Value: value}
+}
+
+// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B
+var staticTable = [...]HeaderField{
+ pair(":authority", ""), // index 1 (1-based)
+ pair(":method", "GET"),
+ pair(":method", "POST"),
+ pair(":path", "/"),
+ pair(":path", "/index.html"),
+ pair(":scheme", "http"),
+ pair(":scheme", "https"),
+ pair(":status", "200"),
+ pair(":status", "204"),
+ pair(":status", "206"),
+ pair(":status", "304"),
+ pair(":status", "400"),
+ pair(":status", "404"),
+ pair(":status", "500"),
+ pair("accept-charset", ""),
+ pair("accept-encoding", "gzip, deflate"),
+ pair("accept-language", ""),
+ pair("accept-ranges", ""),
+ pair("accept", ""),
+ pair("access-control-allow-origin", ""),
+ pair("age", ""),
+ pair("allow", ""),
+ pair("authorization", ""),
+ pair("cache-control", ""),
+ pair("content-disposition", ""),
+ pair("content-encoding", ""),
+ pair("content-language", ""),
+ pair("content-length", ""),
+ pair("content-location", ""),
+ pair("content-range", ""),
+ pair("content-type", ""),
+ pair("cookie", ""),
+ pair("date", ""),
+ pair("etag", ""),
+ pair("expect", ""),
+ pair("expires", ""),
+ pair("from", ""),
+ pair("host", ""),
+ pair("if-match", ""),
+ pair("if-modified-since", ""),
+ pair("if-none-match", ""),
+ pair("if-range", ""),
+ pair("if-unmodified-since", ""),
+ pair("last-modified", ""),
+ pair("link", ""),
+ pair("location", ""),
+ pair("max-forwards", ""),
+ pair("proxy-authenticate", ""),
+ pair("proxy-authorization", ""),
+ pair("range", ""),
+ pair("referer", ""),
+ pair("refresh", ""),
+ pair("retry-after", ""),
+ pair("server", ""),
+ pair("set-cookie", ""),
+ pair("strict-transport-security", ""),
+ pair("transfer-encoding", ""),
+ pair("user-agent", ""),
+ pair("vary", ""),
+ pair("via", ""),
+ pair("www-authenticate", ""),
+}
+
+var huffmanCodes = [256]uint32{
+ 0x1ff8,
+ 0x7fffd8,
+ 0xfffffe2,
+ 0xfffffe3,
+ 0xfffffe4,
+ 0xfffffe5,
+ 0xfffffe6,
+ 0xfffffe7,
+ 0xfffffe8,
+ 0xffffea,
+ 0x3ffffffc,
+ 0xfffffe9,
+ 0xfffffea,
+ 0x3ffffffd,
+ 0xfffffeb,
+ 0xfffffec,
+ 0xfffffed,
+ 0xfffffee,
+ 0xfffffef,
+ 0xffffff0,
+ 0xffffff1,
+ 0xffffff2,
+ 0x3ffffffe,
+ 0xffffff3,
+ 0xffffff4,
+ 0xffffff5,
+ 0xffffff6,
+ 0xffffff7,
+ 0xffffff8,
+ 0xffffff9,
+ 0xffffffa,
+ 0xffffffb,
+ 0x14,
+ 0x3f8,
+ 0x3f9,
+ 0xffa,
+ 0x1ff9,
+ 0x15,
+ 0xf8,
+ 0x7fa,
+ 0x3fa,
+ 0x3fb,
+ 0xf9,
+ 0x7fb,
+ 0xfa,
+ 0x16,
+ 0x17,
+ 0x18,
+ 0x0,
+ 0x1,
+ 0x2,
+ 0x19,
+ 0x1a,
+ 0x1b,
+ 0x1c,
+ 0x1d,
+ 0x1e,
+ 0x1f,
+ 0x5c,
+ 0xfb,
+ 0x7ffc,
+ 0x20,
+ 0xffb,
+ 0x3fc,
+ 0x1ffa,
+ 0x21,
+ 0x5d,
+ 0x5e,
+ 0x5f,
+ 0x60,
+ 0x61,
+ 0x62,
+ 0x63,
+ 0x64,
+ 0x65,
+ 0x66,
+ 0x67,
+ 0x68,
+ 0x69,
+ 0x6a,
+ 0x6b,
+ 0x6c,
+ 0x6d,
+ 0x6e,
+ 0x6f,
+ 0x70,
+ 0x71,
+ 0x72,
+ 0xfc,
+ 0x73,
+ 0xfd,
+ 0x1ffb,
+ 0x7fff0,
+ 0x1ffc,
+ 0x3ffc,
+ 0x22,
+ 0x7ffd,
+ 0x3,
+ 0x23,
+ 0x4,
+ 0x24,
+ 0x5,
+ 0x25,
+ 0x26,
+ 0x27,
+ 0x6,
+ 0x74,
+ 0x75,
+ 0x28,
+ 0x29,
+ 0x2a,
+ 0x7,
+ 0x2b,
+ 0x76,
+ 0x2c,
+ 0x8,
+ 0x9,
+ 0x2d,
+ 0x77,
+ 0x78,
+ 0x79,
+ 0x7a,
+ 0x7b,
+ 0x7ffe,
+ 0x7fc,
+ 0x3ffd,
+ 0x1ffd,
+ 0xffffffc,
+ 0xfffe6,
+ 0x3fffd2,
+ 0xfffe7,
+ 0xfffe8,
+ 0x3fffd3,
+ 0x3fffd4,
+ 0x3fffd5,
+ 0x7fffd9,
+ 0x3fffd6,
+ 0x7fffda,
+ 0x7fffdb,
+ 0x7fffdc,
+ 0x7fffdd,
+ 0x7fffde,
+ 0xffffeb,
+ 0x7fffdf,
+ 0xffffec,
+ 0xffffed,
+ 0x3fffd7,
+ 0x7fffe0,
+ 0xffffee,
+ 0x7fffe1,
+ 0x7fffe2,
+ 0x7fffe3,
+ 0x7fffe4,
+ 0x1fffdc,
+ 0x3fffd8,
+ 0x7fffe5,
+ 0x3fffd9,
+ 0x7fffe6,
+ 0x7fffe7,
+ 0xffffef,
+ 0x3fffda,
+ 0x1fffdd,
+ 0xfffe9,
+ 0x3fffdb,
+ 0x3fffdc,
+ 0x7fffe8,
+ 0x7fffe9,
+ 0x1fffde,
+ 0x7fffea,
+ 0x3fffdd,
+ 0x3fffde,
+ 0xfffff0,
+ 0x1fffdf,
+ 0x3fffdf,
+ 0x7fffeb,
+ 0x7fffec,
+ 0x1fffe0,
+ 0x1fffe1,
+ 0x3fffe0,
+ 0x1fffe2,
+ 0x7fffed,
+ 0x3fffe1,
+ 0x7fffee,
+ 0x7fffef,
+ 0xfffea,
+ 0x3fffe2,
+ 0x3fffe3,
+ 0x3fffe4,
+ 0x7ffff0,
+ 0x3fffe5,
+ 0x3fffe6,
+ 0x7ffff1,
+ 0x3ffffe0,
+ 0x3ffffe1,
+ 0xfffeb,
+ 0x7fff1,
+ 0x3fffe7,
+ 0x7ffff2,
+ 0x3fffe8,
+ 0x1ffffec,
+ 0x3ffffe2,
+ 0x3ffffe3,
+ 0x3ffffe4,
+ 0x7ffffde,
+ 0x7ffffdf,
+ 0x3ffffe5,
+ 0xfffff1,
+ 0x1ffffed,
+ 0x7fff2,
+ 0x1fffe3,
+ 0x3ffffe6,
+ 0x7ffffe0,
+ 0x7ffffe1,
+ 0x3ffffe7,
+ 0x7ffffe2,
+ 0xfffff2,
+ 0x1fffe4,
+ 0x1fffe5,
+ 0x3ffffe8,
+ 0x3ffffe9,
+ 0xffffffd,
+ 0x7ffffe3,
+ 0x7ffffe4,
+ 0x7ffffe5,
+ 0xfffec,
+ 0xfffff3,
+ 0xfffed,
+ 0x1fffe6,
+ 0x3fffe9,
+ 0x1fffe7,
+ 0x1fffe8,
+ 0x7ffff3,
+ 0x3fffea,
+ 0x3fffeb,
+ 0x1ffffee,
+ 0x1ffffef,
+ 0xfffff4,
+ 0xfffff5,
+ 0x3ffffea,
+ 0x7ffff4,
+ 0x3ffffeb,
+ 0x7ffffe6,
+ 0x3ffffec,
+ 0x3ffffed,
+ 0x7ffffe7,
+ 0x7ffffe8,
+ 0x7ffffe9,
+ 0x7ffffea,
+ 0x7ffffeb,
+ 0xffffffe,
+ 0x7ffffec,
+ 0x7ffffed,
+ 0x7ffffee,
+ 0x7ffffef,
+ 0x7fffff0,
+ 0x3ffffee,
+}
+
+var huffmanCodeLen = [256]uint8{
+ 13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28,
+ 28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6,
+ 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10,
+ 13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6,
+ 15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6, 6, 5,
+ 6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28,
+ 20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23,
+ 24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24,
+ 22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23,
+ 21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23,
+ 26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25,
+ 19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27,
+ 20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23,
+ 26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26,
+}
diff --git a/libgo/go/golang_org/x/net/lex/httplex/httplex.go b/libgo/go/golang_org/x/net/lex/httplex/httplex.go
new file mode 100644
index 00000000000..bd0ec24f444
--- /dev/null
+++ b/libgo/go/golang_org/x/net/lex/httplex/httplex.go
@@ -0,0 +1,312 @@
+// 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 httplex contains rules around lexical matters of various
+// HTTP-related specifications.
+//
+// This package is shared by the standard library (which vendors it)
+// and x/net/http2. It comes with no API stability promise.
+package httplex
+
+import (
+ "strings"
+ "unicode/utf8"
+)
+
+var isTokenTable = [127]bool{
+ '!': true,
+ '#': true,
+ '$': true,
+ '%': true,
+ '&': true,
+ '\'': true,
+ '*': true,
+ '+': true,
+ '-': true,
+ '.': true,
+ '0': true,
+ '1': true,
+ '2': true,
+ '3': true,
+ '4': true,
+ '5': true,
+ '6': true,
+ '7': true,
+ '8': true,
+ '9': true,
+ 'A': true,
+ 'B': true,
+ 'C': true,
+ 'D': true,
+ 'E': true,
+ 'F': true,
+ 'G': true,
+ 'H': true,
+ 'I': true,
+ 'J': true,
+ 'K': true,
+ 'L': true,
+ 'M': true,
+ 'N': true,
+ 'O': true,
+ 'P': true,
+ 'Q': true,
+ 'R': true,
+ 'S': true,
+ 'T': true,
+ 'U': true,
+ 'W': true,
+ 'V': true,
+ 'X': true,
+ 'Y': true,
+ 'Z': true,
+ '^': true,
+ '_': true,
+ '`': true,
+ 'a': true,
+ 'b': true,
+ 'c': true,
+ 'd': true,
+ 'e': true,
+ 'f': true,
+ 'g': true,
+ 'h': true,
+ 'i': true,
+ 'j': true,
+ 'k': true,
+ 'l': true,
+ 'm': true,
+ 'n': true,
+ 'o': true,
+ 'p': true,
+ 'q': true,
+ 'r': true,
+ 's': true,
+ 't': true,
+ 'u': true,
+ 'v': true,
+ 'w': true,
+ 'x': true,
+ 'y': true,
+ 'z': true,
+ '|': true,
+ '~': true,
+}
+
+func IsTokenRune(r rune) bool {
+ i := int(r)
+ return i < len(isTokenTable) && isTokenTable[i]
+}
+
+func isNotToken(r rune) bool {
+ return !IsTokenRune(r)
+}
+
+// HeaderValuesContainsToken reports whether any string in values
+// contains the provided token, ASCII case-insensitively.
+func HeaderValuesContainsToken(values []string, token string) bool {
+ for _, v := range values {
+ if headerValueContainsToken(v, token) {
+ return true
+ }
+ }
+ return false
+}
+
+// isOWS reports whether b is an optional whitespace byte, as defined
+// by RFC 7230 section 3.2.3.
+func isOWS(b byte) bool { return b == ' ' || b == '\t' }
+
+// trimOWS returns x with all optional whitespace removes from the
+// beginning and end.
+func trimOWS(x string) string {
+ // TODO: consider using strings.Trim(x, " \t") instead,
+ // if and when it's fast enough. See issue 10292.
+ // But this ASCII-only code will probably always beat UTF-8
+ // aware code.
+ for len(x) > 0 && isOWS(x[0]) {
+ x = x[1:]
+ }
+ for len(x) > 0 && isOWS(x[len(x)-1]) {
+ x = x[:len(x)-1]
+ }
+ return x
+}
+
+// headerValueContainsToken reports whether v (assumed to be a
+// 0#element, in the ABNF extension described in RFC 7230 section 7)
+// contains token amongst its comma-separated tokens, ASCII
+// case-insensitively.
+func headerValueContainsToken(v string, token string) bool {
+ v = trimOWS(v)
+ if comma := strings.IndexByte(v, ','); comma != -1 {
+ return tokenEqual(trimOWS(v[:comma]), token) || headerValueContainsToken(v[comma+1:], token)
+ }
+ return tokenEqual(v, token)
+}
+
+// lowerASCII returns the ASCII lowercase version of b.
+func lowerASCII(b byte) byte {
+ if 'A' <= b && b <= 'Z' {
+ return b + ('a' - 'A')
+ }
+ return b
+}
+
+// tokenEqual reports whether t1 and t2 are equal, ASCII case-insensitively.
+func tokenEqual(t1, t2 string) bool {
+ if len(t1) != len(t2) {
+ return false
+ }
+ for i, b := range t1 {
+ if b >= utf8.RuneSelf {
+ // No UTF-8 or non-ASCII allowed in tokens.
+ return false
+ }
+ if lowerASCII(byte(b)) != lowerASCII(t2[i]) {
+ return false
+ }
+ }
+ return true
+}
+
+// isLWS reports whether b is linear white space, according
+// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
+// LWS = [CRLF] 1*( SP | HT )
+func isLWS(b byte) bool { return b == ' ' || b == '\t' }
+
+// isCTL reports whether b is a control byte, according
+// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
+// CTL = <any US-ASCII control character
+// (octets 0 - 31) and DEL (127)>
+func isCTL(b byte) bool {
+ const del = 0x7f // a CTL
+ return b < ' ' || b == del
+}
+
+// ValidHeaderFieldName reports whether v is a valid HTTP/1.x header name.
+// HTTP/2 imposes the additional restriction that uppercase ASCII
+// letters are not allowed.
+//
+// RFC 7230 says:
+// header-field = field-name ":" OWS field-value OWS
+// field-name = token
+// token = 1*tchar
+// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
+// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
+func ValidHeaderFieldName(v string) bool {
+ if len(v) == 0 {
+ return false
+ }
+ for _, r := range v {
+ if !IsTokenRune(r) {
+ return false
+ }
+ }
+ return true
+}
+
+// ValidHostHeader reports whether h is a valid host header.
+func ValidHostHeader(h string) bool {
+ // The latest spec is actually this:
+ //
+ // http://tools.ietf.org/html/rfc7230#section-5.4
+ // Host = uri-host [ ":" port ]
+ //
+ // Where uri-host is:
+ // http://tools.ietf.org/html/rfc3986#section-3.2.2
+ //
+ // But we're going to be much more lenient for now and just
+ // search for any byte that's not a valid byte in any of those
+ // expressions.
+ for i := 0; i < len(h); i++ {
+ if !validHostByte[h[i]] {
+ return false
+ }
+ }
+ return true
+}
+
+// See the validHostHeader comment.
+var validHostByte = [256]bool{
+ '0': true, '1': true, '2': true, '3': true, '4': true, '5': true, '6': true, '7': true,
+ '8': true, '9': true,
+
+ 'a': true, 'b': true, 'c': true, 'd': true, 'e': true, 'f': true, 'g': true, 'h': true,
+ 'i': true, 'j': true, 'k': true, 'l': true, 'm': true, 'n': true, 'o': true, 'p': true,
+ 'q': true, 'r': true, 's': true, 't': true, 'u': true, 'v': true, 'w': true, 'x': true,
+ 'y': true, 'z': true,
+
+ 'A': true, 'B': true, 'C': true, 'D': true, 'E': true, 'F': true, 'G': true, 'H': true,
+ 'I': true, 'J': true, 'K': true, 'L': true, 'M': true, 'N': true, 'O': true, 'P': true,
+ 'Q': true, 'R': true, 'S': true, 'T': true, 'U': true, 'V': true, 'W': true, 'X': true,
+ 'Y': true, 'Z': true,
+
+ '!': true, // sub-delims
+ '$': true, // sub-delims
+ '%': true, // pct-encoded (and used in IPv6 zones)
+ '&': true, // sub-delims
+ '(': true, // sub-delims
+ ')': true, // sub-delims
+ '*': true, // sub-delims
+ '+': true, // sub-delims
+ ',': true, // sub-delims
+ '-': true, // unreserved
+ '.': true, // unreserved
+ ':': true, // IPv6address + Host expression's optional port
+ ';': true, // sub-delims
+ '=': true, // sub-delims
+ '[': true,
+ '\'': true, // sub-delims
+ ']': true,
+ '_': true, // unreserved
+ '~': true, // unreserved
+}
+
+// ValidHeaderFieldValue reports whether v is a valid "field-value" according to
+// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 :
+//
+// message-header = field-name ":" [ field-value ]
+// field-value = *( field-content | LWS )
+// field-content = <the OCTETs making up the field-value
+// and consisting of either *TEXT or combinations
+// of token, separators, and quoted-string>
+//
+// http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 :
+//
+// TEXT = <any OCTET except CTLs,
+// but including LWS>
+// LWS = [CRLF] 1*( SP | HT )
+// CTL = <any US-ASCII control character
+// (octets 0 - 31) and DEL (127)>
+//
+// RFC 7230 says:
+// field-value = *( field-content / obs-fold )
+// obj-fold = N/A to http2, and deprecated
+// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
+// field-vchar = VCHAR / obs-text
+// obs-text = %x80-FF
+// VCHAR = "any visible [USASCII] character"
+//
+// http2 further says: "Similarly, HTTP/2 allows header field values
+// that are not valid. While most of the values that can be encoded
+// will not alter header field parsing, carriage return (CR, ASCII
+// 0xd), line feed (LF, ASCII 0xa), and the zero character (NUL, ASCII
+// 0x0) might be exploited by an attacker if they are translated
+// verbatim. Any request or response that contains a character not
+// permitted in a header field value MUST be treated as malformed
+// (Section 8.1.2.6). Valid characters are defined by the
+// field-content ABNF rule in Section 3.2 of [RFC7230]."
+//
+// This function does not (yet?) properly handle the rejection of
+// strings that begin or end with SP or HTAB.
+func ValidHeaderFieldValue(v string) bool {
+ for i := 0; i < len(v); i++ {
+ b := v[i]
+ if isCTL(b) && !isLWS(b) {
+ return false
+ }
+ }
+ return true
+}
diff --git a/libgo/go/golang_org/x/net/lex/httplex/httplex_test.go b/libgo/go/golang_org/x/net/lex/httplex/httplex_test.go
new file mode 100644
index 00000000000..c4ace1991b3
--- /dev/null
+++ b/libgo/go/golang_org/x/net/lex/httplex/httplex_test.go
@@ -0,0 +1,101 @@
+// Copyright 2009 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 httplex
+
+import (
+ "testing"
+)
+
+func isChar(c rune) bool { return c <= 127 }
+
+func isCtl(c rune) bool { return c <= 31 || c == 127 }
+
+func isSeparator(c rune) bool {
+ switch c {
+ case '(', ')', '<', '>', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '=', '{', '}', ' ', '\t':
+ return true
+ }
+ return false
+}
+
+func TestIsToken(t *testing.T) {
+ for i := 0; i <= 130; i++ {
+ r := rune(i)
+ expected := isChar(r) && !isCtl(r) && !isSeparator(r)
+ if IsTokenRune(r) != expected {
+ t.Errorf("isToken(0x%x) = %v", r, !expected)
+ }
+ }
+}
+
+func TestHeaderValuesContainsToken(t *testing.T) {
+ tests := []struct {
+ vals []string
+ token string
+ want bool
+ }{
+ {
+ vals: []string{"foo"},
+ token: "foo",
+ want: true,
+ },
+ {
+ vals: []string{"bar", "foo"},
+ token: "foo",
+ want: true,
+ },
+ {
+ vals: []string{"foo"},
+ token: "FOO",
+ want: true,
+ },
+ {
+ vals: []string{"foo"},
+ token: "bar",
+ want: false,
+ },
+ {
+ vals: []string{" foo "},
+ token: "FOO",
+ want: true,
+ },
+ {
+ vals: []string{"foo,bar"},
+ token: "FOO",
+ want: true,
+ },
+ {
+ vals: []string{"bar,foo,bar"},
+ token: "FOO",
+ want: true,
+ },
+ {
+ vals: []string{"bar , foo"},
+ token: "FOO",
+ want: true,
+ },
+ {
+ vals: []string{"foo ,bar "},
+ token: "FOO",
+ want: true,
+ },
+ {
+ vals: []string{"bar, foo ,bar"},
+ token: "FOO",
+ want: true,
+ },
+ {
+ vals: []string{"bar , foo"},
+ token: "FOO",
+ want: true,
+ },
+ }
+ for _, tt := range tests {
+ got := HeaderValuesContainsToken(tt.vals, tt.token)
+ if got != tt.want {
+ t.Errorf("headerValuesContainsToken(%q, %q) = %v; want %v", tt.vals, tt.token, got, tt.want)
+ }
+ }
+}
diff --git a/libgo/go/golang_org/x/net/route/address.go b/libgo/go/golang_org/x/net/route/address.go
new file mode 100644
index 00000000000..206a8371d43
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/address.go
@@ -0,0 +1,269 @@
+// 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.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package route
+
+import "runtime"
+
+// An Addr represents an address associated with packet routing.
+type Addr interface {
+ // Family returns an address family.
+ Family() int
+}
+
+// A LinkAddr represents a link-layer address.
+type LinkAddr struct {
+ Index int // interface index when attached
+ Name string // interface name when attached
+ Addr []byte // link-layer address when attached
+}
+
+// Family implements the Family method of Addr interface.
+func (a *LinkAddr) Family() int { return sysAF_LINK }
+
+func parseLinkAddr(b []byte) (Addr, error) {
+ if len(b) < 8 {
+ return nil, errInvalidAddr
+ }
+ _, a, err := parseKernelLinkAddr(sysAF_LINK, b[4:])
+ if err != nil {
+ return nil, err
+ }
+ a.(*LinkAddr).Index = int(nativeEndian.Uint16(b[2:4]))
+ return a, nil
+}
+
+// parseKernelLinkAddr parses b as a link-layer address in
+// conventional BSD kernel form.
+func parseKernelLinkAddr(_ int, b []byte) (int, Addr, error) {
+ // The encoding looks like the following:
+ // +----------------------------+
+ // | Type (1 octet) |
+ // +----------------------------+
+ // | Name length (1 octet) |
+ // +----------------------------+
+ // | Address length (1 octet) |
+ // +----------------------------+
+ // | Selector length (1 octet) |
+ // +----------------------------+
+ // | Data (variable) |
+ // +----------------------------+
+ //
+ // On some platforms, all-bit-one of length field means "don't
+ // care".
+ nlen, alen, slen := int(b[1]), int(b[2]), int(b[3])
+ if nlen == 0xff {
+ nlen = 0
+ }
+ if alen == 0xff {
+ alen = 0
+ }
+ if slen == 0xff {
+ slen = 0
+ }
+ l := 4 + nlen + alen + slen
+ if len(b) < l {
+ return 0, nil, errInvalidAddr
+ }
+ data := b[4:]
+ var name string
+ var addr []byte
+ if nlen > 0 {
+ name = string(data[:nlen])
+ data = data[nlen:]
+ }
+ if alen > 0 {
+ addr = data[:alen]
+ data = data[alen:]
+ }
+ return l, &LinkAddr{Name: name, Addr: addr}, nil
+}
+
+// An Inet4Addr represents an internet address for IPv4.
+type Inet4Addr struct {
+ IP [4]byte // IP address
+}
+
+// Family implements the Family method of Addr interface.
+func (a *Inet4Addr) Family() int { return sysAF_INET }
+
+// An Inet6Addr represents an internet address for IPv6.
+type Inet6Addr struct {
+ IP [16]byte // IP address
+ ZoneID int // zone identifier
+}
+
+// Family implements the Family method of Addr interface.
+func (a *Inet6Addr) Family() int { return sysAF_INET6 }
+
+// parseInetAddr parses b as an internet address for IPv4 or IPv6.
+func parseInetAddr(af int, b []byte) (Addr, error) {
+ switch af {
+ case sysAF_INET:
+ if len(b) < 16 {
+ return nil, errInvalidAddr
+ }
+ a := &Inet4Addr{}
+ copy(a.IP[:], b[4:8])
+ return a, nil
+ case sysAF_INET6:
+ if len(b) < 28 {
+ return nil, errInvalidAddr
+ }
+ a := &Inet6Addr{ZoneID: int(nativeEndian.Uint32(b[24:28]))}
+ copy(a.IP[:], b[8:24])
+ if a.IP[0] == 0xfe && a.IP[1]&0xc0 == 0x80 || a.IP[0] == 0xff && (a.IP[1]&0x0f == 0x01 || a.IP[1]&0x0f == 0x02) {
+ // KAME based IPv6 protocol stack usually
+ // embeds the interface index in the
+ // interface-local or link-local address as
+ // the kernel-internal form.
+ id := int(bigEndian.Uint16(a.IP[2:4]))
+ if id != 0 {
+ a.ZoneID = id
+ a.IP[2], a.IP[3] = 0, 0
+ }
+ }
+ return a, nil
+ default:
+ return nil, errInvalidAddr
+ }
+}
+
+// parseKernelInetAddr parses b as an internet address in conventional
+// BSD kernel form.
+func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
+ // The encoding looks similar to the NLRI encoding.
+ // +----------------------------+
+ // | Length (1 octet) |
+ // +----------------------------+
+ // | Address prefix (variable) |
+ // +----------------------------+
+ //
+ // The differences between the kernel form and the NLRI
+ // encoding are:
+ //
+ // - The length field of the kernel form indicates the prefix
+ // length in bytes, not in bits
+ //
+ // - In the kernel form, zero value of the length field
+ // doesn't mean 0.0.0.0/0 or ::/0
+ //
+ // - The kernel form appends leading bytes to the prefix field
+ // to make the <length, prefix> tuple to be conformed with
+ // the routing message boundary
+ l := int(b[0])
+ if runtime.GOOS == "darwin" {
+ // On Darwn, an address in the kernel form is also
+ // used as a message filler.
+ if l == 0 || len(b) > roundup(l) {
+ l = roundup(l)
+ }
+ } else {
+ l = roundup(l)
+ }
+ if len(b) < l {
+ return 0, nil, errInvalidAddr
+ }
+ // Don't reorder case expressions.
+ // The case expressions for IPv6 must come first.
+ const (
+ off4 = 4 // offset of in_addr
+ off6 = 8 // offset of in6_addr
+ )
+ switch {
+ case b[0] == 28: // size of sockaddr_in6
+ a := &Inet6Addr{}
+ copy(a.IP[:], b[off6:off6+16])
+ return int(b[0]), a, nil
+ case af == sysAF_INET6:
+ a := &Inet6Addr{}
+ if l-1 < off6 {
+ copy(a.IP[:], b[1:l])
+ } else {
+ copy(a.IP[:], b[l-off6:l])
+ }
+ return int(b[0]), a, nil
+ case b[0] == 16: // size of sockaddr_in
+ a := &Inet4Addr{}
+ copy(a.IP[:], b[off4:off4+4])
+ return int(b[0]), a, nil
+ default: // an old fashion, AF_UNSPEC or unknown means AF_INET
+ a := &Inet4Addr{}
+ if l-1 < off4 {
+ copy(a.IP[:], b[1:l])
+ } else {
+ copy(a.IP[:], b[l-off4:l])
+ }
+ return int(b[0]), a, nil
+ }
+}
+
+// A DefaultAddr represents an address of various operating
+// system-specific features.
+type DefaultAddr struct {
+ af int
+ Raw []byte // raw format of address
+}
+
+// Family implements the Family method of Addr interface.
+func (a *DefaultAddr) Family() int { return a.af }
+
+func parseDefaultAddr(b []byte) (Addr, error) {
+ if len(b) < 2 || len(b) < int(b[0]) {
+ return nil, errInvalidAddr
+ }
+ a := &DefaultAddr{af: int(b[1]), Raw: b[:b[0]]}
+ return a, nil
+}
+
+func parseAddrs(attrs uint, fn func(int, []byte) (int, Addr, error), b []byte) ([]Addr, error) {
+ var as [sysRTAX_MAX]Addr
+ af := int(sysAF_UNSPEC)
+ for i := uint(0); i < sysRTAX_MAX && len(b) >= roundup(0); i++ {
+ if attrs&(1<<i) == 0 {
+ continue
+ }
+ if i <= sysRTAX_BRD {
+ switch b[1] {
+ case sysAF_LINK:
+ a, err := parseLinkAddr(b)
+ if err != nil {
+ return nil, err
+ }
+ as[i] = a
+ b = b[roundup(int(b[0])):]
+ case sysAF_INET, sysAF_INET6:
+ af = int(b[1])
+ a, err := parseInetAddr(af, b)
+ if err != nil {
+ return nil, err
+ }
+ as[i] = a
+ b = b[roundup(int(b[0])):]
+ default:
+ l, a, err := fn(af, b)
+ if err != nil {
+ return nil, err
+ }
+ as[i] = a
+ ll := roundup(l)
+ if len(b) < ll {
+ b = b[l:]
+ } else {
+ b = b[ll:]
+ }
+ }
+ } else {
+ a, err := parseDefaultAddr(b)
+ if err != nil {
+ return nil, err
+ }
+ as[i] = a
+ b = b[roundup(int(b[0])):]
+ }
+ }
+ return as[:], nil
+}
diff --git a/libgo/go/golang_org/x/net/route/address_darwin_test.go b/libgo/go/golang_org/x/net/route/address_darwin_test.go
new file mode 100644
index 00000000000..b86bd3df1f8
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/address_darwin_test.go
@@ -0,0 +1,63 @@
+// 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 route
+
+import (
+ "reflect"
+ "testing"
+)
+
+type parseAddrsOnDarwinTest struct {
+ attrs uint
+ fn func(int, []byte) (int, Addr, error)
+ b []byte
+ as []Addr
+}
+
+var parseAddrsOnDarwinLittleEndianTests = []parseAddrsOnDarwinTest{
+ {
+ sysRTA_DST | sysRTA_GATEWAY | sysRTA_NETMASK,
+ parseKernelInetAddr,
+ []byte{
+ 0x10, 0x2, 0x0, 0x0, 0xc0, 0xa8, 0x56, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+
+ 0x14, 0x12, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+
+ 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ },
+ []Addr{
+ &Inet4Addr{IP: [4]byte{192, 168, 86, 0}},
+ &LinkAddr{Index: 4},
+ &Inet4Addr{IP: [4]byte{255, 255, 255, 255}},
+ nil,
+ nil,
+ nil,
+ nil,
+ nil,
+ },
+ },
+}
+
+func TestParseAddrsOnDarwin(t *testing.T) {
+ tests := parseAddrsOnDarwinLittleEndianTests
+ if nativeEndian != littleEndian {
+ t.Skip("no test for non-little endian machine yet")
+ }
+
+ for i, tt := range tests {
+ as, err := parseAddrs(tt.attrs, tt.fn, tt.b)
+ if err != nil {
+ t.Error(i, err)
+ continue
+ }
+ if !reflect.DeepEqual(as, tt.as) {
+ t.Errorf("#%d: got %+v; want %+v", i, as, tt.as)
+ continue
+ }
+ }
+}
diff --git a/libgo/go/golang_org/x/net/route/address_test.go b/libgo/go/golang_org/x/net/route/address_test.go
new file mode 100644
index 00000000000..2005ef7c20c
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/address_test.go
@@ -0,0 +1,103 @@
+// 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.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package route
+
+import (
+ "reflect"
+ "testing"
+)
+
+type parseAddrsTest struct {
+ attrs uint
+ fn func(int, []byte) (int, Addr, error)
+ b []byte
+ as []Addr
+}
+
+var parseAddrsLittleEndianTests = []parseAddrsTest{
+ {
+ sysRTA_DST | sysRTA_GATEWAY | sysRTA_NETMASK | sysRTA_BRD,
+ parseKernelInetAddr,
+ []byte{
+ 0x38, 0x12, 0x0, 0x0, 0xff, 0xff, 0xff, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+
+ 0x38, 0x12, 0x2, 0x0, 0x6, 0x3, 0x6, 0x0,
+ 0x65, 0x6d, 0x31, 0x0, 0xc, 0x29, 0x66, 0x2c,
+ 0xdc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+
+ 0x10, 0x2, 0x0, 0x0, 0xac, 0x10, 0xdc, 0xb4,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+
+ 0x10, 0x2, 0x0, 0x0, 0xac, 0x10, 0xdc, 0xff,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ },
+ []Addr{
+ &LinkAddr{Index: 0},
+ &LinkAddr{Index: 2, Name: "em1", Addr: []byte{0x00, 0x0c, 0x29, 0x66, 0x2c, 0xdc}},
+ &Inet4Addr{IP: [4]byte{172, 16, 220, 180}},
+ nil,
+ nil,
+ nil,
+ nil,
+ &Inet4Addr{IP: [4]byte{172, 16, 220, 255}},
+ },
+ },
+ {
+ sysRTA_NETMASK | sysRTA_IFP | sysRTA_IFA,
+ parseKernelInetAddr,
+ []byte{
+ 0x7, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0x0,
+
+ 0x18, 0x12, 0xa, 0x0, 0x87, 0x8, 0x0, 0x0,
+ 0x76, 0x6c, 0x61, 0x6e, 0x35, 0x36, 0x38, 0x32,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+
+ 0x10, 0x2, 0x0, 0x0, 0xa9, 0xfe, 0x0, 0x1,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ },
+ []Addr{
+ nil,
+ nil,
+ &Inet4Addr{IP: [4]byte{255, 255, 255, 0}},
+ nil,
+ &LinkAddr{Index: 10, Name: "vlan5682"},
+ &Inet4Addr{IP: [4]byte{169, 254, 0, 1}},
+ nil,
+ nil,
+ },
+ },
+}
+
+func TestParseAddrs(t *testing.T) {
+ tests := parseAddrsLittleEndianTests
+ if nativeEndian != littleEndian {
+ t.Skip("no test for non-little endian machine yet")
+ }
+
+ for i, tt := range tests {
+ as, err := parseAddrs(tt.attrs, tt.fn, tt.b)
+ if err != nil {
+ t.Error(i, err)
+ continue
+ }
+ as = as[:8] // the list varies between operating systems
+ if !reflect.DeepEqual(as, tt.as) {
+ t.Errorf("#%d: got %+v; want %+v", i, as, tt.as)
+ continue
+ }
+ }
+}
diff --git a/libgo/go/golang_org/x/net/route/binary.go b/libgo/go/golang_org/x/net/route/binary.go
new file mode 100644
index 00000000000..4c561631b94
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/binary.go
@@ -0,0 +1,90 @@
+// 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.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package route
+
+// This file contains duplicates of encoding/binary package.
+//
+// This package is supposed to be used by the net package of standard
+// library. Therefore a package set used in the package must be the
+// same as net package.
+
+var (
+ littleEndian binaryLittleEndian
+ bigEndian binaryBigEndian
+)
+
+type binaryByteOrder interface {
+ Uint16([]byte) uint16
+ Uint32([]byte) uint32
+ PutUint16([]byte, uint16)
+ PutUint32([]byte, uint32)
+ Uint64([]byte) uint64
+}
+
+type binaryLittleEndian struct{}
+
+func (binaryLittleEndian) Uint16(b []byte) uint16 {
+ _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint16(b[0]) | uint16(b[1])<<8
+}
+
+func (binaryLittleEndian) PutUint16(b []byte, v uint16) {
+ _ = b[1] // early bounds check to guarantee safety of writes below
+ b[0] = byte(v)
+ b[1] = byte(v >> 8)
+}
+
+func (binaryLittleEndian) Uint32(b []byte) uint32 {
+ _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+}
+
+func (binaryLittleEndian) PutUint32(b []byte, v uint32) {
+ _ = b[3] // early bounds check to guarantee safety of writes below
+ b[0] = byte(v)
+ b[1] = byte(v >> 8)
+ b[2] = byte(v >> 16)
+ b[3] = byte(v >> 24)
+}
+
+func (binaryLittleEndian) Uint64(b []byte) uint64 {
+ _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
+ uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+}
+
+type binaryBigEndian struct{}
+
+func (binaryBigEndian) Uint16(b []byte) uint16 {
+ _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint16(b[1]) | uint16(b[0])<<8
+}
+
+func (binaryBigEndian) PutUint16(b []byte, v uint16) {
+ _ = b[1] // early bounds check to guarantee safety of writes below
+ b[0] = byte(v >> 8)
+ b[1] = byte(v)
+}
+
+func (binaryBigEndian) Uint32(b []byte) uint32 {
+ _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+}
+
+func (binaryBigEndian) PutUint32(b []byte, v uint32) {
+ _ = b[3] // early bounds check to guarantee safety of writes below
+ b[0] = byte(v >> 24)
+ b[1] = byte(v >> 16)
+ b[2] = byte(v >> 8)
+ b[3] = byte(v)
+}
+
+func (binaryBigEndian) Uint64(b []byte) uint64 {
+ _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+ uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+}
diff --git a/libgo/go/golang_org/x/net/route/defs_darwin.go b/libgo/go/golang_org/x/net/route/defs_darwin.go
new file mode 100644
index 00000000000..f452ad14ce6
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/defs_darwin.go
@@ -0,0 +1,106 @@
+// 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.
+
+// +build ignore
+
+package route
+
+/*
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+*/
+import "C"
+
+const (
+ sysAF_UNSPEC = C.AF_UNSPEC
+ sysAF_INET = C.AF_INET
+ sysAF_ROUTE = C.AF_ROUTE
+ sysAF_LINK = C.AF_LINK
+ sysAF_INET6 = C.AF_INET6
+
+ sysNET_RT_DUMP = C.NET_RT_DUMP
+ sysNET_RT_FLAGS = C.NET_RT_FLAGS
+ sysNET_RT_IFLIST = C.NET_RT_IFLIST
+ sysNET_RT_STAT = C.NET_RT_STAT
+ sysNET_RT_TRASH = C.NET_RT_TRASH
+ sysNET_RT_IFLIST2 = C.NET_RT_IFLIST2
+ sysNET_RT_DUMP2 = C.NET_RT_DUMP2
+ sysNET_RT_MAXID = C.NET_RT_MAXID
+)
+
+const (
+ sysCTL_MAXNAME = C.CTL_MAXNAME
+
+ sysCTL_UNSPEC = C.CTL_UNSPEC
+ sysCTL_KERN = C.CTL_KERN
+ sysCTL_VM = C.CTL_VM
+ sysCTL_VFS = C.CTL_VFS
+ sysCTL_NET = C.CTL_NET
+ sysCTL_DEBUG = C.CTL_DEBUG
+ sysCTL_HW = C.CTL_HW
+ sysCTL_MACHDEP = C.CTL_MACHDEP
+ sysCTL_USER = C.CTL_USER
+ sysCTL_MAXID = C.CTL_MAXID
+)
+
+const (
+ sysRTM_VERSION = C.RTM_VERSION
+
+ sysRTM_ADD = C.RTM_ADD
+ sysRTM_DELETE = C.RTM_DELETE
+ sysRTM_CHANGE = C.RTM_CHANGE
+ sysRTM_GET = C.RTM_GET
+ sysRTM_LOSING = C.RTM_LOSING
+ sysRTM_REDIRECT = C.RTM_REDIRECT
+ sysRTM_MISS = C.RTM_MISS
+ sysRTM_LOCK = C.RTM_LOCK
+ sysRTM_OLDADD = C.RTM_OLDADD
+ sysRTM_OLDDEL = C.RTM_OLDDEL
+ sysRTM_RESOLVE = C.RTM_RESOLVE
+ sysRTM_NEWADDR = C.RTM_NEWADDR
+ sysRTM_DELADDR = C.RTM_DELADDR
+ sysRTM_IFINFO = C.RTM_IFINFO
+ sysRTM_NEWMADDR = C.RTM_NEWMADDR
+ sysRTM_DELMADDR = C.RTM_DELMADDR
+ sysRTM_IFINFO2 = C.RTM_IFINFO2
+ sysRTM_NEWMADDR2 = C.RTM_NEWMADDR2
+ sysRTM_GET2 = C.RTM_GET2
+
+ sysRTA_DST = C.RTA_DST
+ sysRTA_GATEWAY = C.RTA_GATEWAY
+ sysRTA_NETMASK = C.RTA_NETMASK
+ sysRTA_GENMASK = C.RTA_GENMASK
+ sysRTA_IFP = C.RTA_IFP
+ sysRTA_IFA = C.RTA_IFA
+ sysRTA_AUTHOR = C.RTA_AUTHOR
+ sysRTA_BRD = C.RTA_BRD
+
+ sysRTAX_DST = C.RTAX_DST
+ sysRTAX_GATEWAY = C.RTAX_GATEWAY
+ sysRTAX_NETMASK = C.RTAX_NETMASK
+ sysRTAX_GENMASK = C.RTAX_GENMASK
+ sysRTAX_IFP = C.RTAX_IFP
+ sysRTAX_IFA = C.RTAX_IFA
+ sysRTAX_AUTHOR = C.RTAX_AUTHOR
+ sysRTAX_BRD = C.RTAX_BRD
+ sysRTAX_MAX = C.RTAX_MAX
+)
+
+const (
+ sizeofIfMsghdrDarwin15 = C.sizeof_struct_if_msghdr
+ sizeofIfaMsghdrDarwin15 = C.sizeof_struct_ifa_msghdr
+ sizeofIfmaMsghdrDarwin15 = C.sizeof_struct_ifma_msghdr
+ sizeofIfMsghdr2Darwin15 = C.sizeof_struct_if_msghdr2
+ sizeofIfmaMsghdr2Darwin15 = C.sizeof_struct_ifma_msghdr2
+ sizeofIfDataDarwin15 = C.sizeof_struct_if_data
+ sizeofIfData64Darwin15 = C.sizeof_struct_if_data64
+
+ sizeofRtMsghdrDarwin15 = C.sizeof_struct_rt_msghdr
+ sizeofRtMsghdr2Darwin15 = C.sizeof_struct_rt_msghdr2
+ sizeofRtMetricsDarwin15 = C.sizeof_struct_rt_metrics
+)
diff --git a/libgo/go/golang_org/x/net/route/defs_dragonfly.go b/libgo/go/golang_org/x/net/route/defs_dragonfly.go
new file mode 100644
index 00000000000..c737751d76d
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/defs_dragonfly.go
@@ -0,0 +1,105 @@
+// 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.
+
+// +build ignore
+
+package route
+
+/*
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+*/
+import "C"
+
+const (
+ sysAF_UNSPEC = C.AF_UNSPEC
+ sysAF_INET = C.AF_INET
+ sysAF_ROUTE = C.AF_ROUTE
+ sysAF_LINK = C.AF_LINK
+ sysAF_INET6 = C.AF_INET6
+
+ sysNET_RT_DUMP = C.NET_RT_DUMP
+ sysNET_RT_FLAGS = C.NET_RT_FLAGS
+ sysNET_RT_IFLIST = C.NET_RT_IFLIST
+ sysNET_RT_MAXID = C.NET_RT_MAXID
+)
+
+const (
+ sysCTL_MAXNAME = C.CTL_MAXNAME
+
+ sysCTL_UNSPEC = C.CTL_UNSPEC
+ sysCTL_KERN = C.CTL_KERN
+ sysCTL_VM = C.CTL_VM
+ sysCTL_VFS = C.CTL_VFS
+ sysCTL_NET = C.CTL_NET
+ sysCTL_DEBUG = C.CTL_DEBUG
+ sysCTL_HW = C.CTL_HW
+ sysCTL_MACHDEP = C.CTL_MACHDEP
+ sysCTL_USER = C.CTL_USER
+ sysCTL_P1003_1B = C.CTL_P1003_1B
+ sysCTL_LWKT = C.CTL_LWKT
+ sysCTL_MAXID = C.CTL_MAXID
+)
+
+const (
+ sysRTM_VERSION = C.RTM_VERSION
+
+ sysRTM_ADD = C.RTM_ADD
+ sysRTM_DELETE = C.RTM_DELETE
+ sysRTM_CHANGE = C.RTM_CHANGE
+ sysRTM_GET = C.RTM_GET
+ sysRTM_LOSING = C.RTM_LOSING
+ sysRTM_REDIRECT = C.RTM_REDIRECT
+ sysRTM_MISS = C.RTM_MISS
+ sysRTM_LOCK = C.RTM_LOCK
+ sysRTM_OLDADD = C.RTM_OLDADD
+ sysRTM_OLDDEL = C.RTM_OLDDEL
+ sysRTM_RESOLVE = C.RTM_RESOLVE
+ sysRTM_NEWADDR = C.RTM_NEWADDR
+ sysRTM_DELADDR = C.RTM_DELADDR
+ sysRTM_IFINFO = C.RTM_IFINFO
+ sysRTM_NEWMADDR = C.RTM_NEWMADDR
+ sysRTM_DELMADDR = C.RTM_DELMADDR
+ sysRTM_IFANNOUNCE = C.RTM_IFANNOUNCE
+ sysRTM_IEEE80211 = C.RTM_IEEE80211
+
+ sysRTA_DST = C.RTA_DST
+ sysRTA_GATEWAY = C.RTA_GATEWAY
+ sysRTA_NETMASK = C.RTA_NETMASK
+ sysRTA_GENMASK = C.RTA_GENMASK
+ sysRTA_IFP = C.RTA_IFP
+ sysRTA_IFA = C.RTA_IFA
+ sysRTA_AUTHOR = C.RTA_AUTHOR
+ sysRTA_BRD = C.RTA_BRD
+ sysRTA_MPLS1 = C.RTA_MPLS1
+ sysRTA_MPLS2 = C.RTA_MPLS2
+ sysRTA_MPLS3 = C.RTA_MPLS3
+
+ sysRTAX_DST = C.RTAX_DST
+ sysRTAX_GATEWAY = C.RTAX_GATEWAY
+ sysRTAX_NETMASK = C.RTAX_NETMASK
+ sysRTAX_GENMASK = C.RTAX_GENMASK
+ sysRTAX_IFP = C.RTAX_IFP
+ sysRTAX_IFA = C.RTAX_IFA
+ sysRTAX_AUTHOR = C.RTAX_AUTHOR
+ sysRTAX_BRD = C.RTAX_BRD
+ sysRTAX_MPLS1 = C.RTAX_MPLS1
+ sysRTAX_MPLS2 = C.RTAX_MPLS2
+ sysRTAX_MPLS3 = C.RTAX_MPLS3
+ sysRTAX_MAX = C.RTAX_MAX
+)
+
+const (
+ sizeofIfMsghdrDragonFlyBSD4 = C.sizeof_struct_if_msghdr
+ sizeofIfaMsghdrDragonFlyBSD4 = C.sizeof_struct_ifa_msghdr
+ sizeofIfmaMsghdrDragonFlyBSD4 = C.sizeof_struct_ifma_msghdr
+ sizeofIfAnnouncemsghdrDragonFlyBSD4 = C.sizeof_struct_if_announcemsghdr
+
+ sizeofRtMsghdrDragonFlyBSD4 = C.sizeof_struct_rt_msghdr
+ sizeofRtMetricsDragonFlyBSD4 = C.sizeof_struct_rt_metrics
+)
diff --git a/libgo/go/golang_org/x/net/route/defs_freebsd.go b/libgo/go/golang_org/x/net/route/defs_freebsd.go
new file mode 100644
index 00000000000..8f834e81db5
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/defs_freebsd.go
@@ -0,0 +1,329 @@
+// 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.
+
+// +build ignore
+
+package route
+
+/*
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+
+struct if_data_freebsd7 {
+ u_char ifi_type;
+ u_char ifi_physical;
+ u_char ifi_addrlen;
+ u_char ifi_hdrlen;
+ u_char ifi_link_state;
+ u_char ifi_spare_char1;
+ u_char ifi_spare_char2;
+ u_char ifi_datalen;
+ u_long ifi_mtu;
+ u_long ifi_metric;
+ u_long ifi_baudrate;
+ u_long ifi_ipackets;
+ u_long ifi_ierrors;
+ u_long ifi_opackets;
+ u_long ifi_oerrors;
+ u_long ifi_collisions;
+ u_long ifi_ibytes;
+ u_long ifi_obytes;
+ u_long ifi_imcasts;
+ u_long ifi_omcasts;
+ u_long ifi_iqdrops;
+ u_long ifi_noproto;
+ u_long ifi_hwassist;
+ time_t __ifi_epoch;
+ struct timeval __ifi_lastchange;
+};
+
+struct if_data_freebsd8 {
+ u_char ifi_type;
+ u_char ifi_physical;
+ u_char ifi_addrlen;
+ u_char ifi_hdrlen;
+ u_char ifi_link_state;
+ u_char ifi_spare_char1;
+ u_char ifi_spare_char2;
+ u_char ifi_datalen;
+ u_long ifi_mtu;
+ u_long ifi_metric;
+ u_long ifi_baudrate;
+ u_long ifi_ipackets;
+ u_long ifi_ierrors;
+ u_long ifi_opackets;
+ u_long ifi_oerrors;
+ u_long ifi_collisions;
+ u_long ifi_ibytes;
+ u_long ifi_obytes;
+ u_long ifi_imcasts;
+ u_long ifi_omcasts;
+ u_long ifi_iqdrops;
+ u_long ifi_noproto;
+ u_long ifi_hwassist;
+ time_t __ifi_epoch;
+ struct timeval __ifi_lastchange;
+};
+
+struct if_data_freebsd9 {
+ u_char ifi_type;
+ u_char ifi_physical;
+ u_char ifi_addrlen;
+ u_char ifi_hdrlen;
+ u_char ifi_link_state;
+ u_char ifi_spare_char1;
+ u_char ifi_spare_char2;
+ u_char ifi_datalen;
+ u_long ifi_mtu;
+ u_long ifi_metric;
+ u_long ifi_baudrate;
+ u_long ifi_ipackets;
+ u_long ifi_ierrors;
+ u_long ifi_opackets;
+ u_long ifi_oerrors;
+ u_long ifi_collisions;
+ u_long ifi_ibytes;
+ u_long ifi_obytes;
+ u_long ifi_imcasts;
+ u_long ifi_omcasts;
+ u_long ifi_iqdrops;
+ u_long ifi_noproto;
+ u_long ifi_hwassist;
+ time_t __ifi_epoch;
+ struct timeval __ifi_lastchange;
+};
+
+struct if_data_freebsd10 {
+ u_char ifi_type;
+ u_char ifi_physical;
+ u_char ifi_addrlen;
+ u_char ifi_hdrlen;
+ u_char ifi_link_state;
+ u_char ifi_vhid;
+ u_char ifi_baudrate_pf;
+ u_char ifi_datalen;
+ u_long ifi_mtu;
+ u_long ifi_metric;
+ u_long ifi_baudrate;
+ u_long ifi_ipackets;
+ u_long ifi_ierrors;
+ u_long ifi_opackets;
+ u_long ifi_oerrors;
+ u_long ifi_collisions;
+ u_long ifi_ibytes;
+ u_long ifi_obytes;
+ u_long ifi_imcasts;
+ u_long ifi_omcasts;
+ u_long ifi_iqdrops;
+ u_long ifi_noproto;
+ uint64_t ifi_hwassist;
+ time_t __ifi_epoch;
+ struct timeval __ifi_lastchange;
+};
+
+struct if_data_freebsd11 {
+ uint8_t ifi_type;
+ uint8_t ifi_physical;
+ uint8_t ifi_addrlen;
+ uint8_t ifi_hdrlen;
+ uint8_t ifi_link_state;
+ uint8_t ifi_vhid;
+ uint16_t ifi_datalen;
+ uint32_t ifi_mtu;
+ uint32_t ifi_metric;
+ uint64_t ifi_baudrate;
+ uint64_t ifi_ipackets;
+ uint64_t ifi_ierrors;
+ uint64_t ifi_opackets;
+ uint64_t ifi_oerrors;
+ uint64_t ifi_collisions;
+ uint64_t ifi_ibytes;
+ uint64_t ifi_obytes;
+ uint64_t ifi_imcasts;
+ uint64_t ifi_omcasts;
+ uint64_t ifi_iqdrops;
+ uint64_t ifi_oqdrops;
+ uint64_t ifi_noproto;
+ uint64_t ifi_hwassist;
+ union {
+ time_t tt;
+ uint64_t ph;
+ } __ifi_epoch;
+ union {
+ struct timeval tv;
+ struct {
+ uint64_t ph1;
+ uint64_t ph2;
+ } ph;
+ } __ifi_lastchange;
+};
+
+struct if_msghdr_freebsd7 {
+ u_short ifm_msglen;
+ u_char ifm_version;
+ u_char ifm_type;
+ int ifm_addrs;
+ int ifm_flags;
+ u_short ifm_index;
+ struct if_data_freebsd7 ifm_data;
+};
+
+struct if_msghdr_freebsd8 {
+ u_short ifm_msglen;
+ u_char ifm_version;
+ u_char ifm_type;
+ int ifm_addrs;
+ int ifm_flags;
+ u_short ifm_index;
+ struct if_data_freebsd8 ifm_data;
+};
+
+struct if_msghdr_freebsd9 {
+ u_short ifm_msglen;
+ u_char ifm_version;
+ u_char ifm_type;
+ int ifm_addrs;
+ int ifm_flags;
+ u_short ifm_index;
+ struct if_data_freebsd9 ifm_data;
+};
+
+struct if_msghdr_freebsd10 {
+ u_short ifm_msglen;
+ u_char ifm_version;
+ u_char ifm_type;
+ int ifm_addrs;
+ int ifm_flags;
+ u_short ifm_index;
+ struct if_data_freebsd10 ifm_data;
+};
+
+struct if_msghdr_freebsd11 {
+ u_short ifm_msglen;
+ u_char ifm_version;
+ u_char ifm_type;
+ int ifm_addrs;
+ int ifm_flags;
+ u_short ifm_index;
+ struct if_data_freebsd11 ifm_data;
+};
+*/
+import "C"
+
+const (
+ sysAF_UNSPEC = C.AF_UNSPEC
+ sysAF_INET = C.AF_INET
+ sysAF_ROUTE = C.AF_ROUTE
+ sysAF_LINK = C.AF_LINK
+ sysAF_INET6 = C.AF_INET6
+
+ sysNET_RT_DUMP = C.NET_RT_DUMP
+ sysNET_RT_FLAGS = C.NET_RT_FLAGS
+ sysNET_RT_IFLIST = C.NET_RT_IFLIST
+ sysNET_RT_IFMALIST = C.NET_RT_IFMALIST
+ sysNET_RT_IFLISTL = C.NET_RT_IFLISTL
+)
+
+const (
+ sysCTL_MAXNAME = C.CTL_MAXNAME
+
+ sysCTL_UNSPEC = C.CTL_UNSPEC
+ sysCTL_KERN = C.CTL_KERN
+ sysCTL_VM = C.CTL_VM
+ sysCTL_VFS = C.CTL_VFS
+ sysCTL_NET = C.CTL_NET
+ sysCTL_DEBUG = C.CTL_DEBUG
+ sysCTL_HW = C.CTL_HW
+ sysCTL_MACHDEP = C.CTL_MACHDEP
+ sysCTL_USER = C.CTL_USER
+ sysCTL_P1003_1B = C.CTL_P1003_1B
+)
+
+const (
+ sysRTM_VERSION = C.RTM_VERSION
+
+ sysRTM_ADD = C.RTM_ADD
+ sysRTM_DELETE = C.RTM_DELETE
+ sysRTM_CHANGE = C.RTM_CHANGE
+ sysRTM_GET = C.RTM_GET
+ sysRTM_LOSING = C.RTM_LOSING
+ sysRTM_REDIRECT = C.RTM_REDIRECT
+ sysRTM_MISS = C.RTM_MISS
+ sysRTM_LOCK = C.RTM_LOCK
+ sysRTM_RESOLVE = C.RTM_RESOLVE
+ sysRTM_NEWADDR = C.RTM_NEWADDR
+ sysRTM_DELADDR = C.RTM_DELADDR
+ sysRTM_IFINFO = C.RTM_IFINFO
+ sysRTM_NEWMADDR = C.RTM_NEWMADDR
+ sysRTM_DELMADDR = C.RTM_DELMADDR
+ sysRTM_IFANNOUNCE = C.RTM_IFANNOUNCE
+ sysRTM_IEEE80211 = C.RTM_IEEE80211
+
+ sysRTA_DST = C.RTA_DST
+ sysRTA_GATEWAY = C.RTA_GATEWAY
+ sysRTA_NETMASK = C.RTA_NETMASK
+ sysRTA_GENMASK = C.RTA_GENMASK
+ sysRTA_IFP = C.RTA_IFP
+ sysRTA_IFA = C.RTA_IFA
+ sysRTA_AUTHOR = C.RTA_AUTHOR
+ sysRTA_BRD = C.RTA_BRD
+
+ sysRTAX_DST = C.RTAX_DST
+ sysRTAX_GATEWAY = C.RTAX_GATEWAY
+ sysRTAX_NETMASK = C.RTAX_NETMASK
+ sysRTAX_GENMASK = C.RTAX_GENMASK
+ sysRTAX_IFP = C.RTAX_IFP
+ sysRTAX_IFA = C.RTAX_IFA
+ sysRTAX_AUTHOR = C.RTAX_AUTHOR
+ sysRTAX_BRD = C.RTAX_BRD
+ sysRTAX_MAX = C.RTAX_MAX
+)
+
+const (
+ sizeofIfMsghdrlFreeBSD10 = C.sizeof_struct_if_msghdrl
+ sizeofIfaMsghdrFreeBSD10 = C.sizeof_struct_ifa_msghdr
+ sizeofIfaMsghdrlFreeBSD10 = C.sizeof_struct_ifa_msghdrl
+ sizeofIfmaMsghdrFreeBSD10 = C.sizeof_struct_ifma_msghdr
+ sizeofIfAnnouncemsghdrFreeBSD10 = C.sizeof_struct_if_announcemsghdr
+
+ sizeofRtMsghdrFreeBSD10 = C.sizeof_struct_rt_msghdr
+ sizeofRtMetricsFreeBSD10 = C.sizeof_struct_rt_metrics
+
+ sizeofIfMsghdrFreeBSD7 = C.sizeof_struct_if_msghdr_freebsd7
+ sizeofIfMsghdrFreeBSD8 = C.sizeof_struct_if_msghdr_freebsd8
+ sizeofIfMsghdrFreeBSD9 = C.sizeof_struct_if_msghdr_freebsd9
+ sizeofIfMsghdrFreeBSD10 = C.sizeof_struct_if_msghdr_freebsd10
+ sizeofIfMsghdrFreeBSD11 = C.sizeof_struct_if_msghdr_freebsd11
+
+ sizeofIfDataFreeBSD7 = C.sizeof_struct_if_data_freebsd7
+ sizeofIfDataFreeBSD8 = C.sizeof_struct_if_data_freebsd8
+ sizeofIfDataFreeBSD9 = C.sizeof_struct_if_data_freebsd9
+ sizeofIfDataFreeBSD10 = C.sizeof_struct_if_data_freebsd10
+ sizeofIfDataFreeBSD11 = C.sizeof_struct_if_data_freebsd11
+
+ sizeofIfMsghdrlFreeBSD10Emu = C.sizeof_struct_if_msghdrl
+ sizeofIfaMsghdrFreeBSD10Emu = C.sizeof_struct_ifa_msghdr
+ sizeofIfaMsghdrlFreeBSD10Emu = C.sizeof_struct_ifa_msghdrl
+ sizeofIfmaMsghdrFreeBSD10Emu = C.sizeof_struct_ifma_msghdr
+ sizeofIfAnnouncemsghdrFreeBSD10Emu = C.sizeof_struct_if_announcemsghdr
+
+ sizeofRtMsghdrFreeBSD10Emu = C.sizeof_struct_rt_msghdr
+ sizeofRtMetricsFreeBSD10Emu = C.sizeof_struct_rt_metrics
+
+ sizeofIfMsghdrFreeBSD7Emu = C.sizeof_struct_if_msghdr_freebsd7
+ sizeofIfMsghdrFreeBSD8Emu = C.sizeof_struct_if_msghdr_freebsd8
+ sizeofIfMsghdrFreeBSD9Emu = C.sizeof_struct_if_msghdr_freebsd9
+ sizeofIfMsghdrFreeBSD10Emu = C.sizeof_struct_if_msghdr_freebsd10
+ sizeofIfMsghdrFreeBSD11Emu = C.sizeof_struct_if_msghdr_freebsd11
+
+ sizeofIfDataFreeBSD7Emu = C.sizeof_struct_if_data_freebsd7
+ sizeofIfDataFreeBSD8Emu = C.sizeof_struct_if_data_freebsd8
+ sizeofIfDataFreeBSD9Emu = C.sizeof_struct_if_data_freebsd9
+ sizeofIfDataFreeBSD10Emu = C.sizeof_struct_if_data_freebsd10
+ sizeofIfDataFreeBSD11Emu = C.sizeof_struct_if_data_freebsd11
+)
diff --git a/libgo/go/golang_org/x/net/route/defs_netbsd.go b/libgo/go/golang_org/x/net/route/defs_netbsd.go
new file mode 100644
index 00000000000..b18d85e0165
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/defs_netbsd.go
@@ -0,0 +1,104 @@
+// 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.
+
+// +build ignore
+
+package route
+
+/*
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+*/
+import "C"
+
+const (
+ sysAF_UNSPEC = C.AF_UNSPEC
+ sysAF_INET = C.AF_INET
+ sysAF_ROUTE = C.AF_ROUTE
+ sysAF_LINK = C.AF_LINK
+ sysAF_INET6 = C.AF_INET6
+
+ sysNET_RT_DUMP = C.NET_RT_DUMP
+ sysNET_RT_FLAGS = C.NET_RT_FLAGS
+ sysNET_RT_IFLIST = C.NET_RT_IFLIST
+ sysNET_RT_MAXID = C.NET_RT_MAXID
+)
+
+const (
+ sysCTL_MAXNAME = C.CTL_MAXNAME
+
+ sysCTL_UNSPEC = C.CTL_UNSPEC
+ sysCTL_KERN = C.CTL_KERN
+ sysCTL_VM = C.CTL_VM
+ sysCTL_VFS = C.CTL_VFS
+ sysCTL_NET = C.CTL_NET
+ sysCTL_DEBUG = C.CTL_DEBUG
+ sysCTL_HW = C.CTL_HW
+ sysCTL_MACHDEP = C.CTL_MACHDEP
+ sysCTL_USER = C.CTL_USER
+ sysCTL_DDB = C.CTL_DDB
+ sysCTL_PROC = C.CTL_PROC
+ sysCTL_VENDOR = C.CTL_VENDOR
+ sysCTL_EMUL = C.CTL_EMUL
+ sysCTL_SECURITY = C.CTL_SECURITY
+ sysCTL_MAXID = C.CTL_MAXID
+)
+
+const (
+ sysRTM_VERSION = C.RTM_VERSION
+
+ sysRTM_ADD = C.RTM_ADD
+ sysRTM_DELETE = C.RTM_DELETE
+ sysRTM_CHANGE = C.RTM_CHANGE
+ sysRTM_GET = C.RTM_GET
+ sysRTM_LOSING = C.RTM_LOSING
+ sysRTM_REDIRECT = C.RTM_REDIRECT
+ sysRTM_MISS = C.RTM_MISS
+ sysRTM_LOCK = C.RTM_LOCK
+ sysRTM_OLDADD = C.RTM_OLDADD
+ sysRTM_OLDDEL = C.RTM_OLDDEL
+ sysRTM_RESOLVE = C.RTM_RESOLVE
+ sysRTM_NEWADDR = C.RTM_NEWADDR
+ sysRTM_DELADDR = C.RTM_DELADDR
+ sysRTM_IFANNOUNCE = C.RTM_IFANNOUNCE
+ sysRTM_IEEE80211 = C.RTM_IEEE80211
+ sysRTM_SETGATE = C.RTM_SETGATE
+ sysRTM_LLINFO_UPD = C.RTM_LLINFO_UPD
+ sysRTM_IFINFO = C.RTM_IFINFO
+ sysRTM_CHGADDR = C.RTM_CHGADDR
+
+ sysRTA_DST = C.RTA_DST
+ sysRTA_GATEWAY = C.RTA_GATEWAY
+ sysRTA_NETMASK = C.RTA_NETMASK
+ sysRTA_GENMASK = C.RTA_GENMASK
+ sysRTA_IFP = C.RTA_IFP
+ sysRTA_IFA = C.RTA_IFA
+ sysRTA_AUTHOR = C.RTA_AUTHOR
+ sysRTA_BRD = C.RTA_BRD
+ sysRTA_TAG = C.RTA_TAG
+
+ sysRTAX_DST = C.RTAX_DST
+ sysRTAX_GATEWAY = C.RTAX_GATEWAY
+ sysRTAX_NETMASK = C.RTAX_NETMASK
+ sysRTAX_GENMASK = C.RTAX_GENMASK
+ sysRTAX_IFP = C.RTAX_IFP
+ sysRTAX_IFA = C.RTAX_IFA
+ sysRTAX_AUTHOR = C.RTAX_AUTHOR
+ sysRTAX_BRD = C.RTAX_BRD
+ sysRTAX_TAG = C.RTAX_TAG
+ sysRTAX_MAX = C.RTAX_MAX
+)
+
+const (
+ sizeofIfMsghdrNetBSD7 = C.sizeof_struct_if_msghdr
+ sizeofIfaMsghdrNetBSD7 = C.sizeof_struct_ifa_msghdr
+ sizeofIfAnnouncemsghdrNetBSD7 = C.sizeof_struct_if_announcemsghdr
+
+ sizeofRtMsghdrNetBSD7 = C.sizeof_struct_rt_msghdr
+ sizeofRtMetricsNetBSD7 = C.sizeof_struct_rt_metrics
+)
diff --git a/libgo/go/golang_org/x/net/route/defs_openbsd.go b/libgo/go/golang_org/x/net/route/defs_openbsd.go
new file mode 100644
index 00000000000..5df7a43bc3e
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/defs_openbsd.go
@@ -0,0 +1,93 @@
+// 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.
+
+// +build ignore
+
+package route
+
+/*
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+*/
+import "C"
+
+const (
+ sysAF_UNSPEC = C.AF_UNSPEC
+ sysAF_INET = C.AF_INET
+ sysAF_ROUTE = C.AF_ROUTE
+ sysAF_LINK = C.AF_LINK
+ sysAF_INET6 = C.AF_INET6
+
+ sysNET_RT_DUMP = C.NET_RT_DUMP
+ sysNET_RT_FLAGS = C.NET_RT_FLAGS
+ sysNET_RT_IFLIST = C.NET_RT_IFLIST
+ sysNET_RT_STATS = C.NET_RT_STATS
+ sysNET_RT_TABLE = C.NET_RT_TABLE
+ sysNET_RT_IFNAMES = C.NET_RT_IFNAMES
+ sysNET_RT_MAXID = C.NET_RT_MAXID
+)
+
+const (
+ sysCTL_MAXNAME = C.CTL_MAXNAME
+
+ sysCTL_UNSPEC = C.CTL_UNSPEC
+ sysCTL_KERN = C.CTL_KERN
+ sysCTL_VM = C.CTL_VM
+ sysCTL_FS = C.CTL_FS
+ sysCTL_NET = C.CTL_NET
+ sysCTL_DEBUG = C.CTL_DEBUG
+ sysCTL_HW = C.CTL_HW
+ sysCTL_MACHDEP = C.CTL_MACHDEP
+ sysCTL_DDB = C.CTL_DDB
+ sysCTL_VFS = C.CTL_VFS
+ sysCTL_MAXID = C.CTL_MAXID
+)
+
+const (
+ sysRTM_VERSION = C.RTM_VERSION
+
+ sysRTM_ADD = C.RTM_ADD
+ sysRTM_DELETE = C.RTM_DELETE
+ sysRTM_CHANGE = C.RTM_CHANGE
+ sysRTM_GET = C.RTM_GET
+ sysRTM_LOSING = C.RTM_LOSING
+ sysRTM_REDIRECT = C.RTM_REDIRECT
+ sysRTM_MISS = C.RTM_MISS
+ sysRTM_LOCK = C.RTM_LOCK
+ sysRTM_RESOLVE = C.RTM_RESOLVE
+ sysRTM_NEWADDR = C.RTM_NEWADDR
+ sysRTM_DELADDR = C.RTM_DELADDR
+ sysRTM_IFINFO = C.RTM_IFINFO
+ sysRTM_IFANNOUNCE = C.RTM_IFANNOUNCE
+ sysRTM_DESYNC = C.RTM_DESYNC
+
+ sysRTA_DST = C.RTA_DST
+ sysRTA_GATEWAY = C.RTA_GATEWAY
+ sysRTA_NETMASK = C.RTA_NETMASK
+ sysRTA_GENMASK = C.RTA_GENMASK
+ sysRTA_IFP = C.RTA_IFP
+ sysRTA_IFA = C.RTA_IFA
+ sysRTA_AUTHOR = C.RTA_AUTHOR
+ sysRTA_BRD = C.RTA_BRD
+ sysRTA_SRC = C.RTA_SRC
+ sysRTA_SRCMASK = C.RTA_SRCMASK
+ sysRTA_LABEL = C.RTA_LABEL
+
+ sysRTAX_DST = C.RTAX_DST
+ sysRTAX_GATEWAY = C.RTAX_GATEWAY
+ sysRTAX_NETMASK = C.RTAX_NETMASK
+ sysRTAX_GENMASK = C.RTAX_GENMASK
+ sysRTAX_IFP = C.RTAX_IFP
+ sysRTAX_IFA = C.RTAX_IFA
+ sysRTAX_AUTHOR = C.RTAX_AUTHOR
+ sysRTAX_BRD = C.RTAX_BRD
+ sysRTAX_SRC = C.RTAX_SRC
+ sysRTAX_SRCMASK = C.RTAX_SRCMASK
+ sysRTAX_LABEL = C.RTAX_LABEL
+ sysRTAX_MAX = C.RTAX_MAX
+)
diff --git a/libgo/go/golang_org/x/net/route/interface.go b/libgo/go/golang_org/x/net/route/interface.go
new file mode 100644
index 00000000000..854906d9c42
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/interface.go
@@ -0,0 +1,64 @@
+// 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.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package route
+
+// An InterfaceMessage represents an interface message.
+type InterfaceMessage struct {
+ Version int // message version
+ Type int // message type
+ Flags int // interface flags
+ Index int // interface index
+ Name string // interface name
+ Addrs []Addr // addresses
+
+ extOff int // offset of header extension
+ raw []byte // raw message
+}
+
+// An InterfaceAddrMessage represents an interface address message.
+type InterfaceAddrMessage struct {
+ Version int // message version
+ Type int // message type
+ Flags int // interface flags
+ Index int // interface index
+ Addrs []Addr // addresses
+
+ raw []byte // raw message
+}
+
+// Sys implements the Sys method of Message interface.
+func (m *InterfaceAddrMessage) Sys() []Sys { return nil }
+
+// An InterfaceMulticastAddrMessage represents an interface multicast
+// address message.
+type InterfaceMulticastAddrMessage struct {
+ Version int // message version
+ Type int // messsage type
+ Flags int // interface flags
+ Index int // interface index
+ Addrs []Addr // addresses
+
+ raw []byte // raw message
+}
+
+// Sys implements the Sys method of Message interface.
+func (m *InterfaceMulticastAddrMessage) Sys() []Sys { return nil }
+
+// An InterfaceAnnounceMessage represents an interface announcement
+// message.
+type InterfaceAnnounceMessage struct {
+ Version int // message version
+ Type int // message type
+ Index int // interface index
+ Name string // interface name
+ What int // what type of announcement
+
+ raw []byte // raw message
+}
+
+// Sys implements the Sys method of Message interface.
+func (m *InterfaceAnnounceMessage) Sys() []Sys { return nil }
diff --git a/libgo/go/golang_org/x/net/route/interface_announce.go b/libgo/go/golang_org/x/net/route/interface_announce.go
new file mode 100644
index 00000000000..520d657b578
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/interface_announce.go
@@ -0,0 +1,32 @@
+// 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.
+
+// +build dragonfly freebsd netbsd
+
+package route
+
+func (w *wireFormat) parseInterfaceAnnounceMessage(_ RIBType, b []byte) (Message, error) {
+ if len(b) < w.bodyOff {
+ return nil, errMessageTooShort
+ }
+ l := int(nativeEndian.Uint16(b[:2]))
+ if len(b) < l {
+ return nil, errInvalidMessage
+ }
+ m := &InterfaceAnnounceMessage{
+ Version: int(b[2]),
+ Type: int(b[3]),
+ Index: int(nativeEndian.Uint16(b[4:6])),
+ What: int(nativeEndian.Uint16(b[22:24])),
+ raw: b[:l],
+ }
+ for i := 0; i < 16; i++ {
+ if b[6+i] != 0 {
+ continue
+ }
+ m.Name = string(b[6 : 6+i])
+ break
+ }
+ return m, nil
+}
diff --git a/libgo/go/golang_org/x/net/route/interface_classic.go b/libgo/go/golang_org/x/net/route/interface_classic.go
new file mode 100644
index 00000000000..ac4e7a6805a
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/interface_classic.go
@@ -0,0 +1,66 @@
+// 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.
+
+// +build darwin dragonfly netbsd
+
+package route
+
+import "runtime"
+
+func (w *wireFormat) parseInterfaceMessage(_ RIBType, b []byte) (Message, error) {
+ if len(b) < w.bodyOff {
+ return nil, errMessageTooShort
+ }
+ l := int(nativeEndian.Uint16(b[:2]))
+ if len(b) < l {
+ return nil, errInvalidMessage
+ }
+ attrs := uint(nativeEndian.Uint32(b[4:8]))
+ if attrs&sysRTA_IFP == 0 {
+ return nil, nil
+ }
+ m := &InterfaceMessage{
+ Version: int(b[2]),
+ Type: int(b[3]),
+ Addrs: make([]Addr, sysRTAX_MAX),
+ Flags: int(nativeEndian.Uint32(b[8:12])),
+ Index: int(nativeEndian.Uint16(b[12:14])),
+ extOff: w.extOff,
+ raw: b[:l],
+ }
+ a, err := parseLinkAddr(b[w.bodyOff:])
+ if err != nil {
+ return nil, err
+ }
+ m.Addrs[sysRTAX_IFP] = a
+ m.Name = a.(*LinkAddr).Name
+ return m, nil
+}
+
+func (w *wireFormat) parseInterfaceAddrMessage(_ RIBType, b []byte) (Message, error) {
+ if len(b) < w.bodyOff {
+ return nil, errMessageTooShort
+ }
+ l := int(nativeEndian.Uint16(b[:2]))
+ if len(b) < l {
+ return nil, errInvalidMessage
+ }
+ m := &InterfaceAddrMessage{
+ Version: int(b[2]),
+ Type: int(b[3]),
+ Flags: int(nativeEndian.Uint32(b[8:12])),
+ raw: b[:l],
+ }
+ if runtime.GOOS == "netbsd" {
+ m.Index = int(nativeEndian.Uint16(b[16:18]))
+ } else {
+ m.Index = int(nativeEndian.Uint16(b[12:14]))
+ }
+ var err error
+ m.Addrs, err = parseAddrs(uint(nativeEndian.Uint32(b[4:8])), parseKernelInetAddr, b[w.bodyOff:])
+ if err != nil {
+ return nil, err
+ }
+ return m, nil
+}
diff --git a/libgo/go/golang_org/x/net/route/interface_freebsd.go b/libgo/go/golang_org/x/net/route/interface_freebsd.go
new file mode 100644
index 00000000000..c83053915da
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/interface_freebsd.go
@@ -0,0 +1,78 @@
+// 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 route
+
+func (w *wireFormat) parseInterfaceMessage(typ RIBType, b []byte) (Message, error) {
+ var extOff, bodyOff int
+ if typ == sysNET_RT_IFLISTL {
+ if len(b) < 20 {
+ return nil, errMessageTooShort
+ }
+ extOff = int(nativeEndian.Uint16(b[18:20]))
+ bodyOff = int(nativeEndian.Uint16(b[16:18]))
+ } else {
+ if len(b) < w.bodyOff {
+ return nil, errMessageTooShort
+ }
+ extOff = w.extOff
+ bodyOff = w.bodyOff
+ }
+ l := int(nativeEndian.Uint16(b[:2]))
+ if len(b) < l {
+ return nil, errInvalidMessage
+ }
+ attrs := uint(nativeEndian.Uint32(b[4:8]))
+ if attrs&sysRTA_IFP == 0 {
+ return nil, nil
+ }
+ m := &InterfaceMessage{
+ Version: int(b[2]),
+ Type: int(b[3]),
+ Flags: int(nativeEndian.Uint32(b[8:12])),
+ Index: int(nativeEndian.Uint16(b[12:14])),
+ Addrs: make([]Addr, sysRTAX_MAX),
+ extOff: extOff,
+ raw: b[:l],
+ }
+ a, err := parseLinkAddr(b[bodyOff:])
+ if err != nil {
+ return nil, err
+ }
+ m.Addrs[sysRTAX_IFP] = a
+ m.Name = a.(*LinkAddr).Name
+ return m, nil
+}
+
+func (w *wireFormat) parseInterfaceAddrMessage(typ RIBType, b []byte) (Message, error) {
+ var bodyOff int
+ if typ == sysNET_RT_IFLISTL {
+ if len(b) < 24 {
+ return nil, errMessageTooShort
+ }
+ bodyOff = int(nativeEndian.Uint16(b[16:18]))
+ } else {
+ if len(b) < w.bodyOff {
+ return nil, errMessageTooShort
+ }
+ bodyOff = w.bodyOff
+ }
+ l := int(nativeEndian.Uint16(b[:2]))
+ if len(b) < l {
+ return nil, errInvalidMessage
+ }
+ m := &InterfaceAddrMessage{
+ Version: int(b[2]),
+ Type: int(b[3]),
+ Flags: int(nativeEndian.Uint32(b[8:12])),
+ Index: int(nativeEndian.Uint16(b[12:14])),
+ raw: b[:l],
+ }
+ var err error
+ m.Addrs, err = parseAddrs(uint(nativeEndian.Uint32(b[4:8])), parseKernelInetAddr, b[bodyOff:])
+ if err != nil {
+ return nil, err
+ }
+ return m, nil
+}
diff --git a/libgo/go/golang_org/x/net/route/interface_multicast.go b/libgo/go/golang_org/x/net/route/interface_multicast.go
new file mode 100644
index 00000000000..1e99a9cc64b
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/interface_multicast.go
@@ -0,0 +1,30 @@
+// 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.
+
+// +build darwin dragonfly freebsd
+
+package route
+
+func (w *wireFormat) parseInterfaceMulticastAddrMessage(_ RIBType, b []byte) (Message, error) {
+ if len(b) < w.bodyOff {
+ return nil, errMessageTooShort
+ }
+ l := int(nativeEndian.Uint16(b[:2]))
+ if len(b) < l {
+ return nil, errInvalidMessage
+ }
+ m := &InterfaceMulticastAddrMessage{
+ Version: int(b[2]),
+ Type: int(b[3]),
+ Flags: int(nativeEndian.Uint32(b[8:12])),
+ Index: int(nativeEndian.Uint16(b[12:14])),
+ raw: b[:l],
+ }
+ var err error
+ m.Addrs, err = parseAddrs(uint(nativeEndian.Uint32(b[4:8])), parseKernelInetAddr, b[w.bodyOff:])
+ if err != nil {
+ return nil, err
+ }
+ return m, nil
+}
diff --git a/libgo/go/golang_org/x/net/route/interface_openbsd.go b/libgo/go/golang_org/x/net/route/interface_openbsd.go
new file mode 100644
index 00000000000..24451d8ca12
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/interface_openbsd.go
@@ -0,0 +1,83 @@
+// 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 route
+
+func (*wireFormat) parseInterfaceMessage(_ RIBType, b []byte) (Message, error) {
+ if len(b) < 32 {
+ return nil, errMessageTooShort
+ }
+ l := int(nativeEndian.Uint16(b[:2]))
+ if len(b) < l {
+ return nil, errInvalidMessage
+ }
+ attrs := uint(nativeEndian.Uint32(b[12:16]))
+ if attrs&sysRTA_IFP == 0 {
+ return nil, nil
+ }
+ m := &InterfaceMessage{
+ Version: int(b[2]),
+ Type: int(b[3]),
+ Flags: int(nativeEndian.Uint32(b[16:20])),
+ Index: int(nativeEndian.Uint16(b[6:8])),
+ Addrs: make([]Addr, sysRTAX_MAX),
+ raw: b[:l],
+ }
+ a, err := parseLinkAddr(b[int(nativeEndian.Uint16(b[4:6])):])
+ if err != nil {
+ return nil, err
+ }
+ m.Addrs[sysRTAX_IFP] = a
+ m.Name = a.(*LinkAddr).Name
+ return m, nil
+}
+
+func (*wireFormat) parseInterfaceAddrMessage(_ RIBType, b []byte) (Message, error) {
+ if len(b) < 24 {
+ return nil, errMessageTooShort
+ }
+ l := int(nativeEndian.Uint16(b[:2]))
+ if len(b) < l {
+ return nil, errInvalidMessage
+ }
+ bodyOff := int(nativeEndian.Uint16(b[4:6]))
+ m := &InterfaceAddrMessage{
+ Version: int(b[2]),
+ Type: int(b[3]),
+ Flags: int(nativeEndian.Uint32(b[12:16])),
+ Index: int(nativeEndian.Uint16(b[6:8])),
+ raw: b[:l],
+ }
+ var err error
+ m.Addrs, err = parseAddrs(uint(nativeEndian.Uint32(b[12:16])), parseKernelInetAddr, b[bodyOff:])
+ if err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (*wireFormat) parseInterfaceAnnounceMessage(_ RIBType, b []byte) (Message, error) {
+ if len(b) < 26 {
+ return nil, errMessageTooShort
+ }
+ l := int(nativeEndian.Uint16(b[:2]))
+ if len(b) < l {
+ return nil, errInvalidMessage
+ }
+ m := &InterfaceAnnounceMessage{
+ Version: int(b[2]),
+ Type: int(b[3]),
+ Index: int(nativeEndian.Uint16(b[6:8])),
+ What: int(nativeEndian.Uint16(b[8:10])),
+ raw: b[:l],
+ }
+ for i := 0; i < 16; i++ {
+ if b[10+i] != 0 {
+ continue
+ }
+ m.Name = string(b[10 : 10+i])
+ break
+ }
+ return m, nil
+}
diff --git a/libgo/go/golang_org/x/net/route/message.go b/libgo/go/golang_org/x/net/route/message.go
new file mode 100644
index 00000000000..27cbf6b77ac
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/message.go
@@ -0,0 +1,70 @@
+// 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.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package route
+
+// A Message represents a routing message.
+//
+// Note: This interface will be changed to support Marshal method in
+// future version.
+type Message interface {
+ // Sys returns operating system-specific information.
+ Sys() []Sys
+}
+
+// A Sys reprensents operating system-specific information.
+type Sys interface {
+ // SysType returns a type of operating system-specific
+ // information.
+ SysType() SysType
+}
+
+// A SysType represents a type of operating system-specific
+// information.
+type SysType int
+
+const (
+ SysMetrics SysType = iota
+ SysStats
+)
+
+// ParseRIB parses b as a routing information base and returns a list
+// of routing messages.
+func ParseRIB(typ RIBType, b []byte) ([]Message, error) {
+ if !typ.parseable() {
+ return nil, errUnsupportedMessage
+ }
+ var msgs []Message
+ nmsgs, nskips := 0, 0
+ for len(b) > 4 {
+ nmsgs++
+ l := int(nativeEndian.Uint16(b[:2]))
+ if b[2] != sysRTM_VERSION {
+ b = b[l:]
+ continue
+ }
+ mtyp := int(b[3])
+ if fn, ok := parseFns[mtyp]; !ok {
+ nskips++
+ } else {
+ m, err := fn(typ, b)
+ if err != nil {
+ return nil, err
+ }
+ if m == nil {
+ nskips++
+ } else {
+ msgs = append(msgs, m)
+ }
+ }
+ b = b[l:]
+ }
+ // We failed to parse any of the messages - version mismatch?
+ if nmsgs != len(msgs)+nskips {
+ return nil, errMessageMismatch
+ }
+ return msgs, nil
+}
diff --git a/libgo/go/golang_org/x/net/route/message_darwin_test.go b/libgo/go/golang_org/x/net/route/message_darwin_test.go
new file mode 100644
index 00000000000..3fdd12df553
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/message_darwin_test.go
@@ -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 route
+
+import "testing"
+
+func TestFetchAndParseRIBOnDarwin(t *testing.T) {
+ for _, af := range []int{sysAF_UNSPEC, sysAF_INET, sysAF_INET6} {
+ for _, typ := range []RIBType{sysNET_RT_FLAGS, sysNET_RT_DUMP2, sysNET_RT_IFLIST2} {
+ ms, err := fetchAndParseRIB(af, typ)
+ if err != nil {
+ t.Error(err)
+ continue
+ }
+ ss, err := msgs(ms).validate()
+ if err != nil {
+ t.Errorf("%v %d %v", addrFamily(af), typ, err)
+ continue
+ }
+ for _, s := range ss {
+ t.Log(s)
+ }
+ }
+ }
+}
diff --git a/libgo/go/golang_org/x/net/route/message_freebsd_test.go b/libgo/go/golang_org/x/net/route/message_freebsd_test.go
new file mode 100644
index 00000000000..785c273f656
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/message_freebsd_test.go
@@ -0,0 +1,106 @@
+// 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 route
+
+import (
+ "testing"
+ "time"
+ "unsafe"
+)
+
+func TestFetchAndParseRIBOnFreeBSD(t *testing.T) {
+ for _, af := range []int{sysAF_UNSPEC, sysAF_INET, sysAF_INET6} {
+ for _, typ := range []RIBType{sysNET_RT_IFMALIST} {
+ ms, err := fetchAndParseRIB(af, typ)
+ if err != nil {
+ t.Error(err)
+ continue
+ }
+ ss, err := msgs(ms).validate()
+ if err != nil {
+ t.Errorf("%v %d %v", addrFamily(af), typ, err)
+ continue
+ }
+ for _, s := range ss {
+ t.Log(s)
+ }
+ }
+ }
+}
+
+func TestFetchAndParseRIBOnFreeBSD10AndAbove(t *testing.T) {
+ if _, err := FetchRIB(sysAF_UNSPEC, sysNET_RT_IFLISTL, 0); err != nil {
+ t.Skip("NET_RT_IFLISTL not supported")
+ }
+ var p uintptr
+ if kernelAlign != int(unsafe.Sizeof(p)) {
+ t.Skip("NET_RT_IFLIST vs. NET_RT_IFLISTL doesn't work for 386 emulation on amd64")
+ }
+
+ var tests = [2]struct {
+ typ RIBType
+ b []byte
+ msgs []Message
+ ss []string
+ }{
+ {typ: sysNET_RT_IFLIST},
+ {typ: sysNET_RT_IFLISTL},
+ }
+ for _, af := range []int{sysAF_UNSPEC, sysAF_INET, sysAF_INET6} {
+ var lastErr error
+ for i := 0; i < 3; i++ {
+ for j := range tests {
+ var err error
+ if tests[j].b, err = FetchRIB(af, tests[j].typ, 0); err != nil {
+ lastErr = err
+ time.Sleep(10 * time.Millisecond)
+ }
+ }
+ if lastErr == nil {
+ break
+ }
+ }
+ if lastErr != nil {
+ t.Error(af, lastErr)
+ continue
+ }
+ for i := range tests {
+ var err error
+ if tests[i].msgs, err = ParseRIB(tests[i].typ, tests[i].b); err != nil {
+ lastErr = err
+ t.Error(af, err)
+ }
+ }
+ if lastErr != nil {
+ continue
+ }
+ for i := range tests {
+ var err error
+ tests[i].ss, err = msgs(tests[i].msgs).validate()
+ if err != nil {
+ lastErr = err
+ t.Error(af, err)
+ }
+ for _, s := range tests[i].ss {
+ t.Log(s)
+ }
+ }
+ if lastErr != nil {
+ continue
+ }
+ for i := len(tests) - 1; i > 0; i-- {
+ if len(tests[i].ss) != len(tests[i-1].ss) {
+ t.Errorf("got %v; want %v", tests[i].ss, tests[i-1].ss)
+ continue
+ }
+ for j, s1 := range tests[i].ss {
+ s0 := tests[i-1].ss[j]
+ if s1 != s0 {
+ t.Errorf("got %s; want %s", s1, s0)
+ }
+ }
+ }
+ }
+}
diff --git a/libgo/go/golang_org/x/net/route/message_test.go b/libgo/go/golang_org/x/net/route/message_test.go
new file mode 100644
index 00000000000..a1263d8f25e
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/message_test.go
@@ -0,0 +1,95 @@
+// 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.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package route
+
+import (
+ "os"
+ "syscall"
+ "testing"
+ "time"
+)
+
+func TestFetchAndParseRIB(t *testing.T) {
+ for _, af := range []int{sysAF_UNSPEC, sysAF_INET, sysAF_INET6} {
+ for _, typ := range []RIBType{sysNET_RT_DUMP, sysNET_RT_IFLIST} {
+ ms, err := fetchAndParseRIB(af, typ)
+ if err != nil {
+ t.Error(err)
+ continue
+ }
+ ss, err := msgs(ms).validate()
+ if err != nil {
+ t.Errorf("%v %d %v", addrFamily(af), typ, err)
+ continue
+ }
+ for _, s := range ss {
+ t.Log(s)
+ }
+ }
+ }
+}
+
+func TestMonitorAndParseRIB(t *testing.T) {
+ if testing.Short() || os.Getuid() != 0 {
+ t.Skip("must be root")
+ }
+
+ // We suppose that using an IPv4 link-local address and the
+ // dot1Q ID for Token Ring and FDDI doesn't harm anyone.
+ pv := &propVirtual{addr: "169.254.0.1", mask: "255.255.255.0"}
+ if err := pv.configure(1002); err != nil {
+ t.Skip(err)
+ }
+ if err := pv.setup(); err != nil {
+ t.Skip(err)
+ }
+ pv.teardown()
+
+ s, err := syscall.Socket(syscall.AF_ROUTE, syscall.SOCK_RAW, syscall.AF_UNSPEC)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer syscall.Close(s)
+
+ go func() {
+ b := make([]byte, os.Getpagesize())
+ for {
+ n, err := syscall.Read(s, b)
+ if err != nil {
+ return
+ }
+ ms, err := ParseRIB(0, b[:n])
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ ss, err := msgs(ms).validate()
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ for _, s := range ss {
+ t.Log(s)
+ }
+ }
+ }()
+
+ for _, vid := range []int{1002, 1003, 1004, 1005} {
+ pv := &propVirtual{addr: "169.254.0.1", mask: "255.255.255.0"}
+ if err := pv.configure(vid); err != nil {
+ t.Fatal(err)
+ }
+ if err := pv.setup(); err != nil {
+ t.Fatal(err)
+ }
+ time.Sleep(200 * time.Millisecond)
+ if err := pv.teardown(); err != nil {
+ t.Fatal(err)
+ }
+ time.Sleep(200 * time.Millisecond)
+ }
+}
diff --git a/libgo/go/golang_org/x/net/route/route.go b/libgo/go/golang_org/x/net/route/route.go
new file mode 100644
index 00000000000..c986e29ebc9
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/route.go
@@ -0,0 +1,74 @@
+// 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.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+// Package route provides basic functions for the manipulation of
+// packet routing facilities on BSD variants.
+//
+// The package supports any version of Darwin, any version of
+// DragonFly BSD, FreeBSD 7 through 11, NetBSD 6 and above, and
+// OpenBSD 5.6 and above.
+package route
+
+import (
+ "errors"
+ "os"
+ "syscall"
+)
+
+var (
+ errUnsupportedMessage = errors.New("unsupported message")
+ errMessageMismatch = errors.New("message mismatch")
+ errMessageTooShort = errors.New("message too short")
+ errInvalidMessage = errors.New("invalid message")
+ errInvalidAddr = errors.New("invalid address")
+)
+
+// A RouteMessage represents a message conveying an address prefix, a
+// nexthop address and an output interface.
+type RouteMessage struct {
+ Version int // message version
+ Type int // message type
+ Flags int // route flags
+ Index int // interface index when atatched
+ Addrs []Addr // addresses
+
+ extOff int // offset of header extension
+ raw []byte // raw message
+}
+
+// A RIBType reprensents a type of routing information base.
+type RIBType int
+
+const (
+ RIBTypeRoute RIBType = syscall.NET_RT_DUMP
+ RIBTypeInterface RIBType = syscall.NET_RT_IFLIST
+)
+
+// FetchRIB fetches a routing information base from the operating
+// system.
+//
+// The provided af must be an address family.
+//
+// The provided arg must be a RIBType-specific argument.
+// When RIBType is related to routes, arg might be a set of route
+// flags. When RIBType is related to network interfaces, arg might be
+// an interface index or a set of interface flags. In most cases, zero
+// means a wildcard.
+func FetchRIB(af int, typ RIBType, arg int) ([]byte, error) {
+ mib := [6]int32{sysCTL_NET, sysAF_ROUTE, 0, int32(af), int32(typ), int32(arg)}
+ n := uintptr(0)
+ if err := sysctl(mib[:], nil, &n, nil, 0); err != nil {
+ return nil, os.NewSyscallError("sysctl", err)
+ }
+ if n == 0 {
+ return nil, nil
+ }
+ b := make([]byte, n)
+ if err := sysctl(mib[:], &b[0], &n, nil, 0); err != nil {
+ return nil, os.NewSyscallError("sysctl", err)
+ }
+ return b[:n], nil
+}
diff --git a/libgo/go/golang_org/x/net/route/route_classic.go b/libgo/go/golang_org/x/net/route/route_classic.go
new file mode 100644
index 00000000000..d333c6aa526
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/route_classic.go
@@ -0,0 +1,31 @@
+// 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.
+
+// +build darwin dragonfly freebsd netbsd
+
+package route
+
+func (w *wireFormat) parseRouteMessage(typ RIBType, b []byte) (Message, error) {
+ if len(b) < w.bodyOff {
+ return nil, errMessageTooShort
+ }
+ l := int(nativeEndian.Uint16(b[:2]))
+ if len(b) < l {
+ return nil, errInvalidMessage
+ }
+ m := &RouteMessage{
+ Version: int(b[2]),
+ Type: int(b[3]),
+ Flags: int(nativeEndian.Uint32(b[8:12])),
+ Index: int(nativeEndian.Uint16(b[4:6])),
+ extOff: w.extOff,
+ raw: b[:l],
+ }
+ var err error
+ m.Addrs, err = parseAddrs(uint(nativeEndian.Uint32(b[12:16])), parseKernelInetAddr, b[w.bodyOff:])
+ if err != nil {
+ return nil, err
+ }
+ return m, nil
+}
diff --git a/libgo/go/golang_org/x/net/route/route_openbsd.go b/libgo/go/golang_org/x/net/route/route_openbsd.go
new file mode 100644
index 00000000000..b07862f04d3
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/route_openbsd.go
@@ -0,0 +1,28 @@
+// 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 route
+
+func (*wireFormat) parseRouteMessage(_ RIBType, b []byte) (Message, error) {
+ if len(b) < 40 {
+ return nil, errMessageTooShort
+ }
+ l := int(nativeEndian.Uint16(b[:2]))
+ if len(b) < l {
+ return nil, errInvalidMessage
+ }
+ m := &RouteMessage{
+ Version: int(b[2]),
+ Type: int(b[3]),
+ Flags: int(nativeEndian.Uint32(b[16:20])),
+ Index: int(nativeEndian.Uint16(b[6:8])),
+ raw: b[:l],
+ }
+ as, err := parseAddrs(uint(nativeEndian.Uint32(b[12:16])), parseKernelInetAddr, b[int(nativeEndian.Uint16(b[4:6])):])
+ if err != nil {
+ return nil, err
+ }
+ m.Addrs = as
+ return m, nil
+}
diff --git a/libgo/go/golang_org/x/net/route/route_test.go b/libgo/go/golang_org/x/net/route/route_test.go
new file mode 100644
index 00000000000..99f57b712d9
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/route_test.go
@@ -0,0 +1,385 @@
+// 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.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package route
+
+import (
+ "fmt"
+ "os/exec"
+ "runtime"
+ "time"
+)
+
+func (m *RouteMessage) String() string {
+ return fmt.Sprintf("%s", addrAttrs(nativeEndian.Uint32(m.raw[12:16])))
+}
+
+func (m *InterfaceMessage) String() string {
+ var attrs addrAttrs
+ if runtime.GOOS == "openbsd" {
+ attrs = addrAttrs(nativeEndian.Uint32(m.raw[12:16]))
+ } else {
+ attrs = addrAttrs(nativeEndian.Uint32(m.raw[4:8]))
+ }
+ return fmt.Sprintf("%s", attrs)
+}
+
+func (m *InterfaceAddrMessage) String() string {
+ var attrs addrAttrs
+ if runtime.GOOS == "openbsd" {
+ attrs = addrAttrs(nativeEndian.Uint32(m.raw[12:16]))
+ } else {
+ attrs = addrAttrs(nativeEndian.Uint32(m.raw[4:8]))
+ }
+ return fmt.Sprintf("%s", attrs)
+}
+
+func (m *InterfaceMulticastAddrMessage) String() string {
+ return fmt.Sprintf("%s", addrAttrs(nativeEndian.Uint32(m.raw[4:8])))
+}
+
+func (m *InterfaceAnnounceMessage) String() string {
+ what := "<nil>"
+ switch m.What {
+ case 0:
+ what = "arrival"
+ case 1:
+ what = "departure"
+ }
+ return fmt.Sprintf("(%d %s %s)", m.Index, m.Name, what)
+}
+
+func (m *InterfaceMetrics) String() string {
+ return fmt.Sprintf("(type=%d mtu=%d)", m.Type, m.MTU)
+}
+
+func (m *RouteMetrics) String() string {
+ return fmt.Sprintf("(pmtu=%d)", m.PathMTU)
+}
+
+type addrAttrs uint
+
+var addrAttrNames = [...]string{
+ "dst",
+ "gateway",
+ "netmask",
+ "genmask",
+ "ifp",
+ "ifa",
+ "author",
+ "brd",
+ "df:mpls1-n:tag-o:src", // mpls1 for dragonfly, tag for netbsd, src for openbsd
+ "df:mpls2-o:srcmask", // mpls2 for dragonfly, srcmask for openbsd
+ "df:mpls3-o:label", // mpls3 for dragonfly, label for openbsd
+}
+
+func (attrs addrAttrs) String() string {
+ var s string
+ for i, name := range addrAttrNames {
+ if attrs&(1<<uint(i)) != 0 {
+ if s != "" {
+ s += "|"
+ }
+ s += name
+ }
+ }
+ if s == "" {
+ return "<nil>"
+ }
+ return s
+}
+
+type msgs []Message
+
+func (ms msgs) validate() ([]string, error) {
+ var ss []string
+ for _, m := range ms {
+ switch m := m.(type) {
+ case *RouteMessage:
+ if err := addrs(m.Addrs).match(addrAttrs(nativeEndian.Uint32(m.raw[12:16]))); err != nil {
+ return nil, err
+ }
+ sys := m.Sys()
+ if sys == nil {
+ return nil, fmt.Errorf("no sys for %s", m.String())
+ }
+ ss = append(ss, m.String()+" "+syss(sys).String()+" "+addrs(m.Addrs).String())
+ case *InterfaceMessage:
+ var attrs addrAttrs
+ if runtime.GOOS == "openbsd" {
+ attrs = addrAttrs(nativeEndian.Uint32(m.raw[12:16]))
+ } else {
+ attrs = addrAttrs(nativeEndian.Uint32(m.raw[4:8]))
+ }
+ if err := addrs(m.Addrs).match(attrs); err != nil {
+ return nil, err
+ }
+ sys := m.Sys()
+ if sys == nil {
+ return nil, fmt.Errorf("no sys for %s", m.String())
+ }
+ ss = append(ss, m.String()+" "+syss(sys).String()+" "+addrs(m.Addrs).String())
+ case *InterfaceAddrMessage:
+ var attrs addrAttrs
+ if runtime.GOOS == "openbsd" {
+ attrs = addrAttrs(nativeEndian.Uint32(m.raw[12:16]))
+ } else {
+ attrs = addrAttrs(nativeEndian.Uint32(m.raw[4:8]))
+ }
+ if err := addrs(m.Addrs).match(attrs); err != nil {
+ return nil, err
+ }
+ ss = append(ss, m.String()+" "+addrs(m.Addrs).String())
+ case *InterfaceMulticastAddrMessage:
+ if err := addrs(m.Addrs).match(addrAttrs(nativeEndian.Uint32(m.raw[4:8]))); err != nil {
+ return nil, err
+ }
+ ss = append(ss, m.String()+" "+addrs(m.Addrs).String())
+ case *InterfaceAnnounceMessage:
+ ss = append(ss, m.String())
+ default:
+ ss = append(ss, fmt.Sprintf("%+v", m))
+ }
+ }
+ return ss, nil
+}
+
+type syss []Sys
+
+func (sys syss) String() string {
+ var s string
+ for _, sy := range sys {
+ switch sy := sy.(type) {
+ case *InterfaceMetrics:
+ if len(s) > 0 {
+ s += " "
+ }
+ s += sy.String()
+ case *RouteMetrics:
+ if len(s) > 0 {
+ s += " "
+ }
+ s += sy.String()
+ }
+ }
+ return s
+}
+
+type addrFamily int
+
+func (af addrFamily) String() string {
+ switch af {
+ case sysAF_UNSPEC:
+ return "unspec"
+ case sysAF_LINK:
+ return "link"
+ case sysAF_INET:
+ return "inet4"
+ case sysAF_INET6:
+ return "inet6"
+ default:
+ return fmt.Sprintf("%d", af)
+ }
+}
+
+const hexDigit = "0123456789abcdef"
+
+type llAddr []byte
+
+func (a llAddr) String() string {
+ if len(a) == 0 {
+ return ""
+ }
+ buf := make([]byte, 0, len(a)*3-1)
+ for i, b := range a {
+ if i > 0 {
+ buf = append(buf, ':')
+ }
+ buf = append(buf, hexDigit[b>>4])
+ buf = append(buf, hexDigit[b&0xF])
+ }
+ return string(buf)
+}
+
+type ipAddr []byte
+
+func (a ipAddr) String() string {
+ if len(a) == 0 {
+ return "<nil>"
+ }
+ if len(a) == 4 {
+ return fmt.Sprintf("%d.%d.%d.%d", a[0], a[1], a[2], a[3])
+ }
+ if len(a) == 16 {
+ return fmt.Sprintf("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15])
+ }
+ s := make([]byte, len(a)*2)
+ for i, tn := range a {
+ s[i*2], s[i*2+1] = hexDigit[tn>>4], hexDigit[tn&0xf]
+ }
+ return string(s)
+}
+
+func (a *LinkAddr) String() string {
+ name := a.Name
+ if name == "" {
+ name = "<nil>"
+ }
+ lla := llAddr(a.Addr).String()
+ if lla == "" {
+ lla = "<nil>"
+ }
+ return fmt.Sprintf("(%v %d %s %s)", addrFamily(a.Family()), a.Index, name, lla)
+}
+
+func (a Inet4Addr) String() string {
+ return fmt.Sprintf("(%v %v)", addrFamily(a.Family()), ipAddr(a.IP[:]))
+}
+
+func (a *Inet6Addr) String() string {
+ return fmt.Sprintf("(%v %v %d)", addrFamily(a.Family()), ipAddr(a.IP[:]), a.ZoneID)
+}
+
+func (a *DefaultAddr) String() string {
+ return fmt.Sprintf("(%v %s)", addrFamily(a.Family()), ipAddr(a.Raw[2:]).String())
+}
+
+type addrs []Addr
+
+func (as addrs) String() string {
+ var s string
+ for _, a := range as {
+ if a == nil {
+ continue
+ }
+ if len(s) > 0 {
+ s += " "
+ }
+ switch a := a.(type) {
+ case *LinkAddr:
+ s += a.String()
+ case *Inet4Addr:
+ s += a.String()
+ case *Inet6Addr:
+ s += a.String()
+ case *DefaultAddr:
+ s += a.String()
+ }
+ }
+ if s == "" {
+ return "<nil>"
+ }
+ return s
+}
+
+func (as addrs) match(attrs addrAttrs) error {
+ var ts addrAttrs
+ af := sysAF_UNSPEC
+ for i := range as {
+ if as[i] != nil {
+ ts |= 1 << uint(i)
+ }
+ switch as[i].(type) {
+ case *Inet4Addr:
+ if af == sysAF_UNSPEC {
+ af = sysAF_INET
+ }
+ if af != sysAF_INET {
+ return fmt.Errorf("got %v; want %v", addrs(as), addrFamily(af))
+ }
+ case *Inet6Addr:
+ if af == sysAF_UNSPEC {
+ af = sysAF_INET6
+ }
+ if af != sysAF_INET6 {
+ return fmt.Errorf("got %v; want %v", addrs(as), addrFamily(af))
+ }
+ }
+ }
+ if ts != attrs && ts > attrs {
+ return fmt.Errorf("%v not included in %v", ts, attrs)
+ }
+ return nil
+}
+
+func fetchAndParseRIB(af int, typ RIBType) ([]Message, error) {
+ var err error
+ var b []byte
+ for i := 0; i < 3; i++ {
+ if b, err = FetchRIB(af, typ, 0); err != nil {
+ time.Sleep(10 * time.Millisecond)
+ continue
+ }
+ break
+ }
+ if err != nil {
+ return nil, fmt.Errorf("%v %d %v", addrFamily(af), typ, err)
+ }
+ ms, err := ParseRIB(typ, b)
+ if err != nil {
+ return nil, fmt.Errorf("%v %d %v", addrFamily(af), typ, err)
+ }
+ return ms, nil
+}
+
+type propVirtual struct {
+ name string
+ addr, mask string
+ setupCmds []*exec.Cmd
+ teardownCmds []*exec.Cmd
+}
+
+func (ti *propVirtual) setup() error {
+ for _, cmd := range ti.setupCmds {
+ if err := cmd.Run(); err != nil {
+ ti.teardown()
+ return err
+ }
+ }
+ return nil
+}
+
+func (ti *propVirtual) teardown() error {
+ for _, cmd := range ti.teardownCmds {
+ if err := cmd.Run(); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (ti *propVirtual) configure(suffix int) error {
+ if runtime.GOOS == "openbsd" {
+ ti.name = fmt.Sprintf("vether%d", suffix)
+ } else {
+ ti.name = fmt.Sprintf("vlan%d", suffix)
+ }
+ xname, err := exec.LookPath("ifconfig")
+ if err != nil {
+ return err
+ }
+ ti.setupCmds = append(ti.setupCmds, &exec.Cmd{
+ Path: xname,
+ Args: []string{"ifconfig", ti.name, "create"},
+ })
+ if runtime.GOOS == "netbsd" {
+ // NetBSD requires an underlying dot1Q-capable network
+ // interface.
+ ti.setupCmds = append(ti.setupCmds, &exec.Cmd{
+ Path: xname,
+ Args: []string{"ifconfig", ti.name, "vlan", fmt.Sprintf("%d", suffix&0xfff), "vlanif", "wm0"},
+ })
+ }
+ ti.setupCmds = append(ti.setupCmds, &exec.Cmd{
+ Path: xname,
+ Args: []string{"ifconfig", ti.name, "inet", ti.addr, "netmask", ti.mask},
+ })
+ ti.teardownCmds = append(ti.teardownCmds, &exec.Cmd{
+ Path: xname,
+ Args: []string{"ifconfig", ti.name, "destroy"},
+ })
+ return nil
+}
diff --git a/libgo/go/golang_org/x/net/route/sys.go b/libgo/go/golang_org/x/net/route/sys.go
new file mode 100644
index 00000000000..80ca83ae137
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/sys.go
@@ -0,0 +1,40 @@
+// 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.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package route
+
+import "unsafe"
+
+var (
+ nativeEndian binaryByteOrder
+ kernelAlign int
+ parseFns map[int]parseFn
+)
+
+func init() {
+ i := uint32(1)
+ b := (*[4]byte)(unsafe.Pointer(&i))
+ if b[0] == 1 {
+ nativeEndian = littleEndian
+ } else {
+ nativeEndian = bigEndian
+ }
+ kernelAlign, parseFns = probeRoutingStack()
+}
+
+func roundup(l int) int {
+ if l == 0 {
+ return kernelAlign
+ }
+ return (l + kernelAlign - 1) & ^(kernelAlign - 1)
+}
+
+type parseFn func(RIBType, []byte) (Message, error)
+
+type wireFormat struct {
+ extOff int // offset of header extension
+ bodyOff int // offset of message body
+}
diff --git a/libgo/go/golang_org/x/net/route/sys_darwin.go b/libgo/go/golang_org/x/net/route/sys_darwin.go
new file mode 100644
index 00000000000..fff3a0fd1db
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/sys_darwin.go
@@ -0,0 +1,80 @@
+// 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 route
+
+func (typ RIBType) parseable() bool {
+ switch typ {
+ case sysNET_RT_STAT, sysNET_RT_TRASH:
+ return false
+ default:
+ return true
+ }
+}
+
+// A RouteMetrics represents route metrics.
+type RouteMetrics struct {
+ PathMTU int // path maximum transmission unit
+}
+
+// SysType implements the SysType method of Sys interface.
+func (rmx *RouteMetrics) SysType() SysType { return SysMetrics }
+
+// Sys implements the Sys method of Message interface.
+func (m *RouteMessage) Sys() []Sys {
+ return []Sys{
+ &RouteMetrics{
+ PathMTU: int(nativeEndian.Uint32(m.raw[m.extOff+4 : m.extOff+8])),
+ },
+ }
+}
+
+// A InterfaceMetrics represents interface metrics.
+type InterfaceMetrics struct {
+ Type int // interface type
+ MTU int // maximum transmission unit
+}
+
+// SysType implements the SysType method of Sys interface.
+func (imx *InterfaceMetrics) SysType() SysType { return SysMetrics }
+
+// Sys implements the Sys method of Message interface.
+func (m *InterfaceMessage) Sys() []Sys {
+ return []Sys{
+ &InterfaceMetrics{
+ Type: int(m.raw[m.extOff]),
+ MTU: int(nativeEndian.Uint32(m.raw[m.extOff+8 : m.extOff+12])),
+ },
+ }
+}
+
+func probeRoutingStack() (int, map[int]parseFn) {
+ rtm := &wireFormat{extOff: 36, bodyOff: sizeofRtMsghdrDarwin15}
+ rtm2 := &wireFormat{extOff: 36, bodyOff: sizeofRtMsghdr2Darwin15}
+ ifm := &wireFormat{extOff: 16, bodyOff: sizeofIfMsghdrDarwin15}
+ ifm2 := &wireFormat{extOff: 32, bodyOff: sizeofIfMsghdr2Darwin15}
+ ifam := &wireFormat{extOff: sizeofIfaMsghdrDarwin15, bodyOff: sizeofIfaMsghdrDarwin15}
+ ifmam := &wireFormat{extOff: sizeofIfmaMsghdrDarwin15, bodyOff: sizeofIfmaMsghdrDarwin15}
+ ifmam2 := &wireFormat{extOff: sizeofIfmaMsghdr2Darwin15, bodyOff: sizeofIfmaMsghdr2Darwin15}
+ // Darwin kernels require 32-bit aligned access to routing facilities.
+ return 4, map[int]parseFn{
+ sysRTM_ADD: rtm.parseRouteMessage,
+ sysRTM_DELETE: rtm.parseRouteMessage,
+ sysRTM_CHANGE: rtm.parseRouteMessage,
+ sysRTM_GET: rtm.parseRouteMessage,
+ sysRTM_LOSING: rtm.parseRouteMessage,
+ sysRTM_REDIRECT: rtm.parseRouteMessage,
+ sysRTM_MISS: rtm.parseRouteMessage,
+ sysRTM_LOCK: rtm.parseRouteMessage,
+ sysRTM_RESOLVE: rtm.parseRouteMessage,
+ sysRTM_NEWADDR: ifam.parseInterfaceAddrMessage,
+ sysRTM_DELADDR: ifam.parseInterfaceAddrMessage,
+ sysRTM_IFINFO: ifm.parseInterfaceMessage,
+ sysRTM_NEWMADDR: ifmam.parseInterfaceMulticastAddrMessage,
+ sysRTM_DELMADDR: ifmam.parseInterfaceMulticastAddrMessage,
+ sysRTM_IFINFO2: ifm2.parseInterfaceMessage,
+ sysRTM_NEWMADDR2: ifmam2.parseInterfaceMulticastAddrMessage,
+ sysRTM_GET2: rtm2.parseRouteMessage,
+ }
+}
diff --git a/libgo/go/golang_org/x/net/route/sys_dragonfly.go b/libgo/go/golang_org/x/net/route/sys_dragonfly.go
new file mode 100644
index 00000000000..da848b3d076
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/sys_dragonfly.go
@@ -0,0 +1,71 @@
+// 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 route
+
+import "unsafe"
+
+func (typ RIBType) parseable() bool { return true }
+
+// A RouteMetrics represents route metrics.
+type RouteMetrics struct {
+ PathMTU int // path maximum transmission unit
+}
+
+// SysType implements the SysType method of Sys interface.
+func (rmx *RouteMetrics) SysType() SysType { return SysMetrics }
+
+// Sys implements the Sys method of Message interface.
+func (m *RouteMessage) Sys() []Sys {
+ return []Sys{
+ &RouteMetrics{
+ PathMTU: int(nativeEndian.Uint64(m.raw[m.extOff+8 : m.extOff+16])),
+ },
+ }
+}
+
+// A InterfaceMetrics represents interface metrics.
+type InterfaceMetrics struct {
+ Type int // interface type
+ MTU int // maximum transmission unit
+}
+
+// SysType implements the SysType method of Sys interface.
+func (imx *InterfaceMetrics) SysType() SysType { return SysMetrics }
+
+// Sys implements the Sys method of Message interface.
+func (m *InterfaceMessage) Sys() []Sys {
+ return []Sys{
+ &InterfaceMetrics{
+ Type: int(m.raw[m.extOff]),
+ MTU: int(nativeEndian.Uint32(m.raw[m.extOff+8 : m.extOff+12])),
+ },
+ }
+}
+
+func probeRoutingStack() (int, map[int]parseFn) {
+ var p uintptr
+ rtm := &wireFormat{extOff: 40, bodyOff: sizeofRtMsghdrDragonFlyBSD4}
+ ifm := &wireFormat{extOff: 16, bodyOff: sizeofIfMsghdrDragonFlyBSD4}
+ ifam := &wireFormat{extOff: sizeofIfaMsghdrDragonFlyBSD4, bodyOff: sizeofIfaMsghdrDragonFlyBSD4}
+ ifmam := &wireFormat{extOff: sizeofIfmaMsghdrDragonFlyBSD4, bodyOff: sizeofIfmaMsghdrDragonFlyBSD4}
+ ifanm := &wireFormat{extOff: sizeofIfAnnouncemsghdrDragonFlyBSD4, bodyOff: sizeofIfAnnouncemsghdrDragonFlyBSD4}
+ return int(unsafe.Sizeof(p)), map[int]parseFn{
+ sysRTM_ADD: rtm.parseRouteMessage,
+ sysRTM_DELETE: rtm.parseRouteMessage,
+ sysRTM_CHANGE: rtm.parseRouteMessage,
+ sysRTM_GET: rtm.parseRouteMessage,
+ sysRTM_LOSING: rtm.parseRouteMessage,
+ sysRTM_REDIRECT: rtm.parseRouteMessage,
+ sysRTM_MISS: rtm.parseRouteMessage,
+ sysRTM_LOCK: rtm.parseRouteMessage,
+ sysRTM_RESOLVE: rtm.parseRouteMessage,
+ sysRTM_NEWADDR: ifam.parseInterfaceAddrMessage,
+ sysRTM_DELADDR: ifam.parseInterfaceAddrMessage,
+ sysRTM_IFINFO: ifm.parseInterfaceMessage,
+ sysRTM_NEWMADDR: ifmam.parseInterfaceMulticastAddrMessage,
+ sysRTM_DELMADDR: ifmam.parseInterfaceMulticastAddrMessage,
+ sysRTM_IFANNOUNCE: ifanm.parseInterfaceAnnounceMessage,
+ }
+}
diff --git a/libgo/go/golang_org/x/net/route/sys_freebsd.go b/libgo/go/golang_org/x/net/route/sys_freebsd.go
new file mode 100644
index 00000000000..7b05c1a5a05
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/sys_freebsd.go
@@ -0,0 +1,150 @@
+// 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 route
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+func (typ RIBType) parseable() bool { return true }
+
+// A RouteMetrics represents route metrics.
+type RouteMetrics struct {
+ PathMTU int // path maximum transmission unit
+}
+
+// SysType implements the SysType method of Sys interface.
+func (rmx *RouteMetrics) SysType() SysType { return SysMetrics }
+
+// Sys implements the Sys method of Message interface.
+func (m *RouteMessage) Sys() []Sys {
+ if kernelAlign == 8 {
+ return []Sys{
+ &RouteMetrics{
+ PathMTU: int(nativeEndian.Uint64(m.raw[m.extOff+8 : m.extOff+16])),
+ },
+ }
+ }
+ return []Sys{
+ &RouteMetrics{
+ PathMTU: int(nativeEndian.Uint32(m.raw[m.extOff+4 : m.extOff+8])),
+ },
+ }
+}
+
+// A InterfaceMetrics represents interface metrics.
+type InterfaceMetrics struct {
+ Type int // interface type
+ MTU int // maximum transmission unit
+}
+
+// SysType implements the SysType method of Sys interface.
+func (imx *InterfaceMetrics) SysType() SysType { return SysMetrics }
+
+// Sys implements the Sys method of Message interface.
+func (m *InterfaceMessage) Sys() []Sys {
+ return []Sys{
+ &InterfaceMetrics{
+ Type: int(m.raw[m.extOff]),
+ MTU: int(nativeEndian.Uint32(m.raw[m.extOff+8 : m.extOff+12])),
+ },
+ }
+}
+
+func probeRoutingStack() (int, map[int]parseFn) {
+ var p uintptr
+ wordSize := int(unsafe.Sizeof(p))
+ align := int(unsafe.Sizeof(p))
+ // In the case of kern.supported_archs="amd64 i386", we need
+ // to know the underlying kernel's architecture because the
+ // alignment for routing facilities are set at the build time
+ // of the kernel.
+ conf, _ := syscall.Sysctl("kern.conftxt")
+ for i, j := 0, 0; j < len(conf); j++ {
+ if conf[j] != '\n' {
+ continue
+ }
+ s := conf[i:j]
+ i = j + 1
+ if len(s) > len("machine") && s[:len("machine")] == "machine" {
+ s = s[len("machine"):]
+ for k := 0; k < len(s); k++ {
+ if s[k] == ' ' || s[k] == '\t' {
+ s = s[1:]
+ }
+ break
+ }
+ if s == "amd64" {
+ align = 8
+ }
+ break
+ }
+ }
+ var rtm, ifm, ifam, ifmam, ifanm *wireFormat
+ if align != wordSize { // 386 emulation on amd64
+ rtm = &wireFormat{extOff: sizeofRtMsghdrFreeBSD10Emu - sizeofRtMetricsFreeBSD10Emu, bodyOff: sizeofRtMsghdrFreeBSD10Emu}
+ ifm = &wireFormat{extOff: 16}
+ ifam = &wireFormat{extOff: sizeofIfaMsghdrFreeBSD10Emu, bodyOff: sizeofIfaMsghdrFreeBSD10Emu}
+ ifmam = &wireFormat{extOff: sizeofIfmaMsghdrFreeBSD10Emu, bodyOff: sizeofIfmaMsghdrFreeBSD10Emu}
+ ifanm = &wireFormat{extOff: sizeofIfAnnouncemsghdrFreeBSD10Emu, bodyOff: sizeofIfAnnouncemsghdrFreeBSD10Emu}
+ } else {
+ rtm = &wireFormat{extOff: sizeofRtMsghdrFreeBSD10 - sizeofRtMetricsFreeBSD10, bodyOff: sizeofRtMsghdrFreeBSD10}
+ ifm = &wireFormat{extOff: 16}
+ ifam = &wireFormat{extOff: sizeofIfaMsghdrFreeBSD10, bodyOff: sizeofIfaMsghdrFreeBSD10}
+ ifmam = &wireFormat{extOff: sizeofIfmaMsghdrFreeBSD10, bodyOff: sizeofIfmaMsghdrFreeBSD10}
+ ifanm = &wireFormat{extOff: sizeofIfAnnouncemsghdrFreeBSD10, bodyOff: sizeofIfAnnouncemsghdrFreeBSD10}
+ }
+ rel, _ := syscall.SysctlUint32("kern.osreldate")
+ switch {
+ case rel < 800000:
+ if align != wordSize { // 386 emulation on amd64
+ ifm.bodyOff = sizeofIfMsghdrFreeBSD7Emu
+ } else {
+ ifm.bodyOff = sizeofIfMsghdrFreeBSD7
+ }
+ case 800000 <= rel && rel < 900000:
+ if align != wordSize { // 386 emulation on amd64
+ ifm.bodyOff = sizeofIfMsghdrFreeBSD8Emu
+ } else {
+ ifm.bodyOff = sizeofIfMsghdrFreeBSD8
+ }
+ case 900000 <= rel && rel < 1000000:
+ if align != wordSize { // 386 emulation on amd64
+ ifm.bodyOff = sizeofIfMsghdrFreeBSD9Emu
+ } else {
+ ifm.bodyOff = sizeofIfMsghdrFreeBSD9
+ }
+ case 1000000 <= rel && rel < 1100000:
+ if align != wordSize { // 386 emulation on amd64
+ ifm.bodyOff = sizeofIfMsghdrFreeBSD10Emu
+ } else {
+ ifm.bodyOff = sizeofIfMsghdrFreeBSD10
+ }
+ default:
+ if align != wordSize { // 386 emulation on amd64
+ ifm.bodyOff = sizeofIfMsghdrFreeBSD11Emu
+ } else {
+ ifm.bodyOff = sizeofIfMsghdrFreeBSD11
+ }
+ }
+ return align, map[int]parseFn{
+ sysRTM_ADD: rtm.parseRouteMessage,
+ sysRTM_DELETE: rtm.parseRouteMessage,
+ sysRTM_CHANGE: rtm.parseRouteMessage,
+ sysRTM_GET: rtm.parseRouteMessage,
+ sysRTM_LOSING: rtm.parseRouteMessage,
+ sysRTM_REDIRECT: rtm.parseRouteMessage,
+ sysRTM_MISS: rtm.parseRouteMessage,
+ sysRTM_LOCK: rtm.parseRouteMessage,
+ sysRTM_RESOLVE: rtm.parseRouteMessage,
+ sysRTM_NEWADDR: ifam.parseInterfaceAddrMessage,
+ sysRTM_DELADDR: ifam.parseInterfaceAddrMessage,
+ sysRTM_IFINFO: ifm.parseInterfaceMessage,
+ sysRTM_NEWMADDR: ifmam.parseInterfaceMulticastAddrMessage,
+ sysRTM_DELMADDR: ifmam.parseInterfaceMulticastAddrMessage,
+ sysRTM_IFANNOUNCE: ifanm.parseInterfaceAnnounceMessage,
+ }
+}
diff --git a/libgo/go/golang_org/x/net/route/sys_netbsd.go b/libgo/go/golang_org/x/net/route/sys_netbsd.go
new file mode 100644
index 00000000000..4d8076b518d
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/sys_netbsd.go
@@ -0,0 +1,67 @@
+// 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 route
+
+func (typ RIBType) parseable() bool { return true }
+
+// A RouteMetrics represents route metrics.
+type RouteMetrics struct {
+ PathMTU int // path maximum transmission unit
+}
+
+// SysType implements the SysType method of Sys interface.
+func (rmx *RouteMetrics) SysType() SysType { return SysMetrics }
+
+// Sys implements the Sys method of Message interface.
+func (m *RouteMessage) Sys() []Sys {
+ return []Sys{
+ &RouteMetrics{
+ PathMTU: int(nativeEndian.Uint64(m.raw[m.extOff+8 : m.extOff+16])),
+ },
+ }
+}
+
+// A InterfaceMetrics represents interface metrics.
+type InterfaceMetrics struct {
+ Type int // interface type
+ MTU int // maximum transmission unit
+}
+
+// SysType implements the SysType method of Sys interface.
+func (imx *InterfaceMetrics) SysType() SysType { return SysMetrics }
+
+// Sys implements the Sys method of Message interface.
+func (m *InterfaceMessage) Sys() []Sys {
+ return []Sys{
+ &InterfaceMetrics{
+ Type: int(m.raw[m.extOff]),
+ MTU: int(nativeEndian.Uint32(m.raw[m.extOff+8 : m.extOff+12])),
+ },
+ }
+}
+
+func probeRoutingStack() (int, map[int]parseFn) {
+ rtm := &wireFormat{extOff: 40, bodyOff: sizeofRtMsghdrNetBSD7}
+ ifm := &wireFormat{extOff: 16, bodyOff: sizeofIfMsghdrNetBSD7}
+ ifam := &wireFormat{extOff: sizeofIfaMsghdrNetBSD7, bodyOff: sizeofIfaMsghdrNetBSD7}
+ ifanm := &wireFormat{extOff: sizeofIfAnnouncemsghdrNetBSD7, bodyOff: sizeofIfAnnouncemsghdrNetBSD7}
+ // NetBSD 6 and above kernels require 64-bit aligned access to
+ // routing facilities.
+ return 8, map[int]parseFn{
+ sysRTM_ADD: rtm.parseRouteMessage,
+ sysRTM_DELETE: rtm.parseRouteMessage,
+ sysRTM_CHANGE: rtm.parseRouteMessage,
+ sysRTM_GET: rtm.parseRouteMessage,
+ sysRTM_LOSING: rtm.parseRouteMessage,
+ sysRTM_REDIRECT: rtm.parseRouteMessage,
+ sysRTM_MISS: rtm.parseRouteMessage,
+ sysRTM_LOCK: rtm.parseRouteMessage,
+ sysRTM_RESOLVE: rtm.parseRouteMessage,
+ sysRTM_NEWADDR: ifam.parseInterfaceAddrMessage,
+ sysRTM_DELADDR: ifam.parseInterfaceAddrMessage,
+ sysRTM_IFANNOUNCE: ifanm.parseInterfaceAnnounceMessage,
+ sysRTM_IFINFO: ifm.parseInterfaceMessage,
+ }
+}
diff --git a/libgo/go/golang_org/x/net/route/sys_openbsd.go b/libgo/go/golang_org/x/net/route/sys_openbsd.go
new file mode 100644
index 00000000000..26d04386961
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/sys_openbsd.go
@@ -0,0 +1,72 @@
+// 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 route
+
+import "unsafe"
+
+func (typ RIBType) parseable() bool {
+ switch typ {
+ case sysNET_RT_STATS, sysNET_RT_TABLE:
+ return false
+ default:
+ return true
+ }
+}
+
+// A RouteMetrics represents route metrics.
+type RouteMetrics struct {
+ PathMTU int // path maximum transmission unit
+}
+
+// SysType implements the SysType method of Sys interface.
+func (rmx *RouteMetrics) SysType() SysType { return SysMetrics }
+
+// Sys implements the Sys method of Message interface.
+func (m *RouteMessage) Sys() []Sys {
+ return []Sys{
+ &RouteMetrics{
+ PathMTU: int(nativeEndian.Uint32(m.raw[60:64])),
+ },
+ }
+}
+
+// A InterfaceMetrics represents interface metrics.
+type InterfaceMetrics struct {
+ Type int // interface type
+ MTU int // maximum transmission unit
+}
+
+// SysType implements the SysType method of Sys interface.
+func (imx *InterfaceMetrics) SysType() SysType { return SysMetrics }
+
+// Sys implements the Sys method of Message interface.
+func (m *InterfaceMessage) Sys() []Sys {
+ return []Sys{
+ &InterfaceMetrics{
+ Type: int(m.raw[24]),
+ MTU: int(nativeEndian.Uint32(m.raw[28:32])),
+ },
+ }
+}
+
+func probeRoutingStack() (int, map[int]parseFn) {
+ var p uintptr
+ nooff := &wireFormat{extOff: -1, bodyOff: -1}
+ return int(unsafe.Sizeof(p)), map[int]parseFn{
+ sysRTM_ADD: nooff.parseRouteMessage,
+ sysRTM_DELETE: nooff.parseRouteMessage,
+ sysRTM_CHANGE: nooff.parseRouteMessage,
+ sysRTM_GET: nooff.parseRouteMessage,
+ sysRTM_LOSING: nooff.parseRouteMessage,
+ sysRTM_REDIRECT: nooff.parseRouteMessage,
+ sysRTM_MISS: nooff.parseRouteMessage,
+ sysRTM_LOCK: nooff.parseRouteMessage,
+ sysRTM_RESOLVE: nooff.parseRouteMessage,
+ sysRTM_NEWADDR: nooff.parseInterfaceAddrMessage,
+ sysRTM_DELADDR: nooff.parseInterfaceAddrMessage,
+ sysRTM_IFINFO: nooff.parseInterfaceMessage,
+ sysRTM_IFANNOUNCE: nooff.parseInterfaceAnnounceMessage,
+ }
+}
diff --git a/libgo/go/golang_org/x/net/route/syscall.go b/libgo/go/golang_org/x/net/route/syscall.go
new file mode 100644
index 00000000000..d136325a30a
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/syscall.go
@@ -0,0 +1,33 @@
+// 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.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package route
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+// TODO: replace with runtime.KeepAlive when available
+//go:noescape
+func keepAlive(p unsafe.Pointer)
+
+var zero uintptr
+
+func sysctl(mib []int32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) error {
+ var p unsafe.Pointer
+ if len(mib) > 0 {
+ p = unsafe.Pointer(&mib[0])
+ } else {
+ p = unsafe.Pointer(&zero)
+ }
+ _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(p), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+ keepAlive(p)
+ if errno != 0 {
+ return error(errno)
+ }
+ return nil
+}
diff --git a/libgo/go/golang_org/x/net/route/zsys_darwin.go b/libgo/go/golang_org/x/net/route/zsys_darwin.go
new file mode 100644
index 00000000000..265b81cd50e
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/zsys_darwin.go
@@ -0,0 +1,93 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_darwin.go
+
+package route
+
+const (
+ sysAF_UNSPEC = 0x0
+ sysAF_INET = 0x2
+ sysAF_ROUTE = 0x11
+ sysAF_LINK = 0x12
+ sysAF_INET6 = 0x1e
+
+ sysNET_RT_DUMP = 0x1
+ sysNET_RT_FLAGS = 0x2
+ sysNET_RT_IFLIST = 0x3
+ sysNET_RT_STAT = 0x4
+ sysNET_RT_TRASH = 0x5
+ sysNET_RT_IFLIST2 = 0x6
+ sysNET_RT_DUMP2 = 0x7
+ sysNET_RT_MAXID = 0xa
+)
+
+const (
+ sysCTL_MAXNAME = 0xc
+
+ sysCTL_UNSPEC = 0x0
+ sysCTL_KERN = 0x1
+ sysCTL_VM = 0x2
+ sysCTL_VFS = 0x3
+ sysCTL_NET = 0x4
+ sysCTL_DEBUG = 0x5
+ sysCTL_HW = 0x6
+ sysCTL_MACHDEP = 0x7
+ sysCTL_USER = 0x8
+ sysCTL_MAXID = 0x9
+)
+
+const (
+ sysRTM_VERSION = 0x5
+
+ sysRTM_ADD = 0x1
+ sysRTM_DELETE = 0x2
+ sysRTM_CHANGE = 0x3
+ sysRTM_GET = 0x4
+ sysRTM_LOSING = 0x5
+ sysRTM_REDIRECT = 0x6
+ sysRTM_MISS = 0x7
+ sysRTM_LOCK = 0x8
+ sysRTM_OLDADD = 0x9
+ sysRTM_OLDDEL = 0xa
+ sysRTM_RESOLVE = 0xb
+ sysRTM_NEWADDR = 0xc
+ sysRTM_DELADDR = 0xd
+ sysRTM_IFINFO = 0xe
+ sysRTM_NEWMADDR = 0xf
+ sysRTM_DELMADDR = 0x10
+ sysRTM_IFINFO2 = 0x12
+ sysRTM_NEWMADDR2 = 0x13
+ sysRTM_GET2 = 0x14
+
+ sysRTA_DST = 0x1
+ sysRTA_GATEWAY = 0x2
+ sysRTA_NETMASK = 0x4
+ sysRTA_GENMASK = 0x8
+ sysRTA_IFP = 0x10
+ sysRTA_IFA = 0x20
+ sysRTA_AUTHOR = 0x40
+ sysRTA_BRD = 0x80
+
+ sysRTAX_DST = 0x0
+ sysRTAX_GATEWAY = 0x1
+ sysRTAX_NETMASK = 0x2
+ sysRTAX_GENMASK = 0x3
+ sysRTAX_IFP = 0x4
+ sysRTAX_IFA = 0x5
+ sysRTAX_AUTHOR = 0x6
+ sysRTAX_BRD = 0x7
+ sysRTAX_MAX = 0x8
+)
+
+const (
+ sizeofIfMsghdrDarwin15 = 0x70
+ sizeofIfaMsghdrDarwin15 = 0x14
+ sizeofIfmaMsghdrDarwin15 = 0x10
+ sizeofIfMsghdr2Darwin15 = 0xa0
+ sizeofIfmaMsghdr2Darwin15 = 0x14
+ sizeofIfDataDarwin15 = 0x60
+ sizeofIfData64Darwin15 = 0x80
+
+ sizeofRtMsghdrDarwin15 = 0x5c
+ sizeofRtMsghdr2Darwin15 = 0x5c
+ sizeofRtMetricsDarwin15 = 0x38
+)
diff --git a/libgo/go/golang_org/x/net/route/zsys_dragonfly.go b/libgo/go/golang_org/x/net/route/zsys_dragonfly.go
new file mode 100644
index 00000000000..dd36dece0f6
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/zsys_dragonfly.go
@@ -0,0 +1,92 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_dragonfly.go
+
+package route
+
+const (
+ sysAF_UNSPEC = 0x0
+ sysAF_INET = 0x2
+ sysAF_ROUTE = 0x11
+ sysAF_LINK = 0x12
+ sysAF_INET6 = 0x1c
+
+ sysNET_RT_DUMP = 0x1
+ sysNET_RT_FLAGS = 0x2
+ sysNET_RT_IFLIST = 0x3
+ sysNET_RT_MAXID = 0x4
+)
+
+const (
+ sysCTL_MAXNAME = 0xc
+
+ sysCTL_UNSPEC = 0x0
+ sysCTL_KERN = 0x1
+ sysCTL_VM = 0x2
+ sysCTL_VFS = 0x3
+ sysCTL_NET = 0x4
+ sysCTL_DEBUG = 0x5
+ sysCTL_HW = 0x6
+ sysCTL_MACHDEP = 0x7
+ sysCTL_USER = 0x8
+ sysCTL_P1003_1B = 0x9
+ sysCTL_LWKT = 0xa
+ sysCTL_MAXID = 0xb
+)
+
+const (
+ sysRTM_VERSION = 0x6
+
+ sysRTM_ADD = 0x1
+ sysRTM_DELETE = 0x2
+ sysRTM_CHANGE = 0x3
+ sysRTM_GET = 0x4
+ sysRTM_LOSING = 0x5
+ sysRTM_REDIRECT = 0x6
+ sysRTM_MISS = 0x7
+ sysRTM_LOCK = 0x8
+ sysRTM_OLDADD = 0x9
+ sysRTM_OLDDEL = 0xa
+ sysRTM_RESOLVE = 0xb
+ sysRTM_NEWADDR = 0xc
+ sysRTM_DELADDR = 0xd
+ sysRTM_IFINFO = 0xe
+ sysRTM_NEWMADDR = 0xf
+ sysRTM_DELMADDR = 0x10
+ sysRTM_IFANNOUNCE = 0x11
+ sysRTM_IEEE80211 = 0x12
+
+ sysRTA_DST = 0x1
+ sysRTA_GATEWAY = 0x2
+ sysRTA_NETMASK = 0x4
+ sysRTA_GENMASK = 0x8
+ sysRTA_IFP = 0x10
+ sysRTA_IFA = 0x20
+ sysRTA_AUTHOR = 0x40
+ sysRTA_BRD = 0x80
+ sysRTA_MPLS1 = 0x100
+ sysRTA_MPLS2 = 0x200
+ sysRTA_MPLS3 = 0x400
+
+ sysRTAX_DST = 0x0
+ sysRTAX_GATEWAY = 0x1
+ sysRTAX_NETMASK = 0x2
+ sysRTAX_GENMASK = 0x3
+ sysRTAX_IFP = 0x4
+ sysRTAX_IFA = 0x5
+ sysRTAX_AUTHOR = 0x6
+ sysRTAX_BRD = 0x7
+ sysRTAX_MPLS1 = 0x8
+ sysRTAX_MPLS2 = 0x9
+ sysRTAX_MPLS3 = 0xa
+ sysRTAX_MAX = 0xb
+)
+
+const (
+ sizeofIfMsghdrDragonFlyBSD4 = 0xb0
+ sizeofIfaMsghdrDragonFlyBSD4 = 0x14
+ sizeofIfmaMsghdrDragonFlyBSD4 = 0x10
+ sizeofIfAnnouncemsghdrDragonFlyBSD4 = 0x18
+
+ sizeofRtMsghdrDragonFlyBSD4 = 0x98
+ sizeofRtMetricsDragonFlyBSD4 = 0x70
+)
diff --git a/libgo/go/golang_org/x/net/route/zsys_freebsd_386.go b/libgo/go/golang_org/x/net/route/zsys_freebsd_386.go
new file mode 100644
index 00000000000..9bac2e3900f
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/zsys_freebsd_386.go
@@ -0,0 +1,120 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_freebsd.go
+
+package route
+
+const (
+ sysAF_UNSPEC = 0x0
+ sysAF_INET = 0x2
+ sysAF_ROUTE = 0x11
+ sysAF_LINK = 0x12
+ sysAF_INET6 = 0x1c
+
+ sysNET_RT_DUMP = 0x1
+ sysNET_RT_FLAGS = 0x2
+ sysNET_RT_IFLIST = 0x3
+ sysNET_RT_IFMALIST = 0x4
+ sysNET_RT_IFLISTL = 0x5
+)
+
+const (
+ sysCTL_MAXNAME = 0x18
+
+ sysCTL_UNSPEC = 0x0
+ sysCTL_KERN = 0x1
+ sysCTL_VM = 0x2
+ sysCTL_VFS = 0x3
+ sysCTL_NET = 0x4
+ sysCTL_DEBUG = 0x5
+ sysCTL_HW = 0x6
+ sysCTL_MACHDEP = 0x7
+ sysCTL_USER = 0x8
+ sysCTL_P1003_1B = 0x9
+)
+
+const (
+ sysRTM_VERSION = 0x5
+
+ sysRTM_ADD = 0x1
+ sysRTM_DELETE = 0x2
+ sysRTM_CHANGE = 0x3
+ sysRTM_GET = 0x4
+ sysRTM_LOSING = 0x5
+ sysRTM_REDIRECT = 0x6
+ sysRTM_MISS = 0x7
+ sysRTM_LOCK = 0x8
+ sysRTM_RESOLVE = 0xb
+ sysRTM_NEWADDR = 0xc
+ sysRTM_DELADDR = 0xd
+ sysRTM_IFINFO = 0xe
+ sysRTM_NEWMADDR = 0xf
+ sysRTM_DELMADDR = 0x10
+ sysRTM_IFANNOUNCE = 0x11
+ sysRTM_IEEE80211 = 0x12
+
+ sysRTA_DST = 0x1
+ sysRTA_GATEWAY = 0x2
+ sysRTA_NETMASK = 0x4
+ sysRTA_GENMASK = 0x8
+ sysRTA_IFP = 0x10
+ sysRTA_IFA = 0x20
+ sysRTA_AUTHOR = 0x40
+ sysRTA_BRD = 0x80
+
+ sysRTAX_DST = 0x0
+ sysRTAX_GATEWAY = 0x1
+ sysRTAX_NETMASK = 0x2
+ sysRTAX_GENMASK = 0x3
+ sysRTAX_IFP = 0x4
+ sysRTAX_IFA = 0x5
+ sysRTAX_AUTHOR = 0x6
+ sysRTAX_BRD = 0x7
+ sysRTAX_MAX = 0x8
+)
+
+const (
+ sizeofIfMsghdrlFreeBSD10 = 0x68
+ sizeofIfaMsghdrFreeBSD10 = 0x14
+ sizeofIfaMsghdrlFreeBSD10 = 0x6c
+ sizeofIfmaMsghdrFreeBSD10 = 0x10
+ sizeofIfAnnouncemsghdrFreeBSD10 = 0x18
+
+ sizeofRtMsghdrFreeBSD10 = 0x5c
+ sizeofRtMetricsFreeBSD10 = 0x38
+
+ sizeofIfMsghdrFreeBSD7 = 0x60
+ sizeofIfMsghdrFreeBSD8 = 0x60
+ sizeofIfMsghdrFreeBSD9 = 0x60
+ sizeofIfMsghdrFreeBSD10 = 0x64
+ sizeofIfMsghdrFreeBSD11 = 0xa8
+
+ sizeofIfDataFreeBSD7 = 0x50
+ sizeofIfDataFreeBSD8 = 0x50
+ sizeofIfDataFreeBSD9 = 0x50
+ sizeofIfDataFreeBSD10 = 0x54
+ sizeofIfDataFreeBSD11 = 0x98
+
+ // MODIFIED BY HAND FOR 386 EMULATION ON AMD64
+ // 386 EMULATION USES THE UNDERLYING RAW DATA LAYOUT
+
+ sizeofIfMsghdrlFreeBSD10Emu = 0xb0
+ sizeofIfaMsghdrFreeBSD10Emu = 0x14
+ sizeofIfaMsghdrlFreeBSD10Emu = 0xb0
+ sizeofIfmaMsghdrFreeBSD10Emu = 0x10
+ sizeofIfAnnouncemsghdrFreeBSD10Emu = 0x18
+
+ sizeofRtMsghdrFreeBSD10Emu = 0x98
+ sizeofRtMetricsFreeBSD10Emu = 0x70
+
+ sizeofIfMsghdrFreeBSD7Emu = 0xa8
+ sizeofIfMsghdrFreeBSD8Emu = 0xa8
+ sizeofIfMsghdrFreeBSD9Emu = 0xa8
+ sizeofIfMsghdrFreeBSD10Emu = 0xa8
+ sizeofIfMsghdrFreeBSD11Emu = 0xa8
+
+ sizeofIfDataFreeBSD7Emu = 0x98
+ sizeofIfDataFreeBSD8Emu = 0x98
+ sizeofIfDataFreeBSD9Emu = 0x98
+ sizeofIfDataFreeBSD10Emu = 0x98
+ sizeofIfDataFreeBSD11Emu = 0x98
+)
diff --git a/libgo/go/golang_org/x/net/route/zsys_freebsd_amd64.go b/libgo/go/golang_org/x/net/route/zsys_freebsd_amd64.go
new file mode 100644
index 00000000000..b1920d7ac16
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/zsys_freebsd_amd64.go
@@ -0,0 +1,117 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_freebsd.go
+
+package route
+
+const (
+ sysAF_UNSPEC = 0x0
+ sysAF_INET = 0x2
+ sysAF_ROUTE = 0x11
+ sysAF_LINK = 0x12
+ sysAF_INET6 = 0x1c
+
+ sysNET_RT_DUMP = 0x1
+ sysNET_RT_FLAGS = 0x2
+ sysNET_RT_IFLIST = 0x3
+ sysNET_RT_IFMALIST = 0x4
+ sysNET_RT_IFLISTL = 0x5
+)
+
+const (
+ sysCTL_MAXNAME = 0x18
+
+ sysCTL_UNSPEC = 0x0
+ sysCTL_KERN = 0x1
+ sysCTL_VM = 0x2
+ sysCTL_VFS = 0x3
+ sysCTL_NET = 0x4
+ sysCTL_DEBUG = 0x5
+ sysCTL_HW = 0x6
+ sysCTL_MACHDEP = 0x7
+ sysCTL_USER = 0x8
+ sysCTL_P1003_1B = 0x9
+)
+
+const (
+ sysRTM_VERSION = 0x5
+
+ sysRTM_ADD = 0x1
+ sysRTM_DELETE = 0x2
+ sysRTM_CHANGE = 0x3
+ sysRTM_GET = 0x4
+ sysRTM_LOSING = 0x5
+ sysRTM_REDIRECT = 0x6
+ sysRTM_MISS = 0x7
+ sysRTM_LOCK = 0x8
+ sysRTM_RESOLVE = 0xb
+ sysRTM_NEWADDR = 0xc
+ sysRTM_DELADDR = 0xd
+ sysRTM_IFINFO = 0xe
+ sysRTM_NEWMADDR = 0xf
+ sysRTM_DELMADDR = 0x10
+ sysRTM_IFANNOUNCE = 0x11
+ sysRTM_IEEE80211 = 0x12
+
+ sysRTA_DST = 0x1
+ sysRTA_GATEWAY = 0x2
+ sysRTA_NETMASK = 0x4
+ sysRTA_GENMASK = 0x8
+ sysRTA_IFP = 0x10
+ sysRTA_IFA = 0x20
+ sysRTA_AUTHOR = 0x40
+ sysRTA_BRD = 0x80
+
+ sysRTAX_DST = 0x0
+ sysRTAX_GATEWAY = 0x1
+ sysRTAX_NETMASK = 0x2
+ sysRTAX_GENMASK = 0x3
+ sysRTAX_IFP = 0x4
+ sysRTAX_IFA = 0x5
+ sysRTAX_AUTHOR = 0x6
+ sysRTAX_BRD = 0x7
+ sysRTAX_MAX = 0x8
+)
+
+const (
+ sizeofIfMsghdrlFreeBSD10 = 0xb0
+ sizeofIfaMsghdrFreeBSD10 = 0x14
+ sizeofIfaMsghdrlFreeBSD10 = 0xb0
+ sizeofIfmaMsghdrFreeBSD10 = 0x10
+ sizeofIfAnnouncemsghdrFreeBSD10 = 0x18
+
+ sizeofRtMsghdrFreeBSD10 = 0x98
+ sizeofRtMetricsFreeBSD10 = 0x70
+
+ sizeofIfMsghdrFreeBSD7 = 0xa8
+ sizeofIfMsghdrFreeBSD8 = 0xa8
+ sizeofIfMsghdrFreeBSD9 = 0xa8
+ sizeofIfMsghdrFreeBSD10 = 0xa8
+ sizeofIfMsghdrFreeBSD11 = 0xa8
+
+ sizeofIfDataFreeBSD7 = 0x98
+ sizeofIfDataFreeBSD8 = 0x98
+ sizeofIfDataFreeBSD9 = 0x98
+ sizeofIfDataFreeBSD10 = 0x98
+ sizeofIfDataFreeBSD11 = 0x98
+
+ sizeofIfMsghdrlFreeBSD10Emu = 0xb0
+ sizeofIfaMsghdrFreeBSD10Emu = 0x14
+ sizeofIfaMsghdrlFreeBSD10Emu = 0xb0
+ sizeofIfmaMsghdrFreeBSD10Emu = 0x10
+ sizeofIfAnnouncemsghdrFreeBSD10Emu = 0x18
+
+ sizeofRtMsghdrFreeBSD10Emu = 0x98
+ sizeofRtMetricsFreeBSD10Emu = 0x70
+
+ sizeofIfMsghdrFreeBSD7Emu = 0xa8
+ sizeofIfMsghdrFreeBSD8Emu = 0xa8
+ sizeofIfMsghdrFreeBSD9Emu = 0xa8
+ sizeofIfMsghdrFreeBSD10Emu = 0xa8
+ sizeofIfMsghdrFreeBSD11Emu = 0xa8
+
+ sizeofIfDataFreeBSD7Emu = 0x98
+ sizeofIfDataFreeBSD8Emu = 0x98
+ sizeofIfDataFreeBSD9Emu = 0x98
+ sizeofIfDataFreeBSD10Emu = 0x98
+ sizeofIfDataFreeBSD11Emu = 0x98
+)
diff --git a/libgo/go/golang_org/x/net/route/zsys_freebsd_arm.go b/libgo/go/golang_org/x/net/route/zsys_freebsd_arm.go
new file mode 100644
index 00000000000..a034d6fcbf2
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/zsys_freebsd_arm.go
@@ -0,0 +1,117 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_freebsd.go
+
+package route
+
+const (
+ sysAF_UNSPEC = 0x0
+ sysAF_INET = 0x2
+ sysAF_ROUTE = 0x11
+ sysAF_LINK = 0x12
+ sysAF_INET6 = 0x1c
+
+ sysNET_RT_DUMP = 0x1
+ sysNET_RT_FLAGS = 0x2
+ sysNET_RT_IFLIST = 0x3
+ sysNET_RT_IFMALIST = 0x4
+ sysNET_RT_IFLISTL = 0x5
+)
+
+const (
+ sysCTL_MAXNAME = 0x18
+
+ sysCTL_UNSPEC = 0x0
+ sysCTL_KERN = 0x1
+ sysCTL_VM = 0x2
+ sysCTL_VFS = 0x3
+ sysCTL_NET = 0x4
+ sysCTL_DEBUG = 0x5
+ sysCTL_HW = 0x6
+ sysCTL_MACHDEP = 0x7
+ sysCTL_USER = 0x8
+ sysCTL_P1003_1B = 0x9
+)
+
+const (
+ sysRTM_VERSION = 0x5
+
+ sysRTM_ADD = 0x1
+ sysRTM_DELETE = 0x2
+ sysRTM_CHANGE = 0x3
+ sysRTM_GET = 0x4
+ sysRTM_LOSING = 0x5
+ sysRTM_REDIRECT = 0x6
+ sysRTM_MISS = 0x7
+ sysRTM_LOCK = 0x8
+ sysRTM_RESOLVE = 0xb
+ sysRTM_NEWADDR = 0xc
+ sysRTM_DELADDR = 0xd
+ sysRTM_IFINFO = 0xe
+ sysRTM_NEWMADDR = 0xf
+ sysRTM_DELMADDR = 0x10
+ sysRTM_IFANNOUNCE = 0x11
+ sysRTM_IEEE80211 = 0x12
+
+ sysRTA_DST = 0x1
+ sysRTA_GATEWAY = 0x2
+ sysRTA_NETMASK = 0x4
+ sysRTA_GENMASK = 0x8
+ sysRTA_IFP = 0x10
+ sysRTA_IFA = 0x20
+ sysRTA_AUTHOR = 0x40
+ sysRTA_BRD = 0x80
+
+ sysRTAX_DST = 0x0
+ sysRTAX_GATEWAY = 0x1
+ sysRTAX_NETMASK = 0x2
+ sysRTAX_GENMASK = 0x3
+ sysRTAX_IFP = 0x4
+ sysRTAX_IFA = 0x5
+ sysRTAX_AUTHOR = 0x6
+ sysRTAX_BRD = 0x7
+ sysRTAX_MAX = 0x8
+)
+
+const (
+ sizeofIfMsghdrlFreeBSD10 = 0x68
+ sizeofIfaMsghdrFreeBSD10 = 0x14
+ sizeofIfaMsghdrlFreeBSD10 = 0x6c
+ sizeofIfmaMsghdrFreeBSD10 = 0x10
+ sizeofIfAnnouncemsghdrFreeBSD10 = 0x18
+
+ sizeofRtMsghdrFreeBSD10 = 0x5c
+ sizeofRtMetricsFreeBSD10 = 0x38
+
+ sizeofIfMsghdrFreeBSD7 = 0x70
+ sizeofIfMsghdrFreeBSD8 = 0x70
+ sizeofIfMsghdrFreeBSD9 = 0x70
+ sizeofIfMsghdrFreeBSD10 = 0x70
+ sizeofIfMsghdrFreeBSD11 = 0xa8
+
+ sizeofIfDataFreeBSD7 = 0x60
+ sizeofIfDataFreeBSD8 = 0x60
+ sizeofIfDataFreeBSD9 = 0x60
+ sizeofIfDataFreeBSD10 = 0x60
+ sizeofIfDataFreeBSD11 = 0x98
+
+ sizeofIfMsghdrlFreeBSD10Emu = 0x68
+ sizeofIfaMsghdrFreeBSD10Emu = 0x14
+ sizeofIfaMsghdrlFreeBSD10Emu = 0x6c
+ sizeofIfmaMsghdrFreeBSD10Emu = 0x10
+ sizeofIfAnnouncemsghdrFreeBSD10Emu = 0x18
+
+ sizeofRtMsghdrFreeBSD10Emu = 0x5c
+ sizeofRtMetricsFreeBSD10Emu = 0x38
+
+ sizeofIfMsghdrFreeBSD7Emu = 0x70
+ sizeofIfMsghdrFreeBSD8Emu = 0x70
+ sizeofIfMsghdrFreeBSD9Emu = 0x70
+ sizeofIfMsghdrFreeBSD10Emu = 0x70
+ sizeofIfMsghdrFreeBSD11Emu = 0xa8
+
+ sizeofIfDataFreeBSD7Emu = 0x60
+ sizeofIfDataFreeBSD8Emu = 0x60
+ sizeofIfDataFreeBSD9Emu = 0x60
+ sizeofIfDataFreeBSD10Emu = 0x60
+ sizeofIfDataFreeBSD11Emu = 0x98
+)
diff --git a/libgo/go/golang_org/x/net/route/zsys_netbsd.go b/libgo/go/golang_org/x/net/route/zsys_netbsd.go
new file mode 100644
index 00000000000..aa4aad1613e
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/zsys_netbsd.go
@@ -0,0 +1,91 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_netbsd.go
+
+package route
+
+const (
+ sysAF_UNSPEC = 0x0
+ sysAF_INET = 0x2
+ sysAF_ROUTE = 0x22
+ sysAF_LINK = 0x12
+ sysAF_INET6 = 0x18
+
+ sysNET_RT_DUMP = 0x1
+ sysNET_RT_FLAGS = 0x2
+ sysNET_RT_IFLIST = 0x5
+ sysNET_RT_MAXID = 0x6
+)
+
+const (
+ sysCTL_MAXNAME = 0xc
+
+ sysCTL_UNSPEC = 0x0
+ sysCTL_KERN = 0x1
+ sysCTL_VM = 0x2
+ sysCTL_VFS = 0x3
+ sysCTL_NET = 0x4
+ sysCTL_DEBUG = 0x5
+ sysCTL_HW = 0x6
+ sysCTL_MACHDEP = 0x7
+ sysCTL_USER = 0x8
+ sysCTL_DDB = 0x9
+ sysCTL_PROC = 0xa
+ sysCTL_VENDOR = 0xb
+ sysCTL_EMUL = 0xc
+ sysCTL_SECURITY = 0xd
+ sysCTL_MAXID = 0xe
+)
+
+const (
+ sysRTM_VERSION = 0x4
+
+ sysRTM_ADD = 0x1
+ sysRTM_DELETE = 0x2
+ sysRTM_CHANGE = 0x3
+ sysRTM_GET = 0x4
+ sysRTM_LOSING = 0x5
+ sysRTM_REDIRECT = 0x6
+ sysRTM_MISS = 0x7
+ sysRTM_LOCK = 0x8
+ sysRTM_OLDADD = 0x9
+ sysRTM_OLDDEL = 0xa
+ sysRTM_RESOLVE = 0xb
+ sysRTM_NEWADDR = 0xc
+ sysRTM_DELADDR = 0xd
+ sysRTM_IFANNOUNCE = 0x10
+ sysRTM_IEEE80211 = 0x11
+ sysRTM_SETGATE = 0x12
+ sysRTM_LLINFO_UPD = 0x13
+ sysRTM_IFINFO = 0x14
+ sysRTM_CHGADDR = 0x15
+
+ sysRTA_DST = 0x1
+ sysRTA_GATEWAY = 0x2
+ sysRTA_NETMASK = 0x4
+ sysRTA_GENMASK = 0x8
+ sysRTA_IFP = 0x10
+ sysRTA_IFA = 0x20
+ sysRTA_AUTHOR = 0x40
+ sysRTA_BRD = 0x80
+ sysRTA_TAG = 0x100
+
+ sysRTAX_DST = 0x0
+ sysRTAX_GATEWAY = 0x1
+ sysRTAX_NETMASK = 0x2
+ sysRTAX_GENMASK = 0x3
+ sysRTAX_IFP = 0x4
+ sysRTAX_IFA = 0x5
+ sysRTAX_AUTHOR = 0x6
+ sysRTAX_BRD = 0x7
+ sysRTAX_TAG = 0x8
+ sysRTAX_MAX = 0x9
+)
+
+const (
+ sizeofIfMsghdrNetBSD7 = 0x98
+ sizeofIfaMsghdrNetBSD7 = 0x18
+ sizeofIfAnnouncemsghdrNetBSD7 = 0x18
+
+ sizeofRtMsghdrNetBSD7 = 0x78
+ sizeofRtMetricsNetBSD7 = 0x50
+)
diff --git a/libgo/go/golang_org/x/net/route/zsys_openbsd.go b/libgo/go/golang_org/x/net/route/zsys_openbsd.go
new file mode 100644
index 00000000000..4fadc4e8fa1
--- /dev/null
+++ b/libgo/go/golang_org/x/net/route/zsys_openbsd.go
@@ -0,0 +1,80 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_openbsd.go
+
+package route
+
+const (
+ sysAF_UNSPEC = 0x0
+ sysAF_INET = 0x2
+ sysAF_ROUTE = 0x11
+ sysAF_LINK = 0x12
+ sysAF_INET6 = 0x18
+
+ sysNET_RT_DUMP = 0x1
+ sysNET_RT_FLAGS = 0x2
+ sysNET_RT_IFLIST = 0x3
+ sysNET_RT_STATS = 0x4
+ sysNET_RT_TABLE = 0x5
+ sysNET_RT_IFNAMES = 0x6
+ sysNET_RT_MAXID = 0x7
+)
+
+const (
+ sysCTL_MAXNAME = 0xc
+
+ sysCTL_UNSPEC = 0x0
+ sysCTL_KERN = 0x1
+ sysCTL_VM = 0x2
+ sysCTL_FS = 0x3
+ sysCTL_NET = 0x4
+ sysCTL_DEBUG = 0x5
+ sysCTL_HW = 0x6
+ sysCTL_MACHDEP = 0x7
+ sysCTL_DDB = 0x9
+ sysCTL_VFS = 0xa
+ sysCTL_MAXID = 0xb
+)
+
+const (
+ sysRTM_VERSION = 0x5
+
+ sysRTM_ADD = 0x1
+ sysRTM_DELETE = 0x2
+ sysRTM_CHANGE = 0x3
+ sysRTM_GET = 0x4
+ sysRTM_LOSING = 0x5
+ sysRTM_REDIRECT = 0x6
+ sysRTM_MISS = 0x7
+ sysRTM_LOCK = 0x8
+ sysRTM_RESOLVE = 0xb
+ sysRTM_NEWADDR = 0xc
+ sysRTM_DELADDR = 0xd
+ sysRTM_IFINFO = 0xe
+ sysRTM_IFANNOUNCE = 0xf
+ sysRTM_DESYNC = 0x10
+
+ sysRTA_DST = 0x1
+ sysRTA_GATEWAY = 0x2
+ sysRTA_NETMASK = 0x4
+ sysRTA_GENMASK = 0x8
+ sysRTA_IFP = 0x10
+ sysRTA_IFA = 0x20
+ sysRTA_AUTHOR = 0x40
+ sysRTA_BRD = 0x80
+ sysRTA_SRC = 0x100
+ sysRTA_SRCMASK = 0x200
+ sysRTA_LABEL = 0x400
+
+ sysRTAX_DST = 0x0
+ sysRTAX_GATEWAY = 0x1
+ sysRTAX_NETMASK = 0x2
+ sysRTAX_GENMASK = 0x3
+ sysRTAX_IFP = 0x4
+ sysRTAX_IFA = 0x5
+ sysRTAX_AUTHOR = 0x6
+ sysRTAX_BRD = 0x7
+ sysRTAX_SRC = 0x8
+ sysRTAX_SRCMASK = 0x9
+ sysRTAX_LABEL = 0xa
+ sysRTAX_MAX = 0xb
+)