...

Source file src/pkg/vendor/golang.org/x/net/lif/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 solaris
     6	
     7	package lif
     8	
     9	import (
    10		"errors"
    11		"unsafe"
    12	)
    13	
    14	// An Addr represents an address associated with packet routing.
    15	type Addr interface {
    16		// Family returns an address family.
    17		Family() int
    18	}
    19	
    20	// An Inet4Addr represents an internet address for IPv4.
    21	type Inet4Addr struct {
    22		IP        [4]byte // IP address
    23		PrefixLen int     // address prefix length
    24	}
    25	
    26	// Family implements the Family method of Addr interface.
    27	func (a *Inet4Addr) Family() int { return sysAF_INET }
    28	
    29	// An Inet6Addr represents an internet address for IPv6.
    30	type Inet6Addr struct {
    31		IP        [16]byte // IP address
    32		PrefixLen int      // address prefix length
    33		ZoneID    int      // zone identifier
    34	}
    35	
    36	// Family implements the Family method of Addr interface.
    37	func (a *Inet6Addr) Family() int { return sysAF_INET6 }
    38	
    39	// Addrs returns a list of interface addresses.
    40	//
    41	// The provided af must be an address family and name must be a data
    42	// link name. The zero value of af or name means a wildcard.
    43	func Addrs(af int, name string) ([]Addr, error) {
    44		eps, err := newEndpoints(af)
    45		if len(eps) == 0 {
    46			return nil, err
    47		}
    48		defer func() {
    49			for _, ep := range eps {
    50				ep.close()
    51			}
    52		}()
    53		lls, err := links(eps, name)
    54		if len(lls) == 0 {
    55			return nil, err
    56		}
    57		var as []Addr
    58		for _, ll := range lls {
    59			var lifr lifreq
    60			for i := 0; i < len(ll.Name); i++ {
    61				lifr.Name[i] = int8(ll.Name[i])
    62			}
    63			for _, ep := range eps {
    64				ioc := int64(sysSIOCGLIFADDR)
    65				err := ioctl(ep.s, uintptr(ioc), unsafe.Pointer(&lifr))
    66				if err != nil {
    67					continue
    68				}
    69				sa := (*sockaddrStorage)(unsafe.Pointer(&lifr.Lifru[0]))
    70				l := int(nativeEndian.Uint32(lifr.Lifru1[:4]))
    71				if l == 0 {
    72					continue
    73				}
    74				switch sa.Family {
    75				case sysAF_INET:
    76					a := &Inet4Addr{PrefixLen: l}
    77					copy(a.IP[:], lifr.Lifru[4:8])
    78					as = append(as, a)
    79				case sysAF_INET6:
    80					a := &Inet6Addr{PrefixLen: l, ZoneID: int(nativeEndian.Uint32(lifr.Lifru[24:28]))}
    81					copy(a.IP[:], lifr.Lifru[8:24])
    82					as = append(as, a)
    83				}
    84			}
    85		}
    86		return as, nil
    87	}
    88	
    89	func parseLinkAddr(b []byte) ([]byte, error) {
    90		nlen, alen, slen := int(b[1]), int(b[2]), int(b[3])
    91		l := 4 + nlen + alen + slen
    92		if len(b) < l {
    93			return nil, errors.New("invalid address")
    94		}
    95		b = b[4:]
    96		var addr []byte
    97		if nlen > 0 {
    98			b = b[nlen:]
    99		}
   100		if alen > 0 {
   101			addr = make([]byte, alen)
   102			copy(addr, b[:alen])
   103		}
   104		return addr, nil
   105	}
   106	

View as plain text