text:
// 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
		}
	}
}


text:
// 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
	}
}

// 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])),
		},
	}
}

// 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]*wireFormat) {
	rtm := &wireFormat{extOff: 36, bodyOff: sizeofRtMsghdrDarwin15}
	rtm.parse = rtm.parseRouteMessage
	rtm2 := &wireFormat{extOff: 36, bodyOff: sizeofRtMsghdr2Darwin15}
	rtm2.parse = rtm2.parseRouteMessage
	ifm := &wireFormat{extOff: 16, bodyOff: sizeofIfMsghdrDarwin15}
	ifm.parse = ifm.parseInterfaceMessage
	ifm2 := &wireFormat{extOff: 32, bodyOff: sizeofIfMsghdr2Darwin15}
	ifm2.parse = ifm2.parseInterfaceMessage
	ifam := &wireFormat{extOff: sizeofIfaMsghdrDarwin15, bodyOff: sizeofIfaMsghdrDarwin15}
	ifam.parse = ifam.parseInterfaceAddrMessage
	ifmam := &wireFormat{extOff: sizeofIfmaMsghdrDarwin15, bodyOff: sizeofIfmaMsghdrDarwin15}
	ifmam.parse = ifmam.parseInterfaceMulticastAddrMessage
	ifmam2 := &wireFormat{extOff: sizeofIfmaMsghdr2Darwin15, bodyOff: sizeofIfmaMsghdr2Darwin15}
	ifmam2.parse = ifmam2.parseInterfaceMulticastAddrMessage
	// Darwin kernels require 32-bit aligned access to routing facilities.
	return 4, map[int]*wireFormat{
		sysRTM_ADD:       rtm,
		sysRTM_DELETE:    rtm,
		sysRTM_CHANGE:    rtm,
		sysRTM_GET:       rtm,
		sysRTM_LOSING:    rtm,
		sysRTM_REDIRECT:  rtm,
		sysRTM_MISS:      rtm,
		sysRTM_LOCK:      rtm,
		sysRTM_RESOLVE:   rtm,
		sysRTM_NEWADDR:   ifam,
		sysRTM_DELADDR:   ifam,
		sysRTM_IFINFO:    ifm,
		sysRTM_NEWMADDR:  ifmam,
		sysRTM_DELMADDR:  ifmam,
		sysRTM_IFINFO2:   ifm2,
		sysRTM_NEWMADDR2: ifmam2,
		sysRTM_GET2:      rtm2,
	}
}

repo_name: dan-v/dosxvpn

repo_language: Go

mime_type: text/x-shellscript


text:
// 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>

#include <netinet/in.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

	sysSOCK_RAW = C.SOCK_RAW

	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

	sizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
	sizeofSockaddrInet    = C.sizeof_struct_sockaddr_in
	sizeofSockaddrInet6   = C.sizeof_struct_sockaddr_in6
)


text:
// 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 _, typ := range []RIBType{sysNET_RT_DUMP, sysNET_RT_IFLIST} {
		var lastErr error
		var ms []Message
		for _, af := range []int{sysAF_UNSPEC, sysAF_INET, sysAF_INET6} {
			rs, err := fetchAndParseRIB(af, typ)
			if err != nil {
				lastErr = err
				continue
			}
			ms = append(ms, rs...)
		}
		if len(ms) == 0 && lastErr != nil {
			t.Error(typ, lastErr)
			continue
		}
		ss, err := msgs(ms).validate()
		if err != nil {
			t.Error(typ, err)
			continue
		}
		for _, s := range ss {
			t.Log(typ, s)
		}
	}
}

var (
	rtmonSock int
	rtmonErr  error
)

func init() {
	// We need to keep rtmonSock alive to avoid treading on
	// recycled socket descriptors.
	rtmonSock, rtmonErr = syscall.Socket(sysAF_ROUTE, sysSOCK_RAW, sysAF_UNSPEC)
}

// TestMonitorAndParseRIB leaks a worker goroutine and a socket
// descriptor but that's intentional.
func TestMonitorAndParseRIB(t *testing.T) {
	if testing.Short() || os.Getuid() != 0 {
		t.Skip("must be root")
	}

	if rtmonErr != nil {
		t.Fatal(rtmonErr)
	}

	// 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()

	go func() {
		b := make([]byte, os.Getpagesize())
		for {
			// There's no easy way to unblock this read
			// call because the routing message exchange
			// over routing socket is a connectionless
			// message-oriented protocol, no control plane
			// for signaling connectivity, and we cannot
			// use the net package of standard library due
			// to the lack of support for routing socket
			// and circular dependency.
			n, err := syscall.Read(rtmonSock, 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)
	}
}

func TestParseRIBWithFuzz(t *testing.T) {
	for _, fuzz := range []string{
		"0\x00\x05\x050000000000000000" +
			"00000000000000000000" +
			"00000000000000000000" +
			"00000000000000000000" +
			"0000000000000\x02000000" +
			"00000000",
		"\x02\x00\x05\f0000000000000000" +
			"0\x0200000000000000",
		"\x02\x00\x05\x100000000000000\x1200" +
			"0\x00\xff\x00",
		"\x02\x00\x05\f0000000000000000" +
			"0\x12000\x00\x02\x0000",
		"\x00\x00\x00\x01\x00",
		"00000",
	} {
		for typ := RIBType(0); typ < 256; typ++ {
			ParseRIB(typ, []byte(fuzz))
		}
	}
}

func TestRouteMessage(t *testing.T) {
	s, err := syscall.Socket(sysAF_ROUTE, sysSOCK_RAW, sysAF_UNSPEC)
	if err != nil {
		t.Fatal(err)
	}
	defer syscall.Close(s)

	var ms []RouteMessage
	for _, af := range []int{sysAF_INET, sysAF_INET6} {
		if _, err := fetchAndParseRIB(af, sysNET_RT_DUMP); err != nil {
			t.Log(err)
			continue
		}
		switch af {
		case sysAF_INET:
			ms = append(ms, []RouteMessage{
				{
					Type: sysRTM_GET,
					Addrs: []Addr{
						&Inet4Addr{IP: [4]byte{127, 0, 0, 1}},
						nil,
						nil,
						nil,
						&LinkAddr{},
						&Inet4Addr{},
						nil,
						&Inet4Addr{},
					},
				},
				{
					Type: sysRTM_GET,
					Addrs: []Addr{
						&Inet4Addr{IP: [4]byte{127, 0, 0, 1}},
					},
				},
			}...)
		case sysAF_INET6:
			ms = append(ms, []RouteMessage{
				{
					Type: sysRTM_GET,
					Addrs: []Addr{
						&Inet6Addr{IP: [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
						nil,
						nil,
						nil,
						&LinkAddr{},
						&Inet6Addr{},
						nil,
						&Inet6Addr{},
					},
				},
				{
					Type: sysRTM_GET,
					Addrs: []Addr{
						&Inet6Addr{IP: [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
					},
				},
			}...)
		}
	}
	for i, m := range ms {
		m.ID = uintptr(os.Getpid())
		m.Seq = i + 1
		wb, err := m.Marshal()
		if err != nil {
			t.Fatalf("%v: %v", m, err)
		}
		if _, err := syscall.Write(s, wb); err != nil {
			t.Fatalf("%v: %v", m, err)
		}
		rb := make([]byte, os.Getpagesize())
		n, err := syscall.Read(s, rb)
		if err != nil {
			t.Fatalf("%v: %v", m, err)
		}
		rms, err := ParseRIB(0, rb[:n])
		if err != nil {
			t.Fatalf("%v: %v", m, err)
		}
		for _, rm := range rms {
			err := rm.(*RouteMessage).Err
			if err != nil {
				t.Errorf("%v: %v", m, err)
			}
		}
		ss, err := msgs(rms).validate()
		if err != nil {
			t.Fatalf("%v: %v", m, err)
		}
		for _, s := range ss {
			t.Log(s)
		}
	}
}


text:
// 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 (a *LinkAddr) lenAndSpace() (int, int) {
	l := 8 + len(a.Name) + len(a.Addr)
	return l, roundup(l)
}

func (a *LinkAddr) marshal(b []byte) (int, error) {
	l, ll := a.lenAndSpace()
	if len(b) < ll {
		return 0, errShortBuffer
	}
	nlen, alen := len(a.Name), len(a.Addr)
	if nlen > 255 || alen > 255 {
		return 0, errInvalidAddr
	}
	b[0] = byte(l)
	b[1] = sysAF_LINK
	if a.Index > 0 {
		nativeEndian.PutUint16(b[2:4], uint16(a.Index))
	}
	data := b[8:]
	if nlen > 0 {
		b[5] = byte(nlen)
		copy(data[:nlen], a.Addr)
		data = data[nlen:]
	}
	if alen > 0 {
		b[6] = byte(alen)
		copy(data[:alen], a.Name)
		data = data[alen:]
	}
	return ll, nil
}

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 }

func (a *Inet4Addr) lenAndSpace() (int, int) {
	return sizeofSockaddrInet, roundup(sizeofSockaddrInet)
}

func (a *Inet4Addr) marshal(b []byte) (int, error) {
	l, ll := a.lenAndSpace()
	if len(b) < ll {
		return 0, errShortBuffer
	}
	b[0] = byte(l)
	b[1] = sysAF_INET
	copy(b[4:8], a.IP[:])
	return ll, nil
}

// 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 }

func (a *Inet6Addr) lenAndSpace() (int, int) {
	return sizeofSockaddrInet6, roundup(sizeofSockaddrInet6)
}

func (a *Inet6Addr) marshal(b []byte) (int, error) {
	l, ll := a.lenAndSpace()
	if len(b) < ll {
		return 0, errShortBuffer
	}
	b[0] = byte(l)
	b[1] = sysAF_INET6
	copy(b[8:24], a.IP[:])
	if a.ZoneID > 0 {
		nativeEndian.PutUint32(b[24:28], uint32(a.ZoneID))
	}
	return ll, nil
}

// 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) < sizeofSockaddrInet {
			return nil, errInvalidAddr
		}
		a := &Inet4Addr{}
		copy(a.IP[:], b[4:8])
		return a, nil
	case sysAF_INET6:
		if len(b) < sizeofSockaddrInet6 {
			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] == sizeofSockaddrInet6:
		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] == sizeofSockaddrInet:
		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 (a *DefaultAddr) lenAndSpace() (int, int) {
	l := len(a.Raw)
	return l, roundup(l)
}

func (a *DefaultAddr) marshal(b []byte) (int, error) {
	l, ll := a.lenAndSpace()
	if len(b) < ll {
		return 0, errShortBuffer
	}
	if l > 255 {
		return 0, errInvalidAddr
	}
	b[1] = byte(l)
	copy(b[:l], a.Raw)
	return ll, nil
}

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 addrsSpace(as []Addr) int {
	var l int
	for _, a := range as {
		switch a := a.(type) {
		case *LinkAddr:
			_, ll := a.lenAndSpace()
			l += ll
		case *Inet4Addr:
			_, ll := a.lenAndSpace()
			l += ll
		case *Inet6Addr:
			_, ll := a.lenAndSpace()
			l += ll
		case *DefaultAddr:
			_, ll := a.lenAndSpace()
			l += ll
		}
	}
	return l
}

// marshalAddrs marshals as and returns a bitmap indicating which
// address is stored in b.
func marshalAddrs(b []byte, as []Addr) (uint, error) {
	var attrs uint
	for i, a := range as {
		switch a := a.(type) {
		case *LinkAddr:
			l, err := a.marshal(b)
			if err != nil {
				return 0, err
			}
			b = b[l:]
			attrs |= 1 << uint(i)
		case *Inet4Addr:
			l, err := a.marshal(b)
			if err != nil {
				return 0, err
			}
			b = b[l:]
			attrs |= 1 << uint(i)
		case *Inet6Addr:
			l, err := a.marshal(b)
			if err != nil {
				return 0, err
			}
			b = b[l:]
			attrs |= 1 << uint(i)
		case *DefaultAddr:
			l, err := a.marshal(b)
			if err != nil {
				return 0, err
			}
			b = b[l:]
			attrs |= 1 << uint(i)
		}
	}
	return attrs, 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
				l := roundup(int(b[0]))
				if len(b) < l {
					return nil, errMessageTooShort
				}
				b = b[l:]
			case sysAF_INET, sysAF_INET6:
				af = int(b[1])
				a, err := parseInetAddr(af, b)
				if err != nil {
					return nil, err
				}
				as[i] = a
				l := roundup(int(b[0]))
				if len(b) < l {
					return nil, errMessageTooShort
				}
				b = b[l:]
			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
			l := roundup(int(b[0]))
			if len(b) < l {
				return nil, errMessageTooShort
			}
			b = b[l:]
		}
	}
	return as[:], nil
}


text:
// 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>

#include <netinet/in.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

	sysSOCK_RAW = C.SOCK_RAW

	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

	sizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
	sizeofSockaddrInet    = C.sizeof_struct_sockaddr_in
	sizeofSockaddrInet6   = C.sizeof_struct_sockaddr_in6
)


text:
// 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
	"o:bfd",                // bfd for openbsd
	"o:dns",                // dns for openbsd
	"o:static",             // static for openbsd
	"o:search",             // search 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
}

// propVirtual is a proprietary virtual network interface.
type propVirtual struct {
	name         string
	addr, mask   string
	setupCmds    []*exec.Cmd
	teardownCmds []*exec.Cmd
}

func (pv *propVirtual) setup() error {
	for _, cmd := range pv.setupCmds {
		if err := cmd.Run(); err != nil {
			pv.teardown()
			return err
		}
	}
	return nil
}

func (pv *propVirtual) teardown() error {
	for _, cmd := range pv.teardownCmds {
		if err := cmd.Run(); err != nil {
			return err
		}
	}
	return nil
}

func (pv *propVirtual) configure(suffix int) error {
	if runtime.GOOS == "openbsd" {
		pv.name = fmt.Sprintf("vether%d", suffix)
	} else {
		pv.name = fmt.Sprintf("vlan%d", suffix)
	}
	xname, err := exec.LookPath("ifconfig")
	if err != nil {
		return err
	}
	pv.setupCmds = append(pv.setupCmds, &exec.Cmd{
		Path: xname,
		Args: []string{"ifconfig", pv.name, "create"},
	})
	if runtime.GOOS == "netbsd" {
		// NetBSD requires an underlying dot1Q-capable network
		// interface.
		pv.setupCmds = append(pv.setupCmds, &exec.Cmd{
			Path: xname,
			Args: []string{"ifconfig", pv.name, "vlan", fmt.Sprintf("%d", suffix&0xfff), "vlanif", "wm0"},
		})
	}
	pv.setupCmds = append(pv.setupCmds, &exec.Cmd{
		Path: xname,
		Args: []string{"ifconfig", pv.name, "inet", pv.addr, "netmask", pv.mask},
	})
	pv.teardownCmds = append(pv.teardownCmds, &exec.Cmd{
		Path: xname,
		Args: []string{"ifconfig", pv.name, "destroy"},
	})
	return nil
}


text:
// 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
}


text:
// 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"
)

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)), newlen)
	if errno != 0 {
		return error(errno)
	}
	return nil
}


text:
// 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

	sysSOCK_RAW = 0x3

	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
	sysRTM_INVALIDATE = 0x11
	sysRTM_BFD        = 0x12
	sysRTM_PROPOSAL   = 0x13

	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
	sysRTA_BFD     = 0x800
	sysRTA_DNS     = 0x1000
	sysRTA_STATIC  = 0x2000
	sysRTA_SEARCH  = 0x4000

	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_BFD     = 0xb
	sysRTAX_DNS     = 0xc
	sysRTAX_STATIC  = 0xd
	sysRTAX_SEARCH  = 0xe
	sysRTAX_MAX     = 0xf
)

const (
	sizeofRtMsghdr = 0x60

	sizeofSockaddrStorage = 0x100
	sizeofSockaddrInet    = 0x10
	sizeofSockaddrInet6   = 0x1c
)


text:
// 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

	sysSOCK_RAW = 0x3

	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

	sizeofSockaddrStorage = 0x80
	sizeofSockaddrInet    = 0x10
	sizeofSockaddrInet6   = 0x1c
)


text:
// 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 }

// 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])),
		},
	}
}

// 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]*wireFormat) {
	var p uintptr
	rtm := &wireFormat{extOff: 40, bodyOff: sizeofRtMsghdrDragonFlyBSD4}
	rtm.parse = rtm.parseRouteMessage
	ifm := &wireFormat{extOff: 16, bodyOff: sizeofIfMsghdrDragonFlyBSD4}
	ifm.parse = ifm.parseInterfaceMessage
	ifam := &wireFormat{extOff: sizeofIfaMsghdrDragonFlyBSD4, bodyOff: sizeofIfaMsghdrDragonFlyBSD4}
	ifam.parse = ifam.parseInterfaceAddrMessage
	ifmam := &wireFormat{extOff: sizeofIfmaMsghdrDragonFlyBSD4, bodyOff: sizeofIfmaMsghdrDragonFlyBSD4}
	ifmam.parse = ifmam.parseInterfaceMulticastAddrMessage
	ifanm := &wireFormat{extOff: sizeofIfAnnouncemsghdrDragonFlyBSD4, bodyOff: sizeofIfAnnouncemsghdrDragonFlyBSD4}
	ifanm.parse = ifanm.parseInterfaceAnnounceMessage
	return int(unsafe.Sizeof(p)), map[int]*wireFormat{
		sysRTM_ADD:        rtm,
		sysRTM_DELETE:     rtm,
		sysRTM_CHANGE:     rtm,
		sysRTM_GET:        rtm,
		sysRTM_LOSING:     rtm,
		sysRTM_REDIRECT:   rtm,
		sysRTM_MISS:       rtm,
		sysRTM_LOCK:       rtm,
		sysRTM_RESOLVE:    rtm,
		sysRTM_NEWADDR:    ifam,
		sysRTM_DELADDR:    ifam,
		sysRTM_IFINFO:     ifm,
		sysRTM_NEWMADDR:   ifmam,
		sysRTM_DELMADDR:   ifmam,
		sysRTM_IFANNOUNCE: ifanm,
	}
}


text:
// 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

import (
	"runtime"
	"syscall"
)

func (m *RouteMessage) marshal() ([]byte, error) {
	w, ok := wireFormats[m.Type]
	if !ok {
		return nil, errUnsupportedMessage
	}
	l := w.bodyOff + addrsSpace(m.Addrs)
	if runtime.GOOS == "darwin" {
		// Fix stray pointer writes on macOS.
		// See golang.org/issue/22456.
		l += 1024
	}
	b := make([]byte, l)
	nativeEndian.PutUint16(b[:2], uint16(l))
	if m.Version == 0 {
		b[2] = sysRTM_VERSION
	} else {
		b[2] = byte(m.Version)
	}
	b[3] = byte(m.Type)
	nativeEndian.PutUint32(b[8:12], uint32(m.Flags))
	nativeEndian.PutUint16(b[4:6], uint16(m.Index))
	nativeEndian.PutUint32(b[16:20], uint32(m.ID))
	nativeEndian.PutUint32(b[20:24], uint32(m.Seq))
	attrs, err := marshalAddrs(b[w.bodyOff:], m.Addrs)
	if err != nil {
		return nil, err
	}
	if attrs > 0 {
		nativeEndian.PutUint32(b[12:16], uint32(attrs))
	}
	return b, nil
}

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])),
		ID:      uintptr(nativeEndian.Uint32(b[16:20])),
		Seq:     int(nativeEndian.Uint32(b[20:24])),
		extOff:  w.extOff,
		raw:     b[:l],
	}
	errno := syscall.Errno(nativeEndian.Uint32(b[28:32]))
	if errno != 0 {
		m.Err = errno
	}
	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
}


text:
// 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
	wireFormats  map[int]*wireFormat
)

func init() {
	i := uint32(1)
	b := (*[4]byte)(unsafe.Pointer(&i))
	if b[0] == 1 {
		nativeEndian = littleEndian
	} else {
		nativeEndian = bigEndian
	}
	kernelAlign, wireFormats = probeRoutingStack()
}

func roundup(l int) int {
	if l == 0 {
		return kernelAlign
	}
	return (l + kernelAlign - 1) & ^(kernelAlign - 1)
}

type wireFormat struct {
	extOff  int // offset of header extension
	bodyOff int // offset of message body
	parse   func(RIBType, []byte) (Message, error)
}


text:
// 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>

#include <netinet/in.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

	sysSOCK_RAW = C.SOCK_RAW

	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

	sizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
	sizeofSockaddrInet    = C.sizeof_struct_sockaddr_in
	sizeofSockaddrInet6   = C.sizeof_struct_sockaddr_in6
)


text:
// 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],
	}
	ll := int(nativeEndian.Uint16(b[4:6]))
	if len(b) < ll {
		return nil, errInvalidMessage
	}
	a, err := parseLinkAddr(b[ll:])
	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]))
	if len(b) < bodyOff {
		return nil, errInvalidMessage
	}
	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
}


text:
// 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>

#include <netinet/in.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

	sysSOCK_RAW = C.SOCK_RAW

	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

	sizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
	sizeofSockaddrInet    = C.sizeof_struct_sockaddr_in
	sizeofSockaddrInet6   = C.sizeof_struct_sockaddr_in6
)


text:
// 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 }

// 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])),
		},
	}
}

// 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]*wireFormat) {
	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
		}
	}
	rtm.parse = rtm.parseRouteMessage
	ifm.parse = ifm.parseInterfaceMessage
	ifam.parse = ifam.parseInterfaceAddrMessage
	ifmam.parse = ifmam.parseInterfaceMulticastAddrMessage
	ifanm.parse = ifanm.parseInterfaceAnnounceMessage
	return align, map[int]*wireFormat{
		sysRTM_ADD:        rtm,
		sysRTM_DELETE:     rtm,
		sysRTM_CHANGE:     rtm,
		sysRTM_GET:        rtm,
		sysRTM_LOSING:     rtm,
		sysRTM_REDIRECT:   rtm,
		sysRTM_MISS:       rtm,
		sysRTM_LOCK:       rtm,
		sysRTM_RESOLVE:    rtm,
		sysRTM_NEWADDR:    ifam,
		sysRTM_DELADDR:    ifam,
		sysRTM_IFINFO:     ifm,
		sysRTM_NEWMADDR:   ifmam,
		sysRTM_DELMADDR:   ifmam,
		sysRTM_IFANNOUNCE: ifanm,
	}
}


text:
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.

// 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 idna

// appendMapping appends the mapping for the respective rune. isMapped must be
// true. A mapping is a categorization of a rune as defined in UTS #46.
func (c info) appendMapping(b []byte, s string) []byte {
	index := int(c >> indexShift)
	if c&xorBit == 0 {
		s := mappings[index:]
		return append(b, s[1:s[0]+1]...)
	}
	b = append(b, s...)
	if c&inlineXOR == inlineXOR {
		// TODO: support and handle two-byte inline masks
		b[len(b)-1] ^= byte(index)
	} else {
		for p := len(b) - int(xorData[index]); p < len(b); p++ {
			index++
			b[p] ^= xorData[index]
		}
	}
	return b
}

// Sparse block handling code.

type valueRange struct {
	value  uint16 // header: value:stride
	lo, hi byte   // header: lo:n
}

type sparseBlocks struct {
	values []valueRange
	offset []uint16
}

var idnaSparse = sparseBlocks{
	values: idnaSparseValues[:],
	offset: idnaSparseOffset[:],
}

// Don't use newIdnaTrie to avoid unconditional linking in of the table.
var trie = &idnaTrie{}

// lookup determines the type of block n and looks up the value for b.
// For n < t.cutoff, the block is a simple lookup table. Otherwise, the block
// is a list of ranges with an accompanying value. Given a matching range r,
// the value for b is by r.value + (b - r.lo) * stride.
func (t *sparseBlocks) lookup(n uint32, b byte) uint16 {
	offset := t.offset[n]
	header := t.values[offset]
	lo := offset + 1
	hi := lo + uint16(header.lo)
	for lo < hi {
		m := lo + (hi-lo)/2
		r := t.values[m]
		if r.lo <= b && b <= r.hi {
			return r.value + uint16(b-r.lo)*header.value
		}
		if b < r.lo {
			hi = m
		} else {
			lo = m + 1
		}
	}
	return 0
}


text:
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.

// 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 idna

// This file implements the Punycode algorithm from RFC 3492.

import (
	"math"
	"strings"
	"unicode/utf8"
)

// These parameter values are specified in section 5.
//
// All computation is done with int32s, so that overflow behavior is identical
// regardless of whether int is 32-bit or 64-bit.
const (
	base        int32 = 36
	damp        int32 = 700
	initialBias int32 = 72
	initialN    int32 = 128
	skew        int32 = 38
	tmax        int32 = 26
	tmin        int32 = 1
)

func punyError(s string) error { return &labelError{s, "A3"} }

// decode decodes a string as specified in section 6.2.
func decode(encoded string) (string, error) {
	if encoded == "" {
		return "", nil
	}
	pos := 1 + strings.LastIndex(encoded, "-")
	if pos == 1 {
		return "", punyError(encoded)
	}
	if pos == len(encoded) {
		return encoded[:len(encoded)-1], nil
	}
	output := make([]rune, 0, len(encoded))
	if pos != 0 {
		for _, r := range encoded[:pos-1] {
			output = append(output, r)
		}
	}
	i, n, bias := int32(0), initialN, initialBias
	for pos < len(encoded) {
		oldI, w := i, int32(1)
		for k := base; ; k += base {
			if pos == len(encoded) {
				return "", punyError(encoded)
			}
			digit, ok := decodeDigit(encoded[pos])
			if !ok {
				return "", punyError(encoded)
			}
			pos++
			i += digit * w
			if i < 0 {
				return "", punyError(encoded)
			}
			t := k - bias
			if t < tmin {
				t = tmin
			} else if t > tmax {
				t = tmax
			}
			if digit < t {
				break
			}
			w *= base - t
			if w >= math.MaxInt32/base {
				return "", punyError(encoded)
			}
		}
		x := int32(len(output) + 1)
		bias = adapt(i-oldI, x, oldI == 0)
		n += i / x
		i %= x
		if n > utf8.MaxRune || len(output) >= 1024 {
			return "", punyError(encoded)
		}
		output = append(output, 0)
		copy(output[i+1:], output[i:])
		output[i] = n
		i++
	}
	return string(output), nil
}

// encode encodes a string as specified in section 6.3 and prepends prefix to
// the result.
//
// The "while h < length(input)" line in the specification becomes "for
// remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes.
func encode(prefix, s string) (string, error) {
	output := make([]byte, len(prefix), len(prefix)+1+2*len(s))
	copy(output, prefix)
	delta, n, bias := int32(0), initialN, initialBias
	b, remaining := int32(0), int32(0)
	for _, r := range s {
		if r < 0x80 {
			b++
			output = append(output, byte(r))
		} else {
			remaining++
		}
	}
	h := b
	if b > 0 {
		output = append(output, '-')
	}
	for remaining != 0 {
		m := int32(0x7fffffff)
		for _, r := range s {
			if m > r && r >= n {
				m = r
			}
		}
		delta += (m - n) * (h + 1)
		if delta < 0 {
			return "", punyError(s)
		}
		n = m
		for _, r := range s {
			if r < n {
				delta++
				if delta < 0 {
					return "", punyError(s)
				}
				continue
			}
			if r > n {
				continue
			}
			q := delta
			for k := base; ; k += base {
				t := k - bias
				if t < tmin {
					t = tmin
				} else if t > tmax {
					t = tmax
				}
				if q < t {
					break
				}
				output = append(output, encodeDigit(t+(q-t)%(base-t)))
				q = (q - t) / (base - t)
			}
			output = append(output, encodeDigit(q))
			bias = adapt(delta, h+1, h == b)
			delta = 0
			h++
			remaining--
		}
		delta++
		n++
	}
	return string(output), nil
}

func decodeDigit(x byte) (digit int32, ok bool) {
	switch {
	case '0' <= x && x <= '9':
		return int32(x - ('0' - 26)), true
	case 'A' <= x && x <= 'Z':
		return int32(x - 'A'), true
	case 'a' <= x && x <= 'z':
		return int32(x - 'a'), true
	}
	return 0, false
}

func encodeDigit(digit int32) byte {
	switch {
	case 0 <= digit && digit < 26:
		return byte(digit + 'a')
	case 26 <= digit && digit < 36:
		return byte(digit + ('0' - 26))
	}
	panic("idna: internal error in punycode encoding")
}

// adapt is the bias adaptation function specified in section 6.1.
func adapt(delta, numPoints int32, firstTime bool) int32 {
	if firstTime {
		delta /= damp
	} else {
		delta /= 2
	}
	delta += delta / numPoints
	k := int32(0)
	for delta > ((base-tmin)*tmax)/2 {
		delta /= base - tmin
		k += base
	}
	return k + (base-tmin+1)*delta/(delta+skew)
}


text:
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.

package idna

// This file contains definitions for interpreting the trie value of the idna
// trie generated by "go run gen*.go". It is shared by both the generator
// program and the resultant package. Sharing is achieved by the generator
// copying gen_trieval.go to trieval.go and changing what's above this comment.

// info holds information from the IDNA mapping table for a single rune. It is
// the value returned by a trie lookup. In most cases, all information fits in
// a 16-bit value. For mappings, this value may contain an index into a slice
// with the mapped string. Such mappings can consist of the actual mapped value
// or an XOR pattern to be applied to the bytes of the UTF8 encoding of the
// input rune. This technique is used by the cases packages and reduces the
// table size significantly.
//
// The per-rune values have the following format:
//
//   if mapped {
//     if inlinedXOR {
//       15..13 inline XOR marker
//       12..11 unused
//       10..3  inline XOR mask
//     } else {
//       15..3  index into xor or mapping table
//     }
//   } else {
//       15..14 unused
//       13     mayNeedNorm
//       12..11 attributes
//       10..8  joining type
//        7..3  category type
//   }
//      2  use xor pattern
//   1..0  mapped category
//
// See the definitions below for a more detailed description of the various
// bits.
type info uint16

const (
	catSmallMask = 0x3
	catBigMask   = 0xF8
	indexShift   = 3
	xorBit       = 0x4    // interpret the index as an xor pattern
	inlineXOR    = 0xE000 // These bits are set if the XOR pattern is inlined.

	joinShift = 8
	joinMask  = 0x07

	// Attributes
	attributesMask = 0x1800
	viramaModifier = 0x1800
	modifier       = 0x1000
	rtl            = 0x0800

	mayNeedNorm = 0x2000
)

// A category corresponds to a category defined in the IDNA mapping table.
type category uint16

const (
	unknown              category = 0 // not currently defined in unicode.
	mapped               category = 1
	disallowedSTD3Mapped category = 2
	deviation            category = 3
)

const (
	valid               category = 0x08
	validNV8            category = 0x18
	validXV8            category = 0x28
	disallowed          category = 0x40
	disallowedSTD3Valid category = 0x80
	ignored             category = 0xC0
)

// join types and additional rune information
const (
	joiningL = (iota + 1)
	joiningD
	joiningT
	joiningR

	//the following types are derived during processing
	joinZWJ
	joinZWNJ
	joinVirama
	numJoinTypes
)

func (c info) isMapped() bool {
	return c&0x3 != 0
}

func (c info) category() category {
	small := c & catSmallMask
	if small != 0 {
		return category(small)
	}
	return category(c & catBigMask)
}

func (c info) joinType() info {
	if c.isMapped() {
		return 0
	}
	return (c >> joinShift) & joinMask
}

func (c info) isModifier() bool {
	return c&(modifier|catSmallMask) == modifier
}

func (c info) isViramaModifier() bool {
	return c&(attributesMask|catSmallMask) == viramaModifier
}


text:
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package idna

import (
	"testing"
)

var idnaTestCases = [...]struct {
	ascii, unicode string
}{
	// Labels.
	{"books", "books"},
	{"xn--bcher-kva", "bücher"},

	// Domains.
	{"foo--xn--bar.org", "foo--xn--bar.org"},
	{"golang.org", "golang.org"},
	{"example.xn--p1ai", "example.рф"},
	{"xn--czrw28b.tw", "商業.tw"},
	{"www.xn--mller-kva.de", "www.müller.de"},
}

func TestIDNA(t *testing.T) {
	for _, tc := range idnaTestCases {
		if a, err := ToASCII(tc.unicode); err != nil {
			t.Errorf("ToASCII(%q): %v", tc.unicode, err)
		} else if a != tc.ascii {
			t.Errorf("ToASCII(%q): got %q, want %q", tc.unicode, a, tc.ascii)
		}

		if u, err := ToUnicode(tc.ascii); err != nil {
			t.Errorf("ToUnicode(%q): %v", tc.ascii, err)
		} else if u != tc.unicode {
			t.Errorf("ToUnicode(%q): got %q, want %q", tc.ascii, u, tc.unicode)
		}
	}
}

func TestIDNASeparators(t *testing.T) {
	type subCase struct {
		unicode   string
		wantASCII string
		wantErr   bool
	}

	testCases := []struct {
		name     string
		profile  *Profile
		subCases []subCase
	}{
		{
			name: "Punycode", profile: Punycode,
			subCases: []subCase{
				{"example\u3002jp", "xn--examplejp-ck3h", false},
				{"東京\uFF0Ejp", "xn--jp-l92cn98g071o", false},
				{"大阪\uFF61jp", "xn--jp-ku9cz72u463f", false},
			},
		},
		{
			name: "Lookup", profile: Lookup,
			subCases: []subCase{
				{"example\u3002jp", "example.jp", false},
				{"東京\uFF0Ejp", "xn--1lqs71d.jp", false},
				{"大阪\uFF61jp", "xn--pssu33l.jp", false},
			},
		},
		{
			name: "Display", profile: Display,
			subCases: []subCase{
				{"example\u3002jp", "example.jp", false},
				{"東京\uFF0Ejp", "xn--1lqs71d.jp", false},
				{"大阪\uFF61jp", "xn--pssu33l.jp", false},
			},
		},
		{
			name: "Registration", profile: Registration,
			subCases: []subCase{
				{"example\u3002jp", "", true},
				{"東京\uFF0Ejp", "", true},
				{"大阪\uFF61jp", "", true},
			},
		},
	}
	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			for _, c := range tc.subCases {
				gotA, err := tc.profile.ToASCII(c.unicode)
				if c.wantErr {
					if err == nil {
						t.Errorf("ToASCII(%q): got no error, but an error expected", c.unicode)
					}
				} else {
					if err != nil {
						t.Errorf("ToASCII(%q): got err=%v, but no error expected", c.unicode, err)
					} else if gotA != c.wantASCII {
						t.Errorf("ToASCII(%q): got %q, want %q", c.unicode, gotA, c.wantASCII)
					}
				}
			}
		})
	}
}

// TODO(nigeltao): test errors, once we've specified when ToASCII and ToUnicode
// return errors.


text:
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package idna

import (
	"strings"
	"testing"
)

var punycodeTestCases = [...]struct {
	s, encoded string
}{
	{"", ""},
	{"-", "--"},
	{"-a", "-a-"},
	{"-a-", "-a--"},
	{"a", "a-"},
	{"a-", "a--"},
	{"a-b", "a-b-"},
	{"books", "books-"},
	{"bücher", "bcher-kva"},
	{"Hello世界", "Hello-ck1hg65u"},
	{"ü", "tda"},
	{"üý", "tdac"},

	// The test cases below come from RFC 3492 section 7.1 with Errata 3026.
	{
		// (A) Arabic (Egyptian).
		"\u0644\u064A\u0647\u0645\u0627\u0628\u062A\u0643\u0644" +
			"\u0645\u0648\u0634\u0639\u0631\u0628\u064A\u061F",
		"egbpdaj6bu4bxfgehfvwxn",
	},
	{
		// (B) Chinese (simplified).
		"\u4ED6\u4EEC\u4E3A\u4EC0\u4E48\u4E0D\u8BF4\u4E2D\u6587",
		"ihqwcrb4cv8a8dqg056pqjye",
	},
	{
		// (C) Chinese (traditional).
		"\u4ED6\u5011\u7232\u4EC0\u9EBD\u4E0D\u8AAA\u4E2D\u6587",
		"ihqwctvzc91f659drss3x8bo0yb",
	},
	{
		// (D) Czech.
		"\u0050\u0072\u006F\u010D\u0070\u0072\u006F\u0073\u0074" +
			"\u011B\u006E\u0065\u006D\u006C\u0075\u0076\u00ED\u010D" +
			"\u0065\u0073\u006B\u0079",
		"Proprostnemluvesky-uyb24dma41a",
	},
	{
		// (E) Hebrew.
		"\u05DC\u05DE\u05D4\u05D4\u05DD\u05E4\u05E9\u05D5\u05D8" +
			"\u05DC\u05D0\u05DE\u05D3\u05D1\u05E8\u05D9\u05DD\u05E2" +
			"\u05D1\u05E8\u05D9\u05EA",
		"4dbcagdahymbxekheh6e0a7fei0b",
	},
	{
		// (F) Hindi (Devanagari).
		"\u092F\u0939\u0932\u094B\u0917\u0939\u093F\u0928\u094D" +
			"\u0926\u0940\u0915\u094D\u092F\u094B\u0902\u0928\u0939" +
			"\u0940\u0902\u092C\u094B\u0932\u0938\u0915\u0924\u0947" +
			"\u0939\u0948\u0902",
		"i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd",
	},
	{
		// (G) Japanese (kanji and hiragana).
		"\u306A\u305C\u307F\u3093\u306A\u65E5\u672C\u8A9E\u3092" +
			"\u8A71\u3057\u3066\u304F\u308C\u306A\u3044\u306E\u304B",
		"n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa",
	},
	{
		// (H) Korean (Hangul syllables).
		"\uC138\uACC4\uC758\uBAA8\uB4E0\uC0AC\uB78C\uB4E4\uC774" +
			"\uD55C\uAD6D\uC5B4\uB97C\uC774\uD574\uD55C\uB2E4\uBA74" +
			"\uC5BC\uB9C8\uB098\uC88B\uC744\uAE4C",
		"989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5j" +
			"psd879ccm6fea98c",
	},
	{
		// (I) Russian (Cyrillic).
		"\u043F\u043E\u0447\u0435\u043C\u0443\u0436\u0435\u043E" +
			"\u043D\u0438\u043D\u0435\u0433\u043E\u0432\u043E\u0440" +
			"\u044F\u0442\u043F\u043E\u0440\u0443\u0441\u0441\u043A" +
			"\u0438",
		"b1abfaaepdrnnbgefbadotcwatmq2g4l",
	},
	{
		// (J) Spanish.
		"\u0050\u006F\u0072\u0071\u0075\u00E9\u006E\u006F\u0070" +
			"\u0075\u0065\u0064\u0065\u006E\u0073\u0069\u006D\u0070" +
			"\u006C\u0065\u006D\u0065\u006E\u0074\u0065\u0068\u0061" +
			"\u0062\u006C\u0061\u0072\u0065\u006E\u0045\u0073\u0070" +
			"\u0061\u00F1\u006F\u006C",
		"PorqunopuedensimplementehablarenEspaol-fmd56a",
	},
	{
		// (K) Vietnamese.
		"\u0054\u1EA1\u0069\u0073\u0061\u006F\u0068\u1ECD\u006B" +
			"\u0068\u00F4\u006E\u0067\u0074\u0068\u1EC3\u0063\u0068" +
			"\u1EC9\u006E\u00F3\u0069\u0074\u0069\u1EBF\u006E\u0067" +
			"\u0056\u0069\u1EC7\u0074",
		"TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g",
	},
	{
		// (L) 3<nen>B<gumi><kinpachi><sensei>.
		"\u0033\u5E74\u0042\u7D44\u91D1\u516B\u5148\u751F",
		"3B-ww4c5e180e575a65lsy2b",
	},
	{
		// (M) <amuro><namie>-with-SUPER-MONKEYS.
		"\u5B89\u5BA4\u5948\u7F8E\u6075\u002D\u0077\u0069\u0074" +
			"\u0068\u002D\u0053\u0055\u0050\u0045\u0052\u002D\u004D" +
			"\u004F\u004E\u004B\u0045\u0059\u0053",
		"-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n",
	},
	{
		// (N) Hello-Another-Way-<sorezore><no><basho>.
		"\u0048\u0065\u006C\u006C\u006F\u002D\u0041\u006E\u006F" +
			"\u0074\u0068\u0065\u0072\u002D\u0057\u0061\u0079\u002D" +
			"\u305D\u308C\u305E\u308C\u306E\u5834\u6240",
		"Hello-Another-Way--fc4qua05auwb3674vfr0b",
	},
	{
		// (O) <hitotsu><yane><no><shita>2.
		"\u3072\u3068\u3064\u5C4B\u6839\u306E\u4E0B\u0032",
		"2-u9tlzr9756bt3uc0v",
	},
	{
		// (P) Maji<de>Koi<suru>5<byou><mae>
		"\u004D\u0061\u006A\u0069\u3067\u004B\u006F\u0069\u3059" +
			"\u308B\u0035\u79D2\u524D",
		"MajiKoi5-783gue6qz075azm5e",
	},
	{
		// (Q) <pafii>de<runba>
		"\u30D1\u30D5\u30A3\u30FC\u0064\u0065\u30EB\u30F3\u30D0",
		"de-jg4avhby1noc0d",
	},
	{
		// (R) <sono><supiido><de>
		"\u305D\u306E\u30B9\u30D4\u30FC\u30C9\u3067",
		"d9juau41awczczp",
	},
	{
		// (S) -> $1.00 <-
		"\u002D\u003E\u0020\u0024\u0031\u002E\u0030\u0030\u0020" +
			"\u003C\u002D",
		"-> $1.00 <--",
	},
}

func TestPunycode(t *testing.T) {
	for _, tc := range punycodeTestCases {
		if got, err := decode(tc.encoded); err != nil {
			t.Errorf("decode(%q): %v", tc.encoded, err)
		} else if got != tc.s {
			t.Errorf("decode(%q): got %q, want %q", tc.encoded, got, tc.s)
		}

		if got, err := encode("", tc.s); err != nil {
			t.Errorf(`encode("", %q): %v`, tc.s, err)
		} else if got != tc.encoded {
			t.Errorf(`encode("", %q): got %q, want %q`, tc.s, got, tc.encoded)
		}
	}
}

var punycodeErrorTestCases = [...]string{
	"decode -",            // A sole '-' is invalid.
	"decode foo\x00bar",   // '\x00' is not in [0-9A-Za-z].
	"decode foo#bar",      // '#' is not in [0-9A-Za-z].
	"decode foo\u00A3bar", // '\u00A3' is not in [0-9A-Za-z].
	"decode 9",            // "9a" decodes to codepoint \u00A3; "9" is truncated.
	"decode 99999a",       // "99999a" decodes to codepoint \U0048A3C1, which is > \U0010FFFF.
	"decode 9999999999a",  // "9999999999a" overflows the int32 calculation.

	"encode " + strings.Repeat("x", 65536) + "\uff00", // int32 overflow.
}

func TestPunycodeErrors(t *testing.T) {
	for _, tc := range punycodeErrorTestCases {
		var err error
		switch {
		case strings.HasPrefix(tc, "decode "):
			_, err = decode(tc[7:])
		case strings.HasPrefix(tc, "encode "):
			_, err = encode("", tc[7:])
		}
		if err == nil {
			if len(tc) > 256 {
				tc = tc[:100] + "..." + tc[len(tc)-100:]
			}
			t.Errorf("no error for %s", tc)
		}
	}
}


text:
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.

// Copyright 2017 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 idna_test

import (
	"fmt"

	"golang.org/x/net/idna"
)

func ExampleProfile() {
	// Raw Punycode has no restrictions and does no mappings.
	fmt.Println(idna.ToASCII(""))
	fmt.Println(idna.ToASCII("*.faß.com"))
	fmt.Println(idna.Punycode.ToASCII("*.faß.com"))

	// Rewrite IDN for lookup. This (currently) uses transitional mappings to
	// find a balance between IDNA2003 and IDNA2008 compatibility.
	fmt.Println(idna.Lookup.ToASCII(""))
	fmt.Println(idna.Lookup.ToASCII("www.faß.com"))

	// Convert an IDN to ASCII for registration purposes. This changes the
	// encoding, but reports an error if the input was illformed.
	fmt.Println(idna.Registration.ToASCII(""))
	fmt.Println(idna.Registration.ToASCII("www.faß.com"))

	// Output:
	//  <nil>
	// *.xn--fa-hia.com <nil>
	// *.xn--fa-hia.com <nil>
	//  <nil>
	// www.fass.com <nil>
	//  idna: invalid label ""
	// www.xn--fa-hia.com <nil>
}

func ExampleNew() {
	var p *idna.Profile

	// Raw Punycode has no restrictions and does no mappings.
	p = idna.New()
	fmt.Println(p.ToASCII("*.faß.com"))

	// Do mappings. Note that star is not allowed in a DNS lookup.
	p = idna.New(
		idna.MapForLookup(),
		idna.Transitional(true)) // Map ß -> ss
	fmt.Println(p.ToASCII("*.faß.com"))

	// Lookup for registration. Also does not allow '*'.
	p = idna.New(idna.ValidateForRegistration())
	fmt.Println(p.ToUnicode("*.faß.com"))

	// Set up a profile maps for lookup, but allows wild cards.
	p = idna.New(
		idna.MapForLookup(),
		idna.Transitional(true),      // Map ß -> ss
		idna.StrictDomainName(false)) // Set more permissive ASCII rules.
	fmt.Println(p.ToASCII("*.faß.com"))

	// Output:
	// *.xn--fa-hia.com <nil>
	// *.fass.com idna: disallowed rune U+002A
	// *.faß.com idna: disallowed rune U+002A
	// *.fass.com <nil>
}