Vendor github.com/typetypetype/conntrack

This commit is contained in:
Bryan Boreham
2018-08-05 09:50:13 +00:00
parent b9405bcc4b
commit 5420692a39
11 changed files with 970 additions and 0 deletions

22
vendor/github.com/typetypetype/conntrack/LICENSE generated vendored Normal file
View File

@@ -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.

33
vendor/github.com/typetypetype/conntrack/cli/main.go generated vendored Normal file
View File

@@ -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)
}
}
}

461
vendor/github.com/typetypetype/conntrack/client.go generated vendored Normal file
View File

@@ -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
}

145
vendor/github.com/typetypetype/conntrack/conntrack.go generated vendored Normal file
View File

@@ -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{}{}
}
}
}

69
vendor/github.com/typetypetype/conntrack/const.go generated vendored Normal file
View File

@@ -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)
)

131
vendor/github.com/typetypetype/conntrack/headers.go generated vendored Normal file
View File

@@ -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
)

View File

@@ -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
)

19
vendor/github.com/typetypetype/conntrack/net.go generated vendored Normal file
View File

@@ -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
}

21
vendor/github.com/typetypetype/conntrack/netlink.go generated vendored Normal file
View File

@@ -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)
}

View File

@@ -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)):]
}