"Fossies" - the Fresh Open Source Software Archive

Member "go/src/vendor/golang.org/x/net/route/address.go" (9 Sep 2020, 9770 Bytes) of package /windows/misc/go1.14.9.windows-386.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "address.go": 1.14.7_vs_1.15.

    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 Darwin, 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 }