github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/net/route/route_classic.go (about)

     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 || freebsd || netbsd
     6  // +build darwin dragonfly freebsd netbsd
     7  
     8  package route
     9  
    10  import (
    11  	"runtime"
    12  	"syscall"
    13  )
    14  
    15  func (m *RouteMessage) marshal() ([]byte, error) {
    16  	w, ok := wireFormats[m.Type]
    17  	if !ok {
    18  		return nil, errUnsupportedMessage
    19  	}
    20  	l := w.bodyOff + addrsSpace(m.Addrs)
    21  	if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
    22  		// Fix stray pointer writes on macOS.
    23  		// See golang.org/issue/22456.
    24  		l += 1024
    25  	}
    26  	b := make([]byte, l)
    27  	nativeEndian.PutUint16(b[:2], uint16(l))
    28  	if m.Version == 0 {
    29  		b[2] = rtmVersion
    30  	} else {
    31  		b[2] = byte(m.Version)
    32  	}
    33  	b[3] = byte(m.Type)
    34  	nativeEndian.PutUint32(b[8:12], uint32(m.Flags))
    35  	nativeEndian.PutUint16(b[4:6], uint16(m.Index))
    36  	nativeEndian.PutUint32(b[16:20], uint32(m.ID))
    37  	nativeEndian.PutUint32(b[20:24], uint32(m.Seq))
    38  	attrs, err := marshalAddrs(b[w.bodyOff:], m.Addrs)
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  	if attrs > 0 {
    43  		nativeEndian.PutUint32(b[12:16], uint32(attrs))
    44  	}
    45  	return b, nil
    46  }
    47  
    48  func (w *wireFormat) parseRouteMessage(typ RIBType, b []byte) (Message, error) {
    49  	if len(b) < w.bodyOff {
    50  		return nil, errMessageTooShort
    51  	}
    52  	l := int(nativeEndian.Uint16(b[:2]))
    53  	if len(b) < l {
    54  		return nil, errInvalidMessage
    55  	}
    56  	m := &RouteMessage{
    57  		Version: int(b[2]),
    58  		Type:    int(b[3]),
    59  		Flags:   int(nativeEndian.Uint32(b[8:12])),
    60  		Index:   int(nativeEndian.Uint16(b[4:6])),
    61  		ID:      uintptr(nativeEndian.Uint32(b[16:20])),
    62  		Seq:     int(nativeEndian.Uint32(b[20:24])),
    63  		extOff:  w.extOff,
    64  		raw:     b[:l],
    65  	}
    66  	errno := syscall.Errno(nativeEndian.Uint32(b[28:32]))
    67  	if errno != 0 {
    68  		m.Err = errno
    69  	}
    70  	var err error
    71  	m.Addrs, err = parseAddrs(uint(nativeEndian.Uint32(b[12:16])), parseKernelInetAddr, b[w.bodyOff:])
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  	return m, nil
    76  }