From 5420692a392219a344fa5aa80acfac4b55c0a2aa Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Sun, 5 Aug 2018 09:50:13 +0000 Subject: [PATCH] Vendor github.com/typetypetype/conntrack --- .../github.com/typetypetype/conntrack/LICENSE | 22 + .../typetypetype/conntrack/cli/main.go | 33 ++ .../typetypetype/conntrack/client.go | 461 ++++++++++++++++++ .../typetypetype/conntrack/conntrack.go | 145 ++++++ .../typetypetype/conntrack/const.go | 69 +++ .../typetypetype/conntrack/headers.go | 131 +++++ .../typetypetype/conntrack/linux_headers.go | 16 + .../github.com/typetypetype/conntrack/net.go | 19 + .../typetypetype/conntrack/netlink.go | 21 + .../typetypetype/conntrack/netlink_attr.go | 45 ++ vendor/manifest | 8 + 11 files changed, 970 insertions(+) create mode 100644 vendor/github.com/typetypetype/conntrack/LICENSE create mode 100644 vendor/github.com/typetypetype/conntrack/cli/main.go create mode 100644 vendor/github.com/typetypetype/conntrack/client.go create mode 100644 vendor/github.com/typetypetype/conntrack/conntrack.go create mode 100644 vendor/github.com/typetypetype/conntrack/const.go create mode 100644 vendor/github.com/typetypetype/conntrack/headers.go create mode 100644 vendor/github.com/typetypetype/conntrack/linux_headers.go create mode 100644 vendor/github.com/typetypetype/conntrack/net.go create mode 100644 vendor/github.com/typetypetype/conntrack/netlink.go create mode 100644 vendor/github.com/typetypetype/conntrack/netlink_attr.go diff --git a/vendor/github.com/typetypetype/conntrack/LICENSE b/vendor/github.com/typetypetype/conntrack/LICENSE new file mode 100644 index 000000000..4eb197f17 --- /dev/null +++ b/vendor/github.com/typetypetype/conntrack/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 typetypetype + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/typetypetype/conntrack/cli/main.go b/vendor/github.com/typetypetype/conntrack/cli/main.go new file mode 100644 index 000000000..e87687ef4 --- /dev/null +++ b/vendor/github.com/typetypetype/conntrack/cli/main.go @@ -0,0 +1,33 @@ +package main + +// Example usage + +import ( + "fmt" + "time" + + "github.com/typetypetype/conntrack" +) + +func main() { + cs, err := conntrack.Established() + if err != nil { + panic(fmt.Sprintf("Established: %s", err)) + } + fmt.Printf("Established on start:\n") + for _, cn := range cs { + fmt.Printf(" - %s\n", cn) + } + fmt.Println("") + + c, err := conntrack.New() + if err != nil { + panic(err) + } + for range time.Tick(1 * time.Second) { + fmt.Printf("Connections:\n") + for _, cn := range c.Connections() { + fmt.Printf(" - %s\n", cn) + } + } +} diff --git a/vendor/github.com/typetypetype/conntrack/client.go b/vendor/github.com/typetypetype/conntrack/client.go new file mode 100644 index 000000000..050d1f4cc --- /dev/null +++ b/vendor/github.com/typetypetype/conntrack/client.go @@ -0,0 +1,461 @@ +package conntrack + +import ( + "encoding/binary" + "errors" + "fmt" + "net" + "strconv" + "syscall" + "unsafe" + + "golang.org/x/sys/unix" +) + +const ( + sizeofGenmsg = uint32(unsafe.Sizeof(unix.Nfgenmsg{})) // TODO +) + +type ConntrackListReq struct { + Header syscall.NlMsghdr + Body unix.Nfgenmsg +} + +func (c *ConntrackListReq) toWireFormat() []byte { + // adapted from syscall/NetlinkRouteRequest.toWireFormat + b := make([]byte, c.Header.Len) + *(*uint32)(unsafe.Pointer(&b[0:4][0])) = c.Header.Len + *(*uint16)(unsafe.Pointer(&b[4:6][0])) = c.Header.Type + *(*uint16)(unsafe.Pointer(&b[6:8][0])) = c.Header.Flags + *(*uint32)(unsafe.Pointer(&b[8:12][0])) = c.Header.Seq + *(*uint32)(unsafe.Pointer(&b[12:16][0])) = c.Header.Pid + b[16] = byte(c.Body.Nfgen_family) + b[17] = byte(c.Body.Version) + *(*uint16)(unsafe.Pointer(&b[18:20][0])) = c.Body.Res_id + return b +} + +func connectNetfilter(bufferSize int, groups uint32) (int, *syscall.SockaddrNetlink, error) { + s, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_NETFILTER) + if err != nil { + return 0, nil, err + } + lsa := &syscall.SockaddrNetlink{ + Family: syscall.AF_NETLINK, + Groups: groups, + } + if err := syscall.Bind(s, lsa); err != nil { + return 0, nil, err + } + if bufferSize > 0 { + // Speculatively try SO_RCVBUFFORCE which needs CAP_NET_ADMIN + if err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_RCVBUFFORCE, bufferSize); err != nil { + // and if that doesn't work fall back to the ordinary SO_RCVBUF + if err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_RCVBUF, bufferSize); err != nil { + return 0, nil, err + } + } + } + + return s, lsa, nil +} + +// Make syscall asking for all connections. Invoke 'cb' for each connection. +func queryAllConnections(bufferSize int, cb func(Conn)) error { + s, lsa, err := connectNetfilter(bufferSize, 0) + if err != nil { + return err + } + defer syscall.Close(s) + + msg := ConntrackListReq{ + Header: syscall.NlMsghdr{ + Len: syscall.NLMSG_HDRLEN + sizeofGenmsg, + Type: (NFNL_SUBSYS_CTNETLINK << 8) | uint16(IpctnlMsgCtGet), + Flags: syscall.NLM_F_REQUEST | syscall.NLM_F_DUMP, + Pid: 0, + Seq: 0, + }, + Body: unix.Nfgenmsg{ + Nfgen_family: syscall.AF_INET, + Version: NFNETLINK_V0, + Res_id: 0, + }, + } + wb := msg.toWireFormat() + // fmt.Printf("msg bytes: %q\n", wb) + if err := syscall.Sendto(s, wb, 0, lsa); err != nil { + return err + } + + return readMsgs(s, cb) +} + +// Stream all connections instead of query for all of them at once. +func StreamAllConnections() chan Conn { + ch := make(chan Conn, 1) + go func() { + queryAllConnections(0, func(c Conn) { + ch <- c + }) + close(ch) + }() + return ch +} + +// Lists all the connections that conntrack is tracking. +func Connections() ([]Conn, error) { + return ConnectionsSize(0) +} + +// Lists all the connections that conntrack is tracking, using specified netlink buffer size. +func ConnectionsSize(bufferSize int) ([]Conn, error) { + var conns []Conn + queryAllConnections(bufferSize, func(c Conn) { + conns = append(conns, c) + }) + return conns, nil +} + +// Established lists all established TCP connections. +func Established() ([]ConnTCP, error) { + var conns []ConnTCP + local := localIPs() + err := queryAllConnections(0, func(c Conn) { + if c.MsgType != NfctMsgUpdate { + fmt.Printf("msg isn't an update: %d\n", c.MsgType) + return + } + if c.TCPState != "ESTABLISHED" { + // fmt.Printf("state isn't ESTABLISHED: %s\n", c.TCPState) + return + } + if tc := c.ConnTCP(local); tc != nil { + conns = append(conns, *tc) + } + }) + if err != nil { + return nil, err + } + return conns, nil +} + +// Follow gives a channel with all changes. +func Follow(flags uint32) (<-chan Conn, func(), error) { + return FollowSize(0, flags) +} + +// Follow gives a channel with all changes, , using specified netlink buffer size. +func FollowSize(bufferSize int, flags uint32) (<-chan Conn, func(), error) { + s, _, err := connectNetfilter(bufferSize, flags) + stop := func() { + syscall.Close(s) + } + if err != nil { + return nil, stop, err + } + + res := make(chan Conn, 1) + go func() { + defer syscall.Close(s) + if err := readMsgs(s, func(c Conn) { + // if conn.TCPState != 3 { + // // 3 is TCP established. + // continue + // } + res <- c + }); err != nil { + panic(err) + } + }() + return res, stop, nil +} + +func readMsgs(s int, cb func(Conn)) error { + rb := make([]byte, 2*syscall.Getpagesize()) +loop: + for { + nr, _, err := syscall.Recvfrom(s, rb, 0) + if err == syscall.ENOBUFS { + // ENOBUF means we miss some events here. No way around it. That's life. + cb(Conn{Err: syscall.ENOBUFS}) + continue + } else if err != nil { + return err + } + + msgs, err := syscall.ParseNetlinkMessage(rb[:nr]) + if err != nil { + return err + } + for _, msg := range msgs { + if msg.Header.Type == unix.NLMSG_ERROR { + return errors.New("NLMSG_ERROR") + } + if msg.Header.Type == unix.NLMSG_DONE { + break loop + } + + if nflnSubsysID(msg.Header.Type) != NFNL_SUBSYS_CTNETLINK { + return fmt.Errorf( + "unexpected subsys_id: %d\n", + nflnSubsysID(msg.Header.Type), + ) + } + conn, err := parsePayload(msg.Data[sizeofGenmsg:]) + if err != nil { + return err + } + + // Taken from conntrack/parse.c:__parse_message_type + switch CntlMsgTypes(nflnMsgType(msg.Header.Type)) { + case IpctnlMsgCtNew: + conn.MsgType = NfctMsgUpdate + if msg.Header.Flags&(syscall.NLM_F_CREATE|syscall.NLM_F_EXCL) > 0 { + conn.MsgType = NfctMsgNew + } + case IpctnlMsgCtDelete: + conn.MsgType = NfctMsgDestroy + } + + cb(*conn) + + if msg.Header.Flags&unix.NLM_F_MULTI > 0 { + break loop + } + } + } + return nil +} + +type Tuple struct { + Proto int + Src net.IP + SrcPort uint16 + Dst net.IP + DstPort uint16 + + // ICMP stuff. + IcmpId uint16 + IcmpType uint8 + IcmpCode uint8 +} + +type Conn struct { + MsgType NfConntrackMsg + TCPState string + Status CtStatus + Orig Tuple + Reply Tuple + + // ct.mark, used to set permission type of the flow. + CtMark uint32 + + // ct.id, used to identify connections. + CtId uint32 + + // For multitenancy. + Zone uint16 + + // Flow stats. + ReplyPktLen uint64 + ReplyPktCount uint64 + OrigPktLen uint64 + OrigPktCount uint64 + + // Error, if any. + Err error +} + +// ConnTCP decides which way this connection is going and makes a ConnTCP. +func (c Conn) ConnTCP(local map[string]struct{}) *ConnTCP { + // conntrack gives us all connections, even things passing through, but it + // doesn't tell us what the local IP is. So we use `local` as a guide + // what's local. + src := c.Orig.Src.String() + dst := c.Orig.Dst.String() + _, srcLocal := local[src] + _, dstLocal := local[dst] + // If both are local we must just order things predictably. + if srcLocal && dstLocal { + srcLocal = c.Orig.SrcPort < c.Orig.DstPort + } + if srcLocal { + return &ConnTCP{ + Local: src, + LocalPort: strconv.Itoa(int(c.Orig.SrcPort)), + Remote: dst, + RemotePort: strconv.Itoa(int(c.Orig.DstPort)), + } + } + if dstLocal { + return &ConnTCP{ + Local: dst, + LocalPort: strconv.Itoa(int(c.Orig.DstPort)), + Remote: src, + RemotePort: strconv.Itoa(int(c.Orig.SrcPort)), + } + } + // Neither is local. conntrack also reports NAT connections. + return nil +} + +func parsePayload(b []byte) (*Conn, error) { + // Most of this comes from libnetfilter_conntrack/src/conntrack/parse_mnl.c + conn := &Conn{} + attrs, err := parseAttrs(b) + if err != nil { + return conn, err + } + for _, attr := range attrs { + switch CtattrType(attr.Typ) { + case CtaTupleOrig: + parseTuple(attr.Msg, &conn.Orig) + case CtaTupleReply: + parseTuple(attr.Msg, &conn.Reply) + case CtaCountersOrig: + conn.OrigPktLen, conn.OrigPktCount, _ = parseCounters(attr.Msg) + case CtaCountersReply: + conn.ReplyPktLen, conn.ReplyPktCount, _ = parseCounters(attr.Msg) + case CtaStatus: + conn.Status = CtStatus(binary.BigEndian.Uint32(attr.Msg)) + case CtaProtoinfo: + parseProtoinfo(attr.Msg, conn) + case CtaMark: + conn.CtMark = binary.BigEndian.Uint32(attr.Msg) + case CtaZone: + conn.Zone = binary.BigEndian.Uint16(attr.Msg) + case CtaId: + conn.CtId = binary.BigEndian.Uint32(attr.Msg) + } + } + return conn, nil +} + +func parseTuple(b []byte, tuple *Tuple) error { + attrs, err := parseAttrs(b) + if err != nil { + return fmt.Errorf("invalid tuple attr: %s", err) + } + for _, attr := range attrs { + // fmt.Printf("pl: %d, type: %d, multi: %t, bigend: %t\n", len(attr.Msg), attr.Typ, attr.IsNested, attr.IsNetByteorder) + switch CtattrTuple(attr.Typ) { + case CtaTupleUnspec: + // fmt.Printf("It's a tuple unspec\n") + case CtaTupleIp: + // fmt.Printf("It's a tuple IP\n") + if err := parseIP(attr.Msg, tuple); err != nil { + return err + } + case CtaTupleProto: + // fmt.Printf("It's a tuple proto\n") + parseProto(attr.Msg, tuple) + } + } + return nil +} + +func parseCounters(b []byte) (uint64, uint64, error) { + attrs, err := parseAttrs(b) + if err != nil { + return 0, 0, fmt.Errorf("invalid tuple attr: %s", err) + } + packets := uint64(0) + bytes := uint64(0) + for _, attr := range attrs { + switch CtattrCounters(attr.Typ) { + case CtaCountersPackets: + packets = binary.BigEndian.Uint64(attr.Msg) + case CtaCountersBytes: + bytes = binary.BigEndian.Uint64(attr.Msg) + } + } + return packets, bytes, nil +} + +func parseIP(b []byte, tuple *Tuple) error { + attrs, err := parseAttrs(b) + if err != nil { + return fmt.Errorf("invalid tuple attr: %s", err) + } + for _, attr := range attrs { + switch CtattrIp(attr.Typ) { + case CtaIpV4Src: + tuple.Src = make(net.IP, len(attr.Msg)) + copy(tuple.Src, attr.Msg) + case CtaIpV4Dst: + tuple.Dst = make(net.IP, len(attr.Msg)) + copy(tuple.Dst, attr.Msg) + case CtaIpV6Src: + // TODO + case CtaIpV6Dst: + // TODO + } + } + return nil +} + +func parseProto(b []byte, tuple *Tuple) error { + attrs, err := parseAttrs(b) + if err != nil { + return fmt.Errorf("invalid tuple attr: %s", err) + } + + for _, attr := range attrs { + switch CtattrL4proto(attr.Typ) { + // Protocol number. + case CtaProtoNum: + tuple.Proto = int(uint8(attr.Msg[0])) + + // TCP stuff. + case CtaProtoSrcPort: + tuple.SrcPort = binary.BigEndian.Uint16(attr.Msg) + case CtaProtoDstPort: + tuple.DstPort = binary.BigEndian.Uint16(attr.Msg) + + // ICMP stuff. + case CtaProtoIcmpId: + tuple.IcmpId = binary.BigEndian.Uint16(attr.Msg) + case CtaProtoIcmpType: + tuple.IcmpType = attr.Msg[0] + case CtaProtoIcmpCode: + tuple.IcmpCode = attr.Msg[0] + } + } + + return nil +} + +func parseProtoinfo(b []byte, conn *Conn) error { + attrs, err := parseAttrs(b) + if err != nil { + return fmt.Errorf("invalid tuple attr: %s", err) + } + for _, attr := range attrs { + switch CtattrProtoinfo(attr.Typ) { + case CtaProtoinfoTcp: + if err := parseProtoinfoTCP(attr.Msg, conn); err != nil { + return err + } + default: + // we're not interested in other protocols + } + } + return nil +} + +func parseProtoinfoTCP(b []byte, conn *Conn) error { + attrs, err := parseAttrs(b) + if err != nil { + return fmt.Errorf("invalid tuple attr: %s", err) + } + for _, attr := range attrs { + switch CtattrProtoinfoTcp(attr.Typ) { + case CtaProtoinfoTcpState: + conn.TCPState = tcpState[uint8(attr.Msg[0])] + default: + // not interested + } + } + return nil +} diff --git a/vendor/github.com/typetypetype/conntrack/conntrack.go b/vendor/github.com/typetypetype/conntrack/conntrack.go new file mode 100644 index 000000000..64cca3452 --- /dev/null +++ b/vendor/github.com/typetypetype/conntrack/conntrack.go @@ -0,0 +1,145 @@ +package conntrack + +import ( + "fmt" + "log" + "time" +) + +// ConnTCP is a connection +type ConnTCP struct { + Local string // net.IP + LocalPort string // int + Remote string // net.IP + RemotePort string // int +} + +func (c ConnTCP) String() string { + return fmt.Sprintf("%s:%s->%s:%s", c.Local, c.LocalPort, c.Remote, c.RemotePort) +} + +// ConnTrack monitors the connections. It is build with Established() and +// Follow(). +type ConnTrack struct { + connReq chan chan []ConnTCP + quit chan struct{} +} + +// New returns a ConnTrack. +func New() (*ConnTrack, error) { + c := ConnTrack{ + connReq: make(chan chan []ConnTCP), + quit: make(chan struct{}), + } + go func() { + for { + err := c.track() + select { + case <-c.quit: + return + default: + } + if err != nil { + log.Printf("conntrack: %s\n", err) + } + time.Sleep(1 * time.Second) + } + }() + + return &c, nil +} + +// Close stops all monitoring and executables. +func (c ConnTrack) Close() { + close(c.quit) +} + +// Connections returns the list of all connections seen since last time you +// called it. +func (c *ConnTrack) Connections() []ConnTCP { + r := make(chan []ConnTCP) + c.connReq <- r + return <-r +} + +// track is the main loop +func (c *ConnTrack) track() error { + // We use Follow() to keep track of conn state changes, but it doesn't give + // us the initial state. If we first look at the established connections + // and then start the follow process we might miss events. + var flags uint32 = NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_UPDATE | + NF_NETLINK_CONNTRACK_DESTROY + events, stop, err := Follow(flags) + if err != nil { + return err + } + + established := map[ConnTCP]struct{}{} + cs, err := Established() + if err != nil { + return err + } + for _, c := range cs { + established[c] = struct{}{} + } + // we keep track of deleted so we can report them + deleted := map[ConnTCP]struct{}{} + + local := localIPs() + updateLocalIPs := time.Tick(time.Minute) + + for { + select { + + case <-c.quit: + stop() + return nil + + case <-updateLocalIPs: + local = localIPs() + + case e, ok := <-events: + if !ok { + return nil + } + switch { + + default: + // not interested + + case e.TCPState == "ESTABLISHED": + cn := e.ConnTCP(local) + if cn == nil { + // log.Printf("not a local connection: %+v\n", e) + continue + } + established[*cn] = struct{}{} + + case e.MsgType == NfctMsgDestroy, e.TCPState == "TIME_WAIT", e.TCPState == "CLOSE": + cn := e.ConnTCP(local) + if cn == nil { + // log.Printf("not a local connection: %+v\n", e) + continue + } + if _, ok := established[*cn]; !ok { + continue + } + delete(established, *cn) + deleted[*cn] = struct{}{} + + } + + case r := <-c.connReq: + cs := make([]ConnTCP, 0, len(established)+len(deleted)) + for c := range established { + cs = append(cs, c) + } + for c := range deleted { + cs = append(cs, c) + } + r <- cs + deleted = map[ConnTCP]struct{}{} + + } + } +} diff --git a/vendor/github.com/typetypetype/conntrack/const.go b/vendor/github.com/typetypetype/conntrack/const.go new file mode 100644 index 000000000..4e3a9eba8 --- /dev/null +++ b/vendor/github.com/typetypetype/conntrack/const.go @@ -0,0 +1,69 @@ +package conntrack + +const ( + // #defined in libnfnetlink/include/libnfnetlink/linux_nfnetlink.h + NFNL_SUBSYS_CTNETLINK = 1 + NFNETLINK_V0 = 0 + + // #defined in libnfnetlink/include/libnfnetlink/linux_nfnetlink_compat.h + NF_NETLINK_CONNTRACK_NEW = 0x00000001 + NF_NETLINK_CONNTRACK_UPDATE = 0x00000002 + NF_NETLINK_CONNTRACK_DESTROY = 0x00000004 + NF_NETLINK_CONNTRACK_EXP_NEW = 0x00000008 + NF_NETLINK_CONNTRACK_EXP_UPDATE = 0x00000010 + NF_NETLINK_CONNTRACK_EXP_DESTROY = 0x00000020 + + // #defined in libnfnetlink/include/libnfnetlink/libnfnetlink.h + NLA_F_NESTED = uint16(1 << 15) + NLA_F_NET_BYTEORDER = uint16(1 << 14) + NLA_TYPE_MASK = ^(NLA_F_NESTED | NLA_F_NET_BYTEORDER) +) + +type NfConntrackMsg int + +const ( + NfctMsgUnknown NfConntrackMsg = 0 + NfctMsgNew NfConntrackMsg = 1 << 0 + NfctMsgUpdate NfConntrackMsg = 1 << 1 + NfctMsgDestroy NfConntrackMsg = 1 << 2 +) + +// taken from libnetfilter_conntrack/src/conntrack/snprintf.c +var tcpState = []string{ + "NONE", + "SYN_SENT", + "SYN_RECV", + "ESTABLISHED", + "FIN_WAIT", + "CLOSE_WAIT", + "LAST_ACK", + "TIME_WAIT", + "CLOSE", + "LISTEN", + "MAX", + "IGNORE", +} + +// Taken from include/uapi/linux/netfilter/nf_conntrack_common.h +type CtStatus uint32 + +const ( + IPS_EXPECTED CtStatus = 1 << iota + IPS_SEEN_REPLY + IPS_ASSURED + IPS_CONFIRMED + IPS_SRC_NAT + IPS_DST_NAT + IPS_SEQ_ADJUST + IPS_SRC_NAT_DONE + IPS_DST_NAT_DONE + IPS_DYING + IPS_FIXED_TIMEOUT + IPS_TEMPLATE + IPS_UNTRACKED + IPS_HELPER + IPS_OFFLOAD + + IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT) + IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE) +) diff --git a/vendor/github.com/typetypetype/conntrack/headers.go b/vendor/github.com/typetypetype/conntrack/headers.go new file mode 100644 index 000000000..55531855e --- /dev/null +++ b/vendor/github.com/typetypetype/conntrack/headers.go @@ -0,0 +1,131 @@ +package conntrack + +// code generated by enum2go. + +type CtattrType int +const ( + CtaUnspec CtattrType = 0 + CtaTupleOrig CtattrType = 1 + CtaTupleReply CtattrType = 2 + CtaStatus CtattrType = 3 + CtaProtoinfo CtattrType = 4 + CtaHelp CtattrType = 5 + CtaNatSrc CtattrType = 6 + CtaTimeout CtattrType = 7 + CtaMark CtattrType = 8 + CtaCountersOrig CtattrType = 9 + CtaCountersReply CtattrType = 10 + CtaUse CtattrType = 11 + CtaId CtattrType = 12 + CtaNatDst CtattrType = 13 + CtaTupleMaster CtattrType = 14 + CtaNatSeqAdjOrig CtattrType = 15 + CtaNatSeqAdjReply CtattrType = 16 + CtaSecmark CtattrType = 17 + CtaZone CtattrType = 18 + CtaSecctx CtattrType = 19 + CtaTimestamp CtattrType = 20 + CtaMarkMask CtattrType = 21 + CtaLabels CtattrType = 22 + CtaLabelsMask CtattrType = 23 + CtaMax CtattrType = 24 +) + +type CtattrTuple int +const ( + CtaTupleUnspec CtattrTuple = 0 + CtaTupleIp CtattrTuple = 1 + CtaTupleProto CtattrTuple = 2 + CtaTupleMax CtattrTuple = 3 +) + +type CtattrCounters int +const ( + CtaCountersUnspec CtattrCounters = 0 + CtaCountersPackets CtattrCounters = 1 /* 64bit counters */ + CtaCountersBytes CtattrCounters = 2 /* 64bit counters */ + CtaCounters32Packets CtattrCounters = 3 /* old 32bit counters, unused */ + CtaCounters32Bytes CtattrCounters = 4 /* old 32bit counters, unused */ + CtaCountersMax CtattrCounters = 5 +) + +type CtattrIp int +const ( + CtaIpUnspec CtattrIp = 0 + CtaIpV4Src CtattrIp = 1 + CtaIpV4Dst CtattrIp = 2 + CtaIpV6Src CtattrIp = 3 + CtaIpV6Dst CtattrIp = 4 + CtaIpMax CtattrIp = 5 +) + +type CtattrL4proto int +const ( + CtaProtoUnspec CtattrL4proto = 0 + CtaProtoNum CtattrL4proto = 1 + CtaProtoSrcPort CtattrL4proto = 2 + CtaProtoDstPort CtattrL4proto = 3 + CtaProtoIcmpId CtattrL4proto = 4 + CtaProtoIcmpType CtattrL4proto = 5 + CtaProtoIcmpCode CtattrL4proto = 6 + CtaProtoIcmpv6Id CtattrL4proto = 7 + CtaProtoIcmpv6Type CtattrL4proto = 8 + CtaProtoIcmpv6Code CtattrL4proto = 9 + CtaProtoMax CtattrL4proto = 10 +) + +type CtattrProtoinfo int +const ( + CtaProtoinfoUnspec CtattrProtoinfo = 0 + CtaProtoinfoTcp CtattrProtoinfo = 1 + CtaProtoinfoDccp CtattrProtoinfo = 2 + CtaProtoinfoSctp CtattrProtoinfo = 3 + CtaProtoinfoMax CtattrProtoinfo = 4 +) + +type CtattrProtoinfoTcp int +const ( + CtaProtoinfoTcpUnspec CtattrProtoinfoTcp = 0 + CtaProtoinfoTcpState CtattrProtoinfoTcp = 1 + CtaProtoinfoTcpWscaleOriginal CtattrProtoinfoTcp = 2 + CtaProtoinfoTcpWscaleReply CtattrProtoinfoTcp = 3 + CtaProtoinfoTcpFlagsOriginal CtattrProtoinfoTcp = 4 + CtaProtoinfoTcpFlagsReply CtattrProtoinfoTcp = 5 + CtaProtoinfoTcpMax CtattrProtoinfoTcp = 6 +) + +type NfConntrackAttrGrp int +const ( + AttrGrpOrigIpv4 NfConntrackAttrGrp = 0 + AttrGrpReplIpv4 NfConntrackAttrGrp = 1 + AttrGrpOrigIpv6 NfConntrackAttrGrp = 2 + AttrGrpReplIpv6 NfConntrackAttrGrp = 3 + AttrGrpOrigPort NfConntrackAttrGrp = 4 + AttrGrpReplPort NfConntrackAttrGrp = 5 + AttrGrpIcmp NfConntrackAttrGrp = 6 + AttrGrpMasterIpv4 NfConntrackAttrGrp = 7 + AttrGrpMasterIpv6 NfConntrackAttrGrp = 8 + AttrGrpMasterPort NfConntrackAttrGrp = 9 + AttrGrpOrigCounters NfConntrackAttrGrp = 10 + AttrGrpReplCounters NfConntrackAttrGrp = 11 + AttrGrpOrigAddrSrc NfConntrackAttrGrp = 12 + AttrGrpOrigAddrDst NfConntrackAttrGrp = 13 + AttrGrpReplAddrSrc NfConntrackAttrGrp = 14 + AttrGrpReplAddrDst NfConntrackAttrGrp = 15 + AttrGrpMax NfConntrackAttrGrp = 16 +) + +type NfConntrackQuery int +const ( + NfctQCreate NfConntrackQuery = 0 + NfctQUpdate NfConntrackQuery = 1 + NfctQDestroy NfConntrackQuery = 2 + NfctQGet NfConntrackQuery = 3 + NfctQFlush NfConntrackQuery = 4 + NfctQDump NfConntrackQuery = 5 + NfctQDumpReset NfConntrackQuery = 6 + NfctQCreateUpdate NfConntrackQuery = 7 + NfctQDumpFilter NfConntrackQuery = 8 + NfctQDumpFilterReset NfConntrackQuery = 9 +) + diff --git a/vendor/github.com/typetypetype/conntrack/linux_headers.go b/vendor/github.com/typetypetype/conntrack/linux_headers.go new file mode 100644 index 000000000..250c856b6 --- /dev/null +++ b/vendor/github.com/typetypetype/conntrack/linux_headers.go @@ -0,0 +1,16 @@ +package conntrack + +// code generated by enum2go, from file "linux_nfnetlink_conntrack.h". + +type CntlMsgTypes int +const ( + IpctnlMsgCtNew CntlMsgTypes = 0 + IpctnlMsgCtGet CntlMsgTypes = 1 + IpctnlMsgCtDelete CntlMsgTypes = 2 + IpctnlMsgCtGetCtrzero CntlMsgTypes = 3 + IpctnlMsgCtGetStatsCpu CntlMsgTypes = 4 + IpctnlMsgCtGetStats CntlMsgTypes = 5 + IpctnlMsgCtGetDying CntlMsgTypes = 6 + IpctnlMsgCtGetUnconfirmed CntlMsgTypes = 7 + IpctnlMsgMax CntlMsgTypes = 8 +) diff --git a/vendor/github.com/typetypetype/conntrack/net.go b/vendor/github.com/typetypetype/conntrack/net.go new file mode 100644 index 000000000..0314379f8 --- /dev/null +++ b/vendor/github.com/typetypetype/conntrack/net.go @@ -0,0 +1,19 @@ +package conntrack + +import ( + "net" +) + +// localIPs gives all IPs we consider local. +func localIPs() map[string]struct{} { + var l = map[string]struct{}{} + if localNets, err := net.InterfaceAddrs(); err == nil { + // Not all networks are IP networks. + for _, localNet := range localNets { + if net, ok := localNet.(*net.IPNet); ok { + l[net.IP.String()] = struct{}{} + } + } + } + return l +} diff --git a/vendor/github.com/typetypetype/conntrack/netlink.go b/vendor/github.com/typetypetype/conntrack/netlink.go new file mode 100644 index 000000000..0d7e1e156 --- /dev/null +++ b/vendor/github.com/typetypetype/conntrack/netlink.go @@ -0,0 +1,21 @@ +package conntrack + +import ( + "syscall" +) + +// NFNL_MSG_TYPE +func nflnMsgType(x uint16) uint8 { + return uint8(x & 0x00ff) +} + +// NFNL_SUBSYS_ID +func nflnSubsysID(x uint16) uint8 { + return uint8((x & 0xff00) >> 8) +} + +// Round the length of a netlink route attribute up to align it +// properly. +func rtaAlignOf(attrlen int) int { + return (attrlen + syscall.RTA_ALIGNTO - 1) & ^(syscall.RTA_ALIGNTO - 1) +} diff --git a/vendor/github.com/typetypetype/conntrack/netlink_attr.go b/vendor/github.com/typetypetype/conntrack/netlink_attr.go new file mode 100644 index 000000000..c25028b0b --- /dev/null +++ b/vendor/github.com/typetypetype/conntrack/netlink_attr.go @@ -0,0 +1,45 @@ +package conntrack + +// Netlink attr parsing. + +import ( + "encoding/binary" + "errors" +) + +const attrHdrLength = 4 + +type Attr struct { + Msg []byte + Typ int + IsNested bool + IsNetByteorder bool +} + +func parseAttrs(b []byte) ([]Attr, error) { + var attrs []Attr + for len(b) >= attrHdrLength { + var attr Attr + attr, b = parseAttr(b) + attrs = append(attrs, attr) + } + if len(b) != 0 { + return nil, errors.New("leftover attr bytes") + } + return attrs, nil +} + +func parseAttr(b []byte) (Attr, []byte) { + l := binary.LittleEndian.Uint16(b[0:2]) + // length is header + payload + l -= uint16(attrHdrLength) + + typ := binary.LittleEndian.Uint16(b[2:4]) + attr := Attr{ + Msg: b[attrHdrLength : attrHdrLength+int(l)], + Typ: int(typ & NLA_TYPE_MASK), + IsNested: typ&NLA_F_NESTED > 0, + IsNetByteorder: typ&NLA_F_NET_BYTEORDER > 0, + } + return attr, b[rtaAlignOf(attrHdrLength+int(l)):] +} diff --git a/vendor/manifest b/vendor/manifest index 8f535fc0f..a89873d66 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -1903,6 +1903,14 @@ "branch": "master", "notests": true }, + { + "importpath": "github.com/typetypetype/conntrack", + "repository": "https://github.com/typetypetype/conntrack", + "vcs": "git", + "revision": "1ea266295634c1151975bfc6759453b06a01469b", + "branch": "master", + "notests": true + }, { "importpath": "github.com/uber-go/tally", "repository": "https://github.com/uber-go/tally",