diff options
Diffstat (limited to 'src/pkg/syscall/netlink_linux.go')
-rw-r--r-- | src/pkg/syscall/netlink_linux.go | 227 |
1 files changed, 0 insertions, 227 deletions
diff --git a/src/pkg/syscall/netlink_linux.go b/src/pkg/syscall/netlink_linux.go deleted file mode 100644 index 681027ab9..000000000 --- a/src/pkg/syscall/netlink_linux.go +++ /dev/null @@ -1,227 +0,0 @@ -// 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 syscall - -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 the 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) - b[0] = byte(rr.Header.Len) - b[1] = byte(rr.Header.Len >> 8) - b[2] = byte(rr.Header.Len >> 16) - b[3] = byte(rr.Header.Len >> 24) - b[4] = byte(rr.Header.Type) - b[5] = byte(rr.Header.Type >> 8) - b[6] = byte(rr.Header.Flags) - b[7] = byte(rr.Header.Flags >> 8) - b[8] = byte(rr.Header.Seq) - b[9] = byte(rr.Header.Seq >> 8) - b[10] = byte(rr.Header.Seq >> 16) - b[11] = byte(rr.Header.Seq >> 24) - b[12] = byte(rr.Header.Pid) - b[13] = byte(rr.Header.Pid >> 8) - b[14] = byte(rr.Header.Pid >> 16) - b[15] = byte(rr.Header.Pid >> 24) - b[16] = byte(rr.Data.Family) - return b -} - -func newNetlinkRouteRequest(proto, seq, family int) []byte { - rr := &NetlinkRouteRequest{} - rr.Header.Len = 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, int) { - var ( - s int - e int - lsanl SockaddrNetlink - seq int - tab []byte - ) - - s, e = Socket(AF_NETLINK, SOCK_RAW, 0) - if e != 0 { - return nil, e - } - defer Close(s) - - lsanl.Family = AF_NETLINK - e = Bind(s, &lsanl) - if e != 0 { - return nil, e - } - - seq++ - wb := newNetlinkRouteRequest(proto, seq, family) - e = Sendto(s, wb, 0, &lsanl) - if e != 0 { - return nil, e - } - - for { - var ( - rb []byte - nr int - lsa Sockaddr - ) - - rb = make([]byte, Getpagesize()) - nr, _, e = Recvfrom(s, rb, 0) - if e != 0 { - return nil, e - } - if nr < NLMSG_HDRLEN { - return nil, EINVAL - } - rb = rb[:nr] - tab = append(tab, rb...) - - msgs, _ := ParseNetlinkMessage(rb) - for _, m := range msgs { - if lsa, e = Getsockname(s); e != 0 { - return nil, e - } - switch v := lsa.(type) { - case *SockaddrNetlink: - if m.Header.Seq != uint32(seq) || m.Header.Pid != v.Pid { - return nil, EINVAL - } - default: - return nil, EINVAL - } - if m.Header.Type == NLMSG_DONE { - goto done - } - if m.Header.Type == NLMSG_ERROR { - return nil, EINVAL - } - } - } - -done: - return tab, 0 -} - -// NetlinkMessage represents the netlink message. -type NetlinkMessage struct { - Header NlMsghdr - Data []byte -} - -// ParseNetlinkMessage parses buf as netlink messages and returns -// the slice containing the NetlinkMessage structs. -func ParseNetlinkMessage(buf []byte) ([]NetlinkMessage, int) { - var ( - h *NlMsghdr - dbuf []byte - dlen int - e int - msgs []NetlinkMessage - ) - - for len(buf) >= NLMSG_HDRLEN { - h, dbuf, dlen, e = netlinkMessageHeaderAndData(buf) - if e != 0 { - break - } - m := NetlinkMessage{} - m.Header = *h - m.Data = dbuf[:h.Len-NLMSG_HDRLEN] - msgs = append(msgs, m) - buf = buf[dlen:] - } - - return msgs, e -} - -func netlinkMessageHeaderAndData(buf []byte) (*NlMsghdr, []byte, int, int) { - h := (*NlMsghdr)(unsafe.Pointer(&buf[0])) - if h.Len < NLMSG_HDRLEN || int(h.Len) > len(buf) { - return nil, nil, 0, EINVAL - } - return h, buf[NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), 0 -} - -// NetlinkRouteAttr represents the netlink route attribute. -type NetlinkRouteAttr struct { - Attr RtAttr - Value []byte -} - -// ParseNetlinkRouteAttr parses msg's payload as netlink route -// attributes and returns the slice containing the NetlinkRouteAttr -// structs. -func ParseNetlinkRouteAttr(msg *NetlinkMessage) ([]NetlinkRouteAttr, int) { - var ( - buf []byte - a *RtAttr - alen int - vbuf []byte - e int - attrs []NetlinkRouteAttr - ) - - switch msg.Header.Type { - case RTM_NEWLINK: - buf = msg.Data[SizeofIfInfomsg:] - case RTM_NEWADDR: - buf = msg.Data[SizeofIfAddrmsg:] - default: - return nil, EINVAL - } - - for len(buf) >= SizeofRtAttr { - a, vbuf, alen, e = netlinkRouteAttrAndValue(buf) - if e != 0 { - break - } - ra := NetlinkRouteAttr{} - ra.Attr = *a - ra.Value = vbuf[:a.Len-SizeofRtAttr] - attrs = append(attrs, ra) - buf = buf[alen:] - } - - return attrs, 0 -} - -func netlinkRouteAttrAndValue(buf []byte) (*RtAttr, []byte, int, int) { - h := (*RtAttr)(unsafe.Pointer(&buf[0])) - if h.Len < SizeofRtAttr || int(h.Len) > len(buf) { - return nil, nil, 0, EINVAL - } - return h, buf[SizeofRtAttr:], rtaAlignOf(int(h.Len)), 0 -} |