...

Source file src/vendor/golang.org/x/net/route/address.go

     1	// Copyright 2016 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// +build darwin dragonfly freebsd netbsd openbsd
     6	
     7	package route
     8	
     9	import "runtime"
    10	
    11	// An Addr represents an address associated with packet routing.
    12	type Addr interface {
    13		// Family returns an address family.
    14		Family() int
    15	}
    16	
    17	// A LinkAddr represents a link-layer address.
    18	type LinkAddr struct {
    19		Index int    // interface index when attached
    20		Name  string // interface name when attached
    21		Addr  []byte // link-layer address when attached
    22	}
    23	
    24	// Family implements the Family method of Addr interface.
    25	func (a *LinkAddr) Family() int { return sysAF_LINK }
    26	
    27	func (a *LinkAddr) lenAndSpace() (int, int) {
    28		l := 8 + len(a.Name) + len(a.Addr)
    29		return l, roundup(l)
    30	}
    31	
    32	func (a *LinkAddr) marshal(b []byte) (int, error) {
    33		l, ll := a.lenAndSpace()
    34		if len(b) < ll {
    35			return 0, errShortBuffer
    36		}
    37		nlen, alen := len(a.Name), len(a.Addr)
    38		if nlen > 255 || alen > 255 {
    39			return 0, errInvalidAddr
    40		}
    41		b[0] = byte(l)
    42		b[1] = sysAF_LINK
    43		if a.Index > 0 {
    44			nativeEndian.PutUint16(b[2:4], uint16(a.Index))
    45		}
    46		data := b[8:]
    47		if nlen > 0 {
    48			b[5] = byte(nlen)
    49			copy(data[:nlen], a.Addr)
    50			data = data[nlen:]
    51		}
    52		if alen > 0 {
    53			b[6] = byte(alen)
    54			copy(data[:alen], a.Name)
    55			data = data[alen:]
    56		}
    57		return ll, nil
    58	}
    59	
    60	func parseLinkAddr(b []byte) (Addr, error) {
    61		if len(b) < 8 {
    62			return nil, errInvalidAddr
    63		}
    64		_, a, err := parseKernelLinkAddr(sysAF_LINK, b[4:])
    65		if err != nil {
    66			return nil, err
    67		}
    68		a.(*LinkAddr).Index = int(nativeEndian.Uint16(b[2:4]))
    69		return a, nil
    70	}
    71	
    72	// parseKernelLinkAddr parses b as a link-layer address in
    73	// conventional BSD kernel form.
    74	func parseKernelLinkAddr(_ int, b []byte) (int, Addr, error) {
    75		// The encoding looks like the following:
    76		// +----------------------------+
    77		// | Type             (1 octet) |
    78		// +----------------------------+
    79		// | Name length      (1 octet) |
    80		// +----------------------------+
    81		// | Address length   (1 octet) |
    82		// +----------------------------+
    83		// | Selector length  (1 octet) |
    84		// +----------------------------+
    85		// | Data            (variable) |
    86		// +----------------------------+
    87		//
    88		// On some platforms, all-bit-one of length field means "don't
    89		// care".
    90		nlen, alen, slen := int(b[1]), int(b[2]), int(b[3])
    91		if nlen == 0xff {
    92			nlen = 0
    93		}
    94		if alen == 0xff {
    95			alen = 0
    96		}
    97		if slen == 0xff {
    98			slen = 0
    99		}
   100		l := 4 + nlen + alen + slen
   101		if len(b) < l {
   102			return 0, nil, errInvalidAddr
   103		}
   104		data := b[4:]
   105		var name string
   106		var addr []byte
   107		if nlen > 0 {
   108			name = string(data[:nlen])
   109			data = data[nlen:]
   110		}
   111		if alen > 0 {
   112			addr = data[:alen]
   113			data = data[alen:]
   114		}
   115		return l, &LinkAddr{Name: name, Addr: addr}, nil
   116	}
   117	
   118	// An Inet4Addr represents an internet address for IPv4.
   119	type Inet4Addr struct {
   120		IP [4]byte // IP address
   121	}
   122	
   123	// Family implements the Family method of Addr interface.
   124	func (a *Inet4Addr) Family() int { return sysAF_INET }
   125	
   126	func (a *Inet4Addr) lenAndSpace() (int, int) {
   127		return sizeofSockaddrInet, roundup(sizeofSockaddrInet)
   128	}
   129	
   130	func (a *Inet4Addr) marshal(b []byte) (int, error) {
   131		l, ll := a.lenAndSpace()
   132		if len(b) < ll {
   133			return 0, errShortBuffer
   134		}
   135		b[0] = byte(l)
   136		b[1] = sysAF_INET
   137		copy(b[4:8], a.IP[:])
   138		return ll, nil
   139	}
   140	
   141	// An Inet6Addr represents an internet address for IPv6.
   142	type Inet6Addr struct {
   143		IP     [16]byte // IP address
   144		ZoneID int      // zone identifier
   145	}
   146	
   147	// Family implements the Family method of Addr interface.
   148	func (a *Inet6Addr) Family() int { return sysAF_INET6 }
   149	
   150	func (a *Inet6Addr) lenAndSpace() (int, int) {
   151		return sizeofSockaddrInet6, roundup(sizeofSockaddrInet6)
   152	}
   153	
   154	func (a *Inet6Addr) marshal(b []byte) (int, error) {
   155		l, ll := a.lenAndSpace()
   156		if len(b) < ll {
   157			return 0, errShortBuffer
   158		}
   159		b[0] = byte(l)
   160		b[1] = sysAF_INET6
   161		copy(b[8:24], a.IP[:])
   162		if a.ZoneID > 0 {
   163			nativeEndian.PutUint32(b[24:28], uint32(a.ZoneID))
   164		}
   165		return ll, nil
   166	}
   167	
   168	// parseInetAddr parses b as an internet address for IPv4 or IPv6.
   169	func parseInetAddr(af int, b []byte) (Addr, error) {
   170		switch af {
   171		case sysAF_INET:
   172			if len(b) < sizeofSockaddrInet {
   173				return nil, errInvalidAddr
   174			}
   175			a := &Inet4Addr{}
   176			copy(a.IP[:], b[4:8])
   177			return a, nil
   178		case sysAF_INET6:
   179			if len(b) < sizeofSockaddrInet6 {
   180				return nil, errInvalidAddr
   181			}
   182			a := &Inet6Addr{ZoneID: int(nativeEndian.Uint32(b[24:28]))}
   183			copy(a.IP[:], b[8:24])
   184			if a.IP[0] == 0xfe && a.IP[1]&0xc0 == 0x80 || a.IP[0] == 0xff && (a.IP[1]&0x0f == 0x01 || a.IP[1]&0x0f == 0x02) {
   185				// KAME based IPv6 protocol stack usually
   186				// embeds the interface index in the
   187				// interface-local or link-local address as
   188				// the kernel-internal form.
   189				id := int(bigEndian.Uint16(a.IP[2:4]))
   190				if id != 0 {
   191					a.ZoneID = id
   192					a.IP[2], a.IP[3] = 0, 0
   193				}
   194			}
   195			return a, nil
   196		default:
   197			return nil, errInvalidAddr
   198		}
   199	}
   200	
   201	// parseKernelInetAddr parses b as an internet address in conventional
   202	// BSD kernel form.
   203	func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
   204		// The encoding looks similar to the NLRI encoding.
   205		// +----------------------------+
   206		// | Length           (1 octet) |
   207		// +----------------------------+
   208		// | Address prefix  (variable) |
   209		// +----------------------------+
   210		//
   211		// The differences between the kernel form and the NLRI
   212		// encoding are:
   213		//
   214		// - The length field of the kernel form indicates the prefix
   215		//   length in bytes, not in bits
   216		//
   217		// - In the kernel form, zero value of the length field
   218		//   doesn't mean 0.0.0.0/0 or ::/0
   219		//
   220		// - The kernel form appends leading bytes to the prefix field
   221		//   to make the <length, prefix> tuple to be conformed with
   222		//   the routing message boundary
   223		l := int(b[0])
   224		if runtime.GOOS == "darwin" {
   225			// On Darwn, an address in the kernel form is also
   226			// used as a message filler.
   227			if l == 0 || len(b) > roundup(l) {
   228				l = roundup(l)
   229			}
   230		} else {
   231			l = roundup(l)
   232		}
   233		if len(b) < l {
   234			return 0, nil, errInvalidAddr
   235		}
   236		// Don't reorder case expressions.
   237		// The case expressions for IPv6 must come first.
   238		const (
   239			off4 = 4 // offset of in_addr
   240			off6 = 8 // offset of in6_addr
   241		)
   242		switch {
   243		case b[0] == sizeofSockaddrInet6:
   244			a := &Inet6Addr{}
   245			copy(a.IP[:], b[off6:off6+16])
   246			return int(b[0]), a, nil
   247		case af == sysAF_INET6:
   248			a := &Inet6Addr{}
   249			if l-1 < off6 {
   250				copy(a.IP[:], b[1:l])
   251			} else {
   252				copy(a.IP[:], b[l-off6:l])
   253			}
   254			return int(b[0]), a, nil
   255		case b[0] == sizeofSockaddrInet:
   256			a := &Inet4Addr{}
   257			copy(a.IP[:], b[off4:off4+4])
   258			return int(b[0]), a, nil
   259		default: // an old fashion, AF_UNSPEC or unknown means AF_INET
   260			a := &Inet4Addr{}
   261			if l-1 < off4 {
   262				copy(a.IP[:], b[1:l])
   263			} else {
   264				copy(a.IP[:], b[l-off4:l])
   265			}
   266			return int(b[0]), a, nil
   267		}
   268	}
   269	
   270	// A DefaultAddr represents an address of various operating
   271	// system-specific features.
   272	type DefaultAddr struct {
   273		af  int
   274		Raw []byte // raw format of address
   275	}
   276	
   277	// Family implements the Family method of Addr interface.
   278	func (a *DefaultAddr) Family() int { return a.af }
   279	
   280	func (a *DefaultAddr) lenAndSpace() (int, int) {
   281		l := len(a.Raw)
   282		return l, roundup(l)
   283	}
   284	
   285	func (a *DefaultAddr) marshal(b []byte) (int, error) {
   286		l, ll := a.lenAndSpace()
   287		if len(b) < ll {
   288			return 0, errShortBuffer
   289		}
   290		if l > 255 {
   291			return 0, errInvalidAddr
   292		}
   293		b[1] = byte(l)
   294		copy(b[:l], a.Raw)
   295		return ll, nil
   296	}
   297	
   298	func parseDefaultAddr(b []byte) (Addr, error) {
   299		if len(b) < 2 || len(b) < int(b[0]) {
   300			return nil, errInvalidAddr
   301		}
   302		a := &DefaultAddr{af: int(b[1]), Raw: b[:b[0]]}
   303		return a, nil
   304	}
   305	
   306	func addrsSpace(as []Addr) int {
   307		var l int
   308		for _, a := range as {
   309			switch a := a.(type) {
   310			case *LinkAddr:
   311				_, ll := a.lenAndSpace()
   312				l += ll
   313			case *Inet4Addr:
   314				_, ll := a.lenAndSpace()
   315				l += ll
   316			case *Inet6Addr:
   317				_, ll := a.lenAndSpace()
   318				l += ll
   319			case *DefaultAddr:
   320				_, ll := a.lenAndSpace()
   321				l += ll
   322			}
   323		}
   324		return l
   325	}
   326	
   327	// marshalAddrs marshals as and returns a bitmap indicating which
   328	// address is stored in b.
   329	func marshalAddrs(b []byte, as []Addr) (uint, error) {
   330		var attrs uint
   331		for i, a := range as {
   332			switch a := a.(type) {
   333			case *LinkAddr:
   334				l, err := a.marshal(b)
   335				if err != nil {
   336					return 0, err
   337				}
   338				b = b[l:]
   339				attrs |= 1 << uint(i)
   340			case *Inet4Addr:
   341				l, err := a.marshal(b)
   342				if err != nil {
   343					return 0, err
   344				}
   345				b = b[l:]
   346				attrs |= 1 << uint(i)
   347			case *Inet6Addr:
   348				l, err := a.marshal(b)
   349				if err != nil {
   350					return 0, err
   351				}
   352				b = b[l:]
   353				attrs |= 1 << uint(i)
   354			case *DefaultAddr:
   355				l, err := a.marshal(b)
   356				if err != nil {
   357					return 0, err
   358				}
   359				b = b[l:]
   360				attrs |= 1 << uint(i)
   361			}
   362		}
   363		return attrs, nil
   364	}
   365	
   366	func parseAddrs(attrs uint, fn func(int, []byte) (int, Addr, error), b []byte) ([]Addr, error) {
   367		var as [sysRTAX_MAX]Addr
   368		af := int(sysAF_UNSPEC)
   369		for i := uint(0); i < sysRTAX_MAX && len(b) >= roundup(0); i++ {
   370			if attrs&(1<<i) == 0 {
   371				continue
   372			}
   373			if i <= sysRTAX_BRD {
   374				switch b[1] {
   375				case sysAF_LINK:
   376					a, err := parseLinkAddr(b)
   377					if err != nil {
   378						return nil, err
   379					}
   380					as[i] = a
   381					l := roundup(int(b[0]))
   382					if len(b) < l {
   383						return nil, errMessageTooShort
   384					}
   385					b = b[l:]
   386				case sysAF_INET, sysAF_INET6:
   387					af = int(b[1])
   388					a, err := parseInetAddr(af, b)
   389					if err != nil {
   390						return nil, err
   391					}
   392					as[i] = a
   393					l := roundup(int(b[0]))
   394					if len(b) < l {
   395						return nil, errMessageTooShort
   396					}
   397					b = b[l:]
   398				default:
   399					l, a, err := fn(af, b)
   400					if err != nil {
   401						return nil, err
   402					}
   403					as[i] = a
   404					ll := roundup(l)
   405					if len(b) < ll {
   406						b = b[l:]
   407					} else {
   408						b = b[ll:]
   409					}
   410				}
   411			} else {
   412				a, err := parseDefaultAddr(b)
   413				if err != nil {
   414					return nil, err
   415				}
   416				as[i] = a
   417				l := roundup(int(b[0]))
   418				if len(b) < l {
   419					return nil, errMessageTooShort
   420				}
   421				b = b[l:]
   422			}
   423		}
   424		return as[:], nil
   425	}
   426	

View as plain text