diff options
Diffstat (limited to 'vendor/github.com/vishvananda/netlink/conntrack_linux.go')
-rw-r--r-- | vendor/github.com/vishvananda/netlink/conntrack_linux.go | 119 |
1 files changed, 71 insertions, 48 deletions
diff --git a/vendor/github.com/vishvananda/netlink/conntrack_linux.go b/vendor/github.com/vishvananda/netlink/conntrack_linux.go index a0fc74a37..4bff0dcba 100644 --- a/vendor/github.com/vishvananda/netlink/conntrack_linux.go +++ b/vendor/github.com/vishvananda/netlink/conntrack_linux.go @@ -22,11 +22,7 @@ const ( // https://github.com/torvalds/linux/blob/master/include/uapi/linux/netfilter/nfnetlink.h -> #define NFNL_SUBSYS_CTNETLINK_EXP 2 ConntrackExpectTable = 2 ) -const ( - // For Parsing Mark - TCP_PROTO = 6 - UDP_PROTO = 17 -) + const ( // backward compatibility with golang 1.6 which does not have io.SeekCurrent seekCurrent = 1 @@ -135,11 +131,13 @@ func (h *Handle) dumpConntrackTable(table ConntrackTableType, family InetFamily) // http://git.netfilter.org/libnetfilter_conntrack/tree/include/internal/object.h // For the time being, the structure below allows to parse and extract the base information of a flow type ipTuple struct { - SrcIP net.IP + Bytes uint64 DstIP net.IP + DstPort uint16 + Packets uint64 Protocol uint8 + SrcIP net.IP SrcPort uint16 - DstPort uint16 } type ConntrackFlow struct { @@ -151,11 +149,12 @@ type ConntrackFlow struct { func (s *ConntrackFlow) String() string { // conntrack cmd output: - // udp 17 src=127.0.0.1 dst=127.0.0.1 sport=4001 dport=1234 [UNREPLIED] src=127.0.0.1 dst=127.0.0.1 sport=1234 dport=4001 mark=0 - return fmt.Sprintf("%s\t%d src=%s dst=%s sport=%d dport=%d\tsrc=%s dst=%s sport=%d dport=%d mark=%d", + // udp 17 src=127.0.0.1 dst=127.0.0.1 sport=4001 dport=1234 packets=5 bytes=532 [UNREPLIED] src=127.0.0.1 dst=127.0.0.1 sport=1234 dport=4001 packets=10 bytes=1078 mark=0 + return fmt.Sprintf("%s\t%d src=%s dst=%s sport=%d dport=%d packets=%d bytes=%d\tsrc=%s dst=%s sport=%d dport=%d packets=%d bytes=%d mark=%d", nl.L4ProtoMap[s.Forward.Protocol], s.Forward.Protocol, - s.Forward.SrcIP.String(), s.Forward.DstIP.String(), s.Forward.SrcPort, s.Forward.DstPort, - s.Reverse.SrcIP.String(), s.Reverse.DstIP.String(), s.Reverse.SrcPort, s.Reverse.DstPort, s.Mark) + s.Forward.SrcIP.String(), s.Forward.DstIP.String(), s.Forward.SrcPort, s.Forward.DstPort, s.Forward.Packets, s.Forward.Bytes, + s.Reverse.SrcIP.String(), s.Reverse.DstIP.String(), s.Reverse.SrcPort, s.Reverse.DstPort, s.Reverse.Packets, s.Reverse.Bytes, + s.Mark) } // This method parse the ip tuple structure @@ -220,9 +219,35 @@ func parseBERaw16(r *bytes.Reader, v *uint16) { binary.Read(r, binary.BigEndian, v) } +func parseBERaw32(r *bytes.Reader, v *uint32) { + binary.Read(r, binary.BigEndian, v) +} + +func parseBERaw64(r *bytes.Reader, v *uint64) { + binary.Read(r, binary.BigEndian, v) +} + +func parseByteAndPacketCounters(r *bytes.Reader) (bytes, packets uint64) { + for i := 0; i < 2; i++ { + switch _, t, _ := parseNfAttrTL(r); t { + case nl.CTA_COUNTERS_BYTES: + parseBERaw64(r, &bytes) + case nl.CTA_COUNTERS_PACKETS: + parseBERaw64(r, &packets) + default: + return + } + } + return +} + +func parseConnectionMark(r *bytes.Reader) (mark uint32) { + parseBERaw32(r, &mark) + return +} + func parseRawData(data []byte) *ConntrackFlow { s := &ConntrackFlow{} - var proto uint8 // First there is the Nfgenmsg header // consume only the family field reader := bytes.NewReader(data) @@ -238,36 +263,31 @@ func parseRawData(data []byte) *ConntrackFlow { // <len, NLA_F_NESTED|CTA_TUPLE_IP> 4 bytes // flow information of the reverse flow for reader.Len() > 0 { - nested, t, l := parseNfAttrTL(reader) - if nested && t == nl.CTA_TUPLE_ORIG { - if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP { - proto = parseIpTuple(reader, &s.Forward) + if nested, t, l := parseNfAttrTL(reader); nested { + switch t { + case nl.CTA_TUPLE_ORIG: + if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP { + parseIpTuple(reader, &s.Forward) + } + case nl.CTA_TUPLE_REPLY: + if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP { + parseIpTuple(reader, &s.Reverse) + } else { + // Header not recognized skip it + reader.Seek(int64(l), seekCurrent) + } + case nl.CTA_COUNTERS_ORIG: + s.Forward.Bytes, s.Forward.Packets = parseByteAndPacketCounters(reader) + case nl.CTA_COUNTERS_REPLY: + s.Reverse.Bytes, s.Reverse.Packets = parseByteAndPacketCounters(reader) } - } else if nested && t == nl.CTA_TUPLE_REPLY { - if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP { - parseIpTuple(reader, &s.Reverse) - - // Got all the useful information stop parsing - break - } else { - // Header not recognized skip it - reader.Seek(int64(l), seekCurrent) + } else { + switch t { + case nl.CTA_MARK: + s.Mark = parseConnectionMark(reader) } } } - if proto == TCP_PROTO { - reader.Seek(64, seekCurrent) - _, t, _, v := parseNfAttrTLV(reader) - if t == nl.CTA_MARK { - s.Mark = uint32(v[3]) - } - } else if proto == UDP_PROTO { - reader.Seek(16, seekCurrent) - _, t, _, v := parseNfAttrTLV(reader) - if t == nl.CTA_MARK { - s.Mark = uint32(v[3]) - } - } return s } @@ -285,7 +305,7 @@ func parseRawData(data []byte) *ConntrackFlow { // Common parameters and options: // -s, --src, --orig-src ip Source address from original direction // -d, --dst, --orig-dst ip Destination address from original direction -// -r, --reply-src ip Source addres from reply direction +// -r, --reply-src ip Source address from reply direction // -q, --reply-dst ip Destination address from reply direction // -p, --protonum proto Layer 4 Protocol, eg. 'tcp' // -f, --family proto Layer 3 Protocol, eg. 'ipv6' @@ -302,11 +322,14 @@ func parseRawData(data []byte) *ConntrackFlow { type ConntrackFilterType uint8 const ( - ConntrackOrigSrcIP = iota // -orig-src ip Source address from original direction - ConntrackOrigDstIP // -orig-dst ip Destination address from original direction - ConntrackNatSrcIP // -src-nat ip Source NAT ip - ConntrackNatDstIP // -dst-nat ip Destination NAT ip - ConntrackNatAnyIP // -any-nat ip Source or destination NAT ip + ConntrackOrigSrcIP = iota // -orig-src ip Source address from original direction + ConntrackOrigDstIP // -orig-dst ip Destination address from original direction + ConntrackReplySrcIP // --reply-src ip Reply Source IP + ConntrackReplyDstIP // --reply-dst ip Reply Destination IP + ConntrackReplyAnyIP // Match source or destination reply IP + ConntrackNatSrcIP = ConntrackReplySrcIP // deprecated use instead ConntrackReplySrcIP + ConntrackNatDstIP = ConntrackReplyDstIP // deprecated use instead ConntrackReplyDstIP + ConntrackNatAnyIP = ConntrackReplyAnyIP // deprecated use instaed ConntrackReplyAnyIP ) type CustomConntrackFilter interface { @@ -351,17 +374,17 @@ func (f *ConntrackFilter) MatchConntrackFlow(flow *ConntrackFlow) bool { } // -src-nat ip Source NAT ip - if elem, found := f.ipFilter[ConntrackNatSrcIP]; match && found { + if elem, found := f.ipFilter[ConntrackReplySrcIP]; match && found { match = match && elem.Equal(flow.Reverse.SrcIP) } // -dst-nat ip Destination NAT ip - if elem, found := f.ipFilter[ConntrackNatDstIP]; match && found { + if elem, found := f.ipFilter[ConntrackReplyDstIP]; match && found { match = match && elem.Equal(flow.Reverse.DstIP) } - // -any-nat ip Source or destination NAT ip - if elem, found := f.ipFilter[ConntrackNatAnyIP]; match && found { + // Match source or destination reply IP + if elem, found := f.ipFilter[ConntrackReplyAnyIP]; match && found { match = match && (elem.Equal(flow.Reverse.SrcIP) || elem.Equal(flow.Reverse.DstIP)) } |