Source file src/internal/routebsd/interface_classic.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  //go:build darwin || dragonfly || netbsd
     6  
     7  package routebsd
     8  
     9  import (
    10  	"runtime"
    11  	"syscall"
    12  )
    13  
    14  func (w *wireFormat) parseInterfaceMessage(b []byte) (Message, error) {
    15  	if len(b) < w.bodyOff {
    16  		return nil, errMessageTooShort
    17  	}
    18  	l := int(nativeEndian.Uint16(b[:2]))
    19  	if len(b) < l {
    20  		return nil, errInvalidMessage
    21  	}
    22  	attrs := uint(nativeEndian.Uint32(b[4:8]))
    23  
    24  	m := &InterfaceMessage{
    25  		Version: int(b[2]),
    26  		Type:    int(b[3]),
    27  		Addrs:   make([]Addr, syscall.RTAX_MAX),
    28  		Flags:   int(nativeEndian.Uint32(b[8:12])),
    29  		Index:   int(nativeEndian.Uint16(b[12:14])),
    30  		extOff:  w.extOff,
    31  		raw:     b[:l],
    32  	}
    33  
    34  	// We used to require that RTA_IFP always be set.
    35  	// It turns out that on darwin messages about the
    36  	// utun interface may not include a name. Issue #71064.
    37  	if attrs&syscall.RTA_IFP != 0 {
    38  		a, err := parseLinkAddr(b[w.bodyOff:])
    39  		if err != nil {
    40  			return nil, err
    41  		}
    42  		m.Addrs[syscall.RTAX_IFP] = a
    43  		m.Name = a.(*LinkAddr).Name
    44  	} else {
    45  		// DragonFly seems to have unnamed interfaces
    46  		// that we can't look up again. Just skip them.
    47  		if runtime.GOOS == "dragonfly" {
    48  			return nil, nil
    49  		}
    50  	}
    51  
    52  	return m, nil
    53  }
    54  
    55  func (w *wireFormat) parseInterfaceAddrMessage(b []byte) (Message, error) {
    56  	if len(b) < w.bodyOff {
    57  		return nil, errMessageTooShort
    58  	}
    59  	l := int(nativeEndian.Uint16(b[:2]))
    60  	if len(b) < l {
    61  		return nil, errInvalidMessage
    62  	}
    63  	m := &InterfaceAddrMessage{
    64  		Version: int(b[2]),
    65  		Type:    int(b[3]),
    66  		Flags:   int(nativeEndian.Uint32(b[8:12])),
    67  		raw:     b[:l],
    68  	}
    69  	if runtime.GOOS == "netbsd" {
    70  		m.Index = int(nativeEndian.Uint16(b[16:18]))
    71  	} else {
    72  		m.Index = int(nativeEndian.Uint16(b[12:14]))
    73  	}
    74  	var err error
    75  	m.Addrs, err = parseAddrs(uint(nativeEndian.Uint32(b[4:8])), b[w.bodyOff:])
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  	return m, nil
    80  }
    81  

View as plain text