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 
An Addr represents an address associated with packet routing.
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 ( *LinkAddr) () int { return sysAF_LINK }

func ( *LinkAddr) () (int, int) {
	 := 8 + len(.Name) + len(.Addr)
	return , roundup()
}

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

func ( []byte) (Addr, error) {
	if len() < 8 {
		return nil, errInvalidAddr
	}
	, ,  := parseKernelLinkAddr(sysAF_LINK, [4:])
	if  != nil {
		return nil, 
	}
	.(*LinkAddr).Index = int(nativeEndian.Uint16([2:4]))
	return , nil
}
parseKernelLinkAddr parses b as a link-layer address in conventional BSD kernel form.
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".
	, ,  := int([1]), int([2]), int([3])
	if  == 0xff {
		 = 0
	}
	if  == 0xff {
		 = 0
	}
	if  == 0xff {
		 = 0
	}
	 := 4 +  +  + 
	if len() <  {
		return 0, nil, errInvalidAddr
	}
	 := [4:]
	var  string
	var  []byte
	if  > 0 {
		 = string([:])
		 = [:]
	}
	if  > 0 {
		 = [:]
		 = [:]
	}
	return , &LinkAddr{Name: , 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 ( *Inet4Addr) () int { return sysAF_INET }

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

func ( *Inet4Addr) ( []byte) (int, error) {
	,  := .lenAndSpace()
	if len() <  {
		return 0, errShortBuffer
	}
	[0] = byte()
	[1] = sysAF_INET
	copy([4:8], .IP[:])
	return , 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 ( *Inet6Addr) () int { return sysAF_INET6 }

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

func ( *Inet6Addr) ( []byte) (int, error) {
	,  := .lenAndSpace()
	if len() <  {
		return 0, errShortBuffer
	}
	[0] = byte()
	[1] = sysAF_INET6
	copy([8:24], .IP[:])
	if .ZoneID > 0 {
		nativeEndian.PutUint32([24:28], uint32(.ZoneID))
	}
	return , nil
}
parseInetAddr parses b as an internet address for IPv4 or IPv6.
func ( int,  []byte) (Addr, error) {
	switch  {
	case sysAF_INET:
		if len() < sizeofSockaddrInet {
			return nil, errInvalidAddr
		}
		 := &Inet4Addr{}
		copy(.IP[:], [4:8])
		return , nil
	case sysAF_INET6:
		if len() < sizeofSockaddrInet6 {
			return nil, errInvalidAddr
		}
		 := &Inet6Addr{ZoneID: int(nativeEndian.Uint32([24:28]))}
		copy(.IP[:], [8:24])
KAME based IPv6 protocol stack usually embeds the interface index in the interface-local or link-local address as the kernel-internal form.
			 := int(bigEndian.Uint16(.IP[2:4]))
			if  != 0 {
				.ZoneID = 
				.IP[2], .IP[3] = 0, 0
			}
		}
		return , nil
	default:
		return nil, errInvalidAddr
	}
}
parseKernelInetAddr parses b as an internet address in conventional BSD kernel form.
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
	 := int([0])
On Darwin, an address in the kernel form is also used as a message filler.
		if  == 0 || len() > roundup() {
			 = roundup()
		}
	} else {
		 = roundup()
	}
	if len() <  {
		return 0, nil, errInvalidAddr
Don't reorder case expressions. The case expressions for IPv6 must come first.
	const (
		 = 4 // offset of in_addr
		 = 8 // offset of in6_addr
	)
	switch {
	case [0] == sizeofSockaddrInet6:
		 := &Inet6Addr{}
		copy(.IP[:], [:+16])
		return int([0]), , nil
	case  == sysAF_INET6:
		 := &Inet6Addr{}
		if -1 <  {
			copy(.IP[:], [1:])
		} else {
			copy(.IP[:], [-:])
		}
		return int([0]), , nil
	case [0] == sizeofSockaddrInet:
		 := &Inet4Addr{}
		copy(.IP[:], [:+4])
		return int([0]), , nil
	default: // an old fashion, AF_UNSPEC or unknown means AF_INET
		 := &Inet4Addr{}
		if -1 <  {
			copy(.IP[:], [1:])
		} else {
			copy(.IP[:], [-:])
		}
		return int([0]), , 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 ( *DefaultAddr) () int { return .af }

func ( *DefaultAddr) () (int, int) {
	 := len(.Raw)
	return , roundup()
}

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

func ( []byte) (Addr, error) {
	if len() < 2 || len() < int([0]) {
		return nil, errInvalidAddr
	}
	 := &DefaultAddr{af: int([1]), Raw: [:[0]]}
	return , nil
}

func ( []Addr) int {
	var  int
	for ,  := range  {
		switch a := .(type) {
		case *LinkAddr:
			,  := .lenAndSpace()
			 += 
		case *Inet4Addr:
			,  := .lenAndSpace()
			 += 
		case *Inet6Addr:
			,  := .lenAndSpace()
			 += 
		case *DefaultAddr:
			,  := .lenAndSpace()
			 += 
		}
	}
	return 
}
marshalAddrs marshals as and returns a bitmap indicating which address is stored in b.
func ( []byte,  []Addr) (uint, error) {
	var  uint
	for ,  := range  {
		switch a := .(type) {
		case *LinkAddr:
			,  := .marshal()
			if  != nil {
				return 0, 
			}
			 = [:]
			 |= 1 << uint()
		case *Inet4Addr:
			,  := .marshal()
			if  != nil {
				return 0, 
			}
			 = [:]
			 |= 1 << uint()
		case *Inet6Addr:
			,  := .marshal()
			if  != nil {
				return 0, 
			}
			 = [:]
			 |= 1 << uint()
		case *DefaultAddr:
			,  := .marshal()
			if  != nil {
				return 0, 
			}
			 = [:]
			 |= 1 << uint()
		}
	}
	return , nil
}

func ( uint,  func(int, []byte) (int, Addr, error),  []byte) ([]Addr, error) {
	var  [sysRTAX_MAX]Addr
	 := int(sysAF_UNSPEC)
	for  := uint(0);  < sysRTAX_MAX && len() >= roundup(0); ++ {
		if &(1<<) == 0 {
			continue
		}
		if  <= sysRTAX_BRD {
			switch [1] {
			case sysAF_LINK:
				,  := parseLinkAddr()
				if  != nil {
					return nil, 
				}
				[] = 
				 := roundup(int([0]))
				if len() <  {
					return nil, errMessageTooShort
				}
				 = [:]
			case sysAF_INET, sysAF_INET6:
				 = int([1])
				,  := parseInetAddr(, )
				if  != nil {
					return nil, 
				}
				[] = 
				 := roundup(int([0]))
				if len() <  {
					return nil, errMessageTooShort
				}
				 = [:]
			default:
				, ,  := (, )
				if  != nil {
					return nil, 
				}
				[] = 
				 := roundup()
				if len() <  {
					 = [:]
				} else {
					 = [:]
				}
			}
		} else {
			,  := parseDefaultAddr()
			if  != nil {
				return nil, 
			}
			[] = 
			 := roundup(int([0]))
			if len() <  {
				return nil, errMessageTooShort
			}
			 = [:]
		}
	}
	return [:], nil