| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 | // 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 openbsdpackage routeimport "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}
 |