mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-15 01:53:51 -06:00
The original contents of `vendor` were inadvertently captured with an older version of `godep`. Here, we recapture dependencies by running the following: ``` godep restore -v cat Godeps/Godeps.json | jq -r '.Deps[].ImportPath' | xargs godep update -v ``` The newer godep makes the following changes as it captures dependencies: * Skips test files * Copies `LICENSE` / `PATENTS` files There is also an additional diff in `golang.org/x/sys/unix` that looks very similar to the diff between `master..c65f27f` in that repo, so I'm guessing that dependency was accidentally captured from master instead of the commit saved to `Godeps.json`. All in all, these changes should all be "more correct" and result in smaller diffs for any future updates made to dependencies.
179 lines
4.7 KiB
Go
179 lines
4.7 KiB
Go
// Copyright 2011 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Netlink sockets and messages
|
|
|
|
package unix
|
|
|
|
import "unsafe"
|
|
|
|
// Round the length of a netlink message up to align it properly.
|
|
func nlmAlignOf(msglen int) int {
|
|
return (msglen + NLMSG_ALIGNTO - 1) & ^(NLMSG_ALIGNTO - 1)
|
|
}
|
|
|
|
// Round the length of a netlink route attribute up to align it
|
|
// properly.
|
|
func rtaAlignOf(attrlen int) int {
|
|
return (attrlen + RTA_ALIGNTO - 1) & ^(RTA_ALIGNTO - 1)
|
|
}
|
|
|
|
// NetlinkRouteRequest represents a request message to receive routing
|
|
// and link states from the kernel.
|
|
type NetlinkRouteRequest struct {
|
|
Header NlMsghdr
|
|
Data RtGenmsg
|
|
}
|
|
|
|
func (rr *NetlinkRouteRequest) toWireFormat() []byte {
|
|
b := make([]byte, rr.Header.Len)
|
|
*(*uint32)(unsafe.Pointer(&b[0:4][0])) = rr.Header.Len
|
|
*(*uint16)(unsafe.Pointer(&b[4:6][0])) = rr.Header.Type
|
|
*(*uint16)(unsafe.Pointer(&b[6:8][0])) = rr.Header.Flags
|
|
*(*uint32)(unsafe.Pointer(&b[8:12][0])) = rr.Header.Seq
|
|
*(*uint32)(unsafe.Pointer(&b[12:16][0])) = rr.Header.Pid
|
|
b[16] = byte(rr.Data.Family)
|
|
return b
|
|
}
|
|
|
|
func newNetlinkRouteRequest(proto, seq, family int) []byte {
|
|
rr := &NetlinkRouteRequest{}
|
|
rr.Header.Len = uint32(NLMSG_HDRLEN + SizeofRtGenmsg)
|
|
rr.Header.Type = uint16(proto)
|
|
rr.Header.Flags = NLM_F_DUMP | NLM_F_REQUEST
|
|
rr.Header.Seq = uint32(seq)
|
|
rr.Data.Family = uint8(family)
|
|
return rr.toWireFormat()
|
|
}
|
|
|
|
// NetlinkRIB returns routing information base, as known as RIB, which
|
|
// consists of network facility information, states and parameters.
|
|
func NetlinkRIB(proto, family int) ([]byte, error) {
|
|
s, err := Socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer Close(s)
|
|
lsa := &SockaddrNetlink{Family: AF_NETLINK}
|
|
if err := Bind(s, lsa); err != nil {
|
|
return nil, err
|
|
}
|
|
wb := newNetlinkRouteRequest(proto, 1, family)
|
|
if err := Sendto(s, wb, 0, lsa); err != nil {
|
|
return nil, err
|
|
}
|
|
var tab []byte
|
|
rbNew := make([]byte, Getpagesize())
|
|
done:
|
|
for {
|
|
rb := rbNew
|
|
nr, _, err := Recvfrom(s, rb, 0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if nr < NLMSG_HDRLEN {
|
|
return nil, EINVAL
|
|
}
|
|
rb = rb[:nr]
|
|
tab = append(tab, rb...)
|
|
msgs, err := ParseNetlinkMessage(rb)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, m := range msgs {
|
|
lsa, err := Getsockname(s)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
switch v := lsa.(type) {
|
|
case *SockaddrNetlink:
|
|
if m.Header.Seq != 1 || m.Header.Pid != v.Pid {
|
|
return nil, EINVAL
|
|
}
|
|
default:
|
|
return nil, EINVAL
|
|
}
|
|
if m.Header.Type == NLMSG_DONE {
|
|
break done
|
|
}
|
|
if m.Header.Type == NLMSG_ERROR {
|
|
return nil, EINVAL
|
|
}
|
|
}
|
|
}
|
|
return tab, nil
|
|
}
|
|
|
|
// NetlinkMessage represents a netlink message.
|
|
type NetlinkMessage struct {
|
|
Header NlMsghdr
|
|
Data []byte
|
|
}
|
|
|
|
// ParseNetlinkMessage parses b as an array of netlink messages and
|
|
// returns the slice containing the NetlinkMessage structures.
|
|
func ParseNetlinkMessage(b []byte) ([]NetlinkMessage, error) {
|
|
var msgs []NetlinkMessage
|
|
for len(b) >= NLMSG_HDRLEN {
|
|
h, dbuf, dlen, err := netlinkMessageHeaderAndData(b)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
m := NetlinkMessage{Header: *h, Data: dbuf[:int(h.Len)-NLMSG_HDRLEN]}
|
|
msgs = append(msgs, m)
|
|
b = b[dlen:]
|
|
}
|
|
return msgs, nil
|
|
}
|
|
|
|
func netlinkMessageHeaderAndData(b []byte) (*NlMsghdr, []byte, int, error) {
|
|
h := (*NlMsghdr)(unsafe.Pointer(&b[0]))
|
|
if int(h.Len) < NLMSG_HDRLEN || int(h.Len) > len(b) {
|
|
return nil, nil, 0, EINVAL
|
|
}
|
|
return h, b[NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), nil
|
|
}
|
|
|
|
// NetlinkRouteAttr represents a netlink route attribute.
|
|
type NetlinkRouteAttr struct {
|
|
Attr RtAttr
|
|
Value []byte
|
|
}
|
|
|
|
// ParseNetlinkRouteAttr parses m's payload as an array of netlink
|
|
// route attributes and returns the slice containing the
|
|
// NetlinkRouteAttr structures.
|
|
func ParseNetlinkRouteAttr(m *NetlinkMessage) ([]NetlinkRouteAttr, error) {
|
|
var b []byte
|
|
switch m.Header.Type {
|
|
case RTM_NEWLINK, RTM_DELLINK:
|
|
b = m.Data[SizeofIfInfomsg:]
|
|
case RTM_NEWADDR, RTM_DELADDR:
|
|
b = m.Data[SizeofIfAddrmsg:]
|
|
case RTM_NEWROUTE, RTM_DELROUTE:
|
|
b = m.Data[SizeofRtMsg:]
|
|
default:
|
|
return nil, EINVAL
|
|
}
|
|
var attrs []NetlinkRouteAttr
|
|
for len(b) >= SizeofRtAttr {
|
|
a, vbuf, alen, err := netlinkRouteAttrAndValue(b)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ra := NetlinkRouteAttr{Attr: *a, Value: vbuf[:int(a.Len)-SizeofRtAttr]}
|
|
attrs = append(attrs, ra)
|
|
b = b[alen:]
|
|
}
|
|
return attrs, nil
|
|
}
|
|
|
|
func netlinkRouteAttrAndValue(b []byte) (*RtAttr, []byte, int, error) {
|
|
a := (*RtAttr)(unsafe.Pointer(&b[0]))
|
|
if int(a.Len) < SizeofRtAttr || int(a.Len) > len(b) {
|
|
return nil, nil, 0, EINVAL
|
|
}
|
|
return a, b[SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil
|
|
}
|