From 07d3dfd45c83d0066a919a364c86850c57fb2612 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Wed, 15 May 2019 12:46:47 +0000 Subject: [PATCH 1/2] Update google/gopacket library To pick up a fix https://github.com/google/gopacket/pull/589 for Go 1.12 --- .../google/gopacket/afpacket/afpacket.go | 77 +- .../google/gopacket/afpacket/header.go | 51 +- .../google/gopacket/afpacket/options.go | 35 +- .../gopacket/afpacket/sockopt_linux_386.go | 57 - .../gopacket/afpacket/sockopt_linux_386.s | 8 - .../google/gopacket/benchmark_test.go | 6 +- .../gopacket/defrag/lcmdefrag/lcmdefrag.go | 144 ++ .../defrag/lcmdefrag/lcmdefrag_test.go | 105 + vendor/github.com/google/gopacket/doc.go | 10 +- .../gopacket/examples/afpacket/afpacket.go | 188 ++ .../gopacket/examples/arpscan/arpscan.go | 4 +- .../gopacket/examples/bidirectional/main.go | 4 + .../gopacket/examples/reassemblydump/main.go | 17 +- vendor/github.com/google/gopacket/flows.go | 2 +- .../google/gopacket/ip4defrag/defrag.go | 33 +- .../google/gopacket/ip4defrag/defrag_test.go | 112 +- .../google/gopacket/layers/base_test.go | 40 +- .../google/gopacket/layers/bfd_test.go | 40 +- .../google/gopacket/layers/decode_test.go | 49 + .../google/gopacket/layers/dhcp_test.go | 52 + .../google/gopacket/layers/dhcpv4.go | 36 +- .../google/gopacket/layers/dhcpv6.go | 341 +++ .../google/gopacket/layers/dhcpv6_options.go | 621 ++++++ .../google/gopacket/layers/dhcpv6_test.go | 93 + .../github.com/google/gopacket/layers/dns.go | 203 +- .../google/gopacket/layers/dns_test.go | 173 +- .../google/gopacket/layers/dot11.go | 789 ++++++- .../google/gopacket/layers/dot11_test.go | 65 +- .../google/gopacket/layers/eapol.go | 241 +++ .../google/gopacket/layers/eapol_test.go | 123 ++ .../google/gopacket/layers/enums.go | 16 + .../google/gopacket/layers/ethernet.go | 1 + .../google/gopacket/layers/geneve.go | 24 +- .../google/gopacket/layers/geneve_test.go | 49 + .../github.com/google/gopacket/layers/gre.go | 25 +- .../github.com/google/gopacket/layers/gtp.go | 181 ++ .../google/gopacket/layers/gtp_test.go | 158 ++ .../google/gopacket/layers/icmp6.go | 61 +- .../gopacket/layers/icmp6NDflags_test.go | 129 ++ .../google/gopacket/layers/icmp6_test.go | 11 +- .../gopacket/layers/icmp6hopbyhop_test.go | 85 + .../google/gopacket/layers/icmp6msg.go | 578 +++++ .../google/gopacket/layers/icmp6msg_test.go | 73 + .../github.com/google/gopacket/layers/ip4.go | 26 +- .../google/gopacket/layers/ip4_test.go | 93 + .../github.com/google/gopacket/layers/ip6.go | 191 +- .../google/gopacket/layers/ip6_test.go | 8 +- .../google/gopacket/layers/layertypes.go | 269 ++- .../github.com/google/gopacket/layers/lcm.go | 213 ++ .../google/gopacket/layers/lcm_test.go | 156 ++ .../google/gopacket/layers/linux_sll.go | 2 + .../github.com/google/gopacket/layers/llc.go | 111 +- .../github.com/google/gopacket/layers/lldp.go | 55 + .../google/gopacket/layers/mldv1.go | 182 ++ .../google/gopacket/layers/mldv1_test.go | 140 ++ .../google/gopacket/layers/mldv2.go | 619 ++++++ .../google/gopacket/layers/mldv2_test.go | 137 ++ .../google/gopacket/layers/modbustcp.go | 150 ++ .../github.com/google/gopacket/layers/ospf.go | 411 +++- .../google/gopacket/layers/ospf_test.go | 457 +++- .../google/gopacket/layers/ports.go | 16 +- .../github.com/google/gopacket/layers/ppp.go | 32 +- .../google/gopacket/layers/radiotap.go | 32 +- .../google/gopacket/layers/sflow.go | 561 +++-- .../google/gopacket/layers/sflow_test.go | 688 +++++- .../github.com/google/gopacket/layers/sip.go | 546 +++++ .../google/gopacket/layers/sip_test.go | 158 ++ .../github.com/google/gopacket/layers/tcp.go | 22 +- .../google/gopacket/layers/tcpip_test.go | 6 +- .../github.com/google/gopacket/layers/tls.go | 208 ++ .../google/gopacket/layers/tls_alert.go | 165 ++ .../google/gopacket/layers/tls_appdata.go | 34 + .../google/gopacket/layers/tls_cipherspec.go | 64 + .../google/gopacket/layers/tls_handshake.go | 28 + .../google/gopacket/layers/tls_test.go | 339 +++ .../github.com/google/gopacket/layers/udp.go | 5 + .../google/gopacket/layers/vxlan.go | 4 + vendor/github.com/google/gopacket/macs/gen.go | 3 +- .../gopacket/macs/valid_mac_prefixes.go | 1885 ++++++++++++++-- vendor/github.com/google/gopacket/packet.go | 36 +- vendor/github.com/google/gopacket/parser.go | 2 +- .../google/gopacket/pcap/bpf_test.go | 70 + .../google/gopacket/pcap/defs_windows_386.go | 74 + .../gopacket/pcap/defs_windows_amd64.go | 76 + vendor/github.com/google/gopacket/pcap/doc.go | 16 +- .../google/gopacket/pcap/generate_defs.go | 157 ++ .../github.com/google/gopacket/pcap/pcap.go | 666 ++---- .../google/gopacket/pcap/pcap_test.go | 10 +- .../google/gopacket/pcap/pcap_tester.go | 5 +- .../google/gopacket/pcap/pcap_unix.go | 650 +++++- .../google/gopacket/pcap/pcap_windows.go | 864 +++++++- .../google/gopacket/pcap/pcapnggo_test.go | 60 + .../google/gopacket/pcapgo/capture.go | 286 +++ .../google/gopacket/pcapgo/capture_test.go | 41 + .../github.com/google/gopacket/pcapgo/doc.go | 63 + .../google/gopacket/pcapgo/ngread.go | 606 ++++++ .../google/gopacket/pcapgo/ngread_test.go | 1922 +++++++++++++++++ .../google/gopacket/pcapgo/ngwrite.go | 397 ++++ .../google/gopacket/pcapgo/ngwrite_test.go | 239 ++ .../google/gopacket/pcapgo/pcapng.go | 187 ++ .../github.com/google/gopacket/pcapgo/read.go | 78 +- .../google/gopacket/pcapgo/read_test.go | 38 + .../google/gopacket/pcapgo/write.go | 17 +- .../google/gopacket/pcapgo/write_test.go | 20 +- .../google/gopacket/pfring/pfring.go | 155 +- .../google/gopacket/pfring/pfring_test.go | 70 + .../google/gopacket/reassembly/tcpassembly.go | 40 +- .../gopacket/reassembly/tcpassembly_test.go | 162 +- .../google/gopacket/reassembly/tcpcheck.go | 8 +- .../gopacket/reassembly/tcpcheck_test.go | 170 +- .../google/gopacket/tcpassembly/assembly.go | 15 +- .../gopacket/tcpassembly/assembly_test.go | 6 + .../gopacket/tcpassembly/tcpreader/reader.go | 2 +- vendor/github.com/google/gopacket/time.go | 72 + .../github.com/google/gopacket/time_test.go | 73 + vendor/github.com/google/gopacket/writer.go | 21 +- vendor/manifest | 2 +- 117 files changed, 18952 insertions(+), 1550 deletions(-) delete mode 100644 vendor/github.com/google/gopacket/afpacket/sockopt_linux_386.go delete mode 100644 vendor/github.com/google/gopacket/afpacket/sockopt_linux_386.s create mode 100644 vendor/github.com/google/gopacket/defrag/lcmdefrag/lcmdefrag.go create mode 100644 vendor/github.com/google/gopacket/defrag/lcmdefrag/lcmdefrag_test.go create mode 100644 vendor/github.com/google/gopacket/examples/afpacket/afpacket.go create mode 100644 vendor/github.com/google/gopacket/layers/dhcpv6.go create mode 100644 vendor/github.com/google/gopacket/layers/dhcpv6_options.go create mode 100644 vendor/github.com/google/gopacket/layers/dhcpv6_test.go create mode 100644 vendor/github.com/google/gopacket/layers/eapol_test.go create mode 100644 vendor/github.com/google/gopacket/layers/gtp.go create mode 100644 vendor/github.com/google/gopacket/layers/gtp_test.go create mode 100644 vendor/github.com/google/gopacket/layers/icmp6NDflags_test.go create mode 100644 vendor/github.com/google/gopacket/layers/icmp6hopbyhop_test.go create mode 100644 vendor/github.com/google/gopacket/layers/icmp6msg.go create mode 100644 vendor/github.com/google/gopacket/layers/icmp6msg_test.go create mode 100644 vendor/github.com/google/gopacket/layers/lcm.go create mode 100644 vendor/github.com/google/gopacket/layers/lcm_test.go create mode 100644 vendor/github.com/google/gopacket/layers/mldv1.go create mode 100644 vendor/github.com/google/gopacket/layers/mldv1_test.go create mode 100644 vendor/github.com/google/gopacket/layers/mldv2.go create mode 100644 vendor/github.com/google/gopacket/layers/mldv2_test.go create mode 100644 vendor/github.com/google/gopacket/layers/modbustcp.go create mode 100644 vendor/github.com/google/gopacket/layers/sip.go create mode 100644 vendor/github.com/google/gopacket/layers/sip_test.go create mode 100644 vendor/github.com/google/gopacket/layers/tls.go create mode 100644 vendor/github.com/google/gopacket/layers/tls_alert.go create mode 100644 vendor/github.com/google/gopacket/layers/tls_appdata.go create mode 100644 vendor/github.com/google/gopacket/layers/tls_cipherspec.go create mode 100644 vendor/github.com/google/gopacket/layers/tls_handshake.go create mode 100644 vendor/github.com/google/gopacket/layers/tls_test.go create mode 100644 vendor/github.com/google/gopacket/pcap/bpf_test.go create mode 100644 vendor/github.com/google/gopacket/pcap/defs_windows_386.go create mode 100644 vendor/github.com/google/gopacket/pcap/defs_windows_amd64.go create mode 100644 vendor/github.com/google/gopacket/pcap/generate_defs.go create mode 100644 vendor/github.com/google/gopacket/pcap/pcapnggo_test.go create mode 100644 vendor/github.com/google/gopacket/pcapgo/capture.go create mode 100644 vendor/github.com/google/gopacket/pcapgo/capture_test.go create mode 100644 vendor/github.com/google/gopacket/pcapgo/doc.go create mode 100644 vendor/github.com/google/gopacket/pcapgo/ngread.go create mode 100644 vendor/github.com/google/gopacket/pcapgo/ngread_test.go create mode 100644 vendor/github.com/google/gopacket/pcapgo/ngwrite.go create mode 100644 vendor/github.com/google/gopacket/pcapgo/ngwrite_test.go create mode 100644 vendor/github.com/google/gopacket/pcapgo/pcapng.go create mode 100644 vendor/github.com/google/gopacket/pfring/pfring_test.go create mode 100644 vendor/github.com/google/gopacket/time.go create mode 100644 vendor/github.com/google/gopacket/time_test.go diff --git a/vendor/github.com/google/gopacket/afpacket/afpacket.go b/vendor/github.com/google/gopacket/afpacket/afpacket.go index 13937c1d85..bdf8888406 100644 --- a/vendor/github.com/google/gopacket/afpacket/afpacket.go +++ b/vendor/github.com/google/gopacket/afpacket/afpacket.go @@ -20,6 +20,7 @@ import ( "runtime" "sync" "sync/atomic" + "syscall" "time" "unsafe" @@ -41,7 +42,6 @@ import ( import "C" var pageSize = unix.Getpagesize() -var tpacketAlignment = uint(C.TPACKET_ALIGNMENT) // ErrPoll returned by poll var ErrPoll = errors.New("packet poll failed") @@ -49,8 +49,11 @@ var ErrPoll = errors.New("packet poll failed") // ErrTimeout returned on poll timeout var ErrTimeout = errors.New("packet poll timeout expired") -func tpacketAlign(v int) int { - return int((uint(v) + tpacketAlignment - 1) & ((^tpacketAlignment) - 1)) +// AncillaryVLAN structures are used to pass the captured VLAN +// as ancillary data via CaptureInfo. +type AncillaryVLAN struct { + // The VLAN VID provided by the kernel. + VLAN int } // Stats is a set of counters detailing the work TPacket has done so far. @@ -66,11 +69,38 @@ type Stats struct { // SocketStats is a struct where socket stats are stored type SocketStats C.struct_tpacket_stats +// Packets returns the number of packets seen by this socket. +func (s *SocketStats) Packets() uint { + return uint(s.tp_packets) +} + +// Drops returns the number of packets dropped on this socket. +func (s *SocketStats) Drops() uint { + return uint(s.tp_drops) +} + // SocketStatsV3 is a struct where socket stats for TPacketV3 are stored type SocketStatsV3 C.struct_tpacket_stats_v3 +// Packets returns the number of packets seen by this socket. +func (s *SocketStatsV3) Packets() uint { + return uint(s.tp_packets) +} + +// Drops returns the number of packets dropped on this socket. +func (s *SocketStatsV3) Drops() uint { + return uint(s.tp_drops) +} + +// QueueFreezes returns the number of queue freezes on this socket. +func (s *SocketStatsV3) QueueFreezes() uint { + return uint(s.tp_freeze_q_cnt) +} + // TPacket implements packet receiving for Linux AF_PACKET versions 1, 2, and 3. type TPacket struct { + // stats is simple statistics on TPacket's run. This MUST be the first entry to ensure alignment for sync.atomic + stats Stats // fd is the C file descriptor. fd int // ring points to the memory space of the ring buffer shared by tpacket and the kernel. @@ -84,8 +114,6 @@ type TPacket struct { offset int // current is the current header. current header - // pollset is used by TPacket for its poll() call. - pollset unix.PollFd // shouldReleasePacket is set to true whenever we return packet data, to make sure we remember to release that data back to the kernel. shouldReleasePacket bool // headerNextNeeded is set to true when header need to move to the next packet. No need to move it case of poll error. @@ -98,8 +126,6 @@ type TPacket struct { v3 v3wrapper statsMu sync.Mutex // guards stats below - // stats is simple statistics on TPacket's run. - stats Stats // socketStats contains stats from the socket socketStats SocketStats // same as socketStats, but with an extra field freeze_q_cnt @@ -283,11 +309,15 @@ retry: goto retry } } - data = h.current.getData() + data = h.current.getData(&h.opts) ci.Timestamp = h.current.getTime() ci.CaptureLength = len(data) ci.Length = h.current.getLength() ci.InterfaceIndex = h.current.getIfaceIndex() + vlan := h.current.getVLAN() + if vlan >= 0 { + ci.AncillaryData = append(ci.AncillaryData, AncillaryVLAN{vlan}) + } atomic.AddInt64(&h.stats.Packets, 1) h.headerNextNeeded = true h.mu.Unlock() @@ -420,19 +450,25 @@ func (h *TPacket) getTPacketHeader() header { func (h *TPacket) pollForFirstPacket(hdr header) error { tm := int(h.opts.pollTimeout / time.Millisecond) - for hdr.getStatus()&C.TP_STATUS_USER == 0 { - h.pollset.Fd = int32(h.fd) - h.pollset.Events = unix.POLLIN - h.pollset.Revents = 0 - n, err := unix.Poll([]unix.PollFd{h.pollset}, tm) + for hdr.getStatus()&unix.TP_STATUS_USER == 0 { + pollset := [1]unix.PollFd{ + { + Fd: int32(h.fd), + Events: unix.POLLIN, + }, + } + n, err := unix.Poll(pollset[:], tm) if n == 0 { return ErrTimeout } atomic.AddInt64(&h.stats.Polls, 1) - if h.pollset.Revents&unix.POLLERR > 0 { + if pollset[0].Revents&unix.POLLERR > 0 { return ErrPoll } + if err == syscall.EINTR { + continue + } if err != nil { return err } @@ -447,12 +483,17 @@ type FanoutType int // FanoutType values. const ( - FanoutHash FanoutType = 0 + FanoutHash FanoutType = unix.PACKET_FANOUT_HASH // It appears that defrag only works with FanoutHash, see: // http://lxr.free-electrons.com/source/net/packet/af_packet.c#L1204 - FanoutHashWithDefrag FanoutType = 0x8000 - FanoutLoadBalance FanoutType = 1 - FanoutCPU FanoutType = 2 + FanoutHashWithDefrag FanoutType = unix.PACKET_FANOUT_FLAG_DEFRAG + FanoutLoadBalance FanoutType = unix.PACKET_FANOUT_LB + FanoutCPU FanoutType = unix.PACKET_FANOUT_CPU + FanoutRollover FanoutType = unix.PACKET_FANOUT_ROLLOVER + FanoutRandom FanoutType = unix.PACKET_FANOUT_RND + FanoutQueueMapping FanoutType = unix.PACKET_FANOUT_QM + FanoutCBPF FanoutType = unix.PACKET_FANOUT_CBPF + FanoutEBPF FanoutType = unix.PACKET_FANOUT_EBPF ) // SetFanout activates TPacket's fanout ability. diff --git a/vendor/github.com/google/gopacket/afpacket/header.go b/vendor/github.com/google/gopacket/afpacket/header.go index 0b9918ec3a..61634e7ab4 100644 --- a/vendor/github.com/google/gopacket/afpacket/header.go +++ b/vendor/github.com/google/gopacket/afpacket/header.go @@ -12,9 +12,13 @@ import ( "reflect" "time" "unsafe" + + "golang.org/x/sys/unix" ) // #include +// #include +// #define VLAN_HLEN 4 import "C" // Our model of handling all TPacket versions is a little hacky, to say the @@ -35,12 +39,14 @@ type header interface { // the header. getTime() time.Time // getData returns the packet data pointed to by the current header. - getData() []byte + getData(opts *options) []byte // getLength returns the total length of the packet. getLength() int // getIfaceIndex returns the index of the network interface // where the packet was seen. The index can later be translated to a name. getIfaceIndex() int + // getVLAN returns the VLAN of a packet if it was provided out-of-band + getVLAN() int // next moves this header to point to the next packet it contains, // returning true on success (in which case getTime and getData will // return values for the new packet) or false if there are no more @@ -48,6 +54,8 @@ type header interface { next() bool } +const tpacketAlignment = uint(unix.TPACKET_ALIGNMENT) + func tpAlign(x int) int { return int((uint(x) + tpacketAlignment - 1) &^ (tpacketAlignment - 1)) } @@ -63,6 +71,19 @@ func makeSlice(start uintptr, length int) (data []byte) { return } +func insertVlanHeader(data []byte, vlanTCI int, opts *options) []byte { + if vlanTCI == 0 || !opts.addVLANHeader { + return data + } + eth := make([]byte, 0, len(data)+C.VLAN_HLEN) + eth = append(eth, data[0:C.ETH_ALEN*2]...) + eth = append(eth, []byte{0x81, 0, byte((vlanTCI >> 8) & 0xff), byte(vlanTCI & 0xff)}...) + return append(eth, data[C.ETH_ALEN*2:]...) +} + +func (h *v1header) getVLAN() int { + return -1 +} func (h *v1header) getStatus() int { return int(h.tp_status) } @@ -72,7 +93,7 @@ func (h *v1header) clearStatus() { func (h *v1header) getTime() time.Time { return time.Unix(int64(h.tp_sec), int64(h.tp_usec)*1000) } -func (h *v1header) getData() []byte { +func (h *v1header) getData(opts *options) []byte { return makeSlice(uintptr(unsafe.Pointer(h))+uintptr(h.tp_mac), int(h.tp_snaplen)) } func (h *v1header) getLength() int { @@ -86,6 +107,9 @@ func (h *v1header) next() bool { return false } +func (h *v2header) getVLAN() int { + return -1 +} func (h *v2header) getStatus() int { return int(h.tp_status) } @@ -95,8 +119,9 @@ func (h *v2header) clearStatus() { func (h *v2header) getTime() time.Time { return time.Unix(int64(h.tp_sec), int64(h.tp_nsec)) } -func (h *v2header) getData() []byte { - return makeSlice(uintptr(unsafe.Pointer(h))+uintptr(h.tp_mac), int(h.tp_snaplen)) +func (h *v2header) getData(opts *options) []byte { + data := makeSlice(uintptr(unsafe.Pointer(h))+uintptr(h.tp_mac), int(h.tp_snaplen)) + return insertVlanHeader(data, int(h.tp_vlan_tci), opts) } func (h *v2header) getLength() int { return int(h.tp_len) @@ -122,6 +147,15 @@ func initV3Wrapper(block unsafe.Pointer) (w v3wrapper) { w.packet = (*C.struct_tpacket3_hdr)(unsafe.Pointer(uintptr(block) + uintptr(w.blockhdr.offset_to_first_pkt))) return } + +func (w *v3wrapper) getVLAN() int { + if w.packet.tp_status&unix.TP_STATUS_VLAN_VALID != 0 { + hv1 := (*C.struct_tpacket_hdr_variant1)(unsafe.Pointer(&w.packet.anon0[0])) + return int(hv1.tp_vlan_tci & 0xfff) + } + return -1 +} + func (w *v3wrapper) getStatus() int { return int(w.blockhdr.block_status) } @@ -131,8 +165,11 @@ func (w *v3wrapper) clearStatus() { func (w *v3wrapper) getTime() time.Time { return time.Unix(int64(w.packet.tp_sec), int64(w.packet.tp_nsec)) } -func (w *v3wrapper) getData() []byte { - return makeSlice(uintptr(unsafe.Pointer(w.packet))+uintptr(w.packet.tp_mac), int(w.packet.tp_snaplen)) +func (w *v3wrapper) getData(opts *options) []byte { + data := makeSlice(uintptr(unsafe.Pointer(w.packet))+uintptr(w.packet.tp_mac), int(w.packet.tp_snaplen)) + + hv1 := (*C.struct_tpacket_hdr_variant1)(unsafe.Pointer(&w.packet.anon0[0])) + return insertVlanHeader(data, int(hv1.tp_vlan_tci), opts) } func (w *v3wrapper) getLength() int { return int(w.packet.tp_len) @@ -151,7 +188,7 @@ func (w *v3wrapper) next() bool { if w.packet.tp_next_offset != 0 { next += uintptr(w.packet.tp_next_offset) } else { - next += uintptr(tpacketAlign(int(w.packet.tp_snaplen) + int(w.packet.tp_mac))) + next += uintptr(tpAlign(int(w.packet.tp_snaplen) + int(w.packet.tp_mac))) } w.packet = (*C.struct_tpacket3_hdr)(unsafe.Pointer(next)) return true diff --git a/vendor/github.com/google/gopacket/afpacket/options.go b/vendor/github.com/google/gopacket/afpacket/options.go index c5ab77196a..3e305c4d67 100644 --- a/vendor/github.com/google/gopacket/afpacket/options.go +++ b/vendor/github.com/google/gopacket/afpacket/options.go @@ -12,11 +12,9 @@ import ( "errors" "fmt" "time" -) -// #include -// #include -import "C" + "golang.org/x/sys/unix" +) // OptTPacketVersion is the version of TPacket to use. // It can be passed into NewTPacket. @@ -55,17 +53,17 @@ const ( // TPacketVersionHighestAvailable tells NewHandle to use the highest available version of tpacket the kernel has available. // This is the default, should a version number not be given in NewHandle's options. TPacketVersionHighestAvailable = OptTPacketVersion(-1) - TPacketVersion1 = OptTPacketVersion(C.TPACKET_V1) - TPacketVersion2 = OptTPacketVersion(C.TPACKET_V2) - TPacketVersion3 = OptTPacketVersion(C.TPACKET_V3) + TPacketVersion1 = OptTPacketVersion(unix.TPACKET_V1) + TPacketVersion2 = OptTPacketVersion(unix.TPACKET_V2) + TPacketVersion3 = OptTPacketVersion(unix.TPACKET_V3) tpacketVersionMax = TPacketVersion3 tpacketVersionMin = -1 // SocketRaw is the default socket type. It returns packet data // including the link layer (ethernet headers, etc). - SocketRaw = OptSocketType(C.SOCK_RAW) + SocketRaw = OptSocketType(unix.SOCK_RAW) // SocketDgram strips off the link layer when reading packets, and adds // the link layer back automatically on packet writes (coming soon...) - SocketDgram = OptSocketType(C.SOCK_DGRAM) + SocketDgram = OptSocketType(unix.SOCK_DGRAM) ) // OptInterface is the specific interface to bind to. @@ -92,6 +90,22 @@ type OptBlockTimeout time.Duration // descriptor to become ready. Specifying a negative value in time‐out means an infinite timeout. type OptPollTimeout time.Duration +// OptAddVLANHeader modifies the packet data that comes back from the +// kernel by adding in the VLAN header that the NIC stripped. AF_PACKET by +// default uses VLAN offloading, in which the NIC strips the VLAN header off of +// the packet before handing it to the kernel. This means that, even if a +// packet has an 802.1q header on the wire, it'll show up without one by the +// time it goes through AF_PACKET. If this option is true, the VLAN header is +// added back in before the packet is returned. Note that this potentially has +// a large performance hit, especially in otherwise zero-copy operation. +// +// Note that if you do not need to have a "real" VLAN layer, it may be +// preferable to use the VLAN ID provided by the AncillaryVLAN struct +// in CaptureInfo.AncillaryData, which is populated out-of-band and has +// negligible performance impact. Such ancillary data will automatically +// be provided if available. +type OptAddVLANHeader bool + // Default constants used by options. const ( DefaultFrameSize = 4096 // Default value for OptFrameSize. @@ -106,6 +120,7 @@ type options struct { framesPerBlock int blockSize int numBlocks int + addVLANHeader bool blockTimeout time.Duration pollTimeout time.Duration version OptTPacketVersion @@ -143,6 +158,8 @@ func parseOptions(opts ...interface{}) (ret options, err error) { ret.iface = string(v) case OptSocketType: ret.socktype = v + case OptAddVLANHeader: + ret.addVLANHeader = bool(v) default: err = errors.New("unknown type in options") return diff --git a/vendor/github.com/google/gopacket/afpacket/sockopt_linux_386.go b/vendor/github.com/google/gopacket/afpacket/sockopt_linux_386.go deleted file mode 100644 index 8c3eb424d4..0000000000 --- a/vendor/github.com/google/gopacket/afpacket/sockopt_linux_386.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2012 Google, Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. - -// +build linux,386 - -package afpacket - -import ( - "unsafe" - - "golang.org/x/sys/unix" -) - -const ( - sysSETSOCKOPT = 0xe - sysGETSOCKOPT = 0xf -) - -func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, unix.Errno) - -// setsockopt provides access to the setsockopt syscall. -func setsockopt(fd, level, name int, v unsafe.Pointer, l uintptr) error { - _, errno := socketcall( - sysSETSOCKOPT, - uintptr(fd), - uintptr(level), - uintptr(name), - uintptr(v), - l, - 0, - ) - if errno != 0 { - return error(errno) - } - - return nil -} - -func getsockopt(fd, level, name int, v unsafe.Pointer, l uintptr) error { - _, errno := socketcall( - sysGETSOCKOPT, - uintptr(fd), - uintptr(level), - uintptr(name), - uintptr(v), - l, - 0, - ) - if errno != 0 { - return error(errno) - } - - return nil -} diff --git a/vendor/github.com/google/gopacket/afpacket/sockopt_linux_386.s b/vendor/github.com/google/gopacket/afpacket/sockopt_linux_386.s deleted file mode 100644 index 7d0336a197..0000000000 --- a/vendor/github.com/google/gopacket/afpacket/sockopt_linux_386.s +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2012 Google, Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. - -TEXT ·socketcall(SB),4,$0-36 - JMP syscall·socketcall(SB) \ No newline at end of file diff --git a/vendor/github.com/google/gopacket/benchmark_test.go b/vendor/github.com/google/gopacket/benchmark_test.go index 74a1d28dfe..4bc20373c0 100644 --- a/vendor/github.com/google/gopacket/benchmark_test.go +++ b/vendor/github.com/google/gopacket/benchmark_test.go @@ -129,7 +129,7 @@ func BenchmarkUnbufferedChannel(b *testing.B) { defer close(ca) go func() { defer close(cb) - for _ = range ca { + for range ca { cb <- true } }() @@ -144,7 +144,7 @@ func BenchmarkSmallBufferedChannel(b *testing.B) { defer close(ca) go func() { defer close(cb) - for _ = range ca { + for range ca { cb <- true } }() @@ -159,7 +159,7 @@ func BenchmarkLargeBufferedChannel(b *testing.B) { defer close(ca) go func() { defer close(cb) - for _ = range ca { + for range ca { cb <- true } }() diff --git a/vendor/github.com/google/gopacket/defrag/lcmdefrag/lcmdefrag.go b/vendor/github.com/google/gopacket/defrag/lcmdefrag/lcmdefrag.go new file mode 100644 index 0000000000..a4cf877010 --- /dev/null +++ b/vendor/github.com/google/gopacket/defrag/lcmdefrag/lcmdefrag.go @@ -0,0 +1,144 @@ +// Copyright 2018 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +// Package lcmdefrag contains a defragmenter for LCM messages. +package lcmdefrag + +import ( + "fmt" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" +) + +const ( + // Packages are cleaned up/removed after no input was received for this + // amount of seconds. + timeout time.Duration = 3 * time.Second +) + +type lcmPacket struct { + lastPacket time.Time + done bool + recFrags uint16 + totalFrags uint16 + frags map[uint16]*layers.LCM +} + +// LCMDefragmenter supports defragmentation of LCM messages. +// +// References +// https://lcm-proj.github.io/ +// https://github.com/lcm-proj/lcm +type LCMDefragmenter struct { + packets map[uint32]*lcmPacket +} + +func newLCMPacket(totalFrags uint16) *lcmPacket { + return &lcmPacket{ + done: false, + recFrags: 0, + totalFrags: totalFrags, + frags: make(map[uint16]*layers.LCM), + } +} + +// NewLCMDefragmenter returns a new LCMDefragmenter. +func NewLCMDefragmenter() *LCMDefragmenter { + return &LCMDefragmenter{ + packets: make(map[uint32]*lcmPacket), + } +} + +func (lp *lcmPacket) append(in *layers.LCM) { + lp.frags[in.FragmentNumber] = in + lp.recFrags++ + lp.lastPacket = time.Now() +} + +func (lp *lcmPacket) assemble() (out *layers.LCM, err error) { + var blob []byte + + //Extract packets + for i := uint16(0); i < lp.totalFrags; i++ { + fragment, ok := lp.frags[i] + if !ok { + err = fmt.Errorf("Tried to defragment incomplete packet. Waiting "+ + "for more potential (unordered) packets... %d", i) + return + } + + // For the very first packet, we also want the header. + if i == 0 { + blob = append(blob, fragment.LayerContents()...) + } + + // Append the data for each packet. + blob = append(blob, fragment.Payload()...) + } + + packet := gopacket.NewPacket(blob, layers.LayerTypeLCM, gopacket.NoCopy) + lcmHdrLayer := packet.Layer(layers.LayerTypeLCM) + out, ok := lcmHdrLayer.(*layers.LCM) + if !ok { + err = fmt.Errorf("Error while decoding the defragmented packet. " + + "Erasing/dropping packet.") + } + + lp.done = true + + return +} + +func (ld *LCMDefragmenter) cleanUp() { + for key, packet := range ld.packets { + if packet.done || time.Now().Sub(packet.lastPacket) > timeout { + delete(ld.packets, key) + } + } +} + +// Defrag takes a reference to an LCM packet and processes it. +// In case the packet does not need to be defragmented, it immediately returns +// the as in passed reference. In case in was the last missing fragment, out +// will be the defragmented packet. If in was a fragment, but we are awaiting +// more, out will be set to nil. +// In the case that in was nil, we will just run the internal cleanup of the +// defragmenter that times out packages. +// If an error was encountered during defragmentation, out will also be nil, +// while err will contain further information on the failure. +func (ld *LCMDefragmenter) Defrag(in *layers.LCM) (out *layers.LCM, err error) { + // Timeout old packages and erase error prone ones. + ld.cleanUp() + + // For running cleanup only + if in == nil { + return + } + + // Quick check if this is acutally a single packet. In that case, just + // return it quickly. + if !in.Fragmented { + out = in + return + } + + // Do we need to start a new fragments obj? + if _, ok := ld.packets[in.SequenceNumber]; !ok { + ld.packets[in.SequenceNumber] = newLCMPacket(in.TotalFragments) + } + + // Append the packet + ld.packets[in.SequenceNumber].append(in) + + // Check if this is the last package of that series + if ld.packets[in.SequenceNumber].recFrags == in.TotalFragments { + out, err = ld.packets[in.SequenceNumber].assemble() + } + + return +} diff --git a/vendor/github.com/google/gopacket/defrag/lcmdefrag/lcmdefrag_test.go b/vendor/github.com/google/gopacket/defrag/lcmdefrag/lcmdefrag_test.go new file mode 100644 index 0000000000..3d54191b4f --- /dev/null +++ b/vendor/github.com/google/gopacket/defrag/lcmdefrag/lcmdefrag_test.go @@ -0,0 +1,105 @@ +// Copyright 2018 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package lcmdefrag + +import ( + "testing" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" +) + +var ( + fragmentOne = []byte{ + 0x4c, 0x43, 0x30, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x02, 0x4c, 0x43, 0x4d, 0x5f, + 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x00, 0x6c, 0x63, + 0x6d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x74, 0x65, 0x73, 0x74, + } + + fragmentTwo = []byte{ + 0x4c, 0x43, 0x30, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x01, 0x00, 0x02, 0x6c, 0x63, 0x6d, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x20, 0x74, 0x65, 0x73, 0x74, + } + + completePacket = []byte{ + 0x4c, 0x43, 0x30, 0x32, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x43, 0x4d, 0x5f, + 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x00, 0x6c, 0x63, + 0x6d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x74, 0x65, 0x73, 0x74, + } +) + +func TestOrderedLCMDefrag(t *testing.T) { + defragmenter := NewLCMDefragmenter() + var err error + + packet := gopacket.NewPacket(fragmentOne, layers.LayerTypeLCM, gopacket.NoCopy) + lcm := packet.Layer(layers.LayerTypeLCM).(*layers.LCM) + + lcm, err = defragmenter.Defrag(lcm) + if lcm != nil { + t.Fatal("Returned incomplete LCM message.") + } + if err != nil { + t.Fatal(err) + } + + packet = gopacket.NewPacket(fragmentTwo, layers.LayerTypeLCM, gopacket.NoCopy) + lcm = packet.Layer(layers.LayerTypeLCM).(*layers.LCM) + + lcm, err = defragmenter.Defrag(lcm) + if lcm == nil { + t.Fatal("Did not receive defragmented LCM message.") + } + if err != nil { + t.Fatal(err) + } +} + +func TestUnorderedLCMDefrag(t *testing.T) { + defragmenter := NewLCMDefragmenter() + var err error + + packet := gopacket.NewPacket(fragmentTwo, layers.LayerTypeLCM, gopacket.NoCopy) + lcm := packet.Layer(layers.LayerTypeLCM).(*layers.LCM) + + lcm, err = defragmenter.Defrag(lcm) + if lcm != nil { + t.Fatal("Returned incomplete LCM message.") + } + if err != nil { + t.Fatal(err) + } + + packet = gopacket.NewPacket(fragmentOne, layers.LayerTypeLCM, gopacket.NoCopy) + lcm = packet.Layer(layers.LayerTypeLCM).(*layers.LCM) + + lcm, err = defragmenter.Defrag(lcm) + if lcm == nil { + t.Fatal("Did not receive defragmented LCM message.") + } + if err != nil { + t.Fatal(err) + } +} + +func TestNonLCMDefrag(t *testing.T) { + defragmenter := NewLCMDefragmenter() + var err error + + packet := gopacket.NewPacket(completePacket, layers.LayerTypeLCM, gopacket.NoCopy) + lcm := packet.Layer(layers.LayerTypeLCM).(*layers.LCM) + + lcm, err = defragmenter.Defrag(lcm) + if lcm == nil { + t.Fatal("Did not receive complete LCM message.") + } + if err != nil { + t.Fatal(err) + } +} diff --git a/vendor/github.com/google/gopacket/doc.go b/vendor/github.com/google/gopacket/doc.go index 6198940723..8e33e562d3 100644 --- a/vendor/github.com/google/gopacket/doc.go +++ b/vendor/github.com/google/gopacket/doc.go @@ -22,6 +22,9 @@ useful, including: Also, if you're looking to dive right into code, see the examples subdirectory for numerous simple binaries built using gopacket libraries. +Minimum go version required is 1.5 except for pcapgo/EthernetHandle, afpacket, +and bsdbpf which need at least 1.7 due to x/sys/unix dependencies. + Basic Usage gopacket takes in packet data as a []byte and decodes it into a packet with @@ -288,7 +291,10 @@ the packet's information. A quick example: parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ð, &ip4, &ip6, &tcp) decoded := []gopacket.LayerType{} for packetData := range somehowGetPacketData() { - err := parser.DecodeLayers(packetData, &decoded) + if err := parser.DecodeLayers(packetData, &decoded); err != nil { + fmt.Fprintf(os.Stderr, "Could not decode layers: %v\n", err) + continue + } for _, layerType := range decoded { switch layerType { case layers.LayerTypeIPv6: @@ -329,7 +335,7 @@ the following manner: } buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{} // See SerializeOptions for more details. - err := ip.SerializeTo(&buf, opts) + err := ip.SerializeTo(buf, opts) if err != nil { panic(err) } fmt.Println(buf.Bytes()) // prints out a byte slice containing the serialized IPv4 layer. diff --git a/vendor/github.com/google/gopacket/examples/afpacket/afpacket.go b/vendor/github.com/google/gopacket/examples/afpacket/afpacket.go new file mode 100644 index 0000000000..cec49de55a --- /dev/null +++ b/vendor/github.com/google/gopacket/examples/afpacket/afpacket.go @@ -0,0 +1,188 @@ +// Copyright 2018 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +// afpacket provides a simple example of using afpacket with zero-copy to read +// packet data. +package main + +import ( + "flag" + "fmt" + "log" + "os" + "runtime/pprof" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/afpacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "golang.org/x/net/bpf" + + _ "github.com/google/gopacket/layers" +) + +var ( + iface = flag.String("i", "any", "Interface to read from") + cpuprofile = flag.String("cpuprofile", "", "If non-empty, write CPU profile here") + snaplen = flag.Int("s", 0, "Snaplen, if <= 0, use 65535") + bufferSize = flag.Int("b", 8, "Interface buffersize (MB)") + filter = flag.String("f", "port not 22", "BPF filter") + count = flag.Int64("c", -1, "If >= 0, # of packets to capture before returning") + verbose = flag.Int64("log_every", 1, "Write a log every X packets") + addVLAN = flag.Bool("add_vlan", false, "If true, add VLAN header") +) + +type afpacketHandle struct { + TPacket *afpacket.TPacket +} + +func newAfpacketHandle(device string, snaplen int, block_size int, num_blocks int, + useVLAN bool, timeout time.Duration) (*afpacketHandle, error) { + + h := &afpacketHandle{} + var err error + + if device == "any" { + h.TPacket, err = afpacket.NewTPacket( + afpacket.OptFrameSize(snaplen), + afpacket.OptBlockSize(block_size), + afpacket.OptNumBlocks(num_blocks), + afpacket.OptAddVLANHeader(useVLAN), + afpacket.OptPollTimeout(timeout), + afpacket.SocketRaw, + afpacket.TPacketVersion3) + } else { + h.TPacket, err = afpacket.NewTPacket( + afpacket.OptInterface(device), + afpacket.OptFrameSize(snaplen), + afpacket.OptBlockSize(block_size), + afpacket.OptNumBlocks(num_blocks), + afpacket.OptAddVLANHeader(useVLAN), + afpacket.OptPollTimeout(timeout), + afpacket.SocketRaw, + afpacket.TPacketVersion3) + } + return h, err +} + +// ZeroCopyReadPacketData satisfies ZeroCopyPacketDataSource interface +func (h *afpacketHandle) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) { + return h.TPacket.ZeroCopyReadPacketData() +} + +// SetBPFFilter translates a BPF filter string into BPF RawInstruction and applies them. +func (h *afpacketHandle) SetBPFFilter(filter string, snaplen int) (err error) { + pcapBPF, err := pcap.CompileBPFFilter(layers.LinkTypeEthernet, snaplen, filter) + if err != nil { + return err + } + bpfIns := []bpf.RawInstruction{} + for _, ins := range pcapBPF { + bpfIns2 := bpf.RawInstruction{ + Op: ins.Code, + Jt: ins.Jt, + Jf: ins.Jf, + K: ins.K, + } + bpfIns = append(bpfIns, bpfIns2) + } + if h.TPacket.SetBPF(bpfIns); err != nil { + return err + } + return h.TPacket.SetBPF(bpfIns) +} + +// LinkType returns ethernet link type. +func (h *afpacketHandle) LinkType() layers.LinkType { + return layers.LinkTypeEthernet +} + +// Close will close afpacket source. +func (h *afpacketHandle) Close() { + h.TPacket.Close() +} + +// SocketStats prints received, dropped, queue-freeze packet stats. +func (h *afpacketHandle) SocketStats() (as afpacket.SocketStats, asv afpacket.SocketStatsV3, err error) { + return h.TPacket.SocketStats() +} + +// afpacketComputeSize computes the block_size and the num_blocks in such a way that the +// allocated mmap buffer is close to but smaller than target_size_mb. +// The restriction is that the block_size must be divisible by both the +// frame size and page size. +func afpacketComputeSize(targetSizeMb int, snaplen int, pageSize int) ( + frameSize int, blockSize int, numBlocks int, err error) { + + if snaplen < pageSize { + frameSize = pageSize / (pageSize / snaplen) + } else { + frameSize = (snaplen/pageSize + 1) * pageSize + } + + // 128 is the default from the gopacket library so just use that + blockSize = frameSize * 128 + numBlocks = (targetSizeMb * 1024 * 1024) / blockSize + + if numBlocks == 0 { + return 0, 0, 0, fmt.Errorf("Interface buffersize is too small") + } + + return frameSize, blockSize, numBlocks, nil +} + +func main() { + flag.Parse() + if *cpuprofile != "" { + log.Printf("Writing CPU profile to %q", *cpuprofile) + f, err := os.Create(*cpuprofile) + if err != nil { + log.Fatal(err) + } + if err := pprof.StartCPUProfile(f); err != nil { + log.Fatal(err) + } + defer pprof.StopCPUProfile() + } + log.Printf("Starting on interface %q", *iface) + if *snaplen <= 0 { + *snaplen = 65535 + } + szFrame, szBlock, numBlocks, err := afpacketComputeSize(*bufferSize, *snaplen, os.Getpagesize()) + if err != nil { + log.Fatal(err) + } + afpacketHandle, err := newAfpacketHandle(*iface, szFrame, szBlock, numBlocks, *addVLAN, pcap.BlockForever) + if err != nil { + log.Fatal(err) + } + err = afpacketHandle.SetBPFFilter(*filter, *snaplen) + if err != nil { + log.Fatal(err) + } + source := gopacket.ZeroCopyPacketDataSource(afpacketHandle) + defer afpacketHandle.Close() + + bytes := uint64(0) + packets := uint64(0) + for ; *count != 0; *count-- { + data, _, err := source.ZeroCopyReadPacketData() + if err != nil { + log.Fatal(err) + } + bytes += uint64(len(data)) + packets++ + if *count%*verbose == 0 { + _, afpacketStats, err := afpacketHandle.SocketStats() + if err != nil { + log.Println(err) + } + log.Printf("Read in %d bytes in %d packets", bytes, packets) + log.Printf("Stats {received dropped queue-freeze}: %d", afpacketStats) + } + } +} diff --git a/vendor/github.com/google/gopacket/examples/arpscan/arpscan.go b/vendor/github.com/google/gopacket/examples/arpscan/arpscan.go index 1a0e33e5d7..b2de0d541e 100644 --- a/vendor/github.com/google/gopacket/examples/arpscan/arpscan.go +++ b/vendor/github.com/google/gopacket/examples/arpscan/arpscan.go @@ -181,8 +181,8 @@ func ips(n *net.IPNet) (out []net.IP) { var buf [4]byte binary.BigEndian.PutUint32(buf[:], num) out = append(out, net.IP(buf[:])) - mask += 1 - num += 1 + mask++ + num++ } return } diff --git a/vendor/github.com/google/gopacket/examples/bidirectional/main.go b/vendor/github.com/google/gopacket/examples/bidirectional/main.go index 4b0b240db0..1d533e69ed 100644 --- a/vendor/github.com/google/gopacket/examples/bidirectional/main.go +++ b/vendor/github.com/google/gopacket/examples/bidirectional/main.go @@ -163,6 +163,10 @@ func main() { streamFactory := &myFactory{bidiMap: make(map[key]*bidi)} streamPool := tcpassembly.NewStreamPool(streamFactory) assembler := tcpassembly.NewAssembler(streamPool) + // Limit memory usage by auto-flushing connection state if we get over 100K + // packets in memory, or over 1000 for a single stream. + assembler.MaxBufferedPagesTotal = 100000 + assembler.MaxBufferedPagesPerConnection = 1000 log.Println("reading in packets") // Read in packets, pass to assembler. diff --git a/vendor/github.com/google/gopacket/examples/reassemblydump/main.go b/vendor/github.com/google/gopacket/examples/reassemblydump/main.go index 9fc379151c..827901185a 100644 --- a/vendor/github.com/google/gopacket/examples/reassemblydump/main.go +++ b/vendor/github.com/google/gopacket/examples/reassemblydump/main.go @@ -117,13 +117,16 @@ func (h *httpReader) Read(p []byte) (int, error) { var outputLevel int var errorsMap map[string]uint +var errorsMapMutex sync.Mutex var errors uint // Too bad for perf that a... is evaluated func Error(t string, s string, a ...interface{}) { + errorsMapMutex.Lock() errors++ nb, _ := errorsMap[t] errorsMap[t] = nb + 1 + errorsMapMutex.Unlock() if outputLevel >= 0 { fmt.Printf(s, a...) } @@ -160,15 +163,19 @@ func (h *httpReader) run(wg *sync.WaitGroup) { } req.Body.Close() Info("HTTP/%s Request: %s %s (body:%d)\n", h.ident, req.Method, req.URL, s) + h.parent.Lock() h.parent.urls = append(h.parent.urls, req.URL.String()) + h.parent.Unlock() } else { res, err := http.ReadResponse(b, nil) var req string + h.parent.Lock() if len(h.parent.urls) == 0 { req = fmt.Sprintf("") } else { req, h.parent.urls = h.parent.urls[0], h.parent.urls[1:] } + h.parent.Unlock() if err == io.EOF || err == io.ErrUnexpectedEOF { break } else if err != nil { @@ -323,9 +330,10 @@ type tcpStream struct { server httpReader urls []string ident string + sync.Mutex } -func (t *tcpStream) Accept(tcp *layers.TCP, ci gopacket.CaptureInfo, dir reassembly.TCPFlowDirection, acked reassembly.Sequence, start *bool, ac reassembly.AssemblerContext) bool { +func (t *tcpStream) Accept(tcp *layers.TCP, ci gopacket.CaptureInfo, dir reassembly.TCPFlowDirection, nextSeq reassembly.Sequence, start *bool, ac reassembly.AssemblerContext) bool { // FSM if !t.tcpstate.CheckState(tcp, dir) { Error("FSM", "%s: Packet rejected by FSM (state:%s)\n", t.ident, t.tcpstate.String()) @@ -339,7 +347,7 @@ func (t *tcpStream) Accept(tcp *layers.TCP, ci gopacket.CaptureInfo, dir reassem } } // Options - err := t.optchecker.Accept(tcp, ci, dir, acked, start) + err := t.optchecker.Accept(tcp, ci, dir, nextSeq, start) if err != nil { Error("OptionChecker", "%s: Packet rejected by OptionChecker: %s\n", t.ident, err) stats.rejectOpt++ @@ -594,7 +602,10 @@ func main() { done := *maxcount > 0 && count >= *maxcount if count%*statsevery == 0 || done { - fmt.Fprintf(os.Stderr, "Processed %v packets (%v bytes) in %v (errors: %v, type:%v)\n", count, bytes, time.Since(start), errors, len(errorsMap)) + errorsMapMutex.Lock() + errorMapLen := len(errorsMap) + errorsMapMutex.Unlock() + fmt.Fprintf(os.Stderr, "Processed %v packets (%v bytes) in %v (errors: %v, errTypes:%v)\n", count, bytes, time.Since(start), errors, errorMapLen) } select { case <-signalChan: diff --git a/vendor/github.com/google/gopacket/flows.go b/vendor/github.com/google/gopacket/flows.go index 7203ead0f6..a00c88398e 100644 --- a/vendor/github.com/google/gopacket/flows.go +++ b/vendor/github.com/google/gopacket/flows.go @@ -49,7 +49,7 @@ func (a Endpoint) Raw() []byte { return a.raw[:a.len] } // For some endpoints, the actual comparison may not make sense, however this // ordering does provide useful information for most Endpoint types. // Ordering is based first on endpoint type, then on raw endpoint bytes. -// Endpoint bytes are sorted lexigraphically. +// Endpoint bytes are sorted lexicographically. func (a Endpoint) LessThan(b Endpoint) bool { return a.typ < b.typ || (a.typ == b.typ && bytes.Compare(a.raw[:a.len], b.raw[:b.len]) < 0) } diff --git a/vendor/github.com/google/gopacket/ip4defrag/defrag.go b/vendor/github.com/google/gopacket/ip4defrag/defrag.go index 9d3862fa60..2fdac78cb1 100644 --- a/vendor/github.com/google/gopacket/ip4defrag/defrag.go +++ b/vendor/github.com/google/gopacket/ip4defrag/defrag.go @@ -31,11 +31,12 @@ func (d debugging) Printf(format string, args ...interface{}) { } // Constants determining how to handle fragments. +// Reference RFC 791, page 25 const ( - IPv4MinimumFragmentSize = 576 // Minimum size of a single fragment + IPv4MinimumFragmentSize = 8 // Minimum size of a single fragment IPv4MaximumSize = 65535 // Maximum size of a fragment (2^16) - IPv4MaximumFragmentOffset = 8189 // Maximum offset of a fragment - IPv4MaximumFragmentListLen = 8 // Back out if we get more than this many fragments + IPv4MaximumFragmentOffset = 8183 // Maximum offset of a fragment + IPv4MaximumFragmentListLen = 8192 // Back out if we get more than this many fragments ) // DefragIPv4 takes in an IPv4 packet with a fragment payload. @@ -89,8 +90,7 @@ func (d *IPv4Defragmenter) DefragIPv4WithTimestamp(in *layers.IPv4, t time.Time) return in, nil } // perfom security checks - st, err := d.securityChecks(in) - if err != nil || st == false { + if err := d.securityChecks(in); err != nil { debug.Printf("defrag: alert security check") return nil, err } @@ -153,8 +153,7 @@ func (d *IPv4Defragmenter) DiscardOlderThan(t time.Time) int { // flush the fragment list for a particular flow func (d *IPv4Defragmenter) flush(ipf ipv4) { d.Lock() - fl := new(fragmentList) - d.ipFlows[ipf] = fl + delete(d.ipFlows, ipf) d.Unlock() } @@ -173,21 +172,29 @@ func (d *IPv4Defragmenter) dontDefrag(ip *layers.IPv4) bool { } // securityChecks performs the needed security checks -func (d *IPv4Defragmenter) securityChecks(ip *layers.IPv4) (bool, error) { +func (d *IPv4Defragmenter) securityChecks(ip *layers.IPv4) error { + fragSize := ip.Length - uint16(ip.IHL)*4 + + // don't allow small fragments outside of specification + if fragSize < IPv4MinimumFragmentSize { + return fmt.Errorf("defrag: fragment too small "+ + "(handcrafted? %d < %d)", fragSize, IPv4MinimumFragmentSize) + } + // don't allow too big fragment offset if ip.FragOffset > IPv4MaximumFragmentOffset { - return false, fmt.Errorf("defrag: fragment offset too big "+ + return fmt.Errorf("defrag: fragment offset too big "+ "(handcrafted? %d > %d)", ip.FragOffset, IPv4MaximumFragmentOffset) } fragOffset := ip.FragOffset * 8 // don't allow fragment that would oversize an IP packet if fragOffset+ip.Length > IPv4MaximumSize { - return false, fmt.Errorf("defrag: fragment will overrun "+ - "(handcrafted? %d > %d)", ip.FragOffset*8+ip.Length, IPv4MaximumSize) + return fmt.Errorf("defrag: fragment will overrun "+ + "(handcrafted? %d > %d)", fragOffset+ip.Length, IPv4MaximumSize) } - return true, nil + return nil } // fragmentList holds a container/list used to contains IP @@ -304,7 +311,7 @@ func (f *fragmentList) build(in *layers.IPv4) (*layers.IPv4, error) { IHL: in.IHL, TOS: in.TOS, Length: f.Highest, - Id: 0, + Id: in.Id, Flags: 0, FragOffset: 0, TTL: in.TTL, diff --git a/vendor/github.com/google/gopacket/ip4defrag/defrag_test.go b/vendor/github.com/google/gopacket/ip4defrag/defrag_test.go index 1eb66d2828..f42c45bd88 100644 --- a/vendor/github.com/google/gopacket/ip4defrag/defrag_test.go +++ b/vendor/github.com/google/gopacket/ip4defrag/defrag_test.go @@ -8,9 +8,11 @@ package ip4defrag import ( "bytes" + "encoding/binary" "fmt" "net" "testing" + "time" "github.com/google/gopacket" "github.com/google/gopacket/bytediff" @@ -57,6 +59,11 @@ func TestDefragPingMultipleFrags(t *testing.T) { bytediff.Diff(validPayload, ip.Payload))) t.Errorf("defrag: payload is not correctly defragmented") } + + discarded := defrag.DiscardOlderThan(time.Now()) + if 0 != discarded { + t.Errorf("defrag: discarded more fragments then expected: %d", discarded) + } } func TestDefragPing1(t *testing.T) { @@ -143,38 +150,115 @@ func TestDefragPing1and2(t *testing.T) { debug = false } -func TestDefragPingTooMuch(t *testing.T) { +func TestDefragTooSmall(t *testing.T) { defrag := NewIPv4Defragmenter() ip1 := layers.IPv4{ Version: 4, + IHL: 5, TTL: 15, SrcIP: net.IPv4(1, 1, 1, 1), DstIP: net.IPv4(2, 2, 2, 2), Id: 0xcc, FragOffset: 0, - Length: 500, + Length: 27, // Minimum fragment size -1 + header (20) Flags: layers.IPv4MoreFragments, } - defrag.DefragIPv4(&ip1) - for i := 2; i < 8; i = i + 1 { - nip := ip1 - nip.FragOffset = ip1.Length * uint16(i) - out, err := defrag.DefragIPv4(&nip) - if err != nil || out != nil { - t.Fatalf("defrag: %s", err) - } + if _, err := defrag.DefragIPv4(&ip1); err == nil { + t.Fatal("defrag: Minimum fragment size is supposed to be 8") + } + + ip1.Length++ + if _, err := defrag.DefragIPv4(&ip1); err != nil { + t.Fatalf("defrag: Minimum fragment size is supposed to be 8, %s", err) + } +} + +func TestDefragFragmentOffset(t *testing.T) { + defrag := NewIPv4Defragmenter() + ip1 := layers.IPv4{ + Version: 4, + IHL: 5, + TTL: 15, + SrcIP: net.IPv4(1, 1, 1, 1), + DstIP: net.IPv4(2, 2, 2, 2), + Id: 0xcc, + FragOffset: 0, + Length: 512, + Flags: layers.IPv4MoreFragments, } - ip8 := ip1 - ip8.FragOffset = 666 + if _, err := defrag.DefragIPv4(&ip1); err != nil { + t.Fatal(err) + } + + ip2 := ip1 + ip2.FragOffset = 8184 - _, err := defrag.DefragIPv4(&ip8) + _, err := defrag.DefragIPv4(&ip2) if err == nil { - t.Fatalf("defrag: Maximum number of fragments are supposed to be 8") + t.Fatalf("defrag: Maximum fragment offset is supposed to be 8183") + } +} + +func TestDefragDiscard(t *testing.T) { + defrag := NewIPv4Defragmenter() + + gentestDefrag(t, defrag, testPing1Frag1, false, "Ping1Frag1") + gentestDefrag(t, defrag, testPing2Frag1, false, "Ping2Frag1") + + discarded := defrag.DiscardOlderThan(time.Now()) + if 2 != discarded { + t.Errorf("defrag: discarded more fragments then expected: %d", discarded) } } +func TestDefragMaxSize(t *testing.T) { + defrag := NewIPv4Defragmenter() + + ip1 := layers.IPv4{ + Version: 4, + IHL: 5, + TTL: 15, + SrcIP: net.IPv4(1, 1, 1, 1), + DstIP: net.IPv4(2, 2, 2, 2), + Id: 0xcc, + FragOffset: 0, + Length: 65535, + Flags: layers.IPv4MoreFragments, + } + if _, err := defrag.DefragIPv4(&ip1); err != nil { + t.Fatal(err) + } + + ip2 := ip1 + ip2.Length = 28 + ip2.FragOffset = 1 + + _, err := defrag.DefragIPv4(&ip2) + if err != nil { + t.Fatal(err) + t.Fatalf("defrag: Maximum length is supposed to be 65535") + } +} + +func TestDefragIDField(t *testing.T) { + defrag := NewIPv4Defragmenter() + + expectedID := binary.BigEndian.Uint16(testPing1Frag1[18:]) + + gentestDefrag(t, defrag, testPing1Frag1, false, "Ping1Frag1") + gentestDefrag(t, defrag, testPing1Frag3, false, "Ping1Frag3") + gentestDefrag(t, defrag, testPing1Frag2, false, "Ping1Frag2") + ipFragmented := gentestDefrag(t, defrag, testPing1Frag4, true, "Ping1Frag4") + + if ipFragmented.Id != expectedID { + t.Fatalf("defrag: expecting a fragmented packet with ID %d, got %d", + expectedID, ipFragmented.Id) + } + +} + func gentestDefrag(t *testing.T, defrag *IPv4Defragmenter, buf []byte, expect bool, label string) *layers.IPv4 { p := gopacket.NewPacket(buf, layers.LinkTypeEthernet, gopacket.Default) if p.ErrorLayer() != nil { diff --git a/vendor/github.com/google/gopacket/layers/base_test.go b/vendor/github.com/google/gopacket/layers/base_test.go index 4be7480bc2..bed5d4fcee 100644 --- a/vendor/github.com/google/gopacket/layers/base_test.go +++ b/vendor/github.com/google/gopacket/layers/base_test.go @@ -9,8 +9,9 @@ package layers import ( - "github.com/google/gopacket" "testing" + + "github.com/google/gopacket" ) func min(a, b int) int { @@ -28,15 +29,42 @@ func checkLayers(p gopacket.Packet, want []gopacket.LayerType, t *testing.T) { len(l.LayerContents()), len(l.LayerPayload())) } t.Log(p) - if len(layers) != len(want) { + if len(layers) < len(want) { t.Errorf(" Number of layers mismatch: got %d want %d", len(layers), len(want)) return } - for i, l := range layers { - if l.LayerType() != want[i] { - t.Errorf(" Layer %d mismatch: got %v want %v", i, l.LayerType(), - want[i]) + for i, l := range want { + if l == gopacket.LayerTypePayload { + // done matching layers + return } + + if layers[i].LayerType() != l { + t.Errorf(" Layer %d mismatch: got %v want %v", i, + layers[i].LayerType(), l) + } + } +} + +// Checks that when a serialized version of p is decoded, p and the serialized version of p are the same. +// Does not work for packets where the order of options can change, like icmpv6 router advertisements, dhcpv6, etc. +func checkSerialization(p gopacket.Packet, t *testing.T) { + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{ + ComputeChecksums: false, + FixLengths: false, + } + if err := gopacket.SerializePacket(buf, opts, p); err != nil { + t.Error("Failed to encode packet:", err) + } + + p2 := gopacket.NewPacket(buf.Bytes(), LinkTypeEthernet, gopacket.Default) + if p2.ErrorLayer() != nil { + t.Error("Failed to decode the re-encoded packet:", p2.ErrorLayer().Error()) + } + + if p2.Dump() != p.Dump() { + t.Errorf("The decoded and the re-encoded packet are different!\nDecoded:\n%s\n Re-Encoded:\n%s", p.Dump(), p2.Dump()) } } diff --git a/vendor/github.com/google/gopacket/layers/bfd_test.go b/vendor/github.com/google/gopacket/layers/bfd_test.go index 1ac84cb5f9..3adc3594d0 100644 --- a/vendor/github.com/google/gopacket/layers/bfd_test.go +++ b/vendor/github.com/google/gopacket/layers/bfd_test.go @@ -89,11 +89,11 @@ func TestBFDNoAuth(t *testing.T) { }, Payload: nil, }, - Version: 1, - Diagnostic: BFDDiagnosticNone, - State: BFDStateDown, - Poll: false, - Final: false, + Version: 1, + Diagnostic: BFDDiagnosticNone, + State: BFDStateDown, + Poll: false, + Final: false, ControlPlaneIndependent: false, AuthPresent: false, Demand: false, @@ -139,11 +139,11 @@ func TestBFDAuthTypePassword(t *testing.T) { }, Payload: nil, }, - Version: 1, - Diagnostic: BFDDiagnosticNone, - State: BFDStateDown, - Poll: false, - Final: false, + Version: 1, + Diagnostic: BFDDiagnosticNone, + State: BFDStateDown, + Poll: false, + Final: false, ControlPlaneIndependent: false, AuthPresent: true, Demand: false, @@ -196,11 +196,11 @@ func TestBFDAuthTypeKeyedMD5(t *testing.T) { }, Payload: nil, }, - Version: 1, - Diagnostic: BFDDiagnosticNone, - State: BFDStateDown, - Poll: false, - Final: false, + Version: 1, + Diagnostic: BFDDiagnosticNone, + State: BFDStateDown, + Poll: false, + Final: false, ControlPlaneIndependent: false, AuthPresent: true, Demand: false, @@ -258,11 +258,11 @@ func TestBFDAuthTypeMeticulousKeyedSHA1(t *testing.T) { }, Payload: nil, }, - Version: 1, - Diagnostic: BFDDiagnosticNone, - State: BFDStateDown, - Poll: false, - Final: false, + Version: 1, + Diagnostic: BFDDiagnosticNone, + State: BFDStateDown, + Poll: false, + Final: false, ControlPlaneIndependent: false, AuthPresent: true, Demand: false, diff --git a/vendor/github.com/google/gopacket/layers/decode_test.go b/vendor/github.com/google/gopacket/layers/decode_test.go index ecfbff7a75..b4ac3b3161 100644 --- a/vendor/github.com/google/gopacket/layers/decode_test.go +++ b/vendor/github.com/google/gopacket/layers/decode_test.go @@ -1074,6 +1074,55 @@ func BenchmarkDecodeMPLS(b *testing.B) { } } +// testPPPGREIPv4IPv6VLAN is the packet from http://packetlife.net/captures/gre_and_4over6.cap +//04:35:03.821897 IP6 2402:f000:1:8e01::5555 > 2607:fcd0:100:2300::b108:2a6b: IP 16.0.0.200 > 192.52.166.154: GREv1, call 6016, seq 430001, ack 539254, length 119: IP 172.16.44.3.40768 > 8.8.8.8.53: 42540+ AAAA? xqt-detect-mode2-97712e88-167a-45b9-93ee-913140e76678. (71) +// 0x0000: 6000 0000 008b 04f6 2402 f000 0001 8e01 `.......$....... +// 0x0010: 0000 0000 0000 5555 2607 fcd0 0100 2300 ......UU&.....#. +// 0x0020: 0000 0000 b108 2a6b 4500 008b 8caf 0000 ......*kE....... +// 0x0030: 402f 75fe 1000 00c8 c034 a69a 3081 880b @/u......4..0... +// 0x0040: 0067 1780 0006 8fb1 0008 3a76 ff03 0021 .g........:v...! +// 0x0050: 4500 0063 0000 4000 3c11 5667 ac10 2c03 E..c..@.<.Vg..,. +// 0x0060: 0808 0808 9f40 0035 004f 2d23 a62c 0100 .....@.5.O-#.,.. +// 0x0070: 0001 0000 0000 0000 3578 7174 2d64 6574 ........5xqt-det +// 0x0080: 6563 742d 6d6f 6465 322d 3937 3731 3265 ect-mode2-97712e +// 0x0090: 3838 2d31 3637 612d 3435 6239 2d39 3365 88-167a-45b9-93e +// 0x00a0: 652d 3931 3331 3430 6537 3636 3738 0000 e-913140e76678.. +// 0x00b0: 1c00 01 +var testPPPGREIPv4IPv6VLAN = []byte{ + 0xc5, 0x00, 0x00, 0x00, 0x82, 0xc4, 0x00, 0x12, 0x1e, 0xf2, 0x61, 0x3d, 0x81, 0x00, 0x00, 0x64, + 0x86, 0xdd, 0x60, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x04, 0xf6, 0x24, 0x02, 0xf0, 0x00, 0x00, 0x01, + 0x8e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x26, 0x07, 0xfc, 0xd0, 0x01, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x08, 0x2a, 0x6b, 0x45, 0x00, 0x00, 0x8b, 0x8c, 0xaf, + 0x00, 0x00, 0x40, 0x2f, 0x75, 0xfe, 0x10, 0x00, 0x00, 0xc8, 0xc0, 0x34, 0xa6, 0x9a, 0x30, 0x81, + 0x88, 0x0b, 0x00, 0x67, 0x17, 0x80, 0x00, 0x06, 0x8f, 0xb1, 0x00, 0x08, 0x3a, 0x76, 0xff, 0x03, + 0x00, 0x21, 0x45, 0x00, 0x00, 0x63, 0x00, 0x00, 0x40, 0x00, 0x3c, 0x11, 0x56, 0x67, 0xac, 0x10, + 0x2c, 0x03, 0x08, 0x08, 0x08, 0x08, 0x9f, 0x40, 0x00, 0x35, 0x00, 0x4f, 0xfb, 0x9f, 0xa6, 0x2c, + 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x78, 0x71, 0x74, 0x2d, 0x64, + 0x65, 0x74, 0x65, 0x63, 0x74, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x32, 0x2d, 0x39, 0x37, 0x37, 0x31, + 0x32, 0x65, 0x38, 0x38, 0x2d, 0x31, 0x36, 0x37, 0x61, 0x2d, 0x34, 0x35, 0x62, 0x39, 0x2d, 0x39, + 0x33, 0x65, 0x65, 0x2d, 0x39, 0x31, 0x33, 0x31, 0x34, 0x30, 0x65, 0x37, 0x36, 0x36, 0x37, 0x38, + 0x00, 0x00, 0x1c, 0x00, 0x01, +} + +func TestPPPGREIPv4IPv6VLAN(t *testing.T) { + p := gopacket.NewPacket(testPPPGREIPv4IPv6VLAN, LinkTypeEthernet, testDecodeOptions) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{ + LayerTypeEthernet, + LayerTypeDot1Q, + LayerTypeIPv6, + LayerTypeIPv4, + LayerTypeGRE, + LayerTypePPP, + LayerTypeIPv4, + LayerTypeUDP, + LayerTypeDNS, + }, t) + testSerialization(t, p, testPPPGREIPv4IPv6VLAN) +} + // testPPPoEICMPv6 is the packet: // 07:43:31.091560 PPPoE [ses 0x11] IP6 fe80::c801:eff:fe88:8 > ff02::1: ICMP6, neighbor advertisement, tgt is fe80::c801:eff:fe88:8, length 24 // 0x0000: cc05 0e88 0000 ca01 0e88 0006 8864 1100 .............d.. diff --git a/vendor/github.com/google/gopacket/layers/dhcp_test.go b/vendor/github.com/google/gopacket/layers/dhcp_test.go index c4975dcc36..c9b32b8c5b 100644 --- a/vendor/github.com/google/gopacket/layers/dhcp_test.go +++ b/vendor/github.com/google/gopacket/layers/dhcp_test.go @@ -67,6 +67,58 @@ func TestDHCPv4EncodeResponse(t *testing.T) { testDHCPEqual(t, dhcp, dhcp2) } +func TestDHCPv4DecodeOption(t *testing.T) { + var tests = []struct { + msg string + buf []byte + err error + }{ + { + msg: "DHCPOptPad", + buf: []byte{0}, + err: nil, + }, + { + msg: "Option with zero length", + buf: []byte{119, 0}, + err: nil, + }, + { + msg: "Option with maximum length", + buf: bytes.Join([][]byte{ + {119, 255}, + bytes.Repeat([]byte{0}, 255), + }, nil), + err: nil, + }, + { + msg: "Too short option", + buf: []byte{}, + err: DecOptionNotEnoughData, + }, + { + msg: "Too short option when option is not 0 or 255", + buf: []byte{119}, + err: DecOptionNotEnoughData, + }, + { + msg: "Malformed option", + buf: []byte{119, 1}, + err: DecOptionMalformed, + }, + } + + for i := range tests { + var ( + opt = new(DHCPOption) + err = opt.decode(tests[i].buf) + ) + if want, got := tests[i].err, err; want != got { + t.Errorf("[#%v %v] Unexpected error want: %v, got: %v\n", i, tests[i].msg, want, err) + } + } +} + func testDHCPEqual(t *testing.T, d1, d2 *DHCPv4) { if d1.Operation != d2.Operation { t.Errorf("expected Operation=%s, got %s", d1.Operation, d2.Operation) diff --git a/vendor/github.com/google/gopacket/layers/dhcpv4.go b/vendor/github.com/google/gopacket/layers/dhcpv4.go index 761b201a29..3bbd036e3f 100644 --- a/vendor/github.com/google/gopacket/layers/dhcpv4.go +++ b/vendor/github.com/google/gopacket/layers/dhcpv4.go @@ -9,7 +9,6 @@ package layers import ( "bytes" "encoding/binary" - "errors" "fmt" "net" @@ -125,6 +124,7 @@ func (d *DHCPv4) LayerType() gopacket.LayerType { return LayerTypeDHCPv4 } // DecodeFromBytes decodes the given bytes into this layer. func (d *DHCPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + d.Options = d.Options[:0] d.Operation = DHCPOp(data[0]) d.HardwareType = LinkType(data[1]) d.HardwareLen = data[2] @@ -140,7 +140,7 @@ func (d *DHCPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error d.ServerName = data[44:108] d.File = data[108:236] if binary.BigEndian.Uint32(data[236:240]) != DHCPMagic { - return errors.New("Bad DHCP header") + return InvalidMagicCookie } if len(data) <= 240 { @@ -538,9 +538,6 @@ func (o *DHCPOption) encode(b []byte) error { case DHCPOptPad, DHCPOptEnd: b[0] = byte(o.Type) default: - if o.Length > 253 { - return errors.New("data too long to encode") - } b[0] = byte(o.Type) b[1] = o.Length copy(b[2:], o.Data) @@ -551,21 +548,38 @@ func (o *DHCPOption) encode(b []byte) error { func (o *DHCPOption) decode(data []byte) error { if len(data) < 1 { // Pad/End have a length of 1 - return errors.New("Not enough data to decode") + return DecOptionNotEnoughData } o.Type = DHCPOpt(data[0]) switch o.Type { case DHCPOptPad, DHCPOptEnd: o.Data = nil default: - if len(data) < 3 { - return errors.New("Not enough data to decode") + if len(data) < 2 { + return DecOptionNotEnoughData } o.Length = data[1] - if o.Length > 253 { - return errors.New("data too long to decode") + if int(o.Length) > len(data[2:]) { + return DecOptionMalformed } - o.Data = data[2 : 2+o.Length] + o.Data = data[2 : 2+int(o.Length)] } return nil } + +// DHCPv4Error is used for constant errors for DHCPv4. It is needed for test asserts. +type DHCPv4Error string + +// DHCPv4Error implements error interface. +func (d DHCPv4Error) Error() string { + return string(d) +} + +const ( + // DecOptionNotEnoughData is returned when there is not enough data during option's decode process + DecOptionNotEnoughData = DHCPv4Error("Not enough data to decode") + // DecOptionMalformed is returned when the option is malformed + DecOptionMalformed = DHCPv4Error("Option is malformed") + // InvalidMagicCookie is returned when Magic cookie is missing into BOOTP header + InvalidMagicCookie = DHCPv4Error("Bad DHCP header") +) diff --git a/vendor/github.com/google/gopacket/layers/dhcpv6.go b/vendor/github.com/google/gopacket/layers/dhcpv6.go new file mode 100644 index 0000000000..052b3943bf --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/dhcpv6.go @@ -0,0 +1,341 @@ +// Copyright 2018 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "fmt" + "net" + + "github.com/google/gopacket" +) + +// DHCPv6MsgType represents a DHCPv6 operation +type DHCPv6MsgType byte + +// Constants that represent DHCP operations +const ( + DHCPv6MsgTypeUnspecified DHCPv6MsgType = iota + DHCPv6MsgTypeSolicit + DHCPv6MsgTypeAdverstise + DHCPv6MsgTypeRequest + DHCPv6MsgTypeConfirm + DHCPv6MsgTypeRenew + DHCPv6MsgTypeRebind + DHCPv6MsgTypeReply + DHCPv6MsgTypeRelease + DHCPv6MsgTypeDecline + DHCPv6MsgTypeReconfigure + DHCPv6MsgTypeInformationRequest + DHCPv6MsgTypeRelayForward + DHCPv6MsgTypeRelayReply +) + +// String returns a string version of a DHCPv6MsgType. +func (o DHCPv6MsgType) String() string { + switch o { + case DHCPv6MsgTypeUnspecified: + return "Unspecified" + case DHCPv6MsgTypeSolicit: + return "Solicit" + case DHCPv6MsgTypeAdverstise: + return "Adverstise" + case DHCPv6MsgTypeRequest: + return "Request" + case DHCPv6MsgTypeConfirm: + return "Confirm" + case DHCPv6MsgTypeRenew: + return "Renew" + case DHCPv6MsgTypeRebind: + return "Rebind" + case DHCPv6MsgTypeReply: + return "Reply" + case DHCPv6MsgTypeRelease: + return "Release" + case DHCPv6MsgTypeDecline: + return "Decline" + case DHCPv6MsgTypeReconfigure: + return "Reconfigure" + case DHCPv6MsgTypeInformationRequest: + return "InformationRequest" + case DHCPv6MsgTypeRelayForward: + return "RelayForward" + case DHCPv6MsgTypeRelayReply: + return "RelayReply" + default: + return "Unknown" + } +} + +// DHCPv6 contains data for a single DHCP packet. +type DHCPv6 struct { + BaseLayer + MsgType DHCPv6MsgType + HopCount uint8 + LinkAddr net.IP + PeerAddr net.IP + TransactionID []byte + Options DHCPv6Options +} + +// LayerType returns gopacket.LayerTypeDHCPv6 +func (d *DHCPv6) LayerType() gopacket.LayerType { return LayerTypeDHCPv6 } + +// DecodeFromBytes decodes the given bytes into this layer. +func (d *DHCPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + d.BaseLayer = BaseLayer{Contents: data} + d.Options = d.Options[:0] + d.MsgType = DHCPv6MsgType(data[0]) + + offset := 0 + if d.MsgType == DHCPv6MsgTypeRelayForward || d.MsgType == DHCPv6MsgTypeRelayReply { + d.HopCount = data[1] + d.LinkAddr = net.IP(data[2:18]) + d.PeerAddr = net.IP(data[18:34]) + offset = 34 + } else { + d.TransactionID = data[1:4] + offset = 4 + } + + stop := len(data) + for offset < stop { + o := DHCPv6Option{} + if err := o.decode(data[offset:]); err != nil { + return err + } + d.Options = append(d.Options, o) + offset += int(o.Length) + 4 // 2 from option code, 2 from option length + } + + return nil +} + +// Len returns the length of a DHCPv6 packet. +func (d *DHCPv6) Len() int { + n := 1 + if d.MsgType == DHCPv6MsgTypeRelayForward || d.MsgType == DHCPv6MsgTypeRelayReply { + n += 33 + } else { + n += 3 + } + + for _, o := range d.Options { + n += int(o.Length) + 4 // 2 from option code, 2 from option length + } + + return n +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (d *DHCPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + plen := int(d.Len()) + + data, err := b.PrependBytes(plen) + if err != nil { + return err + } + + offset := 0 + data[0] = byte(d.MsgType) + if d.MsgType == DHCPv6MsgTypeRelayForward || d.MsgType == DHCPv6MsgTypeRelayReply { + data[1] = byte(d.HopCount) + copy(data[2:18], d.LinkAddr.To16()) + copy(data[18:34], d.PeerAddr.To16()) + offset = 34 + } else { + copy(data[1:4], d.TransactionID) + offset = 4 + } + + if len(d.Options) > 0 { + for _, o := range d.Options { + if err := o.encode(data[offset:], opts); err != nil { + return err + } + offset += int(o.Length) + 4 // 2 from option code, 2 from option length + } + } + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (d *DHCPv6) CanDecode() gopacket.LayerClass { + return LayerTypeDHCPv6 +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (d *DHCPv6) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +func decodeDHCPv6(data []byte, p gopacket.PacketBuilder) error { + dhcp := &DHCPv6{} + err := dhcp.DecodeFromBytes(data, p) + if err != nil { + return err + } + p.AddLayer(dhcp) + return p.NextDecoder(gopacket.LayerTypePayload) +} + +// DHCPv6StatusCode represents a DHCP status code - RFC-3315 +type DHCPv6StatusCode uint16 + +// Constants for the DHCPv6StatusCode. +const ( + DHCPv6StatusCodeSuccess DHCPv6StatusCode = iota + DHCPv6StatusCodeUnspecFail + DHCPv6StatusCodeNoAddrsAvail + DHCPv6StatusCodeNoBinding + DHCPv6StatusCodeNotOnLink + DHCPv6StatusCodeUseMulticast +) + +// String returns a string version of a DHCPv6StatusCode. +func (o DHCPv6StatusCode) String() string { + switch o { + case DHCPv6StatusCodeSuccess: + return "Success" + case DHCPv6StatusCodeUnspecFail: + return "UnspecifiedFailure" + case DHCPv6StatusCodeNoAddrsAvail: + return "NoAddressAvailable" + case DHCPv6StatusCodeNoBinding: + return "NoBinding" + case DHCPv6StatusCodeNotOnLink: + return "NotOnLink" + case DHCPv6StatusCodeUseMulticast: + return "UseMulticast" + default: + return "Unknown" + } +} + +// DHCPv6DUIDType represents a DHCP DUID - RFC-3315 +type DHCPv6DUIDType uint16 + +// Constants for the DHCPv6DUIDType. +const ( + DHCPv6DUIDTypeLLT DHCPv6DUIDType = iota + 1 + DHCPv6DUIDTypeEN + DHCPv6DUIDTypeLL +) + +// String returns a string version of a DHCPv6DUIDType. +func (o DHCPv6DUIDType) String() string { + switch o { + case DHCPv6DUIDTypeLLT: + return "LLT" + case DHCPv6DUIDTypeEN: + return "EN" + case DHCPv6DUIDTypeLL: + return "LL" + default: + return "Unknown" + } +} + +// DHCPv6DUID means DHCP Unique Identifier as stated in RFC 3315, section 9 (https://tools.ietf.org/html/rfc3315#page-19) +type DHCPv6DUID struct { + Type DHCPv6DUIDType + // LLT, LL + HardwareType []byte + // EN + EnterpriseNumber []byte + // LLT + Time []byte + // LLT, LL + LinkLayerAddress net.HardwareAddr + // EN + Identifier []byte +} + +// DecodeFromBytes decodes the given bytes into a DHCPv6DUID +func (d *DHCPv6DUID) DecodeFromBytes(data []byte) error { + if len(data) < 2 { + return errors.New("Not enough bytes to decode: " + string(len(data))) + } + + d.Type = DHCPv6DUIDType(binary.BigEndian.Uint16(data[:2])) + if d.Type == DHCPv6DUIDTypeLLT || d.Type == DHCPv6DUIDTypeLL { + d.HardwareType = data[2:4] + } + + if d.Type == DHCPv6DUIDTypeLLT { + d.Time = data[4:8] + d.LinkLayerAddress = net.HardwareAddr(data[8:]) + } else if d.Type == DHCPv6DUIDTypeEN { + d.EnterpriseNumber = data[2:6] + d.Identifier = data[6:] + } else { // DHCPv6DUIDTypeLL + d.LinkLayerAddress = net.HardwareAddr(data[4:]) + } + + return nil +} + +// Encode encodes the DHCPv6DUID in a slice of bytes +func (d *DHCPv6DUID) Encode() []byte { + length := d.Len() + data := make([]byte, length) + binary.BigEndian.PutUint16(data[0:2], uint16(d.Type)) + + if d.Type == DHCPv6DUIDTypeLLT || d.Type == DHCPv6DUIDTypeLL { + copy(data[2:4], d.HardwareType) + } + + if d.Type == DHCPv6DUIDTypeLLT { + copy(data[4:8], d.Time) + copy(data[8:], d.LinkLayerAddress) + } else if d.Type == DHCPv6DUIDTypeEN { + copy(data[2:6], d.EnterpriseNumber) + copy(data[6:], d.Identifier) + } else { + copy(data[4:], d.LinkLayerAddress) + } + + return data +} + +// Len returns the length of the DHCPv6DUID, respecting the type +func (d *DHCPv6DUID) Len() int { + length := 2 // d.Type + if d.Type == DHCPv6DUIDTypeLLT { + length += 2 /*HardwareType*/ + 4 /*d.Time*/ + len(d.LinkLayerAddress) + } else if d.Type == DHCPv6DUIDTypeEN { + length += 4 /*d.EnterpriseNumber*/ + len(d.Identifier) + } else { // LL + length += 2 /*d.HardwareType*/ + len(d.LinkLayerAddress) + } + + return length +} + +func (d *DHCPv6DUID) String() string { + duid := "Type: " + d.Type.String() + ", " + if d.Type == DHCPv6DUIDTypeLLT { + duid += fmt.Sprintf("HardwareType: %v, Time: %v, LinkLayerAddress: %v", d.HardwareType, d.Time, d.LinkLayerAddress) + } else if d.Type == DHCPv6DUIDTypeEN { + duid += fmt.Sprintf("EnterpriseNumber: %v, Identifier: %v", d.EnterpriseNumber, d.Identifier) + } else { // DHCPv6DUIDTypeLL + duid += fmt.Sprintf("HardwareType: %v, LinkLayerAddress: %v", d.HardwareType, d.LinkLayerAddress) + } + return duid +} + +func decodeDHCPv6DUID(data []byte) (*DHCPv6DUID, error) { + duid := &DHCPv6DUID{} + err := duid.DecodeFromBytes(data) + if err != nil { + return nil, err + } + return duid, nil +} diff --git a/vendor/github.com/google/gopacket/layers/dhcpv6_options.go b/vendor/github.com/google/gopacket/layers/dhcpv6_options.go new file mode 100644 index 0000000000..0c05e35f95 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/dhcpv6_options.go @@ -0,0 +1,621 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "github.com/google/gopacket" +) + +// DHCPv6Opt represents a DHCP option or parameter from RFC-3315 +type DHCPv6Opt uint16 + +// Constants for the DHCPv6Opt options. +const ( + DHCPv6OptClientID DHCPv6Opt = 1 + DHCPv6OptServerID DHCPv6Opt = 2 + DHCPv6OptIANA DHCPv6Opt = 3 + DHCPv6OptIATA DHCPv6Opt = 4 + DHCPv6OptIAAddr DHCPv6Opt = 5 + DHCPv6OptOro DHCPv6Opt = 6 + DHCPv6OptPreference DHCPv6Opt = 7 + DHCPv6OptElapsedTime DHCPv6Opt = 8 + DHCPv6OptRelayMessage DHCPv6Opt = 9 + DHCPv6OptAuth DHCPv6Opt = 11 + DHCPv6OptUnicast DHCPv6Opt = 12 + DHCPv6OptStatusCode DHCPv6Opt = 13 + DHCPv6OptRapidCommit DHCPv6Opt = 14 + DHCPv6OptUserClass DHCPv6Opt = 15 + DHCPv6OptVendorClass DHCPv6Opt = 16 + DHCPv6OptVendorOpts DHCPv6Opt = 17 + DHCPv6OptInterfaceID DHCPv6Opt = 18 + DHCPv6OptReconfigureMessage DHCPv6Opt = 19 + DHCPv6OptReconfigureAccept DHCPv6Opt = 20 + + // RFC 3319 Session Initiation Protocol (SIP) + DHCPv6OptSIPServersDomainList DHCPv6Opt = 21 + DHCPv6OptSIPServersAddressList DHCPv6Opt = 22 + + // RFC 3646 DNS Configuration + DHCPv6OptDNSServers DHCPv6Opt = 23 + DHCPv6OptDomainList DHCPv6Opt = 24 + + // RFC 3633 Prefix Delegation + DHCPv6OptIAPD DHCPv6Opt = 25 + DHCPv6OptIAPrefix DHCPv6Opt = 26 + + // RFC 3898 Network Information Service (NIS) + DHCPv6OptNISServers DHCPv6Opt = 27 + DHCPv6OptNISPServers DHCPv6Opt = 28 + DHCPv6OptNISDomainName DHCPv6Opt = 29 + DHCPv6OptNISPDomainName DHCPv6Opt = 30 + + // RFC 4075 Simple Network Time Protocol (SNTP) + DHCPv6OptSNTPServers DHCPv6Opt = 31 + + // RFC 4242 Information Refresh Time Option + DHCPv6OptInformationRefreshTime DHCPv6Opt = 32 + + // RFC 4280 Broadcast and Multicast Control Servers + DHCPv6OptBCMCSServerDomainNameList DHCPv6Opt = 33 + DHCPv6OptBCMCSServerAddressList DHCPv6Opt = 34 + + // RFC 4776 Civic Address ConfigurationOption + DHCPv6OptGeoconfCivic DHCPv6Opt = 36 + + // RFC 4649 Relay Agent Remote-ID + DHCPv6OptRemoteID DHCPv6Opt = 37 + + // RFC 4580 Relay Agent Subscriber-ID + DHCPv6OptSubscriberID DHCPv6Opt = 38 + + // RFC 4704 Client Full Qualified Domain Name (FQDN) + DHCPv6OptClientFQDN DHCPv6Opt = 39 + + // RFC 5192 Protocol for Carrying Authentication for Network Access (PANA) + DHCPv6OptPanaAgent DHCPv6Opt = 40 + + // RFC 4833 Timezone Options + DHCPv6OptNewPOSIXTimezone DHCPv6Opt = 41 + DHCPv6OptNewTZDBTimezone DHCPv6Opt = 42 + + // RFC 4994 Relay Agent Echo Request + DHCPv6OptEchoRequestOption DHCPv6Opt = 43 + + // RFC 5007 Leasequery + DHCPv6OptLQQuery DHCPv6Opt = 44 + DHCPv6OptCLTTime DHCPv6Opt = 45 + DHCPv6OptClientData DHCPv6Opt = 46 + DHCPv6OptLQRelayData DHCPv6Opt = 47 + DHCPv6OptLQClientLink DHCPv6Opt = 48 + + // RFC 6610 Home Information Discovery in Mobile IPv6 (MIPv6) + DHCPv6OptMIP6HNIDF DHCPv6Opt = 49 + DHCPv6OptMIP6VDINF DHCPv6Opt = 50 + DHCPv6OptMIP6IDINF DHCPv6Opt = 69 + DHCPv6OptMIP6UDINF DHCPv6Opt = 70 + DHCPv6OptMIP6HNP DHCPv6Opt = 71 + DHCPv6OptMIP6HAA DHCPv6Opt = 72 + DHCPv6OptMIP6HAF DHCPv6Opt = 73 + + // RFC 5223 Discovering Location-to-Service Translation (LoST) Servers + DHCPv6OptV6LOST DHCPv6Opt = 51 + + // RFC 5417 Control And Provisioning of Wireless Access Points (CAPWAP) + DHCPv6OptCAPWAPACV6 DHCPv6Opt = 52 + + // RFC 5460 Bulk Leasequery + DHCPv6OptRelayID DHCPv6Opt = 53 + + // RFC 5678 IEEE 802.21 Mobility Services (MoS) Discovery + DHCPv6OptIPv6AddressMoS DHCPv6Opt = 54 + DHCPv6OptIPv6FQDNMoS DHCPv6Opt = 55 + + // RFC 5908 NTP Server Option + DHCPv6OptNTPServer DHCPv6Opt = 56 + + // RFC 5986 Discovering the Local Location Information Server (LIS) + DHCPv6OptV6AccessDomain DHCPv6Opt = 57 + + // RFC 5986 SIP User Agent + DHCPv6OptSIPUACSList DHCPv6Opt = 58 + + // RFC 5970 Options for Network Boot + DHCPv6OptBootFileURL DHCPv6Opt = 59 + DHCPv6OptBootFileParam DHCPv6Opt = 60 + DHCPv6OptClientArchType DHCPv6Opt = 61 + DHCPv6OptNII DHCPv6Opt = 62 + + // RFC 6225 Coordinate-Based Location Configuration Information + DHCPv6OptGeolocation DHCPv6Opt = 63 + + // RFC 6334 Dual-Stack Lite + DHCPv6OptAFTRName DHCPv6Opt = 64 + + // RFC 6440 EAP Re-authentication Protocol (ERP) + DHCPv6OptERPLocalDomainName DHCPv6Opt = 65 + + // RFC 6422 Relay-Supplied DHCP Options + DHCPv6OptRSOO DHCPv6Opt = 66 + + // RFC 6603 Prefix Exclude Option for DHCPv6-based Prefix Delegation + DHCPv6OptPDExclude DHCPv6Opt = 67 + + // RFC 6607 Virtual Subnet Selection + DHCPv6OptVSS DHCPv6Opt = 68 + + // RFC 6731 Improved Recursive DNS Server Selection for Multi-Interfaced Nodes + DHCPv6OptRDNSSSelection DHCPv6Opt = 74 + + // RFC 6784 Kerberos Options for DHCPv6 + DHCPv6OptKRBPrincipalName DHCPv6Opt = 75 + DHCPv6OptKRBRealmName DHCPv6Opt = 76 + DHCPv6OptKRBKDC DHCPv6Opt = 77 + + // RFC 6939 Client Link-Layer Address Option + DHCPv6OptClientLinkLayerAddress DHCPv6Opt = 79 + + // RFC 6977 Triggering DHCPv6 Reconfiguration from Relay Agents + DHCPv6OptLinkAddress DHCPv6Opt = 80 + + // RFC 7037 RADIUS Option for the DHCPv6 Relay Agent + DHCPv6OptRADIUS DHCPv6Opt = 81 + + // RFC 7083 Modification to Default Values of SOL_MAX_RT and INF_MAX_RT + DHCPv6OptSolMaxRt DHCPv6Opt = 82 + DHCPv6OptInfMaxRt DHCPv6Opt = 83 + + // RFC 7078 Distributing Address Selection Policy + DHCPv6OptAddrSel DHCPv6Opt = 84 + DHCPv6OptAddrSelTable DHCPv6Opt = 85 + + // RFC 7291 DHCP Options for the Port Control Protocol (PCP) + DHCPv6OptV6PCPServer DHCPv6Opt = 86 + + // RFC 7341 DHCPv4-over-DHCPv6 (DHCP 4o6) Transport + DHCPv6OptDHCPv4Message DHCPv6Opt = 87 + DHCPv6OptDHCPv4OverDHCPv6Server DHCPv6Opt = 88 + + // RFC 7598 Configuration of Softwire Address and Port-Mapped Clients + DHCPv6OptS46Rule DHCPv6Opt = 89 + DHCPv6OptS46BR DHCPv6Opt = 90 + DHCPv6OptS46DMR DHCPv6Opt = 91 + DHCPv6OptS46V4V4Bind DHCPv6Opt = 92 + DHCPv6OptS46PortParameters DHCPv6Opt = 93 + DHCPv6OptS46ContMAPE DHCPv6Opt = 94 + DHCPv6OptS46ContMAPT DHCPv6Opt = 95 + DHCPv6OptS46ContLW DHCPv6Opt = 96 + + // RFC 7600 IPv4 Residual Deployment via IPv6 + DHCPv6Opt4RD DHCPv6Opt = 97 + DHCPv6Opt4RDMapRule DHCPv6Opt = 98 + DHCPv6Opt4RDNonMapRule DHCPv6Opt = 99 + + // RFC 7653 Active Leasequery + DHCPv6OptLQBaseTime DHCPv6Opt = 100 + DHCPv6OptLQStartTime DHCPv6Opt = 101 + DHCPv6OptLQEndTime DHCPv6Opt = 102 + + // RFC 7710 Captive-Portal Identification + DHCPv6OptCaptivePortal DHCPv6Opt = 103 + + // RFC 7774 Multicast Protocol for Low-Power and Lossy Networks (MPL) Parameter Configuration + DHCPv6OptMPLParameters DHCPv6Opt = 104 + + // RFC 7839 Access-Network-Identifier (ANI) + DHCPv6OptANIATT DHCPv6Opt = 105 + DHCPv6OptANINetworkName DHCPv6Opt = 106 + DHCPv6OptANIAPName DHCPv6Opt = 107 + DHCPv6OptANIAPBSSID DHCPv6Opt = 108 + DHCPv6OptANIOperatorID DHCPv6Opt = 109 + DHCPv6OptANIOperatorRealm DHCPv6Opt = 110 + + // RFC 8026 Unified IPv4-in-IPv6 Softwire Customer Premises Equipment (CPE) + DHCPv6OptS46Priority DHCPv6Opt = 111 + + // draft-ietf-opsawg-mud-25 Manufacturer Usage Description (MUD) + DHCPv6OptMUDURLV6 DHCPv6Opt = 112 + + // RFC 8115 IPv4-Embedded Multicast and Unicast IPv6 Prefixes + DHCPv6OptV6Prefix64 DHCPv6Opt = 113 + + // RFC 8156 DHCPv6 Failover Protocol + DHCPv6OptFBindingStatus DHCPv6Opt = 114 + DHCPv6OptFConnectFlags DHCPv6Opt = 115 + DHCPv6OptFDNSRemovalInfo DHCPv6Opt = 116 + DHCPv6OptFDNSHostName DHCPv6Opt = 117 + DHCPv6OptFDNSZoneName DHCPv6Opt = 118 + DHCPv6OptFDNSFlags DHCPv6Opt = 119 + DHCPv6OptFExpirationTime DHCPv6Opt = 120 + DHCPv6OptFMaxUnacknowledgedBNDUPD DHCPv6Opt = 121 + DHCPv6OptFMCLT DHCPv6Opt = 122 + DHCPv6OptFPartnerLifetime DHCPv6Opt = 123 + DHCPv6OptFPartnerLifetimeSent DHCPv6Opt = 124 + DHCPv6OptFPartnerDownTime DHCPv6Opt = 125 + DHCPv6OptFPartnerRawCltTime DHCPv6Opt = 126 + DHCPv6OptFProtocolVersion DHCPv6Opt = 127 + DHCPv6OptFKeepaliveTime DHCPv6Opt = 128 + DHCPv6OptFReconfigureData DHCPv6Opt = 129 + DHCPv6OptFRelationshipName DHCPv6Opt = 130 + DHCPv6OptFServerFlags DHCPv6Opt = 131 + DHCPv6OptFServerState DHCPv6Opt = 132 + DHCPv6OptFStartTimeOfState DHCPv6Opt = 133 + DHCPv6OptFStateExpirationTime DHCPv6Opt = 134 + + // RFC 8357 Generalized UDP Source Port for DHCP Relay + DHCPv6OptRelayPort DHCPv6Opt = 135 + + // draft-ietf-netconf-zerotouch-25 Zero Touch Provisioning for Networking Devices + DHCPv6OptV6ZeroTouchRedirect DHCPv6Opt = 136 + + // RFC 6153 Access Network Discovery and Selection Function (ANDSF) Discovery + DHCPv6OptIPV6AddressANDSF DHCPv6Opt = 143 +) + +// String returns a string version of a DHCPv6Opt. +func (o DHCPv6Opt) String() string { + switch o { + case DHCPv6OptClientID: + return "ClientID" + case DHCPv6OptServerID: + return "ServerID" + case DHCPv6OptIANA: + return "IA_NA" + case DHCPv6OptIATA: + return "IA_TA" + case DHCPv6OptIAAddr: + return "IAAddr" + case DHCPv6OptOro: + return "Oro" + case DHCPv6OptPreference: + return "Preference" + case DHCPv6OptElapsedTime: + return "ElapsedTime" + case DHCPv6OptRelayMessage: + return "RelayMessage" + case DHCPv6OptAuth: + return "Auth" + case DHCPv6OptUnicast: + return "Unicast" + case DHCPv6OptStatusCode: + return "StatusCode" + case DHCPv6OptRapidCommit: + return "RapidCommit" + case DHCPv6OptUserClass: + return "UserClass" + case DHCPv6OptVendorClass: + return "VendorClass" + case DHCPv6OptVendorOpts: + return "VendorOpts" + case DHCPv6OptInterfaceID: + return "InterfaceID" + case DHCPv6OptReconfigureMessage: + return "ReconfigureMessage" + case DHCPv6OptReconfigureAccept: + return "ReconfigureAccept" + case DHCPv6OptSIPServersDomainList: + return "SIPServersDomainList" + case DHCPv6OptSIPServersAddressList: + return "SIPServersAddressList" + case DHCPv6OptDNSServers: + return "DNSRecursiveNameServer" + case DHCPv6OptDomainList: + return "DomainSearchList" + case DHCPv6OptIAPD: + return "IdentityAssociationPrefixDelegation" + case DHCPv6OptIAPrefix: + return "IAPDPrefix" + case DHCPv6OptNISServers: + return "NISServers" + case DHCPv6OptNISPServers: + return "NISv2Servers" + case DHCPv6OptNISDomainName: + return "NISDomainName" + case DHCPv6OptNISPDomainName: + return "NISv2DomainName" + case DHCPv6OptSNTPServers: + return "SNTPServers" + case DHCPv6OptInformationRefreshTime: + return "InformationRefreshTime" + case DHCPv6OptBCMCSServerDomainNameList: + return "BCMCSControlServersDomainNameList" + case DHCPv6OptBCMCSServerAddressList: + return "BCMCSControlServersAddressList" + case DHCPv6OptGeoconfCivic: + return "CivicAddress" + case DHCPv6OptRemoteID: + return "RelayAgentRemoteID" + case DHCPv6OptSubscriberID: + return "RelayAgentSubscriberID" + case DHCPv6OptClientFQDN: + return "ClientFQDN" + case DHCPv6OptPanaAgent: + return "PANAAuthenticationAgent" + case DHCPv6OptNewPOSIXTimezone: + return "NewPOSIXTimezone" + case DHCPv6OptNewTZDBTimezone: + return "NewTZDBTimezone" + case DHCPv6OptEchoRequestOption: + return "EchoRequest" + case DHCPv6OptLQQuery: + return "LeasequeryQuery" + case DHCPv6OptClientData: + return "LeasequeryClientData" + case DHCPv6OptCLTTime: + return "LeasequeryClientLastTransactionTime" + case DHCPv6OptLQRelayData: + return "LeasequeryRelayData" + case DHCPv6OptLQClientLink: + return "LeasequeryClientLink" + case DHCPv6OptMIP6HNIDF: + return "MIPv6HomeNetworkIDFQDN" + case DHCPv6OptMIP6VDINF: + return "MIPv6VisitedHomeNetworkInformation" + case DHCPv6OptMIP6IDINF: + return "MIPv6IdentifiedHomeNetworkInformation" + case DHCPv6OptMIP6UDINF: + return "MIPv6UnrestrictedHomeNetworkInformation" + case DHCPv6OptMIP6HNP: + return "MIPv6HomeNetworkPrefix" + case DHCPv6OptMIP6HAA: + return "MIPv6HomeAgentAddress" + case DHCPv6OptMIP6HAF: + return "MIPv6HomeAgentFQDN" + case DHCPv6OptV6LOST: + return "LoST Server" + case DHCPv6OptCAPWAPACV6: + return "CAPWAPAccessControllerV6" + case DHCPv6OptRelayID: + return "LeasequeryRelayID" + case DHCPv6OptIPv6AddressMoS: + return "MoSIPv6Address" + case DHCPv6OptIPv6FQDNMoS: + return "MoSDomainNameList" + case DHCPv6OptNTPServer: + return "NTPServer" + case DHCPv6OptV6AccessDomain: + return "AccessNetworkDomainName" + case DHCPv6OptSIPUACSList: + return "SIPUserAgentConfigurationServiceDomains" + case DHCPv6OptBootFileURL: + return "BootFileURL" + case DHCPv6OptBootFileParam: + return "BootFileParameters" + case DHCPv6OptClientArchType: + return "ClientSystemArchitectureType" + case DHCPv6OptNII: + return "ClientNetworkInterfaceIdentifier" + case DHCPv6OptGeolocation: + return "Geolocation" + case DHCPv6OptAFTRName: + return "AFTRName" + case DHCPv6OptERPLocalDomainName: + return "AFTRName" + case DHCPv6OptRSOO: + return "RSOOption" + case DHCPv6OptPDExclude: + return "PrefixExclude" + case DHCPv6OptVSS: + return "VirtualSubnetSelection" + case DHCPv6OptRDNSSSelection: + return "RDNSSSelection" + case DHCPv6OptKRBPrincipalName: + return "KerberosPrincipalName" + case DHCPv6OptKRBRealmName: + return "KerberosRealmName" + case DHCPv6OptKRBKDC: + return "KerberosKDC" + case DHCPv6OptClientLinkLayerAddress: + return "ClientLinkLayerAddress" + case DHCPv6OptLinkAddress: + return "LinkAddress" + case DHCPv6OptRADIUS: + return "RADIUS" + case DHCPv6OptSolMaxRt: + return "SolMaxRt" + case DHCPv6OptInfMaxRt: + return "InfMaxRt" + case DHCPv6OptAddrSel: + return "AddressSelection" + case DHCPv6OptAddrSelTable: + return "AddressSelectionTable" + case DHCPv6OptV6PCPServer: + return "PCPServer" + case DHCPv6OptDHCPv4Message: + return "DHCPv4Message" + case DHCPv6OptDHCPv4OverDHCPv6Server: + return "DHCP4o6ServerAddress" + case DHCPv6OptS46Rule: + return "S46Rule" + case DHCPv6OptS46BR: + return "S46BR" + case DHCPv6OptS46DMR: + return "S46DMR" + case DHCPv6OptS46V4V4Bind: + return "S46IPv4IPv6AddressBinding" + case DHCPv6OptS46PortParameters: + return "S46PortParameters" + case DHCPv6OptS46ContMAPE: + return "S46MAPEContainer" + case DHCPv6OptS46ContMAPT: + return "S46MAPTContainer" + case DHCPv6OptS46ContLW: + return "S46Lightweight4Over6Container" + case DHCPv6Opt4RD: + return "4RD" + case DHCPv6Opt4RDMapRule: + return "4RDMapRule" + case DHCPv6Opt4RDNonMapRule: + return "4RDNonMapRule" + case DHCPv6OptLQBaseTime: + return "LQBaseTime" + case DHCPv6OptLQStartTime: + return "LQStartTime" + case DHCPv6OptLQEndTime: + return "LQEndTime" + case DHCPv6OptCaptivePortal: + return "CaptivePortal" + case DHCPv6OptMPLParameters: + return "MPLParameterConfiguration" + case DHCPv6OptANIATT: + return "ANIAccessTechnologyType" + case DHCPv6OptANINetworkName: + return "ANINetworkName" + case DHCPv6OptANIAPName: + return "ANIAccessPointName" + case DHCPv6OptANIAPBSSID: + return "ANIAccessPointBSSID" + case DHCPv6OptANIOperatorID: + return "ANIOperatorIdentifier" + case DHCPv6OptANIOperatorRealm: + return "ANIOperatorRealm" + case DHCPv6OptS46Priority: + return "S64Priority" + case DHCPv6OptMUDURLV6: + return "ManufacturerUsageDescriptionURL" + case DHCPv6OptV6Prefix64: + return "V6Prefix64" + case DHCPv6OptFBindingStatus: + return "FailoverBindingStatus" + case DHCPv6OptFConnectFlags: + return "FailoverConnectFlags" + case DHCPv6OptFDNSRemovalInfo: + return "FailoverDNSRemovalInfo" + case DHCPv6OptFDNSHostName: + return "FailoverDNSHostName" + case DHCPv6OptFDNSZoneName: + return "FailoverDNSZoneName" + case DHCPv6OptFDNSFlags: + return "FailoverDNSFlags" + case DHCPv6OptFExpirationTime: + return "FailoverExpirationTime" + case DHCPv6OptFMaxUnacknowledgedBNDUPD: + return "FailoverMaxUnacknowledgedBNDUPDMessages" + case DHCPv6OptFMCLT: + return "FailoverMaximumClientLeadTime" + case DHCPv6OptFPartnerLifetime: + return "FailoverPartnerLifetime" + case DHCPv6OptFPartnerLifetimeSent: + return "FailoverPartnerLifetimeSent" + case DHCPv6OptFPartnerDownTime: + return "FailoverPartnerDownTime" + case DHCPv6OptFPartnerRawCltTime: + return "FailoverPartnerRawClientLeadTime" + case DHCPv6OptFProtocolVersion: + return "FailoverProtocolVersion" + case DHCPv6OptFKeepaliveTime: + return "FailoverKeepaliveTime" + case DHCPv6OptFReconfigureData: + return "FailoverReconfigureData" + case DHCPv6OptFRelationshipName: + return "FailoverRelationshipName" + case DHCPv6OptFServerFlags: + return "FailoverServerFlags" + case DHCPv6OptFServerState: + return "FailoverServerState" + case DHCPv6OptFStartTimeOfState: + return "FailoverStartTimeOfState" + case DHCPv6OptFStateExpirationTime: + return "FailoverStateExpirationTime" + case DHCPv6OptRelayPort: + return "RelayPort" + case DHCPv6OptV6ZeroTouchRedirect: + return "ZeroTouch" + case DHCPv6OptIPV6AddressANDSF: + return "ANDSFIPv6Address" + default: + return fmt.Sprintf("Unknown(%d)", uint16(o)) + } +} + +// DHCPv6Options is used to get nicely printed option lists which would normally +// be cut off after 5 options. +type DHCPv6Options []DHCPv6Option + +// String returns a string version of the options list. +func (o DHCPv6Options) String() string { + buf := &bytes.Buffer{} + buf.WriteByte('[') + for i, opt := range o { + buf.WriteString(opt.String()) + if i+1 != len(o) { + buf.WriteString(", ") + } + } + buf.WriteByte(']') + return buf.String() +} + +// DHCPv6Option rerpresents a DHCP option. +type DHCPv6Option struct { + Code DHCPv6Opt + Length uint16 + Data []byte +} + +// String returns a string version of a DHCP Option. +func (o DHCPv6Option) String() string { + switch o.Code { + case DHCPv6OptClientID, DHCPv6OptServerID: + duid, err := decodeDHCPv6DUID(o.Data) + if err != nil { + return fmt.Sprintf("Option(%s:INVALID)", o.Code) + } + return fmt.Sprintf("Option(%s:[%s])", o.Code, duid.String()) + case DHCPv6OptOro: + options := "" + for i := 0; i < int(o.Length); i += 2 { + if options != "" { + options += "," + } + option := DHCPv6Opt(binary.BigEndian.Uint16(o.Data[i : i+2])) + options += option.String() + } + return fmt.Sprintf("Option(%s:[%s])", o.Code, options) + default: + return fmt.Sprintf("Option(%s:%v)", o.Code, o.Data) + } +} + +// NewDHCPv6Option constructs a new DHCPv6Option with a given type and data. +func NewDHCPv6Option(code DHCPv6Opt, data []byte) DHCPv6Option { + o := DHCPv6Option{Code: code} + if data != nil { + o.Data = data + o.Length = uint16(len(data)) + } + + return o +} + +func (o *DHCPv6Option) encode(b []byte, opts gopacket.SerializeOptions) error { + binary.BigEndian.PutUint16(b[0:2], uint16(o.Code)) + if opts.FixLengths { + binary.BigEndian.PutUint16(b[2:4], uint16(len(o.Data))) + } else { + binary.BigEndian.PutUint16(b[2:4], o.Length) + } + copy(b[4:], o.Data) + + return nil +} + +func (o *DHCPv6Option) decode(data []byte) error { + if len(data) < 2 { + return errors.New("not enough data to decode") + } + o.Code = DHCPv6Opt(binary.BigEndian.Uint16(data[0:2])) + if len(data) < 3 { + return errors.New("not enough data to decode") + } + o.Length = binary.BigEndian.Uint16(data[2:4]) + o.Data = data[4 : 4+o.Length] + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/dhcpv6_test.go b/vendor/github.com/google/gopacket/layers/dhcpv6_test.go new file mode 100644 index 0000000000..58fb4452b8 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/dhcpv6_test.go @@ -0,0 +1,93 @@ +// Copyright 2018, Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "bytes" + "testing" + + "github.com/google/gopacket" +) + +func TestDHCPv6EncodeRequest(t *testing.T) { + dhcpv6 := &DHCPv6{MsgType: DHCPv6MsgTypeRequest, HopCount: 0, TransactionID: []byte{87, 25, 88}} + + client := &DHCPv6DUID{Type: DHCPv6DUIDTypeLLT, HardwareType: []byte{0, 1}, Time: []byte{28, 56, 38, 45}, LinkLayerAddress: []byte{8, 0, 39, 254, 143, 149}} + dhcpv6.Options = append(dhcpv6.Options, NewDHCPv6Option(DHCPv6OptClientID, client.Encode())) + + server := &DHCPv6DUID{Type: DHCPv6DUIDTypeLLT, HardwareType: []byte{0, 1}, Time: []byte{28, 56, 37, 232}, LinkLayerAddress: []byte{8, 0, 39, 212, 16, 187}} + dhcpv6.Options = append(dhcpv6.Options, NewDHCPv6Option(DHCPv6OptServerID, server.Encode())) + + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true} + err := gopacket.SerializeLayers(buf, opts, dhcpv6) + if err != nil { + t.Fatal(err) + } + + p2 := gopacket.NewPacket(buf.Bytes(), LayerTypeDHCPv6, testDecodeOptions) + dhcpv62 := p2.Layer(LayerTypeDHCPv6).(*DHCPv6) + testDHCPv6Equal(t, dhcpv6, dhcpv62) +} + +func TestDHCPv6EncodeReply(t *testing.T) { + dhcpv6 := &DHCPv6{MsgType: DHCPv6MsgTypeReply, HopCount: 0, TransactionID: []byte{87, 25, 88}} + + client := &DHCPv6DUID{Type: DHCPv6DUIDTypeLLT, HardwareType: []byte{0, 1}, Time: []byte{28, 56, 38, 45}, LinkLayerAddress: []byte{8, 0, 39, 254, 143, 149}} + dhcpv6.Options = append(dhcpv6.Options, NewDHCPv6Option(DHCPv6OptClientID, client.Encode())) + + server := &DHCPv6DUID{Type: DHCPv6DUIDTypeLLT, HardwareType: []byte{0, 1}, Time: []byte{28, 56, 37, 232}, LinkLayerAddress: []byte{8, 0, 39, 212, 16, 187}} + dhcpv6.Options = append(dhcpv6.Options, NewDHCPv6Option(DHCPv6OptServerID, server.Encode())) + + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true} + err := gopacket.SerializeLayers(buf, opts, dhcpv6) + if err != nil { + t.Fatal(err) + } + + p2 := gopacket.NewPacket(buf.Bytes(), LayerTypeDHCPv6, testDecodeOptions) + dhcpv62 := p2.Layer(LayerTypeDHCPv6).(*DHCPv6) + testDHCPv6Equal(t, dhcpv6, dhcpv62) +} + +func testDHCPv6Equal(t *testing.T, d1, d2 *DHCPv6) { + if d1.MsgType != d2.MsgType { + t.Errorf("expected MsgType=%s, got %s", d1.MsgType, d2.MsgType) + } + if d1.HopCount != d2.HopCount { + t.Errorf("expected HopCount=%d, got %d", d1.HopCount, d2.HopCount) + } + if !d1.LinkAddr.Equal(d2.LinkAddr) { + t.Errorf("expected LinkAddr=%v, got %v", d1.LinkAddr, d2.LinkAddr) + } + if !d1.PeerAddr.Equal(d2.PeerAddr) { + t.Errorf("expected PeerAddr=%v, got %v", d1.PeerAddr, d2.PeerAddr) + } + if !bytes.Equal(d1.TransactionID, d2.TransactionID) { + t.Errorf("expected TransactionID=%v, got %v", d1.TransactionID, d2.TransactionID) + } + if len(d1.Options) != len(d2.Options) { + t.Errorf("expected %d options, got %d", len(d1.Options), len(d2.Options)) + } + + for i, o := range d1.Options { + testDHCPv6OptionEqual(t, i, o, d2.Options[i]) + } +} + +func testDHCPv6OptionEqual(t *testing.T, idx int, d1, d2 DHCPv6Option) { + if d1.Code != d2.Code { + t.Errorf("expection Options[%d].Code = %s, got %s", idx, d1.Code, d2.Code) + } + if d1.Length != d2.Length { + t.Errorf("expection Options[%d].Length = %d, got %d", idx, d1.Length, d2.Length) + } + if !bytes.Equal(d1.Data, d2.Data) { + t.Errorf("expection Options[%d].Data to be = %v, got %v", idx, d1.Data, d2.Data) + } +} diff --git a/vendor/github.com/google/gopacket/layers/dns.go b/vendor/github.com/google/gopacket/layers/dns.go index 2368a28c23..a0b2d721a8 100644 --- a/vendor/github.com/google/gopacket/layers/dns.go +++ b/vendor/github.com/google/gopacket/layers/dns.go @@ -1,4 +1,4 @@ -// Copyright 2014 Google, Inc. All rights reserved. +// Copyright 2014, 2018 GoPacket Authors. All rights reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the LICENSE file in the root of the source @@ -11,6 +11,7 @@ import ( "errors" "fmt" "net" + "strings" "github.com/google/gopacket" ) @@ -69,6 +70,7 @@ const ( DNSTypeTXT DNSType = 16 // text strings DNSTypeAAAA DNSType = 28 // a IPv6 host address [RFC3596] DNSTypeSRV DNSType = 33 // server discovery [RFC2782] [RFC6195] + DNSTypeOPT DNSType = 41 // OPT Pseudo-RR [RFC6891] ) func (dt DNSType) String() string { @@ -111,6 +113,8 @@ func (dt DNSType) String() string { return "AAAA" case DNSTypeSRV: return "SRV" + case DNSTypeOPT: + return "OPT" } } @@ -254,7 +258,7 @@ type DNS struct { TC bool // Truncated RD bool // Recursion desired RA bool // Recursion available - Z uint8 // Resrved for future use + Z uint8 // Reserved for future use ResponseCode DNSResponseCode QDCount uint16 // Number of questions to expect @@ -296,7 +300,7 @@ func (d *DNS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { if len(data) < 12 { df.SetTruncated() - return errors.New("DNS packet too short") + return errDNSPacketTooShort } // since there are no further layers, the baselayer's content is @@ -366,13 +370,13 @@ func (d *DNS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { } if uint16(len(d.Questions)) != d.QDCount { - return errors.New("Invalid query decoding, not the right number of questions") + return errDecodeQueryBadQDCount } else if uint16(len(d.Answers)) != d.ANCount { - return errors.New("Invalid query decoding, not the right number of answers") + return errDecodeQueryBadANCount } else if uint16(len(d.Authorities)) != d.NSCount { - return errors.New("Invalid query decoding, not the right number of authorities") + return errDecodeQueryBadNSCount } else if uint16(len(d.Additionals)) != d.ARCount { - return errors.New("Invalid query decoding, not the right number of additionals info") + return errDecodeQueryBadARCount } return nil } @@ -423,6 +427,12 @@ func recSize(rr *DNSResourceRecord) int { return l case DNSTypeSRV: return 6 + len(rr.SRV.Name) + 2 + case DNSTypeOPT: + l := len(rr.OPT) * 4 + for _, opt := range rr.OPT { + l += len(opt.Data) + } + return l } return 0 @@ -431,7 +441,14 @@ func recSize(rr *DNSResourceRecord) int { func computeSize(recs []DNSResourceRecord) int { sz := 0 for _, rr := range recs { - sz += len(rr.Name) + 14 + v := len(rr.Name) + + if v == 0 { + sz += v + 11 + } else { + sz += v + 12 + } + sz += recSize(&rr) } return sz @@ -504,17 +521,15 @@ func (d *DNS) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOpt return nil } -var errMaxRecursion = errors.New("max DNS recursion level hit") - const maxRecursionLevel = 255 func decodeName(data []byte, offset int, buffer *[]byte, level int) ([]byte, int, error) { if level > maxRecursionLevel { return nil, 0, errMaxRecursion } else if offset >= len(data) { - return nil, 0, errors.New("dns name offset too high") + return nil, 0, errDNSNameOffsetTooHigh } else if offset < 0 { - return nil, 0, errors.New("dns name offset is negative") + return nil, 0, errDNSNameOffsetNegative } start := len(*buffer) index := offset @@ -535,9 +550,9 @@ loop: */ index2 := index + int(data[index]) + 1 if index2-offset > 255 { - return nil, 0, errors.New("dns name is too long") + return nil, 0, errDNSNameTooLong } else if index2 < index+1 || index2 > len(data) { - return nil, 0, errors.New("dns name uncomputable: invalid index") + return nil, 0, errDNSNameInvalidIndex } *buffer = append(*buffer, '.') *buffer = append(*buffer, data[index+1:index2]...) @@ -564,11 +579,11 @@ loop: - a sequence of labels ending with a pointer */ if index+2 > len(data) { - return nil, 0, errors.New("dns offset pointer too high") + return nil, 0, errDNSPointerOffsetTooHigh } offsetp := int(binary.BigEndian.Uint16(data[index:index+2]) & 0x3fff) if offsetp > len(data) { - return nil, 0, errors.New("dns offset pointer too high") + return nil, 0, errDNSPointerOffsetTooHigh } // This looks a little tricky, but actually isn't. Because of how // decodeName is written, calling it appends the decoded name to the @@ -590,11 +605,11 @@ loop: data[index], index) } if index >= len(data) { - return nil, 0, errors.New("dns index walked out of range") + return nil, 0, errDNSIndexOutOfRange } } if len(*buffer) <= start { - return nil, 0, errors.New("no dns data found for name") + return (*buffer)[start:], index + 1, nil } return (*buffer)[start+1:], index + 1, nil } @@ -621,9 +636,10 @@ func (q *DNSQuestion) decode(data []byte, offset int, df gopacket.DecodeFeedback func (q *DNSQuestion) encode(data []byte, offset int) int { noff := encodeName(q.Name, data, offset) + nSz := noff - offset binary.BigEndian.PutUint16(data[noff:], uint16(q.Type)) binary.BigEndian.PutUint16(data[noff+2:], uint16(q.Class)) - return len(q.Name) + 6 + return nSz + 4 } // DNSResourceRecord @@ -667,6 +683,7 @@ type DNSResourceRecord struct { SOA DNSSOA SRV DNSSRV MX DNSMX + OPT []DNSOPT // See RFC 6891, section 6.1.2 // Undecoded TXT for backward compatibility TXT []byte @@ -686,7 +703,7 @@ func (rr *DNSResourceRecord) decode(data []byte, offset int, df gopacket.DecodeF rr.DataLength = binary.BigEndian.Uint16(data[endq+8 : endq+10]) end := endq + 10 + int(rr.DataLength) if end > len(data) { - return 0, fmt.Errorf("resource record length exceeds data") + return 0, errDecodeRecordLength } rr.Data = data[endq+10 : end] @@ -709,6 +726,12 @@ func encodeName(name []byte, data []byte, offset int) int { l++ } } + + if len(name) == 0 { + data[offset] = 0x00 // terminal + return offset + 1 + } + // length for final portion data[offset+len(name)-l] = byte(l) data[offset+len(name)+1] = 0x00 // terminal @@ -718,6 +741,7 @@ func encodeName(name []byte, data []byte, offset int) int { func (rr *DNSResourceRecord) encode(data []byte, offset int, opts gopacket.SerializeOptions) (int, error) { noff := encodeName(rr.Name, data, offset) + nSz := noff - offset binary.BigEndian.PutUint16(data[noff:], uint16(rr.Type)) binary.BigEndian.PutUint16(data[noff+2:], uint16(rr.Class)) @@ -757,6 +781,14 @@ func (rr *DNSResourceRecord) encode(data []byte, offset int, opts gopacket.Seria binary.BigEndian.PutUint16(data[noff+12:], rr.SRV.Weight) binary.BigEndian.PutUint16(data[noff+14:], rr.SRV.Port) encodeName(rr.SRV.Name, data, noff+16) + case DNSTypeOPT: + noff2 := noff + 10 + for _, opt := range rr.OPT { + binary.BigEndian.PutUint16(data[noff2:], uint16(opt.Code)) + binary.BigEndian.PutUint16(data[noff2+2:], uint16(len(opt.Data))) + copy(data[noff2+4:], opt.Data) + noff2 += 4 + len(opt.Data) + } default: return 0, fmt.Errorf("serializing resource record of type %v not supported", rr.Type) } @@ -769,11 +801,18 @@ func (rr *DNSResourceRecord) encode(data []byte, offset int, opts gopacket.Seria rr.DataLength = uint16(dSz) } - return len(rr.Name) + 1 + 11 + dSz, nil + return nSz + 10 + dSz, nil } func (rr *DNSResourceRecord) String() string { + if rr.Type == DNSTypeOPT { + opts := make([]string, len(rr.OPT)) + for i, opt := range rr.OPT { + opts[i] = opt.String() + } + return "OPT " + strings.Join(opts, ",") + } if rr.Class == DNSClassIN { switch rr.Type { case DNSTypeA, DNSTypeAAAA: @@ -798,13 +837,39 @@ func decodeCharacterStrings(data []byte) ([][]byte, error) { for index, index2 := 0, 0; index != end; index = index2 { index2 = index + 1 + int(data[index]) // index increases by 1..256 and does not overflow if index2 > end { - return nil, errors.New("Insufficient data for a ") + return nil, errCharStringMissData } strings = append(strings, data[index+1:index2]) } return strings, nil } +func decodeOPTs(data []byte, offset int) ([]DNSOPT, error) { + allOPT := []DNSOPT{} + end := len(data) + + if offset == end { + return allOPT, nil // There is no data to read + } + + if offset+4 > end { + return allOPT, fmt.Errorf("DNSOPT record is of length %d, it should be at least length 4", end-offset) + } + + for i := offset; i < end; { + opt := DNSOPT{} + opt.Code = DNSOptionCode(binary.BigEndian.Uint16(data[i : i+2])) + l := binary.BigEndian.Uint16(data[i+2 : i+4]) + if i+4+int(l) > end { + return allOPT, fmt.Errorf("Malformed DNSOPT record. The length (%d) field implies a packet larger than the one received", l) + } + opt.Data = data[i+4 : i+4+int(l)] + allOPT = append(allOPT, opt) + i += int(l) + 4 + } + return allOPT, nil +} + func (rr *DNSResourceRecord) decodeRData(data []byte, offset int, buffer *[]byte) error { switch rr.Type { case DNSTypeA: @@ -868,6 +933,12 @@ func (rr *DNSResourceRecord) decodeRData(data []byte, offset int, buffer *[]byte return err } rr.SRV.Name = name + case DNSTypeOPT: + allOPT, err := decodeOPTs(data, offset) + if err != nil { + return err + } + rr.OPT = allOPT } return nil } @@ -892,3 +963,91 @@ type DNSMX struct { Preference uint16 Name []byte } + +// DNSOptionCode represents the code of a DNS Option, see RFC6891, section 6.1.2 +type DNSOptionCode uint16 + +func (doc DNSOptionCode) String() string { + switch doc { + default: + return "Unknown" + case DNSOptionCodeNSID: + return "NSID" + case DNSOptionCodeDAU: + return "DAU" + case DNSOptionCodeDHU: + return "DHU" + case DNSOptionCodeN3U: + return "N3U" + case DNSOptionCodeEDNSClientSubnet: + return "EDNSClientSubnet" + case DNSOptionCodeEDNSExpire: + return "EDNSExpire" + case DNSOptionCodeCookie: + return "Cookie" + case DNSOptionCodeEDNSKeepAlive: + return "EDNSKeepAlive" + case DNSOptionCodePadding: + return "CodePadding" + case DNSOptionCodeChain: + return "CodeChain" + case DNSOptionCodeEDNSKeyTag: + return "CodeEDNSKeyTag" + case DNSOptionCodeEDNSClientTag: + return "EDNSClientTag" + case DNSOptionCodeEDNSServerTag: + return "EDNSServerTag" + case DNSOptionCodeDeviceID: + return "DeviceID" + } +} + +// DNSOptionCode known values. See IANA +const ( + DNSOptionCodeNSID DNSOptionCode = 3 + DNSOptionCodeDAU DNSOptionCode = 5 + DNSOptionCodeDHU DNSOptionCode = 6 + DNSOptionCodeN3U DNSOptionCode = 7 + DNSOptionCodeEDNSClientSubnet DNSOptionCode = 8 + DNSOptionCodeEDNSExpire DNSOptionCode = 9 + DNSOptionCodeCookie DNSOptionCode = 10 + DNSOptionCodeEDNSKeepAlive DNSOptionCode = 11 + DNSOptionCodePadding DNSOptionCode = 12 + DNSOptionCodeChain DNSOptionCode = 13 + DNSOptionCodeEDNSKeyTag DNSOptionCode = 14 + DNSOptionCodeEDNSClientTag DNSOptionCode = 16 + DNSOptionCodeEDNSServerTag DNSOptionCode = 17 + DNSOptionCodeDeviceID DNSOptionCode = 26946 +) + +// DNSOPT is a DNS Option, see RFC6891, section 6.1.2 +type DNSOPT struct { + Code DNSOptionCode + Data []byte +} + +func (opt DNSOPT) String() string { + return fmt.Sprintf("%s=%x", opt.Code, opt.Data) +} + +var ( + errMaxRecursion = errors.New("max DNS recursion level hit") + + errDNSNameOffsetTooHigh = errors.New("dns name offset too high") + errDNSNameOffsetNegative = errors.New("dns name offset is negative") + errDNSPacketTooShort = errors.New("DNS packet too short") + errDNSNameTooLong = errors.New("dns name is too long") + errDNSNameInvalidIndex = errors.New("dns name uncomputable: invalid index") + errDNSPointerOffsetTooHigh = errors.New("dns offset pointer too high") + errDNSIndexOutOfRange = errors.New("dns index walked out of range") + errDNSNameHasNoData = errors.New("no dns data found for name") + + errCharStringMissData = errors.New("Insufficient data for a ") + + errDecodeRecordLength = errors.New("resource record length exceeds data") + + errDecodeQueryBadQDCount = errors.New("Invalid query decoding, not the right number of questions") + errDecodeQueryBadANCount = errors.New("Invalid query decoding, not the right number of answers") + errDecodeQueryBadNSCount = errors.New("Invalid query decoding, not the right number of authorities") + errDecodeQueryBadARCount = errors.New("Invalid query decoding, not the right number of additionals info") +) diff --git a/vendor/github.com/google/gopacket/layers/dns_test.go b/vendor/github.com/google/gopacket/layers/dns_test.go index 264513b16e..262d2f2e6c 100644 --- a/vendor/github.com/google/gopacket/layers/dns_test.go +++ b/vendor/github.com/google/gopacket/layers/dns_test.go @@ -1,4 +1,4 @@ -// Copyright 2012, Google, Inc. All rights reserved. +// Copyright 2012, 2018 GoPacket Authors. All rights reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the LICENSE file in the root of the source @@ -78,6 +78,48 @@ func TestParseDNSTypeTXT(t *testing.T) { } } +var testParseDNSTypeOPT = []byte{ + 0x00, 0x90, 0x0b, 0x12, 0x91, 0xc1, 0x00, 0x1c, 0xc0, 0x93, 0x33, 0xfb, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x5A, 0xce, 0x58, 0x00, 0x00, 0x40, 0x11, 0x67, 0xe2, 0xac, 0x10, 0x01, 0xc7, 0x4b, 0x4b, + 0x4b, 0x4b, 0xd6, 0x00, 0x00, 0x35, 0x00, 0x46, 0x44, 0xb0, 0x50, 0x12, 0x01, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x77, 0x77, 0x77, 0x04, 0x69, 0x65, 0x74, 0x66, 0x03, + 0x6f, 0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x13, 0x69, 0x42, 0x00, 0x0F, 0x4F, 0x70, 0x65, 0x6E, 0x44, 0x4E, 0x53, 0x01, 0x23, + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, +} + +func TestParseDNSTypeOPT(t *testing.T) { + p := gopacket.NewPacket(testParseDNSTypeOPT, LinkTypeEthernet, testDecodeOptions) + + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeUDP, LayerTypeDNS}, t) + questions := p.Layer(LayerTypeDNS).(*DNS).Questions + if len(questions) != 1 { + t.Error("Failed to parse 1 DNS question") + } + additionals := p.Layer(LayerTypeDNS).(*DNS).Additionals + if len(additionals) != 1 { + t.Error("Failed to parse 1 DNS additional") + } + + optAll := additionals[0].OPT + if len(optAll) != 1 { + t.Errorf("Parsed %d OPTs, expected 1", len(optAll)) + } + + if additionals[0].OPT[0].Code != DNSOptionCodeDeviceID { + t.Error("Failed to parse the OPT Code") + } + if string(additionals[0].OPT[0].Data[:7]) != "OpenDNS" { + t.Error("Failed to parse the Data Part 1") + } + if !bytes.Equal(additionals[0].OPT[0].Data[7:], []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}) { + t.Error("Failed to parse the Data Part 2") + } +} + func testQuestionEqual(t *testing.T, i int, exp, got DNSQuestion) { if !bytes.Equal(exp.Name, got.Name) { t.Errorf("expected Questions[%d].Name = %v, got %v", i, string(exp.Name), string(got.Name)) @@ -173,6 +215,20 @@ func testResourceEqual(t *testing.T, i int, name string, exp, got DNSResourceRec if exp.MX.Preference != got.MX.Preference { t.Errorf("expected %s[%d].MX.Preference = %v, got %v", name, i, exp.MX.Preference, got.MX.Preference) } + + // OPT + if len(exp.OPT) != len(got.OPT) { + t.Errorf("expected len(%s[%d].OPT) = %v, got %v", name, i, len(exp.OPT), len(got.OPT)) + } + + for j := range exp.OPT { + if exp.OPT[j].Code != got.OPT[j].Code { + t.Errorf("expected %s[%d].OPT[%d].Code = %v, got %v", name, i, j, exp.OPT[j].Code, got.OPT[j].Code) + } + if !bytes.Equal(exp.OPT[j].Data, got.OPT[j].Data) { + t.Errorf("expected %s[%d].OPT[%d].Data = %v, got %v", name, i, j, exp.OPT[j].Data, got.OPT[j].Data) + } + } } func testDNSEqual(t *testing.T, exp, got *DNS) { @@ -279,6 +335,51 @@ func TestDNSEncodeQuery(t *testing.T) { testDNSEqual(t, dns, dns2) } +func TestDNSEncodeQueryWithOPT(t *testing.T) { + dns := &DNS{ID: 1234, OpCode: DNSOpCodeQuery, RD: true} + dns.Questions = append(dns.Questions, + DNSQuestion{ + Name: []byte("example1.com"), + Type: DNSTypeA, + Class: DNSClassIN, + }) + + dns.Questions = append(dns.Questions, + DNSQuestion{ + Name: []byte("example2.com"), + Type: DNSTypeA, + Class: DNSClassIN, + }) + dns.Additionals = append(dns.Additionals, + DNSResourceRecord{ + Type: DNSTypeOPT, + Class: 4096, + OPT: []DNSOPT{ + DNSOPT{ + Code: DNSOptionCodeDeviceID, + Data: []byte("OpenDNS"), + }, + }, + }) + + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{FixLengths: true} + err := gopacket.SerializeLayers(buf, opts, dns) + if err != nil { + t.Fatal(err) + } + if int(dns.QDCount) != len(dns.Questions) { + t.Errorf("fix lengths did not adjust QDCount, expected %d got %d", len(dns.Questions), dns.QDCount) + } + if int(dns.ARCount) != len(dns.Additionals) { + t.Errorf("fix lengths did not adjust ARCount, expected %d got %d", len(dns.Additionals), dns.ARCount) + } + + p2 := gopacket.NewPacket(buf.Bytes(), LayerTypeDNS, testDecodeOptions) + dns2 := p2.Layer(LayerTypeDNS).(*DNS) + testDNSEqual(t, dns, dns2) +} + func TestDNSEncodeResponse(t *testing.T) { dns := &DNS{ID: 1234, QR: true, OpCode: DNSOpCodeQuery, AA: true, RD: true, RA: true} @@ -398,7 +499,7 @@ func TestDNSMalformedPacket2(t *testing.T) { } } -// testMalformedRootQuery is the packet: +// testBlankNameRootQuery is the packet: // 08:31:18.143065 IP 10.77.0.26.53 > 10.1.0.233.65071: 59508- 0/13/3 (508) // 0x0000: 0055 22af c637 0022 55ac deac 0800 4500 .U"..7."U.....E. // 0x0010: 0218 76b2 4000 7211 7ad2 0a4d 001a 0a01 ..v.@.r.z..M.... @@ -435,7 +536,7 @@ func TestDNSMalformedPacket2(t *testing.T) { // 0x0200: 0004 ca0c 1b21 c058 0001 0001 0000 0e10 .....!.X........ // 0x0210: 0004 c629 0004 c078 0001 0001 0000 0e10 ...)...x........ // 0x0220: 0004 c024 9411 ...$.. -var testMalformedRootQuery = []byte{ +var testBlankNameRootQuery = []byte{ 0x00, 0x55, 0x22, 0xaf, 0xc6, 0x37, 0x00, 0x22, 0x55, 0xac, 0xde, 0xac, 0x08, 0x00, 0x45, 0x00, 0x02, 0x18, 0x76, 0xb2, 0x40, 0x00, 0x72, 0x11, 0x7a, 0xd2, 0x0a, 0x4d, 0x00, 0x1a, 0x0a, 0x01, 0x00, 0xe9, 0x00, 0x35, 0xfe, 0x2f, 0x02, 0x04, 0xb8, 0xf5, 0xe8, 0x74, 0x81, 0x00, 0x00, 0x01, @@ -473,12 +574,10 @@ var testMalformedRootQuery = []byte{ 0x00, 0x04, 0xc0, 0x24, 0x94, 0x11, } -func TestMalformedRootQuery(t *testing.T) { - p := gopacket.NewPacket(testMalformedRootQuery, LinkTypeEthernet, testDecodeOptions) - if errLayer := p.ErrorLayer(); errLayer == nil { - t.Error("No error layer on invalid DNS name") - } else if err := errLayer.Error(); !strings.Contains(err.Error(), "no dns data found") { - t.Errorf("unexpected error message: %v", err) +func TestBlankNameRootQuery(t *testing.T) { + p := gopacket.NewPacket(testBlankNameRootQuery, LinkTypeEthernet, testDecodeOptions) + if err := p.ErrorLayer(); err != nil { + t.Error("Error layer on blank DNS name field:", err) } } @@ -748,6 +847,25 @@ func TestMalformedDNSOhGodMakeItStop(t *testing.T) { } } +var testMalformedDNSOPT = []byte{ + 0x00, 0x90, 0x0b, 0x12, 0x91, 0xc1, 0x00, 0x1c, 0xc0, 0x93, 0x33, 0xfb, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x5A, 0xce, 0x58, 0x00, 0x00, 0x40, 0x11, 0x67, 0xe2, 0xac, 0x10, 0x01, 0xc7, 0x4b, 0x4b, + 0x4b, 0x4b, 0xd6, 0x00, 0x00, 0x35, 0x00, 0x46, 0x44, 0xb0, 0x50, 0x12, 0x01, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x77, 0x77, 0x77, 0x04, 0x69, 0x65, 0x74, 0x66, 0x03, + 0x6f, 0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x13, 0x69, 0x42, 0x00, 0x10, 0x4F, 0x70, 0x65, 0x6E, 0x44, 0x4E, 0x53, 0x01, 0x23, + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, +} + +func TestMalformedDNSOPT(t *testing.T) { + p := gopacket.NewPacket(testMalformedDNSOPT, LinkTypeEthernet, testDecodeOptions) + if errLayer := p.ErrorLayer(); errLayer == nil { + t.Error("No error layer on invalid DNS name") + } else if err := errLayer.Error(); !strings.Contains(err.Error(), "Malformed DNSOPT record") { + t.Errorf("unexpected error message: %v", err) + } +} + // testPacketDNSPanic7 is the packet: // 07:56:25.174747 IP 10.77.0.11.53 > 10.1.0.67.55777: 41808*-| 3/7/0 TXT "google-site-verification=DC2uC-T8kD33lINhNzfo0bNBrw-vrCXs5BPF5BXY56g", TXT "v=spf1 include:spf-a.outlook.com include:spf-b.outlook.com ip4:157.55.9.128/25 include:spf.protection.outlook.com include:spf-a.hotmail.com include:_spf-ssg-b.microsoft.com include:_spf-ssg-c.microsoft.com ~all", TXT "google-site-verification=0iLWhIMhXEkeWwWfFU4ursTn-_OvoOjaA0Lr7Pg1sEM" (512) // 0x0000: 0055 22af c637 0022 55ac deac 0800 4500 .U"..7."U.....E. @@ -831,3 +949,40 @@ func TestPacketDNSPanic7(t *testing.T) { t.Errorf("unexpected error message: %v", err) } } + +func TestDNSPacketWriteAnswer(t *testing.T) { + dns := &DNS{ID: 0x1234, QR: true, OpCode: DNSOpCodeQuery, ResponseCode: DNSResponseCodeNoErr, Answers: []DNSResourceRecord{ + DNSResourceRecord{ + Name: []byte("www.example.com"), + Type: DNSTypeA, + Class: DNSClassIN, + IP: net.IPv4(127, 0, 0, 1), + }, + DNSResourceRecord{ + Name: []byte("www.example.com"), + Type: DNSTypeAAAA, + Class: DNSClassIN, + IP: net.IP{15: 1}, + }, + }} + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{ComputeChecksums: true, FixLengths: true} + if err := gopacket.SerializeLayers(buf, opts, dns); err != nil { + t.Fatal(err) + } + dns2 := &DNS{} + if err := dns2.DecodeFromBytes(buf.Bytes(), gopacket.NilDecodeFeedback); err != nil { + t.Fatalf("could not decode: %v", err) + } + if want, got := 2, len(dns2.Answers); want != got { + t.Fatalf("num answers, want %d got %d", want, got) + } else if got, want := string(dns2.Answers[0].Name), "www.example.com"; got != want { + t.Fatalf("unexpected first answer name %q, want %q", got, want) + } else if got, want := string(dns2.Answers[1].Name), "www.example.com"; got != want { + t.Fatalf("unexpected second answer name %q, want %q", got, want) + } + t.Log(gopacket.LayerString(dns2)) + if want, got := 86, len(buf.Bytes()); want != got { + t.Fatalf("Encoded size, want %d got %d", want, got) + } +} diff --git a/vendor/github.com/google/gopacket/layers/dot11.go b/vendor/github.com/google/gopacket/layers/dot11.go index 1b53026f29..3843d70bd2 100644 --- a/vendor/github.com/google/gopacket/layers/dot11.go +++ b/vendor/github.com/google/gopacket/layers/dot11.go @@ -240,24 +240,178 @@ func (a Dot11Algorithm) String() string { type Dot11InformationElementID uint8 -// TODO: Verify these element ids, and append more ids if more. - const ( - Dot11InformationElementIDSSID Dot11InformationElementID = 0 - Dot11InformationElementIDRates Dot11InformationElementID = 1 - Dot11InformationElementIDFHSet Dot11InformationElementID = 2 - Dot11InformationElementIDDSSet Dot11InformationElementID = 3 - Dot11InformationElementIDCFSet Dot11InformationElementID = 4 - Dot11InformationElementIDTIM Dot11InformationElementID = 5 - Dot11InformationElementIDIBSSSet Dot11InformationElementID = 6 - Dot11InformationElementIDChallenge Dot11InformationElementID = 16 - Dot11InformationElementIDERPInfo Dot11InformationElementID = 42 - Dot11InformationElementIDQOSCapability Dot11InformationElementID = 46 - Dot11InformationElementIDERPInfo2 Dot11InformationElementID = 47 - Dot11InformationElementIDRSNInfo Dot11InformationElementID = 48 - Dot11InformationElementIDESRates Dot11InformationElementID = 50 - Dot11InformationElementIDVendor Dot11InformationElementID = 221 - Dot11InformationElementIDReserved Dot11InformationElementID = 68 + Dot11InformationElementIDSSID Dot11InformationElementID = 0 + Dot11InformationElementIDRates Dot11InformationElementID = 1 + Dot11InformationElementIDFHSet Dot11InformationElementID = 2 + Dot11InformationElementIDDSSet Dot11InformationElementID = 3 + Dot11InformationElementIDCFSet Dot11InformationElementID = 4 + Dot11InformationElementIDTIM Dot11InformationElementID = 5 + Dot11InformationElementIDIBSSSet Dot11InformationElementID = 6 + Dot11InformationElementIDCountryInfo Dot11InformationElementID = 7 + Dot11InformationElementIDHoppingPatternParam Dot11InformationElementID = 8 + Dot11InformationElementIDHoppingPatternTable Dot11InformationElementID = 9 + Dot11InformationElementIDRequest Dot11InformationElementID = 10 + Dot11InformationElementIDQBSSLoadElem Dot11InformationElementID = 11 + Dot11InformationElementIDEDCAParamSet Dot11InformationElementID = 12 + Dot11InformationElementIDTrafficSpec Dot11InformationElementID = 13 + Dot11InformationElementIDTrafficClass Dot11InformationElementID = 14 + Dot11InformationElementIDSchedule Dot11InformationElementID = 15 + Dot11InformationElementIDChallenge Dot11InformationElementID = 16 + Dot11InformationElementIDPowerConst Dot11InformationElementID = 32 + Dot11InformationElementIDPowerCapability Dot11InformationElementID = 33 + Dot11InformationElementIDTPCRequest Dot11InformationElementID = 34 + Dot11InformationElementIDTPCReport Dot11InformationElementID = 35 + Dot11InformationElementIDSupportedChannels Dot11InformationElementID = 36 + Dot11InformationElementIDSwitchChannelAnnounce Dot11InformationElementID = 37 + Dot11InformationElementIDMeasureRequest Dot11InformationElementID = 38 + Dot11InformationElementIDMeasureReport Dot11InformationElementID = 39 + Dot11InformationElementIDQuiet Dot11InformationElementID = 40 + Dot11InformationElementIDIBSSDFS Dot11InformationElementID = 41 + Dot11InformationElementIDERPInfo Dot11InformationElementID = 42 + Dot11InformationElementIDTSDelay Dot11InformationElementID = 43 + Dot11InformationElementIDTCLASProcessing Dot11InformationElementID = 44 + Dot11InformationElementIDHTCapabilities Dot11InformationElementID = 45 + Dot11InformationElementIDQOSCapability Dot11InformationElementID = 46 + Dot11InformationElementIDERPInfo2 Dot11InformationElementID = 47 + Dot11InformationElementIDRSNInfo Dot11InformationElementID = 48 + Dot11InformationElementIDESRates Dot11InformationElementID = 50 + Dot11InformationElementIDAPChannelReport Dot11InformationElementID = 51 + Dot11InformationElementIDNeighborReport Dot11InformationElementID = 52 + Dot11InformationElementIDRCPI Dot11InformationElementID = 53 + Dot11InformationElementIDMobilityDomain Dot11InformationElementID = 54 + Dot11InformationElementIDFastBSSTrans Dot11InformationElementID = 55 + Dot11InformationElementIDTimeoutInt Dot11InformationElementID = 56 + Dot11InformationElementIDRICData Dot11InformationElementID = 57 + Dot11InformationElementIDDSERegisteredLoc Dot11InformationElementID = 58 + Dot11InformationElementIDSuppOperatingClass Dot11InformationElementID = 59 + Dot11InformationElementIDExtChanSwitchAnnounce Dot11InformationElementID = 60 + Dot11InformationElementIDHTInfo Dot11InformationElementID = 61 + Dot11InformationElementIDSecChanOffset Dot11InformationElementID = 62 + Dot11InformationElementIDBSSAverageAccessDelay Dot11InformationElementID = 63 + Dot11InformationElementIDAntenna Dot11InformationElementID = 64 + Dot11InformationElementIDRSNI Dot11InformationElementID = 65 + Dot11InformationElementIDMeasurePilotTrans Dot11InformationElementID = 66 + Dot11InformationElementIDBSSAvailAdmCapacity Dot11InformationElementID = 67 + Dot11InformationElementIDBSSACAccDelayWAPIParam Dot11InformationElementID = 68 + Dot11InformationElementIDTimeAdvertisement Dot11InformationElementID = 69 + Dot11InformationElementIDRMEnabledCapabilities Dot11InformationElementID = 70 + Dot11InformationElementIDMultipleBSSID Dot11InformationElementID = 71 + Dot11InformationElementID2040BSSCoExist Dot11InformationElementID = 72 + Dot11InformationElementID2040BSSIntChanReport Dot11InformationElementID = 73 + Dot11InformationElementIDOverlapBSSScanParam Dot11InformationElementID = 74 + Dot11InformationElementIDRICDescriptor Dot11InformationElementID = 75 + Dot11InformationElementIDManagementMIC Dot11InformationElementID = 76 + Dot11InformationElementIDEventRequest Dot11InformationElementID = 78 + Dot11InformationElementIDEventReport Dot11InformationElementID = 79 + Dot11InformationElementIDDiagnosticRequest Dot11InformationElementID = 80 + Dot11InformationElementIDDiagnosticReport Dot11InformationElementID = 81 + Dot11InformationElementIDLocationParam Dot11InformationElementID = 82 + Dot11InformationElementIDNonTransBSSIDCapability Dot11InformationElementID = 83 + Dot11InformationElementIDSSIDList Dot11InformationElementID = 84 + Dot11InformationElementIDMultipleBSSIDIndex Dot11InformationElementID = 85 + Dot11InformationElementIDFMSDescriptor Dot11InformationElementID = 86 + Dot11InformationElementIDFMSRequest Dot11InformationElementID = 87 + Dot11InformationElementIDFMSResponse Dot11InformationElementID = 88 + Dot11InformationElementIDQOSTrafficCapability Dot11InformationElementID = 89 + Dot11InformationElementIDBSSMaxIdlePeriod Dot11InformationElementID = 90 + Dot11InformationElementIDTFSRequest Dot11InformationElementID = 91 + Dot11InformationElementIDTFSResponse Dot11InformationElementID = 92 + Dot11InformationElementIDWNMSleepMode Dot11InformationElementID = 93 + Dot11InformationElementIDTIMBroadcastRequest Dot11InformationElementID = 94 + Dot11InformationElementIDTIMBroadcastResponse Dot11InformationElementID = 95 + Dot11InformationElementIDCollInterferenceReport Dot11InformationElementID = 96 + Dot11InformationElementIDChannelUsage Dot11InformationElementID = 97 + Dot11InformationElementIDTimeZone Dot11InformationElementID = 98 + Dot11InformationElementIDDMSRequest Dot11InformationElementID = 99 + Dot11InformationElementIDDMSResponse Dot11InformationElementID = 100 + Dot11InformationElementIDLinkIdentifier Dot11InformationElementID = 101 + Dot11InformationElementIDWakeupSchedule Dot11InformationElementID = 102 + Dot11InformationElementIDChannelSwitchTiming Dot11InformationElementID = 104 + Dot11InformationElementIDPTIControl Dot11InformationElementID = 105 + Dot11InformationElementIDPUBufferStatus Dot11InformationElementID = 106 + Dot11InformationElementIDInterworking Dot11InformationElementID = 107 + Dot11InformationElementIDAdvertisementProtocol Dot11InformationElementID = 108 + Dot11InformationElementIDExpBWRequest Dot11InformationElementID = 109 + Dot11InformationElementIDQOSMapSet Dot11InformationElementID = 110 + Dot11InformationElementIDRoamingConsortium Dot11InformationElementID = 111 + Dot11InformationElementIDEmergencyAlertIdentifier Dot11InformationElementID = 112 + Dot11InformationElementIDMeshConfiguration Dot11InformationElementID = 113 + Dot11InformationElementIDMeshID Dot11InformationElementID = 114 + Dot11InformationElementIDMeshLinkMetricReport Dot11InformationElementID = 115 + Dot11InformationElementIDCongestionNotification Dot11InformationElementID = 116 + Dot11InformationElementIDMeshPeeringManagement Dot11InformationElementID = 117 + Dot11InformationElementIDMeshChannelSwitchParam Dot11InformationElementID = 118 + Dot11InformationElementIDMeshAwakeWindows Dot11InformationElementID = 119 + Dot11InformationElementIDBeaconTiming Dot11InformationElementID = 120 + Dot11InformationElementIDMCCAOPSetupRequest Dot11InformationElementID = 121 + Dot11InformationElementIDMCCAOPSetupReply Dot11InformationElementID = 122 + Dot11InformationElementIDMCCAOPAdvertisement Dot11InformationElementID = 123 + Dot11InformationElementIDMCCAOPTeardown Dot11InformationElementID = 124 + Dot11InformationElementIDGateAnnouncement Dot11InformationElementID = 125 + Dot11InformationElementIDRootAnnouncement Dot11InformationElementID = 126 + Dot11InformationElementIDExtCapability Dot11InformationElementID = 127 + Dot11InformationElementIDAgereProprietary Dot11InformationElementID = 128 + Dot11InformationElementIDPathRequest Dot11InformationElementID = 130 + Dot11InformationElementIDPathReply Dot11InformationElementID = 131 + Dot11InformationElementIDPathError Dot11InformationElementID = 132 + Dot11InformationElementIDCiscoCCX1CKIPDeviceName Dot11InformationElementID = 133 + Dot11InformationElementIDCiscoCCX2 Dot11InformationElementID = 136 + Dot11InformationElementIDProxyUpdate Dot11InformationElementID = 137 + Dot11InformationElementIDProxyUpdateConfirmation Dot11InformationElementID = 138 + Dot11InformationElementIDAuthMeshPerringExch Dot11InformationElementID = 139 + Dot11InformationElementIDMIC Dot11InformationElementID = 140 + Dot11InformationElementIDDestinationURI Dot11InformationElementID = 141 + Dot11InformationElementIDUAPSDCoexistence Dot11InformationElementID = 142 + Dot11InformationElementIDWakeupSchedule80211ad Dot11InformationElementID = 143 + Dot11InformationElementIDExtendedSchedule Dot11InformationElementID = 144 + Dot11InformationElementIDSTAAvailability Dot11InformationElementID = 145 + Dot11InformationElementIDDMGTSPEC Dot11InformationElementID = 146 + Dot11InformationElementIDNextDMGATI Dot11InformationElementID = 147 + Dot11InformationElementIDDMSCapabilities Dot11InformationElementID = 148 + Dot11InformationElementIDCiscoUnknown95 Dot11InformationElementID = 149 + Dot11InformationElementIDVendor2 Dot11InformationElementID = 150 + Dot11InformationElementIDDMGOperating Dot11InformationElementID = 151 + Dot11InformationElementIDDMGBSSParamChange Dot11InformationElementID = 152 + Dot11InformationElementIDDMGBeamRefinement Dot11InformationElementID = 153 + Dot11InformationElementIDChannelMeasFeedback Dot11InformationElementID = 154 + Dot11InformationElementIDAwakeWindow Dot11InformationElementID = 157 + Dot11InformationElementIDMultiBand Dot11InformationElementID = 158 + Dot11InformationElementIDADDBAExtension Dot11InformationElementID = 159 + Dot11InformationElementIDNEXTPCPList Dot11InformationElementID = 160 + Dot11InformationElementIDPCPHandover Dot11InformationElementID = 161 + Dot11InformationElementIDDMGLinkMargin Dot11InformationElementID = 162 + Dot11InformationElementIDSwitchingStream Dot11InformationElementID = 163 + Dot11InformationElementIDSessionTransmission Dot11InformationElementID = 164 + Dot11InformationElementIDDynamicTonePairReport Dot11InformationElementID = 165 + Dot11InformationElementIDClusterReport Dot11InformationElementID = 166 + Dot11InformationElementIDRelayCapabilities Dot11InformationElementID = 167 + Dot11InformationElementIDRelayTransferParameter Dot11InformationElementID = 168 + Dot11InformationElementIDBeamlinkMaintenance Dot11InformationElementID = 169 + Dot11InformationElementIDMultipleMacSublayers Dot11InformationElementID = 170 + Dot11InformationElementIDUPID Dot11InformationElementID = 171 + Dot11InformationElementIDDMGLinkAdaptionAck Dot11InformationElementID = 172 + Dot11InformationElementIDSymbolProprietary Dot11InformationElementID = 173 + Dot11InformationElementIDMCCAOPAdvertOverview Dot11InformationElementID = 174 + Dot11InformationElementIDQuietPeriodRequest Dot11InformationElementID = 175 + Dot11InformationElementIDQuietPeriodResponse Dot11InformationElementID = 177 + Dot11InformationElementIDECPACPolicy Dot11InformationElementID = 182 + Dot11InformationElementIDClusterTimeOffset Dot11InformationElementID = 183 + Dot11InformationElementIDAntennaSectorID Dot11InformationElementID = 190 + Dot11InformationElementIDVHTCapabilities Dot11InformationElementID = 191 + Dot11InformationElementIDVHTOperation Dot11InformationElementID = 192 + Dot11InformationElementIDExtendedBSSLoad Dot11InformationElementID = 193 + Dot11InformationElementIDWideBWChannelSwitch Dot11InformationElementID = 194 + Dot11InformationElementIDVHTTxPowerEnvelope Dot11InformationElementID = 195 + Dot11InformationElementIDChannelSwitchWrapper Dot11InformationElementID = 196 + Dot11InformationElementIDOperatingModeNotification Dot11InformationElementID = 199 + Dot11InformationElementIDUPSIM Dot11InformationElementID = 200 + Dot11InformationElementIDReducedNeighborReport Dot11InformationElementID = 201 + Dot11InformationElementIDTVHTOperation Dot11InformationElementID = 202 + Dot11InformationElementIDDeviceLocation Dot11InformationElementID = 204 + Dot11InformationElementIDWhiteSpaceMap Dot11InformationElementID = 205 + Dot11InformationElementIDFineTuningMeasureParams Dot11InformationElementID = 206 + Dot11InformationElementIDVendor Dot11InformationElementID = 221 ) // String provides a human readable string for Dot11InformationElementID. @@ -267,35 +421,347 @@ const ( func (a Dot11InformationElementID) String() string { switch a { case Dot11InformationElementIDSSID: - return "SSID" + return "SSID parameter set" case Dot11InformationElementIDRates: - return "Rates" + return "Supported Rates" case Dot11InformationElementIDFHSet: - return "FHset" + return "FH Parameter set" case Dot11InformationElementIDDSSet: - return "DSset" + return "DS Parameter set" case Dot11InformationElementIDCFSet: - return "CFset" + return "CF Parameter set" case Dot11InformationElementIDTIM: - return "TIM" + return "Traffic Indication Map (TIM)" case Dot11InformationElementIDIBSSSet: - return "IBSSset" + return "IBSS Parameter set" + case Dot11InformationElementIDCountryInfo: + return "Country Information" + case Dot11InformationElementIDHoppingPatternParam: + return "Hopping Pattern Parameters" + case Dot11InformationElementIDHoppingPatternTable: + return "Hopping Pattern Table" + case Dot11InformationElementIDRequest: + return "Request" + case Dot11InformationElementIDQBSSLoadElem: + return "QBSS Load Element" + case Dot11InformationElementIDEDCAParamSet: + return "EDCA Parameter Set" + case Dot11InformationElementIDTrafficSpec: + return "Traffic Specification" + case Dot11InformationElementIDTrafficClass: + return "Traffic Classification" + case Dot11InformationElementIDSchedule: + return "Schedule" case Dot11InformationElementIDChallenge: - return "Challenge" + return "Challenge text" + case Dot11InformationElementIDPowerConst: + return "Power Constraint" + case Dot11InformationElementIDPowerCapability: + return "Power Capability" + case Dot11InformationElementIDTPCRequest: + return "TPC Request" + case Dot11InformationElementIDTPCReport: + return "TPC Report" + case Dot11InformationElementIDSupportedChannels: + return "Supported Channels" + case Dot11InformationElementIDSwitchChannelAnnounce: + return "Channel Switch Announcement" + case Dot11InformationElementIDMeasureRequest: + return "Measurement Request" + case Dot11InformationElementIDMeasureReport: + return "Measurement Report" + case Dot11InformationElementIDQuiet: + return "Quiet" + case Dot11InformationElementIDIBSSDFS: + return "IBSS DFS" case Dot11InformationElementIDERPInfo: - return "ERPinfo" + return "ERP Information" + case Dot11InformationElementIDTSDelay: + return "TS Delay" + case Dot11InformationElementIDTCLASProcessing: + return "TCLAS Processing" + case Dot11InformationElementIDHTCapabilities: + return "HT Capabilities (802.11n D1.10)" case Dot11InformationElementIDQOSCapability: - return "QOS capability" + return "QOS Capability" case Dot11InformationElementIDERPInfo2: - return "ERPinfo2" + return "ERP Information-2" case Dot11InformationElementIDRSNInfo: - return "RSNinfo" + return "RSN Information" case Dot11InformationElementIDESRates: - return "ESrates" + return "Extended Supported Rates" + case Dot11InformationElementIDAPChannelReport: + return "AP Channel Report" + case Dot11InformationElementIDNeighborReport: + return "Neighbor Report" + case Dot11InformationElementIDRCPI: + return "RCPI" + case Dot11InformationElementIDMobilityDomain: + return "Mobility Domain" + case Dot11InformationElementIDFastBSSTrans: + return "Fast BSS Transition" + case Dot11InformationElementIDTimeoutInt: + return "Timeout Interval" + case Dot11InformationElementIDRICData: + return "RIC Data" + case Dot11InformationElementIDDSERegisteredLoc: + return "DSE Registered Location" + case Dot11InformationElementIDSuppOperatingClass: + return "Supported Operating Classes" + case Dot11InformationElementIDExtChanSwitchAnnounce: + return "Extended Channel Switch Announcement" + case Dot11InformationElementIDHTInfo: + return "HT Information (802.11n D1.10)" + case Dot11InformationElementIDSecChanOffset: + return "Secondary Channel Offset (802.11n D1.10)" + case Dot11InformationElementIDBSSAverageAccessDelay: + return "BSS Average Access Delay" + case Dot11InformationElementIDAntenna: + return "Antenna" + case Dot11InformationElementIDRSNI: + return "RSNI" + case Dot11InformationElementIDMeasurePilotTrans: + return "Measurement Pilot Transmission" + case Dot11InformationElementIDBSSAvailAdmCapacity: + return "BSS Available Admission Capacity" + case Dot11InformationElementIDBSSACAccDelayWAPIParam: + return "BSS AC Access Delay/WAPI Parameter Set" + case Dot11InformationElementIDTimeAdvertisement: + return "Time Advertisement" + case Dot11InformationElementIDRMEnabledCapabilities: + return "RM Enabled Capabilities" + case Dot11InformationElementIDMultipleBSSID: + return "Multiple BSSID" + case Dot11InformationElementID2040BSSCoExist: + return "20/40 BSS Coexistence" + case Dot11InformationElementID2040BSSIntChanReport: + return "20/40 BSS Intolerant Channel Report" + case Dot11InformationElementIDOverlapBSSScanParam: + return "Overlapping BSS Scan Parameters" + case Dot11InformationElementIDRICDescriptor: + return "RIC Descriptor" + case Dot11InformationElementIDManagementMIC: + return "Management MIC" + case Dot11InformationElementIDEventRequest: + return "Event Request" + case Dot11InformationElementIDEventReport: + return "Event Report" + case Dot11InformationElementIDDiagnosticRequest: + return "Diagnostic Request" + case Dot11InformationElementIDDiagnosticReport: + return "Diagnostic Report" + case Dot11InformationElementIDLocationParam: + return "Location Parameters" + case Dot11InformationElementIDNonTransBSSIDCapability: + return "Non Transmitted BSSID Capability" + case Dot11InformationElementIDSSIDList: + return "SSID List" + case Dot11InformationElementIDMultipleBSSIDIndex: + return "Multiple BSSID Index" + case Dot11InformationElementIDFMSDescriptor: + return "FMS Descriptor" + case Dot11InformationElementIDFMSRequest: + return "FMS Request" + case Dot11InformationElementIDFMSResponse: + return "FMS Response" + case Dot11InformationElementIDQOSTrafficCapability: + return "QoS Traffic Capability" + case Dot11InformationElementIDBSSMaxIdlePeriod: + return "BSS Max Idle Period" + case Dot11InformationElementIDTFSRequest: + return "TFS Request" + case Dot11InformationElementIDTFSResponse: + return "TFS Response" + case Dot11InformationElementIDWNMSleepMode: + return "WNM-Sleep Mode" + case Dot11InformationElementIDTIMBroadcastRequest: + return "TIM Broadcast Request" + case Dot11InformationElementIDTIMBroadcastResponse: + return "TIM Broadcast Response" + case Dot11InformationElementIDCollInterferenceReport: + return "Collocated Interference Report" + case Dot11InformationElementIDChannelUsage: + return "Channel Usage" + case Dot11InformationElementIDTimeZone: + return "Time Zone" + case Dot11InformationElementIDDMSRequest: + return "DMS Request" + case Dot11InformationElementIDDMSResponse: + return "DMS Response" + case Dot11InformationElementIDLinkIdentifier: + return "Link Identifier" + case Dot11InformationElementIDWakeupSchedule: + return "Wakeup Schedule" + case Dot11InformationElementIDChannelSwitchTiming: + return "Channel Switch Timing" + case Dot11InformationElementIDPTIControl: + return "PTI Control" + case Dot11InformationElementIDPUBufferStatus: + return "PU Buffer Status" + case Dot11InformationElementIDInterworking: + return "Interworking" + case Dot11InformationElementIDAdvertisementProtocol: + return "Advertisement Protocol" + case Dot11InformationElementIDExpBWRequest: + return "Expedited Bandwidth Request" + case Dot11InformationElementIDQOSMapSet: + return "QoS Map Set" + case Dot11InformationElementIDRoamingConsortium: + return "Roaming Consortium" + case Dot11InformationElementIDEmergencyAlertIdentifier: + return "Emergency Alert Identifier" + case Dot11InformationElementIDMeshConfiguration: + return "Mesh Configuration" + case Dot11InformationElementIDMeshID: + return "Mesh ID" + case Dot11InformationElementIDMeshLinkMetricReport: + return "Mesh Link Metric Report" + case Dot11InformationElementIDCongestionNotification: + return "Congestion Notification" + case Dot11InformationElementIDMeshPeeringManagement: + return "Mesh Peering Management" + case Dot11InformationElementIDMeshChannelSwitchParam: + return "Mesh Channel Switch Parameters" + case Dot11InformationElementIDMeshAwakeWindows: + return "Mesh Awake Windows" + case Dot11InformationElementIDBeaconTiming: + return "Beacon Timing" + case Dot11InformationElementIDMCCAOPSetupRequest: + return "MCCAOP Setup Request" + case Dot11InformationElementIDMCCAOPSetupReply: + return "MCCAOP SETUP Reply" + case Dot11InformationElementIDMCCAOPAdvertisement: + return "MCCAOP Advertisement" + case Dot11InformationElementIDMCCAOPTeardown: + return "MCCAOP Teardown" + case Dot11InformationElementIDGateAnnouncement: + return "Gate Announcement" + case Dot11InformationElementIDRootAnnouncement: + return "Root Announcement" + case Dot11InformationElementIDExtCapability: + return "Extended Capabilities" + case Dot11InformationElementIDAgereProprietary: + return "Agere Proprietary" + case Dot11InformationElementIDPathRequest: + return "Path Request" + case Dot11InformationElementIDPathReply: + return "Path Reply" + case Dot11InformationElementIDPathError: + return "Path Error" + case Dot11InformationElementIDCiscoCCX1CKIPDeviceName: + return "Cisco CCX1 CKIP + Device Name" + case Dot11InformationElementIDCiscoCCX2: + return "Cisco CCX2" + case Dot11InformationElementIDProxyUpdate: + return "Proxy Update" + case Dot11InformationElementIDProxyUpdateConfirmation: + return "Proxy Update Confirmation" + case Dot11InformationElementIDAuthMeshPerringExch: + return "Auhenticated Mesh Perring Exchange" + case Dot11InformationElementIDMIC: + return "MIC (Message Integrity Code)" + case Dot11InformationElementIDDestinationURI: + return "Destination URI" + case Dot11InformationElementIDUAPSDCoexistence: + return "U-APSD Coexistence" + case Dot11InformationElementIDWakeupSchedule80211ad: + return "Wakeup Schedule 802.11ad" + case Dot11InformationElementIDExtendedSchedule: + return "Extended Schedule" + case Dot11InformationElementIDSTAAvailability: + return "STA Availability" + case Dot11InformationElementIDDMGTSPEC: + return "DMG TSPEC" + case Dot11InformationElementIDNextDMGATI: + return "Next DMG ATI" + case Dot11InformationElementIDDMSCapabilities: + return "DMG Capabilities" + case Dot11InformationElementIDCiscoUnknown95: + return "Cisco Unknown 95" + case Dot11InformationElementIDVendor2: + return "Vendor Specific" + case Dot11InformationElementIDDMGOperating: + return "DMG Operating" + case Dot11InformationElementIDDMGBSSParamChange: + return "DMG BSS Parameter Change" + case Dot11InformationElementIDDMGBeamRefinement: + return "DMG Beam Refinement" + case Dot11InformationElementIDChannelMeasFeedback: + return "Channel Measurement Feedback" + case Dot11InformationElementIDAwakeWindow: + return "Awake Window" + case Dot11InformationElementIDMultiBand: + return "Multi Band" + case Dot11InformationElementIDADDBAExtension: + return "ADDBA Extension" + case Dot11InformationElementIDNEXTPCPList: + return "NEXTPCP List" + case Dot11InformationElementIDPCPHandover: + return "PCP Handover" + case Dot11InformationElementIDDMGLinkMargin: + return "DMG Link Margin" + case Dot11InformationElementIDSwitchingStream: + return "Switching Stream" + case Dot11InformationElementIDSessionTransmission: + return "Session Transmission" + case Dot11InformationElementIDDynamicTonePairReport: + return "Dynamic Tone Pairing Report" + case Dot11InformationElementIDClusterReport: + return "Cluster Report" + case Dot11InformationElementIDRelayCapabilities: + return "Relay Capabilities" + case Dot11InformationElementIDRelayTransferParameter: + return "Relay Transfer Parameter" + case Dot11InformationElementIDBeamlinkMaintenance: + return "Beamlink Maintenance" + case Dot11InformationElementIDMultipleMacSublayers: + return "Multiple MAC Sublayers" + case Dot11InformationElementIDUPID: + return "U-PID" + case Dot11InformationElementIDDMGLinkAdaptionAck: + return "DMG Link Adaption Acknowledgment" + case Dot11InformationElementIDSymbolProprietary: + return "Symbol Proprietary" + case Dot11InformationElementIDMCCAOPAdvertOverview: + return "MCCAOP Advertisement Overview" + case Dot11InformationElementIDQuietPeriodRequest: + return "Quiet Period Request" + case Dot11InformationElementIDQuietPeriodResponse: + return "Quiet Period Response" + case Dot11InformationElementIDECPACPolicy: + return "ECPAC Policy" + case Dot11InformationElementIDClusterTimeOffset: + return "Cluster Time Offset" + case Dot11InformationElementIDAntennaSectorID: + return "Antenna Sector ID" + case Dot11InformationElementIDVHTCapabilities: + return "VHT Capabilities (IEEE Std 802.11ac/D3.1)" + case Dot11InformationElementIDVHTOperation: + return "VHT Operation (IEEE Std 802.11ac/D3.1)" + case Dot11InformationElementIDExtendedBSSLoad: + return "Extended BSS Load" + case Dot11InformationElementIDWideBWChannelSwitch: + return "Wide Bandwidth Channel Switch" + case Dot11InformationElementIDVHTTxPowerEnvelope: + return "VHT Tx Power Envelope (IEEE Std 802.11ac/D5.0)" + case Dot11InformationElementIDChannelSwitchWrapper: + return "Channel Switch Wrapper" + case Dot11InformationElementIDOperatingModeNotification: + return "Operating Mode Notification" + case Dot11InformationElementIDUPSIM: + return "UP SIM" + case Dot11InformationElementIDReducedNeighborReport: + return "Reduced Neighbor Report" + case Dot11InformationElementIDTVHTOperation: + return "TVHT Op" + case Dot11InformationElementIDDeviceLocation: + return "Device Location" + case Dot11InformationElementIDWhiteSpaceMap: + return "White Space Map" + case Dot11InformationElementIDFineTuningMeasureParams: + return "Fine Tuning Measure Parameters" case Dot11InformationElementIDVendor: return "Vendor" - case Dot11InformationElementIDReserved: - return "Reserved" default: return "Unknown information element id" } @@ -303,7 +769,7 @@ func (a Dot11InformationElementID) String() string { // Dot11 provides an IEEE 802.11 base packet header. // See http://standards.ieee.org/findstds/standard/802.11-2012.html -// for excrutiating detail. +// for excruciating detail. type Dot11 struct { BaseLayer Type Dot11Type @@ -317,23 +783,138 @@ type Dot11 struct { SequenceNumber uint16 FragmentNumber uint16 Checksum uint32 + QOS *Dot11QOS + HTControl *Dot11HTControl + DataLayer gopacket.Layer +} + +type Dot11QOS struct { + TID uint8 /* Traffic IDentifier */ + EOSP bool /* End of service period */ + AckPolicy Dot11AckPolicy + TXOP uint8 +} + +type Dot11HTControl struct { + ACConstraint bool + RDGMorePPDU bool + + VHT *Dot11HTControlVHT + HT *Dot11HTControlHT +} + +type Dot11HTControlHT struct { + LinkAdapationControl *Dot11LinkAdapationControl + CalibrationPosition uint8 + CalibrationSequence uint8 + CSISteering uint8 + NDPAnnouncement bool + DEI bool +} + +type Dot11HTControlVHT struct { + MRQ bool + UnsolicitedMFB bool + MSI *uint8 + MFB Dot11HTControlMFB + CompressedMSI *uint8 + STBCIndication bool + MFSI *uint8 + GID *uint8 + CodingType *Dot11CodingType + FbTXBeamformed bool +} + +type Dot11HTControlMFB struct { + NumSTS uint8 + VHTMCS uint8 + BW uint8 + SNR int8 +} + +type Dot11LinkAdapationControl struct { + TRQ bool + MRQ bool + MSI uint8 + MFSI uint8 + ASEL *Dot11ASEL + MFB *uint8 +} + +type Dot11ASEL struct { + Command uint8 + Data uint8 +} + +type Dot11CodingType uint8 + +const ( + Dot11CodingTypeBCC = 0 + Dot11CodingTypeLDPC = 1 +) + +func (a Dot11CodingType) String() string { + switch a { + case Dot11CodingTypeBCC: + return "BCC" + case Dot11CodingTypeLDPC: + return "LDPC" + default: + return "Unknown coding type" + } +} + +func (m *Dot11HTControlMFB) NoFeedBackPresent() bool { + return m.VHTMCS == 15 && m.NumSTS == 7 } func decodeDot11(data []byte, p gopacket.PacketBuilder) error { d := &Dot11{} - return decodingLayerDecoder(d, data, p) + err := d.DecodeFromBytes(data, p) + if err != nil { + return err + } + p.AddLayer(d) + if d.DataLayer != nil { + p.AddLayer(d.DataLayer) + } + return p.NextDecoder(d.NextLayerType()) } func (m *Dot11) LayerType() gopacket.LayerType { return LayerTypeDot11 } func (m *Dot11) CanDecode() gopacket.LayerClass { return LayerTypeDot11 } func (m *Dot11) NextLayerType() gopacket.LayerType { - if m.Flags.WEP() { - return (LayerTypeDot11WEP) + if m.DataLayer != nil { + if m.Flags.WEP() { + return LayerTypeDot11WEP + } + return m.DataLayer.(gopacket.DecodingLayer).NextLayerType() } - return m.Type.LayerType() } +func createU8(x uint8) *uint8 { + return &x +} + +var dataDecodeMap = map[Dot11Type]func() gopacket.DecodingLayer{ + Dot11TypeData: func() gopacket.DecodingLayer { return &Dot11Data{} }, + Dot11TypeDataCFAck: func() gopacket.DecodingLayer { return &Dot11DataCFAck{} }, + Dot11TypeDataCFPoll: func() gopacket.DecodingLayer { return &Dot11DataCFPoll{} }, + Dot11TypeDataCFAckPoll: func() gopacket.DecodingLayer { return &Dot11DataCFAckPoll{} }, + Dot11TypeDataNull: func() gopacket.DecodingLayer { return &Dot11DataNull{} }, + Dot11TypeDataCFAckNoData: func() gopacket.DecodingLayer { return &Dot11DataCFAckNoData{} }, + Dot11TypeDataCFPollNoData: func() gopacket.DecodingLayer { return &Dot11DataCFPollNoData{} }, + Dot11TypeDataCFAckPollNoData: func() gopacket.DecodingLayer { return &Dot11DataCFAckPollNoData{} }, + Dot11TypeDataQOSData: func() gopacket.DecodingLayer { return &Dot11DataQOSData{} }, + Dot11TypeDataQOSDataCFAck: func() gopacket.DecodingLayer { return &Dot11DataQOSDataCFAck{} }, + Dot11TypeDataQOSDataCFPoll: func() gopacket.DecodingLayer { return &Dot11DataQOSDataCFPoll{} }, + Dot11TypeDataQOSDataCFAckPoll: func() gopacket.DecodingLayer { return &Dot11DataQOSDataCFAckPoll{} }, + Dot11TypeDataQOSNull: func() gopacket.DecodingLayer { return &Dot11DataQOSNull{} }, + Dot11TypeDataQOSCFPollNoData: func() gopacket.DecodingLayer { return &Dot11DataQOSCFPollNoData{} }, + Dot11TypeDataQOSCFAckPollNoData: func() gopacket.DecodingLayer { return &Dot11DataQOSCFAckPollNoData{} }, +} + func (m *Dot11) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { if len(data) < 10 { df.SetTruncated() @@ -385,7 +966,112 @@ func (m *Dot11) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { offset += 6 } - m.BaseLayer = BaseLayer{Contents: data[0:offset], Payload: data[offset : len(data)-4]} + if m.Type.QOS() { + if len(data) < offset+2 { + df.SetTruncated() + return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+6) + } + m.QOS = &Dot11QOS{ + TID: (uint8(data[offset]) & 0x0F), + EOSP: (uint8(data[offset]) & 0x10) == 0x10, + AckPolicy: Dot11AckPolicy((uint8(data[offset]) & 0x60) >> 5), + TXOP: uint8(data[offset+1]), + } + offset += 2 + } + if m.Flags.Order() && (m.Type.QOS() || mainType == Dot11TypeMgmt) { + if len(data) < offset+4 { + df.SetTruncated() + return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+6) + } + + htc := &Dot11HTControl{ + ACConstraint: data[offset+3]&0x40 != 0, + RDGMorePPDU: data[offset+3]&0x80 != 0, + } + m.HTControl = htc + + if data[offset]&0x1 != 0 { // VHT Variant + vht := &Dot11HTControlVHT{} + htc.VHT = vht + vht.MRQ = data[offset]&0x4 != 0 + vht.UnsolicitedMFB = data[offset+3]&0x20 != 0 + vht.MFB = Dot11HTControlMFB{ + NumSTS: uint8(data[offset+1] >> 1 & 0x7), + VHTMCS: uint8(data[offset+1] >> 4 & 0xF), + BW: uint8(data[offset+2] & 0x3), + SNR: int8((-(data[offset+2] >> 2 & 0x20))+data[offset+2]>>2&0x1F) + 22, + } + + if vht.UnsolicitedMFB { + if !vht.MFB.NoFeedBackPresent() { + vht.CompressedMSI = createU8(data[offset] >> 3 & 0x3) + vht.STBCIndication = data[offset]&0x20 != 0 + vht.CodingType = (*Dot11CodingType)(createU8(data[offset+3] >> 3 & 0x1)) + vht.FbTXBeamformed = data[offset+3]&0x10 != 0 + vht.GID = createU8( + data[offset]>>6 + + (data[offset+1] & 0x1 << 2) + + data[offset+3]&0x7<<3) + } + } else { + if vht.MRQ { + vht.MSI = createU8((data[offset] >> 3) & 0x07) + } + vht.MFSI = createU8(data[offset]>>6 + (data[offset+1] & 0x1 << 2)) + } + + } else { // HT Variant + ht := &Dot11HTControlHT{} + htc.HT = ht + + lac := &Dot11LinkAdapationControl{} + ht.LinkAdapationControl = lac + lac.TRQ = data[offset]&0x2 != 0 + lac.MFSI = data[offset]>>6&0x3 + data[offset+1]&0x1<<3 + if data[offset]&0x3C == 0x38 { // ASEL + lac.ASEL = &Dot11ASEL{ + Command: data[offset+1] >> 1 & 0x7, + Data: data[offset+1] >> 4 & 0xF, + } + } else { + lac.MRQ = data[offset]&0x4 != 0 + if lac.MRQ { + lac.MSI = data[offset] >> 3 & 0x7 + } + lac.MFB = createU8(data[offset+1] >> 1) + } + ht.CalibrationPosition = data[offset+2] & 0x3 + ht.CalibrationSequence = data[offset+2] >> 2 & 0x3 + ht.CSISteering = data[offset+2] >> 6 & 0x3 + ht.NDPAnnouncement = data[offset+3]&0x1 != 0 + if mainType != Dot11TypeMgmt { + ht.DEI = data[offset+3]&0x20 != 0 + } + } + + offset += 4 + } + + if len(data) < offset+4 { + df.SetTruncated() + return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+4) + } + + m.BaseLayer = BaseLayer{ + Contents: data[0:offset], + Payload: data[offset : len(data)-4], + } + + if mainType == Dot11TypeData { + l := dataDecodeMap[m.Type]() + err := l.DecodeFromBytes(m.BaseLayer.Payload, df) + if err != nil { + return err + } + m.DataLayer = l.(gopacket.Layer) + } + m.Checksum = binary.LittleEndian.Uint32(data[len(data)-4 : len(data)]) return nil } @@ -474,7 +1160,7 @@ type Dot11WEP struct { BaseLayer } -func (m *Dot11WEP) NextLayerType() gopacket.LayerType { return LayerTypeLLC } +func (m *Dot11WEP) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload } func (m *Dot11WEP) LayerType() gopacket.LayerType { return LayerTypeDot11WEP } func (m *Dot11WEP) CanDecode() gopacket.LayerClass { return LayerTypeDot11WEP } @@ -493,7 +1179,9 @@ type Dot11Data struct { BaseLayer } -func (m *Dot11Data) NextLayerType() gopacket.LayerType { return LayerTypeLLC } +func (m *Dot11Data) NextLayerType() gopacket.LayerType { + return LayerTypeLLC +} func (m *Dot11Data) LayerType() gopacket.LayerType { return LayerTypeDot11Data } func (m *Dot11Data) CanDecode() gopacket.LayerClass { return LayerTypeDot11Data } @@ -618,23 +1306,10 @@ func (m *Dot11DataCFAckPollNoData) DecodeFromBytes(data []byte, df gopacket.Deco type Dot11DataQOS struct { Dot11Ctrl - TID uint8 /* Traffic IDentifier */ - EOSP bool /* End of service period */ - AckPolicy Dot11AckPolicy - TXOP uint8 } func (m *Dot11DataQOS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { - if len(data) < 4 { - df.SetTruncated() - return fmt.Errorf("Dot11DataQOS length %v too short, %v required", len(data), 4) - } - m.TID = (uint8(data[0]) & 0x0F) - m.EOSP = (uint8(data[0]) & 0x10) == 0x10 - m.AckPolicy = Dot11AckPolicy((uint8(data[0]) & 0x60) >> 5) - m.TXOP = uint8(data[1]) - // TODO: Mesh Control bytes 2:4 - m.BaseLayer = BaseLayer{Contents: data[0:4], Payload: data[4:]} + m.BaseLayer = BaseLayer{Payload: data} return nil } @@ -802,7 +1477,7 @@ func (m *Dot11InformationElement) DecodeFromBytes(data []byte, df gopacket.Decod func (d *Dot11InformationElement) String() string { if d.ID == 0 { - return fmt.Sprintf("802.11 Information Element (SSID: %v)", string(d.Info)) + return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, SSID: %v)", d.ID, d.Length, string(d.Info)) } else if d.ID == 1 { rates := "" for i := 0; i < len(d.Info); i++ { @@ -812,9 +1487,9 @@ func (d *Dot11InformationElement) String() string { rates += fmt.Sprintf("%.1f* ", float32(d.Info[i]&0x7F)*0.5) } } - return fmt.Sprintf("802.11 Information Element (Rates: %s Mbit)", rates) + return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, Rates: %s Mbit)", d.ID, d.Length, rates) } else if d.ID == 221 { - return fmt.Sprintf("802.11 Information Element (Vendor: ID: %v, Length: %v, OUI: %X, Info: %X)", d.ID, d.Length, d.OUI, d.Info) + return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, OUI: %X, Info: %X)", d.ID, d.Length, d.OUI, d.Info) } else { return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, Info: %X)", d.ID, d.Length, d.Info) } diff --git a/vendor/github.com/google/gopacket/layers/dot11_test.go b/vendor/github.com/google/gopacket/layers/dot11_test.go index b0299fc629..f734fbcf33 100644 --- a/vendor/github.com/google/gopacket/layers/dot11_test.go +++ b/vendor/github.com/google/gopacket/layers/dot11_test.go @@ -464,7 +464,7 @@ func TestPacketP6196(t *testing.T) { t.Error("Failed to decode packet:", p.ErrorLayer().Error()) } - checkLayers(p, []gopacket.LayerType{LayerTypeRadioTap, LayerTypeDot11, LayerTypeDot11WEP}, t) + checkLayers(p, []gopacket.LayerType{LayerTypeRadioTap, LayerTypeDot11, LayerTypeDot11DataQOSData, LayerTypeDot11WEP}, t) } func BenchmarkDecodePacketP6196(b *testing.B) { @@ -473,6 +473,69 @@ func BenchmarkDecodePacketP6196(b *testing.B) { } } +// testPacketDot11HTControl is the packet: +// 0000 00 00 26 00 2b 48 20 00 bf 70 06 02 00 00 00 00 ..&.+H .¿p...... +// 0010 40 00 78 14 40 01 b8 00 00 00 44 00 00 01 73 00 @.x.@.¸...D...s. +// 0020 00 00 00 00 00 00 88 c9 30 14 01 02 03 04 05 06 .......É0.ò.Jòs} +// 0030 11 12 13 14 15 16 21 22 23 24 25 26 c0 bd 00 14 .öP.6:M 2.Á7À½.. +// 0040 0e 28 00 a8 06 01 00 04 e6 73 b3 4a 24 3e 19 ea .(.¨....æs³J$>.ê +// 0050 2a b7 1f 3c c7 89 2b 22 e2 2b 28 6c 69 aa 0a ee *·.<Ç.+"â+(liª.î +// 0060 1e bc 2d 2a 00 35 68 39 ad 6f 29 52 38 07 ae cf .¼-*.5h9.o)R8.®Ï +// 0070 03 e7 0d 53 8b 3c 12 28 52 05 cc 70 be c7 68 5e .ç.S.<.(R.Ìp¾Çh^ +// 0080 5f b1 06 f4 73 22 63 ef 77 41 7b 86 _±.ôs"cïwA{. +var testPacketDot11HTControl = []byte{ + 0x00, 0x00, 0x26, 0x00, 0x2b, 0x48, 0x20, 0x00, 0xbf, 0x70, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x78, 0x14, 0x40, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x01, 0x73, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xc9, 0x30, 0x14, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0xc0, 0xbd, 0x00, 0x14, + 0x0e, 0x28, 0x00, 0xa8, 0x06, 0x01, 0x00, 0x04, 0xe6, 0x73, 0xb3, 0x4a, 0x24, 0x3e, 0x19, 0xea, + 0x2a, 0xb7, 0x1f, 0x3c, 0xc7, 0x89, 0x2b, 0x22, 0xe2, 0x2b, 0x28, 0x6c, 0x69, 0xaa, 0x0a, 0xee, + 0x1e, 0xbc, 0x2d, 0x2a, 0x00, 0x35, 0x68, 0x39, 0xad, 0x6f, 0x29, 0x52, 0x38, 0x07, 0xae, 0xcf, + 0x03, 0xe7, 0x0d, 0x53, 0x8b, 0x3c, 0x12, 0x28, 0x52, 0x05, 0xcc, 0x70, 0xbe, 0xc7, 0x68, 0x5e, + 0x5f, 0xb1, 0x06, 0xf4, 0x73, 0x22, 0x63, 0xef, 0x77, 0x41, 0x7b, 0x86, +} + +var mfb = uint8(20) + +var wantHTControl = Dot11HTControl{ + ACConstraint: false, + RDGMorePPDU: true, + HT: &Dot11HTControlHT{ + LinkAdapationControl: &Dot11LinkAdapationControl{ + TRQ: true, + MRQ: true, + MSI: 1, + MFSI: 0, + ASEL: nil, + MFB: &mfb, + }, + CalibrationPosition: 0, + CalibrationSequence: 0, + CSISteering: 0, + NDPAnnouncement: false, + DEI: true, + }, +} + +func TestPacketDot11HTControl(t *testing.T) { + p := gopacket.NewPacket(testPacketDot11HTControl, LinkTypeIEEE80211Radio, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + + checkLayers(p, []gopacket.LayerType{LayerTypeRadioTap, LayerTypeDot11, LayerTypeDot11DataQOSData, LayerTypeDot11WEP}, t) + + ld11 := p.Layer(LayerTypeDot11) + if dot11, ok := ld11.(*Dot11); ok { + if dot11.HTControl == nil { + t.Fatal("Packet didn't contain HTControl") + } + if !reflect.DeepEqual(*dot11.HTControl, wantHTControl) { + t.Errorf("Dot11 packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", dot11.HTControl, wantHTControl) + } + } +} + func TestInformationElement(t *testing.T) { bin := []byte{ 0, 0, diff --git a/vendor/github.com/google/gopacket/layers/eapol.go b/vendor/github.com/google/gopacket/layers/eapol.go index 041cd59425..12aa5ba26c 100644 --- a/vendor/github.com/google/gopacket/layers/eapol.go +++ b/vendor/github.com/google/gopacket/layers/eapol.go @@ -8,6 +8,7 @@ package layers import ( "encoding/binary" + "fmt" "github.com/google/gopacket" ) @@ -55,3 +56,243 @@ func decodeEAPOL(data []byte, p gopacket.PacketBuilder) error { e := &EAPOL{} return decodingLayerDecoder(e, data, p) } + +// EAPOLKeyDescriptorType is an enumeration of key descriptor types +// as specified by 802.1x in the EAPOL-Key frame +type EAPOLKeyDescriptorType uint8 + +// Enumeration of EAPOLKeyDescriptorType +const ( + EAPOLKeyDescriptorTypeRC4 EAPOLKeyDescriptorType = 1 + EAPOLKeyDescriptorTypeDot11 EAPOLKeyDescriptorType = 2 + EAPOLKeyDescriptorTypeWPA EAPOLKeyDescriptorType = 254 +) + +func (kdt EAPOLKeyDescriptorType) String() string { + switch kdt { + case EAPOLKeyDescriptorTypeRC4: + return "RC4" + case EAPOLKeyDescriptorTypeDot11: + return "802.11" + case EAPOLKeyDescriptorTypeWPA: + return "WPA" + default: + return fmt.Sprintf("unknown descriptor type %d", kdt) + } +} + +// EAPOLKeyDescriptorVersion is an enumeration of versions specifying the +// encryption algorithm for the key data and the authentication for the +// message integrity code (MIC) +type EAPOLKeyDescriptorVersion uint8 + +// Enumeration of EAPOLKeyDescriptorVersion +const ( + EAPOLKeyDescriptorVersionOther EAPOLKeyDescriptorVersion = 0 + EAPOLKeyDescriptorVersionRC4HMACMD5 EAPOLKeyDescriptorVersion = 1 + EAPOLKeyDescriptorVersionAESHMACSHA1 EAPOLKeyDescriptorVersion = 2 + EAPOLKeyDescriptorVersionAES128CMAC EAPOLKeyDescriptorVersion = 3 +) + +func (v EAPOLKeyDescriptorVersion) String() string { + switch v { + case EAPOLKeyDescriptorVersionOther: + return "Other" + case EAPOLKeyDescriptorVersionRC4HMACMD5: + return "RC4-HMAC-MD5" + case EAPOLKeyDescriptorVersionAESHMACSHA1: + return "AES-HMAC-SHA1-128" + case EAPOLKeyDescriptorVersionAES128CMAC: + return "AES-128-CMAC" + default: + return fmt.Sprintf("unknown version %d", v) + } +} + +// EAPOLKeyType is an enumeration of key derivation types describing +// the purpose of the keys being derived. +type EAPOLKeyType uint8 + +// Enumeration of EAPOLKeyType +const ( + EAPOLKeyTypeGroupSMK EAPOLKeyType = 0 + EAPOLKeyTypePairwise EAPOLKeyType = 1 +) + +func (kt EAPOLKeyType) String() string { + switch kt { + case EAPOLKeyTypeGroupSMK: + return "Group/SMK" + case EAPOLKeyTypePairwise: + return "Pairwise" + default: + return fmt.Sprintf("unknown key type %d", kt) + } +} + +// EAPOLKey defines an EAPOL-Key frame for 802.1x authentication +type EAPOLKey struct { + BaseLayer + KeyDescriptorType EAPOLKeyDescriptorType + KeyDescriptorVersion EAPOLKeyDescriptorVersion + KeyType EAPOLKeyType + KeyIndex uint8 + Install bool + KeyACK bool + KeyMIC bool + Secure bool + MICError bool + Request bool + HasEncryptedKeyData bool + SMKMessage bool + KeyLength uint16 + ReplayCounter uint64 + Nonce []byte + IV []byte + RSC uint64 + ID uint64 + MIC []byte + KeyDataLength uint16 + EncryptedKeyData []byte +} + +// LayerType returns LayerTypeEAPOLKey. +func (ek *EAPOLKey) LayerType() gopacket.LayerType { + return LayerTypeEAPOLKey +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (ek *EAPOLKey) CanDecode() gopacket.LayerType { + return LayerTypeEAPOLKey +} + +// NextLayerType returns layers.LayerTypeDot11InformationElement if the key +// data exists and is unencrypted, otherwise it does not expect a next layer. +func (ek *EAPOLKey) NextLayerType() gopacket.LayerType { + if !ek.HasEncryptedKeyData && ek.KeyDataLength > 0 { + return LayerTypeDot11InformationElement + } + return gopacket.LayerTypePayload +} + +const eapolKeyFrameLen = 95 + +// DecodeFromBytes decodes the given bytes into this layer. +func (ek *EAPOLKey) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < eapolKeyFrameLen { + df.SetTruncated() + return fmt.Errorf("EAPOLKey length %v too short, %v required", + len(data), eapolKeyFrameLen) + } + + ek.KeyDescriptorType = EAPOLKeyDescriptorType(data[0]) + + info := binary.BigEndian.Uint16(data[1:3]) + ek.KeyDescriptorVersion = EAPOLKeyDescriptorVersion(info & 0x0007) + ek.KeyType = EAPOLKeyType((info & 0x0008) >> 3) + ek.KeyIndex = uint8((info & 0x0030) >> 4) + ek.Install = (info & 0x0040) != 0 + ek.KeyACK = (info & 0x0080) != 0 + ek.KeyMIC = (info & 0x0100) != 0 + ek.Secure = (info & 0x0200) != 0 + ek.MICError = (info & 0x0400) != 0 + ek.Request = (info & 0x0800) != 0 + ek.HasEncryptedKeyData = (info & 0x1000) != 0 + ek.SMKMessage = (info & 0x2000) != 0 + + ek.KeyLength = binary.BigEndian.Uint16(data[3:5]) + ek.ReplayCounter = binary.BigEndian.Uint64(data[5:13]) + + ek.Nonce = data[13:45] + ek.IV = data[45:61] + ek.RSC = binary.BigEndian.Uint64(data[61:69]) + ek.ID = binary.BigEndian.Uint64(data[69:77]) + ek.MIC = data[77:93] + + ek.KeyDataLength = binary.BigEndian.Uint16(data[93:95]) + + totalLength := eapolKeyFrameLen + int(ek.KeyDataLength) + if len(data) < totalLength { + df.SetTruncated() + return fmt.Errorf("EAPOLKey data length %d too short, %d required", + len(data)-eapolKeyFrameLen, ek.KeyDataLength) + } + + if ek.HasEncryptedKeyData { + ek.EncryptedKeyData = data[eapolKeyFrameLen:totalLength] + ek.BaseLayer = BaseLayer{ + Contents: data[:totalLength], + Payload: data[totalLength:], + } + } else { + ek.BaseLayer = BaseLayer{ + Contents: data[:eapolKeyFrameLen], + Payload: data[eapolKeyFrameLen:], + } + } + + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (ek *EAPOLKey) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + buf, err := b.PrependBytes(eapolKeyFrameLen + len(ek.EncryptedKeyData)) + if err != nil { + return err + } + + buf[0] = byte(ek.KeyDescriptorType) + + var info uint16 + info |= uint16(ek.KeyDescriptorVersion) + info |= uint16(ek.KeyType) << 3 + info |= uint16(ek.KeyIndex) << 4 + if ek.Install { + info |= 0x0040 + } + if ek.KeyACK { + info |= 0x0080 + } + if ek.KeyMIC { + info |= 0x0100 + } + if ek.Secure { + info |= 0x0200 + } + if ek.MICError { + info |= 0x0400 + } + if ek.Request { + info |= 0x0800 + } + if ek.HasEncryptedKeyData { + info |= 0x1000 + } + if ek.SMKMessage { + info |= 0x2000 + } + binary.BigEndian.PutUint16(buf[1:3], info) + + binary.BigEndian.PutUint16(buf[3:5], ek.KeyLength) + binary.BigEndian.PutUint64(buf[5:13], ek.ReplayCounter) + + copy(buf[13:45], ek.Nonce) + copy(buf[45:61], ek.IV) + binary.BigEndian.PutUint64(buf[61:69], ek.RSC) + binary.BigEndian.PutUint64(buf[69:77], ek.ID) + copy(buf[77:93], ek.MIC) + + binary.BigEndian.PutUint16(buf[93:95], ek.KeyDataLength) + if len(ek.EncryptedKeyData) > 0 { + copy(buf[95:95+len(ek.EncryptedKeyData)], ek.EncryptedKeyData) + } + + return nil +} + +func decodeEAPOLKey(data []byte, p gopacket.PacketBuilder) error { + ek := &EAPOLKey{} + return decodingLayerDecoder(ek, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/eapol_test.go b/vendor/github.com/google/gopacket/layers/eapol_test.go new file mode 100644 index 0000000000..40b4a7fbb7 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/eapol_test.go @@ -0,0 +1,123 @@ +// Copyright placeholder +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +package layers + +import ( + "reflect" + "testing" + + "github.com/google/gopacket" +) + +const eapolErrFmt = "%s packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n" + +// testPacketEAPOLKey is frame 87 in the capture: +// https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=wpa-Induction.pcap +// It's the first EAPOL-Key frame in the WPA 4-way handshake: +// 0x0000 02 03 00 75 02 00 8a 00 10 00 00 00 00 00 00 00 ...u............ +// 0x0010 00 3e 8e 96 7d ac d9 60 32 4c ac 5b 6a a7 21 23 .>..}..`2L.[j.!# +// 0x0020 5b f5 7b 94 97 71 c8 67 98 9f 49 d0 4e d4 7c 69 [.{..q.g..I.N.|i +// 0x0030 33 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3............... +// 0x0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +// 0x0050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +// 0x0060 00 00 16 dd 14 00 0f ac 04 59 2d a8 80 96 c4 61 .........Y-....a +// 0x0070 da 24 6c 69 00 1e 87 7f 3d .$li....= + +var testPacketEAPOLKey = []byte{ + 0x02, 0x03, 0x00, 0x75, 0x02, 0x00, 0x8a, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3e, 0x8e, 0x96, 0x7d, 0xac, 0xd9, 0x60, + 0x32, 0x4c, 0xac, 0x5b, 0x6a, 0xa7, 0x21, 0x23, + 0x5b, 0xf5, 0x7b, 0x94, 0x97, 0x71, 0xc8, 0x67, + 0x98, 0x9f, 0x49, 0xd0, 0x4e, 0xd4, 0x7c, 0x69, + 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x16, 0xdd, 0x14, 0x00, 0x0f, 0xac, + 0x04, 0x59, 0x2d, 0xa8, 0x80, 0x96, 0xc4, 0x61, + 0xda, 0x24, 0x6c, 0x69, 0x00, 0x1e, 0x87, 0x7f, + 0x3d, +} + +func TestPacketEAPOLKey(t *testing.T) { + p := gopacket.NewPacket(testPacketEAPOLKey, LayerTypeEAPOL, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEAPOL, LayerTypeEAPOLKey, + LayerTypeDot11InformationElement}, t) + + { + got := p.Layer(LayerTypeEAPOL).(*EAPOL) + want := &EAPOL{ + BaseLayer: BaseLayer{ + Contents: testPacketEAPOLKey[:4], + Payload: testPacketEAPOLKey[4:], + }, + Version: 2, + Type: EAPOLTypeKey, + Length: 117, + } + if !reflect.DeepEqual(got, want) { + t.Errorf(eapolErrFmt, "EAPOL", got, want) + } + } + + { + got := p.Layer(LayerTypeEAPOLKey).(*EAPOLKey) + want := &EAPOLKey{ + BaseLayer: BaseLayer{ + Contents: testPacketEAPOLKey[4 : 4+eapolKeyFrameLen], + Payload: testPacketEAPOLKey[4+eapolKeyFrameLen:], + }, + KeyDescriptorType: EAPOLKeyDescriptorTypeDot11, + KeyDescriptorVersion: EAPOLKeyDescriptorVersionAESHMACSHA1, + KeyType: EAPOLKeyTypePairwise, + KeyACK: true, + KeyLength: 16, + Nonce: []byte{ + 0x3e, 0x8e, 0x96, 0x7d, 0xac, 0xd9, 0x60, 0x32, + 0x4c, 0xac, 0x5b, 0x6a, 0xa7, 0x21, 0x23, 0x5b, + 0xf5, 0x7b, 0x94, 0x97, 0x71, 0xc8, 0x67, 0x98, + 0x9f, 0x49, 0xd0, 0x4e, 0xd4, 0x7c, 0x69, 0x33, + }, + IV: make([]byte, 16), + MIC: make([]byte, 16), + KeyDataLength: 22, + } + if !reflect.DeepEqual(got, want) { + t.Errorf(eapolErrFmt, "EAPOLKey", got, want) + } + } + { + got := p.Layer(LayerTypeDot11InformationElement).(*Dot11InformationElement) + want := &Dot11InformationElement{ + BaseLayer: BaseLayer{ + Contents: testPacketEAPOLKey[4+eapolKeyFrameLen:], + Payload: []byte{}, + }, + ID: Dot11InformationElementIDVendor, + Length: 20, + OUI: []byte{0x00, 0x0f, 0xac, 0x04}, + Info: []byte{ + 0x59, 0x2d, 0xa8, 0x80, 0x96, 0xc4, 0x61, 0xda, + 0x24, 0x6c, 0x69, 0x00, 0x1e, 0x87, 0x7f, 0x3d, + }, + } + if !reflect.DeepEqual(got, want) { + t.Errorf(eapolErrFmt, "Dot11InformationElement", got, want) + } + } +} + +func BenchmarkDecodePacketEAPOLKey(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketEAPOLKey, nil, gopacket.NoCopy) + } +} diff --git a/vendor/github.com/google/gopacket/layers/enums.go b/vendor/github.com/google/gopacket/layers/enums.go index 896147bdb5..fa443e6323 100644 --- a/vendor/github.com/google/gopacket/layers/enums.go +++ b/vendor/github.com/google/gopacket/layers/enums.go @@ -10,6 +10,7 @@ package layers import ( "errors" "fmt" + "runtime" "github.com/google/gopacket" ) @@ -49,6 +50,7 @@ const ( EthernetTypeNortelDiscovery EthernetType = 0x01a2 EthernetTypeTransparentEthernetBridging EthernetType = 0x6558 EthernetTypeDot1Q EthernetType = 0x8100 + EthernetTypePPP EthernetType = 0x880b EthernetTypePPPoEDiscovery EthernetType = 0x8863 EthernetTypePPPoESession EthernetType = 0x8864 EthernetTypeMPLSUnicast EthernetType = 0x8847 @@ -219,12 +221,17 @@ func (d Dot11Type) MainType() Dot11Type { return d & dot11TypeMask } +func (d Dot11Type) QOS() bool { + return d&dot11QOSMask == Dot11TypeDataQOSData +} + const ( Dot11TypeMgmt Dot11Type = 0x00 Dot11TypeCtrl Dot11Type = 0x01 Dot11TypeData Dot11Type = 0x02 Dot11TypeReserved Dot11Type = 0x03 dot11TypeMask = 0x03 + dot11QOSMask = 0x23 // The following are type/subtype conglomerations. @@ -305,6 +312,7 @@ func initActualTypeData() { EthernetTypeMetadata[EthernetTypeIPv6] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6} EthernetTypeMetadata[EthernetTypeARP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeARP), Name: "ARP", LayerType: LayerTypeARP} EthernetTypeMetadata[EthernetTypeDot1Q] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot1Q), Name: "Dot1Q", LayerType: LayerTypeDot1Q} + EthernetTypeMetadata[EthernetTypePPP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPP), Name: "PPP", LayerType: LayerTypePPP} EthernetTypeMetadata[EthernetTypePPPoEDiscovery] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPPoE), Name: "PPPoEDiscovery", LayerType: LayerTypePPPoE} EthernetTypeMetadata[EthernetTypePPPoESession] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPPoE), Name: "PPPoESession", LayerType: LayerTypePPPoE} EthernetTypeMetadata[EthernetTypeEthernetCTP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEthernetCTP), Name: "EthernetCTP", LayerType: LayerTypeEthernetCTP} @@ -370,6 +378,13 @@ func initActualTypeData() { LinkTypeMetadata[LinkTypeLoop] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLoopback), Name: "Loop"} LinkTypeMetadata[LinkTypeIEEE802_11] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11), Name: "802.11"} LinkTypeMetadata[LinkTypeRaw] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4or6), Name: "Raw"} + // See https://github.com/the-tcpdump-group/libpcap/blob/170f717e6e818cdc4bcbbfd906b63088eaa88fa0/pcap/dlt.h#L85 + // Or https://github.com/wireshark/wireshark/blob/854cfe53efe44080609c78053ecfb2342ad84a08/wiretap/pcap-common.c#L508 + if runtime.GOOS == "openbsd" { + LinkTypeMetadata[14] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4or6), Name: "Raw"} + } else { + LinkTypeMetadata[12] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4or6), Name: "Raw"} + } LinkTypeMetadata[LinkTypePFLog] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePFLog), Name: "PFLog"} LinkTypeMetadata[LinkTypeIEEE80211Radio] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeRadioTap), Name: "RadioTap"} LinkTypeMetadata[LinkTypeLinuxUSB] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSB), Name: "USB"} @@ -379,6 +394,7 @@ func initActualTypeData() { FDDIFrameControlMetadata[FDDIFrameControlLLC] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLLC), Name: "LLC"} EAPOLTypeMetadata[EAPOLTypeEAP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEAP), Name: "EAP", LayerType: LayerTypeEAP} + EAPOLTypeMetadata[EAPOLTypeKey] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEAPOLKey), Name: "EAPOLKey", LayerType: LayerTypeEAPOLKey} ProtocolFamilyMetadata[ProtocolFamilyIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: "IPv4", LayerType: LayerTypeIPv4} ProtocolFamilyMetadata[ProtocolFamilyIPv6BSD] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6} diff --git a/vendor/github.com/google/gopacket/layers/ethernet.go b/vendor/github.com/google/gopacket/layers/ethernet.go index 4eebf8c614..b73748f2f7 100644 --- a/vendor/github.com/google/gopacket/layers/ethernet.go +++ b/vendor/github.com/google/gopacket/layers/ethernet.go @@ -46,6 +46,7 @@ func (eth *Ethernet) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) er eth.SrcMAC = net.HardwareAddr(data[6:12]) eth.EthernetType = EthernetType(binary.BigEndian.Uint16(data[12:14])) eth.BaseLayer = BaseLayer{data[:14], data[14:]} + eth.Length = 0 if eth.EthernetType < 0x0600 { eth.Length = uint16(eth.EthernetType) eth.EthernetType = EthernetTypeLLC diff --git a/vendor/github.com/google/gopacket/layers/geneve.go b/vendor/github.com/google/gopacket/layers/geneve.go index 6dc05cf35b..72fe7c779c 100644 --- a/vendor/github.com/google/gopacket/layers/geneve.go +++ b/vendor/github.com/google/gopacket/layers/geneve.go @@ -8,6 +8,7 @@ package layers import ( "encoding/binary" + "errors" "github.com/google/gopacket" ) @@ -52,19 +53,25 @@ func (gn *Geneve) LayerType() gopacket.LayerType { return LayerTypeGeneve } func decodeGeneveOption(data []byte, gn *Geneve) (*GeneveOption, uint8) { opt := &GeneveOption{} - opt.Class = binary.BigEndian.Uint16(data[0:1]) + opt.Class = binary.BigEndian.Uint16(data[0:2]) opt.Type = data[2] opt.Flags = data[3] >> 4 - opt.Length = data[3] & 0xf + opt.Length = (data[3]&0xf)*4 + 4 + opt.Data = make([]byte, opt.Length-4) copy(opt.Data, data[4:opt.Length]) - return opt, 4 + opt.Length + return opt, opt.Length } func (gn *Geneve) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 7 { + df.SetTruncated() + return errors.New("geneve packet too short") + } + gn.Version = data[0] >> 7 - gn.OptionsLength = data[0] & 0x3f + gn.OptionsLength = (data[0] & 0x3f) * 4 gn.OAMPacket = data[1]&0x80 > 0 gn.CriticalOption = data[1]&0x40 > 0 @@ -74,12 +81,17 @@ func (gn *Geneve) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error copy(buf[1:], data[4:7]) gn.VNI = binary.BigEndian.Uint32(buf[:]) - offset, length := uint8(8), gn.OptionsLength + offset, length := uint8(8), int32(gn.OptionsLength) + if len(data) < int(length+7) { + df.SetTruncated() + return errors.New("geneve packet too short") + } + for length > 0 { opt, len := decodeGeneveOption(data[offset:], gn) gn.Options = append(gn.Options, opt) - length -= len + length -= int32(len) offset += len } diff --git a/vendor/github.com/google/gopacket/layers/geneve_test.go b/vendor/github.com/google/gopacket/layers/geneve_test.go index ee34d5247f..f1a420bc6a 100644 --- a/vendor/github.com/google/gopacket/layers/geneve_test.go +++ b/vendor/github.com/google/gopacket/layers/geneve_test.go @@ -45,6 +45,19 @@ var testPacketGeneve2 = []byte{ 0x34, 0x35, 0x36, 0x37, } +var testPacketGeneve3 = []byte{ + 0x00, 0x1b, 0x21, 0x3c, 0xac, 0x30, 0x00, 0x1b, 0x21, 0x3c, 0xab, 0x64, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x8e, 0xdf, 0xad, 0x40, 0x00, 0x40, 0x11, 0x32, 0xaf, 0x14, 0x00, 0x00, 0x01, 0x14, 0x00, + 0x00, 0x02, 0x31, 0x4a, 0x17, 0xc1, 0x00, 0x7a, 0x00, 0x00, 0x02, 0x40, 0x65, 0x58, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x0c, 0xfe, 0x71, 0xd8, 0x83, 0x72, 0x4f, + 0xb6, 0x9e, 0xd2, 0x49, 0x51, 0x48, 0x08, 0x00, 0x45, 0x00, 0x00, 0x54, 0xbd, 0xa2, 0x40, 0x00, + 0x40, 0x01, 0x41, 0x04, 0x1e, 0x00, 0x00, 0x01, 0x1e, 0x00, 0x00, 0x02, 0x08, 0x00, 0x2c, 0x54, + 0x29, 0x52, 0x00, 0x17, 0xf1, 0xa2, 0xce, 0x54, 0x00, 0x00, 0x00, 0x00, 0x17, 0x78, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +} + func TestDecodeGeneve1(t *testing.T) { p := gopacket.NewPacket(testPacketGeneve1, LinkTypeLinuxSLL, gopacket.Default) if p.ErrorLayer() != nil { @@ -101,6 +114,42 @@ func TestDecodeGeneve2(t *testing.T) { } } +func TestDecodeGeneve3(t *testing.T) { + p := gopacket.NewPacket(testPacketGeneve3, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{ + LayerTypeEthernet, LayerTypeIPv4, LayerTypeUDP, LayerTypeGeneve, + LayerTypeEthernet, LayerTypeIPv4, LayerTypeICMPv4, gopacket.LayerTypePayload, + }, t) + if got, ok := p.Layer(LayerTypeGeneve).(*Geneve); ok { + want := &Geneve{ + BaseLayer: BaseLayer{ + Contents: testPacketGeneve3[42:58], + Payload: testPacketGeneve3[58:156], + }, + Version: 0x0, + OptionsLength: 0x8, + OAMPacket: false, + CriticalOption: true, + Protocol: EthernetTypeTransparentEthernetBridging, + VNI: 0xa, + Options: []*GeneveOption{ + &GeneveOption{ + Class: 0x0, + Type: 0x80, + Length: 8, + Data: []byte{0, 0, 0, 0xc}, + }, + }, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("Geneve layer mismatch, \nwant %#v\ngot %#v\n", want, got) + } + } +} + func BenchmarkDecodeGeneve1(b *testing.B) { for i := 0; i < b.N; i++ { gopacket.NewPacket(testPacketGeneve1, LinkTypeEthernet, gopacket.NoCopy) diff --git a/vendor/github.com/google/gopacket/layers/gre.go b/vendor/github.com/google/gopacket/layers/gre.go index 15d5290b2a..9c5e7d246f 100644 --- a/vendor/github.com/google/gopacket/layers/gre.go +++ b/vendor/github.com/google/gopacket/layers/gre.go @@ -15,11 +15,11 @@ import ( // GRE is a Generic Routing Encapsulation header. type GRE struct { BaseLayer - ChecksumPresent, RoutingPresent, KeyPresent, SeqPresent, StrictSourceRoute bool - RecursionControl, Flags, Version uint8 - Protocol EthernetType - Checksum, Offset uint16 - Key, Seq uint32 + ChecksumPresent, RoutingPresent, KeyPresent, SeqPresent, StrictSourceRoute, AckPresent bool + RecursionControl, Flags, Version uint8 + Protocol EthernetType + Checksum, Offset uint16 + Key, Seq, Ack uint32 *GRERouting } @@ -42,6 +42,7 @@ func (g *GRE) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { g.KeyPresent = data[0]&0x20 != 0 g.SeqPresent = data[0]&0x10 != 0 g.StrictSourceRoute = data[0]&0x08 != 0 + g.AckPresent = data[1]&0x80 != 0 g.RecursionControl = data[0] & 0x7 g.Flags = data[1] >> 3 g.Version = data[1] & 0x7 @@ -77,6 +78,10 @@ func (g *GRE) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { tail = &sre.Next } } + if g.AckPresent { + g.Ack = binary.BigEndian.Uint32(data[offset : offset+4]) + offset += 4 + } g.BaseLayer = BaseLayer{data[:offset], data[offset:]} return nil } @@ -102,6 +107,9 @@ func (g *GRE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOpt } size += 4 } + if g.AckPresent { + size += 4 + } buf, err := b.PrependBytes(size) if err != nil { return err @@ -124,6 +132,9 @@ func (g *GRE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOpt if g.StrictSourceRoute { buf[0] |= 0x08 } + if g.AckPresent { + buf[1] |= 0x80 + } buf[0] |= g.RecursionControl buf[1] |= g.Flags << 3 buf[1] |= g.Version @@ -159,6 +170,10 @@ func (g *GRE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOpt // Terminate routing field with a "NULL" SRE. binary.BigEndian.PutUint32(buf[offset:offset+4], 0) } + if g.AckPresent { + binary.BigEndian.PutUint32(buf[offset:offset+4], g.Ack) + offset += 4 + } if g.ChecksumPresent { if opts.ComputeChecksums { g.Checksum = tcpipChecksum(b.Bytes(), 0) diff --git a/vendor/github.com/google/gopacket/layers/gtp.go b/vendor/github.com/google/gopacket/layers/gtp.go new file mode 100644 index 0000000000..0ec8a6a002 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/gtp.go @@ -0,0 +1,181 @@ +// Copyright 2017 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +// + +package layers + +import ( + "encoding/binary" + "fmt" + "github.com/google/gopacket" +) + +const gtpMinimumSizeInBytes int = 8 + +// GTPExtensionHeader is used to carry extra data and enable future extensions of the GTP without the need to use another version number. +type GTPExtensionHeader struct { + Type uint8 + Content []byte +} + +// GTPv1U protocol is used to exchange user data over GTP tunnels across the Sx interfaces. +// Defined in https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1595 +type GTPv1U struct { + BaseLayer + Version uint8 + ProtocolType uint8 + Reserved uint8 + ExtensionHeaderFlag bool + SequenceNumberFlag bool + NPDUFlag bool + MessageType uint8 + MessageLength uint16 + TEID uint32 + SequenceNumber uint16 + NPDU uint8 + GTPExtensionHeaders []GTPExtensionHeader +} + +// LayerType returns LayerTypeGTPV1U +func (g *GTPv1U) LayerType() gopacket.LayerType { return LayerTypeGTPv1U } + +// DecodeFromBytes analyses a byte slice and attempts to decode it as a GTPv1U packet +func (g *GTPv1U) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + hLen := gtpMinimumSizeInBytes + dLen := len(data) + if dLen < hLen { + return fmt.Errorf("GTP packet too small: %d bytes", dLen) + } + g.Version = (data[0] >> 5) & 0x07 + g.ProtocolType = (data[0] >> 4) & 0x01 + g.Reserved = (data[0] >> 3) & 0x01 + g.SequenceNumberFlag = ((data[0] >> 1) & 0x01) == 1 + g.NPDUFlag = (data[0] & 0x01) == 1 + g.ExtensionHeaderFlag = ((data[0] >> 2) & 0x01) == 1 + g.MessageType = data[1] + g.MessageLength = binary.BigEndian.Uint16(data[2:4]) + pLen := 8 + g.MessageLength + if uint16(dLen) < pLen { + return fmt.Errorf("GTP packet too small: %d bytes", dLen) + } + // Field used to multiplex different connections in the same GTP tunnel. + g.TEID = binary.BigEndian.Uint32(data[4:8]) + cIndex := uint16(hLen) + if g.SequenceNumberFlag || g.NPDUFlag || g.ExtensionHeaderFlag { + hLen += 4 + cIndex += 4 + if dLen < hLen { + return fmt.Errorf("GTP packet too small: %d bytes", dLen) + } + if g.SequenceNumberFlag { + g.SequenceNumber = binary.BigEndian.Uint16(data[8:10]) + } + if g.NPDUFlag { + g.NPDU = data[10] + } + if g.ExtensionHeaderFlag { + extensionFlag := true + for extensionFlag { + extensionType := uint8(data[cIndex-1]) + extensionLength := uint(data[cIndex]) + if extensionLength == 0 { + return fmt.Errorf("GTP packet with invalid extension header") + } + // extensionLength is in 4-octet units + lIndex := cIndex + (uint16(extensionLength) * 4) + if uint16(dLen) < lIndex { + fmt.Println(dLen, lIndex) + return fmt.Errorf("GTP packet with small extension header: %d bytes", dLen) + } + content := data[cIndex+1 : lIndex-1] + eh := GTPExtensionHeader{Type: extensionType, Content: content} + g.GTPExtensionHeaders = append(g.GTPExtensionHeaders, eh) + cIndex = lIndex + // Check if coming bytes are from an extension header + extensionFlag = data[cIndex-1] != 0 + + } + } + } + g.BaseLayer = BaseLayer{Contents: data[:cIndex], Payload: data[cIndex:]} + return nil + +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (g *GTPv1U) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + data, err := b.PrependBytes(gtpMinimumSizeInBytes) + if err != nil { + return err + } + data[0] |= (g.Version << 5) + data[0] |= (1 << 4) + if len(g.GTPExtensionHeaders) > 0 { + data[0] |= 0x04 + g.ExtensionHeaderFlag = true + } + if g.SequenceNumberFlag { + data[0] |= 0x02 + } + if g.NPDUFlag { + data[0] |= 0x01 + } + data[1] = g.MessageType + binary.BigEndian.PutUint16(data[2:4], g.MessageLength) + binary.BigEndian.PutUint32(data[4:8], g.TEID) + if g.ExtensionHeaderFlag || g.SequenceNumberFlag || g.NPDUFlag { + data, err := b.AppendBytes(4) + if err != nil { + return err + } + binary.BigEndian.PutUint16(data[:2], g.SequenceNumber) + data[2] = g.NPDU + for _, eh := range g.GTPExtensionHeaders { + data[len(data)-1] = eh.Type + lContent := len(eh.Content) + // extensionLength is in 4-octet units + extensionLength := (lContent + 2) / 4 + // Get two extra byte for the next extension header type and length + data, err = b.AppendBytes(lContent + 2) + if err != nil { + return err + } + data[0] = byte(extensionLength) + copy(data[1:lContent+1], eh.Content) + } + } + return nil + +} + +// CanDecode returns a set of layers that GTP objects can decode. +func (g *GTPv1U) CanDecode() gopacket.LayerClass { + return LayerTypeGTPv1U +} + +// NextLayerType specifies the next layer that GoPacket should attempt to +func (g *GTPv1U) NextLayerType() gopacket.LayerType { + version := uint8(g.LayerPayload()[0]) >> 4 + if version == 4 { + return LayerTypeIPv4 + } else if version == 6 { + return LayerTypeIPv6 + } else { + return LayerTypePPP + } +} + +func decodeGTPv1u(data []byte, p gopacket.PacketBuilder) error { + gtp := >Pv1U{} + err := gtp.DecodeFromBytes(data, p) + if err != nil { + return err + } + p.AddLayer(gtp) + return p.NextDecoder(gtp.NextLayerType()) +} diff --git a/vendor/github.com/google/gopacket/layers/gtp_test.go b/vendor/github.com/google/gopacket/layers/gtp_test.go new file mode 100644 index 0000000000..9f934ee598 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/gtp_test.go @@ -0,0 +1,158 @@ +// Copyright 2017 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +// + +package layers + +import ( + "github.com/google/gopacket" + "reflect" + "testing" +) + +// testGTPPacket is the packet: +//0000 00 0c 29 e3 c6 4d 00 0c 29 da d1 de 08 00 45 00 ..)..M.. ).....E. +//0010 00 7c 00 00 40 00 40 11 67 bb c0 a8 28 b2 c0 a8 .|..@.@. g...(... +//0020 28 b3 08 68 08 68 00 68 c1 c4 32 ff 00 58 00 00 (..h.h.h ..2..X.. +//0030 00 01 26 7b 00 00 45 00 00 54 06 76 00 00 40 01 ..&{..E. .T.v..@. +//0040 98 2f c0 a8 28 b2 ca 0b 28 9e 00 00 39 e9 00 00 ./..(... (...9... +//0050 28 7d 06 11 20 4b 7f 3a 0d 00 08 09 0a 0b 0c 0d (}.. K.: ........ +//0060 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d ........ ........ +//0070 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d .. !"#$% &'()*+,- +//0080 2e 2f 30 31 32 33 34 35 36 37 ./012345 67 + +var testGTPPacket = []byte{ + 0x00, 0x0c, 0x29, 0xe3, 0xc6, 0x4d, 0x00, 0x0c, + 0x29, 0xda, 0xd1, 0xde, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x7c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, + 0x67, 0xbb, 0xc0, 0xa8, 0x28, 0xb2, 0xc0, 0xa8, + 0x28, 0xb3, 0x08, 0x68, 0x08, 0x68, 0x00, 0x68, + 0xc1, 0xc4, 0x32, 0xff, 0x00, 0x58, 0x00, 0x00, + 0x00, 0x01, 0x26, 0x7b, 0x00, 0x00, 0x45, 0x00, + 0x00, 0x54, 0x06, 0x76, 0x00, 0x00, 0x40, 0x01, + 0x98, 0x2f, 0xc0, 0xa8, 0x28, 0xb2, 0xca, 0x0b, + 0x28, 0x9e, 0x00, 0x00, 0x39, 0xe9, 0x00, 0x00, + 0x28, 0x7d, 0x06, 0x11, 0x20, 0x4b, 0x7f, 0x3a, + 0x0d, 0x00, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, +} + +func TestGTPPacket(t *testing.T) { + p := gopacket.NewPacket(testGTPPacket, LayerTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeUDP, LayerTypeGTPv1U, LayerTypeIPv4, + LayerTypeICMPv4, gopacket.LayerTypePayload}, t) + if got, ok := p.Layer(LayerTypeGTPv1U).(*GTPv1U); ok { + want := >Pv1U{ + Version: 1, + ProtocolType: 1, + Reserved: 0, + ExtensionHeaderFlag: false, + SequenceNumberFlag: true, + NPDUFlag: false, + MessageType: 255, + MessageLength: 88, + TEID: 1, + SequenceNumber: 9851, + } + want.BaseLayer = BaseLayer{testGTPPacket[42:54], testGTPPacket[54:]} + if !reflect.DeepEqual(got, want) { + t.Errorf("GTP packet mismatch:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + + } + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{} + err := got.SerializeTo(buf, opts) + if err != nil { + t.Error(err) + } + if !reflect.DeepEqual(got.Contents, buf.Bytes()) { + t.Errorf("GTP packet serialization failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", buf.Bytes(), got.Contents) + } + } else { + t.Error("Incorrect gtp packet") + } +} + +// testGTPPacketWithEH is the packet +//000000 00 0c 29 e3 c6 4d 00 0c 29 da d1 de 08 00 45 00 ..)..M..).....E. +//000010 00 80 00 00 40 00 40 11 67 bb c0 a8 28 b2 c0 a8 ....@.@.g...(... +//000020 28 b3 08 68 08 68 00 6c c1 95 36 ff 00 58 00 10 (..h.h.l..6..X.. +//000030 06 57 00 05 00 c0 01 09 04 00 45 00 00 54 06 a5 .W........E..T.. +//000040 00 00 40 01 98 00 c0 a8 28 b2 ca 0b 28 9e 00 00 ..@.....(...(... +//000050 e3 b6 00 00 28 ac 35 11 20 4b a6 3d 0d 00 08 09 ....(.5. K.=.... +//000060 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 ................ +//000070 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 ...... !"#$%&'() +//000080 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 + +var testGTPPacketWithEH = []byte{ + 0x00, 0x0c, 0x29, 0xe3, 0xc6, 0x4d, 0x00, 0x0c, + 0x29, 0xda, 0xd1, 0xde, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, + 0x67, 0xbb, 0xc0, 0xa8, 0x28, 0xb2, 0xc0, 0xa8, + 0x28, 0xb3, 0x08, 0x68, 0x08, 0x68, 0x00, 0x6c, + 0xc1, 0x95, 0x36, 0xff, 0x00, 0x58, 0x00, 0x10, + 0x06, 0x57, 0x00, 0x05, 0x00, 0xc0, 0x01, 0x09, + 0x04, 0x00, 0x45, 0x00, 0x00, 0x54, 0x06, 0xa5, + 0x00, 0x00, 0x40, 0x01, 0x98, 0x00, 0xc0, 0xa8, + 0x28, 0xb2, 0xca, 0x0b, 0x28, 0x9e, 0x00, 0x00, + 0xe3, 0xb6, 0x00, 0x00, 0x28, 0xac, 0x35, 0x11, + 0x20, 0x4b, 0xa6, 0x3d, 0x0d, 0x00, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +} + +func TestGTPPacketWithEH(t *testing.T) { + p := gopacket.NewPacket(testGTPPacketWithEH, LayerTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeUDP, LayerTypeGTPv1U, LayerTypeIPv4, + LayerTypeICMPv4, gopacket.LayerTypePayload}, t) + if got, ok := p.Layer(LayerTypeGTPv1U).(*GTPv1U); ok { + want := >Pv1U{ + Version: 1, + ProtocolType: 1, + Reserved: 0, + ExtensionHeaderFlag: true, + SequenceNumberFlag: true, + NPDUFlag: false, + MessageType: 255, + MessageLength: 88, + TEID: 1050199, + SequenceNumber: 5, + GTPExtensionHeaders: []GTPExtensionHeader{GTPExtensionHeader{Type: uint8(192), Content: []byte{0x9, 0x4}}}, + } + want.BaseLayer = BaseLayer{testGTPPacketWithEH[42:58], testGTPPacketWithEH[58:]} + if !reflect.DeepEqual(got, want) { + t.Errorf("GTP packet mismatch:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + + } + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{} + err := got.SerializeTo(buf, opts) + if err != nil { + t.Error(err) + } + if !reflect.DeepEqual(got.Contents, buf.Bytes()) { + t.Errorf("GTP packet serialization failed:\ngot :\n%#v\n\nbuf :\n%#v\n\n", got.Contents, buf.Bytes()) + } + } else { + t.Errorf("Invalid GTP packet") + } + +} diff --git a/vendor/github.com/google/gopacket/layers/icmp6.go b/vendor/github.com/google/gopacket/layers/icmp6.go index 03a3213168..09afd11a60 100644 --- a/vendor/github.com/google/gopacket/layers/icmp6.go +++ b/vendor/github.com/google/gopacket/layers/icmp6.go @@ -24,12 +24,21 @@ const ( ICMPv6TypeParameterProblem = 4 ICMPv6TypeEchoRequest = 128 ICMPv6TypeEchoReply = 129 + // The following are from RFC 4861 ICMPv6TypeRouterSolicitation = 133 ICMPv6TypeRouterAdvertisement = 134 ICMPv6TypeNeighborSolicitation = 135 ICMPv6TypeNeighborAdvertisement = 136 ICMPv6TypeRedirect = 137 + + // The following are from RFC 2710 + ICMPv6TypeMLDv1MulticastListenerQueryMessage = 130 + ICMPv6TypeMLDv1MulticastListenerReportMessage = 131 + ICMPv6TypeMLDv1MulticastListenerDoneMessage = 132 + + // The following are from RFC 3810 + ICMPv6TypeMLDv2MulticastListenerReportMessageV2 = 143 ) const ( @@ -165,8 +174,10 @@ func CreateICMPv6TypeCode(typ uint8, code uint8) ICMPv6TypeCode { // ICMPv6 is the layer for IPv6 ICMP packet data type ICMPv6 struct { BaseLayer - TypeCode ICMPv6TypeCode - Checksum uint16 + TypeCode ICMPv6TypeCode + Checksum uint16 + // TypeBytes is deprecated and always nil. See the different ICMPv6 message types + // instead (e.g. ICMPv6TypeRouterSolicitation). TypeBytes []byte tcpipchecksum } @@ -176,14 +187,13 @@ func (i *ICMPv6) LayerType() gopacket.LayerType { return LayerTypeICMPv6 } // DecodeFromBytes decodes the given bytes into this layer. func (i *ICMPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { - if len(data) < 8 { + if len(data) < 4 { df.SetTruncated() - return errors.New("ICMP layer less then 8 bytes for ICMPv6 packet") + return errors.New("ICMP layer less then 4 bytes for ICMPv6 packet") } i.TypeCode = CreateICMPv6TypeCode(data[0], data[1]) i.Checksum = binary.BigEndian.Uint16(data[2:4]) - i.TypeBytes = data[4:8] - i.BaseLayer = BaseLayer{data[:8], data[8:]} + i.BaseLayer = BaseLayer{data[:4], data[4:]} return nil } @@ -191,17 +201,12 @@ func (i *ICMPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error // SerializationBuffer, implementing gopacket.SerializableLayer. // See the docs for gopacket.SerializableLayer for more info. func (i *ICMPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { - if i.TypeBytes == nil { - i.TypeBytes = lotsOfZeros[:4] - } else if len(i.TypeBytes) != 4 { - return fmt.Errorf("invalid type bytes for ICMPv6 packet: %v", i.TypeBytes) - } - bytes, err := b.PrependBytes(8) + bytes, err := b.PrependBytes(4) if err != nil { return err } i.TypeCode.SerializeTo(bytes) - copy(bytes[4:8], i.TypeBytes) + if opts.ComputeChecksums { bytes[2] = 0 bytes[3] = 0 @@ -212,6 +217,7 @@ func (i *ICMPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Serialize i.Checksum = csum } binary.BigEndian.PutUint16(bytes[2:], i.Checksum) + return nil } @@ -222,6 +228,35 @@ func (i *ICMPv6) CanDecode() gopacket.LayerClass { // NextLayerType returns the layer type contained by this DecodingLayer. func (i *ICMPv6) NextLayerType() gopacket.LayerType { + switch i.TypeCode.Type() { + case ICMPv6TypeEchoRequest: + return LayerTypeICMPv6Echo + case ICMPv6TypeEchoReply: + return LayerTypeICMPv6Echo + case ICMPv6TypeRouterSolicitation: + return LayerTypeICMPv6RouterSolicitation + case ICMPv6TypeRouterAdvertisement: + return LayerTypeICMPv6RouterAdvertisement + case ICMPv6TypeNeighborSolicitation: + return LayerTypeICMPv6NeighborSolicitation + case ICMPv6TypeNeighborAdvertisement: + return LayerTypeICMPv6NeighborAdvertisement + case ICMPv6TypeRedirect: + return LayerTypeICMPv6Redirect + case ICMPv6TypeMLDv1MulticastListenerQueryMessage: // Same Code for MLDv1 Query and MLDv2 Query + if len(i.Payload) > 20 { // Only payload size differs + return LayerTypeMLDv2MulticastListenerQuery + } else { + return LayerTypeMLDv1MulticastListenerQuery + } + case ICMPv6TypeMLDv1MulticastListenerDoneMessage: + return LayerTypeMLDv1MulticastListenerDone + case ICMPv6TypeMLDv1MulticastListenerReportMessage: + return LayerTypeMLDv1MulticastListenerReport + case ICMPv6TypeMLDv2MulticastListenerReportMessageV2: + return LayerTypeMLDv2MulticastListenerReport + } + return gopacket.LayerTypePayload } diff --git a/vendor/github.com/google/gopacket/layers/icmp6NDflags_test.go b/vendor/github.com/google/gopacket/layers/icmp6NDflags_test.go new file mode 100644 index 0000000000..cfb281f264 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/icmp6NDflags_test.go @@ -0,0 +1,129 @@ +// Copyright 2012, Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "github.com/google/gopacket" + "testing" +) + +var icmp6NeighborAnnouncementData = []byte{ + // Ethernet layer + 0x00, 0x1F, 0xCA, 0xB3, 0x76, 0x40, // destination + 0x24, 0xBE, 0x05, 0x27, 0x0B, 0x17, // source + 0x86, 0xDD, // type IPv6 + + // IPv6 layer + 0x60, 0x00, 0x00, 0x00, // version; traffic class; flow label + 0x00, 0x18, // payload length? + 0x3A, // Next Header - IPv6-ICMP + 0xFF, // Hop Limit + 0x26, 0x20, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x26, 0xBE, 0x05, 0xFF, 0xFE, 0x27, 0x0B, 0x17, // source + 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1F, 0xCA, 0xFF, 0xFE, 0xB3, 0x76, 0x40, // destination + + // ICMPv6 layer + 0x88, 0x00, // ICMP type 136, code 0 + + 0x1E, 0xD6, // checksum + 0x40, 0x00, 0x00, 0x00, // flags & reserved + 0x26, 0x20, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x26, 0xBE, 0x05, 0xFF, 0xFE, 0x27, 0x0B, 0x17, // target address +} + +var icmp6RouterAdvertisementData = []byte{ + // Ethernet layer + 0x33, 0x33, 0x00, 0x00, 0x00, 0x01, // destination, + 0xde, 0x42, 0x72, 0xb0, 0x1e, 0xf4, // source + 0x86, 0xdd, + + // IPv6 layer + 0x60, 0x00, 0x00, 0x00, // version; traffic class; flow label + 0x00, 0x20, // payload length? + 0x3a, // Next Header - IPv6-ICMP + 0xff, // Hop Limit + 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x42, 0x72, 0xff, 0xfe, 0xb0, 0x1e, 0xf4, // source, + 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // destination + + // ICMPv6 layer + 0x86, 0x00, // ICMP type 134, code 0 + + 0x4c, 0x6b, // checksum + 0x40, // current hop limit + 0x00, // flags & reserves + 0x07, 0x08, // router lifetime + 0x00, 0x00, 0x00, 0x00, // reachable time + 0x00, 0x00, 0x00, 0x00, //retrans time + 0x01, 0x01, 0xde, 0x42, 0x72, 0xb0, 0x1e, 0xf4, // source link layer address + 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0xdc, // MTU option +} + +func TestPacketICMPv6NeighborAnnouncementFlags(t *testing.T) { + var ethLayer Ethernet + var ipV6Layer IPv6 + var icmpLayer ICMPv6 + + var icmpNeighAdvLayer ICMPv6NeighborAdvertisement + + parser := gopacket.NewDecodingLayerParser(LayerTypeEthernet, ðLayer, &ipV6Layer, &icmpLayer) + parser.IgnoreUnsupported = true + + respLayers := make([]gopacket.LayerType, 0) + err := parser.DecodeLayers(icmp6NeighborAnnouncementData, &respLayers) + + if err != nil { + t.Errorf("error decoding layers %s", err) + return + } + + err = icmpNeighAdvLayer.DecodeFromBytes(icmpLayer.LayerPayload(), gopacket.NilDecodeFeedback) + if err != nil { + t.Errorf("Error while Decodeing From Bytes: %s", err) + return + } + + if icmpNeighAdvLayer.Router() { + t.Errorf("This Neighbor Advertisement message's Router flag should not be set") + } + if !icmpNeighAdvLayer.Solicited() { + t.Errorf("This Neighbor Advertisement message's Solicited flag should be set") + } + if icmpNeighAdvLayer.Override() { + t.Errorf("This Neighbor Advertisement message's Override bit should not be set") + } +} + +func TestPacketICMPv6RouterAnnouncementFlags(t *testing.T) { + var ethLayer Ethernet + var ipV6Layer IPv6 + var icmpLayer ICMPv6 + + var icmpRouterAdvLayer ICMPv6RouterAdvertisement + + parser := gopacket.NewDecodingLayerParser(LayerTypeEthernet, ðLayer, &ipV6Layer, &icmpLayer) + parser.IgnoreUnsupported = true + + respLayers := make([]gopacket.LayerType, 0) + err := parser.DecodeLayers(icmp6RouterAdvertisementData, &respLayers) + + if err != nil { + t.Errorf("error decoding layers %s", err) + return + } + + err = icmpRouterAdvLayer.DecodeFromBytes(icmpLayer.LayerPayload(), gopacket.NilDecodeFeedback) + if err != nil { + t.Errorf("Error while Decodeing From Bytes: %s", err) + return + } + + if icmpRouterAdvLayer.ManagedAddressConfig() { + t.Errorf("This Router Advertisement message's ManagedAddressConfig flag should not be set") + } + if icmpRouterAdvLayer.OtherConfig() { + t.Errorf("This Router Advertisement message's OtherConfig flag should not be set") + } +} diff --git a/vendor/github.com/google/gopacket/layers/icmp6_test.go b/vendor/github.com/google/gopacket/layers/icmp6_test.go index 4a6d248fca..ceadf53a37 100644 --- a/vendor/github.com/google/gopacket/layers/icmp6_test.go +++ b/vendor/github.com/google/gopacket/layers/icmp6_test.go @@ -35,6 +35,8 @@ func TestPacketICMPv6(t *testing.T) { t.Error("Failed to decode packet:", p.ErrorLayer().Error()) } checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeICMPv6, gopacket.LayerTypePayload}, t) + checkSerialization(p, t) + if got, ok := p.Layer(LayerTypeIPv6).(*IPv6); ok { want := &IPv6{ BaseLayer: BaseLayer{ @@ -64,13 +66,12 @@ func TestPacketICMPv6(t *testing.T) { if got, ok := p.Layer(LayerTypeICMPv6).(*ICMPv6); ok { want := &ICMPv6{ BaseLayer: BaseLayer{ - Contents: []byte{0x88, 0x0, 0x1e, 0xd6, 0x40, 0x0, 0x0, 0x0}, - Payload: []byte{0x26, 0x20, 0x0, 0x0, 0x10, + Contents: []byte{0x88, 0x0, 0x1e, 0xd6}, + Payload: []byte{0x40, 0x0, 0x0, 0x0, 0x26, 0x20, 0x0, 0x0, 0x10, 0x5, 0x0, 0x0, 0x26, 0xbe, 0x5, 0xff, 0xfe, 0x27, 0xb, 0x17}, }, - TypeCode: 0x8800, - Checksum: 0x1ed6, - TypeBytes: []byte{0x40, 0x0, 0x0, 0x0}, + TypeCode: 0x8800, + Checksum: 0x1ed6, } if !reflect.DeepEqual(got, want) { t.Errorf("ICMPv6 packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) diff --git a/vendor/github.com/google/gopacket/layers/icmp6hopbyhop_test.go b/vendor/github.com/google/gopacket/layers/icmp6hopbyhop_test.go new file mode 100644 index 0000000000..19e43aeec8 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/icmp6hopbyhop_test.go @@ -0,0 +1,85 @@ +// Copyright 2012, Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "github.com/google/gopacket" + "testing" +) + +var icmp6HopByHopData = []byte{ + // Ethernet layer + 0x33, 0x33, 0x00, 0x00, 0x00, 0x16, // destination + 0x1e, 0xc3, 0xe3, 0xb7, 0xc4, 0xd5, // source + 0x86, 0xdd, // type IPv6 + + // IPv6 layer + 0x60, 0x00, 0x00, 0x00, // version; traffic class; flow label + 0x00, 0x88, // payload length? + 0x00, // Next Header + 0x01, // Hop Limit + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // source + 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, // destination + + // IPv6 Hop-by-hop option + 0x3a, // Next Header - IPv6-ICMP + 0x00, // Hdr Ext Len + 0x05, 0x02, 0x00, 0x00, 0x01, 0x00, // Options and Padding + + // ICMPv6 layer + 0x8f, 0x00, // ICMP type 143, code 0 + + 0x9e, 0xed, 0x00, 0x00, 0x00, 0x06, 0x03, 0x00, + 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xb7, + 0xc4, 0xd5, 0x03, 0x00, 0x00, 0x00, 0xff, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x11, + 0x00, 0x79, 0x04, 0x00, 0x00, 0x00, 0xff, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xff, 0x00, 0x00, 0x01, 0x04, 0x00, + 0x00, 0x00, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0xff, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, +} + +func TestPacketICMPv6WithHopByHop(t *testing.T) { + var ethLayerResp Ethernet + var ipV6LayerResp IPv6 + var icmpLayerResp ICMPv6 + var payload gopacket.Payload + + parser := gopacket.NewDecodingLayerParser(LayerTypeEthernet, ðLayerResp, &ipV6LayerResp, &icmpLayerResp, &payload) + parser.IgnoreUnsupported = true // avoid `No decoder for layer type ICMPv6RouterAdvertisement` error + + respLayers := make([]gopacket.LayerType, 0) + err := parser.DecodeLayers(icmp6HopByHopData, &respLayers) + + if err != nil { + t.Errorf("error decoding layers %s", err) + return + } + + expectedType := uint8(icmp6HopByHopData[62]) + actualType := uint8(icmpLayerResp.TypeCode.Type()) + if expectedType != actualType { + t.Errorf("expected ICMP layer's TypeCode to be %d but was %d", expectedType, actualType) + } + + p := gopacket.NewPacket(icmp6HopByHopData, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeIPv6HopByHop, LayerTypeICMPv6}, t) + // See https://github.com/google/gopacket/issues/517 + // checkSerialization(p, t) +} diff --git a/vendor/github.com/google/gopacket/layers/icmp6msg.go b/vendor/github.com/google/gopacket/layers/icmp6msg.go new file mode 100644 index 0000000000..d9268db056 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/icmp6msg.go @@ -0,0 +1,578 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "encoding/hex" + "errors" + "fmt" + "net" + "time" + + "github.com/google/gopacket" +) + +// Based on RFC 4861 + +// ICMPv6Opt indicate how to decode the data associated with each ICMPv6Option. +type ICMPv6Opt uint8 + +const ( + _ ICMPv6Opt = iota + + // ICMPv6OptSourceAddress contains the link-layer address of the sender of + // the packet. It is used in the Neighbor Solicitation, Router + // Solicitation, and Router Advertisement packets. Must be ignored for other + // Neighbor discovery messages. + ICMPv6OptSourceAddress + + // ICMPv6OptTargetAddress contains the link-layer address of the target. It + // is used in Neighbor Advertisement and Redirect packets. Must be ignored + // for other Neighbor discovery messages. + ICMPv6OptTargetAddress + + // ICMPv6OptPrefixInfo provides hosts with on-link prefixes and prefixes + // for Address Autoconfiguration. The Prefix Information option appears in + // Router Advertisement packets and MUST be silently ignored for other + // messages. + ICMPv6OptPrefixInfo + + // ICMPv6OptRedirectedHeader is used in Redirect messages and contains all + // or part of the packet that is being redirected. + ICMPv6OptRedirectedHeader + + // ICMPv6OptMTU is used in Router Advertisement messages to ensure that all + // nodes on a link use the same MTU value in those cases where the link MTU + // is not well known. This option MUST be silently ignored for other + // Neighbor Discovery messages. + ICMPv6OptMTU +) + +// ICMPv6Echo represents the structure of a ping. +type ICMPv6Echo struct { + BaseLayer + Identifier uint16 + SeqNumber uint16 +} + +// ICMPv6RouterSolicitation is sent by hosts to find routers. +type ICMPv6RouterSolicitation struct { + BaseLayer + Options ICMPv6Options +} + +// ICMPv6RouterAdvertisement is sent by routers in response to Solicitation. +type ICMPv6RouterAdvertisement struct { + BaseLayer + HopLimit uint8 + Flags uint8 + RouterLifetime uint16 + ReachableTime uint32 + RetransTimer uint32 + Options ICMPv6Options +} + +// ICMPv6NeighborSolicitation is sent to request the link-layer address of a +// target node. +type ICMPv6NeighborSolicitation struct { + BaseLayer + TargetAddress net.IP + Options ICMPv6Options +} + +// ICMPv6NeighborAdvertisement is sent by nodes in response to Solicitation. +type ICMPv6NeighborAdvertisement struct { + BaseLayer + Flags uint8 + TargetAddress net.IP + Options ICMPv6Options +} + +// ICMPv6Redirect is sent by routers to inform hosts of a better first-hop node +// on the path to a destination. +type ICMPv6Redirect struct { + BaseLayer + TargetAddress net.IP + DestinationAddress net.IP + Options ICMPv6Options +} + +// ICMPv6Option contains the type and data for a single option. +type ICMPv6Option struct { + Type ICMPv6Opt + Data []byte +} + +// ICMPv6Options is a slice of ICMPv6Option. +type ICMPv6Options []ICMPv6Option + +func (i ICMPv6Opt) String() string { + switch i { + case ICMPv6OptSourceAddress: + return "SourceAddress" + case ICMPv6OptTargetAddress: + return "TargetAddress" + case ICMPv6OptPrefixInfo: + return "PrefixInfo" + case ICMPv6OptRedirectedHeader: + return "RedirectedHeader" + case ICMPv6OptMTU: + return "MTU" + default: + return fmt.Sprintf("Unknown(%d)", i) + } +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (i *ICMPv6Echo) CanDecode() gopacket.LayerClass { + return LayerTypeICMPv6Echo +} + +// LayerType returns LayerTypeICMPv6Echo. +func (i *ICMPv6Echo) LayerType() gopacket.LayerType { + return LayerTypeICMPv6Echo +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (i *ICMPv6Echo) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (i *ICMPv6Echo) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 4 { + df.SetTruncated() + return errors.New("ICMP layer less then 4 bytes for ICMPv6 Echo") + } + i.Identifier = binary.BigEndian.Uint16(data[0:2]) + i.SeqNumber = binary.BigEndian.Uint16(data[2:4]) + + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (i *ICMPv6Echo) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + buf, err := b.PrependBytes(4) + if err != nil { + return err + } + + binary.BigEndian.PutUint16(buf, i.Identifier) + binary.BigEndian.PutUint16(buf[2:], i.SeqNumber) + return nil +} + +// LayerType returns LayerTypeICMPv6. +func (i *ICMPv6RouterSolicitation) LayerType() gopacket.LayerType { + return LayerTypeICMPv6RouterSolicitation +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (i *ICMPv6RouterSolicitation) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (i *ICMPv6RouterSolicitation) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + // first 4 bytes are reserved followed by options + if len(data) < 4 { + df.SetTruncated() + return errors.New("ICMP layer less then 4 bytes for ICMPv6 router solicitation") + } + + // truncate old options + i.Options = i.Options[:0] + + return i.Options.DecodeFromBytes(data[4:], df) +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (i *ICMPv6RouterSolicitation) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if err := i.Options.SerializeTo(b, opts); err != nil { + return err + } + + buf, err := b.PrependBytes(4) + if err != nil { + return err + } + + copy(buf, lotsOfZeros[:4]) + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (i *ICMPv6RouterSolicitation) CanDecode() gopacket.LayerClass { + return LayerTypeICMPv6RouterSolicitation +} + +// LayerType returns LayerTypeICMPv6RouterAdvertisement. +func (i *ICMPv6RouterAdvertisement) LayerType() gopacket.LayerType { + return LayerTypeICMPv6RouterAdvertisement +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (i *ICMPv6RouterAdvertisement) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (i *ICMPv6RouterAdvertisement) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 12 { + df.SetTruncated() + return errors.New("ICMP layer less then 12 bytes for ICMPv6 router advertisement") + } + + i.HopLimit = uint8(data[0]) + // M, O bit followed by 6 reserved bits + i.Flags = uint8(data[1]) + i.RouterLifetime = binary.BigEndian.Uint16(data[2:4]) + i.ReachableTime = binary.BigEndian.Uint32(data[4:8]) + i.RetransTimer = binary.BigEndian.Uint32(data[8:12]) + i.BaseLayer = BaseLayer{data, nil} // assume no payload + + // truncate old options + i.Options = i.Options[:0] + + return i.Options.DecodeFromBytes(data[12:], df) +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (i *ICMPv6RouterAdvertisement) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if err := i.Options.SerializeTo(b, opts); err != nil { + return err + } + + buf, err := b.PrependBytes(12) + if err != nil { + return err + } + + buf[0] = byte(i.HopLimit) + buf[1] = byte(i.Flags) + binary.BigEndian.PutUint16(buf[2:], i.RouterLifetime) + binary.BigEndian.PutUint32(buf[4:], i.ReachableTime) + binary.BigEndian.PutUint32(buf[8:], i.RetransTimer) + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (i *ICMPv6RouterAdvertisement) CanDecode() gopacket.LayerClass { + return LayerTypeICMPv6RouterAdvertisement +} + +// ManagedAddressConfig is true when addresses are available via DHCPv6. If +// set, the OtherConfig flag is redundant. +func (i *ICMPv6RouterAdvertisement) ManagedAddressConfig() bool { + return i.Flags&0x80 != 0 +} + +// OtherConfig is true when there is other configuration information available +// via DHCPv6. For example, DNS-related information. +func (i *ICMPv6RouterAdvertisement) OtherConfig() bool { + return i.Flags&0x40 != 0 +} + +// LayerType returns LayerTypeICMPv6NeighborSolicitation. +func (i *ICMPv6NeighborSolicitation) LayerType() gopacket.LayerType { + return LayerTypeICMPv6NeighborSolicitation +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (i *ICMPv6NeighborSolicitation) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (i *ICMPv6NeighborSolicitation) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 20 { + df.SetTruncated() + return errors.New("ICMP layer less then 20 bytes for ICMPv6 neighbor solicitation") + } + + i.TargetAddress = net.IP(data[4:20]) + i.BaseLayer = BaseLayer{data, nil} // assume no payload + + // truncate old options + i.Options = i.Options[:0] + + return i.Options.DecodeFromBytes(data[20:], df) +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (i *ICMPv6NeighborSolicitation) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if err := i.Options.SerializeTo(b, opts); err != nil { + return err + } + + buf, err := b.PrependBytes(20) + if err != nil { + return err + } + + copy(buf, lotsOfZeros[:4]) + copy(buf[4:], i.TargetAddress) + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (i *ICMPv6NeighborSolicitation) CanDecode() gopacket.LayerClass { + return LayerTypeICMPv6NeighborSolicitation +} + +// LayerType returns LayerTypeICMPv6NeighborAdvertisement. +func (i *ICMPv6NeighborAdvertisement) LayerType() gopacket.LayerType { + return LayerTypeICMPv6NeighborAdvertisement +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (i *ICMPv6NeighborAdvertisement) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (i *ICMPv6NeighborAdvertisement) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 20 { + df.SetTruncated() + return errors.New("ICMP layer less then 20 bytes for ICMPv6 neighbor advertisement") + } + + i.Flags = uint8(data[0]) + i.TargetAddress = net.IP(data[4:20]) + i.BaseLayer = BaseLayer{data, nil} // assume no payload + + // truncate old options + i.Options = i.Options[:0] + + return i.Options.DecodeFromBytes(data[20:], df) +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (i *ICMPv6NeighborAdvertisement) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if err := i.Options.SerializeTo(b, opts); err != nil { + return err + } + + buf, err := b.PrependBytes(20) + if err != nil { + return err + } + + buf[0] = byte(i.Flags) + copy(buf[1:], lotsOfZeros[:3]) + copy(buf[4:], i.TargetAddress) + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (i *ICMPv6NeighborAdvertisement) CanDecode() gopacket.LayerClass { + return LayerTypeICMPv6NeighborAdvertisement +} + +// Router indicates whether the sender is a router or not. +func (i *ICMPv6NeighborAdvertisement) Router() bool { + return i.Flags&0x80 != 0 +} + +// Solicited indicates whether the advertisement was solicited or not. +func (i *ICMPv6NeighborAdvertisement) Solicited() bool { + return i.Flags&0x40 != 0 +} + +// Override indicates whether the advertisement should Override an existing +// cache entry. +func (i *ICMPv6NeighborAdvertisement) Override() bool { + return i.Flags&0x20 != 0 +} + +// LayerType returns LayerTypeICMPv6Redirect. +func (i *ICMPv6Redirect) LayerType() gopacket.LayerType { + return LayerTypeICMPv6Redirect +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (i *ICMPv6Redirect) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (i *ICMPv6Redirect) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 36 { + df.SetTruncated() + return errors.New("ICMP layer less then 36 bytes for ICMPv6 redirect") + } + + i.TargetAddress = net.IP(data[4:20]) + i.DestinationAddress = net.IP(data[20:36]) + i.BaseLayer = BaseLayer{data, nil} // assume no payload + + // truncate old options + i.Options = i.Options[:0] + + return i.Options.DecodeFromBytes(data[36:], df) +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (i *ICMPv6Redirect) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if err := i.Options.SerializeTo(b, opts); err != nil { + return err + } + + buf, err := b.PrependBytes(36) + if err != nil { + return err + } + + copy(buf, lotsOfZeros[:4]) + copy(buf[4:], i.TargetAddress) + copy(buf[20:], i.DestinationAddress) + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (i *ICMPv6Redirect) CanDecode() gopacket.LayerClass { + return LayerTypeICMPv6Redirect +} + +func (i ICMPv6Option) String() string { + hd := hex.EncodeToString(i.Data) + if len(hd) > 0 { + hd = " 0x" + hd + } + + switch i.Type { + case ICMPv6OptSourceAddress, ICMPv6OptTargetAddress: + return fmt.Sprintf("ICMPv6Option(%s:%v)", + i.Type, + net.HardwareAddr(i.Data)) + case ICMPv6OptPrefixInfo: + if len(i.Data) == 30 { + prefixLen := uint8(i.Data[0]) + onLink := (i.Data[1]&0x80 != 0) + autonomous := (i.Data[1]&0x40 != 0) + validLifetime := time.Duration(binary.BigEndian.Uint32(i.Data[2:6])) * time.Second + preferredLifetime := time.Duration(binary.BigEndian.Uint32(i.Data[6:10])) * time.Second + + prefix := net.IP(i.Data[14:]) + + return fmt.Sprintf("ICMPv6Option(%s:%v/%v:%t:%t:%v:%v)", + i.Type, + prefix, prefixLen, + onLink, autonomous, + validLifetime, preferredLifetime) + } + case ICMPv6OptRedirectedHeader: + // could invoke IP decoder on data... probably best not to + break + case ICMPv6OptMTU: + if len(i.Data) == 6 { + return fmt.Sprintf("ICMPv6Option(%s:%v)", + i.Type, + binary.BigEndian.Uint32(i.Data[2:])) + } + + } + return fmt.Sprintf("ICMPv6Option(%s:%s)", i.Type, hd) +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (i *ICMPv6Options) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + for len(data) > 0 { + if len(data) < 2 { + df.SetTruncated() + return errors.New("ICMP layer less then 2 bytes for ICMPv6 message option") + } + + // unit is 8 octets, convert to bytes + length := int(data[1]) * 8 + + if length == 0 { + df.SetTruncated() + return errors.New("ICMPv6 message option with length 0") + } + + if len(data) < length { + df.SetTruncated() + return fmt.Errorf("ICMP layer only %v bytes for ICMPv6 message option with length %v", len(data), length) + } + + o := ICMPv6Option{ + Type: ICMPv6Opt(data[0]), + Data: data[2:length], + } + + // chop off option we just consumed + data = data[length:] + + *i = append(*i, o) + } + + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (i *ICMPv6Options) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + for _, opt := range []ICMPv6Option(*i) { + length := len(opt.Data) + 2 + buf, err := b.PrependBytes(length) + if err != nil { + return err + } + + buf[0] = byte(opt.Type) + buf[1] = byte(length / 8) + copy(buf[2:], opt.Data) + } + + return nil +} + +func decodeICMPv6Echo(data []byte, p gopacket.PacketBuilder) error { + i := &ICMPv6Echo{} + return decodingLayerDecoder(i, data, p) +} + +func decodeICMPv6RouterSolicitation(data []byte, p gopacket.PacketBuilder) error { + i := &ICMPv6RouterSolicitation{} + return decodingLayerDecoder(i, data, p) +} + +func decodeICMPv6RouterAdvertisement(data []byte, p gopacket.PacketBuilder) error { + i := &ICMPv6RouterAdvertisement{} + return decodingLayerDecoder(i, data, p) +} + +func decodeICMPv6NeighborSolicitation(data []byte, p gopacket.PacketBuilder) error { + i := &ICMPv6NeighborSolicitation{} + return decodingLayerDecoder(i, data, p) +} + +func decodeICMPv6NeighborAdvertisement(data []byte, p gopacket.PacketBuilder) error { + i := &ICMPv6NeighborAdvertisement{} + return decodingLayerDecoder(i, data, p) +} + +func decodeICMPv6Redirect(data []byte, p gopacket.PacketBuilder) error { + i := &ICMPv6Redirect{} + return decodingLayerDecoder(i, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/icmp6msg_test.go b/vendor/github.com/google/gopacket/layers/icmp6msg_test.go new file mode 100644 index 0000000000..5bc44d0bdd --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/icmp6msg_test.go @@ -0,0 +1,73 @@ +// Copyright 2012, Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "github.com/google/gopacket" + "testing" +) + +// testPacketICMPv6RouterAdvertisement is the packet: +// 23:34:40.014307 IP6 (class 0xe0, hlim 255, next-header ICMPv6 (58) payload length: 64) fe80::c000:54ff:fef5:0 > ip6-allnodes: [icmp6 sum ok] ICMP6, router advertisement, length 64 +// hop limit 64, Flags [none], pref medium, router lifetime 1800s, reachable time 0s, retrans time 0s +// source link-address option (1), length 8 (1): c2:00:54:f5:00:00 +// 0x0000: c200 54f5 0000 +// mtu option (5), length 8 (1): 1500 +// 0x0000: 0000 0000 05dc +// prefix info option (3), length 32 (4): 2001:db8:0:1::/64, Flags [onlink, auto], valid time 2592000s, pref. time 604800s +// 0x0000: 40c0 0027 8d00 0009 3a80 0000 0000 2001 +// 0x0010: 0db8 0000 0001 0000 0000 0000 0000 +// 0x0000: 3333 0000 0001 c200 54f5 0000 86dd 6e00 33......T.....n. +// 0x0010: 0000 0040 3aff fe80 0000 0000 0000 c000 ...@:........... +// 0x0020: 54ff fef5 0000 ff02 0000 0000 0000 0000 T............... +// 0x0030: 0000 0000 0001 8600 c4fe 4000 0708 0000 ..........@..... +// 0x0040: 0000 0000 0000 0101 c200 54f5 0000 0501 ..........T..... +// 0x0050: 0000 0000 05dc 0304 40c0 0027 8d00 0009 ........@..'.... +// 0x0060: 3a80 0000 0000 2001 0db8 0000 0001 0000 :............... +// 0x0070: 0000 0000 0000 +var testPacketICMPv6RouterAdvertisement = []byte{ + 0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0xc2, 0x00, 0x54, 0xf5, 0x00, 0x00, 0x86, 0xdd, 0x6e, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x3a, 0xff, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, + 0x54, 0xff, 0xfe, 0xf5, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, 0xc4, 0xfe, 0x40, 0x00, 0x07, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xc2, 0x00, 0x54, 0xf5, 0x00, 0x00, 0x05, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x05, 0xdc, 0x03, 0x04, 0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00, 0x00, 0x09, + 0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +func TestPacketICMPv6RouterAdvertisement(t *testing.T) { + p := gopacket.NewPacket(testPacketICMPv6RouterAdvertisement, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeICMPv6, LayerTypeICMPv6RouterAdvertisement}, t) +} + +// testPacketICMPv6NeighborSolicitation is the packet: +// 23:34:39.647300 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 24) :: > ff02::1:ff0e:4c67: [icmp6 sum ok] ICMP6, neighbor solicitation, length 24, who has fe80::20c:29ff:fe0e:4c67 +// 0x0000: 3333 ff0e 4c67 000c 290e 4c67 86dd 6000 33..Lg..).Lg..`. +// 0x0010: 0000 0018 3aff 0000 0000 0000 0000 0000 ....:........... +// 0x0020: 0000 0000 0000 ff02 0000 0000 0000 0000 ................ +// 0x0030: 0001 ff0e 4c67 8700 b930 0000 0000 fe80 ....Lg...0...... +// 0x0040: 0000 0000 0000 020c 29ff fe0e 4c67 ........)...Lg +var testPacketICMPv6NeighborSolicitation = []byte{ + 0x33, 0x33, 0xff, 0x0e, 0x4c, 0x67, 0x00, 0x0c, 0x29, 0x0e, 0x4c, 0x67, 0x86, 0xdd, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xff, 0x0e, 0x4c, 0x67, 0x87, 0x00, 0xb9, 0x30, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x29, 0xff, 0xfe, 0x0e, 0x4c, 0x67, +} + +func TestPacketICMPv6NeighborSolicitation(t *testing.T) { + p := gopacket.NewPacket(testPacketICMPv6NeighborSolicitation, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeICMPv6, LayerTypeICMPv6NeighborSolicitation}, t) +} diff --git a/vendor/github.com/google/gopacket/layers/ip4.go b/vendor/github.com/google/gopacket/layers/ip4.go index 3f31b27487..2b3c0c6bff 100644 --- a/vendor/github.com/google/gopacket/layers/ip4.go +++ b/vendor/github.com/google/gopacket/layers/ip4.go @@ -186,6 +186,10 @@ func (ip *IPv4) flagsfrags() (ff uint16) { // DecodeFromBytes decodes the given bytes into this layer. func (ip *IPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 20 { + df.SetTruncated() + return fmt.Errorf("Invalid ip4 header. Length %d less than 20", len(data)) + } flagsfrags := binary.BigEndian.Uint16(data[6:8]) ip.Version = uint8(data[0]) >> 4 @@ -201,6 +205,7 @@ func (ip *IPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { ip.SrcIP = data[12:16] ip.DstIP = data[16:20] ip.Options = ip.Options[:0] + ip.Padding = nil // Set up an initial guess for contents/payload... we'll reset these soon. ip.BaseLayer = BaseLayer{Contents: data} @@ -243,19 +248,28 @@ func (ip *IPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { opt.OptionLength = 1 ip.Options = append(ip.Options, opt) ip.Padding = data[1:] - break + return nil case 1: // 1 byte padding opt.OptionLength = 1 + data = data[1:] + ip.Options = append(ip.Options, opt) default: + if len(data) < 2 { + df.SetTruncated() + return fmt.Errorf("Invalid ip4 option length. Length %d less than 2", len(data)) + } opt.OptionLength = data[1] + if len(data) < int(opt.OptionLength) { + df.SetTruncated() + return fmt.Errorf("IP option length exceeds remaining IP header size, option type %v length %v", opt.OptionType, opt.OptionLength) + } + if opt.OptionLength <= 2 { + return fmt.Errorf("Invalid IP option type %v length %d. Must be greater than 2", opt.OptionType, opt.OptionLength) + } opt.OptionData = data[2:opt.OptionLength] - } - if len(data) >= int(opt.OptionLength) { data = data[opt.OptionLength:] - } else { - return fmt.Errorf("IP option length exceeds remaining IP header size, option type %v length %v", opt.OptionType, opt.OptionLength) + ip.Options = append(ip.Options, opt) } - ip.Options = append(ip.Options, opt) } return nil } diff --git a/vendor/github.com/google/gopacket/layers/ip4_test.go b/vendor/github.com/google/gopacket/layers/ip4_test.go index ec6b35129e..374778d8b3 100644 --- a/vendor/github.com/google/gopacket/layers/ip4_test.go +++ b/vendor/github.com/google/gopacket/layers/ip4_test.go @@ -9,9 +9,11 @@ package layers import ( + "bytes" "encoding/binary" "encoding/hex" "net" + "reflect" "testing" "github.com/google/gopacket" @@ -129,3 +131,94 @@ func TestChecksum(t *testing.T) { } } } + +func TestIPv4InvalidOptionLength(t *testing.T) { + // ip4 Packet with option 136 length set to zero + b, err := hex.DecodeString("460000705f5b0000ff114e02af2db00295ab7e0f88001234") + if err != nil { + t.Fatalf("Failed to Decode header: %v", err) + } + var ip4 IPv4 + err = ip4.DecodeFromBytes(b, gopacket.NilDecodeFeedback) + if err == nil { + t.Fatal("Expected 'invalid IP option length' error, but got none.") + } +} + +func TestIPv4Options(t *testing.T) { + var ip4 IPv4 // reuse ip4 to test reset + for _, test := range []struct { + packet string + options []IPv4Option + padding []byte + }{ + { + packet: "4800002803040000fe01c1e0af2db00095ab7e0b820b00000000000000000000", + options: []IPv4Option{ + { + OptionType: 130, + OptionData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0}, + OptionLength: 11, + }, + { + OptionType: 0, + OptionLength: 1, + }, + }, + }, + { + packet: "4900002803040000fe01c1e0af2db00095ab7e0b01820b00000000000000000000010203", + options: []IPv4Option{ + { + OptionType: 1, + OptionLength: 1, + }, + { + OptionType: 130, + OptionData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0}, + OptionLength: 11, + }, + { + OptionType: 0, + OptionLength: 1, + }, + }, + padding: []byte{1, 2, 3}, + }, + { + packet: "4800002803040000fe01c1e0af2db00095ab7e0b820c00000000000000000000", + options: []IPv4Option{ + { + OptionType: 130, + OptionData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + OptionLength: 12, + }, + }, + }, + { + packet: "4900002803040000fe01c1e0af2db00095ab7e0b00820b00000000000000000000010203", + options: []IPv4Option{ + { + OptionType: 0, + OptionLength: 1, + }, + }, + padding: []byte{0x82, 0x0b, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3}, + }, + } { + b, err := hex.DecodeString(test.packet) + if err != nil { + t.Fatalf("Failed to Decode header: %v", err) + } + err = ip4.DecodeFromBytes(b, gopacket.NilDecodeFeedback) + if err != nil { + t.Fatal("Unexpected error during decoding:", err) + } + if !reflect.DeepEqual(ip4.Options, test.options) { + t.Fatalf("Options mismatch.\nGot:\n%#v\nExpected:\n%#v\n", ip4.Options, test.options) + } + if !bytes.Equal(ip4.Padding, test.padding) { + t.Fatalf("Padding mismatch.\nGot:\n%#v\nExpected:\n%#v\n", ip4.Padding, test.padding) + } + } +} diff --git a/vendor/github.com/google/gopacket/layers/ip6.go b/vendor/github.com/google/gopacket/layers/ip6.go index b5befe9c6b..70e9c8d558 100644 --- a/vendor/github.com/google/gopacket/layers/ip6.go +++ b/vendor/github.com/google/gopacket/layers/ip6.go @@ -17,7 +17,8 @@ import ( ) const ( - IPv6HopByHopOptionJumbogram = 0xC2 // RFC 2675 + // IPv6HopByHopOptionJumbogram code as defined in RFC 2675 + IPv6HopByHopOptionJumbogram = 0xC2 ) const ( @@ -42,10 +43,11 @@ type IPv6 struct { } // LayerType returns LayerTypeIPv6 -func (i *IPv6) LayerType() gopacket.LayerType { return LayerTypeIPv6 } +func (ipv6 *IPv6) LayerType() gopacket.LayerType { return LayerTypeIPv6 } -func (i *IPv6) NetworkFlow() gopacket.Flow { - return gopacket.NewFlow(EndpointIPv6, i.SrcIP, i.DstIP) +// NetworkFlow returns this new Flow (EndpointIPv6, SrcIP, DstIP) +func (ipv6 *IPv6) NetworkFlow() gopacket.Flow { + return gopacket.NewFlow(EndpointIPv6, ipv6.SrcIP, ipv6.DstIP) } // Search for Jumbo Payload TLV in IPv6HopByHop and return (length, true) if found @@ -115,7 +117,7 @@ func setIPv6PayloadJumboLength(hbh []byte) error { opt := hbh[offset] if opt == 0 { //Pad1 - offset += 1 + offset++ continue } optLen := int(hbh[offset+1]) @@ -134,7 +136,7 @@ func setIPv6PayloadJumboLength(hbh []byte) error { // SerializeTo writes the serialized form of this layer into the // SerializationBuffer, implementing gopacket.SerializableLayer. // See the docs for gopacket.SerializableLayer for more info. -func (ip6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { +func (ipv6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { var jumbo bool var err error @@ -145,11 +147,11 @@ func (ip6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Serialize if opts.FixLengths { // We need to set the length later because the hop-by-hop header may // not exist or else need padding, so pLen may yet change - addIPv6JumboOption(ip6) - } else if ip6.HopByHop == nil { + addIPv6JumboOption(ipv6) + } else if ipv6.HopByHop == nil { return fmt.Errorf("Cannot fit payload length of %d into IPv6 packet", pLen) } else { - _, ok, err := getIPv6HopByHopJumboLength(ip6.HopByHop) + _, ok, err := getIPv6HopByHopJumboLength(ipv6.HopByHop) if err != nil { return err } @@ -158,12 +160,22 @@ func (ip6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Serialize } } } - if ip6.HopByHop != nil { - if ip6.NextHeader != IPProtocolIPv6HopByHop { + + hbhAlreadySerialized := false + if ipv6.HopByHop != nil { + for _, l := range b.Layers() { + if l == LayerTypeIPv6HopByHop { + hbhAlreadySerialized = true + break + } + } + } + if ipv6.HopByHop != nil && !hbhAlreadySerialized { + if ipv6.NextHeader != IPProtocolIPv6HopByHop { // Just fix it instead of throwing an error - ip6.NextHeader = IPProtocolIPv6HopByHop + ipv6.NextHeader = IPProtocolIPv6HopByHop } - err = ip6.HopByHop.SerializeTo(b, opts) + err = ipv6.HopByHop.SerializeTo(b, opts) if err != nil { return err } @@ -176,6 +188,7 @@ func (ip6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Serialize } } } + if !jumbo && pLen > ipv6MaxPayloadLength { return errors.New("Cannot fit payload into IPv6 header") } @@ -183,88 +196,98 @@ func (ip6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Serialize if err != nil { return err } - bytes[0] = (ip6.Version << 4) | (ip6.TrafficClass >> 4) - bytes[1] = (ip6.TrafficClass << 4) | uint8(ip6.FlowLabel>>16) - binary.BigEndian.PutUint16(bytes[2:], uint16(ip6.FlowLabel)) + bytes[0] = (ipv6.Version << 4) | (ipv6.TrafficClass >> 4) + bytes[1] = (ipv6.TrafficClass << 4) | uint8(ipv6.FlowLabel>>16) + binary.BigEndian.PutUint16(bytes[2:], uint16(ipv6.FlowLabel)) if opts.FixLengths { if jumbo { - ip6.Length = 0 + ipv6.Length = 0 } else { - ip6.Length = uint16(pLen) + ipv6.Length = uint16(pLen) } } - binary.BigEndian.PutUint16(bytes[4:], ip6.Length) - bytes[6] = byte(ip6.NextHeader) - bytes[7] = byte(ip6.HopLimit) - if err := ip6.AddressTo16(); err != nil { + binary.BigEndian.PutUint16(bytes[4:], ipv6.Length) + bytes[6] = byte(ipv6.NextHeader) + bytes[7] = byte(ipv6.HopLimit) + if err := ipv6.AddressTo16(); err != nil { return err } - copy(bytes[8:], ip6.SrcIP) - copy(bytes[24:], ip6.DstIP) + copy(bytes[8:], ipv6.SrcIP) + copy(bytes[24:], ipv6.DstIP) return nil } -func (ip6 *IPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { - ip6.Version = uint8(data[0]) >> 4 - ip6.TrafficClass = uint8((binary.BigEndian.Uint16(data[0:2]) >> 4) & 0x00FF) - ip6.FlowLabel = binary.BigEndian.Uint32(data[0:4]) & 0x000FFFFF - ip6.Length = binary.BigEndian.Uint16(data[4:6]) - ip6.NextHeader = IPProtocol(data[6]) - ip6.HopLimit = data[7] - ip6.SrcIP = data[8:24] - ip6.DstIP = data[24:40] - ip6.HopByHop = nil - ip6.BaseLayer = BaseLayer{data[:40], data[40:]} +// DecodeFromBytes implementation according to gopacket.DecodingLayer +func (ipv6 *IPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 40 { + df.SetTruncated() + return fmt.Errorf("Invalid ip6 header. Length %d less than 40", len(data)) + } + ipv6.Version = uint8(data[0]) >> 4 + ipv6.TrafficClass = uint8((binary.BigEndian.Uint16(data[0:2]) >> 4) & 0x00FF) + ipv6.FlowLabel = binary.BigEndian.Uint32(data[0:4]) & 0x000FFFFF + ipv6.Length = binary.BigEndian.Uint16(data[4:6]) + ipv6.NextHeader = IPProtocol(data[6]) + ipv6.HopLimit = data[7] + ipv6.SrcIP = data[8:24] + ipv6.DstIP = data[24:40] + ipv6.HopByHop = nil + ipv6.BaseLayer = BaseLayer{data[:40], data[40:]} // We treat a HopByHop IPv6 option as part of the IPv6 packet, since its // options are crucial for understanding what's actually happening per packet. - if ip6.NextHeader == IPProtocolIPv6HopByHop { - err := ip6.hbh.DecodeFromBytes(ip6.Payload, df) + if ipv6.NextHeader == IPProtocolIPv6HopByHop { + err := ipv6.hbh.DecodeFromBytes(ipv6.Payload, df) if err != nil { return err } - ip6.HopByHop = &ip6.hbh - pEnd, jumbo, err := getIPv6HopByHopJumboLength(ip6.HopByHop) + ipv6.HopByHop = &ipv6.hbh + pEnd, jumbo, err := getIPv6HopByHopJumboLength(ipv6.HopByHop) if err != nil { return err } - if jumbo && ip6.Length == 0 { + if jumbo && ipv6.Length == 0 { pEnd := int(pEnd) - if pEnd > len(ip6.Payload) { + if pEnd > len(ipv6.Payload) { df.SetTruncated() - pEnd = len(ip6.Payload) + pEnd = len(ipv6.Payload) } - ip6.Payload = ip6.Payload[:pEnd] + ipv6.Payload = ipv6.Payload[:pEnd] return nil - } else if jumbo && ip6.Length != 0 { + } else if jumbo && ipv6.Length != 0 { return errors.New("IPv6 has jumbo length and IPv6 length is not 0") - } else if !jumbo && ip6.Length == 0 { + } else if !jumbo && ipv6.Length == 0 { return errors.New("IPv6 length 0, but HopByHop header does not have jumbogram option") + } else { + ipv6.Payload = ipv6.Payload[ipv6.hbh.ActualLength:] } } - if ip6.Length == 0 { - return fmt.Errorf("IPv6 length 0, but next header is %v, not HopByHop", ip6.NextHeader) - } else { - pEnd := int(ip6.Length) - if pEnd > len(ip6.Payload) { - df.SetTruncated() - pEnd = len(ip6.Payload) - } - ip6.Payload = ip6.Payload[:pEnd] + if ipv6.Length == 0 { + return fmt.Errorf("IPv6 length 0, but next header is %v, not HopByHop", ipv6.NextHeader) + } + + pEnd := int(ipv6.Length) + if pEnd > len(ipv6.Payload) { + df.SetTruncated() + pEnd = len(ipv6.Payload) } + ipv6.Payload = ipv6.Payload[:pEnd] + return nil } -func (i *IPv6) CanDecode() gopacket.LayerClass { +// CanDecode implementation according to gopacket.DecodingLayer +func (ipv6 *IPv6) CanDecode() gopacket.LayerClass { return LayerTypeIPv6 } -func (i *IPv6) NextLayerType() gopacket.LayerType { - if i.HopByHop != nil { - return i.HopByHop.NextHeader.LayerType() +// NextLayerType implementation according to gopacket.DecodingLayer +func (ipv6 *IPv6) NextLayerType() gopacket.LayerType { + if ipv6.HopByHop != nil { + return ipv6.HopByHop.NextHeader.LayerType() } - return i.NextHeader.LayerType() + return ipv6.NextHeader.LayerType() } func decodeIPv6(data []byte, p gopacket.PacketBuilder) error { @@ -384,10 +407,17 @@ type ipv6ExtensionBase struct { ActualLength int } -func decodeIPv6ExtensionBase(data []byte) (i ipv6ExtensionBase) { +func decodeIPv6ExtensionBase(data []byte, df gopacket.DecodeFeedback) (i ipv6ExtensionBase, returnedErr error) { + if len(data) < 2 { + df.SetTruncated() + return ipv6ExtensionBase{}, fmt.Errorf("Invalid ip6-extension header. Length %d less than 2", len(data)) + } i.NextHeader = IPProtocol(data[0]) i.HeaderLength = data[1] i.ActualLength = int(i.HeaderLength)*8 + 8 + if len(data) < i.ActualLength { + return ipv6ExtensionBase{}, fmt.Errorf("Invalid ip6-extension header. Length %d less than specified length %d", len(data), i.ActualLength) + } i.Contents = data[:i.ActualLength] i.Payload = data[i.ActualLength:] return @@ -401,17 +431,23 @@ type IPv6ExtensionSkipper struct { BaseLayer } +// DecodeFromBytes implementation according to gopacket.DecodingLayer func (i *IPv6ExtensionSkipper) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { - extension := decodeIPv6ExtensionBase(data) + extension, err := decodeIPv6ExtensionBase(data, df) + if err != nil { + return err + } i.BaseLayer = BaseLayer{data[:extension.ActualLength], data[extension.ActualLength:]} i.NextHeader = extension.NextHeader return nil } +// CanDecode implementation according to gopacket.DecodingLayer func (i *IPv6ExtensionSkipper) CanDecode() gopacket.LayerClass { return LayerClassIPv6Extension } +// NextLayerType implementation according to gopacket.DecodingLayer func (i *IPv6ExtensionSkipper) NextLayerType() gopacket.LayerType { return i.NextHeader.LayerType() } @@ -428,6 +464,7 @@ type IPv6HopByHop struct { // LayerType returns LayerTypeIPv6HopByHop. func (i *IPv6HopByHop) LayerType() gopacket.LayerType { return LayerTypeIPv6HopByHop } +// SerializeTo implementation according to gopacket.SerializableLayer func (i *IPv6HopByHop) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { var bytes []byte var err error @@ -460,8 +497,13 @@ func (i *IPv6HopByHop) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Ser return nil } +// DecodeFromBytes implementation according to gopacket.DecodingLayer func (i *IPv6HopByHop) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { - i.ipv6ExtensionBase = decodeIPv6ExtensionBase(data) + var err error + i.ipv6ExtensionBase, err = decodeIPv6ExtensionBase(data, df) + if err != nil { + return err + } offset := 2 for offset < i.ActualLength { opt := decodeIPv6HeaderTLVOption(data[offset:]) @@ -481,6 +523,7 @@ func decodeIPv6HopByHop(data []byte, p gopacket.PacketBuilder) error { return p.NextDecoder(i.NextHeader) } +// SetJumboLength adds the IPv6HopByHopOptionJumbogram with the given length func (o *IPv6HopByHopOption) SetJumboLength(len uint32) { o.OptionType = IPv6HopByHopOptionJumbogram o.OptionLength = 4 @@ -509,8 +552,12 @@ type IPv6Routing struct { func (i *IPv6Routing) LayerType() gopacket.LayerType { return LayerTypeIPv6Routing } func decodeIPv6Routing(data []byte, p gopacket.PacketBuilder) error { + base, err := decodeIPv6ExtensionBase(data, p) + if err != nil { + return err + } i := &IPv6Routing{ - ipv6ExtensionBase: decodeIPv6ExtensionBase(data), + ipv6ExtensionBase: base, RoutingType: data[2], SegmentsLeft: data[3], Reserved: data[4:8], @@ -548,6 +595,10 @@ type IPv6Fragment struct { func (i *IPv6Fragment) LayerType() gopacket.LayerType { return LayerTypeIPv6Fragment } func decodeIPv6Fragment(data []byte, p gopacket.PacketBuilder) error { + if len(data) < 8 { + p.SetTruncated() + return fmt.Errorf("Invalid ip6-fragment header. Length %d less than 8", len(data)) + } i := &IPv6Fragment{ BaseLayer: BaseLayer{data[:8], data[8:]}, NextHeader: IPProtocol(data[0]), @@ -573,8 +624,13 @@ type IPv6Destination struct { // LayerType returns LayerTypeIPv6Destination. func (i *IPv6Destination) LayerType() gopacket.LayerType { return LayerTypeIPv6Destination } +// DecodeFromBytes implementation according to gopacket.DecodingLayer func (i *IPv6Destination) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { - i.ipv6ExtensionBase = decodeIPv6ExtensionBase(data) + var err error + i.ipv6ExtensionBase, err = decodeIPv6ExtensionBase(data, df) + if err != nil { + return err + } offset := 2 for offset < i.ActualLength { opt := decodeIPv6HeaderTLVOption(data[offset:]) @@ -639,11 +695,12 @@ func checkIPv6Address(addr net.IP) error { return fmt.Errorf("wrong length of %d bytes instead of %d", len(addr), net.IPv6len) } -func (ip *IPv6) AddressTo16() error { - if err := checkIPv6Address(ip.SrcIP); err != nil { +// AddressTo16 ensures IPv6.SrcIP and IPv6.DstIP are actually IPv6 addresses (i.e. 16 byte addresses) +func (ipv6 *IPv6) AddressTo16() error { + if err := checkIPv6Address(ipv6.SrcIP); err != nil { return fmt.Errorf("Invalid source IPv6 address (%s)", err) } - if err := checkIPv6Address(ip.DstIP); err != nil { + if err := checkIPv6Address(ipv6.DstIP); err != nil { return fmt.Errorf("Invalid destination IPv6 address (%s)", err) } return nil diff --git a/vendor/github.com/google/gopacket/layers/ip6_test.go b/vendor/github.com/google/gopacket/layers/ip6_test.go index ab22f1784c..0c2531ae6c 100644 --- a/vendor/github.com/google/gopacket/layers/ip6_test.go +++ b/vendor/github.com/google/gopacket/layers/ip6_test.go @@ -99,7 +99,7 @@ var testPacketIPv6HopByHop0 = []byte{ } func TestPacketIPv6HopByHop0Serialize(t *testing.T) { - var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 2) + var serialize = make([]gopacket.SerializableLayer, 0, 2) var err error ip6 := &IPv6{} @@ -140,7 +140,7 @@ func TestPacketIPv6HopByHop0Decode(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, }, - Payload: []byte{0x3b, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00}, + Payload: []byte{}, }, Version: 6, TrafficClass: 0, @@ -208,7 +208,7 @@ var testPacketIPv6Destination0 = []byte{ } func TestPacketIPv6Destination0Serialize(t *testing.T) { - var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 2) + var serialize = make([]gopacket.SerializableLayer, 0, 2) var err error ip6 := &IPv6{} @@ -308,7 +308,7 @@ var testPacketIPv6JumbogramHeader = []byte{ } func TestIPv6JumbogramSerialize(t *testing.T) { - var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 2) + var serialize = make([]gopacket.SerializableLayer, 0, 2) var err error ip6 := &IPv6{} diff --git a/vendor/github.com/google/gopacket/layers/layertypes.go b/vendor/github.com/google/gopacket/layers/layertypes.go index faffb91ad8..56fdb5a50c 100644 --- a/vendor/github.com/google/gopacket/layers/layertypes.go +++ b/vendor/github.com/google/gopacket/layers/layertypes.go @@ -11,120 +11,138 @@ import ( ) var ( - LayerTypeARP = gopacket.RegisterLayerType(10, gopacket.LayerTypeMetadata{Name: "ARP", Decoder: gopacket.DecodeFunc(decodeARP)}) - LayerTypeCiscoDiscovery = gopacket.RegisterLayerType(11, gopacket.LayerTypeMetadata{Name: "CiscoDiscovery", Decoder: gopacket.DecodeFunc(decodeCiscoDiscovery)}) - LayerTypeEthernetCTP = gopacket.RegisterLayerType(12, gopacket.LayerTypeMetadata{Name: "EthernetCTP", Decoder: gopacket.DecodeFunc(decodeEthernetCTP)}) - LayerTypeEthernetCTPForwardData = gopacket.RegisterLayerType(13, gopacket.LayerTypeMetadata{Name: "EthernetCTPForwardData", Decoder: nil}) - LayerTypeEthernetCTPReply = gopacket.RegisterLayerType(14, gopacket.LayerTypeMetadata{Name: "EthernetCTPReply", Decoder: nil}) - LayerTypeDot1Q = gopacket.RegisterLayerType(15, gopacket.LayerTypeMetadata{Name: "Dot1Q", Decoder: gopacket.DecodeFunc(decodeDot1Q)}) - LayerTypeEtherIP = gopacket.RegisterLayerType(16, gopacket.LayerTypeMetadata{Name: "EtherIP", Decoder: gopacket.DecodeFunc(decodeEtherIP)}) - LayerTypeEthernet = gopacket.RegisterLayerType(17, gopacket.LayerTypeMetadata{Name: "Ethernet", Decoder: gopacket.DecodeFunc(decodeEthernet)}) - LayerTypeGRE = gopacket.RegisterLayerType(18, gopacket.LayerTypeMetadata{Name: "GRE", Decoder: gopacket.DecodeFunc(decodeGRE)}) - LayerTypeICMPv4 = gopacket.RegisterLayerType(19, gopacket.LayerTypeMetadata{Name: "ICMPv4", Decoder: gopacket.DecodeFunc(decodeICMPv4)}) - LayerTypeIPv4 = gopacket.RegisterLayerType(20, gopacket.LayerTypeMetadata{Name: "IPv4", Decoder: gopacket.DecodeFunc(decodeIPv4)}) - LayerTypeIPv6 = gopacket.RegisterLayerType(21, gopacket.LayerTypeMetadata{Name: "IPv6", Decoder: gopacket.DecodeFunc(decodeIPv6)}) - LayerTypeLLC = gopacket.RegisterLayerType(22, gopacket.LayerTypeMetadata{Name: "LLC", Decoder: gopacket.DecodeFunc(decodeLLC)}) - LayerTypeSNAP = gopacket.RegisterLayerType(23, gopacket.LayerTypeMetadata{Name: "SNAP", Decoder: gopacket.DecodeFunc(decodeSNAP)}) - LayerTypeMPLS = gopacket.RegisterLayerType(24, gopacket.LayerTypeMetadata{Name: "MPLS", Decoder: gopacket.DecodeFunc(decodeMPLS)}) - LayerTypePPP = gopacket.RegisterLayerType(25, gopacket.LayerTypeMetadata{Name: "PPP", Decoder: gopacket.DecodeFunc(decodePPP)}) - LayerTypePPPoE = gopacket.RegisterLayerType(26, gopacket.LayerTypeMetadata{Name: "PPPoE", Decoder: gopacket.DecodeFunc(decodePPPoE)}) - LayerTypeRUDP = gopacket.RegisterLayerType(27, gopacket.LayerTypeMetadata{Name: "RUDP", Decoder: gopacket.DecodeFunc(decodeRUDP)}) - LayerTypeSCTP = gopacket.RegisterLayerType(28, gopacket.LayerTypeMetadata{Name: "SCTP", Decoder: gopacket.DecodeFunc(decodeSCTP)}) - LayerTypeSCTPUnknownChunkType = gopacket.RegisterLayerType(29, gopacket.LayerTypeMetadata{Name: "SCTPUnknownChunkType", Decoder: nil}) - LayerTypeSCTPData = gopacket.RegisterLayerType(30, gopacket.LayerTypeMetadata{Name: "SCTPData", Decoder: nil}) - LayerTypeSCTPInit = gopacket.RegisterLayerType(31, gopacket.LayerTypeMetadata{Name: "SCTPInit", Decoder: nil}) - LayerTypeSCTPSack = gopacket.RegisterLayerType(32, gopacket.LayerTypeMetadata{Name: "SCTPSack", Decoder: nil}) - LayerTypeSCTPHeartbeat = gopacket.RegisterLayerType(33, gopacket.LayerTypeMetadata{Name: "SCTPHeartbeat", Decoder: nil}) - LayerTypeSCTPError = gopacket.RegisterLayerType(34, gopacket.LayerTypeMetadata{Name: "SCTPError", Decoder: nil}) - LayerTypeSCTPShutdown = gopacket.RegisterLayerType(35, gopacket.LayerTypeMetadata{Name: "SCTPShutdown", Decoder: nil}) - LayerTypeSCTPShutdownAck = gopacket.RegisterLayerType(36, gopacket.LayerTypeMetadata{Name: "SCTPShutdownAck", Decoder: nil}) - LayerTypeSCTPCookieEcho = gopacket.RegisterLayerType(37, gopacket.LayerTypeMetadata{Name: "SCTPCookieEcho", Decoder: nil}) - LayerTypeSCTPEmptyLayer = gopacket.RegisterLayerType(38, gopacket.LayerTypeMetadata{Name: "SCTPEmptyLayer", Decoder: nil}) - LayerTypeSCTPInitAck = gopacket.RegisterLayerType(39, gopacket.LayerTypeMetadata{Name: "SCTPInitAck", Decoder: nil}) - LayerTypeSCTPHeartbeatAck = gopacket.RegisterLayerType(40, gopacket.LayerTypeMetadata{Name: "SCTPHeartbeatAck", Decoder: nil}) - LayerTypeSCTPAbort = gopacket.RegisterLayerType(41, gopacket.LayerTypeMetadata{Name: "SCTPAbort", Decoder: nil}) - LayerTypeSCTPShutdownComplete = gopacket.RegisterLayerType(42, gopacket.LayerTypeMetadata{Name: "SCTPShutdownComplete", Decoder: nil}) - LayerTypeSCTPCookieAck = gopacket.RegisterLayerType(43, gopacket.LayerTypeMetadata{Name: "SCTPCookieAck", Decoder: nil}) - LayerTypeTCP = gopacket.RegisterLayerType(44, gopacket.LayerTypeMetadata{Name: "TCP", Decoder: gopacket.DecodeFunc(decodeTCP)}) - LayerTypeUDP = gopacket.RegisterLayerType(45, gopacket.LayerTypeMetadata{Name: "UDP", Decoder: gopacket.DecodeFunc(decodeUDP)}) - LayerTypeIPv6HopByHop = gopacket.RegisterLayerType(46, gopacket.LayerTypeMetadata{Name: "IPv6HopByHop", Decoder: gopacket.DecodeFunc(decodeIPv6HopByHop)}) - LayerTypeIPv6Routing = gopacket.RegisterLayerType(47, gopacket.LayerTypeMetadata{Name: "IPv6Routing", Decoder: gopacket.DecodeFunc(decodeIPv6Routing)}) - LayerTypeIPv6Fragment = gopacket.RegisterLayerType(48, gopacket.LayerTypeMetadata{Name: "IPv6Fragment", Decoder: gopacket.DecodeFunc(decodeIPv6Fragment)}) - LayerTypeIPv6Destination = gopacket.RegisterLayerType(49, gopacket.LayerTypeMetadata{Name: "IPv6Destination", Decoder: gopacket.DecodeFunc(decodeIPv6Destination)}) - LayerTypeIPSecAH = gopacket.RegisterLayerType(50, gopacket.LayerTypeMetadata{Name: "IPSecAH", Decoder: gopacket.DecodeFunc(decodeIPSecAH)}) - LayerTypeIPSecESP = gopacket.RegisterLayerType(51, gopacket.LayerTypeMetadata{Name: "IPSecESP", Decoder: gopacket.DecodeFunc(decodeIPSecESP)}) - LayerTypeUDPLite = gopacket.RegisterLayerType(52, gopacket.LayerTypeMetadata{Name: "UDPLite", Decoder: gopacket.DecodeFunc(decodeUDPLite)}) - LayerTypeFDDI = gopacket.RegisterLayerType(53, gopacket.LayerTypeMetadata{Name: "FDDI", Decoder: gopacket.DecodeFunc(decodeFDDI)}) - LayerTypeLoopback = gopacket.RegisterLayerType(54, gopacket.LayerTypeMetadata{Name: "Loopback", Decoder: gopacket.DecodeFunc(decodeLoopback)}) - LayerTypeEAP = gopacket.RegisterLayerType(55, gopacket.LayerTypeMetadata{Name: "EAP", Decoder: gopacket.DecodeFunc(decodeEAP)}) - LayerTypeEAPOL = gopacket.RegisterLayerType(56, gopacket.LayerTypeMetadata{Name: "EAPOL", Decoder: gopacket.DecodeFunc(decodeEAPOL)}) - LayerTypeICMPv6 = gopacket.RegisterLayerType(57, gopacket.LayerTypeMetadata{Name: "ICMPv6", Decoder: gopacket.DecodeFunc(decodeICMPv6)}) - LayerTypeLinkLayerDiscovery = gopacket.RegisterLayerType(58, gopacket.LayerTypeMetadata{Name: "LinkLayerDiscovery", Decoder: gopacket.DecodeFunc(decodeLinkLayerDiscovery)}) - LayerTypeCiscoDiscoveryInfo = gopacket.RegisterLayerType(59, gopacket.LayerTypeMetadata{Name: "CiscoDiscoveryInfo", Decoder: gopacket.DecodeFunc(decodeCiscoDiscoveryInfo)}) - LayerTypeLinkLayerDiscoveryInfo = gopacket.RegisterLayerType(60, gopacket.LayerTypeMetadata{Name: "LinkLayerDiscoveryInfo", Decoder: nil}) - LayerTypeNortelDiscovery = gopacket.RegisterLayerType(61, gopacket.LayerTypeMetadata{Name: "NortelDiscovery", Decoder: gopacket.DecodeFunc(decodeNortelDiscovery)}) - LayerTypeIGMP = gopacket.RegisterLayerType(62, gopacket.LayerTypeMetadata{Name: "IGMP", Decoder: gopacket.DecodeFunc(decodeIGMP)}) - LayerTypePFLog = gopacket.RegisterLayerType(63, gopacket.LayerTypeMetadata{Name: "PFLog", Decoder: gopacket.DecodeFunc(decodePFLog)}) - LayerTypeRadioTap = gopacket.RegisterLayerType(64, gopacket.LayerTypeMetadata{Name: "RadioTap", Decoder: gopacket.DecodeFunc(decodeRadioTap)}) - LayerTypeDot11 = gopacket.RegisterLayerType(65, gopacket.LayerTypeMetadata{Name: "Dot11", Decoder: gopacket.DecodeFunc(decodeDot11)}) - LayerTypeDot11Ctrl = gopacket.RegisterLayerType(66, gopacket.LayerTypeMetadata{Name: "Dot11Ctrl", Decoder: gopacket.DecodeFunc(decodeDot11Ctrl)}) - LayerTypeDot11Data = gopacket.RegisterLayerType(67, gopacket.LayerTypeMetadata{Name: "Dot11Data", Decoder: gopacket.DecodeFunc(decodeDot11Data)}) - LayerTypeDot11DataCFAck = gopacket.RegisterLayerType(68, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAck)}) - LayerTypeDot11DataCFPoll = gopacket.RegisterLayerType(69, gopacket.LayerTypeMetadata{Name: "Dot11DataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFPoll)}) - LayerTypeDot11DataCFAckPoll = gopacket.RegisterLayerType(70, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAckPoll)}) - LayerTypeDot11DataNull = gopacket.RegisterLayerType(71, gopacket.LayerTypeMetadata{Name: "Dot11DataNull", Decoder: gopacket.DecodeFunc(decodeDot11DataNull)}) - LayerTypeDot11DataCFAckNoData = gopacket.RegisterLayerType(72, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAck)}) - LayerTypeDot11DataCFPollNoData = gopacket.RegisterLayerType(73, gopacket.LayerTypeMetadata{Name: "Dot11DataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFPoll)}) - LayerTypeDot11DataCFAckPollNoData = gopacket.RegisterLayerType(74, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAckPoll)}) - LayerTypeDot11DataQOSData = gopacket.RegisterLayerType(75, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSData", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSData)}) - LayerTypeDot11DataQOSDataCFAck = gopacket.RegisterLayerType(76, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAck)}) - LayerTypeDot11DataQOSDataCFPoll = gopacket.RegisterLayerType(77, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFPoll)}) - LayerTypeDot11DataQOSDataCFAckPoll = gopacket.RegisterLayerType(78, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAckPoll)}) - LayerTypeDot11DataQOSNull = gopacket.RegisterLayerType(79, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSNull", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSNull)}) - LayerTypeDot11DataQOSCFPollNoData = gopacket.RegisterLayerType(80, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSCFPollNoData)}) - LayerTypeDot11DataQOSCFAckPollNoData = gopacket.RegisterLayerType(81, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSCFAckPollNoData)}) - LayerTypeDot11InformationElement = gopacket.RegisterLayerType(82, gopacket.LayerTypeMetadata{Name: "Dot11InformationElement", Decoder: gopacket.DecodeFunc(decodeDot11InformationElement)}) - LayerTypeDot11CtrlCTS = gopacket.RegisterLayerType(83, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCTS", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCTS)}) - LayerTypeDot11CtrlRTS = gopacket.RegisterLayerType(84, gopacket.LayerTypeMetadata{Name: "Dot11CtrlRTS", Decoder: gopacket.DecodeFunc(decodeDot11CtrlRTS)}) - LayerTypeDot11CtrlBlockAckReq = gopacket.RegisterLayerType(85, gopacket.LayerTypeMetadata{Name: "Dot11CtrlBlockAckReq", Decoder: gopacket.DecodeFunc(decodeDot11CtrlBlockAckReq)}) - LayerTypeDot11CtrlBlockAck = gopacket.RegisterLayerType(86, gopacket.LayerTypeMetadata{Name: "Dot11CtrlBlockAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlBlockAck)}) - LayerTypeDot11CtrlPowersavePoll = gopacket.RegisterLayerType(87, gopacket.LayerTypeMetadata{Name: "Dot11CtrlPowersavePoll", Decoder: gopacket.DecodeFunc(decodeDot11CtrlPowersavePoll)}) - LayerTypeDot11CtrlAck = gopacket.RegisterLayerType(88, gopacket.LayerTypeMetadata{Name: "Dot11CtrlAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlAck)}) - LayerTypeDot11CtrlCFEnd = gopacket.RegisterLayerType(89, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCFEnd", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCFEnd)}) - LayerTypeDot11CtrlCFEndAck = gopacket.RegisterLayerType(90, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCFEndAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCFEndAck)}) - LayerTypeDot11MgmtAssociationReq = gopacket.RegisterLayerType(91, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAssociationReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAssociationReq)}) - LayerTypeDot11MgmtAssociationResp = gopacket.RegisterLayerType(92, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAssociationResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAssociationResp)}) - LayerTypeDot11MgmtReassociationReq = gopacket.RegisterLayerType(93, gopacket.LayerTypeMetadata{Name: "Dot11MgmtReassociationReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtReassociationReq)}) - LayerTypeDot11MgmtReassociationResp = gopacket.RegisterLayerType(94, gopacket.LayerTypeMetadata{Name: "Dot11MgmtReassociationResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtReassociationResp)}) - LayerTypeDot11MgmtProbeReq = gopacket.RegisterLayerType(95, gopacket.LayerTypeMetadata{Name: "Dot11MgmtProbeReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtProbeReq)}) - LayerTypeDot11MgmtProbeResp = gopacket.RegisterLayerType(96, gopacket.LayerTypeMetadata{Name: "Dot11MgmtProbeResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtProbeResp)}) - LayerTypeDot11MgmtMeasurementPilot = gopacket.RegisterLayerType(97, gopacket.LayerTypeMetadata{Name: "Dot11MgmtMeasurementPilot", Decoder: gopacket.DecodeFunc(decodeDot11MgmtMeasurementPilot)}) - LayerTypeDot11MgmtBeacon = gopacket.RegisterLayerType(98, gopacket.LayerTypeMetadata{Name: "Dot11MgmtBeacon", Decoder: gopacket.DecodeFunc(decodeDot11MgmtBeacon)}) - LayerTypeDot11MgmtATIM = gopacket.RegisterLayerType(99, gopacket.LayerTypeMetadata{Name: "Dot11MgmtATIM", Decoder: gopacket.DecodeFunc(decodeDot11MgmtATIM)}) - LayerTypeDot11MgmtDisassociation = gopacket.RegisterLayerType(100, gopacket.LayerTypeMetadata{Name: "Dot11MgmtDisassociation", Decoder: gopacket.DecodeFunc(decodeDot11MgmtDisassociation)}) - LayerTypeDot11MgmtAuthentication = gopacket.RegisterLayerType(101, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAuthentication", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAuthentication)}) - LayerTypeDot11MgmtDeauthentication = gopacket.RegisterLayerType(102, gopacket.LayerTypeMetadata{Name: "Dot11MgmtDeauthentication", Decoder: gopacket.DecodeFunc(decodeDot11MgmtDeauthentication)}) - LayerTypeDot11MgmtAction = gopacket.RegisterLayerType(103, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAction", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAction)}) - LayerTypeDot11MgmtActionNoAck = gopacket.RegisterLayerType(104, gopacket.LayerTypeMetadata{Name: "Dot11MgmtActionNoAck", Decoder: gopacket.DecodeFunc(decodeDot11MgmtActionNoAck)}) - LayerTypeDot11MgmtArubaWLAN = gopacket.RegisterLayerType(105, gopacket.LayerTypeMetadata{Name: "Dot11MgmtArubaWLAN", Decoder: gopacket.DecodeFunc(decodeDot11MgmtArubaWLAN)}) - LayerTypeDot11WEP = gopacket.RegisterLayerType(106, gopacket.LayerTypeMetadata{Name: "Dot11WEP", Decoder: gopacket.DecodeFunc(decodeDot11WEP)}) - LayerTypeDNS = gopacket.RegisterLayerType(107, gopacket.LayerTypeMetadata{Name: "DNS", Decoder: gopacket.DecodeFunc(decodeDNS)}) - LayerTypeUSB = gopacket.RegisterLayerType(108, gopacket.LayerTypeMetadata{Name: "USB", Decoder: gopacket.DecodeFunc(decodeUSB)}) - LayerTypeUSBRequestBlockSetup = gopacket.RegisterLayerType(109, gopacket.LayerTypeMetadata{Name: "USBRequestBlockSetup", Decoder: gopacket.DecodeFunc(decodeUSBRequestBlockSetup)}) - LayerTypeUSBControl = gopacket.RegisterLayerType(110, gopacket.LayerTypeMetadata{Name: "USBControl", Decoder: gopacket.DecodeFunc(decodeUSBControl)}) - LayerTypeUSBInterrupt = gopacket.RegisterLayerType(111, gopacket.LayerTypeMetadata{Name: "USBInterrupt", Decoder: gopacket.DecodeFunc(decodeUSBInterrupt)}) - LayerTypeUSBBulk = gopacket.RegisterLayerType(112, gopacket.LayerTypeMetadata{Name: "USBBulk", Decoder: gopacket.DecodeFunc(decodeUSBBulk)}) - LayerTypeLinuxSLL = gopacket.RegisterLayerType(113, gopacket.LayerTypeMetadata{Name: "Linux SLL", Decoder: gopacket.DecodeFunc(decodeLinuxSLL)}) - LayerTypeSFlow = gopacket.RegisterLayerType(114, gopacket.LayerTypeMetadata{Name: "SFlow", Decoder: gopacket.DecodeFunc(decodeSFlow)}) - LayerTypePrismHeader = gopacket.RegisterLayerType(115, gopacket.LayerTypeMetadata{Name: "Prism monitor mode header", Decoder: gopacket.DecodeFunc(decodePrismHeader)}) - LayerTypeVXLAN = gopacket.RegisterLayerType(116, gopacket.LayerTypeMetadata{Name: "VXLAN", Decoder: gopacket.DecodeFunc(decodeVXLAN)}) - LayerTypeNTP = gopacket.RegisterLayerType(117, gopacket.LayerTypeMetadata{Name: "NTP", Decoder: gopacket.DecodeFunc(decodeNTP)}) - LayerTypeDHCPv4 = gopacket.RegisterLayerType(118, gopacket.LayerTypeMetadata{Name: "DHCPv4", Decoder: gopacket.DecodeFunc(decodeDHCPv4)}) - LayerTypeVRRP = gopacket.RegisterLayerType(119, gopacket.LayerTypeMetadata{Name: "VRRP", Decoder: gopacket.DecodeFunc(decodeVRRP)}) - LayerTypeGeneve = gopacket.RegisterLayerType(120, gopacket.LayerTypeMetadata{Name: "Geneve", Decoder: gopacket.DecodeFunc(decodeGeneve)}) - LayerTypeSTP = gopacket.RegisterLayerType(121, gopacket.LayerTypeMetadata{Name: "STP", Decoder: gopacket.DecodeFunc(decodeSTP)}) - LayerTypeBFD = gopacket.RegisterLayerType(122, gopacket.LayerTypeMetadata{Name: "BFD", Decoder: gopacket.DecodeFunc(decodeBFD)}) - LayerTypeOSPF = gopacket.RegisterLayerType(123, gopacket.LayerTypeMetadata{Name: "OSPF", Decoder: gopacket.DecodeFunc(decodeOSPF)}) + LayerTypeARP = gopacket.RegisterLayerType(10, gopacket.LayerTypeMetadata{Name: "ARP", Decoder: gopacket.DecodeFunc(decodeARP)}) + LayerTypeCiscoDiscovery = gopacket.RegisterLayerType(11, gopacket.LayerTypeMetadata{Name: "CiscoDiscovery", Decoder: gopacket.DecodeFunc(decodeCiscoDiscovery)}) + LayerTypeEthernetCTP = gopacket.RegisterLayerType(12, gopacket.LayerTypeMetadata{Name: "EthernetCTP", Decoder: gopacket.DecodeFunc(decodeEthernetCTP)}) + LayerTypeEthernetCTPForwardData = gopacket.RegisterLayerType(13, gopacket.LayerTypeMetadata{Name: "EthernetCTPForwardData", Decoder: nil}) + LayerTypeEthernetCTPReply = gopacket.RegisterLayerType(14, gopacket.LayerTypeMetadata{Name: "EthernetCTPReply", Decoder: nil}) + LayerTypeDot1Q = gopacket.RegisterLayerType(15, gopacket.LayerTypeMetadata{Name: "Dot1Q", Decoder: gopacket.DecodeFunc(decodeDot1Q)}) + LayerTypeEtherIP = gopacket.RegisterLayerType(16, gopacket.LayerTypeMetadata{Name: "EtherIP", Decoder: gopacket.DecodeFunc(decodeEtherIP)}) + LayerTypeEthernet = gopacket.RegisterLayerType(17, gopacket.LayerTypeMetadata{Name: "Ethernet", Decoder: gopacket.DecodeFunc(decodeEthernet)}) + LayerTypeGRE = gopacket.RegisterLayerType(18, gopacket.LayerTypeMetadata{Name: "GRE", Decoder: gopacket.DecodeFunc(decodeGRE)}) + LayerTypeICMPv4 = gopacket.RegisterLayerType(19, gopacket.LayerTypeMetadata{Name: "ICMPv4", Decoder: gopacket.DecodeFunc(decodeICMPv4)}) + LayerTypeIPv4 = gopacket.RegisterLayerType(20, gopacket.LayerTypeMetadata{Name: "IPv4", Decoder: gopacket.DecodeFunc(decodeIPv4)}) + LayerTypeIPv6 = gopacket.RegisterLayerType(21, gopacket.LayerTypeMetadata{Name: "IPv6", Decoder: gopacket.DecodeFunc(decodeIPv6)}) + LayerTypeLLC = gopacket.RegisterLayerType(22, gopacket.LayerTypeMetadata{Name: "LLC", Decoder: gopacket.DecodeFunc(decodeLLC)}) + LayerTypeSNAP = gopacket.RegisterLayerType(23, gopacket.LayerTypeMetadata{Name: "SNAP", Decoder: gopacket.DecodeFunc(decodeSNAP)}) + LayerTypeMPLS = gopacket.RegisterLayerType(24, gopacket.LayerTypeMetadata{Name: "MPLS", Decoder: gopacket.DecodeFunc(decodeMPLS)}) + LayerTypePPP = gopacket.RegisterLayerType(25, gopacket.LayerTypeMetadata{Name: "PPP", Decoder: gopacket.DecodeFunc(decodePPP)}) + LayerTypePPPoE = gopacket.RegisterLayerType(26, gopacket.LayerTypeMetadata{Name: "PPPoE", Decoder: gopacket.DecodeFunc(decodePPPoE)}) + LayerTypeRUDP = gopacket.RegisterLayerType(27, gopacket.LayerTypeMetadata{Name: "RUDP", Decoder: gopacket.DecodeFunc(decodeRUDP)}) + LayerTypeSCTP = gopacket.RegisterLayerType(28, gopacket.LayerTypeMetadata{Name: "SCTP", Decoder: gopacket.DecodeFunc(decodeSCTP)}) + LayerTypeSCTPUnknownChunkType = gopacket.RegisterLayerType(29, gopacket.LayerTypeMetadata{Name: "SCTPUnknownChunkType", Decoder: nil}) + LayerTypeSCTPData = gopacket.RegisterLayerType(30, gopacket.LayerTypeMetadata{Name: "SCTPData", Decoder: nil}) + LayerTypeSCTPInit = gopacket.RegisterLayerType(31, gopacket.LayerTypeMetadata{Name: "SCTPInit", Decoder: nil}) + LayerTypeSCTPSack = gopacket.RegisterLayerType(32, gopacket.LayerTypeMetadata{Name: "SCTPSack", Decoder: nil}) + LayerTypeSCTPHeartbeat = gopacket.RegisterLayerType(33, gopacket.LayerTypeMetadata{Name: "SCTPHeartbeat", Decoder: nil}) + LayerTypeSCTPError = gopacket.RegisterLayerType(34, gopacket.LayerTypeMetadata{Name: "SCTPError", Decoder: nil}) + LayerTypeSCTPShutdown = gopacket.RegisterLayerType(35, gopacket.LayerTypeMetadata{Name: "SCTPShutdown", Decoder: nil}) + LayerTypeSCTPShutdownAck = gopacket.RegisterLayerType(36, gopacket.LayerTypeMetadata{Name: "SCTPShutdownAck", Decoder: nil}) + LayerTypeSCTPCookieEcho = gopacket.RegisterLayerType(37, gopacket.LayerTypeMetadata{Name: "SCTPCookieEcho", Decoder: nil}) + LayerTypeSCTPEmptyLayer = gopacket.RegisterLayerType(38, gopacket.LayerTypeMetadata{Name: "SCTPEmptyLayer", Decoder: nil}) + LayerTypeSCTPInitAck = gopacket.RegisterLayerType(39, gopacket.LayerTypeMetadata{Name: "SCTPInitAck", Decoder: nil}) + LayerTypeSCTPHeartbeatAck = gopacket.RegisterLayerType(40, gopacket.LayerTypeMetadata{Name: "SCTPHeartbeatAck", Decoder: nil}) + LayerTypeSCTPAbort = gopacket.RegisterLayerType(41, gopacket.LayerTypeMetadata{Name: "SCTPAbort", Decoder: nil}) + LayerTypeSCTPShutdownComplete = gopacket.RegisterLayerType(42, gopacket.LayerTypeMetadata{Name: "SCTPShutdownComplete", Decoder: nil}) + LayerTypeSCTPCookieAck = gopacket.RegisterLayerType(43, gopacket.LayerTypeMetadata{Name: "SCTPCookieAck", Decoder: nil}) + LayerTypeTCP = gopacket.RegisterLayerType(44, gopacket.LayerTypeMetadata{Name: "TCP", Decoder: gopacket.DecodeFunc(decodeTCP)}) + LayerTypeUDP = gopacket.RegisterLayerType(45, gopacket.LayerTypeMetadata{Name: "UDP", Decoder: gopacket.DecodeFunc(decodeUDP)}) + LayerTypeIPv6HopByHop = gopacket.RegisterLayerType(46, gopacket.LayerTypeMetadata{Name: "IPv6HopByHop", Decoder: gopacket.DecodeFunc(decodeIPv6HopByHop)}) + LayerTypeIPv6Routing = gopacket.RegisterLayerType(47, gopacket.LayerTypeMetadata{Name: "IPv6Routing", Decoder: gopacket.DecodeFunc(decodeIPv6Routing)}) + LayerTypeIPv6Fragment = gopacket.RegisterLayerType(48, gopacket.LayerTypeMetadata{Name: "IPv6Fragment", Decoder: gopacket.DecodeFunc(decodeIPv6Fragment)}) + LayerTypeIPv6Destination = gopacket.RegisterLayerType(49, gopacket.LayerTypeMetadata{Name: "IPv6Destination", Decoder: gopacket.DecodeFunc(decodeIPv6Destination)}) + LayerTypeIPSecAH = gopacket.RegisterLayerType(50, gopacket.LayerTypeMetadata{Name: "IPSecAH", Decoder: gopacket.DecodeFunc(decodeIPSecAH)}) + LayerTypeIPSecESP = gopacket.RegisterLayerType(51, gopacket.LayerTypeMetadata{Name: "IPSecESP", Decoder: gopacket.DecodeFunc(decodeIPSecESP)}) + LayerTypeUDPLite = gopacket.RegisterLayerType(52, gopacket.LayerTypeMetadata{Name: "UDPLite", Decoder: gopacket.DecodeFunc(decodeUDPLite)}) + LayerTypeFDDI = gopacket.RegisterLayerType(53, gopacket.LayerTypeMetadata{Name: "FDDI", Decoder: gopacket.DecodeFunc(decodeFDDI)}) + LayerTypeLoopback = gopacket.RegisterLayerType(54, gopacket.LayerTypeMetadata{Name: "Loopback", Decoder: gopacket.DecodeFunc(decodeLoopback)}) + LayerTypeEAP = gopacket.RegisterLayerType(55, gopacket.LayerTypeMetadata{Name: "EAP", Decoder: gopacket.DecodeFunc(decodeEAP)}) + LayerTypeEAPOL = gopacket.RegisterLayerType(56, gopacket.LayerTypeMetadata{Name: "EAPOL", Decoder: gopacket.DecodeFunc(decodeEAPOL)}) + LayerTypeICMPv6 = gopacket.RegisterLayerType(57, gopacket.LayerTypeMetadata{Name: "ICMPv6", Decoder: gopacket.DecodeFunc(decodeICMPv6)}) + LayerTypeLinkLayerDiscovery = gopacket.RegisterLayerType(58, gopacket.LayerTypeMetadata{Name: "LinkLayerDiscovery", Decoder: gopacket.DecodeFunc(decodeLinkLayerDiscovery)}) + LayerTypeCiscoDiscoveryInfo = gopacket.RegisterLayerType(59, gopacket.LayerTypeMetadata{Name: "CiscoDiscoveryInfo", Decoder: gopacket.DecodeFunc(decodeCiscoDiscoveryInfo)}) + LayerTypeLinkLayerDiscoveryInfo = gopacket.RegisterLayerType(60, gopacket.LayerTypeMetadata{Name: "LinkLayerDiscoveryInfo", Decoder: nil}) + LayerTypeNortelDiscovery = gopacket.RegisterLayerType(61, gopacket.LayerTypeMetadata{Name: "NortelDiscovery", Decoder: gopacket.DecodeFunc(decodeNortelDiscovery)}) + LayerTypeIGMP = gopacket.RegisterLayerType(62, gopacket.LayerTypeMetadata{Name: "IGMP", Decoder: gopacket.DecodeFunc(decodeIGMP)}) + LayerTypePFLog = gopacket.RegisterLayerType(63, gopacket.LayerTypeMetadata{Name: "PFLog", Decoder: gopacket.DecodeFunc(decodePFLog)}) + LayerTypeRadioTap = gopacket.RegisterLayerType(64, gopacket.LayerTypeMetadata{Name: "RadioTap", Decoder: gopacket.DecodeFunc(decodeRadioTap)}) + LayerTypeDot11 = gopacket.RegisterLayerType(65, gopacket.LayerTypeMetadata{Name: "Dot11", Decoder: gopacket.DecodeFunc(decodeDot11)}) + LayerTypeDot11Ctrl = gopacket.RegisterLayerType(66, gopacket.LayerTypeMetadata{Name: "Dot11Ctrl", Decoder: gopacket.DecodeFunc(decodeDot11Ctrl)}) + LayerTypeDot11Data = gopacket.RegisterLayerType(67, gopacket.LayerTypeMetadata{Name: "Dot11Data", Decoder: gopacket.DecodeFunc(decodeDot11Data)}) + LayerTypeDot11DataCFAck = gopacket.RegisterLayerType(68, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAck)}) + LayerTypeDot11DataCFPoll = gopacket.RegisterLayerType(69, gopacket.LayerTypeMetadata{Name: "Dot11DataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFPoll)}) + LayerTypeDot11DataCFAckPoll = gopacket.RegisterLayerType(70, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAckPoll)}) + LayerTypeDot11DataNull = gopacket.RegisterLayerType(71, gopacket.LayerTypeMetadata{Name: "Dot11DataNull", Decoder: gopacket.DecodeFunc(decodeDot11DataNull)}) + LayerTypeDot11DataCFAckNoData = gopacket.RegisterLayerType(72, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAck)}) + LayerTypeDot11DataCFPollNoData = gopacket.RegisterLayerType(73, gopacket.LayerTypeMetadata{Name: "Dot11DataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFPoll)}) + LayerTypeDot11DataCFAckPollNoData = gopacket.RegisterLayerType(74, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAckPoll)}) + LayerTypeDot11DataQOSData = gopacket.RegisterLayerType(75, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSData", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSData)}) + LayerTypeDot11DataQOSDataCFAck = gopacket.RegisterLayerType(76, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAck)}) + LayerTypeDot11DataQOSDataCFPoll = gopacket.RegisterLayerType(77, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFPoll)}) + LayerTypeDot11DataQOSDataCFAckPoll = gopacket.RegisterLayerType(78, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAckPoll)}) + LayerTypeDot11DataQOSNull = gopacket.RegisterLayerType(79, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSNull", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSNull)}) + LayerTypeDot11DataQOSCFPollNoData = gopacket.RegisterLayerType(80, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSCFPollNoData)}) + LayerTypeDot11DataQOSCFAckPollNoData = gopacket.RegisterLayerType(81, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSCFAckPollNoData)}) + LayerTypeDot11InformationElement = gopacket.RegisterLayerType(82, gopacket.LayerTypeMetadata{Name: "Dot11InformationElement", Decoder: gopacket.DecodeFunc(decodeDot11InformationElement)}) + LayerTypeDot11CtrlCTS = gopacket.RegisterLayerType(83, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCTS", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCTS)}) + LayerTypeDot11CtrlRTS = gopacket.RegisterLayerType(84, gopacket.LayerTypeMetadata{Name: "Dot11CtrlRTS", Decoder: gopacket.DecodeFunc(decodeDot11CtrlRTS)}) + LayerTypeDot11CtrlBlockAckReq = gopacket.RegisterLayerType(85, gopacket.LayerTypeMetadata{Name: "Dot11CtrlBlockAckReq", Decoder: gopacket.DecodeFunc(decodeDot11CtrlBlockAckReq)}) + LayerTypeDot11CtrlBlockAck = gopacket.RegisterLayerType(86, gopacket.LayerTypeMetadata{Name: "Dot11CtrlBlockAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlBlockAck)}) + LayerTypeDot11CtrlPowersavePoll = gopacket.RegisterLayerType(87, gopacket.LayerTypeMetadata{Name: "Dot11CtrlPowersavePoll", Decoder: gopacket.DecodeFunc(decodeDot11CtrlPowersavePoll)}) + LayerTypeDot11CtrlAck = gopacket.RegisterLayerType(88, gopacket.LayerTypeMetadata{Name: "Dot11CtrlAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlAck)}) + LayerTypeDot11CtrlCFEnd = gopacket.RegisterLayerType(89, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCFEnd", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCFEnd)}) + LayerTypeDot11CtrlCFEndAck = gopacket.RegisterLayerType(90, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCFEndAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCFEndAck)}) + LayerTypeDot11MgmtAssociationReq = gopacket.RegisterLayerType(91, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAssociationReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAssociationReq)}) + LayerTypeDot11MgmtAssociationResp = gopacket.RegisterLayerType(92, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAssociationResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAssociationResp)}) + LayerTypeDot11MgmtReassociationReq = gopacket.RegisterLayerType(93, gopacket.LayerTypeMetadata{Name: "Dot11MgmtReassociationReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtReassociationReq)}) + LayerTypeDot11MgmtReassociationResp = gopacket.RegisterLayerType(94, gopacket.LayerTypeMetadata{Name: "Dot11MgmtReassociationResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtReassociationResp)}) + LayerTypeDot11MgmtProbeReq = gopacket.RegisterLayerType(95, gopacket.LayerTypeMetadata{Name: "Dot11MgmtProbeReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtProbeReq)}) + LayerTypeDot11MgmtProbeResp = gopacket.RegisterLayerType(96, gopacket.LayerTypeMetadata{Name: "Dot11MgmtProbeResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtProbeResp)}) + LayerTypeDot11MgmtMeasurementPilot = gopacket.RegisterLayerType(97, gopacket.LayerTypeMetadata{Name: "Dot11MgmtMeasurementPilot", Decoder: gopacket.DecodeFunc(decodeDot11MgmtMeasurementPilot)}) + LayerTypeDot11MgmtBeacon = gopacket.RegisterLayerType(98, gopacket.LayerTypeMetadata{Name: "Dot11MgmtBeacon", Decoder: gopacket.DecodeFunc(decodeDot11MgmtBeacon)}) + LayerTypeDot11MgmtATIM = gopacket.RegisterLayerType(99, gopacket.LayerTypeMetadata{Name: "Dot11MgmtATIM", Decoder: gopacket.DecodeFunc(decodeDot11MgmtATIM)}) + LayerTypeDot11MgmtDisassociation = gopacket.RegisterLayerType(100, gopacket.LayerTypeMetadata{Name: "Dot11MgmtDisassociation", Decoder: gopacket.DecodeFunc(decodeDot11MgmtDisassociation)}) + LayerTypeDot11MgmtAuthentication = gopacket.RegisterLayerType(101, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAuthentication", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAuthentication)}) + LayerTypeDot11MgmtDeauthentication = gopacket.RegisterLayerType(102, gopacket.LayerTypeMetadata{Name: "Dot11MgmtDeauthentication", Decoder: gopacket.DecodeFunc(decodeDot11MgmtDeauthentication)}) + LayerTypeDot11MgmtAction = gopacket.RegisterLayerType(103, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAction", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAction)}) + LayerTypeDot11MgmtActionNoAck = gopacket.RegisterLayerType(104, gopacket.LayerTypeMetadata{Name: "Dot11MgmtActionNoAck", Decoder: gopacket.DecodeFunc(decodeDot11MgmtActionNoAck)}) + LayerTypeDot11MgmtArubaWLAN = gopacket.RegisterLayerType(105, gopacket.LayerTypeMetadata{Name: "Dot11MgmtArubaWLAN", Decoder: gopacket.DecodeFunc(decodeDot11MgmtArubaWLAN)}) + LayerTypeDot11WEP = gopacket.RegisterLayerType(106, gopacket.LayerTypeMetadata{Name: "Dot11WEP", Decoder: gopacket.DecodeFunc(decodeDot11WEP)}) + LayerTypeDNS = gopacket.RegisterLayerType(107, gopacket.LayerTypeMetadata{Name: "DNS", Decoder: gopacket.DecodeFunc(decodeDNS)}) + LayerTypeUSB = gopacket.RegisterLayerType(108, gopacket.LayerTypeMetadata{Name: "USB", Decoder: gopacket.DecodeFunc(decodeUSB)}) + LayerTypeUSBRequestBlockSetup = gopacket.RegisterLayerType(109, gopacket.LayerTypeMetadata{Name: "USBRequestBlockSetup", Decoder: gopacket.DecodeFunc(decodeUSBRequestBlockSetup)}) + LayerTypeUSBControl = gopacket.RegisterLayerType(110, gopacket.LayerTypeMetadata{Name: "USBControl", Decoder: gopacket.DecodeFunc(decodeUSBControl)}) + LayerTypeUSBInterrupt = gopacket.RegisterLayerType(111, gopacket.LayerTypeMetadata{Name: "USBInterrupt", Decoder: gopacket.DecodeFunc(decodeUSBInterrupt)}) + LayerTypeUSBBulk = gopacket.RegisterLayerType(112, gopacket.LayerTypeMetadata{Name: "USBBulk", Decoder: gopacket.DecodeFunc(decodeUSBBulk)}) + LayerTypeLinuxSLL = gopacket.RegisterLayerType(113, gopacket.LayerTypeMetadata{Name: "Linux SLL", Decoder: gopacket.DecodeFunc(decodeLinuxSLL)}) + LayerTypeSFlow = gopacket.RegisterLayerType(114, gopacket.LayerTypeMetadata{Name: "SFlow", Decoder: gopacket.DecodeFunc(decodeSFlow)}) + LayerTypePrismHeader = gopacket.RegisterLayerType(115, gopacket.LayerTypeMetadata{Name: "Prism monitor mode header", Decoder: gopacket.DecodeFunc(decodePrismHeader)}) + LayerTypeVXLAN = gopacket.RegisterLayerType(116, gopacket.LayerTypeMetadata{Name: "VXLAN", Decoder: gopacket.DecodeFunc(decodeVXLAN)}) + LayerTypeNTP = gopacket.RegisterLayerType(117, gopacket.LayerTypeMetadata{Name: "NTP", Decoder: gopacket.DecodeFunc(decodeNTP)}) + LayerTypeDHCPv4 = gopacket.RegisterLayerType(118, gopacket.LayerTypeMetadata{Name: "DHCPv4", Decoder: gopacket.DecodeFunc(decodeDHCPv4)}) + LayerTypeVRRP = gopacket.RegisterLayerType(119, gopacket.LayerTypeMetadata{Name: "VRRP", Decoder: gopacket.DecodeFunc(decodeVRRP)}) + LayerTypeGeneve = gopacket.RegisterLayerType(120, gopacket.LayerTypeMetadata{Name: "Geneve", Decoder: gopacket.DecodeFunc(decodeGeneve)}) + LayerTypeSTP = gopacket.RegisterLayerType(121, gopacket.LayerTypeMetadata{Name: "STP", Decoder: gopacket.DecodeFunc(decodeSTP)}) + LayerTypeBFD = gopacket.RegisterLayerType(122, gopacket.LayerTypeMetadata{Name: "BFD", Decoder: gopacket.DecodeFunc(decodeBFD)}) + LayerTypeOSPF = gopacket.RegisterLayerType(123, gopacket.LayerTypeMetadata{Name: "OSPF", Decoder: gopacket.DecodeFunc(decodeOSPF)}) + LayerTypeICMPv6RouterSolicitation = gopacket.RegisterLayerType(124, gopacket.LayerTypeMetadata{Name: "ICMPv6RouterSolicitation", Decoder: gopacket.DecodeFunc(decodeICMPv6RouterSolicitation)}) + LayerTypeICMPv6RouterAdvertisement = gopacket.RegisterLayerType(125, gopacket.LayerTypeMetadata{Name: "ICMPv6RouterAdvertisement", Decoder: gopacket.DecodeFunc(decodeICMPv6RouterAdvertisement)}) + LayerTypeICMPv6NeighborSolicitation = gopacket.RegisterLayerType(126, gopacket.LayerTypeMetadata{Name: "ICMPv6NeighborSolicitation", Decoder: gopacket.DecodeFunc(decodeICMPv6NeighborSolicitation)}) + LayerTypeICMPv6NeighborAdvertisement = gopacket.RegisterLayerType(127, gopacket.LayerTypeMetadata{Name: "ICMPv6NeighborAdvertisement", Decoder: gopacket.DecodeFunc(decodeICMPv6NeighborAdvertisement)}) + LayerTypeICMPv6Redirect = gopacket.RegisterLayerType(128, gopacket.LayerTypeMetadata{Name: "ICMPv6Redirect", Decoder: gopacket.DecodeFunc(decodeICMPv6Redirect)}) + LayerTypeGTPv1U = gopacket.RegisterLayerType(129, gopacket.LayerTypeMetadata{Name: "GTPv1U", Decoder: gopacket.DecodeFunc(decodeGTPv1u)}) + LayerTypeEAPOLKey = gopacket.RegisterLayerType(130, gopacket.LayerTypeMetadata{Name: "EAPOLKey", Decoder: gopacket.DecodeFunc(decodeEAPOLKey)}) + LayerTypeLCM = gopacket.RegisterLayerType(131, gopacket.LayerTypeMetadata{Name: "LCM", Decoder: gopacket.DecodeFunc(decodeLCM)}) + LayerTypeICMPv6Echo = gopacket.RegisterLayerType(132, gopacket.LayerTypeMetadata{Name: "ICMPv6Echo", Decoder: gopacket.DecodeFunc(decodeICMPv6Echo)}) + LayerTypeSIP = gopacket.RegisterLayerType(133, gopacket.LayerTypeMetadata{Name: "SIP", Decoder: gopacket.DecodeFunc(decodeSIP)}) + LayerTypeDHCPv6 = gopacket.RegisterLayerType(134, gopacket.LayerTypeMetadata{Name: "DHCPv6", Decoder: gopacket.DecodeFunc(decodeDHCPv6)}) + LayerTypeMLDv1MulticastListenerReport = gopacket.RegisterLayerType(135, gopacket.LayerTypeMetadata{Name: "MLDv1MulticastListenerReport", Decoder: gopacket.DecodeFunc(decodeMLDv1MulticastListenerReport)}) + LayerTypeMLDv1MulticastListenerDone = gopacket.RegisterLayerType(136, gopacket.LayerTypeMetadata{Name: "MLDv1MulticastListenerDone", Decoder: gopacket.DecodeFunc(decodeMLDv1MulticastListenerDone)}) + LayerTypeMLDv1MulticastListenerQuery = gopacket.RegisterLayerType(137, gopacket.LayerTypeMetadata{Name: "MLDv1MulticastListenerQuery", Decoder: gopacket.DecodeFunc(decodeMLDv1MulticastListenerQuery)}) + LayerTypeMLDv2MulticastListenerReport = gopacket.RegisterLayerType(138, gopacket.LayerTypeMetadata{Name: "MLDv2MulticastListenerReport", Decoder: gopacket.DecodeFunc(decodeMLDv2MulticastListenerReport)}) + LayerTypeMLDv2MulticastListenerQuery = gopacket.RegisterLayerType(139, gopacket.LayerTypeMetadata{Name: "MLDv2MulticastListenerQuery", Decoder: gopacket.DecodeFunc(decodeMLDv2MulticastListenerQuery)}) + LayerTypeTLS = gopacket.RegisterLayerType(140, gopacket.LayerTypeMetadata{Name: "TLS", Decoder: gopacket.DecodeFunc(decodeTLS)}) + LayerTypeModbusTCP = gopacket.RegisterLayerType(141, gopacket.LayerTypeMetadata{Name: "ModbusTCP", Decoder: gopacket.DecodeFunc(decodeModbusTCP)}) ) var ( @@ -174,4 +192,27 @@ var ( LayerTypeIPSecAH, LayerTypeIPSecESP, }) + // LayerClassICMPv6NDP contains ICMPv6 neighbor discovery protocol + // messages. + LayerClassICMPv6NDP = gopacket.NewLayerClass([]gopacket.LayerType{ + LayerTypeICMPv6RouterSolicitation, + LayerTypeICMPv6RouterAdvertisement, + LayerTypeICMPv6NeighborSolicitation, + LayerTypeICMPv6NeighborAdvertisement, + LayerTypeICMPv6Redirect, + }) + // LayerClassMLDv1 contains multicast listener discovery protocol + LayerClassMLDv1 = gopacket.NewLayerClass([]gopacket.LayerType{ + LayerTypeMLDv1MulticastListenerQuery, + LayerTypeMLDv1MulticastListenerReport, + LayerTypeMLDv1MulticastListenerDone, + }) + // LayerClassMLDv2 contains multicast listener discovery protocol v2 + LayerClassMLDv2 = gopacket.NewLayerClass([]gopacket.LayerType{ + LayerTypeMLDv1MulticastListenerReport, + LayerTypeMLDv1MulticastListenerDone, + LayerTypeMLDv2MulticastListenerReport, + LayerTypeMLDv1MulticastListenerQuery, + LayerTypeMLDv2MulticastListenerQuery, + }) ) diff --git a/vendor/github.com/google/gopacket/layers/lcm.go b/vendor/github.com/google/gopacket/layers/lcm.go new file mode 100644 index 0000000000..5fe9fa5440 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/lcm.go @@ -0,0 +1,213 @@ +// Copyright 2018 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "fmt" + + "github.com/google/gopacket" +) + +const ( + // LCMShortHeaderMagic is the LCM small message header magic number + LCMShortHeaderMagic uint32 = 0x4c433032 + // LCMFragmentedHeaderMagic is the LCM fragmented message header magic number + LCMFragmentedHeaderMagic uint32 = 0x4c433033 +) + +// LCM (Lightweight Communications and Marshalling) is a set of libraries and +// tools for message passing and data marshalling, targeted at real-time systems +// where high-bandwidth and low latency are critical. It provides a +// publish/subscribe message passing model and automatic +// marshalling/unmarshalling code generation with bindings for applications in a +// variety of programming languages. +// +// References +// https://lcm-proj.github.io/ +// https://github.com/lcm-proj/lcm +type LCM struct { + // Common (short & fragmented header) fields + Magic uint32 + SequenceNumber uint32 + // Fragmented header only fields + PayloadSize uint32 + FragmentOffset uint32 + FragmentNumber uint16 + TotalFragments uint16 + // Common field + ChannelName string + // Gopacket helper fields + Fragmented bool + fingerprint LCMFingerprint + contents []byte + payload []byte +} + +// LCMFingerprint is the type of a LCM fingerprint. +type LCMFingerprint uint64 + +var ( + // lcmLayerTypes contains a map of all LCM fingerprints that we support and + // their LayerType + lcmLayerTypes = map[LCMFingerprint]gopacket.LayerType{} + layerTypeIndex = 1001 +) + +// RegisterLCMLayerType allows users to register decoders for the underlying +// LCM payload. This is done based on the fingerprint that every LCM message +// contains and which identifies it uniquely. If num is not the zero value it +// will be used when registering with RegisterLayerType towards gopacket, +// otherwise an incremental value starting from 1001 will be used. +func RegisterLCMLayerType(num int, name string, fingerprint LCMFingerprint, + decoder gopacket.Decoder) gopacket.LayerType { + metadata := gopacket.LayerTypeMetadata{Name: name, Decoder: decoder} + + if num == 0 { + num = layerTypeIndex + layerTypeIndex++ + } + + lcmLayerTypes[fingerprint] = gopacket.RegisterLayerType(num, metadata) + + return lcmLayerTypes[fingerprint] +} + +// SupportedLCMFingerprints returns a slice of all LCM fingerprints that has +// been registered so far. +func SupportedLCMFingerprints() []LCMFingerprint { + fingerprints := make([]LCMFingerprint, 0, len(lcmLayerTypes)) + for fp := range lcmLayerTypes { + fingerprints = append(fingerprints, fp) + } + return fingerprints +} + +// GetLCMLayerType returns the underlying LCM message's LayerType. +// This LayerType has to be registered by using RegisterLCMLayerType. +func GetLCMLayerType(fingerprint LCMFingerprint) gopacket.LayerType { + layerType, ok := lcmLayerTypes[fingerprint] + if !ok { + return gopacket.LayerTypePayload + } + + return layerType +} + +func decodeLCM(data []byte, p gopacket.PacketBuilder) error { + lcm := &LCM{} + + err := lcm.DecodeFromBytes(data, p) + if err != nil { + return err + } + + p.AddLayer(lcm) + p.SetApplicationLayer(lcm) + + return p.NextDecoder(lcm.NextLayerType()) +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (lcm *LCM) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + offset := 0 + + lcm.Magic = binary.BigEndian.Uint32(data[offset:4]) + offset += 4 + + if lcm.Magic != LCMShortHeaderMagic && lcm.Magic != LCMFragmentedHeaderMagic { + return fmt.Errorf("Received LCM header magic %v does not match know "+ + "LCM magic numbers. Dropping packet.", lcm.Magic) + } + + lcm.SequenceNumber = binary.BigEndian.Uint32(data[offset:8]) + offset += 4 + + if lcm.Magic == LCMFragmentedHeaderMagic { + lcm.Fragmented = true + + lcm.PayloadSize = binary.BigEndian.Uint32(data[offset : offset+4]) + offset += 4 + + lcm.FragmentOffset = binary.BigEndian.Uint32(data[offset : offset+4]) + offset += 4 + + lcm.FragmentNumber = binary.BigEndian.Uint16(data[offset : offset+2]) + offset += 2 + + lcm.TotalFragments = binary.BigEndian.Uint16(data[offset : offset+2]) + offset += 2 + } else { + lcm.Fragmented = false + } + + if !lcm.Fragmented || (lcm.Fragmented && lcm.FragmentNumber == 0) { + buffer := make([]byte, 0) + for _, b := range data[offset:] { + offset++ + + if b == 0 { + break + } + + buffer = append(buffer, b) + } + + lcm.ChannelName = string(buffer) + } + + lcm.fingerprint = LCMFingerprint( + binary.BigEndian.Uint64(data[offset : offset+8])) + + lcm.contents = data[:offset] + lcm.payload = data[offset:] + + return nil +} + +// CanDecode returns a set of layers that LCM objects can decode. +// As LCM objects can only decode the LCM layer, we just return that layer. +func (lcm LCM) CanDecode() gopacket.LayerClass { + return LayerTypeLCM +} + +// NextLayerType specifies the LCM payload layer type following this header. +// As LCM packets are serialized structs with uniq fingerprints for each uniq +// combination of data types, lookup of correct layer type is based on that +// fingerprint. +func (lcm LCM) NextLayerType() gopacket.LayerType { + if !lcm.Fragmented || (lcm.Fragmented && lcm.FragmentNumber == 0) { + return GetLCMLayerType(lcm.fingerprint) + } + + return gopacket.LayerTypeFragment +} + +// LayerType returns LayerTypeLCM +func (lcm LCM) LayerType() gopacket.LayerType { + return LayerTypeLCM +} + +// LayerContents returns the contents of the LCM header. +func (lcm LCM) LayerContents() []byte { + return lcm.contents +} + +// LayerPayload returns the payload following this LCM header. +func (lcm LCM) LayerPayload() []byte { + return lcm.payload +} + +// Payload returns the payload following this LCM header. +func (lcm LCM) Payload() []byte { + return lcm.LayerPayload() +} + +// Fingerprint returns the LCM fingerprint of the underlying message. +func (lcm LCM) Fingerprint() LCMFingerprint { + return lcm.fingerprint +} diff --git a/vendor/github.com/google/gopacket/layers/lcm_test.go b/vendor/github.com/google/gopacket/layers/lcm_test.go new file mode 100644 index 0000000000..fe2975b547 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/lcm_test.go @@ -0,0 +1,156 @@ +// Copyright 2018 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/hex" + "testing" + + "github.com/google/gopacket" +) + +var ( + fingerprint uint64 = 0x6c636d2073656c66 + + shortPacket = []byte{ + 0x4c, 0x43, 0x30, 0x32, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x43, 0x4d, 0x5f, + 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x00, 0x6c, 0x63, + 0x6d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x74, 0x65, 0x73, 0x74, + } + + fragmentedPacket = []byte{ + 0x4c, 0x43, 0x30, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x02, 0x4c, 0x43, 0x4d, 0x5f, + 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x00, 0x6c, 0x63, + 0x6d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x74, 0x65, 0x73, 0x74, + } + + invalidPacket = []byte{ + 0x4c, 0x43, 0x30, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + } + + expectedChannel = "LCM_SELF_TEST" +) + +func TestLCMDecode(t *testing.T) { + testShortLCM(t) + testFragmentedLCM(t) + testInvalidLCM(t) +} + +func testShortLCM(t *testing.T) { + lcm := &LCM{} + + err := lcm.DecodeFromBytes(shortPacket, gopacket.NilDecodeFeedback) + if err != nil { + t.Fatal(err) + } + + if lcm.Magic != LCMShortHeaderMagic { + t.Errorf("Expected LCM Magic %x, but decoded %x.\n", + LCMShortHeaderMagic, lcm.Magic) + } + + if lcm.SequenceNumber != 0x00 { + t.Errorf("Expected an LCM Sequence Number of %x, but decoded %x.\n", + 0x00, lcm.SequenceNumber) + } + + if lcm.ChannelName != expectedChannel { + t.Errorf("Expected channel name %s but received %s\n", + expectedChannel, lcm.ChannelName) + } + + if lcm.Fragmented { + t.Errorf("Misinterpreted non-fragmented packet as fragmented.") + } + + for i, val := range lcm.LayerContents() { + if val != shortPacket[i] { + t.Errorf("\nLCM Payload: expected\n%sbut received\n%s", + hex.Dump(shortPacket[:22]), hex.Dump(lcm.Payload())) + } + } + + for i, val := range lcm.Payload() { + if val != shortPacket[i+22] { + t.Errorf("\nLCM Payload: expected\n%sbut received\n%s", + hex.Dump(shortPacket[22:]), hex.Dump(lcm.Payload())) + } + } +} + +func testFragmentedLCM(t *testing.T) { + lcm := LCM{} + + err := lcm.DecodeFromBytes(fragmentedPacket, gopacket.NilDecodeFeedback) + if err != nil { + t.Fatal(err) + } + + if lcm.Magic != LCMFragmentedHeaderMagic { + t.Errorf("Expected LCM Magic %x, but decoded %x.\n", + LCMFragmentedHeaderMagic, lcm.Magic) + } + + if lcm.SequenceNumber != 0x01 { + t.Errorf("Expected an LCM Sequence Number of %x, but decoded %x.\n", + 0x01, lcm.SequenceNumber) + } + + if lcm.PayloadSize != 0x0d { + t.Errorf("Expected an LCM Payload Size of %x, but decoded %x.\n", 0x0d, + lcm.PayloadSize) + } + + if lcm.FragmentOffset != 0x2d { + t.Errorf("Expected an LCM Fragment Offset of %x, but decoded %x.\n", + 0x2d, lcm.FragmentOffset) + } + + if lcm.FragmentNumber != 0x00 { + t.Errorf("Expected the first LCM fragment (%x), but decoded %x.\n", + 0x00, lcm.FragmentNumber) + } + + if lcm.TotalFragments != 0x02 { + t.Errorf("Expected two LCM fragments (%x), but decoded %x.\n", 0x02, + lcm.TotalFragments) + } + + if lcm.ChannelName != expectedChannel { + t.Errorf("Expected LCM Channel Name %s but decoded %s\n", + expectedChannel, lcm.ChannelName) + } + + if !lcm.Fragmented { + t.Errorf("Misinterpreted fragmented packet as non-fragmented.") + } + + for i, val := range lcm.LayerContents() { + if val != fragmentedPacket[i] { + t.Errorf("\nLCM Payload: expected\n%sbut received\n%s", + hex.Dump(fragmentedPacket[:22]), hex.Dump(lcm.Payload())) + } + } + + for i, val := range lcm.Payload() { + if val != fragmentedPacket[i+34] { + t.Errorf("\nLCM Payload: expected\n%sbut received\n%s", + hex.Dump(fragmentedPacket[34:]), hex.Dump(lcm.Payload())) + } + } +} + +func testInvalidLCM(t *testing.T) { + lcm := LCM{} + + err := lcm.DecodeFromBytes(invalidPacket, gopacket.NilDecodeFeedback) + if err == nil { + t.Fatal("Did not detect LCM decode error.") + } +} diff --git a/vendor/github.com/google/gopacket/layers/linux_sll.go b/vendor/github.com/google/gopacket/layers/linux_sll.go index b1860536a9..85a4f8bdd0 100644 --- a/vendor/github.com/google/gopacket/layers/linux_sll.go +++ b/vendor/github.com/google/gopacket/layers/linux_sll.go @@ -54,6 +54,7 @@ type LinuxSLL struct { AddrLen uint16 Addr net.HardwareAddr EthernetType EthernetType + AddrType uint16 } // LayerType returns LayerTypeLinuxSLL. @@ -76,6 +77,7 @@ func (sll *LinuxSLL) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) er return errors.New("Linux SLL packet too small") } sll.PacketType = LinuxSLLPacketType(binary.BigEndian.Uint16(data[0:2])) + sll.AddrType = binary.BigEndian.Uint16(data[2:4]) sll.AddrLen = binary.BigEndian.Uint16(data[4:6]) sll.Addr = net.HardwareAddr(data[6 : sll.AddrLen+6]) diff --git a/vendor/github.com/google/gopacket/layers/llc.go b/vendor/github.com/google/gopacket/layers/llc.go index 59453fee80..cad6803671 100644 --- a/vendor/github.com/google/gopacket/layers/llc.go +++ b/vendor/github.com/google/gopacket/layers/llc.go @@ -27,6 +27,47 @@ type LLC struct { // LayerType returns gopacket.LayerTypeLLC. func (l *LLC) LayerType() gopacket.LayerType { return LayerTypeLLC } +// DecodeFromBytes decodes the given bytes into this layer. +func (l *LLC) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 3 { + return errors.New("LLC header too small") + } + l.DSAP = data[0] & 0xFE + l.IG = data[0]&0x1 != 0 + l.SSAP = data[1] & 0xFE + l.CR = data[1]&0x1 != 0 + l.Control = uint16(data[2]) + + if l.Control&0x1 == 0 || l.Control&0x3 == 0x1 { + if len(data) < 4 { + return errors.New("LLC header too small") + } + l.Control = l.Control<<8 | uint16(data[3]) + l.Contents = data[:4] + l.Payload = data[4:] + } else { + l.Contents = data[:3] + l.Payload = data[3:] + } + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (l *LLC) CanDecode() gopacket.LayerClass { + return LayerTypeLLC +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (l *LLC) NextLayerType() gopacket.LayerType { + switch { + case l.DSAP == 0xAA && l.SSAP == 0xAA: + return LayerTypeSNAP + case l.DSAP == 0x42 && l.SSAP == 0x42: + return LayerTypeSTP + } + return gopacket.LayerTypeZero // Not implemented +} + // SNAP is used inside LLC. See // http://standards.ieee.org/getieee802/download/802-2001.pdf. // From http://en.wikipedia.org/wiki/Subnetwork_Access_Protocol: @@ -42,37 +83,43 @@ type SNAP struct { // LayerType returns gopacket.LayerTypeSNAP. func (s *SNAP) LayerType() gopacket.LayerType { return LayerTypeSNAP } -func decodeLLC(data []byte, p gopacket.PacketBuilder) error { - l := &LLC{ - DSAP: data[0] & 0xFE, - IG: data[0]&0x1 != 0, - SSAP: data[1] & 0xFE, - CR: data[1]&0x1 != 0, - Control: uint16(data[2]), +// DecodeFromBytes decodes the given bytes into this layer. +func (s *SNAP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 5 { + return errors.New("SNAP header too small") } - if l.Control&0x1 == 0 || l.Control&0x3 == 0x1 { - l.Control = l.Control<<8 | uint16(data[3]) - l.Contents = data[:4] - l.Payload = data[4:] - } else { - l.Contents = data[:3] - l.Payload = data[3:] + s.OrganizationalCode = data[:3] + s.Type = EthernetType(binary.BigEndian.Uint16(data[3:5])) + s.BaseLayer = BaseLayer{data[:5], data[5:]} + return nil +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (s *SNAP) CanDecode() gopacket.LayerClass { + return LayerTypeSNAP +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (s *SNAP) NextLayerType() gopacket.LayerType { + // See BUG(gconnel) in decodeSNAP + return s.Type.LayerType() +} + +func decodeLLC(data []byte, p gopacket.PacketBuilder) error { + l := &LLC{} + err := l.DecodeFromBytes(data, p) + if err != nil { + return err } p.AddLayer(l) - switch { - case l.DSAP == 0xAA && l.SSAP == 0xAA: - return p.NextDecoder(LayerTypeSNAP) - case l.DSAP == 0x42 && l.SSAP == 0x42: - return p.NextDecoder(LayerTypeSTP) - } - return p.NextDecoder(gopacket.DecodeUnknown) + return p.NextDecoder(l.NextLayerType()) } func decodeSNAP(data []byte, p gopacket.PacketBuilder) error { - s := &SNAP{ - OrganizationalCode: data[:3], - Type: EthernetType(binary.BigEndian.Uint16(data[3:5])), - BaseLayer: BaseLayer{data[:5], data[5:]}, + s := &SNAP{} + err := s.DecodeFromBytes(data, p) + if err != nil { + return err } p.AddLayer(s) // BUG(gconnell): When decoding SNAP, we treat the SNAP type as an Ethernet @@ -85,7 +132,7 @@ func decodeSNAP(data []byte, p gopacket.PacketBuilder) error { // SerializationBuffer, implementing gopacket.SerializableLayer. // See the docs for gopacket.SerializableLayer for more info. func (l *LLC) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { - var ig_flag, cr_flag byte + var igFlag, crFlag byte var length int if l.Control&0xFF00 != 0 { @@ -105,18 +152,18 @@ func (l *LLC) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOpt if buf, err := b.PrependBytes(length); err != nil { return err } else { - ig_flag = 0 + igFlag = 0 if l.IG { - ig_flag = 0x1 + igFlag = 0x1 } - cr_flag = 0 + crFlag = 0 if l.CR { - cr_flag = 0x1 + crFlag = 0x1 } - buf[0] = l.DSAP + ig_flag - buf[1] = l.SSAP + cr_flag + buf[0] = l.DSAP + igFlag + buf[1] = l.SSAP + crFlag if length == 4 { buf[2] = uint8(l.Control >> 8) diff --git a/vendor/github.com/google/gopacket/layers/lldp.go b/vendor/github.com/google/gopacket/layers/lldp.go index 92ec7daff4..e12826032f 100644 --- a/vendor/github.com/google/gopacket/layers/lldp.go +++ b/vendor/github.com/google/gopacket/layers/lldp.go @@ -37,6 +37,10 @@ type LinkLayerDiscoveryValue struct { Value []byte } +func (c *LinkLayerDiscoveryValue) len() int { + return 0 +} + // LLDPChassisIDSubType specifies the value type for a single LLDPChassisID.ID type LLDPChassisIDSubType byte @@ -57,6 +61,20 @@ type LLDPChassisID struct { ID []byte } +func (c *LLDPChassisID) serialize() []byte { + + var buf = make([]byte, c.serializedLen()) + idLen := uint16(LLDPTLVChassisID)<<9 | uint16(len(c.ID)+1) //id should take 7 bits, length should take 9 bits, +1 for subtype + binary.BigEndian.PutUint16(buf[0:2], idLen) + buf[2] = byte(c.Subtype) + copy(buf[3:], c.ID) + return buf +} + +func (c *LLDPChassisID) serializedLen() int { + return len(c.ID) + 3 // +2 for id and length, +1 for subtype +} + // LLDPPortIDSubType specifies the value type for a single LLDPPortID.ID type LLDPPortIDSubType byte @@ -77,6 +95,20 @@ type LLDPPortID struct { ID []byte } +func (c *LLDPPortID) serialize() []byte { + + var buf = make([]byte, c.serializedLen()) + idLen := uint16(LLDPTLVPortID)<<9 | uint16(len(c.ID)+1) //id should take 7 bits, length should take 9 bits, +1 for subtype + binary.BigEndian.PutUint16(buf[0:2], idLen) + buf[2] = byte(c.Subtype) + copy(buf[3:], c.ID) + return buf +} + +func (c *LLDPPortID) serializedLen() int { + return len(c.ID) + 3 // +2 for id and length, +1 for subtype +} + // LinkLayerDiscovery is a packet layer containing the LinkLayer Discovery Protocol. // See http:http://standards.ieee.org/getieee802/download/802.1AB-2009.pdf // ChassisID, PortID and TTL are mandatory TLV's. Other values can be decoded @@ -733,6 +765,29 @@ func (c *LinkLayerDiscovery) LayerType() gopacket.LayerType { return LayerTypeLinkLayerDiscovery } +// SerializeTo serializes LLDP packet to bytes and writes on SerializeBuffer. +func (c *LinkLayerDiscovery) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + chassIDLen := c.ChassisID.serializedLen() + portIDLen := c.PortID.serializedLen() + vb, err := b.AppendBytes(chassIDLen + portIDLen + 4) // +4 for TTL + if err != nil { + return err + } + copy(vb[:chassIDLen], c.ChassisID.serialize()) + copy(vb[chassIDLen:], c.PortID.serialize()) + ttlIDLen := uint16(LLDPTLVTTL)<<9 | uint16(2) + binary.BigEndian.PutUint16(vb[chassIDLen+portIDLen:], ttlIDLen) + binary.BigEndian.PutUint16(vb[chassIDLen+portIDLen+2:], c.TTL) + + vb, err = b.AppendBytes(2) // End Tlv, 2 bytes + if err != nil { + return err + } + binary.BigEndian.PutUint16(vb[len(vb)-2:], uint16(0)) //End tlv, 2 bytes, all zero + return nil + +} + func decodeLinkLayerDiscovery(data []byte, p gopacket.PacketBuilder) error { var vals []LinkLayerDiscoveryValue vData := data[0:] diff --git a/vendor/github.com/google/gopacket/layers/mldv1.go b/vendor/github.com/google/gopacket/layers/mldv1.go new file mode 100644 index 0000000000..e1bb1dc00f --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/mldv1.go @@ -0,0 +1,182 @@ +// Copyright 2018 GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "fmt" + "math" + "net" + "time" + + "github.com/google/gopacket" +) + +// MLDv1Message represents the common structure of all MLDv1 messages +type MLDv1Message struct { + BaseLayer + // 3.4. Maximum Response Delay + MaximumResponseDelay time.Duration + // 3.6. Multicast Address + // Zero in general query + // Specific IPv6 multicast address otherwise + MulticastAddress net.IP +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (m *MLDv1Message) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 20 { + df.SetTruncated() + return errors.New("ICMP layer less than 20 bytes for Multicast Listener Query Message V1") + } + + m.MaximumResponseDelay = time.Duration(binary.BigEndian.Uint16(data[0:2])) * time.Millisecond + // data[2:4] is reserved and not used in mldv1 + m.MulticastAddress = data[4:20] + + return nil +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (*MLDv1Message) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypeZero +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (m *MLDv1Message) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + buf, err := b.PrependBytes(20) + if err != nil { + return err + } + + if m.MaximumResponseDelay < 0 { + return errors.New("maximum response delay must not be negative") + } + dms := m.MaximumResponseDelay / time.Millisecond + if dms > math.MaxUint16 { + return fmt.Errorf("maximum response delay %dms is more than the allowed 65535ms", dms) + } + binary.BigEndian.PutUint16(buf[0:2], uint16(dms)) + + copy(buf[2:4], []byte{0x0, 0x0}) + + ma16 := m.MulticastAddress.To16() + if ma16 == nil { + return fmt.Errorf("invalid multicast address '%s'", m.MulticastAddress) + } + copy(buf[4:20], ma16) + + return nil +} + +// Sums this layer up nicely formatted +func (m *MLDv1Message) String() string { + return fmt.Sprintf( + "Maximum Response Delay: %dms, Multicast Address: %s", + m.MaximumResponseDelay/time.Millisecond, + m.MulticastAddress) +} + +// MLDv1MulticastListenerQueryMessage are sent by the router to determine +// whether there are multicast listeners on the link. +// https://tools.ietf.org/html/rfc2710 Page 5 +type MLDv1MulticastListenerQueryMessage struct { + MLDv1Message +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (m *MLDv1MulticastListenerQueryMessage) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + err := m.MLDv1Message.DecodeFromBytes(data, df) + if err != nil { + return err + } + + if len(data) > 20 { + m.Payload = data[20:] + } + + return nil +} + +// LayerType returns LayerTypeMLDv1MulticastListenerQuery. +func (*MLDv1MulticastListenerQueryMessage) LayerType() gopacket.LayerType { + return LayerTypeMLDv1MulticastListenerQuery +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (*MLDv1MulticastListenerQueryMessage) CanDecode() gopacket.LayerClass { + return LayerTypeMLDv1MulticastListenerQuery +} + +// IsGeneralQuery is true when this is a general query. +// In a Query message, the Multicast Address field is set to zero when +// sending a General Query. +// https://tools.ietf.org/html/rfc2710#section-3.6 +func (m *MLDv1MulticastListenerQueryMessage) IsGeneralQuery() bool { + return net.IPv6zero.Equal(m.MulticastAddress) +} + +// IsSpecificQuery is true when this is not a general query. +// In a Query message, the Multicast Address field is set to a specific +// IPv6 multicast address when sending a Multicast-Address-Specific Query. +// https://tools.ietf.org/html/rfc2710#section-3.6 +func (m *MLDv1MulticastListenerQueryMessage) IsSpecificQuery() bool { + return !m.IsGeneralQuery() +} + +// MLDv1MulticastListenerReportMessage is sent by a client listening on +// a specific multicast address to indicate that it is (still) listening +// on the specific multicast address. +// https://tools.ietf.org/html/rfc2710 Page 6 +type MLDv1MulticastListenerReportMessage struct { + MLDv1Message +} + +// LayerType returns LayerTypeMLDv1MulticastListenerReport. +func (*MLDv1MulticastListenerReportMessage) LayerType() gopacket.LayerType { + return LayerTypeMLDv1MulticastListenerReport +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (*MLDv1MulticastListenerReportMessage) CanDecode() gopacket.LayerClass { + return LayerTypeMLDv1MulticastListenerReport +} + +// MLDv1MulticastListenerDoneMessage should be sent by a client when it ceases +// to listen to a multicast address on an interface. +// https://tools.ietf.org/html/rfc2710 Page 7 +type MLDv1MulticastListenerDoneMessage struct { + MLDv1Message +} + +// LayerType returns LayerTypeMLDv1MulticastListenerDone. +func (*MLDv1MulticastListenerDoneMessage) LayerType() gopacket.LayerType { + return LayerTypeMLDv1MulticastListenerDone +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (*MLDv1MulticastListenerDoneMessage) CanDecode() gopacket.LayerClass { + return LayerTypeMLDv1MulticastListenerDone +} + +func decodeMLDv1MulticastListenerReport(data []byte, p gopacket.PacketBuilder) error { + m := &MLDv1MulticastListenerReportMessage{} + return decodingLayerDecoder(m, data, p) +} + +func decodeMLDv1MulticastListenerQuery(data []byte, p gopacket.PacketBuilder) error { + m := &MLDv1MulticastListenerQueryMessage{} + return decodingLayerDecoder(m, data, p) +} + +func decodeMLDv1MulticastListenerDone(data []byte, p gopacket.PacketBuilder) error { + m := &MLDv1MulticastListenerDoneMessage{} + return decodingLayerDecoder(m, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/mldv1_test.go b/vendor/github.com/google/gopacket/layers/mldv1_test.go new file mode 100644 index 0000000000..438e3aa773 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/mldv1_test.go @@ -0,0 +1,140 @@ +// Copyright 2018 GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "testing" + + "github.com/google/gopacket" +) + +// Adapted from https://github.com/the-tcpdump-group/tcpdump/blob/master/tests/icmpv6.pcap +// BSD licensed content +// +// Frame 3: 90 bytes on wire (720 bits), 90 bytes captured (720 bits) +// Ethernet II, Src: JuniperN_0c:d4:e8 (b0:a8:6e:0c:d4:e8), Dst: IPv6mcast_01 (33:33:00:00:00:01) +// Internet Protocol Version 6, Src: fe80::b2a8:6eff:fe0c:d4e8, Dst: ff02::1 +// 0110 .... = Version: 6 +// .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT) +// .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000 +// Payload Length: 36 +// Next Header: IPv6 Hop-by-Hop Option (0) +// Hop Limit: 1 +// Source: fe80::b2a8:6eff:fe0c:d4e8 +// Destination: ff02::1 +// [Source SA MAC: JuniperN_0c:d4:e8 (b0:a8:6e:0c:d4:e8)] +// IPv6 Hop-by-Hop Option +// Internet Control Message Protocol v6 +// Type: Multicast Listener Query (130) +// Code: 0 +// Checksum: 0x623a [correct] +// [Checksum Status: Good] +// Maximum Response Code: 10000 +// Reserved: 0000 +// Multicast Address: :: +var testPacketMulticastListenerQueryMessageV1 = []byte{ + 0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0xb0, 0xa8, 0x6e, 0x0c, 0xd4, 0xe8, 0x86, 0xdd, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0xa8, + 0x6e, 0xff, 0xfe, 0x0c, 0xd4, 0xe8, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3a, 0x00, 0x05, 0x02, 0x00, 0x00, 0x01, 0x00, 0x82, 0x00, + 0x62, 0x3a, 0x27, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +func TestPacketMulticastListenerQueryMessageV1(t *testing.T) { + p := gopacket.NewPacket(testPacketMulticastListenerQueryMessageV1, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeIPv6HopByHop, LayerTypeICMPv6, LayerTypeMLDv1MulticastListenerQuery}, t) + // See https://github.com/google/gopacket/issues/517 + // checkSerialization(p, t) +} + +// Adapted from https://github.com/the-tcpdump-group/tcpdump/blob/master/tests/icmpv6.pcap +// BSD licensed content +// +// Ethernet II, Src: JuniperN_0c:d4:e8 (b0:a8:6e:0c:d4:e8), Dst: IPv6mcast_01 (33:33:00:00:00:01) +// Internet Protocol Version 6, Src: fe80::b2a8:6eff:fe0c:d4e8, Dst: ff02::1 +// 0110 .... = Version: 6 +// .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT) +// .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000 +// Payload Length: 36 +// Next Header: IPv6 Hop-by-Hop Option (0) +// Hop Limit: 1 +// Source: fe80::b2a8:6eff:fe0c:d4e8 +// Destination: ff02::1 +// [Source SA MAC: JuniperN_0c:d4:e8 (b0:a8:6e:0c:d4:e8)] +// IPv6 Hop-by-Hop Option +// Internet Control Message Protocol v6 +// Type: Multicast Listener Report (131) +// Code: 0 +// Checksum: 0x623a [incorrect] +// [Checksum Status: Invalid] +// Maximum Response Code: 10000 +// Reserved: 0000 +// Multicast Address: ff02::db8:1122:3344 +var testPacketMulticastListenerReportMessageV1 = []byte{ + 0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0xb0, 0xa8, 0x6e, 0x0c, 0xd4, 0xe8, 0x86, 0xdd, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0xa8, + 0x6e, 0xff, 0xfe, 0x0c, 0xd4, 0xe8, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3a, 0x00, 0x05, 0x02, 0x00, 0x00, 0x01, 0x00, 0x83, 0x00, + 0x62, 0x3a, 0x27, 0x10, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0d, 0xb8, 0x11, 0x22, 0x33, 0x44, +} + +func TestPacketMulticastListenerReportMessageV1(t *testing.T) { + p := gopacket.NewPacket(testPacketMulticastListenerReportMessageV1, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeIPv6HopByHop, LayerTypeICMPv6, LayerTypeMLDv1MulticastListenerReport}, t) + // See https://github.com/google/gopacket/issues/517 + // checkSerialization(p, t) +} + +// Adapted from https://github.com/the-tcpdump-group/tcpdump/blob/master/tests/icmpv6.pcap +// BSD licensed content +// +// Ethernet II, Src: JuniperN_0c:d4:e8 (b0:a8:6e:0c:d4:e8), Dst: IPv6mcast_01 (33:33:00:00:00:01) +// Internet Protocol Version 6, Src: fe80::b2a8:6eff:fe0c:d4e8, Dst: ff02::1 +// 0110 .... = Version: 6 +// .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT) +// .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000 +// Payload Length: 36 +// Next Header: IPv6 Hop-by-Hop Option (0) +// Hop Limit: 1 +// Source: fe80::b2a8:6eff:fe0c:d4e8 +// Destination: ff02::1 +// [Source SA MAC: JuniperN_0c:d4:e8 (b0:a8:6e:0c:d4:e8)] +// IPv6 Hop-by-Hop Option +// Internet Control Message Protocol v6 +// Type: Multicast Listener Done (132) +// Code: 0 +// Checksum: 0x623a [incorrect] +// [Checksum Status: Invalid] +// Maximum Response Code: 10000 +// Reserved: 0000 +// Multicast Address: ff02::db8:1122:3344 +var testPacketMulticastListenerDoneMessageV1 = []byte{ + 0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0xb0, 0xa8, 0x6e, 0x0c, 0xd4, 0xe8, 0x86, 0xdd, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0xa8, + 0x6e, 0xff, 0xfe, 0x0c, 0xd4, 0xe8, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3a, 0x00, 0x05, 0x02, 0x00, 0x00, 0x01, 0x00, 0x84, 0x00, + 0x62, 0x3a, 0x27, 0x10, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0d, 0xb8, 0x11, 0x22, 0x33, 0x44, +} + +func TestPacketMulticastListenerDoneMessageV1(t *testing.T) { + p := gopacket.NewPacket(testPacketMulticastListenerDoneMessageV1, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv6, LayerTypeIPv6HopByHop, LayerTypeICMPv6, LayerTypeMLDv1MulticastListenerDone}, t) + // See https://github.com/google/gopacket/issues/517 + // checkSerialization(p, t) +} diff --git a/vendor/github.com/google/gopacket/layers/mldv2.go b/vendor/github.com/google/gopacket/layers/mldv2.go new file mode 100644 index 0000000000..248cf749ef --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/mldv2.go @@ -0,0 +1,619 @@ +// Copyright 2018 GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + "fmt" + "math" + "net" + "time" + + "github.com/google/gopacket" +) + +const ( + // S Flag bit is 1 + mldv2STrue uint8 = 0x8 + + // S Flag value mask + // mldv2STrue & mldv2SMask == mldv2STrue // true + // 0x1 & mldv2SMask == mldv2STrue // true + // 0x0 & mldv2SMask == mldv2STrue // false + mldv2SMask uint8 = 0x8 + + // QRV value mask + mldv2QRVMask uint8 = 0x7 +) + +// MLDv2MulticastListenerQueryMessage are sent by multicast routers to query the +// multicast listening state of neighboring interfaces. +// https://tools.ietf.org/html/rfc3810#section-5.1 +// +// Some information, like Maximum Response Code and Multicast Address are in the +// previous layer LayerTypeMLDv1MulticastListenerQuery +type MLDv2MulticastListenerQueryMessage struct { + BaseLayer + // 5.1.3. Maximum Response Delay COde + MaximumResponseCode uint16 + // 5.1.5. Multicast Address + // Zero in general query + // Specific IPv6 multicast address otherwise + MulticastAddress net.IP + // 5.1.7. S Flag (Suppress Router-Side Processing) + SuppressRoutersideProcessing bool + // 5.1.8. QRV (Querier's Robustness Variable) + QueriersRobustnessVariable uint8 + // 5.1.9. QQIC (Querier's Query Interval Code) + QueriersQueryIntervalCode uint8 + // 5.1.10. Number of Sources (N) + NumberOfSources uint16 + // 5.1.11 Source Address [i] + SourceAddresses []net.IP +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (m *MLDv2MulticastListenerQueryMessage) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 24 { + df.SetTruncated() + return errors.New("ICMP layer less than 24 bytes for Multicast Listener Query Message V2") + } + + m.MaximumResponseCode = binary.BigEndian.Uint16(data[0:2]) + // ignore data[2:4] as per https://tools.ietf.org/html/rfc3810#section-5.1.4 + m.MulticastAddress = data[4:20] + m.SuppressRoutersideProcessing = (data[20] & mldv2SMask) == mldv2STrue + m.QueriersRobustnessVariable = data[20] & mldv2QRVMask + m.QueriersQueryIntervalCode = data[21] + + m.NumberOfSources = binary.BigEndian.Uint16(data[22:24]) + + var end int + for i := uint16(0); i < m.NumberOfSources; i++ { + begin := 24 + (int(i) * 16) + end = begin + 16 + + if end > len(data) { + df.SetTruncated() + return fmt.Errorf("ICMP layer less than %d bytes for Multicast Listener Query Message V2", end) + } + + m.SourceAddresses = append(m.SourceAddresses, data[begin:end]) + } + + return nil +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (*MLDv2MulticastListenerQueryMessage) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypeZero +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (m *MLDv2MulticastListenerQueryMessage) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if err := m.serializeSourceAddressesTo(b, opts); err != nil { + return err + } + + buf, err := b.PrependBytes(24) + if err != nil { + return err + } + + binary.BigEndian.PutUint16(buf[0:2], m.MaximumResponseCode) + copy(buf[2:4], []byte{0x00, 0x00}) // set reserved bytes to zero + + ma16 := m.MulticastAddress.To16() + if ma16 == nil { + return fmt.Errorf("invalid MulticastAddress '%s'", m.MulticastAddress) + } + copy(buf[4:20], ma16) + + byte20 := m.QueriersRobustnessVariable & mldv2QRVMask + if m.SuppressRoutersideProcessing { + byte20 |= mldv2STrue + } else { + byte20 &= ^mldv2STrue // the complement of mldv2STrue + } + byte20 &= 0x0F // set reserved bits to zero + buf[20] = byte20 + + binary.BigEndian.PutUint16(buf[22:24], m.NumberOfSources) + buf[21] = m.QueriersQueryIntervalCode + + return nil +} + +// writes each source address to the buffer preserving the order +func (m *MLDv2MulticastListenerQueryMessage) serializeSourceAddressesTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + numberOfSourceAddresses := len(m.SourceAddresses) + if numberOfSourceAddresses > math.MaxUint16 { + return fmt.Errorf( + "there are more than %d source addresses, but 65535 is the maximum number of supported addresses", + numberOfSourceAddresses) + } + + if opts.FixLengths { + m.NumberOfSources = uint16(numberOfSourceAddresses) + } + + lastSAIdx := numberOfSourceAddresses - 1 + for k := range m.SourceAddresses { + i := lastSAIdx - k // reverse order + + buf, err := b.PrependBytes(16) + if err != nil { + return err + } + + sa16 := m.SourceAddresses[i].To16() + if sa16 == nil { + return fmt.Errorf("invalid source address [%d] '%s'", i, m.SourceAddresses[i]) + } + copy(buf[0:16], sa16) + } + + return nil +} + +// String sums this layer up nicely formatted +func (m *MLDv2MulticastListenerQueryMessage) String() string { + return fmt.Sprintf( + "Maximum Response Code: %#x (%dms), Multicast Address: %s, Suppress Routerside Processing: %t, QRV: %#x, QQIC: %#x (%ds), Number of Source Address: %d (actual: %d), Source Addresses: %s", + m.MaximumResponseCode, + m.MaximumResponseDelay(), + m.MulticastAddress, + m.SuppressRoutersideProcessing, + m.QueriersRobustnessVariable, + m.QueriersQueryIntervalCode, + m.QQI()/time.Second, + m.NumberOfSources, + len(m.SourceAddresses), + m.SourceAddresses) +} + +// LayerType returns LayerTypeMLDv2MulticastListenerQuery. +func (*MLDv2MulticastListenerQueryMessage) LayerType() gopacket.LayerType { + return LayerTypeMLDv2MulticastListenerQuery +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (*MLDv2MulticastListenerQueryMessage) CanDecode() gopacket.LayerClass { + return LayerTypeMLDv2MulticastListenerQuery +} + +// QQI calculates the Querier's Query Interval based on the QQIC +// according to https://tools.ietf.org/html/rfc3810#section-5.1.9 +func (m *MLDv2MulticastListenerQueryMessage) QQI() time.Duration { + data := m.QueriersQueryIntervalCode + if data < 128 { + return time.Second * time.Duration(data) + } + + exp := uint16(data) & 0x70 >> 4 + mant := uint16(data) & 0x0F + return time.Second * time.Duration(mant|0x1000<<(exp+3)) +} + +// SetQQI calculates and updates the Querier's Query Interval Code (QQIC) +// according to https://tools.ietf.org/html/rfc3810#section-5.1.9 +func (m *MLDv2MulticastListenerQueryMessage) SetQQI(d time.Duration) error { + if d < 0 { + m.QueriersQueryIntervalCode = 0 + return errors.New("QQI duration is negative") + } + + if d == 0 { + m.QueriersQueryIntervalCode = 0 + return nil + } + + dms := d / time.Second + if dms < 128 { + m.QueriersQueryIntervalCode = uint8(dms) + } + + if dms > 31744 { // mant=0xF, exp=0x7 + m.QueriersQueryIntervalCode = 0xFF + return fmt.Errorf("QQI duration %ds is, maximum allowed is 31744s", dms) + } + + value := uint16(dms) // ok, because 31744 < math.MaxUint16 + exp := uint8(7) + for mask := uint16(0x4000); exp > 0; exp-- { + if mask&value != 0 { + break + } + + mask >>= 1 + } + + mant := uint8(0x000F & (value >> (exp + 3))) + sig := uint8(0x10) + m.QueriersQueryIntervalCode = sig | exp<<4 | mant + + return nil +} + +// MaximumResponseDelay returns the Maximum Response Delay based on the +// Maximum Response Code according to +// https://tools.ietf.org/html/rfc3810#section-5.1.3 +func (m *MLDv2MulticastListenerQueryMessage) MaximumResponseDelay() time.Duration { + if m.MaximumResponseCode < 0x8000 { + return time.Duration(m.MaximumResponseCode) + } + + exp := m.MaximumResponseCode & 0x7000 >> 12 + mant := m.MaximumResponseCode & 0x0FFF + + return time.Millisecond * time.Duration(mant|0x1000<<(exp+3)) +} + +// SetMLDv2MaximumResponseDelay updates the Maximum Response Code according to +// https://tools.ietf.org/html/rfc3810#section-5.1.3 +func (m *MLDv2MulticastListenerQueryMessage) SetMLDv2MaximumResponseDelay(d time.Duration) error { + if d == 0 { + m.MaximumResponseCode = 0 + return nil + } + + if d < 0 { + return errors.New("maximum response delay must not be negative") + } + + dms := d / time.Millisecond + + if dms < 32768 { + m.MaximumResponseCode = uint16(dms) + } + + if dms > 4193280 { // mant=0xFFF, exp=0x7 + return fmt.Errorf("maximum response delay %dms is bigger the than maximum of 4193280ms", dms) + } + + value := uint32(dms) // ok, because 4193280 < math.MaxUint32 + exp := uint8(7) + for mask := uint32(0x40000000); exp > 0; exp-- { + if mask&value != 0 { + break + } + + mask >>= 1 + } + + mant := uint16(0x00000FFF & (value >> (exp + 3))) + sig := uint16(0x1000) + m.MaximumResponseCode = sig | uint16(exp)<<12 | mant + return nil +} + +// MLDv2MulticastListenerReportMessage is sent by an IP node to report the +// current multicast listening state, or changes therein. +// https://tools.ietf.org/html/rfc3810#section-5.2 +type MLDv2MulticastListenerReportMessage struct { + BaseLayer + // 5.2.3. Nr of Mcast Address Records + NumberOfMulticastAddressRecords uint16 + // 5.2.4. Multicast Address Record [i] + MulticastAddressRecords []MLDv2MulticastAddressRecord +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (m *MLDv2MulticastListenerReportMessage) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 4 { + df.SetTruncated() + return errors.New("ICMP layer less than 4 bytes for Multicast Listener Report Message V2") + } + + // ignore data[0:2] as per RFC + // https://tools.ietf.org/html/rfc3810#section-5.2.1 + m.NumberOfMulticastAddressRecords = binary.BigEndian.Uint16(data[2:4]) + + begin := 4 + for i := uint16(0); i < m.NumberOfMulticastAddressRecords; i++ { + mar := MLDv2MulticastAddressRecord{} + read, err := mar.decode(data[begin:], df) + if err != nil { + return err + } + + m.MulticastAddressRecords = append(m.MulticastAddressRecords, mar) + + begin += read + } + + return nil +} + +// SerializeTo writes the serialized form of this layer into the +// SerializationBuffer, implementing gopacket.SerializableLayer. +// See the docs for gopacket.SerializableLayer for more info. +func (m *MLDv2MulticastListenerReportMessage) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + lastItemIdx := len(m.MulticastAddressRecords) - 1 + for k := range m.MulticastAddressRecords { + i := lastItemIdx - k // reverse order + + err := m.MulticastAddressRecords[i].serializeTo(b, opts) + if err != nil { + return err + } + } + + if opts.FixLengths { + numberOfMAR := len(m.MulticastAddressRecords) + if numberOfMAR > math.MaxUint16 { + return fmt.Errorf( + "%d multicast address records added, but the maximum is 65535", + numberOfMAR) + } + + m.NumberOfMulticastAddressRecords = uint16(numberOfMAR) + } + + buf, err := b.PrependBytes(4) + if err != nil { + return err + } + + copy(buf[0:2], []byte{0x0, 0x0}) + binary.BigEndian.PutUint16(buf[2:4], m.NumberOfMulticastAddressRecords) + return nil +} + +// Sums this layer up nicely formatted +func (m *MLDv2MulticastListenerReportMessage) String() string { + return fmt.Sprintf( + "Number of Mcast Addr Records: %d (actual %d), Multicast Address Records: %+v", + m.NumberOfMulticastAddressRecords, + len(m.MulticastAddressRecords), + m.MulticastAddressRecords) +} + +// LayerType returns LayerTypeMLDv2MulticastListenerQuery. +func (*MLDv2MulticastListenerReportMessage) LayerType() gopacket.LayerType { + return LayerTypeMLDv2MulticastListenerReport +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode. +func (*MLDv2MulticastListenerReportMessage) CanDecode() gopacket.LayerClass { + return LayerTypeMLDv2MulticastListenerReport +} + +// NextLayerType returns the layer type contained by this DecodingLayer. +func (*MLDv2MulticastListenerReportMessage) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +// MLDv2MulticastAddressRecordType holds the type of a +// Multicast Address Record, according to +// https://tools.ietf.org/html/rfc3810#section-5.2.5 and +// https://tools.ietf.org/html/rfc3810#section-5.2.12 +type MLDv2MulticastAddressRecordType uint8 + +const ( + // MLDv2MulticastAddressRecordTypeModeIsIncluded stands for + // MODE_IS_INCLUDE - indicates that the interface has a filter + // mode of INCLUDE for the specified multicast address. + MLDv2MulticastAddressRecordTypeModeIsIncluded MLDv2MulticastAddressRecordType = 1 + // MLDv2MulticastAddressRecordTypeModeIsExcluded stands for + // MODE_IS_EXCLUDE - indicates that the interface has a filter + // mode of EXCLUDE for the specified multicast address. + MLDv2MulticastAddressRecordTypeModeIsExcluded MLDv2MulticastAddressRecordType = 2 + // MLDv2MulticastAddressRecordTypeChangeToIncludeMode stands for + // CHANGE_TO_INCLUDE_MODE - indicates that the interface has + // changed to INCLUDE filter mode for the specified multicast + // address. + MLDv2MulticastAddressRecordTypeChangeToIncludeMode MLDv2MulticastAddressRecordType = 3 + // MLDv2MulticastAddressRecordTypeChangeToExcludeMode stands for + // CHANGE_TO_EXCLUDE_MODE - indicates that the interface has + // changed to EXCLUDE filter mode for the specified multicast + // address + MLDv2MulticastAddressRecordTypeChangeToExcludeMode MLDv2MulticastAddressRecordType = 4 + // MLDv2MulticastAddressRecordTypeAllowNewSources stands for + // ALLOW_NEW_SOURCES - indicates that the Source Address [i] + // fields in this Multicast Address Record contain a list of + // the additional sources that the node wishes to listen to, + // for packets sent to the specified multicast address. + MLDv2MulticastAddressRecordTypeAllowNewSources MLDv2MulticastAddressRecordType = 5 + // MLDv2MulticastAddressRecordTypeBlockOldSources stands for + // BLOCK_OLD_SOURCES - indicates that the Source Address [i] + // fields in this Multicast Address Record contain a list of + // the sources that the node no longer wishes to listen to, + // for packets sent to the specified multicast address. + MLDv2MulticastAddressRecordTypeBlockOldSources MLDv2MulticastAddressRecordType = 6 +) + +// Human readable record types +// Naming follows https://tools.ietf.org/html/rfc3810#section-5.2.12 +func (m MLDv2MulticastAddressRecordType) String() string { + switch m { + case MLDv2MulticastAddressRecordTypeModeIsIncluded: + return "MODE_IS_INCLUDE" + case MLDv2MulticastAddressRecordTypeModeIsExcluded: + return "MODE_IS_EXCLUDE" + case MLDv2MulticastAddressRecordTypeChangeToIncludeMode: + return "CHANGE_TO_INCLUDE_MODE" + case MLDv2MulticastAddressRecordTypeChangeToExcludeMode: + return "CHANGE_TO_EXCLUDE_MODE" + case MLDv2MulticastAddressRecordTypeAllowNewSources: + return "ALLOW_NEW_SOURCES" + case MLDv2MulticastAddressRecordTypeBlockOldSources: + return "BLOCK_OLD_SOURCES" + default: + return fmt.Sprintf("UNKNOWN(%d)", m) + } +} + +// MLDv2MulticastAddressRecord contains information on the sender listening to a +// single multicast address on the interface the report is sent. +// https://tools.ietf.org/html/rfc3810#section-5.2.4 +type MLDv2MulticastAddressRecord struct { + // 5.2.5. Record Type + RecordType MLDv2MulticastAddressRecordType + // 5.2.6. Auxiliary Data Length (number of 32-bit words) + AuxDataLen uint8 + // 5.2.7. Number Of Sources (N) + N uint16 + // 5.2.8. Multicast Address + MulticastAddress net.IP + // 5.2.9 Source Address [i] + SourceAddresses []net.IP + // 5.2.10 Auxiliary Data + AuxiliaryData []byte +} + +// decodes a multicast address record from bytes +func (m *MLDv2MulticastAddressRecord) decode(data []byte, df gopacket.DecodeFeedback) (int, error) { + if len(data) < 4 { + df.SetTruncated() + return 0, errors.New( + "Multicast Listener Report Message V2 layer less than 4 bytes for Multicast Address Record") + } + + m.RecordType = MLDv2MulticastAddressRecordType(data[0]) + m.AuxDataLen = data[1] + m.N = binary.BigEndian.Uint16(data[2:4]) + m.MulticastAddress = data[4:20] + + for i := uint16(0); i < m.N; i++ { + begin := 20 + (int(i) * 16) + end := begin + 16 + + if len(data) < end { + df.SetTruncated() + return begin, fmt.Errorf( + "Multicast Listener Report Message V2 layer less than %d bytes for Multicast Address Record", end) + } + + m.SourceAddresses = append(m.SourceAddresses, data[begin:end]) + } + + expectedLengthWithouAuxData := 20 + (int(m.N) * 16) + expectedTotalLength := (int(m.AuxDataLen) * 4) + expectedLengthWithouAuxData // *4 because AuxDataLen are 32bit words + if len(data) < expectedTotalLength { + return expectedLengthWithouAuxData, fmt.Errorf( + "Multicast Listener Report Message V2 layer less than %d bytes for Multicast Address Record", + expectedLengthWithouAuxData) + } + + m.AuxiliaryData = data[expectedLengthWithouAuxData:expectedTotalLength] + + return expectedTotalLength, nil +} + +// String sums this layer up nicely formatted +func (m *MLDv2MulticastAddressRecord) String() string { + return fmt.Sprintf( + "RecordType: %d (%s), AuxDataLen: %d [32-bit words], N: %d, Multicast Address: %s, SourceAddresses: %s, Auxiliary Data: %#x", + m.RecordType, + m.RecordType.String(), + m.AuxDataLen, + m.N, + m.MulticastAddress.To16(), + m.SourceAddresses, + m.AuxiliaryData) +} + +// serializes a multicast address record +func (m *MLDv2MulticastAddressRecord) serializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if err := m.serializeAuxiliaryDataTo(b, opts); err != nil { + return err + } + + if err := m.serializeSourceAddressesTo(b, opts); err != nil { + return err + } + + buf, err := b.PrependBytes(20) + if err != nil { + return err + } + + buf[0] = uint8(m.RecordType) + buf[1] = m.AuxDataLen + binary.BigEndian.PutUint16(buf[2:4], m.N) + + ma16 := m.MulticastAddress.To16() + if ma16 == nil { + return fmt.Errorf("invalid multicast address '%s'", m.MulticastAddress) + } + copy(buf[4:20], ma16) + + return nil +} + +// serializes the auxiliary data of a multicast address record +func (m *MLDv2MulticastAddressRecord) serializeAuxiliaryDataTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if remainder := len(m.AuxiliaryData) % 4; remainder != 0 { + zeroWord := []byte{0x0, 0x0, 0x0, 0x0} + m.AuxiliaryData = append(m.AuxiliaryData, zeroWord[:remainder]...) + } + + if opts.FixLengths { + auxDataLen := len(m.AuxiliaryData) / 4 + + if auxDataLen > math.MaxUint8 { + return fmt.Errorf("auxilary data is %d 32-bit words, but the maximum is 255 32-bit words", auxDataLen) + } + + m.AuxDataLen = uint8(auxDataLen) + } + + buf, err := b.PrependBytes(len(m.AuxiliaryData)) + if err != nil { + return err + } + + copy(buf, m.AuxiliaryData) + return nil +} + +// serializes the source addresses of a multicast address record preserving the order +func (m *MLDv2MulticastAddressRecord) serializeSourceAddressesTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if opts.FixLengths { + numberOfSourceAddresses := len(m.SourceAddresses) + + if numberOfSourceAddresses > math.MaxUint16 { + return fmt.Errorf( + "%d source addresses added, but the maximum is 65535", + numberOfSourceAddresses) + } + + m.N = uint16(numberOfSourceAddresses) + } + + lastItemIdx := len(m.SourceAddresses) - 1 + for k := range m.SourceAddresses { + i := lastItemIdx - k // reverse order + + buf, err := b.PrependBytes(16) + if err != nil { + return err + } + + sa16 := m.SourceAddresses[i].To16() + if sa16 == nil { + return fmt.Errorf("invalid source address [%d] '%s'", i, m.SourceAddresses[i]) + } + copy(buf, sa16) + } + + return nil +} + +func decodeMLDv2MulticastListenerReport(data []byte, p gopacket.PacketBuilder) error { + m := &MLDv2MulticastListenerReportMessage{} + return decodingLayerDecoder(m, data, p) +} + +func decodeMLDv2MulticastListenerQuery(data []byte, p gopacket.PacketBuilder) error { + m := &MLDv2MulticastListenerQueryMessage{} + return decodingLayerDecoder(m, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/mldv2_test.go b/vendor/github.com/google/gopacket/layers/mldv2_test.go new file mode 100644 index 0000000000..8aeec45738 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/mldv2_test.go @@ -0,0 +1,137 @@ +// Copyright 2018 GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "testing" + + "github.com/google/gopacket" +) + +// Adapted from https://github.com/the-tcpdump-group/tcpdump/blob/master/tests/icmpv6.pcap +// BSD licensed content +// +// Ethernet II, Src: JuniperN_0c:d4:e8 (b0:a8:6e:0c:d4:e8), Dst: IPv6mcast_01 (33:33:00:00:00:01) +// Internet Protocol Version 6, Src: fe80::b2a8:6eff:fe0c:d4e8, Dst: ff02::1 +// 0110 .... = Version: 6 +// .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT) +// .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000 +// Payload Length: 36 +// Next Header: IPv6 Hop-by-Hop Option (0) +// Hop Limit: 1 +// Source: fe80::b2a8:6eff:fe0c:d4e8 +// Destination: ff02::1 +// [Source SA MAC: JuniperN_0c:d4:e8 (b0:a8:6e:0c:d4:e8)] +// IPv6 Hop-by-Hop Option +// Internet Control Message Protocol v6 +// Type: Multicast Listener Query (130) +// Code: 0 +// Checksum: 0x623a [correct] +// [Checksum Status: Good] +// Maximum Response Code: 10000 +// Reserved: 0000 +// Multicast Address: :: +// Flags: 0x02 +// .... 0... = Suppress Router-Side Processing: False +// .... .010 = QRV (Querier's Robustness Variable): 2 +// 0000 .... = Reserved: 0 +// QQIC (Querier's Query Interval Code): 60 +// Number of Sources: 0 +var testPacketMulticastListenerQueryMessageV2 = []byte{ + 0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0xb0, 0xa8, 0x6e, 0x0c, 0xd4, 0xe8, 0x86, 0xdd, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0xa8, + 0x6e, 0xff, 0xfe, 0x0c, 0xd4, 0xe8, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3a, 0x00, 0x05, 0x02, 0x00, 0x00, 0x01, 0x00, 0x82, 0x00, + 0x62, 0x3a, 0x27, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x00, +} + +func TestPacketMulticastListenerQueryMessageV2(t *testing.T) { + p := gopacket.NewPacket(testPacketMulticastListenerQueryMessageV2, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{ + LayerTypeEthernet, + LayerTypeIPv6, + LayerTypeIPv6HopByHop, + LayerTypeICMPv6, + LayerTypeMLDv2MulticastListenerQuery}, t) + // See https://github.com/google/gopacket/issues/517 + // checkSerialization(p, t) +} + +// Adapted from https://github.com/the-tcpdump-group/tcpdump/blob/master/tests/icmpv6.pcap +// BSD licensed content +// +// Frame 4: 150 bytes on wire (1200 bits), 150 bytes captured (1200 bits) +// Ethernet II, Src: IntelCor_cc:e5:46 (00:15:17:cc:e5:46), Dst: IPv6mcast_16 (33:33:00:00:00:16) +// Internet Protocol Version 6, Src: fe80::215:17ff:fecc:e546, Dst: ff02::16 +// 0110 .... = Version: 6 +// .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT) +// .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000 +// Payload Length: 96 +// Next Header: IPv6 Hop-by-Hop Option (0) +// Hop Limit: 1 +// Source: fe80::215:17ff:fecc:e546 +// Destination: ff02::16 +// [Source SA MAC: IntelCor_cc:e5:46 (00:15:17:cc:e5:46)] +// IPv6 Hop-by-Hop Option +// Internet Control Message Protocol v6 +// Type: Multicast Listener Report Message v2 (143) +// Code: 0 +// Checksum: 0x2a0e [correct] +// [Checksum Status: Good] +// Reserved: 0000 +// Number of Multicast Address Records: 4 +// Multicast Address Record Exclude: ff02::db8:1122:3344 +// Record Type: Exclude (2) +// Aux Data Len: 0 +// Number of Sources: 0 +// Multicast Address: ff02::db8:1122:3344 +// Multicast Address Record Exclude: ff02::1:ffcc:e546 +// Record Type: Exclude (2) +// Aux Data Len: 0 +// Number of Sources: 0 +// Multicast Address: ff02::1:ffcc:e546 +// Multicast Address Record Exclude: ff02::1:ffa7:10ad +// Record Type: Exclude (2) +// Aux Data Len: 0 +// Number of Sources: 0 +// Multicast Address: ff02::1:ffa7:10ad +// Multicast Address Record Exclude: ff02::1:ff00:2 +// Record Type: Exclude (2) +// Aux Data Len: 0 +// Number of Sources: 0 +// Multicast Address: ff02::1:ff00:2 +var testPacketMulticastListenerReportMessageV2 = []byte{ + 0x33, 0x33, 0x00, 0x00, 0x00, 0x16, 0x00, 0x15, 0x17, 0xcc, 0xe5, 0x46, 0x86, 0xdd, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x00, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x15, + 0x17, 0xff, 0xfe, 0xcc, 0xe5, 0x46, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x3a, 0x00, 0x05, 0x02, 0x00, 0x00, 0x01, 0x00, 0x8f, 0x00, + 0x2a, 0x0e, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0xb8, 0x11, 0x22, 0x33, 0x44, 0x02, 0x00, 0x00, 0x00, 0xff, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xcc, 0xe5, 0x46, 0x02, 0x00, + 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xa7, + 0x10, 0xad, 0x02, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xff, 0x00, 0x00, 0x02, +} + +func TestPacketMulticastListenerReportMessageV2(t *testing.T) { + p := gopacket.NewPacket(testPacketMulticastListenerReportMessageV2, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{ + LayerTypeEthernet, + LayerTypeIPv6, + LayerTypeIPv6HopByHop, + LayerTypeICMPv6, + LayerTypeMLDv2MulticastListenerReport}, t) + // See https://github.com/google/gopacket/issues/517 + // checkSerialization(p, t) +} diff --git a/vendor/github.com/google/gopacket/layers/modbustcp.go b/vendor/github.com/google/gopacket/layers/modbustcp.go new file mode 100644 index 0000000000..bafbd7436c --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/modbustcp.go @@ -0,0 +1,150 @@ +// Copyright 2018, The GoPacket Authors, All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +// +//****************************************************************************** + +package layers + +import ( + "encoding/binary" + "errors" + "github.com/google/gopacket" +) + +//****************************************************************************** +// +// ModbusTCP Decoding Layer +// ------------------------------------------ +// This file provides a GoPacket decoding layer for ModbusTCP. +// +//****************************************************************************** + +const mbapRecordSizeInBytes int = 7 +const modbusPDUMinimumRecordSizeInBytes int = 2 +const modbusPDUMaximumRecordSizeInBytes int = 253 + +// ModbusProtocol type +type ModbusProtocol uint16 + +// ModbusProtocol known values. +const ( + ModbusProtocolModbus ModbusProtocol = 0 +) + +func (mp ModbusProtocol) String() string { + switch mp { + default: + return "Unknown" + case ModbusProtocolModbus: + return "Modbus" + } +} + +//****************************************************************************** + +// ModbusTCP Type +// -------- +// Type ModbusTCP implements the DecodingLayer interface. Each ModbusTCP object +// represents in a structured form the MODBUS Application Protocol header (MBAP) record present as the TCP +// payload in an ModbusTCP TCP packet. +// +type ModbusTCP struct { + BaseLayer // Stores the packet bytes and payload (Modbus PDU) bytes . + + TransactionIdentifier uint16 // Identification of a MODBUS Request/Response transaction + ProtocolIdentifier ModbusProtocol // It is used for intra-system multiplexing + Length uint16 // Number of following bytes (includes 1 byte for UnitIdentifier + Modbus data length + UnitIdentifier uint8 // Identification of a remote slave connected on a serial line or on other buses +} + +//****************************************************************************** + +// LayerType returns the layer type of the ModbusTCP object, which is LayerTypeModbusTCP. +func (d *ModbusTCP) LayerType() gopacket.LayerType { + return LayerTypeModbusTCP +} + +//****************************************************************************** + +// decodeModbusTCP analyses a byte slice and attempts to decode it as an ModbusTCP +// record of a TCP packet. +// +// If it succeeds, it loads p with information about the packet and returns nil. +// If it fails, it returns an error (non nil). +// +// This function is employed in layertypes.go to register the ModbusTCP layer. +func decodeModbusTCP(data []byte, p gopacket.PacketBuilder) error { + + // Attempt to decode the byte slice. + d := &ModbusTCP{} + err := d.DecodeFromBytes(data, p) + if err != nil { + return err + } + // If the decoding worked, add the layer to the packet and set it + // as the application layer too, if there isn't already one. + p.AddLayer(d) + p.SetApplicationLayer(d) + + return p.NextDecoder(d.NextLayerType()) + +} + +//****************************************************************************** + +// DecodeFromBytes analyses a byte slice and attempts to decode it as an ModbusTCP +// record of a TCP packet. +// +// Upon succeeds, it loads the ModbusTCP object with information about the packet +// and returns nil. +// Upon failure, it returns an error (non nil). +func (d *ModbusTCP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + + // If the data block is too short to be a MBAP record, then return an error. + if len(data) < mbapRecordSizeInBytes+modbusPDUMinimumRecordSizeInBytes { + df.SetTruncated() + return errors.New("ModbusTCP packet too short") + } + + if len(data) > mbapRecordSizeInBytes+modbusPDUMaximumRecordSizeInBytes { + df.SetTruncated() + return errors.New("ModbusTCP packet too long") + } + + // ModbusTCP type embeds type BaseLayer which contains two fields: + // Contents is supposed to contain the bytes of the data at this level (MPBA). + // Payload is supposed to contain the payload of this level (PDU). + d.BaseLayer = BaseLayer{Contents: data[:mbapRecordSizeInBytes], Payload: data[mbapRecordSizeInBytes:len(data)]} + + // Extract the fields from the block of bytes. + // The fields can just be copied in big endian order. + d.TransactionIdentifier = binary.BigEndian.Uint16(data[:2]) + d.ProtocolIdentifier = ModbusProtocol(binary.BigEndian.Uint16(data[2:4])) + d.Length = binary.BigEndian.Uint16(data[4:6]) + + // Length should have the size of the payload plus one byte (size of UnitIdentifier) + if d.Length != uint16(len(d.BaseLayer.Payload)+1) { + df.SetTruncated() + return errors.New("ModbusTCP packet with wrong field value (Length)") + } + d.UnitIdentifier = uint8(data[6]) + + return nil +} + +//****************************************************************************** + +// NextLayerType returns the layer type of the ModbusTCP payload, which is LayerTypePayload. +func (d *ModbusTCP) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +//****************************************************************************** + +// Payload returns Modbus Protocol Data Unit (PDU) composed by Function Code and Data, it is carried within ModbusTCP packets +func (d *ModbusTCP) Payload() []byte { + return d.BaseLayer.Payload +} diff --git a/vendor/github.com/google/gopacket/layers/ospf.go b/vendor/github.com/google/gopacket/layers/ospf.go index eee8542093..f3f2ca9adb 100644 --- a/vendor/github.com/google/gopacket/layers/ospf.go +++ b/vendor/github.com/google/gopacket/layers/ospf.go @@ -27,14 +27,19 @@ const ( // LSA Function Codes for LSAheader.LSType const ( - RouterLSAtype = 0x2001 - NetworkLSAtype = 0x2002 - InterAreaPrefixLSAtype = 0x2003 - InterAreaRouterLSAtype = 0x2004 - ASExternalLSAtype = 0x4005 - NSSALSAtype = 0x2007 - LinkLSAtype = 0x0008 - IntraAreaPrefixLSAtype = 0x2009 + RouterLSAtypeV2 = 0x1 + RouterLSAtype = 0x2001 + NetworkLSAtypeV2 = 0x2 + NetworkLSAtype = 0x2002 + SummaryLSANetworktypeV2 = 0x3 + InterAreaPrefixLSAtype = 0x2003 + SummaryLSAASBRtypeV2 = 0x4 + InterAreaRouterLSAtype = 0x2004 + ASExternalLSAtypeV2 = 0x5 + ASExternalLSAtype = 0x4005 + NSSALSAtype = 0x2007 + LinkLSAtype = 0x0008 + IntraAreaPrefixLSAtype = 0x2009 ) // String conversions for OSPFType @@ -81,6 +86,15 @@ type LinkLSA struct { Prefixes []Prefix } +// ASExternalLSAV2 is the struct from RFC 2328 A.4.5. +type ASExternalLSAV2 struct { + NetworkMask uint32 + ExternalBit uint8 + Metric uint32 + ForwardingAddress uint32 + ExternalRouteTag uint32 +} + // ASExternalLSA is the struct from RFC 5340 A.4.7. type ASExternalLSA struct { Flags uint8 @@ -115,6 +129,21 @@ type NetworkLSA struct { AttachedRouter []uint32 } +// RouterV2 extends RouterLSAV2 +type RouterV2 struct { + Type uint8 + LinkID uint32 + LinkData uint32 + Metric uint16 +} + +// RouterLSAV2 is the struct from RFC 2328 A.4.2. +type RouterLSAV2 struct { + Flags uint8 + Links uint16 + Routers []RouterV2 +} + // Router extends RouterLSA type Router struct { Type uint8 @@ -131,7 +160,7 @@ type RouterLSA struct { Routers []Router } -// LSAheader is the struct from RFC 5340 A.4.2. +// LSAheader is the struct from RFC 5340 A.4.2 and RFC 2328 A.4.1. type LSAheader struct { LSAge uint16 LSType uint16 @@ -140,6 +169,7 @@ type LSAheader struct { LSSeqNumber uint32 LSChecksum uint16 Length uint16 + LSOptions uint8 } // LSA links LSAheader with the structs from RFC 5340 A.4. @@ -176,7 +206,7 @@ type HelloPkg struct { RtrPriority uint8 Options uint32 HelloInterval uint16 - RouterDeadInterval uint16 + RouterDeadInterval uint32 DesignatedRouterID uint32 BackupDesignatedRouterID uint32 NeighborID []uint32 @@ -215,124 +245,187 @@ type OSPFv3 struct { Reserved uint8 } -// getLSAs parses the LSA information from the packet -func getLSAs(num uint32, data []byte) ([]LSA, error) { +// getLSAsv2 parses the LSA information from the packet for OSPFv2 +func getLSAsv2(num uint32, data []byte) ([]LSA, error) { var lsas []LSA var i uint32 = 0 var offset uint32 = 0 for ; i < num; i++ { - var content interface{} - lstype := binary.BigEndian.Uint16(data[offset+2 : offset+4]) + lstype := uint16(data[offset+3]) lsalength := binary.BigEndian.Uint16(data[offset+18 : offset+20]) + content, err := extractLSAInformation(lstype, lsalength, data[offset:]) + if err != nil { + return nil, fmt.Errorf("Could not extract Link State type.") + } + lsa := LSA{ + LSAheader: LSAheader{ + LSAge: binary.BigEndian.Uint16(data[offset : offset+2]), + LSOptions: data[offset+2], + LSType: lstype, + LinkStateID: binary.BigEndian.Uint32(data[offset+4 : offset+8]), + AdvRouter: binary.BigEndian.Uint32(data[offset+8 : offset+12]), + LSSeqNumber: binary.BigEndian.Uint32(data[offset+12 : offset+16]), + LSChecksum: binary.BigEndian.Uint16(data[offset+16 : offset+18]), + Length: lsalength, + }, + Content: content, + } + lsas = append(lsas, lsa) + offset += uint32(lsalength) + } + return lsas, nil +} - switch lstype { - case RouterLSAtype: - var routers []Router - var j uint32 - for j = 24; j < uint32(lsalength); j += 16 { - router := Router{ - Type: uint8(data[offset+j]), - Metric: binary.BigEndian.Uint16(data[offset+j+2 : offset+j+4]), - InterfaceID: binary.BigEndian.Uint32(data[offset+j+4 : offset+j+8]), - NeighborInterfaceID: binary.BigEndian.Uint32(data[offset+j+8 : offset+j+12]), - NeighborRouterID: binary.BigEndian.Uint32(data[offset+j+12 : offset+j+16]), - } - routers = append(routers, router) - } - content = RouterLSA{ - Flags: uint8(data[offset+20]), - Options: binary.BigEndian.Uint32(data[offset+20:offset+24]) & 0x00FFFFFF, - Routers: routers, - } - case NetworkLSAtype: - var routers []uint32 - var j uint32 - for j = 24; j < uint32(lsalength); j += 4 { - routers = append(routers, binary.BigEndian.Uint32(data[offset+j:offset+j+4])) - } - content = NetworkLSA{ - Options: binary.BigEndian.Uint32(data[offset+20:offset+24]) & 0x00FFFFFF, - AttachedRouter: routers, - } - case InterAreaPrefixLSAtype: - content = InterAreaPrefixLSA{ - Metric: binary.BigEndian.Uint32(data[offset+20:offset+24]) & 0x00FFFFFF, - PrefixLength: uint8(data[offset+24]), - PrefixOptions: uint8(data[offset+25]), - AddressPrefix: data[offset+28 : offset+uint32(lsalength)], - } - case InterAreaRouterLSAtype: - content = InterAreaRouterLSA{ - Options: binary.BigEndian.Uint32(data[offset+20:offset+24]) & 0x00FFFFFF, - Metric: binary.BigEndian.Uint32(data[offset+24:offset+28]) & 0x00FFFFFF, - DestinationRouterID: binary.BigEndian.Uint32(data[offset+28 : offset+32]), - } - case ASExternalLSAtype: - fallthrough - case NSSALSAtype: - - flags := uint8(data[offset+20]) - prefixLen := uint8(data[offset+24]) / 8 - var forwardingAddress []byte - if (flags & 0x02) == 0x02 { - forwardingAddress = data[offset+28+uint32(prefixLen) : offset+28+uint32(prefixLen)+16] - } - content = ASExternalLSA{ - Flags: flags, - Metric: binary.BigEndian.Uint32(data[offset+20:offset+24]) & 0x00FFFFFF, - PrefixLength: prefixLen, - PrefixOptions: uint8(data[offset+25]), - RefLSType: binary.BigEndian.Uint16(data[offset+26 : offset+28]), - AddressPrefix: data[offset+28 : offset+28+uint32(prefixLen)], - ForwardingAddress: forwardingAddress, - } - case LinkLSAtype: - var prefixes []Prefix - var prefixOffset uint32 = offset + 44 - var j uint32 - numOfPrefixes := binary.BigEndian.Uint32(data[offset+40 : offset+44]) - for j = 0; j < numOfPrefixes; j++ { - prefixLen := uint8(data[prefixOffset]) - prefix := Prefix{ - PrefixLength: prefixLen, - PrefixOptions: uint8(data[prefixOffset+1]), - AddressPrefix: data[prefixOffset+4 : prefixOffset+4+uint32(prefixLen)/8], - } - prefixes = append(prefixes, prefix) - prefixOffset = prefixOffset + 4 + uint32(prefixLen)/8 - } - content = LinkLSA{ - RtrPriority: uint8(data[offset+20]), - Options: binary.BigEndian.Uint32(data[offset+20:offset+24]) & 0x00FFFFFF, - LinkLocalAddress: data[offset+24 : offset+40], - NumOfPrefixes: numOfPrefixes, - Prefixes: prefixes, +// extractLSAInformation extracts all the LSA information +func extractLSAInformation(lstype, lsalength uint16, data []byte) (interface{}, error) { + if lsalength < 20 { + return nil, fmt.Errorf("Link State header length %v too short, %v required", lsalength, 20) + } + if len(data) < int(lsalength) { + return nil, fmt.Errorf("Link State header length %v too short, %v required", len(data), lsalength) + } + var content interface{} + switch lstype { + case RouterLSAtypeV2: + var routers []RouterV2 + links := binary.BigEndian.Uint16(data[22:24]) + content = RouterLSAV2{ + Flags: data[20], + Links: links, + Routers: routers, + } + case ASExternalLSAtypeV2: + content = ASExternalLSAV2{ + NetworkMask: binary.BigEndian.Uint32(data[20:24]), + ExternalBit: data[24] & 0x80, + Metric: binary.BigEndian.Uint32(data[24:28]) & 0x00FFFFFF, + ForwardingAddress: binary.BigEndian.Uint32(data[28:32]), + ExternalRouteTag: binary.BigEndian.Uint32(data[32:36]), + } + case RouterLSAtype: + var routers []Router + var j uint32 + for j = 24; j < uint32(lsalength); j += 16 { + router := Router{ + Type: uint8(data[j]), + Metric: binary.BigEndian.Uint16(data[j+2 : j+4]), + InterfaceID: binary.BigEndian.Uint32(data[j+4 : j+8]), + NeighborInterfaceID: binary.BigEndian.Uint32(data[j+8 : j+12]), + NeighborRouterID: binary.BigEndian.Uint32(data[j+12 : j+16]), } - case IntraAreaPrefixLSAtype: - var prefixes []Prefix - var prefixOffset uint32 = offset + 32 - var j uint16 - numOfPrefixes := binary.BigEndian.Uint16(data[offset+20 : offset+22]) - for j = 0; j < numOfPrefixes; j++ { - prefixLen := uint8(data[prefixOffset]) - prefix := Prefix{ - PrefixLength: prefixLen, - PrefixOptions: uint8(data[prefixOffset+1]), - Metric: binary.BigEndian.Uint16(data[prefixOffset+2 : prefixOffset+4]), - AddressPrefix: data[prefixOffset+4 : prefixOffset+4+uint32(prefixLen)/8], - } - prefixes = append(prefixes, prefix) - prefixOffset = prefixOffset + 4 + uint32(prefixLen) + routers = append(routers, router) + } + content = RouterLSA{ + Flags: uint8(data[20]), + Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF, + Routers: routers, + } + case NetworkLSAtype: + var routers []uint32 + var j uint32 + for j = 24; j < uint32(lsalength); j += 4 { + routers = append(routers, binary.BigEndian.Uint32(data[j:j+4])) + } + content = NetworkLSA{ + Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF, + AttachedRouter: routers, + } + case InterAreaPrefixLSAtype: + content = InterAreaPrefixLSA{ + Metric: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF, + PrefixLength: uint8(data[24]), + PrefixOptions: uint8(data[25]), + AddressPrefix: data[28:uint32(lsalength)], + } + case InterAreaRouterLSAtype: + content = InterAreaRouterLSA{ + Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF, + Metric: binary.BigEndian.Uint32(data[24:28]) & 0x00FFFFFF, + DestinationRouterID: binary.BigEndian.Uint32(data[28:32]), + } + case ASExternalLSAtype: + fallthrough + case NSSALSAtype: + + flags := uint8(data[20]) + prefixLen := uint8(data[24]) / 8 + var forwardingAddress []byte + if (flags & 0x02) == 0x02 { + forwardingAddress = data[28+uint32(prefixLen) : 28+uint32(prefixLen)+16] + } + content = ASExternalLSA{ + Flags: flags, + Metric: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF, + PrefixLength: prefixLen, + PrefixOptions: uint8(data[25]), + RefLSType: binary.BigEndian.Uint16(data[26:28]), + AddressPrefix: data[28 : 28+uint32(prefixLen)], + ForwardingAddress: forwardingAddress, + } + case LinkLSAtype: + var prefixes []Prefix + var prefixOffset uint32 = 44 + var j uint32 + numOfPrefixes := binary.BigEndian.Uint32(data[40:44]) + for j = 0; j < numOfPrefixes; j++ { + prefixLen := uint8(data[prefixOffset]) + prefix := Prefix{ + PrefixLength: prefixLen, + PrefixOptions: uint8(data[prefixOffset+1]), + AddressPrefix: data[prefixOffset+4 : prefixOffset+4+uint32(prefixLen)/8], } - content = IntraAreaPrefixLSA{ - NumOfPrefixes: numOfPrefixes, - RefLSType: binary.BigEndian.Uint16(data[offset+22 : offset+24]), - RefLinkStateID: binary.BigEndian.Uint32(data[offset+24 : offset+28]), - RefAdvRouter: binary.BigEndian.Uint32(data[offset+28 : offset+32]), - Prefixes: prefixes, + prefixes = append(prefixes, prefix) + prefixOffset = prefixOffset + 4 + uint32(prefixLen)/8 + } + content = LinkLSA{ + RtrPriority: uint8(data[20]), + Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF, + LinkLocalAddress: data[24:40], + NumOfPrefixes: numOfPrefixes, + Prefixes: prefixes, + } + case IntraAreaPrefixLSAtype: + var prefixes []Prefix + var prefixOffset uint32 = 32 + var j uint16 + numOfPrefixes := binary.BigEndian.Uint16(data[20:22]) + for j = 0; j < numOfPrefixes; j++ { + prefixLen := uint8(data[prefixOffset]) + prefix := Prefix{ + PrefixLength: prefixLen, + PrefixOptions: uint8(data[prefixOffset+1]), + Metric: binary.BigEndian.Uint16(data[prefixOffset+2 : prefixOffset+4]), + AddressPrefix: data[prefixOffset+4 : prefixOffset+4+uint32(prefixLen)/8], } - default: - return nil, fmt.Errorf("Unknown Link State type.") + prefixes = append(prefixes, prefix) + prefixOffset = prefixOffset + 4 + uint32(prefixLen) + } + content = IntraAreaPrefixLSA{ + NumOfPrefixes: numOfPrefixes, + RefLSType: binary.BigEndian.Uint16(data[22:24]), + RefLinkStateID: binary.BigEndian.Uint32(data[24:28]), + RefAdvRouter: binary.BigEndian.Uint32(data[28:32]), + Prefixes: prefixes, + } + default: + return nil, fmt.Errorf("Unknown Link State type.") + } + return content, nil +} + +// getLSAs parses the LSA information from the packet for OSPFv3 +func getLSAs(num uint32, data []byte) ([]LSA, error) { + var lsas []LSA + var i uint32 = 0 + var offset uint32 = 0 + for ; i < num; i++ { + var content interface{} + lstype := binary.BigEndian.Uint16(data[offset+2 : offset+4]) + lsalength := binary.BigEndian.Uint16(data[offset+18 : offset+20]) + + content, err := extractLSAInformation(lstype, lsalength, data[offset:]) + if err != nil { + return nil, fmt.Errorf("Could not extract Link State type.") } lsa := LSA{ LSAheader: LSAheader{ @@ -367,6 +460,84 @@ func (ospf *OSPFv2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) err ospf.AuType = binary.BigEndian.Uint16(data[14:16]) ospf.Authentication = binary.BigEndian.Uint64(data[16:24]) + switch ospf.Type { + case OSPFHello: + var neighbors []uint32 + for i := 44; uint16(i+4) <= ospf.PacketLength; i += 4 { + neighbors = append(neighbors, binary.BigEndian.Uint32(data[i:i+4])) + } + ospf.Content = HelloPkgV2{ + NetworkMask: binary.BigEndian.Uint32(data[24:28]), + HelloPkg: HelloPkg{ + HelloInterval: binary.BigEndian.Uint16(data[28:30]), + Options: uint32(data[30]), + RtrPriority: uint8(data[31]), + RouterDeadInterval: binary.BigEndian.Uint32(data[32:36]), + DesignatedRouterID: binary.BigEndian.Uint32(data[36:40]), + BackupDesignatedRouterID: binary.BigEndian.Uint32(data[40:44]), + NeighborID: neighbors, + }, + } + case OSPFDatabaseDescription: + var lsas []LSAheader + for i := 32; uint16(i+20) <= ospf.PacketLength; i += 20 { + lsa := LSAheader{ + LSAge: binary.BigEndian.Uint16(data[i : i+2]), + LSType: binary.BigEndian.Uint16(data[i+2 : i+4]), + LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]), + AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]), + LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]), + LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]), + Length: binary.BigEndian.Uint16(data[i+18 : i+20]), + } + lsas = append(lsas, lsa) + } + ospf.Content = DbDescPkg{ + InterfaceMTU: binary.BigEndian.Uint16(data[24:26]), + Options: uint32(data[26]), + Flags: uint16(data[27]), + DDSeqNumber: binary.BigEndian.Uint32(data[28:32]), + LSAinfo: lsas, + } + case OSPFLinkStateRequest: + var lsrs []LSReq + for i := 24; uint16(i+12) <= ospf.PacketLength; i += 12 { + lsr := LSReq{ + LSType: binary.BigEndian.Uint16(data[i+2 : i+4]), + LSID: binary.BigEndian.Uint32(data[i+4 : i+8]), + AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]), + } + lsrs = append(lsrs, lsr) + } + ospf.Content = lsrs + case OSPFLinkStateUpdate: + num := binary.BigEndian.Uint32(data[24:28]) + + lsas, err := getLSAsv2(num, data[28:]) + if err != nil { + return fmt.Errorf("Cannot parse Link State Update packet: %v", err) + } + ospf.Content = LSUpdate{ + NumOfLSAs: num, + LSAs: lsas, + } + case OSPFLinkStateAcknowledgment: + var lsas []LSAheader + for i := 24; uint16(i+20) <= ospf.PacketLength; i += 20 { + lsa := LSAheader{ + LSAge: binary.BigEndian.Uint16(data[i : i+2]), + LSOptions: data[i+2], + LSType: uint16(data[i+3]), + LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]), + AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]), + LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]), + LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]), + Length: binary.BigEndian.Uint16(data[i+18 : i+20]), + } + lsas = append(lsas, lsa) + } + ospf.Content = lsas + } return nil } @@ -397,7 +568,7 @@ func (ospf *OSPFv3) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) err RtrPriority: uint8(data[20]), Options: binary.BigEndian.Uint32(data[21:25]) >> 8, HelloInterval: binary.BigEndian.Uint16(data[24:26]), - RouterDeadInterval: binary.BigEndian.Uint16(data[26:28]), + RouterDeadInterval: uint32(binary.BigEndian.Uint16(data[26:28])), DesignatedRouterID: binary.BigEndian.Uint32(data[28:32]), BackupDesignatedRouterID: binary.BigEndian.Uint32(data[32:36]), NeighborID: neighbors, diff --git a/vendor/github.com/google/gopacket/layers/ospf_test.go b/vendor/github.com/google/gopacket/layers/ospf_test.go index 930bb4d064..766f62ef20 100644 --- a/vendor/github.com/google/gopacket/layers/ospf_test.go +++ b/vendor/github.com/google/gopacket/layers/ospf_test.go @@ -7,11 +7,73 @@ package layers import ( - "github.com/google/gopacket" "reflect" "testing" + + "github.com/google/gopacket" ) +// testPacketOSPF2Hello is the packet: +// 13:19:20.008765 IP 192.168.170.8 > 224.0.0.5: OSPFv2, Hello, length 44 +// 0x0000: 0100 5e00 0005 00e0 18b1 0cad 0800 45c0 ..^...........E. +// 0x0010: 0040 0812 0000 0159 65dd c0a8 aa08 e000 .@.....Ye....... +// 0x0020: 0005 0201 002c c0a8 aa08 0000 0001 273b .....,........'; +// 0x0030: 0000 0000 0000 0000 0000 ffff ff00 000a ................ +// 0x0040: 0201 0000 0028 c0a8 aa08 0000 0000 .....(........ +var testPacketOSPF2Hello = []byte{ + 0x01, 0x00, 0x5e, 0x00, 0x00, 0x05, 0x00, 0xe0, 0x18, 0xb1, 0x0c, 0xad, 0x08, 0x00, 0x45, 0xc0, + 0x00, 0x40, 0x08, 0x12, 0x00, 0x00, 0x01, 0x59, 0x65, 0xdd, 0xc0, 0xa8, 0xaa, 0x08, 0xe0, 0x00, + 0x00, 0x05, 0x02, 0x01, 0x00, 0x2c, 0xc0, 0xa8, 0xaa, 0x08, 0x00, 0x00, 0x00, 0x01, 0x27, 0x3b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0a, + 0x02, 0x01, 0x00, 0x00, 0x00, 0x28, 0xc0, 0xa8, 0xaa, 0x08, 0x00, 0x00, 0x00, 0x00, +} + +func TestPacketOSPF2Hello(t *testing.T) { + p := gopacket.NewPacket(testPacketOSPF2Hello, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeOSPF}, t) + + ospf := p.Layer(LayerTypeOSPF).(*OSPFv2) + if ospf.Version != 2 { + t.Fatal("Invalid OSPF version") + } + if got, ok := p.Layer(LayerTypeOSPF).(*OSPFv2); ok { + want := &OSPFv2{ + OSPF: OSPF{ + Version: 2, + Type: OSPFHello, + PacketLength: 44, + RouterID: 0xc0a8aa08, + AreaID: 1, + Checksum: 0x273b, + Content: HelloPkgV2{ + NetworkMask: 0xffffff00, + HelloPkg: HelloPkg{ + RtrPriority: 0x1, + Options: 0x2, + HelloInterval: 0xa, + RouterDeadInterval: 0x28, + DesignatedRouterID: 0xc0a8aa08, + BackupDesignatedRouterID: 0x0, + }, + }, + }, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("OSPF packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } else { + t.Error("No OSPF layer type found in packet") + } +} +func BenchmarkDecodePacketPacket5(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketOSPF2Hello, LinkTypeEthernet, gopacket.NoCopy) + } +} + // testPacketOSPF3Hello is the packet: // 14:43:11.663317 IP6 fe80::1 > ff02::5: OSPFv3, Hello, length 36 // 0x0000: 3333 0000 0005 c200 1ffa 0001 86dd 6e00 33............n. @@ -75,6 +137,57 @@ func BenchmarkDecodePacketPacket0(b *testing.B) { } } +// testPacketOSPF2DBDesc is the packet: +// 13:20:14.414477 IP 192.168.170.8 > 192.168.170.2: OSPFv2, Database Description, length 32 +// 0x0000: 0060 0881 7a70 00e0 18b1 0cad 0800 45c0 .`..zp........E. +// 0x0010: 0034 2be5 0000 0159 b770 c0a8 aa08 c0a8 .4+....Y.p...... +// 0x0020: aa02 0202 0020 c0a8 aa08 0000 0001 a052 ...............R +// 0x0030: 0000 0000 0000 0000 0000 05dc 0207 4177 ..............Aw +// 0x0040: a97e .~ +var testPacketOSPF2DBDesc = []byte{ + 0x00, 0x60, 0x08, 0x81, 0x7a, 0x70, 0x00, 0xe0, 0x18, 0xb1, 0x0c, 0xad, 0x08, 0x00, 0x45, 0xc0, + 0x00, 0x34, 0x2b, 0xe5, 0x00, 0x00, 0x01, 0x59, 0xb7, 0x70, 0xc0, 0xa8, 0xaa, 0x08, 0xc0, 0xa8, + 0xaa, 0x02, 0x02, 0x02, 0x00, 0x20, 0xc0, 0xa8, 0xaa, 0x08, 0x00, 0x00, 0x00, 0x01, 0xa0, 0x52, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xdc, 0x02, 0x07, 0x41, 0x77, + 0xa9, 0x7e, +} + +func TestPacketOSPF2DBDesc(t *testing.T) { + p := gopacket.NewPacket(testPacketOSPF2DBDesc, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeOSPF}, t) + if got, ok := p.Layer(LayerTypeOSPF).(*OSPFv2); ok { + want := &OSPFv2{ + OSPF: OSPF{ + Version: 2, + Type: OSPFDatabaseDescription, + PacketLength: 32, + RouterID: 0xc0a8aa08, + AreaID: 1, + Checksum: 0xa052, + Content: DbDescPkg{ + Options: 0x02, + InterfaceMTU: 1500, + Flags: 0x7, + DDSeqNumber: 1098361214, + }, + }, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("OSPF packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } else { + t.Error("No OSPF layer type found in packet") + } +} +func BenchmarkDecodePacketPacket6(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketOSPF2DBDesc, LinkTypeEthernet, gopacket.NoCopy) + } +} + // testPacketOSPF3DBDesc is the packet: // 14:43:51.657571 IP6 fe80::2 > fe80::1: OSPFv3, Database Description, length 28 // 0x0000: c200 1ffa 0001 c201 1ffa 0001 86dd 6e00 ..............n. @@ -130,6 +243,58 @@ func BenchmarkDecodePacketPacket1(b *testing.B) { } } +// testPacketOSPF2LSRequest is the packet: +// 13:20:14.418003 IP 192.168.170.2 > 192.168.170.8: OSPFv2, LS-Request, length 36 +// 0x0000: 00e0 18b1 0cad 0060 0881 7a70 0800 45c0 .......`..zp..E. +// 0x0010: 0038 88c6 0000 0159 5a8b c0a8 aa02 c0a8 .8.....YZ....... +// 0x0020: aa08 0203 0024 c0a8 aa03 0000 0001 bdc7 .....$.......... +// 0x0030: 0000 0000 0000 0000 0000 0000 0001 c0a8 ................ +// 0x0040: aa08 c0a8 aa08 ...... +var testPacketOSPF2LSRequest = []byte{ + 0x00, 0xe0, 0x18, 0xb1, 0x0c, 0xad, 0x00, 0x60, 0x08, 0x81, 0x7a, 0x70, 0x08, 0x00, 0x45, 0xc0, + 0x00, 0x38, 0x88, 0xc6, 0x00, 0x00, 0x01, 0x59, 0x5a, 0x8b, 0xc0, 0xa8, 0xaa, 0x02, 0xc0, 0xa8, + 0xaa, 0x08, 0x02, 0x03, 0x00, 0x24, 0xc0, 0xa8, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x01, 0xbd, 0xc7, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0xa8, + 0xaa, 0x08, 0xc0, 0xa8, 0xaa, 0x08, +} + +func TestPacketOSPF2LSRequest(t *testing.T) { + p := gopacket.NewPacket(testPacketOSPF2LSRequest, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeOSPF}, t) + if got, ok := p.Layer(LayerTypeOSPF).(*OSPFv2); ok { + want := &OSPFv2{ + OSPF: OSPF{ + Version: 2, + Type: OSPFLinkStateRequest, + PacketLength: 36, + RouterID: 0xc0a8aa03, + AreaID: 1, + Checksum: 0xbdc7, + Content: []LSReq{ + LSReq{ + LSType: 0x1, + LSID: 0xc0a8aa08, + AdvRouter: 0xc0a8aa08, + }, + }, + }, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("OSPF packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } else { + t.Error("No OSPF layer type found in packet") + } +} +func BenchmarkDecodePacketPacket7(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketOSPF2LSRequest, LinkTypeEthernet, gopacket.NoCopy) + } +} + // testPacketOSPF3LSRequest is the packet: // 14:43:51.673584 IP6 fe80::2 > fe80::1: OSPFv3, LS-Request, length 100 // 0x0000: c200 1ffa 0001 c201 1ffa 0001 86dd 6e00 ..............n. @@ -224,6 +389,218 @@ func BenchmarkDecodePacketPacket2(b *testing.B) { } } +// testPacketOSPF2LSUpdate is the packet: +// 13:20:14.420459 IP 192.168.170.2 > 224.0.0.6: OSPFv2, LS-Update, length 292 +// 0x0000: 0100 5e00 0006 0060 0881 7a70 0800 45c0 ..^....`..zp..E. +// 0x0010: 0138 3025 0000 0159 3cd7 c0a8 aa02 e000 .80%...Y<....... +// 0x0020: 0006 0204 0124 c0a8 aa03 0000 0001 366b .....$........6k +// 0x0030: 0000 0000 0000 0000 0000 0000 0007 0002 ................ +// 0x0040: 0201 c0a8 aa03 c0a8 aa03 8000 0001 3a9c ..............:. +// 0x0050: 0030 0200 0002 c0a8 aa00 ffff ff00 0300 .0.............. +// 0x0060: 000a c0a8 aa00 ffff ff00 0300 000a 0003 ................ +// 0x0070: 0205 50d4 1000 c0a8 aa02 8000 0001 2a49 ..P...........*I +// 0x0080: 0024 ffff ffff 8000 0014 0000 0000 0000 .$.............. +// 0x0090: 0000 0003 0205 9479 ab00 c0a8 aa02 8000 .......y........ +// 0x00a0: 0001 34a5 0024 ffff ff00 8000 0014 c0a8 ..4..$.......... +// 0x00b0: aa01 0000 0000 0003 0205 c082 7800 c0a8 ............x... +// 0x00c0: aa02 8000 0001 d319 0024 ffff ff00 8000 .........$...... +// 0x00d0: 0014 0000 0000 0000 0000 0003 0205 c0a8 ................ +// 0x00e0: 0000 c0a8 aa02 8000 0001 3708 0024 ffff ..........7..$.. +// 0x00f0: ff00 8000 0014 0000 0000 0000 0000 0003 ................ +// 0x0100: 0205 c0a8 0100 c0a8 aa02 8000 0001 2c12 ..............,. +// 0x0110: 0024 ffff ff00 8000 0014 0000 0000 0000 .$.............. +// 0x0120: 0000 0003 0205 c0a8 ac00 c0a8 aa02 8000 ................ +// 0x0130: 0001 3341 0024 ffff ff00 8000 0014 c0a8 ..3A.$.......... +// 0x0140: aa0a 0000 0000 ...... +var testPacketOSPF2LSUpdate = []byte{ + 0x01, 0x00, 0x5e, 0x00, 0x00, 0x06, 0x00, 0x60, 0x08, 0x81, 0x7a, 0x70, 0x08, 0x00, 0x45, 0xc0, + 0x01, 0x38, 0x30, 0x25, 0x00, 0x00, 0x01, 0x59, 0x3c, 0xd7, 0xc0, 0xa8, 0xaa, 0x02, 0xe0, 0x00, + 0x00, 0x06, 0x02, 0x04, 0x01, 0x24, 0xc0, 0xa8, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x01, 0x36, 0x6b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, + 0x02, 0x01, 0xc0, 0xa8, 0xaa, 0x03, 0xc0, 0xa8, 0xaa, 0x03, 0x80, 0x00, 0x00, 0x01, 0x3a, 0x9c, + 0x00, 0x30, 0x02, 0x00, 0x00, 0x02, 0xc0, 0xa8, 0xaa, 0x00, 0xff, 0xff, 0xff, 0x00, 0x03, 0x00, + 0x00, 0x0a, 0xc0, 0xa8, 0xaa, 0x00, 0xff, 0xff, 0xff, 0x00, 0x03, 0x00, 0x00, 0x0a, 0x00, 0x03, + 0x02, 0x05, 0x50, 0xd4, 0x10, 0x00, 0xc0, 0xa8, 0xaa, 0x02, 0x80, 0x00, 0x00, 0x01, 0x2a, 0x49, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x02, 0x05, 0x94, 0x79, 0xab, 0x00, 0xc0, 0xa8, 0xaa, 0x02, 0x80, 0x00, + 0x00, 0x01, 0x34, 0xa5, 0x00, 0x24, 0xff, 0xff, 0xff, 0x00, 0x80, 0x00, 0x00, 0x14, 0xc0, 0xa8, + 0xaa, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x05, 0xc0, 0x82, 0x78, 0x00, 0xc0, 0xa8, + 0xaa, 0x02, 0x80, 0x00, 0x00, 0x01, 0xd3, 0x19, 0x00, 0x24, 0xff, 0xff, 0xff, 0x00, 0x80, 0x00, + 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x05, 0xc0, 0xa8, + 0x00, 0x00, 0xc0, 0xa8, 0xaa, 0x02, 0x80, 0x00, 0x00, 0x01, 0x37, 0x08, 0x00, 0x24, 0xff, 0xff, + 0xff, 0x00, 0x80, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x02, 0x05, 0xc0, 0xa8, 0x01, 0x00, 0xc0, 0xa8, 0xaa, 0x02, 0x80, 0x00, 0x00, 0x01, 0x2c, 0x12, + 0x00, 0x24, 0xff, 0xff, 0xff, 0x00, 0x80, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x02, 0x05, 0xc0, 0xa8, 0xac, 0x00, 0xc0, 0xa8, 0xaa, 0x02, 0x80, 0x00, + 0x00, 0x01, 0x33, 0x41, 0x00, 0x24, 0xff, 0xff, 0xff, 0x00, 0x80, 0x00, 0x00, 0x14, 0xc0, 0xa8, + 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, +} + +func TestPacketOSPF2LSUpdate(t *testing.T) { + p := gopacket.NewPacket(testPacketOSPF2LSUpdate, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeOSPF}, t) + if got, ok := p.Layer(LayerTypeOSPF).(*OSPFv2); ok { + want := &OSPFv2{ + OSPF: OSPF{ + Version: 2, + Type: OSPFLinkStateUpdate, + PacketLength: 292, + RouterID: 0xc0a8aa03, + AreaID: 1, + Checksum: 0x366b, + Content: LSUpdate{ + NumOfLSAs: 7, + LSAs: []LSA{ + LSA{ + LSAheader: LSAheader{ + LSAge: 0x2, + LSType: 0x1, + LinkStateID: 0xc0a8aa03, + AdvRouter: 0xc0a8aa03, + LSSeqNumber: 0x80000001, + LSChecksum: 0x3a9c, + Length: 0x30, + LSOptions: 0x2, + }, + Content: RouterLSAV2{ + Flags: 0x2, + Links: 0x2, + }, + }, + LSA{ + LSAheader: LSAheader{ + LSAge: 0x3, + LSType: 0x5, + LinkStateID: 0x50d41000, + AdvRouter: 0xc0a8aa02, + LSSeqNumber: 0x80000001, + LSChecksum: 0x2a49, + Length: 0x24, + LSOptions: 0x2, + }, + Content: ASExternalLSAV2{ + NetworkMask: 0xffffffff, + ExternalBit: 0x80, + Metric: 0x14, + ForwardingAddress: 0x0, + ExternalRouteTag: 0x0, + }, + }, + LSA{ + LSAheader: LSAheader{ + LSAge: 0x3, + LSType: 0x5, + LinkStateID: 0x9479ab00, + AdvRouter: 0xc0a8aa02, + LSSeqNumber: 0x80000001, + LSChecksum: 0x34a5, + Length: 0x24, + LSOptions: 0x2, + }, + Content: ASExternalLSAV2{ + NetworkMask: 0xffffff00, + ExternalBit: 0x80, + Metric: 0x14, + ForwardingAddress: 0xc0a8aa01, + ExternalRouteTag: 0x0, + }, + }, + LSA{ + LSAheader: LSAheader{ + LSAge: 0x3, + LSType: 0x5, + LinkStateID: 0xc0827800, + AdvRouter: 0xc0a8aa02, + LSSeqNumber: 0x80000001, + LSChecksum: 0xd319, + Length: 0x24, + LSOptions: 0x2, + }, + Content: ASExternalLSAV2{ + NetworkMask: 0xffffff00, + ExternalBit: 0x80, + Metric: 0x14, + ForwardingAddress: 0x0, + ExternalRouteTag: 0x0, + }, + }, + LSA{ + LSAheader: LSAheader{ + LSAge: 0x3, + LSType: 0x5, + LinkStateID: 0xc0a80000, + AdvRouter: 0xc0a8aa02, + LSSeqNumber: 0x80000001, + LSChecksum: 0x3708, + Length: 0x24, + LSOptions: 0x2, + }, + Content: ASExternalLSAV2{ + NetworkMask: 0xffffff00, + ExternalBit: 0x80, + Metric: 0x14, + ForwardingAddress: 0x0, + ExternalRouteTag: 0x0, + }, + }, + LSA{ + LSAheader: LSAheader{ + LSAge: 0x3, + LSType: 0x5, + LinkStateID: 0xc0a80100, + AdvRouter: 0xc0a8aa02, + LSSeqNumber: 0x80000001, + LSChecksum: 0x2c12, + Length: 0x24, + LSOptions: 0x2, + }, + Content: ASExternalLSAV2{ + NetworkMask: 0xffffff00, + ExternalBit: 0x80, + Metric: 0x14, + ForwardingAddress: 0x0, + ExternalRouteTag: 0x0, + }, + }, + LSA{ + LSAheader: LSAheader{ + LSAge: 0x3, + LSType: 0x5, + LinkStateID: 0xc0a8ac00, + AdvRouter: 0xc0a8aa02, + LSSeqNumber: 0x80000001, + LSChecksum: 0x3341, + Length: 0x24, + LSOptions: 0x2, + }, + Content: ASExternalLSAV2{ + NetworkMask: 0xffffff00, + ExternalBit: 0x80, + Metric: 0x14, + ForwardingAddress: 0xc0a8aa0a, + ExternalRouteTag: 0x0, + }, + }, + }, + }, + }, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("OSPF packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } else { + t.Error("No OSPF layer type found in packet") + } +} +func BenchmarkDecodePacketPacket8(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketOSPF2LSUpdate, LinkTypeEthernet, gopacket.NoCopy) + } +} + // testPacketOSPF3LSUpdate is the packet: // 14:43:51.681554 IP6 fe80::1 > fe80::2: OSPFv3, LS-Update, length 288 // 0x0000: c201 1ffa 0001 c200 1ffa 0001 86dd 6e00 ..............n. @@ -441,6 +818,63 @@ func BenchmarkDecodePacketPacket3(b *testing.B) { } } +// testPacketOSPF2LSAck is the packet: +// 13:20:20.858322 IP 192.168.170.8 > 192.168.170.2: OSPFv2, LS-Ack, length 44 +// 0x0000: 0060 0881 7a70 00e0 18b1 0cad 0800 45c0 .`..zp........E. +// 0x0010: 0040 2bea 0000 0159 b75f c0a8 aa08 c0a8 .@+....Y._...... +// 0x0020: aa02 0205 002c c0a8 aa08 0000 0001 e2f4 .....,.......... +// 0x0030: 0000 0000 0000 0000 0000 0e10 0201 c0a8 ................ +// 0x0040: aa02 c0a8 aa02 8000 0001 4a8e 0030 ..........J..0 +var testPacketOSPF2LSAck = []byte{ + 0x00, 0x60, 0x08, 0x81, 0x7a, 0x70, 0x00, 0xe0, 0x18, 0xb1, 0x0c, 0xad, 0x08, 0x00, 0x45, 0xc0, + 0x00, 0x40, 0x2b, 0xea, 0x00, 0x00, 0x01, 0x59, 0xb7, 0x5f, 0xc0, 0xa8, 0xaa, 0x08, 0xc0, 0xa8, + 0xaa, 0x02, 0x02, 0x05, 0x00, 0x2c, 0xc0, 0xa8, 0xaa, 0x08, 0x00, 0x00, 0x00, 0x01, 0xe2, 0xf4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x02, 0x01, 0xc0, 0xa8, + 0xaa, 0x02, 0xc0, 0xa8, 0xaa, 0x02, 0x80, 0x00, 0x00, 0x01, 0x4a, 0x8e, 0x00, 0x30, +} + +func TestPacketOSPF2LSAck(t *testing.T) { + p := gopacket.NewPacket(testPacketOSPF2LSAck, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeOSPF}, t) + if got, ok := p.Layer(LayerTypeOSPF).(*OSPFv2); ok { + want := &OSPFv2{ + OSPF: OSPF{ + Version: 2, + Type: OSPFLinkStateAcknowledgment, + PacketLength: 44, + RouterID: 0xc0a8aa08, + AreaID: 1, + Checksum: 0xe2f4, + Content: []LSAheader{ + LSAheader{ + LSAge: 0xe10, + LSType: 0x1, + LinkStateID: 0xc0a8aa02, + AdvRouter: 0xc0a8aa02, + LSSeqNumber: 0x80000001, + LSChecksum: 0x4a8e, + Length: 0x30, + LSOptions: 0x2, + }, + }, + }, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("OSPF packet processing failed:\ngot :\n%#v\n\nwant :\n%#v\n\n", got, want) + } + } else { + t.Error("No OSPF layer type found in packet") + } +} +func BenchmarkDecodePacketPacket9(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(testPacketOSPF3LSAck, LinkTypeEthernet, gopacket.NoCopy) + } +} + // testPacketOSPF3LSAck is the packet: // 14:43:54.185384 IP6 fe80::1 > ff02::5: OSPFv3, LS-Ack, length 136 // 0x0000: 3333 0000 0005 c200 1ffa 0001 86dd 6e00 33............n. @@ -552,6 +986,27 @@ func TestPacketOSPF3LSAck(t *testing.T) { t.Error("No OSPF layer type found in packet") } } + +var testPacketOSPFInvalidLSA = []byte{ + 0x5c, 0xfa, 0x00, 0x00, 0xfa, 0x6c, 0xbd, 0xe4, 0x19, 0x72, 0x1d, 0x1f, + 0x08, 0x00, 0x45, 0x00, 0x00, 0xad, 0x00, 0x00, 0x40, 0x00, 0x40, 0x59, + 0x6e, 0xef, 0x6b, 0x96, 0x61, 0x11, 0xb4, 0x96, 0xc0, 0xa8, 0x02, 0x04, + 0x00, 0xa2, 0x80, 0x00, 0x01, 0x1f, 0x08, 0x00, 0x45, 0x00, 0x6f, 0x76, + 0x65, 0x72, 0x66, 0x6c, 0x7f, 0xff, 0x12, 0x12, 0x00, 0x5a, 0xf6, 0x73, + 0xa2, 0xba, 0x81, 0x90, 0x00, 0x01, 0x40, 0x6f, 0x77, 0x20, 0x6f, 0x6e, + 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x00, 0x00, 0x00, 0x01, + 0x96, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x00, 0x6e, 0x00, 0x6f, + 0x77, +} + +func TestPacketOSPFInvalidLSA(t *testing.T) { + p := gopacket.NewPacket(testPacketOSPFInvalidLSA, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() == nil { + t.Error("Bad packet decoded successfully") + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, gopacket.LayerTypeDecodeFailure}, t) +} + func BenchmarkDecodePacketPacket4(b *testing.B) { for i := 0; i < b.N; i++ { gopacket.NewPacket(testPacketOSPF3LSAck, LinkTypeEthernet, gopacket.NoCopy) diff --git a/vendor/github.com/google/gopacket/layers/ports.go b/vendor/github.com/google/gopacket/layers/ports.go index 431358c12d..705fd1dbaf 100644 --- a/vendor/github.com/google/gopacket/layers/ports.go +++ b/vendor/github.com/google/gopacket/layers/ports.go @@ -60,7 +60,17 @@ func (a TCPPort) LayerType() gopacket.LayerType { } var tcpPortLayerType = [65536]gopacket.LayerType{ - 53: LayerTypeDNS, + 53: LayerTypeDNS, + 443: LayerTypeTLS, // https + 502: LayerTypeModbusTCP, // modbustcp + 636: LayerTypeTLS, // ldaps + 989: LayerTypeTLS, // ftps-data + 990: LayerTypeTLS, // ftps + 992: LayerTypeTLS, // telnets + 993: LayerTypeTLS, // imaps + 994: LayerTypeTLS, // ircs + 995: LayerTypeTLS, // pop3s + 5061: LayerTypeTLS, // ips } // RegisterTCPPortLayerType creates a new mapping between a TCPPort @@ -98,9 +108,13 @@ var udpPortLayerType = [65536]gopacket.LayerType{ 4789: LayerTypeVXLAN, 67: LayerTypeDHCPv4, 68: LayerTypeDHCPv4, + 546: LayerTypeDHCPv6, + 547: LayerTypeDHCPv6, + 5060: LayerTypeSIP, 6343: LayerTypeSFlow, 6081: LayerTypeGeneve, 3784: LayerTypeBFD, + 2152: LayerTypeGTPv1U, } // RegisterUDPPortLayerType creates a new mapping between a UDPPort diff --git a/vendor/github.com/google/gopacket/layers/ppp.go b/vendor/github.com/google/gopacket/layers/ppp.go index 1d2e7b8c43..e534d698cb 100644 --- a/vendor/github.com/google/gopacket/layers/ppp.go +++ b/vendor/github.com/google/gopacket/layers/ppp.go @@ -15,7 +15,8 @@ import ( // PPP is the layer for PPP encapsulation headers. type PPP struct { BaseLayer - PPPType PPPType + PPPType PPPType + HasPPTPHeader bool } // PPPEndpoint is a singleton endpoint for PPP. Since there is no actual @@ -36,17 +37,22 @@ func (p *PPP) LinkFlow() gopacket.Flow { return PPPFlow } func decodePPP(data []byte, p gopacket.PacketBuilder) error { ppp := &PPP{} - if data[0]&0x1 == 0 { - if data[1]&0x1 == 0 { + offset := 0 + if data[0] == 0xff && data[1] == 0x03 { + offset = 2 + ppp.HasPPTPHeader = true + } + if data[offset]&0x1 == 0 { + if data[offset+1]&0x1 == 0 { return errors.New("PPP has invalid type") } - ppp.PPPType = PPPType(binary.BigEndian.Uint16(data[:2])) - ppp.Contents = data[:2] - ppp.Payload = data[2:] + ppp.PPPType = PPPType(binary.BigEndian.Uint16(data[offset : offset+2])) + ppp.Contents = data[offset : offset+2] + ppp.Payload = data[offset+2:] } else { - ppp.PPPType = PPPType(data[0]) - ppp.Contents = data[:1] - ppp.Payload = data[1:] + ppp.PPPType = PPPType(data[offset]) + ppp.Contents = data[offset : offset+1] + ppp.Payload = data[offset+1:] } p.AddLayer(ppp) p.SetLinkLayer(ppp) @@ -70,5 +76,13 @@ func (p *PPP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOpt } bytes[0] = uint8(p.PPPType) } + if p.HasPPTPHeader { + bytes, err := b.PrependBytes(2) + if err != nil { + return err + } + bytes[0] = 0xff + bytes[1] = 0x03 + } return nil } diff --git a/vendor/github.com/google/gopacket/layers/radiotap.go b/vendor/github.com/google/gopacket/layers/radiotap.go index 4304e75310..17c61335e6 100644 --- a/vendor/github.com/google/gopacket/layers/radiotap.go +++ b/vendor/github.com/google/gopacket/layers/radiotap.go @@ -859,12 +859,36 @@ func (m *RadioTap) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) erro } payload := data[m.Length:] - if !m.Flags.FCS() { // Dot11.DecodeFromBytes() expects FCS present - fcs := make([]byte, 4) + + // Remove non standard padding used by some Wi-Fi drivers + if m.Flags.Datapad() && + payload[0]&0xC == 0x8 { //&& // Data frame + headlen := 24 + if payload[0]&0x8C == 0x88 { // QoS + headlen += 2 + } + if payload[1]&0x3 == 0x3 { // 4 addresses + headlen += 2 + } + if headlen%4 == 2 { + payload = append(payload[:headlen], payload[headlen+2:len(payload)]...) + } + } + + if !m.Flags.FCS() { + // Dot11.DecodeFromBytes() expects FCS present and performs a hard chop on the checksum + // If a user is handing in subslices or packets from a buffered stream, the capacity of the slice + // may extend beyond the len, rather than expecting callers to enforce cap==len on every packet + // we take the hit in this one case and do a reallocation. If the user DOES enforce cap==len + // then the reallocation will happen anyway on the append. This is requried because the append + // write to the memory directly after the payload if there is sufficient capacity, which callers + // may not expect. + reallocPayload := make([]byte, len(payload)+4) + copy(reallocPayload[0:len(payload)], payload) h := crc32.NewIEEE() h.Write(payload) - binary.LittleEndian.PutUint32(fcs, h.Sum32()) - payload = append(payload, fcs...) + binary.LittleEndian.PutUint32(reallocPayload[len(payload):], h.Sum32()) + payload = reallocPayload } m.BaseLayer = BaseLayer{Contents: data[:m.Length], Payload: payload} diff --git a/vendor/github.com/google/gopacket/layers/sflow.go b/vendor/github.com/google/gopacket/layers/sflow.go index 55ce31e779..c56fe89d21 100644 --- a/vendor/github.com/google/gopacket/layers/sflow.go +++ b/vendor/github.com/google/gopacket/layers/sflow.go @@ -486,139 +486,148 @@ func decodeFlowSample(data *[]byte, expanded bool) (SFlowFlowSample, error) { for i := uint32(0); i < s.RecordCount; i++ { rdf := SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - _, flowRecordType := rdf.decode() - - switch flowRecordType { - case SFlowTypeRawPacketFlow: - if record, err := decodeRawPacketFlowRecord(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedUserFlow: - if record, err := decodeExtendedUserFlow(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedUrlFlow: - if record, err := decodeExtendedURLRecord(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedSwitchFlow: - if record, err := decodeExtendedSwitchFlowRecord(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedRouterFlow: - if record, err := decodeExtendedRouterFlowRecord(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedGatewayFlow: - if record, err := decodeExtendedGatewayFlowRecord(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeEthernetFrameFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeEthernetFrameFlow") - case SFlowTypeIpv4Flow: - if record, err := decodeSFlowIpv4Record(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeIpv6Flow: - if record, err := decodeSFlowIpv6Record(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err + enterpriseID, flowRecordType := rdf.decode() + + // Try to decode when EnterpriseID is 0 signaling + // default sflow structs are used according specification + // Unexpected behavior detected for e.g. with pmacct + if enterpriseID == 0 { + switch flowRecordType { + case SFlowTypeRawPacketFlow: + if record, err := decodeRawPacketFlowRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedUserFlow: + if record, err := decodeExtendedUserFlow(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedUrlFlow: + if record, err := decodeExtendedURLRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedSwitchFlow: + if record, err := decodeExtendedSwitchFlowRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedRouterFlow: + if record, err := decodeExtendedRouterFlowRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedGatewayFlow: + if record, err := decodeExtendedGatewayFlowRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeEthernetFrameFlow: + if record, err := decodeEthernetFrameFlowRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeIpv4Flow: + if record, err := decodeSFlowIpv4Record(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeIpv6Flow: + if record, err := decodeSFlowIpv6Record(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedMlpsFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeExtendedMlpsFlow") + case SFlowTypeExtendedNatFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeExtendedNatFlow") + case SFlowTypeExtendedMlpsTunnelFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeExtendedMlpsTunnelFlow") + case SFlowTypeExtendedMlpsVcFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeExtendedMlpsVcFlow") + case SFlowTypeExtendedMlpsFecFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeExtendedMlpsFecFlow") + case SFlowTypeExtendedMlpsLvpFecFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeExtendedMlpsLvpFecFlow") + case SFlowTypeExtendedVlanFlow: + // TODO + skipRecord(data) + return s, errors.New("skipping TypeExtendedVlanFlow") + case SFlowTypeExtendedIpv4TunnelEgressFlow: + if record, err := decodeExtendedIpv4TunnelEgress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedIpv4TunnelIngressFlow: + if record, err := decodeExtendedIpv4TunnelIngress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedIpv6TunnelEgressFlow: + if record, err := decodeExtendedIpv6TunnelEgress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedIpv6TunnelIngressFlow: + if record, err := decodeExtendedIpv6TunnelIngress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedDecapsulateEgressFlow: + if record, err := decodeExtendedDecapsulateEgress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedDecapsulateIngressFlow: + if record, err := decodeExtendedDecapsulateIngress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedVniEgressFlow: + if record, err := decodeExtendedVniEgress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedVniIngressFlow: + if record, err := decodeExtendedVniIngress(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + default: + return s, fmt.Errorf("Unsupported flow record type: %d", flowRecordType) } - case SFlowTypeExtendedMlpsFlow: - // TODO + } else { skipRecord(data) - return s, errors.New("skipping TypeExtendedMlpsFlow") - case SFlowTypeExtendedNatFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeExtendedNatFlow") - case SFlowTypeExtendedMlpsTunnelFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeExtendedMlpsTunnelFlow") - case SFlowTypeExtendedMlpsVcFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeExtendedMlpsVcFlow") - case SFlowTypeExtendedMlpsFecFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeExtendedMlpsFecFlow") - case SFlowTypeExtendedMlpsLvpFecFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeExtendedMlpsLvpFecFlow") - case SFlowTypeExtendedVlanFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeExtendedVlanFlow") - case SFlowTypeExtendedIpv4TunnelEgressFlow: - if record, err := decodeExtendedIpv4TunnelEgress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedIpv4TunnelIngressFlow: - if record, err := decodeExtendedIpv4TunnelIngress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedIpv6TunnelEgressFlow: - if record, err := decodeExtendedIpv6TunnelEgress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedIpv6TunnelIngressFlow: - if record, err := decodeExtendedIpv6TunnelIngress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedDecapsulateEgressFlow: - if record, err := decodeExtendedDecapsulateEgress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedDecapsulateIngressFlow: - if record, err := decodeExtendedDecapsulateIngress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedVniEgressFlow: - if record, err := decodeExtendedVniEgress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedVniIngressFlow: - if record, err := decodeExtendedVniIngress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - default: - return s, fmt.Errorf("Unsupported flow record type: %d", flowRecordType) } } return s, nil @@ -684,7 +693,12 @@ const ( SFlowTypeTokenRingInterfaceCounters SFlowCounterRecordType = 3 SFlowType100BaseVGInterfaceCounters SFlowCounterRecordType = 4 SFlowTypeVLANCounters SFlowCounterRecordType = 5 + SFlowTypeLACPCounters SFlowCounterRecordType = 7 SFlowTypeProcessorCounters SFlowCounterRecordType = 1001 + SFlowTypeOpenflowPortCounters SFlowCounterRecordType = 1004 + SFlowTypePORTNAMECounters SFlowCounterRecordType = 1005 + SFLowTypeAPPRESOURCESCounters SFlowCounterRecordType = 2203 + SFlowTypeOVSDPCounters SFlowCounterRecordType = 2207 ) func (cr SFlowCounterRecordType) String() string { @@ -699,8 +713,18 @@ func (cr SFlowCounterRecordType) String() string { return "100BaseVG Interface Counters" case SFlowTypeVLANCounters: return "VLAN Counters" + case SFlowTypeLACPCounters: + return "LACP Counters" case SFlowTypeProcessorCounters: return "Processor Counters" + case SFlowTypeOpenflowPortCounters: + return "Openflow Port Counters" + case SFlowTypePORTNAMECounters: + return "PORT NAME Counters" + case SFLowTypeAPPRESOURCESCounters: + return "App Resources Counters" + case SFlowTypeOVSDPCounters: + return "OVSDP Counters" default: return "" @@ -749,14 +773,47 @@ func decodeCounterSample(data *[]byte, expanded bool) (SFlowCounterSample, error skipRecord(data) return s, errors.New("skipping Type100BaseVGInterfaceCounters") case SFlowTypeVLANCounters: - skipRecord(data) - return s, errors.New("skipping TypeVLANCounters") + if record, err := decodeVLANCounters(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeLACPCounters: + if record, err := decodeLACPCounters(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } case SFlowTypeProcessorCounters: if record, err := decodeProcessorCounters(data); err == nil { s.Records = append(s.Records, record) } else { return s, err } + case SFlowTypeOpenflowPortCounters: + if record, err := decodeOpenflowportCounters(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypePORTNAMECounters: + if record, err := decodePortnameCounters(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFLowTypeAPPRESOURCESCounters: + if record, err := decodeAppresourcesCounters(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeOVSDPCounters: + if record, err := decodeOVSDPCounters(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } default: return s, fmt.Errorf("Invalid counter record type: %d", counterRecordType) } @@ -1970,9 +2027,18 @@ func (bcr SFlowBaseCounterRecord) GetType() SFlowCounterRecordType { return SFlowType100BaseVGInterfaceCounters case SFlowTypeVLANCounters: return SFlowTypeVLANCounters + case SFlowTypeLACPCounters: + return SFlowTypeLACPCounters case SFlowTypeProcessorCounters: return SFlowTypeProcessorCounters - + case SFlowTypeOpenflowPortCounters: + return SFlowTypeOpenflowPortCounters + case SFlowTypePORTNAMECounters: + return SFlowTypePORTNAMECounters + case SFLowTypeAPPRESOURCESCounters: + return SFLowTypeAPPRESOURCESCounters + case SFlowTypeOVSDPCounters: + return SFlowTypeOVSDPCounters } unrecognized := fmt.Sprint("Unrecognized counter record type:", bcr.Format) panic(unrecognized) @@ -2135,6 +2201,83 @@ func decodeEthernetCounters(data *[]byte) (SFlowEthernetCounters, error) { return ec, nil } +// VLAN Counter + +type SFlowVLANCounters struct { + SFlowBaseCounterRecord + VlanID uint32 + Octets uint64 + UcastPkts uint32 + MulticastPkts uint32 + BroadcastPkts uint32 + Discards uint32 +} + +func decodeVLANCounters(data *[]byte) (SFlowVLANCounters, error) { + vc := SFlowVLANCounters{} + var cdf SFlowCounterDataFormat + + *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) + vc.EnterpriseID, vc.Format = cdf.decode() + vc.EnterpriseID, vc.Format = cdf.decode() + *data, vc.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, vc.VlanID = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, vc.Octets = (*data)[8:], binary.BigEndian.Uint64((*data)[:8]) + *data, vc.UcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, vc.MulticastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, vc.BroadcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, vc.Discards = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + return vc, nil +} + +//SFLLACPportState : SFlow LACP Port State (All(4) - 32 bit) +type SFLLACPPortState struct { + PortStateAll uint32 +} + +//LACPcounters : LACP SFlow Counters ( 64 Bytes ) +type SFlowLACPCounters struct { + SFlowBaseCounterRecord + ActorSystemID net.HardwareAddr + PartnerSystemID net.HardwareAddr + AttachedAggID uint32 + LacpPortState SFLLACPPortState + LACPDUsRx uint32 + MarkerPDUsRx uint32 + MarkerResponsePDUsRx uint32 + UnknownRx uint32 + IllegalRx uint32 + LACPDUsTx uint32 + MarkerPDUsTx uint32 + MarkerResponsePDUsTx uint32 +} + +func decodeLACPCounters(data *[]byte) (SFlowLACPCounters, error) { + la := SFlowLACPCounters{} + var cdf SFlowCounterDataFormat + + *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) + la.EnterpriseID, la.Format = cdf.decode() + *data, la.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, la.ActorSystemID = (*data)[6:], (*data)[:6] + *data = (*data)[2:] // remove padding + *data, la.PartnerSystemID = (*data)[6:], (*data)[:6] + *data = (*data)[2:] //remove padding + *data, la.AttachedAggID = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, la.LacpPortState.PortStateAll = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, la.LACPDUsRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, la.MarkerPDUsRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, la.MarkerResponsePDUsRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, la.UnknownRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, la.IllegalRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, la.LACPDUsTx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, la.MarkerPDUsTx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, la.MarkerResponsePDUsTx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + return la, nil + +} + // ************************************************** // Processor Counter Record // ************************************************** @@ -2185,3 +2328,153 @@ func decodeProcessorCounters(data *[]byte) (SFlowProcessorCounters, error) { return pc, nil } + +// SFlowEthernetFrameFlowRecord give additional information +// about the sampled packet if it's available. +// An agent may or may not provide this information. +type SFlowEthernetFrameFlowRecord struct { + SFlowBaseFlowRecord + FrameLength uint32 + SrcMac net.HardwareAddr + DstMac net.HardwareAddr + Type uint32 +} + +// Ethernet frame flow records have the following structure: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Source Mac Address | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Destination Mac Address | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Ethernet Packet Type | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +func decodeEthernetFrameFlowRecord(data *[]byte) (SFlowEthernetFrameFlowRecord, error) { + es := SFlowEthernetFrameFlowRecord{} + var fdf SFlowFlowDataFormat + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + es.EnterpriseID, es.Format = fdf.decode() + *data, es.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + *data, es.FrameLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, es.SrcMac = (*data)[8:], net.HardwareAddr((*data)[:6]) + *data, es.DstMac = (*data)[8:], net.HardwareAddr((*data)[:6]) + *data, es.Type = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + return es, nil +} + +//SFlowOpenflowPortCounters : OVS-Sflow OpenFlow Port Counter ( 20 Bytes ) +type SFlowOpenflowPortCounters struct { + SFlowBaseCounterRecord + DatapathID uint64 + PortNo uint32 +} + +func decodeOpenflowportCounters(data *[]byte) (SFlowOpenflowPortCounters, error) { + ofp := SFlowOpenflowPortCounters{} + var cdf SFlowCounterDataFormat + + *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) + ofp.EnterpriseID, ofp.Format = cdf.decode() + *data, ofp.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ofp.DatapathID = (*data)[8:], binary.BigEndian.Uint64((*data)[:8]) + *data, ofp.PortNo = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + return ofp, nil +} + +//SFlowAppresourcesCounters : OVS_Sflow App Resources Counter ( 48 Bytes ) +type SFlowAppresourcesCounters struct { + SFlowBaseCounterRecord + UserTime uint32 + SystemTime uint32 + MemUsed uint64 + MemMax uint64 + FdOpen uint32 + FdMax uint32 + ConnOpen uint32 + ConnMax uint32 +} + +func decodeAppresourcesCounters(data *[]byte) (SFlowAppresourcesCounters, error) { + app := SFlowAppresourcesCounters{} + var cdf SFlowCounterDataFormat + + *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) + app.EnterpriseID, app.Format = cdf.decode() + *data, app.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, app.UserTime = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, app.SystemTime = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, app.MemUsed = (*data)[8:], binary.BigEndian.Uint64((*data)[:8]) + *data, app.MemMax = (*data)[8:], binary.BigEndian.Uint64((*data)[:8]) + *data, app.FdOpen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, app.FdMax = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, app.ConnOpen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, app.ConnMax = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + return app, nil +} + +//SFlowOVSDPCounters : OVS-Sflow DataPath Counter ( 32 Bytes ) +type SFlowOVSDPCounters struct { + SFlowBaseCounterRecord + NHit uint32 + NMissed uint32 + NLost uint32 + NMaskHit uint32 + NFlows uint32 + NMasks uint32 +} + +func decodeOVSDPCounters(data *[]byte) (SFlowOVSDPCounters, error) { + dp := SFlowOVSDPCounters{} + var cdf SFlowCounterDataFormat + + *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) + dp.EnterpriseID, dp.Format = cdf.decode() + *data, dp.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, dp.NHit = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, dp.NMissed = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, dp.NLost = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, dp.NMaskHit = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, dp.NFlows = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, dp.NMasks = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + return dp, nil +} + +//SFlowPORTNAME : OVS-Sflow PORTNAME Counter Sampletype ( 20 Bytes ) +type SFlowPORTNAME struct { + SFlowBaseCounterRecord + Len uint32 + Str string +} + +func decodeString(data *[]byte) (len uint32, str string) { + *data, len = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + str = string((*data)[:len]) + if (len % 4) != 0 { + len += 4 - len%4 + } + *data = (*data)[len:] + return +} + +func decodePortnameCounters(data *[]byte) (SFlowPORTNAME, error) { + pn := SFlowPORTNAME{} + var cdf SFlowCounterDataFormat + + *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) + pn.EnterpriseID, pn.Format = cdf.decode() + *data, pn.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + pn.Len, pn.Str = decodeString(data) + + return pn, nil +} diff --git a/vendor/github.com/google/gopacket/layers/sflow_test.go b/vendor/github.com/google/gopacket/layers/sflow_test.go index ca0f2abde8..20e5aefbfa 100644 --- a/vendor/github.com/google/gopacket/layers/sflow_test.go +++ b/vendor/github.com/google/gopacket/layers/sflow_test.go @@ -6,10 +6,11 @@ package layers import ( - "github.com/google/gopacket" "net" "reflect" "testing" + + "github.com/google/gopacket" ) // Test packet collected from live network. See the test below for contents @@ -279,6 +280,130 @@ var SFlowTestPacket8 = []byte{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, } +// Counter Sample - port name +var SFlowTestPacket9 = []byte{ + 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x01, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xb3, 0x6d, + 0x0e, 0x04, 0xd2, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xd8, + 0x00, 0x00, 0x5b, 0xe0, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x62, 0xd3, 0x3c, 0xe7, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0xed, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0e, 0x74, 0x61, 0x70, 0x64, 0x39, 0x38, 0x31, 0x35, + 0x34, 0x66, 0x32, 0x2d, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x58, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x54, 0x0b, 0xe4, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x49, + 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x0b, + 0x00, 0x00, 0x01, 0xd2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +// Vlan counter samples +var SFlowTestPacket10 = []byte{ + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, + 0x0a, 0x14, 0x04, 0x00, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x01, 0x78, 0xe0, 0x73, 0x03, 0x48, 0x78, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x34, 0x00, 0x01, 0x78, 0xe0, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x8c, 0x2c, 0xcc, + 0x00, 0x00, 0x96, 0x83, 0x00, 0x02, 0x90, 0x16, + 0x00, 0x01, 0xf6, 0x73, 0x00, 0x00, 0x00, 0x00, +} + +//LACP counter samples +var SFlowTestPacket11 = []byte{ + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, + 0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0xe5, 0x05, 0xae, 0x16, 0x18, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x0d, 0x30, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x38, + 0x7e, 0x60, 0x69, 0x73, 0x8f, 0x42, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x05, 0x75, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x95, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +} + +// Test packet collected from live network. - contains ethernet frame flow record +var SFlowEthernetFramePacket = []byte{ + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0xb9, 0x78, 0x16, 0xf6, 0x00, 0x01, 0x86, 0xa0, + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x32, 0x97, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0xe8, + 0x00, 0x01, 0xe8, 0x48, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x25, 0x90, 0xa2, 0x53, 0x58, 0x00, 0x00, 0x00, 0x1d, 0xb5, 0xa2, 0x5f, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x7e, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x01, 0xec, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x10, 0x00, 0x25, 0x90, 0xa2, 0x53, 0x58, 0x00, 0x00, + 0x7a, 0x7d, 0x48, 0x51, 0xaa, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0xe8, + 0x00, 0x01, 0xf0, 0x18, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x25, 0x90, 0xa2, 0x53, 0x58, 0x00, 0x00, 0x7a, 0x7d, 0x48, 0x51, 0xaa, 0xc7, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x10, 0x00, 0x25, 0x90, 0xa2, 0x53, 0x58, 0x00, 0x00, + 0x7a, 0x7d, 0x48, 0x51, 0xaa, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0xe8, + 0x00, 0x01, 0xf7, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x25, 0x90, 0xa2, 0x53, 0x58, 0x00, 0x00, 0x9e, 0x2b, 0xbb, 0x23, 0x50, 0xb5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x82, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x01, 0xfb, 0xd0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1d, 0xb5, 0xa2, 0x5f, 0xc0, 0x00, 0x00, + 0x00, 0x25, 0x90, 0xa2, 0x53, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0xe8, + 0x00, 0x01, 0xff, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x25, 0x90, 0xa2, 0x53, 0x58, 0x00, 0x00, 0x9e, 0x2b, 0xbb, 0x23, 0x50, 0xb5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, +} + +// Openflow counter sample +var SFlowTestPacket12 = []byte{ + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xb3, 0x5a, 0x0e, 0x04, 0x12, 0xe0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x5b, 0xdb, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xec, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x62, 0xd3, 0x3c, 0xe7, 0x6e, 0x49, 0x00, 0x00, 0xff, 0xfe, + 0x00, 0x00, 0x03, 0xed, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x62, 0x72, 0x2d, 0x69, + 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x05, 0xf5, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +} + +// AppResources and Ovsdb counter samples +var SFlowTestPacket13 = []byte{ + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xb3, 0x5f, 0x0e, 0x04, 0x51, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x5b, 0xdd, 0x02, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x08, 0x9b, 0x00, 0x00, 0x00, 0x28, 0x00, 0x0b, 0x15, 0x2d, 0x00, 0x0a, 0x37, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x9f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x03, 0xf7, 0x00, 0x00, 0x01, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + func TestDecodeUDPSFlow(t *testing.T) { p := gopacket.NewPacket(SFlowTestPacket1, LayerTypeEthernet, gopacket.Default) if p.ErrorLayer() != nil { @@ -1207,6 +1332,549 @@ func TestDecodeExtendedIpv4TunnelEgressFlow(t *testing.T) { } } +func TestDecodeEthernetFrameFlow(t *testing.T) { + p := gopacket.NewPacket(SFlowEthernetFramePacket, LayerTypeSFlow, gopacket.Default) + + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeSFlow}, t) + + got := p.ApplicationLayer().(*SFlowDatagram) + + want := &SFlowDatagram{ + DatagramVersion: uint32(5), + AgentAddress: net.IP{0xb9, 0x78, 0x16, 0xf6}, + SubAgentID: 0x186a0, + SequenceNumber: 0xb, + AgentUptime: 0x3297, + SampleCount: 0x7, + FlowSamples: []SFlowFlowSample{ + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 0x40, + SequenceNumber: 0x7d, + SourceIDClass: 0x0, + SourceIDIndex: 0x3, + SamplingRate: 0x3e8, + SamplePool: 0x1e848, + Dropped: 0x0, + InputInterfaceFormat: 0x0, + InputInterface: 0x3fffffff, + OutputInterfaceFormat: 0x0, + OutputInterface: 0x3, + RecordCount: 0x1, + Records: []SFlowRecord{ + SFlowEthernetFrameFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + 0x0, + 0x2, + 0x18, + }, + FrameLength: 0x10, + SrcMac: net.HardwareAddr{0x0, 0x25, 0x90, 0xa2, 0x53, 0x58}, + DstMac: net.HardwareAddr{0x0, 0x1d, 0xb5, 0xa2, 0x5f, 0xc0}, + Type: 0x3, + }, + }, + }, + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 0x40, + SequenceNumber: 0x7e, + SourceIDClass: 0x0, + SourceIDIndex: 0x3, + SamplingRate: 0x3e8, + SamplePool: 0x1ec30, + Dropped: 0x0, + InputInterfaceFormat: 0x0, + InputInterface: 0x3fffffff, + OutputInterfaceFormat: 0x0, + OutputInterface: 0x3, + RecordCount: 0x1, + Records: []SFlowRecord{ + SFlowEthernetFrameFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x2, + FlowDataLength: 0x18, + }, FrameLength: 0x10, + SrcMac: net.HardwareAddr{0x0, 0x25, 0x90, 0xa2, 0x53, 0x58}, + DstMac: net.HardwareAddr{0x7a, 0x7d, 0x48, 0x51, 0xaa, 0xc7}, + Type: 0x3, + }, + }, + }, SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 0x40, + SequenceNumber: 0x7f, + SourceIDClass: 0x0, + SourceIDIndex: 0x3, + SamplingRate: 0x3e8, + SamplePool: 0x1f018, + Dropped: 0x0, + InputInterfaceFormat: 0x0, + InputInterface: 0x3fffffff, + OutputInterfaceFormat: 0x0, + OutputInterface: 0x3, + RecordCount: 0x1, + Records: []SFlowRecord{ + SFlowEthernetFrameFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x2, + FlowDataLength: 0x18, + }, + FrameLength: 0x10, + SrcMac: net.HardwareAddr{0x0, 0x25, 0x90, 0xa2, 0x53, 0x58}, + DstMac: net.HardwareAddr{0x7a, 0x7d, 0x48, 0x51, 0xaa, 0xc7}, + Type: 0x3, + }, + }, + }, + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 0x40, + SequenceNumber: 0x80, + SourceIDClass: 0x0, + SourceIDIndex: 0x3, + SamplingRate: 0x3e8, + SamplePool: 0x1f400, + Dropped: 0x0, + InputInterfaceFormat: 0x0, + InputInterface: 0x3fffffff, + OutputInterfaceFormat: 0x0, + OutputInterface: 0x3, + RecordCount: 0x1, + Records: []SFlowRecord{ + SFlowEthernetFrameFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x2, + FlowDataLength: 0x18, + }, + FrameLength: 0x10, + SrcMac: net.HardwareAddr{0x0, 0x25, 0x90, 0xa2, 0x53, 0x58}, + DstMac: net.HardwareAddr{0x7a, 0x7d, 0x48, 0x51, 0xaa, 0xc7}, + Type: 0x3, + }, + }, + }, + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 0x40, + SequenceNumber: 0x81, + SourceIDClass: 0x0, + SourceIDIndex: 0x3, + SamplingRate: 0x3e8, + SamplePool: 0x1f7e8, + Dropped: 0x0, + InputInterfaceFormat: 0x0, + InputInterface: 0x3fffffff, + OutputInterfaceFormat: 0x0, + OutputInterface: 0x3, + RecordCount: 0x1, + Records: []SFlowRecord{ + SFlowEthernetFrameFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x2, + FlowDataLength: 0x18, + }, + FrameLength: 0x10, + SrcMac: net.HardwareAddr{0x0, 0x25, 0x90, 0xa2, 0x53, 0x58}, + DstMac: net.HardwareAddr{0x9e, 0x2b, 0xbb, 0x23, 0x50, 0xb5}, + Type: 0x3, + }, + }, + }, + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 0x40, + SequenceNumber: 0x82, + SourceIDClass: 0x0, + SourceIDIndex: 0x3, + SamplingRate: 0x3e8, + SamplePool: 0x1fbd0, + Dropped: 0x0, + InputInterfaceFormat: 0x0, + InputInterface: 0x3, + OutputInterfaceFormat: 0x0, + OutputInterface: 0x3fffffff, + RecordCount: 0x1, + Records: []SFlowRecord{ + SFlowEthernetFrameFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x2, + FlowDataLength: 0x18, + }, + FrameLength: 0x10, + SrcMac: net.HardwareAddr{0x0, 0x1d, 0xb5, 0xa2, 0x5f, 0xc0}, + DstMac: net.HardwareAddr{0x0, 0x25, 0x90, 0xa2, 0x53, 0x58}, + Type: 0x3, + }, + }, + }, + SFlowFlowSample{ + EnterpriseID: 0x0, + Format: 0x1, + SampleLength: 0x40, + SequenceNumber: 0x83, + SourceIDClass: 0x0, + SourceIDIndex: 0x3, + SamplingRate: 0x3e8, + SamplePool: 0x1ffb8, + Dropped: 0x0, + InputInterfaceFormat: 0x0, + InputInterface: 0x3fffffff, + OutputInterfaceFormat: 0x0, + OutputInterface: 0x3, + RecordCount: 0x1, + Records: []SFlowRecord{ + SFlowEthernetFrameFlowRecord{ + SFlowBaseFlowRecord: SFlowBaseFlowRecord{ + EnterpriseID: 0x0, + Format: 0x2, + FlowDataLength: 0x18, + }, + FrameLength: 0x10, + SrcMac: net.HardwareAddr{0x0, 0x25, 0x90, 0xa2, 0x53, 0x58}, + DstMac: net.HardwareAddr{0x9e, 0x2b, 0xbb, 0x23, 0x50, 0xb5}, + Type: 0x3, + }, + }, + }, + }, + CounterSamples: []SFlowCounterSample(nil), + } + if !reflect.DeepEqual(want, got) { + t.Errorf("SFlow layer mismatch, \nwant:\n\n%#v\ngot:\n\n\n%#v\n\n", want, got) + } +} + +func TestDecodePortnameCounter(t *testing.T) { + p := gopacket.NewPacket(SFlowTestPacket9, LayerTypeSFlow, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeSFlow}, t) + + got := p.ApplicationLayer().(*SFlowDatagram) + + want := &SFlowDatagram{ + DatagramVersion: 0x5, + AgentAddress: net.IP{0x7f, 0x0, 0x0, 0x1}, + SequenceNumber: 0x1b36d, + AgentUptime: 0xe04d248, + SampleCount: 0x1, + CounterSamples: []SFlowCounterSample{ + SFlowCounterSample{ + Format: 0x2, + SampleLength: 0xd8, + SequenceNumber: 0x5be0, + SourceIDIndex: 0xe, + RecordCount: 0x4, + Records: []SFlowRecord{ + SFlowEthernetCounters{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + Format: SFlowTypeEthernetInterfaceCounters, + FlowDataLength: 0x34, + }, + SingleCollisionFrames: 0xffffffff, + MultipleCollisionFrames: 0xffffffff, + SQETestErrors: 0xffffffff, + DeferredTransmissions: 0xffffffff, + LateCollisions: 0xffffffff, + ExcessiveCollisions: 0xffffffff, + InternalMacTransmitErrors: 0xffffffff, + CarrierSenseErrors: 0xffffffff, + FrameTooLongs: 0xffffffff, + InternalMacReceiveErrors: 0xffffffff, + SymbolErrors: 0xffffffff, + }, + SFlowOpenflowPortCounters{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + Format: SFlowTypeOpenflowPortCounters, + FlowDataLength: 0xc, + }, + DatapathID: 0x62d33ce76e49, + PortNo: 0x3, + }, + SFlowPORTNAME{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + Format: SFlowTypePORTNAMECounters, + FlowDataLength: 0x14, + }, + Len: 0x10, + Str: "tapd98154f2-00", + }, + SFlowGenericInterfaceCounters{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + Format: SFlowTypeGenericInterfaceCounters, + FlowDataLength: 0x58, + }, + IfIndex: 0xe, + IfType: 0x6, + IfSpeed: 0x2540be400, + IfDirection: 0x1, + IfStatus: 0x3, + IfInOctets: 0x4749, + IfInUcastPkts: 0xb5, + IfInBroadcastPkts: 0xffffffff, + IfInUnknownProtos: 0xffffffff, + IfOutOctets: 0x8a0b, + IfOutUcastPkts: 0x1d2, + IfOutMulticastPkts: 0xffffffff, + IfOutBroadcastPkts: 0xffffffff, + }, + }, + }, + }, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("SFlow layer mismatch, \nwant:\n\n%#v\ngot:\n\n\n%#v\n\n", want, got) + } +} + +func TestDecodeVLANCounter(t *testing.T) { + p := gopacket.NewPacket(SFlowTestPacket10, LayerTypeSFlow, gopacket.Default) + + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeSFlow}, t) + + got := p.ApplicationLayer().(*SFlowDatagram) + + want := &SFlowDatagram{ + DatagramVersion: uint32(5), + AgentAddress: []byte{0x0a, 0x14, 0x04, 0x00}, + SubAgentID: uint32(0x64), + SequenceNumber: uint32(96480), + AgentUptime: uint32(1929595000), + SampleCount: uint32(1), + CounterSamples: []SFlowCounterSample{ + SFlowCounterSample{ + Format: SFlowTypeExpandedCounterSample, + SampleLength: 0x34, + SequenceNumber: 0x0178e0, + SourceIDClass: 0x00, + SourceIDIndex: 0x01, + RecordCount: 0x01, + Records: []SFlowRecord{ + SFlowVLANCounters{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + EnterpriseID: 0x0, + Format: SFlowTypeVLANCounters, + FlowDataLength: 0x1c, + }, + VlanID: 0x0a, + Octets: 0x018c2ccc, + UcastPkts: 0x9683, + MulticastPkts: 0x029016, + BroadcastPkts: 0x01f673, + Discards: 0x00, + }, + }, + }, + }, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("SFlow layer mismatch, \nwant:\n\n%#v\ngot:\n\n\n%#v\n\n", want, got) + } +} + +func TestDecodeLACPCounter(t *testing.T) { + p := gopacket.NewPacket(SFlowTestPacket11, LayerTypeSFlow, gopacket.Default) + + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeSFlow}, t) + + got := p.ApplicationLayer().(*SFlowDatagram) + + want := &SFlowDatagram{ + DatagramVersion: uint32(5), + AgentAddress: []byte{0x7f, 0x00, 0x00, 0x01}, + SubAgentID: uint32(0x00), + SequenceNumber: uint32(14565), //38e5 + AgentUptime: uint32(95295000), //5AE1618 + SampleCount: uint32(1), + CounterSamples: []SFlowCounterSample{ + SFlowCounterSample{ + Format: SFlowTypeCounterSample, + SampleLength: 0x74, + SequenceNumber: 0x0d30, + SourceIDClass: 0x00, + SourceIDIndex: 0x1, + RecordCount: 0x01, + Records: []SFlowRecord{ + SFlowLACPCounters{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + EnterpriseID: 0x0, + Format: SFlowTypeLACPCounters, + FlowDataLength: 0x38, + }, + ActorSystemID: net.HardwareAddr{0x7e, 0x60, 0x69, 0x73, 0x8f, 0x42}, + PartnerSystemID: net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + AttachedAggID: uint32(1), + LacpPortState: SFLLACPPortState{PortStateAll: uint32(91553792)}, + LACPDUsRx: uint32(0), + MarkerPDUsRx: uint32(4294967295), + MarkerResponsePDUsRx: uint32(4294967295), + UnknownRx: uint32(4294967295), + IllegalRx: uint32(0), + LACPDUsTx: uint32(1173), + MarkerPDUsTx: uint32(4294967295), + MarkerResponsePDUsTx: uint32(4294967295), + }, + }, + }, + }, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("SFlow layer mismatch, \nwant:\n\n%#v\ngot:\n\n\n%#v\n\n", want, got) + } +} + +func TestDecodeOpenflowCounter(t *testing.T) { + p := gopacket.NewPacket(SFlowTestPacket12, LayerTypeSFlow, gopacket.Default) + + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeSFlow}, t) + + got := p.ApplicationLayer().(*SFlowDatagram) + + want := &SFlowDatagram{ + DatagramVersion: 0x5, + AgentAddress: net.IP{0x7f, 0x0, 0x0, 0x1}, + SequenceNumber: 0x1b35a, + AgentUptime: 0xe0412e0, + SampleCount: 0x1, + CounterSamples: []SFlowCounterSample{ + SFlowCounterSample{ + Format: SFlowTypeCounterSample, + SampleLength: 0xd0, + SequenceNumber: 0x5bdb, + SourceIDIndex: 0xb, + RecordCount: 0x4, + Records: []SFlowRecord{ + SFlowEthernetCounters{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + Format: SFlowTypeEthernetInterfaceCounters, + FlowDataLength: 0x34, + }, + SingleCollisionFrames: 0xffffffff, + MultipleCollisionFrames: 0xffffffff, + SQETestErrors: 0xffffffff, + DeferredTransmissions: 0xffffffff, + LateCollisions: 0xffffffff, + ExcessiveCollisions: 0xffffffff, + InternalMacTransmitErrors: 0xffffffff, + CarrierSenseErrors: 0xffffffff, + FrameTooLongs: 0xffffffff, + InternalMacReceiveErrors: 0xffffffff, + SymbolErrors: 0xffffffff, + }, + SFlowOpenflowPortCounters{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + Format: SFlowTypeOpenflowPortCounters, + FlowDataLength: 0xc, + }, + DatapathID: 0x62d33ce76e49, + PortNo: 0xfffe, + }, + SFlowPORTNAME{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + Format: SFlowTypePORTNAMECounters, + FlowDataLength: 0xc, + }, + Len: 0x8, + Str: "br-int", + }, + SFlowGenericInterfaceCounters{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + Format: SFlowTypeGenericInterfaceCounters, + FlowDataLength: 0x58, + }, + IfIndex: 0xb, + IfType: 0x6, + IfSpeed: 0x5f5e100, + IfInBroadcastPkts: 0xffffffff, + IfInUnknownProtos: 0xffffffff, + IfOutMulticastPkts: 0xffffffff, + IfOutBroadcastPkts: 0xffffffff, + }, + }, + }, + }, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("SFlow layer mismatch, \nwant:\n\n%#v\ngot:\n\n\n%#v\n\n", want, got) + } +} + +func TestDecodeAppResourcesOvsdbCounter(t *testing.T) { + p := gopacket.NewPacket(SFlowTestPacket13, LayerTypeSFlow, gopacket.Default) + + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeSFlow}, t) + + got := p.ApplicationLayer().(*SFlowDatagram) + + want := &SFlowDatagram{ + DatagramVersion: 0x5, + AgentAddress: net.IP{0x7f, 0x0, 0x0, 0x1}, + SequenceNumber: 0x1b35f, + AgentUptime: 0xe045160, + SampleCount: 0x1, + CounterSamples: []SFlowCounterSample{ + SFlowCounterSample{ + Format: SFlowTypeCounterSample, + SampleLength: 0x5c, + SequenceNumber: 0x5bdd, + SourceIDIndex: 0x20003e8, + RecordCount: 0x2, + Records: []SFlowRecord{ + SFlowAppresourcesCounters{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + Format: SFLowTypeAPPRESOURCESCounters, + FlowDataLength: 0x28, + }, + UserTime: 0xb152d, + SystemTime: 0xa3739, + MemUsed: 0x58b000, + }, + SFlowOVSDPCounters{ + SFlowBaseCounterRecord: SFlowBaseCounterRecord{ + Format: SFlowTypeOVSDPCounters, + FlowDataLength: 0x18, + }, + NHit: 0x3f7, + NMissed: 0x148, + NMaskHit: 0xa3b, + }, + }, + }, + }, + } + if !reflect.DeepEqual(want, got) { + t.Errorf("SFlow layer mismatch, \nwant:\n\n%#v\ngot:\n\n\n%#v\n\n", want, got) + } +} + func BenchmarkDecodeSFlowPacket1(b *testing.B) { for i := 0; i < b.N; i++ { gopacket.NewPacket(SFlowTestPacket1, LinkTypeEthernet, gopacket.NoCopy) @@ -1231,6 +1899,24 @@ func BenchmarkDecodeSFlowPacket4(b *testing.B) { } } +func BenchmarkDecodeSFlowPacket9(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(SFlowTestPacket9, LinkTypeEthernet, gopacket.NoCopy) + } +} + +func BenchmarkDecodeSFlowPacket10(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(SFlowTestPacket10, LinkTypeEthernet, gopacket.NoCopy) + } +} + +func BenchmarkDecodeSFlowPacket11(b *testing.B) { + for i := 0; i < b.N; i++ { + gopacket.NewPacket(SFlowTestPacket11, LinkTypeEthernet, gopacket.NoCopy) + } +} + func BenchmarkDecodeSFlowLayerPacket1(b *testing.B) { var sflow SFlowDatagram for i := 0; i < b.N; i++ { diff --git a/vendor/github.com/google/gopacket/layers/sip.go b/vendor/github.com/google/gopacket/layers/sip.go new file mode 100644 index 0000000000..540368811e --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/sip.go @@ -0,0 +1,546 @@ +// Copyright 2017 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "bytes" + "fmt" + "io" + "strconv" + "strings" + + "github.com/google/gopacket" +) + +// SIPVersion defines the different versions of the SIP Protocol +type SIPVersion uint8 + +// Represents all the versions of SIP protocol +const ( + SIPVersion1 SIPVersion = 1 + SIPVersion2 SIPVersion = 2 +) + +func (sv SIPVersion) String() string { + switch sv { + default: + // Defaulting to SIP/2.0 + return "SIP/2.0" + case SIPVersion1: + return "SIP/1.0" + case SIPVersion2: + return "SIP/2.0" + } +} + +// GetSIPVersion is used to get SIP version constant +func GetSIPVersion(version string) (SIPVersion, error) { + switch strings.ToUpper(version) { + case "SIP/1.0": + return SIPVersion1, nil + case "SIP/2.0": + return SIPVersion2, nil + default: + return 0, fmt.Errorf("Unknown SIP version: '%s'", version) + + } +} + +// SIPMethod defines the different methods of the SIP Protocol +// defined in the different RFC's +type SIPMethod uint16 + +// Here are all the SIP methods +const ( + SIPMethodInvite SIPMethod = 1 // INVITE [RFC3261] + SIPMethodAck SIPMethod = 2 // ACK [RFC3261] + SIPMethodBye SIPMethod = 3 // BYE [RFC3261] + SIPMethodCancel SIPMethod = 4 // CANCEL [RFC3261] + SIPMethodOptions SIPMethod = 5 // OPTIONS [RFC3261] + SIPMethodRegister SIPMethod = 6 // REGISTER [RFC3261] + SIPMethodPrack SIPMethod = 7 // PRACK [RFC3262] + SIPMethodSubscribe SIPMethod = 8 // SUBSCRIBE [RFC6665] + SIPMethodNotify SIPMethod = 9 // NOTIFY [RFC6665] + SIPMethodPublish SIPMethod = 10 // PUBLISH [RFC3903] + SIPMethodInfo SIPMethod = 11 // INFO [RFC6086] + SIPMethodRefer SIPMethod = 12 // REFER [RFC3515] + SIPMethodMessage SIPMethod = 13 // MESSAGE [RFC3428] + SIPMethodUpdate SIPMethod = 14 // UPDATE [RFC3311] + SIPMethodPing SIPMethod = 15 // PING [https://tools.ietf.org/html/draft-fwmiller-ping-03] +) + +func (sm SIPMethod) String() string { + switch sm { + default: + return "Unknown method" + case SIPMethodInvite: + return "INVITE" + case SIPMethodAck: + return "ACK" + case SIPMethodBye: + return "BYE" + case SIPMethodCancel: + return "CANCEL" + case SIPMethodOptions: + return "OPTIONS" + case SIPMethodRegister: + return "REGISTER" + case SIPMethodPrack: + return "PRACK" + case SIPMethodSubscribe: + return "SUBSCRIBE" + case SIPMethodNotify: + return "NOTIFY" + case SIPMethodPublish: + return "PUBLISH" + case SIPMethodInfo: + return "INFO" + case SIPMethodRefer: + return "REFER" + case SIPMethodMessage: + return "MESSAGE" + case SIPMethodUpdate: + return "UPDATE" + case SIPMethodPing: + return "PING" + } +} + +// GetSIPMethod returns the constant of a SIP method +// from its string +func GetSIPMethod(method string) (SIPMethod, error) { + switch strings.ToUpper(method) { + case "INVITE": + return SIPMethodInvite, nil + case "ACK": + return SIPMethodAck, nil + case "BYE": + return SIPMethodBye, nil + case "CANCEL": + return SIPMethodCancel, nil + case "OPTIONS": + return SIPMethodOptions, nil + case "REGISTER": + return SIPMethodRegister, nil + case "PRACK": + return SIPMethodPrack, nil + case "SUBSCRIBE": + return SIPMethodSubscribe, nil + case "NOTIFY": + return SIPMethodNotify, nil + case "PUBLISH": + return SIPMethodPublish, nil + case "INFO": + return SIPMethodInfo, nil + case "REFER": + return SIPMethodRefer, nil + case "MESSAGE": + return SIPMethodMessage, nil + case "UPDATE": + return SIPMethodUpdate, nil + case "PING": + return SIPMethodPing, nil + default: + return 0, fmt.Errorf("Unknown SIP method: '%s'", method) + } +} + +// Here is a correspondance between long header names and short +// as defined in rfc3261 in section 20 +var compactSipHeadersCorrespondance = map[string]string{ + "accept-contact": "a", + "allow-events": "u", + "call-id": "i", + "contact": "m", + "content-encoding": "e", + "content-length": "l", + "content-type": "c", + "event": "o", + "from": "f", + "identity": "y", + "refer-to": "r", + "referred-by": "b", + "reject-contact": "j", + "request-disposition": "d", + "session-expires": "x", + "subject": "s", + "supported": "k", + "to": "t", + "via": "v", +} + +// SIP object will contains information about decoded SIP packet. +// -> The SIP Version +// -> The SIP Headers (in a map[string][]string because of multiple headers with the same name +// -> The SIP Method +// -> The SIP Response code (if it's a response) +// -> The SIP Status line (if it's a response) +// You can easily know the type of the packet with the IsResponse boolean +// +type SIP struct { + BaseLayer + + // Base information + Version SIPVersion + Method SIPMethod + Headers map[string][]string + + // Request + RequestURI string + + // Response + IsResponse bool + ResponseCode int + ResponseStatus string + + // Private fields + cseq int64 + contentLength int64 + lastHeaderParsed string +} + +// decodeSIP decodes the byte slice into a SIP type. It also +// setups the application Layer in PacketBuilder. +func decodeSIP(data []byte, p gopacket.PacketBuilder) error { + s := NewSIP() + err := s.DecodeFromBytes(data, p) + if err != nil { + return err + } + p.AddLayer(s) + p.SetApplicationLayer(s) + return nil +} + +// NewSIP instantiates a new empty SIP object +func NewSIP() *SIP { + s := new(SIP) + s.Headers = make(map[string][]string) + return s +} + +// LayerType returns gopacket.LayerTypeSIP. +func (s *SIP) LayerType() gopacket.LayerType { + return LayerTypeSIP +} + +// Payload returns the base layer payload +func (s *SIP) Payload() []byte { + return s.BaseLayer.Payload +} + +// CanDecode returns the set of layer types that this DecodingLayer can decode +func (s *SIP) CanDecode() gopacket.LayerClass { + return LayerTypeSIP +} + +// NextLayerType returns the layer type contained by this DecodingLayer +func (s *SIP) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +// DecodeFromBytes decodes the slice into the SIP struct. +func (s *SIP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + + // Init some vars for parsing follow-up + var countLines int + var line []byte + var err error + + // Clean leading new line + data = bytes.Trim(data, "\n") + + // Iterate on all lines of the SIP Headers + // and stop when we reach the SDP (aka when the new line + // is at index 0 of the remaining packet) + buffer := bytes.NewBuffer(data) + + for { + + // Read next line + line, err = buffer.ReadBytes(byte('\n')) + if err != nil { + if err == io.EOF { + break + } else { + return err + } + } + + // Trim the new line delimiters + line = bytes.Trim(line, "\r\n") + + // Empty line, we hit Body + // Putting packet remain in Paypload + if len(line) == 0 { + s.BaseLayer.Payload = buffer.Bytes() + break + } + + // First line is the SIP request/response line + // Other lines are headers + if countLines == 0 { + err = s.ParseFirstLine(line) + if err != nil { + return err + } + + } else { + err = s.ParseHeader(line) + if err != nil { + return err + } + } + + countLines++ + } + + return nil +} + +// ParseFirstLine will compute the first line of a SIP packet. +// The first line will tell us if it's a request or a response. +// +// Examples of first line of SIP Prococol : +// +// Request : INVITE bob@example.com SIP/2.0 +// Response : SIP/2.0 200 OK +// Response : SIP/2.0 501 Not Implemented +// +func (s *SIP) ParseFirstLine(firstLine []byte) error { + + var err error + + // Splits line by space + splits := strings.SplitN(string(firstLine), " ", 3) + + // We must have at least 3 parts + if len(splits) < 3 { + return fmt.Errorf("invalid first SIP line: '%s'", string(firstLine)) + } + + // Determine the SIP packet type + if strings.HasPrefix(splits[0], "SIP") { + + // --> Response + s.IsResponse = true + + // Validate SIP Version + s.Version, err = GetSIPVersion(splits[0]) + if err != nil { + return err + } + + // Compute code + s.ResponseCode, err = strconv.Atoi(splits[1]) + if err != nil { + return err + } + + // Compute status line + s.ResponseStatus = splits[2] + + } else { + + // --> Request + + // Validate method + s.Method, err = GetSIPMethod(splits[0]) + if err != nil { + return err + } + + s.RequestURI = splits[1] + + // Validate SIP Version + s.Version, err = GetSIPVersion(splits[2]) + if err != nil { + return err + } + } + + return nil +} + +// ParseHeader will parse a SIP Header +// SIP Headers are quite simple, there are colon separated name and value +// Headers can be spread over multiple lines +// +// Examples of header : +// +// CSeq: 1 REGISTER +// Via: SIP/2.0/UDP there.com:5060 +// Authorization:Digest username="UserB", +// realm="MCI WorldCom SIP", +// nonce="1cec4341ae6cbe5a359ea9c8e88df84f", opaque="", +// uri="sip:ss2.wcom.com", response="71ba27c64bd01de719686aa4590d5824" +// +func (s *SIP) ParseHeader(header []byte) (err error) { + + // Ignore empty headers + if len(header) == 0 { + return + } + + // Check if this is the following of last header + // RFC 3261 - 7.3.1 - Header Field Format specify that following lines of + // multiline headers must begin by SP or TAB + if header[0] == '\t' || header[0] == ' ' { + + header = bytes.TrimSpace(header) + s.Headers[s.lastHeaderParsed][len(s.Headers[s.lastHeaderParsed])-1] += fmt.Sprintf(" %s", string(header)) + return + } + + // Find the ':' to separate header name and value + index := bytes.Index(header, []byte(":")) + if index >= 0 { + + headerName := strings.ToLower(string(bytes.Trim(header[:index], " "))) + headerValue := string(bytes.Trim(header[index+1:], " ")) + + // Add header to object + s.Headers[headerName] = append(s.Headers[headerName], headerValue) + s.lastHeaderParsed = headerName + + // Compute specific headers + err = s.ParseSpecificHeaders(headerName, headerValue) + if err != nil { + return err + } + } + + return nil +} + +// ParseSpecificHeaders will parse some specific key values from +// specific headers like CSeq or Content-Length integer values +func (s *SIP) ParseSpecificHeaders(headerName string, headerValue string) (err error) { + + switch headerName { + case "cseq": + + // CSeq header value is formatted like that : + // CSeq: 123 INVITE + // We split the value to parse Cseq integer value, and method + splits := strings.Split(headerValue, " ") + if len(splits) > 1 { + + // Parse Cseq + s.cseq, err = strconv.ParseInt(splits[0], 10, 64) + if err != nil { + return err + } + + // Validate method + if s.IsResponse { + s.Method, err = GetSIPMethod(splits[1]) + if err != nil { + return err + } + } + } + + case "content-length": + + // Parse Content-Length + s.contentLength, err = strconv.ParseInt(headerValue, 10, 64) + if err != nil { + return err + } + } + + return nil +} + +// GetAllHeaders will return the full headers of the +// current SIP packets in a map[string][]string +func (s *SIP) GetAllHeaders() map[string][]string { + return s.Headers +} + +// GetHeader will return all the headers with +// the specified name. +func (s *SIP) GetHeader(headerName string) []string { + headerName = strings.ToLower(headerName) + h := make([]string, 0) + if _, ok := s.Headers[headerName]; ok { + if len(s.Headers[headerName]) > 0 { + return s.Headers[headerName] + } else if len(s.Headers[compactSipHeadersCorrespondance[headerName]]) > 0 { + return s.Headers[compactSipHeadersCorrespondance[headerName]] + } + } + return h +} + +// GetFirstHeader will return the first header with +// the specified name. If the current SIP packet has multiple +// headers with the same name, it returns the first. +func (s *SIP) GetFirstHeader(headerName string) string { + headerName = strings.ToLower(headerName) + if _, ok := s.Headers[headerName]; ok { + if len(s.Headers[headerName]) > 0 { + return s.Headers[headerName][0] + } else if len(s.Headers[compactSipHeadersCorrespondance[headerName]]) > 0 { + return s.Headers[compactSipHeadersCorrespondance[headerName]][0] + } + } + return "" +} + +// +// Some handy getters for most used SIP headers +// + +// GetAuthorization will return the Authorization +// header of the current SIP packet +func (s *SIP) GetAuthorization() string { + return s.GetFirstHeader("Authorization") +} + +// GetFrom will return the From +// header of the current SIP packet +func (s *SIP) GetFrom() string { + return s.GetFirstHeader("From") +} + +// GetTo will return the To +// header of the current SIP packet +func (s *SIP) GetTo() string { + return s.GetFirstHeader("To") +} + +// GetContact will return the Contact +// header of the current SIP packet +func (s *SIP) GetContact() string { + return s.GetFirstHeader("Contact") +} + +// GetCallID will return the Call-ID +// header of the current SIP packet +func (s *SIP) GetCallID() string { + return s.GetFirstHeader("Call-ID") +} + +// GetUserAgent will return the User-Agent +// header of the current SIP packet +func (s *SIP) GetUserAgent() string { + return s.GetFirstHeader("User-Agent") +} + +// GetContentLength will return the parsed integer +// Content-Length header of the current SIP packet +func (s *SIP) GetContentLength() int64 { + return s.contentLength +} + +// GetCSeq will return the parsed integer CSeq header +// header of the current SIP packet +func (s *SIP) GetCSeq() int64 { + return s.cseq +} diff --git a/vendor/github.com/google/gopacket/layers/sip_test.go b/vendor/github.com/google/gopacket/layers/sip_test.go new file mode 100644 index 0000000000..7c28d6bf0e --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/sip_test.go @@ -0,0 +1,158 @@ +// Copyright 2017 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "testing" + + "github.com/google/gopacket" +) + +// First packet is a REGISTER Request +// +// REGISTER sip:sip.provider.com SIP/2.0 +// Via:SIP/2.0/UDP 172.16.254.66:5060;branch=z9hG4bK3e5380d454981e88702eb2269669462;rport +// From:"Bob" ;tag=3718850509 +// To:"Alice" +// Call-ID:306366781@172_16_254_66 +// CSeq:3 REGISTER +// Max-Forwards:70 +// Allow:INVITE,ACK,CANCEL,BYE,OPTIONS,INFO,SUBSCRIBE,NOTIFY,REFER,UPDATE +// Contact: +// Expires:1800 +// User-Agent:C530 IP/42.245.00.000.000 +// Content-Length:0 +// +var testPacketSIPRequest = []byte{ + 0x00, 0x07, 0x7d, 0x41, 0x2e, 0x40, 0x00, 0xd0, 0x03, 0x75, 0xe0, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x01, 0xf4, 0x73, 0x74, 0x00, 0x00, 0x75, 0x11, 0xca, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, + 0x02, 0x02, 0x13, 0xc4, 0x13, 0xc4, 0x01, 0xe0, 0x86, 0xa0, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, + 0x45, 0x52, 0x20, 0x73, 0x69, 0x70, 0x3a, 0x73, 0x69, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x20, 0x53, 0x49, 0x50, 0x2f, 0x32, 0x2e, 0x30, 0x0d, + 0x0a, 0x56, 0x69, 0x61, 0x3a, 0x53, 0x49, 0x50, 0x2f, 0x32, 0x2e, 0x30, 0x2f, 0x55, 0x44, 0x50, + 0x20, 0x31, 0x37, 0x32, 0x2e, 0x31, 0x36, 0x2e, 0x32, 0x35, 0x34, 0x2e, 0x36, 0x36, 0x3a, 0x35, + 0x30, 0x36, 0x30, 0x3b, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x3d, 0x7a, 0x39, 0x68, 0x47, 0x34, + 0x62, 0x4b, 0x33, 0x65, 0x35, 0x33, 0x38, 0x30, 0x64, 0x34, 0x35, 0x34, 0x39, 0x38, 0x31, 0x65, + 0x38, 0x38, 0x37, 0x30, 0x32, 0x65, 0x62, 0x32, 0x32, 0x36, 0x39, 0x36, 0x36, 0x39, 0x34, 0x36, + 0x32, 0x3b, 0x72, 0x70, 0x6f, 0x72, 0x74, 0x0d, 0x0a, 0x46, 0x72, 0x6f, 0x6d, 0x3a, 0x22, 0x42, + 0x6f, 0x62, 0x22, 0x20, 0x3c, 0x73, 0x69, 0x70, 0x3a, 0x62, 0x6f, 0x62, 0x40, 0x73, 0x69, 0x70, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, 0x3b, 0x74, + 0x61, 0x67, 0x3d, 0x33, 0x37, 0x31, 0x38, 0x38, 0x35, 0x30, 0x35, 0x30, 0x39, 0x0d, 0x0a, 0x54, + 0x6f, 0x3a, 0x22, 0x41, 0x6c, 0x69, 0x63, 0x65, 0x22, 0x20, 0x3c, 0x73, 0x69, 0x70, 0x3a, 0x61, + 0x6c, 0x69, 0x63, 0x65, 0x40, 0x73, 0x69, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, 0x0d, 0x0a, 0x43, 0x61, 0x6c, 0x6c, 0x2d, 0x49, 0x44, 0x3a, + 0x33, 0x30, 0x36, 0x33, 0x36, 0x36, 0x37, 0x38, 0x31, 0x40, 0x31, 0x37, 0x32, 0x5f, 0x31, 0x36, + 0x5f, 0x32, 0x35, 0x34, 0x5f, 0x36, 0x36, 0x0d, 0x0a, 0x43, 0x53, 0x65, 0x71, 0x3a, 0x33, 0x20, + 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x0d, 0x0a, 0x4d, 0x61, 0x78, 0x2d, 0x46, 0x6f, + 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x3a, 0x37, 0x30, 0x0d, 0x0a, 0x41, 0x6c, 0x6c, 0x6f, 0x77, + 0x3a, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x2c, 0x41, 0x43, 0x4b, 0x2c, 0x43, 0x41, 0x4e, 0x43, + 0x45, 0x4c, 0x2c, 0x42, 0x59, 0x45, 0x2c, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x2c, 0x49, + 0x4e, 0x46, 0x4f, 0x2c, 0x53, 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x42, 0x45, 0x2c, 0x4e, 0x4f, + 0x54, 0x49, 0x46, 0x59, 0x2c, 0x52, 0x45, 0x46, 0x45, 0x52, 0x2c, 0x55, 0x50, 0x44, 0x41, 0x54, + 0x45, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x3a, 0x20, 0x3c, 0x73, 0x69, 0x70, + 0x3a, 0x62, 0x6f, 0x62, 0x40, 0x31, 0x37, 0x32, 0x2e, 0x31, 0x36, 0x2e, 0x32, 0x35, 0x34, 0x2e, + 0x36, 0x36, 0x3a, 0x35, 0x30, 0x36, 0x30, 0x3e, 0x0d, 0x0a, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, + 0x73, 0x3a, 0x31, 0x38, 0x30, 0x30, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x3a, 0x43, 0x35, 0x33, 0x30, 0x20, 0x49, 0x50, 0x2f, 0x34, 0x32, 0x2e, 0x32, 0x34, + 0x35, 0x2e, 0x30, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x30, 0x0d, 0x0a, + 0x0d, 0x0a, +} + +// Second packet is a REGISTER Response +// +// SIP/2.0 200 OK +// Via:SIP/2.0/UDP 172.16.254.66:5060;received=8.8.8.8;rport=5060;branch=z9hG4bK3e5380d454981e88702eb2269669462 +// From:"Bob" ;tag=3718850509 +// To:"Alice" ;tag=02-32748-1417c4ac-24835dbf3 +// Call-ID:306366781@172_16_254_66 +// CSeq:3 REGISTER +// Contact: ;expires=1800 +// P-Associated-URI: +// Content-Length:0 +// +var testPacketSIPResponse = []byte{ + 0x00, 0xd0, 0x00, 0x4a, 0x2c, 0x00, 0x00, 0x07, 0x7d, 0x41, 0x2e, 0x40, 0x08, 0x00, 0x45, 0x00, + 0x01, 0xc1, 0x00, 0x00, 0x40, 0x00, 0x3f, 0x11, 0x34, 0x27, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, + 0x01, 0x01, 0x13, 0xc4, 0x13, 0xc4, 0x01, 0xad, 0x60, 0x36, 0x53, 0x49, 0x50, 0x2f, 0x32, 0x2e, + 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x56, 0x69, 0x61, 0x3a, 0x53, 0x49, + 0x50, 0x2f, 0x32, 0x2e, 0x30, 0x2f, 0x55, 0x44, 0x50, 0x20, 0x31, 0x37, 0x32, 0x2e, 0x31, 0x36, + 0x2e, 0x32, 0x35, 0x34, 0x2e, 0x36, 0x36, 0x3a, 0x35, 0x30, 0x36, 0x30, 0x3b, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x65, 0x64, 0x3d, 0x38, 0x2e, 0x38, 0x2e, 0x38, 0x2e, 0x38, 0x3b, 0x72, 0x70, + 0x6f, 0x72, 0x74, 0x3d, 0x35, 0x30, 0x36, 0x30, 0x3b, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x3d, + 0x7a, 0x39, 0x68, 0x47, 0x34, 0x62, 0x4b, 0x33, 0x65, 0x35, 0x33, 0x38, 0x30, 0x64, 0x34, 0x35, + 0x34, 0x39, 0x38, 0x31, 0x65, 0x38, 0x38, 0x37, 0x30, 0x32, 0x65, 0x62, 0x32, 0x32, 0x36, 0x39, + 0x36, 0x36, 0x39, 0x34, 0x36, 0x32, 0x0d, 0x0a, 0x46, 0x72, 0x6f, 0x6d, 0x3a, 0x22, 0x42, 0x6f, + 0x62, 0x22, 0x20, 0x3c, 0x73, 0x69, 0x70, 0x3a, 0x62, 0x6f, 0x62, 0x40, 0x73, 0x69, 0x70, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, 0x3b, 0x74, 0x61, + 0x67, 0x3d, 0x33, 0x37, 0x31, 0x38, 0x38, 0x35, 0x30, 0x35, 0x30, 0x39, 0x0d, 0x0a, 0x54, 0x6f, + 0x3a, 0x22, 0x41, 0x6c, 0x69, 0x63, 0x65, 0x22, 0x20, 0x3c, 0x73, 0x69, 0x70, 0x3a, 0x61, 0x6c, + 0x69, 0x63, 0x65, 0x40, 0x73, 0x69, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x3e, 0x3b, 0x74, 0x61, 0x67, 0x3d, 0x30, 0x32, 0x2d, 0x33, 0x32, 0x37, + 0x34, 0x38, 0x2d, 0x31, 0x34, 0x31, 0x37, 0x63, 0x34, 0x61, 0x63, 0x2d, 0x32, 0x34, 0x38, 0x33, + 0x35, 0x64, 0x62, 0x66, 0x33, 0x0d, 0x0a, 0x43, 0x61, 0x6c, 0x6c, 0x2d, 0x49, 0x44, 0x3a, 0x33, + 0x30, 0x36, 0x33, 0x36, 0x36, 0x37, 0x38, 0x31, 0x40, 0x31, 0x37, 0x32, 0x5f, 0x31, 0x36, 0x5f, + 0x32, 0x35, 0x34, 0x5f, 0x36, 0x36, 0x0d, 0x0a, 0x43, 0x53, 0x65, 0x71, 0x3a, 0x33, 0x20, 0x52, + 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, + 0x3a, 0x20, 0x3c, 0x73, 0x69, 0x70, 0x3a, 0x62, 0x6f, 0x62, 0x40, 0x31, 0x37, 0x32, 0x2e, 0x31, + 0x36, 0x2e, 0x32, 0x35, 0x34, 0x2e, 0x36, 0x36, 0x3a, 0x35, 0x30, 0x36, 0x30, 0x3e, 0x3b, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x3d, 0x31, 0x38, 0x30, 0x30, 0x0d, 0x0a, 0x50, 0x2d, 0x41, + 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x2d, 0x55, 0x52, 0x49, 0x3a, 0x20, 0x3c, + 0x73, 0x69, 0x70, 0x3a, 0x62, 0x6f, 0x62, 0x40, 0x73, 0x69, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x30, 0x0d, 0x0a, 0x0d, 0x0a, +} + +func TestSIPMain(t *testing.T) { + + expectedHeaders := map[string]string{"Call-ID": "306366781@172_16_254_66", "Contact": ""} + _TestPacketSIP(t, testPacketSIPRequest, SIPMethodRegister, false, 3, expectedHeaders, "sip:sip.provider.com") + + expectedHeaders = map[string]string{"Call-ID": "306366781@172_16_254_66", "Contact": ";expires=1800"} + _TestPacketSIP(t, testPacketSIPResponse, SIPMethodRegister, true, 3, expectedHeaders, "") + +} + +func _TestPacketSIP(t *testing.T, packetData []byte, methodWanted SIPMethod, isResponse bool, wantedCseq int64, expectedHeaders map[string]string, expectedRequestURI string) { + + p := gopacket.NewPacket(packetData, LinkTypeEthernet, gopacket.Default) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + + if got, ok := p.Layer(LayerTypeSIP).(*SIP); ok { + + // Check method + if got.Method != methodWanted { + t.Errorf("SIP Packet should be a %s method, got : %s", methodWanted, got.Method) + } + + // Check if it's right packet type + if got.IsResponse != isResponse { + t.Errorf("SIP packet type is not the same as expected") + } + + // Check the RequestURI if it's a request + if !isResponse { + if got.RequestURI != expectedRequestURI { + t.Errorf("SIP packet type is not the same as expected") + } + } + + // Check headers + for headerName, headerValue := range expectedHeaders { + if got.GetFirstHeader(headerName) != headerValue { + t.Errorf("Header %s shoud be %s, got : %s", headerName, headerValue, got.GetFirstHeader(headerName)) + } + } + + // Check CSeq + if got.GetCSeq() != wantedCseq { + t.Errorf("SIP Packet should be %d. Got : %d", wantedCseq, got.GetCSeq()) + } + } +} diff --git a/vendor/github.com/google/gopacket/layers/tcp.go b/vendor/github.com/google/gopacket/layers/tcp.go index fb731da1c9..6b37f56d0c 100644 --- a/vendor/github.com/google/gopacket/layers/tcp.go +++ b/vendor/github.com/google/gopacket/layers/tcp.go @@ -170,7 +170,7 @@ func (t *TCP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOpt } bytes[start+1] = o.OptionLength copy(bytes[start+2:start+len(o.OptionData)+2], o.OptionData) - start += int(o.OptionLength) + start += len(o.OptionData) + 2 } } copy(bytes[start:], t.Padding) @@ -225,6 +225,10 @@ func (t *TCP) flagsAndOffset() uint16 { } func (tcp *TCP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 20 { + df.SetTruncated() + return fmt.Errorf("Invalid TCP header. Length %d less than 20", len(data)) + } tcp.SrcPort = TCPPort(binary.BigEndian.Uint16(data[0:2])) tcp.sPort = data[0:2] tcp.DstPort = TCPPort(binary.BigEndian.Uint16(data[2:4])) @@ -244,7 +248,12 @@ func (tcp *TCP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { tcp.Window = binary.BigEndian.Uint16(data[14:16]) tcp.Checksum = binary.BigEndian.Uint16(data[16:18]) tcp.Urgent = binary.BigEndian.Uint16(data[18:20]) - tcp.Options = tcp.opts[:0] + if tcp.Options == nil { + // Pre-allocate to avoid allocating a slice. + tcp.Options = tcp.opts[:0] + } else { + tcp.Options = tcp.Options[:0] + } if tcp.DataOffset < 5 { return fmt.Errorf("Invalid TCP data offset %d < 5", tcp.DataOffset) } @@ -260,10 +269,6 @@ func (tcp *TCP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { // From here on, data points just to the header options. data = data[20:dataStart] for len(data) > 0 { - if tcp.Options == nil { - // Pre-allocate to avoid allocating a slice. - tcp.Options = tcp.opts[:0] - } tcp.Options = append(tcp.Options, TCPOption{OptionType: TCPOptionKind(data[0])}) opt := &tcp.Options[len(tcp.Options)-1] switch opt.OptionType { @@ -274,10 +279,15 @@ func (tcp *TCP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { case TCPOptionKindNop: // 1 byte padding opt.OptionLength = 1 default: + if len(data) < 2 { + df.SetTruncated() + return fmt.Errorf("Invalid TCP option length. Length %d less than 2", len(data)) + } opt.OptionLength = data[1] if opt.OptionLength < 2 { return fmt.Errorf("Invalid TCP option length %d < 2", opt.OptionLength) } else if int(opt.OptionLength) > len(data) { + df.SetTruncated() return fmt.Errorf("Invalid TCP option length %d exceeds remaining %d bytes", opt.OptionLength, len(data)) } opt.OptionData = data[2:opt.OptionLength] diff --git a/vendor/github.com/google/gopacket/layers/tcpip_test.go b/vendor/github.com/google/gopacket/layers/tcpip_test.go index c002e8491a..3193f5f620 100644 --- a/vendor/github.com/google/gopacket/layers/tcpip_test.go +++ b/vendor/github.com/google/gopacket/layers/tcpip_test.go @@ -55,7 +55,7 @@ func createUDPChecksumTestLayer() (udp *UDP) { } func TestIPv4UDPChecksum(t *testing.T) { - var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 2) + var serialize = make([]gopacket.SerializableLayer, 0, 2) var u *UDP var err error @@ -93,7 +93,7 @@ func TestIPv4UDPChecksum(t *testing.T) { } func TestIPv6UDPChecksumWithIPv6DstOpts(t *testing.T) { - var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 3) + var serialize = make([]gopacket.SerializableLayer, 0, 3) var u *UDP var err error @@ -135,7 +135,7 @@ func TestIPv6UDPChecksumWithIPv6DstOpts(t *testing.T) { } func TestIPv6JumbogramUDPChecksum(t *testing.T) { - var serialize []gopacket.SerializableLayer = make([]gopacket.SerializableLayer, 0, 4) + var serialize = make([]gopacket.SerializableLayer, 0, 4) var u *UDP var err error diff --git a/vendor/github.com/google/gopacket/layers/tls.go b/vendor/github.com/google/gopacket/layers/tls.go new file mode 100644 index 0000000000..ddb6ff9d29 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/tls.go @@ -0,0 +1,208 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "encoding/binary" + "errors" + + "github.com/google/gopacket" +) + +// TLSType defines the type of data after the TLS Record +type TLSType uint8 + +// TLSType known values. +const ( + TLSChangeCipherSpec TLSType = 20 + TLSAlert TLSType = 21 + TLSHandshake TLSType = 22 + TLSApplicationData TLSType = 23 + TLSUnknown TLSType = 255 +) + +// String shows the register type nicely formatted +func (tt TLSType) String() string { + switch tt { + default: + return "Unknown" + case TLSChangeCipherSpec: + return "Change Cipher Spec" + case TLSAlert: + return "Alert" + case TLSHandshake: + return "Handshake" + case TLSApplicationData: + return "Application Data" + } +} + +// TLSVersion represents the TLS version in numeric format +type TLSVersion uint16 + +// Strings shows the TLS version nicely formatted +func (tv TLSVersion) String() string { + switch tv { + default: + return "Unknown" + case 0x0200: + return "SSL 2.0" + case 0x0300: + return "SSL 3.0" + case 0x0301: + return "TLS 1.0" + case 0x0302: + return "TLS 1.1" + case 0x0303: + return "TLS 1.2" + case 0x0304: + return "TLS 1.3" + } +} + +// TLS is specified in RFC 5246 +// +// TLS Record Protocol +// 0 1 2 3 4 5 6 7 8 +// +--+--+--+--+--+--+--+--+ +// | Content Type | +// +--+--+--+--+--+--+--+--+ +// | Version (major) | +// +--+--+--+--+--+--+--+--+ +// | Version (minor) | +// +--+--+--+--+--+--+--+--+ +// | Length | +// +--+--+--+--+--+--+--+--+ +// | Length | +// +--+--+--+--+--+--+--+--+ + +// TLS is actually a slide of TLSrecord structures +type TLS struct { + BaseLayer + + // TLS Records + ChangeCipherSpec []TLSChangeCipherSpecRecord + Handshake []TLSHandshakeRecord + AppData []TLSAppDataRecord + Alert []TLSAlertRecord +} + +// TLSRecordHeader contains all the information that each TLS Record types should have +type TLSRecordHeader struct { + ContentType TLSType + Version TLSVersion + Length uint16 +} + +// LayerType returns gopacket.LayerTypeTLS. +func (t *TLS) LayerType() gopacket.LayerType { return LayerTypeTLS } + +// decodeTLS decodes the byte slice into a TLS type. It also +// setups the application Layer in PacketBuilder. +func decodeTLS(data []byte, p gopacket.PacketBuilder) error { + t := &TLS{} + err := t.DecodeFromBytes(data, p) + if err != nil { + return err + } + p.AddLayer(t) + p.SetApplicationLayer(t) + return nil +} + +// DecodeFromBytes decodes the slice into the TLS struct. +func (t *TLS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + t.BaseLayer.Contents = data + t.BaseLayer.Payload = nil + + t.ChangeCipherSpec = t.ChangeCipherSpec[:0] + t.Handshake = t.Handshake[:0] + t.AppData = t.AppData[:0] + t.Alert = t.Alert[:0] + + return t.decodeTLSRecords(data, df) +} + +func (t *TLS) decodeTLSRecords(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 5 { + df.SetTruncated() + return errors.New("TLS record too short") + } + + // since there are no further layers, the baselayer's content is + // pointing to this layer + t.BaseLayer = BaseLayer{Contents: data[:len(data)]} + + var h TLSRecordHeader + h.ContentType = TLSType(data[0]) + h.Version = TLSVersion(binary.BigEndian.Uint16(data[1:3])) + h.Length = binary.BigEndian.Uint16(data[3:5]) + + if h.ContentType.String() == "Unknown" { + return errors.New("Unknown TLS record type") + } + + hl := 5 // header length + tl := hl + int(h.Length) + if len(data) < tl { + df.SetTruncated() + return errors.New("TLS packet length mismatch") + } + + switch h.ContentType { + default: + return errors.New("Unknown TLS record type") + case TLSChangeCipherSpec: + var r TLSChangeCipherSpecRecord + e := r.decodeFromBytes(h, data[hl:tl], df) + if e != nil { + return e + } + t.ChangeCipherSpec = append(t.ChangeCipherSpec, r) + case TLSAlert: + var r TLSAlertRecord + e := r.decodeFromBytes(h, data[hl:tl], df) + if e != nil { + return e + } + t.Alert = append(t.Alert, r) + case TLSHandshake: + var r TLSHandshakeRecord + e := r.decodeFromBytes(h, data[hl:tl], df) + if e != nil { + return e + } + t.Handshake = append(t.Handshake, r) + case TLSApplicationData: + var r TLSAppDataRecord + e := r.decodeFromBytes(h, data[hl:tl], df) + if e != nil { + return e + } + t.AppData = append(t.AppData, r) + } + + if len(data) == tl { + return nil + } + return t.decodeTLSRecords(data[tl:len(data)], df) +} + +// CanDecode implements gopacket.DecodingLayer. +func (t *TLS) CanDecode() gopacket.LayerClass { + return LayerTypeTLS +} + +// NextLayerType implements gopacket.DecodingLayer. +func (t *TLS) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypeZero +} + +// Payload returns nil, since TLS encrypted payload is inside TLSAppDataRecord +func (t *TLS) Payload() []byte { + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/tls_alert.go b/vendor/github.com/google/gopacket/layers/tls_alert.go new file mode 100644 index 0000000000..0c5aee0218 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/tls_alert.go @@ -0,0 +1,165 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "errors" + "fmt" + + "github.com/google/gopacket" +) + +// TLSAlertLevel defines the alert level data type +type TLSAlertLevel uint8 + +// TLSAlertDescr defines the alert descrption data type +type TLSAlertDescr uint8 + +const ( + TLSAlertWarning TLSAlertLevel = 1 + TLSAlertFatal TLSAlertLevel = 2 + TLSAlertUnknownLevel TLSAlertLevel = 255 + + TLSAlertCloseNotify TLSAlertDescr = 0 + TLSAlertUnexpectedMessage TLSAlertDescr = 10 + TLSAlertBadRecordMac TLSAlertDescr = 20 + TLSAlertDecryptionFailedRESERVED TLSAlertDescr = 21 + TLSAlertRecordOverflow TLSAlertDescr = 22 + TLSAlertDecompressionFailure TLSAlertDescr = 30 + TLSAlertHandshakeFailure TLSAlertDescr = 40 + TLSAlertNoCertificateRESERVED TLSAlertDescr = 41 + TLSAlertBadCertificate TLSAlertDescr = 42 + TLSAlertUnsupportedCertificate TLSAlertDescr = 43 + TLSAlertCertificateRevoked TLSAlertDescr = 44 + TLSAlertCertificateExpired TLSAlertDescr = 45 + TLSAlertCertificateUnknown TLSAlertDescr = 46 + TLSAlertIllegalParameter TLSAlertDescr = 47 + TLSAlertUnknownCa TLSAlertDescr = 48 + TLSAlertAccessDenied TLSAlertDescr = 49 + TLSAlertDecodeError TLSAlertDescr = 50 + TLSAlertDecryptError TLSAlertDescr = 51 + TLSAlertExportRestrictionRESERVED TLSAlertDescr = 60 + TLSAlertProtocolVersion TLSAlertDescr = 70 + TLSAlertInsufficientSecurity TLSAlertDescr = 71 + TLSAlertInternalError TLSAlertDescr = 80 + TLSAlertUserCanceled TLSAlertDescr = 90 + TLSAlertNoRenegotiation TLSAlertDescr = 100 + TLSAlertUnsupportedExtension TLSAlertDescr = 110 + TLSAlertUnknownDescription TLSAlertDescr = 255 +) + +// TLS Alert +// 0 1 2 3 4 5 6 7 8 +// +--+--+--+--+--+--+--+--+ +// | Level | +// +--+--+--+--+--+--+--+--+ +// | Description | +// +--+--+--+--+--+--+--+--+ + +// TLSAlertRecord contains all the information that each Alert Record type should have +type TLSAlertRecord struct { + TLSRecordHeader + + Level TLSAlertLevel + Description TLSAlertDescr + + EncryptedMsg []byte +} + +// DecodeFromBytes decodes the slice into the TLS struct. +func (t *TLSAlertRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error { + // TLS Record Header + t.ContentType = h.ContentType + t.Version = h.Version + t.Length = h.Length + + if len(data) < 2 { + df.SetTruncated() + return errors.New("TLS Alert packet too short") + } + + if t.Length == 2 { + t.Level = TLSAlertLevel(data[0]) + t.Description = TLSAlertDescr(data[1]) + } else { + t.Level = TLSAlertUnknownLevel + t.Description = TLSAlertUnknownDescription + t.EncryptedMsg = data + } + + return nil +} + +// Strings shows the TLS alert level nicely formatted +func (al TLSAlertLevel) String() string { + switch al { + default: + return fmt.Sprintf("Unknown(%d)", al) + case TLSAlertWarning: + return "Warning" + case TLSAlertFatal: + return "Fatal" + } +} + +// Strings shows the TLS alert description nicely formatted +func (ad TLSAlertDescr) String() string { + switch ad { + default: + return "Unknown" + case TLSAlertCloseNotify: + return "close_notify" + case TLSAlertUnexpectedMessage: + return "unexpected_message" + case TLSAlertBadRecordMac: + return "bad_record_mac" + case TLSAlertDecryptionFailedRESERVED: + return "decryption_failed_RESERVED" + case TLSAlertRecordOverflow: + return "record_overflow" + case TLSAlertDecompressionFailure: + return "decompression_failure" + case TLSAlertHandshakeFailure: + return "handshake_failure" + case TLSAlertNoCertificateRESERVED: + return "no_certificate_RESERVED" + case TLSAlertBadCertificate: + return "bad_certificate" + case TLSAlertUnsupportedCertificate: + return "unsupported_certificate" + case TLSAlertCertificateRevoked: + return "certificate_revoked" + case TLSAlertCertificateExpired: + return "certificate_expired" + case TLSAlertCertificateUnknown: + return "certificate_unknown" + case TLSAlertIllegalParameter: + return "illegal_parameter" + case TLSAlertUnknownCa: + return "unknown_ca" + case TLSAlertAccessDenied: + return "access_denied" + case TLSAlertDecodeError: + return "decode_error" + case TLSAlertDecryptError: + return "decrypt_error" + case TLSAlertExportRestrictionRESERVED: + return "export_restriction_RESERVED" + case TLSAlertProtocolVersion: + return "protocol_version" + case TLSAlertInsufficientSecurity: + return "insufficient_security" + case TLSAlertInternalError: + return "internal_error" + case TLSAlertUserCanceled: + return "user_canceled" + case TLSAlertNoRenegotiation: + return "no_renegotiation" + case TLSAlertUnsupportedExtension: + return "unsupported_extension" + } +} diff --git a/vendor/github.com/google/gopacket/layers/tls_appdata.go b/vendor/github.com/google/gopacket/layers/tls_appdata.go new file mode 100644 index 0000000000..dedd1d587b --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/tls_appdata.go @@ -0,0 +1,34 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "errors" + + "github.com/google/gopacket" +) + +// TLSAppDataRecord contains all the information that each AppData Record types should have +type TLSAppDataRecord struct { + TLSRecordHeader + Payload []byte +} + +// DecodeFromBytes decodes the slice into the TLS struct. +func (t *TLSAppDataRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error { + // TLS Record Header + t.ContentType = h.ContentType + t.Version = h.Version + t.Length = h.Length + + if len(data) != int(t.Length) { + return errors.New("TLS Application Data length mismatch") + } + + t.Payload = data + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/tls_cipherspec.go b/vendor/github.com/google/gopacket/layers/tls_cipherspec.go new file mode 100644 index 0000000000..8f3dc62ba5 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/tls_cipherspec.go @@ -0,0 +1,64 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "errors" + + "github.com/google/gopacket" +) + +// TLSchangeCipherSpec defines the message value inside ChangeCipherSpec Record +type TLSchangeCipherSpec uint8 + +const ( + TLSChangecipherspecMessage TLSchangeCipherSpec = 1 + TLSChangecipherspecUnknown TLSchangeCipherSpec = 255 +) + +// TLS Change Cipher Spec +// 0 1 2 3 4 5 6 7 8 +// +--+--+--+--+--+--+--+--+ +// | Message | +// +--+--+--+--+--+--+--+--+ + +// TLSChangeCipherSpecRecord defines the type of data inside ChangeCipherSpec Record +type TLSChangeCipherSpecRecord struct { + TLSRecordHeader + + Message TLSchangeCipherSpec +} + +// DecodeFromBytes decodes the slice into the TLS struct. +func (t *TLSChangeCipherSpecRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error { + // TLS Record Header + t.ContentType = h.ContentType + t.Version = h.Version + t.Length = h.Length + + if len(data) != 1 { + df.SetTruncated() + return errors.New("TLS Change Cipher Spec record incorrect length") + } + + t.Message = TLSchangeCipherSpec(data[0]) + if t.Message != TLSChangecipherspecMessage { + t.Message = TLSChangecipherspecUnknown + } + + return nil +} + +// String shows the message value nicely formatted +func (ccs TLSchangeCipherSpec) String() string { + switch ccs { + default: + return "Unknown" + case TLSChangecipherspecMessage: + return "Change Cipher Spec Message" + } +} diff --git a/vendor/github.com/google/gopacket/layers/tls_handshake.go b/vendor/github.com/google/gopacket/layers/tls_handshake.go new file mode 100644 index 0000000000..e45e2c7cbc --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/tls_handshake.go @@ -0,0 +1,28 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "github.com/google/gopacket" +) + +// TLSHandshakeRecord defines the structure of a Handshare Record +type TLSHandshakeRecord struct { + TLSRecordHeader +} + +// DecodeFromBytes decodes the slice into the TLS struct. +func (t *TLSHandshakeRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error { + // TLS Record Header + t.ContentType = h.ContentType + t.Version = h.Version + t.Length = h.Length + + // TODO + + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/tls_test.go b/vendor/github.com/google/gopacket/layers/tls_test.go new file mode 100644 index 0000000000..61d4c4eb39 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/tls_test.go @@ -0,0 +1,339 @@ +package layers + +import ( + "reflect" + "testing" + + "github.com/google/gopacket" +) + +// https://github.com/tintinweb/scapy-ssl_tls/blob/master/tests/files/RSA_WITH_AES_128_CBC_SHA.pcap +// WARNING! Tests are specific for each packet. If you change a packet, please review their tests. + +// Packet 4 - Client Hello (full packet, from Ethernet to TLS layers) +var testClientHello = []byte{ + 0x00, 0x0c, 0x29, 0x1f, 0xab, 0x17, 0x00, 0x50, 0x56, 0xc0, 0x00, 0x08, 0x08, 0x00, 0x45, 0x00, + 0x00, 0xfe, 0x71, 0x42, 0x40, 0x00, 0x80, 0x06, 0x4e, 0xe1, 0xc0, 0xa8, 0xdc, 0x01, 0xc0, 0xa8, + 0xdc, 0x83, 0x2f, 0x0e, 0x01, 0xbb, 0x25, 0x6c, 0xbd, 0x3d, 0xcc, 0xce, 0xe1, 0xf7, 0x50, 0x18, + 0xff, 0xff, 0x7c, 0xaf, 0x00, 0x00, 0x16, 0x03, 0x01, 0x00, 0xd1, 0x01, 0x00, 0x00, 0xcd, 0x03, + 0x01, 0xff, 0xa2, 0x88, 0x97, 0x7c, 0x41, 0xa1, 0x08, 0x34, 0x2c, 0x98, 0xc2, 0x70, 0x04, 0xa0, + 0x5d, 0x5f, 0x39, 0xef, 0xe0, 0x70, 0xd5, 0x12, 0xf1, 0x35, 0x17, 0xb6, 0x0d, 0xc4, 0xd3, 0x09, + 0x85, 0x00, 0x00, 0x5a, 0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x39, 0x00, 0x38, 0x00, 0x88, 0x00, 0x87, + 0xc0, 0x0f, 0xc0, 0x05, 0x00, 0x35, 0x00, 0x84, 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x33, 0x00, 0x32, + 0x00, 0x9a, 0x00, 0x99, 0x00, 0x45, 0x00, 0x44, 0xc0, 0x0e, 0xc0, 0x04, 0x00, 0x2f, 0x00, 0x96, + 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, 0xc0, 0x02, 0x00, 0x05, 0x00, 0x04, 0xc0, 0x12, + 0xc0, 0x08, 0x00, 0x16, 0x00, 0x13, 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x12, + 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, 0x00, 0x08, 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, 0x02, 0x01, + 0x00, 0x00, 0x49, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, 0x00, 0x34, 0x00, + 0x32, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x09, 0x00, + 0x0a, 0x00, 0x16, 0x00, 0x17, 0x00, 0x08, 0x00, 0x06, 0x00, 0x07, 0x00, 0x14, 0x00, 0x15, 0x00, + 0x04, 0x00, 0x05, 0x00, 0x12, 0x00, 0x13, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x0f, 0x00, + 0x10, 0x00, 0x11, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x01, +} +var testClientHelloDecoded = &TLS{ + BaseLayer: BaseLayer{ + Contents: testClientHello[54:], + Payload: nil, + }, + ChangeCipherSpec: nil, + Handshake: []TLSHandshakeRecord{ + { + TLSRecordHeader{ + ContentType: 22, + Version: 0x0301, + Length: 209, + }, + }, + }, + AppData: nil, + Alert: nil, +} + +// Packet 6 - Server Hello, Certificate, Server Hello Done +var testServerHello = []byte{ + 0x16, 0x03, 0x01, 0x00, 0x3a, 0x02, 0x00, 0x00, 0x36, 0x03, 0x01, 0x55, 0x5c, 0xd6, 0x97, 0xa3, + 0x97, 0xe9, 0xf4, 0x0c, 0xf4, 0x56, 0x14, 0x9f, 0xe4, 0x24, 0xf9, 0xeb, 0x49, 0xd4, 0xd1, 0x5f, + 0xfc, 0x12, 0xb4, 0xfd, 0x45, 0x4e, 0x3d, 0xeb, 0x6a, 0xad, 0xcf, 0x00, 0x00, 0x2f, 0x01, 0x00, + 0x0e, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x01, 0x16, + 0x03, 0x01, 0x01, 0x90, 0x0b, 0x00, 0x01, 0x8c, 0x00, 0x01, 0x89, 0x00, 0x01, 0x86, 0x30, 0x82, + 0x01, 0x82, 0x30, 0x82, 0x01, 0x2c, 0x02, 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, 0x30, 0x38, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x03, 0x51, 0x4c, 0x44, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, + 0x53, 0x53, 0x4c, 0x65, 0x61, 0x79, 0x2f, 0x72, 0x73, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, + 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x39, 0x35, 0x31, 0x30, 0x30, 0x39, 0x32, 0x33, 0x33, 0x32, + 0x30, 0x35, 0x5a, 0x17, 0x0d, 0x39, 0x38, 0x30, 0x37, 0x30, 0x35, 0x32, 0x33, 0x33, 0x32, 0x30, + 0x35, 0x5a, 0x30, 0x60, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, + 0x55, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x03, 0x51, 0x4c, 0x44, 0x31, + 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x4d, 0x69, 0x6e, 0x63, 0x6f, 0x6d, + 0x20, 0x50, 0x74, 0x79, 0x2e, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x0b, 0x13, 0x02, 0x43, 0x53, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x12, 0x53, 0x53, 0x4c, 0x65, 0x61, 0x79, 0x20, 0x64, 0x65, 0x6d, 0x6f, 0x20, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xb7, 0x2c, 0x25, + 0xdc, 0x49, 0xc5, 0xae, 0x6b, 0x43, 0xc5, 0x2e, 0x41, 0xc1, 0x2e, 0x6d, 0x95, 0x7a, 0x3a, 0xa9, + 0x03, 0x51, 0x78, 0x45, 0x0f, 0x2a, 0xd1, 0x58, 0xd1, 0x88, 0xf6, 0x9f, 0x8f, 0x1f, 0xd9, 0xfd, + 0xa5, 0x87, 0xde, 0x2a, 0x5d, 0x31, 0x5b, 0xee, 0x24, 0x66, 0xbf, 0xc0, 0x55, 0xdb, 0xfe, 0x70, + 0xc5, 0x2c, 0x39, 0x5f, 0x5a, 0x9f, 0xa8, 0x08, 0xfc, 0x21, 0x06, 0xd5, 0x4f, 0x02, 0x03, 0x01, + 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04, 0x05, + 0x00, 0x03, 0x41, 0x00, 0x2b, 0x34, 0x5b, 0x22, 0x85, 0x62, 0x23, 0x07, 0x36, 0xf4, 0x0c, 0x2b, + 0x14, 0xd0, 0x1b, 0xcb, 0xd9, 0xbb, 0xd2, 0xc0, 0x9a, 0xcf, 0x12, 0xa1, 0x65, 0x90, 0x3a, 0xb7, + 0x17, 0x83, 0x3a, 0x10, 0x6b, 0xad, 0x2f, 0xd6, 0xb1, 0x11, 0xc0, 0x0d, 0x5a, 0x06, 0xdb, 0x11, + 0xd0, 0x2f, 0x34, 0x90, 0xf5, 0x76, 0x61, 0x26, 0xa1, 0x69, 0xf2, 0xdb, 0xb3, 0xe7, 0x20, 0xcb, + 0x3a, 0x64, 0xe6, 0x41, 0x16, 0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, +} + +// Packet 7 - Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message +var testClientKeyExchange = []byte{ + 0x16, 0x03, 0x01, 0x00, 0x46, 0x10, 0x00, 0x00, 0x42, 0x00, 0x40, 0x9e, 0x73, 0xdf, 0xe0, 0xf2, + 0xd0, 0x40, 0x32, 0x44, 0x9a, 0x34, 0x7f, 0x57, 0x86, 0x10, 0xea, 0x3d, 0xc5, 0xe2, 0xf9, 0xa5, + 0x69, 0x43, 0xc9, 0x0b, 0x00, 0x7e, 0x91, 0x31, 0x57, 0xfc, 0xc5, 0x65, 0x18, 0x0d, 0x44, 0xfd, + 0x51, 0xf8, 0xda, 0x8a, 0x7a, 0xab, 0x16, 0x03, 0xeb, 0xac, 0x23, 0x6e, 0x8d, 0xdd, 0xbb, 0xf4, + 0x75, 0xe7, 0xb7, 0xa3, 0xce, 0xdb, 0x67, 0x6b, 0x7d, 0x30, 0x2a, 0x14, 0x03, 0x01, 0x00, 0x01, + 0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0x15, 0xcb, 0x7a, 0x5b, 0x2d, 0xc0, 0x27, 0x09, 0x28, 0x62, + 0x95, 0x44, 0x9f, 0xa1, 0x1e, 0x4e, 0x6a, 0xfb, 0x49, 0x9d, 0x6a, 0x24, 0x44, 0xc6, 0x8e, 0x26, + 0xbc, 0xc1, 0x28, 0x8c, 0x27, 0xcc, 0xa2, 0xba, 0xec, 0x38, 0x63, 0x6e, 0x64, 0xd8, 0x52, 0x94, + 0x17, 0x96, 0x61, 0xfd, 0x9c, 0x54, +} +var testClientKeyExchangeDecoded = &TLS{ + BaseLayer: BaseLayer{ + Contents: testClientKeyExchange[81:], + Payload: nil, + }, + ChangeCipherSpec: []TLSChangeCipherSpecRecord{ + { + TLSRecordHeader{ + ContentType: 20, + Version: 0x0301, + Length: 1, + }, + 1, + }, + }, + Handshake: []TLSHandshakeRecord{ + { + TLSRecordHeader{ + ContentType: 22, + Version: 0x0301, + Length: 70, + }, + }, + { + TLSRecordHeader{ + ContentType: 22, + Version: 0x0301, + Length: 48, + }, + }, + }, + AppData: nil, + Alert: nil, +} + +// Packet 9 - New Session Ticket, Change Cipher Spec, Encryption Handshake Message +var testNewSessionTicket = []byte{ + 0x16, 0x03, 0x01, 0x00, 0xaa, 0x04, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x1c, 0x20, 0x00, 0xa0, 0xd4, + 0xee, 0xb0, 0x9b, 0xb5, 0xa2, 0xd3, 0x00, 0x57, 0x84, 0x59, 0xec, 0x0d, 0xbf, 0x05, 0x0c, 0xd5, + 0xb9, 0xe2, 0xf8, 0x32, 0xb5, 0xec, 0xce, 0xe2, 0x9c, 0x25, 0x25, 0xd9, 0x3e, 0x4a, 0x94, 0x5b, + 0xca, 0x18, 0x2b, 0x0f, 0x5f, 0xf6, 0x73, 0x38, 0x62, 0xcd, 0xcc, 0xf1, 0x32, 0x39, 0xe4, 0x5e, + 0x30, 0xf3, 0x94, 0xf5, 0xc5, 0x94, 0x3a, 0x8c, 0x8e, 0xe5, 0x12, 0x4a, 0x1e, 0xd8, 0x31, 0xb5, + 0x17, 0x09, 0xa6, 0x4c, 0x69, 0xca, 0xae, 0xfb, 0x04, 0x17, 0x64, 0x54, 0x9e, 0xc2, 0xfa, 0xf3, + 0x6d, 0xe9, 0xa5, 0xed, 0xa6, 0x65, 0xfe, 0x2f, 0xf3, 0xc6, 0xce, 0x78, 0x40, 0xf7, 0x65, 0xe0, + 0x13, 0xd3, 0x77, 0xc7, 0xc5, 0x79, 0x16, 0x56, 0x4c, 0x30, 0x94, 0xcf, 0xb0, 0x3c, 0x00, 0x91, + 0xbd, 0x86, 0x08, 0x9f, 0x2f, 0x05, 0x67, 0x03, 0x6f, 0xa7, 0x3b, 0xb9, 0x36, 0xf2, 0x80, 0x4f, + 0x60, 0x5d, 0x4c, 0xc4, 0x42, 0x5d, 0x02, 0x44, 0xba, 0x31, 0x8f, 0x39, 0x8e, 0x0c, 0x1e, 0xa8, + 0x26, 0x4f, 0x3e, 0x01, 0x96, 0xb3, 0x6f, 0xc6, 0x25, 0xe4, 0x30, 0x03, 0xd6, 0x3a, 0x7d, 0x14, + 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0x25, 0xb8, 0x58, 0xc1, 0xa6, 0x3f, + 0xf8, 0xbd, 0xe6, 0xae, 0xbd, 0x98, 0xd4, 0x75, 0xa5, 0x45, 0x1b, 0xd8, 0x6a, 0x70, 0x79, 0x86, + 0x29, 0x4e, 0x4f, 0x64, 0xba, 0xe7, 0x1f, 0xca, 0x4b, 0x96, 0x9b, 0xf7, 0x0b, 0x50, 0xf5, 0x4f, + 0xfd, 0xda, 0xda, 0xcd, 0xcd, 0x4b, 0x12, 0x2e, 0xdf, 0xd5, +} + +// Packet 13 - Two Application Data Records +var testDoubleAppData = []byte{ + 0x17, 0x03, 0x01, 0x00, 0x20, 0x77, 0x3a, 0x94, 0x7d, 0xb4, 0x47, 0x4a, 0x1d, 0xd4, 0x6c, 0x5a, + 0x69, 0x74, 0x03, 0x93, 0x32, 0xca, 0x54, 0x5e, 0xa5, 0x81, 0x99, 0x6a, 0x73, 0x66, 0xbf, 0x06, + 0xa0, 0xdc, 0x6a, 0x9c, 0xb1, 0x17, 0x03, 0x01, 0x00, 0x20, 0x44, 0x64, 0xc8, 0xc2, 0x5a, 0xfc, + 0x4a, 0x82, 0xdd, 0x53, 0x6d, 0x30, 0x82, 0x4d, 0x35, 0x22, 0xf1, 0x5f, 0x3b, 0x96, 0x66, 0x79, + 0x61, 0x9f, 0x51, 0x93, 0x1b, 0xbf, 0x53, 0x3b, 0xf8, 0x26, +} +var testDoubleAppDataDecoded = &TLS{ + BaseLayer: BaseLayer{ + Contents: testDoubleAppData[37:], + Payload: nil, + }, + ChangeCipherSpec: nil, + Handshake: nil, + AppData: []TLSAppDataRecord{ + { + TLSRecordHeader{ + ContentType: 23, + Version: 0x0301, + Length: 32, + }, + testDoubleAppData[5 : 5+32], + }, + { + TLSRecordHeader{ + ContentType: 23, + Version: 0x0301, + Length: 32, + }, + testDoubleAppData[42 : 42+32], + }, + }, + Alert: nil, +} + +var testAlertEncrypted = []byte{ + 0x15, 0x03, 0x03, 0x00, 0x20, 0x44, 0xb9, 0x9c, 0x2c, 0x6e, 0xab, 0xa3, 0xdf, 0xb1, 0x77, 0x04, + 0xa2, 0xa4, 0x3a, 0x9a, 0x08, 0x1d, 0xe6, 0x51, 0xac, 0xa0, 0x5f, 0xab, 0x74, 0xa7, 0x96, 0x24, + 0xfe, 0x62, 0xfe, 0xe8, 0x5e, +} +var testAlertEncryptedDecoded = &TLS{ + BaseLayer: BaseLayer{ + Contents: testAlertEncrypted, + Payload: nil, + }, + ChangeCipherSpec: nil, + Handshake: nil, + AppData: nil, + Alert: []TLSAlertRecord{ + { + TLSRecordHeader{ + ContentType: 21, + Version: 0x0303, + Length: 32, + }, + 0xFF, + 0xFF, + testAlertEncrypted[5:], + }, + }, +} + +// Malformed TLS records +var testMalformed = []byte{ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, +} + +var testTLSDecodeOptions = gopacket.DecodeOptions{ + SkipDecodeRecovery: true, + DecodeStreamsAsDatagrams: true, +} + +func TestParseTLSClientHello(t *testing.T) { + p := gopacket.NewPacket(testClientHello, LinkTypeEthernet, testTLSDecodeOptions) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeTCP, LayerTypeTLS}, t) + + if got, ok := p.Layer(LayerTypeTLS).(*TLS); ok { + want := testClientHelloDecoded + if !reflect.DeepEqual(got, want) { + t.Errorf("TLS ClientHello packet processing failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } + } else { + t.Error("No TLS layer type found in packet") + } +} + +func testTLSClientHelloDecodeFromBytes(t *testing.T) { + var got TLS + want := testClientKeyExchangeDecoded + + if err := got.DecodeFromBytes(testClientKeyExchange, gopacket.NilDecodeFeedback); err != nil { + t.Errorf("TLS DecodeFromBytes first decode failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("TLS DecodeFromBytes first decode doesn't match:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } + + if err := got.DecodeFromBytes(testClientKeyExchange, gopacket.NilDecodeFeedback); err != nil { + t.Errorf("TLS DecodeFromBytes second decode failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("TLS DecodeFromBytes second decode doesn't match:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } +} + +func TestParseTLSChangeCipherSpec(t *testing.T) { + p := gopacket.NewPacket(testClientKeyExchange, LayerTypeTLS, testTLSDecodeOptions) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeTLS}, t) + + if got, ok := p.Layer(LayerTypeTLS).(*TLS); ok { + want := testClientKeyExchangeDecoded + if !reflect.DeepEqual(got, want) { + t.Errorf("TLS ChangeCipherSpec packet processing failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } + } else { + t.Error("No TLS layer type found in packet") + } +} + +func TestParseTLSAppData(t *testing.T) { + p := gopacket.NewPacket(testDoubleAppData, LayerTypeTLS, testTLSDecodeOptions) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeTLS}, t) + + if got, ok := p.Layer(LayerTypeTLS).(*TLS); ok { + want := testDoubleAppDataDecoded + if !reflect.DeepEqual(got, want) { + t.Errorf("TLS TLSAppData packet processing failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } + } else { + t.Error("No TLS layer type found in packet") + } +} + +func TestParseTLSMalformed(t *testing.T) { + p := gopacket.NewPacket(testMalformed, LayerTypeTLS, testTLSDecodeOptions) + if p.ErrorLayer() == nil { + t.Error("No Decoding Error when parsing a malformed data") + } +} + +func TestParseTLSTooShort(t *testing.T) { + p := gopacket.NewPacket(testMalformed[0:2], LayerTypeTLS, testTLSDecodeOptions) + if p.ErrorLayer() == nil { + t.Error("No Decoding Error when parsing a malformed data") + } +} + +func TestParseTLSLengthMismatch(t *testing.T) { + var testLengthMismatch = make([]byte, len(testDoubleAppData)) + copy(testLengthMismatch, testDoubleAppData) + testLengthMismatch[3] = 0xFF + testLengthMismatch[4] = 0xFF + p := gopacket.NewPacket(testLengthMismatch, LayerTypeTLS, testTLSDecodeOptions) + if p.ErrorLayer() == nil { + t.Error("No Decoding Error when parsing a malformed data") + } +} + +func TestParseTLSAlertEncrypted(t *testing.T) { + p := gopacket.NewPacket(testAlertEncrypted, LayerTypeTLS, testTLSDecodeOptions) + if p.ErrorLayer() != nil { + t.Error("Failed to decode packet:", p.ErrorLayer().Error()) + } + checkLayers(p, []gopacket.LayerType{LayerTypeTLS}, t) + + if got, ok := p.Layer(LayerTypeTLS).(*TLS); ok { + want := testAlertEncryptedDecoded + if !reflect.DeepEqual(got, want) { + t.Errorf("TLS TLSAlert packet processing failed:\ngot:\n%#v\n\nwant:\n%#v\n\n", got, want) + } + } else { + t.Error("No TLS layer type found in packet") + } +} diff --git a/vendor/github.com/google/gopacket/layers/udp.go b/vendor/github.com/google/gopacket/layers/udp.go index 4c88ecbc07..97e81c69fc 100644 --- a/vendor/github.com/google/gopacket/layers/udp.go +++ b/vendor/github.com/google/gopacket/layers/udp.go @@ -10,6 +10,7 @@ package layers import ( "encoding/binary" "fmt" + "github.com/google/gopacket" ) @@ -27,6 +28,10 @@ type UDP struct { func (u *UDP) LayerType() gopacket.LayerType { return LayerTypeUDP } func (udp *UDP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 8 { + df.SetTruncated() + return fmt.Errorf("Invalid UDP header. Length %d less than 8", len(data)) + } udp.SrcPort = UDPPort(binary.BigEndian.Uint16(data[0:2])) udp.sPort = data[0:2] udp.DstPort = UDPPort(binary.BigEndian.Uint16(data[2:4])) diff --git a/vendor/github.com/google/gopacket/layers/vxlan.go b/vendor/github.com/google/gopacket/layers/vxlan.go index 08f1ecb4dc..4f79ea4eae 100644 --- a/vendor/github.com/google/gopacket/layers/vxlan.go +++ b/vendor/github.com/google/gopacket/layers/vxlan.go @@ -72,6 +72,10 @@ func (vx *VXLAN) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Serialize return err } + // PrependBytes does not guarantee that bytes are zeroed. Setting flags via OR requires that they start off at zero + bytes[0] = 0 + bytes[1] = 0 + if vx.ValidIDFlag { bytes[0] |= 0x08 } diff --git a/vendor/github.com/google/gopacket/macs/gen.go b/vendor/github.com/google/gopacket/macs/gen.go index ccfcc34f41..1fb685facc 100644 --- a/vendor/github.com/google/gopacket/macs/gen.go +++ b/vendor/github.com/google/gopacket/macs/gen.go @@ -46,7 +46,7 @@ var ValidMACPrefixMap = validMACPrefixMap var validMACPrefixMap = map[[3]byte]string{ ` -var url = flag.String("url", "http://standards.ieee.org/develop/regauth/oui/oui.txt", "URL to fetch MACs from") +var url = flag.String("url", "http://standards-oui.ieee.org/oui/oui.txt", "URL to fetch MACs from") type mac struct { prefix [3]byte @@ -60,6 +60,7 @@ func (m macs) Less(i, j int) bool { return bytes.Compare(m[i].prefix[:], m[j].pr func (m macs) Swap(i, j int) { m[i], m[j] = m[j], m[i] } func main() { + flag.Parse() fmt.Fprintf(os.Stderr, "Fetching MACs from %q\n", *url) resp, err := http.Get(*url) if err != nil { diff --git a/vendor/github.com/google/gopacket/macs/valid_mac_prefixes.go b/vendor/github.com/google/gopacket/macs/valid_mac_prefixes.go index 0a93cad0b6..19043aa895 100644 --- a/vendor/github.com/google/gopacket/macs/valid_mac_prefixes.go +++ b/vendor/github.com/google/gopacket/macs/valid_mac_prefixes.go @@ -7,8 +7,8 @@ package macs // Created by gen.go, don't edit manually -// Generated at 2017-09-19 13:06:19.654271144 -0600 MDT -// Fetched from "http://standards.ieee.org/develop/regauth/oui/oui.txt" +// Generated at 2018-09-13 15:43:56.426726842 +0200 CEST m=+27.853121393 +// Fetched from "http://standards-oui.ieee.org/oui/oui.txt" // ValidMACPrefixMap maps a valid MAC address prefix to the name of the // organization that owns the rights to use it. We map it to a hidden @@ -183,7 +183,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 0, 165}: "Tattile SRL", [3]byte{0, 0, 166}: "NETWORK GENERAL CORPORATION", [3]byte{0, 0, 167}: "NETWORK COMPUTING DEVICES INC.", - [3]byte{0, 0, 168}: "STRATUS COMPUTER INC.", + [3]byte{0, 0, 168}: "Stratus Technologies", [3]byte{0, 0, 169}: "NETWORK SYSTEMS CORP.", [3]byte{0, 0, 170}: "XEROX CORPORATION", [3]byte{0, 0, 171}: "LOGIC MODELING CORPORATION", @@ -204,13 +204,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 0, 186}: "SIIG, INC.", [3]byte{0, 0, 187}: "TRI-DATA", [3]byte{0, 0, 188}: "Rockwell Automation", - [3]byte{0, 0, 189}: "MITSUBISHI CABLE COMPANY", + [3]byte{0, 0, 189}: "Mitsubishi Cable Industries, Ltd. / Ryosei Systems", [3]byte{0, 0, 190}: "THE NTI GROUP", [3]byte{0, 0, 191}: "SYMMETRIC COMPUTER SYSTEMS", [3]byte{0, 0, 192}: "WESTERN DIGITAL CORPORATION", [3]byte{0, 0, 193}: "Madge Ltd.", [3]byte{0, 0, 194}: "INFORMATION PRESENTATION TECH.", - [3]byte{0, 0, 195}: "HARRIS CORP COMPUTER SYS DIV", + [3]byte{0, 0, 195}: "Harris Corporation", [3]byte{0, 0, 196}: "WATERS DIV. OF MILLIPORE", [3]byte{0, 0, 197}: "ARRIS Group, Inc.", [3]byte{0, 0, 198}: "EON SYSTEMS", @@ -273,8 +273,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 0, 255}: "CAMTEC ELECTRONICS LTD.", [3]byte{0, 1, 0}: "EQUIP'TRANS", [3]byte{0, 1, 1}: "Private", - [3]byte{0, 1, 2}: "3COM CORPORATION", - [3]byte{0, 1, 3}: "3COM CORPORATION", + [3]byte{0, 1, 2}: "3COM", + [3]byte{0, 1, 3}: "3COM", [3]byte{0, 1, 4}: "DVICO Co., Ltd.", [3]byte{0, 1, 5}: "Beckhoff Automation GmbH", [3]byte{0, 1, 6}: "Tews Datentechnik GmbH", @@ -304,7 +304,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 1, 30}: "Precidia Technologies, Inc.", [3]byte{0, 1, 31}: "RC Networks, Inc.", [3]byte{0, 1, 32}: "OSCILLOQUARTZ S.A.", - [3]byte{0, 1, 33}: "Watchguard Technologies, Inc.", + [3]byte{0, 1, 33}: "WatchGuard Technologies, Inc.", [3]byte{0, 1, 34}: "Trend Communications, Ltd.", [3]byte{0, 1, 35}: "Schneider Electric Japan Holdings Ltd.", [3]byte{0, 1, 36}: "Acer Incorporated", @@ -344,7 +344,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 1, 70}: "Tesco Controls, Inc.", [3]byte{0, 1, 71}: "Zhone Technologies", [3]byte{0, 1, 72}: "X-traWeb Inc.", - [3]byte{0, 1, 73}: "T.D.T. Transfer Data Test GmbH", + [3]byte{0, 1, 73}: "TDT AG", [3]byte{0, 1, 74}: "Sony Corporation", [3]byte{0, 1, 75}: "Ennovate Networks, Inc.", [3]byte{0, 1, 76}: "Berkeley Process Control", @@ -456,7 +456,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 1, 182}: "SAEJIN T&M Co., Ltd.", [3]byte{0, 1, 183}: "Centos, Inc.", [3]byte{0, 1, 184}: "Netsensity, Inc.", - [3]byte{0, 1, 185}: "SKF Condition Monitoring", + [3]byte{0, 1, 185}: "SKF (U.K.) Limited", [3]byte{0, 1, 186}: "IC-Net, Inc.", [3]byte{0, 1, 187}: "Frequentis", [3]byte{0, 1, 188}: "Brains Corporation", @@ -471,8 +471,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 1, 197}: "Simpler Networks", [3]byte{0, 1, 198}: "Quarry Technologies", [3]byte{0, 1, 199}: "Cisco Systems, Inc", - [3]byte{0, 1, 200}: "THOMAS CONRAD CORP.", [3]byte{0, 1, 200}: "CONRAD CORP.", + [3]byte{0, 1, 200}: "THOMAS CONRAD CORP.", [3]byte{0, 1, 201}: "Cisco Systems, Inc", [3]byte{0, 1, 202}: "Geocast Network Systems, Inc.", [3]byte{0, 1, 203}: "EVR", @@ -591,7 +591,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 2, 60}: "Creative Technology, Ltd.", [3]byte{0, 2, 61}: "Cisco Systems, Inc", [3]byte{0, 2, 62}: "Selta Telematica S.p.a", - [3]byte{0, 2, 63}: "COMPAL ELECTRONICS, INC.", + [3]byte{0, 2, 63}: "Compal Electronics INC.", [3]byte{0, 2, 64}: "Seedek Co., Ltd.", [3]byte{0, 2, 65}: "Amer.com", [3]byte{0, 2, 66}: "Videoframe Systems", @@ -660,7 +660,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 2, 129}: "Madge Ltd.", [3]byte{0, 2, 130}: "ViaClix, Inc.", [3]byte{0, 2, 131}: "Spectrum Controls, Inc.", - [3]byte{0, 2, 132}: "AREVA T&D", + [3]byte{0, 2, 132}: "UK Grid Solutions Limited", [3]byte{0, 2, 133}: "Riverstone Networks", [3]byte{0, 2, 134}: "Occam Networks", [3]byte{0, 2, 135}: "Adapcom", @@ -935,7 +935,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 3, 148}: "Connect One", [3]byte{0, 3, 149}: "California Amplifier", [3]byte{0, 3, 150}: "EZ Cast Co., Ltd.", - [3]byte{0, 3, 151}: "Watchfront Limited", + [3]byte{0, 3, 151}: "FireBrick Limited", [3]byte{0, 3, 152}: "WISI", [3]byte{0, 3, 153}: "Dongju Informations & Communications Co., Ltd.", [3]byte{0, 3, 154}: "SiConnect", @@ -1051,7 +1051,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 4, 8}: "Sanko Electronics Co., Ltd.", [3]byte{0, 4, 9}: "Cratos Networks", [3]byte{0, 4, 10}: "Sage Systems", - [3]byte{0, 4, 11}: "3COM EUROPE LTD.", + [3]byte{0, 4, 11}: "3COM EUROPE LTD", [3]byte{0, 4, 12}: "Kanno Works, Ltd.", [3]byte{0, 4, 13}: "Avaya Inc", [3]byte{0, 4, 14}: "AVM GmbH", @@ -1059,7 +1059,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 4, 16}: "Spinnaker Networks, Inc.", [3]byte{0, 4, 17}: "Inkra Networks, Inc.", [3]byte{0, 4, 18}: "WaveSmith Networks, Inc.", - [3]byte{0, 4, 19}: "SNOM Technology AG", + [3]byte{0, 4, 19}: "snom technology GmbH", [3]byte{0, 4, 20}: "Umezawa Musen Denki Co., Ltd.", [3]byte{0, 4, 21}: "Rasteme Systems Co., Ltd.", [3]byte{0, 4, 22}: "Parks S/A Comunicacoes Digitais", @@ -1157,8 +1157,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 4, 114}: "Telelynx, Inc.", [3]byte{0, 4, 115}: "Photonex Corporation", [3]byte{0, 4, 116}: "LEGRAND", - [3]byte{0, 4, 117}: "3 Com Corporation", - [3]byte{0, 4, 118}: "3 Com Corporation", + [3]byte{0, 4, 117}: "3COM", + [3]byte{0, 4, 118}: "3COM", [3]byte{0, 4, 119}: "Scalant Systems, Inc.", [3]byte{0, 4, 120}: "G. Star Technology Corporation", [3]byte{0, 4, 121}: "Radius Co., Ltd.", @@ -1292,7 +1292,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 4, 249}: "Xtera Communications, Inc.", [3]byte{0, 4, 250}: "NBS Technologies Inc.", [3]byte{0, 4, 251}: "Commtech, Inc.", - [3]byte{0, 4, 252}: "Stratus Computer (DE), Inc.", + [3]byte{0, 4, 252}: "Stratus Technologies", [3]byte{0, 4, 253}: "Japan Control Engineering Co., Ltd.", [3]byte{0, 4, 254}: "Pelago Networks", [3]byte{0, 4, 255}: "Acronet Co., Ltd.", @@ -1322,7 +1322,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 5, 23}: "Shellcomm, Inc.", [3]byte{0, 5, 24}: "Jupiters Technology", [3]byte{0, 5, 25}: "Siemens Building Technologies AG,", - [3]byte{0, 5, 26}: "3COM EUROPE LTD.", + [3]byte{0, 5, 26}: "3COM EUROPE LTD", [3]byte{0, 5, 27}: "Magic Control Technology Corporation", [3]byte{0, 5, 28}: "Xnet Technology Corp.", [3]byte{0, 5, 29}: "Airocon, Inc.", @@ -1620,7 +1620,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 6, 65}: "ITCN", [3]byte{0, 6, 66}: "Genetel Systems Inc.", [3]byte{0, 6, 67}: "SONO Computer Co., Ltd.", - [3]byte{0, 6, 68}: "neix,Inc", + [3]byte{0, 6, 68}: "NextGen Business Solutions, Inc", [3]byte{0, 6, 69}: "Meisei Electric Co. Ltd.", [3]byte{0, 6, 70}: "ShenZhen XunBao Network Technology Co Ltd", [3]byte{0, 6, 71}: "Etrali S.A.", @@ -1692,7 +1692,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 6, 137}: "yLez Technologies Pte Ltd", [3]byte{0, 6, 138}: "NeuronNet Co. Ltd. R&D Center", [3]byte{0, 6, 139}: "AirRunner Technologies, Inc.", - [3]byte{0, 6, 140}: "3COM CORPORATION", + [3]byte{0, 6, 140}: "3COM", [3]byte{0, 6, 141}: "SEPATON, Inc.", [3]byte{0, 6, 142}: "HID Corporation", [3]byte{0, 6, 143}: "Telemonitor, Inc.", @@ -1866,7 +1866,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 7, 55}: "Soriya Co. Ltd.", [3]byte{0, 7, 56}: "Young Technology Co., Ltd.", [3]byte{0, 7, 57}: "Scotty Group Austria Gmbh", - [3]byte{0, 7, 58}: "Inventel Systemes", + [3]byte{0, 7, 58}: "INVENTEL", [3]byte{0, 7, 59}: "Tenovis GmbH & Co KG", [3]byte{0, 7, 60}: "Telecom Design", [3]byte{0, 7, 61}: "Nanjing Postel Telecommunications Co., Ltd.", @@ -1976,7 +1976,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 7, 165}: "Y.D.K Co. Ltd.", [3]byte{0, 7, 166}: "Leviton Manufacturing Co., Inc.", [3]byte{0, 7, 167}: "A-Z Inc.", - [3]byte{0, 7, 168}: "Haier Group Technologies Ltd.", + [3]byte{0, 7, 168}: "Haier Group Technologies Ltd", [3]byte{0, 7, 169}: "Novasonics", [3]byte{0, 7, 170}: "Quantum Data Inc.", [3]byte{0, 7, 171}: "Samsung Electronics Co.,Ltd", @@ -2174,7 +2174,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 8, 134}: "Hansung Teliann, Inc.", [3]byte{0, 8, 135}: "Maschinenfabrik Reinhausen GmbH", [3]byte{0, 8, 136}: "OULLIM Information Technology Inc,.", - [3]byte{0, 8, 137}: "Echostar Technologies Corp", + [3]byte{0, 8, 137}: "Dish Technologies Corp", [3]byte{0, 8, 138}: "Minds@Work", [3]byte{0, 8, 139}: "Tropic Networks Inc.", [3]byte{0, 8, 140}: "Quanta Network Systems Inc.", @@ -2351,7 +2351,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 9, 55}: "Inventec Appliance Corp", [3]byte{0, 9, 56}: "Allot Communications", [3]byte{0, 9, 57}: "ShibaSoku Co.,Ltd.", - [3]byte{0, 9, 58}: "Molex", + [3]byte{0, 9, 58}: "Molex CMS", [3]byte{0, 9, 59}: "HYUNDAI NETWORKS INC.", [3]byte{0, 9, 60}: "Jacques Technologies P/L", [3]byte{0, 9, 61}: "Newisys,Inc.", @@ -2516,7 +2516,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 9, 220}: "Galaxis Technology AG", [3]byte{0, 9, 221}: "Mavin Technology Inc.", [3]byte{0, 9, 222}: "Samjin Information & Communications Co., Ltd.", - [3]byte{0, 9, 223}: "Vestel Komunikasyon Sanayi ve Ticaret A.S.", + [3]byte{0, 9, 223}: "Vestel Elektronik San ve Tic. A.Ş.", [3]byte{0, 9, 224}: "XEMICS S.A.", [3]byte{0, 9, 225}: "Gemtek Technology Co., Ltd.", [3]byte{0, 9, 226}: "Sinbon Electronics Co., Ltd.", @@ -2642,7 +2642,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 10, 91}: "Power-One as", [3]byte{0, 10, 92}: "Carel s.p.a.", [3]byte{0, 10, 93}: "FingerTec Worldwide Sdn Bhd", - [3]byte{0, 10, 94}: "3COM Corporation", + [3]byte{0, 10, 94}: "3COM", [3]byte{0, 10, 95}: "almedio inc.", [3]byte{0, 10, 96}: "Autostar Technology Pte Ltd", [3]byte{0, 10, 97}: "Cellinx Systems Inc.", @@ -2765,9 +2765,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 10, 214}: "BeamReach Networks", [3]byte{0, 10, 215}: "Origin ELECTRIC CO.,LTD.", [3]byte{0, 10, 216}: "IPCserv Technology Corp.", - [3]byte{0, 10, 217}: "Sony Mobile Communications AB", + [3]byte{0, 10, 217}: "Sony Mobile Communications Inc", [3]byte{0, 10, 218}: "Vindicator Technologies", - [3]byte{0, 10, 219}: "SkyPilot Network, Inc", + [3]byte{0, 10, 219}: "Trilliant", [3]byte{0, 10, 220}: "RuggedCom Inc.", [3]byte{0, 10, 221}: "Allworx Corp.", [3]byte{0, 10, 222}: "Happy Communication Co., Ltd.", @@ -2839,7 +2839,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 11, 32}: "Hirata corporation", [3]byte{0, 11, 33}: "G-Star Communications Inc.", [3]byte{0, 11, 34}: "Environmental Systems and Services", - [3]byte{0, 11, 35}: "Siemens Subscriber Networks", + [3]byte{0, 11, 35}: "Siemens Home & Office Comm. Devices", [3]byte{0, 11, 36}: "AirLogic", [3]byte{0, 11, 37}: "Aeluros", [3]byte{0, 11, 38}: "Wetek Corporation", @@ -2967,7 +2967,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 11, 160}: "T&L Information Inc.", [3]byte{0, 11, 161}: "Fujikura Solutions Ltd.", [3]byte{0, 11, 162}: "Sumitomo Electric Industries,Ltd", - [3]byte{0, 11, 163}: "Siemens AG, I&S", + [3]byte{0, 11, 163}: "Siemens AG", [3]byte{0, 11, 164}: "Shiron Satellite Communications Ltd. (1996)", [3]byte{0, 11, 165}: "Quasar Cipta Mandiri, PT", [3]byte{0, 11, 166}: "Miyakawa Electric Works Ltd.", @@ -3446,7 +3446,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 13, 127}: "MIDAS COMMUNICATION TECHNOLOGIES PTE LTD ( Foreign Branch)", [3]byte{0, 13, 128}: "Online Development Inc", [3]byte{0, 13, 129}: "Pepperl+Fuchs GmbH", - [3]byte{0, 13, 130}: "PHS srl", + [3]byte{0, 13, 130}: "PHSNET SRLS", [3]byte{0, 13, 131}: "Sanmina-SCI Hungary Ltd.", [3]byte{0, 13, 132}: "Makus Inc.", [3]byte{0, 13, 133}: "Tapwave, Inc.", @@ -3579,7 +3579,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 14, 4}: "CMA/Microdialysis AB", [3]byte{0, 14, 5}: "WIRELESS MATRIX CORP.", [3]byte{0, 14, 6}: "Team Simoco Ltd", - [3]byte{0, 14, 7}: "Sony Mobile Communications AB", + [3]byte{0, 14, 7}: "Sony Mobile Communications Inc", [3]byte{0, 14, 8}: "Cisco-Linksys, LLC", [3]byte{0, 14, 9}: "Shenzhen Coship Software Co.,LTD.", [3]byte{0, 14, 10}: "SAKUMA DESIGN OFFICE", @@ -3715,7 +3715,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 14, 140}: "Siemens AG A&D ET", [3]byte{0, 14, 141}: "Systems in Progress Holding GmbH", [3]byte{0, 14, 142}: "SparkLAN Communications, Inc.", - [3]byte{0, 14, 143}: "Sercomm Corp.", + [3]byte{0, 14, 143}: "Sercomm Corporation.", [3]byte{0, 14, 144}: "PONICO CORP.", [3]byte{0, 14, 145}: "Navico Auckland Ltd", [3]byte{0, 14, 146}: "Open Telecom", @@ -3849,7 +3849,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 15, 18}: "Panasonic Europe Ltd.", [3]byte{0, 15, 19}: "Nisca corporation", [3]byte{0, 15, 20}: "Mindray Co., Ltd.", - [3]byte{0, 15, 21}: "Kjaerulff1 A/S", + [3]byte{0, 15, 21}: "Icotera A/S", [3]byte{0, 15, 22}: "JAY HOW TECHNOLOGY CO.,", [3]byte{0, 15, 23}: "Insta Elektro GmbH", [3]byte{0, 15, 24}: "Industrial Control Systems", @@ -4004,7 +4004,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 15, 173}: "FMN communications GmbH", [3]byte{0, 15, 174}: "E2O Communications", [3]byte{0, 15, 175}: "Dialog Inc.", - [3]byte{0, 15, 176}: "COMPAL ELECTRONICS, INC.", + [3]byte{0, 15, 176}: "Compal Electronics INC.", [3]byte{0, 15, 177}: "Cognio Inc.", [3]byte{0, 15, 178}: "Broadband Pacenet (India) Pvt. Ltd.", [3]byte{0, 15, 179}: "Actiontec Electronics, Inc", @@ -4050,7 +4050,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 15, 219}: "Westell Technologies Inc.", [3]byte{0, 15, 220}: "Ueda Japan Radio Co., Ltd.", [3]byte{0, 15, 221}: "SORDIN AB", - [3]byte{0, 15, 222}: "Sony Mobile Communications AB", + [3]byte{0, 15, 222}: "Sony Mobile Communications Inc", [3]byte{0, 15, 223}: "SOLOMON Technology Corp.", [3]byte{0, 15, 224}: "NComputing Co.,Ltd.", [3]byte{0, 15, 225}: "ID DIGITAL CORPORATION", @@ -4159,7 +4159,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 16, 72}: "HTRC AUTOMATION, INC.", [3]byte{0, 16, 73}: "ShoreTel, Inc", [3]byte{0, 16, 74}: "The Parvus Corporation", - [3]byte{0, 16, 75}: "3COM CORPORATION", + [3]byte{0, 16, 75}: "3COM", [3]byte{0, 16, 76}: "Teledyne LeCroy, Inc", [3]byte{0, 16, 77}: "SURTEC INDUSTRIES, INC.", [3]byte{0, 16, 78}: "CEOLOGIC", @@ -4174,7 +4174,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 16, 87}: "Rebel.com, Inc.", [3]byte{0, 16, 88}: "ArrowPoint Communications", [3]byte{0, 16, 89}: "DIABLO RESEARCH CO. LLC", - [3]byte{0, 16, 90}: "3COM CORPORATION", + [3]byte{0, 16, 90}: "3COM", [3]byte{0, 16, 91}: "NET INSIGHT AB", [3]byte{0, 16, 92}: "QUANTUM DESIGNS (H.K.) LTD.", [3]byte{0, 16, 93}: "Draeger Medical", @@ -4370,7 +4370,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 17, 27}: "Targa Systems Div L-3 Communications", [3]byte{0, 17, 28}: "Pleora Technologies Inc.", [3]byte{0, 17, 29}: "Hectrix Limited", - [3]byte{0, 17, 30}: "EPSG (Ethernet Powerlink Standardization Group)", + [3]byte{0, 17, 30}: "ETHERNET Powerlink Standarization Group (EPSG)", [3]byte{0, 17, 31}: "Doremi Labs, Inc.", [3]byte{0, 17, 32}: "Cisco Systems, Inc", [3]byte{0, 17, 33}: "Cisco Systems, Inc", @@ -4391,7 +4391,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 17, 48}: "Allied Telesis (Hong Kong) Ltd.", [3]byte{0, 17, 49}: "UNATECH. CO.,LTD", [3]byte{0, 17, 50}: "Synology Incorporated", - [3]byte{0, 17, 51}: "Siemens Austria SIMEA", + [3]byte{0, 17, 51}: "Siemens AG Austria", [3]byte{0, 17, 52}: "MediaCell, Inc.", [3]byte{0, 17, 53}: "Grandeye Ltd", [3]byte{0, 17, 54}: "Goodrich Sensor Systems", @@ -4675,7 +4675,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 18, 76}: "BBWM Corporation", [3]byte{0, 18, 77}: "Inducon BV", [3]byte{0, 18, 78}: "XAC AUTOMATION CORP.", - [3]byte{0, 18, 79}: "Pentair Thermal Management", + [3]byte{0, 18, 79}: "nVent", [3]byte{0, 18, 80}: "Tokyo Aircaft Instrument Co., Ltd.", [3]byte{0, 18, 81}: "SILINK", [3]byte{0, 18, 82}: "Citronix, LLC", @@ -4761,7 +4761,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 18, 162}: "VITA", [3]byte{0, 18, 163}: "Trust International B.V.", [3]byte{0, 18, 164}: "ThingMagic, LLC", - [3]byte{0, 18, 165}: "Stargen, Inc.", + [3]byte{0, 18, 165}: "Dolphin Interconnect Solutions AS", [3]byte{0, 18, 166}: "Dolby Australia", [3]byte{0, 18, 167}: "ISR TECHNOLOGIES Inc", [3]byte{0, 18, 168}: "intec GmbH", @@ -4834,7 +4834,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 18, 235}: "PDH Solutions, LLC", [3]byte{0, 18, 236}: "Movacolor b.v.", [3]byte{0, 18, 237}: "AVG Advanced Technologies", - [3]byte{0, 18, 238}: "Sony Mobile Communications AB", + [3]byte{0, 18, 238}: "Sony Mobile Communications Inc", [3]byte{0, 18, 239}: "OneAccess SA", [3]byte{0, 18, 240}: "Intel Corporate", [3]byte{0, 18, 241}: "IFOTEC", @@ -4931,7 +4931,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 19, 76}: "YDT Technology International", [3]byte{0, 19, 77}: "Inepro BV", [3]byte{0, 19, 78}: "Valox Systems, Inc.", - [3]byte{0, 19, 79}: "Tranzeo Wireless Technologies Inc.", + [3]byte{0, 19, 79}: "Rapidus Wireless Networks Inc.", [3]byte{0, 19, 80}: "Silver Spring Networks, Inc", [3]byte{0, 19, 81}: "Niles Audio Corporation", [3]byte{0, 19, 82}: "Naztec, Inc.", @@ -4986,11 +4986,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 19, 131}: "Application Technologies and Engineering Research Laboratory", [3]byte{0, 19, 132}: "Advanced Motion Controls", [3]byte{0, 19, 133}: "Add-On Technology Co., LTD.", - [3]byte{0, 19, 134}: "ABB Inc./Totalflow", + [3]byte{0, 19, 134}: "ABB Inc/Totalflow", [3]byte{0, 19, 135}: "27M Technologies AB", [3]byte{0, 19, 136}: "WiMedia Alliance", [3]byte{0, 19, 137}: "Redes de Telefonía Móvil S.A.", - [3]byte{0, 19, 138}: "QINGDAO GOERTEK ELECTRONICS CO.,LTD.", + [3]byte{0, 19, 138}: "Qingdao GoerTek Technology Co., Ltd.", [3]byte{0, 19, 139}: "Phantom Technologies LLC", [3]byte{0, 19, 140}: "Kumyoung.Co.Ltd", [3]byte{0, 19, 141}: "Kinghold", @@ -5015,7 +5015,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 19, 160}: "ALGOSYSTEM Co., Ltd.", [3]byte{0, 19, 161}: "Crow Electronic Engeneering", [3]byte{0, 19, 162}: "MaxStream, Inc", - [3]byte{0, 19, 163}: "Siemens Com CPE Devices", + [3]byte{0, 19, 163}: "Siemens Home & Office Comm. Devices", [3]byte{0, 19, 164}: "KeyEye Communications", [3]byte{0, 19, 165}: "General Solutions, LTD.", [3]byte{0, 19, 166}: "Extricom Ltd", @@ -5137,7 +5137,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 20, 26}: "DEICY CORPORATION", [3]byte{0, 20, 27}: "Cisco Systems, Inc", [3]byte{0, 20, 28}: "Cisco Systems, Inc", - [3]byte{0, 20, 29}: "LTi DRIVES GmbH", + [3]byte{0, 20, 29}: "LTI-Motion GmbH", [3]byte{0, 20, 30}: "P.A. Semi, Inc.", [3]byte{0, 20, 31}: "SunKwang Electronics Co., Ltd", [3]byte{0, 20, 32}: "G-Links networking company", @@ -5222,12 +5222,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 20, 111}: "Kohler Co", [3]byte{0, 20, 112}: "Prokom Software SA", [3]byte{0, 20, 113}: "Eastern Asia Technology Limited", - [3]byte{0, 20, 114}: "China Broadband Wireless IP Standard Group", + [3]byte{0, 20, 114}: "China Broadband Wireless IP Standard group(ChinaBWIPS)", [3]byte{0, 20, 115}: "Bookham Inc", [3]byte{0, 20, 116}: "K40 Electronics", [3]byte{0, 20, 117}: "Wiline Networks, Inc.", [3]byte{0, 20, 118}: "MultiCom Industries Limited", - [3]byte{0, 20, 119}: "Nertec Inc.", + [3]byte{0, 20, 119}: "Trilliant", [3]byte{0, 20, 120}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{0, 20, 121}: "NEC Magnus Communications,Ltd.", [3]byte{0, 20, 122}: "Eubus GmbH", @@ -5394,7 +5394,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 21, 27}: "Isilon Systems Inc.", [3]byte{0, 21, 28}: "LENECO", [3]byte{0, 21, 29}: "M2I CORPORATION", - [3]byte{0, 21, 30}: "Ethernet Powerlink Standardization Group (EPSG)", + [3]byte{0, 21, 30}: "ETHERNET Powerlink Standarization Group (EPSG)", [3]byte{0, 21, 31}: "Multivision Intelligent Surveillance (Hong Kong) Ltd", [3]byte{0, 21, 32}: "Radiocrafts AS", [3]byte{0, 21, 33}: "Horoquartz", @@ -5652,7 +5652,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 22, 29}: "Innovative Wireless Technologies, Inc.", [3]byte{0, 22, 30}: "Woojinnet", [3]byte{0, 22, 31}: "SUNWAVETEC Co., Ltd.", - [3]byte{0, 22, 32}: "Sony Mobile Communications AB", + [3]byte{0, 22, 32}: "Sony Mobile Communications Inc", [3]byte{0, 22, 33}: "Colorado Vnet", [3]byte{0, 22, 34}: "BBH SYSTEMS GMBH", [3]byte{0, 22, 35}: "Interval Media", @@ -5712,7 +5712,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 22, 89}: "Z.M.P. RADWAG", [3]byte{0, 22, 90}: "Harman Specialty Group", [3]byte{0, 22, 91}: "Grip Audio", - [3]byte{0, 22, 92}: "Trackflow Ltd", + [3]byte{0, 22, 92}: "Trackflow Ltd.", [3]byte{0, 22, 93}: "AirDefense, Inc.", [3]byte{0, 22, 94}: "Precision I/O", [3]byte{0, 22, 95}: "Fairmount Automation", @@ -5804,7 +5804,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 22, 181}: "ARRIS Group, Inc.", [3]byte{0, 22, 182}: "Cisco-Linksys, LLC", [3]byte{0, 22, 183}: "Seoul Commtech", - [3]byte{0, 22, 184}: "Sony Mobile Communications AB", + [3]byte{0, 22, 184}: "Sony Mobile Communications Inc", [3]byte{0, 22, 185}: "ProCurve Networking by HP", [3]byte{0, 22, 186}: "WEATHERNEWS INC.", [3]byte{0, 22, 187}: "Law-Chain Computer Technology Co Ltd", @@ -6058,7 +6058,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 23, 179}: "Aftek Infosys Limited", [3]byte{0, 23, 180}: "Remote Security Systems, LLC", [3]byte{0, 23, 181}: "Peerless Systems Corporation", - [3]byte{0, 23, 182}: "Aquantia", + [3]byte{0, 23, 182}: "Aquantia Corporation", [3]byte{0, 23, 183}: "Tonze Technology Co.", [3]byte{0, 23, 184}: "NOVATRON CO., LTD.", [3]byte{0, 23, 185}: "Gambro Lundia AB", @@ -6119,7 +6119,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 23, 240}: "SZCOM Broadband Network Technology Co.,Ltd", [3]byte{0, 23, 241}: "Renu Electronics Pvt Ltd", [3]byte{0, 23, 242}: "Apple, Inc.", - [3]byte{0, 23, 243}: "Harris Corparation", + [3]byte{0, 23, 243}: "Harris Corporation", [3]byte{0, 23, 244}: "ZERON ALLIANCE", [3]byte{0, 23, 245}: "LIG NEOPTEK", [3]byte{0, 23, 246}: "Pyramid Meriden Inc.", @@ -6151,7 +6151,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 24, 16}: "IPTrade S.A.", [3]byte{0, 24, 17}: "Neuros Technology International, LLC.", [3]byte{0, 24, 18}: "Beijing Xinwei Telecom Technology Co., Ltd.", - [3]byte{0, 24, 19}: "Sony Mobile Communications AB", + [3]byte{0, 24, 19}: "Sony Mobile Communications Inc", [3]byte{0, 24, 20}: "Mitutoyo Corporation", [3]byte{0, 24, 21}: "GZ Technologies, Inc.", [3]byte{0, 24, 22}: "Ubixon Co., Ltd.", @@ -6205,7 +6205,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 24, 70}: "Crypto S.A.", [3]byte{0, 24, 71}: "AceNet Technology Inc.", [3]byte{0, 24, 72}: "Vecima Networks Inc.", - [3]byte{0, 24, 73}: "Pigeon Point Systems LLC", + [3]byte{0, 24, 73}: "nVent, Schroff GmbH", [3]byte{0, 24, 74}: "Catcher, Inc.", [3]byte{0, 24, 75}: "Las Vegas Gaming, Inc.", [3]byte{0, 24, 76}: "Bogen Communications", @@ -6350,7 +6350,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 24, 215}: "JAVAD GNSS, Inc.", [3]byte{0, 24, 216}: "ARCH METER Corporation", [3]byte{0, 24, 217}: "Santosha Internatonal, Inc", - [3]byte{0, 24, 218}: "AMBER wireless GmbH", + [3]byte{0, 24, 218}: "Würth Elektronik eiSos GmbH & Co. KG", [3]byte{0, 24, 219}: "EPL Technology Ltd", [3]byte{0, 24, 220}: "Prostar Co., Ltd.", [3]byte{0, 24, 221}: "Silicondust Engineering Ltd", @@ -6487,7 +6487,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 25, 96}: "DoCoMo Systems, Inc.", [3]byte{0, 25, 97}: "Blaupunkt Embedded Systems GmbH", [3]byte{0, 25, 98}: "Commerciant, LP", - [3]byte{0, 25, 99}: "Sony Mobile Communications AB", + [3]byte{0, 25, 99}: "Sony Mobile Communications Inc", [3]byte{0, 25, 100}: "Doorking Inc.", [3]byte{0, 25, 101}: "YuHua TelTech (ShangHai) Co., Ltd.", [3]byte{0, 25, 102}: "Asiarock Technology Limited", @@ -6693,7 +6693,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 26, 46}: "Ziova Coporation", [3]byte{0, 26, 47}: "Cisco Systems, Inc", [3]byte{0, 26, 48}: "Cisco Systems, Inc", - [3]byte{0, 26, 49}: "SCAN COIN Industries AB", + [3]byte{0, 26, 49}: "SCAN COIN AB", [3]byte{0, 26, 50}: "ACTIVA MULTIMEDIA", [3]byte{0, 26, 51}: "ASI Communications, Inc.", [3]byte{0, 26, 52}: "Konka Group Co., Ltd.", @@ -6761,7 +6761,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 26, 114}: "Mosart Semiconductor Corp.", [3]byte{0, 26, 115}: "Gemtek Technology Co., Ltd.", [3]byte{0, 26, 116}: "Procare International Co", - [3]byte{0, 26, 117}: "Sony Mobile Communications AB", + [3]byte{0, 26, 117}: "Sony Mobile Communications Inc", [3]byte{0, 26, 118}: "SDT information Technology Co.,LTD.", [3]byte{0, 26, 119}: "ARRIS Group, Inc.", [3]byte{0, 26, 120}: "ubtos", @@ -6841,7 +6841,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 26, 194}: "YEC Co.,Ltd.", [3]byte{0, 26, 195}: "Scientific-Atlanta, Inc", [3]byte{0, 26, 196}: "2Wire Inc", - [3]byte{0, 26, 197}: "BreakingPoint Systems, Inc.", + [3]byte{0, 26, 197}: "Keysight Technologies, Inc.", [3]byte{0, 26, 198}: "Micro Control Designs", [3]byte{0, 26, 199}: "UNIPOINT", [3]byte{0, 26, 200}: "ISL (Instrumentation Scientifique de Laboratoire)", @@ -6989,7 +6989,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 27, 86}: "Tehuti Networks Ltd.", [3]byte{0, 27, 87}: "SEMINDIA SYSTEMS PRIVATE LIMITED", [3]byte{0, 27, 88}: "ACE CAD Enterprise Co., Ltd.", - [3]byte{0, 27, 89}: "Sony Mobile Communications AB", + [3]byte{0, 27, 89}: "Sony Mobile Communications Inc", [3]byte{0, 27, 90}: "Apollo Imaging Technologies, Inc.", [3]byte{0, 27, 91}: "2Wire Inc", [3]byte{0, 27, 92}: "Azuretec Co., Ltd.", @@ -7010,7 +7010,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 27, 107}: "Swyx Solutions AG", [3]byte{0, 27, 108}: "LookX Digital Media BV", [3]byte{0, 27, 109}: "Midtronics, Inc.", - [3]byte{0, 27, 110}: "Anue Systems, Inc.", + [3]byte{0, 27, 110}: "Keysight Technologies, Inc.", [3]byte{0, 27, 111}: "Teletrak Ltd", [3]byte{0, 27, 112}: "IRI Ubiteq, INC.", [3]byte{0, 27, 113}: "Telular Corp.", @@ -7116,8 +7116,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 27, 213}: "Cisco Systems, Inc", [3]byte{0, 27, 214}: "Kelvin Hughes Ltd", [3]byte{0, 27, 215}: "Cisco SPVTG", - [3]byte{0, 27, 216}: "DVTel LTD", - [3]byte{0, 27, 217}: "Edgewater Computer Systems", + [3]byte{0, 27, 216}: "FLIR Systems Inc", + [3]byte{0, 27, 217}: "Edgewater Wireless Systems Inc", [3]byte{0, 27, 218}: "UTStarcom Inc", [3]byte{0, 27, 219}: "Valeo VECS", [3]byte{0, 27, 220}: "Vencer Co., Ltd.", @@ -7320,7 +7320,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 28, 161}: "AKAMAI TECHNOLOGIES, INC.", [3]byte{0, 28, 162}: "ADB Broadband Italia", [3]byte{0, 28, 163}: "Terra", - [3]byte{0, 28, 164}: "Sony Mobile Communications AB", + [3]byte{0, 28, 164}: "Sony Mobile Communications Inc", [3]byte{0, 28, 165}: "Zygo Corporation", [3]byte{0, 28, 166}: "Win4NET", [3]byte{0, 28, 167}: "International Quartz Limited", @@ -7452,7 +7452,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 29, 37}: "Samsung Electronics Co.,Ltd", [3]byte{0, 29, 38}: "Rockridgesound Technology Co.", [3]byte{0, 29, 39}: "NAC-INTERCOM", - [3]byte{0, 29, 40}: "Sony Mobile Communications AB", + [3]byte{0, 29, 40}: "Sony Mobile Communications Inc", [3]byte{0, 29, 41}: "Doro AB", [3]byte{0, 29, 42}: "SHENZHEN BUL-TECH CO.,LTD.", [3]byte{0, 29, 43}: "Wuhan Pont Technology CO. , LTD", @@ -7719,7 +7719,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 30, 48}: "Shireen Inc", [3]byte{0, 30, 49}: "INFOMARK CO.,LTD.", [3]byte{0, 30, 50}: "Zensys", - [3]byte{0, 30, 51}: "INVENTEC Corporation", + [3]byte{0, 30, 51}: "INVENTEC CORPORATION", [3]byte{0, 30, 52}: "CryptoMetrics", [3]byte{0, 30, 53}: "Nintendo Co., Ltd.", [3]byte{0, 30, 54}: "IPTE", @@ -7737,7 +7737,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 30, 66}: "Teltonika", [3]byte{0, 30, 67}: "AISIN AW CO.,LTD.", [3]byte{0, 30, 68}: "SANTEC", - [3]byte{0, 30, 69}: "Sony Mobile Communications AB", + [3]byte{0, 30, 69}: "Sony Mobile Communications Inc", [3]byte{0, 30, 70}: "ARRIS Group, Inc.", [3]byte{0, 30, 71}: "PT. Hariff Daya Tunggal Engineering", [3]byte{0, 30, 72}: "Wi-Links", @@ -7796,7 +7796,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 30, 125}: "Samsung Electronics Co.,Ltd", [3]byte{0, 30, 126}: "Nortel Networks", [3]byte{0, 30, 127}: "CBM of America", - [3]byte{0, 30, 128}: "Last Mile Ltd.", + [3]byte{0, 30, 128}: "Icotera A/S", [3]byte{0, 30, 129}: "CNB Technology Inc.", [3]byte{0, 30, 130}: "SanDisk Corporation", [3]byte{0, 30, 131}: "LAN/MAN Standards Association (LMSC)", @@ -7888,7 +7888,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 30, 217}: "Mitsubishi Precision Co.,LTd.", [3]byte{0, 30, 218}: "Wesemann Elektrotechniek B.V.", [3]byte{0, 30, 219}: "Giken Trastem Co., Ltd.", - [3]byte{0, 30, 220}: "Sony Mobile Communications AB", + [3]byte{0, 30, 220}: "Sony Mobile Communications Inc", [3]byte{0, 30, 221}: "WASKO S.A.", [3]byte{0, 30, 222}: "BYD COMPANY LIMITED", [3]byte{0, 30, 223}: "Master Industrialization Center Kista", @@ -8152,7 +8152,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 31, 225}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{0, 31, 226}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{0, 31, 227}: "LG Electronics (Mobile Communications)", - [3]byte{0, 31, 228}: "Sony Mobile Communications AB", + [3]byte{0, 31, 228}: "Sony Mobile Communications Inc", [3]byte{0, 31, 229}: "In-Circuit GmbH", [3]byte{0, 31, 230}: "Alphion Corporation", [3]byte{0, 31, 231}: "Simet", @@ -8194,7 +8194,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 32, 11}: "OCTAGON SYSTEMS CORP.", [3]byte{0, 32, 12}: "ADASTRA SYSTEMS CORP.", [3]byte{0, 32, 13}: "CARL ZEISS", - [3]byte{0, 32, 14}: "SATELLITE TECHNOLOGY MGMT, INC", + [3]byte{0, 32, 14}: "NSSLGlobal Technologies AS", [3]byte{0, 32, 15}: "EBRAINS Inc", [3]byte{0, 32, 16}: "JEOL SYSTEM TECHNOLOGY CO. LTD", [3]byte{0, 32, 17}: "CANOPUS CO., LTD.", @@ -8241,7 +8241,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 32, 58}: "DIGITAL BI0METRICS INC.", [3]byte{0, 32, 59}: "WISDM LTD.", [3]byte{0, 32, 60}: "EUROTIME AB", - [3]byte{0, 32, 61}: "Honeywell ECC", + [3]byte{0, 32, 61}: "Honeywell Environmental & Combustion Controls", [3]byte{0, 32, 62}: "LogiCan Technologies, Inc.", [3]byte{0, 32, 63}: "JUKI CORPORATION", [3]byte{0, 32, 64}: "ARRIS Group, Inc.", @@ -8355,7 +8355,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 32, 172}: "INTERFLEX DATENSYSTEME GMBH", [3]byte{0, 32, 173}: "LINQ SYSTEMS", [3]byte{0, 32, 174}: "ORNET DATA COMMUNICATION TECH.", - [3]byte{0, 32, 175}: "3COM CORPORATION", + [3]byte{0, 32, 175}: "3COM", [3]byte{0, 32, 176}: "GATEWAY DEVICES, INC.", [3]byte{0, 32, 177}: "COMTECH RESEARCH INC.", [3]byte{0, 32, 178}: "GKD Gesellschaft Fur Kommunikation Und Datentechnik", @@ -8594,7 +8594,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 33, 155}: "Dell Inc.", [3]byte{0, 33, 156}: "Honeywld Technology Corp.", [3]byte{0, 33, 157}: "Adesys BV", - [3]byte{0, 33, 158}: "Sony Mobile Communications AB", + [3]byte{0, 33, 158}: "Sony Mobile Communications Inc", [3]byte{0, 33, 159}: "SATEL OY", [3]byte{0, 33, 160}: "Cisco Systems, Inc", [3]byte{0, 33, 161}: "Cisco Systems, Inc", @@ -8716,7 +8716,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 34, 21}: "ASUSTek COMPUTER INC.", [3]byte{0, 34, 22}: "SHIBAURA VENDING MACHINE CORPORATION", [3]byte{0, 34, 23}: "Neat Electronics", - [3]byte{0, 34, 24}: "Verivue Inc.", + [3]byte{0, 34, 24}: "AKAMAI TECHNOLOGIES INC", [3]byte{0, 34, 25}: "Dell Inc.", [3]byte{0, 34, 26}: "Audio Precision", [3]byte{0, 34, 27}: "Morega Systems", @@ -8844,7 +8844,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 34, 149}: "SGM Technology for lighting spa", [3]byte{0, 34, 150}: "LinoWave Corporation", [3]byte{0, 34, 151}: "XMOS Semiconductor", - [3]byte{0, 34, 152}: "Sony Mobile Communications AB", + [3]byte{0, 34, 152}: "Sony Mobile Communications Inc", [3]byte{0, 34, 153}: "SeaMicro Inc.", [3]byte{0, 34, 154}: "Lastar, Inc.", [3]byte{0, 34, 155}: "AverLogic Technologies, Inc.", @@ -9009,7 +9009,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 35, 58}: "Samsung Electronics Co.,Ltd", [3]byte{0, 35, 59}: "C-Matic Systems Ltd", [3]byte{0, 35, 60}: "Alflex", - [3]byte{0, 35, 61}: "Novero holding B.V.", + [3]byte{0, 35, 61}: "Laird Technologies", [3]byte{0, 35, 62}: "Alcatel-Lucent IPD", [3]byte{0, 35, 63}: "Purechoice Inc", [3]byte{0, 35, 64}: "MiXTelematics", @@ -9017,7 +9017,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 35, 66}: "Coffee Equipment Company", [3]byte{0, 35, 67}: "TEM AG", [3]byte{0, 35, 68}: "Objective Interface Systems, Inc.", - [3]byte{0, 35, 69}: "Sony Mobile Communications AB", + [3]byte{0, 35, 69}: "Sony Mobile Communications Inc", [3]byte{0, 35, 70}: "Vestac", [3]byte{0, 35, 71}: "ProCurve Networking by HP", [3]byte{0, 35, 72}: "Sagemcom Broadband SAS", @@ -9028,7 +9028,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 35, 77}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{0, 35, 78}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{0, 35, 79}: "Luminous Power Technologies Pvt. Ltd.", - [3]byte{0, 35, 80}: "LynTec", + [3]byte{0, 35, 80}: "RDC, Inc. dba LynTec", [3]byte{0, 35, 81}: "2Wire Inc", [3]byte{0, 35, 82}: "DATASENSOR S.p.A.", [3]byte{0, 35, 83}: "F E T Elettronica snc", @@ -9189,7 +9189,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 35, 238}: "ARRIS Group, Inc.", [3]byte{0, 35, 239}: "Zuend Systemtechnik AG", [3]byte{0, 35, 240}: "Shanghai Jinghan Weighing Apparatus Co. Ltd.", - [3]byte{0, 35, 241}: "Sony Mobile Communications AB", + [3]byte{0, 35, 241}: "Sony Mobile Communications Inc", [3]byte{0, 35, 242}: "TVLogic", [3]byte{0, 35, 243}: "Glocom, Inc.", [3]byte{0, 35, 244}: "Masternaut", @@ -9375,8 +9375,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 36, 171}: "A7 Engineering, Inc.", [3]byte{0, 36, 172}: "Hangzhou DPtech Technologies Co., Ltd.", [3]byte{0, 36, 173}: "Adolf Thies Gmbh & Co. KG", - [3]byte{0, 36, 174}: "Morpho", - [3]byte{0, 36, 175}: "Echostar Technologies Corp", + [3]byte{0, 36, 174}: "IDEMIA", + [3]byte{0, 36, 175}: "Dish Technologies Corp", [3]byte{0, 36, 176}: "ESAB AB", [3]byte{0, 36, 177}: "Coulomb Technologies", [3]byte{0, 36, 178}: "NETGEAR", @@ -9440,7 +9440,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 36, 236}: "United Information Technology Co.,Ltd.", [3]byte{0, 36, 237}: "YT Elec. Co,.Ltd.", [3]byte{0, 36, 238}: "Wynmax Inc.", - [3]byte{0, 36, 239}: "Sony Mobile Communications AB", + [3]byte{0, 36, 239}: "Sony Mobile Communications Inc", [3]byte{0, 36, 240}: "Seanodes", [3]byte{0, 36, 241}: "Shenzhen Fanhai Sanjiang Electronics Co., Ltd.", [3]byte{0, 36, 242}: "Uniphone Telecommunication Co., Ltd.", @@ -9469,7 +9469,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 37, 9}: "SHARETRONIC Group LTD", [3]byte{0, 37, 10}: "Security Expert Co. Ltd", [3]byte{0, 37, 11}: "CENTROFACTOR INC", - [3]byte{0, 37, 12}: "Enertrac", + [3]byte{0, 37, 12}: "Senet Inc", [3]byte{0, 37, 13}: "GZT Telkom-Telmor sp. z o.o.", [3]byte{0, 37, 14}: "gt german telematics gmbh", [3]byte{0, 37, 15}: "On-Ramp Wireless, Inc.", @@ -9686,7 +9686,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 37, 228}: "OMNI-WiFi, LLC", [3]byte{0, 37, 229}: "LG Electronics (Mobile Communications)", [3]byte{0, 37, 230}: "Belgian Monitoring Systems bvba", - [3]byte{0, 37, 231}: "Sony Mobile Communications AB", + [3]byte{0, 37, 231}: "Sony Mobile Communications Inc", [3]byte{0, 37, 232}: "Idaho Technology", [3]byte{0, 37, 233}: "i-mate Development, Inc.", [3]byte{0, 37, 234}: "Iphion BV", @@ -9792,7 +9792,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 38, 81}: "Cisco Systems, Inc", [3]byte{0, 38, 82}: "Cisco Systems, Inc", [3]byte{0, 38, 83}: "DaySequerra Corporation", - [3]byte{0, 38, 84}: "3Com Corporation", + [3]byte{0, 38, 84}: "3COM", [3]byte{0, 38, 85}: "Hewlett Packard", [3]byte{0, 38, 86}: "Sansonic Electronics USA", [3]byte{0, 38, 87}: "OOO NPP EKRA", @@ -9816,7 +9816,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 38, 105}: "Nokia Danmark A/S", [3]byte{0, 38, 106}: "ESSENSIUM NV", [3]byte{0, 38, 107}: "SHINE UNION ENTERPRISE LIMITED", - [3]byte{0, 38, 108}: "INVENTEC Corporation", + [3]byte{0, 38, 108}: "INVENTEC CORPORATION", [3]byte{0, 38, 109}: "MobileAccess Networks", [3]byte{0, 38, 110}: "Nissho-denki Co.,LTD.", [3]byte{0, 38, 111}: "Coordiwise Technology Corp.", @@ -9897,7 +9897,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 38, 186}: "ARRIS Group, Inc.", [3]byte{0, 38, 187}: "Apple, Inc.", [3]byte{0, 38, 188}: "General Jack Technology Ltd.", - [3]byte{0, 38, 189}: "JTEC Card & Communication Co., Ltd.", + [3]byte{0, 38, 189}: "JTEC Card & Communication Co., Ltd", [3]byte{0, 38, 190}: "Schoonderbeek Elektronica Systemen B.V.", [3]byte{0, 38, 191}: "ShenZhen Temobi Science&Tech Development Co.,Ltd", [3]byte{0, 38, 192}: "EnergyHub", @@ -10011,6 +10011,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 44, 200}: "Cisco Systems, Inc", [3]byte{0, 45, 118}: "TITECH GmbH", [3]byte{0, 46, 199}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{0, 47, 217}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{0, 48, 0}: "ALLWELL TECHNOLOGY CORP.", [3]byte{0, 48, 1}: "SMP", [3]byte{0, 48, 2}: "Expand Networks", @@ -10041,7 +10042,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 48, 27}: "SHUTTLE, INC.", [3]byte{0, 48, 28}: "ALTVATER AIRDATA SYSTEMS", [3]byte{0, 48, 29}: "SKYSTREAM, INC.", - [3]byte{0, 48, 30}: "3COM EUROPE LTD.", + [3]byte{0, 48, 30}: "3COM EUROPE LTD", [3]byte{0, 48, 31}: "OPTICAL NETWORKS, INC.", [3]byte{0, 48, 32}: "TSI, Inc..", [3]byte{0, 48, 33}: "HSING TECH. ENTERPRISE CO.,LTD", @@ -10290,8 +10291,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 58, 156}: "Cisco Systems, Inc", [3]byte{0, 58, 157}: "NEC Platforms, Ltd.", [3]byte{0, 58, 175}: "BlueBit Ltd.", + [3]byte{0, 60, 16}: "Cisco Systems, Inc", [3]byte{0, 60, 197}: "WONWOO Engineering Co., Ltd", [3]byte{0, 61, 65}: "Hatteland Computer AS", + [3]byte{0, 61, 232}: "LG Electronics (Mobile Communications)", [3]byte{0, 62, 225}: "Apple, Inc.", [3]byte{0, 64, 0}: "PCI COMPONENTES DA AMZONIA LTD", [3]byte{0, 64, 1}: "Zero One Technology Co. Ltd.", @@ -10425,7 +10428,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 64, 129}: "MANNESMANN SCANGRAPHIC GMBH", [3]byte{0, 64, 130}: "LABORATORY EQUIPMENT CORP.", [3]byte{0, 64, 131}: "TDA INDUSTRIA DE PRODUTOS", - [3]byte{0, 64, 132}: "HONEYWELL ACS", + [3]byte{0, 64, 132}: "Honeywell International HPS", [3]byte{0, 64, 133}: "SAAB INSTRUMENTS AB", [3]byte{0, 64, 134}: "MICHELS & KLEBERHOFF COMPUTER", [3]byte{0, 64, 135}: "UBITREX CORPORATION", @@ -10450,7 +10453,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 64, 154}: "NETWORK EXPRESS, INC.", [3]byte{0, 64, 155}: "HAL COMPUTER SYSTEMS INC.", [3]byte{0, 64, 156}: "TRANSWARE", - [3]byte{0, 64, 157}: "DIGIBOARD, INC.", + [3]byte{0, 64, 157}: "DigiBoard", [3]byte{0, 64, 158}: "CONCURRENT TECHNOLOGIES LTD.", [3]byte{0, 64, 159}: "Telco Systems, Inc.", [3]byte{0, 64, 160}: "GOLDSTAR CO., LTD.", @@ -10554,8 +10557,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 66, 82}: "RLX Technologies", [3]byte{0, 66, 90}: "Cisco Systems, Inc", [3]byte{0, 66, 104}: "Cisco Systems, Inc", + [3]byte{0, 66, 121}: "Sunitec Enterprise Co.,Ltd", [3]byte{0, 67, 255}: "KETRON S.R.L.", [3]byte{0, 69, 1}: "Versus Technology, Inc.", + [3]byte{0, 69, 29}: "Cisco Systems, Inc", [3]byte{0, 70, 75}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{0, 74, 119}: "zte corporation", [3]byte{0, 75, 243}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", @@ -10564,7 +10569,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 80, 1}: "YAMASHITA SYSTEMS CORP.", [3]byte{0, 80, 2}: "OMNISEC AG", [3]byte{0, 80, 3}: "Xrite Inc", - [3]byte{0, 80, 4}: "3COM CORPORATION", + [3]byte{0, 80, 4}: "3COM", [3]byte{0, 80, 6}: "TAC AB", [3]byte{0, 80, 7}: "SIEMENS TELECOMMUNICATION SYSTEMS LIMITED", [3]byte{0, 80, 8}: "TIVA MICROCOMPUTER CORP. (TMC)", @@ -10702,7 +10707,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 80, 150}: "SALIX TECHNOLOGIES, INC.", [3]byte{0, 80, 151}: "MMC-EMBEDDED COMPUTERTECHNIK GmbH", [3]byte{0, 80, 152}: "GLOBALOOP, LTD.", - [3]byte{0, 80, 153}: "3COM EUROPE, LTD.", + [3]byte{0, 80, 153}: "3COM EUROPE LTD", [3]byte{0, 80, 154}: "TAG ELECTRONIC SYSTEMS", [3]byte{0, 80, 155}: "SWITCHCORE AB", [3]byte{0, 80, 156}: "BETA RESEARCH", @@ -10766,7 +10771,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 80, 215}: "TELSTRAT", [3]byte{0, 80, 216}: "UNICORN COMPUTER CORP.", [3]byte{0, 80, 217}: "ENGETRON-ENGENHARIA ELETRONICA IND. e COM. LTDA", - [3]byte{0, 80, 218}: "3COM CORPORATION", + [3]byte{0, 80, 218}: "3COM", [3]byte{0, 80, 219}: "CONTEMPORARY CONTROL", [3]byte{0, 80, 220}: "TAS TELEFONBAU A. SCHWABE GMBH & CO. KG", [3]byte{0, 80, 221}: "SERRA SOLDADURA, S.A.", @@ -10800,6 +10805,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 80, 253}: "VISIONCOMM CO., LTD.", [3]byte{0, 80, 254}: "PCTVnet ASA", [3]byte{0, 80, 255}: "HAKKO ELECTRONICS CO., LTD.", + [3]byte{0, 81, 237}: "LG Innotek", [3]byte{0, 82, 24}: "Wuxi Keboda Electron Co.Ltd", [3]byte{0, 84, 159}: "Avaya Inc", [3]byte{0, 84, 175}: "Continental Automotive Systems Inc.", @@ -10807,7 +10813,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 85, 218}: "IEEE Registration Authority", [3]byte{0, 86, 43}: "Cisco Systems, Inc", [3]byte{0, 86, 205}: "Apple, Inc.", + [3]byte{0, 87, 193}: "LG Electronics (Mobile Communications)", [3]byte{0, 87, 210}: "Cisco Systems, Inc", + [3]byte{0, 88, 63}: "PC Aquarius", [3]byte{0, 89, 7}: "LenovoEMC Products USA, LLC", [3]byte{0, 89, 121}: "Networked Energy Services", [3]byte{0, 89, 172}: "KPN. B.V.", @@ -10828,7 +10836,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 96, 5}: "FEEDBACK DATA LTD.", [3]byte{0, 96, 6}: "SOTEC CO., LTD", [3]byte{0, 96, 7}: "ACRES GAMING, INC.", - [3]byte{0, 96, 8}: "3COM CORPORATION", + [3]byte{0, 96, 8}: "3COM", [3]byte{0, 96, 9}: "Cisco Systems, Inc", [3]byte{0, 96, 10}: "SORD COMPUTER CORPORATION", [3]byte{0, 96, 11}: "LOGWARE GmbH", @@ -10960,7 +10968,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 96, 137}: "XATA", [3]byte{0, 96, 138}: "CITADEL COMPUTER", [3]byte{0, 96, 139}: "ConferTech International", - [3]byte{0, 96, 140}: "3COM CORPORATION", + [3]byte{0, 96, 140}: "3COM", [3]byte{0, 96, 141}: "UNIPULSE CORP.", [3]byte{0, 96, 142}: "HE ELECTRONICS, TECHNOLOGIE & SYSTEMTECHNIK GmbH", [3]byte{0, 96, 143}: "TEKRAM TECHNOLOGY CO., LTD.", @@ -10971,7 +10979,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 96, 148}: "IBM Corp", [3]byte{0, 96, 149}: "ACCU-TIME SYSTEMS, INC.", [3]byte{0, 96, 150}: "T.S. MICROTECH INC.", - [3]byte{0, 96, 151}: "3COM CORPORATION", + [3]byte{0, 96, 151}: "3COM", [3]byte{0, 96, 152}: "HT COMMUNICATIONS", [3]byte{0, 96, 153}: "SBE, Inc.", [3]byte{0, 96, 154}: "NJK TECHNO CO.", @@ -11092,9 +11100,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 111, 100}: "Samsung Electronics Co.,Ltd", [3]byte{0, 112, 176}: "M/A-COM INC. COMPANIES", [3]byte{0, 112, 179}: "DATA RECALL LTD.", + [3]byte{0, 113, 71}: "Amazon Technologies Inc.", [3]byte{0, 113, 194}: "PEGATRON CORPORATION", [3]byte{0, 113, 204}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{0, 114, 4}: "Samsung Electronics Co., Ltd. ARTIK", [3]byte{0, 114, 99}: "Netcore Technology Inc.", + [3]byte{0, 114, 120}: "Cisco Systems, Inc", [3]byte{0, 115, 141}: "Shenzhen TINNO Mobile Technology Corp.", [3]byte{0, 115, 224}: "Samsung Electronics Co.,Ltd", [3]byte{0, 116, 156}: "Ruijie Networks Co.,LTD", @@ -11106,8 +11117,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 120, 158}: "Sagemcom Broadband SAS", [3]byte{0, 120, 205}: "Ignition Design Labs", [3]byte{0, 123, 24}: "SENTRY Co., LTD.", + [3]byte{0, 124, 45}: "Samsung Electronics Co.,Ltd", [3]byte{0, 125, 250}: "Volkswagen Group of America", [3]byte{0, 126, 86}: "China Dragon Technology Limited", + [3]byte{0, 126, 149}: "Cisco Systems, Inc", [3]byte{0, 127, 40}: "Actiontec Electronics, Inc", [3]byte{0, 128, 0}: "MULTITECH SYSTEMS, INC.", [3]byte{0, 128, 1}: "PERIPHONICS CORPORATION", @@ -11291,7 +11304,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 128, 179}: "AVAL DATA CORPORATION", [3]byte{0, 128, 180}: "SOPHIA SYSTEMS", [3]byte{0, 128, 181}: "UNITED NETWORKS INC.", - [3]byte{0, 128, 182}: "THEMIS COMPUTER", + [3]byte{0, 128, 182}: "Mercury Systems – Trusted Mission Solutions, Inc.", [3]byte{0, 128, 183}: "STELLAR COMPUTER", [3]byte{0, 128, 184}: "DMG MORI B.U.G. CO., LTD.", [3]byte{0, 128, 185}: "ARCHE TECHNOLIGIES INC.", @@ -11378,7 +11391,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 139, 252}: "mixi,Inc.", [3]byte{0, 140, 16}: "Black Box Corp.", [3]byte{0, 140, 84}: "ADB Broadband Italia", - [3]byte{0, 140, 250}: "INVENTEC Corporation", + [3]byte{0, 140, 250}: "INVENTEC CORPORATION", [3]byte{0, 141, 78}: "CJSC NII STT", [3]byte{0, 141, 218}: "Link One Co., Ltd.", [3]byte{0, 142, 115}: "Cisco Systems, Inc", @@ -11387,7 +11400,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 144, 1}: "NISHIMU ELECTRONICS INDUSTRIES CO., LTD.", [3]byte{0, 144, 2}: "ALLGON AB", [3]byte{0, 144, 3}: "APLIO", - [3]byte{0, 144, 4}: "3COM EUROPE LTD.", + [3]byte{0, 144, 4}: "3COM EUROPE LTD", [3]byte{0, 144, 5}: "PROTECH SYSTEMS CO., LTD.", [3]byte{0, 144, 6}: "Hamamatsu Photonics K.K.", [3]byte{0, 144, 7}: "DOMEX TECHNOLOGY CORP.", @@ -11530,7 +11543,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 144, 144}: "I-BUS", [3]byte{0, 144, 145}: "DigitalScape, Inc.", [3]byte{0, 144, 146}: "Cisco Systems, Inc", - [3]byte{0, 144, 147}: "NANAO CORPORATION", + [3]byte{0, 144, 147}: "EIZO Corporation", [3]byte{0, 144, 148}: "OSPREY TECHNOLOGIES, INC.", [3]byte{0, 144, 149}: "UNIVERSAL AVIONICS", [3]byte{0, 144, 150}: "ASKEY COMPUTER CORP", @@ -11589,7 +11602,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 144, 203}: "Wireless OnLine, Inc.", [3]byte{0, 144, 204}: "PLANEX COMMUNICATIONS INC.", [3]byte{0, 144, 205}: "ENT-EMPRESA NACIONAL DE TELECOMMUNICACOES, S.A.", - [3]byte{0, 144, 206}: "TETRA GmbH", + [3]byte{0, 144, 206}: "avateramedical Mechatronics GmbH", [3]byte{0, 144, 207}: "NORTEL", [3]byte{0, 144, 208}: "Thomson Telecom Belgium", [3]byte{0, 144, 209}: "LEICHU ENTERPRISE CO., LTD.", @@ -11649,6 +11662,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 154, 205}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{0, 154, 210}: "Cisco Systems, Inc", [3]byte{0, 156, 2}: "Hewlett Packard", + [3]byte{0, 157, 107}: "Murata Manufacturing Co., Ltd.", [3]byte{0, 157, 142}: "CARDIAC RECORDERS, INC.", [3]byte{0, 158, 30}: "Cisco Systems, Inc", [3]byte{0, 158, 200}: "Xiaomi Communications Co Ltd", @@ -11685,10 +11699,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 160, 30}: "EST CORPORATION", [3]byte{0, 160, 31}: "TRICORD SYSTEMS, INC.", [3]byte{0, 160, 32}: "CITICORP/TTI", - [3]byte{0, 160, 33}: "General Dynamics", + [3]byte{0, 160, 33}: "General Dynamics Mission Systems", [3]byte{0, 160, 34}: "CENTRE FOR DEVELOPMENT OF ADVANCED COMPUTING", [3]byte{0, 160, 35}: "APPLIED CREATIVE TECHNOLOGY, INC.", - [3]byte{0, 160, 36}: "3COM CORPORATION", + [3]byte{0, 160, 36}: "3COM", [3]byte{0, 160, 37}: "REDCOM LABS INC.", [3]byte{0, 160, 38}: "TELDAT, S.A.", [3]byte{0, 160, 39}: "FIREPOWER SYSTEMS, INC.", @@ -11865,7 +11879,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 160, 210}: "ALLIED TELESIS INTERNATIONAL CORPORATION", [3]byte{0, 160, 211}: "INSTEM COMPUTER SYSTEMS, LTD.", [3]byte{0, 160, 212}: "RADIOLAN, INC.", - [3]byte{0, 160, 213}: "SIERRA WIRELESS INC.", + [3]byte{0, 160, 213}: "Sierra Wireless", [3]byte{0, 160, 214}: "SBE, Inc.", [3]byte{0, 160, 215}: "KASTEN CHASE APPLIED RESEARCH", [3]byte{0, 160, 216}: "SPECTRA - TEK", @@ -11917,6 +11931,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 163, 142}: "Cisco Systems, Inc", [3]byte{0, 163, 209}: "Cisco Systems, Inc", [3]byte{0, 165, 9}: "WigWag Inc.", + [3]byte{0, 165, 191}: "Cisco Systems, Inc", [3]byte{0, 166, 202}: "Cisco Systems, Inc", [3]byte{0, 167, 66}: "Cisco Systems, Inc", [3]byte{0, 167, 132}: "ITX security", @@ -11924,8 +11939,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 170, 1}: "Intel Corporation", [3]byte{0, 170, 2}: "Intel Corporation", [3]byte{0, 170, 60}: "OLIVETTI TELECOM SPA (OLTECO)", + [3]byte{0, 170, 110}: "Cisco Systems, Inc", [3]byte{0, 170, 112}: "LG Electronics (Mobile Communications)", [3]byte{0, 172, 224}: "ARRIS Group, Inc.", + [3]byte{0, 173, 36}: "D-Link International", [3]byte{0, 174, 205}: "Pensando Systems", [3]byte{0, 174, 250}: "Murata Manufacturing Co., Ltd.", [3]byte{0, 175, 31}: "Cisco Systems, Inc", @@ -11966,29 +11983,41 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 176, 238}: "Ajile Systems, Inc.", [3]byte{0, 176, 240}: "CALY NETWORKS", [3]byte{0, 176, 245}: "NetWorth Technologies, Inc.", - [3]byte{0, 179, 56}: "Kontron Design Manufacturing Services (M) Sdn. Bhd", + [3]byte{0, 177, 227}: "Cisco Systems, Inc", + [3]byte{0, 179, 56}: "Kontron Asia Pacific Design Sdn. Bhd", [3]byte{0, 179, 66}: "MacroSAN Technologies Co., Ltd.", [3]byte{0, 179, 98}: "Apple, Inc.", + [3]byte{0, 180, 245}: "DongGuan Siyoto Electronics Co., Ltd", [3]byte{0, 181, 109}: "David Electronics Co., LTD.", + [3]byte{0, 181, 208}: "Samsung Electronics Co.,Ltd", [3]byte{0, 181, 214}: "Omnibit Inc.", + [3]byte{0, 182, 112}: "Cisco Systems, Inc", [3]byte{0, 182, 159}: "Latch", + [3]byte{0, 183, 113}: "Cisco Systems, Inc", [3]byte{0, 183, 141}: "Nanjing Shining Electric Automation Co., Ltd", + [3]byte{0, 184, 179}: "Cisco Systems, Inc", + [3]byte{0, 184, 194}: "Heights Telecom T ltd", [3]byte{0, 185, 246}: "Shenzhen Super Rich Electronics Co.,Ltd", [3]byte{0, 186, 192}: "Biometric Access Company", [3]byte{0, 187, 1}: "OCTOTHORPE CORP.", - [3]byte{0, 187, 58}: "Private", + [3]byte{0, 187, 58}: "Amazon Technologies Inc.", + [3]byte{0, 187, 96}: "Intel Corporate", [3]byte{0, 187, 142}: "HME Co., Ltd.", [3]byte{0, 187, 193}: "CANON INC.", [3]byte{0, 187, 240}: "UNGERMANN-BASS INC.", + [3]byte{0, 188, 96}: "Cisco Systems, Inc", [3]byte{0, 189, 39}: "Exar Corp.", [3]byte{0, 189, 58}: "Nokia Corporation", [3]byte{0, 189, 130}: "Shenzhen YOUHUA Technology Co., Ltd", + [3]byte{0, 190, 59}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{0, 190, 117}: "Cisco Systems, Inc", [3]byte{0, 190, 158}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{0, 191, 21}: "Genetec Inc.", [3]byte{0, 191, 97}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 191, 119}: "Cisco Systems, Inc", [3]byte{0, 192, 0}: "LANOPTICS, LTD.", [3]byte{0, 192, 1}: "DIATEK PATIENT MANAGMENT", - [3]byte{0, 192, 2}: "SERCOMM CORPORATION", + [3]byte{0, 192, 2}: "Sercomm Corporation.", [3]byte{0, 192, 3}: "GLOBALNET COMMUNICATIONS", [3]byte{0, 192, 4}: "JAPAN BUSINESS COMPUTER CO.LTD", [3]byte{0, 192, 5}: "LIVINGSTON ENTERPRISES, INC.", @@ -12246,16 +12275,20 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 193, 100}: "Cisco Systems, Inc", [3]byte{0, 193, 177}: "Cisco Systems, Inc", [3]byte{0, 194, 198}: "Intel Corporate", + [3]byte{0, 195, 244}: "Samsung Electronics Co.,Ltd", [3]byte{0, 197, 219}: "Datatech Sistemas Digitales Avanzados SL", [3]byte{0, 198, 16}: "Apple, Inc.", [3]byte{0, 200, 139}: "Cisco Systems, Inc", [3]byte{0, 202, 229}: "Cisco Systems, Inc", [3]byte{0, 203, 0}: "Private", + [3]byte{0, 203, 180}: "SHENZHEN ATEKO PHOTOELECTRICITY CO.,LTD", [3]byte{0, 203, 189}: "Cambridge Broadband Networks Ltd.", + [3]byte{0, 204, 63}: "Universal Electronics, Inc.", [3]byte{0, 204, 252}: "Cisco Systems, Inc", [3]byte{0, 205, 144}: "MAS Elektronik AG", [3]byte{0, 205, 254}: "Apple, Inc.", [3]byte{0, 207, 28}: "Communication Machinery Corporation", + [3]byte{0, 207, 192}: "China Mobile Group Device Co.,Ltd.", [3]byte{0, 208, 0}: "FERRAN SCIENTIFIC, INC.", [3]byte{0, 208, 1}: "VST TECHNOLOGIES, INC.", [3]byte{0, 208, 2}: "DITECH CORPORATION", @@ -12301,7 +12334,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 208, 42}: "Voxent Systems Ltd.", [3]byte{0, 208, 43}: "JETCELL, INC.", [3]byte{0, 208, 44}: "CAMPBELL SCIENTIFIC, INC.", - [3]byte{0, 208, 45}: "ADEMCO", + [3]byte{0, 208, 45}: "Resideo", [3]byte{0, 208, 46}: "COMMUNICATION AUTOMATION CORP.", [3]byte{0, 208, 47}: "VLSI TECHNOLOGY INC.", [3]byte{0, 208, 48}: "Safetran Systems Corp", @@ -12406,7 +12439,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 208, 147}: "TQ - COMPONENTS GMBH", [3]byte{0, 208, 148}: "Seeion Control LLC", [3]byte{0, 208, 149}: "Alcatel-Lucent Enterprise", - [3]byte{0, 208, 150}: "3COM EUROPE LTD.", + [3]byte{0, 208, 150}: "3COM EUROPE LTD", [3]byte{0, 208, 151}: "Cisco Systems, Inc", [3]byte{0, 208, 152}: "Photon Dynamics Canada Inc.", [3]byte{0, 208, 153}: "Elcard Wireless Systems Oy", @@ -12462,7 +12495,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 208, 203}: "DASAN CO., LTD.", [3]byte{0, 208, 204}: "TECHNOLOGIES LYRE INC.", [3]byte{0, 208, 205}: "ATAN TECHNOLOGY INC.", - [3]byte{0, 208, 206}: "ASYST ELECTRONIC", + [3]byte{0, 208, 206}: "iSystem Labs", [3]byte{0, 208, 207}: "MORETON BAY", [3]byte{0, 208, 208}: "ZHONGXING TELECOM LTD.", [3]byte{0, 208, 209}: "Sycamore Networks", @@ -12472,7 +12505,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 208, 213}: "GRUNDIG AG", [3]byte{0, 208, 214}: "AETHRA TELECOMUNICAZIONI", [3]byte{0, 208, 215}: "B2C2, INC.", - [3]byte{0, 208, 216}: "3Com Corporation", + [3]byte{0, 208, 216}: "3COM", [3]byte{0, 208, 217}: "DEDICATED MICROCOMPUTERS", [3]byte{0, 208, 218}: "TAICOM DATA SYSTEMS CO., LTD.", [3]byte{0, 208, 219}: "MCQUAY INTERNATIONAL", @@ -12516,7 +12549,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 211, 24}: "SPG Controls", [3]byte{0, 211, 141}: "Hotel Technology Next Generation", [3]byte{0, 214, 50}: "GE Energy", + [3]byte{0, 214, 254}: "Cisco Systems, Inc", [3]byte{0, 215, 143}: "Cisco Systems, Inc", + [3]byte{0, 216, 97}: "Micro-Star INTL CO., LTD.", [3]byte{0, 217, 209}: "Sony Interactive Entertainment Inc.", [3]byte{0, 218, 85}: "Cisco Systems, Inc", [3]byte{0, 219, 30}: "Albedo Telecom SL", @@ -12549,7 +12584,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 224, 6}: "SILICON INTEGRATED SYS. CORP.", [3]byte{0, 224, 7}: "Avaya ECS Ltd", [3]byte{0, 224, 8}: "AMAZING CONTROLS! INC.", - [3]byte{0, 224, 9}: "MARATHON TECHNOLOGIES CORP.", + [3]byte{0, 224, 9}: "Stratus Technologies", [3]byte{0, 224, 10}: "DIBA, INC.", [3]byte{0, 224, 11}: "ROOFTOP COMMUNICATIONS CORP.", [3]byte{0, 224, 12}: "MOTOROLA", @@ -12632,7 +12667,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 224, 89}: "CONTROLLED ENVIRONMENTS, LTD.", [3]byte{0, 224, 90}: "GALEA NETWORK SECURITY", [3]byte{0, 224, 91}: "WEST END SYSTEMS CORP.", - [3]byte{0, 224, 92}: "Panasonic Healthcare Co., Ltd.", + [3]byte{0, 224, 92}: "PHC Corporation", [3]byte{0, 224, 93}: "UNITEC CO., LTD.", [3]byte{0, 224, 94}: "JAPAN AVIATION ELECTRONICS INDUSTRY, LTD.", [3]byte{0, 224, 95}: "e-Net, Inc.", @@ -12805,7 +12840,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 230, 211}: "NIXDORF COMPUTER CORP.", [3]byte{0, 230, 232}: "Netzin Technology Corporation,.Ltd.", [3]byte{0, 232, 171}: "Meggitt Training Systems, Inc.", - [3]byte{0, 235, 45}: "Sony Mobile Communications AB", + [3]byte{0, 234, 189}: "Cisco Systems, Inc", + [3]byte{0, 235, 45}: "Sony Mobile Communications Inc", [3]byte{0, 235, 213}: "Cisco Systems, Inc", [3]byte{0, 236, 10}: "Xiaomi Communications Co Ltd", [3]byte{0, 238, 189}: "HTC Corporation", @@ -12815,6 +12851,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 243, 219}: "WOO Sports", [3]byte{0, 244, 3}: "Orbis Systems Oy", [3]byte{0, 244, 111}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 244, 141}: "Liteon Technology Corporation", [3]byte{0, 244, 185}: "Apple, Inc.", [3]byte{0, 246, 99}: "Cisco Systems, Inc", [3]byte{0, 247, 111}: "Apple, Inc.", @@ -12827,30 +12864,35 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{0, 252, 112}: "Intrepid Control Systems, Inc.", [3]byte{0, 252, 139}: "Amazon Technologies Inc.", [3]byte{0, 252, 141}: "Hitron Technologies. Inc", + [3]byte{0, 252, 186}: "Cisco Systems, Inc", [3]byte{0, 253, 69}: "Hewlett Packard Enterprise", [3]byte{0, 253, 76}: "NEVATEC", [3]byte{0, 254, 200}: "Cisco Systems, Inc", [3]byte{2, 7, 1}: "RACAL-DATACOM", [3]byte{2, 28, 124}: "PERQ SYSTEMS CORPORATION", [3]byte{2, 96, 134}: "LOGIC REPLACEMENT TECH. LTD.", - [3]byte{2, 96, 140}: "3COM CORPORATION", + [3]byte{2, 96, 140}: "3COM", [3]byte{2, 112, 1}: "RACAL-DATACOM", [3]byte{2, 112, 176}: "M/A-COM INC. COMPANIES", [3]byte{2, 112, 179}: "DATA RECALL LTD.", [3]byte{2, 157, 142}: "CARDIAC RECORDERS, INC.", [3]byte{2, 170, 60}: "OLIVETTI TELECOMM SPA (OLTECO)", [3]byte{2, 187, 1}: "OCTOTHORPE CORP.", - [3]byte{2, 192, 140}: "3COM CORPORATION", + [3]byte{2, 192, 140}: "3COM", [3]byte{2, 207, 28}: "Communication Machinery Corporation", [3]byte{2, 230, 211}: "NIXDORF COMPUTER CORP.", [3]byte{4, 2, 31}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{4, 2, 202}: "Shenzhen Vtsonic Co.,ltd", [3]byte{4, 3, 214}: "Nintendo Co.,Ltd", [3]byte{4, 4, 234}: "Valens Semiconductor Ltd.", + [3]byte{4, 9, 115}: "Hewlett Packard Enterprise", + [3]byte{4, 9, 165}: "HFR, Inc.", [3]byte{4, 10, 131}: "Alcatel-Lucent", [3]byte{4, 10, 224}: "XMIT AG COMPUTER NETWORKS", [3]byte{4, 12, 206}: "Apple, Inc.", [3]byte{4, 14, 194}: "ViewSonic Mobile China Limited", [3]byte{4, 21, 82}: "Apple, Inc.", + [3]byte{4, 21, 217}: "Viwone", [3]byte{4, 24, 15}: "Samsung Electronics Co.,Ltd", [3]byte{4, 24, 182}: "Private", [3]byte{4, 24, 214}: "Ubiquiti Networks Inc.", @@ -12875,10 +12917,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{4, 47, 86}: "ATOCS (Shenzhen) LTD", [3]byte{4, 49, 16}: "Inspur Group Co., Ltd.", [3]byte{4, 50, 244}: "Partron", + [3]byte{4, 51, 133}: "Nanchang BlackShark Co.,Ltd.", [3]byte{4, 51, 137}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{4, 54, 4}: "Gyeyoung I&T", [3]byte{4, 58, 13}: "SM Optics S.r.l.", [3]byte{4, 61, 152}: "ChongQing QingJia Electronics CO.,LTD", + [3]byte{4, 64, 169}: "New H3C Technologies Co., Ltd", [3]byte{4, 65, 105}: "GoPro", [3]byte{4, 68, 161}: "TELECON GALICIA,S.A.", [3]byte{4, 70, 101}: "Murata Manufacturing Co., Ltd.", @@ -12889,6 +12933,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{4, 76, 239}: "Fujian Sanao Technology Co.,Ltd", [3]byte{4, 78, 6}: "Ericsson AB", [3]byte{4, 78, 90}: "ARRIS Group, Inc.", + [3]byte{4, 78, 175}: "LG Innotek", + [3]byte{4, 79, 23}: "HUMAX Co., Ltd.", [3]byte{4, 79, 76}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{4, 79, 139}: "Adapteva, Inc.", [3]byte{4, 79, 170}: "Ruckus Wireless", @@ -12914,6 +12960,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{4, 101, 101}: "Testop", [3]byte{4, 103, 133}: "scemtec Hard- und Software fuer Mess- und Steuerungstechnik GmbH", [3]byte{4, 105, 248}: "Apple, Inc.", + [3]byte{4, 107, 27}: "SYSDINE Co., Ltd.", + [3]byte{4, 107, 37}: "SICHUAN TIANYI COMHEART TELECOM CO.,LTD", [3]byte{4, 108, 157}: "Cisco Systems, Inc", [3]byte{4, 109, 66}: "Bryston Ltd.", [3]byte{4, 110, 2}: "OpenRTLS Group", @@ -12925,6 +12973,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{4, 117, 245}: "CSST", [3]byte{4, 118, 110}: "ALPS ELECTRIC CO.,LTD.", [3]byte{4, 120, 99}: "Shanghai MXCHIP Information Technology Co., Ltd.", + [3]byte{4, 121, 112}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{4, 121, 183}: "Texas Instruments", [3]byte{4, 125, 80}: "Shenzhen Kang Ying Technology Co.Ltd.", [3]byte{4, 125, 123}: "QUANTA COMPUTER INC.", [3]byte{4, 126, 74}: "moobox CO., Ltd.", @@ -12933,9 +12983,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{4, 136, 140}: "Eifelwerk Butler Systeme GmbH", [3]byte{4, 136, 226}: "Beats Electronics LLC", [3]byte{4, 138, 21}: "Avaya Inc", + [3]byte{4, 138, 225}: "FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD.", [3]byte{4, 139, 66}: "Skspruce Technologies", [3]byte{4, 140, 3}: "ThinPAD Technology (Shenzhen)CO.,LTD", [3]byte{4, 141, 56}: "Netcore Technology Inc.", + [3]byte{4, 145, 98}: "Microchip Technology Inc.", + [3]byte{4, 146, 38}: "ASUSTek COMPUTER INC.", [3]byte{4, 146, 238}: "iway AG", [3]byte{4, 148, 107}: "TECNO MOBILE LIMITED", [3]byte{4, 148, 161}: "CATCH THE WIND INC", @@ -12954,6 +13007,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{4, 163, 22}: "Texas Instruments", [3]byte{4, 163, 243}: "Emicon", [3]byte{4, 168, 42}: "Nokia Corporation", + [3]byte{4, 171, 24}: "ELECOM CO.,LTD.", + [3]byte{4, 172, 68}: "Holtek Semiconductor Inc.", [3]byte{4, 176, 231}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{4, 177, 103}: "Xiaomi Communications Co Ltd", [3]byte{4, 179, 182}: "Seamap (UK) Ltd", @@ -12961,6 +13016,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{4, 182, 72}: "ZENNER", [3]byte{4, 186, 54}: "Li Seng Technology Ltd", [3]byte{4, 187, 249}: "Pavilion Data Systems Inc", + [3]byte{4, 188, 135}: "Shenzhen JustLink Technology Co., LTD", [3]byte{4, 189, 112}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{4, 189, 136}: "Aruba Networks", [3]byte{4, 191, 109}: "Zyxel Communications Corporation", @@ -12971,13 +13027,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{4, 193, 3}: "Clover Network, Inc.", [3]byte{4, 193, 185}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{4, 194, 62}: "HTC Corporation", + [3]byte{4, 194, 65}: "Nokia", + [3]byte{4, 195, 230}: "IEEE Registration Authority", [3]byte{4, 197, 164}: "Cisco Systems, Inc", [3]byte{4, 200, 128}: "Samtec Inc", [3]byte{4, 201, 145}: "Phistek INC.", - [3]byte{4, 201, 217}: "Echostar Technologies Corp", + [3]byte{4, 201, 217}: "Dish Technologies Corp", [3]byte{4, 203, 29}: "Traka plc", [3]byte{4, 206, 20}: "Wilocity LTD.", + [3]byte{4, 206, 126}: "NXP France Semiconductors France", [3]byte{4, 207, 37}: "MANYCOLORS, INC.", + [3]byte{4, 207, 140}: "XIAOMI Electronics,CO.,LTD", + [3]byte{4, 209, 58}: "Xiaomi Communications Co Ltd", + [3]byte{4, 211, 176}: "Intel Corporate", [3]byte{4, 211, 207}: "Apple, Inc.", [3]byte{4, 212, 55}: "ZNV", [3]byte{4, 214, 170}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", @@ -12992,13 +13054,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{4, 224, 176}: "Shenzhen YOUHUA Technology Co., Ltd", [3]byte{4, 224, 196}: "TRIUMPH-ADLER AG", [3]byte{4, 225, 200}: "IMS Soluções em Energia Ltda.", + [3]byte{4, 226, 41}: "Qingdao Haier Technology Co.,Ltd", [3]byte{4, 226, 248}: "AEP Ticketing solutions srl", [3]byte{4, 228, 81}: "Texas Instruments", [3]byte{4, 229, 54}: "Apple, Inc.", [3]byte{4, 229, 72}: "Cohda Wireless Pty Ltd", + [3]byte{4, 229, 152}: "Xiaomi Communications Co Ltd", [3]byte{4, 230, 98}: "Acroname Inc.", [3]byte{4, 230, 118}: "AMPAK Technology, Inc.", [3]byte{4, 233, 229}: "PJRC.COM, LLC", + [3]byte{4, 235, 64}: "Cisco Systems, Inc", + [3]byte{4, 236, 187}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{4, 238, 145}: "x-fabric GmbH", [3]byte{4, 240, 33}: "Compex Systems Pte Ltd", [3]byte{4, 241, 40}: "HMD Global Oy", @@ -13008,7 +13074,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{4, 247, 228}: "Apple, Inc.", [3]byte{4, 248, 194}: "Flaircomm Microelectronics, Inc.", [3]byte{4, 249, 56}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{4, 249, 217}: "Speaker Electronic(Jiashan) Co.,Ltd", [3]byte{4, 250, 63}: "Opticore Inc.", + [3]byte{4, 250, 131}: "Qingdao Haier Technology Co.,Ltd", [3]byte{4, 254, 49}: "Samsung Electronics Co.,Ltd", [3]byte{4, 254, 127}: "Cisco Systems, Inc", [3]byte{4, 254, 141}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -13092,7 +13160,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{8, 0, 75}: "Planning Research Corp.", [3]byte{8, 0, 76}: "HYDRA COMPUTER SYSTEMS INC.", [3]byte{8, 0, 77}: "CORVUS SYSTEMS INC.", - [3]byte{8, 0, 78}: "3COM EUROPE LTD.", + [3]byte{8, 0, 78}: "3COM EUROPE LTD", [3]byte{8, 0, 79}: "CYGNET SYSTEMS", [3]byte{8, 0, 80}: "DAISY SYSTEMS CORP.", [3]byte{8, 0, 81}: "ExperData", @@ -13181,6 +13249,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{8, 24, 26}: "zte corporation", [3]byte{8, 24, 76}: "A. S. Thomas, Inc.", [3]byte{8, 25, 166}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{8, 29, 196}: "Thermo Fisher Scientific Messtechnik GmbH", [3]byte{8, 29, 251}: "Shanghai Mexon Communication Technology Co.,Ltd", [3]byte{8, 31, 63}: "WondaLink Inc.", [3]byte{8, 31, 113}: "TP-LINK TECHNOLOGIES CO.,LTD.", @@ -13189,12 +13258,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{8, 33, 239}: "Samsung Electronics Co.,Ltd", [3]byte{8, 35, 178}: "vivo Mobile Communication Co., Ltd.", [3]byte{8, 37, 34}: "ADVANSEE", + [3]byte{8, 37, 37}: "Xiaomi Communications Co Ltd", [3]byte{8, 39, 25}: "APS systems/electronic AG", [3]byte{8, 39, 206}: "NAGANO KEIKI CO., LTD.", [3]byte{8, 42, 208}: "SRD Innovations Inc.", [3]byte{8, 44, 176}: "Network Instruments", [3]byte{8, 46, 95}: "Hewlett Packard", [3]byte{8, 48, 107}: "Palo Alto Networks", + [3]byte{8, 53, 27}: "Shenzhen Jialihua Electronic Technology Co., Ltd", [3]byte{8, 53, 113}: "CASwell INC.", [3]byte{8, 53, 178}: "CoreEdge Networks Co., Ltd", [3]byte{8, 55, 61}: "Samsung Electronics Co.,Ltd", @@ -13212,6 +13283,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{8, 64, 39}: "Gridstore Inc.", [3]byte{8, 64, 243}: "Tenda Technology Co.,Ltd.Dongguan branch", [3]byte{8, 70, 86}: "VEO-LABS", + [3]byte{8, 71, 208}: "Nokia Shanghai Bell Co. Ltd.)", [3]byte{8, 72, 44}: "Raycore Taiwan Co., LTD.", [3]byte{8, 74, 207}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{8, 78, 28}: "H2A Systems, LLC", @@ -13233,6 +13305,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{8, 104, 208}: "Japan System Design", [3]byte{8, 104, 234}: "EITO ELECTRONICS CO., LTD.", [3]byte{8, 106, 10}: "ASKEY COMPUTER CORP", + [3]byte{8, 107, 215}: "Silicon Laboratories", [3]byte{8, 109, 65}: "Apple, Inc.", [3]byte{8, 109, 242}: "Shenzhen MIMOWAVE Technology Co.,Ltd", [3]byte{8, 112, 69}: "Apple, Inc.", @@ -13258,10 +13331,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{8, 141, 200}: "Ryowa Electronics Co.,Ltd", [3]byte{8, 142, 79}: "SF Software Solutions", [3]byte{8, 143, 44}: "Hills Sound Vision & Lighting", + [3]byte{8, 144, 186}: "Danlaw Inc", [3]byte{8, 148, 239}: "Wistron Infocomm (Zhongshan) Corporation", [3]byte{8, 149, 42}: "Technicolor CH USA Inc.", [3]byte{8, 150, 173}: "Cisco Systems, Inc", [3]byte{8, 150, 215}: "AVM GmbH", + [3]byte{8, 151, 52}: "Hewlett Packard Enterprise", [3]byte{8, 151, 88}: "Shenzhen Strong Rising Electronics Co.,Ltd DongGuan Subsidiary", [3]byte{8, 155, 75}: "iKuai Networks", [3]byte{8, 158, 1}: "QUANTA COMPUTER INC.", @@ -13272,6 +13347,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{8, 168, 161}: "Cyclotronics Power Concepts, Inc", [3]byte{8, 169, 90}: "AzureWave Technology Inc.", [3]byte{8, 172, 165}: "Benu Video, Inc.", + [3]byte{8, 174, 214}: "Samsung Electronics Co.,Ltd", [3]byte{8, 175, 120}: "Totus Solutions, Inc.", [3]byte{8, 178, 88}: "Juniper Networks", [3]byte{8, 178, 163}: "Cynny Italia S.r.L.", @@ -13279,6 +13355,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{8, 183, 56}: "Lite-On Technogy Corp.", [3]byte{8, 183, 236}: "Wireless Seismic", [3]byte{8, 186, 34}: "Swaive Corporation", + [3]byte{8, 186, 95}: "Qingdao Hisense Electronics Co.,Ltd.", [3]byte{8, 187, 204}: "AK-NORD EDV VERTRIEBSGES. mbH", [3]byte{8, 188, 32}: "Hangzhou Royal Cloud Technology Co., Ltd", [3]byte{8, 189, 67}: "NETGEAR", @@ -13286,6 +13363,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{8, 190, 119}: "Green Electronics", [3]byte{8, 190, 172}: "Edimax Technology Co. Ltd.", [3]byte{8, 192, 33}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{8, 197, 225}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", [3]byte{8, 198, 179}: "QTECH LLC", [3]byte{8, 202, 69}: "Toyou Feiji Electronics Co., Ltd.", [3]byte{8, 204, 104}: "Cisco Systems, Inc", @@ -13297,11 +13375,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{8, 211, 75}: "Techman Electronics (Changshu) Co., Ltd.", [3]byte{8, 212, 12}: "Intel Corporate", [3]byte{8, 212, 43}: "Samsung Electronics Co.,Ltd", + [3]byte{8, 212, 106}: "LG Electronics (Mobile Communications)", + [3]byte{8, 213, 157}: "Sagemcom Broadband SAS", [3]byte{8, 213, 192}: "Seers Technology Co., Ltd", [3]byte{8, 216, 51}: "Shenzhen RF Technology Co., Ltd", [3]byte{8, 223, 31}: "Bose Corporation", + [3]byte{8, 223, 203}: "Systrome Networks", [3]byte{8, 229, 218}: "NANJING FUJITSU COMPUTER PRODUCTS CO.,LTD.", [3]byte{8, 230, 114}: "JEBSEE ELECTRONICS CO.,LTD.", + [3]byte{8, 230, 137}: "Apple, Inc.", [3]byte{8, 232, 79}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{8, 234, 64}: "SHENZHEN BILIAN ELECTRONIC CO.,LTD", [3]byte{8, 234, 68}: "Aerohive Networks Inc.", @@ -13315,17 +13397,21 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{8, 239, 59}: "MCS Logic Inc.", [3]byte{8, 239, 171}: "SAYME WIRELESS SENSOR NETWORK", [3]byte{8, 241, 183}: "Towerstream Corpration", + [3]byte{8, 241, 234}: "Hewlett Packard Enterprise", [3]byte{8, 242, 244}: "Net One Partners Co.,Ltd.", [3]byte{8, 244, 171}: "Apple, Inc.", + [3]byte{8, 246, 156}: "Apple, Inc.", [3]byte{8, 246, 248}: "GET Engineering", [3]byte{8, 247, 40}: "GLOBO Multimedia Sp. z o.o. Sp.k.", [3]byte{8, 250, 224}: "Fohhn Audio AG", [3]byte{8, 252, 82}: "OpenXS BV", [3]byte{8, 252, 136}: "Samsung Electronics Co.,Ltd", [3]byte{8, 253, 14}: "Samsung Electronics Co.,Ltd", + [3]byte{12, 1, 219}: "Infinix mobility limited", [3]byte{12, 2, 39}: "Technicolor CH USA Inc.", [3]byte{12, 4, 0}: "Jantar d.o.o.", [3]byte{12, 5, 53}: "Juniper Systems", + [3]byte{12, 8, 180}: "HUMAX Co., Ltd.", [3]byte{12, 17, 5}: "Ringslink (Xiamen) Network Communication Technologies Co., Ltd", [3]byte{12, 17, 103}: "Cisco Systems, Inc", [3]byte{12, 18, 98}: "zte corporation", @@ -13336,15 +13422,21 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{12, 23, 241}: "TELECSYS", [3]byte{12, 25, 31}: "Inform Electronik", [3]byte{12, 26, 16}: "Acoustic Stream", + [3]byte{12, 28, 25}: "LONGCONN ELECTRONICS(SHENZHEN) CO.,LTD", [3]byte{12, 28, 32}: "Kakao Corp", + [3]byte{12, 28, 87}: "Texas Instruments", [3]byte{12, 29, 175}: "Xiaomi Communications Co Ltd", [3]byte{12, 29, 194}: "SeAH Networks", [3]byte{12, 32, 38}: "noax Technologies AG", + [3]byte{12, 33, 56}: "Hengstler GmbH", + [3]byte{12, 35, 105}: "Honeywell SPS", [3]byte{12, 37, 118}: "LONGCHEER TELECOMMUNICATION LIMITED", [3]byte{12, 39, 36}: "Cisco Systems, Inc", [3]byte{12, 39, 85}: "Valuable Techologies Limited", [3]byte{12, 42, 105}: "electric imp, incorporated", + [3]byte{12, 42, 134}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{12, 42, 231}: "Beijing General Research Institute of Mining and Metallurgy", + [3]byte{12, 44, 84}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{12, 45, 137}: "QiiQ Communications Inc.", [3]byte{12, 48, 33}: "Apple, Inc.", [3]byte{12, 55, 71}: "zte corporation", @@ -13354,7 +13446,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{12, 60, 101}: "Dome Imaging Inc", [3]byte{12, 60, 205}: "Universal Global Scientific Industrial Co., Ltd.", [3]byte{12, 62, 159}: "Apple, Inc.", + [3]byte{12, 65, 1}: "Ruichi Auto Technology (Guangzhou) Co., Ltd.", [3]byte{12, 65, 62}: "Microsoft Corporation", + [3]byte{12, 65, 233}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{12, 69, 186}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{12, 70, 157}: "MS Sedco", [3]byte{12, 71, 61}: "Hitron Technologies. Inc", @@ -13368,6 +13462,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{12, 81, 1}: "Apple, Inc.", [3]byte{12, 81, 247}: "CHAUVIN ARNOUX", [3]byte{12, 82, 3}: "AGM GROUP LIMITED", + [3]byte{12, 83, 49}: "ETH Zurich", + [3]byte{12, 84, 21}: "Intel Corporate", [3]byte{12, 84, 165}: "PEGATRON CORPORATION", [3]byte{12, 84, 185}: "Nokia", [3]byte{12, 85, 33}: "Axiros GmbH", @@ -13382,21 +13478,28 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{12, 97, 17}: "Anda Technologies SAC", [3]byte{12, 97, 39}: "Actiontec Electronics, Inc", [3]byte{12, 97, 207}: "Texas Instruments", + [3]byte{12, 98, 166}: "Hui Zhou Gaoshengda Technology Co.,LTD", [3]byte{12, 99, 252}: "Nanjing Signway Technology Co., Ltd", [3]byte{12, 104, 3}: "Cisco Systems, Inc", + [3]byte{12, 106, 188}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{12, 106, 230}: "Stanley Security Solutions", [3]byte{12, 110, 79}: "PrimeVOLT Co., Ltd.", [3]byte{12, 111, 156}: "Shaw Communications Inc.", + [3]byte{12, 112, 74}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{12, 113, 93}: "Samsung Electronics Co.,Ltd", [3]byte{12, 114, 44}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{12, 114, 217}: "zte corporation", [3]byte{12, 115, 190}: "Dongguan Haimai Electronie Technology Co.,Ltd", + [3]byte{12, 115, 235}: "IEEE Registration Authority", [3]byte{12, 116, 194}: "Apple, Inc.", + [3]byte{12, 117, 18}: "Shenzhen Kunlun TongTai Technology Co.,Ltd.", [3]byte{12, 117, 35}: "BEIJING GEHUA CATV NETWORK CO.,LTD", [3]byte{12, 117, 108}: "Anaren Microwave, Inc.", [3]byte{12, 117, 189}: "Cisco Systems, Inc", [3]byte{12, 119, 26}: "Apple, Inc.", + [3]byte{12, 124, 40}: "Nokia", [3]byte{12, 125, 124}: "Kexiang Information Technology Co, Ltd.", + [3]byte{12, 128, 99}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{12, 129, 18}: "Private", [3]byte{12, 130, 48}: "SHENZHEN MAGNUS TECHNOLOGIES CO.,LTD", [3]byte{12, 130, 104}: "TP-LINK TECHNOLOGIES CO.,LTD.", @@ -13408,7 +13511,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{12, 134, 16}: "Juniper Networks", [3]byte{12, 137, 16}: "Samsung Electronics Co.,Ltd", [3]byte{12, 138, 135}: "AgLogica Holdings, Inc", + [3]byte{12, 139, 211}: "ITEL MOBILE LIMITED", [3]byte{12, 139, 253}: "Intel Corporate", + [3]byte{12, 140, 36}: "SHENZHEN BILIAN ELECTRONIC CO.,LTD", [3]byte{12, 140, 143}: "Kamo Technology Limited", [3]byte{12, 140, 220}: "Suunto Oy", [3]byte{12, 141, 152}: "TOP EIGHT IND CORP", @@ -13418,29 +13523,40 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{12, 146, 78}: "Rice Lake Weighing Systems", [3]byte{12, 147, 1}: "PT. Prasimax Inovasi Teknologi", [3]byte{12, 147, 251}: "BNS Solutions", + [3]byte{12, 149, 65}: "CHIPSEA TECHNOLOGIES (SHENZHEN) CORP.", [3]byte{12, 150, 191}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{12, 150, 230}: "Cloud Network Technology (Samoa) Limited", [3]byte{12, 152, 56}: "Xiaomi Communications Co Ltd", + [3]byte{12, 154, 66}: "FN-LINK TECHNOLOGY LIMITED", [3]byte{12, 155, 19}: "Shanghai Magic Mobile Telecommunication Co.Ltd.", [3]byte{12, 157, 86}: "Consort Controls Ltd", + [3]byte{12, 157, 146}: "ASUSTek COMPUTER INC.", [3]byte{12, 158, 145}: "Sankosha Corporation", [3]byte{12, 161, 56}: "Blinq Wireless Inc.", [3]byte{12, 162, 244}: "Chameleon Technology (UK) Limited", [3]byte{12, 164, 2}: "Alcatel-Lucent IPD", [3]byte{12, 164, 42}: "OB Telecom Electronic Technology Co., Ltd", [3]byte{12, 166, 148}: "Sunitec Enterprise Co.,Ltd", + [3]byte{12, 168, 167}: "Samsung Electronics Co.,Ltd", [3]byte{12, 172, 5}: "Unitend Technologies Inc.", + [3]byte{12, 174, 125}: "Texas Instruments", [3]byte{12, 175, 90}: "GENUS POWER INFRASTRUCTURES LIMITED", [3]byte{12, 178, 183}: "Texas Instruments", [3]byte{12, 179, 25}: "Samsung Electronics Co.,Ltd", + [3]byte{12, 179, 79}: "Shenzhen Xiaoqi Intelligent Technology Co., Ltd.", [3]byte{12, 180, 89}: "Marketech International Corp.", + [3]byte{12, 180, 164}: "Xintai Automobile Intelligent Network Technology", [3]byte{12, 180, 239}: "Digience Co.,Ltd.", + [3]byte{12, 181, 39}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{12, 181, 222}: "Alcatel Lucent", + [3]byte{12, 182, 210}: "D-Link International", [3]byte{12, 185, 18}: "JM-DATA GmbH", [3]byte{12, 185, 55}: "Ubee Interactive Co., Limited", [3]byte{12, 188, 159}: "Apple, Inc.", [3]byte{12, 189, 81}: "TCT mobile ltd", [3]byte{12, 191, 21}: "Genetec Inc.", [3]byte{12, 191, 63}: "Shenzhen Lencotion Technology Co.,Ltd", + [3]byte{12, 191, 116}: "Morse Micro", [3]byte{12, 192, 192}: "MAGNETI MARELLI SISTEMAS ELECTRONICOS MEXICO", [3]byte{12, 195, 167}: "Meritec", [3]byte{12, 196, 122}: "Super Micro Computer, Inc.", @@ -13448,15 +13564,18 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{12, 198, 85}: "Wuxi YSTen Technology Co.,Ltd.", [3]byte{12, 198, 106}: "Nokia Corporation", [3]byte{12, 198, 172}: "DAGS", + [3]byte{12, 198, 204}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{12, 199, 49}: "Currant, Inc.", [3]byte{12, 200, 31}: "Summer Infant, Inc.", [3]byte{12, 201, 198}: "Samwin Hong Kong Limited", + [3]byte{12, 203, 133}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{12, 203, 141}: "ASCO Numatics GmbH", [3]byte{12, 204, 38}: "Airenetworks", [3]byte{12, 205, 211}: "EASTRIVER TECHNOLOGY CO., LTD.", [3]byte{12, 205, 251}: "EDIC Systems Inc.", [3]byte{12, 206, 246}: "Guizhou Fortuneship Technology Co., Ltd", [3]byte{12, 207, 209}: "SPRINGWAVE Co., Ltd", + [3]byte{12, 208, 248}: "Cisco Systems, Inc", [3]byte{12, 210, 146}: "Intel Corporate", [3]byte{12, 210, 181}: "Binatone Telecommunication Pvt. Ltd", [3]byte{12, 213, 2}: "Westell Technologies Inc.", @@ -13471,6 +13590,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{12, 220, 204}: "Inala Technologies", [3]byte{12, 221, 239}: "Nokia Corporation", [3]byte{12, 223, 164}: "Samsung Electronics Co.,Ltd", + [3]byte{12, 224, 220}: "Samsung Electronics Co.,Ltd", [3]byte{12, 224, 228}: "PLANTRONICS, INC.", [3]byte{12, 229, 211}: "DH electronics GmbH", [3]byte{12, 231, 9}: "Fox Crypto B.V.", @@ -13483,6 +13603,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{12, 239, 175}: "IEEE Registration Authority", [3]byte{12, 240, 25}: "Malgn Technology Co., Ltd.", [3]byte{12, 240, 180}: "Globalsat International Technology Ltd", + [3]byte{12, 243, 70}: "Xiaomi Communications Co Ltd", [3]byte{12, 243, 97}: "Java Information", [3]byte{12, 243, 238}: "EM Microelectronic", [3]byte{12, 244, 5}: "Beijing Signalway Technologies Co.,Ltd", @@ -13493,6 +13614,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{12, 252, 131}: "Airoha Technology Corp.,", [3]byte{12, 253, 55}: "SUSE Linux GmbH", [3]byte{12, 254, 69}: "Sony Interactive Entertainment Inc.", + [3]byte{12, 254, 93}: "IEEE Registration Authority", [3]byte{16, 0, 0}: "Private", [3]byte{16, 0, 90}: "IBM Corp", [3]byte{16, 0, 232}: "NATIONAL SEMICONDUCTOR", @@ -13519,18 +13641,20 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{16, 18, 24}: "Korins Inc.", [3]byte{16, 18, 72}: "ITG, Inc.", [3]byte{16, 18, 80}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", + [3]byte{16, 18, 180}: "SICHUAN TIANYI COMHEART TELECOM CO.,LTD", [3]byte{16, 19, 49}: "Technicolor", [3]byte{16, 19, 238}: "Justec International Technology INC.", [3]byte{16, 24, 158}: "Elmo Motion Control", [3]byte{16, 27, 84}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{16, 28, 12}: "Apple, Inc.", - [3]byte{16, 29, 81}: "ON-Q LLC dba ON-Q Mesh Networks", + [3]byte{16, 29, 81}: "8Mesh Networks Limited", [3]byte{16, 29, 192}: "Samsung Electronics Co.,Ltd", [3]byte{16, 31, 116}: "Hewlett Packard", [3]byte{16, 34, 121}: "ZeroDesktop, Inc.", [3]byte{16, 39, 190}: "TVIP", [3]byte{16, 40, 49}: "Morion Inc.", [3]byte{16, 42, 179}: "Xiaomi Communications Co Ltd", + [3]byte{16, 44, 107}: "AMPAK Technology, Inc.", [3]byte{16, 44, 131}: "XIMEA", [3]byte{16, 45, 150}: "Looxcie Inc.", [3]byte{16, 46, 175}: "Texas Instruments", @@ -13562,7 +13686,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{16, 86, 17}: "ARRIS Group, Inc.", [3]byte{16, 86, 202}: "Peplink International Ltd.", [3]byte{16, 88, 135}: "Fiberhome Telecommunication Technologies Co.,LTD", + [3]byte{16, 89, 23}: "Tonal", [3]byte{16, 90, 247}: "ADB Italia", + [3]byte{16, 91, 173}: "Mega Well Limited", [3]byte{16, 92, 59}: "Perma-Pipe, Inc.", [3]byte{16, 92, 191}: "DuroByte Inc", [3]byte{16, 95, 6}: "Actiontec Electronics, Inc", @@ -13570,8 +13696,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{16, 96, 75}: "Hewlett Packard", [3]byte{16, 98, 201}: "Adatis GmbH & Co. KG", [3]byte{16, 98, 208}: "Technicolor CH USA Inc.", + [3]byte{16, 98, 229}: "Hewlett Packard", [3]byte{16, 98, 235}: "D-Link International", [3]byte{16, 100, 226}: "ADFweb.com s.r.l.", + [3]byte{16, 101, 48}: "Dell Inc.", [3]byte{16, 101, 163}: "Core Brands LLC", [3]byte{16, 101, 207}: "IQSIM", [3]byte{16, 102, 130}: "NEC Platforms, Ltd.", @@ -13589,22 +13717,30 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{16, 120, 210}: "Elitegroup Computer Systems Co.,Ltd.", [3]byte{16, 122, 134}: "U&U ENGINEERING INC.", [3]byte{16, 123, 68}: "ASUSTek COMPUTER INC.", + [3]byte{16, 123, 164}: "Olive & Dove Co.,Ltd.", [3]byte{16, 123, 239}: "Zyxel Communications Corporation", [3]byte{16, 125, 26}: "Dell Inc.", + [3]byte{16, 129, 180}: "Hunan Greatwall Galaxy Science and Technology Co.,Ltd.", [3]byte{16, 131, 210}: "Microseven Systems, LLC", [3]byte{16, 134, 140}: "ARRIS Group, Inc.", [3]byte{16, 136, 15}: "Daruma Telecomunicações e Informática S.A.", [3]byte{16, 136, 206}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{16, 138, 27}: "RAONIX Inc.", [3]byte{16, 140, 207}: "Cisco Systems, Inc", + [3]byte{16, 142, 224}: "Samsung Electronics Co.,Ltd", [3]byte{16, 146, 102}: "Samsung Electronics Co.,Ltd", [3]byte{16, 147, 233}: "Apple, Inc.", + [3]byte{16, 148, 187}: "Apple, Inc.", [3]byte{16, 149, 75}: "Megabyte Ltd.", [3]byte{16, 152, 54}: "Dell Inc.", + [3]byte{16, 152, 195}: "Murata Manufacturing Co., Ltd.", [3]byte{16, 154, 185}: "Tosibox Oy", [3]byte{16, 154, 221}: "Apple, Inc.", + [3]byte{16, 158, 58}: "Zhejiang Tmall Technology Co., Ltd.", [3]byte{16, 159, 169}: "Actiontec Electronics, Inc", [3]byte{16, 161, 59}: "FUJIKURA RUBBER LTD.", + [3]byte{16, 162, 78}: "GOLD3LINK ELECTRONICS CO., LTD", + [3]byte{16, 164, 185}: "Baidu Online Network Technology (Beijing) Co., Ltd", [3]byte{16, 164, 190}: "SHENZHEN BILIAN ELECTRONIC CO.,LTD", [3]byte{16, 165, 208}: "Murata Manufacturing Co., Ltd.", [3]byte{16, 166, 89}: "Mobile Create Co.,Ltd.", @@ -13614,8 +13750,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{16, 175, 120}: "Shenzhen ATUE Technology Co., Ltd", [3]byte{16, 177, 248}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{16, 178, 107}: "base Co.,Ltd.", + [3]byte{16, 179, 111}: "Bowei Technology Company Limited", [3]byte{16, 183, 19}: "Private", [3]byte{16, 183, 246}: "Plastoform Industries Ltd.", + [3]byte{16, 185, 247}: "Niko-Servodan", [3]byte{16, 185, 254}: "Lika srl", [3]byte{16, 186, 165}: "GANA I&C CO., LTD", [3]byte{16, 189, 24}: "Cisco Systems, Inc", @@ -13623,17 +13761,23 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{16, 190, 245}: "D-Link International", [3]byte{16, 191, 72}: "ASUSTek COMPUTER INC.", [3]byte{16, 192, 124}: "Blu-ray Disc Association", + [3]byte{16, 193, 114}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{16, 194, 47}: "China Entropy Co., Ltd.", + [3]byte{16, 194, 90}: "Technicolor CH USA Inc.", [3]byte{16, 194, 186}: "UTT Co., Ltd.", [3]byte{16, 195, 123}: "ASUSTek COMPUTER INC.", [3]byte{16, 197, 134}: "BIO SOUND LAB CO., LTD.", + [3]byte{16, 197, 149}: "Lenovo", [3]byte{16, 198, 12}: "Domino UK Ltd", [3]byte{16, 198, 31}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{16, 198, 126}: "SHENZHEN JUCHIN TECHNOLOGY CO., LTD", [3]byte{16, 198, 252}: "Garmin International", [3]byte{16, 199, 63}: "Midas Klark Teknik Ltd", + [3]byte{16, 199, 83}: "Qingdao Intelligent&Precise Electronics Co.,Ltd.", [3]byte{16, 202, 129}: "PRECIA", [3]byte{16, 204, 27}: "Liverock technologies,INC", [3]byte{16, 204, 219}: "AXIMUM PRODUITS ELECTRONIQUES", + [3]byte{16, 205, 110}: "FISYS", [3]byte{16, 205, 174}: "Avaya Inc", [3]byte{16, 205, 182}: "Essential Products, Inc.", [3]byte{16, 206, 169}: "Texas Instruments", @@ -13647,11 +13791,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{16, 221, 244}: "Maxway Electronics CO.,LTD", [3]byte{16, 222, 228}: "automationNEXT GmbH", [3]byte{16, 223, 139}: "Shenzhen CareDear Communication Technology Co.,Ltd", + [3]byte{16, 223, 252}: "Siemens AG", [3]byte{16, 226, 213}: "Qi Hardware Inc.", [3]byte{16, 227, 199}: "Seohwa Telecom", [3]byte{16, 228, 175}: "APR, LLC", [3]byte{16, 230, 143}: "KWANGSUNG ELECTRONICS KOREA CO.,LTD.", [3]byte{16, 230, 174}: "Source Technologies, LLC", + [3]byte{16, 231, 198}: "Hewlett Packard", [3]byte{16, 232, 120}: "Nokia", [3]byte{16, 232, 238}: "PhaseSpace", [3]byte{16, 234, 89}: "Cisco SPVTG", @@ -13664,6 +13810,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{16, 244, 154}: "T3 Innovation", [3]byte{16, 246, 129}: "vivo Mobile Communication Co., Ltd.", [3]byte{16, 249, 111}: "LG Electronics (Mobile Communications)", + [3]byte{16, 249, 235}: "Industria Fueguina de Relojería Electrónica s.a.", [3]byte{16, 249, 238}: "Nokia Corporation", [3]byte{16, 250, 206}: "Reacheng Communication Technology Co.,Ltd", [3]byte{16, 251, 240}: "KangSheng LTD.", @@ -13676,15 +13823,18 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{20, 4, 103}: "SNK Technologies Co.,Ltd.", [3]byte{20, 7, 8}: "Private", [3]byte{20, 7, 224}: "Abrantix AG", + [3]byte{20, 9, 220}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{20, 12, 91}: "PLNetworks", [3]byte{20, 12, 118}: "FREEBOX SAS", [3]byte{20, 13, 79}: "Flextronics International", [3]byte{20, 16, 159}: "Apple, Inc.", + [3]byte{20, 17, 20}: "TECNO MOBILE LIMITED", [3]byte{20, 19, 48}: "Anakreon UK LLP", [3]byte{20, 19, 87}: "ATP Electronics, Inc.", [3]byte{20, 20, 75}: "Ruijie Networks Co.,LTD", [3]byte{20, 20, 230}: "Ningbo Sanhe Digital Co.,Ltd", [3]byte{20, 21, 124}: "TOKYO COSMOS ELECTRIC CO.,LTD.", + [3]byte{20, 22, 158}: "Wingtech Group (HongKong)Limited", [3]byte{20, 24, 119}: "Dell Inc.", [3]byte{20, 26, 81}: "Treetech Sistemas Digitais", [3]byte{20, 26, 163}: "Motorola Mobility LLC, a Lenovo Company", @@ -13692,6 +13842,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{20, 27, 240}: "Intellimedia Systems Ltd", [3]byte{20, 31, 120}: "Samsung Electronics Co.,Ltd", [3]byte{20, 31, 186}: "IEEE Registration Authority", + [3]byte{20, 32, 94}: "Apple, Inc.", + [3]byte{20, 34, 51}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{20, 34, 219}: "eero inc.", [3]byte{20, 35, 215}: "EUTRONIX CO., LTD.", [3]byte{20, 40, 130}: "MIDICOM ELECTRONICS CO.LTD", @@ -13711,6 +13863,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{20, 53, 179}: "Future Designs, Inc.", [3]byte{20, 54, 5}: "Nokia Corporation", [3]byte{20, 54, 198}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{20, 55, 25}: "PT Prakarsa Visi Valutama", [3]byte{20, 55, 59}: "PROCOM Systems", [3]byte{20, 58, 234}: "Dynapower Company LLC", [3]byte{20, 61, 242}: "Beijing Shidai Hongyuan Network Communication Co.,Ltd", @@ -13722,16 +13875,21 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{20, 67, 25}: "Creative&Link Technology Limited", [3]byte{20, 68, 74}: "Apollo Seiko Ltd.", [3]byte{20, 70, 228}: "AVISTEL", + [3]byte{20, 72, 2}: "THE YEOLRIM Co.,Ltd.", [3]byte{20, 72, 139}: "Shenzhen Doov Technology Co.,Ltd", [3]byte{20, 73, 120}: "Digital Control Incorporated", [3]byte{20, 73, 224}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", [3]byte{20, 76, 26}: "Max Communication GmbH", [3]byte{20, 77, 103}: "Zioncom Electronics (Shenzhen) Ltd.", + [3]byte{20, 78, 52}: "Remote Solution", + [3]byte{20, 79, 138}: "Intel Corporate", [3]byte{20, 79, 215}: "IEEE Registration Authority", [3]byte{20, 84, 18}: "Entis Co., Ltd.", [3]byte{20, 86, 69}: "Savitech Corp.", [3]byte{20, 86, 142}: "Samsung Electronics Co.,Ltd", + [3]byte{20, 87, 159}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{20, 88, 208}: "Hewlett Packard", + [3]byte{20, 89, 192}: "NETGEAR", [3]byte{20, 90, 5}: "Apple, Inc.", [3]byte{20, 90, 131}: "Logi-D inc", [3]byte{20, 91, 209}: "ARRIS Group, Inc.", @@ -13742,13 +13900,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{20, 97, 2}: "Alpine Electronics, Inc.", [3]byte{20, 97, 47}: "Avaya Inc", [3]byte{20, 99, 8}: "JABIL CIRCUIT (SHANGHAI) LTD.", + [3]byte{20, 105, 162}: "SICHUAN TIANYI COMHEART TELECOM CO.,LTD", [3]byte{20, 106, 11}: "Cypress Electronics Limited", [3]byte{20, 107, 114}: "Shenzhen Fortune Ship Technology Co., Ltd.", + [3]byte{20, 107, 156}: "SHENZHEN BILIAN ELECTRONIC CO.,LTD", [3]byte{20, 110, 10}: "Private", [3]byte{20, 115, 115}: "TUBITAK UEKAE", [3]byte{20, 116, 17}: "RIM", [3]byte{20, 117, 144}: "TP-LINK TECHNOLOGIES CO.,LTD.", - [3]byte{20, 120, 11}: "PerkinElmer Technologies GmbH & Co. KG", + [3]byte{20, 120, 11}: "Varex Imaging Deutschland AG", [3]byte{20, 121, 243}: "China Mobile Group Device Co.,Ltd.", [3]byte{20, 125, 179}: "JOA TELECOM.CO.,LTD", [3]byte{20, 125, 197}: "Murata Manufacturing Co., Ltd.", @@ -13763,10 +13923,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{20, 144, 144}: "KongTop industrial(shen zhen)CO.,LTD", [3]byte{20, 145, 130}: "Belkin International Inc.", [3]byte{20, 147, 70}: "PNI sensor corporation", + [3]byte{20, 148, 47}: "USYS CO.,LTD.", [3]byte{20, 148, 72}: "BLU CASTLE S.A.", + [3]byte{20, 150, 229}: "Samsung Electronics Co.,Ltd", [3]byte{20, 152, 125}: "Technicolor CH USA Inc.", [3]byte{20, 153, 226}: "Apple, Inc.", [3]byte{20, 154, 16}: "Microsoft Corporation", + [3]byte{20, 155, 47}: "JiangSu ZhongXie Intelligent Technology co., LTD", [3]byte{20, 157, 9}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{20, 158, 207}: "Dell Inc.", [3]byte{20, 159, 60}: "Samsung Electronics Co.,Ltd", @@ -13776,6 +13939,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{20, 163, 100}: "Samsung Electronics Co.,Ltd", [3]byte{20, 165, 26}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{20, 166, 44}: "S.M. Dezac S.A.", + [3]byte{20, 167, 43}: "currentoptronics Pvt.Ltd", [3]byte{20, 167, 139}: "Zhejiang Dahua Technology Co., Ltd.", [3]byte{20, 168, 107}: "ShenZhen Telacom Science&Technology Co., Ltd", [3]byte{20, 169, 227}: "MST CORPORATION", @@ -13796,14 +13960,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{20, 192, 137}: "DUNE HD LTD", [3]byte{20, 193, 38}: "Nokia Corporation", [3]byte{20, 193, 255}: "ShenZhen QianHai Comlan communication Co.,LTD", + [3]byte{20, 194, 19}: "Apple, Inc.", [3]byte{20, 194, 29}: "Sabtech Industries", [3]byte{20, 195, 194}: "K.A. Schmersal GmbH & Co. KG", + [3]byte{20, 198, 151}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{20, 201, 19}: "LG Electronics", + [3]byte{20, 202, 160}: "Hu&Co", [3]byte{20, 204, 32}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{20, 207, 141}: "OHSUNG", [3]byte{20, 207, 146}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{20, 207, 226}: "ARRIS Group, Inc.", + [3]byte{20, 208, 13}: "Apple, Inc.", [3]byte{20, 209, 31}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{20, 209, 105}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{20, 212, 254}: "ARRIS Group, Inc.", [3]byte{20, 214, 77}: "D-Link International", [3]byte{20, 215, 110}: "CONCH ELECTRONIC Co.,Ltd", @@ -13814,11 +13983,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{20, 228, 236}: "mLogic LLC", [3]byte{20, 230, 228}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{20, 231, 200}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", + [3]byte{20, 233, 178}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{20, 235, 51}: "BSMediasoft Co., Ltd.", [3]byte{20, 237, 165}: "Wächter GmbH Sicherheitssysteme", [3]byte{20, 237, 187}: "2Wire Inc", [3]byte{20, 237, 228}: "Kaiam Corporation", [3]byte{20, 238, 157}: "AirNav Systems LLC", + [3]byte{20, 239, 207}: "SCHREDER", [3]byte{20, 240, 197}: "Xtremio Ltd.", [3]byte{20, 242, 142}: "ShenYang ZhongKe-Allwin Technology Co.LTD", [3]byte{20, 244, 42}: "Samsung Electronics Co.,Ltd", @@ -13826,18 +13997,21 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{20, 248, 147}: "Wuhan FiberHome Digital Technology Co.,Ltd.", [3]byte{20, 254, 175}: "SAGITTAR LIMITED", [3]byte{20, 254, 181}: "Dell Inc.", - [3]byte{24, 0, 45}: "Sony Mobile Communications AB", + [3]byte{24, 0, 45}: "Sony Mobile Communications Inc", [3]byte{24, 0, 219}: "Fitbit Inc.", [3]byte{24, 1, 125}: "Harbin Arteor technology co., LTD", [3]byte{24, 1, 227}: "Bittium Wireless Ltd", + [3]byte{24, 1, 241}: "Xiaomi Communications Co Ltd", [3]byte{24, 3, 115}: "Dell Inc.", [3]byte{24, 3, 250}: "IBT Interfaces", + [3]byte{24, 4, 237}: "Texas Instruments", [3]byte{24, 6, 117}: "Dilax Intelcom GmbH", [3]byte{24, 6, 255}: "Acer Computer(Shanghai) Limited.", [3]byte{24, 11, 82}: "Nanotron Technologies GmbH", [3]byte{24, 12, 20}: "iSonea Limited", [3]byte{24, 12, 119}: "Westinghouse Electric Company, LLC", [3]byte{24, 12, 172}: "CANON INC.", + [3]byte{24, 15, 118}: "D-Link International", [3]byte{24, 16, 78}: "CEDINT-UPM", [3]byte{24, 18, 18}: "Cepton Technologies", [3]byte{24, 20, 32}: "TEB SAS", @@ -13847,7 +14021,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{24, 23, 37}: "Cameo Communications, Inc.", [3]byte{24, 25, 63}: "Tamtron Oy", [3]byte{24, 27, 235}: "Actiontec Electronics, Inc", + [3]byte{24, 29, 234}: "Intel Corporate", [3]byte{24, 30, 120}: "Sagemcom Broadband SAS", + [3]byte{24, 30, 149}: "AuVerte", [3]byte{24, 30, 176}: "Samsung Electronics Co.,Ltd", [3]byte{24, 32, 18}: "Aztech Associates Inc.", [3]byte{24, 32, 50}: "Apple, Inc.", @@ -13857,12 +14033,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{24, 34, 126}: "Samsung Electronics Co.,Ltd", [3]byte{24, 38, 102}: "Samsung Electronics Co.,Ltd", [3]byte{24, 40, 97}: "AirTies Wireless Networks", + [3]byte{24, 42, 68}: "HIROSE ELECTRONIC SYSTEM", [3]byte{24, 42, 123}: "Nintendo Co., Ltd.", [3]byte{24, 43, 5}: "8D Technologies", [3]byte{24, 44, 145}: "Concept Development, Inc.", [3]byte{24, 44, 180}: "Nectarsoft Co., Ltd.", [3]byte{24, 45, 152}: "Jinwoo Industrial system", [3]byte{24, 48, 9}: "Woojin Industrial Systems Co., Ltd.", + [3]byte{24, 49, 191}: "ASUSTek COMPUTER INC.", [3]byte{24, 50, 162}: "LAON TECHNOLOGY CO., LTD.", [3]byte{24, 51, 157}: "Cisco Systems, Inc", [3]byte{24, 52, 81}: "Apple, Inc.", @@ -13870,9 +14048,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{24, 54, 252}: "Elecsys International Corporation", [3]byte{24, 56, 37}: "Wuhan Lingjiu High-tech Co.,Ltd.", [3]byte{24, 56, 100}: "CAP-TECH INTERNATIONAL CO., LTD.", + [3]byte{24, 56, 174}: "CONSPIN SOLUTION", [3]byte{24, 57, 25}: "Unicoi Systems", [3]byte{24, 57, 110}: "SUNSEA TELECOMMUNICATIONS CO.,LTD.", [3]byte{24, 58, 45}: "Samsung Electronics Co.,Ltd", + [3]byte{24, 58, 72}: "VostroNet", [3]byte{24, 59, 210}: "BYD Precision Manufacture Company Ltd.", [3]byte{24, 61, 162}: "Intel Corporate", [3]byte{24, 63, 71}: "Samsung Electronics Co.,Ltd", @@ -13884,13 +14064,18 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{24, 70, 23}: "Samsung Electronics Co.,Ltd", [3]byte{24, 72, 216}: "Fastback Networks", [3]byte{24, 74, 111}: "Alcatel-Lucent Shanghai Bell Co., Ltd", + [3]byte{24, 75, 13}: "Ruckus Wireless", + [3]byte{24, 75, 223}: "Caavo Inc", + [3]byte{24, 76, 8}: "Rockwell Automation", [3]byte{24, 78, 148}: "MESSOA TECHNOLOGIES INC.", [3]byte{24, 79, 50}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{24, 80, 42}: "SOARNEX", [3]byte{24, 82, 7}: "SICHUAN TIANYI COMHEART TELECOMCO., LTD", [3]byte{24, 82, 83}: "Pixord Corporation", [3]byte{24, 82, 130}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{24, 83, 224}: "Hanyang Digitech Co.Ltd", [3]byte{24, 85, 15}: "Cisco SPVTG", + [3]byte{24, 86, 128}: "Intel Corporate", [3]byte{24, 89, 51}: "Cisco SPVTG", [3]byte{24, 89, 54}: "Xiaomi Communications Co Ltd", [3]byte{24, 90, 232}: "Zenotech.Co.,Ltd", @@ -13899,9 +14084,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{24, 96, 36}: "Hewlett Packard", [3]byte{24, 97, 199}: "lemonbeat GmbH", [3]byte{24, 98, 44}: "Sagemcom Broadband SAS", + [3]byte{24, 98, 228}: "Texas Instruments", [3]byte{24, 100, 114}: "Aruba Networks", [3]byte{24, 101, 113}: "Top Victory Electronics (Taiwan) Co., Ltd.", [3]byte{24, 101, 144}: "Apple, Inc.", + [3]byte{24, 102, 199}: "Shenzhen Libre Technology Co., Ltd", [3]byte{24, 102, 218}: "Dell Inc.", [3]byte{24, 102, 227}: "Veros Systems, Inc.", [3]byte{24, 103, 63}: "Hanover Displays Limited", @@ -13910,6 +14097,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{24, 104, 106}: "zte corporation", [3]byte{24, 104, 130}: "Beward R&D Co., Ltd.", [3]byte{24, 104, 203}: "Hangzhou Hikvision Digital Technology Co.,Ltd.", + [3]byte{24, 105, 218}: "China Mobile Group Device Co.,Ltd.", [3]byte{24, 109, 153}: "Adanis Inc.", [3]byte{24, 113, 23}: "eta plus electronic gmbh", [3]byte{24, 116, 46}: "Amazon Technologies Inc.", @@ -13921,6 +14109,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{24, 128, 144}: "Cisco Systems, Inc", [3]byte{24, 128, 206}: "Barberry Solutions Ltd", [3]byte{24, 128, 245}: "Alcatel-Lucent Shanghai Bell Co., Ltd", + [3]byte{24, 129, 14}: "Apple, Inc.", [3]byte{24, 130, 25}: "Alibaba Cloud Computing Ltd.", [3]byte{24, 131, 49}: "Samsung Electronics Co.,Ltd", [3]byte{24, 131, 191}: "Arcadyan Technology Corporation", @@ -13930,6 +14119,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{24, 135, 150}: "HTC Corporation", [3]byte{24, 136, 87}: "Beijing Jinhong Xi-Dian Information Technology Corp.", [3]byte{24, 137, 91}: "Samsung Electronics Co.,Ltd", + [3]byte{24, 137, 160}: "Wuhan Funshion Online Technologies Co.,Ltd", [3]byte{24, 137, 223}: "CerebrEX Inc.", [3]byte{24, 139, 21}: "ShenZhen ZhongRuiJing Technology co.,LTD", [3]byte{24, 139, 69}: "Cisco Systems, Inc", @@ -13938,20 +14128,26 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{24, 142, 249}: "G2C Co. Ltd.", [3]byte{24, 144, 216}: "Sagemcom Broadband SAS", [3]byte{24, 146, 44}: "Virtual Instruments", + [3]byte{24, 147, 127}: "AMPAK Technology, Inc.", [3]byte{24, 147, 215}: "Texas Instruments", + [3]byte{24, 148, 198}: "ShenZhen Chenyee Technology Co., Ltd.", [3]byte{24, 151, 255}: "TechFaith Wireless Technology Limited", [3]byte{24, 153, 245}: "Sichuan Changhong Electric Ltd.", [3]byte{24, 154, 103}: "CSE-Servelec Limited", [3]byte{24, 155, 165}: "IEEE Registration Authority", + [3]byte{24, 156, 39}: "ARRIS Group, Inc.", [3]byte{24, 156, 93}: "Cisco Systems, Inc", [3]byte{24, 158, 252}: "Apple, Inc.", + [3]byte{24, 162, 138}: "Essel-T Co., Ltd", [3]byte{24, 163, 232}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{24, 166, 247}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{24, 167, 241}: "Qingdao Haier Technology Co.,Ltd", [3]byte{24, 169, 5}: "Hewlett Packard", [3]byte{24, 169, 88}: "PROVISION THAI CO., LTD.", [3]byte{24, 169, 155}: "Dell Inc.", [3]byte{24, 170, 69}: "Fon Technology", [3]byte{24, 171, 245}: "Ultra Electronics Electrics", + [3]byte{24, 172, 158}: "ITEL MOBILE LIMITED", [3]byte{24, 173, 77}: "Polostar Technology Corporation", [3]byte{24, 174, 187}: "Siemens Convergence Creators GmbH&Co.KG", [3]byte{24, 175, 97}: "Apple, Inc.", @@ -13964,10 +14160,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{24, 181, 145}: "I-Storm", [3]byte{24, 183, 158}: "Invoxia", [3]byte{24, 184, 31}: "ARRIS Group, Inc.", + [3]byte{24, 185, 5}: "Hong Kong Bouffalo Lab Limited", + [3]byte{24, 187, 38}: "FN-LINK TECHNOLOGY LIMITED", [3]byte{24, 188, 90}: "Zhejiang Tmall Technology Co., Ltd.", [3]byte{24, 189, 173}: "L-TECH CORPORATION", + [3]byte{24, 190, 146}: "Delta Networks, Inc.", [3]byte{24, 192, 134}: "Broadcom", [3]byte{24, 193, 157}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", + [3]byte{24, 194, 191}: "BUFFALO.INC", [3]byte{24, 196, 81}: "Tucson Embedded Systems", [3]byte{24, 197, 1}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", [3]byte{24, 197, 138}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -13982,6 +14182,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{24, 214, 106}: "Inmarsat", [3]byte{24, 214, 199}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{24, 214, 207}: "Kurth Electronic GmbH", + [3]byte{24, 215, 23}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{24, 217, 73}: "Qvis Labs, LLC", [3]byte{24, 219, 242}: "Dell Inc.", [3]byte{24, 220, 86}: "Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd", @@ -13993,11 +14194,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{24, 231, 40}: "Cisco Systems, Inc", [3]byte{24, 231, 244}: "Apple, Inc.", [3]byte{24, 232, 15}: "Viking Electronics Inc.", + [3]byte{24, 232, 41}: "Ubiquiti Networks Inc.", [3]byte{24, 232, 221}: "MODULETEK", [3]byte{24, 238, 105}: "Apple, Inc.", [3]byte{24, 239, 99}: "Cisco Systems, Inc", [3]byte{24, 240, 228}: "Xiaomi Communications Co Ltd", [3]byte{24, 241, 69}: "NetComm Wireless Limited", + [3]byte{24, 241, 216}: "Apple, Inc.", [3]byte{24, 242, 146}: "Shannon Systems", [3]byte{24, 244, 106}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{24, 246, 67}: "Apple, Inc.", @@ -14010,11 +14213,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{24, 254, 52}: "Espressif Inc.", [3]byte{24, 255, 15}: "Intel Corporate", [3]byte{24, 255, 46}: "Shenzhen Rui Ying Da Technology Co., Ltd", + [3]byte{28, 0, 66}: "NARI Technology Co., Ltd.", [3]byte{28, 6, 86}: "IDY Corporation", [3]byte{28, 8, 193}: "Lg Innotek", [3]byte{28, 11, 82}: "EPICOM S.A", [3]byte{28, 15, 175}: "Lucid Vision Labs", [3]byte{28, 15, 207}: "Sypro Optics GmbH", + [3]byte{28, 17, 97}: "Ciena Corporation", [3]byte{28, 17, 225}: "Wartsila Finland Oy", [3]byte{28, 18, 157}: "IEEE PES PSRC/SUB", [3]byte{28, 20, 72}: "ARRIS Group, Inc.", @@ -14026,6 +14231,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{28, 26, 192}: "Apple, Inc.", [3]byte{28, 27, 13}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", [3]byte{28, 27, 104}: "ARRIS Group, Inc.", + [3]byte{28, 27, 181}: "Intel Corporate", [3]byte{28, 28, 253}: "Dalian Hi-Think Computer Technology, Corp", [3]byte{28, 29, 103}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{28, 29, 134}: "Cisco Systems, Inc", @@ -14034,6 +14240,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{28, 33, 209}: "IEEE Registration Authority", [3]byte{28, 35, 44}: "Samsung Electronics Co.,Ltd", [3]byte{28, 35, 79}: "EDMI Europe Ltd", + [3]byte{28, 36, 205}: "Askey Computer Corp.", [3]byte{28, 37, 225}: "China Mobile IOT Company Limited", [3]byte{28, 39, 221}: "Datang Gohighsec(zhejiang)Information Technology Co.,Ltd.", [3]byte{28, 51, 14}: "PernixData", @@ -14051,6 +14258,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{28, 64, 36}: "Dell Inc.", [3]byte{28, 64, 232}: "SHENZHEN PROGRESS&WIN TECHNOLOGY CO.,LTD", [3]byte{28, 65, 88}: "Gemalto M2M GmbH", + [3]byte{28, 66, 125}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{28, 67, 236}: "JAPAN CIRCUIT CO.,LTD", [3]byte{28, 68, 25}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{28, 69, 147}: "Texas Instruments", @@ -14065,9 +14273,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{28, 81, 181}: "Techaya LTD", [3]byte{28, 82, 22}: "DONGGUAN HELE ELECTRONICS CO., LTD", [3]byte{28, 82, 214}: "FLAT DISPLAY TECHNOLOGY CORPORATION", + [3]byte{28, 84, 158}: "Universal Electronics, Inc.", [3]byte{28, 85, 58}: "QianGua Corp.", [3]byte{28, 86, 254}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{28, 87, 216}: "Kraftway Corporation PLC", + [3]byte{28, 89, 155}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{28, 90, 11}: "Tegile Systems", [3]byte{28, 90, 62}: "Samsung Electronics Co.,Ltd", [3]byte{28, 90, 107}: "Philips Electronics Nederland BV", @@ -14076,7 +14286,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{28, 92, 242}: "Apple, Inc.", [3]byte{28, 95, 43}: "D-Link International", [3]byte{28, 95, 255}: "Beijing Ereneben Information Technology Co.,Ltd Shenzhen Branch", - [3]byte{28, 96, 222}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", + [3]byte{28, 96, 222}: "MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", [3]byte{28, 98, 184}: "Samsung Electronics Co.,Ltd", [3]byte{28, 99, 183}: "OpenProducts 237 AB", [3]byte{28, 101, 157}: "Liteon Technology Corporation", @@ -14097,7 +14307,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{28, 118, 202}: "Terasic Technologies Inc.", [3]byte{28, 119, 246}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{28, 120, 57}: "Shenzhen Tencent Computer System Co., Ltd.", - [3]byte{28, 123, 33}: "Sony Mobile Communications AB", + [3]byte{28, 123, 33}: "Sony Mobile Communications Inc", [3]byte{28, 123, 35}: "Qingdao Hisense Communications Co.,Ltd.", [3]byte{28, 124, 17}: "EID", [3]byte{28, 124, 69}: "Vitek Industrial Video Products, Inc.", @@ -14118,7 +14328,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{28, 148, 146}: "RUAG Schweiz AG", [3]byte{28, 149, 93}: "I-LAX ELECTRONICS INC.", [3]byte{28, 149, 159}: "Veethree Electronics And Marine LLC", - [3]byte{28, 150, 90}: "Weifang GoerTek Technology Co.,Ltd.", + [3]byte{28, 150, 90}: "WEIFANG GOERTEK ELECTRONICS CO.,LTD", [3]byte{28, 151, 61}: "PRICOM Design", [3]byte{28, 152, 236}: "Hewlett Packard Enterprise", [3]byte{28, 153, 76}: "Murata Manufacturing Co., Ltd.", @@ -14126,6 +14336,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{28, 157, 62}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{28, 158, 70}: "Apple, Inc.", [3]byte{28, 158, 203}: "Beijing Nari Smartchip Microelectronics Company Limited", + [3]byte{28, 160, 184}: "Hon Hai Precision Ind. Co., Ltd.", [3]byte{28, 160, 211}: "IEEE Registration Authority", [3]byte{28, 162, 177}: "ruwido austria gmbh", [3]byte{28, 165, 50}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", @@ -14138,6 +14349,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{28, 173, 209}: "Bosung Electronics Co., Ltd.", [3]byte{28, 175, 5}: "Samsung Electronics Co.,Ltd", [3]byte{28, 175, 247}: "D-Link International", + [3]byte{28, 176, 68}: "ASKEY COMPUTER CORP", [3]byte{28, 176, 148}: "HTC Corporation", [3]byte{28, 177, 127}: "NEC Platforms, Ltd.", [3]byte{28, 178, 67}: "TDC A/S", @@ -14153,6 +14365,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{28, 193, 26}: "Wavetronix", [3]byte{28, 193, 222}: "Hewlett Packard", [3]byte{28, 195, 22}: "MileSight Technology Co., Ltd.", + [3]byte{28, 195, 235}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{28, 197, 134}: "Absolute Acoustics", [3]byte{28, 198, 60}: "Arcadyan Technology Corporation", [3]byte{28, 199, 45}: "Shenzhen Huapu Digital CO.,Ltd", @@ -14178,10 +14391,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{28, 239, 206}: "bebro electronic GmbH", [3]byte{28, 240, 62}: "Wearhaus Inc.", [3]byte{28, 240, 97}: "SCAPS GmbH", + [3]byte{28, 242, 154}: "Google, Inc.", [3]byte{28, 244, 202}: "Private", [3]byte{28, 245, 231}: "Turtle Industry Co., Ltd.", [3]byte{28, 250, 104}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{28, 252, 187}: "Realfiction ApS", + [3]byte{28, 253, 8}: "IEEE Registration Authority", [3]byte{28, 254, 167}: "IDentytech Solutins Ltd.", [3]byte{32, 1, 79}: "Linea Research Ltd", [3]byte{32, 2, 175}: "Murata Manufacturing Co., Ltd.", @@ -14193,36 +14408,47 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{32, 11, 199}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{32, 12, 200}: "NETGEAR", [3]byte{32, 14, 149}: "IEC – TC9 WG43", + [3]byte{32, 15, 112}: "FOXTECH", [3]byte{32, 16, 122}: "Gemtek Technology Co., Ltd.", [3]byte{32, 18, 87}: "Most Lucky Trading Ltd", [3]byte{32, 18, 213}: "Scientech Materials Corporation", [3]byte{32, 19, 224}: "Samsung Electronics Co.,Ltd", + [3]byte{32, 22, 61}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", + [3]byte{32, 22, 185}: "Intel Corporate", [3]byte{32, 22, 216}: "Liteon Technology Corporation", [3]byte{32, 24, 14}: "Shenzhen Sunchip Technology Co., Ltd", [3]byte{32, 26, 6}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", [3]byte{32, 29, 3}: "Elatec GmbH", + [3]byte{32, 31, 49}: "Inteno Broadband Technology AB", [3]byte{32, 33, 165}: "LG Electronics (Mobile Communications)", [3]byte{32, 37, 100}: "PEGATRON CORPORATION", [3]byte{32, 37, 152}: "Teleview", + [3]byte{32, 40, 62}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{32, 40, 188}: "Visionscape Co,. Ltd.", [3]byte{32, 43, 193}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{32, 44, 183}: "Kong Yue Electronics & Information Industry (Xinhui) Ltd.", [3]byte{32, 45, 7}: "Samsung Electronics Co.,Ltd", + [3]byte{32, 45, 35}: "Collinear Networks Inc.", [3]byte{32, 45, 248}: "Digital Media Cartridge Ltd.", [3]byte{32, 49, 235}: "HDSN", + [3]byte{32, 50, 51}: "SHENZHEN BILIAN ELECTRONIC CO.,LTD", + [3]byte{32, 54, 91}: "Megafone Limited", [3]byte{32, 55, 6}: "Cisco Systems, Inc", [3]byte{32, 55, 188}: "Kuipers Electronic Engineering BV", + [3]byte{32, 57, 86}: "HMD Global Oy", [3]byte{32, 58, 7}: "Cisco Systems, Inc", [3]byte{32, 58, 239}: "Sivantos GmbH", [3]byte{32, 60, 174}: "Apple, Inc.", [3]byte{32, 61, 102}: "ARRIS Group, Inc.", [3]byte{32, 61, 178}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{32, 61, 189}: "LG Innotek", [3]byte{32, 64, 5}: "feno GmbH", [3]byte{32, 65, 90}: "Smarteh d.o.o.", [3]byte{32, 68, 58}: "Schneider Electric Asia Pacific Ltd", [3]byte{32, 70, 161}: "VECOW Co., Ltd", [3]byte{32, 70, 249}: "Advanced Network Devices (dba:AND)", [3]byte{32, 71, 71}: "Dell Inc.", + [3]byte{32, 71, 218}: "Xiaomi Communications Co Ltd", [3]byte{32, 71, 237}: "BSkyB Ltd", [3]byte{32, 74, 170}: "Hanscan Spain S.A.", [3]byte{32, 76, 3}: "Aruba Networks", @@ -14232,7 +14458,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{32, 78, 113}: "Juniper Networks", [3]byte{32, 78, 127}: "NETGEAR", [3]byte{32, 83, 202}: "Risk Technology Ltd", - [3]byte{32, 84, 118}: "Sony Mobile Communications AB", + [3]byte{32, 84, 118}: "Sony Mobile Communications Inc", [3]byte{32, 84, 250}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{32, 85, 49}: "Samsung Electronics Co.,Ltd", [3]byte{32, 85, 50}: "Gotech International Technology Limited", @@ -14248,6 +14474,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{32, 98, 116}: "Microsoft Corporation", [3]byte{32, 99, 95}: "Abeeway", [3]byte{32, 100, 50}: "SAMSUNG ELECTRO MECHANICS CO., LTD.", + [3]byte{32, 103, 124}: "Hewlett Packard Enterprise", [3]byte{32, 103, 177}: "Pluto inc.", [3]byte{32, 104, 157}: "Liteon Technology Corporation", [3]byte{32, 106, 138}: "Wistron Infocomm (Zhongshan) Corporation", @@ -14265,6 +14492,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{32, 120, 11}: "Delta Faucet Company", [3]byte{32, 120, 82}: "Nokia", [3]byte{32, 120, 240}: "Apple, Inc.", + [3]byte{32, 121, 24}: "Intel Corporate", [3]byte{32, 124, 143}: "Quanta Microsystems,Inc.", [3]byte{32, 125, 116}: "Apple, Inc.", [3]byte{32, 130, 192}: "Xiaomi Communications Co Ltd", @@ -14285,16 +14513,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{32, 155, 205}: "Apple, Inc.", [3]byte{32, 162, 228}: "Apple, Inc.", [3]byte{32, 162, 231}: "Lee-Dickens Ltd", + [3]byte{32, 166, 12}: "Xiaomi Communications Co Ltd", [3]byte{32, 166, 128}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{32, 166, 205}: "Hewlett Packard Enterprise", [3]byte{32, 167, 131}: "miControl GmbH", [3]byte{32, 167, 135}: "Bointec Taiwan Corporation Limited", - [3]byte{32, 168, 185}: "Siemens", + [3]byte{32, 168, 185}: "SIEMENS AG", [3]byte{32, 169, 14}: "TCT mobile ltd", [3]byte{32, 169, 155}: "Microsoft Corporation", [3]byte{32, 170, 37}: "IP-NET LLC", [3]byte{32, 170, 75}: "Cisco-Linksys, LLC", [3]byte{32, 171, 55}: "Apple, Inc.", + [3]byte{32, 173, 86}: "Continental Automotive Systems Inc.", + [3]byte{32, 176, 1}: "Technicolor", [3]byte{32, 176, 247}: "Enclustra GmbH", [3]byte{32, 179, 153}: "Enterasys", [3]byte{32, 181, 198}: "Mimosa Networks", @@ -14323,10 +14554,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{32, 213, 191}: "Samsung Electronics Co.,Ltd", [3]byte{32, 214, 7}: "Nokia Corporation", [3]byte{32, 215, 90}: "Posh Mobile Limited", + [3]byte{32, 216, 11}: "Juniper Networks", [3]byte{32, 217, 6}: "Iota, Inc.", [3]byte{32, 219, 171}: "Samsung Electronics Co., Ltd.", [3]byte{32, 220, 147}: "Cheetah Hi-Tech, Inc.", [3]byte{32, 220, 230}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{32, 222, 136}: "IC Realtime LLC", [3]byte{32, 223, 63}: "Nanjing SAC Power Grid Automation Co., Ltd.", [3]byte{32, 223, 185}: "Google, Inc.", [3]byte{32, 224, 156}: "Nokia", @@ -14334,6 +14567,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{32, 229, 42}: "NETGEAR", [3]byte{32, 229, 100}: "ARRIS Group, Inc.", [3]byte{32, 231, 145}: "Siemens Healthcare Diagnostics, Inc", + [3]byte{32, 232, 130}: "zte corporation", [3]byte{32, 234, 199}: "SHENZHEN RIOPINE ELECTRONICS CO., LTD", [3]byte{32, 237, 116}: "Ability enterprise co.,Ltd.", [3]byte{32, 238, 40}: "Apple, Inc.", @@ -14346,6 +14580,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{32, 244, 82}: "Shanghai IUV Software Development Co. Ltd", [3]byte{32, 245, 16}: "Codex Digital Limited", [3]byte{32, 245, 67}: "Hui Zhou Gaoshengda Technology Co.,LTD", + [3]byte{32, 247, 124}: "vivo Mobile Communication Co., Ltd.", [3]byte{32, 248, 94}: "Delta Electronics", [3]byte{32, 250, 187}: "Cambridge Executive Limited", [3]byte{32, 253, 241}: "3COM EUROPE LTD", @@ -14354,10 +14589,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{36, 0, 186}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{36, 1, 199}: "Cisco Systems, Inc", [3]byte{36, 5, 15}: "MTN Electronic Co. Ltd", + [3]byte{36, 5, 136}: "Google, Inc.", [3]byte{36, 5, 245}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{36, 9, 23}: "Devlin Electronics Limited", [3]byte{36, 9, 149}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{36, 10, 17}: "TCT mobile ltd", + [3]byte{36, 10, 99}: "ARRIS Group, Inc.", [3]byte{36, 10, 100}: "AzureWave Technology Inc.", [3]byte{36, 10, 196}: "Espressif Inc.", [3]byte{36, 11, 10}: "Palo Alto Networks", @@ -14370,23 +14607,30 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{36, 17, 37}: "Hutek Co., Ltd.", [3]byte{36, 17, 72}: "Entropix, LLC", [3]byte{36, 17, 208}: "Chongqing Ehs Science and Technology Development Co.,Ltd.", + [3]byte{36, 24, 29}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", [3]byte{36, 26, 140}: "Squarehead Technology AS", [3]byte{36, 27, 19}: "Shanghai Nutshell Electronic Co., Ltd.", [3]byte{36, 27, 68}: "Hangzhou Tuners Electronics Co., Ltd", + [3]byte{36, 27, 122}: "Apple, Inc.", [3]byte{36, 28, 4}: "SHENZHEN JEHE TECHNOLOGY DEVELOPMENT CO., LTD.", [3]byte{36, 30, 235}: "Apple, Inc.", [3]byte{36, 31, 44}: "Calsys, Inc.", [3]byte{36, 31, 160}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{36, 32, 199}: "Sagemcom Broadband SAS", - [3]byte{36, 33, 171}: "Sony Mobile Communications AB", + [3]byte{36, 33, 36}: "Nokia", + [3]byte{36, 33, 171}: "Sony Mobile Communications Inc", [3]byte{36, 36, 14}: "Apple, Inc.", [3]byte{36, 38, 66}: "SHARP Corporation.", + [3]byte{36, 41, 254}: "KYOCERA Corporation", + [3]byte{36, 46, 2}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{36, 46, 144}: "PALIT MICROSYSTEMS, LTD", [3]byte{36, 47, 250}: "Toshiba Global Commerce Solutions", [3]byte{36, 49, 132}: "SHARP Corporation", [3]byte{36, 51, 108}: "Private", [3]byte{36, 53, 204}: "Zhongshan Scinan Internet of Things Co.,Ltd.", [3]byte{36, 55, 76}: "Cisco SPVTG", [3]byte{36, 55, 239}: "EMC Electronic Media Communication SA", + [3]byte{36, 58, 130}: "IRTS", [3]byte{36, 60, 32}: "Dynamode Group", [3]byte{36, 66, 188}: "Alinco,incorporated", [3]byte{36, 68, 39}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -14396,8 +14640,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{36, 75, 3}: "Samsung Electronics Co.,Ltd", [3]byte{36, 75, 129}: "Samsung Electronics Co.,Ltd", [3]byte{36, 76, 7}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{36, 76, 227}: "Amazon Technologies Inc.", [3]byte{36, 78, 123}: "IEEE Registration Authority", [3]byte{36, 79, 29}: "iRule LLC", + [3]byte{36, 83, 191}: "Enernet", [3]byte{36, 88, 128}: "VIZEO", [3]byte{36, 89, 11}: "White Sky Inc. Limited", [3]byte{36, 91, 167}: "Apple, Inc.", @@ -14426,11 +14672,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{36, 119, 3}: "Intel Corporate", [3]byte{36, 121, 42}: "Ruckus Wireless", [3]byte{36, 124, 76}: "Herman Miller", + [3]byte{36, 125, 77}: "Texas Instruments", + [3]byte{36, 126, 18}: "Cisco Systems, Inc", + [3]byte{36, 126, 81}: "zte corporation", [3]byte{36, 127, 32}: "Sagemcom Broadband SAS", [3]byte{36, 127, 60}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{36, 128, 0}: "Westcontrol AS", [3]byte{36, 129, 170}: "KSH International Co., Ltd.", [3]byte{36, 130, 138}: "Prowave Technologies Ltd.", + [3]byte{36, 132, 152}: "Beijing Jiaoda Microunion Tech.Co.,Ltd.", [3]byte{36, 134, 244}: "Ctek, Inc.", [3]byte{36, 135, 7}: "SEnergy Corporation", [3]byte{36, 136, 148}: "shenzhen lensun Communication Technology LTD", @@ -14468,6 +14718,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{36, 188, 130}: "Dali Wireless, Inc.", [3]byte{36, 188, 248}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{36, 190, 5}: "Hewlett Packard", + [3]byte{36, 190, 24}: "DADOUTEK COMPANY LIMITED", [3]byte{36, 191, 116}: "Private", [3]byte{36, 192, 179}: "RSF", [3]byte{36, 193, 189}: "CRRC DALIAN R&D CO.,LTD.", @@ -14475,15 +14726,18 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{36, 196, 47}: "Philips Lifeline", [3]byte{36, 196, 74}: "zte corporation", [3]byte{36, 198, 150}: "Samsung Electronics Co.,Ltd", - [3]byte{36, 200, 72}: "mywerk system GmbH", + [3]byte{36, 200, 72}: "mywerk Portal GmbH", [3]byte{36, 200, 110}: "Chaney Instrument Co.", [3]byte{36, 201, 161}: "Ruckus Wireless", [3]byte{36, 201, 222}: "Genoray", + [3]byte{36, 202, 203}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{36, 203, 231}: "MYK, Inc.", [3]byte{36, 207, 33}: "Shenzhen State Micro Technology Co., Ltd", [3]byte{36, 209, 63}: "MEXUS CO.,LTD", [3]byte{36, 210, 204}: "SmartDrive Systems Inc.", + [3]byte{36, 211, 242}: "zte corporation", [3]byte{36, 213, 28}: "Zhongtian broadband technology co., LTD", + [3]byte{36, 215, 107}: "Syntronic AB", [3]byte{36, 217, 33}: "Avaya Inc", [3]byte{36, 218, 17}: "NO NDA Inc", [3]byte{36, 218, 155}: "Motorola Mobility LLC, a Lenovo Company", @@ -14502,19 +14756,26 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{36, 233, 179}: "Cisco Systems, Inc", [3]byte{36, 234, 64}: "Helmholz GmbH & Co. KG", [3]byte{36, 235, 101}: "SAET I.S. S.r.l.", + [3]byte{36, 236, 81}: "ADF Technologies Sdn Bhd", [3]byte{36, 236, 153}: "ASKEY COMPUTER CORP", [3]byte{36, 236, 214}: "CSG Science & Technology Co.,Ltd.Hefei", [3]byte{36, 238, 58}: "Chengdu Yingji Electronic Hi-tech Co Ltd", [3]byte{36, 240, 148}: "Apple, Inc.", [3]byte{36, 240, 255}: "GHT Co., Ltd.", + [3]byte{36, 241, 40}: "Telstra", [3]byte{36, 242, 127}: "Hewlett Packard Enterprise", [3]byte{36, 242, 221}: "Radiant Zemax LLC", [3]byte{36, 245, 126}: "HWH CO., LTD.", [3]byte{36, 245, 162}: "Belkin International Inc.", [3]byte{36, 245, 170}: "Samsung Electronics Co.,Ltd", [3]byte{36, 246, 119}: "Apple, Inc.", + [3]byte{36, 250, 243}: "Shanghai Flexem Technology Co.,Ltd.", + [3]byte{36, 251, 101}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{36, 252, 229}: "Samsung Electronics Co.,Ltd", [3]byte{36, 253, 82}: "Liteon Technology Corporation", [3]byte{36, 253, 91}: "SmartThings, Inc.", + [3]byte{40, 2, 69}: "Konze System Technology Co.,Ltd.", + [3]byte{40, 2, 216}: "Samsung Electronics Co.,Ltd", [3]byte{40, 4, 224}: "FERMAX ELECTRONICA S.A.U.", [3]byte{40, 6, 30}: "NINGBO GLOBAL USEFUL ELECTRIC CO.,LTD", [3]byte{40, 6, 141}: "ITL, LLC", @@ -14526,8 +14787,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{40, 14, 139}: "Beijing Spirit Technology Development Co., Ltd.", [3]byte{40, 16, 27}: "MagnaCom", [3]byte{40, 16, 123}: "D-Link International", + [3]byte{40, 17, 165}: "Bose Corporation", [3]byte{40, 20, 113}: "Lantis co., LTD.", [3]byte{40, 22, 46}: "2Wire Inc", + [3]byte{40, 22, 168}: "Microsoft Corporation", [3]byte{40, 22, 173}: "Intel Corporate", [3]byte{40, 23, 206}: "Omnisense Ltd", [3]byte{40, 24, 120}: "Microsoft Corporation", @@ -14542,10 +14805,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{40, 41, 134}: "APC by Schneider Electric", [3]byte{40, 41, 204}: "Corsa Technology Incorporated", [3]byte{40, 41, 217}: "GlobalBeiMing technology (Beijing)Co. Ltd", + [3]byte{40, 44, 2}: "IEEE Registration Authority", [3]byte{40, 44, 178}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{40, 47, 194}: "Automotive Data Solutions", [3]byte{40, 48, 172}: "Frontiir Co. Ltd.", [3]byte{40, 49, 82}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{40, 49, 102}: "vivo Mobile Communication Co., Ltd.", [3]byte{40, 50, 197}: "HUMAX Co., Ltd.", [3]byte{40, 52, 16}: "Enigma Diagnostics Limited", [3]byte{40, 52, 162}: "Cisco Systems, Inc", @@ -14553,12 +14818,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{40, 54, 56}: "IEEE Registration Authority", [3]byte{40, 55, 19}: "Shenzhen 3Nod Digital Technology Co., Ltd.", [3]byte{40, 55, 55}: "Apple, Inc.", + [3]byte{40, 56, 92}: "FLEXTRONICS", [3]byte{40, 56, 207}: "Gen2wave", + [3]byte{40, 57, 38}: "CyberTAN Technology Inc.", [3]byte{40, 57, 94}: "Samsung Electronics Co.,Ltd", [3]byte{40, 57, 231}: "Preceno Technology Pte.Ltd.", + [3]byte{40, 58, 77}: "Cloud Network Technology (Samoa) Limited", + [3]byte{40, 59, 130}: "D-Link International", [3]byte{40, 59, 150}: "Cool Control LTD", [3]byte{40, 60, 228}: "HUAWEI TECHNOLOGIES CO.,LTD", - [3]byte{40, 63, 105}: "Sony Mobile Communications AB", + [3]byte{40, 62, 118}: "Common Networks", + [3]byte{40, 63, 105}: "Sony Mobile Communications Inc", [3]byte{40, 64, 26}: "C8 MediSensors, Inc.", [3]byte{40, 65, 33}: "OptiSense Network, LLC", [3]byte{40, 68, 48}: "GenesisTechnical Systems (UK) Ltd", @@ -14573,24 +14843,27 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{40, 82, 224}: "Layon international Electronic & Telecom Co.,Ltd", [3]byte{40, 86, 90}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{40, 86, 193}: "Harman International", - [3]byte{40, 87, 103}: "Echostar Technologies Corp", + [3]byte{40, 87, 103}: "Dish Technologies Corp", [3]byte{40, 87, 190}: "Hangzhou Hikvision Digital Technology Co.,Ltd.", [3]byte{40, 90, 235}: "Apple, Inc.", [3]byte{40, 95, 47}: "RNware Co.,Ltd.", [3]byte{40, 95, 219}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{40, 96, 70}: "Lantech Communications Global, Inc.", [3]byte{40, 96, 148}: "CAPELEC", - [3]byte{40, 99, 54}: "Siemens AG - Industrial Automation - EWA", + [3]byte{40, 99, 54}: "Siemens AG", [3]byte{40, 101, 107}: "Keystone Microtech Corporation", + [3]byte{40, 102, 227}: "AzureWave Technology Inc.", [3]byte{40, 106, 184}: "Apple, Inc.", [3]byte{40, 106, 186}: "Apple, Inc.", [3]byte{40, 108, 7}: "XIAOMI Electronics,CO.,LTD", [3]byte{40, 109, 151}: "SAMJIN Co., Ltd.", + [3]byte{40, 109, 205}: "Beijing Winner Microelectronics Co.,Ltd.", [3]byte{40, 110, 212}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{40, 111, 127}: "Cisco Systems, Inc", [3]byte{40, 113, 132}: "Spire Payments", [3]byte{40, 114, 197}: "Smartmatic Corp", [3]byte{40, 114, 240}: "ATHENA", + [3]byte{40, 117, 216}: "FUJIAN STAR-NET COMMUNICATION CO.,LTD", [3]byte{40, 118, 16}: "IgniteNet", [3]byte{40, 118, 205}: "Funshion Online Technologies Co.,Ltd", [3]byte{40, 121, 148}: "Realplay Digital Technology(Shenzhen) Co.,Ltd", @@ -14615,7 +14888,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{40, 153, 58}: "Arista Networks", [3]byte{40, 154, 75}: "SteelSeries ApS", [3]byte{40, 154, 250}: "TCT mobile ltd", + [3]byte{40, 158, 151}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{40, 158, 223}: "Danfoss Turbocor Compressors, Inc", + [3]byte{40, 158, 252}: "Sagemcom Broadband SAS", [3]byte{40, 160, 43}: "Apple, Inc.", [3]byte{40, 161, 131}: "ALPS ELECTRIC CO.,LTD.", [3]byte{40, 161, 134}: "enblink", @@ -14628,6 +14903,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{40, 166, 172}: "seca gmbh & co. kg", [3]byte{40, 166, 219}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{40, 172, 103}: "Mach Power, Rappresentanze Internazionali s.r.l.", + [3]byte{40, 172, 158}: "Cisco Systems, Inc", [3]byte{40, 173, 62}: "Shenzhen TONG BO WEI Technology CO.,LTD", [3]byte{40, 175, 10}: "Sirius XM Radio Inc", [3]byte{40, 176, 204}: "Xenya d.o.o.", @@ -14664,6 +14940,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{40, 207, 8}: "ESSYS", [3]byte{40, 207, 218}: "Apple, Inc.", [3]byte{40, 207, 233}: "Apple, Inc.", + [3]byte{40, 208, 203}: "Cambridge Communication Systems Ltd", [3]byte{40, 209, 175}: "Nokia Corporation", [3]byte{40, 210, 68}: "LCFC(HeFei) Electronics Technology Co., Ltd.", [3]byte{40, 212, 54}: "Jiangsu dewosi electric co., LTD", @@ -14683,8 +14960,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{40, 230, 233}: "SIS Sat Internet Services GmbH", [3]byte{40, 231, 148}: "Microtime Computer Inc.", [3]byte{40, 231, 207}: "Apple, Inc.", + [3]byte{40, 233, 142}: "Mitsubishi Electric Corporation", + [3]byte{40, 236, 154}: "Texas Instruments", [3]byte{40, 237, 88}: "JAG Jakob AG", [3]byte{40, 237, 106}: "Apple, Inc.", + [3]byte{40, 237, 224}: "AMPAK Technology, Inc.", [3]byte{40, 238, 44}: "Frontline Test Equipment", [3]byte{40, 238, 82}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{40, 238, 211}: "Shenzhen Super D Technology Co., Ltd", @@ -14702,6 +14982,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{40, 252, 246}: "Shenzhen Xin KingBrand enterprises Co.,Ltd", [3]byte{40, 253, 128}: "IEEE Registration Authority", [3]byte{40, 254, 205}: "Lemobile Information Technology (Beijing) Co., Ltd.", + [3]byte{40, 254, 222}: "COMESTA, Inc.", + [3]byte{40, 255, 60}: "Apple, Inc.", [3]byte{40, 255, 62}: "zte corporation", [3]byte{44, 0, 44}: "UNOWHY", [3]byte{44, 0, 51}: "EControls, LLC", @@ -14717,10 +14999,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{44, 11, 233}: "Cisco Systems, Inc", [3]byte{44, 14, 61}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", [3]byte{44, 16, 193}: "Nintendo Co., Ltd.", + [3]byte{44, 21, 225}: "Phicomm (Shanghai) Co., Ltd.", + [3]byte{44, 24, 117}: "Skyworth Digital Technology(Shenzhen) Co.,Ltd", [3]byte{44, 24, 174}: "Trend Electronics Co., Ltd.", [3]byte{44, 25, 132}: "IDN Telecom, Inc.", [3]byte{44, 26, 49}: "Electronics Company Limited", [3]byte{44, 27, 200}: "Hunan Topview Network System CO.,LTD", + [3]byte{44, 28, 246}: "Alien Green LLC", [3]byte{44, 29, 184}: "ARRIS Group, Inc.", [3]byte{44, 30, 234}: "AERODEV", [3]byte{44, 31, 35}: "Apple, Inc.", @@ -14737,6 +15022,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{44, 39, 158}: "IEEE Registration Authority", [3]byte{44, 39, 215}: "Hewlett Packard", [3]byte{44, 40, 45}: "BBK EDUCATIONAL ELECTRONICS CORP.,LTD.", + [3]byte{44, 40, 183}: "Hangzhou Ruiying technology co., LTD", [3]byte{44, 41, 151}: "Microsoft Corporation", [3]byte{44, 45, 72}: "bct electronic GesmbH", [3]byte{44, 48, 51}: "NETGEAR", @@ -14769,8 +15055,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{44, 68, 1}: "Samsung Electronics Co.,Ltd", [3]byte{44, 68, 27}: "Spectrum Medical Limited", [3]byte{44, 68, 253}: "Hewlett Packard", + [3]byte{44, 71, 89}: "Beijing MEGA preponderance Science & Technology Co. Ltd", + [3]byte{44, 72, 53}: "IEEE Registration Authority", [3]byte{44, 77, 84}: "ASUSTek COMPUTER INC.", - [3]byte{44, 77, 121}: "Weifang GoerTek Technology Co.,Ltd.", + [3]byte{44, 77, 121}: "WEIFANG GOERTEK ELECTRONICS CO.,LTD", [3]byte{44, 80, 137}: "Shenzhen Kaixuan Visual Technology Co.,Limited", [3]byte{44, 83, 74}: "Shenzhen Winyao Electronic Limited", [3]byte{44, 84, 45}: "Cisco Systems, Inc", @@ -14780,6 +15068,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{44, 85, 211}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{44, 86, 220}: "ASUSTek COMPUTER INC.", [3]byte{44, 87, 49}: "Wingtech Group (HongKong)Limited", + [3]byte{44, 88, 79}: "ARRIS Group, Inc.", [3]byte{44, 89, 138}: "LG Electronics (Mobile Communications)", [3]byte{44, 89, 229}: "Hewlett Packard", [3]byte{44, 90, 5}: "Nokia Corporation", @@ -14791,6 +15080,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{44, 93, 147}: "Ruckus Wireless", [3]byte{44, 95, 243}: "Pertronic Industries", [3]byte{44, 96, 12}: "QUANTA COMPUTER INC.", + [3]byte{44, 97, 4}: "SHENZHEN FENGLIAN TECHNOLOGY CO., LTD.", + [3]byte{44, 97, 246}: "Apple, Inc.", [3]byte{44, 98, 90}: "Finest Security Systems Co., Ltd", [3]byte{44, 98, 137}: "Regenersis (Glenrothes) Ltd", [3]byte{44, 99, 115}: "SICHUAN TIANYI COMHEART TELECOMCO., LTD", @@ -14807,8 +15098,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{44, 115, 96}: "Earda Technologies co Ltd", [3]byte{44, 117, 15}: "Shanghai Dongzhou-Lawton Communication Technology Co. Ltd.", [3]byte{44, 118, 138}: "Hewlett Packard", + [3]byte{44, 121, 215}: "Sagemcom Broadband SAS", [3]byte{44, 123, 90}: "Milper Ltd", [3]byte{44, 123, 132}: "OOO Petr Telegin", + [3]byte{44, 124, 228}: "Wuhan Tianyu Information Industry Co., Ltd.", [3]byte{44, 126, 129}: "ARRIS Group, Inc.", [3]byte{44, 126, 207}: "Onzo Ltd", [3]byte{44, 128, 101}: "HARTING Inc. of North America", @@ -14819,15 +15112,18 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{44, 145, 39}: "Eintechno Corporation", [3]byte{44, 146, 44}: "Kishu Giken Kogyou Company Ltd,.", [3]byte{44, 148, 100}: "Cincoze Co., Ltd.", + [3]byte{44, 149, 105}: "ARRIS Group, Inc.", [3]byte{44, 149, 127}: "zte corporation", [3]byte{44, 150, 98}: "Invenit BV", [3]byte{44, 151, 23}: "I.C.Y. B.V.", + [3]byte{44, 151, 177}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{44, 153, 36}: "ARRIS Group, Inc.", [3]byte{44, 154, 164}: "Eolo SpA", [3]byte{44, 157, 30}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{44, 158, 95}: "ARRIS Group, Inc.", [3]byte{44, 158, 236}: "Jabil Circuit Penang", [3]byte{44, 158, 252}: "CANON INC.", + [3]byte{44, 160, 47}: "Veroguard Systems Pty Ltd", [3]byte{44, 161, 87}: "acromate, Inc.", [3]byte{44, 161, 125}: "ARRIS Group, Inc.", [3]byte{44, 162, 180}: "Fortify Technologies, LLC", @@ -14835,6 +15131,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{44, 165, 57}: "Parallel Wireless, Inc", [3]byte{44, 167, 128}: "True Technologies Inc.", [3]byte{44, 168, 53}: "RIM", + [3]byte{44, 169, 240}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", + [3]byte{44, 170, 142}: "Wyze Labs Inc", [3]byte{44, 171, 0}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{44, 171, 37}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", [3]byte{44, 171, 164}: "Cisco SPVTG", @@ -14849,13 +15147,16 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{44, 180, 58}: "Apple, Inc.", [3]byte{44, 182, 147}: "Radware", [3]byte{44, 182, 157}: "RED Digital Cinema", + [3]byte{44, 184, 237}: "SonicWall", [3]byte{44, 186, 186}: "Samsung Electronics Co.,Ltd", [3]byte{44, 190, 8}: "Apple, Inc.", [3]byte{44, 190, 151}: "Ingenieurbuero Bickele und Buehler GmbH", [3]byte{44, 194, 96}: "Oracle Corporation", [3]byte{44, 197, 72}: "IAdea Corporation", [3]byte{44, 197, 211}: "Ruckus Wireless", + [3]byte{44, 202, 12}: "WITHUS PLANET", [3]byte{44, 204, 21}: "Nokia Corporation", + [3]byte{44, 204, 68}: "Sony Interactive Entertainment Inc.", [3]byte{44, 205, 39}: "Precor Inc", [3]byte{44, 205, 67}: "Summit Technology Group", [3]byte{44, 205, 105}: "Aqavi.com", @@ -14866,6 +15167,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{44, 209, 218}: "Sanjole, Inc.", [3]byte{44, 210, 231}: "Nokia Corporation", [3]byte{44, 212, 68}: "FUJITSU LIMITED", + [3]byte{44, 217, 116}: "Hui Zhou Gaoshengda Technology Co.,LTD", [3]byte{44, 220, 173}: "Wistron Neweb Corporation", [3]byte{44, 221, 12}: "Discovergy GmbH", [3]byte{44, 221, 149}: "Taicang T&W Electronics", @@ -14890,6 +15192,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{48, 5, 63}: "JTI Co.,Ltd.", [3]byte{48, 5, 92}: "Brother industries, LTD.", [3]byte{48, 7, 77}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", + [3]byte{48, 9, 249}: "IEEE Registration Authority", + [3]byte{48, 10, 96}: "IEEE Registration Authority", + [3]byte{48, 10, 197}: "Ruio telecommunication technologies Co., Limited", [3]byte{48, 11, 156}: "Delta Mobile Systems, Inc.", [3]byte{48, 12, 35}: "zte corporation", [3]byte{48, 13, 42}: "Zhejiang Wellcom Technology Co.,Ltd.", @@ -14898,15 +15203,21 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{48, 14, 227}: "Aquantia Corporation", [3]byte{48, 16, 179}: "Liteon Technology Corporation", [3]byte{48, 16, 228}: "Apple, Inc.", + [3]byte{48, 19, 137}: "Siemens AG, Automations & Drives,", [3]byte{48, 20, 45}: "Piciorgros GmbH", [3]byte{48, 20, 74}: "Wistron Neweb Corporation", [3]byte{48, 21, 24}: "Ubiquitous Communication Co. ltd.", [3]byte{48, 22, 141}: "ProLon", - [3]byte{48, 23, 200}: "Sony Mobile Communications AB", + [3]byte{48, 23, 200}: "Sony Mobile Communications Inc", [3]byte{48, 24, 207}: "DEOS control systems GmbH", [3]byte{48, 25, 102}: "Samsung Electronics Co.,Ltd", [3]byte{48, 26, 40}: "Mako Networks Ltd", + [3]byte{48, 31, 154}: "IEEE Registration Authority", [3]byte{48, 33, 91}: "Shenzhen Ostar Display Electronic Co.,Ltd", + [3]byte{48, 35, 3}: "Belkin International Inc.", + [3]byte{48, 36, 50}: "Intel Corporate", + [3]byte{48, 36, 120}: "Sagemcom Broadband SAS", + [3]byte{48, 41, 82}: "Hillstone Networks Inc", [3]byte{48, 41, 190}: "Shanghai MRDcom Co.,Ltd", [3]byte{48, 45, 232}: "JDA, LLC (JDA Systems)", [3]byte{48, 50, 148}: "W-IE-NE-R Plein & Baus GmbH", @@ -14916,7 +15227,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{48, 53, 173}: "Apple, Inc.", [3]byte{48, 55, 166}: "Cisco Systems, Inc", [3]byte{48, 56, 85}: "Nokia Corporation", - [3]byte{48, 57, 38}: "Sony Mobile Communications AB", + [3]byte{48, 57, 38}: "Sony Mobile Communications Inc", [3]byte{48, 57, 85}: "Shenzhen Jinhengjia Electronic Co., Ltd.", [3]byte{48, 57, 242}: "ADB Broadband Italia", [3]byte{48, 58, 100}: "Intel Corporate", @@ -14924,11 +15235,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{48, 62, 173}: "Sonavox Canada Inc", [3]byte{48, 65, 116}: "ALTEC LANSING LLC", [3]byte{48, 66, 37}: "BURG-WÄCHTER KG", + [3]byte{48, 66, 161}: "ilumisys Inc. DBA Toggled", [3]byte{48, 68, 73}: "PLATH GmbH", [3]byte{48, 68, 135}: "Hefei Radio Communication Technology Co., Ltd", [3]byte{48, 68, 161}: "Shanghai Nanchao Information Technology", + [3]byte{48, 69, 17}: "Texas Instruments", + [3]byte{48, 69, 150}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{48, 70, 154}: "NETGEAR", [3]byte{48, 73, 59}: "Nanjing Z-Com Wireless Co.,Ltd", + [3]byte{48, 75, 7}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{48, 76, 126}: "Panasonic Electric Works Automation Controls Techno Co.,Ltd.", [3]byte{48, 78, 195}: "Tianjin Techua Technology Co., Ltd.", [3]byte{48, 81, 248}: "BYK-Gardner GmbH", @@ -14941,6 +15256,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{48, 89, 183}: "Microsoft", [3]byte{48, 90, 58}: "ASUSTek COMPUTER INC.", [3]byte{48, 93, 56}: "Beissbarth", + [3]byte{48, 93, 166}: "ADVALY SYSTEM Inc.", [3]byte{48, 96, 35}: "ARRIS Group, Inc.", [3]byte{48, 97, 18}: "PAV GmbH", [3]byte{48, 97, 24}: "Paradom Inc.", @@ -14948,17 +15264,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{48, 101, 236}: "Wistron (ChongQing)", [3]byte{48, 104, 140}: "Reach Technology Inc.", [3]byte{48, 105, 75}: "RIM", + [3]byte{48, 106, 133}: "Samsung Electronics Co.,Ltd", [3]byte{48, 108, 190}: "Skymotion Technology (HK) Limited", [3]byte{48, 110, 92}: "Validus Technologies", [3]byte{48, 113, 178}: "Hangzhou Prevail Optoelectronic Equipment Co.,LTD.", [3]byte{48, 115, 80}: "Inpeco SA", [3]byte{48, 116, 150}: "HUAWEI TECHNOLOGIES CO.,LTD", - [3]byte{48, 117, 18}: "Sony Mobile Communications AB", + [3]byte{48, 117, 18}: "Sony Mobile Communications Inc", [3]byte{48, 118, 111}: "LG Electronics (Mobile Communications)", [3]byte{48, 119, 203}: "Maike Industry(Shenzhen)CO.,LTD", [3]byte{48, 120, 92}: "Partow Tamas Novin (Parman)", [3]byte{48, 120, 107}: "TIANJIN Golden Pentagon Electronics Co., Ltd.", - [3]byte{48, 120, 194}: "Innowireless, Co. Ltd.", + [3]byte{48, 120, 194}: "Innowireless / QUCELL Networks", + [3]byte{48, 123, 172}: "New H3C Technologies Co., Ltd", [3]byte{48, 124, 48}: "RIM", [3]byte{48, 124, 94}: "Juniper Networks", [3]byte{48, 124, 178}: "ANOV FRANCE", @@ -14967,6 +15285,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{48, 133, 169}: "ASUSTek COMPUTER INC.", [3]byte{48, 135, 48}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{48, 135, 217}: "Ruckus Wireless", + [3]byte{48, 136, 65}: "Sichuan\u00a0AI-Link\u00a0Technology\u00a0Co.,\u00a0Ltd.", [3]byte{48, 137, 118}: "DALIAN LAMBA TECHNOLOGY CO.,LTD", [3]byte{48, 137, 153}: "Guangdong East Power Co.,", [3]byte{48, 137, 211}: "HONGKONG UCLOUDLINK NETWORK TECHNOLOGY LIMITED", @@ -14981,16 +15300,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{48, 155, 173}: "BBK EDUCATIONAL ELECTRONICS CORP.,LTD.", [3]byte{48, 156, 35}: "Micro-Star INTL CO., LTD.", [3]byte{48, 159, 251}: "Ardomus Networks Corporation", + [3]byte{48, 161, 250}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{48, 162, 32}: "ARG Telecom", [3]byte{48, 162, 67}: "Shenzhen Prifox Innovation Technology Co., Ltd.", - [3]byte{48, 168, 219}: "Sony Mobile Communications AB", + [3]byte{48, 168, 219}: "Sony Mobile Communications Inc", [3]byte{48, 169, 222}: "LG Innotek", [3]byte{48, 170, 189}: "Shanghai Reallytek Information Technology Co.,Ltd", [3]byte{48, 174, 123}: "Deqing Dusun Electron CO., LTD", [3]byte{48, 174, 164}: "Espressif Inc.", [3]byte{48, 174, 246}: "Radio Mobile Access", [3]byte{48, 177, 100}: "Power Electronics International Inc.", - [3]byte{48, 178, 22}: "Hytec Geraetebau GmbH", + [3]byte{48, 178, 22}: "ABB AG - Power Grids - Grid Automation", [3]byte{48, 179, 162}: "Shenzhen Heguang Measurement & Control Technology Co.,Ltd", [3]byte{48, 180, 158}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{48, 180, 184}: "LG Electronics", @@ -14998,6 +15318,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{48, 181, 241}: "Aitexin Technology Co., Ltd", [3]byte{48, 182, 45}: "Mojo Networks, Inc.", [3]byte{48, 182, 79}: "Juniper Networks", + [3]byte{48, 183, 212}: "Hitron Technologies. Inc", [3]byte{48, 192, 27}: "Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd", [3]byte{48, 195, 217}: "ALPS ELECTRIC CO.,LTD.", [3]byte{48, 197, 7}: "ECI Telecom Ltd.", @@ -15006,21 +15327,26 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{48, 200, 42}: "WI-BIZ srl", [3]byte{48, 203, 248}: "Samsung Electronics Co.,Ltd", [3]byte{48, 205, 167}: "Samsung Electronics Co.,Ltd", + [3]byte{48, 209, 107}: "Liteon Technology Corporation", [3]byte{48, 209, 126}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{48, 211, 45}: "devolo AG", [3]byte{48, 211, 87}: "Logosol, Inc.", [3]byte{48, 211, 134}: "zte corporation", [3]byte{48, 212, 106}: "Autosales Incorporated", [3]byte{48, 213, 135}: "Samsung Electronics Co.,Ltd", + [3]byte{48, 214, 89}: "Merging Technologies SA", [3]byte{48, 214, 201}: "Samsung Electronics Co.,Ltd", + [3]byte{48, 217, 217}: "Apple, Inc.", [3]byte{48, 222, 134}: "Cedac Software S.r.l.", [3]byte{48, 224, 144}: "Linctronix Ltd,", [3]byte{48, 225, 113}: "Hewlett Packard", [3]byte{48, 227, 122}: "Intel Corporate", + [3]byte{48, 227, 214}: "Spotify USA Inc.", [3]byte{48, 228, 142}: "Vodafone UK", [3]byte{48, 228, 219}: "Cisco Systems, Inc", [3]byte{48, 235, 31}: "Skylab M&C Technology Co.,Ltd", [3]byte{48, 235, 37}: "INTEK DIGITAL", + [3]byte{48, 235, 90}: "LANDIS + GYR", [3]byte{48, 239, 209}: "Alstom Strongwish (Shenzhen) Co., Ltd.", [3]byte{48, 243, 29}: "zte corporation", [3]byte{48, 243, 53}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -15037,23 +15363,27 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{48, 251, 148}: "Shanghai Fangzhiwei Information Technology CO.,Ltd.", [3]byte{48, 252, 104}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{48, 253, 17}: "MACROTECH (USA) INC.", + [3]byte{48, 253, 56}: "Google, Inc.", [3]byte{48, 254, 49}: "Nokia", [3]byte{48, 255, 246}: "HangZhou KuoHeng Technology Co.,ltd", [3]byte{52, 0, 138}: "IEEE Registration Authority", [3]byte{52, 0, 163}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{52, 2, 134}: "Intel Corporate", [3]byte{52, 2, 155}: "CloudBerry Technologies Private Limited", + [3]byte{52, 3, 222}: "Texas Instruments", [3]byte{52, 4, 158}: "IEEE Registration Authority", [3]byte{52, 7, 79}: "AccelStor, Inc.", [3]byte{52, 7, 251}: "Ericsson AB", [3]byte{52, 8, 4}: "D-Link Corporation", [3]byte{52, 8, 188}: "Apple, Inc.", [3]byte{52, 10, 34}: "TOP-ACCESS ELECTRONICS CO LTD", + [3]byte{52, 10, 152}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{52, 10, 255}: "Qingdao Hisense Communications Co.,Ltd.", [3]byte{52, 11, 64}: "MIOS ELETTRONICA SRL", [3]byte{52, 12, 237}: "Moduel AB", [3]byte{52, 18, 144}: "Treeview Co.,Ltd.", [3]byte{52, 18, 152}: "Apple, Inc.", + [3]byte{52, 18, 249}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{52, 19, 168}: "Mediplan Limited", [3]byte{52, 19, 232}: "Intel Corporate", [3]byte{52, 20, 95}: "Samsung Electronics Co.,Ltd", @@ -15070,11 +15400,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{52, 35, 186}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", [3]byte{52, 37, 93}: "Shenzhen Loadcom Technology Co.,Ltd", [3]byte{52, 38, 6}: "CarePredict, Inc.", + [3]byte{52, 39, 146}: "FREEBOX SAS", [3]byte{52, 40, 240}: "ATN International Limited", + [3]byte{52, 41, 18}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{52, 41, 143}: "IEEE Registration Authority", [3]byte{52, 41, 234}: "MCD ELECTRONICS SP. Z O.O.", [3]byte{52, 42, 241}: "Texas Instruments", + [3]byte{52, 44, 196}: "Compal Broadband Networks, Inc.", [3]byte{52, 45, 13}: "Samsung Electronics Co.,Ltd", + [3]byte{52, 46, 182}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{52, 47, 110}: "Anywire corporation", [3]byte{52, 49, 17}: "Samsung Electronics Co.,Ltd", [3]byte{52, 49, 196}: "AVM GmbH", @@ -15087,6 +15421,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{52, 61, 196}: "BUFFALO.INC", [3]byte{52, 64, 181}: "IBM", [3]byte{52, 65, 93}: "Intel Corporate", + [3]byte{52, 66, 98}: "Apple, Inc.", [3]byte{52, 70, 111}: "HiTEM Engineering", [3]byte{52, 75, 61}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{52, 75, 80}: "zte corporation", @@ -15102,6 +15437,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{52, 84, 60}: "TAKAOKA TOKO CO.,LTD.", [3]byte{52, 86, 254}: "Cisco Meraki", [3]byte{52, 87, 96}: "MitraStar Technology Corp.", + [3]byte{52, 90, 6}: "SHARP Corporation", + [3]byte{52, 90, 186}: "tcloud intelligence", [3]byte{52, 91, 17}: "EVI HEAT AB", [3]byte{52, 91, 187}: "GD Midea Air-Conditioning Equipment Co.,Ltd.", [3]byte{52, 92, 64}: "Cargt Holdings LLC", @@ -15109,10 +15446,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{52, 97, 120}: "The Boeing Company", [3]byte{52, 98, 136}: "Cisco Systems, Inc", [3]byte{52, 100, 169}: "Hewlett Packard", + [3]byte{52, 102, 234}: "VERTU INTERNATIONAL CORPORATION LIMITED", [3]byte{52, 104, 74}: "Teraworks Co., Ltd.", [3]byte{52, 104, 149}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{52, 105, 135}: "zte corporation", [3]byte{52, 106, 194}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{52, 107, 70}: "Sagemcom Broadband SAS", [3]byte{52, 107, 211}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{52, 108, 15}: "Pramod Telecom Pvt. Ltd", [3]byte{52, 110, 138}: "Ecosense", @@ -15124,8 +15463,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{52, 118, 197}: "I-O DATA DEVICE, INC.", [3]byte{52, 120, 119}: "O-Net Communications (Shenzhen) Limited", [3]byte{52, 120, 215}: "Gionee Communication Equipment Co.,Ltd.", + [3]byte{52, 121, 22}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{52, 122, 96}: "ARRIS Group, Inc.", + [3]byte{52, 124, 37}: "Apple, Inc.", [3]byte{52, 126, 57}: "Nokia Danmark A/S", + [3]byte{52, 126, 92}: "Sonos, Inc.", + [3]byte{52, 126, 202}: "NEXTWILL", + [3]byte{52, 128, 13}: "Cavium Inc", [3]byte{52, 128, 179}: "Xiaomi Communications Co Ltd", [3]byte{52, 129, 55}: "UNICARD SA", [3]byte{52, 129, 196}: "AVM GmbH", @@ -15139,7 +15483,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{52, 136, 93}: "Logitech Far East", [3]byte{52, 138, 123}: "Samsung Electronics Co.,Ltd", [3]byte{52, 138, 174}: "Sagemcom Broadband SAS", + [3]byte{52, 139, 117}: "LAVA INTERNATIONAL(H.K) LIMITED", [3]byte{52, 143, 39}: "Ruckus Wireless", + [3]byte{52, 147, 66}: "TTE Corporation", [3]byte{52, 149, 219}: "Logitec Corporation", [3]byte{52, 150, 114}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{52, 151, 246}: "ASUSTek COMPUTER INC.", @@ -15174,7 +15520,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{52, 183, 253}: "Guangzhou Younghead Electronic Technology Co.,Ltd", [3]byte{52, 186, 56}: "PAL MOHAN ELECTRONICS PVT LTD", [3]byte{52, 186, 81}: "Se-Kure Controls, Inc.", - [3]byte{52, 186, 117}: "Tembo Systems, Inc.", + [3]byte{52, 186, 117}: "Everest Networks, Inc", [3]byte{52, 186, 154}: "Asiatelco Technologies Co.", [3]byte{52, 187, 31}: "BlackBerry RTS", [3]byte{52, 187, 38}: "Motorola Mobility LLC, a Lenovo Company", @@ -15203,21 +15549,26 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{52, 208, 184}: "IEEE Registration Authority", [3]byte{52, 210, 112}: "Amazon Technologies Inc.", [3]byte{52, 210, 196}: "RENA GmbH Print Systeme", + [3]byte{52, 215, 18}: "Smartisan Digital Co., Ltd", [3]byte{52, 215, 180}: "Tributary Systems, Inc.", [3]byte{52, 217, 84}: "WiBotic Inc.", + [3]byte{52, 218, 193}: "SAE Technologies Development(Dongguan) Co., Ltd.", [3]byte{52, 219, 253}: "Cisco Systems, Inc", [3]byte{52, 222, 26}: "Intel Corporate", [3]byte{52, 222, 52}: "zte corporation", [3]byte{52, 223, 42}: "Fujikon Industrial Co.,Limited", [3]byte{52, 224, 207}: "zte corporation", [3]byte{52, 224, 215}: "DONGGUAN QISHENG ELECTRONICS INDUSTRIAL CO., LTD", + [3]byte{52, 225, 45}: "Intel Corporate", [3]byte{52, 226, 253}: "Apple, Inc.", [3]byte{52, 227, 128}: "Genexis B.V.", [3]byte{52, 228, 42}: "Automatic Bar Controls Inc.", + [3]byte{52, 229, 236}: "Palo Alto Networks", [3]byte{52, 230, 173}: "Intel Corporate", [3]byte{52, 230, 215}: "Dell Inc.", [3]byte{52, 231, 11}: "HAN Networks Co., Ltd", [3]byte{52, 231, 28}: "Shenzhen YOUHUA Technology Co., Ltd", + [3]byte{52, 232, 148}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{52, 233, 17}: "vivo Mobile Communication Co., Ltd.", [3]byte{52, 234, 52}: "HangZhou Gubei Electronics Technology Co.,Ltd", [3]byte{52, 237, 11}: "Shanghai XZ-COM.CO.,Ltd.", @@ -15229,6 +15580,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{52, 246, 45}: "SHARP Corporation", [3]byte{52, 246, 75}: "Intel Corporate", [3]byte{52, 246, 210}: "Panasonic Taiwan Co.,Ltd.", + [3]byte{52, 248, 231}: "Cisco Systems, Inc", [3]byte{52, 249, 104}: "ATEK Products, LLC", [3]byte{52, 250, 64}: "Guangzhou Robustel Technologies Co., Limited", [3]byte{52, 250, 159}: "Ruckus Wireless", @@ -15247,6 +15599,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{56, 10, 10}: "Sky-City Communication and Electronics Limited Company", [3]byte{56, 10, 148}: "Samsung Electronics Co.,Ltd", [3]byte{56, 10, 171}: "Formlabs", + [3]byte{56, 11, 60}: "Texas Instruments", [3]byte{56, 11, 64}: "Samsung Electronics Co.,Ltd", [3]byte{56, 13, 212}: "Primax Electronics Ltd.", [3]byte{56, 14, 77}: "Cisco Systems, Inc", @@ -15278,7 +15631,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{56, 44, 74}: "ASUSTek COMPUTER INC.", [3]byte{56, 45, 209}: "Samsung Electronics Co.,Ltd", [3]byte{56, 45, 232}: "Samsung Electronics Co.,Ltd", + [3]byte{56, 48, 249}: "LG Electronics (Mobile Communications)", [3]byte{56, 49, 172}: "WEG", + [3]byte{56, 53, 251}: "Sagemcom Broadband SAS", [3]byte{56, 55, 139}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{56, 58, 33}: "IEEE Registration Authority", [3]byte{56, 59, 200}: "2Wire Inc", @@ -15297,7 +15652,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{56, 79, 73}: "Juniper Networks", [3]byte{56, 79, 240}: "AzureWave Technology Inc.", [3]byte{56, 82, 26}: "Nokia", + [3]byte{56, 83, 156}: "Apple, Inc.", [3]byte{56, 86, 16}: "CANDY HOUSE, Inc.", + [3]byte{56, 86, 181}: "Peerbridge Health Inc", [3]byte{56, 88, 12}: "Panaccess Systems GmbH", [3]byte{56, 89, 248}: "MindMade Sp. z o.o.", [3]byte{56, 89, 249}: "Hon Hai Precision Ind. Co.,Ltd.", @@ -15310,10 +15667,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{56, 102, 69}: "OOSIC Technology CO.,Ltd", [3]byte{56, 102, 240}: "Apple, Inc.", [3]byte{56, 103, 147}: "Asia Optical Co., Inc.", + [3]byte{56, 104, 221}: "INVENTEC CORPORATION", [3]byte{56, 107, 28}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", [3]byte{56, 107, 187}: "ARRIS Group, Inc.", [3]byte{56, 108, 155}: "Ivy Biomedical", [3]byte{56, 110, 33}: "Wasion Group Ltd.", + [3]byte{56, 110, 136}: "zte corporation", [3]byte{56, 110, 162}: "vivo Mobile Communication Co., Ltd.", [3]byte{56, 112, 12}: "ARRIS Group, Inc.", [3]byte{56, 113, 222}: "Apple, Inc.", @@ -15321,11 +15680,16 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{56, 115, 234}: "IEEE Registration Authority", [3]byte{56, 118, 202}: "Shenzhen Smart Intelligent Technology Co.Ltd", [3]byte{56, 118, 209}: "Euronda SpA", + [3]byte{56, 120, 98}: "Sony Mobile Communications Inc", [3]byte{56, 123, 71}: "AKELA, Inc.", + [3]byte{56, 128, 223}: "Motorola Mobility LLC, a Lenovo Company", + [3]byte{56, 129, 215}: "Texas Instruments", [3]byte{56, 131, 69}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{56, 134, 2}: "Flexoptix GmbH", + [3]byte{56, 137, 44}: "Apple, Inc.", [3]byte{56, 137, 220}: "Opticon Sensors Europe B.V.", [3]byte{56, 138, 183}: "ITC Networks", + [3]byte{56, 139, 89}: "Google, Inc.", [3]byte{56, 140, 80}: "LG Electronics", [3]byte{56, 142, 231}: "Fanhattan LLC", [3]byte{56, 144, 165}: "Cisco Systems, Inc", @@ -15352,14 +15716,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{56, 172, 61}: "Nephos Inc", [3]byte{56, 173, 142}: "New H3C Technologies Co., Ltd", [3]byte{56, 173, 190}: "New H3C Technologies Co., Ltd", + [3]byte{56, 175, 41}: "Zhejiang Dahua Technology Co., Ltd.", [3]byte{56, 175, 215}: "FUJITSU LIMITED", [3]byte{56, 177, 45}: "Sonotronic Nagel GmbH", [3]byte{56, 177, 219}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{56, 180, 211}: "BSH Hausgeraete GmbH", [3]byte{56, 181, 77}: "Apple, Inc.", [3]byte{56, 181, 189}: "E.G.O. Elektro-Ger", [3]byte{56, 183, 37}: "Wistron Infocomm (Zhongshan) Corporation", [3]byte{56, 183, 77}: "Fijowave Limited", [3]byte{56, 184, 235}: "IEEE Registration Authority", + [3]byte{56, 186, 248}: "Intel Corporate", [3]byte{56, 187, 35}: "OzVision America LLC", [3]byte{56, 187, 60}: "Avaya Inc", [3]byte{56, 188, 1}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -15384,10 +15751,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{56, 216, 47}: "zte corporation", [3]byte{56, 219, 187}: "Sunbow Telecom Co., Ltd.", [3]byte{56, 222, 96}: "Mohlenhoff GmbH", + [3]byte{56, 222, 173}: "Intel Corporate", [3]byte{56, 224, 142}: "Mitsubishi Electric Corporation", + [3]byte{56, 225, 170}: "zte corporation", [3]byte{56, 226, 221}: "zte corporation", [3]byte{56, 227, 197}: "Taicang T&W Electronics", [3]byte{56, 229, 149}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", + [3]byte{56, 230, 10}: "Xiaomi Communications Co Ltd", [3]byte{56, 231, 216}: "HTC Corporation", [3]byte{56, 232, 223}: "b gmbh medien + datenbanken", [3]byte{56, 233, 140}: "Reco S.p.A.", @@ -15401,6 +15771,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{56, 241, 53}: "SensorTec-Canada", [3]byte{56, 242, 62}: "Microsoft Mobile Oy", [3]byte{56, 243, 63}: "TATSUNO CORPORATION", + [3]byte{56, 245, 84}: "HISENSE ELECTRIC CO.,LTD", [3]byte{56, 245, 87}: "JOLATA, INC.", [3]byte{56, 245, 151}: "home2net GmbH", [3]byte{56, 247, 8}: "National Resource Management, Inc.", @@ -15409,11 +15780,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{56, 248, 137}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{56, 248, 183}: "V2COM PARTICIPACOES S.A.", [3]byte{56, 248, 202}: "OWIN Inc.", + [3]byte{56, 249, 211}: "Apple, Inc.", [3]byte{56, 250, 202}: "Skyworth Digital Technology(Shenzhen) Co.,Ltd", [3]byte{56, 253, 254}: "IEEE Registration Authority", [3]byte{56, 254, 197}: "Ellips B.V.", [3]byte{56, 255, 54}: "Ruckus Wireless", + [3]byte{60, 1, 239}: "Sony Mobile Communications Inc", [3]byte{60, 2, 177}: "Creation Technologies LP", + [3]byte{60, 4, 97}: "ARRIS Group, Inc.", [3]byte{60, 4, 191}: "PRAVIS SYSTEMS Co.Ltd.,", [3]byte{60, 5, 24}: "Samsung Electronics Co.,Ltd", [3]byte{60, 5, 171}: "Product Creation Studio", @@ -15432,6 +15806,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{60, 17, 178}: "Fraunhofer FIT", [3]byte{60, 21, 194}: "Apple, Inc.", [3]byte{60, 21, 234}: "TESCOM CO., LTD.", + [3]byte{60, 21, 251}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{60, 23, 16}: "Sagemcom Broadband SAS", [3]byte{60, 24, 159}: "Nokia Corporation", [3]byte{60, 24, 160}: "Luxshare Precision Industry Company Limited", [3]byte{60, 25, 21}: "GFI Chrono Time", @@ -15442,10 +15818,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{60, 28, 190}: "JADAK LLC", [3]byte{60, 30, 4}: "D-Link International", [3]byte{60, 30, 19}: "HANGZHOU SUNRISE TECHNOLOGY CO., LTD", + [3]byte{60, 36, 240}: "IEEE Registration Authority", [3]byte{60, 37, 215}: "Nokia Corporation", [3]byte{60, 38, 213}: "Sotera Wireless", [3]byte{60, 39, 99}: "SLE quality engineering GmbH & Co. KG", + [3]byte{60, 40, 109}: "Google, Inc.", [3]byte{60, 42, 244}: "Brother Industries, LTD.", + [3]byte{60, 44, 48}: "Dell Inc.", [3]byte{60, 44, 148}: "杭州德澜科技有限公司(HangZhou Delan Technology Co.,Ltd)", [3]byte{60, 44, 153}: "Edgecore Networks Corporation", [3]byte{60, 45, 183}: "Texas Instruments", @@ -15458,27 +15837,33 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{60, 53, 86}: "Cognitec Systems GmbH", [3]byte{60, 54, 61}: "Nokia Corporation", [3]byte{60, 54, 228}: "ARRIS Group, Inc.", + [3]byte{60, 55, 134}: "NETGEAR", [3]byte{60, 56, 136}: "ConnectQuest, llc", [3]byte{60, 57, 195}: "JW Electronics Co., Ltd.", [3]byte{60, 57, 231}: "IEEE Registration Authority", [3]byte{60, 58, 115}: "Avaya Inc", [3]byte{60, 63, 81}: "2CRSI", [3]byte{60, 64, 79}: "GUANGDONG PISEN ELECTRONICS CO.,LTD", + [3]byte{60, 66, 126}: "IEEE Registration Authority", [3]byte{60, 67, 142}: "ARRIS Group, Inc.", [3]byte{60, 70, 216}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{60, 71, 17}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{60, 71, 155}: "Theissen Training Systems, Inc.", [3]byte{60, 73, 55}: "ASSMANN Electronic GmbH", [3]byte{60, 74, 146}: "Hewlett Packard", [3]byte{60, 76, 105}: "Infinity System S.L.", [3]byte{60, 76, 208}: "CERAGON NETWORKS", [3]byte{60, 78, 71}: "Etronic A/S", [3]byte{60, 82, 130}: "Hewlett Packard", + [3]byte{60, 87, 79}: "China Mobile Group Device Co.,Ltd.", + [3]byte{60, 87, 108}: "Samsung Electronics Co.,Ltd", [3]byte{60, 87, 189}: "Kessler Crane Inc.", [3]byte{60, 87, 213}: "FiveCo", [3]byte{60, 89, 30}: "TCL King Electrical Appliances (Huizhou) Co., Ltd", [3]byte{60, 90, 55}: "Samsung Electronics Co.,Ltd", [3]byte{60, 90, 180}: "Google, Inc.", [3]byte{60, 92, 195}: "Shenzhen First Blue Chip Technology Ltd", + [3]byte{60, 92, 196}: "Amazon Technologies Inc.", [3]byte{60, 94, 195}: "Cisco Systems, Inc", [3]byte{60, 95, 1}: "Synerchip Co., Ltd.", [3]byte{60, 97, 4}: "Juniper Networks", @@ -15488,13 +15873,16 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{60, 103, 44}: "Sciovid Inc.", [3]byte{60, 103, 140}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{60, 104, 22}: "VXi Corporation", + [3]byte{60, 106, 44}: "IEEE Registration Authority", [3]byte{60, 106, 125}: "Niigata Power Systems Co., Ltd.", [3]byte{60, 106, 157}: "Dexatek Technology LTD.", + [3]byte{60, 106, 167}: "Intel Corporate", [3]byte{60, 110, 99}: "Mitron OY", [3]byte{60, 111, 69}: "Fiberpro Inc.", [3]byte{60, 111, 234}: "Panasonic India Pvt. Ltd.", [3]byte{60, 111, 247}: "EnTek Systems, Inc.", [3]byte{60, 112, 89}: "MakerBot Industries", + [3]byte{60, 113, 191}: "Espressif Inc.", [3]byte{60, 116, 55}: "RIM", [3]byte{60, 117, 74}: "ARRIS Group, Inc.", [3]byte{60, 119, 230}: "Hon Hai Precision Ind. Co.,Ltd.", @@ -15510,6 +15898,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{60, 131, 181}: "Advance Vision Electronics Co. Ltd.", [3]byte{60, 134, 168}: "Sangshin elecom .co,, LTD", [3]byte{60, 137, 112}: "Neosfar", + [3]byte{60, 137, 148}: "BSkyB Ltd", [3]byte{60, 137, 166}: "KAPELSE", [3]byte{60, 138, 176}: "Juniper Networks", [3]byte{60, 138, 229}: "Tensun Information Technology(Hangzhou) Co.,LTD", @@ -15517,6 +15906,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{60, 139, 254}: "Samsung Electronics Co.,Ltd", [3]byte{60, 140, 64}: "Hangzhou H3C Technologies Co., Limited", [3]byte{60, 140, 248}: "TRENDnet, Inc.", + [3]byte{60, 141, 32}: "Google, Inc.", [3]byte{60, 144, 102}: "SmartRG, Inc.", [3]byte{60, 145, 43}: "Vexata Inc", [3]byte{60, 145, 87}: "Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd", @@ -15526,9 +15916,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{60, 149, 9}: "Liteon Technology Corporation", [3]byte{60, 151, 14}: "Wistron InfoComm(Kunshan)Co.,Ltd.", [3]byte{60, 151, 126}: "IPS Technology Limited", + [3]byte{60, 152, 114}: "Sercomm Corporation.", [3]byte{60, 152, 191}: "Quest Controls, Inc.", [3]byte{60, 153, 247}: "Lansentechnology AB", [3]byte{60, 154, 119}: "Technicolor CH USA Inc.", + [3]byte{60, 155, 214}: "Vizio, Inc", [3]byte{60, 159, 129}: "Shenzhen CATIC Bit Communications Technology Co.,Ltd", [3]byte{60, 160, 103}: "Liteon Technology Corporation", [3]byte{60, 161, 13}: "Samsung Electronics Co.,Ltd", @@ -15566,6 +15958,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{60, 202, 135}: "Iders Incorporated", [3]byte{60, 203, 124}: "TCT mobile ltd", [3]byte{60, 205, 90}: "Technische Alternative GmbH", + [3]byte{60, 205, 93}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{60, 205, 147}: "LG ELECTRONICS INC", [3]byte{60, 206, 21}: "Mercedes-Benz USA, LLC", [3]byte{60, 206, 115}: "Cisco Systems, Inc", @@ -15577,26 +15970,33 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{60, 217, 43}: "Hewlett Packard", [3]byte{60, 217, 206}: "Eclipse WiFi", [3]byte{60, 218, 42}: "zte corporation", + [3]byte{60, 220, 188}: "Samsung Electronics Co.,Ltd", [3]byte{60, 221, 137}: "SOMO HOLDINGS & TECH. CO.,LTD.", [3]byte{60, 223, 30}: "Cisco Systems, Inc", [3]byte{60, 223, 169}: "ARRIS Group, Inc.", [3]byte{60, 223, 189}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{60, 224, 114}: "Apple, Inc.", + [3]byte{60, 225, 161}: "Universal Global Scientific Industrial Co., Ltd.", [3]byte{60, 229, 166}: "Hangzhou H3C Technologies Co., Limited", [3]byte{60, 229, 180}: "KIDASEN INDUSTRIA E COMERCIO DE ANTENAS LTDA", [3]byte{60, 230, 36}: "LG Display", + [3]byte{60, 232, 36}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{60, 234, 79}: "2Wire Inc", + [3]byte{60, 234, 249}: "JUBIXCOLTD", [3]byte{60, 234, 251}: "NSE AG", [3]byte{60, 239, 140}: "Zhejiang Dahua Technology Co., Ltd.", [3]byte{60, 243, 146}: "Virtualtek. Co. Ltd", + [3]byte{60, 244, 249}: "Moda-InnoChips", [3]byte{60, 245, 44}: "DSPECIALISTS GmbH", [3]byte{60, 245, 145}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", + [3]byte{60, 245, 204}: "New H3C Technologies Co., Ltd", [3]byte{60, 247, 42}: "Nokia Corporation", [3]byte{60, 247, 72}: "Shenzhen Linsn Technology Development Co.,Ltd", [3]byte{60, 247, 164}: "Samsung Electronics Co.,Ltd", [3]byte{60, 248, 8}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{60, 248, 98}: "Intel Corporate", [3]byte{60, 250, 67}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{60, 251, 92}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{60, 251, 150}: "Emcraft Systems LLC", [3]byte{60, 253, 254}: "Intel Corporate", [3]byte{64, 0, 224}: "Derek(Shaoguan)Limited", @@ -15604,6 +16004,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{64, 1, 122}: "Cisco Systems, Inc", [3]byte{64, 1, 198}: "3COM EUROPE LTD", [3]byte{64, 4, 12}: "A&T", + [3]byte{64, 6, 160}: "Texas Instruments", [3]byte{64, 7, 192}: "Railtec Systems GmbH", [3]byte{64, 13, 16}: "ARRIS Group, Inc.", [3]byte{64, 14, 103}: "Tremol Ltd.", @@ -15616,19 +16017,22 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{64, 22, 126}: "ASUSTek COMPUTER INC.", [3]byte{64, 22, 159}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{64, 22, 250}: "EKM Metering", + [3]byte{64, 23, 226}: "INTAI TECHNOLOGY CORP.", [3]byte{64, 24, 177}: "Aerohive Networks Inc.", [3]byte{64, 24, 215}: "Smartronix, Inc.", - [3]byte{64, 27, 95}: "Weifang GoerTek Technology Co.,Ltd.", + [3]byte{64, 27, 95}: "WEIFANG GOERTEK ELECTRONICS CO.,LTD", [3]byte{64, 29, 89}: "Biometric Associates, LP", [3]byte{64, 34, 237}: "Digital Projection Ltd", [3]byte{64, 37, 194}: "Intel Corporate", + [3]byte{64, 38, 25}: "Apple, Inc.", [3]byte{64, 39, 11}: "Mobileeco Co., Ltd", [3]byte{64, 40, 20}: "RFI Engineering", - [3]byte{64, 43, 161}: "Sony Mobile Communications AB", + [3]byte{64, 43, 161}: "Sony Mobile Communications Inc", [3]byte{64, 44, 244}: "Universal Global Scientific Industrial Co., Ltd.", [3]byte{64, 46, 40}: "MiXTelematics", [3]byte{64, 48, 4}: "Apple, Inc.", [3]byte{64, 48, 103}: "Conlog (Pty) Ltd", + [3]byte{64, 49, 60}: "XIAOMI Electronics,CO.,LTD", [3]byte{64, 51, 26}: "Apple, Inc.", [3]byte{64, 51, 108}: "Godrej & Boyce Mfg. co. ltd", [3]byte{64, 55, 173}: "Macro Image Technology, Inc.", @@ -15637,7 +16041,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{64, 63, 140}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{64, 64, 34}: "ZIV", [3]byte{64, 64, 107}: "Icomera", - [3]byte{64, 64, 167}: "Sony Mobile Communications AB", + [3]byte{64, 64, 167}: "Sony Mobile Communications Inc", [3]byte{64, 66, 41}: "Layer3TV, Inc", [3]byte{64, 69, 218}: "Spreadtrum Communications (Shanghai) Co., Ltd.", [3]byte{64, 71, 106}: "AG Acquisition Corp. d.b.a. ASTRO Gaming", @@ -15651,6 +16055,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{64, 77, 142}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{64, 78, 54}: "HTC Corporation", [3]byte{64, 78, 235}: "Higher Way Electronic Co., Ltd.", + [3]byte{64, 80, 181}: "Shenzhen New Species Technology Co., Ltd.", [3]byte{64, 80, 224}: "Milton Security Group LLC", [3]byte{64, 81, 108}: "Grandex International Corporation", [3]byte{64, 82, 13}: "Pico Technology", @@ -15658,6 +16063,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{64, 85, 57}: "Cisco Systems, Inc", [3]byte{64, 86, 12}: "In Home Displays Ltd", [3]byte{64, 86, 45}: "Smartron India Pvt ltd", + [3]byte{64, 86, 98}: "GuoTengShengHua Electronics LTD.", [3]byte{64, 90, 155}: "ANOVO", [3]byte{64, 92, 253}: "Dell Inc.", [3]byte{64, 93, 130}: "NETGEAR", @@ -15667,7 +16073,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{64, 96, 90}: "Hawkeye Tech Co. Ltd", [3]byte{64, 97, 134}: "MICRO-STAR INT'L CO.,LTD", [3]byte{64, 97, 142}: "Stella-Green Co", + [3]byte{64, 98, 49}: "GIFA", [3]byte{64, 98, 182}: "Tele system communication", + [3]byte{64, 98, 234}: "China Mobile Group Device Co.,Ltd.", + [3]byte{64, 100, 164}: "THE FURUKAWA ELECTRIC CO., LTD", [3]byte{64, 101, 163}: "Sagemcom Broadband SAS", [3]byte{64, 102, 122}: "mediola - connected living AG", [3]byte{64, 104, 38}: "Thales UK Limited", @@ -15688,6 +16097,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{64, 125, 15}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{64, 127, 224}: "Glory Star Technics (ShenZhen) Limited", [3]byte{64, 130, 86}: "Continental Automotive GmbH", + [3]byte{64, 131, 29}: "Apple, Inc.", [3]byte{64, 131, 222}: "Zebra Technologies Inc", [3]byte{64, 132, 147}: "Clavister AB", [3]byte{64, 134, 46}: "JDM MOBILE INTERNET SOLUTION CO., LTD.", @@ -15703,6 +16113,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{64, 152, 76}: "Casacom Solutions AG", [3]byte{64, 152, 78}: "Texas Instruments", [3]byte{64, 152, 123}: "Aisino Corporation", + [3]byte{64, 152, 173}: "Apple, Inc.", [3]byte{64, 153, 34}: "AzureWave Technology Inc.", [3]byte{64, 155, 13}: "Shenzhen Yourf Kwan Industrial Co., Ltd", [3]byte{64, 155, 205}: "D-Link International", @@ -15710,6 +16121,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{64, 159, 56}: "AzureWave Technology Inc.", [3]byte{64, 159, 135}: "Jide Technology (Hong Kong) Limited", [3]byte{64, 159, 199}: "BAEKCHUN I&C Co., Ltd.", + [3]byte{64, 161, 8}: "Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.", [3]byte{64, 163, 204}: "Intel Corporate", [3]byte{64, 165, 239}: "Shenzhen Four Seas Global Link Network Technology Co., Ltd.", [3]byte{64, 166, 119}: "Juniper Networks", @@ -15722,6 +16134,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{64, 176, 52}: "Hewlett Packard", [3]byte{64, 176, 250}: "LG Electronics (Mobile Communications)", [3]byte{64, 178, 200}: "Nortel Networks", + [3]byte{64, 179, 14}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{64, 179, 149}: "Apple, Inc.", [3]byte{64, 179, 205}: "Chiyoda Electronics Co.,Ltd.", [3]byte{64, 179, 252}: "Logital Co. Limited", @@ -15730,22 +16143,28 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{64, 182, 136}: "LEGIC Identsystems AG", [3]byte{64, 182, 177}: "SUNGSAM CO,.Ltd", [3]byte{64, 183, 243}: "ARRIS Group, Inc.", - [3]byte{64, 184, 55}: "Sony Mobile Communications AB", + [3]byte{64, 184, 55}: "Sony Mobile Communications Inc", [3]byte{64, 184, 154}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{64, 185, 60}: "Hewlett Packard Enterprise", [3]byte{64, 186, 97}: "ARIMA Communications Corp.", + [3]byte{64, 188, 96}: "Apple, Inc.", [3]byte{64, 188, 115}: "Cronoplast S.L.", [3]byte{64, 188, 139}: "itelio GmbH", + [3]byte{64, 189, 50}: "Texas Instruments", [3]byte{64, 189, 158}: "Physio-Control, Inc", [3]byte{64, 191, 23}: "Digistar Telecom. SA", [3]byte{64, 194, 69}: "Shenzhen Hexicom Technology Co., Ltd.", + [3]byte{64, 195, 198}: "SnapRoute", [3]byte{64, 196, 214}: "ChongQing Camyu Technology Development Co.,Ltd.", [3]byte{64, 198, 42}: "Shanghai Jing Ren Electronic Technology Co., Ltd.", [3]byte{64, 199, 41}: "Sagemcom Broadband SAS", [3]byte{64, 199, 201}: "Naviit Inc.", + [3]byte{64, 200, 31}: "Shenzhen Xinguodu Technology Co., Ltd.", [3]byte{64, 200, 203}: "AM Telecom co., Ltd.", [3]byte{64, 203, 168}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{64, 203, 192}: "Apple, Inc.", [3]byte{64, 205, 58}: "Z3 Technology", + [3]byte{64, 205, 122}: "Qingdao Hisense Communications Co.,Ltd.", [3]byte{64, 206, 36}: "Cisco Systems, Inc", [3]byte{64, 210, 138}: "Nintendo Co., Ltd.", [3]byte{64, 211, 45}: "Apple, Inc.", @@ -15755,6 +16174,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{64, 213, 89}: "MICRO S.E.R.I.", [3]byte{64, 214, 60}: "Equitech Industrial(DongGuan)Co.,Ltd", [3]byte{64, 216, 85}: "IEEE Registration Authority", + [3]byte{64, 220, 157}: "HAJEN", [3]byte{64, 226, 48}: "AzureWave Technology Inc.", [3]byte{64, 227, 214}: "Aruba Networks", [3]byte{64, 231, 48}: "DEY Storage Systems, Inc.", @@ -15762,8 +16182,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{64, 234, 206}: "FOUNDER BROADBAND NETWORK SERVICE CO.,LTD", [3]byte{64, 236, 248}: "Siemens AG", [3]byte{64, 237, 152}: "IEEE Registration Authority", + [3]byte{64, 238, 221}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{64, 239, 76}: "Fihonest communication co.,Ltd", [3]byte{64, 240, 47}: "Liteon Technology Corporation", + [3]byte{64, 240, 78}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{64, 241, 76}: "ISE Europe SPRL", [3]byte{64, 242, 1}: "Sagemcom Broadband SAS", [3]byte{64, 242, 233}: "IBM", @@ -15778,9 +16200,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{64, 252, 137}: "ARRIS Group, Inc.", [3]byte{64, 254, 13}: "MAXIO", [3]byte{68, 0, 16}: "Apple, Inc.", + [3]byte{68, 0, 73}: "Amazon Technologies Inc.", [3]byte{68, 3, 44}: "Intel Corporate", [3]byte{68, 3, 167}: "Cisco Systems, Inc", [3]byte{68, 4, 68}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", + [3]byte{68, 7, 11}: "Google, Inc.", [3]byte{68, 9, 184}: "Salcomp (Shenzhen) CO., LTD.", [3]byte{68, 12, 253}: "NetMan Co., Ltd.", [3]byte{68, 17, 2}: "EDMI Europe Ltd", @@ -15789,11 +16213,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{68, 20, 65}: "AudioControl Inc.", [3]byte{68, 24, 79}: "Fitview", [3]byte{68, 25, 182}: "Hangzhou Hikvision Digital Technology Co.,Ltd.", + [3]byte{68, 28, 18}: "Technicolor CH USA Inc.", [3]byte{68, 28, 168}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{68, 30, 145}: "ARVIDA Intelligent Electronics Technology Co.,Ltd.", + [3]byte{68, 30, 152}: "Ruckus Wireless", [3]byte{68, 30, 161}: "Hewlett Packard", + [3]byte{68, 34, 241}: "S.FAC, INC", [3]byte{68, 35, 170}: "Farmage Co., Ltd.", [3]byte{68, 37, 187}: "Bamboo Entertainment Corporation", + [3]byte{68, 40, 163}: "Jiangsu fulian Communication Technology Co., Ltd.", [3]byte{68, 41, 56}: "NietZsche enterprise Co.Ltd.", [3]byte{68, 42, 96}: "Apple, Inc.", [3]byte{68, 42, 255}: "E3 Technology, Inc.", @@ -15804,6 +16232,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{68, 50, 200}: "Technicolor CH USA Inc.", [3]byte{68, 51, 76}: "Shenzhen Bilian electronic CO.,LTD", [3]byte{68, 52, 143}: "MXT INDUSTRIAL LTDA", + [3]byte{68, 52, 167}: "ARRIS Group, Inc.", [3]byte{68, 53, 111}: "Neterix", [3]byte{68, 55, 8}: "MRV Comunications", [3]byte{68, 55, 25}: "2 Save Energy Ltd", @@ -15815,10 +16244,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{68, 61, 33}: "Nuvolt", [3]byte{68, 62, 178}: "DEOTRON Co., LTD.", [3]byte{68, 68, 80}: "OttoQ", + [3]byte{68, 71, 204}: "Hangzhou Hikvision Digital Technology Co.,Ltd.", [3]byte{68, 72, 145}: "HDMI Licensing, LLC", [3]byte{68, 72, 193}: "Hewlett Packard Enterprise", [3]byte{68, 74, 101}: "Silverflare Ltd.", [3]byte{68, 74, 176}: "Zhejiang Moorgen Intelligence Technology Co., Ltd", + [3]byte{68, 75, 93}: "GE Healthcare", [3]byte{68, 76, 12}: "Apple, Inc.", [3]byte{68, 76, 168}: "Arista Networks", [3]byte{68, 78, 26}: "Samsung Electronics Co.,Ltd", @@ -15840,7 +16271,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{68, 98, 70}: "Comat AG", [3]byte{68, 101, 13}: "Amazon Technologies Inc.", [3]byte{68, 101, 106}: "Mega Video Electronic(HK) Industry Co., Ltd", + [3]byte{68, 101, 127}: "Calix Inc.", [3]byte{68, 102, 110}: "IP-LINE", + [3]byte{68, 102, 252}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{68, 103, 85}: "Orbit Irrigation", [3]byte{68, 104, 171}: "JUIN COMPANY, LIMITED", [3]byte{68, 106, 46}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -15852,7 +16285,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{68, 112, 11}: "IFFU", [3]byte{68, 112, 152}: "MING HONG TECHNOLOGY (SHEN ZHEN) LIMITED", [3]byte{68, 115, 214}: "Logitech", - [3]byte{68, 116, 108}: "Sony Mobile Communications AB", + [3]byte{68, 116, 108}: "Sony Mobile Communications Inc", [3]byte{68, 120, 62}: "Samsung Electronics Co.,Ltd", [3]byte{68, 123, 187}: "Shenzhen YOUHUA Technology Co., Ltd", [3]byte{68, 123, 196}: "DualShine Technology(SZ)Co.,Ltd", @@ -15882,8 +16315,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{68, 151, 90}: "SHENZHEN FAST TECHNOLOGIES CO.,LTD", [3]byte{68, 155, 120}: "The Now Factory", [3]byte{68, 156, 181}: "Alcomp, Inc", + [3]byte{68, 158, 249}: "vivo Mobile Communication Co., Ltd.", [3]byte{68, 159, 127}: "DataCore Software Corporation", [3]byte{68, 164, 45}: "TCT mobile ltd", + [3]byte{68, 164, 102}: "GROUPE LDLC", [3]byte{68, 166, 137}: "PROMAX ELECTRONICA SA", [3]byte{68, 166, 229}: "THINKING TECHNOLOGY CO.,LTD", [3]byte{68, 167, 207}: "Murata Manufacturing Co., Ltd.", @@ -15916,9 +16351,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{68, 209, 250}: "Shenzhen Yunlink Technology Co., Ltd", [3]byte{68, 210, 68}: "Seiko Epson Corporation", [3]byte{68, 210, 202}: "Anvia TV Oy", + [3]byte{68, 211, 173}: "Shenzhen TINNO Mobile Technology Corp.", [3]byte{68, 211, 202}: "Cisco Systems, Inc", [3]byte{68, 212, 55}: "Inteno Broadband Technology AB", - [3]byte{68, 212, 224}: "Sony Mobile Communications AB", + [3]byte{68, 212, 224}: "Sony Mobile Communications Inc", [3]byte{68, 213, 165}: "AddOn Computer", [3]byte{68, 214, 61}: "Talari Networks", [3]byte{68, 214, 225}: "Snuza International Pty. Ltd.", @@ -15931,13 +16367,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{68, 225, 55}: "ARRIS Group, Inc.", [3]byte{68, 228, 154}: "OMNITRONICS PTY LTD", [3]byte{68, 228, 217}: "Cisco Systems, Inc", + [3]byte{68, 228, 238}: "Wistron Neweb Corporation", + [3]byte{68, 230, 110}: "Apple, Inc.", [3]byte{68, 232, 165}: "Myreka Technologies Sdn. Bhd.", [3]byte{68, 233, 221}: "Sagemcom Broadband SAS", [3]byte{68, 234, 75}: "Actlas Inc.", [3]byte{68, 234, 216}: "Texas Instruments", + [3]byte{68, 236, 206}: "Juniper Networks", [3]byte{68, 237, 87}: "Longicorn, inc.", [3]byte{68, 238, 2}: "MTI Ltd.", [3]byte{68, 238, 48}: "Budelmann Elektronik GmbH", + [3]byte{68, 239, 207}: "UGENE SOLUTION inc.", [3]byte{68, 240, 52}: "Kaonmedia CO., LTD.", [3]byte{68, 244, 54}: "zte corporation", [3]byte{68, 244, 89}: "Samsung Electronics Co.,Ltd", @@ -15945,11 +16385,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{68, 248, 73}: "Union Pacific Railroad", [3]byte{68, 251, 66}: "Apple, Inc.", [3]byte{68, 253, 163}: "Everysight LTD.", + [3]byte{68, 255, 186}: "zte corporation", [3]byte{72, 0, 49}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{72, 0, 51}: "Technicolor CH USA Inc.", [3]byte{72, 2, 42}: "B-Link Electronic Limited", [3]byte{72, 3, 98}: "DESAY ELECTRONICS(HUIZHOU)CO.,LTD", [3]byte{72, 6, 106}: "Tempered Networks, Inc.", + [3]byte{72, 11, 178}: "IEEE Registration Authority", [3]byte{72, 12, 73}: "NAKAYO Inc", [3]byte{72, 14, 236}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{72, 15, 207}: "Hewlett Packard", @@ -15959,15 +16401,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{72, 19, 243}: "BBK EDUCATIONAL ELECTRONICS CORP.,LTD.", [3]byte{72, 23, 76}: "MicroPower technologies", [3]byte{72, 24, 66}: "Shanghai Winaas Co. Equipment Co. Ltd.", + [3]byte{72, 24, 250}: "Nocsys", [3]byte{72, 26, 132}: "Pointer Telocation Ltd", [3]byte{72, 27, 210}: "Intron Scientific co., ltd.", [3]byte{72, 29, 112}: "Cisco SPVTG", [3]byte{72, 38, 232}: "Tek-Air Systems, Inc.", [3]byte{72, 39, 234}: "Samsung Electronics Co.,Ltd", [3]byte{72, 40, 47}: "zte corporation", + [3]byte{72, 42, 227}: "Wistron InfoComm(Kunshan)Co.,Ltd.", + [3]byte{72, 44, 160}: "Xiaomi Communications Co Ltd", [3]byte{72, 44, 234}: "Motorola Inc Business Light Radios", [3]byte{72, 51, 221}: "ZENNIO AVANCE Y TECNOLOGIA, S.L.", [3]byte{72, 52, 61}: "IEP GmbH", + [3]byte{72, 53, 46}: "Shenzhen Wolck Network Product Co.,LTD", [3]byte{72, 54, 95}: "Wintecronics Ltd.", [3]byte{72, 57, 116}: "Proware Technologies Co., Ltd.", [3]byte{72, 59, 56}: "Apple, Inc.", @@ -15981,6 +16427,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{72, 70, 241}: "Uros Oy", [3]byte{72, 70, 251}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{72, 73, 199}: "Samsung Electronics Co.,Ltd", + [3]byte{72, 74, 233}: "Hewlett Packard Enterprise", [3]byte{72, 75, 170}: "Apple, Inc.", [3]byte{72, 77, 126}: "Dell Inc.", [3]byte{72, 80, 115}: "Microsoft Corporation", @@ -15989,6 +16436,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{72, 84, 21}: "NET RULES TECNOLOGIA EIRELI", [3]byte{72, 85, 92}: "Wu Qi Technologies,Inc.", [3]byte{72, 85, 95}: "Fiberhome Telecommunication Technologies Co.,LTD", + [3]byte{72, 87, 2}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{72, 87, 221}: "Facebook Inc", [3]byte{72, 89, 41}: "LG Electronics (Mobile Communications)", [3]byte{72, 89, 164}: "zte corporation", @@ -15997,10 +16445,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{72, 91, 57}: "ASUSTek COMPUTER INC.", [3]byte{72, 93, 54}: "Verizon", [3]byte{72, 93, 96}: "AzureWave Technology Inc.", + [3]byte{72, 95, 153}: "Cloud Network Technology (Samoa) Limited", + [3]byte{72, 96, 95}: "LG Electronics (Mobile Communications)", [3]byte{72, 96, 188}: "Apple, Inc.", [3]byte{72, 97, 163}: "Concern Axion JSC", [3]byte{72, 98, 118}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{72, 101, 238}: "IEEE Registration Authority", + [3]byte{72, 104, 52}: "Silicon Motion, Inc.", [3]byte{72, 107, 44}: "BBK EDUCATIONAL ELECTRONICS CORP.,LTD.", [3]byte{72, 107, 145}: "Fleetwood Group Inc.", [3]byte{72, 109, 187}: "Vestel Elektronik San ve Tic. A.Ş.", @@ -16009,6 +16460,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{72, 111, 210}: "StorSimple Inc", [3]byte{72, 113, 25}: "SGB GROUP LTD.", [3]byte{72, 116, 110}: "Apple, Inc.", + [3]byte{72, 117, 131}: "Intellion AG", [3]byte{72, 118, 4}: "Private", [3]byte{72, 122, 85}: "ALE International", [3]byte{72, 122, 218}: "Hangzhou H3C Technologies Co., Limited", @@ -16018,24 +16470,32 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{72, 130, 242}: "Appel Elektronik GmbH", [3]byte{72, 131, 199}: "Sagemcom Broadband SAS", [3]byte{72, 134, 232}: "Microsoft Corporation", + [3]byte{72, 135, 45}: "SHEN ZHEN DA XIA LONG QUE TECHNOLOGY CO.,LTD", [3]byte{72, 136, 3}: "ManTechnology Inc.", + [3]byte{72, 136, 30}: "EthoSwitch LLC", [3]byte{72, 136, 202}: "Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.", - [3]byte{72, 138, 210}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", + [3]byte{72, 138, 210}: "MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", [3]byte{72, 141, 54}: "Arcadyan Corporation", [3]byte{72, 142, 66}: "DIGALOG GmbH", [3]byte{72, 142, 239}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{72, 145, 83}: "Weinmann Geräte für Medizin GmbH + Co. KG", [3]byte{72, 145, 246}: "Shenzhen Reach software technology CO.,LTD", + [3]byte{72, 152, 202}: "Sichuan\u00a0AI-Link\u00a0Technology\u00a0Co.,\u00a0Ltd.", [3]byte{72, 154, 66}: "Technomate Ltd", [3]byte{72, 155, 226}: "SCI Innovations Ltd", [3]byte{72, 157, 24}: "Flashbay Limited", [3]byte{72, 157, 36}: "BlackBerry RTS", + [3]byte{72, 160, 248}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{72, 161, 149}: "Apple, Inc.", [3]byte{72, 162, 45}: "Shenzhen Huaxuchang Telecom Technology Co.,Ltd", [3]byte{72, 162, 183}: "Kodofon JSC", [3]byte{72, 163, 128}: "Gionee Communication Equipment Co.,Ltd.", + [3]byte{72, 164, 114}: "Intel Corporate", + [3]byte{72, 164, 147}: "TAIYO YUDEN CO.,LTD", + [3]byte{72, 166, 184}: "Sonos, Inc.", [3]byte{72, 166, 210}: "GJsun Optical Science and Tech Co.,Ltd.", [3]byte{72, 167, 78}: "zte corporation", + [3]byte{72, 169, 28}: "Apple, Inc.", [3]byte{72, 169, 210}: "Wistron Neweb Corporation", [3]byte{72, 170, 93}: "Store Electronic Systems", [3]byte{72, 173, 8}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -16047,6 +16507,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{72, 185, 194}: "Teletics Inc.", [3]byte{72, 186, 78}: "Hewlett Packard", [3]byte{72, 188, 166}: "\u200bASUNG TECHNO CO.,Ltd", + [3]byte{72, 189, 61}: "New H3C Technologies Co., Ltd", [3]byte{72, 190, 45}: "Symanitron", [3]byte{72, 191, 107}: "Apple, Inc.", [3]byte{72, 191, 116}: "Baicells Technologies Co.,LTD", @@ -16055,6 +16516,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{72, 193, 172}: "PLANTRONICS, INC.", [3]byte{72, 197, 141}: "Lear Corporation GmbH", [3]byte{72, 198, 99}: "GTO Access Systems LLC", + [3]byte{72, 199, 150}: "Samsung Electronics Co.,Ltd", [3]byte{72, 200, 98}: "Simo Wireless,Inc.", [3]byte{72, 200, 182}: "SysTec GmbH", [3]byte{72, 203, 110}: "Cello Electronics (UK) Ltd", @@ -16073,10 +16535,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{72, 218, 150}: "Eddy Smart Home Solutions Inc.", [3]byte{72, 219, 80}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{72, 220, 251}: "Nokia Corporation", + [3]byte{72, 221, 157}: "ITEL MOBILE LIMITED", [3]byte{72, 223, 28}: "Wuhan NEC Fibre Optic Communications industry Co. Ltd", [3]byte{72, 223, 55}: "Hewlett Packard Enterprise", [3]byte{72, 225, 175}: "Vity", [3]byte{72, 226, 68}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{72, 230, 149}: "Insigma Inc", [3]byte{72, 233, 241}: "Apple, Inc.", [3]byte{72, 234, 99}: "Zhejiang Uniview Technologies Co., Ltd.", [3]byte{72, 235, 48}: "ETERNA TECHNOLOGY, INC.", @@ -16085,6 +16549,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{72, 238, 7}: "Silver Palm Technologies LLC", [3]byte{72, 238, 12}: "D-Link International", [3]byte{72, 238, 134}: "UTStarcom (China) Co.,Ltd", + [3]byte{72, 240, 39}: "Chengdu newifi Co.,Ltd", [3]byte{72, 240, 123}: "ALPS ELECTRIC CO.,LTD.", [3]byte{72, 242, 48}: "Ubizcore Co.,LTD", [3]byte{72, 243, 23}: "Private", @@ -16100,6 +16565,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{72, 253, 142}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{72, 254, 234}: "HOMA B.V.", [3]byte{76, 0, 130}: "Cisco Systems, Inc", + [3]byte{76, 1, 67}: "eero inc.", [3]byte{76, 2, 46}: "CMR KOREA CO., LTD", [3]byte{76, 2, 137}: "LEX COMPUTECH CO., LTD", [3]byte{76, 6, 138}: "Basler Electric Company", @@ -16110,8 +16576,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{76, 11, 190}: "Microsoft", [3]byte{76, 13, 238}: "JABIL CIRCUIT (SHANGHAI) LTD.", [3]byte{76, 15, 110}: "Hon Hai Precision Ind. Co.,Ltd.", - [3]byte{76, 15, 199}: "Earda Electronics Co.,Ltd", + [3]byte{76, 15, 199}: "Earda Technologies co Ltd", + [3]byte{76, 17, 89}: "Vision Information & Communications", [3]byte{76, 17, 191}: "Zhejiang Dahua Technology Co., Ltd.", + [3]byte{76, 18, 101}: "ARRIS Group, Inc.", [3]byte{76, 19, 101}: "Emplus Technologies", [3]byte{76, 20, 128}: "NOREGON SYSTEMS, INC", [3]byte{76, 20, 163}: "TCL Technoly Electronics (Huizhou) Co., Ltd.", @@ -16123,8 +16591,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{76, 26, 58}: "PRIMA Research And Production Enterprise Ltd.", [3]byte{76, 26, 61}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{76, 26, 149}: "Novakon Co., Ltd.", + [3]byte{76, 27, 134}: "Arcadyan Corporation", [3]byte{76, 31, 204}: "HUAWEI TECHNOLOGIES CO.,LTD", - [3]byte{76, 33, 208}: "Sony Mobile Communications AB", + [3]byte{76, 33, 208}: "Sony Mobile Communications Inc", [3]byte{76, 34, 88}: "cozybit, Inc.", [3]byte{76, 37, 120}: "Nokia Corporation", [3]byte{76, 38, 231}: "Welgate Co., Ltd.", @@ -16137,12 +16606,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{76, 50, 217}: "M Rutty Holdings Pty. Ltd.", [3]byte{76, 51, 78}: "HIGHTECH", [3]byte{76, 52, 136}: "Intel Corporate", + [3]byte{76, 54, 78}: "Panasonic Corporation Connected Solutions Company", [3]byte{76, 56, 213}: "MITAC COMPUTING TECHNOLOGY CORPORATION", [3]byte{76, 56, 216}: "ARRIS Group, Inc.", [3]byte{76, 57, 9}: "HPL Electric & Power Private Limited", [3]byte{76, 57, 16}: "Newtek Electronics co., Ltd.", [3]byte{76, 59, 116}: "VOGTEC(H.K.) Co., Ltd", [3]byte{76, 60, 22}: "Samsung Electronics Co.,Ltd", + [3]byte{76, 63, 211}: "Texas Instruments", [3]byte{76, 72, 218}: "Beijing Autelan Technology Co.,Ltd", [3]byte{76, 73, 227}: "Xiaomi Communications Co Ltd", [3]byte{76, 75, 104}: "Mobile Device, Inc.", @@ -16154,6 +16625,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{76, 85, 133}: "Hamilton Systems", [3]byte{76, 85, 184}: "Turkcell Teknoloji", [3]byte{76, 85, 204}: "Zentri Pty Ltd", + [3]byte{76, 86, 157}: "Apple, Inc.", [3]byte{76, 87, 202}: "Apple, Inc.", [3]byte{76, 93, 205}: "Oy Finnish Electric Vehicle Technologies Ltd", [3]byte{76, 94, 12}: "Routerboard.com", @@ -16174,6 +16646,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{76, 116, 191}: "Apple, Inc.", [3]byte{76, 118, 37}: "Dell Inc.", [3]byte{76, 119, 79}: "Embedded Wireless Labs", + [3]byte{76, 119, 109}: "Cisco Systems, Inc", [3]byte{76, 120, 114}: "Cav. Uff. Giacomo Cimberio S.p.A.", [3]byte{76, 120, 151}: "Arrowhead Alarm Products Ltd", [3]byte{76, 121, 186}: "Intel Corporate", @@ -16182,7 +16655,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{76, 128, 79}: "Armstrong Monitoring Corp", [3]byte{76, 128, 147}: "Intel Corporate", [3]byte{76, 129, 32}: "Taicang T&W Electronics", - [3]byte{76, 130, 207}: "Echostar Technologies Corp", + [3]byte{76, 130, 207}: "Dish Technologies Corp", [3]byte{76, 131, 222}: "Cisco SPVTG", [3]byte{76, 139, 48}: "Actiontec Electronics, Inc", [3]byte{76, 139, 85}: "Grupo Digicon", @@ -16204,6 +16677,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{76, 169, 40}: "Insensi", [3]byte{76, 170, 22}: "AzureWave Technologies (Shanghai) Inc.", [3]byte{76, 171, 51}: "KST technology", + [3]byte{76, 171, 252}: "zte corporation", [3]byte{76, 172, 10}: "zte corporation", [3]byte{76, 174, 28}: "SaiNXT Technologies LLP", [3]byte{76, 174, 49}: "ShengHai Electronics (Shenzhen) Ltd", @@ -16224,6 +16698,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{76, 188, 66}: "Shenzhen Hangsheng Electronics Co.,Ltd.", [3]byte{76, 188, 165}: "Samsung Electronics Co.,Ltd", [3]byte{76, 189, 143}: "Hangzhou Hikvision Digital Technology Co.,Ltd.", + [3]byte{76, 192, 10}: "vivo Mobile Communication Co., Ltd.", + [3]byte{76, 194, 6}: "Somfy", [3]byte{76, 196, 82}: "Shang Hai Tyd. Electon Technology Ltd.", [3]byte{76, 198, 2}: "Radios, Inc.", [3]byte{76, 198, 129}: "Shenzhen Aisat Electronic Co., Ltd.", @@ -16233,19 +16709,26 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{76, 204, 52}: "Motorola Solutions Inc.", [3]byte{76, 204, 106}: "Micro-Star INTL CO., LTD.", [3]byte{76, 208, 138}: "HUMAX Co., Ltd.", + [3]byte{76, 208, 203}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{76, 209, 161}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{76, 214, 55}: "Qsono Electronics Co., Ltd", [3]byte{76, 215, 182}: "Helmer Scientific", + [3]byte{76, 217, 143}: "Dell Inc.", [3]byte{76, 217, 196}: "Magneti Marelli Automotive Electronics (Guangzhou) Co. Ltd", + [3]byte{76, 221, 49}: "Samsung Electronics Co.,Ltd", [3]byte{76, 223, 61}: "TEAM ENGINEERS ADVANCE TECHNOLOGIES INDIA PVT LTD", [3]byte{76, 225, 115}: "IEEE Registration Authority", [3]byte{76, 225, 187}: "Zhuhai HiFocus Technology Co., Ltd.", [3]byte{76, 226, 241}: "sclak srl", + [3]byte{76, 229, 174}: "Tianjin Beebox Intelligent Technology Co.,Ltd.", [3]byte{76, 230, 118}: "BUFFALO.INC", [3]byte{76, 233, 51}: "RailComm, LLC", [3]byte{76, 235, 66}: "Intel Corporate", [3]byte{76, 236, 239}: "Soraa, Inc.", [3]byte{76, 237, 222}: "ASKEY COMPUTER CORP", + [3]byte{76, 237, 251}: "ASUSTek COMPUTER INC.", [3]byte{76, 238, 176}: "SHC Netzwerktechnik GmbH", + [3]byte{76, 239, 192}: "Amazon Technologies Inc.", [3]byte{76, 240, 46}: "Vifa Denmark A/S", [3]byte{76, 242, 191}: "Cambridge Industries(Group) Co.,Ltd.", [3]byte{76, 244, 91}: "Blue Clover Devices", @@ -16270,12 +16753,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{80, 15, 128}: "Cisco Systems, Inc", [3]byte{80, 15, 245}: "Tenda Technology Co.,Ltd.Dongguan branch", [3]byte{80, 17, 235}: "SilverNet Ltd", + [3]byte{80, 20, 121}: "iRobot Corporation", [3]byte{80, 20, 181}: "Richfit Information Technology Co., Ltd", [3]byte{80, 23, 255}: "Cisco Systems, Inc", [3]byte{80, 24, 76}: "Platina Systems Inc.", [3]byte{80, 26, 165}: "GN Netcom A/S", [3]byte{80, 26, 197}: "Microsoft", + [3]byte{80, 28, 176}: "Cisco Systems, Inc", [3]byte{80, 28, 191}: "Cisco Systems, Inc", + [3]byte{80, 29, 147}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{80, 30, 45}: "StreamUnlimited Engineering GmbH", [3]byte{80, 32, 107}: "Emerson Climate Technologies Transportation Solutions", [3]byte{80, 34, 103}: "PixeLINK", @@ -16283,6 +16769,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{80, 38, 144}: "FUJITSU LIMITED", [3]byte{80, 39, 199}: "TECHNART Co.,Ltd", [3]byte{80, 41, 77}: "NANJING IOT SENSOR TECHNOLOGY CO,LTD", + [3]byte{80, 41, 245}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{80, 42, 126}: "Smart electronic GmbH", [3]byte{80, 42, 139}: "Telekom Research and Development Sdn Bhd", [3]byte{80, 43, 115}: "Tenda Technology Co.,Ltd.Dongguan branch", @@ -16291,6 +16778,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{80, 45, 244}: "Phytec Messtechnik GmbH", [3]byte{80, 46, 92}: "HTC Corporation", [3]byte{80, 46, 206}: "Asahi Electronics Co.,Ltd", + [3]byte{80, 47, 168}: "Cisco Systems, Inc", [3]byte{80, 49, 173}: "ABB Global Industries and Services Private Limited", [3]byte{80, 50, 55}: "Apple, Inc.", [3]byte{80, 50, 117}: "Samsung Electronics Co.,Ltd", @@ -16313,21 +16801,28 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{80, 74, 94}: "Masimo Corporation", [3]byte{80, 74, 110}: "NETGEAR", [3]byte{80, 75, 91}: "CONTROLtronic GmbH", + [3]byte{80, 76, 126}: "THE 41ST INSTITUTE OF CETC", [3]byte{80, 78, 220}: "Ping Communication", [3]byte{80, 79, 148}: "Loxone Electronics GmbH", [3]byte{80, 80, 42}: "Egardia", [3]byte{80, 80, 101}: "TAKT Corporation", + [3]byte{80, 80, 206}: "Hangzhou Dianyixia Communication Technology Co. Ltd.", [3]byte{80, 82, 210}: "Hangzhou Telin Technologies Co., Limited", [3]byte{80, 85, 39}: "LG Electronics (Mobile Communications)", [3]byte{80, 86, 99}: "Texas Instruments", [3]byte{80, 86, 168}: "Jolla Ltd", [3]byte{80, 86, 191}: "Samsung Electronics Co.,Ltd", + [3]byte{80, 87, 156}: "Seiko Epson Corporation", [3]byte{80, 87, 168}: "Cisco Systems, Inc", [3]byte{80, 88, 0}: "WyTec International, Inc.", [3]byte{80, 88, 79}: "waytotec,Inc.", + [3]byte{80, 89, 103}: "Intent Solutions Inc", [3]byte{80, 90, 198}: "GUANGDONG SUPER TELECOM CO.,LTD.", + [3]byte{80, 91, 194}: "Liteon Technology Corporation", + [3]byte{80, 93, 172}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{80, 96, 40}: "Xirrus Inc.", [3]byte{80, 97, 132}: "Avaya Inc", + [3]byte{80, 97, 191}: "Cisco Systems, Inc", [3]byte{80, 97, 214}: "Indu-Sol GmbH", [3]byte{80, 99, 19}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{80, 100, 43}: "XIAOMI Electronics,CO.,LTD", @@ -16339,8 +16834,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{80, 103, 240}: "Zyxel Communications Corporation", [3]byte{80, 104, 10}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{80, 106, 3}: "NETGEAR", + [3]byte{80, 107, 75}: "Mellanox Technologies, Inc.", [3]byte{80, 107, 141}: "Nutanix", + [3]byte{80, 108, 190}: "InnosiliconTechnology Ltd", [3]byte{80, 110, 146}: "Innocent Technology Co., Ltd.", + [3]byte{80, 111, 119}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{80, 111, 152}: "Sehaj Synergy Technologies Private Limited", [3]byte{80, 111, 154}: "Wi-Fi Alliance", [3]byte{80, 112, 229}: "He Shan World Fair Electronics Technology Limited", @@ -16348,6 +16846,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{80, 114, 77}: "BEG Brueck Electronic GmbH", [3]byte{80, 118, 145}: "Tekpea, Inc.", [3]byte{80, 118, 166}: "Ecil Informatica Ind. Com. Ltda", + [3]byte{80, 118, 175}: "Intel Corporate", [3]byte{80, 119, 5}: "Samsung Electronics Co.,Ltd", [3]byte{80, 121, 91}: "Interexport Telecomunicaciones S.A.", [3]byte{80, 122, 85}: "Apple, Inc.", @@ -16364,10 +16863,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{80, 138, 203}: "SHENZHEN MAXMADE TECHNOLOGY CO., LTD.", [3]byte{80, 140, 119}: "DIRMEIER Schanktechnik GmbH &Co KG", [3]byte{80, 140, 177}: "Texas Instruments", + [3]byte{80, 140, 245}: "China Mobile Group Device Co.,Ltd.", [3]byte{80, 141, 111}: "CHAHOO Limited", [3]byte{80, 143, 76}: "Xiaomi Communications Co Ltd", [3]byte{80, 146, 185}: "Samsung Electronics Co.,Ltd", [3]byte{80, 147, 79}: "Gradual Tecnologia Ltda.", + [3]byte{80, 149, 81}: "ARRIS Group, Inc.", [3]byte{80, 151, 114}: "Westinghouse Digital", [3]byte{80, 152, 113}: "Inventum Technologies Private Limited", [3]byte{80, 152, 243}: "Rheem Australia Pty Ltd", @@ -16375,10 +16876,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{80, 158, 167}: "Samsung Electronics Co.,Ltd", [3]byte{80, 159, 39}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{80, 159, 59}: "OI ELECTRIC CO.,LTD", + [3]byte{80, 160, 9}: "Xiaomi Communications Co Ltd", [3]byte{80, 160, 84}: "Actineon", + [3]byte{80, 160, 164}: "Nokia", [3]byte{80, 160, 191}: "Alba Fiber Systems Inc.", [3]byte{80, 164, 200}: "Samsung Electronics Co.,Ltd", [3]byte{80, 164, 208}: "IEEE Registration Authority", + [3]byte{80, 166, 127}: "Apple, Inc.", [3]byte{80, 166, 227}: "David Clark Company", [3]byte{80, 167, 21}: "Aboundi, Inc.", [3]byte{80, 167, 43}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -16394,6 +16898,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{80, 183, 195}: "Samsung Electronics Co.,Ltd", [3]byte{80, 184, 136}: "wi2be Tecnologia S/A", [3]byte{80, 184, 162}: "ImTech Technologies LLC,", + [3]byte{80, 188, 150}: "Apple, Inc.", [3]byte{80, 189, 95}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{80, 192, 6}: "Carmanah Signs", [3]byte{80, 194, 113}: "SECURETECH INC", @@ -16413,9 +16918,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{80, 214, 215}: "Takahata Precision", [3]byte{80, 215, 83}: "CONELCOM GmbH", [3]byte{80, 218, 0}: "Hangzhou H3C Technologies Co., Limited", + [3]byte{80, 219, 63}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", + [3]byte{80, 220, 231}: "Amazon Technologies Inc.", + [3]byte{80, 220, 252}: "ECOCOM", [3]byte{80, 221, 79}: "Automation Components, Inc", [3]byte{80, 223, 149}: "Lytx", [3]byte{80, 224, 199}: "TurControlSystme AG", + [3]byte{80, 224, 239}: "Nokia", [3]byte{80, 225, 74}: "Private", [3]byte{80, 229, 73}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", [3]byte{80, 230, 102}: "Shenzhen Techtion Electronics Co., Ltd.", @@ -16447,8 +16956,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{84, 5, 54}: "Vivago Oy", [3]byte{84, 5, 95}: "Alcatel Lucent", [3]byte{84, 5, 147}: "WOORI ELEC Co.,Ltd", + [3]byte{84, 6, 139}: "Ningbo Deli Kebei Technology Co.LTD", [3]byte{84, 9, 85}: "zte corporation", [3]byte{84, 9, 141}: "deister electronic GmbH", + [3]byte{84, 16, 49}: "SMARTO", [3]byte{84, 16, 236}: "Microchip Technology Inc.", [3]byte{84, 17, 47}: "Sulzer Pump Solutions Finland Oy", [3]byte{84, 17, 95}: "Atamo Pty Ltd", @@ -16468,6 +16979,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{84, 39, 30}: "AzureWave Technology Inc.", [3]byte{84, 39, 88}: "Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.", [3]byte{84, 39, 108}: "Jiangsu Houge Technology Corp.", + [3]byte{84, 39, 141}: "NXP (China) Management Ltd.", [3]byte{84, 42, 156}: "LSY Defense, LLC.", [3]byte{84, 42, 162}: "Alpha Networks Inc.", [3]byte{84, 43, 87}: "Night Owl SP", @@ -16483,10 +16995,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{84, 57, 223}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{84, 59, 48}: "duagon AG", [3]byte{84, 61, 55}: "Ruckus Wireless", + [3]byte{84, 62, 100}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{84, 64, 173}: "Samsung Electronics Co.,Ltd", [3]byte{84, 66, 73}: "Sony Corporation", [3]byte{84, 68, 8}: "Nokia Corporation", [3]byte{84, 70, 107}: "Shenzhen CZTIC Electronic Technology Co., Ltd", + [3]byte{84, 72, 16}: "Dell Inc.", [3]byte{84, 72, 156}: "CDOUBLES ELECTRONICS CO. LTD.", [3]byte{84, 74, 0}: "Cisco Systems, Inc", [3]byte{84, 74, 5}: "wenglor sensoric gmbh", @@ -16509,6 +17023,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{84, 101, 222}: "ARRIS Group, Inc.", [3]byte{84, 102, 108}: "Shenzhen YOUHUA Technology Co., Ltd", [3]byte{84, 103, 81}: "Compal Broadband Networks, Inc.", + [3]byte{84, 106, 216}: "Elster Water Metering", [3]byte{84, 108, 14}: "Texas Instruments", [3]byte{84, 109, 82}: "TOPVIEW OPTRONICS CORP.", [3]byte{84, 114, 79}: "Apple, Inc.", @@ -16524,7 +17039,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{84, 127, 84}: "INGENICO", [3]byte{84, 127, 168}: "TELCO systems, s.r.o.", [3]byte{84, 127, 238}: "Cisco Systems, Inc", + [3]byte{84, 128, 40}: "Hewlett Packard Enterprise", + [3]byte{84, 129, 45}: "PAX Computer Technology(Shenzhen) Ltd.", [3]byte{84, 129, 173}: "Eagle Research Corporation", + [3]byte{84, 131, 58}: "Zyxel Communications Corporation", [3]byte{84, 132, 123}: "Digital Devices GmbH", [3]byte{84, 136, 14}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", [3]byte{84, 137, 34}: "Zelfy Inc", @@ -16533,13 +17051,16 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{84, 146, 190}: "Samsung Electronics Co.,Ltd", [3]byte{84, 147, 89}: "SHENZHEN TWOWING TECHNOLOGIES CO.,LTD.", [3]byte{84, 148, 120}: "Silvershore Technology Partners", + [3]byte{84, 153, 99}: "Apple, Inc.", [3]byte{84, 154, 17}: "IEEE Registration Authority", [3]byte{84, 154, 22}: "Uzushio Electric Co.,Ltd.", [3]byte{84, 154, 76}: "GUANGDONG HOMECARE TECHNOLOGY CO.,LTD.", [3]byte{84, 155, 18}: "Samsung Electronics Co.,Ltd", + [3]byte{84, 155, 114}: "Ericsson AB", [3]byte{84, 157, 133}: "EnerAccess inc", [3]byte{84, 159, 19}: "Apple, Inc.", [3]byte{84, 159, 53}: "Dell Inc.", + [3]byte{84, 159, 174}: "iBASE Gaming Inc", [3]byte{84, 160, 79}: "t-mac Technologies Ltd", [3]byte{84, 160, 80}: "ASUSTek COMPUTER INC.", [3]byte{84, 162, 116}: "Cisco Systems, Inc", @@ -16548,17 +17069,23 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{84, 165, 27}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{84, 165, 75}: "NSC Communications Siberia Ltd", [3]byte{84, 166, 25}: "Alcatel-Lucent Shanghai Bell Co., Ltd", + [3]byte{84, 166, 92}: "Technicolor CH USA Inc.", [3]byte{84, 169, 212}: "Minibar Systems", [3]byte{84, 171, 58}: "QUANTA COMPUTER INC.", [3]byte{84, 174, 39}: "Apple, Inc.", [3]byte{84, 177, 33}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{84, 178, 3}: "PEGATRON CORPORATION", [3]byte{84, 181, 108}: "Xi'an NovaStar Tech Co., Ltd", [3]byte{84, 182, 32}: "SUHDOL E&C Co.Ltd.", [3]byte{84, 183, 83}: "Hunan Fenghui Yinjia Science And Technology Co.,Ltd", + [3]byte{84, 183, 229}: "Rayson Technology Co., Ltd.", + [3]byte{84, 184, 2}: "Samsung Electronics Co.,Ltd", [3]byte{84, 184, 10}: "D-Link International", [3]byte{84, 189, 121}: "Samsung Electronics Co.,Ltd", [3]byte{84, 190, 83}: "zte corporation", [3]byte{84, 190, 247}: "PEGATRON CORPORATION", + [3]byte{84, 191, 100}: "Dell Inc.", + [3]byte{84, 195, 62}: "Ciena Corporation", [3]byte{84, 196, 21}: "Hangzhou Hikvision Digital Technology Co.,Ltd.", [3]byte{84, 197, 122}: "Sunnovo International Limited", [3]byte{84, 200, 15}: "TP-LINK TECHNOLOGIES CO.,LTD.", @@ -16603,11 +17130,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{84, 250, 62}: "Samsung Electronics Co.,Ltd", [3]byte{84, 250, 150}: "Nokia", [3]byte{84, 251, 88}: "WISEWARE, Lda", + [3]byte{84, 252, 240}: "Samsung Electronics Co.,Ltd", [3]byte{84, 253, 191}: "Scheidt & Bachmann GmbH", [3]byte{84, 255, 130}: "Davit Solution co.", [3]byte{84, 255, 207}: "Mopria Alliance", [3]byte{88, 0, 187}: "Juniper Networks", [3]byte{88, 0, 227}: "Liteon Technology Corporation", + [3]byte{88, 3, 251}: "Hangzhou Hikvision Digital Technology Co.,Ltd.", [3]byte{88, 4, 84}: "ICOMM HK LIMITED", [3]byte{88, 4, 203}: "Tianjin Huisun Technology Co.,Ltd.", [3]byte{88, 5, 40}: "LABRIS NETWORKS", @@ -16619,7 +17148,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{88, 16, 140}: "Intelbras", [3]byte{88, 18, 67}: "AcSiP Technology Corp.", [3]byte{88, 22, 38}: "Avaya Inc", - [3]byte{88, 23, 12}: "Sony Mobile Communications AB", + [3]byte{88, 23, 12}: "Sony Mobile Communications Inc", [3]byte{88, 25, 248}: "ARRIS Group, Inc.", [3]byte{88, 28, 189}: "Affinegy", [3]byte{88, 29, 145}: "Advanced Mobile Telecom co.,ltd.", @@ -16629,16 +17158,20 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{88, 31, 239}: "Tuttnaer LTD", [3]byte{88, 32, 177}: "Hewlett Packard", [3]byte{88, 33, 54}: "KMB systems, s.r.o.", + [3]byte{88, 33, 233}: "TWPI", [3]byte{88, 35, 140}: "Technicolor CH USA Inc.", [3]byte{88, 42, 247}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{88, 43, 219}: "Pax AB", + [3]byte{88, 45, 52}: "Qingping Electronics (Suzhou) Co., Ltd", [3]byte{88, 46, 254}: "Lighting Science Group", + [3]byte{88, 47, 64}: "Nintendo Co.,Ltd", [3]byte{88, 47, 66}: "Universal Electric Corporation", [3]byte{88, 49, 18}: "DRUST", [3]byte{88, 50, 119}: "Reliance Communications LLC", [3]byte{88, 52, 59}: "Glovast Technology Ltd.", [3]byte{88, 53, 217}: "Cisco Systems, Inc", [3]byte{88, 56, 121}: "RICOH COMPANY, LTD.", + [3]byte{88, 59, 217}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{88, 60, 198}: "Omneality Ltd.", [3]byte{88, 63, 84}: "LG Electronics (Mobile Communications)", [3]byte{88, 64, 78}: "Apple, Inc.", @@ -16647,7 +17180,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{88, 70, 143}: "Koncar Electronics and Informatics", [3]byte{88, 70, 225}: "Baxter International Inc", [3]byte{88, 71, 4}: "Shenzhen Webridge Technology Co.,Ltd", - [3]byte{88, 72, 34}: "Sony Mobile Communications AB", + [3]byte{88, 72, 34}: "Sony Mobile Communications Inc", [3]byte{88, 72, 192}: "COFLEC", [3]byte{88, 73, 37}: "E3 Enterprise", [3]byte{88, 73, 59}: "Palo Alto Networks", @@ -16662,6 +17195,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{88, 85, 202}: "Apple, Inc.", [3]byte{88, 86, 232}: "ARRIS Group, Inc.", [3]byte{88, 87, 13}: "Danfoss Solar Inverters", + [3]byte{88, 95, 246}: "zte corporation", [3]byte{88, 96, 95}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{88, 97, 99}: "Quantum Networks (SG) Pte. Ltd.", [3]byte{88, 99, 86}: "FN-LINK TECHNOLOGY LIMITED", @@ -16674,6 +17208,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{88, 105, 108}: "Ruijie Networks Co.,LTD", [3]byte{88, 105, 249}: "Fusion Transactive Ltd.", [3]byte{88, 106, 177}: "Hangzhou H3C Technologies Co., Limited", + [3]byte{88, 107, 20}: "Apple, Inc.", [3]byte{88, 109, 143}: "Cisco-Linksys, LLC", [3]byte{88, 110, 214}: "Private", [3]byte{88, 112, 198}: "Shanghai Xiaoyi Technology Co., Ltd.", @@ -16682,6 +17217,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{88, 118, 197}: "DIGI I'S LTD", [3]byte{88, 122, 77}: "Stonesoft Corporation", [3]byte{88, 122, 98}: "Texas Instruments", + [3]byte{88, 122, 106}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{88, 123, 233}: "AirPro Technology India Pvt. Ltd", [3]byte{88, 126, 97}: "Qingdao Hisense Communications Co.,Ltd.", [3]byte{88, 127, 87}: "Apple, Inc.", @@ -16710,17 +17246,23 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{88, 152, 111}: "Revolution Display", [3]byte{88, 155, 11}: "Shineway Technologies, Inc.", [3]byte{88, 156, 252}: "FreeBSD Foundation", + [3]byte{88, 158, 198}: "Gigaset Communications GmbH", [3]byte{88, 160, 203}: "TrackNet, Inc", [3]byte{88, 162, 181}: "LG Electronics (Mobile Communications)", + [3]byte{88, 164, 142}: "PixArt Imaging Inc.", [3]byte{88, 167, 111}: "iD corporation", [3]byte{88, 168, 57}: "Intel Corporate", [3]byte{88, 172, 120}: "Cisco Systems, Inc", [3]byte{88, 176, 53}: "Apple, Inc.", [3]byte{88, 176, 212}: "ZuniData Systems Inc.", + [3]byte{88, 177, 15}: "Samsung Electronics Co.,Ltd", + [3]byte{88, 179, 252}: "SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.", [3]byte{88, 180, 45}: "YSTen Technology Co.,Ltd", + [3]byte{88, 181, 104}: "SECURITAS DIRECT ESPAÑA, SAU", [3]byte{88, 182, 51}: "Ruckus Wireless", [3]byte{88, 185, 97}: "SOLEM Electronique", [3]byte{88, 185, 225}: "Crystalfontz America, Inc.", + [3]byte{88, 186, 212}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{88, 188, 39}: "Cisco Systems, Inc", [3]byte{88, 188, 143}: "Cognitive Systems Corp.", [3]byte{88, 189, 163}: "Nintendo Co., Ltd.", @@ -16731,13 +17273,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{88, 195, 139}: "Samsung Electronics Co.,Ltd", [3]byte{88, 197, 131}: "ITEL MOBILE LIMITED", [3]byte{88, 197, 203}: "Samsung Electronics Co.,Ltd", + [3]byte{88, 200, 118}: "China Mobile (Hangzhou) Information Technology Co., Ltd.", [3]byte{88, 201, 53}: "Chiun Mai Communication Systems, Inc", [3]byte{88, 207, 75}: "Lufkin Industries", [3]byte{88, 208, 113}: "BW Broadcast", [3]byte{88, 208, 143}: "IEEE 1904.1 Working Group", + [3]byte{88, 213, 110}: "D-Link International", [3]byte{88, 214, 122}: "TCPlink", [3]byte{88, 214, 211}: "Dairy Cheq Inc", + [3]byte{88, 215, 89}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{88, 217, 213}: "Tenda Technology Co.,Ltd.Dongguan branch", + [3]byte{88, 219, 21}: "TECNO MOBILE LIMITED", [3]byte{88, 219, 141}: "Fast Co., Ltd.", [3]byte{88, 220, 109}: "Exceptional Innovation, Inc.", [3]byte{88, 224, 44}: "Micro Technic A/S", @@ -16746,6 +17292,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{88, 227, 38}: "Compass Technologies Inc.", [3]byte{88, 228, 118}: "CENTRON COMMUNICATIONS TECHNOLOGIES FUJIAN CO.,LTD", [3]byte{88, 230, 54}: "EVRsafe Technologies", + [3]byte{88, 230, 186}: "Apple, Inc.", [3]byte{88, 231, 71}: "Deltanet AG", [3]byte{88, 232, 8}: "AUTONICS CORPORATION", [3]byte{88, 232, 118}: "IEEE Registration Authority", @@ -16759,14 +17306,18 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{88, 244, 150}: "Source Chain", [3]byte{88, 246, 123}: "Xia Men UnionCore Technology LTD.", [3]byte{88, 246, 191}: "Kyoto University", + [3]byte{88, 249, 135}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{88, 249, 142}: "SECUDOS GmbH", [3]byte{88, 251, 132}: "Intel Corporate", [3]byte{88, 252, 115}: "Arria Live Media, Inc.", [3]byte{88, 252, 219}: "IEEE Registration Authority", [3]byte{88, 253, 32}: "Bravida Sakerhet AB", + [3]byte{88, 253, 190}: "Shenzhen Taikaida Technology Co., Ltd", + [3]byte{92, 0, 56}: "Viasat Group S.p.A.", [3]byte{92, 2, 106}: "Applied Vision Corporation", [3]byte{92, 3, 57}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{92, 7, 111}: "Thought Creator", + [3]byte{92, 9, 71}: "Apple, Inc.", [3]byte{92, 9, 121}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{92, 10, 91}: "SAMSUNG ELECTRO MECHANICS CO., LTD.", [3]byte{92, 12, 14}: "Guizhou Huaxintong Semiconductor Technology Co Ltd", @@ -16781,12 +17332,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{92, 23, 211}: "LGE", [3]byte{92, 24, 181}: "Talon Communications", [3]byte{92, 26, 111}: "Cambridge Industries(Group) Co.,Ltd.", + [3]byte{92, 29, 217}: "Apple, Inc.", [3]byte{92, 32, 208}: "Asoni Communication Co., Ltd.", [3]byte{92, 34, 196}: "DAE EUN ELETRONICS CO., LTD", [3]byte{92, 36, 67}: "O-Sung Telecom Co., Ltd.", [3]byte{92, 36, 121}: "Baltech AG", [3]byte{92, 37, 76}: "Avire Global Pte Ltd", [3]byte{92, 38, 10}: "Dell Inc.", + [3]byte{92, 38, 35}: "WaveLynx Technologies Corporation", [3]byte{92, 42, 239}: "Open Access Pty Ltd", [3]byte{92, 43, 245}: "Vivint Wireless Inc.", [3]byte{92, 46, 89}: "Samsung Electronics Co.,Ltd", @@ -16821,11 +17374,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{92, 87, 200}: "Nokia Corporation", [3]byte{92, 88, 25}: "Jingsheng Technology Co., Ltd.", [3]byte{92, 89, 72}: "Apple, Inc.", + [3]byte{92, 90, 234}: "FORD", [3]byte{92, 91, 53}: "Mist Systems, Inc.", [3]byte{92, 91, 194}: "YIK Corporation", [3]byte{92, 94, 171}: "Juniper Networks", [3]byte{92, 95, 103}: "Intel Corporate", [3]byte{92, 99, 191}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{92, 99, 201}: "Intellithings Ltd.", [3]byte{92, 103, 118}: "IDS Imaging Development Systems GmbH", [3]byte{92, 105, 132}: "NUVICO", [3]byte{92, 106, 125}: "KENTKART EGE ELEKTRONIK SAN. VE TIC. LTD. STI.", @@ -16874,8 +17429,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{92, 175, 6}: "LG Electronics (Mobile Communications)", [3]byte{92, 176, 102}: "ARRIS Group, Inc.", [3]byte{92, 179, 149}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{92, 179, 246}: "Human, Incorporated", [3]byte{92, 180, 62}: "HUAWEI TECHNOLOGIES CO.,LTD", - [3]byte{92, 181, 36}: "Sony Mobile Communications AB", + [3]byte{92, 181, 36}: "Sony Mobile Communications Inc", [3]byte{92, 181, 89}: "CNEX Labs", [3]byte{92, 182, 204}: "NovaComm Technologies Inc.", [3]byte{92, 184, 203}: "Allis Communications", @@ -16888,14 +17444,18 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{92, 198, 208}: "Skyworth Digital Technology(Shenzhen) Co.,Ltd", [3]byte{92, 198, 233}: "Edifier International", [3]byte{92, 199, 215}: "AZROAD TECHNOLOGY COMPANY LIMITED", + [3]byte{92, 201, 153}: "New H3C Technologies Co., Ltd", [3]byte{92, 201, 211}: "PALLADIUM ENERGY ELETRONICA DA AMAZONIA LTDA", [3]byte{92, 202, 26}: "Microsoft Mobile Oy", [3]byte{92, 202, 50}: "Theben AG", + [3]byte{92, 203, 202}: "FUJIAN STAR-NET COMMUNICATION CO.,LTD", [3]byte{92, 204, 160}: "Gridwiz Inc.", [3]byte{92, 204, 255}: "Techroutes Network Pvt Ltd", + [3]byte{92, 205, 124}: "MEIZU Technology Co.,Ltd.", [3]byte{92, 206, 173}: "CDYNE Corporation", [3]byte{92, 207, 127}: "Espressif Inc.", [3]byte{92, 209, 53}: "Xtreme Power Systems", + [3]byte{92, 210, 11}: "Yytek Co., Ltd.", [3]byte{92, 210, 228}: "Intel Corporate", [3]byte{92, 212, 27}: "UCZOON Technology Co., LTD", [3]byte{92, 212, 171}: "Zektor", @@ -16936,6 +17496,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{92, 249, 106}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{92, 249, 221}: "Dell Inc.", [3]byte{92, 249, 240}: "Atomos Engineering P/L", + [3]byte{92, 251, 124}: "Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd", [3]byte{92, 252, 102}: "Cisco Systems, Inc", [3]byte{92, 255, 53}: "Wistron Corporation", [3]byte{92, 255, 255}: "Shenzhen Kezhonglong Optoelectronic Technology Co., Ltd", @@ -16945,6 +17506,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{96, 3, 8}: "Apple, Inc.", [3]byte{96, 3, 71}: "Billion Electric Co. Ltd.", [3]byte{96, 4, 23}: "POSBANK CO.,LTD", + [3]byte{96, 5, 138}: "Hitachi Metals, Ltd.", [3]byte{96, 8, 16}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{96, 8, 55}: "ivvi Scientific(Nanchang)Co.Ltd", [3]byte{96, 11, 3}: "Hangzhou H3C Technologies Co., Limited", @@ -16963,6 +17525,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{96, 25, 112}: "HUIZHOU QIAOXING ELECTRONICS TECHNOLOGY CO., LTD.", [3]byte{96, 25, 113}: "ARRIS Group, Inc.", [3]byte{96, 29, 15}: "Midnite Solar", + [3]byte{96, 29, 145}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{96, 30, 2}: "EltexAlatau", [3]byte{96, 33, 1}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{96, 33, 3}: "I4VINE, INC", @@ -16972,11 +17535,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{96, 42, 84}: "CardioTek B.V.", [3]byte{96, 42, 208}: "Cisco SPVTG", [3]byte{96, 46, 32}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{96, 48, 212}: "Apple, Inc.", [3]byte{96, 49, 59}: "Sunnovo International Limited", [3]byte{96, 49, 151}: "Zyxel Communications Corporation", [3]byte{96, 50, 240}: "Mplus technology", [3]byte{96, 51, 75}: "Apple, Inc.", [3]byte{96, 53, 83}: "Buwon Technology", + [3]byte{96, 53, 192}: "SFR", [3]byte{96, 54, 150}: "The Sapling Company", [3]byte{96, 54, 221}: "Intel Corporate", [3]byte{96, 56, 14}: "ALPS ELECTRIC CO.,LTD.", @@ -16997,7 +17562,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{96, 72, 38}: "Newbridge Technologies Int. Ltd.", [3]byte{96, 73, 193}: "Avaya Inc", [3]byte{96, 74, 28}: "SUYIN Corporation", - [3]byte{96, 75, 170}: "Private", + [3]byte{96, 75, 170}: "Magic Leap, Inc.", [3]byte{96, 80, 193}: "Kinetek Sports", [3]byte{96, 81, 44}: "TCT mobile ltd", [3]byte{96, 82, 208}: "FACTS Engineering", @@ -17005,6 +17570,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{96, 84, 100}: "Eyedro Green Solutions Inc.", [3]byte{96, 87, 24}: "Intel Corporate", [3]byte{96, 91, 180}: "AzureWave Technology Inc.", + [3]byte{96, 95, 141}: "eero inc.", [3]byte{96, 96, 31}: "SZ DJI TECHNOLOGY CO.,LTD", [3]byte{96, 99, 249}: "Ciholas, Inc.", [3]byte{96, 99, 253}: "Transcend Communication Beijing Co.,Ltd.", @@ -17015,6 +17581,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{96, 105, 68}: "Apple, Inc.", [3]byte{96, 105, 155}: "isepos GmbH", [3]byte{96, 107, 189}: "Samsung Electronics Co.,Ltd", + [3]byte{96, 107, 255}: "Nintendo Co.,Ltd", [3]byte{96, 108, 102}: "Intel Corporate", [3]byte{96, 109, 60}: "Luxshare Precision Industry Company Limited", [3]byte{96, 109, 199}: "Hon Hai Precision Ind. Co.,Ltd.", @@ -17030,11 +17597,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{96, 131, 52}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{96, 131, 178}: "GkWare e.K.", [3]byte{96, 132, 59}: "Soladigm, Inc.", + [3]byte{96, 132, 189}: "BUFFALO.INC", [3]byte{96, 134, 69}: "Avery Weigh-Tronix, LLC", [3]byte{96, 137, 60}: "Thermo Fisher Scientific P.O.A.", [3]byte{96, 137, 177}: "Key Digital Systems", [3]byte{96, 137, 183}: "KAEL MÜHENDİSLİK ELEKTRONİK TİCARET SANAYİ LİMİTED ŞİRKETİ", [3]byte{96, 140, 43}: "Hanson Technology", + [3]byte{96, 140, 74}: "Apple, Inc.", [3]byte{96, 140, 230}: "ARRIS Group, Inc.", [3]byte{96, 141, 23}: "Sentrus Government Systems Division, Inc", [3]byte{96, 142, 8}: "Samsung Electronics Co.,Ltd", @@ -17043,6 +17612,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{96, 145, 243}: "vivo Mobile Communication Co., Ltd.", [3]byte{96, 146, 23}: "Apple, Inc.", [3]byte{96, 150, 32}: "Private", + [3]byte{96, 151, 221}: "MicroSys Electronics GmbH", + [3]byte{96, 152, 19}: "Shanghai Visking Digital Technology Co. LTD", [3]byte{96, 153, 209}: "Vuzix / Lenovo", [3]byte{96, 154, 164}: "GVI SECURITY INC.", [3]byte{96, 154, 193}: "Apple, Inc.", @@ -17054,6 +17625,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{96, 163, 125}: "Apple, Inc.", [3]byte{96, 164, 76}: "ASUSTek COMPUTER INC.", [3]byte{96, 164, 208}: "Samsung Electronics Co.,Ltd", + [3]byte{96, 167, 48}: "Shenzhen Yipinfang Internet Technology Co.,Ltd", [3]byte{96, 168, 254}: "Nokia", [3]byte{96, 169, 176}: "Merchandising Technologies, Inc", [3]byte{96, 172, 200}: "KunTeng Inc.", @@ -17083,8 +17655,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{96, 203, 251}: "AirScape Inc.", [3]byte{96, 205, 169}: "Abloomy", [3]byte{96, 205, 197}: "Taiwan Carol Electronics., Ltd", + [3]byte{96, 206, 146}: "The Refined Industry Company Limited", + [3]byte{96, 208, 44}: "Ruckus Wireless", [3]byte{96, 208, 169}: "Samsung Electronics Co.,Ltd", [3]byte{96, 209, 170}: "Vishal Telecommunications Pvt Ltd", + [3]byte{96, 210, 28}: "Sunnovo International Limited", [3]byte{96, 210, 98}: "Tzukuri Pty Ltd", [3]byte{96, 210, 185}: "REALAND BIO CO., LTD.", [3]byte{96, 211, 10}: "Quatius Limited", @@ -17096,6 +17671,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{96, 218, 131}: "Hangzhou H3C Technologies Co., Limited", [3]byte{96, 219, 42}: "HNS", [3]byte{96, 222, 68}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{96, 222, 243}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{96, 224, 14}: "SHINSEI ELECTRONICS CO LTD", [3]byte{96, 227, 39}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{96, 227, 172}: "LG Electronics (Mobile Communications)", @@ -17108,6 +17684,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{96, 239, 198}: "Shenzhen Chima Technologies Co Limited", [3]byte{96, 241, 61}: "JABLOCOM s.r.o.", [3]byte{96, 241, 137}: "Murata Manufacturing Co., Ltd.", + [3]byte{96, 241, 138}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{96, 242, 129}: "TRANWO TECHNOLOGY CO., LTD.", [3]byte{96, 242, 239}: "VisionVera International Co., Ltd.", [3]byte{96, 243, 218}: "Logic Way GmbH", @@ -17117,6 +17694,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{96, 246, 115}: "TERUMO CORPORATION", [3]byte{96, 246, 119}: "Intel Corporate", [3]byte{96, 248, 29}: "Apple, Inc.", + [3]byte{96, 250, 157}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{96, 250, 205}: "Apple, Inc.", [3]byte{96, 251, 66}: "Apple, Inc.", [3]byte{96, 253, 86}: "WOORISYSTEMS CO., Ltd", @@ -17128,6 +17706,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{100, 0, 45}: "Powerlinq Co., LTD", [3]byte{100, 0, 106}: "Dell Inc.", [3]byte{100, 0, 241}: "Cisco Systems, Inc", + [3]byte{100, 2, 203}: "ARRIS Group, Inc.", [3]byte{100, 5, 190}: "NEW LIGHT LED", [3]byte{100, 5, 233}: "Shenzhen WayOS Technology Crop., Ltd.", [3]byte{100, 9, 76}: "Beijing Superbee Wireless Technology Co.,Ltd", @@ -17141,6 +17720,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{100, 16, 132}: "HEXIUM Technical Development Co., Ltd.", [3]byte{100, 18, 37}: "Cisco Systems, Inc", [3]byte{100, 18, 105}: "ARRIS Group, Inc.", + [3]byte{100, 19, 49}: "Bosch Car Multimedia (Wuhu) Co. Ltd.", [3]byte{100, 19, 108}: "zte corporation", [3]byte{100, 22, 102}: "Nest Labs Inc.", [3]byte{100, 22, 127}: "Polycom", @@ -17148,6 +17728,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{100, 22, 240}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{100, 26, 34}: "Heliospectra AB", [3]byte{100, 28, 103}: "DIGIBRAS INDUSTRIA DO BRASILS/A", + [3]byte{100, 28, 174}: "Samsung Electronics Co.,Ltd", + [3]byte{100, 28, 176}: "Samsung Electronics Co.,Ltd", [3]byte{100, 30, 129}: "Dowslake Microsystems", [3]byte{100, 32, 12}: "Apple, Inc.", [3]byte{100, 32, 159}: "Tilgin AB", @@ -17171,6 +17753,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{100, 75, 195}: "Shanghai WOASiS Telecommunications Ltd., Co.", [3]byte{100, 75, 240}: "CalDigit, Inc", [3]byte{100, 77, 112}: "dSPACE GmbH", + [3]byte{100, 79, 66}: "JETTER CO., Ltd.", [3]byte{100, 79, 116}: "LENUS Co., Ltd.", [3]byte{100, 79, 176}: "Hyunjin.com", [3]byte{100, 81, 6}: "Hewlett Packard", @@ -17182,14 +17765,18 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{100, 85, 127}: "NSFOCUS Information Technology Co., Ltd.", [3]byte{100, 85, 177}: "ARRIS Group, Inc.", [3]byte{100, 86, 1}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{100, 88, 173}: "China Mobile IOT Company Limited", [3]byte{100, 89, 248}: "Vodafone Omnitel B.V.", [3]byte{100, 90, 4}: "Chicony Electronics Co., Ltd.", + [3]byte{100, 90, 237}: "Apple, Inc.", + [3]byte{100, 93, 134}: "Intel Corporate", [3]byte{100, 93, 146}: "SICHUAN TIANYI COMHEART TELECOMCO.,LTD", [3]byte{100, 93, 215}: "Shenzhen Lifesense Medical Electronics Co., Ltd.", [3]byte{100, 94, 190}: "Yahoo! JAPAN", [3]byte{100, 95, 255}: "Nicolet Neuro", [3]byte{100, 97, 132}: "VELUX", [3]byte{100, 98, 35}: "Cellient Co., Ltd.", + [3]byte{100, 98, 138}: "evon GmbH", [3]byte{100, 100, 155}: "Juniper Networks", [3]byte{100, 101, 192}: "Nuvon, Inc", [3]byte{100, 102, 179}: "TP-LINK TECHNOLOGIES CO.,LTD.", @@ -17199,10 +17786,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{100, 106, 82}: "Avaya Inc", [3]byte{100, 106, 116}: "AUTH-SERVERS, LLC", [3]byte{100, 108, 178}: "Samsung Electronics Co.,Ltd", + [3]byte{100, 109, 108}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{100, 110, 105}: "Liteon Technology Corporation", [3]byte{100, 110, 108}: "Radio Datacom LLC", [3]byte{100, 110, 234}: "Iskratel d.o.o.", [3]byte{100, 112, 2}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{100, 112, 51}: "Apple, Inc.", [3]byte{100, 114, 216}: "GooWi Technology Co.,Limited", [3]byte{100, 115, 226}: "Arbiter Systems, Inc.", [3]byte{100, 116, 246}: "Shooter Detection Systems", @@ -17211,6 +17800,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{100, 119, 125}: "Hitron Technologies. Inc", [3]byte{100, 119, 145}: "Samsung Electronics Co.,Ltd", [3]byte{100, 121, 167}: "Phison Electronics Corp.", + [3]byte{100, 123, 206}: "Samsung Electronics Co.,Ltd", [3]byte{100, 123, 212}: "Texas Instruments", [3]byte{100, 124, 52}: "Ubee Interactive Co., Limited", [3]byte{100, 125, 129}: "YOKOTA INDUSTRIAL CO,.LTD", @@ -17223,6 +17813,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{100, 136, 255}: "Sichuan Changhong Electric Ltd.", [3]byte{100, 137, 154}: "LG Electronics (Mobile Communications)", [3]byte{100, 141, 158}: "IVT Electronic Co.,Ltd", + [3]byte{100, 152, 41}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{100, 153, 93}: "LGE", [3]byte{100, 153, 104}: "Elentec", [3]byte{100, 153, 160}: "AG Elektronik AB", @@ -17236,6 +17827,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{100, 159, 247}: "Kone OYj", [3]byte{100, 160, 231}: "Cisco Systems, Inc", [3]byte{100, 162, 50}: "OOO Samlight", + [3]byte{100, 162, 249}: "OnePlus Technology (Shenzhen) Co., Ltd", [3]byte{100, 163, 65}: "Wonderlan (Beijing) Technology Co., Ltd.", [3]byte{100, 163, 203}: "Apple, Inc.", [3]byte{100, 165, 195}: "Apple, Inc.", @@ -17259,10 +17851,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{100, 188, 12}: "LG Electronics (Mobile Communications)", [3]byte{100, 188, 17}: "CombiQ AB", [3]byte{100, 195, 84}: "Avaya Inc", + [3]byte{100, 195, 214}: "Juniper Networks", [3]byte{100, 197, 170}: "South African Broadcasting Corporation", [3]byte{100, 198, 103}: "Barnes&Noble", [3]byte{100, 198, 175}: "AXERRA Networks Ltd", + [3]byte{100, 199, 83}: "Apple, Inc.", [3]byte{100, 201, 68}: "LARK Technologies, Inc", + [3]byte{100, 203, 93}: "SIA TeleSet", [3]byte{100, 203, 163}: "Pointmobile", [3]byte{100, 204, 46}: "Xiaomi Communications Co Ltd", [3]byte{100, 207, 217}: "Texas Instruments", @@ -17280,6 +17875,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{100, 219, 24}: "OpenPattern", [3]byte{100, 219, 67}: "Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.", [3]byte{100, 219, 129}: "Syszone Co., Ltd.", + [3]byte{100, 219, 139}: "Hangzhou Hikvision Digital Technology Co.,Ltd.", [3]byte{100, 219, 160}: "Select Comfort", [3]byte{100, 220, 1}: "Static Systems Group PLC", [3]byte{100, 222, 28}: "Kingnetic Pte Ltd", @@ -17296,9 +17892,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{100, 235, 140}: "Seiko Epson Corporation", [3]byte{100, 237, 87}: "ARRIS Group, Inc.", [3]byte{100, 237, 98}: "WOORI SYSTEMS Co., Ltd", + [3]byte{100, 238, 183}: "Netcore Technology Inc", [3]byte{100, 242, 66}: "Gerdes Aktiengesellschaft", [3]byte{100, 245, 14}: "Kinion Technology Company Limited", [3]byte{100, 246, 157}: "Cisco Systems, Inc", + [3]byte{100, 248, 28}: "Huawei Technologies Co., Ltd.", [3]byte{100, 248, 138}: "China Mobile IOT Company Limited", [3]byte{100, 249, 112}: "Kenade Electronics Technology Co.,LTD.", [3]byte{100, 249, 135}: "Avvasi Inc.", @@ -17331,17 +17929,23 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{104, 39, 55}: "Samsung Electronics Co.,Ltd", [3]byte{104, 40, 186}: "Dejai", [3]byte{104, 40, 246}: "Vubiq Networks, Inc.", + [3]byte{104, 41, 220}: "Ficosa Electronics S.L.U.", + [3]byte{104, 44, 123}: "Cisco Systems, Inc", [3]byte{104, 45, 220}: "Wuhan Changjiang Electro-Communication Equipment CO.,LTD", [3]byte{104, 49, 254}: "Teladin Co.,Ltd.", [3]byte{104, 53, 99}: "SHENZHEN LIOWN ELECTRONICS CO.,LTD.", [3]byte{104, 54, 181}: "DriveScale, Inc.", [3]byte{104, 55, 233}: "Amazon Technologies Inc.", + [3]byte{104, 58, 30}: "Cisco Meraki", [3]byte{104, 59, 30}: "Countwise LTD", [3]byte{104, 60, 125}: "Magic Intelligence Technology Limited", [3]byte{104, 62, 2}: "SIEMENS AG, Digital Factory, Motion Control System", [3]byte{104, 62, 52}: "MEIZU Technology Co., Ltd.", [3]byte{104, 62, 236}: "ERECA", [3]byte{104, 67, 82}: "Bhuu Limited", + [3]byte{104, 67, 215}: "Agilecom Photonics Solutions Guangdong Limited", + [3]byte{104, 69, 241}: "TOSHIBA CLIENT SOLUTIONS CO., LTD.", + [3]byte{104, 71, 73}: "Texas Instruments", [3]byte{104, 72, 152}: "Samsung Electronics Co.,Ltd", [3]byte{104, 75, 136}: "Galtronics Telemetry Inc.", [3]byte{104, 76, 168}: "Shenzhen Herotel Tech. Co., Ltd.", @@ -17352,8 +17956,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{104, 84, 237}: "Alcatel-Lucent", [3]byte{104, 84, 245}: "enLighted Inc", [3]byte{104, 84, 253}: "Amazon Technologies Inc.", + [3]byte{104, 87, 45}: "HANGZHOU AIXIANGJI TECHNOLOGY CO., LTD", [3]byte{104, 88, 197}: "ZF TRW Automotive", [3]byte{104, 89, 127}: "Alcatel Lucent", + [3]byte{104, 90, 207}: "Samsung Electronics Co.,Ltd", [3]byte{104, 91, 53}: "Apple, Inc.", [3]byte{104, 91, 54}: "POWERTECH INDUSTRIAL CO., LTD.", [3]byte{104, 93, 67}: "Intel Corporate", @@ -17367,7 +17973,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{104, 110, 72}: "Prophet Electronic Technology Corp.,Ltd", [3]byte{104, 114, 81}: "Ubiquiti Networks Inc.", [3]byte{104, 114, 220}: "CETORY.TV Company Limited", - [3]byte{104, 118, 79}: "Sony Mobile Communications AB", + [3]byte{104, 118, 79}: "Sony Mobile Communications Inc", [3]byte{104, 120, 72}: "Westunitis Co., Ltd.", [3]byte{104, 120, 76}: "Nortel Networks", [3]byte{104, 121, 36}: "ELS-GmbH & Co. KG", @@ -17382,10 +17988,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{104, 134, 167}: "Cisco Systems, Inc", [3]byte{104, 134, 231}: "Orbotix, Inc.", [3]byte{104, 135, 107}: "INQ Mobile Limited", + [3]byte{104, 137, 117}: "nuoxc", [3]byte{104, 137, 193}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{104, 138, 181}: "EDP Servicos", [3]byte{104, 138, 240}: "zte corporation", [3]byte{104, 141, 182}: "AETEK INC.", + [3]byte{104, 143, 46}: "Hitron Technologies. Inc", [3]byte{104, 143, 132}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{104, 145, 208}: "IEEE Registration Authority", [3]byte{104, 146, 52}: "Ruckus Wireless", @@ -17394,6 +18002,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{104, 150, 123}: "Apple, Inc.", [3]byte{104, 151, 75}: "Shenzhen Costar Electronics Co. Ltd.", [3]byte{104, 151, 232}: "Society of Motion Picture & Television Engineers", + [3]byte{104, 152, 97}: "Beacon Inc", [3]byte{104, 153, 205}: "Cisco Systems, Inc", [3]byte{104, 154, 183}: "Atelier Vision Corporation", [3]byte{104, 156, 94}: "AcSiP Technology Corp.", @@ -17406,10 +18015,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{104, 163, 120}: "FREEBOX SAS", [3]byte{104, 163, 196}: "Liteon Technology Corporation", [3]byte{104, 164, 14}: "BSH Hausgeräte GmbH", + [3]byte{104, 164, 125}: "Sun Cupid Technology (HK) LTD", [3]byte{104, 166, 130}: "Shenzhen YOUHUA Technology Co., Ltd", [3]byte{104, 168, 40}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{104, 168, 109}: "Apple, Inc.", + [3]byte{104, 168, 225}: "Wacom Co.,Ltd.", [3]byte{104, 170, 210}: "DATECS LTD.,", + [3]byte{104, 171, 30}: "Apple, Inc.", [3]byte{104, 171, 138}: "RF IDeas", [3]byte{104, 174, 32}: "Apple, Inc.", [3]byte{104, 175, 19}: "Futura Mobility", @@ -17426,12 +18038,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{104, 198, 58}: "Espressif Inc.", [3]byte{104, 201, 11}: "Texas Instruments", [3]byte{104, 202, 0}: "Octopus Systems Limited", + [3]byte{104, 202, 228}: "Cisco Systems, Inc", [3]byte{104, 204, 110}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{104, 204, 156}: "Mine Site Technologies", [3]byte{104, 205, 15}: "U Tek Company Limited", [3]byte{104, 206, 78}: "L-3 Communications Infrared Products", + [3]byte{104, 209, 186}: "Shenzhen YOUHUA Technology Co., Ltd", [3]byte{104, 209, 253}: "Shenzhen Trimax Technology Co.,Ltd", [3]byte{104, 210, 71}: "Portalis LC", + [3]byte{104, 212, 130}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", [3]byte{104, 217, 37}: "ProSys Development Services", [3]byte{104, 217, 60}: "Apple, Inc.", [3]byte{104, 219, 84}: "Phicomm (Shanghai) Co., Ltd.", @@ -17439,9 +18054,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{104, 219, 150}: "OPWILL Technologies CO .,LTD", [3]byte{104, 219, 202}: "Apple, Inc.", [3]byte{104, 220, 232}: "PacketStorm Communications", + [3]byte{104, 221, 38}: "Shanghai Focus Vision Security Technology Co.,Ltd", [3]byte{104, 223, 221}: "Xiaomi Communications Co Ltd", [3]byte{104, 225, 102}: "Private", [3]byte{104, 228, 31}: "Unglaube Identech GmbH", + [3]byte{104, 231, 194}: "Samsung Electronics Co.,Ltd", [3]byte{104, 232, 235}: "Linktel Technologies Co.,Ltd", [3]byte{104, 235, 174}: "Samsung Electronics Co.,Ltd", [3]byte{104, 235, 197}: "Angstrem Telecom", @@ -17450,6 +18067,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{104, 237, 67}: "BlackBerry RTS", [3]byte{104, 237, 164}: "Shenzhen Seavo Technology Co.,Ltd", [3]byte{104, 238, 150}: "Cisco SPVTG", + [3]byte{104, 239, 67}: "Apple, Inc.", [3]byte{104, 239, 189}: "Cisco Systems, Inc", [3]byte{104, 240, 109}: "ALONG INDUSTRIAL CO., LIMITED", [3]byte{104, 240, 188}: "Shenzhen LiWiFi Technology Co., Ltd", @@ -17460,13 +18078,16 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{104, 251, 126}: "Apple, Inc.", [3]byte{104, 251, 149}: "Generalplus Technology Inc.", [3]byte{104, 252, 179}: "Next Level Security Systems, Inc.", + [3]byte{104, 254, 218}: "Fiberhome Telecommunication Technologies Co.,LTD", + [3]byte{104, 254, 247}: "Apple, Inc.", + [3]byte{108, 0, 107}: "Samsung Electronics Co.,Ltd", [3]byte{108, 2, 115}: "Shenzhen Jin Yun Video Equipment Co., Ltd.", [3]byte{108, 4, 96}: "RBH Access Technologies Inc.", [3]byte{108, 5, 213}: "Ethertronics Inc", [3]byte{108, 9, 10}: "GEMATICA SRL", [3]byte{108, 9, 214}: "Digiquest Electronics LTD", [3]byte{108, 11, 132}: "Universal Global Scientific Industrial Co., Ltd.", - [3]byte{108, 14, 13}: "Sony Mobile Communications AB", + [3]byte{108, 14, 13}: "Sony Mobile Communications Inc", [3]byte{108, 14, 230}: "Chengdu Xiyida Electronic Technology Co,.Ltd", [3]byte{108, 15, 106}: "JDC Tech Co., Ltd.", [3]byte{108, 20, 247}: "Erhardt+Leimer GmbH", @@ -17478,20 +18099,25 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{108, 30, 112}: "Guangzhou YBDS IT Co.,Ltd", [3]byte{108, 30, 144}: "Hansol Technics Co., Ltd.", [3]byte{108, 32, 86}: "Cisco Systems, Inc", + [3]byte{108, 33, 162}: "AMPAK Technology, Inc.", [3]byte{108, 34, 171}: "Ainsworth Game Technology", - [3]byte{108, 35, 185}: "Sony Mobile Communications AB", + [3]byte{108, 35, 185}: "Sony Mobile Communications Inc", [3]byte{108, 36, 131}: "Microsoft Mobile Oy", [3]byte{108, 37, 185}: "BBK EDUCATIONAL ELECTRONICS CORP.,LTD.", [3]byte{108, 39, 121}: "Microsoft Mobile Oy", [3]byte{108, 41, 149}: "Intel Corporate", [3]byte{108, 42, 203}: "Paxton Access Ltd", + [3]byte{108, 43, 89}: "Dell Inc.", [3]byte{108, 44, 6}: "OOO NPP Systemotechnika-NN", + [3]byte{108, 44, 220}: "Skyworth Digital Technology(Shenzhen) Co.,Ltd", [3]byte{108, 46, 51}: "Accelink Technologies Co.,Ltd.", [3]byte{108, 46, 114}: "B&B EXPORTING LIMITED", [3]byte{108, 46, 133}: "Sagemcom Broadband SAS", [3]byte{108, 47, 44}: "Samsung Electronics Co.,Ltd", [3]byte{108, 50, 222}: "Indieon Technologies Pvt. Ltd.", [3]byte{108, 51, 169}: "Magicjack LP", + [3]byte{108, 56, 56}: "Marking System Technology Co., Ltd.", + [3]byte{108, 56, 69}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{108, 56, 161}: "Ubee Interactive Co., Limited", [3]byte{108, 57, 29}: "Beijing ZhongHuaHun Network Information center", [3]byte{108, 58, 132}: "Shenzhen Aero-Startech. Co.Ltd", @@ -17509,15 +18135,18 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{108, 74, 57}: "BITA", [3]byte{108, 75, 127}: "Vossloh-Schwabe Deutschland GmbH", [3]byte{108, 75, 144}: "LiteON", + [3]byte{108, 77, 115}: "Apple, Inc.", [3]byte{108, 78, 134}: "Third Millennium Systems Ltd.", [3]byte{108, 80, 77}: "Cisco Systems, Inc", + [3]byte{108, 84, 205}: "LAMPEX ELECTRONICS LIMITED", [3]byte{108, 86, 151}: "Amazon Technologies Inc.", [3]byte{108, 87, 121}: "Aclima, Inc.", - [3]byte{108, 89, 64}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", + [3]byte{108, 89, 64}: "MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", [3]byte{108, 89, 118}: "Shanghai Tricheer Technology Co.,Ltd.", [3]byte{108, 90, 52}: "Shenzhen Haitianxiong Electronic Co., Ltd.", [3]byte{108, 90, 181}: "TCL Technoly Electronics (Huizhou) Co., Ltd.", [3]byte{108, 92, 20}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", + [3]byte{108, 92, 61}: "IEEE Registration Authority", [3]byte{108, 92, 222}: "SunReports, Inc.", [3]byte{108, 93, 99}: "ShenZhen Rapoo Technology Co., Ltd.", [3]byte{108, 94, 122}: "Ubiquitous Internet Telecom Co., Ltd", @@ -17526,6 +18155,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{108, 97, 38}: "Rinicom Holdings", [3]byte{108, 98, 109}: "Micro-Star INT'L CO., LTD", [3]byte{108, 100, 26}: "Penguin Computing", + [3]byte{108, 108, 211}: "Cisco Systems, Inc", [3]byte{108, 110, 254}: "Core Logic Inc.", [3]byte{108, 111, 24}: "Stereotaxis, Inc.", [3]byte{108, 112, 57}: "Novar GmbH", @@ -17556,6 +18186,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{108, 153, 137}: "Cisco Systems, Inc", [3]byte{108, 154, 201}: "Valentine Research, Inc.", [3]byte{108, 155, 2}: "Nokia Corporation", + [3]byte{108, 155, 192}: "Chemoptics Inc.", [3]byte{108, 156, 233}: "Nimble Storage", [3]byte{108, 156, 237}: "Cisco Systems, Inc", [3]byte{108, 161, 0}: "Intel Corporate", @@ -17566,6 +18197,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{108, 168, 73}: "Avaya Inc", [3]byte{108, 168, 88}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{108, 169, 6}: "Telefield Ltd", + [3]byte{108, 169, 40}: "HMD Global Oy", [3]byte{108, 169, 111}: "TransPacket AS", [3]byte{108, 170, 179}: "Ruckus Wireless", [3]byte{108, 171, 49}: "Apple, Inc.", @@ -17575,6 +18207,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{108, 173, 239}: "KZ Broadband Technologies, Ltd.", [3]byte{108, 173, 248}: "AzureWave Technology Inc.", [3]byte{108, 174, 139}: "IBM Corporation", + [3]byte{108, 175, 21}: "Webasto SE", [3]byte{108, 176, 206}: "NETGEAR", [3]byte{108, 178, 39}: "Sony Video & Sound Products Inc.", [3]byte{108, 178, 174}: "Cisco Systems, Inc", @@ -17582,6 +18215,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{108, 179, 80}: "Anhui comhigher tech co.,ltd", [3]byte{108, 180, 167}: "Landauer, Inc.", [3]byte{108, 181, 107}: "HUMAX Co., Ltd.", + [3]byte{108, 182, 202}: "DIVUS GmbH", [3]byte{108, 183, 73}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{108, 183, 244}: "Samsung Electronics Co.,Ltd", [3]byte{108, 185, 197}: "Delta Networks, Inc.", @@ -17591,6 +18225,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{108, 193, 210}: "ARRIS Group, Inc.", [3]byte{108, 194, 23}: "Hewlett Packard", [3]byte{108, 194, 107}: "Apple, Inc.", + [3]byte{108, 195, 116}: "Texas Instruments", + [3]byte{108, 196, 213}: "HMD Global Oy", + [3]byte{108, 199, 236}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", [3]byte{108, 202, 8}: "ARRIS Group, Inc.", [3]byte{108, 208, 50}: "LG Electronics", [3]byte{108, 209, 70}: "Smartek d.o.o.", @@ -17598,10 +18235,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{108, 214, 138}: "LG Electronics (Mobile Communications)", [3]byte{108, 220, 106}: "Promethean Limited", [3]byte{108, 221, 48}: "Cisco Systems, Inc", + [3]byte{108, 223, 251}: "IEEE Registration Authority", [3]byte{108, 224, 30}: "Modcam AB", [3]byte{108, 224, 176}: "SOUND4", [3]byte{108, 227, 182}: "Nera Telecommunications Ltd.", [3]byte{108, 228, 206}: "Villiger Security Solutions AG", + [3]byte{108, 228, 218}: "NEC Platforms, Ltd.", + [3]byte{108, 232, 92}: "Apple, Inc.", [3]byte{108, 232, 115}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{108, 233, 7}: "Nokia Corporation", [3]byte{108, 233, 131}: "Gastron Co., LTD.", @@ -17609,22 +18249,29 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{108, 236, 90}: "Hon Hai Precision Ind. CO.,Ltd.", [3]byte{108, 236, 161}: "SHENZHEN CLOU ELECTRONICS CO. LTD.", [3]byte{108, 236, 235}: "Texas Instruments", + [3]byte{108, 237, 81}: "NEXCONTROL Co.,Ltd", [3]byte{108, 239, 198}: "SHENZHEN TWOWING TECHNOLOGIES CO.,LTD.", [3]byte{108, 240, 73}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", [3]byte{108, 243, 115}: "Samsung Electronics Co.,Ltd", [3]byte{108, 243, 127}: "Aruba Networks", [3]byte{108, 245, 232}: "Mooredoll Inc.", [3]byte{108, 249, 124}: "Nanoptix Inc.", - [3]byte{108, 249, 210}: "Chengdu Goods for the Road Electronic Technology C", + [3]byte{108, 249, 210}: "CHENGDU POVODO ELECTRONIC TECHNOLOGY CO., LTD", [3]byte{108, 250, 88}: "Avaya Inc", [3]byte{108, 250, 137}: "Cisco Systems, Inc", [3]byte{108, 250, 167}: "AMPAK Technology, Inc.", [3]byte{108, 253, 185}: "Proware Technologies Co Ltd.", [3]byte{108, 255, 190}: "MPB Communications Inc.", [3]byte{112, 1, 54}: "FATEK Automation Corporation", + [3]byte{112, 1, 181}: "Cisco Systems, Inc", [3]byte{112, 2, 88}: "01DB-METRAVIB", + [3]byte{112, 3, 126}: "Technicolor CH USA Inc.", [3]byte{112, 5, 20}: "LG Electronics (Mobile Communications)", + [3]byte{112, 6, 172}: "Eastcompeace Technology Co., Ltd", + [3]byte{112, 11, 1}: "Sagemcom Broadband SAS", + [3]byte{112, 11, 79}: "Cisco Systems, Inc", [3]byte{112, 11, 192}: "Dewav Technology Company", + [3]byte{112, 15, 106}: "Cisco Systems, Inc", [3]byte{112, 15, 199}: "SHENZHEN IKINLOOP TECHNOLOGY CO.,LTD.", [3]byte{112, 15, 236}: "Poindus Systems Corp.", [3]byte{112, 16, 92}: "Cisco Systems, Inc", @@ -17633,10 +18280,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{112, 17, 174}: "Music Life LTD", [3]byte{112, 20, 4}: "Limited Liability Company", [3]byte{112, 20, 166}: "Apple, Inc.", + [3]byte{112, 22, 159}: "EtherCAT Technology Group", [3]byte{112, 24, 139}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{112, 25, 47}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{112, 26, 4}: "Liteon Technology Corporation", [3]byte{112, 26, 237}: "ADVAS CO., LTD.", [3]byte{112, 28, 231}: "Intel Corporate", + [3]byte{112, 29, 8}: "99IOT Shenzhen co.,ltd", [3]byte{112, 29, 127}: "Comtech Technology Co., Ltd.", [3]byte{112, 29, 196}: "NorthStar Battery Company, LLC", [3]byte{112, 31, 83}: "Cisco Systems, Inc", @@ -17648,11 +18298,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{112, 40, 139}: "Samsung Electronics Co.,Ltd", [3]byte{112, 41, 0}: "Shenzhen ChipTrip Technology Co,Ltd", [3]byte{112, 42, 125}: "EpSpot AB", + [3]byte{112, 42, 213}: "Samsung Electronics Co.,Ltd", [3]byte{112, 43, 29}: "E-Domus International Limited", [3]byte{112, 44, 31}: "Wisol", [3]byte{112, 45, 132}: "i4C Innovations", [3]byte{112, 45, 209}: "Newings Communication CO., LTD.", [3]byte{112, 46, 34}: "zte corporation", + [3]byte{112, 46, 217}: "Guangzhou Shiyuan Electronics Co., Ltd.", [3]byte{112, 47, 75}: "PolyVision Inc.", [3]byte{112, 47, 151}: "Aava Mobile Oy", [3]byte{112, 48, 24}: "Avaya Inc", @@ -17660,10 +18312,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{112, 48, 94}: "Nanjing Zhongke Menglian Information Technology Co.,LTD", [3]byte{112, 49, 135}: "ACX GmbH", [3]byte{112, 50, 213}: "Athena Wireless Communications Inc", + [3]byte{112, 53, 9}: "Cisco Systems, Inc", [3]byte{112, 56, 17}: "Invensys Rail", [3]byte{112, 56, 180}: "Low Tech Solutions", [3]byte{112, 56, 238}: "Avaya Inc", [3]byte{112, 58, 14}: "Aruba Networks", + [3]byte{112, 58, 81}: "Xiaomi Communications Co Ltd", + [3]byte{112, 58, 115}: "Shenzhen Sundray Technologies Company Limited", [3]byte{112, 58, 203}: "Google, Inc.", [3]byte{112, 58, 216}: "Shenzhen Afoundry Electronic Co., Ltd", [3]byte{112, 60, 3}: "RadiAnt Co.,Ltd", @@ -17681,12 +18336,16 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{112, 77, 123}: "ASUSTek COMPUTER INC.", [3]byte{112, 78, 1}: "KWANGWON TECH CO., LTD.", [3]byte{112, 78, 102}: "SHENZHEN FAST TECHNOLOGIES CO.,LTD", + [3]byte{112, 79, 8}: "Shenzhen Huisheng Information Technology Co., Ltd.", [3]byte{112, 79, 87}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{112, 79, 184}: "ARRIS Group, Inc.", [3]byte{112, 80, 175}: "BSkyB Ltd", [3]byte{112, 82, 197}: "Avaya Inc", [3]byte{112, 83, 63}: "Alfa Instrumentos Eletronicos Ltda.", + [3]byte{112, 84, 180}: "Vestel Elektronik San ve Tic. A.Ş.", [3]byte{112, 84, 210}: "PEGATRON CORPORATION", [3]byte{112, 84, 245}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{112, 85, 248}: "Cerebras Systems Inc", [3]byte{112, 86, 129}: "Apple, Inc.", [3]byte{112, 88, 18}: "Panasonic Corporation AVC Networks Company", [3]byte{112, 88, 150}: "InShow Technology", @@ -17694,9 +18353,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{112, 89, 134}: "OOO TTV", [3]byte{112, 90, 15}: "Hewlett Packard", [3]byte{112, 90, 158}: "Technicolor CH USA Inc.", + [3]byte{112, 90, 172}: "Samsung Electronics Co.,Ltd", [3]byte{112, 90, 182}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", [3]byte{112, 91, 46}: "M2Communication Inc.", [3]byte{112, 92, 173}: "Konami Gaming Inc", + [3]byte{112, 93, 204}: "EFM Networks", [3]byte{112, 94, 170}: "Action Target, Inc.", [3]byte{112, 96, 222}: "LaVision GmbH", [3]byte{112, 97, 115}: "Calantec GmbH", @@ -17706,7 +18367,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{112, 101, 163}: "Kandao lightforge Co., Ltd.", [3]byte{112, 102, 27}: "Sonova AG", [3]byte{112, 104, 121}: "Saijo Denki International Co., Ltd.", + [3]byte{112, 105, 90}: "Cisco Systems, Inc", [3]byte{112, 107, 185}: "Cisco Systems, Inc", + [3]byte{112, 109, 21}: "Cisco Systems, Inc", [3]byte{112, 109, 236}: "Wifi-soft LLC", [3]byte{112, 110, 109}: "Cisco Systems, Inc", [3]byte{112, 111, 129}: "Private", @@ -17727,6 +18390,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{112, 120, 139}: "vivo Mobile Communication Co., Ltd.", [3]byte{112, 121, 56}: "Wuxi Zhanrui Electronic Technology Co.,LTD", [3]byte{112, 121, 144}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{112, 121, 179}: "Cisco Systems, Inc", [3]byte{112, 123, 232}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{112, 124, 24}: "ADATA Technology Co., Ltd", [3]byte{112, 124, 105}: "Avaya Inc", @@ -17742,6 +18406,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{112, 133, 198}: "ARRIS Group, Inc.", [3]byte{112, 134, 193}: "Texas Instruments", [3]byte{112, 136, 77}: "JAPAN RADIO CO., LTD.", + [3]byte{112, 137, 204}: "China Mobile Group Device Co.,Ltd.", [3]byte{112, 138, 9}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{112, 139, 120}: "citygrow technology co., ltd", [3]byte{112, 139, 205}: "ASUSTek COMPUTER INC.", @@ -17759,6 +18424,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{112, 158, 41}: "Sony Interactive Entertainment Inc.", [3]byte{112, 158, 134}: "X6D Limited", [3]byte{112, 159, 45}: "zte corporation", + [3]byte{112, 159, 169}: "TECNO MOBILE LIMITED", [3]byte{112, 161, 145}: "Trendsetter Medical, LLC", [3]byte{112, 162, 179}: "Apple, Inc.", [3]byte{112, 164, 28}: "Advanced Wireless Dynamics S.L.", @@ -17774,17 +18440,24 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{112, 176, 140}: "Shenou Communication Equipment Co.,Ltd", [3]byte{112, 177, 78}: "ARRIS Group, Inc.", [3]byte{112, 178, 101}: "Hiltron s.r.l.", + [3]byte{112, 179, 23}: "Cisco Systems, Inc", [3]byte{112, 179, 213}: "IEEE Registration Authority", [3]byte{112, 181, 153}: "Embedded Technologies s.r.o.", + [3]byte{112, 183, 170}: "vivo Mobile Communication Co., Ltd.", [3]byte{112, 183, 226}: "Jiangsu Miter Technology Co.,Ltd.", [3]byte{112, 185, 33}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{112, 186, 239}: "Hangzhou H3C Technologies Co., Limited", + [3]byte{112, 187, 233}: "Xiaomi Communications Co Ltd", [3]byte{112, 191, 62}: "Charles River Laboratories", [3]byte{112, 198, 172}: "Bosch Automotive Aftermarket", [3]byte{112, 199, 111}: "INNO S", + [3]byte{112, 200, 51}: "Wirepas Oy", + [3]byte{112, 201, 78}: "Liteon Technology Corporation", [3]byte{112, 202, 77}: "Shenzhen lnovance Technology Co.,Ltd.", [3]byte{112, 202, 155}: "Cisco Systems, Inc", [3]byte{112, 205, 96}: "Apple, Inc.", + [3]byte{112, 208, 129}: "Beijing Netpower Technologies Inc.", + [3]byte{112, 211, 19}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{112, 211, 121}: "Cisco Systems, Inc", [3]byte{112, 212, 242}: "RIM", [3]byte{112, 213, 126}: "Scalar Corporation", @@ -17811,24 +18484,29 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{112, 236, 228}: "Apple, Inc.", [3]byte{112, 238, 80}: "Netatmo", [3]byte{112, 238, 163}: "Eoptolink Technology Inc. Ltd,", + [3]byte{112, 239, 0}: "Apple, Inc.", [3]byte{112, 240, 135}: "Apple, Inc.", [3]byte{112, 241, 28}: "Shenzhen Ogemray Technology Co.,Ltd", [3]byte{112, 241, 118}: "Data Modul AG", [3]byte{112, 241, 150}: "Actiontec Electronics, Inc", [3]byte{112, 241, 161}: "Liteon Technology Corporation", [3]byte{112, 241, 229}: "Xetawave LLC", + [3]byte{112, 242, 32}: "Actiontec Electronics, Inc", [3]byte{112, 243, 90}: "Cisco Systems, Inc", [3]byte{112, 243, 149}: "Universal Global Scientific Industrial Co., Ltd.", [3]byte{112, 248, 231}: "IEEE Registration Authority", [3]byte{112, 249, 39}: "Samsung Electronics Co.,Ltd", [3]byte{112, 249, 109}: "Hangzhou H3C Technologies Co., Limited", [3]byte{112, 252, 140}: "OneAccess SA", + [3]byte{112, 253, 70}: "Samsung Electronics Co.,Ltd", [3]byte{112, 255, 92}: "Cheerzing Communication(Xiamen)Technology Co.,Ltd", [3]byte{112, 255, 118}: "Texas Instruments", [3]byte{116, 3, 189}: "BUFFALO.INC", [3]byte{116, 4, 43}: "Lenovo Mobile Communication (Wuhan) Company Limited", + [3]byte{116, 5, 165}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{116, 10, 188}: "LightwaveRF Technology Ltd", [3]byte{116, 14, 219}: "Optowiz Co., Ltd", + [3]byte{116, 18, 187}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{116, 20, 137}: "SRT Wireless", [3]byte{116, 21, 226}: "Tri-Sen Systems Corporation", [3]byte{116, 24, 101}: "Shanghai DareGlobal Technologies Co.,Ltd", @@ -17838,6 +18516,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{116, 28, 39}: "ITEL MOBILE LIMITED", [3]byte{116, 30, 147}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{116, 31, 74}: "Hangzhou H3C Technologies Co., Limited", + [3]byte{116, 31, 121}: "YOUNGKOOK ELECTRONICS CO.,LTD", [3]byte{116, 35, 68}: "Xiaomi Communications Co Ltd", [3]byte{116, 37, 138}: "Hangzhou H3C Technologies Co., Limited", [3]byte{116, 38, 172}: "Cisco Systems, Inc", @@ -17852,12 +18531,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{116, 47, 104}: "AzureWave Technology Inc.", [3]byte{116, 49, 112}: "Arcadyan Technology Corporation", [3]byte{116, 50, 86}: "NT-ware Systemprg GmbH", + [3]byte{116, 52, 0}: "MTG Co., Ltd.", + [3]byte{116, 54, 109}: "Vodafone Italia S.p.A.", [3]byte{116, 55, 47}: "Tongfang Shenzhen Cloudcomputing Technology Co.,Ltd", [3]byte{116, 55, 59}: "UNINET Co.,Ltd.", [3]byte{116, 56, 137}: "ANNAX Anzeigesysteme GmbH", [3]byte{116, 58, 101}: "NEC Corporation", [3]byte{116, 62, 43}: "Ruckus Wireless", [3]byte{116, 62, 203}: "Gentrice tech", + [3]byte{116, 64, 187}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{116, 68, 1}: "NETGEAR", [3]byte{116, 69, 138}: "Samsung Electronics Co.,Ltd", [3]byte{116, 70, 160}: "Hewlett Packard", @@ -17870,11 +18552,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{116, 84, 125}: "Cisco SPVTG", [3]byte{116, 86, 18}: "ARRIS Group, Inc.", [3]byte{116, 87, 152}: "TRUMPF Laser GmbH + Co. KG", + [3]byte{116, 89, 51}: "Danal Entertainment", [3]byte{116, 90, 170}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{116, 92, 75}: "GN Audio A/S", [3]byte{116, 92, 159}: "TCT mobile ltd", [3]byte{116, 94, 28}: "PIONEER CORPORATION", [3]byte{116, 95, 0}: "Samsung Semiconductor Inc.", + [3]byte{116, 95, 144}: "LAM Technologies", [3]byte{116, 95, 174}: "TSL PPL", [3]byte{116, 97, 75}: "Chongqing Huijiatong Information Technology Co., Ltd.", [3]byte{116, 99, 223}: "VTS GmbH", @@ -17885,10 +18569,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{116, 106, 137}: "Rezolt Corporation", [3]byte{116, 106, 143}: "VS Vision Systems GmbH", [3]byte{116, 107, 130}: "MOVEK", + [3]byte{116, 107, 171}: "GUANGDONG ENOK COMMUNICATION CO., LTD", [3]byte{116, 110, 228}: "Asia Vital Components Co.,Ltd.", [3]byte{116, 111, 25}: "ICARVISIONS (SHENZHEN) TECHNOLOGY CO., LTD.", [3]byte{116, 111, 61}: "Contec GmbH", [3]byte{116, 111, 247}: "Wistron Neweb Corporation", + [3]byte{116, 112, 253}: "Intel Corporate", + [3]byte{116, 114, 30}: "Edison Labs Inc.", [3]byte{116, 114, 176}: "Guangzhou Shiyuan Electronics Co., Ltd.", [3]byte{116, 114, 242}: "Chipsip Technology Co., Ltd.", [3]byte{116, 115, 54}: "MICRODIGTAL Inc", @@ -17901,13 +18588,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{116, 126, 45}: "Beijing Thomson CITIC Digital Technology Co. LTD.", [3]byte{116, 129, 20}: "Apple, Inc.", [3]byte{116, 129, 154}: "PT. Hartono Istana Teknologi", + [3]byte{116, 131, 194}: "Ubiquiti Networks Inc.", [3]byte{116, 131, 239}: "Arista Networks", [3]byte{116, 133, 42}: "PEGATRON CORPORATION", + [3]byte{116, 133, 196}: "New H3C Technologies Co., Ltd", [3]byte{116, 134, 11}: "Cisco Systems, Inc", [3]byte{116, 134, 122}: "Dell Inc.", [3]byte{116, 135, 169}: "OCT Technology Co., Ltd.", + [3]byte{116, 135, 187}: "Ciena Corporation", [3]byte{116, 136, 42}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{116, 136, 139}: "ADB Broadband Italia", + [3]byte{116, 138, 13}: "ARRIS Group, Inc.", [3]byte{116, 138, 105}: "Korea Image Technology Co., Ltd", [3]byte{116, 141, 8}: "Apple, Inc.", [3]byte{116, 142, 8}: "Bestek Corp.", @@ -17925,8 +18616,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{116, 153, 117}: "IBM Corporation", [3]byte{116, 156, 82}: "Huizhou Desay SV Automotive Co., Ltd.", [3]byte{116, 156, 227}: "KodaCloud Canada, Inc", + [3]byte{116, 157, 121}: "Sercomm Corporation.", [3]byte{116, 157, 143}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{116, 157, 220}: "2Wire Inc", + [3]byte{116, 158, 175}: "Apple, Inc.", [3]byte{116, 160, 47}: "Cisco Systems, Inc", [3]byte{116, 160, 99}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{116, 162, 230}: "Cisco Systems, Inc", @@ -17942,12 +18635,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{116, 176, 12}: "Network Video Technologies, Inc", [3]byte{116, 180, 114}: "CIESSE", [3]byte{116, 181, 126}: "zte corporation", + [3]byte{116, 181, 135}: "Apple, Inc.", + [3]byte{116, 185, 30}: "Nanjing Bestway Automation System Co., Ltd", [3]byte{116, 185, 235}: "JinQianMao Technology Co.,Ltd.", [3]byte{116, 186, 219}: "Longconn Electornics(shenzhen)Co.,Ltd", [3]byte{116, 187, 211}: "Shenzhen xeme Communication Co., Ltd.", [3]byte{116, 190, 8}: "ATEK Products, LLC", [3]byte{116, 191, 161}: "HYUNTECK", [3]byte{116, 191, 183}: "Nusoft Corporation", + [3]byte{116, 191, 192}: "CANON INC.", + [3]byte{116, 193, 79}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{116, 193, 125}: "Infinix mobility limited", [3]byte{116, 194, 70}: "Amazon Technologies Inc.", [3]byte{116, 195, 48}: "SHENZHEN FAST TECHNOLOGIES CO.,LTD", [3]byte{116, 198, 33}: "Zhejiang Hite Renewable Energy Co.,LTD", @@ -17974,6 +18672,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{116, 223, 191}: "Liteon Technology Corporation", [3]byte{116, 224, 110}: "Ergophone GmbH", [3]byte{116, 225, 74}: "IEEE Registration Authority", + [3]byte{116, 225, 130}: "Texas Instruments", [3]byte{116, 225, 154}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{116, 225, 182}: "Apple, Inc.", [3]byte{116, 226, 119}: "Vizmonet Pte Ltd", @@ -17991,6 +18690,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{116, 234, 200}: "New H3C Technologies Co., Ltd", [3]byte{116, 234, 203}: "New H3C Technologies Co., Ltd", [3]byte{116, 234, 232}: "ARRIS Group, Inc.", + [3]byte{116, 235, 128}: "Samsung Electronics Co.,Ltd", + [3]byte{116, 236, 66}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{116, 236, 241}: "Acumen", [3]byte{116, 240, 109}: "AzureWave Technology Inc.", [3]byte{116, 240, 125}: "BnCOM Co.,Ltd", @@ -18000,6 +18701,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{116, 246, 28}: "HTC Corporation", [3]byte{116, 246, 97}: "Schneider Electric Fire & Security Oy", [3]byte{116, 247, 38}: "Neuron Robotics", + [3]byte{116, 247, 55}: "KCE", [3]byte{116, 248, 93}: "Berkeley Nucleonics Corp", [3]byte{116, 248, 219}: "IEEE Registration Authority", [3]byte{116, 249, 26}: "Onface", @@ -18012,10 +18714,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{120, 2, 177}: "Cisco Systems, Inc", [3]byte{120, 2, 183}: "ShenZhen Ultra Easy Technology CO.,LTD", [3]byte{120, 2, 248}: "Xiaomi Communications Co Ltd", + [3]byte{120, 4, 115}: "Texas Instruments", [3]byte{120, 5, 65}: "Queclink Wireless Solutions Co., Ltd", + [3]byte{120, 5, 95}: "Shenzhen WYC Technology Co., Ltd.", [3]byte{120, 7, 56}: "Z.U.K. Elzab S.A.", [3]byte{120, 10, 199}: "Baofeng TV Co., Ltd.", [3]byte{120, 12, 184}: "Intel Corporate", + [3]byte{120, 12, 240}: "Cisco Systems, Inc", + [3]byte{120, 14, 209}: "TRUMPF Werkzeugmaschinen GmbH+Co.KG", + [3]byte{120, 15, 119}: "HangZhou Gubei Electronics Technology Co.,Ltd", [3]byte{120, 17, 133}: "NBS Payment Solutions Inc.", [3]byte{120, 17, 220}: "XIAOMI Electronics,CO.,LTD", [3]byte{120, 18, 184}: "ORANTEK LIMITED", @@ -18023,26 +18730,33 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{120, 25, 46}: "NASCENT Technology", [3]byte{120, 25, 247}: "Juniper Networks", [3]byte{120, 28, 90}: "SHARP Corporation", + [3]byte{120, 29, 74}: "zte corporation", [3]byte{120, 29, 186}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{120, 29, 253}: "Jabil Inc", [3]byte{120, 31, 219}: "Samsung Electronics Co.,Ltd", [3]byte{120, 32, 121}: "ID Tech", [3]byte{120, 34, 61}: "Affirmed Networks", + [3]byte{120, 35, 39}: "Samsung Electronics Co.,Ltd", [3]byte{120, 35, 174}: "ARRIS Group, Inc.", [3]byte{120, 36, 175}: "ASUSTek COMPUTER INC.", [3]byte{120, 37, 68}: "Omnima Limited", + [3]byte{120, 37, 122}: "LEO Innovation Lab", [3]byte{120, 37, 173}: "Samsung Electronics Co.,Ltd", [3]byte{120, 40, 202}: "Sonos, Inc.", + [3]byte{120, 41, 237}: "ASKEY COMPUTER CORP", [3]byte{120, 43, 203}: "Dell Inc.", [3]byte{120, 45, 126}: "TRENDnet, Inc.", [3]byte{120, 46, 239}: "Nokia Corporation", + [3]byte{120, 47, 23}: "Xlab Co.,Ltd", [3]byte{120, 48, 59}: "Stephen Technologies Co.,Limited", [3]byte{120, 48, 225}: "UltraClenz, LLC", [3]byte{120, 49, 43}: "zte corporation", [3]byte{120, 49, 193}: "Apple, Inc.", [3]byte{120, 50, 27}: "D-Link International", [3]byte{120, 50, 79}: "Millennium Group, Inc.", + [3]byte{120, 53, 160}: "Zurn Industries LLC", [3]byte{120, 54, 144}: "Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd", + [3]byte{120, 54, 204}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{120, 58, 132}: "Apple, Inc.", [3]byte{120, 60, 227}: "Kai-EE", [3]byte{120, 61, 91}: "TELNET Redes Inteligentes S.A.", @@ -18057,6 +18771,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{120, 69, 196}: "Dell Inc.", [3]byte{120, 70, 196}: "DAEHAP HYPER-TECH", [3]byte{120, 71, 29}: "Samsung Electronics Co.,Ltd", + [3]byte{120, 71, 227}: "SICHUAN TIANYI COMHEART TELECOM CO.,LTD", [3]byte{120, 72, 89}: "Hewlett Packard", [3]byte{120, 73, 29}: "The Will-Burt Company", [3]byte{120, 75, 8}: "f.robotics acquisitions ltd", @@ -18064,17 +18779,21 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{120, 79, 67}: "Apple, Inc.", [3]byte{120, 81, 12}: "LiveU Ltd.", [3]byte{120, 82, 26}: "Samsung Electronics Co.,Ltd", + [3]byte{120, 82, 74}: "Ensenso GmbH", [3]byte{120, 82, 98}: "Shenzhen Hojy Software Co., Ltd.", + [3]byte{120, 83, 100}: "SHIFT GmbH", [3]byte{120, 83, 242}: "ROXTON Ltd.", [3]byte{120, 84, 46}: "D-Link International", [3]byte{120, 85, 23}: "SankyuElectronics", [3]byte{120, 87, 18}: "Mobile Integration Workgroup", + [3]byte{120, 88, 96}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{120, 88, 243}: "Vachen Co.,Ltd", [3]byte{120, 89, 62}: "RAFI GmbH & Co.KG", [3]byte{120, 89, 94}: "Samsung Electronics Co.,Ltd", [3]byte{120, 89, 104}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{120, 92, 40}: "Prime Motion Inc.", [3]byte{120, 92, 114}: "Hioso Technology Co., Ltd.", + [3]byte{120, 93, 200}: "LG Electronics", [3]byte{120, 95, 76}: "Argox Information Co., Ltd.", [3]byte{120, 97, 124}: "MITSUMI ELECTRIC CO.,LTD.", [3]byte{120, 98, 86}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -18085,9 +18804,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{120, 106, 137}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{120, 108, 28}: "Apple, Inc.", [3]byte{120, 109, 148}: "Palo Alto Networks", + [3]byte{120, 112, 82}: "Welotec GmbH", [3]byte{120, 113, 156}: "ARRIS Group, Inc.", + [3]byte{120, 114, 93}: "Cisco Systems, Inc", [3]byte{120, 123, 138}: "Apple, Inc.", [3]byte{120, 125, 72}: "ITEL MOBILE LIMITED", + [3]byte{120, 125, 83}: "Aerohive Networks Inc.", [3]byte{120, 126, 97}: "Apple, Inc.", [3]byte{120, 127, 98}: "GiK mbH", [3]byte{120, 128, 56}: "FUNAI ELECTRIC CO., LTD.", @@ -18102,7 +18824,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{120, 138, 32}: "Ubiquiti Networks Inc.", [3]byte{120, 139, 119}: "Standar Telecom", [3]byte{120, 140, 77}: "Indyme Solutions, LLC", - [3]byte{120, 140, 84}: "Eltek Technologies LTD", + [3]byte{120, 140, 84}: "Ping Communication", [3]byte{120, 141, 247}: "Hitron Technologies. Inc", [3]byte{120, 142, 51}: "Jiangsu SEUIC Technology Co.,Ltd", [3]byte{120, 146, 62}: "Nokia Corporation", @@ -18139,11 +18861,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{120, 172, 192}: "Hewlett Packard", [3]byte{120, 174, 12}: "Far South Networks", [3]byte{120, 175, 88}: "GIMASI SA", + [3]byte{120, 175, 228}: "Comau S.p.A", [3]byte{120, 178, 141}: "Beijing Tengling Technology CO.Ltd", [3]byte{120, 179, 185}: "ShangHai sunup lighting CO.,LTD", [3]byte{120, 179, 206}: "Elo touch solutions", [3]byte{120, 181, 210}: "Ever Treasure Industrial Limited", [3]byte{120, 182, 193}: "AOBO Telecom Co.,Ltd", + [3]byte{120, 182, 236}: "Scuf Gaming International LLC", [3]byte{120, 184, 26}: "INTER SALES A/S", [3]byte{120, 184, 75}: "SICHUAN TIANYI COMHEART TELECOMCO.,LTD", [3]byte{120, 186, 208}: "Shinybow Technology Co. Ltd.", @@ -18168,6 +18892,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{120, 205, 142}: "SMC Networks Inc", [3]byte{120, 208, 4}: "Neousys Technology Inc.", [3]byte{120, 209, 41}: "Vicos", + [3]byte{120, 210, 148}: "NETGEAR", [3]byte{120, 211, 79}: "Pace-O-Matic, Inc.", [3]byte{120, 211, 141}: "HONGKONG YUNLINK TECHNOLOGY LIMITED", [3]byte{120, 213, 181}: "NAVIELEKTRO KY", @@ -18178,6 +18903,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{120, 215, 95}: "Apple, Inc.", [3]byte{120, 216, 0}: "IEEE Registration Authority", [3]byte{120, 217, 159}: "NuCom HK Ltd.", + [3]byte{120, 218, 7}: "Zhejiang Tmall Technology Co., Ltd.", [3]byte{120, 218, 110}: "Cisco Systems, Inc", [3]byte{120, 218, 179}: "GBO Technology", [3]byte{120, 221, 8}: "Hon Hai Precision Ind. Co.,Ltd.", @@ -18203,6 +18929,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{120, 247, 208}: "Silverbrook Research", [3]byte{120, 248, 130}: "LG Electronics (Mobile Communications)", [3]byte{120, 249, 68}: "Private", + [3]byte{120, 249, 180}: "Nokia", [3]byte{120, 252, 20}: "Family Zone Cyber Safety Ltd", [3]byte{120, 253, 148}: "Apple, Inc.", [3]byte{120, 254, 61}: "Juniper Networks", @@ -18215,6 +18942,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{124, 1, 145}: "Apple, Inc.", [3]byte{124, 2, 188}: "Hansung Electronics Co. LTD", [3]byte{124, 3, 76}: "Sagemcom Broadband SAS", + [3]byte{124, 3, 171}: "Xiaomi Communications Co Ltd", [3]byte{124, 3, 201}: "Shenzhen YOUHUA Technology Co., Ltd", [3]byte{124, 3, 216}: "Sagemcom Broadband SAS", [3]byte{124, 4, 208}: "Apple, Inc.", @@ -18225,6 +18953,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{124, 9, 43}: "Bekey A/S", [3]byte{124, 10, 80}: "J-MEX Inc.", [3]byte{124, 11, 198}: "Samsung Electronics Co.,Ltd", + [3]byte{124, 12, 246}: "Guangdong Huiwei High-tech Co., Ltd.", [3]byte{124, 14, 206}: "Cisco Systems, Inc", [3]byte{124, 16, 21}: "Brilliant Home Technology, Inc.", [3]byte{124, 17, 190}: "Apple, Inc.", @@ -18243,12 +18972,16 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{124, 30, 179}: "2N TELEKOMUNIKACE a.s.", [3]byte{124, 32, 72}: "KoamTac", [3]byte{124, 32, 100}: "Alcatel-Lucent IPD", + [3]byte{124, 36, 12}: "Telechips, Inc.", + [3]byte{124, 37, 134}: "Juniper Networks", [3]byte{124, 37, 135}: "chaowifi.com", [3]byte{124, 38, 52}: "ARRIS Group, Inc.", [3]byte{124, 38, 100}: "Sagemcom Broadband SAS", + [3]byte{124, 42, 49}: "Intel Corporate", [3]byte{124, 43, 225}: "Shenzhen Ferex Electrical Co.,Ltd", [3]byte{124, 44, 243}: "Secure Electrans Ltd", [3]byte{124, 46, 13}: "Blackmagic Design", + [3]byte{124, 46, 189}: "Google, Inc.", [3]byte{124, 46, 221}: "Samsung Electronics Co.,Ltd", [3]byte{124, 47, 128}: "Gigaset Communications GmbH", [3]byte{124, 51, 110}: "MEG Electronics Inc.", @@ -18256,14 +18989,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{124, 56, 102}: "Texas Instruments", [3]byte{124, 56, 108}: "Real Time Logic", [3]byte{124, 57, 32}: "SSOMA SECURITY", + [3]byte{124, 57, 83}: "zte corporation", [3]byte{124, 59, 213}: "Imago Group", [3]byte{124, 60, 182}: "Shenzhen Homecare Technology Co.,Ltd.", [3]byte{124, 62, 157}: "PATECH", + [3]byte{124, 65, 162}: "Nokia", [3]byte{124, 67, 143}: "E-Band Communications Corp.", [3]byte{124, 68, 76}: "Entertainment Solutions, S.L.", [3]byte{124, 70, 133}: "Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.", [3]byte{124, 71, 124}: "IEEE Registration Authority", [3]byte{124, 73, 185}: "Plexus Manufacturing Sdn Bhd", + [3]byte{124, 73, 235}: "XIAOMI Electronics,CO.,LTD", [3]byte{124, 74, 130}: "Portsmith LLC", [3]byte{124, 74, 168}: "MindTree Wireless PVT Ltd", [3]byte{124, 75, 120}: "Red Sun Synthesis Pte Ltd", @@ -18283,6 +19019,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{124, 100, 86}: "Samsung Electronics Co.,Ltd", [3]byte{124, 102, 157}: "Texas Instruments", [3]byte{124, 103, 162}: "Intel Corporate", + [3]byte{124, 105, 107}: "Atmosic Technologies", [3]byte{124, 105, 246}: "Cisco Systems, Inc", [3]byte{124, 106, 179}: "IBC TECHNOLOGIES INC.", [3]byte{124, 106, 195}: "GatesAir, Inc", @@ -18290,10 +19027,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{124, 106, 243}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{124, 107, 51}: "Tenyu Tech Co. Ltd.", [3]byte{124, 107, 82}: "Tigaro Wireless", + [3]byte{124, 107, 156}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{124, 107, 247}: "NTI co., ltd.", [3]byte{124, 108, 57}: "PIXSYS SRL", [3]byte{124, 108, 143}: "AMS NEVE LTD", [3]byte{124, 109, 98}: "Apple, Inc.", + [3]byte{124, 109, 166}: "Superwave Group LLC", [3]byte{124, 109, 248}: "Apple, Inc.", [3]byte{124, 111, 6}: "Caterpillar Trimble Control Technologies", [3]byte{124, 111, 248}: "ShenZhen ACTO Digital Video Technology Co.,Ltd.", @@ -18303,6 +19042,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{124, 115, 139}: "Cocoon Alarm Ltd", [3]byte{124, 118, 48}: "Shenzhen YOUHUA Technology Co., Ltd", [3]byte{124, 118, 53}: "Intel Corporate", + [3]byte{124, 118, 104}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{124, 118, 115}: "ENMAS GmbH", [3]byte{124, 120, 126}: "Samsung Electronics Co.,Ltd", [3]byte{124, 121, 232}: "PayRange Inc.", @@ -18315,6 +19055,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{124, 130, 45}: "Nortec", [3]byte{124, 130, 116}: "Shenzhen Hikeen Technology CO.,LTD", [3]byte{124, 131, 6}: "Glen Dimplex Nordic as", + [3]byte{124, 137, 193}: "Palo Alto Networks", + [3]byte{124, 139, 181}: "Samsung Electronics Co.,Ltd", [3]byte{124, 139, 202}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{124, 141, 145}: "Shanghai Hongzhuo Information Technology co.,LTD", [3]byte{124, 142, 228}: "Texas Instruments", @@ -18322,9 +19064,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{124, 148, 178}: "Philips Healthcare PCCI", [3]byte{124, 149, 177}: "Aerohive Networks Inc.", [3]byte{124, 149, 243}: "Cisco Systems, Inc", + [3]byte{124, 150, 210}: "Fihonest communication co.,Ltd", [3]byte{124, 151, 99}: "Openmatics s.r.o.", + [3]byte{124, 154, 84}: "Technicolor CH USA Inc.", [3]byte{124, 154, 155}: "VSE valencia smart energy", [3]byte{124, 161, 93}: "GN ReSound A/S", + [3]byte{124, 161, 119}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{124, 162, 55}: "King Slide Technology CO., LTD.", [3]byte{124, 162, 62}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{124, 162, 155}: "D.SignT GmbH & Co. KG", @@ -18347,9 +19092,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{124, 186, 204}: "IEEE Registration Authority", [3]byte{124, 187, 111}: "Cosco Electronics Co., Ltd.", [3]byte{124, 187, 138}: "Nintendo Co., Ltd.", + [3]byte{124, 188, 132}: "IEEE Registration Authority", [3]byte{124, 189, 6}: "AE REFUsol", [3]byte{124, 191, 136}: "Mobilicom LTD", [3]byte{124, 191, 177}: "ARRIS Group, Inc.", + [3]byte{124, 195, 133}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{124, 195, 161}: "Apple, Inc.", [3]byte{124, 196, 239}: "Devialet", [3]byte{124, 197, 55}: "Apple, Inc.", @@ -18367,11 +19114,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{124, 205, 60}: "Guangzhou Juzing Technology Co., Ltd", [3]byte{124, 207, 207}: "Shanghai SEARI Intelligent System Co., Ltd", [3]byte{124, 209, 195}: "Apple, Inc.", - [3]byte{124, 211, 10}: "INVENTEC Corporation", + [3]byte{124, 211, 10}: "INVENTEC CORPORATION", [3]byte{124, 215, 98}: "Freestyle Technology Pty Ltd", [3]byte{124, 216, 68}: "Enmotus Inc", [3]byte{124, 217, 254}: "New Cosmos Electric Co., Ltd.", [3]byte{124, 218, 132}: "Dongnian Networks Inc.", + [3]byte{124, 219, 152}: "ASKEY COMPUTER CORP", [3]byte{124, 221, 17}: "Chongqing MAS SCI&TECH.Co.,Ltd", [3]byte{124, 221, 32}: "IOXOS Technologies S.A.", [3]byte{124, 221, 118}: "Suzhou Hanming Technologies Co., Ltd.", @@ -18403,12 +19151,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{124, 254, 40}: "Salutron Inc.", [3]byte{124, 254, 78}: "Shenzhen Safe vision Technology Co.,LTD", [3]byte{124, 254, 144}: "Mellanox Technologies, Inc.", + [3]byte{124, 255, 77}: "AVM Audiovisuelles Marketing und Computersysteme GmbH", [3]byte{124, 255, 98}: "Huizhou Super Electron Technology Co.,Ltd.", [3]byte{128, 0, 11}: "Intel Corporate", [3]byte{128, 0, 16}: "AT&T", [3]byte{128, 0, 110}: "Apple, Inc.", [3]byte{128, 1, 132}: "HTC Corporation", + [3]byte{128, 2, 156}: "Gemtek Technology Co., Ltd.", [3]byte{128, 2, 223}: "ORA Inc.", + [3]byte{128, 5, 136}: "Ruijie Networks Co.,LTD", [3]byte{128, 5, 223}: "Montage Technology Group Limited", [3]byte{128, 7, 162}: "Esson Technology Inc.", [3]byte{128, 9, 2}: "Keysight Technologies, Inc.", @@ -18429,17 +19180,21 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{128, 25, 254}: "JianLing Technology CO., LTD", [3]byte{128, 29, 170}: "Avaya Inc", [3]byte{128, 31, 2}: "Edimax Technology Co. Ltd.", + [3]byte{128, 31, 18}: "Microchip Technology Inc.", [3]byte{128, 32, 175}: "Trade FIDES, a.s.", [3]byte{128, 34, 117}: "Beijing Beny Wave Technology Co Ltd", [3]byte{128, 38, 137}: "D-Link International", [3]byte{128, 41, 148}: "Technicolor CH USA Inc.", [3]byte{128, 42, 168}: "Ubiquiti Networks Inc.", [3]byte{128, 42, 250}: "Germaneers GmbH", + [3]byte{128, 43, 249}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{128, 45, 225}: "Solarbridge Technologies", [3]byte{128, 46, 20}: "azeti Networks AG", [3]byte{128, 47, 222}: "Zurich Instruments AG", [3]byte{128, 48, 220}: "Texas Instruments", + [3]byte{128, 48, 224}: "Hewlett Packard Enterprise", [3]byte{128, 52, 87}: "OT Systems Limited", + [3]byte{128, 53, 193}: "Xiaomi Communications Co Ltd", [3]byte{128, 55, 115}: "NETGEAR", [3]byte{128, 56, 150}: "SHARP Corporation", [3]byte{128, 56, 188}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -18447,21 +19202,26 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{128, 57, 229}: "PATLITE CORPORATION", [3]byte{128, 58, 10}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{128, 58, 89}: "AT&T", + [3]byte{128, 58, 244}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{128, 59, 42}: "ABB Xiamen Low Voltage Equipment Co.,Ltd.", [3]byte{128, 59, 154}: "ghe-ces electronic ag", [3]byte{128, 59, 246}: "LOOK EASY INTERNATIONAL LIMITED", [3]byte{128, 63, 93}: "Winstars Technology Ltd", [3]byte{128, 63, 214}: "bytes at work AG", + [3]byte{128, 65, 38}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{128, 65, 78}: "BBK EDUCATIONAL ELECTRONICS CORP.,LTD.", [3]byte{128, 66, 124}: "Adolf Tedsen GmbH & Co. KG", [3]byte{128, 71, 49}: "Packet Design, Inc.", [3]byte{128, 72, 165}: "SICHUAN TIANYI COMHEART TELECOMCO.,LTD", [3]byte{128, 73, 113}: "Apple, Inc.", [3]byte{128, 75, 32}: "Ventilation Control", + [3]byte{128, 78, 112}: "Samsung Electronics Co.,Ltd", [3]byte{128, 78, 129}: "Samsung Electronics Co.,Ltd", [3]byte{128, 79, 88}: "ThinkEco, Inc.", [3]byte{128, 80, 27}: "Nokia Corporation", [3]byte{128, 80, 103}: "W & D TECHNOLOGY CORPORATION", + [3]byte{128, 80, 246}: "ITEL MOBILE LIMITED", + [3]byte{128, 84, 106}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", [3]byte{128, 86, 242}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{128, 87, 25}: "Samsung Electronics Co.,Ltd", [3]byte{128, 88, 197}: "NovaTec Kommunikationstechnik GmbH", @@ -18469,6 +19229,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{128, 89, 253}: "Noviga", [3]byte{128, 90, 4}: "LG Electronics (Mobile Communications)", [3]byte{128, 94, 12}: "YEALINK(XIAMEN) NETWORK TECHNOLOGY CO.,LTD.", + [3]byte{128, 94, 79}: "FN-LINK TECHNOLOGY LIMITED", [3]byte{128, 94, 192}: "YEALINK(XIAMEN) NETWORK TECHNOLOGY CO.,LTD.", [3]byte{128, 96, 7}: "RIM", [3]byte{128, 97, 95}: "Beijing Sinead Technology Co., Ltd.", @@ -18477,10 +19238,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{128, 101, 109}: "Samsung Electronics Co.,Ltd", [3]byte{128, 101, 233}: "BenQ Corporation", [3]byte{128, 102, 41}: "Prescope Technologies CO.,LTD.", + [3]byte{128, 105, 51}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{128, 105, 64}: "LEXAR CO.,LIMITED", [3]byte{128, 106, 176}: "Shenzhen TINNO Mobile Technology Corp.", [3]byte{128, 108, 27}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{128, 108, 139}: "KAESER KOMPRESSOREN AG", [3]byte{128, 108, 188}: "NET New Electronic Technology GmbH", + [3]byte{128, 111, 176}: "Texas Instruments", [3]byte{128, 113, 31}: "Juniper Networks", [3]byte{128, 113, 122}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{128, 115, 159}: "KYOCERA CORPORATION", @@ -18491,9 +19255,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{128, 122, 191}: "HTC Corporation", [3]byte{128, 123, 30}: "Corsair Components", [3]byte{128, 123, 133}: "IEEE Registration Authority", + [3]byte{128, 125, 20}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{128, 125, 27}: "Neosystem Co. Ltd.", + [3]byte{128, 125, 58}: "Espressif Inc.", [3]byte{128, 125, 227}: "Chongqing Sichuan Instrument Microcircuit Co.LTD.", [3]byte{128, 129, 165}: "TONGQING COMMUNICATION EQUIPMENT (SHENZHEN) Co.,Ltd", + [3]byte{128, 130, 35}: "Apple, Inc.", [3]byte{128, 130, 135}: "ATCOM Technology Co.Ltd.", [3]byte{128, 134, 152}: "Netronics Technologies Inc.", [3]byte{128, 134, 242}: "Intel Corporate", @@ -18506,6 +19273,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{128, 146, 159}: "Apple, Inc.", [3]byte{128, 147, 147}: "Xapt GmbH", [3]byte{128, 148, 108}: "TOKYO RADAR CORPORATION", + [3]byte{128, 150, 33}: "Lenovo", [3]byte{128, 150, 177}: "ARRIS Group, Inc.", [3]byte{128, 150, 202}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{128, 151, 27}: "Altenergy Power System,Inc.", @@ -18515,15 +19283,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{128, 161, 171}: "Intellisis", [3]byte{128, 161, 215}: "Shanghai DareGlobal Technologies Co.,Ltd", [3]byte{128, 165, 137}: "AzureWave Technology Inc.", + [3]byte{128, 167, 150}: "Neurotek LLC", [3]byte{128, 168, 93}: "Osterhout Design Group", [3]byte{128, 170, 164}: "USAG", [3]byte{128, 172, 172}: "Juniper Networks", + [3]byte{128, 173, 22}: "Xiaomi Communications Co Ltd", [3]byte{128, 173, 103}: "Kasda Networks Inc", [3]byte{128, 176, 61}: "Apple, Inc.", [3]byte{128, 178, 25}: "ELEKTRON TECHNOLOGY UK LIMITED", [3]byte{128, 178, 52}: "Technicolor CH USA Inc.", [3]byte{128, 178, 137}: "Forworld Electronics Ltd.", - [3]byte{128, 179, 42}: "Alstom Grid", + [3]byte{128, 179, 42}: "UK Grid Solutions Ltd", + [3]byte{128, 181, 117}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{128, 182, 36}: "IVS", [3]byte{128, 182, 134}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{128, 183, 8}: "Blue Danube Systems, Inc", [3]byte{128, 183, 9}: "Viptela, Inc", @@ -18533,16 +19305,21 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{128, 187, 235}: "Satmap Systems Ltd", [3]byte{128, 190, 5}: "Apple, Inc.", [3]byte{128, 193, 110}: "Hewlett Packard", + [3]byte{128, 197, 72}: "Shenzhen Zowee Technology Co.,Ltd", [3]byte{128, 197, 230}: "Microsoft Corporation", [3]byte{128, 197, 242}: "AzureWave Technology Inc.", [3]byte{128, 198, 63}: "Remec Broadband Wireless , LLC", [3]byte{128, 198, 171}: "Technicolor CH USA Inc.", [3]byte{128, 198, 202}: "Endian s.r.l.", [3]byte{128, 199, 85}: "Panasonic Appliances Company", + [3]byte{128, 199, 197}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{128, 200, 98}: "Openpeak, Inc", + [3]byte{128, 206, 98}: "Hewlett Packard", [3]byte{128, 206, 177}: "Theissen Training Systems GmbH", + [3]byte{128, 206, 185}: "Samsung Electronics Co.,Ltd", [3]byte{128, 207, 65}: "Lenovo Mobile Communication Technology Ltd.", [3]byte{128, 208, 25}: "Embed, Inc", + [3]byte{128, 208, 101}: "CKS Corporation", [3]byte{128, 208, 155}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{128, 209, 96}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{128, 209, 139}: "Hangzhou I'converge Technology Co.,Ltd", @@ -18569,18 +19346,21 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{128, 248, 235}: "RayTight", [3]byte{128, 250, 91}: "CLEVO CO.", [3]byte{128, 251, 6}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{128, 251, 240}: "Quectel Wireless Solutions Co., Ltd.", [3]byte{128, 255, 168}: "UNIDIS", [3]byte{132, 0, 45}: "PEGATRON CORPORATION", - [3]byte{132, 0, 210}: "Sony Mobile Communications AB", + [3]byte{132, 0, 210}: "Sony Mobile Communications Inc", [3]byte{132, 1, 167}: "Greyware Automation Products, Inc", [3]byte{132, 4, 210}: "Kirale Technologies SL", [3]byte{132, 11, 45}: "SAMSUNG ELECTRO MECHANICS CO., LTD.", + [3]byte{132, 13, 142}: "Espressif Inc.", [3]byte{132, 15, 69}: "Shanghai GMT Digital Technologies Co., Ltd", [3]byte{132, 16, 13}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{132, 17, 158}: "Samsung Electronics Co.,Ltd", [3]byte{132, 22, 249}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{132, 23, 21}: "GP Electronics (HK) Ltd.", - [3]byte{132, 23, 102}: "Weifang GoerTek Technology Co.,Ltd.", + [3]byte{132, 23, 102}: "WEIFANG GOERTEK ELECTRONICS CO.,LTD", + [3]byte{132, 23, 239}: "Technicolor CH USA Inc.", [3]byte{132, 24, 38}: "Osram GmbH", [3]byte{132, 24, 58}: "Ruckus Wireless", [3]byte{132, 24, 136}: "Juniper Networks", @@ -18609,6 +19389,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{132, 46, 39}: "Samsung Electronics Co.,Ltd", [3]byte{132, 47, 117}: "Innokas Group", [3]byte{132, 48, 229}: "SkyHawke Technologies, LLC", + [3]byte{132, 50, 111}: "GUANGZHOU AVA ELECTRONICS TECHNOLOGY CO.,LTD", [3]byte{132, 50, 234}: "ANHUI WANZTEN P&T CO., LTD", [3]byte{132, 52, 151}: "Hewlett Packard", [3]byte{132, 54, 17}: "hyungseul publishing networks", @@ -18640,11 +19421,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{132, 98, 166}: "EuroCB (Phils), Inc.", [3]byte{132, 99, 214}: "Microsoft Corporation", [3]byte{132, 104, 62}: "Intel Corporate", + [3]byte{132, 104, 120}: "Apple, Inc.", + [3]byte{132, 106, 102}: "Sumitomo Kizai Co.,Ltd.", [3]byte{132, 106, 237}: "Wireless Tsukamoto.,co.LTD", [3]byte{132, 110, 177}: "Park Assist LLC", [3]byte{132, 114, 7}: "I&C Technology", [3]byte{132, 115, 3}: "Letv Mobile and Intelligent Information Technology (Beijing) Corporation Ltd.", [3]byte{132, 116, 42}: "zte corporation", + [3]byte{132, 116, 96}: "zte corporation", [3]byte{132, 118, 22}: "Addat s.r.o.", [3]byte{132, 119, 120}: "Cochlear Limited", [3]byte{132, 120, 139}: "Apple, Inc.", @@ -18655,6 +19439,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{132, 123, 235}: "Dell Inc.", [3]byte{132, 125, 80}: "Holley Metering Limited", [3]byte{132, 126, 64}: "Texas Instruments", + [3]byte{132, 127, 61}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{132, 128, 45}: "Cisco Systems, Inc", [3]byte{132, 130, 244}: "Beijing Huasun Unicreate Technology Co., Ltd", [3]byte{132, 131, 25}: "Hangzhou Zero Zero Technology Co., Ltd.", @@ -18665,11 +19450,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{132, 133, 10}: "Hella Sonnen- und Wetterschutztechnik GmbH", [3]byte{132, 134, 243}: "Greenvity Communications", [3]byte{132, 137, 173}: "Apple, Inc.", + [3]byte{132, 137, 236}: "IEEE Registration Authority", + [3]byte{132, 138, 141}: "Cisco Systems, Inc", [3]byte{132, 141, 132}: "Rajant Corporation", [3]byte{132, 141, 199}: "Cisco SPVTG", [3]byte{132, 142, 12}: "Apple, Inc.", [3]byte{132, 142, 150}: "Embertec Pty Ltd", - [3]byte{132, 142, 223}: "Sony Mobile Communications AB", + [3]byte{132, 142, 223}: "Sony Mobile Communications Inc", [3]byte{132, 143, 105}: "Dell Inc.", [3]byte{132, 144, 0}: "Arnold & Richter Cine Technik", [3]byte{132, 147, 12}: "InCoax Networks Europe AB", @@ -18684,12 +19471,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{132, 159, 181}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{132, 161, 52}: "Apple, Inc.", [3]byte{132, 161, 209}: "Sagemcom Broadband SAS", + [3]byte{132, 162, 77}: "Birds Eye Systems Private Limited", [3]byte{132, 164, 35}: "Sagemcom Broadband SAS", [3]byte{132, 164, 102}: "Samsung Electronics Co.,Ltd", [3]byte{132, 166, 200}: "Intel Corporate", [3]byte{132, 167, 131}: "Alcatel Lucent", [3]byte{132, 167, 136}: "Perples", [3]byte{132, 168, 228}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{132, 169, 62}: "Hewlett Packard", [3]byte{132, 169, 145}: "Cyber Trans Japan Co.,Ltd.", [3]byte{132, 169, 196}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{132, 170, 156}: "MitraStar Technology Corp.", @@ -18700,6 +19489,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{132, 175, 236}: "BUFFALO.INC", [3]byte{132, 177, 83}: "Apple, Inc.", [3]byte{132, 178, 97}: "Cisco Systems, Inc", + [3]byte{132, 179, 27}: "Kinexon GmbH", [3]byte{132, 181, 23}: "Cisco Systems, Inc", [3]byte{132, 181, 65}: "Samsung Electronics Co.,Ltd", [3]byte{132, 181, 156}: "Juniper Networks", @@ -18712,9 +19502,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{132, 195, 232}: "Vaillant GmbH", [3]byte{132, 199, 39}: "Gnodal Ltd", [3]byte{132, 199, 169}: "C3PO S.A.", - [3]byte{132, 199, 234}: "Sony Mobile Communications AB", + [3]byte{132, 199, 234}: "Sony Mobile Communications Inc", [3]byte{132, 200, 177}: "Incognito Software Systems Inc.", [3]byte{132, 201, 178}: "D-Link International", + [3]byte{132, 201, 198}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", [3]byte{132, 205, 98}: "ShenZhen IDWELL Technology CO.,Ltd", [3]byte{132, 207, 191}: "Fairphone", [3]byte{132, 211, 42}: "IEEE 1905.1", @@ -18723,7 +19514,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{132, 214, 208}: "Amazon Technologies Inc.", [3]byte{132, 217, 49}: "Hangzhou H3C Technologies Co., Limited", [3]byte{132, 217, 200}: "Unipattern Co.,", - [3]byte{132, 219, 47}: "Sierra Wireless Inc", + [3]byte{132, 219, 47}: "Sierra Wireless", + [3]byte{132, 219, 158}: "Aifloo AB", [3]byte{132, 219, 172}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{132, 219, 252}: "Nokia", [3]byte{132, 221, 32}: "Texas Instruments", @@ -18736,6 +19528,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{132, 227, 35}: "Green Wave Telecommunication SDN BHD", [3]byte{132, 227, 39}: "TAILYN TECHNOLOGIES INC", [3]byte{132, 228, 217}: "Shenzhen NEED technology Ltd.", + [3]byte{132, 229, 216}: "Guangdong UNIPOE IoT Technology Co.,Ltd.", [3]byte{132, 230, 41}: "Bluwan SA", [3]byte{132, 231, 20}: "Liang Herng Enterprise,Co.Ltd.", [3]byte{132, 234, 153}: "Vieworks", @@ -18743,6 +19536,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{132, 237, 51}: "BBMC Co.,Ltd", [3]byte{132, 239, 24}: "Intel Corporate", [3]byte{132, 241, 41}: "Metrascale Inc.", + [3]byte{132, 243, 235}: "Espressif Inc.", [3]byte{132, 244, 147}: "OMS spol. s.r.o.", [3]byte{132, 246, 76}: "Cross Point BV", [3]byte{132, 246, 250}: "Miovision Technologies Incorporated", @@ -18750,18 +19544,24 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{132, 252, 254}: "Apple, Inc.", [3]byte{132, 254, 158}: "RTC Industries, Inc.", [3]byte{132, 254, 220}: "Borqs Beijing Ltd.", + [3]byte{136, 1, 24}: "BLT Co", [3]byte{136, 1, 242}: "Vitec System Engineering Inc.", [3]byte{136, 3, 85}: "Arcadyan Technology Corporation", [3]byte{136, 7, 75}: "LG Electronics (Mobile Communications)", [3]byte{136, 9, 5}: "MTMCommunications", + [3]byte{136, 9, 7}: "MKT Systemtechnik GmbH & Co. KG", [3]byte{136, 9, 175}: "Masimo Corporation", [3]byte{136, 15, 16}: "Huami Information Technology Co.,Ltd.", [3]byte{136, 15, 182}: "Jabil Circuits India Pvt Ltd,-EHTP unit", [3]byte{136, 16, 54}: "Panodic(ShenZhen) Electronics Limted", + [3]byte{136, 16, 143}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{136, 17, 150}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{136, 18, 78}: "Qualcomm Inc.", [3]byte{136, 20, 43}: "Protonic Holland", [3]byte{136, 21, 68}: "Cisco Meraki", + [3]byte{136, 23, 163}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{136, 24, 174}: "Tamron Co., Ltd", + [3]byte{136, 25, 8}: "Apple, Inc.", [3]byte{136, 27, 153}: "SHENZHEN XIN FEI JIA ELECTRONIC CO. LTD.", [3]byte{136, 29, 252}: "Cisco Systems, Inc", [3]byte{136, 31, 161}: "Apple, Inc.", @@ -18772,19 +19572,25 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{136, 37, 44}: "Arcadyan Technology Corporation", [3]byte{136, 37, 147}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{136, 40, 179}: "HUAWEI TECHNOLOGIES CO.,LTD", - [3]byte{136, 41, 80}: "Dalian Netmoon Tech Develop Co.,Ltd", + [3]byte{136, 41, 80}: "Netmoon Technology Co., Ltd", [3]byte{136, 43, 215}: "ADDÉNERGIE TECHNOLOGIES", + [3]byte{136, 45, 83}: "Baidu Online Network Technology (Beijing) Co., Ltd.", [3]byte{136, 46, 90}: "storONE", [3]byte{136, 48, 138}: "Murata Manufacturing Co., Ltd.", [3]byte{136, 50, 155}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", [3]byte{136, 51, 20}: "Texas Instruments", [3]byte{136, 51, 190}: "Ivenix, Inc.", + [3]byte{136, 52, 254}: "Bosch Automotive Products (Suzhou) Co. Ltd", [3]byte{136, 53, 76}: "Transics", + [3]byte{136, 53, 193}: "OI ELECTRIC CO.,LTD", [3]byte{136, 54, 18}: "SRC Computers, LLC", [3]byte{136, 54, 95}: "LG Electronics (Mobile Communications)", [3]byte{136, 54, 108}: "EFM Networks", [3]byte{136, 59, 139}: "Cheering Connection Co. Ltd.", [3]byte{136, 60, 28}: "MERCURY CORPORATION", + [3]byte{136, 61, 36}: "Google, Inc.", + [3]byte{136, 63, 74}: "Texas Instruments", + [3]byte{136, 63, 153}: "Siemens AG", [3]byte{136, 63, 211}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{136, 65, 87}: "Shenzhen Atsmart Technology Co.,Ltd.", [3]byte{136, 65, 193}: "ORBISAT DA AMAZONIA IND E AEROL SA", @@ -18797,6 +19603,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{136, 75, 57}: "Siemens AG, Healthcare Sector", [3]byte{136, 76, 207}: "Pulzze Systems, Inc", [3]byte{136, 80, 221}: "Infiniband Trade Association", + [3]byte{136, 80, 246}: "Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd", [3]byte{136, 81, 251}: "Hewlett Packard", [3]byte{136, 83, 46}: "Intel Corporate", [3]byte{136, 83, 149}: "Apple, Inc.", @@ -18808,6 +19615,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{136, 92, 71}: "Alcatel Lucent", [3]byte{136, 93, 144}: "IEEE Registration Authority", [3]byte{136, 93, 251}: "zte corporation", + [3]byte{136, 95, 232}: "IEEE Registration Authority", [3]byte{136, 97, 90}: "Siano Mobile Silicon Ltd.", [3]byte{136, 99, 223}: "Apple, Inc.", [3]byte{136, 102, 57}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -18822,6 +19630,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{136, 112, 51}: "Hangzhou Silan Microelectronic Inc", [3]byte{136, 112, 140}: "Lenovo Mobile Communication Technology Ltd.", [3]byte{136, 112, 239}: "SC Professional Trading Co., Ltd.", + [3]byte{136, 113, 177}: "ARRIS Group, Inc.", [3]byte{136, 113, 229}: "Amazon Technologies Inc.", [3]byte{136, 115, 132}: "Toshiba", [3]byte{136, 115, 152}: "K2E Tekpoint", @@ -18852,13 +19661,16 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{136, 148, 126}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{136, 148, 249}: "Gemicom Technology, Inc.", [3]byte{136, 149, 185}: "Unified Packet Systems Crop", + [3]byte{136, 150, 78}: "ARRIS Group, Inc.", [3]byte{136, 150, 118}: "TTC MARCONI s.r.o.", [3]byte{136, 150, 182}: "Global Fire Equipment S.A.", [3]byte{136, 150, 242}: "Valeo Schalter und Sensoren GmbH", + [3]byte{136, 151, 101}: "exands", [3]byte{136, 151, 223}: "Entrypass Corporation Sdn. Bhd.", [3]byte{136, 152, 33}: "TERAON", [3]byte{136, 155, 57}: "Samsung Electronics Co.,Ltd", [3]byte{136, 156, 166}: "BTB Korea INC", + [3]byte{136, 159, 111}: "Samsung Electronics Co.,Ltd", [3]byte{136, 159, 250}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{136, 160, 132}: "Formation Data Systems", [3]byte{136, 162, 94}: "Juniper Networks", @@ -18867,19 +19679,26 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{136, 165, 189}: "QPCOM INC.", [3]byte{136, 166, 198}: "Sagemcom Broadband SAS", [3]byte{136, 167, 60}: "Ragentek Technology Group", + [3]byte{136, 169, 167}: "IEEE Registration Authority", [3]byte{136, 172, 193}: "Generiton Co., Ltd.", [3]byte{136, 173, 67}: "PEGATRON CORPORATION", [3]byte{136, 173, 210}: "Samsung Electronics Co.,Ltd", + [3]byte{136, 174, 7}: "Apple, Inc.", [3]byte{136, 174, 29}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", [3]byte{136, 177, 17}: "Intel Corporate", [3]byte{136, 177, 104}: "Delta Control GmbH", [3]byte{136, 177, 225}: "Mojo Networks, Inc.", + [3]byte{136, 179, 98}: "Nokia Shanghai Bell Co. Ltd.)", [3]byte{136, 180, 166}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{136, 182, 39}: "Gembird Europe BV", + [3]byte{136, 182, 107}: "easynetworks", + [3]byte{136, 182, 238}: "Dish Technologies Corp", [3]byte{136, 184, 208}: "Dongguan Koppo Electronic Co.,Ltd", [3]byte{136, 186, 127}: "Qfiednet Co., Ltd.", + [3]byte{136, 189, 69}: "Samsung Electronics Co.,Ltd", [3]byte{136, 189, 120}: "Flaircomm Microelectronics,Inc.", [3]byte{136, 191, 213}: "Simple Audio Ltd", + [3]byte{136, 191, 228}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{136, 194, 66}: "Poynt Co.", [3]byte{136, 194, 85}: "Texas Instruments", [3]byte{136, 195, 110}: "Beijing Ereneben lnformation Technology Limited", @@ -18894,16 +19713,21 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{136, 207, 152}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{136, 208, 57}: "TCL Technoly Electronics(Huizhou).,Ltd", [3]byte{136, 209, 113}: "BEGHELLI S.P.A", + [3]byte{136, 210, 17}: "Eko Devices, Inc.", [3]byte{136, 210, 116}: "zte corporation", + [3]byte{136, 210, 191}: "German Autolabs", [3]byte{136, 211, 123}: "FirmTek, LLC", [3]byte{136, 213, 12}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", + [3]byte{136, 214, 82}: "AMERGINT Technologies", [3]byte{136, 215, 188}: "DEP Company", [3]byte{136, 215, 246}: "ASUSTek COMPUTER INC.", [3]byte{136, 217, 98}: "Canopus Systems US LLC", [3]byte{136, 218, 26}: "Redpine Signals, Inc.", [3]byte{136, 220, 150}: "SENAO Networks, Inc.", [3]byte{136, 221, 121}: "Voltaire", + [3]byte{136, 222, 124}: "Askey Computer Corp.", [3]byte{136, 222, 169}: "Roku, Inc.", + [3]byte{136, 223, 158}: "New H3C Technologies Co., Ltd", [3]byte{136, 224, 160}: "Shenzhen VisionSTOR Technologies Co., Ltd", [3]byte{136, 224, 243}: "Juniper Networks", [3]byte{136, 225, 97}: "Art Beijing Science and Technology Development Co., Ltd.", @@ -18914,12 +19738,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{136, 231, 166}: "iKnowledge Integration Corp.", [3]byte{136, 232, 127}: "Apple, Inc.", [3]byte{136, 232, 248}: "YONG TAI ELECTRONIC (DONGGUAN) LTD.", + [3]byte{136, 233, 15}: "innomdlelab", [3]byte{136, 233, 23}: "Tamaggo", + [3]byte{136, 233, 254}: "Apple, Inc.", [3]byte{136, 237, 28}: "Cudo Communication Co., Ltd.", [3]byte{136, 240, 49}: "Cisco Systems, Inc", [3]byte{136, 240, 119}: "Cisco Systems, Inc", [3]byte{136, 244, 136}: "cellon communications technology(shenzhen)Co.,Ltd.", [3]byte{136, 244, 144}: "Jetmobile Pte Ltd", + [3]byte{136, 247, 191}: "vivo Mobile Communication Co., Ltd.", [3]byte{136, 247, 199}: "Technicolor CH USA Inc.", [3]byte{136, 253, 21}: "LINEEYE CO., LTD", [3]byte{136, 254, 214}: "ShangHai WangYong Software Co., Ltd.", @@ -18938,9 +19765,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{140, 16, 212}: "Sagemcom Broadband SAS", [3]byte{140, 17, 203}: "ABUS Security-Center GmbH & Co. KG", [3]byte{140, 20, 125}: "IEEE Registration Authority", + [3]byte{140, 20, 180}: "zte corporation", + [3]byte{140, 21, 199}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{140, 22, 69}: "LCFC(HeFei) Electronics Technology co., ltd", + [3]byte{140, 24, 80}: "China Mobile (Hangzhou) Information Technology Co., Ltd.", [3]byte{140, 24, 217}: "Shenzhen RF Technology Co., Ltd", [3]byte{140, 25, 45}: "IEEE Registration Authority", [3]byte{140, 26, 191}: "Samsung Electronics Co.,Ltd", + [3]byte{140, 28, 218}: "IEEE Registration Authority", [3]byte{140, 31, 148}: "RF Surgical System Inc.", [3]byte{140, 33, 10}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{140, 37, 5}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -18953,16 +19785,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{140, 51, 48}: "EmFirst Co., Ltd.", [3]byte{140, 51, 87}: "HiteVision Digital Media Technology Co.,Ltd.", [3]byte{140, 52, 253}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{140, 53, 121}: "QDIQO Sp. z o.o.", [3]byte{140, 57, 92}: "Bit4id Srl", [3]byte{140, 58, 227}: "LG Electronics (Mobile Communications)", [3]byte{140, 59, 173}: "NETGEAR", [3]byte{140, 60, 7}: "Skiva Technologies, Inc.", [3]byte{140, 60, 74}: "NAKAYO Inc", [3]byte{140, 65, 242}: "RDA Technologies Ltd.", + [3]byte{140, 65, 244}: "IPmotion GmbH", [3]byte{140, 68, 53}: "Shanghai BroadMobi Communication Technology Co., Ltd.", [3]byte{140, 69, 0}: "Murata Manufacturing Co., Ltd.", [3]byte{140, 74, 238}: "GIGA TMS INC", [3]byte{140, 75, 89}: "3D Imaging & Simulations Corp", + [3]byte{140, 76, 173}: "Evoluzn Inc.", [3]byte{140, 76, 220}: "PLANEX COMMUNICATIONS INC.", [3]byte{140, 77, 185}: "Unmonday Ltd", [3]byte{140, 77, 234}: "Cerio Corporation", @@ -18974,6 +19809,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{140, 87, 155}: "Wistron Neweb Corporation", [3]byte{140, 87, 253}: "LVX Western", [3]byte{140, 88, 119}: "Apple, Inc.", + [3]byte{140, 89, 115}: "Zyxel Communications Corporation", [3]byte{140, 89, 139}: "C Technologies AB", [3]byte{140, 89, 195}: "ADB Italia", [3]byte{140, 90, 240}: "Exeltech Solar Products", @@ -18985,11 +19821,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{140, 96, 79}: "Cisco Systems, Inc", [3]byte{140, 96, 231}: "MPGIO CO.,LTD", [3]byte{140, 97, 2}: "Beijing Baofengmojing Technologies Co., Ltd", + [3]byte{140, 97, 163}: "ARRIS Group, Inc.", [3]byte{140, 100, 11}: "Beyond Devices d.o.o.", - [3]byte{140, 100, 34}: "Sony Mobile Communications AB", + [3]byte{140, 100, 34}: "Sony Mobile Communications Inc", [3]byte{140, 104, 120}: "Nortek-AS", [3]byte{140, 106, 228}: "Viogem Limited", [3]byte{140, 109, 80}: "SHENZHEN MTC CO LTD", + [3]byte{140, 109, 119}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{140, 112, 90}: "Intel Corporate", [3]byte{140, 113, 248}: "Samsung Electronics Co.,Ltd", [3]byte{140, 115, 110}: "FUJITSU LIMITED", @@ -18999,16 +19837,20 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{140, 120, 215}: "SHENZHEN FAST TECHNOLOGIES CO.,LTD", [3]byte{140, 121, 103}: "zte corporation", [3]byte{140, 123, 157}: "Apple, Inc.", + [3]byte{140, 123, 240}: "Xufeng Development Limited", [3]byte{140, 124, 146}: "Apple, Inc.", [3]byte{140, 124, 181}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{140, 124, 255}: "Brocade Communications Systems, Inc.", [3]byte{140, 126, 179}: "Lytro, Inc.", [3]byte{140, 127, 59}: "ARRIS Group, Inc.", + [3]byte{140, 129, 38}: "ARCOM", [3]byte{140, 130, 168}: "Insigma Technology Co.,Ltd", [3]byte{140, 131, 157}: "SHENZHEN XINYUPENG ELECTRONIC TECHNOLOGY CO., LTD", + [3]byte{140, 131, 225}: "Samsung Electronics Co.,Ltd", [3]byte{140, 132, 1}: "Private", [3]byte{140, 133, 128}: "Smart Innovation LLC", [3]byte{140, 133, 144}: "Apple, Inc.", + [3]byte{140, 133, 230}: "Cleondris GmbH", [3]byte{140, 135, 59}: "Leica Camera AG", [3]byte{140, 137, 122}: "AUGTEK", [3]byte{140, 137, 165}: "Micro-Star INT'L CO., LTD", @@ -19017,10 +19859,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{140, 139, 131}: "Texas Instruments", [3]byte{140, 142, 118}: "taskit GmbH", [3]byte{140, 142, 242}: "Apple, Inc.", + [3]byte{140, 143, 139}: "China Mobile Chongqing branch", [3]byte{140, 143, 233}: "Apple, Inc.", [3]byte{140, 144, 211}: "Nokia", [3]byte{140, 145, 9}: "Toyoshima Electric Technoeogy(Suzhou) Co.,Ltd.", [3]byte{140, 146, 54}: "Aus.Linx Technology Co., Ltd.", + [3]byte{140, 146, 70}: "Oerlikon Textile Gmbh&Co.KG", [3]byte{140, 147, 81}: "Jigowatts Inc.", [3]byte{140, 148, 207}: "Encell Technology, Inc.", [3]byte{140, 153, 230}: "TCT mobile ltd", @@ -19034,6 +19878,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{140, 174, 76}: "Plugable Technologies", [3]byte{140, 174, 137}: "Y-cam Solutions Ltd", [3]byte{140, 176, 148}: "Airtech I&C Co., Ltd", + [3]byte{140, 176, 233}: "Samsung Electronics.,LTD", [3]byte{140, 182, 79}: "Cisco Systems, Inc", [3]byte{140, 183, 247}: "Shenzhen UniStrong Science & Technology Co., Ltd", [3]byte{140, 184, 44}: "IPitomy Communications", @@ -19074,13 +19919,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{140, 235, 198}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{140, 236, 75}: "Dell Inc.", [3]byte{140, 238, 198}: "Precepscion Pty. Ltd.", - [3]byte{140, 242, 40}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", + [3]byte{140, 242, 40}: "MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", [3]byte{140, 245, 163}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", + [3]byte{140, 247, 16}: "AMPAK Technology, Inc.", + [3]byte{140, 247, 115}: "Nokia", [3]byte{140, 248, 19}: "ORANGE POLSKA", [3]byte{140, 249, 69}: "Power Automation pte Ltd", + [3]byte{140, 249, 87}: "RuiXingHengFang Network (Shenzhen) Co.,Ltd", [3]byte{140, 249, 201}: "MESADA Technology Co.,Ltd.", [3]byte{140, 250, 186}: "Apple, Inc.", + [3]byte{140, 252, 160}: "Shenzhen Smart Device Technology Co., LTD.", [3]byte{140, 253, 240}: "Qualcomm Inc.", + [3]byte{140, 254, 87}: "Apple, Inc.", + [3]byte{140, 254, 116}: "Ruckus Wireless", [3]byte{140, 254, 180}: "VSOONTECH ELECTRONICS CO., LIMITED", [3]byte{144, 0, 78}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{144, 0, 219}: "Samsung Electronics Co.,Ltd", @@ -19088,6 +19939,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{144, 2, 138}: "Shenzhen Shidean Legrand Electronic Products Co.,Ltd", [3]byte{144, 2, 169}: "Zhejiang Dahua Technology Co., Ltd.", [3]byte{144, 3, 37}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{144, 3, 114}: "Longnan Junya Digital Technology Co. Ltd.", [3]byte{144, 3, 183}: "PARROT SA", [3]byte{144, 6, 40}: "Samsung Electronics Co.,Ltd", [3]byte{144, 9, 23}: "Far-sighted mobile", @@ -19099,6 +19951,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{144, 13, 102}: "Digimore Electronics Co., Ltd", [3]byte{144, 13, 203}: "ARRIS Group, Inc.", [3]byte{144, 14, 131}: "Monico Monitoring, Inc.", + [3]byte{144, 14, 179}: "Shenzhen Amediatech Technology Co., Ltd.", [3]byte{144, 23, 17}: "Hagenuk Marinekommunikation GmbH", [3]byte{144, 23, 155}: "Nanomegas", [3]byte{144, 23, 172}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -19118,6 +19971,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{144, 35, 236}: "Availink, Inc.", [3]byte{144, 39, 228}: "Apple, Inc.", [3]byte{144, 43, 52}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{144, 43, 210}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{144, 44, 199}: "C-MAX Asia Limited", [3]byte{144, 46, 28}: "Intel Corporate", [3]byte{144, 46, 135}: "LabJack", @@ -19128,11 +19982,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{144, 53, 110}: "Vodafone Omnitel N.V.", [3]byte{144, 56, 9}: "Ericsson AB", [3]byte{144, 56, 223}: "Changzhou Tiannengbo System Co. Ltd.", + [3]byte{144, 58, 114}: "Ruckus Wireless", [3]byte{144, 58, 160}: "Nokia", [3]byte{144, 58, 230}: "PARROT SA", [3]byte{144, 60, 146}: "Apple, Inc.", [3]byte{144, 60, 174}: "Yunnan KSEC Digital Technology Co.,Ltd.", [3]byte{144, 61, 90}: "Shenzhen Wision Technology Holding Limited", + [3]byte{144, 61, 104}: "G-Printec, Inc.", [3]byte{144, 61, 107}: "Zicon Technology Corp.", [3]byte{144, 61, 189}: "SECURE METERS LIMITED", [3]byte{144, 62, 171}: "ARRIS Group, Inc.", @@ -19142,6 +19998,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{144, 71, 22}: "RORZE CORPORATION", [3]byte{144, 72, 154}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{144, 73, 250}: "Intel Corporate", + [3]byte{144, 76, 129}: "Hewlett Packard Enterprise", [3]byte{144, 76, 229}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{144, 77, 74}: "Sagemcom Broadband SAS", [3]byte{144, 78, 43}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -19161,6 +20018,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{144, 96, 241}: "Apple, Inc.", [3]byte{144, 97, 12}: "Fida International (S) Pte Ltd", [3]byte{144, 97, 174}: "Intel Corporate", + [3]byte{144, 99, 59}: "Samsung Electronics Co.,Ltd", [3]byte{144, 103, 23}: "Alphion India Private Limited", [3]byte{144, 103, 28}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{144, 103, 181}: "Alcatel-Lucent", @@ -19175,6 +20033,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{144, 112, 101}: "Texas Instruments", [3]byte{144, 114, 64}: "Apple, Inc.", [3]byte{144, 114, 130}: "Sagemcom Broadband SAS", + [3]byte{144, 121, 16}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{144, 121, 144}: "Benchmark Electronics Romania SRL", [3]byte{144, 122, 10}: "Gebr. Bode GmbH & Co KG", [3]byte{144, 122, 40}: "Beijing Morncloud Information And Technology Co. Ltd.", @@ -19182,10 +20041,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{144, 126, 186}: "UTEK TECHNOLOGY (SHENZHEN) CO.,LTD", [3]byte{144, 127, 97}: "Chicony Electronics Co., Ltd.", [3]byte{144, 130, 96}: "IEEE 1904.1 Working Group", + [3]byte{144, 131, 75}: "BEIJING YUNYI TIMES TECHNOLOGY CO,.LTD", [3]byte{144, 131, 122}: "General Electric Water & Process Technologies", [3]byte{144, 132, 13}: "Apple, Inc.", [3]byte{144, 132, 43}: "LEGO System A/S", + [3]byte{144, 132, 139}: "HDR10+ Technologies, LLC", [3]byte{144, 134, 116}: "SICHUAN TIANYI COMHEART TELECOMCO., LTD", + [3]byte{144, 134, 155}: "zte corporation", [3]byte{144, 136, 162}: "IONICS TECHNOLOGY ME LTDA", [3]byte{144, 140, 9}: "Total Phase", [3]byte{144, 140, 68}: "H.K ZONGMU TECHNOLOGY CO., LTD.", @@ -19197,6 +20059,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{144, 144, 60}: "TRISON TECHNOLOGY CORPORATION", [3]byte{144, 144, 96}: "RSI VIDEO TECHNOLOGIES", [3]byte{144, 146, 180}: "Diehl BGT Defence GmbH & Co. KG", + [3]byte{144, 148, 151}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{144, 148, 228}: "D-Link International", [3]byte{144, 151, 213}: "Espressif Inc.", [3]byte{144, 151, 243}: "Samsung Electronics Co.,Ltd", @@ -19206,6 +20069,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{144, 157, 224}: "Newland Design + Assoc. Inc.", [3]byte{144, 159, 51}: "EFM Networks", [3]byte{144, 159, 67}: "Accutron Instruments Inc.", + [3]byte{144, 161, 55}: "Beijing Splendidtel Communication Technology Co,. Ltd", [3]byte{144, 162, 16}: "United Telecoms Ltd", [3]byte{144, 162, 218}: "GHEO SA", [3]byte{144, 163, 101}: "HMD Global Oy", @@ -19226,13 +20090,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{144, 184, 208}: "Joyent, Inc.", [3]byte{144, 185, 49}: "Apple, Inc.", [3]byte{144, 185, 125}: "Johnson Outdoors Marine Electronics d/b/a Minnkota", - [3]byte{144, 193, 21}: "Sony Mobile Communications AB", + [3]byte{144, 193, 21}: "Sony Mobile Communications Inc", [3]byte{144, 193, 198}: "Apple, Inc.", [3]byte{144, 195, 95}: "Nanjing Jiahao Technology Co., Ltd.", + [3]byte{144, 197, 74}: "vivo Mobile Communication Co., Ltd.", [3]byte{144, 198, 130}: "IEEE Registration Authority", [3]byte{144, 199, 146}: "ARRIS Group, Inc.", [3]byte{144, 199, 216}: "zte corporation", - [3]byte{144, 201, 155}: "Recore Systems", + [3]byte{144, 201, 155}: "Tesorion Nederland B.V.", [3]byte{144, 204, 36}: "Synaptics, Inc", [3]byte{144, 205, 182}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{144, 207, 21}: "Nokia Corporation", @@ -19248,11 +20113,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{144, 218, 78}: "AVANU", [3]byte{144, 218, 106}: "FOCUS H&S Co., Ltd.", [3]byte{144, 219, 70}: "E-LEAD ELECTRONIC CO., LTD", + [3]byte{144, 221, 93}: "Apple, Inc.", [3]byte{144, 223, 183}: "s.m.s smart microwave sensors GmbH", [3]byte{144, 223, 251}: "HOMERIDER SYSTEMS", [3]byte{144, 224, 240}: "IEEE 1722a Working Group", + [3]byte{144, 225, 123}: "Apple, Inc.", + [3]byte{144, 226, 2}: "Texas Instruments", [3]byte{144, 226, 186}: "Intel Corporate", [3]byte{144, 230, 186}: "ASUSTek COMPUTER INC.", + [3]byte{144, 231, 16}: "New H3C Technologies Co., Ltd", [3]byte{144, 231, 196}: "HTC Corporation", [3]byte{144, 234, 96}: "SPI Lasers Ltd", [3]byte{144, 236, 80}: "C.O.B.O. SPA", @@ -19288,11 +20157,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{148, 20, 122}: "vivo Mobile Communication Co., Ltd.", [3]byte{148, 22, 115}: "Point Core SARL", [3]byte{148, 24, 130}: "Hewlett Packard Enterprise", + [3]byte{148, 25, 58}: "Elvaco AB", [3]byte{148, 29, 28}: "TLab West Systems AB", [3]byte{148, 32, 83}: "Nokia Corporation", [3]byte{148, 33, 151}: "Stalmart Technology Limited", [3]byte{148, 35, 110}: "Shenzhen Junlan Electronic Ltd", [3]byte{148, 40, 46}: "New H3C Technologies Co., Ltd", + [3]byte{148, 41, 12}: "Shenyang wisdom Foundation Technology Development Co., Ltd.", + [3]byte{148, 41, 141}: "Shanghai AdaptComm Technology Co., Ltd.", [3]byte{148, 42, 63}: "Diversey Inc", [3]byte{148, 44, 179}: "HUMAX Co., Ltd.", [3]byte{148, 46, 23}: "Schneider Electric Canada Inc", @@ -19313,7 +20185,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{148, 70, 150}: "BaudTec Corporation", [3]byte{148, 73, 150}: "WiSilica Inc", [3]byte{148, 74, 9}: "BitWise Controls", - [3]byte{148, 74, 12}: "Sercomm Corporation", + [3]byte{148, 74, 12}: "Sercomm Corporation.", + [3]byte{148, 79, 76}: "Sound United LLC", [3]byte{148, 80, 71}: "Rechnerbetriebsgruppe", [3]byte{148, 80, 137}: "SimonsVoss Technologies GmbH", [3]byte{148, 81, 3}: "Samsung Electronics Co.,Ltd", @@ -19321,17 +20194,21 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{148, 81, 191}: "Hyundai ESG", [3]byte{148, 83, 48}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{148, 84, 147}: "Rigado, LLC", + [3]byte{148, 84, 223}: "YST CORP.", [3]byte{148, 87, 165}: "Hewlett Packard", + [3]byte{148, 88, 203}: "Nintendo Co.,Ltd", [3]byte{148, 89, 7}: "Shanghai HITE-BELDEN Network Technology Co., Ltd.", [3]byte{148, 89, 45}: "EKE Building Technology Systems Ltd", [3]byte{148, 91, 126}: "TRILOBIT LTDA.", [3]byte{148, 97, 30}: "Wata Electronics Co.,Ltd.", [3]byte{148, 97, 36}: "Pason Systems", [3]byte{148, 98, 105}: "ARRIS Group, Inc.", + [3]byte{148, 99, 114}: "vivo Mobile Communication Co., Ltd.", [3]byte{148, 99, 209}: "Samsung Electronics Co.,Ltd", [3]byte{148, 101, 45}: "OnePlus Technology (Shenzhen) Co., Ltd", [3]byte{148, 101, 156}: "Intel Corporate", [3]byte{148, 102, 231}: "WOM Engineering", + [3]byte{148, 106, 176}: "Arcadyan Corporation", [3]byte{148, 112, 210}: "WINFIRM TECHNOLOGY", [3]byte{148, 113, 172}: "TCT mobile ltd", [3]byte{148, 117, 110}: "QinetiQ North America", @@ -19346,27 +20223,36 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{148, 134, 205}: "SEOUL ELECTRONICS&TELECOM", [3]byte{148, 134, 212}: "Surveillance Pro Corporation", [3]byte{148, 135, 124}: "ARRIS Group, Inc.", + [3]byte{148, 135, 224}: "Xiaomi Communications Co Ltd", [3]byte{148, 136, 21}: "Infinique Worldwide Inc", [3]byte{148, 136, 84}: "Texas Instruments", [3]byte{148, 136, 94}: "Surfilter Network Technology Co., Ltd.", [3]byte{148, 139, 3}: "EAGET Innovation and Technology Co., Ltd.", [3]byte{148, 139, 193}: "Samsung Electronics Co.,Ltd", [3]byte{148, 141, 80}: "Beamex Oy Ab", + [3]byte{148, 141, 239}: "Oetiker Schweiz AG", [3]byte{148, 142, 137}: "INDUSTRIAS UNIDAS SA DE CV", + [3]byte{148, 143, 207}: "ARRIS Group, Inc.", [3]byte{148, 143, 238}: "Verizon Telematics", + [3]byte{148, 145, 127}: "ASKEY COMPUTER CORP", [3]byte{148, 146, 188}: "SYNTECH(HK) TECHNOLOGY LIMITED", [3]byte{148, 148, 38}: "Apple, Inc.", [3]byte{148, 149, 160}: "Google, Inc.", [3]byte{148, 152, 162}: "Shanghai LISTEN TECH.LTD", [3]byte{148, 153, 1}: "Shenzhen YITOA Digital Appliance CO.,LTD", + [3]byte{148, 153, 144}: "VTC Telecommunications", [3]byte{148, 154, 169}: "Microsoft Corporation", + [3]byte{148, 155, 44}: "Extreme Networks, Inc.", [3]byte{148, 155, 253}: "Trans New Technology, Inc.", [3]byte{148, 156, 85}: "Alta Data Technologies", + [3]byte{148, 157, 87}: "Panasonic do Brasil Limitada", [3]byte{148, 159, 62}: "Sonos, Inc.", [3]byte{148, 159, 63}: "Optek Digital Technology company limited", [3]byte{148, 159, 180}: "ChengDu JiaFaAnTai Technology Co.,Ltd", [3]byte{148, 160, 78}: "Bostex Technology Co., LTD", [3]byte{148, 161, 162}: "AMPAK Technology, Inc.", + [3]byte{148, 163, 202}: "KonnectONE, LLC", + [3]byte{148, 164, 12}: "Diehl Metering GmbH", [3]byte{148, 167, 183}: "zte corporation", [3]byte{148, 167, 188}: "BodyMedia, Inc.", [3]byte{148, 170, 184}: "Joview(Beijing) Technology Co. Ltd.", @@ -19374,21 +20260,24 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{148, 172, 202}: "trivum technologies GmbH", [3]byte{148, 174, 97}: "Alcatel Lucent", [3]byte{148, 174, 227}: "Belden Hirschmann Industries (Suzhou) Ltd.", + [3]byte{148, 176, 31}: "Apple, Inc.", [3]byte{148, 177, 10}: "Samsung Electronics Co.,Ltd", [3]byte{148, 178, 204}: "PIONEER CORPORATION", [3]byte{148, 180, 15}: "Aruba Networks", [3]byte{148, 184, 25}: "Nokia", + [3]byte{148, 184, 109}: "Intel Corporate", [3]byte{148, 184, 197}: "RuggedCom Inc.", [3]byte{148, 185, 180}: "Aptos Technology", [3]byte{148, 186, 49}: "Visiontec da Amazônia Ltda.", [3]byte{148, 186, 86}: "Shenzhen Coship Electronics Co., Ltd.", [3]byte{148, 187, 174}: "Husqvarna AB", [3]byte{148, 191, 30}: "eflow Inc. / Smart Device Planning and Development Division", + [3]byte{148, 191, 45}: "Apple, Inc.", [3]byte{148, 191, 149}: "Shenzhen Coship Electronics Co., Ltd", [3]byte{148, 192, 20}: "Sorter Sp. j. Konrad Grzeszczyk MichaA, Ziomek", [3]byte{148, 192, 56}: "Tallac Networks", [3]byte{148, 193, 80}: "2Wire Inc", - [3]byte{148, 195, 228}: "SCA Schucker Gmbh & Co KG", + [3]byte{148, 195, 228}: "Atlas Copco IAS GmbH", [3]byte{148, 196, 233}: "PowerLayer Microsystems HongKong Limited", [3]byte{148, 198, 145}: "EliteGroup Computer Systems Co., LTD", [3]byte{148, 198, 235}: "NOVA electronics, Inc.", @@ -19398,7 +20287,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{148, 202, 15}: "Honeywell Analytics", [3]byte{148, 204, 185}: "ARRIS Group, Inc.", [3]byte{148, 205, 172}: "Creowave Oy", - [3]byte{148, 206, 44}: "Sony Mobile Communications AB", + [3]byte{148, 206, 44}: "Sony Mobile Communications Inc", [3]byte{148, 206, 49}: "CTS Limited", [3]byte{148, 208, 25}: "Cydle Corp.", [3]byte{148, 208, 41}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", @@ -19419,6 +20308,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{148, 223, 78}: "Wistron InfoComm(Kunshan)Co.,Ltd.", [3]byte{148, 223, 88}: "IJ Electron CO.,Ltd.", [3]byte{148, 224, 208}: "HealthStream Taiwan Inc.", + [3]byte{148, 224, 214}: "China Dragon Technology Limited", + [3]byte{148, 225, 172}: "Hangzhou Hikvision Digital Technology Co.,Ltd.", [3]byte{148, 226, 38}: "D. ORtiz Consulting, LLC", [3]byte{148, 226, 253}: "Boge Kompressoren OTTO Boge GmbH & Co. KG", [3]byte{148, 227, 109}: "Texas Instruments", @@ -19428,6 +20319,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{148, 233, 106}: "Apple, Inc.", [3]byte{148, 233, 121}: "Liteon Technology Corporation", [3]byte{148, 233, 140}: "Nokia", + [3]byte{148, 234, 234}: "TELLESCOM INDUSTRIA E COMERCIO EM TELECOMUNICACAO", [3]byte{148, 235, 44}: "Google, Inc.", [3]byte{148, 235, 205}: "BlackBerry RTS", [3]byte{148, 241, 40}: "Hewlett Packard Enterprise", @@ -19437,6 +20329,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{148, 246, 101}: "Ruckus Wireless", [3]byte{148, 246, 146}: "Geminico co.,Ltd.", [3]byte{148, 246, 163}: "Apple, Inc.", + [3]byte{148, 246, 214}: "Apple, Inc.", [3]byte{148, 247, 32}: "Tianjin Deviser Electronics Instrument Co., Ltd", [3]byte{148, 250, 232}: "Shenzhen Eycom Technology Co., Ltd", [3]byte{148, 251, 41}: "Zebra Technologies Inc.", @@ -19444,6 +20337,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{148, 253, 29}: "WhereWhen Corp", [3]byte{148, 253, 46}: "Shanghai Uniscope Technologies Co.,Ltd", [3]byte{148, 254, 34}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{148, 254, 157}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", [3]byte{148, 254, 244}: "Sagemcom Broadband SAS", [3]byte{152, 0, 116}: "Raisecom Technology CO., LTD", [3]byte{152, 0, 193}: "GuangZhou CREATOR Technology Co.,Ltd.(CHINA)", @@ -19451,6 +20345,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{152, 1, 167}: "Apple, Inc.", [3]byte{152, 2, 132}: "Theobroma Systems GmbH", [3]byte{152, 2, 216}: "IEEE Registration Authority", + [3]byte{152, 3, 155}: "Mellanox Technologies, Inc.", [3]byte{152, 3, 160}: "ABB n.v. Power Quality Products", [3]byte{152, 3, 216}: "Apple, Inc.", [3]byte{152, 7, 45}: "Texas Instruments", @@ -19461,7 +20356,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{152, 16, 148}: "Shenzhen Vsun communication technology Co.,ltd", [3]byte{152, 16, 232}: "Apple, Inc.", [3]byte{152, 19, 51}: "zte corporation", + [3]byte{152, 20, 210}: "Avonic", [3]byte{152, 22, 236}: "IC Intracom", + [3]byte{152, 24, 136}: "Cisco Meraki", [3]byte{152, 29, 250}: "Samsung Electronics Co.,Ltd", [3]byte{152, 30, 15}: "Jeelan (Shanghai Jeelan Technology Information Inc", [3]byte{152, 31, 177}: "Shenzhen Lemon Network Technology Co.,Ltd", @@ -19486,10 +20383,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{152, 55, 19}: "PT.Navicom Indonesia", [3]byte{152, 57, 142}: "Samsung Electronics Co.,Ltd", [3]byte{152, 59, 22}: "AMPAK Technology, Inc.", + [3]byte{152, 59, 143}: "Intel Corporate", [3]byte{152, 63, 159}: "China SSJ (Suzhou) Network Technology Inc.", [3]byte{152, 64, 187}: "Dell Inc.", [3]byte{152, 66, 70}: "SOL INDUSTRY PTE., LTD", [3]byte{152, 67, 218}: "INTERTECH", + [3]byte{152, 69, 98}: "Shanghai Baud Data Communication Co.,Ltd.", [3]byte{152, 71, 60}: "SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD", [3]byte{152, 74, 71}: "CHG Hospital Beds", [3]byte{152, 75, 74}: "ARRIS Group, Inc.", @@ -19507,6 +20406,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{152, 91, 176}: "KMDATA INC.", [3]byte{152, 92, 147}: "SBG Systems SAS", [3]byte{152, 93, 70}: "PeopleNet Communication", + [3]byte{152, 93, 130}: "Arista Networks", [3]byte{152, 93, 173}: "Texas Instruments", [3]byte{152, 94, 27}: "ConversDigital Co., Ltd.", [3]byte{152, 95, 211}: "Microsoft Corporation", @@ -19536,6 +20436,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{152, 139, 173}: "Corintech Ltd.", [3]byte{152, 142, 52}: "ZHEJIANG BOXSAM ELECTRONIC CO.,LTD", [3]byte{152, 142, 74}: "NOXUS(BEIJING) TECHNOLOGY CO.,LTD", + [3]byte{152, 142, 212}: "ITEL MOBILE LIMITED", [3]byte{152, 142, 221}: "TE Connectivity Limerick", [3]byte{152, 144, 128}: "Linkpower Network System Inc Ltd.", [3]byte{152, 144, 150}: "Dell Inc.", @@ -19544,30 +20445,37 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{152, 151, 209}: "MitraStar Technology Corp.", [3]byte{152, 156, 87}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{152, 158, 99}: "Apple, Inc.", + [3]byte{152, 164, 4}: "Ericsson AB", [3]byte{152, 164, 14}: "Snap, Inc.", [3]byte{152, 167, 176}: "MCST ZAO", [3]byte{152, 170, 60}: "Will i-tech Co., Ltd.", [3]byte{152, 170, 215}: "BLUE WAVE NETWORKING CO LTD", [3]byte{152, 170, 252}: "IEEE Registration Authority", + [3]byte{152, 174, 113}: "VVDN Technologies Pvt Ltd", [3]byte{152, 176, 57}: "Nokia", [3]byte{152, 182, 233}: "Nintendo Co.,Ltd", [3]byte{152, 184, 227}: "Apple, Inc.", [3]byte{152, 187, 30}: "BYD Precision Manufacture Company Ltd.", + [3]byte{152, 187, 153}: "Phicomm (Sichuan) Co.,Ltd.", [3]byte{152, 188, 87}: "SVA TECHNOLOGIES CO.LTD", [3]byte{152, 188, 153}: "Edeltech Co.,Ltd.", [3]byte{152, 190, 148}: "IBM", [3]byte{152, 192, 235}: "Global Regency Ltd", [3]byte{152, 197, 219}: "Ericsson AB", [3]byte{152, 200, 69}: "PacketAccess", + [3]byte{152, 202, 51}: "Apple, Inc.", [3]byte{152, 203, 39}: "Galore Networks Pvt. Ltd.", + [3]byte{152, 204, 77}: "Shenzhen mantunsci co., LTD", [3]byte{152, 205, 180}: "Virident Systems, Inc.", [3]byte{152, 207, 83}: "BBK EDUCATIONAL ELECTRONICS CORP.,LTD.", [3]byte{152, 210, 147}: "Google, Inc.", [3]byte{152, 211, 49}: "Shenzhen Bolutek Technology Co.,Ltd.", [3]byte{152, 211, 210}: "MEKRA Lang GmbH & Co. KG", + [3]byte{152, 211, 231}: "Netafim L", [3]byte{152, 214, 134}: "Chyi Lee industry Co., ltd.", [3]byte{152, 214, 187}: "Apple, Inc.", [3]byte{152, 214, 247}: "LG Electronics (Mobile Communications)", + [3]byte{152, 216, 99}: "Shanghai High-Flying Electronics Technology Co., Ltd", [3]byte{152, 216, 140}: "Nortel Networks", [3]byte{152, 218, 146}: "Vuzix Corporation", [3]byte{152, 220, 217}: "UNITEC Co., Ltd.", @@ -19581,6 +20489,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{152, 231, 245}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{152, 232, 72}: "Axiim", [3]byte{152, 236, 101}: "Cosesy ApS", + [3]byte{152, 237, 92}: "Tesla Motors, Inc", [3]byte{152, 238, 203}: "Wistron Infocomm (Zhongshan) Corporation", [3]byte{152, 239, 155}: "OHSUNG", [3]byte{152, 240, 88}: "Lynxspring, Incl.", @@ -19594,6 +20503,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{152, 247, 215}: "ARRIS Group, Inc.", [3]byte{152, 248, 193}: "IDT Technology Limited", [3]byte{152, 248, 219}: "Marini Impianti Industriali s.r.l.", + [3]byte{152, 249, 199}: "IEEE Registration Authority", [3]byte{152, 250, 227}: "Xiaomi Communications Co Ltd", [3]byte{152, 251, 18}: "Grand Electronics (HK) Ltd", [3]byte{152, 252, 17}: "Cisco-Linksys, LLC", @@ -19610,12 +20520,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{156, 4, 235}: "Apple, Inc.", [3]byte{156, 6, 27}: "Hangzhou H3C Technologies Co., Limited", [3]byte{156, 6, 110}: "Hytera Communications Corporation Limited", + [3]byte{156, 12, 223}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{156, 13, 172}: "Tymphany HK Limited", [3]byte{156, 14, 74}: "Shenzhen Vastking Electronic Co.,Ltd.", [3]byte{156, 19, 171}: "Chanson Water Co., Ltd.", [3]byte{156, 20, 101}: "Edata Elektronik San. ve Tic. A.Ş.", [3]byte{156, 24, 116}: "Nokia Danmark A/S", [3]byte{156, 28, 18}: "Aruba Networks", + [3]byte{156, 29, 54}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{156, 29, 88}: "Texas Instruments", [3]byte{156, 30, 149}: "Actiontec Electronics, Inc", [3]byte{156, 31, 221}: "Accupix Inc.", @@ -19628,11 +20540,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{156, 41, 63}: "Apple, Inc.", [3]byte{156, 42, 112}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{156, 42, 131}: "Samsung Electronics Co.,Ltd", + [3]byte{156, 46, 161}: "Xiaomi Communications Co Ltd", + [3]byte{156, 47, 115}: "Universal Tiancheng Technology (Beijing) Co., Ltd.", [3]byte{156, 48, 91}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{156, 48, 102}: "RWE Effizienz GmbH", [3]byte{156, 49, 120}: "Foshan Huadian Intelligent Communications Teachnologies Co.,Ltd", [3]byte{156, 49, 182}: "Kulite Semiconductor Products Inc", [3]byte{156, 50, 169}: "SICHUAN TIANYI COMHEART TELECOMCO., LTD", + [3]byte{156, 50, 206}: "CANON INC.", [3]byte{156, 52, 38}: "ARRIS Group, Inc.", [3]byte{156, 53, 131}: "Nipro Diagnostics, Inc", [3]byte{156, 53, 235}: "Apple, Inc.", @@ -19641,6 +20556,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{156, 61, 207}: "NETGEAR", [3]byte{156, 62, 170}: "EnvyLogic Co.,Ltd.", [3]byte{156, 65, 124}: "Hame Technology Co., Limited", + [3]byte{156, 67, 30}: "IEEE Registration Authority", [3]byte{156, 68, 61}: "CHENGDU XUGUANG TECHNOLOGY CO, LTD", [3]byte{156, 68, 166}: "SwiftTest, Inc.", [3]byte{156, 69, 99}: "DIMEP Sistemas", @@ -19660,10 +20576,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{156, 85, 180}: "I.S.E. S.r.l.", [3]byte{156, 87, 17}: "Feitian Xunda(Beijing) Aeronautical Information Technology Co., Ltd.", [3]byte{156, 87, 173}: "Cisco Systems, Inc", + [3]byte{156, 90, 68}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", [3]byte{156, 91, 150}: "NMR Corporation", [3]byte{156, 92, 141}: "FIREMAX INDÚSTRIA E COMÉRCIO DE PRODUTOS ELETRÔNICOS LTDA", [3]byte{156, 92, 142}: "ASUSTek COMPUTER INC.", - [3]byte{156, 92, 249}: "Sony Mobile Communications AB", + [3]byte{156, 92, 249}: "Sony Mobile Communications Inc", [3]byte{156, 93, 18}: "Aerohive Networks Inc.", [3]byte{156, 93, 149}: "VTC Electronics Corp.", [3]byte{156, 94, 115}: "Calibre UK LTD", @@ -19672,14 +20589,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{156, 98, 171}: "Sumavision Technologies Co.,Ltd", [3]byte{156, 99, 237}: "zte corporation", [3]byte{156, 100, 94}: "Harman Consumer Group", + [3]byte{156, 100, 139}: "Apple, Inc.", [3]byte{156, 101, 176}: "Samsung Electronics Co.,Ltd", [3]byte{156, 101, 238}: "DASAN Network Solutions", [3]byte{156, 101, 249}: "AcSiP Technology Corp.", [3]byte{156, 102, 80}: "Glodio Technolies Co.,Ltd Tianjin Branch", [3]byte{156, 104, 91}: "Octonion SA", + [3]byte{156, 105, 55}: "Qorvo Utrecht B.V.", [3]byte{156, 106, 190}: "QEES ApS.", [3]byte{156, 108, 21}: "Microsoft Corporation", [3]byte{156, 111, 82}: "zte corporation", + [3]byte{156, 113, 58}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{156, 116, 26}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{156, 117, 20}: "Wildix srl", [3]byte{156, 119, 170}: "NADASNV", @@ -19687,8 +20607,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{156, 122, 3}: "Ciena Corporation", [3]byte{156, 123, 210}: "NEOLAB Convergence", [3]byte{156, 125, 163}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{156, 127, 87}: "UNIC Memory Technology Co Ltd", [3]byte{156, 128, 125}: "SYSCABLE Korea Inc.", [3]byte{156, 128, 223}: "Arcadyan Technology Corporation", + [3]byte{156, 130, 117}: "Yichip\u00a0Microelectronics (Hangzhou) Co.,Ltd", [3]byte{156, 131, 191}: "PRO-VISION, Inc.", [3]byte{156, 132, 191}: "Apple, Inc.", [3]byte{156, 134, 218}: "Phoenix Geophysics Ltd.", @@ -19697,6 +20619,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{156, 139, 160}: "Apple, Inc.", [3]byte{156, 139, 241}: "The Warehouse Limited", [3]byte{156, 140, 110}: "Samsung Electronics Co.,Ltd", + [3]byte{156, 140, 216}: "Hewlett Packard Enterprise", [3]byte{156, 141, 26}: "INTEG process group inc", [3]byte{156, 141, 124}: "ALPS ELECTRIC CO.,LTD.", [3]byte{156, 141, 211}: "Leonton Technologies", @@ -19716,10 +20639,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{156, 161, 52}: "Nike, Inc.", [3]byte{156, 163, 169}: "Guangzhou Juan Optical and Electronical Tech Joint Stock Co., Ltd", [3]byte{156, 163, 186}: "SAKURA Internet Inc.", + [3]byte{156, 165, 37}: "Shandong USR IOT Technology Limited", [3]byte{156, 165, 119}: "Osorno Enterprises Inc.", [3]byte{156, 165, 192}: "vivo Mobile Communication Co., Ltd.", + [3]byte{156, 166, 21}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{156, 166, 157}: "Whaley Technology Co.Ltd", [3]byte{156, 169, 228}: "zte corporation", + [3]byte{156, 170, 27}: "Microsoft Corporation", [3]byte{156, 172, 109}: "Universal Electronics, Inc.", [3]byte{156, 173, 151}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{156, 173, 239}: "Obihai Technology, Inc.", @@ -19742,6 +20668,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{156, 199, 166}: "AVM GmbH", [3]byte{156, 199, 209}: "SHARP Corporation", [3]byte{156, 200, 174}: "Becton, Dickinson and Company", + [3]byte{156, 200, 252}: "ARRIS Group, Inc.", + [3]byte{156, 201, 80}: "Baumer Holding", [3]byte{156, 202, 217}: "Nokia Corporation", [3]byte{156, 204, 131}: "Juniper Networks", [3]byte{156, 205, 130}: "CHENG UEI PRECISION INDUSTRY CO.,LTD", @@ -19766,8 +20694,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{156, 227, 63}: "Apple, Inc.", [3]byte{156, 227, 116}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{156, 230, 53}: "Nintendo Co., Ltd.", + [3]byte{156, 230, 94}: "Apple, Inc.", [3]byte{156, 230, 231}: "Samsung Electronics Co.,Ltd", [3]byte{156, 231, 189}: "Winduskorea co., Ltd", + [3]byte{156, 232, 43}: "vivo Mobile Communication Co., Ltd.", + [3]byte{156, 232, 149}: "New H3C Technologies Co., Ltd", [3]byte{156, 233, 81}: "Shenzhen Sang Fei Consumer Communications Ltd., Co.", [3]byte{156, 235, 232}: "BizLink (Kunshan) Co.,Ltd", [3]byte{156, 239, 213}: "Panda Wireless, Inc.", @@ -19775,12 +20706,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{156, 244, 142}: "Apple, Inc.", [3]byte{156, 246, 26}: "UTC Fire and Security", [3]byte{156, 246, 125}: "Ricardo Prague, s.r.o.", + [3]byte{156, 246, 221}: "IEEE Registration Authority", [3]byte{156, 248, 219}: "shenzhen eyunmei technology co,.ltd", [3]byte{156, 249, 56}: "AREVA NP GmbH", [3]byte{156, 251, 213}: "vivo Mobile Communication Co., Ltd.", [3]byte{156, 251, 241}: "MESOMATIC GmbH & Co.KG", [3]byte{156, 252, 1}: "Apple, Inc.", [3]byte{156, 252, 209}: "Aetheris Technology (Shanghai) Co., Ltd.", + [3]byte{156, 254, 161}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{156, 255, 190}: "OTSL Inc.", [3]byte{160, 2, 220}: "Amazon Technologies Inc.", [3]byte{160, 3, 99}: "Robert Bosch Healthcare GmbH", @@ -19805,6 +20738,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{160, 24, 40}: "Apple, Inc.", [3]byte{160, 24, 89}: "Shenzhen Yidashi Electronics Co Ltd", [3]byte{160, 25, 23}: "Bertel S.p.a.", + [3]byte{160, 25, 178}: "IEEE Registration Authority", [3]byte{160, 27, 41}: "Sagemcom Broadband SAS", [3]byte{160, 28, 5}: "NIMAX TELECOM CO.,LTD.", [3]byte{160, 29, 72}: "Hewlett Packard", @@ -19814,6 +20748,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{160, 33, 183}: "NETGEAR", [3]byte{160, 35, 27}: "TeleComp R&D Corp.", [3]byte{160, 35, 159}: "Cisco Systems, Inc", + [3]byte{160, 40, 51}: "IEEE Registration Authority", [3]byte{160, 43, 184}: "Hewlett Packard", [3]byte{160, 44, 54}: "FN-LINK TECHNOLOGY LIMITED", [3]byte{160, 46, 243}: "United Integrated Services Co., Led.", @@ -19822,6 +20757,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{160, 54, 159}: "Intel Corporate", [3]byte{160, 54, 240}: "Comprehensive Power", [3]byte{160, 54, 250}: "Ettus Research LLC", + [3]byte{160, 56, 248}: "OURA Health Oy", + [3]byte{160, 57, 238}: "Sagemcom Broadband SAS", [3]byte{160, 57, 247}: "LG Electronics (Mobile Communications)", [3]byte{160, 58, 117}: "PSS Belgium N.V.", [3]byte{160, 59, 27}: "Inspire Tech", @@ -19835,6 +20772,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{160, 65, 167}: "NL Ministry of Defense", [3]byte{160, 66, 63}: "Tyan Computer Corp", [3]byte{160, 67, 219}: "Sitael S.p.A.", + [3]byte{160, 71, 215}: "Best IT World (India) Pvt Ltd", [3]byte{160, 72, 28}: "Hewlett Packard", [3]byte{160, 76, 91}: "Shenzhen TINNO Mobile Technology Corp.", [3]byte{160, 76, 193}: "Helixtech Corp.", @@ -19846,6 +20784,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{160, 85, 79}: "Cisco Systems, Inc", [3]byte{160, 85, 222}: "ARRIS Group, Inc.", [3]byte{160, 86, 178}: "Harman/Becker Automotive Systems GmbH", + [3]byte{160, 86, 243}: "Apple, Inc.", + [3]byte{160, 87, 227}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{160, 89, 58}: "V.D.S. Video Display Systems srl", [3]byte{160, 90, 164}: "Grand Products Nevada, Inc.", [3]byte{160, 91, 33}: "ENVINET GmbH", @@ -19856,6 +20796,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{160, 99, 145}: "NETGEAR", [3]byte{160, 100, 143}: "ASKEY COMPUTER CORP", [3]byte{160, 101, 24}: "VNPT TECHNOLOGY", + [3]byte{160, 102, 16}: "FUJITSU LIMITED", [3]byte{160, 103, 190}: "Sicon srl", [3]byte{160, 105, 134}: "Wellav Technologies Ltd", [3]byte{160, 106, 0}: "Verilink Corporation", @@ -19871,6 +20812,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{160, 115, 50}: "Cashmaster International Limited", [3]byte{160, 115, 252}: "Rancore Technologies Private Limited", [3]byte{160, 117, 145}: "Samsung Electronics Co.,Ltd", + [3]byte{160, 117, 234}: "BoxLock, Inc.", [3]byte{160, 119, 113}: "Vialis BV", [3]byte{160, 120, 186}: "Pantech Co., Ltd.", [3]byte{160, 130, 31}: "Samsung Electronics Co.,Ltd", @@ -19894,7 +20836,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{160, 145, 105}: "LG Electronics (Mobile Communications)", [3]byte{160, 145, 200}: "zte corporation", [3]byte{160, 147, 71}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", - [3]byte{160, 149, 12}: "China Mobile IOTCompany Limited", + [3]byte{160, 147, 81}: "Cisco Systems, Inc", + [3]byte{160, 149, 12}: "China Mobile IOT Company Limited", [3]byte{160, 152, 5}: "OpenVox Communication Co Ltd", [3]byte{160, 152, 237}: "Shandong Intelligent Optical Communication Development Co., Ltd.", [3]byte{160, 153, 155}: "Apple, Inc.", @@ -19907,7 +20850,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{160, 161, 48}: "DLI Taiwan Branch office", [3]byte{160, 162, 60}: "GPMS", [3]byte{160, 163, 59}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{160, 163, 184}: "WISCLOUD", [3]byte{160, 163, 226}: "Actiontec Electronics, Inc", + [3]byte{160, 164, 197}: "Intel Corporate", [3]byte{160, 166, 92}: "Supercomputing Systems AG", [3]byte{160, 167, 99}: "Polytron Vertrieb GmbH", [3]byte{160, 168, 205}: "Intel Corporate", @@ -19915,10 +20860,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{160, 171, 27}: "D-Link International", [3]byte{160, 173, 161}: "JMR Electronics, Inc", [3]byte{160, 175, 189}: "Intel Corporate", + [3]byte{160, 176, 69}: "Halong Mining", [3]byte{160, 177, 0}: "ShenZhen Cando Electronics Co.,Ltd", [3]byte{160, 179, 204}: "Hewlett Packard", [3]byte{160, 180, 55}: "GD Mission Systems", [3]byte{160, 180, 165}: "Samsung Electronics Co.,Ltd", + [3]byte{160, 181, 73}: "Arcadyan Corporation", [3]byte{160, 181, 218}: "HongKong THTF Co., Ltd", [3]byte{160, 182, 98}: "Acutvista Innovation Co., Ltd.", [3]byte{160, 184, 248}: "Amgen U.S.A. Inc.", @@ -19944,6 +20891,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{160, 211, 122}: "Intel Corporate", [3]byte{160, 211, 133}: "AUMA Riester GmbH & Co. KG", [3]byte{160, 211, 193}: "Hewlett Packard", + [3]byte{160, 214, 53}: "WBS Technology", [3]byte{160, 215, 149}: "Apple, Inc.", [3]byte{160, 216, 111}: "Private", [3]byte{160, 218, 146}: "Nanjing Glarun Atten Technology Co. Ltd.", @@ -19955,10 +20903,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{160, 226, 1}: "AVTrace Ltd.(China)", [3]byte{160, 226, 90}: "Amicus SK, s.r.o.", [3]byte{160, 226, 149}: "DAT System Co.,Ltd", - [3]byte{160, 228, 83}: "Sony Mobile Communications AB", + [3]byte{160, 228, 83}: "Sony Mobile Communications Inc", [3]byte{160, 228, 203}: "Zyxel Communications Corporation", [3]byte{160, 229, 52}: "Stratec Biomedical AG", [3]byte{160, 229, 233}: "enimai Inc", + [3]byte{160, 230, 23}: "MATIS", [3]byte{160, 230, 248}: "Texas Instruments", [3]byte{160, 233, 219}: "Ningbo FreeWings Technologies Co.,Ltd", [3]byte{160, 235, 118}: "AirCUVE Inc.", @@ -19989,15 +20938,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{164, 8, 245}: "Sagemcom Broadband SAS", [3]byte{164, 9, 203}: "Alfred Kaercher GmbH & Co KG", [3]byte{164, 11, 237}: "Carry Technology Co.,Ltd", + [3]byte{164, 12, 102}: "Shenzhen Colorful Yugong Technology and Development Co., Ltd.", [3]byte{164, 12, 195}: "Cisco Systems, Inc", [3]byte{164, 13, 188}: "Xiamen Intretech Inc.", [3]byte{164, 14, 43}: "Facebook Inc", [3]byte{164, 17, 21}: "Robert Bosch Engineering and Business Solutions pvt. Ltd.", [3]byte{164, 17, 99}: "IEEE Registration Authority", + [3]byte{164, 17, 148}: "Lenovo", [3]byte{164, 18, 66}: "NEC Platforms, Ltd.", [3]byte{164, 19, 78}: "Luxul", [3]byte{164, 20, 55}: "Hangzhou Hikvision Digital Technology Co.,Ltd.", - [3]byte{164, 21, 102}: "Weifang GoerTek Technology Co.,Ltd.", + [3]byte{164, 21, 102}: "WEIFANG GOERTEK ELECTRONICS CO.,LTD", [3]byte{164, 21, 136}: "ARRIS Group, Inc.", [3]byte{164, 23, 49}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{164, 24, 117}: "Cisco Systems, Inc", @@ -20008,6 +20959,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{164, 36, 179}: "FlatFrog Laboratories AB", [3]byte{164, 36, 221}: "Cambrionix Ltd", [3]byte{164, 37, 27}: "Avaya Inc", + [3]byte{164, 38, 24}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", + [3]byte{164, 38, 85}: "LTI Motion (Shanghai) Co., Ltd.", [3]byte{164, 41, 64}: "Shenzhen YOUHUA Technology Co., Ltd", [3]byte{164, 41, 131}: "Boeing Defence Australia", [3]byte{164, 41, 183}: "bluesky", @@ -20017,15 +20970,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{164, 49, 17}: "ZIV", [3]byte{164, 49, 53}: "Apple, Inc.", [3]byte{164, 51, 209}: "Fibrlink Communications Co.,Ltd.", + [3]byte{164, 51, 215}: "MitraStar Technology Corp.", [3]byte{164, 52, 18}: "Thales Alenia Space", [3]byte{164, 52, 217}: "Intel Corporate", [3]byte{164, 52, 241}: "Texas Instruments", + [3]byte{164, 53, 35}: "Guangdong Donyan Network Technologies Co.,Ltd.", [3]byte{164, 56, 49}: "RF elements s.r.o.", + [3]byte{164, 56, 204}: "Nintendo Co.,Ltd", [3]byte{164, 56, 252}: "Plastic Logic", [3]byte{164, 58, 105}: "Vers Inc", [3]byte{164, 59, 250}: "IEEE Registration Authority", [3]byte{164, 61, 120}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{164, 62, 81}: "ANOV FRANCE", + [3]byte{164, 64, 39}: "zte corporation", [3]byte{164, 68, 209}: "Wingtech Group (HongKong)Limited", [3]byte{164, 70, 107}: "EOC Technology", [3]byte{164, 70, 250}: "AmTRAN Video Corporation", @@ -20036,13 +20993,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{164, 78, 45}: "Adaptive Wireless Solutions, LLC", [3]byte{164, 78, 49}: "Intel Corporate", [3]byte{164, 79, 41}: "IEEE Registration Authority", - [3]byte{164, 80, 85}: "busware.de", + [3]byte{164, 80, 70}: "Xiaomi Communications Co Ltd", + [3]byte{164, 80, 85}: "BUSWARE.DE", [3]byte{164, 81, 111}: "Microsoft Mobile Oy", [3]byte{164, 82, 111}: "ADB Broadband Italia", - [3]byte{164, 83, 133}: "Weifang GoerTek Technology Co.,Ltd.", + [3]byte{164, 83, 133}: "WEIFANG GOERTEK ELECTRONICS CO.,LTD", [3]byte{164, 86, 2}: "fenglian Technology Co.,Ltd.", [3]byte{164, 86, 27}: "MCOT Corporation", [3]byte{164, 86, 48}: "Cisco Systems, Inc", + [3]byte{164, 86, 204}: "Technicolor CH USA Inc.", [3]byte{164, 88, 15}: "IEEE Registration Authority", [3]byte{164, 90, 28}: "smart-electronic GmbH", [3]byte{164, 92, 39}: "Nintendo Co., Ltd.", @@ -20051,11 +21010,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{164, 94, 96}: "Apple, Inc.", [3]byte{164, 96, 17}: "Verifone", [3]byte{164, 96, 50}: "MRV Communications (Networks) LTD", + [3]byte{164, 97, 145}: "NamJunSa", [3]byte{164, 98, 223}: "DS Global. Co., LTD", [3]byte{164, 103, 6}: "Apple, Inc.", [3]byte{164, 104, 188}: "Private", [3]byte{164, 108, 42}: "Cisco Systems, Inc", [3]byte{164, 108, 193}: "LTi REEnergy GmbH", + [3]byte{164, 108, 241}: "Samsung Electronics Co.,Ltd", [3]byte{164, 110, 121}: "DFT System Co.Ltd", [3]byte{164, 112, 214}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{164, 113, 116}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -20078,17 +21039,22 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{164, 133, 107}: "Q Electronics Ltd", [3]byte{164, 134, 174}: "Quectel Wireless Solutions", [3]byte{164, 137, 91}: "ARK INFOSOLUTIONS PVT LTD", + [3]byte{164, 140, 192}: "JLG Industries, Inc.", [3]byte{164, 140, 219}: "Lenovo", [3]byte{164, 141, 59}: "Vizio, Inc", [3]byte{164, 142, 10}: "DeLaval International AB", [3]byte{164, 144, 5}: "CHINA GREATWALL COMPUTER SHENZHEN CO.,LTD", [3]byte{164, 145, 177}: "Technicolor", + [3]byte{164, 146, 203}: "Nokia", + [3]byte{164, 147, 63}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{164, 147, 76}: "Cisco Systems, Inc", + [3]byte{164, 148, 38}: "Elgama-Elektronika Ltd.", [3]byte{164, 151, 187}: "Hitachi Industrial Equipment Systems Co.,Ltd", [3]byte{164, 153, 71}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{164, 153, 129}: "FuJian Elite Power Tech CO.,LTD.", [3]byte{164, 154, 88}: "Samsung Electronics Co.,Ltd", [3]byte{164, 155, 19}: "Digital Check", + [3]byte{164, 155, 79}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{164, 155, 245}: "Hybridserver Tec GmbH", [3]byte{164, 157, 73}: "Ketra, Inc.", [3]byte{164, 158, 219}: "AutoCrib, Inc.", @@ -20116,6 +21082,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{164, 186, 118}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{164, 186, 219}: "Dell Inc.", [3]byte{164, 187, 175}: "Lime Instruments", + [3]byte{164, 190, 43}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{164, 190, 97}: "EutroVision System, Inc.", [3]byte{164, 191, 1}: "Intel Corporate", [3]byte{164, 192, 199}: "ShenZhen Hitom Communication Technology Co..LTD", @@ -20134,10 +21101,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{164, 209, 209}: "ECOtality North America", [3]byte{164, 209, 210}: "Apple, Inc.", [3]byte{164, 211, 181}: "GLITEL Stropkov, s.r.o.", + [3]byte{164, 212, 178}: "Shenzhen MeiG Smart Technology Co.,Ltd", [3]byte{164, 213, 120}: "Texas Instruments", [3]byte{164, 216, 86}: "Gimbal, Inc", [3]byte{164, 216, 202}: "HONG KONG WATER WORLD TECHNOLOGY CO. LIMITED", + [3]byte{164, 217, 49}: "Apple, Inc.", + [3]byte{164, 217, 144}: "Samsung Electronics Co.,Ltd", [3]byte{164, 217, 164}: "neXus ID Solutions AB", + [3]byte{164, 218, 34}: "IEEE Registration Authority", + [3]byte{164, 218, 50}: "Texas Instruments", [3]byte{164, 218, 63}: "Bionics Corp.", [3]byte{164, 219, 46}: "Kingspan Environmental Ltd", [3]byte{164, 219, 48}: "Liteon Technology Corporation", @@ -20149,13 +21121,16 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{164, 227, 145}: "DENY FONTAINE", [3]byte{164, 228, 184}: "BlackBerry RTS", [3]byte{164, 229, 151}: "Gessler GmbH", + [3]byte{164, 230, 21}: "SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD", [3]byte{164, 230, 177}: "Shanghai Joindata Technology Co.,Ltd.", [3]byte{164, 231, 49}: "Nokia Corporation", [3]byte{164, 231, 228}: "Connex GmbH", [3]byte{164, 233, 117}: "Apple, Inc.", [3]byte{164, 233, 145}: "SISTEMAS AUDIOVISUALES ITELSIS S.L.", [3]byte{164, 233, 163}: "Honest Technology Co., Ltd", + [3]byte{164, 234, 142}: "Extreme Networks, Inc.", [3]byte{164, 235, 211}: "Samsung Electronics Co.,Ltd", + [3]byte{164, 237, 67}: "IEEE Registration Authority", [3]byte{164, 237, 78}: "ARRIS Group, Inc.", [3]byte{164, 238, 87}: "Seiko Epson Corporation", [3]byte{164, 239, 82}: "Telewave Co., Ltd.", @@ -20166,18 +21141,22 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{164, 245, 34}: "CHOFU SEISAKUSHO CO.,LTD", [3]byte{164, 247, 208}: "LAN Accessories Co., Ltd.", [3]byte{164, 251, 141}: "Hangzhou Dunchong Technology Co.Ltd", + [3]byte{164, 252, 119}: "Mega Well Limited", [3]byte{164, 252, 206}: "Security Expert Ltd.", + [3]byte{168, 1, 109}: "Aiwa Corporation", [3]byte{168, 1, 128}: "IMAGO Technologies GmbH", [3]byte{168, 6, 0}: "Samsung Electronics Co.,Ltd", [3]byte{168, 12, 13}: "Cisco Systems, Inc", [3]byte{168, 12, 99}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{168, 12, 202}: "Shenzhen Sundray Technologies Company Limited", + [3]byte{168, 16, 135}: "Texas Instruments", [3]byte{168, 17, 252}: "ARRIS Group, Inc.", [3]byte{168, 19, 116}: "Panasonic Corporation AVC Networks Company", [3]byte{168, 21, 77}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{168, 21, 89}: "Breathometer, Inc.", [3]byte{168, 21, 214}: "Shenzhen Meione Technology CO., LTD", [3]byte{168, 22, 178}: "LG Electronics (Mobile Communications)", + [3]byte{168, 22, 208}: "Samsung Electronics Co.,Ltd", [3]byte{168, 23, 88}: "Elektronik System i Umeå AB", [3]byte{168, 27, 24}: "XTS CORP", [3]byte{168, 27, 90}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", @@ -20187,15 +21166,20 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{168, 30, 132}: "QUANTA COMPUTER INC.", [3]byte{168, 31, 175}: "KRYPTON POLSKA", [3]byte{168, 32, 102}: "Apple, Inc.", + [3]byte{168, 35, 254}: "LG Electronics", [3]byte{168, 36, 235}: "ZAO NPO Introtest", [3]byte{168, 37, 235}: "Cambridge Industries(Group) Co.,Ltd.", [3]byte{168, 38, 217}: "HTC Corporation", [3]byte{168, 41, 76}: "Precision Optical Transceivers, Inc.", [3]byte{168, 43, 181}: "Edgecore Networks Corporation", + [3]byte{168, 43, 185}: "Samsung Electronics Co.,Ltd", [3]byte{168, 43, 214}: "Shina System Co., Ltd", - [3]byte{168, 48, 173}: "Weifang GoerTek Technology Co.,Ltd.", + [3]byte{168, 48, 173}: "WEIFANG GOERTEK ELECTRONICS CO.,LTD", [3]byte{168, 50, 154}: "Digicom Futuristic Technologies Ltd.", + [3]byte{168, 54, 122}: "frogblue TECHNOLOGY GmbH", [3]byte{168, 57, 68}: "Actiontec Electronics, Inc", + [3]byte{168, 62, 14}: "HMD Global Oy", + [3]byte{168, 63, 161}: "IEEE Registration Authority", [3]byte{168, 64, 65}: "Dragino Technology Co., Limited", [3]byte{168, 68, 129}: "Nokia Corporation", [3]byte{168, 69, 205}: "Siselectron Technology LTD.", @@ -20203,16 +21187,20 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{168, 71, 74}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{168, 73, 165}: "Lisantech Co., Ltd.", [3]byte{168, 78, 63}: "Hitron Technologies. Inc", + [3]byte{168, 81, 91}: "Samsung Electronics Co.,Ltd", [3]byte{168, 84, 178}: "Wistron Neweb Corporation", [3]byte{168, 85, 106}: "Pocketnet Technology Inc.", [3]byte{168, 87, 78}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{168, 88, 64}: "Cambridge Industries(Group) Co.,Ltd.", + [3]byte{168, 90, 243}: "Shanghai Siflower Communication Technology Co., Ltd", + [3]byte{168, 91, 108}: "Robert Bosch Gmbh, CM-CI2", [3]byte{168, 91, 120}: "Apple, Inc.", [3]byte{168, 91, 176}: "Shenzhen Dehoo Technology Co.,Ltd", [3]byte{168, 91, 243}: "Audivo GmbH", [3]byte{168, 92, 44}: "Apple, Inc.", [3]byte{168, 94, 228}: "12Sided Technology, LLC", [3]byte{168, 96, 182}: "Apple, Inc.", + [3]byte{168, 97, 10}: "ARDUINO AG", [3]byte{168, 97, 170}: "Cloudview Limited", [3]byte{168, 98, 162}: "JIWUMEDIA CO., LTD.", [3]byte{168, 99, 223}: "DISPLAIRE CORPORATION", @@ -20232,6 +21220,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{168, 119, 111}: "Zonoff", [3]byte{168, 123, 57}: "Nokia Corporation", [3]byte{168, 124, 1}: "Samsung Electronics Co.,Ltd", + [3]byte{168, 125, 18}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{168, 126, 51}: "Nokia Danmark A/S", [3]byte{168, 128, 56}: "ShenZhen MovingComm Technology Co., Limited", [3]byte{168, 129, 149}: "Samsung Electronics Co.,Ltd", @@ -20240,12 +21229,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{168, 130, 127}: "CIBN Oriental Network(Beijing) CO.,Ltd", [3]byte{168, 134, 221}: "Apple, Inc.", [3]byte{168, 135, 146}: "Broadband Antenna Tracking Systems", + [3]byte{168, 135, 179}: "Samsung Electronics Co.,Ltd", [3]byte{168, 135, 237}: "ARC Wireless LLC", [3]byte{168, 136, 8}: "Apple, Inc.", [3]byte{168, 140, 238}: "MicroMade Galka i Drozdz sp.j.", [3]byte{168, 141, 123}: "SunDroid Global limited.", [3]byte{168, 142, 36}: "Apple, Inc.", [3]byte{168, 144, 8}: "Beijing Yuecheng Technology Co. Ltd.", + [3]byte{168, 144, 66}: "Beijing Wanwei Intelligent Technology Co., Ltd.", [3]byte{168, 146, 44}: "LG Electronics (Mobile Communications)", [3]byte{168, 147, 82}: "SHANGHAI ZHONGMI COMMUNICATION TECHNOLOGY CO.,LTD", [3]byte{168, 147, 230}: "JIANGXI JINGGANGSHAN CKING COMMUNICATION TECHNOLOGY CO.,LTD", @@ -20255,7 +21246,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{168, 151, 220}: "IBM", [3]byte{168, 152, 198}: "Shinbo Co., Ltd.", [3]byte{168, 153, 92}: "aizo ag", + [3]byte{168, 153, 105}: "Dell Inc.", + [3]byte{168, 154, 147}: "Sagemcom Broadband SAS", [3]byte{168, 155, 16}: "inMotion Ltd.", + [3]byte{168, 156, 164}: "Furrion Limited", [3]byte{168, 157, 33}: "Cisco Systems, Inc", [3]byte{168, 157, 210}: "Shanghai DareGlobal Technologies Co.,Ltd", [3]byte{168, 159, 186}: "Samsung Electronics Co.,Ltd", @@ -20270,10 +21264,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{168, 176, 174}: "LEONI", [3]byte{168, 177, 212}: "Cisco Systems, Inc", [3]byte{168, 178, 218}: "FUJITSU LIMITED", + [3]byte{168, 180, 86}: "Cisco Systems, Inc", [3]byte{168, 184, 110}: "LG Electronics (Mobile Communications)", [3]byte{168, 185, 179}: "ESSYS", [3]byte{168, 187, 80}: "WiZ IoT Company Limited", [3]byte{168, 187, 207}: "Apple, Inc.", + [3]byte{168, 188, 156}: "Cloud Light Technology Limited", [3]byte{168, 189, 26}: "Honey Bee (Hong Kong) Limited", [3]byte{168, 189, 39}: "Hewlett Packard Enterprise", [3]byte{168, 189, 58}: "UNIONMAN TECHNOLOGY CO.,LTD", @@ -20282,6 +21278,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{168, 200, 58}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{168, 200, 127}: "Roqos, Inc.", [3]byte{168, 202, 123}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{168, 202, 185}: "SAMSUNG ELECTRO MECHANICS CO., LTD.", [3]byte{168, 203, 149}: "EAST BEST CO., LTD.", [3]byte{168, 204, 197}: "Saab AB (publ)", [3]byte{168, 206, 144}: "CVC", @@ -20291,12 +21288,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{168, 211, 200}: "Topcon Electronics GmbH & Co. KG", [3]byte{168, 211, 247}: "Arcadyan Technology Corporation", [3]byte{168, 212, 9}: "USA 111 Inc", + [3]byte{168, 212, 152}: "Avira Operations GmbH & Co. KG", [3]byte{168, 213, 121}: "Beijing Chushang Science and Technology Co.,Ltd", [3]byte{168, 216, 40}: "Ascensia Diabetes Care", [3]byte{168, 216, 138}: "Wyconn", + [3]byte{168, 218, 1}: "Shenzhen NUOLIJIA Digital Technology Co.,Ltd", [3]byte{168, 224, 24}: "Nokia Corporation", [3]byte{168, 227, 238}: "Sony Interactive Entertainment Inc.", [3]byte{168, 229, 57}: "Moimstone Co.,Ltd", + [3]byte{168, 229, 82}: "JUWEL Aquarium AG & Co. KG", [3]byte{168, 231, 5}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{168, 232, 36}: "INIM ELECTRONICS S.R.L.", [3]byte{168, 238, 198}: "Muuselabs NV/SA", @@ -20304,6 +21304,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{168, 240, 56}: "SHEN ZHEN SHI JIN HUA TAI ELECTRONICS CO.,LTD", [3]byte{168, 242, 116}: "Samsung Electronics Co.,Ltd", [3]byte{168, 244, 112}: "Fujian Newland Communication Science Technologies Co.,Ltd.", + [3]byte{168, 245, 172}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{168, 245, 221}: "ARRIS Group, Inc.", [3]byte{168, 247, 224}: "PLANET Technology Corporation", [3]byte{168, 249, 75}: "Eltex Enterprise Ltd.", [3]byte{168, 250, 216}: "Apple, Inc.", @@ -20322,14 +21324,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{172, 4, 129}: "Jiangsu Huaxing Electronics Co., Ltd.", [3]byte{172, 6, 19}: "Senselogix Ltd", [3]byte{172, 6, 199}: "ServerNet S.r.l.", + [3]byte{172, 7, 95}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{172, 10, 97}: "Labor S.r.L.", [3]byte{172, 13, 27}: "LG Electronics (Mobile Communications)", [3]byte{172, 13, 254}: "Ekon GmbH - myGEKKO", [3]byte{172, 17, 211}: "Suzhou HOTEK Video Technology Co. Ltd", [3]byte{172, 20, 97}: "ATAW Co., Ltd.", [3]byte{172, 20, 210}: "wi-daq, inc.", + [3]byte{172, 21, 133}: "silergy corp", [3]byte{172, 22, 45}: "Hewlett Packard", [3]byte{172, 23, 2}: "Fibar Group sp. z o.o.", + [3]byte{172, 23, 200}: "Cisco Meraki", [3]byte{172, 24, 38}: "Seiko Epson Corporation", [3]byte{172, 25, 159}: "SUNGROW POWER SUPPLY CO.,LTD.", [3]byte{172, 29, 223}: "IEEE Registration Authority", @@ -20349,10 +21354,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{172, 47, 168}: "Humannix Co.,Ltd.", [3]byte{172, 49, 157}: "Shenzhen TG-NET Botone Technology Co.,Ltd.", [3]byte{172, 52, 203}: "Shanhai GBCOM Communication Technology Co. Ltd", + [3]byte{172, 53, 238}: "FN-LINK TECHNOLOGY LIMITED", [3]byte{172, 54, 19}: "Samsung Electronics Co.,Ltd", [3]byte{172, 55, 67}: "HTC Corporation", [3]byte{172, 56, 112}: "Lenovo Mobile Communication Technology Ltd.", [3]byte{172, 58, 122}: "Roku, Inc.", + [3]byte{172, 59, 119}: "Sagemcom Broadband SAS", [3]byte{172, 60, 11}: "Apple, Inc.", [3]byte{172, 60, 180}: "Nilan A/S", [3]byte{172, 61, 5}: "Instorescreen Aisa", @@ -20369,9 +21376,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{172, 78, 145}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{172, 79, 252}: "SVS-VISTEK GmbH", [3]byte{172, 80, 54}: "Pi-Coral Inc", + [3]byte{172, 80, 147}: "Magna Electronics Europe GmbH & Co. OHG", [3]byte{172, 81, 44}: "Infinix mobility limited", [3]byte{172, 81, 53}: "MPI TECH", [3]byte{172, 81, 238}: "Cambridge Communication Systems Ltd", + [3]byte{172, 84, 116}: "China Mobile IOT Company Limited", [3]byte{172, 84, 236}: "IEEE P1823 Standards Working Group", [3]byte{172, 86, 44}: "LAVA INTERNATIONAL(H.K) LIMITED", [3]byte{172, 88, 59}: "Human Assembler, Inc.", @@ -20386,7 +21395,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{172, 97, 234}: "Apple, Inc.", [3]byte{172, 98, 13}: "Jabil Circuit(Wuxi) Co.,Ltd", [3]byte{172, 99, 190}: "Amazon Technologies Inc.", - [3]byte{172, 100, 23}: "Siemens AG - Industrial Automation - EWA", + [3]byte{172, 100, 23}: "Siemens AG", [3]byte{172, 100, 98}: "zte corporation", [3]byte{172, 100, 221}: "IEEE Registration Authority", [3]byte{172, 103, 6}: "Ruckus Wireless", @@ -20400,6 +21409,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{172, 114, 54}: "Lexking Technology Co., Ltd.", [3]byte{172, 114, 137}: "Intel Corporate", [3]byte{172, 116, 9}: "Hangzhou H3C Technologies Co., Limited", + [3]byte{172, 117, 29}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{172, 122, 66}: "iConnectivity", [3]byte{172, 122, 77}: "ALPS ELECTRIC CO.,LTD.", [3]byte{172, 123, 161}: "Intel Corporate", @@ -20420,6 +21430,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{172, 137, 149}: "AzureWave Technology Inc.", [3]byte{172, 138, 205}: "ROGER D.Wensker, G.Wensker sp.j.", [3]byte{172, 141, 20}: "Smartrove Inc", + [3]byte{172, 146, 50}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{172, 147, 47}: "Nokia Corporation", [3]byte{172, 148, 3}: "Envision Peripherals Inc", [3]byte{172, 154, 34}: "NXP Semiconductors", @@ -20439,6 +21450,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{172, 171, 46}: "Beijing LasNubes Technology Co., Ltd.", [3]byte{172, 171, 141}: "Lyngso Marine A/S", [3]byte{172, 171, 191}: "AthenTek Inc.", + [3]byte{172, 174, 25}: "Roku, Inc", [3]byte{172, 175, 185}: "Samsung Electronics Co.,Ltd", [3]byte{172, 179, 19}: "ARRIS Group, Inc.", [3]byte{172, 181, 125}: "Liteon Technology Corporation", @@ -20500,11 +21512,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{172, 242, 197}: "Cisco Systems, Inc", [3]byte{172, 247, 243}: "Xiaomi Communications Co Ltd", [3]byte{172, 248, 92}: "Private", + [3]byte{172, 249, 112}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{172, 249, 126}: "ELESYS INC.", - [3]byte{172, 253, 147}: "Weifang GoerTek Technology Co.,Ltd.", + [3]byte{172, 253, 147}: "WEIFANG GOERTEK ELECTRONICS CO.,LTD", [3]byte{172, 253, 206}: "Intel Corporate", [3]byte{172, 253, 236}: "Apple, Inc.", [3]byte{176, 0, 180}: "Cisco Systems, Inc", + [3]byte{176, 2, 71}: "AMPAK Technology, Inc.", + [3]byte{176, 2, 126}: "MULLER SERVICES", [3]byte{176, 5, 148}: "Liteon Technology Corporation", [3]byte{176, 8, 191}: "Vital Connect, Inc.", [3]byte{176, 9, 211}: "Avizia", @@ -20514,6 +21529,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{176, 18, 102}: "Futaba-Kikaku", [3]byte{176, 20, 8}: "LIGHTSPEED INTERNATIONAL CO.", [3]byte{176, 23, 67}: "EDISON GLOBAL CIRCUITS LLC", + [3]byte{176, 24, 134}: "SmarDTV", [3]byte{176, 25, 198}: "Apple, Inc.", [3]byte{176, 27, 124}: "Ontrol A.S.", [3]byte{176, 27, 210}: "Le Shi Zhi Xin Electronic Technology (Tianjin) Limited", @@ -20523,6 +21539,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{176, 36, 243}: "Progeny Systems", [3]byte{176, 37, 170}: "Private", [3]byte{176, 38, 40}: "Broadcom Limited", + [3]byte{176, 38, 128}: "Cisco Systems, Inc", + [3]byte{176, 42, 67}: "Google, Inc.", + [3]byte{176, 51, 166}: "Juniper Networks", [3]byte{176, 52, 149}: "Apple, Inc.", [3]byte{176, 53, 11}: "MOBIWIRE MOBILES (NINGBO) CO.,LTD", [3]byte{176, 53, 141}: "Nokia Corporation", @@ -20534,6 +21553,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{176, 62, 176}: "MICRODIA Ltd.", [3]byte{176, 64, 137}: "Senient Systems LTD", [3]byte{176, 65, 29}: "ITTIM Technologies", + [3]byte{176, 65, 111}: "Shenzhen Maxtang Computer Co.,Ltd", [3]byte{176, 67, 93}: "NuLEDs, Inc.", [3]byte{176, 69, 21}: "mira fitness,LLC.", [3]byte{176, 69, 25}: "TCT mobile ltd", @@ -20549,6 +21569,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{176, 80, 188}: "SHENZHEN BASICOM ELECTRONIC CO.,LTD.", [3]byte{176, 81, 142}: "Holl technology CO.Ltd.", [3]byte{176, 82, 22}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{176, 83, 101}: "China Mobile IOT Company Limited", [3]byte{176, 85, 8}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{176, 87, 6}: "Vallox Oy", [3]byte{176, 88, 196}: "Broadcast Microwave Services, Inc", @@ -20560,6 +21581,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{176, 97, 199}: "Ericsson-LG Enterprise", [3]byte{176, 101, 99}: "Shanghai Railway Communication Factory", [3]byte{176, 101, 189}: "Apple, Inc.", + [3]byte{176, 103, 47}: "Bowers & Wilkins", [3]byte{176, 104, 182}: "Hangzhou OYE Technology Co. Ltd", [3]byte{176, 105, 113}: "DEI Sales, Inc.", [3]byte{176, 108, 191}: "3ality Digital Systems GmbH", @@ -20577,18 +21599,22 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{176, 121, 148}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{176, 125, 71}: "Cisco Systems, Inc", [3]byte{176, 125, 98}: "Dipl.-Ing. H. Horstmann GmbH", + [3]byte{176, 126, 17}: "Texas Instruments", [3]byte{176, 126, 112}: "Zadara Storage Ltd.", [3]byte{176, 127, 185}: "NETGEAR", [3]byte{176, 128, 140}: "Laser Light Engines", [3]byte{176, 129, 216}: "I-sys Corp", + [3]byte{176, 131, 214}: "ARRIS Group, Inc.", [3]byte{176, 131, 254}: "Dell Inc.", [3]byte{176, 134, 158}: "Chloride S.r.L", [3]byte{176, 136, 7}: "Strata Worldwide", [3]byte{176, 137, 0}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{176, 137, 145}: "LGE", [3]byte{176, 137, 194}: "Zyptonite", + [3]byte{176, 139, 207}: "Cisco Systems, Inc", [3]byte{176, 142, 26}: "URadio Systems Co., Ltd", [3]byte{176, 144, 116}: "Fulan Electronics Limited", + [3]byte{176, 144, 126}: "Cisco Systems, Inc", [3]byte{176, 144, 212}: "Shenzhen Hoin Internet Technology Co., Ltd", [3]byte{176, 145, 34}: "Texas Instruments", [3]byte{176, 145, 52}: "Taleo", @@ -20605,28 +21631,34 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{176, 159, 186}: "Apple, Inc.", [3]byte{176, 161, 10}: "Pivotal Systems Corporation", [3]byte{176, 162, 231}: "Shenzhen TINNO Mobile Technology Corp.", - [3]byte{176, 163, 126}: "Qingdao Haier Telecom Co.,Ltd", + [3]byte{176, 163, 126}: "QING DAO HAIER TELECOM CO.,LTD.", [3]byte{176, 167, 42}: "Ensemble Designs, Inc.", [3]byte{176, 167, 55}: "Roku, Inc.", [3]byte{176, 168, 110}: "Juniper Networks", [3]byte{176, 170, 54}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{176, 170, 119}: "Cisco Systems, Inc", + [3]byte{176, 172, 210}: "zte corporation", [3]byte{176, 172, 250}: "FUJITSU LIMITED", [3]byte{176, 173, 170}: "Avaya Inc", + [3]byte{176, 174, 37}: "Varikorea", [3]byte{176, 178, 143}: "Sagemcom Broadband SAS", [3]byte{176, 178, 220}: "Zyxel Communications Corporation", [3]byte{176, 179, 43}: "Slican Sp. z o.o.", + [3]byte{176, 179, 173}: "HUMAX Co., Ltd.", [3]byte{176, 180, 72}: "Texas Instruments", + [3]byte{176, 184, 103}: "Hewlett Packard Enterprise", [3]byte{176, 184, 213}: "Nanjing Nengrui Auto Equipment CO.,Ltd", [3]byte{176, 185, 138}: "NETGEAR", [3]byte{176, 189, 109}: "Echostreams Innovative Solutions", [3]byte{176, 189, 161}: "ZAKLAD ELEKTRONICZNY SIMS", + [3]byte{176, 190, 118}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{176, 191, 153}: "WIZITDONGDO", [3]byte{176, 192, 144}: "Chicony Electronics Co., Ltd.", [3]byte{176, 193, 40}: "Adler ELREHA GmbH", [3]byte{176, 193, 158}: "zte corporation", [3]byte{176, 194, 5}: "BIONIME", [3]byte{176, 194, 135}: "Technicolor CH USA Inc.", + [3]byte{176, 195, 135}: "GOEFER, Inc.", [3]byte{176, 196, 108}: "Senseit", [3]byte{176, 196, 231}: "Samsung Electronics Co.,Ltd", [3]byte{176, 197, 84}: "D-Link International", @@ -20661,6 +21693,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{176, 232, 146}: "Seiko Epson Corporation", [3]byte{176, 233, 126}: "Advanced Micro Peripherals", [3]byte{176, 234, 188}: "ASKEY COMPUTER CORP", + [3]byte{176, 235, 87}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{176, 236, 113}: "Samsung Electronics Co.,Ltd", [3]byte{176, 236, 143}: "GMX SAS", [3]byte{176, 236, 225}: "Private", @@ -20672,6 +21705,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{176, 248, 147}: "Shanghai MXCHIP Information Technology Co., Ltd.", [3]byte{176, 249, 99}: "Hangzhou H3C Technologies Co., Limited", [3]byte{176, 250, 235}: "Cisco Systems, Inc", + [3]byte{176, 252, 13}: "Amazon Technologies Inc.", [3]byte{176, 252, 54}: "CyberTAN Technology Inc.", [3]byte{176, 254, 189}: "Private", [3]byte{180, 0, 22}: "INGENICO TERMINALS SAS", @@ -20683,15 +21717,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{180, 8, 50}: "TC Communications", [3]byte{180, 10, 198}: "DEXON Systems Ltd.", [3]byte{180, 11, 68}: "Smartisan Technology Co., Ltd.", + [3]byte{180, 11, 120}: "Brusa Elektronik AG", [3]byte{180, 11, 122}: "Brusa Elektronik AG", [3]byte{180, 12, 37}: "Palo Alto Networks", [3]byte{180, 14, 150}: "HERAN", [3]byte{180, 14, 220}: "LG-Ericsson Co.,Ltd.", [3]byte{180, 15, 59}: "Tenda Technology Co.,Ltd.Dongguan branch", + [3]byte{180, 15, 179}: "vivo Mobile Communication Co., Ltd.", [3]byte{180, 20, 137}: "Cisco Systems, Inc", [3]byte{180, 21, 19}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{180, 23, 128}: "DTI Group Ltd", [3]byte{180, 24, 209}: "Apple, Inc.", + [3]byte{180, 28, 48}: "zte corporation", + [3]byte{180, 29, 43}: "Shenzhen YOUHUA Technology Co., Ltd", [3]byte{180, 29, 239}: "Internet Laboratories, Inc.", [3]byte{180, 33, 29}: "Beijing GuangXin Technology Co., Ltd", [3]byte{180, 33, 138}: "Dog Hunter LLC", @@ -20703,6 +21741,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{180, 44, 146}: "Zhejiang Weirong Electronic Co., Ltd", [3]byte{180, 44, 190}: "Direct Payment Solutions Limited", [3]byte{180, 45, 86}: "Extreme Networks, Inc.", + [3]byte{180, 46, 153}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{180, 46, 248}: "Eline Technology co.Ltd", [3]byte{180, 48, 82}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{180, 48, 192}: "York Instruments Ltd", [3]byte{180, 49, 184}: "Aviwest", @@ -20720,14 +21760,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{180, 62, 59}: "Viableware, Inc", [3]byte{180, 65, 122}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", [3]byte{180, 67, 13}: "Broadlink Pty Ltd", + [3]byte{180, 67, 38}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{180, 71, 94}: "Avaya Inc", + [3]byte{180, 71, 245}: "Earda Technologies co Ltd", [3]byte{180, 75, 210}: "Apple, Inc.", + [3]byte{180, 75, 214}: "IEEE Registration Authority", [3]byte{180, 76, 194}: "NR ELECTRIC CO., LTD", [3]byte{180, 79, 150}: "Zhejiang Xinzailing Technology co., ltd", [3]byte{180, 81, 249}: "NB Software", [3]byte{180, 82, 83}: "Seagate Technology", - [3]byte{180, 82, 125}: "Sony Mobile Communications AB", - [3]byte{180, 82, 126}: "Sony Mobile Communications AB", + [3]byte{180, 82, 125}: "Sony Mobile Communications Inc", + [3]byte{180, 82, 126}: "Sony Mobile Communications Inc", [3]byte{180, 85, 112}: "Borea", [3]byte{180, 86, 185}: "Teraspek Technologies Co.,Ltd", [3]byte{180, 88, 97}: "CRemote, LLC", @@ -20739,6 +21782,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{180, 98, 173}: "Elysia Germany GmbH", [3]byte{180, 102, 152}: "Zealabs srl", [3]byte{180, 103, 233}: "Qingdao GoerTek Technology Co., Ltd.", + [3]byte{180, 105, 33}: "Intel Corporate", + [3]byte{180, 107, 252}: "Intel Corporate", [3]byte{180, 109, 53}: "Dalian Seasky Automation Co;Ltd", [3]byte{180, 109, 131}: "Intel Corporate", [3]byte{180, 115, 86}: "Hangzhou Treebear Networking Co., Ltd.", @@ -20746,15 +21791,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{180, 116, 71}: "CoreOS", [3]byte{180, 116, 159}: "ASKEY COMPUTER CORP", [3]byte{180, 117, 14}: "Belkin International Inc.", + [3]byte{180, 119, 72}: "Shenzhen Neoway Technology Co.,Ltd.", [3]byte{180, 121, 167}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", + [3]byte{180, 121, 200}: "Ruckus Wireless", [3]byte{180, 124, 41}: "Shenzhen Guzidi Technology Co.,Ltd", [3]byte{180, 124, 156}: "Amazon Technologies Inc.", [3]byte{180, 127, 94}: "Foresight Manufacture (S) Pte Ltd", + [3]byte{180, 129, 191}: "Meta-Networks, LLC", [3]byte{180, 130, 85}: "Research Products Corporation", [3]byte{180, 130, 123}: "AKG Acoustics GmbH", [3]byte{180, 130, 197}: "Relay2, Inc.", [3]byte{180, 130, 254}: "ASKEY COMPUTER CORP", [3]byte{180, 133, 71}: "Amptown System Company GmbH", + [3]byte{180, 134, 85}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{180, 137, 16}: "Coster T.E. S.P.A.", [3]byte{180, 139, 25}: "Apple, Inc.", [3]byte{180, 148, 78}: "WeTelecom Co., Ltd.", @@ -20774,8 +21823,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{180, 165, 239}: "Sercomm Corporation.", [3]byte{180, 168, 40}: "Shenzhen Concox Information Technology Co., Ltd", [3]byte{180, 168, 43}: "Histar Digital Electronics Co., Ltd.", + [3]byte{180, 168, 185}: "Cisco Systems, Inc", + [3]byte{180, 169, 79}: "MERCURY CORPORATION", [3]byte{180, 169, 90}: "Avaya Inc", [3]byte{180, 169, 132}: "Symantec Corporation", + [3]byte{180, 169, 252}: "Quanta Computer Inc.", [3]byte{180, 169, 254}: "GHIA Technology (Shenzhen) LTD", [3]byte{180, 170, 77}: "Ensequence, Inc.", [3]byte{180, 171, 44}: "MtM Technology Corporation", @@ -20790,16 +21842,22 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{180, 181, 66}: "Hubbell Power Systems, Inc.", [3]byte{180, 181, 175}: "Minsung Electronics", [3]byte{180, 182, 118}: "Intel Corporate", + [3]byte{180, 182, 134}: "Hewlett Packard", [3]byte{180, 184, 89}: "Texa Spa", [3]byte{180, 184, 141}: "Thuh Company", [3]byte{180, 191, 246}: "Samsung Electronics Co.,Ltd", + [3]byte{180, 192, 245}: "Shenzhen TINNO Mobile Technology Corp.", [3]byte{180, 193, 112}: "Yi chip Microelectronics (Hangzhou) Co., Ltd", [3]byte{180, 196, 78}: "VXL eTech Pvt Ltd", + [3]byte{180, 198, 46}: "Molex CMS", [3]byte{180, 198, 248}: "Axilspot Communication", [3]byte{180, 199, 153}: "Extreme Networks, Inc.", [3]byte{180, 200, 16}: "UMPI Elettronica", + [3]byte{180, 203, 87}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{180, 204, 233}: "PROSYST", + [3]byte{180, 205, 39}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{180, 206, 246}: "HTC Corporation", + [3]byte{180, 206, 254}: "James Czekaj", [3]byte{180, 207, 219}: "Shenzhen Jiuzhou Electric Co.,LTD", [3]byte{180, 209, 53}: "Cloudistics", [3]byte{180, 213, 189}: "Intel Corporate", @@ -20807,15 +21865,22 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{180, 216, 169}: "BetterBots", [3]byte{180, 216, 222}: "iota Computing, Inc.", [3]byte{180, 221, 21}: "ControlThings Oy Ab", + [3]byte{180, 221, 208}: "Continental Automotive Hungary Kft", + [3]byte{180, 222, 49}: "Cisco Systems, Inc", + [3]byte{180, 222, 223}: "zte corporation", [3]byte{180, 223, 59}: "Chromlech", [3]byte{180, 223, 250}: "Litemax Electronics Inc.", + [3]byte{180, 224, 29}: "CONCEPTION ELECTRONIQUE", [3]byte{180, 224, 205}: "Fusion-io, Inc", [3]byte{180, 225, 15}: "Dell Inc.", [3]byte{180, 225, 196}: "Microsoft Mobile Oy", [3]byte{180, 225, 235}: "Private", [3]byte{180, 230, 42}: "LG Innotek", + [3]byte{180, 230, 45}: "Espressif Inc.", [3]byte{180, 231, 130}: "Vivalnk", + [3]byte{180, 233, 163}: "port GmbH", [3]byte{180, 233, 176}: "Cisco Systems, Inc", + [3]byte{180, 236, 2}: "ALPS ELECTRIC CO.,LTD.", [3]byte{180, 237, 25}: "Pie Digital, Inc.", [3]byte{180, 237, 84}: "Wohler Technologies", [3]byte{180, 238, 180}: "ASKEY COMPUTER CORP", @@ -20828,8 +21893,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{180, 242, 232}: "ARRIS Group, Inc.", [3]byte{180, 243, 35}: "PETATEL INC.", [3]byte{180, 246, 28}: "Apple, Inc.", + [3]byte{180, 247, 161}: "LG Electronics (Mobile Communications)", [3]byte{180, 248, 30}: "Kinova", + [3]byte{180, 249, 73}: "optilink networks pvt ltd", [3]byte{180, 251, 228}: "Ubiquiti Networks Inc.", + [3]byte{180, 251, 249}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{180, 252, 117}: "SEMA Electronics(HK) CO.,LTD", [3]byte{180, 254, 140}: "Centro Sicurezza Italia SpA", [3]byte{184, 0, 24}: "Htel", @@ -20854,6 +21922,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{184, 36, 16}: "Magneti Marelli Slovakia s.r.o.", [3]byte{184, 36, 26}: "SWEDA INFORMATICA LTDA", [3]byte{184, 36, 240}: "SOYO Technology Development Co., Ltd.", + [3]byte{184, 37, 154}: "Thalmic Labs", [3]byte{184, 38, 108}: "ANOV France", [3]byte{184, 38, 212}: "Furukawa Industrial S.A. Produtos Elétricos", [3]byte{184, 39, 235}: "Raspberry Pi Foundation", @@ -20861,8 +21930,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{184, 41, 247}: "Blaster Tech", [3]byte{184, 42, 114}: "Dell Inc.", [3]byte{184, 42, 220}: "EFR Europäische Funk-Rundsteuerung GmbH", - [3]byte{184, 44, 160}: "Honeywell HomMed", + [3]byte{184, 44, 160}: "Resideo", [3]byte{184, 48, 168}: "Road-Track Telematics Development", + [3]byte{184, 49, 181}: "Microsoft Corporation", [3]byte{184, 50, 65}: "Wuhan Tianyu Information Industry Co., Ltd.", [3]byte{184, 54, 216}: "Videoswitch", [3]byte{184, 55, 101}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", @@ -20874,6 +21944,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{184, 61, 78}: "Shenzhen Cultraview Digital Technology Co.,Ltd Shanghai Branch", [3]byte{184, 62, 89}: "Roku, Inc.", [3]byte{184, 65, 95}: "ASP AG", + [3]byte{184, 65, 164}: "Apple, Inc.", [3]byte{184, 67, 228}: "Vlatacom", [3]byte{184, 68, 217}: "Apple, Inc.", [3]byte{184, 71, 198}: "SanJet Technology Corp.", @@ -20896,6 +21967,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{184, 100, 145}: "CK Telecom Ltd", [3]byte{184, 101, 59}: "Bolymin, Inc.", [3]byte{184, 105, 194}: "Sunitec Enterprise Co., Ltd.", + [3]byte{184, 105, 244}: "Routerboard.com", + [3]byte{184, 106, 151}: "Edgecore Networks Corporation", [3]byte{184, 107, 35}: "Toshiba", [3]byte{184, 108, 232}: "Samsung Electronics Co.,Ltd", [3]byte{184, 112, 244}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", @@ -20904,12 +21977,16 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{184, 117, 192}: "PayPal, Inc.", [3]byte{184, 118, 63}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{184, 119, 195}: "METER Group", + [3]byte{184, 120, 38}: "Nintendo Co.,Ltd", [3]byte{184, 120, 46}: "Apple, Inc.", [3]byte{184, 120, 121}: "Roche Diagnostics GmbH", [3]byte{184, 121, 126}: "Secure Meters (UK) Limited", [3]byte{184, 122, 201}: "Siemens Ltd.", + [3]byte{184, 124, 111}: "NXP (China) Management Ltd.", [3]byte{184, 124, 242}: "Aerohive Networks Inc.", [3]byte{184, 129, 152}: "Intel Corporate", + [3]byte{184, 131, 3}: "Hewlett Packard Enterprise", + [3]byte{184, 133, 132}: "Dell Inc.", [3]byte{184, 134, 135}: "Liteon Technology Corporation", [3]byte{184, 135, 30}: "Good Mind Industries Co., Ltd.", [3]byte{184, 135, 168}: "Step Ahead Innovations Inc.", @@ -20917,12 +21994,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{184, 137, 129}: "Chengdu InnoThings Technology Co., Ltd.", [3]byte{184, 137, 202}: "ILJIN ELECTRIC Co., Ltd.", [3]byte{184, 138, 96}: "Intel Corporate", + [3]byte{184, 138, 236}: "Nintendo Co.,Ltd", [3]byte{184, 141, 18}: "Apple, Inc.", [3]byte{184, 142, 58}: "Infinite Technologies JLT", [3]byte{184, 142, 198}: "Stateless Networks", [3]byte{184, 142, 223}: "Zencheer Communication Technology Co., Ltd.", [3]byte{184, 143, 20}: "Analytica GmbH", [3]byte{184, 146, 29}: "BG T&A", + [3]byte{184, 148, 54}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{184, 148, 210}: "Retail Innovation HTT AB", [3]byte{184, 150, 116}: "AllDSP GmbH & Co. KG", [3]byte{184, 151, 90}: "BIOSTAR Microtech Int'l Corp.", @@ -20930,10 +22009,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{184, 152, 247}: "Gionee Communication Equipment Co,Ltd.ShenZhen", [3]byte{184, 153, 25}: "7signal Solutions, Inc", [3]byte{184, 153, 176}: "Cohere Technologies", + [3]byte{184, 154, 154}: "Xin Shi Jia Technology (Beijing) Co.,Ltd", [3]byte{184, 154, 205}: "ELITE OPTOELECTRONIC(ASIA)CO.,LTD", [3]byte{184, 154, 237}: "OceanServer Technology, Inc", [3]byte{184, 155, 201}: "SMC Networks Inc", [3]byte{184, 155, 228}: "ABB Power Systems Power Generation", + [3]byte{184, 159, 9}: "Wistron Neweb Corporation", [3]byte{184, 161, 117}: "Roku, Inc.", [3]byte{184, 163, 134}: "D-Link International", [3]byte{184, 163, 224}: "BenRui Technology Co.,Ltd", @@ -20948,6 +22029,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{184, 179, 220}: "DEREK (SHAOGUAN) LIMITED", [3]byte{184, 180, 46}: "Gionee Communication Equipment Co,Ltd.ShenZhen", [3]byte{184, 183, 215}: "2GIG Technologies", + [3]byte{184, 183, 241}: "Wistron Neweb Corporation", [3]byte{184, 184, 30}: "Intel Corporate", [3]byte{184, 185, 78}: "Shenzhen iBaby Labs, Inc.", [3]byte{184, 186, 104}: "Xi'an Jizhong Digital Communication Co.,Ltd", @@ -20958,13 +22040,16 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{184, 188, 27}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{184, 189, 121}: "TrendPoint Systems", [3]byte{184, 190, 191}: "Cisco Systems, Inc", + [3]byte{184, 190, 244}: "devolo AG", [3]byte{184, 191, 131}: "Intel Corporate", [3]byte{184, 193, 17}: "Apple, Inc.", [3]byte{184, 193, 162}: "Dragon Path Technologies Co., Limited", + [3]byte{184, 194, 39}: "PSTec", [3]byte{184, 195, 191}: "Henan Chengshi NetWork Technology Co.,Ltd", [3]byte{184, 196, 111}: "PRIMMCON INDUSTRIES INC", [3]byte{184, 198, 142}: "Samsung Electronics Co.,Ltd", [3]byte{184, 199, 22}: "Fiberhome Telecommunication Technologies Co.,LTD", + [3]byte{184, 199, 74}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{184, 199, 93}: "Apple, Inc.", [3]byte{184, 200, 85}: "Shanghai GBCOM Communication Technology Co.,Ltd.", [3]byte{184, 200, 235}: "ITEL MOBILE LIMITED", @@ -20983,6 +22068,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{184, 218, 247}: "Advanced Photonics, Inc.", [3]byte{184, 219, 28}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{184, 220, 135}: "IAI Corporation", + [3]byte{184, 222, 94}: "LONGCHEER TELECOMMUNICATION LIMITED", [3]byte{184, 223, 107}: "SpotCam Co., Ltd.", [3]byte{184, 229, 137}: "Payter BV", [3]byte{184, 230, 37}: "2Wire Inc", @@ -21004,7 +22090,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{184, 248, 40}: "Changshu Gaoshida Optoelectronic Technology Co. Ltd.", [3]byte{184, 248, 131}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{184, 248, 190}: "BLUECOM", - [3]byte{184, 249, 52}: "Sony Mobile Communications AB", + [3]byte{184, 249, 52}: "Sony Mobile Communications Inc", [3]byte{184, 252, 154}: "Le Shi Zhi Xin Electronic Technology (Tianjin) Limited", [3]byte{184, 253, 50}: "Zhejiang ROICX Microelectronics", [3]byte{184, 255, 97}: "Apple, Inc.", @@ -21017,6 +22103,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{188, 13, 165}: "Texas Instruments", [3]byte{188, 15, 43}: "FORTUNE TECHGROUP CO.,LTD", [3]byte{188, 15, 100}: "Intel Corporate", + [3]byte{188, 15, 167}: "Ouster", [3]byte{188, 18, 94}: "Beijing WisVideo INC.", [3]byte{188, 20, 1}: "Hitron Technologies. Inc", [3]byte{188, 20, 133}: "Samsung Electronics Co.,Ltd", @@ -21029,9 +22116,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{188, 28, 129}: "Sichuan iLink Technology Co., Ltd.", [3]byte{188, 32, 164}: "Samsung Electronics Co.,Ltd", [3]byte{188, 32, 186}: "Inspur (Shandong) Electronic Information Co., Ltd", + [3]byte{188, 34, 251}: "RF Industries", [3]byte{188, 37, 224}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{188, 37, 240}: "3D Display Technologies Co., Ltd.", [3]byte{188, 38, 29}: "HONG KONG TECON TECHNOLOGY", + [3]byte{188, 38, 67}: "Elprotronic Inc.", + [3]byte{188, 38, 199}: "Cisco Systems, Inc", [3]byte{188, 40, 44}: "e-Smart Systems Pvt. Ltd", [3]byte{188, 40, 70}: "NextBIT Computing Pvt. Ltd.", [3]byte{188, 40, 214}: "Rowley Associates Limited", @@ -21044,8 +22134,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{188, 48, 91}: "Dell Inc.", [3]byte{188, 48, 125}: "Wistron Neweb Corporation", [3]byte{188, 48, 126}: "Wistron Neweb Corporation", + [3]byte{188, 48, 217}: "Arcadyan Corporation", + [3]byte{188, 50, 95}: "Zhejiang Dahua Technology Co., Ltd.", [3]byte{188, 52, 0}: "IEEE Registration Authority", [3]byte{188, 53, 229}: "Hydro Systems Company", + [3]byte{188, 56, 101}: "JWCNETWORKS", [3]byte{188, 56, 210}: "Pandachip Limited", [3]byte{188, 57, 166}: "CSUN System Technology Co.,LTD", [3]byte{188, 57, 217}: "Z-TEC", @@ -21053,6 +22146,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{188, 59, 175}: "Apple, Inc.", [3]byte{188, 61, 133}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{188, 62, 19}: "Accordance Systems Inc.", + [3]byte{188, 63, 78}: "Teleepoch Ltd", [3]byte{188, 63, 143}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{188, 65, 0}: "CODACO ELECTRONIC s.r.o.", [3]byte{188, 65, 1}: "Shenzhen TINNO Mobile Technology Corp.", @@ -21076,8 +22170,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{188, 84, 249}: "Drogoo Technology Co., Ltd.", [3]byte{188, 84, 252}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", [3]byte{188, 92, 76}: "ELECOM CO.,LTD.", + [3]byte{188, 94, 161}: "PsiKick, Inc.", [3]byte{188, 95, 244}: "ASRock Incorporation", - [3]byte{188, 95, 246}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", + [3]byte{188, 95, 246}: "MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", [3]byte{188, 96, 16}: "Qingdao Hisense Communications Co.,Ltd.", [3]byte{188, 96, 167}: "Sony Interactive Entertainment Inc.", [3]byte{188, 98, 14}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -21094,12 +22189,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{188, 106, 68}: "Commend International GmbH", [3]byte{188, 107, 77}: "Nokia", [3]byte{188, 108, 33}: "Apple, Inc.", - [3]byte{188, 110, 100}: "Sony Mobile Communications AB", + [3]byte{188, 110, 100}: "Sony Mobile Communications Inc", [3]byte{188, 110, 118}: "Green Energy Options Ltd", [3]byte{188, 113, 193}: "XTrillion, Inc.", [3]byte{188, 114, 177}: "Samsung Electronics Co.,Ltd", [3]byte{188, 116, 215}: "HangZhou JuRu Technology CO.,LTD", [3]byte{188, 117, 116}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{188, 117, 150}: "Beijing Broadwit Technology Co., Ltd.", [3]byte{188, 118, 78}: "Rackspace US, Inc.", [3]byte{188, 118, 94}: "Samsung Electronics Co.,Ltd", [3]byte{188, 118, 112}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -21124,25 +22220,33 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{188, 144, 58}: "Robert Bosch GmbH", [3]byte{188, 145, 181}: "Infinix mobility limited", [3]byte{188, 146, 107}: "Apple, Inc.", + [3]byte{188, 147, 37}: "Ningbo Joyson Preh Car Connect Co.,Ltd.", [3]byte{188, 150, 128}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", [3]byte{188, 152, 137}: "Fiberhome Telecommunication Technologies Co.,LTD", + [3]byte{188, 153, 17}: "Zyxel Communications Corporation", [3]byte{188, 153, 188}: "FonSee Technology Inc.", + [3]byte{188, 155, 104}: "Technicolor CH USA Inc.", [3]byte{188, 156, 49}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{188, 156, 197}: "Beijing Huafei Technology Co., Ltd.", [3]byte{188, 157, 165}: "DASCOM Europe GmbH", [3]byte{188, 159, 239}: "Apple, Inc.", [3]byte{188, 160, 66}: "SHANGHAI FLYCO ELECTRICAL APPLIANCE CO.,LTD", [3]byte{188, 164, 225}: "Nabto", + [3]byte{188, 165, 139}: "Samsung Electronics Co.,Ltd", [3]byte{188, 168, 166}: "Intel Corporate", [3]byte{188, 169, 32}: "Apple, Inc.", [3]byte{188, 169, 214}: "Cyber-Rain, Inc.", + [3]byte{188, 171, 124}: "TRnP KOREA Co Ltd", [3]byte{188, 173, 40}: "Hangzhou Hikvision Digital Technology Co.,Ltd.", [3]byte{188, 173, 171}: "Avaya Inc", [3]byte{188, 174, 197}: "ASUSTek COMPUTER INC.", + [3]byte{188, 175, 145}: "TE Connectivity Sensor Solutions", [3]byte{188, 177, 129}: "SHARP CORPORATION", [3]byte{188, 177, 243}: "Samsung Electronics Co.,Ltd", + [3]byte{188, 178, 43}: "EM-Tech", [3]byte{188, 179, 8}: "HONGKONG RAGENTEK COMMUNICATION TECHNOLOGY CO.,LIMITED", [3]byte{188, 184, 82}: "Cybera, Inc.", + [3]byte{188, 184, 99}: "Apple, Inc.", [3]byte{188, 186, 225}: "AREC Inc.", [3]byte{188, 187, 201}: "Kellendonk Elektronik GmbH", [3]byte{188, 188, 70}: "SKS Welding Systems GmbH", @@ -21165,10 +22269,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{188, 213, 182}: "d2d technologies", [3]byte{188, 215, 19}: "Owl Labs", [3]byte{188, 217, 64}: "ASR Co,.Ltd.", + [3]byte{188, 221, 194}: "Espressif Inc.", [3]byte{188, 224, 157}: "Eoslink", + [3]byte{188, 225, 67}: "Apple, Inc.", + [3]byte{188, 226, 101}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{188, 229, 159}: "WATERWORLD Technology Co.,LTD", [3]byte{188, 230, 63}: "Samsung Electronics Co.,Ltd", [3]byte{188, 231, 103}: "Quanzhou TDX Electronics Co., Ltd", + [3]byte{188, 231, 150}: "Wireless CCTV Ltd", [3]byte{188, 234, 43}: "CityCom GmbH", [3]byte{188, 234, 250}: "Hewlett Packard", [3]byte{188, 235, 95}: "Fujian Beifeng Telecom Technology Co., Ltd.", @@ -21178,26 +22286,31 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{188, 241, 242}: "Cisco Systems, Inc", [3]byte{188, 242, 146}: "PLANTRONICS, INC.", [3]byte{188, 242, 175}: "devolo AG", + [3]byte{188, 243, 16}: "Aerohive Networks Inc.", [3]byte{188, 245, 172}: "LG Electronics (Mobile Communications)", [3]byte{188, 246, 28}: "Geomodeling Wuxi Technology Co. Ltd.", [3]byte{188, 246, 133}: "D-Link International", [3]byte{188, 248, 17}: "Xiamen DNAKE Technology Co.,Ltd", [3]byte{188, 254, 140}: "Altronic, LLC", + [3]byte{188, 254, 217}: "Apple, Inc.", [3]byte{188, 255, 172}: "TOPCON CORPORATION", [3]byte{188, 255, 235}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{192, 2, 141}: "WINSTAR Display CO.,Ltd", + [3]byte{192, 3, 128}: "Juniper Networks", [3]byte{192, 5, 194}: "ARRIS Group, Inc.", [3]byte{192, 13, 126}: "Additech, Inc.", [3]byte{192, 17, 115}: "Samsung Electronics Co.,Ltd", [3]byte{192, 17, 166}: "Fort-Telecom ltd.", [3]byte{192, 18, 66}: "Alpha Security Products", + [3]byte{192, 19, 43}: "Sichuan Changhong Electric Ltd.", [3]byte{192, 20, 61}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{192, 23, 77}: "Samsung Electronics Co.,Ltd", [3]byte{192, 24, 133}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{192, 26, 218}: "Apple, Inc.", + [3]byte{192, 27, 35}: "SICHUAN TIANYI COMHEART TELECOM CO.,LTD", [3]byte{192, 30, 155}: "Pixavi AS", [3]byte{192, 33, 13}: "SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.", - [3]byte{192, 34, 80}: "Private", + [3]byte{192, 34, 80}: "Koss Corporation", [3]byte{192, 37, 6}: "AVM GmbH", [3]byte{192, 37, 92}: "Cisco Systems, Inc", [3]byte{192, 37, 103}: "Nexxt Solutions", @@ -21220,13 +22333,18 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{192, 56, 249}: "Nokia Danmark A/S", [3]byte{192, 59, 143}: "Minicom Digital Signage", [3]byte{192, 61, 70}: "Shanghai Sango Network Technology Co.,Ltd", + [3]byte{192, 61, 217}: "MitraStar Technology Corp.", [3]byte{192, 62, 15}: "BSkyB Ltd", [3]byte{192, 63, 14}: "NETGEAR", [3]byte{192, 63, 42}: "Biscotti, Inc.", [3]byte{192, 63, 213}: "Elitegroup Computer Systems Co.,Ltd.", + [3]byte{192, 64, 4}: "Medicaroid Corporation", [3]byte{192, 65, 246}: "LG ELECTRONICS INC", + [3]byte{192, 66, 208}: "Juniper Networks", [3]byte{192, 67, 1}: "Epec Oy", [3]byte{192, 68, 227}: "Shenzhen Sinkna Electronics Co., LTD", + [3]byte{192, 72, 230}: "Samsung Electronics Co.,Ltd", + [3]byte{192, 72, 251}: "Shenzhen JingHanDa Electronics Co.Ltd", [3]byte{192, 73, 61}: "MAITRISE TECHNOLOGIQUE", [3]byte{192, 74, 0}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{192, 74, 9}: "Zhejiang Everbright Communication Equip. Co,. Ltd", @@ -21248,12 +22366,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{192, 109, 26}: "Tianjin Henxinhuifeng Technology Co.,Ltd.", [3]byte{192, 112, 9}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{192, 116, 43}: "SHENZHEN XUNLONG SOFTWARE CO.,LIMITED", + [3]byte{192, 116, 173}: "Grandstream Networks, Inc.", + [3]byte{192, 120, 120}: "FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD.", [3]byte{192, 123, 188}: "Cisco Systems, Inc", [3]byte{192, 124, 209}: "PEGATRON CORPORATION", [3]byte{192, 126, 64}: "SHENZHEN XDK COMMUNICATION EQUIPMENT CO.,LTD", + [3]byte{192, 129, 53}: "Ningbo Forfan technology Co., LTD", [3]byte{192, 129, 112}: "Effigis GeoSolutions", [3]byte{192, 131, 10}: "2Wire Inc", + [3]byte{192, 131, 89}: "IEEE Registration Authority", [3]byte{192, 132, 122}: "Apple, Inc.", + [3]byte{192, 132, 125}: "AMPAK Technology, Inc.", [3]byte{192, 132, 136}: "Finis Inc", [3]byte{192, 133, 76}: "Ragentek Technology Group", [3]byte{192, 135, 235}: "Samsung Electronics Co.,Ltd", @@ -21266,8 +22389,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{192, 145, 52}: "ProCurve Networking by HP", [3]byte{192, 151, 39}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", [3]byte{192, 152, 121}: "Acer Inc.", + [3]byte{192, 152, 218}: "China Mobile IOT Company Limited", [3]byte{192, 152, 229}: "University of Michigan", [3]byte{192, 154, 113}: "XIAMEN MEITU MOBILE TECHNOLOGY CO.LTD", + [3]byte{192, 154, 208}: "Apple, Inc.", [3]byte{192, 156, 4}: "Shaanxi GuoLian Digital TV Technology Co.,Ltd.", [3]byte{192, 156, 146}: "COBY", [3]byte{192, 157, 38}: "Topicon HK Lmd.", @@ -21284,15 +22409,21 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{192, 163, 158}: "EarthCam, Inc.", [3]byte{192, 165, 62}: "Apple, Inc.", [3]byte{192, 165, 221}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", + [3]byte{192, 166, 0}: "Apple, Inc.", + [3]byte{192, 168, 240}: "Adamson Systems Engineering", [3]byte{192, 170, 104}: "OSASI Technos Inc.", [3]byte{192, 172, 84}: "Sagemcom Broadband SAS", [3]byte{192, 179, 57}: "Comigo Ltd.", [3]byte{192, 179, 87}: "Yoshiki Electronics Industry Ltd.", + [3]byte{192, 182, 88}: "Apple, Inc.", + [3]byte{192, 182, 249}: "Intel Corporate", [3]byte{192, 183, 19}: "Beijing Xiaoyuer Technology Co. Ltd.", [3]byte{192, 184, 177}: "BitBox Ltd", [3]byte{192, 186, 230}: "Application Solutions (Electronics and Vision) Ltd", [3]byte{192, 189, 66}: "ZPA Smart Energy a.s.", + [3]byte{192, 189, 200}: "Samsung Electronics Co.,Ltd", [3]byte{192, 189, 209}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", + [3]byte{192, 191, 167}: "Juniper Networks", [3]byte{192, 191, 192}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{192, 193, 192}: "Cisco-Linksys, LLC", [3]byte{192, 195, 182}: "Automatic Systems", @@ -21308,6 +22439,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{192, 207, 163}: "Creative Electronics & Software, Inc.", [3]byte{192, 208, 18}: "Apple, Inc.", [3]byte{192, 208, 68}: "Sagemcom Broadband SAS", + [3]byte{192, 208, 255}: "China Mobile IOT Company Limited", + [3]byte{192, 210, 243}: "Hui Zhou Gaoshengda Technology Co.,LTD", [3]byte{192, 211, 145}: "IEEE Registration Authority", [3]byte{192, 211, 192}: "Samsung Electronics Co.,Ltd", [3]byte{192, 217, 98}: "ASKEY COMPUTER CORP", @@ -21318,11 +22451,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{192, 228, 34}: "Texas Instruments", [3]byte{192, 228, 45}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{192, 229, 78}: "ARIES Embedded GmbH", + [3]byte{192, 232, 98}: "Apple, Inc.", [3]byte{192, 234, 228}: "Sonicwall", [3]byte{192, 238, 64}: "Laird Technologies", + [3]byte{192, 238, 181}: "Enice Network.", [3]byte{192, 238, 251}: "OnePlus Tech (Shenzhen) Ltd", [3]byte{192, 241, 196}: "Pacidal Corporation Ltd.", [3]byte{192, 242, 251}: "Apple, Inc.", + [3]byte{192, 244, 230}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{192, 246, 54}: "Hangzhou Kuaiyue Technologies, Ltd.", [3]byte{192, 247, 157}: "Powercode", [3]byte{192, 248, 218}: "Hon Hai Precision Ind. Co.,Ltd.", @@ -21331,6 +22467,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{192, 255, 212}: "NETGEAR", [3]byte{196, 0, 6}: "Lipi Data Systems Ltd.", [3]byte{196, 0, 73}: "Kamama", + [3]byte{196, 0, 173}: "Advantech Technology (CHINA) Co., Ltd.", [3]byte{196, 1, 66}: "MaxMedia Technology Limited", [3]byte{196, 1, 124}: "Ruckus Wireless", [3]byte{196, 1, 177}: "SeekTech INC", @@ -21359,14 +22496,18 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{196, 30, 206}: "HMI Sources Ltd.", [3]byte{196, 33, 200}: "KYOCERA CORPORATION", [3]byte{196, 35, 122}: "WhizNets Inc.", + [3]byte{196, 35, 162}: "PT. Emsonic Indonesia", [3]byte{196, 36, 46}: "Galvanic Applied Sciences Inc", + [3]byte{196, 36, 86}: "Palo Alto Networks", [3]byte{196, 38, 40}: "Airo Wireless", [3]byte{196, 39, 149}: "Technicolor CH USA Inc.", [3]byte{196, 40, 45}: "Embedded Intellect Pty Ltd", [3]byte{196, 41, 29}: "KLEMSAN ELEKTRIK ELEKTRONIK SAN.VE TIC.AS.", [3]byte{196, 44, 3}: "Apple, Inc.", + [3]byte{196, 44, 79}: "Qingdao Hisense Mobile Communication Technology Co,Ltd", [3]byte{196, 47, 144}: "Hangzhou Hikvision Digital Technology Co.,Ltd.", [3]byte{196, 48, 24}: "MCS Logic Inc.", + [3]byte{196, 51, 6}: "China Mobile Group Device Co.,Ltd.", [3]byte{196, 52, 107}: "Hewlett Packard", [3]byte{196, 54, 85}: "Shenzhen Fenglian Technology Co., Ltd.", [3]byte{196, 54, 108}: "LG Innotek", @@ -21374,7 +22515,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{196, 56, 211}: "TAGATEC CO.,LTD", [3]byte{196, 57, 58}: "SMC Networks Inc", [3]byte{196, 58, 159}: "Siconix Inc.", - [3]byte{196, 58, 190}: "Sony Mobile Communications AB", + [3]byte{196, 58, 190}: "Sony Mobile Communications Inc", [3]byte{196, 60, 60}: "CYBELEC SA", [3]byte{196, 61, 199}: "NETGEAR", [3]byte{196, 64, 68}: "RackTop Systems Inc.", @@ -21392,7 +22533,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{196, 75, 209}: "Wallys Communications Teachnologies Co.,Ltd.", [3]byte{196, 78, 31}: "BlueN", [3]byte{196, 78, 172}: "Shenzhen Shiningworth Technology Co., Ltd.", + [3]byte{196, 79, 51}: "Espressif Inc.", [3]byte{196, 80, 6}: "Samsung Electronics Co.,Ltd", + [3]byte{196, 81, 141}: "Shenzhen YOUHUA Technology Co., Ltd", [3]byte{196, 84, 68}: "QUANTA COMPUTER INC.", [3]byte{196, 85, 166}: "Cadac Holdings Ltd", [3]byte{196, 85, 194}: "Bach-Simpson", @@ -21404,10 +22547,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{196, 89, 118}: "Fugoo Coorporation", [3]byte{196, 93, 216}: "HDMI Forum", [3]byte{196, 96, 68}: "Everex Electronics Limited", + [3]byte{196, 97, 139}: "Apple, Inc.", [3]byte{196, 98, 107}: "ZPT Vigantice", [3]byte{196, 98, 234}: "Samsung Electronics Co.,Ltd", [3]byte{196, 99, 84}: "U-Raku, Inc.", [3]byte{196, 100, 19}: "Cisco Systems, Inc", + [3]byte{196, 100, 227}: "Texas Instruments", [3]byte{196, 102, 153}: "vivo Mobile Communication Co., Ltd.", [3]byte{196, 103, 181}: "Libratone A/S", [3]byte{196, 104, 208}: "VTech Telecommunications Ltd.", @@ -21416,12 +22561,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{196, 107, 180}: "myIDkey", [3]byte{196, 109, 241}: "DataGravity", [3]byte{196, 110, 31}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{196, 110, 123}: "SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.", [3]byte{196, 112, 11}: "GUANGZHOU CHIP TECHNOLOGIES CO.,LTD", [3]byte{196, 113, 48}: "Fon Technology S.L.", [3]byte{196, 113, 84}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{196, 113, 254}: "Cisco Systems, Inc", [3]byte{196, 114, 149}: "Cisco Systems, Inc", [3]byte{196, 115, 30}: "Samsung Electronics Co.,Ltd", + [3]byte{196, 116, 248}: "Hot Pepper, Inc.", [3]byte{196, 119, 171}: "Beijing ASU Tech Co.,Ltd", [3]byte{196, 119, 175}: "Advanced Digital Broadcast SA", [3]byte{196, 123, 47}: "Beijing JoinHope Image Technology Ltd.", @@ -21435,6 +22582,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{196, 130, 63}: "Fujian Newland Auto-ID Tech. Co,.Ltd.", [3]byte{196, 130, 78}: "Changzhou Uchip Electronics Co., LTD.", [3]byte{196, 131, 111}: "Ciena Corporation", + [3]byte{196, 132, 102}: "Apple, Inc.", [3]byte{196, 133, 8}: "Intel Corporate", [3]byte{196, 134, 233}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{196, 136, 229}: "Samsung Electronics Co.,Ltd", @@ -21445,11 +22593,16 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{196, 147, 0}: "8Devices", [3]byte{196, 147, 19}: "100fio networks technology llc", [3]byte{196, 147, 128}: "Speedytel technology", + [3]byte{196, 147, 217}: "Samsung Electronics Co.,Ltd", + [3]byte{196, 149, 0}: "Amazon Technologies Inc.", [3]byte{196, 149, 162}: "SHENZHEN WEIJIU INDUSTRY AND TRADE DEVELOPMENT CO., LTD", [3]byte{196, 152, 5}: "Minieum Networks, Inc", + [3]byte{196, 152, 92}: "Hui Zhou Gaoshengda Technology Co.,LTD", + [3]byte{196, 152, 128}: "Apple, Inc.", [3]byte{196, 154, 2}: "LG Electronics (Mobile Communications)", [3]byte{196, 157, 237}: "Microsoft Corporation", [3]byte{196, 158, 65}: "G24 Power Limited", + [3]byte{196, 159, 76}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{196, 159, 243}: "Mciao Technologies, Inc.", [3]byte{196, 163, 102}: "zte corporation", [3]byte{196, 168, 29}: "D-Link International", @@ -21460,6 +22613,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{196, 174, 18}: "Samsung Electronics Co.,Ltd", [3]byte{196, 179, 1}: "Apple, Inc.", [3]byte{196, 181, 18}: "General Electric Digital Energy", + [3]byte{196, 184, 180}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{196, 185, 205}: "Cisco Systems, Inc", [3]byte{196, 186, 153}: "I+ME Actia Informatik und Mikro-Elektronik GmbH", [3]byte{196, 186, 163}: "Beijing Winicssec Technologies Co., Ltd.", @@ -21486,6 +22640,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{196, 218, 125}: "Ivium Technologies B.V.", [3]byte{196, 224, 50}: "IEEE 1904.1 Working Group", [3]byte{196, 225, 124}: "U2S co.", + [3]byte{196, 229, 6}: "Piper Networks, Inc.", [3]byte{196, 229, 16}: "Mechatro, Inc.", [3]byte{196, 231, 190}: "SCSpro Co.,Ltd", [3]byte{196, 233, 47}: "AB Sciex", @@ -21503,7 +22658,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{196, 245, 124}: "Brocade Communications Systems, Inc.", [3]byte{196, 245, 165}: "Kumalift Co., Ltd.", [3]byte{196, 252, 228}: "DishTV NZ Ltd", + [3]byte{196, 253, 230}: "DRTECH", + [3]byte{196, 254, 226}: "AMICCOM Electronics Corporation", [3]byte{196, 255, 31}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{196, 255, 188}: "IEEE Registration Authority", [3]byte{200, 0, 132}: "Cisco Systems, Inc", [3]byte{200, 2, 16}: "LG Innotek", [3]byte{200, 2, 88}: "ITW GSE ApS", @@ -21535,6 +22693,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{200, 37, 225}: "Lemobile Information Technology (Beijing) Co., Ltd", [3]byte{200, 41, 42}: "Barun Electronics", [3]byte{200, 42, 20}: "Apple, Inc.", + [3]byte{200, 46, 71}: "Suzhou SmartChip Semiconductor Co., LTD", [3]byte{200, 46, 148}: "Halfa Enterprise Co., Ltd.", [3]byte{200, 49, 104}: "eZEX corporation", [3]byte{200, 50, 50}: "Hunting Innova", @@ -21557,11 +22716,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{200, 69, 41}: "IMK Networks Co.,Ltd", [3]byte{200, 69, 68}: "Asia Pacific CIS (Wuxi) Co, Ltd", [3]byte{200, 69, 143}: "Wyler AG", + [3]byte{200, 71, 130}: "Areson Technology Corp.", [3]byte{200, 71, 140}: "Beken Corporation", [3]byte{200, 72, 245}: "MEDISON Xray Co., Ltd", [3]byte{200, 76, 117}: "Cisco Systems, Inc", [3]byte{200, 80, 233}: "Raisecom Technology CO., LTD", [3]byte{200, 81, 149}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{200, 84, 75}: "Zyxel Communications Corporation", [3]byte{200, 86, 69}: "Intermas France", [3]byte{200, 86, 99}: "Sunflex Europe GmbH", [3]byte{200, 91, 118}: "LCFC(HeFei) Electronics Technology co., ltd", @@ -21579,7 +22740,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{200, 114, 72}: "Aplicom Oy", [3]byte{200, 115, 36}: "Sow Cheng Technology Co. Ltd.", [3]byte{200, 117, 91}: "Quantify Technology Pty. Ltd.", - [3]byte{200, 119, 139}: "Themis Computer", + [3]byte{200, 119, 101}: "Tiesse SpA", + [3]byte{200, 119, 139}: "Mercury Systems – Trusted Mission Solutions, Inc.", [3]byte{200, 123, 91}: "zte corporation", [3]byte{200, 124, 188}: "Valink Co., Ltd.", [3]byte{200, 125, 119}: "Shenzhen Kingtech Communication Equipment Co.,Ltd", @@ -21587,12 +22749,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{200, 132, 57}: "Sunrise Technologies", [3]byte{200, 132, 71}: "Beautiful Enterprise Co., Ltd", [3]byte{200, 133, 80}: "Apple, Inc.", + [3]byte{200, 134, 41}: "Shenzhen Duubee Intelligent Technologies Co.,LTD.", [3]byte{200, 135, 34}: "Lumenpulse", [3]byte{200, 135, 59}: "Net Optics", [3]byte{200, 138, 131}: "Dongguan HuaHong Electronics Co.,Ltd", [3]byte{200, 139, 71}: "Nolangroup S.P.A con Socio Unico", [3]byte{200, 141, 131}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{200, 142, 209}: "IEEE Registration Authority", + [3]byte{200, 143, 38}: "Skyworth Digital Technology(Shenzhen) Co.,Ltd", [3]byte{200, 144, 62}: "Pakton Technologies", [3]byte{200, 145, 249}: "Sagemcom Broadband SAS", [3]byte{200, 147, 70}: "MXCHIP Company Limited", @@ -21600,6 +22764,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{200, 148, 187}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{200, 148, 210}: "Jiangsu Datang Electronic Products Co., Ltd", [3]byte{200, 151, 159}: "Nokia Corporation", + [3]byte{200, 156, 19}: "Inspiremobile", [3]byte{200, 156, 29}: "Cisco Systems, Inc", [3]byte{200, 156, 220}: "Elitegroup Computer Systems Co.,Ltd.", [3]byte{200, 159, 29}: "SHENZHEN COMMUNICATION TECHNOLOGIES CO.,LTD", @@ -21619,22 +22784,26 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{200, 174, 156}: "Shanghai TYD Elecronic Technology Co. Ltd", [3]byte{200, 175, 64}: "marco Systemanalyse und Entwicklung GmbH", [3]byte{200, 175, 227}: "Hefei Radio Communication Technology Co., Ltd", + [3]byte{200, 177, 238}: "Qorvo", [3]byte{200, 178, 30}: "CHIPSEA TECHNOLOGIES (SHENZHEN) CORP.", [3]byte{200, 179, 115}: "Cisco-Linksys, LLC", [3]byte{200, 181, 173}: "Hewlett Packard Enterprise", [3]byte{200, 181, 183}: "Apple, Inc.", [3]byte{200, 186, 148}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", + [3]byte{200, 186, 233}: "QDIS", [3]byte{200, 187, 211}: "Embrane", [3]byte{200, 188, 200}: "Apple, Inc.", [3]byte{200, 190, 25}: "D-Link International", [3]byte{200, 193, 38}: "ZPM Industria e Comercio Ltda", [3]byte{200, 193, 60}: "RuggedTek Hangzhou Co., Ltd", [3]byte{200, 194, 198}: "Shanghai Airm2m Communication Technology Co., Ltd", + [3]byte{200, 194, 245}: "FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD.", [3]byte{200, 197, 14}: "Shenzhen Primestone Network Technologies.Co., Ltd.", [3]byte{200, 199, 145}: "Zero1.tv GmbH", [3]byte{200, 203, 184}: "Hewlett Packard", [3]byte{200, 205, 114}: "Sagemcom Broadband SAS", [3]byte{200, 208, 25}: "Shanghai Tigercel Communication Technology Co.,Ltd", + [3]byte{200, 208, 131}: "Apple, Inc.", [3]byte{200, 209, 11}: "Nokia Corporation", [3]byte{200, 209, 42}: "Comtrend Corporation", [3]byte{200, 209, 94}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -21646,8 +22815,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{200, 213, 144}: "FLIGHT DATA SYSTEMS", [3]byte{200, 213, 254}: "Shenzhen Zowee Technology Co., Ltd", [3]byte{200, 215, 25}: "Cisco-Linksys, LLC", - [3]byte{200, 215, 121}: "Qingdao Haier Telecom Co.,Ltd", + [3]byte{200, 215, 121}: "QING DAO HAIER TELECOM CO.,LTD.", [3]byte{200, 215, 176}: "Samsung Electronics Co.,Ltd", + [3]byte{200, 217, 210}: "Hewlett Packard", [3]byte{200, 219, 38}: "Logitech", [3]byte{200, 221, 201}: "Lenovo Mobile Communication Technology Ltd.", [3]byte{200, 222, 81}: "IntegraOptics", @@ -21659,7 +22829,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{200, 225, 167}: "Vertu Corporation Limited", [3]byte{200, 228, 47}: "Technical Research Design and Development", [3]byte{200, 231, 118}: "PTCOM Technology", - [3]byte{200, 231, 216}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", + [3]byte{200, 231, 216}: "MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", [3]byte{200, 231, 240}: "Juniper Networks", [3]byte{200, 238, 8}: "TANGTOP TECHNOLOGY CO.,LTD", [3]byte{200, 238, 117}: "Pishion International Co. Ltd", @@ -21678,6 +22848,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{200, 249, 129}: "Seneca s.r.l.", [3]byte{200, 249, 200}: "NewSharp Technology(SuZhou)Co,Ltd", [3]byte{200, 249, 249}: "Cisco Systems, Inc", + [3]byte{200, 250, 225}: "ARQ Digital LLC", [3]byte{200, 251, 38}: "Cisco SPVTG", [3]byte{200, 253, 25}: "Texas Instruments", [3]byte{200, 254, 48}: "Bejing DAYO Mobile Communication Technology Ltd.", @@ -21694,6 +22865,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{204, 7, 228}: "Lenovo Mobile Communication Technology Ltd.", [3]byte{204, 8, 141}: "Apple, Inc.", [3]byte{204, 8, 224}: "Apple, Inc.", + [3]byte{204, 8, 251}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{204, 9, 200}: "IMAQLIQ LTD", [3]byte{204, 12, 218}: "Miljovakt AS", [3]byte{204, 13, 236}: "Cisco SPVTG", @@ -21707,6 +22879,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{204, 30, 255}: "Metrological Group BV", [3]byte{204, 31, 196}: "InVue", [3]byte{204, 32, 232}: "Apple, Inc.", + [3]byte{204, 33, 25}: "Samsung Electronics Co.,Ltd", [3]byte{204, 34, 24}: "InnoDigital Co., Ltd.", [3]byte{204, 34, 55}: "IEEE Registration Authority", [3]byte{204, 37, 239}: "Apple, Inc.", @@ -21716,6 +22889,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{204, 45, 33}: "Tenda Technology Co.,Ltd.Dongguan branch", [3]byte{204, 45, 131}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{204, 45, 140}: "LG ELECTRONICS INC", + [3]byte{204, 45, 183}: "Apple, Inc.", [3]byte{204, 45, 224}: "Routerboard.com", [3]byte{204, 47, 113}: "Intel Corporate", [3]byte{204, 48, 128}: "VAIO Corporation", @@ -21728,6 +22902,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{204, 58, 97}: "SAMSUNG ELECTRO MECHANICS CO., LTD.", [3]byte{204, 58, 223}: "Private", [3]byte{204, 59, 62}: "Lester Electrical", + [3]byte{204, 59, 88}: "Curiouser Products Inc", [3]byte{204, 60, 63}: "SA.S.S. Datentechnik AG", [3]byte{204, 61, 130}: "Intel Corporate", [3]byte{204, 62, 95}: "Hewlett Packard", @@ -21741,11 +22916,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{204, 74, 225}: "fourtec -Fourier Technologies", [3]byte{204, 75, 115}: "AMPAK Technology, Inc.", [3]byte{204, 75, 251}: "Hellberg Safety AB", + [3]byte{204, 77, 56}: "Carnegie Technologies", [3]byte{204, 78, 36}: "Brocade Communications Systems, Inc.", [3]byte{204, 78, 236}: "HUMAX Co., Ltd.", [3]byte{204, 80, 10}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{204, 80, 28}: "KVH Industries, Inc.", [3]byte{204, 80, 118}: "Ocom Communications, Inc.", + [3]byte{204, 80, 227}: "Espressif Inc.", + [3]byte{204, 81, 180}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{204, 82, 175}: "Universal Global Scientific Industrial Co., Ltd.", [3]byte{204, 83, 181}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{204, 84, 89}: "OnTime Networks AS", @@ -21767,8 +22945,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{204, 109, 239}: "TJK Tietolaite Oy", [3]byte{204, 110, 164}: "Samsung Electronics Co.,Ltd", [3]byte{204, 114, 15}: "Viscount Systems Inc.", + [3]byte{204, 114, 134}: "Xi'an Fengyu Information Technology Co., Ltd.", [3]byte{204, 115, 20}: "HONG KONG WHEATEK TECHNOLOGY LIMITED", [3]byte{204, 116, 152}: "Filmetrics Inc.", + [3]byte{204, 117, 226}: "ARRIS Group, Inc.", [3]byte{204, 118, 105}: "SEETECH", [3]byte{204, 120, 95}: "Apple, Inc.", [3]byte{204, 120, 171}: "Texas Instruments", @@ -21776,6 +22956,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{204, 121, 207}: "SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.", [3]byte{204, 122, 48}: "CMAX Wireless Co., Ltd.", [3]byte{204, 123, 53}: "zte corporation", + [3]byte{204, 123, 97}: "NIKKISO CO., LTD.", [3]byte{204, 125, 55}: "ARRIS Group, Inc.", [3]byte{204, 126, 231}: "Panasonic Corporation AVC Networks Company", [3]byte{204, 129, 218}: "Phicomm (Shanghai) Co., Ltd.", @@ -21784,15 +22965,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{204, 137, 253}: "Nokia Corporation", [3]byte{204, 140, 218}: "Shenzhen Wei Da Intelligent Technology Go.,Ltd", [3]byte{204, 140, 227}: "Texas Instruments", + [3]byte{204, 142, 113}: "Cisco Systems, Inc", [3]byte{204, 144, 147}: "Hansong Tehnologies", [3]byte{204, 144, 232}: "Shenzhen YOUHUA Technology Co., Ltd", [3]byte{204, 145, 43}: "TE Connectivity Touch Solutions", + [3]byte{204, 147, 74}: "Sierra Wireless", [3]byte{204, 148, 74}: "Pfeiffer Vacuum GmbH", [3]byte{204, 148, 112}: "Kinestral Technologies, Inc.", [3]byte{204, 149, 215}: "Vizio, Inc", [3]byte{204, 150, 53}: "LVS Co.,Ltd.", [3]byte{204, 150, 160}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{204, 152, 139}: "SONY Visual Products Inc.", [3]byte{204, 152, 145}: "Cisco Systems, Inc", + [3]byte{204, 153, 22}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{204, 158, 0}: "Nintendo Co., Ltd.", [3]byte{204, 159, 53}: "Transbit Sp. z o.o.", [3]byte{204, 159, 122}: "Chiun Mai Communication Systems, Inc", @@ -21815,17 +23000,22 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{204, 184, 136}: "AnB Securite s.a.", [3]byte{204, 184, 168}: "AMPAK Technology, Inc.", [3]byte{204, 184, 241}: "EAGLE KINGDOM TECHNOLOGIES LIMITED", + [3]byte{204, 187, 254}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{204, 189, 53}: "Steinel GmbH", [3]byte{204, 189, 211}: "Ultimaker B.V.", [3]byte{204, 190, 89}: "Calix Inc.", [3]byte{204, 190, 113}: "OptiLogix BV", + [3]byte{204, 192, 121}: "Murata Manufacturing Co., Ltd.", [3]byte{204, 193, 4}: "Applied Technical Systems", + [3]byte{204, 194, 224}: "Raisecom Technology CO., LTD", [3]byte{204, 195, 234}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{204, 197, 10}: "SHENZHEN DAJIAHAO TECHNOLOGY CO.,LTD", + [3]byte{204, 197, 229}: "Dell Inc.", [3]byte{204, 197, 239}: "Co-Comm Servicios Telecomunicaciones S.L.", [3]byte{204, 198, 43}: "Tri-Systems Corporation", [3]byte{204, 199, 96}: "Apple, Inc.", [3]byte{204, 200, 215}: "CIAS Elettronica srl", + [3]byte{204, 201, 44}: "Schindler - PORT Technology", [3]byte{204, 204, 78}: "Sun Fountainhead USA. Corp", [3]byte{204, 204, 129}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{204, 205, 100}: "SM-Electronic GmbH", @@ -21833,7 +23023,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{204, 206, 64}: "Janteq Corp", [3]byte{204, 210, 155}: "Shenzhen Bopengfa Elec&Technology CO.,Ltd", [3]byte{204, 211, 30}: "IEEE Registration Authority", + [3]byte{204, 211, 193}: "Vestel Elektronik San ve Tic. A.Ş.", [3]byte{204, 211, 226}: "Jiangsu Yinhe Electronics Co.,Ltd.", + [3]byte{204, 212, 161}: "MitraStar Technology Corp.", [3]byte{204, 213, 57}: "Cisco Systems, Inc", [3]byte{204, 216, 17}: "Aiconn Technology Corporation", [3]byte{204, 216, 193}: "Cisco Systems, Inc", @@ -21845,8 +23037,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{204, 231, 223}: "American Magnetics, Inc.", [3]byte{204, 232, 172}: "SOYEA Technology Co.,Ltd.", [3]byte{204, 234, 28}: "DCONWORKS Co., Ltd", - [3]byte{204, 238, 217}: "VAHLE DETO GmbH", + [3]byte{204, 238, 217}: "VAHLE Automation GmbH", [3]byte{204, 239, 72}: "Cisco Systems, Inc", + [3]byte{204, 240, 253}: "China Mobile (Hangzhou) Information Technology Co., Ltd.", [3]byte{204, 243, 165}: "Chi Mei Communication Systems, Inc", [3]byte{204, 244, 7}: "EUKREA ELECTROMATIQUE SARL", [3]byte{204, 245, 56}: "3isysnetworks", @@ -21863,6 +23056,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{204, 253, 23}: "TCT mobile ltd", [3]byte{204, 254, 60}: "Samsung Electronics Co.,Ltd", [3]byte{208, 3, 75}: "Apple, Inc.", + [3]byte{208, 3, 223}: "Samsung Electronics Co.,Ltd", [3]byte{208, 4, 1}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{208, 4, 146}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{208, 5, 42}: "Arcadyan Corporation", @@ -21876,6 +23070,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{208, 19, 30}: "Sunrex Technology Corp", [3]byte{208, 19, 253}: "LG Electronics (Mobile Communications)", [3]byte{208, 21, 74}: "zte corporation", + [3]byte{208, 22, 180}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{208, 23, 106}: "Samsung Electronics Co.,Ltd", [3]byte{208, 23, 194}: "ASUSTek COMPUTER INC.", [3]byte{208, 26, 167}: "UniPrint", @@ -21883,10 +23078,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{208, 34, 18}: "IEEE Registration Authority", [3]byte{208, 34, 190}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", [3]byte{208, 35, 219}: "Apple, Inc.", - [3]byte{208, 37, 22}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", + [3]byte{208, 37, 22}: "MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", [3]byte{208, 37, 68}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", [3]byte{208, 37, 152}: "Apple, Inc.", [3]byte{208, 39, 136}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{208, 43, 32}: "Apple, Inc.", [3]byte{208, 44, 69}: "littleBits Electronics, Inc.", [3]byte{208, 45, 179}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{208, 49, 16}: "Ingenic Semiconductor Co.,Ltd", @@ -21906,7 +23102,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{208, 77, 44}: "Roku, Inc.", [3]byte{208, 79, 126}: "Apple, Inc.", [3]byte{208, 80, 153}: "ASRock Incorporation", - [3]byte{208, 81, 98}: "Sony Mobile Communications AB", + [3]byte{208, 81, 98}: "Sony Mobile Communications Inc", [3]byte{208, 82, 168}: "Physical Graph Corporation", [3]byte{208, 83, 73}: "Liteon Technology Corporation", [3]byte{208, 84, 45}: "Cambridge Industries(Group) Co.,Ltd.", @@ -21917,6 +23113,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{208, 87, 161}: "Werma Signaltechnik GmbH & Co. KG", [3]byte{208, 88, 117}: "Active Control Technology Inc.", [3]byte{208, 88, 168}: "zte corporation", + [3]byte{208, 88, 252}: "BSkyB Ltd", [3]byte{208, 89, 149}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{208, 89, 195}: "CeraMicro Technology Corporation", [3]byte{208, 89, 228}: "Samsung Electronics Co.,Ltd", @@ -21948,21 +23145,27 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{208, 115, 213}: "LIFI LABS MANAGEMENT PTY LTD", [3]byte{208, 117, 190}: "Reno A&E", [3]byte{208, 118, 80}: "IEEE Registration Authority", + [3]byte{208, 118, 231}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{208, 119, 20}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{208, 122, 181}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{208, 124, 45}: "Leie IOT technology Co., Ltd", [3]byte{208, 125, 229}: "Forward Pay Systems, Inc.", [3]byte{208, 126, 40}: "Hewlett Packard", [3]byte{208, 126, 53}: "Intel Corporate", + [3]byte{208, 127, 160}: "Samsung Electronics Co.,Ltd", [3]byte{208, 127, 196}: "Ou Wei Technology Co.,Ltd. of Shenzhen City", + [3]byte{208, 129, 122}: "Apple, Inc.", [3]byte{208, 131, 212}: "Xtel Wireless ApS", [3]byte{208, 132, 176}: "Sagemcom Broadband SAS", [3]byte{208, 135, 226}: "Samsung Electronics Co.,Ltd", [3]byte{208, 137, 153}: "APCON, Inc.", [3]byte{208, 138, 85}: "Skullcandy", + [3]byte{208, 138, 145}: "Technicolor CH USA Inc.", [3]byte{208, 139, 126}: "Passif Semiconductor", [3]byte{208, 140, 181}: "Texas Instruments", [3]byte{208, 140, 255}: "UPWIS AB", [3]byte{208, 146, 158}: "Microsoft Corporation", + [3]byte{208, 146, 250}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{208, 147, 128}: "Ducere Technologies Pvt. Ltd.", [3]byte{208, 147, 248}: "Stonestreet One LLC", [3]byte{208, 148, 102}: "Dell Inc.", @@ -21982,12 +23185,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{208, 175, 182}: "Linktop Technology Co., LTD", [3]byte{208, 176, 205}: "Moen", [3]byte{208, 177, 40}: "Samsung Electronics Co.,Ltd", + [3]byte{208, 178, 20}: "PoeWit Inc", [3]byte{208, 178, 196}: "Technicolor CH USA Inc.", [3]byte{208, 179, 63}: "Shenzhen TINNO Mobile Technology Corp.", [3]byte{208, 180, 152}: "Robert Bosch LLC Automotive Electronics", [3]byte{208, 181, 35}: "Bestcare Cloucal Corp.", [3]byte{208, 181, 61}: "SEPRO ROBOTIQUE", [3]byte{208, 181, 194}: "Texas Instruments", + [3]byte{208, 182, 10}: "Xingluo Technology Company Limited", [3]byte{208, 186, 228}: "Shanghai MXCHIP Information Technology Co., Ltd.", [3]byte{208, 187, 128}: "SHL Telemedicine International Ltd.", [3]byte{208, 189, 1}: "DS International", @@ -21998,6 +23203,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{208, 193, 177}: "Samsung Electronics Co.,Ltd", [3]byte{208, 194, 130}: "Cisco Systems, Inc", [3]byte{208, 196, 47}: "Tamagawa Seiki Co.,Ltd.", + [3]byte{208, 197, 211}: "AzureWave Technology Inc.", + [3]byte{208, 197, 216}: "LATECOERE", [3]byte{208, 197, 243}: "Apple, Inc.", [3]byte{208, 199, 137}: "Cisco Systems, Inc", [3]byte{208, 199, 192}: "TP-LINK TECHNOLOGIES CO.,LTD.", @@ -22012,6 +23219,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{208, 212, 18}: "ADB Broadband Italia", [3]byte{208, 212, 113}: "MVTECH co., Ltd", [3]byte{208, 214, 204}: "Wintop", + [3]byte{208, 215, 131}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{208, 217, 79}: "IEEE Registration Authority", [3]byte{208, 219, 50}: "Nokia Corporation", [3]byte{208, 223, 154}: "Liteon Technology Corporation", @@ -22025,6 +23233,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{208, 231, 130}: "AzureWave Technology Inc.", [3]byte{208, 235, 3}: "Zhehua technology limited", [3]byte{208, 235, 158}: "Seowoo Inc.", + [3]byte{208, 239, 193}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{208, 240, 219}: "Ericsson", [3]byte{208, 242, 127}: "SteadyServ Technoligies, LLC", [3]byte{208, 247, 59}: "Helmut Mauell GmbH Werk Weida", @@ -22048,6 +23257,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{212, 16, 144}: "iNFORM Systems AG", [3]byte{212, 16, 207}: "Huanshun Network Science and Technology Co., Ltd.", [3]byte{212, 17, 214}: "ShotSpotter, Inc.", + [3]byte{212, 18, 67}: "AMPAK Technology, Inc.", [3]byte{212, 18, 150}: "Anobit Technologies Ltd.", [3]byte{212, 18, 187}: "Quadrant Components Inc. Ltd", [3]byte{212, 19, 111}: "Asia Pacific Brands", @@ -22057,7 +23267,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{212, 30, 53}: "TOHO Electronics INC.", [3]byte{212, 31, 12}: "JAI Oy", [3]byte{212, 32, 109}: "HTC Corporation", - [3]byte{212, 33, 34}: "Sercomm Corporation", + [3]byte{212, 33, 34}: "Sercomm Corporation.", [3]byte{212, 34, 63}: "Lenovo Mobile Communication Technology Ltd.", [3]byte{212, 34, 78}: "Alcatel Lucent", [3]byte{212, 37, 139}: "Intel Corporate", @@ -22070,11 +23280,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{212, 44, 68}: "Cisco Systems, Inc", [3]byte{212, 47, 35}: "Akenori PTE Ltd", [3]byte{212, 49, 157}: "Sinwatec", + [3]byte{212, 50, 96}: "GoPro", [3]byte{212, 50, 102}: "Fike Corporation", [3]byte{212, 54, 57}: "Texas Instruments", [3]byte{212, 54, 219}: "Jiangsu Toppower Automotive Electronics Co., Ltd", [3]byte{212, 55, 215}: "zte corporation", - [3]byte{212, 56, 156}: "Sony Mobile Communications AB", + [3]byte{212, 56, 156}: "Sony Mobile Communications Inc", [3]byte{212, 58, 101}: "IGRS Engineering Lab Ltd.", [3]byte{212, 58, 233}: "DONGGUAN ipt INDUSTRIAL CO., LTD", [3]byte{212, 61, 103}: "Carma Industries Inc.", @@ -22101,29 +23312,35 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{212, 93, 66}: "Nokia Corporation", [3]byte{212, 93, 223}: "PEGATRON CORPORATION", [3]byte{212, 95, 37}: "Shenzhen YOUHUA Technology Co., Ltd", + [3]byte{212, 96, 227}: "Sercomm Corporation.", [3]byte{212, 97, 46}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{212, 97, 50}: "Pro Concept Manufacturer Co.,Ltd.", [3]byte{212, 97, 157}: "Apple, Inc.", + [3]byte{212, 97, 218}: "Apple, Inc.", [3]byte{212, 97, 254}: "Hangzhou H3C Technologies Co., Limited", [3]byte{212, 99, 198}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{212, 99, 254}: "Arcadyan Corporation", [3]byte{212, 100, 247}: "CHENGDU USEE DIGITAL TECHNOLOGY CO., LTD", - [3]byte{212, 102, 168}: "Riedo Networks GmbH", - [3]byte{212, 103, 97}: "SAHAB TECHNOLOGY", + [3]byte{212, 102, 168}: "Riedo Networks Ltd", + [3]byte{212, 103, 97}: "United Gulf Gate Co.", [3]byte{212, 103, 231}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{212, 104, 77}: "Ruckus Wireless", [3]byte{212, 104, 103}: "Neoventus Design Group", [3]byte{212, 104, 186}: "Shenzhen Sundray Technologies Company Limited", + [3]byte{212, 105, 165}: "Miura Systems Ltd.", [3]byte{212, 106, 106}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{212, 106, 145}: "Snap AV", [3]byte{212, 106, 168}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{212, 108, 191}: "Goodrich ISR", [3]byte{212, 108, 218}: "CSM GmbH", [3]byte{212, 109, 80}: "Cisco Systems, Inc", + [3]byte{212, 109, 109}: "Intel Corporate", [3]byte{212, 110, 14}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{212, 110, 92}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{212, 111, 66}: "WAXESS USA Inc", [3]byte{212, 114, 8}: "Bragi GmbH", + [3]byte{212, 114, 38}: "zte corporation", + [3]byte{212, 116, 27}: "Beijing HuaDa ZhiBao Electronic System Co.,Ltd.", [3]byte{212, 118, 234}: "zte corporation", [3]byte{212, 120, 86}: "Avaya Inc", [3]byte{212, 121, 195}: "Cameronet GmbH & Co. KG", @@ -22131,6 +23348,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{212, 123, 53}: "NEO Monitors AS", [3]byte{212, 123, 117}: "HARTING Electronics GmbH", [3]byte{212, 123, 176}: "ASKEY COMPUTER CORP", + [3]byte{212, 124, 68}: "IEEE Registration Authority", [3]byte{212, 125, 252}: "TECNO MOBILE LIMITED", [3]byte{212, 129, 202}: "iDevices, LLC", [3]byte{212, 129, 215}: "Dell Inc.", @@ -22144,6 +23362,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{212, 141, 217}: "Meld Technology, Inc", [3]byte{212, 143, 51}: "Microsoft Corporation", [3]byte{212, 143, 170}: "Sogecam Industrial, S.A.", + [3]byte{212, 144, 156}: "Apple, Inc.", [3]byte{212, 144, 224}: "Topcon Electronics GmbH & Co. KG", [3]byte{212, 145, 175}: "Electroacustica General Iberica, S.A.", [3]byte{212, 147, 152}: "Nokia Corporation", @@ -22158,13 +23377,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{212, 155, 92}: "Chongqing Miedu Technology Co., Ltd.", [3]byte{212, 156, 40}: "JayBird LLC", [3]byte{212, 156, 142}: "University of FUKUI", + [3]byte{212, 156, 244}: "Palo Alto Networks", + [3]byte{212, 158, 5}: "zte corporation", [3]byte{212, 158, 109}: "Wuhan Zhongyuan Huadian Science & Technology Co.,", [3]byte{212, 160, 42}: "Cisco Systems, Inc", [3]byte{212, 161, 72}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{212, 163, 61}: "Apple, Inc.", [3]byte{212, 164, 37}: "SMAX Technology Co., Ltd.", [3]byte{212, 164, 153}: "InView Technology Corporation", [3]byte{212, 169, 40}: "GreenWave Reality Inc", [3]byte{212, 170, 255}: "MICRO WORLD", + [3]byte{212, 171, 130}: "ARRIS Group, Inc.", [3]byte{212, 172, 78}: "BODi rS, LLC", [3]byte{212, 173, 45}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{212, 174, 5}: "Samsung Electronics Co.,Ltd", @@ -22174,13 +23397,16 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{212, 178, 122}: "ARRIS Group, Inc.", [3]byte{212, 180, 62}: "Messcomp Datentechnik GmbH", [3]byte{212, 184, 255}: "Home Control Singapore Pte Ltd", + [3]byte{212, 189, 30}: "5VT Technologies,Taiwan LTd.", [3]byte{212, 190, 217}: "Dell Inc.", [3]byte{212, 191, 45}: "SE Controls Asia Pacific Ltd", [3]byte{212, 191, 127}: "UPVEL", + [3]byte{212, 193, 158}: "Ruckus Wireless", [3]byte{212, 193, 200}: "zte corporation", [3]byte{212, 193, 252}: "Nokia Corporation", [3]byte{212, 199, 102}: "Acentic GmbH", [3]byte{212, 200, 176}: "Prime Electronics & Satellitics Inc.", + [3]byte{212, 201, 75}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{212, 201, 178}: "Quanergy Systems Inc", [3]byte{212, 201, 239}: "Hewlett Packard", [3]byte{212, 202, 109}: "Routerboard.com", @@ -22202,6 +23428,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{212, 224, 142}: "ValueHD Corporation", [3]byte{212, 227, 44}: "S. Siedle & Sohne", [3]byte{212, 227, 63}: "Nokia", + [3]byte{212, 230, 183}: "Samsung Electronics Co.,Ltd", [3]byte{212, 232, 178}: "Samsung Electronics Co.,Ltd", [3]byte{212, 233, 11}: "CVT CO.,LTD", [3]byte{212, 234, 14}: "Avaya Inc", @@ -22216,7 +23443,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{212, 244, 190}: "Palo Alto Networks", [3]byte{212, 245, 19}: "Texas Instruments", [3]byte{212, 246, 63}: "IEA S.R.L.", + [3]byte{212, 247, 134}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{212, 249, 161}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{212, 252, 19}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{216, 0, 77}: "Apple, Inc.", [3]byte{216, 5, 46}: "Skyviia Corporation", [3]byte{216, 6, 209}: "Honeywell Fire System (Shanghai) Co,. Ltd.", @@ -22224,6 +23453,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{216, 8, 245}: "Arcadia Networks Co. Ltd.", [3]byte{216, 9, 195}: "Cercacor Labs", [3]byte{216, 12, 207}: "C.G.V. S.A.S.", + [3]byte{216, 13, 23}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{216, 13, 227}: "FXI TECHNOLOGIES AS", [3]byte{216, 15, 153}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{216, 20, 214}: "SURE SYSTEM Co Ltd", @@ -22231,15 +23461,18 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{216, 22, 10}: "Nippon Electro-Sensory Devices", [3]byte{216, 22, 193}: "DEWAV (HK) ELECTRONICS LIMITED", [3]byte{216, 24, 43}: "Conti Temic Microelectronic GmbH", + [3]byte{216, 24, 211}: "Juniper Networks", [3]byte{216, 25, 122}: "Nuheara Ltd", [3]byte{216, 25, 206}: "Telesquare", [3]byte{216, 27, 254}: "TWINLINX CORPORATION", [3]byte{216, 28, 20}: "Compacta International, Ltd.", + [3]byte{216, 28, 121}: "Apple, Inc.", [3]byte{216, 29, 114}: "Apple, Inc.", [3]byte{216, 30, 222}: "B&W Group Ltd", [3]byte{216, 31, 204}: "Brocade Communications Systems, Inc.", [3]byte{216, 32, 159}: "Cubro Acronet GesmbH", [3]byte{216, 34, 244}: "Avnet Silica", + [3]byte{216, 36, 119}: "Universal Electric Corporation", [3]byte{216, 36, 189}: "Cisco Systems, Inc", [3]byte{216, 37, 34}: "ARRIS Group, Inc.", [3]byte{216, 37, 176}: "Rockeetech Systems Co.,Ltd.", @@ -22256,6 +23489,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{216, 49, 207}: "Samsung Electronics Co.,Ltd", [3]byte{216, 50, 20}: "Tenda Technology Co.,Ltd.Dongguan branch", [3]byte{216, 50, 90}: "Shenzhen YOUHUA Technology Co., Ltd", + [3]byte{216, 50, 227}: "Xiaomi Communications Co Ltd", [3]byte{216, 51, 127}: "Office FA.com Co.,Ltd.", [3]byte{216, 55, 190}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", [3]byte{216, 56, 13}: "SHENZHEN IP-COM Network Co.,Ltd", @@ -22264,6 +23498,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{216, 66, 172}: "Shanghai Feixun Communication Co.,Ltd.", [3]byte{216, 66, 226}: "Canary Connect, Inc.", [3]byte{216, 67, 237}: "Suzuken", + [3]byte{216, 68, 92}: "DEV Tecnologia Ind Com Man Eq LTDA", [3]byte{216, 69, 43}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{216, 70, 6}: "Silicon Valley Global Marketing", [3]byte{216, 71, 16}: "Sichuan Changhong Electric Ltd.", @@ -22295,6 +23530,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{216, 102, 198}: "Shenzhen Daystar Technology Co.,ltd", [3]byte{216, 102, 238}: "BOXIN COMMUNICATION CO.,LTD.", [3]byte{216, 103, 217}: "Cisco Systems, Inc", + [3]byte{216, 104, 195}: "Samsung Electronics Co.,Ltd", [3]byte{216, 105, 96}: "Steinsvik", [3]byte{216, 107, 247}: "Nintendo Co., Ltd.", [3]byte{216, 108, 2}: "Huaqin Telecom Technology Co.,Ltd", @@ -22307,6 +23543,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{216, 120, 229}: "KUHN SA", [3]byte{216, 121, 136}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{216, 124, 221}: "SANIX INCORPORATED", + [3]byte{216, 125, 127}: "Sagemcom Broadband SAS", [3]byte{216, 126, 177}: "x.o.ware, inc.", [3]byte{216, 128, 57}: "Microchip Technology Inc.", [3]byte{216, 128, 60}: "Anhui Huami Information Technology Company Limited", @@ -22319,6 +23556,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{216, 141, 92}: "Elentec", [3]byte{216, 143, 118}: "Apple, Inc.", [3]byte{216, 144, 232}: "Samsung Electronics Co.,Ltd", + [3]byte{216, 145, 42}: "Zyxel Communications Corporation", [3]byte{216, 147, 65}: "General Electric Global Research", [3]byte{216, 148, 3}: "Hewlett Packard Enterprise", [3]byte{216, 149, 47}: "Texas Instruments", @@ -22330,6 +23568,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{216, 151, 124}: "Grey Innovation", [3]byte{216, 151, 186}: "PEGATRON CORPORATION", [3]byte{216, 154, 52}: "Beijing SHENQI Technology Co., Ltd.", + [3]byte{216, 156, 103}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{216, 157, 103}: "Hewlett Packard", [3]byte{216, 157, 185}: "eMegatech International Corp.", [3]byte{216, 158, 63}: "Apple, Inc.", @@ -22338,6 +23577,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{216, 161, 5}: "Syslane, Co., Ltd.", [3]byte{216, 162, 94}: "Apple, Inc.", [3]byte{216, 165, 52}: "Spectronix Corporation", + [3]byte{216, 166, 253}: "Ghost Locomotion", + [3]byte{216, 167, 86}: "Sagemcom Broadband SAS", + [3]byte{216, 169, 139}: "Texas Instruments", [3]byte{216, 173, 221}: "Sonavation, Inc.", [3]byte{216, 174, 144}: "Itibia Technologies", [3]byte{216, 175, 59}: "Hangzhou Bigbright Integrated communications system Co.,Ltd", @@ -22367,6 +23609,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{216, 200, 233}: "Phicomm (Shanghai) Co., Ltd.", [3]byte{216, 201, 157}: "EA DISPLAY LIMITED", [3]byte{216, 203, 138}: "Micro-Star INTL CO., LTD.", + [3]byte{216, 206, 58}: "Xiaomi Communications Co Ltd", [3]byte{216, 207, 156}: "Apple, Inc.", [3]byte{216, 209, 203}: "Apple, Inc.", [3]byte{216, 210, 124}: "JEMA ENERGY, SA", @@ -22374,7 +23617,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{216, 212, 60}: "Sony Corporation", [3]byte{216, 213, 185}: "Rainforest Automation, Inc.", [3]byte{216, 214, 126}: "GSK CNC EQUIPMENT CO.,LTD", + [3]byte{216, 214, 243}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{216, 215, 35}: "IDS, Inc", + [3]byte{216, 215, 117}: "Sagemcom Broadband SAS", [3]byte{216, 216, 102}: "SHENZHEN TOZED TECHNOLOGIES CO.,LTD.", [3]byte{216, 218, 82}: "APATOR S.A.", [3]byte{216, 220, 233}: "Kunshan Erlab ductless filtration system Co.,Ltd", @@ -22397,6 +23642,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{216, 239, 205}: "Nokia", [3]byte{216, 240, 242}: "Zeebo Inc", [3]byte{216, 241, 240}: "Pepxim International Limited", + [3]byte{216, 242, 202}: "Intel Corporate", + [3]byte{216, 243, 219}: "Post CH AG", [3]byte{216, 247, 16}: "Libre Wireless Technologies Inc.", [3]byte{216, 251, 17}: "AXACORE", [3]byte{216, 251, 94}: "ASKEY COMPUTER CORP", @@ -22412,6 +23659,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{220, 5, 117}: "SIEMENS ENERGY AUTOMATION", [3]byte{220, 5, 237}: "Nabtesco Corporation", [3]byte{220, 7, 193}: "HangZhou QiYang Technology Co.,Ltd.", + [3]byte{220, 8, 15}: "Apple, Inc.", [3]byte{220, 8, 86}: "Alcatel-Lucent Enterprise", [3]byte{220, 9, 20}: "Talk-A-Phone Co.", [3]byte{220, 9, 76}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -22423,6 +23671,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{220, 14, 161}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", [3]byte{220, 21, 219}: "Ge Ruili Intelligent Technology ( Beijing ) Co., Ltd.", [3]byte{220, 22, 162}: "Medtronic Diabetes", + [3]byte{220, 22, 178}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{220, 23, 90}: "Hitachi High-Technologies Corporation", [3]byte{220, 23, 146}: "Captivate Network", [3]byte{220, 26, 1}: "Ecoliv Technology ( Shenzhen ) Ltd.", @@ -22431,7 +23680,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{220, 29, 212}: "Microstep-MIS spol. s r.o.", [3]byte{220, 30, 163}: "Accensus LLC", [3]byte{220, 32, 8}: "ASD Electronics Ltd", + [3]byte{220, 33, 185}: "Sentec Co.Ltd", [3]byte{220, 40, 52}: "HAKKO Corporation", + [3]byte{220, 41, 25}: "AltoBeam (Xiamen) Technology Ltd, Co.", [3]byte{220, 41, 58}: "Shenzhen Nuoshi Technology Co., LTD.", [3]byte{220, 42, 20}: "Shanghai Longjing Technology Co.", [3]byte{220, 43, 42}: "Apple, Inc.", @@ -22443,14 +23694,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{220, 46, 106}: "HCT. Co., Ltd.", [3]byte{220, 47, 3}: "Step forward Group Co., Ltd.", [3]byte{220, 48, 156}: "Heyrex Limited", - [3]byte{220, 51, 13}: "Qingdao Haier Telecom Co.,Ltd", + [3]byte{220, 51, 13}: "QING DAO HAIER TELECOM CO.,LTD.", [3]byte{220, 51, 80}: "TechSAT GmbH", [3]byte{220, 53, 241}: "Positivo Informática SA.", [3]byte{220, 55, 20}: "Apple, Inc.", [3]byte{220, 55, 82}: "GE", + [3]byte{220, 55, 87}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{220, 55, 210}: "Hunan HKT Electronic Technology Co., Ltd", [3]byte{220, 56, 225}: "Juniper Networks", - [3]byte{220, 57, 121}: "Skyport Systems", + [3]byte{220, 57, 121}: "Cisco Systems, Inc", [3]byte{220, 58, 94}: "Roku, Inc.", [3]byte{220, 60, 46}: "Manufacturing System Insights, Inc.", [3]byte{220, 60, 132}: "Ticom Geomatics, Inc.", @@ -22458,6 +23710,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{220, 62, 81}: "Solberg & Andersen AS", [3]byte{220, 62, 248}: "Nokia Corporation", [3]byte{220, 65, 95}: "Apple, Inc.", + [3]byte{220, 65, 229}: "Shenzhen Zhixin Data Service Co., Ltd.", [3]byte{220, 68, 39}: "IEEE Registration Authority", [3]byte{220, 68, 109}: "Allwinner Technology Co., Ltd", [3]byte{220, 68, 182}: "Samsung Electronics Co.,Ltd", @@ -22467,11 +23720,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{220, 74, 62}: "Hewlett Packard", [3]byte{220, 77, 35}: "MRV Comunications", [3]byte{220, 78, 222}: "SHINYEI TECHNOLOGY CO., LTD.", + [3]byte{220, 78, 244}: "Shenzhen MTN Electronics CO., Ltd", [3]byte{220, 79, 34}: "Espressif Inc.", [3]byte{220, 83, 96}: "Intel Corporate", [3]byte{220, 83, 124}: "Compal Broadband Networks, Inc.", [3]byte{220, 85, 131}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{220, 86, 230}: "Shenzhen Bococom Technology Co.,LTD", + [3]byte{220, 86, 231}: "Apple, Inc.", [3]byte{220, 87, 38}: "Power-One", [3]byte{220, 94, 54}: "Paterson Technology", [3]byte{220, 96, 161}: "Teledyne DALSA Professional Imaging", @@ -22486,6 +23741,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{220, 111, 8}: "Bay Storage Technology", [3]byte{220, 112, 20}: "Private", [3]byte{220, 113, 68}: "SAMSUNG ELECTRO MECHANICS CO., LTD.", + [3]byte{220, 114, 155}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{220, 116, 168}: "Samsung Electronics Co.,Ltd", [3]byte{220, 120, 52}: "LOGICOM SA", [3]byte{220, 123, 148}: "Cisco Systems, Inc", @@ -22494,6 +23750,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{220, 130, 246}: "iPort", [3]byte{220, 133, 222}: "AzureWave Technology Inc.", [3]byte{220, 134, 216}: "Apple, Inc.", + [3]byte{220, 139, 40}: "Intel Corporate", + [3]byte{220, 144, 136}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{220, 153, 20}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{220, 154, 142}: "Nanjing Cocomm electronics co., LTD", [3]byte{220, 155, 30}: "Intercom, Inc.", [3]byte{220, 155, 156}: "Apple, Inc.", @@ -22501,6 +23760,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{220, 156, 159}: "Shenzhen YOUHUA Technology Co., Ltd", [3]byte{220, 159, 164}: "Nokia Corporation", [3]byte{220, 159, 219}: "Ubiquiti Networks Inc.", + [3]byte{220, 162, 102}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{220, 163, 51}: "Shenzhen YOUHUA Technology Co., Ltd", [3]byte{220, 163, 172}: "RBcloudtech", [3]byte{220, 164, 202}: "Apple, Inc.", [3]byte{220, 165, 244}: "Cisco Systems, Inc", @@ -22512,8 +23773,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{220, 169, 137}: "MACANDC", [3]byte{220, 173, 158}: "GreenPriz", [3]byte{220, 174, 4}: "CELOXICA Ltd", + [3]byte{220, 175, 104}: "WEIFANG GOERTEK ELECTRONICS CO.,LTD", [3]byte{220, 176, 88}: "Bürkert Werke GmbH", [3]byte{220, 179, 180}: "Honeywell Environmental & Combustion Controls (Tianjin) Co., Ltd.", + [3]byte{220, 180, 172}: "FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD.", [3]byte{220, 180, 196}: "Microsoft XCG", [3]byte{220, 190, 122}: "Zhejiang Nurotron Biotechnology Co.", [3]byte{220, 191, 144}: "HUIZHOU QIAOXING TELECOMMUNICATION INDUSTRY CO.,LTD.", @@ -22536,17 +23799,24 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{220, 210, 85}: "Kinpo Electronics, Inc.", [3]byte{220, 210, 252}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{220, 211, 33}: "HUMAX Co., Ltd.", + [3]byte{220, 211, 162}: "Apple, Inc.", [3]byte{220, 213, 42}: "Sunny Heart Limited", [3]byte{220, 216, 124}: "Beijing Jingdong Century Trading Co., LTD.", [3]byte{220, 216, 127}: "Shenzhen JoinCyber Telecom Equipment Ltd", [3]byte{220, 217, 22}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{220, 218, 79}: "GETCK TECHNOLOGY, INC", + [3]byte{220, 218, 128}: "New H3C Technologies Co., Ltd", [3]byte{220, 219, 112}: "Tonfunk Systementwicklung und Service GmbH", [3]byte{220, 220, 7}: "TRP Systems BV", + [3]byte{220, 221, 36}: "Energica Motor Company SpA", + [3]byte{220, 222, 79}: "Gionee Communication Equipment Co Ltd", [3]byte{220, 222, 202}: "Akyllor", [3]byte{220, 224, 38}: "Patrol Tag, Inc", + [3]byte{220, 224, 235}: "Nanjing Aozheng Information Technology Co.Ltd", [3]byte{220, 225, 173}: "Shenzhen Wintop Photoelectric Technology Co., Ltd", [3]byte{220, 226, 172}: "Lumens Digital Optics Inc.", + [3]byte{220, 227, 5}: "ZAO NPK Rotek", + [3]byte{220, 229, 51}: "IEEE Registration Authority", [3]byte{220, 229, 120}: "Experimental Factory of Scientific Engineering and Special Design Department", [3]byte{220, 231, 28}: "AUG Elektronik GmbH", [3]byte{220, 232, 56}: "CK Telecom (Shenzhen) Limited", @@ -22559,7 +23829,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{220, 240, 93}: "Letta Teknoloji", [3]byte{220, 240, 144}: "Nubia Technology Co.,Ltd.", [3]byte{220, 241, 16}: "Nokia Corporation", + [3]byte{220, 244, 1}: "Dell Inc.", + [3]byte{220, 245, 5}: "AzureWave Technology Inc.", + [3]byte{220, 247, 25}: "Cisco Systems, Inc", [3]byte{220, 247, 85}: "SITRONIK", + [3]byte{220, 247, 86}: "Samsung Electronics Co.,Ltd", [3]byte{220, 248, 88}: "Lorent Networks, Inc.", [3]byte{220, 250, 213}: "STRONG Ges.m.b.H.", [3]byte{220, 251, 2}: "BUFFALO.INC", @@ -22573,10 +23847,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{224, 12, 127}: "Nintendo Co., Ltd.", [3]byte{224, 13, 185}: "Cree, Inc.", [3]byte{224, 14, 218}: "Cisco Systems, Inc", + [3]byte{224, 14, 225}: "We Corporation Inc.", [3]byte{224, 16, 127}: "Ruckus Wireless", + [3]byte{224, 18, 131}: "Shenzhen Fanzhuo Communication Technology Co., Lt", + [3]byte{224, 19, 181}: "vivo Mobile Communication Co., Ltd.", [3]byte{224, 20, 62}: "Modoosis Inc.", [3]byte{224, 24, 119}: "FUJITSU LIMITED", + [3]byte{224, 24, 159}: "EM Microelectronic", [3]byte{224, 25, 29}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{224, 25, 216}: "BH TECHNOLOGIES", [3]byte{224, 26, 234}: "Allied Telesis, Inc.", [3]byte{224, 28, 65}: "Aerohive Networks Inc.", [3]byte{224, 28, 238}: "Bravo Tech, Inc.", @@ -22599,11 +23878,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{224, 48, 5}: "Alcatel-Lucent Shanghai Bell Co., Ltd", [3]byte{224, 49, 158}: "Valve Corporation", [3]byte{224, 49, 208}: "SZ Telstar CO., LTD", + [3]byte{224, 51, 142}: "Apple, Inc.", [3]byte{224, 52, 228}: "Feit Electric Company, Inc.", [3]byte{224, 53, 96}: "Challenger Supply Holdings, LLC", [3]byte{224, 54, 118}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{224, 54, 227}: "Stage One International Co., Ltd.", [3]byte{224, 55, 191}: "Wistron Neweb Corporation", + [3]byte{224, 56, 63}: "zte corporation", [3]byte{224, 57, 215}: "Plexxi, Inc.", [3]byte{224, 60, 91}: "SHENZHEN JIAXINJIE ELECTRON CO.,LTD", [3]byte{224, 62, 68}: "Broadcom", @@ -22612,9 +23893,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{224, 63, 73}: "ASUSTek COMPUTER INC.", [3]byte{224, 65, 54}: "MitraStar Technology Corp.", [3]byte{224, 67, 219}: "Shenzhen ViewAt Technology Co.,Ltd.", + [3]byte{224, 69, 109}: "China Mobile Group Device Co.,Ltd.", [3]byte{224, 70, 154}: "NETGEAR", + [3]byte{224, 70, 229}: "Gosuncn Technology Group Co., Ltd.", [3]byte{224, 72, 175}: "Premietech Limited", [3]byte{224, 72, 211}: "MOBIWIRE MOBILES (NINGBO) CO.,LTD", + [3]byte{224, 73, 237}: "Audeze LLC", [3]byte{224, 75, 69}: "Hi-P Electronics Pte Ltd", [3]byte{224, 79, 67}: "Universal Global Scientific Industrial Co., Ltd.", [3]byte{224, 79, 189}: "SICHUAN TIANYI COMHEART TELECOMCO.,LTD", @@ -22626,25 +23910,31 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{224, 86, 244}: "AxesNetwork Solutions inc.", [3]byte{224, 88, 158}: "Laerdal Medical", [3]byte{224, 91, 112}: "Innovid, Co., Ltd.", + [3]byte{224, 93, 92}: "Oy Everon Ab", [3]byte{224, 93, 166}: "Detlef Fink Elektronik & Softwareentwicklung", [3]byte{224, 95, 69}: "Apple, Inc.", [3]byte{224, 95, 185}: "Cisco Systems, Inc", - [3]byte{224, 96, 102}: "Sercomm Corporation", + [3]byte{224, 96, 102}: "Sercomm Corporation.", [3]byte{224, 96, 137}: "Cloudleaf, Inc.", [3]byte{224, 97, 178}: "HANGZHOU ZENOINTEL TECHNOLOGY CO., LTD", + [3]byte{224, 98, 103}: "Xiaomi Communications Co Ltd", [3]byte{224, 98, 144}: "Jinan Jovision Science & Technology Co., Ltd.", - [3]byte{224, 99, 229}: "Sony Mobile Communications AB", + [3]byte{224, 99, 218}: "Ubiquiti Networks Inc.", + [3]byte{224, 99, 229}: "Sony Mobile Communications Inc", [3]byte{224, 100, 187}: "DigiView S.r.l.", [3]byte{224, 102, 120}: "Apple, Inc.", [3]byte{224, 103, 179}: "C-Data Technology Co., Ltd", [3]byte{224, 104, 109}: "Raybased AB", [3]byte{224, 105, 149}: "PEGATRON CORPORATION", + [3]byte{224, 115, 95}: "NUCOM", [3]byte{224, 117, 10}: "ALPS ELECTRIC CO.,LTD.", [3]byte{224, 117, 125}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{224, 118, 208}: "AMPAK Technology, Inc.", [3]byte{224, 120, 163}: "Shanghai Winner Information Technology Co.,Inc", + [3]byte{224, 121, 94}: "Wuxi Xiaohu Technology Co.,Ltd.", [3]byte{224, 124, 19}: "zte corporation", [3]byte{224, 124, 98}: "Whistle Labs, Inc.", + [3]byte{224, 125, 234}: "Texas Instruments", [3]byte{224, 127, 83}: "TECHBOARD SRL", [3]byte{224, 127, 136}: "EVIDENCE Network SIA", [3]byte{224, 129, 119}: "GreenBytes, Inc.", @@ -22670,6 +23960,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{224, 161, 215}: "SFR", [3]byte{224, 163, 15}: "Pevco", [3]byte{224, 163, 172}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{224, 165, 9}: "Bitmain Technologies Inc", [3]byte{224, 166, 112}: "Nokia Corporation", [3]byte{224, 167, 0}: "Verkada Inc", [3]byte{224, 168, 184}: "Le Shi Zhi Xin Electronic Technology (Tianjin) Limited", @@ -22683,6 +23974,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{224, 174, 178}: "Bender GmbH & Co.KG", [3]byte{224, 174, 237}: "LOENK", [3]byte{224, 175, 75}: "Pluribus Networks, Inc.", + [3]byte{224, 175, 79}: "Deutsche Telekom AG", [3]byte{224, 178, 241}: "FN-LINK TECHNOLOGY LIMITED", [3]byte{224, 181, 45}: "Apple, Inc.", [3]byte{224, 182, 245}: "IEEE Registration Authority", @@ -22692,6 +23984,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{224, 185, 165}: "AzureWave Technology Inc.", [3]byte{224, 185, 186}: "Apple, Inc.", [3]byte{224, 185, 229}: "Technicolor", + [3]byte{224, 186, 180}: "Arrcus, Inc", [3]byte{224, 188, 67}: "C2 Microsystems, Inc.", [3]byte{224, 192, 209}: "CK Telecom (Shenzhen) Limited", [3]byte{224, 194, 134}: "Aisai Communication Technology Co., Ltd.", @@ -22728,6 +24021,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{224, 220, 160}: "Siemens Industrial Automation Products Ltd Chengdu", [3]byte{224, 221, 192}: "vivo Mobile Communication Co., Ltd.", [3]byte{224, 229, 207}: "Texas Instruments", + [3]byte{224, 230, 46}: "TCT mobile ltd", [3]byte{224, 230, 49}: "SNB TECHNOLOGIES LIMITED", [3]byte{224, 231, 81}: "Nintendo Co., Ltd.", [3]byte{224, 231, 187}: "Nureva, Inc.", @@ -22746,6 +24040,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{224, 255, 247}: "Softiron Inc.", [3]byte{228, 2, 155}: "Intel Corporate", [3]byte{228, 4, 57}: "TomTom Software Ltd", + [3]byte{228, 14, 238}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{228, 17, 91}: "Hewlett Packard", [3]byte{228, 18, 24}: "ShenZhen Rapoo Technology Co., Ltd.", [3]byte{228, 18, 29}: "Samsung Electronics Co.,Ltd", @@ -22756,6 +24051,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{228, 28, 75}: "V2 TECHNOLOGY, INC.", [3]byte{228, 29, 45}: "Mellanox Technologies, Inc.", [3]byte{228, 31, 19}: "IBM Corp", + [3]byte{228, 31, 233}: "Dunkermotoren GmbH", [3]byte{228, 34, 165}: "PLANTRONICS, INC.", [3]byte{228, 35, 84}: "SHENZHEN FUZHI SOFTWARE TECHNOLOGY CO.,LTD", [3]byte{228, 37, 231}: "Apple, Inc.", @@ -22765,27 +24061,34 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{228, 43, 52}: "Apple, Inc.", [3]byte{228, 44, 86}: "Lilee Systems, Ltd.", [3]byte{228, 45, 2}: "TCT mobile ltd", + [3]byte{228, 45, 123}: "China Mobile IOT Company Limited", [3]byte{228, 47, 38}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{228, 47, 86}: "OptoMET GmbH", [3]byte{228, 47, 246}: "Unicore communication Inc.", + [3]byte{228, 48, 34}: "Hanwha Techwin Security Vietnam", [3]byte{228, 50, 203}: "Samsung Electronics Co.,Ltd", + [3]byte{228, 52, 147}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{228, 53, 147}: "Hangzhou GoTo technology Co.Ltd", [3]byte{228, 53, 200}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{228, 53, 251}: "Sabre Technology (Hull) Ltd", [3]byte{228, 55, 215}: "HENRI DEPAEPE S.A.S.", + [3]byte{228, 56, 140}: "Digital Products Limited", [3]byte{228, 56, 242}: "Advantage Controls", [3]byte{228, 58, 110}: "Shenzhen Zeroone Technology CO.,LTD", + [3]byte{228, 60, 128}: "University of Oklahoma", [3]byte{228, 62, 215}: "Arcadyan Corporation", [3]byte{228, 63, 162}: "Wuxi DSP Technologies Inc.", [3]byte{228, 64, 226}: "Samsung Electronics Co.,Ltd", [3]byte{228, 65, 230}: "Ottec Technology GmbH", [3]byte{228, 66, 166}: "Intel Corporate", + [3]byte{228, 67, 75}: "Dell Inc.", [3]byte{228, 70, 189}: "C&C TECHNIC TAIWAN CO., LTD.", [3]byte{228, 70, 218}: "Xiaomi Communications Co Ltd", [3]byte{228, 71, 144}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{228, 72, 199}: "Cisco SPVTG", [3]byte{228, 76, 108}: "Shenzhen Guo Wei Electronic Co,. Ltd.", [3]byte{228, 78, 24}: "Gardasoft VisionLimited", + [3]byte{228, 78, 118}: "CHAMPIONTECH ENTERPRISE (SHENZHEN) INC", [3]byte{228, 79, 41}: "MA Lighting Technology GmbH", [3]byte{228, 79, 95}: "EDS Elektronik Destek San.Tic.Ltd.Sti", [3]byte{228, 80, 154}: "HW Communications Ltd", @@ -22799,6 +24102,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{228, 93, 81}: "SFR", [3]byte{228, 93, 82}: "Avaya Inc", [3]byte{228, 93, 117}: "Samsung Electronics Co.,Ltd", + [3]byte{228, 96, 89}: "Pingtek Co., Ltd.", [3]byte{228, 98, 81}: "HAO CHENG GROUP LIMITED", [3]byte{228, 100, 73}: "ARRIS Group, Inc.", [3]byte{228, 103, 186}: "Danish Interpretation Systems A/S", @@ -22822,6 +24126,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{228, 127, 178}: "FUJITSU LIMITED", [3]byte{228, 129, 132}: "Nokia", [3]byte{228, 129, 179}: "Shenzhen ACT Industrial Co.,Ltd.", + [3]byte{228, 130, 204}: "Jumptronic GmbH", [3]byte{228, 131, 153}: "ARRIS Group, Inc.", [3]byte{228, 133, 1}: "Geberit International AG", [3]byte{228, 138, 213}: "RF WINDOW CO., LTD.", @@ -22829,6 +24134,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{228, 140, 15}: "Discovery Insure", [3]byte{228, 141, 140}: "Routerboard.com", [3]byte{228, 143, 52}: "Vodafone Italia S.p.A.", + [3]byte{228, 143, 101}: "Yelatma Instrument Making Enterprise, JSC", [3]byte{228, 144, 105}: "Rockwell Automation", [3]byte{228, 144, 126}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{228, 146, 231}: "Gridlink Tech. Co.,Ltd.", @@ -22857,34 +24163,46 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{228, 175, 161}: "HES-SO", [3]byte{228, 176, 5}: "Beijing IQIYI Science & Technology Co., Ltd.", [3]byte{228, 176, 33}: "Samsung Electronics Co.,Ltd", + [3]byte{228, 178, 251}: "Apple, Inc.", [3]byte{228, 179, 24}: "Intel Corporate", + [3]byte{228, 185, 122}: "Dell Inc.", [3]byte{228, 186, 217}: "360 Fly Inc.", [3]byte{228, 189, 75}: "zte corporation", [3]byte{228, 190, 237}: "Netcore Technology Inc.", [3]byte{228, 193, 70}: "Objetivos y Servicios de Valor A", [3]byte{228, 193, 241}: "SHENZHEN SPOTMAU INFORMATION TECHNOLIGY CO., Ltd", [3]byte{228, 194, 209}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{228, 196, 131}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{228, 198, 43}: "Airware", [3]byte{228, 198, 61}: "Apple, Inc.", [3]byte{228, 198, 230}: "Mophie, LLC", [3]byte{228, 199, 34}: "Cisco Systems, Inc", [3]byte{228, 200, 1}: "BLU Products Inc", [3]byte{228, 200, 6}: "Ceiec Electric Technology Inc.", + [3]byte{228, 202, 18}: "zte corporation", + [3]byte{228, 203, 89}: "Beijing Loveair Science and Technology Co. Ltd.", [3]byte{228, 206, 2}: "WyreStorm Technologies Ltd", [3]byte{228, 206, 112}: "Health & Life co., Ltd.", [3]byte{228, 206, 143}: "Apple, Inc.", + [3]byte{228, 209, 36}: "Mojo Networks, Inc.", [3]byte{228, 211, 50}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{228, 211, 170}: "FUJITSU CONNECTED TECHNOLOGIES LIMITED", [3]byte{228, 211, 241}: "Cisco Systems, Inc", [3]byte{228, 213, 61}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{228, 215, 29}: "Oraya Therapeutics", + [3]byte{228, 219, 109}: "Beijing Xiaomi Electronics Co., Ltd.", [3]byte{228, 221, 121}: "En-Vision America, Inc.", + [3]byte{228, 224, 166}: "Apple, Inc.", [3]byte{228, 224, 197}: "Samsung Electronics Co.,Ltd", + [3]byte{228, 225, 48}: "TCT mobile ltd", [3]byte{228, 228, 9}: "LEIFHEIT AG", [3]byte{228, 228, 171}: "Apple, Inc.", + [3]byte{228, 234, 131}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", [3]byte{228, 236, 16}: "Nokia Corporation", [3]byte{228, 238, 253}: "MR&D Manufacturing", [3]byte{228, 240, 4}: "Dell Inc.", [3]byte{228, 240, 66}: "Google, Inc.", + [3]byte{228, 241, 76}: "Private", [3]byte{228, 243, 101}: "Time-O-Matic, Inc.", [3]byte{228, 243, 227}: "Shanghai iComhome Co.,Ltd.", [3]byte{228, 243, 245}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", @@ -22898,6 +24216,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{228, 250, 253}: "Intel Corporate", [3]byte{228, 251, 93}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{228, 251, 143}: "MOBIWIRE MOBILES (NINGBO) CO.,LTD", + [3]byte{228, 252, 130}: "Juniper Networks", [3]byte{228, 254, 217}: "EDMI Europe Ltd", [3]byte{228, 255, 221}: "ELECTRON INDIA", [3]byte{232, 0, 54}: "Befs co,. ltd", @@ -22926,15 +24245,21 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{232, 22, 43}: "IDEO Security Co., Ltd.", [3]byte{232, 23, 252}: "Fujitsu Cloud Technologies Limited", [3]byte{232, 24, 99}: "IEEE Registration Authority", + [3]byte{232, 26, 88}: "TECHNOLOGIC SYSTEMS", + [3]byte{232, 26, 172}: "ORFEO SOUNDWORKS Inc.", + [3]byte{232, 28, 186}: "Fortinet, Inc.", [3]byte{232, 29, 168}: "Ruckus Wireless", [3]byte{232, 32, 226}: "HUMAX Co., Ltd.", [3]byte{232, 40, 119}: "TMY Co., Ltd.", [3]byte{232, 40, 213}: "Cots Technology", [3]byte{232, 42, 68}: "Liteon Technology Corporation", [3]byte{232, 42, 234}: "Intel Corporate", + [3]byte{232, 44, 109}: "SmartRG, Inc.", [3]byte{232, 46, 36}: "Out of the Fog Research LLC", + [3]byte{232, 51, 13}: "Xaptec GmbH", [3]byte{232, 51, 129}: "ARRIS Group, Inc.", [3]byte{232, 52, 62}: "Beijing Infosec Technologies Co., LTD.", + [3]byte{232, 54, 23}: "Apple, Inc.", [3]byte{232, 54, 29}: "Sense Labs, Inc.", [3]byte{232, 55, 122}: "Zyxel Communications Corporation", [3]byte{232, 57, 53}: "Hewlett Packard", @@ -22961,9 +24286,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{232, 86, 89}: "Advanced-Connectek Inc.", [3]byte{232, 86, 214}: "NCTech Ltd", [3]byte{232, 90, 167}: "LLC Emzior", + [3]byte{232, 90, 209}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{232, 91, 91}: "LG ELECTRONICS INC", [3]byte{232, 91, 240}: "Imaging Diagnostics", [3]byte{232, 93, 107}: "Luminate Wireless", + [3]byte{232, 93, 134}: "CHANG YOW TECHNOLOGIES INTERNATIONAL CO.,LTD.", [3]byte{232, 94, 83}: "Infratec Datentechnik GmbH", [3]byte{232, 97, 31}: "Dawning Information Industry Co.,Ltd", [3]byte{232, 97, 126}: "Liteon Technology Corporation", @@ -22973,6 +24300,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{232, 101, 212}: "Tenda Technology Co.,Ltd.Dongguan branch", [3]byte{232, 102, 196}: "Diamanti", [3]byte{232, 104, 25}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{232, 106, 100}: "LCFC(HeFei) Electronics Technology co., ltd", [3]byte{232, 108, 218}: "Supercomputers and Neurocomputers Research Center", [3]byte{232, 109, 82}: "ARRIS Group, Inc.", [3]byte{232, 109, 84}: "Digit Mobile Inc", @@ -22997,25 +24325,31 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{232, 146, 24}: "Arcontia International AB", [3]byte{232, 146, 164}: "LG Electronics (Mobile Communications)", [3]byte{232, 147, 9}: "Samsung Electronics Co.,Ltd", + [3]byte{232, 147, 99}: "Nokia", [3]byte{232, 148, 76}: "Cogent Healthcare Systems Ltd", [3]byte{232, 148, 246}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{232, 150, 6}: "testo Instruments (Shenzhen) Co., Ltd.", + [3]byte{232, 152, 109}: "Palo Alto Networks", [3]byte{232, 153, 90}: "PiiGAB, Processinformation i Goteborg AB", [3]byte{232, 153, 196}: "HTC Corporation", [3]byte{232, 154, 143}: "QUANTA COMPUTER INC.", - [3]byte{232, 154, 255}: "Fujian Landi Commercial Equipment Co.,Ltd", + [3]byte{232, 154, 255}: "Fujian LANDI Commercial Equipment Co.,Ltd", [3]byte{232, 157, 135}: "Toshiba", [3]byte{232, 158, 12}: "Private", [3]byte{232, 158, 180}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{232, 159, 236}: "CHENGDU KT ELECTRONIC HI-TECH CO.,LTD", [3]byte{232, 163, 100}: "Signal Path International / Peachtree Audio", [3]byte{232, 164, 193}: "Deep Sea Electronics PLC", + [3]byte{232, 167, 136}: "XIAMEN LEELEN TECHNOLOGY CO., LTD", [3]byte{232, 167, 242}: "sTraffic", + [3]byte{232, 171, 243}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{232, 171, 250}: "Shenzhen Reecam Tech.Ltd.", + [3]byte{232, 173, 166}: "Sagemcom Broadband SAS", [3]byte{232, 177, 252}: "Intel Corporate", [3]byte{232, 178, 172}: "Apple, Inc.", [3]byte{232, 180, 174}: "Shenzhen C&D Electronics Co.,Ltd", [3]byte{232, 180, 200}: "Samsung Electronics Co.,Ltd", + [3]byte{232, 181, 65}: "zte corporation", [3]byte{232, 182, 194}: "Juniper Networks", [3]byte{232, 183, 72}: "Cisco Systems, Inc", [3]byte{232, 186, 112}: "Cisco Systems, Inc", @@ -23023,15 +24357,18 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{232, 187, 168}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{232, 189, 209}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{232, 190, 129}: "Sagemcom Broadband SAS", + [3]byte{232, 193, 184}: "Nanjing Bangzhong Electronic Commerce Limited", [3]byte{232, 193, 215}: "Philips", [3]byte{232, 194, 41}: "H-Displays (MSC) Bhd", [3]byte{232, 195, 32}: "Austco Communication Systems Pty Ltd", + [3]byte{232, 197, 122}: "Ufispace Co., LTD.", [3]byte{232, 199, 79}: "Liteon Technology Corporation", [3]byte{232, 203, 161}: "Nokia Corporation", [3]byte{232, 204, 24}: "D-Link International", [3]byte{232, 204, 50}: "Micronet LTD", [3]byte{232, 205, 45}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{232, 206, 6}: "SkyHawke Technologies, LLC.", + [3]byte{232, 208, 153}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{232, 208, 250}: "MKS Instruments Deutschland GmbH", [3]byte{232, 209, 27}: "ASKEY COMPUTER CORP", [3]byte{232, 212, 131}: "ULTIMATE Europe Transportation Equipment GmbH", @@ -23039,9 +24376,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{232, 216, 25}: "AzureWave Technology Inc.", [3]byte{232, 218, 150}: "Zhuhai Tianrui Electrical Power Tech. Co., Ltd.", [3]byte{232, 218, 170}: "VideoHome Technology Corp.", + [3]byte{232, 222, 0}: "ChongQing GuanFang Technology Co.,LTD", [3]byte{232, 222, 39}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{232, 222, 142}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{232, 222, 214}: "Intrising Networks, Inc.", + [3]byte{232, 222, 251}: "MESOTIC SAS", [3]byte{232, 223, 112}: "AVM Audiovisuelles Marketing und Computersysteme GmbH", [3]byte{232, 223, 242}: "PRF Co., Ltd.", [3]byte{232, 224, 143}: "GRAVOTECH MARKING SAS", @@ -23065,6 +24404,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{232, 242, 227}: "Starcor Beijing Co.,Limited", [3]byte{232, 247, 36}: "Hewlett Packard Enterprise", [3]byte{232, 249, 40}: "RFTECH SRL", + [3]byte{232, 250, 247}: "Guangdong Uniteddata Holding Group Co., Ltd.", [3]byte{232, 252, 96}: "ELCOM Innovations Private Limited", [3]byte{232, 252, 175}: "NETGEAR", [3]byte{232, 253, 114}: "SHANGHAI LINGUO TECHNOLOGY CO., LTD.", @@ -23102,10 +24442,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{236, 38, 251}: "TECC CO.,LTD.", [3]byte{236, 42, 240}: "Ypsomed AG", [3]byte{236, 44, 73}: "University of Tokyo", + [3]byte{236, 44, 226}: "Apple, Inc.", [3]byte{236, 46, 78}: "HITACHI-LG DATA STORAGE INC", [3]byte{236, 48, 145}: "Cisco Systems, Inc", [3]byte{236, 53, 134}: "Apple, Inc.", [3]byte{236, 54, 63}: "Markov Corporation", + [3]byte{236, 56, 115}: "Juniper Networks", [3]byte{236, 56, 143}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{236, 59, 240}: "NovelSat", [3]byte{236, 60, 90}: "SHEN ZHEN HENG SHENG HUI DIGITAL TECHNOLOGY CO.,LTD", @@ -23131,45 +24473,57 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{236, 82, 220}: "WORLD MEDIA AND TECHNOLOGY Corp.", [3]byte{236, 84, 46}: "Shanghai XiMei Electronic Technology Co. Ltd", [3]byte{236, 85, 249}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{236, 88, 234}: "Ruckus Wireless", [3]byte{236, 89, 231}: "Microsoft Corporation", [3]byte{236, 90, 134}: "Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd", + [3]byte{236, 92, 104}: "CHONGQING FUGUI ELECTRONICS CO.,LTD.", [3]byte{236, 92, 105}: "MITSUBISHI HEAVY INDUSTRIES MECHATRONICS SYSTEMS,LTD.", [3]byte{236, 95, 35}: "Qinghai Kimascend Electronics Technology Co. Ltd.", [3]byte{236, 96, 224}: "AVI-ON LABS", [3]byte{236, 98, 100}: "Global411 Internet Services, LLC", [3]byte{236, 99, 229}: "ePBoard Design LLC", [3]byte{236, 100, 231}: "MOCACARE Corporation", + [3]byte{236, 101, 204}: "Panasonic Automotive Systems Company of America", [3]byte{236, 102, 209}: "B&W Group LTD", [3]byte{236, 104, 129}: "Palo Alto Networks", [3]byte{236, 108, 159}: "Chengdu Volans Technology CO.,LTD", + [3]byte{236, 111, 11}: "FADU, Inc.", [3]byte{236, 112, 151}: "ARRIS Group, Inc.", [3]byte{236, 113, 219}: "Shenzhen Baichuan Digital Technology Co., Ltd.", [3]byte{236, 116, 186}: "Hirschmann Automation and Control GmbH", + [3]byte{236, 121, 242}: "Startel", [3]byte{236, 124, 116}: "Justone Technologies Co., Ltd.", [3]byte{236, 125, 17}: "vivo Mobile Communication Co., Ltd.", [3]byte{236, 125, 157}: "MEI", + [3]byte{236, 127, 198}: "ECCEL CORPORATION SAS", [3]byte{236, 128, 9}: "NovaSparks", [3]byte{236, 129, 147}: "Logitech, Inc", [3]byte{236, 131, 80}: "Microsoft Corporation", [3]byte{236, 131, 108}: "RM Tech Co., Ltd.", + [3]byte{236, 131, 213}: "GIRD Systems Inc", + [3]byte{236, 132, 180}: "CIG SHANGHAI CO LTD", [3]byte{236, 133, 47}: "Apple, Inc.", [3]byte{236, 136, 143}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{236, 136, 146}: "Motorola Mobility LLC, a Lenovo Company", + [3]byte{236, 137, 20}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{236, 137, 245}: "Lenovo Mobile Communication Technology Ltd.", [3]byte{236, 138, 76}: "zte corporation", [3]byte{236, 138, 199}: "Fiberhome Telecommunication Technologies Co.,LTD", + [3]byte{236, 140, 154}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{236, 140, 162}: "Ruckus Wireless", [3]byte{236, 142, 173}: "DLX", [3]byte{236, 142, 174}: "Nagravision SA", [3]byte{236, 142, 181}: "Hewlett Packard", [3]byte{236, 146, 51}: "Eddyfi NDT Inc", [3]byte{236, 147, 39}: "MEMMERT GmbH + Co. KG", + [3]byte{236, 147, 101}: "Mapper.ai, Inc.", [3]byte{236, 147, 237}: "DDoS-Guard LTD", [3]byte{236, 150, 129}: "2276427 Ontario Inc", [3]byte{236, 152, 108}: "Lufft Mess- und Regeltechnik GmbH", [3]byte{236, 152, 193}: "Beijing Risbo Network Technology Co.,Ltd", [3]byte{236, 154, 116}: "Hewlett Packard", [3]byte{236, 155, 91}: "Nokia Corporation", + [3]byte{236, 155, 139}: "Hewlett Packard Enterprise", [3]byte{236, 155, 243}: "SAMSUNG ELECTRO-MECHANICS(THAILAND)", [3]byte{236, 158, 205}: "Artesyn Embedded Technologies", [3]byte{236, 159, 13}: "IEEE Registration Authority", @@ -23178,9 +24532,11 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{236, 169, 250}: "GUANGDONG GENIUS TECHNOLOGY CO.,LTD.", [3]byte{236, 170, 160}: "PEGATRON CORPORATION", [3]byte{236, 173, 184}: "Apple, Inc.", + [3]byte{236, 175, 151}: "GIT", [3]byte{236, 176, 225}: "Ciena Corporation", [3]byte{236, 177, 6}: "Acuro Networks, Inc", [3]byte{236, 177, 215}: "Hewlett Packard", + [3]byte{236, 179, 19}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", [3]byte{236, 181, 65}: "SHINANO E and E Co.Ltd.", [3]byte{236, 181, 250}: "Philips Lighting BV", [3]byte{236, 184, 112}: "Beijing Heweinet Technology Co.,Ltd.", @@ -23191,6 +24547,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{236, 189, 29}: "Cisco Systems, Inc", [3]byte{236, 192, 106}: "PowerChord Group Limited", [3]byte{236, 195, 138}: "Accuenergy (CANADA) Inc", + [3]byte{236, 196, 13}: "Nintendo Co.,Ltd", [3]byte{236, 200, 130}: "Cisco Systems, Inc", [3]byte{236, 203, 48}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{236, 205, 109}: "Allied Telesis, Inc.", @@ -23218,11 +24575,13 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{236, 235, 184}: "Hewlett Packard Enterprise", [3]byte{236, 238, 216}: "ZTLX Network Technology Co.,Ltd", [3]byte{236, 240, 14}: "AboCom", + [3]byte{236, 240, 254}: "zte corporation", [3]byte{236, 242, 54}: "NEOMONTANA ELECTRONICS", [3]byte{236, 243, 66}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", [3]byte{236, 243, 91}: "Nokia Corporation", [3]byte{236, 244, 81}: "Arcadyan Corporation", [3]byte{236, 244, 187}: "Dell Inc.", + [3]byte{236, 246, 189}: "SNCF MOBILITÉS", [3]byte{236, 247, 43}: "HD DIGITAL TECH CO., LTD.", [3]byte{236, 248, 235}: "SICHUAN TIANYI COMHEART TELECOMCO., LTD", [3]byte{236, 250, 3}: "FCA", @@ -23238,10 +24597,14 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{240, 7, 134}: "Shandong Bittel Electronics Co., Ltd", [3]byte{240, 8, 241}: "Samsung Electronics Co.,Ltd", [3]byte{240, 13, 92}: "JinQianMao Technology Co.,Ltd.", + [3]byte{240, 14, 29}: "Megafone Limited", + [3]byte{240, 14, 191}: "ZettaHash Inc.", + [3]byte{240, 15, 236}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{240, 19, 195}: "SHENZHEN FENDA TECHNOLOGY CO., LTD", [3]byte{240, 21, 160}: "KyungDong One Co., Ltd.", [3]byte{240, 21, 185}: "PlayFusion Limited", [3]byte{240, 24, 43}: "LG Chem", + [3]byte{240, 24, 152}: "Apple, Inc.", [3]byte{240, 27, 108}: "vivo Mobile Communication Co., Ltd.", [3]byte{240, 28, 19}: "LG Electronics (Mobile Communications)", [3]byte{240, 28, 45}: "Juniper Networks", @@ -23278,15 +24641,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{240, 62, 191}: "GOGORO TAIWAN LIMITED", [3]byte{240, 63, 248}: "R L Drake", [3]byte{240, 64, 123}: "Fiberhome Telecommunication Technologies Co.,LTD", + [3]byte{240, 65, 200}: "IEEE Registration Authority", [3]byte{240, 66, 28}: "Intel Corporate", [3]byte{240, 67, 53}: "DVN(Shanghai)Ltd.", [3]byte{240, 67, 71}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{240, 69, 218}: "Texas Instruments", [3]byte{240, 74, 43}: "PYRAMID Computer GmbH", + [3]byte{240, 75, 58}: "Juniper Networks", [3]byte{240, 75, 106}: "Scientific Production Association Siberian Arsenal, Ltd.", [3]byte{240, 75, 242}: "JTECH Communications, Inc.", + [3]byte{240, 76, 213}: "Maxlinear, Inc", [3]byte{240, 77, 162}: "Dell Inc.", [3]byte{240, 79, 124}: "Private", + [3]byte{240, 84, 148}: "Honeywell Connected Building", [3]byte{240, 88, 73}: "CareView Communications", [3]byte{240, 90, 9}: "Samsung Electronics Co.,Ltd", [3]byte{240, 91, 123}: "Samsung Electronics Co.,Ltd", @@ -23297,6 +24664,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{240, 97, 48}: "Advantage Pharmacy Services, LLC", [3]byte{240, 98, 13}: "Shenzhen Egreat Tech Corp.,Ltd", [3]byte{240, 98, 129}: "ProCurve Networking by HP", + [3]byte{240, 99, 249}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{240, 101, 194}: "Yanfeng Visteon Electronics Technology (Shanghai) Co.,Ltd.", [3]byte{240, 101, 221}: "Primax Electronics Ltd.", [3]byte{240, 104, 83}: "Integrated Corporation", @@ -23309,6 +24677,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{240, 116, 133}: "NGD Systems, Inc.", [3]byte{240, 116, 228}: "Thundercomm Technology Co., Ltd", [3]byte{240, 118, 28}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", + [3]byte{240, 118, 111}: "Apple, Inc.", [3]byte{240, 119, 101}: "Sourcefire, Inc", [3]byte{240, 119, 208}: "Xcellen", [3]byte{240, 120, 22}: "Cisco Systems, Inc", @@ -23319,6 +24688,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{240, 125, 104}: "D-Link Corporation", [3]byte{240, 127, 6}: "Cisco Systems, Inc", [3]byte{240, 127, 12}: "Leopold Kostal GmbH &Co. KG", + [3]byte{240, 129, 115}: "Amazon Technologies Inc.", [3]byte{240, 129, 175}: "IRZ AUTOMATION TECHNOLOGIES LTD", [3]byte{240, 130, 97}: "Sagemcom Broadband SAS", [3]byte{240, 132, 47}: "ADB Broadband Italia", @@ -23332,15 +24702,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{240, 146, 180}: "SICHUAN TIANYI COMHEART TELECOMCO., LTD", [3]byte{240, 147, 58}: "NxtConect", [3]byte{240, 147, 197}: "Garland Technology", + [3]byte{240, 149, 241}: "Carl Zeiss AG", [3]byte{240, 151, 229}: "TAMIO, INC", [3]byte{240, 152, 56}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{240, 152, 157}: "Apple, Inc.", + [3]byte{240, 153, 182}: "Apple, Inc.", [3]byte{240, 153, 191}: "Apple, Inc.", [3]byte{240, 154, 81}: "Shanghai Viroyal Electronic Technology Company Limited", [3]byte{240, 156, 187}: "RaonThink Inc.", + [3]byte{240, 156, 215}: "Guangzhou Blue Cheetah Intelligent Technology Co., Ltd.", [3]byte{240, 156, 233}: "Aerohive Networks Inc.", [3]byte{240, 158, 99}: "Cisco Systems, Inc", [3]byte{240, 159, 194}: "Ubiquiti Networks Inc.", + [3]byte{240, 159, 252}: "SHARP Corporation", [3]byte{240, 162, 37}: "Private", [3]byte{240, 167, 100}: "GST Co., Ltd.", [3]byte{240, 171, 84}: "MITSUMI ELECTRIC CO.,LTD.", @@ -23348,13 +24722,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{240, 172, 215}: "IEEE Registration Authority", [3]byte{240, 173, 78}: "Globalscale Technologies, Inc.", [3]byte{240, 174, 81}: "Xi3 Corp", + [3]byte{240, 175, 80}: "Phantom Intelligence", + [3]byte{240, 175, 133}: "ARRIS Group, Inc.", + [3]byte{240, 176, 20}: "AVM Audiovisuelles Marketing und Computersysteme GmbH", [3]byte{240, 176, 82}: "Ruckus Wireless", [3]byte{240, 176, 231}: "Apple, Inc.", [3]byte{240, 178, 229}: "Cisco Systems, Inc", [3]byte{240, 180, 41}: "Xiaomi Communications Co Ltd", [3]byte{240, 180, 121}: "Apple, Inc.", + [3]byte{240, 181, 183}: "Disruptive Technologies Research AS", + [3]byte{240, 181, 209}: "Texas Instruments", [3]byte{240, 182, 235}: "Poslab Technology Co., Ltd.", [3]byte{240, 188, 200}: "MaxID (Pty) Ltd", + [3]byte{240, 188, 201}: "PFU LIMITED", [3]byte{240, 189, 46}: "H+S Polatis Ltd", [3]byte{240, 189, 241}: "Sipod Inc.", [3]byte{240, 191, 151}: "Sony Corporation", @@ -23364,6 +24744,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{240, 199, 127}: "Texas Instruments", [3]byte{240, 200, 80}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{240, 200, 140}: "LeddarTech Inc.", + [3]byte{240, 201, 209}: "GD Midea Air-Conditioning Equipment Co.,Ltd.", [3]byte{240, 203, 161}: "Apple, Inc.", [3]byte{240, 209, 79}: "LINEAR LLC", [3]byte{240, 209, 169}: "Apple, Inc.", @@ -23376,6 +24757,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{240, 214, 87}: "ECHOSENS", [3]byte{240, 215, 103}: "Axema Passagekontroll AB", [3]byte{240, 215, 170}: "Motorola Mobility LLC, a Lenovo Company", + [3]byte{240, 215, 220}: "Wesine (Wuhan) Technology Co., Ltd.", [3]byte{240, 217, 178}: "EXO S.A.", [3]byte{240, 218, 124}: "RLH INDUSTRIES,INC.", [3]byte{240, 219, 48}: "Yottabyte", @@ -23385,6 +24767,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{240, 222, 113}: "Shanghai EDO Technologies Co.,Ltd.", [3]byte{240, 222, 185}: "ShangHai Y&Y Electronics Co., Ltd", [3]byte{240, 222, 241}: "Wistron Infocomm (Zhongshan) Corporation", + [3]byte{240, 227, 220}: "Tecon MT, LLC", [3]byte{240, 229, 195}: "Drägerwerk AG & Co. KG aA", [3]byte{240, 231, 126}: "Samsung Electronics Co.,Ltd", [3]byte{240, 235, 208}: "Shanghai Feixun Communication Co.,Ltd.", @@ -23395,6 +24778,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{240, 238, 187}: "VIPAR GmbH", [3]byte{240, 239, 210}: "TF PAYMENT SERVICE CO., LTD", [3]byte{240, 240, 2}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{240, 240, 143}: "Nextek Solutions Pte Ltd", [3]byte{240, 242, 73}: "Hitron Technologies. Inc", [3]byte{240, 242, 96}: "Mobitec AB", [3]byte{240, 243, 54}: "TP-LINK TECHNOLOGIES CO.,LTD.", @@ -23407,6 +24791,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{240, 248, 66}: "KEEBOX, Inc.", [3]byte{240, 248, 242}: "Texas Instruments", [3]byte{240, 249, 247}: "IES GmbH & Co. KG", + [3]byte{240, 252, 200}: "ARRIS Group, Inc.", [3]byte{240, 253, 160}: "Acurix Networks Pty Ltd", [3]byte{240, 254, 107}: "Shanghai High-Flying Electronics Technology Co., Ltd", [3]byte{244, 3, 4}: "Google, Inc.", @@ -23414,6 +24799,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{244, 3, 47}: "Reduxio Systems", [3]byte{244, 3, 67}: "Hewlett Packard Enterprise", [3]byte{244, 4, 76}: "ValenceTech Limited", + [3]byte{244, 6, 22}: "Apple, Inc.", [3]byte{244, 6, 105}: "Intel Corporate", [3]byte{244, 6, 141}: "devolo AG", [3]byte{244, 6, 165}: "Hangzhou Bianfeng Networking Technology Co., Ltd.", @@ -23448,6 +24834,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{244, 54, 225}: "Abilis Systems SARL", [3]byte{244, 55, 183}: "Apple, Inc.", [3]byte{244, 56, 20}: "Shanghai Howell Electronic Co.,Ltd", + [3]byte{244, 57, 9}: "Hewlett Packard", [3]byte{244, 61, 128}: "FAG Industrial Services GmbH", [3]byte{244, 62, 97}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", [3]byte{244, 62, 157}: "Benu Networks, Inc.", @@ -23482,7 +24869,9 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{244, 95, 212}: "Cisco SPVTG", [3]byte{244, 95, 247}: "DQ Technology Inc.", [3]byte{244, 96, 13}: "Panoptic Technology, Inc", + [3]byte{244, 96, 226}: "Xiaomi Communications Co Ltd", [3]byte{244, 98, 208}: "Not for Radio, LLC", + [3]byte{244, 99, 31}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{244, 99, 73}: "Diffon Corporation", [3]byte{244, 100, 93}: "Toshiba", [3]byte{244, 103, 45}: "ShenZhen Topstar Technology Company", @@ -23493,15 +24882,18 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{244, 109, 226}: "zte corporation", [3]byte{244, 110, 36}: "NEC Personal Computers, Ltd.", [3]byte{244, 112, 171}: "vivo Mobile Communication Co., Ltd.", + [3]byte{244, 113, 144}: "Samsung Electronics Co.,Ltd", [3]byte{244, 115, 202}: "Conversion Sound Inc.", [3]byte{244, 118, 38}: "Viltechmeda UAB", [3]byte{244, 122, 78}: "Woojeon&Handan", [3]byte{244, 122, 204}: "SolidFire, Inc.", [3]byte{244, 123, 94}: "Samsung Electronics Co.,Ltd", + [3]byte{244, 125, 239}: "Samsung Electronics Co.,Ltd", [3]byte{244, 127, 53}: "Cisco Systems, Inc", [3]byte{244, 129, 57}: "CANON INC.", [3]byte{244, 131, 205}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{244, 131, 225}: "Shanghai Clouder Semiconductor Co.,Ltd", + [3]byte{244, 132, 76}: "Texas Instruments", [3]byte{244, 133, 198}: "FDT Technologies", [3]byte{244, 135, 113}: "Infoblox", [3]byte{244, 139, 50}: "Xiaomi Communications Co Ltd", @@ -23515,6 +24907,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{244, 147, 159}: "Hon Hai Precision Ind. Co., Ltd.", [3]byte{244, 148, 97}: "NexGen Storage", [3]byte{244, 148, 102}: "CountMax, ltd", + [3]byte{244, 149, 27}: "Hefei Radio Communication Technology Co., Ltd", [3]byte{244, 150, 52}: "Intel Corporate", [3]byte{244, 150, 81}: "NAKAYO Inc", [3]byte{244, 153, 172}: "WEBER Schraubautomaten GmbH", @@ -23537,13 +24930,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{244, 183, 226}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{244, 184, 94}: "Texas Instruments", [3]byte{244, 184, 167}: "zte corporation", + [3]byte{244, 188, 151}: "Shenzhen Crave Communication Co., LTD", [3]byte{244, 189, 124}: "Chengdu jinshi communication Co., LTD", + [3]byte{244, 191, 128}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{244, 194, 72}: "Samsung Electronics Co.,Ltd", [3]byte{244, 196, 71}: "Coagent International Enterprise Limited", [3]byte{244, 196, 214}: "Shenzhen Xinfa Electronic Co.,ltd", [3]byte{244, 198, 19}: "Alcatel-Lucent Shanghai Bell Co., Ltd", [3]byte{244, 198, 215}: "blackned GmbH", [3]byte{244, 199, 20}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{244, 199, 149}: "WEY Elektronik AG", + [3]byte{244, 199, 200}: "Kelvin Inc.", [3]byte{244, 202, 36}: "FreeBit Co., Ltd.", [3]byte{244, 202, 229}: "FREEBOX SAS", [3]byte{244, 203, 82}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -23552,15 +24949,19 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{244, 206, 70}: "Hewlett Packard", [3]byte{244, 207, 226}: "Cisco Systems, Inc", [3]byte{244, 208, 50}: "Yunnan Ideal Information&Technology.,Ltd", + [3]byte{244, 209, 8}: "Intel Corporate", [3]byte{244, 210, 97}: "SEMOCON Co., Ltd", [3]byte{244, 215, 178}: "LGS Innovations, LLC", [3]byte{244, 217, 251}: "Samsung Electronics Co.,Ltd", + [3]byte{244, 219, 230}: "Cisco Systems, Inc", [3]byte{244, 220, 65}: "YOUNGZONE CULTURE (SHANGHAI) CORP", [3]byte{244, 220, 77}: "Beijing CCD Digital Technology Co., Ltd", + [3]byte{244, 220, 165}: "DAWON DNS", [3]byte{244, 220, 218}: "Zhuhai Jiahe Communication Technology Co., limited", [3]byte{244, 220, 249}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{244, 221, 158}: "GoPro", [3]byte{244, 222, 12}: "ESPOD Ltd.", + [3]byte{244, 225, 30}: "Texas Instruments", [3]byte{244, 225, 66}: "Delta Elektronika BV", [3]byte{244, 226, 4}: "Traqueur", [3]byte{244, 227, 251}: "HUAWEI TECHNOLOGIES CO.,LTD", @@ -23573,9 +24974,10 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{244, 235, 56}: "Sagemcom Broadband SAS", [3]byte{244, 236, 56}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{244, 237, 95}: "SHENZHEN KTC TECHNOLOGY GROUP", - [3]byte{244, 238, 20}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", + [3]byte{244, 238, 20}: "MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", [3]byte{244, 239, 158}: "SGSG SCIENCE & TECHNOLOGY CO. LTD", [3]byte{244, 241, 90}: "Apple, Inc.", + [3]byte{244, 241, 151}: "EMTAKE Inc", [3]byte{244, 241, 225}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{244, 242, 109}: "TP-LINK TECHNOLOGIES CO.,LTD.", [3]byte{244, 243, 170}: "JBL GmbH & Co. KG", @@ -23602,9 +25004,12 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{248, 13, 67}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{248, 13, 96}: "CANON INC.", [3]byte{248, 13, 234}: "ZyCast Technology Inc.", + [3]byte{248, 13, 241}: "Sontex SA", [3]byte{248, 15, 65}: "Wistron Infocomm (Zhongshan) Corporation", + [3]byte{248, 15, 111}: "Cisco Systems, Inc", [3]byte{248, 15, 132}: "Natural Security SAS", [3]byte{248, 16, 55}: "Atopia Systems, LP", + [3]byte{248, 19, 8}: "Nokia", [3]byte{248, 21, 71}: "Avaya Inc", [3]byte{248, 22, 84}: "Intel Corporate", [3]byte{248, 24, 151}: "2Wire Inc", @@ -23619,12 +25024,15 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{248, 34, 133}: "Cypress Technology CO., LTD.", [3]byte{248, 35, 178}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{248, 36, 65}: "Yeelink", + [3]byte{248, 39, 46}: "Mercku", [3]byte{248, 39, 147}: "Apple, Inc.", [3]byte{248, 40, 25}: "Liteon Technology Corporation", [3]byte{248, 43, 200}: "Jiangsu Switter Co., Ltd", [3]byte{248, 44, 24}: "2Wire Inc", + [3]byte{248, 45, 124}: "Apple, Inc.", + [3]byte{248, 45, 192}: "ARRIS Group, Inc.", [3]byte{248, 46, 219}: "RTW GmbH & Co. KG", - [3]byte{248, 47, 8}: "Molex", + [3]byte{248, 47, 8}: "Molex CMS", [3]byte{248, 47, 91}: "eGauge Systems LLC", [3]byte{248, 47, 168}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{248, 48, 148}: "Alcatel-Lucent Telecom Limited", @@ -23634,6 +25042,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{248, 52, 65}: "Intel Corporate", [3]byte{248, 53, 83}: "Magenta Research Ltd.", [3]byte{248, 53, 221}: "Gemtek Technology Co., Ltd.", + [3]byte{248, 54, 155}: "Texas Instruments", + [3]byte{248, 56, 128}: "Apple, Inc.", [3]byte{248, 61, 78}: "Softlink Automation System Co., Ltd", [3]byte{248, 61, 255}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{248, 63, 81}: "Samsung Electronics Co.,Ltd", @@ -23648,6 +25058,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{248, 74, 127}: "Innometriks Inc", [3]byte{248, 74, 191}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{248, 79, 87}: "Cisco Systems, Inc", + [3]byte{248, 80, 28}: "Tianjin Geneuo Technology Co.,Ltd", [3]byte{248, 80, 99}: "Verathon", [3]byte{248, 81, 109}: "Denwa Technology Corp.", [3]byte{248, 82, 223}: "VNL Europe AB", @@ -23658,7 +25069,8 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{248, 91, 156}: "SB SYSTEMS Co.,Ltd", [3]byte{248, 91, 201}: "M-Cube Spa", [3]byte{248, 92, 69}: "IC Nexus Co. Ltd.", - [3]byte{248, 92, 77}: "NOKIA", + [3]byte{248, 92, 77}: "Nokia", + [3]byte{248, 94, 60}: "SHENZHEN ZHIBOTONG ELECTRONICS CO.,LTD", [3]byte{248, 95, 42}: "Nokia Corporation", [3]byte{248, 98, 20}: "Apple, Inc.", [3]byte{248, 98, 170}: "xn systems", @@ -23671,6 +25083,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{248, 108, 225}: "Taicang T&W Electronics", [3]byte{248, 110, 207}: "Arcx Inc", [3]byte{248, 110, 238}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{248, 111, 193}: "Apple, Inc.", [3]byte{248, 113, 254}: "The Goldman Sachs Group, Inc.", [3]byte{248, 114, 234}: "Cisco Systems, Inc", [3]byte{248, 115, 148}: "NETGEAR", @@ -23688,18 +25101,23 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{248, 132, 121}: "Yaojin Technology(Shenzhen)Co.,Ltd", [3]byte{248, 132, 242}: "Samsung Electronics Co.,Ltd", [3]byte{248, 138, 60}: "IEEE Registration Authority", + [3]byte{248, 139, 55}: "ARRIS Group, Inc.", [3]byte{248, 140, 28}: "KAISHUN ELECTRONIC TECHNOLOGY CO., LTD. BEIJING", [3]byte{248, 141, 239}: "Tenebraex", [3]byte{248, 142, 133}: "Comtrend Corporation", [3]byte{248, 143, 202}: "Google, Inc.", + [3]byte{248, 144, 102}: "Nain Inc.", [3]byte{248, 145, 42}: "GLP German Light Products GmbH", [3]byte{248, 147, 243}: "VOLANS", [3]byte{248, 148, 194}: "Intel Corporate", [3]byte{248, 149, 80}: "Proton Products Chengdu Ltd", [3]byte{248, 149, 199}: "LG Electronics (Mobile Communications)", + [3]byte{248, 149, 234}: "Apple, Inc.", [3]byte{248, 151, 207}: "DAESHIN-INFORMATION TECHNOLOGY CO., LTD.", [3]byte{248, 152, 58}: "Leeman International (HongKong) Limited", [3]byte{248, 152, 185}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{248, 152, 239}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{248, 153, 16}: "Integrated Device Technology (Malaysia) Sdn. Bhd.", [3]byte{248, 153, 85}: "Fortress Technology Inc", [3]byte{248, 157, 13}: "Control Technology Inc.", [3]byte{248, 157, 187}: "Tintri", @@ -23708,6 +25126,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{248, 160, 151}: "ARRIS Group, Inc.", [3]byte{248, 161, 136}: "LED Roadway Lighting", [3]byte{248, 162, 180}: "RHEWA-WAAGENFABRIK August Freudewald GmbH &Co. KG", + [3]byte{248, 162, 214}: "Liteon Technology Corporation", [3]byte{248, 163, 79}: "zte corporation", [3]byte{248, 164, 95}: "Xiaomi Communications Co Ltd", [3]byte{248, 165, 197}: "Cisco Systems, Inc", @@ -23729,12 +25148,16 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{248, 191, 9}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{248, 192, 1}: "Juniper Networks", [3]byte{248, 192, 145}: "Highgates Technology", + [3]byte{248, 193, 32}: "Xi'an Link-Science Technology Co.,Ltd", + [3]byte{248, 194, 73}: "Private", [3]byte{248, 194, 136}: "Cisco Systems, Inc", [3]byte{248, 195, 114}: "TSUZUKI DENKI", [3]byte{248, 195, 151}: "NZXT Corp. Ltd.", + [3]byte{248, 195, 158}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{248, 198, 120}: "Carefusion", [3]byte{248, 201, 108}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{248, 202, 184}: "Dell Inc.", + [3]byte{248, 204, 110}: "DEPO Electronics Ltd", [3]byte{248, 207, 197}: "Motorola Mobility LLC, a Lenovo Company", [3]byte{248, 208, 39}: "Seiko Epson Corporation", [3]byte{248, 208, 172}: "Sony Interactive Entertainment Inc.", @@ -23744,6 +25167,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{248, 212, 98}: "Pumatronix Equipamentos Eletronicos Ltda.", [3]byte{248, 215, 86}: "Simm Tronic Limited", [3]byte{248, 215, 191}: "REV Ritter GmbH", + [3]byte{248, 217, 184}: "Open Mesh, Inc.", [3]byte{248, 218, 12}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{248, 218, 223}: "EcoTech, Inc.", [3]byte{248, 218, 226}: "Beta LaserMike", @@ -23752,14 +25176,17 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{248, 219, 127}: "HTC Corporation", [3]byte{248, 219, 136}: "Dell Inc.", [3]byte{248, 220, 122}: "Variscite LTD", + [3]byte{248, 223, 21}: "Sunitec Enterprise Co.,Ltd", [3]byte{248, 223, 168}: "zte corporation", [3]byte{248, 224, 121}: "Motorola Mobility LLC, a Lenovo Company", + [3]byte{248, 228, 78}: "MCOT INC.", [3]byte{248, 228, 251}: "Actiontec Electronics, Inc", [3]byte{248, 230, 26}: "Samsung Electronics Co.,Ltd", [3]byte{248, 231, 30}: "Ruckus Wireless", [3]byte{248, 231, 181}: "µTech Tecnologia LTDA", [3]byte{248, 232, 17}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{248, 233, 3}: "D-Link International", + [3]byte{248, 233, 78}: "Apple, Inc.", [3]byte{248, 233, 104}: "Egker Kft.", [3]byte{248, 234, 10}: "Dipl.-Math. Michael Rauch", [3]byte{248, 237, 165}: "ARRIS Group, Inc.", @@ -23770,6 +25197,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{248, 242, 30}: "Intel Corporate", [3]byte{248, 242, 90}: "G-Lab GmbH", [3]byte{248, 244, 100}: "Rawe Electonic GmbH", + [3]byte{248, 245, 50}: "ARRIS Group, Inc.", [3]byte{248, 247, 211}: "International Communications Corporation", [3]byte{248, 247, 255}: "SYN-TECH SYSTEMS INC", [3]byte{248, 251, 47}: "Santur Corporation", @@ -23781,6 +25209,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{252, 1, 124}: "Hon Hai Precision Ind. Co.,Ltd.", [3]byte{252, 1, 158}: "VIEVU", [3]byte{252, 1, 205}: "FUNDACION TEKNIKER", + [3]byte{252, 3, 159}: "Samsung Electronics Co.,Ltd", [3]byte{252, 6, 71}: "Cortland Research, LLC", [3]byte{252, 6, 237}: "M2Motive Technology Inc.", [3]byte{252, 7, 160}: "LRE Medical GmbH", @@ -23798,6 +25227,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{252, 21, 180}: "Hewlett Packard", [3]byte{252, 22, 7}: "Taian Technology(Wuxi) Co.,Ltd.", [3]byte{252, 23, 148}: "InterCreative Co., Ltd", + [3]byte{252, 24, 60}: "Apple, Inc.", [3]byte{252, 25, 16}: "Samsung Electronics Co.,Ltd", [3]byte{252, 25, 208}: "Cloud Vision Networks Technology Co.,Ltd.", [3]byte{252, 26, 17}: "vivo Mobile Communication Co., Ltd.", @@ -23812,6 +25242,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{252, 37, 63}: "Apple, Inc.", [3]byte{252, 39, 162}: "TRANS ELECTRIC CO., LTD.", [3]byte{252, 42, 84}: "Connected Data, Inc.", + [3]byte{252, 42, 156}: "Apple, Inc.", [3]byte{252, 45, 94}: "zte corporation", [3]byte{252, 46, 45}: "Lorom Industrial Co.LTD.", [3]byte{252, 47, 64}: "Calxeda, Inc.", @@ -23852,17 +25283,23 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{252, 91, 57}: "Cisco Systems, Inc", [3]byte{252, 96, 24}: "Zhejiang Kangtai Electric Co., Ltd.", [3]byte{252, 97, 152}: "NEC Personal Products, Ltd", + [3]byte{252, 97, 233}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{252, 98, 110}: "Beijing MDC Telecom", [3]byte{252, 98, 185}: "ALPS ELECTRIC CO.,LTD.", + [3]byte{252, 100, 58}: "Samsung Electronics Co.,Ltd", [3]byte{252, 100, 186}: "Xiaomi Communications Co Ltd", [3]byte{252, 101, 222}: "Amazon Technologies Inc.", [3]byte{252, 104, 62}: "Directed Perception, Inc", + [3]byte{252, 105, 71}: "Texas Instruments", + [3]byte{252, 107, 240}: "TOPWELL INTERNATIONAL HOLDINDS LIMITED", [3]byte{252, 108, 49}: "LXinstruments GmbH", [3]byte{252, 109, 192}: "BME CORPORATION", [3]byte{252, 111, 183}: "ARRIS Group, Inc.", [3]byte{252, 117, 22}: "D-Link International", [3]byte{252, 117, 230}: "Handreamnet", + [3]byte{252, 119, 116}: "Intel Corporate", [3]byte{252, 121, 11}: "Hitachi High Technologies America, Inc.", + [3]byte{252, 124, 2}: "Phicomm (Shanghai) Co., Ltd.", [3]byte{252, 124, 231}: "FCI USA LLC", [3]byte{252, 127, 86}: "CoSyst Control Systems GmbH", [3]byte{252, 131, 41}: "Trei technics", @@ -23870,34 +25307,47 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{252, 131, 198}: "N-Radio Technologies Co., Ltd.", [3]byte{252, 139, 151}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", [3]byte{252, 142, 126}: "ARRIS Group, Inc.", + [3]byte{252, 143, 125}: "SHENZHEN GONGJIN ELECTRONICS CO.,LT", [3]byte{252, 143, 144}: "Samsung Electronics Co.,Ltd", [3]byte{252, 143, 196}: "Intelligent Technology Inc.", + [3]byte{252, 144, 250}: "Independent Technologies", [3]byte{252, 145, 20}: "Technicolor CH USA Inc.", [3]byte{252, 146, 59}: "Nokia Corporation", [3]byte{252, 148, 108}: "UBIVELOX", + [3]byte{252, 148, 206}: "zte corporation", [3]byte{252, 148, 227}: "Technicolor CH USA Inc.", [3]byte{252, 153, 71}: "Cisco Systems, Inc", [3]byte{252, 154, 250}: "Motus Global Inc.", + [3]byte{252, 155, 198}: "Sumavision Technologies Co.,Ltd", [3]byte{252, 157, 216}: "Beijing TongTongYiLian Science and Technology Ltd.", [3]byte{252, 159, 174}: "Fidus Systems Inc", [3]byte{252, 159, 225}: "CONWIN.Tech. Ltd", [3]byte{252, 161, 62}: "Samsung Electronics Co.,Ltd", + [3]byte{252, 161, 131}: "Amazon Technologies Inc.", [3]byte{252, 162, 42}: "PT. Callysta Multi Engineering", [3]byte{252, 163, 134}: "SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD", + [3]byte{252, 166, 33}: "Samsung Electronics Co.,Ltd", [3]byte{252, 166, 103}: "Amazon Technologies Inc.", + [3]byte{252, 166, 205}: "Fiberhome Telecommunication Technologies Co.,LTD", [3]byte{252, 168, 65}: "Avaya Inc", [3]byte{252, 168, 154}: "Sunitec Enterprise Co.,Ltd", [3]byte{252, 169, 176}: "MIARTECH (SHANGHAI),INC.", [3]byte{252, 170, 20}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{252, 170, 182}: "Samsung Electronics Co.,Ltd", [3]byte{252, 173, 15}: "QTS NETWORKS", + [3]byte{252, 174, 52}: "ARRIS Group, Inc.", [3]byte{252, 175, 106}: "Qulsar Inc", [3]byte{252, 175, 172}: "Socionext Inc.", [3]byte{252, 176, 196}: "Shanghai DareGlobal Technologies Co.,Ltd", + [3]byte{252, 177, 13}: "Shenzhen Tian Kun Technology Co.,LTD.", [3]byte{252, 180, 230}: "ASKEY COMPUTER CORP", [3]byte{252, 181, 138}: "Wapice Ltd.", [3]byte{252, 182, 152}: "Cambridge Industries(Group) Co.,Ltd.", + [3]byte{252, 182, 216}: "Apple, Inc.", + [3]byte{252, 183, 240}: "Idaho National Laboratory", [3]byte{252, 187, 161}: "Shenzhen Minicreate Technology Co.,Ltd", [3]byte{252, 188, 156}: "Vimar Spa", + [3]byte{252, 190, 123}: "vivo Mobile Communication Co., Ltd.", [3]byte{252, 194, 51}: "Private", [3]byte{252, 194, 61}: "Atmel Corporation", [3]byte{252, 194, 222}: "Murata Manufacturing Co., Ltd.", @@ -23925,6 +25375,7 @@ var validMACPrefixMap = map[[3]byte]string{ [3]byte{252, 226, 63}: "CLAY PAKY SPA", [3]byte{252, 227, 60}: "HUAWEI TECHNOLOGIES CO.,LTD", [3]byte{252, 229, 87}: "Nokia Corporation", + [3]byte{252, 230, 106}: "Industrial Software Co", [3]byte{252, 232, 146}: "Hangzhou Lancable Technology Co.,Ltd", [3]byte{252, 233, 152}: "Apple, Inc.", [3]byte{252, 236, 218}: "Ubiquiti Networks Inc.", diff --git a/vendor/github.com/google/gopacket/packet.go b/vendor/github.com/google/gopacket/packet.go index 76b62d8ad4..3a7c4b3d80 100644 --- a/vendor/github.com/google/gopacket/packet.go +++ b/vendor/github.com/google/gopacket/packet.go @@ -12,10 +12,12 @@ import ( "errors" "fmt" "io" + "net" "os" "reflect" "runtime/debug" "strings" + "syscall" "time" ) @@ -31,6 +33,10 @@ type CaptureInfo struct { Length int // InterfaceIndex InterfaceIndex int + // The packet source can place ancillary data of various types here. + // For example, the afpacket source can report the VLAN of captured + // packets this way. + AncillaryData []interface{} } // PacketMetadata contains metadata for a packet. @@ -804,17 +810,37 @@ func (p *PacketSource) NextPacket() (Packet, error) { } // packetsToChannel reads in all packets from the packet source and sends them -// to the given channel. When it receives an error, it ignores it. When it -// receives an io.EOF, it closes the channel. +// to the given channel. This routine terminates when a non-temporary error +// is returned by NextPacket(). func (p *PacketSource) packetsToChannel() { defer close(p.c) for { packet, err := p.NextPacket() - if err == io.EOF { - return - } else if err == nil { + if err == nil { p.c <- packet + continue + } + + // Immediately retry for temporary network errors + if nerr, ok := err.(net.Error); ok && nerr.Temporary() { + continue } + + // Immediately retry for EAGAIN + if err == syscall.EAGAIN { + continue + } + + // Immediately break for known unrecoverable errors + if err == io.EOF || err == io.ErrUnexpectedEOF || + err == io.ErrNoProgress || err == io.ErrClosedPipe || err == io.ErrShortBuffer || + err == syscall.EBADF || + strings.Contains(err.Error(), "use of closed file") { + break + } + + // Sleep briefly and try again + time.Sleep(time.Millisecond * time.Duration(5)) } } diff --git a/vendor/github.com/google/gopacket/parser.go b/vendor/github.com/google/gopacket/parser.go index 760613fafc..e5dc0e45d8 100644 --- a/vendor/github.com/google/gopacket/parser.go +++ b/vendor/github.com/google/gopacket/parser.go @@ -116,7 +116,7 @@ func NewDecodingLayerParser(first LayerType, decoders ...DecodingLayer) *Decodin // decodedLayers := make([]gopacket.LayerType, 0, 10) // for { // data, _, err := source.ReadPacketData() -// if err == nil { +// if err != nil { // fmt.Println("Error reading packet data: ", err) // continue // } diff --git a/vendor/github.com/google/gopacket/pcap/bpf_test.go b/vendor/github.com/google/gopacket/pcap/bpf_test.go new file mode 100644 index 0000000000..409055544f --- /dev/null +++ b/vendor/github.com/google/gopacket/pcap/bpf_test.go @@ -0,0 +1,70 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +package pcap + +import ( + "testing" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" +) + +var ( + snaplen = 65535 + packet = [...]byte{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // dst mac + 0x0, 0x11, 0x22, 0x33, 0x44, 0x55, // src mac + 0x08, 0x0, // ether type + 0x45, 0x0, 0x0, 0x3c, 0xa6, 0xc3, 0x40, 0x0, 0x40, 0x06, 0x3d, 0xd8, // ip header + 0xc0, 0xa8, 0x50, 0x2f, // src ip + 0xc0, 0xa8, 0x50, 0x2c, // dst ip + 0xaf, 0x14, // src port + 0x0, 0x50, // dst port + } + matchingBPFFilter = "ip and tcp and port 80" + nonmatchingBPFFilter = "udp and port 80" +) + +func BenchmarkPcapNonmatchingBPFFilter(b *testing.B) { + bpf, err := NewBPF(layers.LinkTypeEthernet, snaplen, nonmatchingBPFFilter) + if err != nil { + b.Fatal("incorrect filter") + } + + ci := gopacket.CaptureInfo{ + InterfaceIndex: 0, + CaptureLength: len(packet), + Length: len(packet), + Timestamp: time.Now(), + } + + for i := 0; i < b.N; i++ { + if bpf.Matches(ci, packet[:]) { + b.Fatal("filter must not match the packet") + } + } +} + +func BenchmarkPcapMatchingBPFFilter(b *testing.B) { + bpf, err := NewBPF(layers.LinkTypeEthernet, snaplen, matchingBPFFilter) + if err != nil { + b.Fatal("incorrect filter") + } + + ci := gopacket.CaptureInfo{ + InterfaceIndex: 0, + CaptureLength: len(packet), + Length: len(packet), + Timestamp: time.Now(), + } + + for i := 0; i < b.N; i++ { + if !bpf.Matches(ci, packet[:]) { + b.Fatal("filter must match the packet") + } + } +} diff --git a/vendor/github.com/google/gopacket/pcap/defs_windows_386.go b/vendor/github.com/google/gopacket/pcap/defs_windows_386.go new file mode 100644 index 0000000000..774e907e8e --- /dev/null +++ b/vendor/github.com/google/gopacket/pcap/defs_windows_386.go @@ -0,0 +1,74 @@ +// Copyright 2019 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +// This file contains necessary structs/constants generated from libpcap headers with cgo -godefs +// generated with: generate_defs.exe +// DO NOT MODIFY + +package pcap + +import "syscall" + +const errorBufferSize = 0x100 + +const ( + pcapErrorNotActivated = -0x3 + pcapErrorActivated = -0x4 + pcapWarningPromisc = 0x2 + pcapErrorNoSuchDevice = -0x5 + pcapErrorDenied = -0x8 + pcapErrorNotUp = -0x9 + pcapError = -0x1 + pcapWarning = 0x1 + pcapDIN = 0x1 + pcapDOUT = 0x2 + pcapDINOUT = 0x0 + pcapNetmaskUnknown = 0xffffffff + pcapTstampPrecisionMicro = 0x0 + pcapTstampPrecisionNano = 0x1 +) + +type timeval struct { + Sec int32 + Usec int32 +} +type pcapPkthdr struct { + Ts timeval + Caplen uint32 + Len uint32 +} +type pcapTPtr uintptr +type pcapBpfInstruction struct { + Code uint16 + Jt uint8 + Jf uint8 + K uint32 +} +type pcapBpfProgram struct { + Len uint32 + Insns *pcapBpfInstruction +} +type pcapStats struct { + Recv uint32 + Drop uint32 + Ifdrop uint32 +} +type pcapCint int32 +type pcapIf struct { + Next *pcapIf + Name *int8 + Description *int8 + Addresses *pcapAddr + Flags uint32 +} + +type pcapAddr struct { + Next *pcapAddr + Addr *syscall.RawSockaddr + Netmask *syscall.RawSockaddr + Broadaddr *syscall.RawSockaddr + Dstaddr *syscall.RawSockaddr +} diff --git a/vendor/github.com/google/gopacket/pcap/defs_windows_amd64.go b/vendor/github.com/google/gopacket/pcap/defs_windows_amd64.go new file mode 100644 index 0000000000..9619215903 --- /dev/null +++ b/vendor/github.com/google/gopacket/pcap/defs_windows_amd64.go @@ -0,0 +1,76 @@ +// Copyright 2019 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +// This file contains necessary structs/constants generated from libpcap headers with cgo -godefs +// generated with: generate_defs.exe +// DO NOT MODIFY + +package pcap + +import "syscall" + +const errorBufferSize = 0x100 + +const ( + pcapErrorNotActivated = -0x3 + pcapErrorActivated = -0x4 + pcapWarningPromisc = 0x2 + pcapErrorNoSuchDevice = -0x5 + pcapErrorDenied = -0x8 + pcapErrorNotUp = -0x9 + pcapError = -0x1 + pcapWarning = 0x1 + pcapDIN = 0x1 + pcapDOUT = 0x2 + pcapDINOUT = 0x0 + pcapNetmaskUnknown = 0xffffffff + pcapTstampPrecisionMicro = 0x0 + pcapTstampPrecisionNano = 0x1 +) + +type timeval struct { + Sec int32 + Usec int32 +} +type pcapPkthdr struct { + Ts timeval + Caplen uint32 + Len uint32 +} +type pcapTPtr uintptr +type pcapBpfInstruction struct { + Code uint16 + Jt uint8 + Jf uint8 + K uint32 +} +type pcapBpfProgram struct { + Len uint32 + Pad_cgo_0 [4]byte + Insns *pcapBpfInstruction +} +type pcapStats struct { + Recv uint32 + Drop uint32 + Ifdrop uint32 +} +type pcapCint int32 +type pcapIf struct { + Next *pcapIf + Name *int8 + Description *int8 + Addresses *pcapAddr + Flags uint32 + Pad_cgo_0 [4]byte +} + +type pcapAddr struct { + Next *pcapAddr + Addr *syscall.RawSockaddr + Netmask *syscall.RawSockaddr + Broadaddr *syscall.RawSockaddr + Dstaddr *syscall.RawSockaddr +} diff --git a/vendor/github.com/google/gopacket/pcap/doc.go b/vendor/github.com/google/gopacket/pcap/doc.go index 5bf8d86f3f..38b3141fcc 100644 --- a/vendor/github.com/google/gopacket/pcap/doc.go +++ b/vendor/github.com/google/gopacket/pcap/doc.go @@ -12,6 +12,12 @@ This package is meant to be used with its parent, http://github.com/google/gopacket, although it can also be used independently if you just want to get packet data from the wire. +Depending on libpcap version, os support, or file timestamp resolution, +nanosecond resolution is used for the internal timestamps. Returned timestamps +are always scaled to nanosecond resolution due to the usage of time.Time. +libpcap must be at least version 1.5 to support nanosecond timestamps. OpenLive +supports only microsecond resolution. + Reading PCAP Files The following code can be used to read in data from a pcap file. @@ -28,7 +34,7 @@ The following code can be used to read in data from a pcap file. Reading Live Packets The following code can be used to read in data from a live device, in this case -"eth0". +"eth0". Be aware, that OpenLive only supports microsecond resolution. if handle, err := pcap.OpenLive("eth0", 1600, true, pcap.BlockForever); err != nil { panic(err) @@ -97,10 +103,10 @@ PCAP File Writing This package does not implement PCAP file writing. However, gopacket/pcapgo does! Look there if you'd like to write PCAP files. -Note For Windows 10 Users +Note For Windows Users -If you're trying to use 64-bit winpcap on Windows 10, you might have to do -the crazy hijinks detailed at -http://stackoverflow.com/questions/38047858/compile-gopacket-on-windows-64bit +gopacket can use winpcap or npcap. If both are installed at the same time, +npcap is preferred. Make sure the right windows service is loaded (npcap for npcap +and npf for winpcap). */ package pcap diff --git a/vendor/github.com/google/gopacket/pcap/generate_defs.go b/vendor/github.com/google/gopacket/pcap/generate_defs.go new file mode 100644 index 0000000000..bcbf161cf1 --- /dev/null +++ b/vendor/github.com/google/gopacket/pcap/generate_defs.go @@ -0,0 +1,157 @@ +// Copyright 2019 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +// +build ignore + +package main + +// This file generates the godefs needed for the windows version. +// Rebuild is only necessary if additional libpcap functionality is implemented, or a new arch is implemented in golang. +// Call with go run generate_windows.go [-I includepath] +// Needs npcap sdk, go tool cgo, and gofmt to work. Location of npcap includes can be specified with -I + +import ( + "bytes" + "flag" + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "strings" +) + +const header = `// Copyright 2019 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +// This file contains necessary structs/constants generated from libpcap headers with cgo -godefs +// generated with: %s +// DO NOT MODIFY + +` + +const source = ` +package pcap + +//#include +import "C" + +import "syscall" // needed for RawSockaddr + +const errorBufferSize = C.PCAP_ERRBUF_SIZE + +const ( + pcapErrorNotActivated = C.PCAP_ERROR_NOT_ACTIVATED + pcapErrorActivated = C.PCAP_ERROR_ACTIVATED + pcapWarningPromisc = C.PCAP_WARNING_PROMISC_NOTSUP + pcapErrorNoSuchDevice = C.PCAP_ERROR_NO_SUCH_DEVICE + pcapErrorDenied = C.PCAP_ERROR_PERM_DENIED + pcapErrorNotUp = C.PCAP_ERROR_IFACE_NOT_UP + pcapError = C.PCAP_ERROR + pcapWarning = C.PCAP_WARNING + pcapDIN = C.PCAP_D_IN + pcapDOUT = C.PCAP_D_OUT + pcapDINOUT = C.PCAP_D_INOUT + pcapNetmaskUnknown = C.PCAP_NETMASK_UNKNOWN + pcapTstampPrecisionMicro = C.PCAP_TSTAMP_PRECISION_MICRO + pcapTstampPrecisionNano = C.PCAP_TSTAMP_PRECISION_NANO +) + +type timeval C.struct_timeval +type pcapPkthdr C.struct_pcap_pkthdr +type pcapTPtr uintptr +type pcapBpfInstruction C.struct_bpf_insn +type pcapBpfProgram C.struct_bpf_program +type pcapStats C.struct_pcap_stat +type pcapCint C.int +type pcapIf C.struct_pcap_if +// +godefs map struct_sockaddr syscall.RawSockaddr +type pcapAddr C.struct_pcap_addr +` + +var includes = flag.String("I", "C:\\npcap-sdk-1.01\\Include", "Include path containing libpcap headers") + +func main() { + flag.Parse() + + infile, err := ioutil.TempFile(".", "defs.*.go") + if err != nil { + log.Fatal("Couldn't create temporary source file: ", err) + } + defer infile.Close() + defer os.Remove(infile.Name()) + + _, err = infile.WriteString(source) + if err != nil { + log.Fatalf("Couldn't write definitions to temporary file %s: %s", infile.Name(), err) + } + err = infile.Close() + if err != nil { + log.Fatalf("Couldn't close temporary source file %s: %s", infile.Name(), err) + } + + archs := []string{"386", "amd64"} + for _, arch := range archs { + env := append(os.Environ(), "GOARCH="+arch) + cmd := exec.Command("go", "tool", "cgo", "-godefs", "--", "-I", *includes, infile.Name()) + cmd.Env = env + cmd.Stderr = os.Stderr + var generated bytes.Buffer + cmd.Stdout = &generated + err := cmd.Run() + if err != nil { + log.Fatalf("Couldn't generated defs for %s: %s\n", arch, err) + } + + cmd = exec.Command("gofmt") + cmd.Env = env + cmd.Stderr = os.Stderr + outName := fmt.Sprintf("defs_windows_%s.go", arch) + out, err := os.Create(outName) + if err != nil { + log.Fatalf("Couldn't open file %s: %s", outName, err) + } + cmd.Stdout = out + in, err := cmd.StdinPipe() + if err != nil { + log.Fatal("Couldn't create input pipe for gofmt: ", err) + } + err = cmd.Start() + if err != nil { + log.Fatal("Couldn't start gofmt: ", err) + } + + _, err = fmt.Fprintf(in, header, strings.Join(append([]string{filepath.Base(os.Args[0])}, os.Args[1:]...), " ")) + if err != nil { + log.Fatal("Couldn't write header to gofmt: ", err) + } + + for { + line, err := generated.ReadBytes('\n') + if err != nil { + break + } + // remove godefs comments + if bytes.HasPrefix(line, []byte("//")) { + continue + } + _, err = in.Write(line) + if err != nil { + log.Fatal("Couldn't write line to gofmt: ", err) + } + } + in.Close() + err = cmd.Wait() + if err != nil { + log.Fatal("gofmt failed: ", err) + } + out.Close() + } +} diff --git a/vendor/github.com/google/gopacket/pcap/pcap.go b/vendor/github.com/google/gopacket/pcap/pcap.go index 7129c46115..6a4ef63524 100644 --- a/vendor/github.com/google/gopacket/pcap/pcap.go +++ b/vendor/github.com/google/gopacket/pcap/pcap.go @@ -7,109 +7,12 @@ package pcap -/* -#cgo solaris LDFLAGS: -L /opt/local/lib -lpcap -#cgo linux LDFLAGS: -lpcap -#cgo dragonfly LDFLAGS: -lpcap -#cgo freebsd LDFLAGS: -lpcap -#cgo openbsd LDFLAGS: -lpcap -#cgo netbsd LDFLAGS: -lpcap -#cgo darwin LDFLAGS: -lpcap -#cgo windows CFLAGS: -I C:/WpdPack/Include -#cgo windows,386 LDFLAGS: -L C:/WpdPack/Lib -lwpcap -#cgo windows,amd64 LDFLAGS: -L C:/WpdPack/Lib/x64 -lwpcap -#include -#include -#include - -// Some old versions of pcap don't define this constant. -#ifndef PCAP_NETMASK_UNKNOWN -#define PCAP_NETMASK_UNKNOWN 0xffffffff -#endif - -// libpcap doesn't actually export its version in a #define-guardable way, -// so we have to use other defined things to differentiate versions. -// We assume at least libpcap v1.1 at the moment. -// See http://upstream-tracker.org/versions/libpcap.html - -#ifndef PCAP_ERROR_TSTAMP_PRECISION_NOTSUP // < v1.5 - -int pcap_set_immediate_mode(pcap_t *p, int mode) { - return PCAP_ERROR; -} - -#ifndef PCAP_TSTAMP_HOST // < v1.2 - -int pcap_set_tstamp_type(pcap_t* p, int t) { return -1; } -int pcap_list_tstamp_types(pcap_t* p, int** t) { return 0; } -void pcap_free_tstamp_types(int *tstamp_types) {} -const char* pcap_tstamp_type_val_to_name(int t) { - return "pcap timestamp types not supported"; -} -int pcap_tstamp_type_name_to_val(const char* t) { - return PCAP_ERROR; -} - -#endif // < v1.2 -#endif // < v1.5 - -#ifndef PCAP_ERROR_PROMISC_PERM_DENIED -#define PCAP_ERROR_PROMISC_PERM_DENIED -11 -#endif - -// WinPcap doesn't export a pcap_statustostr, so use the less-specific -// pcap_strerror. Note that linking against something like cygwin libpcap -// may result is less-specific error messages. -#ifdef WIN32 -#define pcap_statustostr pcap_strerror - -// WinPcap also doesn't export pcap_can_set_rfmon and pcap_set_rfmon, -// as those are handled by separate libraries (airpcap). -// https://www.winpcap.org/docs/docs_412/html/group__wpcapfunc.html -// Stub out those functions here, returning values that indicate rfmon -// setting is unavailable/unsuccessful. -int pcap_can_set_rfmon(pcap_t *p) { - return 0; -} - -int pcap_set_rfmon(pcap_t *p, int rfmon) { - return PCAP_ERROR; -} -#endif - -// Windows, Macs, and Linux all use different time types. Joy. -#ifdef WIN32 -#define gopacket_time_secs_t long -#define gopacket_time_usecs_t long -#elif __APPLE__ -#define gopacket_time_secs_t __darwin_time_t -#define gopacket_time_usecs_t __darwin_suseconds_t -#elif __GLIBC__ -#define gopacket_time_secs_t __time_t -#define gopacket_time_usecs_t __suseconds_t -#else // Some form of linux/bsd/etc... -#include -#ifdef __OpenBSD__ -#define gopacket_time_secs_t u_int32_t -#define gopacket_time_usecs_t u_int32_t -#else -#define gopacket_time_secs_t time_t -#define gopacket_time_usecs_t suseconds_t -#endif -#endif - -// The things we do to avoid pointers escaping to the heap... -int pcap_next_ex_escaping(pcap_t *p, uintptr_t pkt_hdr, uintptr_t pkt_data) { - return pcap_next_ex(p, (struct pcap_pkthdr**)(pkt_hdr), (const u_char**)(pkt_data)); -} -*/ -import "C" - import ( "errors" "fmt" "io" "net" + "os" "reflect" "runtime" "strconv" @@ -123,10 +26,8 @@ import ( "github.com/google/gopacket/layers" ) -const errorBufferSize = 256 - // ErrNotActive is returned if handle is not activated -const ErrNotActive = int(C.PCAP_ERROR_NOT_ACTIVATED) +const ErrNotActive = pcapErrorNotActivated // MaxBpfInstructions is the maximum number of BPF instructions supported (BPF_MAXINSNS), // taken from Linux kernel: include/uapi/linux/bpf_common.h @@ -143,23 +44,25 @@ const bpfInstructionBufferSize = 8 * MaxBpfInstructions // // Handles are already pcap_activate'd type Handle struct { - // cptr is the handle for the actual pcap C object. - cptr *C.pcap_t - timeout time.Duration - device string - deviceIndex int - mu sync.Mutex - closeMu sync.Mutex // stop is set to a non-zero value by Handle.Close to signal to // getNextBufPtrLocked to stop trying to read packets + // This must be the first entry to ensure alignment for sync.atomic stop uint64 + // cptr is the handle for the actual pcap C object. + cptr pcapTPtr + timeout time.Duration + device string + deviceIndex int + mu sync.Mutex + closeMu sync.Mutex + nanoSecsFactor int64 // Since pointers to these objects are passed into a C function, if // they're declared locally then the Go compiler thinks they may have // escaped into C-land, so it allocates them on the heap. This causes a // huge memory hit, so to handle that we store them here instead. - pkthdr *C.struct_pcap_pkthdr - bufptr *C.u_char + pkthdr *pcapPkthdr + bufptr *uint8 } // Stats contains statistics on how many packets were handled by a pcap handle, @@ -196,7 +99,8 @@ type InterfaceAddress struct { // BPF is a compiled filter program, useful for offline packet matching. type BPF struct { orig string - bpf _Ctype_struct_bpf_program // takes a finalizer, not overriden by outsiders + bpf pcapBpfProgram // takes a finalizer, not overriden by outsiders + hdr pcapPkthdr // allocate on the heap to enable optimizations } // BPFInstruction is a byte encoded structure holding a BPF instruction @@ -212,7 +116,7 @@ type BPFInstruction struct { // quickly. const BlockForever = -time.Millisecond * 10 -func timeoutMillis(timeout time.Duration) C.int { +func timeoutMillis(timeout time.Duration) int { // Flip sign if necessary. See package docs on timeout for reasoning behind this. if timeout < 0 { timeout *= -1 @@ -221,24 +125,28 @@ func timeoutMillis(timeout time.Duration) C.int { if timeout != 0 && timeout < time.Millisecond { timeout = time.Millisecond } - return C.int(timeout / time.Millisecond) + return int(timeout / time.Millisecond) } // OpenLive opens a device and returns a *Handle. // It takes as arguments the name of the device ("eth0"), the maximum size to // read for each packet (snaplen), whether to put the interface in promiscuous -// mode, and a timeout. +// mode, and a timeout. Warning: this function supports only microsecond timestamps. +// For nanosecond resolution use an InactiveHandle. // // See the package documentation for important details regarding 'timeout'. func OpenLive(device string, snaplen int32, promisc bool, timeout time.Duration) (handle *Handle, _ error) { - buf := (*C.char)(C.calloc(errorBufferSize, 1)) - defer C.free(unsafe.Pointer(buf)) - - var pro C.int + var pro int if promisc { pro = 1 } - p := &Handle{timeout: timeout, device: device} + + p, err := pcapOpenLive(device, int(snaplen), pro, timeoutMillis(timeout)) + if err != nil { + return nil, err + } + p.timeout = timeout + p.device = device ifc, err := net.InterfaceByName(device) if err != nil { @@ -249,35 +157,53 @@ func OpenLive(device string, snaplen int32, promisc bool, timeout time.Duration) p.deviceIndex = ifc.Index } - dev := C.CString(device) - defer C.free(unsafe.Pointer(dev)) + p.nanoSecsFactor = 1000 - p.cptr = C.pcap_open_live(dev, C.int(snaplen), pro, timeoutMillis(timeout), buf) - if p.cptr == nil { - return nil, errors.New(C.GoString(buf)) - } - - if err := p.openLive(); err != nil { - C.pcap_close(p.cptr) - return nil, err + // Only set the PCAP handle into non-blocking mode if we have a timeout + // greater than zero. If the user wants to block forever, we'll let libpcap + // handle that. + if p.timeout > 0 { + if err := p.setNonBlocking(); err != nil { + p.pcapClose() + return nil, err + } } return p, nil } -// OpenOffline opens a file and returns its contents as a *Handle. +// OpenOffline opens a file and returns its contents as a *Handle. Depending on libpcap support and +// on the timestamp resolution used in the file, nanosecond or microsecond resolution is used +// internally. All returned timestamps are scaled to nanosecond resolution. Resolution() can be used +// to query the actual resolution used. func OpenOffline(file string) (handle *Handle, err error) { - buf := (*C.char)(C.calloc(errorBufferSize, 1)) - defer C.free(unsafe.Pointer(buf)) - cf := C.CString(file) - defer C.free(unsafe.Pointer(cf)) - - cptr := C.pcap_open_offline(cf, buf) - if cptr == nil { - return nil, errors.New(C.GoString(buf)) + handle, err = openOffline(file) + if err != nil { + return + } + if pcapGetTstampPrecision(handle.cptr) == pcapTstampPrecisionNano { + handle.nanoSecsFactor = 1 + } else { + handle.nanoSecsFactor = 1000 } - h := &Handle{cptr: cptr} - return h, nil + return +} + +// OpenOfflineFile returns contents of input file as a *Handle. Depending on libpcap support and +// on the timestamp resolution used in the file, nanosecond or microsecond resolution is used +// internally. All returned timestamps are scaled to nanosecond resolution. Resolution() can be used +// to query the actual resolution used. +func OpenOfflineFile(file *os.File) (handle *Handle, err error) { + handle, err = openOfflineFile(file) + if err != nil { + return + } + if pcapGetTstampPrecision(handle.cptr) == pcapTstampPrecisionNano { + handle.nanoSecsFactor = 1 + } else { + handle.nanoSecsFactor = 1000 + } + return } // NextError is the return code from a call to Next. @@ -318,7 +244,8 @@ func (p *Handle) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err err p.mu.Lock() err = p.getNextBufPtrLocked(&ci) if err == nil { - data = C.GoBytes(unsafe.Pointer(p.bufptr), C.int(ci.CaptureLength)) + data = make([]byte, ci.CaptureLength) + copy(data, (*(*[1 << 30]byte)(unsafe.Pointer(p.bufptr)))[:]) } p.mu.Unlock() if err == NextErrorTimeoutExpired { @@ -327,15 +254,16 @@ func (p *Handle) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err err return } -type activateError C.int +type activateError int const ( - aeNoError = 0 - aeActivated = C.PCAP_ERROR_ACTIVATED - aePromisc = C.PCAP_WARNING_PROMISC_NOTSUP - aeNoSuchDevice = C.PCAP_ERROR_NO_SUCH_DEVICE - aeDenied = C.PCAP_ERROR_PERM_DENIED - aeNotUp = C.PCAP_ERROR_IFACE_NOT_UP + aeNoError = activateError(0) + aeActivated = activateError(pcapErrorActivated) + aePromisc = activateError(pcapWarningPromisc) + aeNoSuchDevice = activateError(pcapErrorNoSuchDevice) + aeDenied = activateError(pcapErrorDenied) + aeNotUp = activateError(pcapErrorNotUp) + aeWarning = activateError(pcapWarning) ) func (a activateError) Error() string { @@ -352,6 +280,8 @@ func (a activateError) Error() string { return "Permission Denied" case aeNotUp: return "Interface Not Up" + case aeWarning: + return fmt.Sprintf("Warning: %v", activateErrMsg.Error()) default: return fmt.Sprintf("unknown activated error: %d", a) } @@ -360,31 +290,26 @@ func (a activateError) Error() string { // getNextBufPtrLocked is shared code for ReadPacketData and // ZeroCopyReadPacketData. func (p *Handle) getNextBufPtrLocked(ci *gopacket.CaptureInfo) error { - if p.cptr == nil { + if !p.isOpen() { return io.EOF } - // This horrible magic allows us to pass a ptr-to-ptr to pcap_next_ex - // without causing that ptr-to-ptr to itself be allocated on the heap. - // Since Handle itself survives through the duration of the pcap_next_ex - // call, this should be perfectly safe for GC stuff, etc. - pp := C.uintptr_t(uintptr(unsafe.Pointer(&p.pkthdr))) - bp := C.uintptr_t(uintptr(unsafe.Pointer(&p.bufptr))) + // set after we have call waitForPacket for the first time + var waited bool for atomic.LoadUint64(&p.stop) == 0 { // try to read a packet if one is immediately available - result := NextError(C.pcap_next_ex_escaping(p.cptr, pp, bp)) + result := p.pcapNextPacketEx() switch result { case NextErrorOk: - // got a packet, set capture info and return - sec := int64(p.pkthdr.ts.tv_sec) + sec := p.pkthdr.getSec() // convert micros to nanos - nanos := int64(p.pkthdr.ts.tv_usec) * 1000 + nanos := int64(p.pkthdr.getUsec()) * p.nanoSecsFactor ci.Timestamp = time.Unix(sec, nanos) - ci.CaptureLength = int(p.pkthdr.caplen) - ci.Length = int(p.pkthdr.len) + ci.CaptureLength = p.pkthdr.getCaplen() + ci.Length = p.pkthdr.getLen() ci.InterfaceIndex = p.deviceIndex return nil @@ -392,13 +317,18 @@ func (p *Handle) getNextBufPtrLocked(ci *gopacket.CaptureInfo) error { // no more packets, return EOF rather than libpcap-specific error return io.EOF case NextErrorTimeoutExpired: - // Negative timeout means to loop forever, instead of actually returning - // the timeout error. - if p.timeout < 0 { - // must have had a timeout... wait before trying again - p.waitForPacket() - continue + // we've already waited for a packet and we're supposed to time out + // + // we should never actually hit this if we were passed BlockForever + // since we should block on C.pcap_next_ex until there's a packet + // to read. + if waited && p.timeout > 0 { + return result } + + // wait for packet before trying again + p.waitForPacket() + waited = true default: return result } @@ -439,7 +369,7 @@ func (p *Handle) Close() { p.closeMu.Lock() defer p.closeMu.Unlock() - if p.cptr == nil { + if !p.isOpen() { return } @@ -449,106 +379,53 @@ func (p *Handle) Close() { p.mu.Lock() defer p.mu.Unlock() - C.pcap_close(p.cptr) - p.cptr = nil + p.pcapClose() } // Error returns the current error associated with a pcap handle (pcap_geterr). func (p *Handle) Error() error { - return errors.New(C.GoString(C.pcap_geterr(p.cptr))) + return p.pcapGeterr() } // Stats returns statistics on the underlying pcap handle. func (p *Handle) Stats() (stat *Stats, err error) { - var cstats _Ctype_struct_pcap_stat - if -1 == C.pcap_stats(p.cptr, &cstats) { - return nil, p.Error() - } - return &Stats{ - PacketsReceived: int(cstats.ps_recv), - PacketsDropped: int(cstats.ps_drop), - PacketsIfDropped: int(cstats.ps_ifdrop), - }, nil + return p.pcapStats() } // ListDataLinks obtains a list of all possible data link types supported for an interface. func (p *Handle) ListDataLinks() (datalinks []Datalink, err error) { - var dltbuf *C.int - - n := int(C.pcap_list_datalinks(p.cptr, &dltbuf)) - if -1 == n { - return nil, p.Error() - } - - defer C.pcap_free_datalinks(dltbuf) - - datalinks = make([]Datalink, n) - - dltArray := (*[100]C.int)(unsafe.Pointer(dltbuf)) - - for i := 0; i < n; i++ { - expr := C.pcap_datalink_val_to_name((*dltArray)[i]) - datalinks[i].Name = C.GoString(expr) - - expr = C.pcap_datalink_val_to_description((*dltArray)[i]) - datalinks[i].Description = C.GoString(expr) - } - - return datalinks, nil + return p.pcapListDatalinks() } -// pcap_compile is NOT thread-safe, so protect it. -var pcapCompileMu sync.Mutex - -// compileBPFFilter always returns an allocated _Ctype_struct_bpf_program +// compileBPFFilter always returns an allocated C.struct_bpf_program // It is the callers responsibility to free the memory again, e.g. // // C.pcap_freecode(&bpf) // -func (p *Handle) compileBPFFilter(expr string) (_Ctype_struct_bpf_program, error) { - errorBuf := (*C.char)(C.calloc(errorBufferSize, 1)) - defer C.free(unsafe.Pointer(errorBuf)) - - var netp uint32 - var maskp uint32 +func (p *Handle) compileBPFFilter(expr string) (pcapBpfProgram, error) { + var maskp = uint32(pcapNetmaskUnknown) // Only do the lookup on network interfaces. // No device indicates we're handling a pcap file. if len(p.device) > 0 { - dev := C.CString(p.device) - defer C.free(unsafe.Pointer(dev)) - if -1 == C.pcap_lookupnet( - dev, - (*C.bpf_u_int32)(unsafe.Pointer(&netp)), - (*C.bpf_u_int32)(unsafe.Pointer(&maskp)), - errorBuf, - ) { + var err error + _, maskp, err = pcapLookupnet(p.device) + if err != nil { // We can't lookup the network, but that could be because the interface // doesn't have an IPv4. + maskp = uint32(pcapNetmaskUnknown) } } - var bpf _Ctype_struct_bpf_program - cexpr := C.CString(expr) - defer C.free(unsafe.Pointer(cexpr)) - - pcapCompileMu.Lock() - defer pcapCompileMu.Unlock() - if -1 == C.pcap_compile(p.cptr, &bpf, cexpr, 1, C.bpf_u_int32(maskp)) { - return bpf, p.Error() - } - - return bpf, nil + return p.pcapCompile(expr, maskp) } // CompileBPFFilter compiles and returns a BPF filter with given a link type and capture length. func CompileBPFFilter(linkType layers.LinkType, captureLength int, expr string) ([]BPFInstruction, error) { - cptr := C.pcap_open_dead(C.int(linkType), C.int(captureLength)) - if cptr == nil { - return nil, errors.New("error opening dead capture") + h, err := pcapOpenDead(linkType, captureLength) + if err != nil { + return nil, err } - - h := Handle{cptr: cptr} defer h.Close() return h.CompileBPFFilter(expr) } @@ -556,37 +433,23 @@ func CompileBPFFilter(linkType layers.LinkType, captureLength int, expr string) // CompileBPFFilter compiles and returns a BPF filter for the pcap handle. func (p *Handle) CompileBPFFilter(expr string) ([]BPFInstruction, error) { bpf, err := p.compileBPFFilter(expr) - defer C.pcap_freecode(&bpf) + defer bpf.free() if err != nil { return nil, err } - bpfInsn := (*[bpfInstructionBufferSize]_Ctype_struct_bpf_insn)(unsafe.Pointer(bpf.bf_insns))[0:bpf.bf_len:bpf.bf_len] - bpfInstruction := make([]BPFInstruction, len(bpfInsn), len(bpfInsn)) - - for i, v := range bpfInsn { - bpfInstruction[i].Code = uint16(v.code) - bpfInstruction[i].Jt = uint8(v.jt) - bpfInstruction[i].Jf = uint8(v.jf) - bpfInstruction[i].K = uint32(v.k) - } - - return bpfInstruction, nil + return bpf.toBPFInstruction(), nil } // SetBPFFilter compiles and sets a BPF filter for the pcap handle. func (p *Handle) SetBPFFilter(expr string) (err error) { bpf, err := p.compileBPFFilter(expr) - defer C.pcap_freecode(&bpf) + defer bpf.free() if err != nil { return err } - if -1 == C.pcap_setfilter(p.cptr, &bpf) { - return p.Error() - } - - return nil + return p.pcapSetfilter(bpf) } // SetBPFInstructionFilter may be used to apply a filter in BPF asm byte code format. @@ -623,17 +486,12 @@ func (p *Handle) SetBPFInstructionFilter(bpfInstructions []BPFInstruction) (err if err != nil { return err } + defer bpf.free() - if -1 == C.pcap_setfilter(p.cptr, &bpf) { - C.pcap_freecode(&bpf) - return p.Error() - } - - C.pcap_freecode(&bpf) - - return nil + return p.pcapSetfilter(bpf) } -func bpfInstructionFilter(bpfInstructions []BPFInstruction) (bpf _Ctype_struct_bpf_program, err error) { + +func bpfInstructionFilter(bpfInstructions []BPFInstruction) (bpf pcapBpfProgram, err error) { if len(bpfInstructions) < 1 { return bpf, errors.New("bpfInstructions must not be empty") } @@ -642,13 +500,7 @@ func bpfInstructionFilter(bpfInstructions []BPFInstruction) (bpf _Ctype_struct_b return bpf, fmt.Errorf("bpfInstructions must not be larger than %d", MaxBpfInstructions) } - bpf.bf_len = C.u_int(len(bpfInstructions)) - cbpfInsns := C.calloc(C.size_t(len(bpfInstructions)), C.size_t(unsafe.Sizeof(bpfInstructions[0]))) - - copy((*[bpfInstructionBufferSize]BPFInstruction)(cbpfInsns)[0:len(bpfInstructions)], bpfInstructions) - bpf.bf_insns = (*_Ctype_struct_bpf_insn)(cbpfInsns) - - return + return pcapBpfProgramFromInstructions(bpfInstructions), nil } // NewBPF compiles the given string into a new filter program. @@ -657,19 +509,37 @@ func bpfInstructionFilter(bpfInstructions []BPFInstruction) (bpf _Ctype_struct_b // know the underlying link type to correctly compile their offsets. func (p *Handle) NewBPF(expr string) (*BPF, error) { bpf := &BPF{orig: expr} - cexpr := C.CString(expr) - defer C.free(unsafe.Pointer(cexpr)) - pcapCompileMu.Lock() - defer pcapCompileMu.Unlock() - if C.pcap_compile(p.cptr, &bpf.bpf, cexpr /* optimize */, 1, C.PCAP_NETMASK_UNKNOWN) != 0 { - return nil, p.Error() + var err error + bpf.bpf, err = p.pcapCompile(expr, pcapNetmaskUnknown) + if err != nil { + return nil, err } runtime.SetFinalizer(bpf, destroyBPF) return bpf, nil } +// NewBPF allows to create a BPF without requiring an existing handle. +// This allows to match packets obtained from a-non GoPacket capture source +// to be matched. +// +// buf := make([]byte, MaxFrameSize) +// bpfi, _ := pcap.NewBPF(layers.LinkTypeEthernet, MaxFrameSize, "icmp") +// n, _ := someIO.Read(buf) +// ci := gopacket.CaptureInfo{CaptureLength: n, Length: n} +// if bpfi.Matches(ci, buf) { +// doSomething() +// } +func NewBPF(linkType layers.LinkType, captureLength int, expr string) (*BPF, error) { + h, err := pcapOpenDead(linkType, captureLength) + if err != nil { + return nil, err + } + defer h.Close() + return h.NewBPF(expr) +} + // NewBPFInstructionFilter sets the given BPFInstructions as new filter program. // // More details see func SetBPFInstructionFilter @@ -689,7 +559,7 @@ func (p *Handle) NewBPFInstructionFilter(bpfInstructions []BPFInstruction) (*BPF return bpf, nil } func destroyBPF(bpf *BPF) { - C.pcap_freecode(&bpf.bpf) + bpf.bpf.free() } // String returns the original string this BPF filter was compiled from. @@ -699,108 +569,86 @@ func (b *BPF) String() string { // Matches returns true if the given packet data matches this filter. func (b *BPF) Matches(ci gopacket.CaptureInfo, data []byte) bool { - var hdr C.struct_pcap_pkthdr - hdr.ts.tv_sec = C.gopacket_time_secs_t(ci.Timestamp.Unix()) - hdr.ts.tv_usec = C.gopacket_time_usecs_t(ci.Timestamp.Nanosecond() / 1000) - hdr.caplen = C.bpf_u_int32(len(data)) // Trust actual length over ci.Length. - hdr.len = C.bpf_u_int32(ci.Length) - dataptr := (*C.u_char)(unsafe.Pointer(&data[0])) - return C.pcap_offline_filter(&b.bpf, &hdr, dataptr) != 0 + return b.pcapOfflineFilter(ci, data) } // Version returns pcap_lib_version. func Version() string { - return C.GoString(C.pcap_lib_version()) + return pcapLibVersion() } // LinkType returns pcap_datalink, as a layers.LinkType. func (p *Handle) LinkType() layers.LinkType { - return layers.LinkType(C.pcap_datalink(p.cptr)) + return p.pcapDatalink() } // SetLinkType calls pcap_set_datalink on the pcap handle. func (p *Handle) SetLinkType(dlt layers.LinkType) error { - if -1 == C.pcap_set_datalink(p.cptr, C.int(dlt)) { - return p.Error() - } - return nil + return p.pcapSetDatalink(dlt) } // DatalinkValToName returns pcap_datalink_val_to_name as string func DatalinkValToName(dlt int) string { - return C.GoString(C.pcap_datalink_val_to_name(C.int(dlt))) + return pcapDatalinkValToName(dlt) } // DatalinkValToDescription returns pcap_datalink_val_to_description as string func DatalinkValToDescription(dlt int) string { - return C.GoString(C.pcap_datalink_val_to_description(C.int(dlt))) + return pcapDatalinkValToDescription(dlt) } // DatalinkNameToVal returns pcap_datalink_name_to_val as int -func DatalinkNameToVal(name string) C.int { - cptr := C.CString(name) - defer C.free(unsafe.Pointer(cptr)) - return C.int(C.pcap_datalink_name_to_val(cptr)) +func DatalinkNameToVal(name string) int { + return pcapDatalinkNameToVal(name) } // FindAllDevs attempts to enumerate all interfaces on the current machine. func FindAllDevs() (ifs []Interface, err error) { - var buf *C.char - buf = (*C.char)(C.calloc(errorBufferSize, 1)) - defer C.free(unsafe.Pointer(buf)) - var alldevsp *C.pcap_if_t - - if -1 == C.pcap_findalldevs((**C.pcap_if_t)(&alldevsp), buf) { - return nil, errors.New(C.GoString(buf)) - } - defer C.pcap_freealldevs((*C.pcap_if_t)(alldevsp)) - dev := alldevsp - var i uint32 - for i = 0; dev != nil; dev = (*C.pcap_if_t)(dev.next) { - i++ + alldevsp, err := pcapFindAllDevs() + if err != nil { + return nil, err } - ifs = make([]Interface, i) - dev = alldevsp - for j := uint32(0); dev != nil; dev = (*C.pcap_if_t)(dev.next) { + defer alldevsp.free() + + for alldevsp.next() { var iface Interface - iface.Name = C.GoString(dev.name) - iface.Description = C.GoString(dev.description) - iface.Addresses = findalladdresses(dev.addresses) - iface.Flags = uint32(dev.flags) - ifs[j] = iface - j++ + iface.Name = alldevsp.name() + iface.Description = alldevsp.description() + iface.Addresses = findalladdresses(alldevsp.addresses()) + iface.Flags = alldevsp.flags() + ifs = append(ifs, iface) } return } -func findalladdresses(addresses *_Ctype_struct_pcap_addr) (retval []InterfaceAddress) { +func findalladdresses(addresses pcapAddresses) (retval []InterfaceAddress) { // TODO - make it support more than IPv4 and IPv6? retval = make([]InterfaceAddress, 0, 1) - for curaddr := addresses; curaddr != nil; curaddr = (*_Ctype_struct_pcap_addr)(curaddr.next) { + for addresses.next() { // Strangely, it appears that in some cases, we get a pcap address back from // pcap_findalldevs with a nil .addr. It appears that we can skip over // these. - if curaddr.addr == nil { + if addresses.addr() == nil { continue } var a InterfaceAddress var err error - if a.IP, err = sockaddrToIP((*syscall.RawSockaddr)(unsafe.Pointer(curaddr.addr))); err != nil { + if a.IP, err = sockaddrToIP(addresses.addr()); err != nil { continue } // To be safe, we'll also check for netmask. - if curaddr.netmask == nil { + if addresses.netmask() == nil { continue } - if a.Netmask, err = sockaddrToIP((*syscall.RawSockaddr)(unsafe.Pointer(curaddr.netmask))); err != nil { + if a.Netmask, err = sockaddrToIP(addresses.netmask()); err != nil { // If we got an IP address but we can't get a netmask, just return the IP // address. a.Netmask = nil } - if a.Broadaddr, err = sockaddrToIP((*syscall.RawSockaddr)(unsafe.Pointer(curaddr.broadaddr))); err != nil { + if a.Broadaddr, err = sockaddrToIP(addresses.broadaddr()); err != nil { a.Broadaddr = nil } - if a.P2P, err = sockaddrToIP((*syscall.RawSockaddr)(unsafe.Pointer(curaddr.dstaddr))); err != nil { + if a.P2P, err = sockaddrToIP(addresses.dstaddr()); err != nil { a.P2P = nil } retval = append(retval, a) @@ -809,7 +657,7 @@ func findalladdresses(addresses *_Ctype_struct_pcap_addr) (retval []InterfaceAdd } func sockaddrToIP(rsa *syscall.RawSockaddr) (IP []byte, err error) { - if unsafe.Pointer(rsa) == nil { + if rsa == nil { err = errors.New("Value not set") return } @@ -835,10 +683,7 @@ func sockaddrToIP(rsa *syscall.RawSockaddr) (IP []byte, err error) { // WritePacketData calls pcap_sendpacket, injecting the given data into the pcap handle. func (p *Handle) WritePacketData(data []byte) (err error) { - if -1 == C.pcap_sendpacket(p.cptr, (*C.u_char)(&data[0]), (C.int)(len(data))) { - err = p.Error() - } - return + return p.pcapSendpacket(data) } // Direction is used by Handle.SetDirection. @@ -846,9 +691,9 @@ type Direction uint8 // Direction values for Handle.SetDirection. const ( - DirectionIn Direction = C.PCAP_D_IN - DirectionOut Direction = C.PCAP_D_OUT - DirectionInOut Direction = C.PCAP_D_INOUT + DirectionIn = Direction(pcapDIN) + DirectionOut = Direction(pcapDOUT) + DirectionInOut = Direction(pcapDINOUT) ) // SetDirection sets the direction for which packets will be captured. @@ -856,75 +701,87 @@ func (p *Handle) SetDirection(direction Direction) error { if direction != DirectionIn && direction != DirectionOut && direction != DirectionInOut { return fmt.Errorf("Invalid direction: %v", direction) } - if status := C.pcap_setdirection(p.cptr, (C.pcap_direction_t)(direction)); status < 0 { - return statusError(status) - } - return nil + return p.pcapSetdirection(direction) } // SnapLen returns the snapshot length func (p *Handle) SnapLen() int { - len := C.pcap_snapshot(p.cptr) - return int(len) + return p.pcapSnapshot() +} + +// Resolution returns the timestamp resolution of acquired timestamps before scaling to NanosecondTimestampResolution. +func (p *Handle) Resolution() gopacket.TimestampResolution { + if p.nanoSecsFactor == 1 { + return gopacket.TimestampResolutionMicrosecond + } + return gopacket.TimestampResolutionNanosecond } // TimestampSource tells PCAP which type of timestamp to use for packets. -type TimestampSource C.int +type TimestampSource int // String returns the timestamp type as a human-readable string. func (t TimestampSource) String() string { - return C.GoString(C.pcap_tstamp_type_val_to_name(C.int(t))) + return t.pcapTstampTypeValToName() } // TimestampSourceFromString translates a string into a timestamp type, case // insensitive. func TimestampSourceFromString(s string) (TimestampSource, error) { - cs := C.CString(s) - defer C.free(unsafe.Pointer(cs)) - t := C.pcap_tstamp_type_name_to_val(cs) - if t < 0 { - return 0, statusError(t) - } - return TimestampSource(t), nil -} - -func statusError(status C.int) error { - return errors.New(C.GoString(C.pcap_statustostr(status))) + return pcapTstampTypeNameToVal(s) } // InactiveHandle allows you to call pre-pcap_activate functions on your pcap // handle to set it up just the way you'd like. type InactiveHandle struct { // cptr is the handle for the actual pcap C object. - cptr *C.pcap_t + cptr pcapTPtr device string deviceIndex int timeout time.Duration } +// holds the err messoge in case activation returned a Warning +var activateErrMsg error + +// Error returns the current error associated with a pcap handle (pcap_geterr). +func (p *InactiveHandle) Error() error { + return p.pcapGeterr() +} + // Activate activates the handle. The current InactiveHandle becomes invalid // and all future function calls on it will fail. func (p *InactiveHandle) Activate() (*Handle, error) { - err := activateError(C.pcap_activate(p.cptr)) + // ignore error with set_tstamp_precision, since the actual precision is queried later anyway + pcapSetTstampPrecision(p.cptr, pcapTstampPrecisionNano) + handle, err := p.pcapActivate() if err != aeNoError { + if err == aeWarning { + activateErrMsg = p.Error() + } return nil, err } - h := &Handle{ - cptr: p.cptr, - timeout: p.timeout, - device: p.device, - deviceIndex: p.deviceIndex, + handle.timeout = p.timeout + if p.timeout > 0 { + if err := handle.setNonBlocking(); err != nil { + handle.pcapClose() + return nil, err + } } - p.cptr = nil - return h, nil + handle.device = p.device + handle.deviceIndex = p.deviceIndex + if pcapGetTstampPrecision(handle.cptr) == pcapTstampPrecisionNano { + handle.nanoSecsFactor = 1 + } else { + handle.nanoSecsFactor = 1000 + } + return handle, nil } // CleanUp cleans up any stuff left over from a successful or failed building // of a handle. func (p *InactiveHandle) CleanUp() { - if p.cptr != nil { - C.pcap_close(p.cptr) - } + p.pcapClose() } // NewInactiveHandle creates a new InactiveHandle, which wraps an un-activated PCAP handle. @@ -932,11 +789,6 @@ func (p *InactiveHandle) CleanUp() { // inactive := NewInactiveHandle("eth0") // defer inactive.CleanUp() func NewInactiveHandle(device string) (*InactiveHandle, error) { - buf := (*C.char)(C.calloc(errorBufferSize, 1)) - defer C.free(unsafe.Pointer(buf)) - dev := C.CString(device) - defer C.free(unsafe.Pointer(dev)) - // Try to get the interface index, but iy could be something like "any" // in which case use 0, which doesn't exist in nature deviceIndex := 0 @@ -946,40 +798,33 @@ func NewInactiveHandle(device string) (*InactiveHandle, error) { } // This copies a bunch of the pcap_open_live implementation from pcap.c: - cptr := C.pcap_create(dev, buf) - if cptr == nil { - return nil, errors.New(C.GoString(buf)) + handle, err := pcapCreate(device) + if err != nil { + return nil, err } - return &InactiveHandle{cptr: cptr, device: device, deviceIndex: deviceIndex}, nil + handle.device = device + handle.deviceIndex = deviceIndex + return handle, nil } // SetSnapLen sets the snap length (max bytes per packet to capture). func (p *InactiveHandle) SetSnapLen(snaplen int) error { - if status := C.pcap_set_snaplen(p.cptr, C.int(snaplen)); status < 0 { - return statusError(status) - } - return nil + return p.pcapSetSnaplen(snaplen) } // SetPromisc sets the handle to either be promiscuous (capture packets // unrelated to this host) or not. func (p *InactiveHandle) SetPromisc(promisc bool) error { - var pro C.int - if promisc { - pro = 1 - } - if status := C.pcap_set_promisc(p.cptr, pro); status < 0 { - return statusError(status) - } - return nil + return p.pcapSetPromisc(promisc) } // SetTimeout sets the read timeout for the handle. // // See the package documentation for important details regarding 'timeout'. func (p *InactiveHandle) SetTimeout(timeout time.Duration) error { - if status := C.pcap_set_timeout(p.cptr, timeoutMillis(timeout)); status < 0 { - return statusError(status) + err := p.pcapSetTimeout(timeout) + if err != nil { + return err } p.timeout = timeout return nil @@ -988,23 +833,13 @@ func (p *InactiveHandle) SetTimeout(timeout time.Duration) error { // SupportedTimestamps returns a list of supported timstamp types for this // handle. func (p *InactiveHandle) SupportedTimestamps() (out []TimestampSource) { - var types *C.int - n := int(C.pcap_list_tstamp_types(p.cptr, &types)) - defer C.pcap_free_tstamp_types(types) - typesArray := (*[100]C.int)(unsafe.Pointer(types)) - for i := 0; i < n; i++ { - out = append(out, TimestampSource((*typesArray)[i])) - } - return + return p.pcapListTstampTypes() } // SetTimestampSource sets the type of timestamp generator PCAP uses when // attaching timestamps to packets. func (p *InactiveHandle) SetTimestampSource(t TimestampSource) error { - if status := C.pcap_set_tstamp_type(p.cptr, C.int(t)); status < 0 { - return statusError(status) - } - return nil + return p.pcapSetTstampType(t) } // CannotSetRFMon is returned by SetRFMon if the handle does not allow @@ -1015,42 +850,17 @@ var CannotSetRFMon = errors.New("Cannot set rfmon for this handle") // wireless networks. If this mode is enabled, the interface will not need to // associate with an access point before it can receive traffic. func (p *InactiveHandle) SetRFMon(monitor bool) error { - var mon C.int - if monitor { - mon = 1 - } - switch canset := C.pcap_can_set_rfmon(p.cptr); canset { - case 0: - return CannotSetRFMon - case 1: - // success - default: - return statusError(canset) - } - if status := C.pcap_set_rfmon(p.cptr, mon); status != 0 { - return statusError(status) - } - return nil + return p.pcapSetRfmon(monitor) } // SetBufferSize sets the buffer size (in bytes) of the handle. func (p *InactiveHandle) SetBufferSize(bufferSize int) error { - if status := C.pcap_set_buffer_size(p.cptr, C.int(bufferSize)); status < 0 { - return statusError(status) - } - return nil + return p.pcapSetBufferSize(bufferSize) } // SetImmediateMode sets (or unsets) the immediate mode of the // handle. In immediate mode, packets are delivered to the application // as soon as they arrive. In other words, this overrides SetTimeout. func (p *InactiveHandle) SetImmediateMode(mode bool) error { - var md C.int - if mode { - md = 1 - } - if status := C.pcap_set_immediate_mode(p.cptr, md); status < 0 { - return statusError(status) - } - return nil + return p.pcapSetImmediateMode(mode) } diff --git a/vendor/github.com/google/gopacket/pcap/pcap_test.go b/vendor/github.com/google/gopacket/pcap/pcap_test.go index 04f1812400..e823da4ba3 100644 --- a/vendor/github.com/google/gopacket/pcap/pcap_test.go +++ b/vendor/github.com/google/gopacket/pcap/pcap_test.go @@ -39,13 +39,13 @@ func TestPcapFileRead(t *testing.T) { if err != nil { t.Fatal(err) } + invalidPcap.Close() // if the file is still open later, the invalid test fails with permission denied on windows defer os.Remove(invalidPcap.Name()) err = ioutil.WriteFile(invalidPcap.Name(), invalidData, 0644) if err != nil { t.Fatal(err) } - defer invalidPcap.Close() for _, file := range []struct { filename string @@ -62,7 +62,7 @@ func TestPcapFileRead(t *testing.T) { }, }, {filename: "test_ethernet.pcap", - num: 16, + num: 10, expectedLayers: []gopacket.LayerType{ layers.LayerTypeEthernet, layers.LayerTypeIPv4, @@ -299,10 +299,4 @@ func ExampleBPF() { // SYN flag not set // SYN flag not set // SYN flag not set - // SYN flag not set - // SYN flag not set - // SYN flag not set - // SYN flag not set - // SYN flag not set - // SYN flag not set } diff --git a/vendor/github.com/google/gopacket/pcap/pcap_tester.go b/vendor/github.com/google/gopacket/pcap/pcap_tester.go index ee32690866..7873a96c0c 100644 --- a/vendor/github.com/google/gopacket/pcap/pcap_tester.go +++ b/vendor/github.com/google/gopacket/pcap/pcap_tester.go @@ -15,7 +15,6 @@ import ( "flag" "fmt" "log" - "net" "net/http" "os" "time" @@ -35,7 +34,7 @@ func generatePackets() { func main() { flag.Parse() - ifaces, err := net.Interfaces() + ifaces, err := pcap.FindAllDevs() if err != nil { log.Fatal(err) } @@ -51,7 +50,7 @@ func main() { os.Exit(1) } -func tryCapture(iface net.Interface) error { +func tryCapture(iface pcap.Interface) error { if iface.Name[:2] == "lo" { return errors.New("skipping loopback") } diff --git a/vendor/github.com/google/gopacket/pcap/pcap_unix.go b/vendor/github.com/google/gopacket/pcap/pcap_unix.go index b2a6dcd681..4d6a4fbe42 100644 --- a/vendor/github.com/google/gopacket/pcap/pcap_unix.go +++ b/vendor/github.com/google/gopacket/pcap/pcap_unix.go @@ -9,9 +9,136 @@ package pcap +import ( + "errors" + "os" + "sync" + "syscall" + "time" + "unsafe" + + "github.com/google/gopacket" + + "github.com/google/gopacket/layers" +) + /* +#cgo solaris LDFLAGS: -L /opt/local/lib -lpcap +#cgo linux LDFLAGS: -lpcap +#cgo dragonfly LDFLAGS: -lpcap +#cgo freebsd LDFLAGS: -lpcap +#cgo openbsd LDFLAGS: -lpcap +#cgo netbsd LDFLAGS: -lpcap +#cgo darwin LDFLAGS: -lpcap #include #include +#include + +// Some old versions of pcap don't define this constant. +#ifndef PCAP_NETMASK_UNKNOWN +#define PCAP_NETMASK_UNKNOWN 0xffffffff +#endif + +// libpcap doesn't actually export its version in a #define-guardable way, +// so we have to use other defined things to differentiate versions. +// We assume at least libpcap v1.1 at the moment. +// See http://upstream-tracker.org/versions/libpcap.html + +#ifndef PCAP_ERROR_TSTAMP_PRECISION_NOTSUP // < v1.5 +#define PCAP_ERROR_TSTAMP_PRECISION_NOTSUP -12 + +int pcap_set_immediate_mode(pcap_t *p, int mode) { + return PCAP_ERROR; +} + +// libpcap version < v1.5 doesn't have timestamp precision (everything is microsecond) +// +// This means *_tstamp_* functions and macros are missing. Therefore, we emulate these +// functions here and pretend the setting the precision works. This is actually the way +// the pcap_open_offline_with_tstamp_precision works, because it doesn't return an error +// if it was not possible to set the precision, which depends on support by the given file. +// => The rest of the functions always pretend as if they could set nano precision and +// verify the actual precision with pcap_get_tstamp_precision, which is emulated for +#ifdef __OpenBSD__ +#define gopacket_time_secs_t u_int32_t +#define gopacket_time_usecs_t u_int32_t +#else +#define gopacket_time_secs_t time_t +#define gopacket_time_usecs_t suseconds_t +#endif +#endif + +// The things we do to avoid pointers escaping to the heap... +// According to https://github.com/the-tcpdump-group/libpcap/blob/1131a7c26c6f4d4772e4a2beeaf7212f4dea74ac/pcap.c#L398-L406 , +// the return value of pcap_next_ex could be greater than 1 for success. +// Let's just make it 1 if it comes bigger than 1. +int pcap_next_ex_escaping(pcap_t *p, uintptr_t pkt_hdr, uintptr_t pkt_data) { + int ex = pcap_next_ex(p, (struct pcap_pkthdr**)(pkt_hdr), (const u_char**)(pkt_data)); + if (ex > 1) { + ex = 1; + } + return ex; +} + +int pcap_offline_filter_escaping(struct bpf_program *fp, uintptr_t pkt_hdr, uintptr_t pkt) { + return pcap_offline_filter(fp, (struct pcap_pkthdr*)(pkt_hdr), (const u_char*)(pkt)); +} // pcap_wait returns when the next packet is available or the timeout expires. // Since it uses pcap_get_selectable_fd, it will not work in Windows. @@ -38,21 +165,517 @@ int pcap_wait(pcap_t *p, int usec) { // block indefinitely if no timeout provided return select(fd+1, &fds, NULL, NULL, NULL); } + */ import "C" -import ( - "errors" - "unsafe" +const errorBufferSize = C.PCAP_ERRBUF_SIZE + +const ( + pcapErrorNotActivated = C.PCAP_ERROR_NOT_ACTIVATED + pcapErrorActivated = C.PCAP_ERROR_ACTIVATED + pcapWarningPromisc = C.PCAP_WARNING_PROMISC_NOTSUP + pcapErrorNoSuchDevice = C.PCAP_ERROR_NO_SUCH_DEVICE + pcapErrorDenied = C.PCAP_ERROR_PERM_DENIED + pcapErrorNotUp = C.PCAP_ERROR_IFACE_NOT_UP + pcapWarning = C.PCAP_WARNING + pcapDIN = C.PCAP_D_IN + pcapDOUT = C.PCAP_D_OUT + pcapDINOUT = C.PCAP_D_INOUT + pcapNetmaskUnknown = C.PCAP_NETMASK_UNKNOWN + pcapTstampPrecisionMicro = C.PCAP_TSTAMP_PRECISION_MICRO + pcapTstampPrecisionNano = C.PCAP_TSTAMP_PRECISION_NANO ) -func (p *Handle) openLive() error { +type pcapPkthdr C.struct_pcap_pkthdr +type pcapTPtr *C.struct_pcap +type pcapBpfProgram C.struct_bpf_program + +func (h *pcapPkthdr) getSec() int64 { + return int64(h.ts.tv_sec) +} + +func (h *pcapPkthdr) getUsec() int64 { + return int64(h.ts.tv_usec) +} + +func (h *pcapPkthdr) getLen() int { + return int(h.len) +} + +func (h *pcapPkthdr) getCaplen() int { + return int(h.caplen) +} + +func pcapGetTstampPrecision(cptr pcapTPtr) int { + return int(C.pcap_get_tstamp_precision(cptr)) +} + +func pcapSetTstampPrecision(cptr pcapTPtr, precision int) error { + ret := C.pcap_set_tstamp_precision(cptr, C.int(precision)) + if ret < 0 { + return errors.New(C.GoString(C.pcap_geterr(cptr))) + } + return nil +} + +func statusError(status C.int) error { + return errors.New(C.GoString(C.pcap_statustostr(status))) +} + +func pcapOpenLive(device string, snaplen int, pro int, timeout int) (*Handle, error) { + buf := (*C.char)(C.calloc(errorBufferSize, 1)) + defer C.free(unsafe.Pointer(buf)) + + dev := C.CString(device) + defer C.free(unsafe.Pointer(dev)) + + cptr := C.pcap_open_live(dev, C.int(snaplen), C.int(pro), C.int(timeout), buf) + if cptr == nil { + return nil, errors.New(C.GoString(buf)) + } + return &Handle{cptr: cptr}, nil +} + +func openOffline(file string) (handle *Handle, err error) { + buf := (*C.char)(C.calloc(errorBufferSize, 1)) + defer C.free(unsafe.Pointer(buf)) + cf := C.CString(file) + defer C.free(unsafe.Pointer(cf)) + + cptr := C.pcap_open_offline_with_tstamp_precision(cf, C.PCAP_TSTAMP_PRECISION_NANO, buf) + if cptr == nil { + return nil, errors.New(C.GoString(buf)) + } + return &Handle{cptr: cptr}, nil +} + +func (p *Handle) pcapClose() { + if p.cptr != nil { + C.pcap_close(p.cptr) + } + p.cptr = nil +} + +func (p *Handle) pcapGeterr() error { + return errors.New(C.GoString(C.pcap_geterr(p.cptr))) +} + +func (p *Handle) pcapStats() (*Stats, error) { + var cstats C.struct_pcap_stat + if C.pcap_stats(p.cptr, &cstats) < 0 { + return nil, p.pcapGeterr() + } + return &Stats{ + PacketsReceived: int(cstats.ps_recv), + PacketsDropped: int(cstats.ps_drop), + PacketsIfDropped: int(cstats.ps_ifdrop), + }, nil +} + +// for libpcap < 1.8 pcap_compile is NOT thread-safe, so protect it. +var pcapCompileMu sync.Mutex + +func (p *Handle) pcapCompile(expr string, maskp uint32) (pcapBpfProgram, error) { + var bpf pcapBpfProgram + cexpr := C.CString(expr) + defer C.free(unsafe.Pointer(cexpr)) + + pcapCompileMu.Lock() + defer pcapCompileMu.Unlock() + if C.pcap_compile(p.cptr, (*C.struct_bpf_program)(&bpf), cexpr, 1, C.bpf_u_int32(maskp)) < 0 { + return bpf, p.pcapGeterr() + } + return bpf, nil +} + +func (p pcapBpfProgram) free() { + C.pcap_freecode((*C.struct_bpf_program)(&p)) +} + +func (p pcapBpfProgram) toBPFInstruction() []BPFInstruction { + bpfInsn := (*[bpfInstructionBufferSize]C.struct_bpf_insn)(unsafe.Pointer(p.bf_insns))[0:p.bf_len:p.bf_len] + bpfInstruction := make([]BPFInstruction, len(bpfInsn), len(bpfInsn)) + + for i, v := range bpfInsn { + bpfInstruction[i].Code = uint16(v.code) + bpfInstruction[i].Jt = uint8(v.jt) + bpfInstruction[i].Jf = uint8(v.jf) + bpfInstruction[i].K = uint32(v.k) + } + return bpfInstruction +} + +func pcapBpfProgramFromInstructions(bpfInstructions []BPFInstruction) pcapBpfProgram { + var bpf pcapBpfProgram + bpf.bf_len = C.u_int(len(bpfInstructions)) + cbpfInsns := C.calloc(C.size_t(len(bpfInstructions)), C.size_t(unsafe.Sizeof(bpfInstructions[0]))) + gbpfInsns := (*[bpfInstructionBufferSize]C.struct_bpf_insn)(cbpfInsns) + + for i, v := range bpfInstructions { + gbpfInsns[i].code = C.u_short(v.Code) + gbpfInsns[i].jt = C.u_char(v.Jt) + gbpfInsns[i].jf = C.u_char(v.Jf) + gbpfInsns[i].k = C.bpf_u_int32(v.K) + } + + bpf.bf_insns = (*C.struct_bpf_insn)(cbpfInsns) + return bpf +} + +func pcapLookupnet(device string) (netp, maskp uint32, err error) { + errorBuf := (*C.char)(C.calloc(errorBufferSize, 1)) + defer C.free(unsafe.Pointer(errorBuf)) + dev := C.CString(device) + defer C.free(unsafe.Pointer(dev)) + if C.pcap_lookupnet( + dev, + (*C.bpf_u_int32)(unsafe.Pointer(&netp)), + (*C.bpf_u_int32)(unsafe.Pointer(&maskp)), + errorBuf, + ) < 0 { + return 0, 0, errors.New(C.GoString(errorBuf)) + // We can't lookup the network, but that could be because the interface + // doesn't have an IPv4. + } + return +} + +func (b *BPF) pcapOfflineFilter(ci gopacket.CaptureInfo, data []byte) bool { + hdr := (*C.struct_pcap_pkthdr)(&b.hdr) + hdr.ts.tv_sec = C.gopacket_time_secs_t(ci.Timestamp.Unix()) + hdr.ts.tv_usec = C.gopacket_time_usecs_t(ci.Timestamp.Nanosecond() / 1000) + hdr.caplen = C.bpf_u_int32(len(data)) // Trust actual length over ci.Length. + hdr.len = C.bpf_u_int32(ci.Length) + dataptr := (*C.u_char)(unsafe.Pointer(&data[0])) + return C.pcap_offline_filter_escaping((*C.struct_bpf_program)(&b.bpf), + C.uintptr_t(uintptr(unsafe.Pointer(hdr))), + C.uintptr_t(uintptr(unsafe.Pointer(dataptr)))) != 0 +} + +func (p *Handle) pcapSetfilter(bpf pcapBpfProgram) error { + if C.pcap_setfilter(p.cptr, (*C.struct_bpf_program)(&bpf)) < 0 { + return p.pcapGeterr() + } + return nil +} + +func (p *Handle) pcapListDatalinks() (datalinks []Datalink, err error) { + var dltbuf *C.int + + n := int(C.pcap_list_datalinks(p.cptr, &dltbuf)) + if n < 0 { + return nil, p.pcapGeterr() + } + + defer C.pcap_free_datalinks(dltbuf) + + datalinks = make([]Datalink, n) + + dltArray := (*[1 << 28]C.int)(unsafe.Pointer(dltbuf)) + + for i := 0; i < n; i++ { + datalinks[i].Name = pcapDatalinkValToName(int((*dltArray)[i])) + datalinks[i].Description = pcapDatalinkValToDescription(int((*dltArray)[i])) + } + + return datalinks, nil +} + +func pcapOpenDead(linkType layers.LinkType, captureLength int) (*Handle, error) { + cptr := C.pcap_open_dead(C.int(linkType), C.int(captureLength)) + if cptr == nil { + return nil, errors.New("error opening dead capture") + } + + return &Handle{cptr: cptr}, nil +} + +func (p *Handle) pcapNextPacketEx() NextError { + // This horrible magic allows us to pass a ptr-to-ptr to pcap_next_ex + // without causing that ptr-to-ptr to itself be allocated on the heap. + // Since Handle itself survives through the duration of the pcap_next_ex + // call, this should be perfectly safe for GC stuff, etc. + + return NextError(C.pcap_next_ex_escaping(p.cptr, C.uintptr_t(uintptr(unsafe.Pointer(&p.pkthdr))), C.uintptr_t(uintptr(unsafe.Pointer(&p.bufptr))))) +} + +func (p *Handle) pcapDatalink() layers.LinkType { + return layers.LinkType(C.pcap_datalink(p.cptr)) +} + +func (p *Handle) pcapSetDatalink(dlt layers.LinkType) error { + if C.pcap_set_datalink(p.cptr, C.int(dlt)) < 0 { + return p.pcapGeterr() + } + return nil +} + +func pcapDatalinkValToName(dlt int) string { + return C.GoString(C.pcap_datalink_val_to_name(C.int(dlt))) +} + +func pcapDatalinkValToDescription(dlt int) string { + return C.GoString(C.pcap_datalink_val_to_description(C.int(dlt))) +} + +func pcapDatalinkNameToVal(name string) int { + cptr := C.CString(name) + defer C.free(unsafe.Pointer(cptr)) + return int(C.pcap_datalink_name_to_val(cptr)) +} + +func pcapLibVersion() string { + return C.GoString(C.pcap_lib_version()) +} + +func (p *Handle) isOpen() bool { + return p.cptr != nil +} + +type pcapDevices struct { + all, cur *C.pcap_if_t +} + +func (p pcapDevices) free() { + C.pcap_freealldevs((*C.pcap_if_t)(p.all)) +} + +func (p *pcapDevices) next() bool { + if p.cur == nil { + p.cur = p.all + if p.cur == nil { + return false + } + return true + } + if p.cur.next == nil { + return false + } + p.cur = p.cur.next + return true +} + +func (p pcapDevices) name() string { + return C.GoString(p.cur.name) +} + +func (p pcapDevices) description() string { + return C.GoString(p.cur.description) +} + +func (p pcapDevices) flags() uint32 { + return uint32(p.cur.flags) +} + +type pcapAddresses struct { + all, cur *C.pcap_addr_t +} + +func (p *pcapAddresses) next() bool { + if p.cur == nil { + p.cur = p.all + if p.cur == nil { + return false + } + return true + } + if p.cur.next == nil { + return false + } + p.cur = p.cur.next + return true +} + +func (p pcapAddresses) addr() *syscall.RawSockaddr { + return (*syscall.RawSockaddr)(unsafe.Pointer(p.cur.addr)) +} + +func (p pcapAddresses) netmask() *syscall.RawSockaddr { + return (*syscall.RawSockaddr)(unsafe.Pointer(p.cur.netmask)) +} + +func (p pcapAddresses) broadaddr() *syscall.RawSockaddr { + return (*syscall.RawSockaddr)(unsafe.Pointer(p.cur.broadaddr)) +} + +func (p pcapAddresses) dstaddr() *syscall.RawSockaddr { + return (*syscall.RawSockaddr)(unsafe.Pointer(p.cur.dstaddr)) +} + +func (p pcapDevices) addresses() pcapAddresses { + return pcapAddresses{all: p.cur.addresses} +} + +func pcapFindAllDevs() (pcapDevices, error) { + var buf *C.char + buf = (*C.char)(C.calloc(errorBufferSize, 1)) + defer C.free(unsafe.Pointer(buf)) + var alldevsp pcapDevices + + if C.pcap_findalldevs((**C.pcap_if_t)(&alldevsp.all), buf) < 0 { + return pcapDevices{}, errors.New(C.GoString(buf)) + } + return alldevsp, nil +} + +func (p *Handle) pcapSendpacket(data []byte) error { + if C.pcap_sendpacket(p.cptr, (*C.u_char)(&data[0]), (C.int)(len(data))) < 0 { + return p.pcapGeterr() + } + return nil +} + +func (p *Handle) pcapSetdirection(direction Direction) error { + if status := C.pcap_setdirection(p.cptr, (C.pcap_direction_t)(direction)); status < 0 { + return statusError(status) + } + return nil +} + +func (p *Handle) pcapSnapshot() int { + return int(C.pcap_snapshot(p.cptr)) +} + +func (t TimestampSource) pcapTstampTypeValToName() string { + return C.GoString(C.pcap_tstamp_type_val_to_name(C.int(t))) +} + +func pcapTstampTypeNameToVal(s string) (TimestampSource, error) { + cs := C.CString(s) + defer C.free(unsafe.Pointer(cs)) + t := C.pcap_tstamp_type_name_to_val(cs) + if t < 0 { + return 0, statusError(t) + } + return TimestampSource(t), nil +} + +func (p *InactiveHandle) pcapGeterr() error { + return errors.New(C.GoString(C.pcap_geterr(p.cptr))) +} + +func (p *InactiveHandle) pcapActivate() (*Handle, activateError) { + ret := activateError(C.pcap_activate(p.cptr)) + if ret != aeNoError { + return nil, ret + } + h := &Handle{ + cptr: p.cptr, + } + p.cptr = nil + return h, ret +} + +func (p *InactiveHandle) pcapClose() { + if p.cptr != nil { + C.pcap_close(p.cptr) + } +} + +func pcapCreate(device string) (*InactiveHandle, error) { + buf := (*C.char)(C.calloc(errorBufferSize, 1)) + defer C.free(unsafe.Pointer(buf)) + dev := C.CString(device) + defer C.free(unsafe.Pointer(dev)) + + cptr := C.pcap_create(dev, buf) + if cptr == nil { + return nil, errors.New(C.GoString(buf)) + } + return &InactiveHandle{cptr: cptr}, nil +} + +func (p *InactiveHandle) pcapSetSnaplen(snaplen int) error { + if status := C.pcap_set_snaplen(p.cptr, C.int(snaplen)); status < 0 { + return statusError(status) + } + return nil +} + +func (p *InactiveHandle) pcapSetPromisc(promisc bool) error { + var pro C.int + if promisc { + pro = 1 + } + if status := C.pcap_set_promisc(p.cptr, pro); status < 0 { + return statusError(status) + } + return nil +} + +func (p *InactiveHandle) pcapSetTimeout(timeout time.Duration) error { + if status := C.pcap_set_timeout(p.cptr, C.int(timeoutMillis(timeout))); status < 0 { + return statusError(status) + } + return nil +} + +func (p *InactiveHandle) pcapListTstampTypes() (out []TimestampSource) { + var types *C.int + n := int(C.pcap_list_tstamp_types(p.cptr, &types)) + if n < 0 { + return // public interface doesn't have error :( + } + defer C.pcap_free_tstamp_types(types) + typesArray := (*[1 << 28]C.int)(unsafe.Pointer(types)) + for i := 0; i < n; i++ { + out = append(out, TimestampSource((*typesArray)[i])) + } + return +} + +func (p *InactiveHandle) pcapSetTstampType(t TimestampSource) error { + if status := C.pcap_set_tstamp_type(p.cptr, C.int(t)); status < 0 { + return statusError(status) + } + return nil +} + +func (p *InactiveHandle) pcapSetRfmon(monitor bool) error { + var mon C.int + if monitor { + mon = 1 + } + switch canset := C.pcap_can_set_rfmon(p.cptr); canset { + case 0: + return CannotSetRFMon + case 1: + // success + default: + return statusError(canset) + } + if status := C.pcap_set_rfmon(p.cptr, mon); status != 0 { + return statusError(status) + } + return nil +} + +func (p *InactiveHandle) pcapSetBufferSize(bufferSize int) error { + if status := C.pcap_set_buffer_size(p.cptr, C.int(bufferSize)); status < 0 { + return statusError(status) + } + return nil +} + +func (p *InactiveHandle) pcapSetImmediateMode(mode bool) error { + var md C.int + if mode { + md = 1 + } + if status := C.pcap_set_immediate_mode(p.cptr, md); status < 0 { + return statusError(status) + } + return nil +} + +func (p *Handle) setNonBlocking() error { buf := (*C.char)(C.calloc(errorBufferSize, 1)) defer C.free(unsafe.Pointer(buf)) // Change the device to non-blocking, we'll use pcap_wait to wait until the // handle is ready to read. - if v := C.pcap_setnonblock(p.cptr, 1, buf); v == -1 { + if v := C.pcap_setnonblock(p.cptr, 1, buf); v < -1 { return errors.New(C.GoString(buf)) } @@ -67,5 +690,20 @@ func (p *Handle) waitForPacket() { usec := timeoutMillis(p.timeout) * 1000 usec -= 100 - C.pcap_wait(p.cptr, usec) + C.pcap_wait(p.cptr, C.int(usec)) +} + +// openOfflineFile returns contents of input file as a *Handle. +func openOfflineFile(file *os.File) (handle *Handle, err error) { + buf := (*C.char)(C.calloc(errorBufferSize, 1)) + defer C.free(unsafe.Pointer(buf)) + cmode := C.CString("rb") + defer C.free(unsafe.Pointer(cmode)) + cf := C.fdopen(C.int(file.Fd()), cmode) + + cptr := C.pcap_fopen_offline_with_tstamp_precision(cf, C.PCAP_TSTAMP_PRECISION_NANO, buf) + if cptr == nil { + return nil, errors.New(C.GoString(buf)) + } + return &Handle{cptr: cptr}, nil } diff --git a/vendor/github.com/google/gopacket/pcap/pcap_windows.go b/vendor/github.com/google/gopacket/pcap/pcap_windows.go index e3df123975..0a533380c6 100644 --- a/vendor/github.com/google/gopacket/pcap/pcap_windows.go +++ b/vendor/github.com/google/gopacket/pcap/pcap_windows.go @@ -8,10 +8,849 @@ package pcap import ( + "errors" + "fmt" + "os" "runtime" + "sync" + "syscall" + "time" + "unsafe" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" +) + +var pcapLoaded = false + +const npcapPath = "\\Npcap" + +func initDllPath(kernel32 syscall.Handle) { + setDllDirectory, err := syscall.GetProcAddress(kernel32, "SetDllDirectoryA") + if err != nil { + // we can't do anything since SetDllDirectoryA is missing - fall back to use first wpcap.dll we encounter + return + } + getSystemDirectory, err := syscall.GetProcAddress(kernel32, "GetSystemDirectoryA") + if err != nil { + // we can't do anything since SetDllDirectoryA is missing - fall back to use first wpcap.dll we encounter + return + } + buf := make([]byte, 4096) + r, _, _ := syscall.Syscall(getSystemDirectory, 2, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0) + if r == 0 || r > 4096-uintptr(len(npcapPath))-1 { + // we can't do anything since SetDllDirectoryA is missing - fall back to use first wpcap.dll we encounter + return + } + copy(buf[r:], npcapPath) + _, _, _ = syscall.Syscall(setDllDirectory, 1, uintptr(unsafe.Pointer(&buf[0])), 0, 0) + // ignore errors here - we just fallback to load wpcap.dll from default locations +} + +// loadedDllPath will hold the full pathname of the loaded wpcap.dll after init if possible +var loadedDllPath = "wpcap.dll" + +func initLoadedDllPath(kernel32 syscall.Handle) { + getModuleFileName, err := syscall.GetProcAddress(kernel32, "GetModuleFileNameA") + if err != nil { + // we can't get the filename of the loaded module in this case - just leave default of wpcap.dll + return + } + buf := make([]byte, 4096) + r, _, _ := syscall.Syscall(getModuleFileName, 3, uintptr(wpcapHandle), uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf))) + if r == 0 { + // we can't get the filename of the loaded module in this case - just leave default of wpcap.dll + return + } + loadedDllPath = string(buf[:int(r)]) +} + +func mustLoad(fun string) uintptr { + addr, err := syscall.GetProcAddress(wpcapHandle, fun) + if err != nil { + panic(fmt.Sprintf("Couldn't load function %s from %s", fun, loadedDllPath)) + } + return addr +} + +func mightLoad(fun string) uintptr { + addr, err := syscall.GetProcAddress(wpcapHandle, fun) + if err != nil { + return 0 + } + return addr +} + +func byteSliceToString(bval []byte) string { + for i := range bval { + if bval[i] == 0 { + return string(bval[:i]) + } + } + return string(bval[:]) +} + +// bytePtrToString returns a string copied from pointer to a null terminated byte array +// WARNING: ONLY SAFE WITH IF r POINTS TO C MEMORY! +// govet will complain about this function for the reason stated above +func bytePtrToString(r uintptr) string { + if r == 0 { + return "" + } + bval := (*[1 << 30]byte)(unsafe.Pointer(r)) + return byteSliceToString(bval[:]) +} + +var wpcapHandle syscall.Handle +var msvcrtHandle syscall.Handle +var ( + callocPtr, + pcapStrerrorPtr, + pcapStatustostrPtr, + pcapOpenLivePtr, + pcapOpenOfflinePtr, + pcapClosePtr, + pcapGeterrPtr, + pcapStatsPtr, + pcapCompilePtr, + pcapFreecodePtr, + pcapLookupnetPtr, + pcapOfflineFilterPtr, + pcapSetfilterPtr, + pcapListDatalinksPtr, + pcapFreeDatalinksPtr, + pcapDatalinkValToNamePtr, + pcapDatalinkValToDescriptionPtr, + pcapOpenDeadPtr, + pcapNextExPtr, + pcapDatalinkPtr, + pcapSetDatalinkPtr, + pcapDatalinkNameToValPtr, + pcapLibVersionPtr, + pcapFreealldevsPtr, + pcapFindalldevsPtr, + pcapSendpacketPtr, + pcapSetdirectionPtr, + pcapSnapshotPtr, + pcapTstampTypeValToNamePtr, + pcapTstampTypeNameToValPtr, + pcapListTstampTypesPtr, + pcapFreeTstampTypesPtr, + pcapSetTstampTypePtr, + pcapGetTstampPrecisionPtr, + pcapSetTstampPrecisionPtr, + pcapOpenOfflineWithTstampPrecisionPtr, + pcapHOpenOfflineWithTstampPrecisionPtr, + pcapActivatePtr, + pcapCreatePtr, + pcapSetSnaplenPtr, + pcapSetPromiscPtr, + pcapSetTimeoutPtr, + pcapCanSetRfmonPtr, + pcapSetRfmonPtr, + pcapSetBufferSizePtr, + pcapSetImmediateModePtr, + pcapHopenOfflinePtr uintptr ) -func (p *Handle) openLive() error { +func init() { + LoadWinPCAP() +} + +// LoadWinPCAP attempts to dynamically load the wpcap DLL and resolve necessary functions +func LoadWinPCAP() error { + if pcapLoaded { + return nil + } + + kernel32, err := syscall.LoadLibrary("kernel32.dll") + if err != nil { + return fmt.Errorf("couldn't load kernel32.dll") + } + defer syscall.FreeLibrary(kernel32) + + initDllPath(kernel32) + + wpcapHandle, err = syscall.LoadLibrary("wpcap.dll") + if err != nil { + return fmt.Errorf("couldn't load wpcap.dll") + } + initLoadedDllPath(kernel32) + msvcrtHandle, err = syscall.LoadLibrary("msvcrt.dll") + if err != nil { + return fmt.Errorf("couldn't load msvcrt.dll") + } + callocPtr, err = syscall.GetProcAddress(msvcrtHandle, "calloc") + if err != nil { + return fmt.Errorf("couldn't get calloc function") + } + + pcapStrerrorPtr = mustLoad("pcap_strerror") + pcapStatustostrPtr = mightLoad("pcap_statustostr") // not available on winpcap + pcapOpenLivePtr = mustLoad("pcap_open_live") + pcapOpenOfflinePtr = mustLoad("pcap_open_offline") + pcapClosePtr = mustLoad("pcap_close") + pcapGeterrPtr = mustLoad("pcap_geterr") + pcapStatsPtr = mustLoad("pcap_stats") + pcapCompilePtr = mustLoad("pcap_compile") + pcapFreecodePtr = mustLoad("pcap_freecode") + pcapLookupnetPtr = mustLoad("pcap_lookupnet") + pcapOfflineFilterPtr = mustLoad("pcap_offline_filter") + pcapSetfilterPtr = mustLoad("pcap_setfilter") + pcapListDatalinksPtr = mustLoad("pcap_list_datalinks") + pcapFreeDatalinksPtr = mustLoad("pcap_free_datalinks") + pcapDatalinkValToNamePtr = mustLoad("pcap_datalink_val_to_name") + pcapDatalinkValToDescriptionPtr = mustLoad("pcap_datalink_val_to_description") + pcapOpenDeadPtr = mustLoad("pcap_open_dead") + pcapNextExPtr = mustLoad("pcap_next_ex") + pcapDatalinkPtr = mustLoad("pcap_datalink") + pcapSetDatalinkPtr = mustLoad("pcap_set_datalink") + pcapDatalinkNameToValPtr = mustLoad("pcap_datalink_name_to_val") + pcapLibVersionPtr = mustLoad("pcap_lib_version") + pcapFreealldevsPtr = mustLoad("pcap_freealldevs") + pcapFindalldevsPtr = mustLoad("pcap_findalldevs") + pcapSendpacketPtr = mustLoad("pcap_sendpacket") + pcapSetdirectionPtr = mustLoad("pcap_setdirection") + pcapSnapshotPtr = mustLoad("pcap_snapshot") + //libpcap <1.2 doesn't have pcap_*_tstamp_* functions + pcapTstampTypeValToNamePtr = mightLoad("pcap_tstamp_type_val_to_name") + pcapTstampTypeNameToValPtr = mightLoad("pcap_tstamp_type_name_to_val") + pcapListTstampTypesPtr = mightLoad("pcap_list_tstamp_types") + pcapFreeTstampTypesPtr = mightLoad("pcap_free_tstamp_types") + pcapSetTstampTypePtr = mightLoad("pcap_set_tstamp_type") + pcapGetTstampPrecisionPtr = mightLoad("pcap_get_tstamp_precision") + pcapSetTstampPrecisionPtr = mightLoad("pcap_set_tstamp_precision") + pcapOpenOfflineWithTstampPrecisionPtr = mightLoad("pcap_open_offline_with_tstamp_precision") + pcapHOpenOfflineWithTstampPrecisionPtr = mightLoad("pcap_hopen_offline_with_tstamp_precision") + pcapActivatePtr = mustLoad("pcap_activate") + pcapCreatePtr = mustLoad("pcap_create") + pcapSetSnaplenPtr = mustLoad("pcap_set_snaplen") + pcapSetPromiscPtr = mustLoad("pcap_set_promisc") + pcapSetTimeoutPtr = mustLoad("pcap_set_timeout") + //winpcap does not support rfmon + pcapCanSetRfmonPtr = mightLoad("pcap_can_set_rfmon") + pcapSetRfmonPtr = mightLoad("pcap_set_rfmon") + pcapSetBufferSizePtr = mustLoad("pcap_set_buffer_size") + //libpcap <1.5 does not have pcap_set_immediate_mode + pcapSetImmediateModePtr = mightLoad("pcap_set_immediate_mode") + pcapHopenOfflinePtr = mustLoad("pcap_hopen_offline") + + pcapLoaded = true + return nil +} + +func (h *pcapPkthdr) getSec() int64 { + return int64(h.Ts.Sec) +} + +func (h *pcapPkthdr) getUsec() int64 { + return int64(h.Ts.Usec) +} + +func (h *pcapPkthdr) getLen() int { + return int(h.Len) +} + +func (h *pcapPkthdr) getCaplen() int { + return int(h.Caplen) +} + +func statusError(status pcapCint) error { + var ret uintptr + if pcapStatustostrPtr == 0 { + ret, _, _ = syscall.Syscall(pcapStrerrorPtr, 1, uintptr(status), 0, 0) + } else { + ret, _, _ = syscall.Syscall(pcapStatustostrPtr, 1, uintptr(status), 0, 0) + } + return errors.New(bytePtrToString(ret)) +} + +func pcapGetTstampPrecision(cptr pcapTPtr) int { + if pcapGetTstampPrecisionPtr == 0 { + return pcapTstampPrecisionMicro + } + ret, _, _ := syscall.Syscall(pcapGetTstampPrecisionPtr, 1, uintptr(cptr), 0, 0) + return int(pcapCint(ret)) +} + +func pcapSetTstampPrecision(cptr pcapTPtr, precision int) error { + if pcapSetTstampPrecisionPtr == 0 { + return errors.New("Not supported") + } + ret, _, _ := syscall.Syscall(pcapSetTstampPrecisionPtr, 2, uintptr(cptr), uintptr(precision), 0) + if pcapCint(ret) < 0 { + return errors.New("Not supported") + } + return nil +} + +func pcapOpenLive(device string, snaplen int, pro int, timeout int) (*Handle, error) { + err := LoadWinPCAP() + if err != nil { + return nil, err + } + + buf := make([]byte, errorBufferSize) + dev, err := syscall.BytePtrFromString(device) + if err != nil { + return nil, err + } + + cptr, _, _ := syscall.Syscall6(pcapOpenLivePtr, 5, uintptr(unsafe.Pointer(dev)), uintptr(snaplen), uintptr(pro), uintptr(timeout), uintptr(unsafe.Pointer(&buf[0])), 0) + + if cptr == 0 { + return nil, errors.New(byteSliceToString(buf)) + } + return &Handle{cptr: pcapTPtr(cptr)}, nil +} + +func openOffline(file string) (handle *Handle, err error) { + err = LoadWinPCAP() + if err != nil { + return nil, err + } + + buf := make([]byte, errorBufferSize) + f, err := syscall.BytePtrFromString(file) + if err != nil { + return nil, err + } + + var cptr uintptr + if pcapOpenOfflineWithTstampPrecisionPtr == 0 { + cptr, _, _ = syscall.Syscall(pcapOpenOfflinePtr, 2, uintptr(unsafe.Pointer(f)), uintptr(unsafe.Pointer(&buf[0])), 0) + } else { + cptr, _, _ = syscall.Syscall(pcapOpenOfflineWithTstampPrecisionPtr, 3, uintptr(unsafe.Pointer(f)), uintptr(pcapTstampPrecisionNano), uintptr(unsafe.Pointer(&buf[0]))) + } + + if cptr == 0 { + return nil, errors.New(byteSliceToString(buf)) + } + + h := &Handle{cptr: pcapTPtr(cptr)} + return h, nil +} + +func (p *Handle) pcapClose() { + if p.cptr != 0 { + _, _, _ = syscall.Syscall(pcapClosePtr, 1, uintptr(p.cptr), 0, 0) + } + p.cptr = 0 +} + +func (p *Handle) pcapGeterr() error { + ret, _, _ := syscall.Syscall(pcapGeterrPtr, 1, uintptr(p.cptr), 0, 0) + return errors.New(bytePtrToString(ret)) +} + +func (p *Handle) pcapStats() (*Stats, error) { + var cstats pcapStats + ret, _, _ := syscall.Syscall(pcapStatsPtr, 2, uintptr(p.cptr), uintptr(unsafe.Pointer(&cstats)), 0) + if pcapCint(ret) < 0 { + return nil, p.pcapGeterr() + } + return &Stats{ + PacketsReceived: int(cstats.Recv), + PacketsDropped: int(cstats.Drop), + PacketsIfDropped: int(cstats.Ifdrop), + }, nil +} + +// for libpcap < 1.8 pcap_compile is NOT thread-safe, so protect it. +var pcapCompileMu sync.Mutex + +func (p *Handle) pcapCompile(expr string, maskp uint32) (pcapBpfProgram, error) { + var bpf pcapBpfProgram + cexpr, err := syscall.BytePtrFromString(expr) + if err != nil { + return pcapBpfProgram{}, err + } + pcapCompileMu.Lock() + defer pcapCompileMu.Unlock() + res, _, _ := syscall.Syscall6(pcapCompilePtr, 5, uintptr(p.cptr), uintptr(unsafe.Pointer(&bpf)), uintptr(unsafe.Pointer(cexpr)), uintptr(1), uintptr(maskp), 0) + if pcapCint(res) < 0 { + return bpf, p.pcapGeterr() + } + return bpf, nil +} + +func (p pcapBpfProgram) free() { + _, _, _ = syscall.Syscall(pcapFreecodePtr, 1, uintptr(unsafe.Pointer(&p)), 0, 0) +} + +func (p pcapBpfProgram) toBPFInstruction() []BPFInstruction { + bpfInsn := (*[bpfInstructionBufferSize]pcapBpfInstruction)(unsafe.Pointer(p.Insns))[0:p.Len:p.Len] + bpfInstruction := make([]BPFInstruction, len(bpfInsn), len(bpfInsn)) + + for i, v := range bpfInsn { + bpfInstruction[i].Code = v.Code + bpfInstruction[i].Jt = v.Jt + bpfInstruction[i].Jf = v.Jf + bpfInstruction[i].K = v.K + } + return bpfInstruction +} + +func pcapBpfProgramFromInstructions(bpfInstructions []BPFInstruction) pcapBpfProgram { + var bpf pcapBpfProgram + bpf.Len = uint32(len(bpfInstructions)) + cbpfInsns, _, _ := syscall.Syscall(callocPtr, 2, uintptr(len(bpfInstructions)), uintptr(unsafe.Sizeof(bpfInstructions[0])), 0) + gbpfInsns := (*[bpfInstructionBufferSize]pcapBpfInstruction)(unsafe.Pointer(cbpfInsns)) + + for i, v := range bpfInstructions { + gbpfInsns[i].Code = v.Code + gbpfInsns[i].Jt = v.Jt + gbpfInsns[i].Jf = v.Jf + gbpfInsns[i].K = v.K + } + + bpf.Insns = (*pcapBpfInstruction)(unsafe.Pointer(cbpfInsns)) + return bpf +} + +func pcapLookupnet(device string) (netp, maskp uint32, err error) { + err = LoadWinPCAP() + if err != nil { + return 0, 0, err + } + + buf := make([]byte, errorBufferSize) + dev, err := syscall.BytePtrFromString(device) + if err != nil { + return 0, 0, err + } + e, _, _ := syscall.Syscall6(pcapLookupnetPtr, 4, uintptr(unsafe.Pointer(dev)), uintptr(unsafe.Pointer(&netp)), uintptr(unsafe.Pointer(&maskp)), uintptr(unsafe.Pointer(&buf[0])), 0, 0) + if pcapCint(e) < 0 { + return 0, 0, errors.New(byteSliceToString(buf)) + } + return +} + +func (b *BPF) pcapOfflineFilter(ci gopacket.CaptureInfo, data []byte) bool { + var hdr pcapPkthdr + hdr.Ts.Sec = int32(ci.Timestamp.Unix()) + hdr.Ts.Usec = int32(ci.Timestamp.Nanosecond() / 1000) + hdr.Caplen = uint32(len(data)) // Trust actual length over ci.Length. + hdr.Len = uint32(ci.Length) + e, _, _ := syscall.Syscall(pcapOfflineFilterPtr, 3, uintptr(unsafe.Pointer(&b.bpf)), uintptr(unsafe.Pointer(&hdr)), uintptr(unsafe.Pointer(&data[0]))) + return e != 0 +} + +func (p *Handle) pcapSetfilter(bpf pcapBpfProgram) error { + e, _, _ := syscall.Syscall(pcapSetfilterPtr, 2, uintptr(p.cptr), uintptr(unsafe.Pointer(&bpf)), 0) + if pcapCint(e) < 0 { + return p.pcapGeterr() + } + return nil +} + +func (p *Handle) pcapListDatalinks() (datalinks []Datalink, err error) { + var dltbuf *pcapCint + ret, _, _ := syscall.Syscall(pcapListDatalinksPtr, 2, uintptr(p.cptr), uintptr(unsafe.Pointer(&dltbuf)), 0) + + n := int(pcapCint(ret)) + + if n < 0 { + return nil, p.pcapGeterr() + } + defer syscall.Syscall(pcapFreeDatalinksPtr, 1, uintptr(unsafe.Pointer(dltbuf)), 0, 0) + + datalinks = make([]Datalink, n) + + dltArray := (*[1 << 28]pcapCint)(unsafe.Pointer(dltbuf)) + + for i := 0; i < n; i++ { + datalinks[i].Name = pcapDatalinkValToName(int((*dltArray)[i])) + datalinks[i].Description = pcapDatalinkValToDescription(int((*dltArray)[i])) + } + + return datalinks, nil +} + +func pcapOpenDead(linkType layers.LinkType, captureLength int) (*Handle, error) { + err := LoadWinPCAP() + if err != nil { + return nil, err + } + + cptr, _, _ := syscall.Syscall(pcapOpenDeadPtr, 2, uintptr(linkType), uintptr(captureLength), 0) + if cptr == 0 { + return nil, errors.New("error opening dead capture") + } + + return &Handle{cptr: pcapTPtr(cptr)}, nil +} + +func (p *Handle) pcapNextPacketEx() NextError { + r, _, _ := syscall.Syscall(pcapNextExPtr, 3, uintptr(p.cptr), uintptr(unsafe.Pointer(&p.pkthdr)), uintptr(unsafe.Pointer(&p.bufptr))) + ret := pcapCint(r) + // According to https://github.com/the-tcpdump-group/libpcap/blob/1131a7c26c6f4d4772e4a2beeaf7212f4dea74ac/pcap.c#L398-L406 , + // the return value of pcap_next_ex could be greater than 1 for success. + // Let's just make it 1 if it comes bigger than 1. + if ret > 1 { + ret = 1 + } + return NextError(ret) +} + +func (p *Handle) pcapDatalink() layers.LinkType { + ret, _, _ := syscall.Syscall(pcapDatalinkPtr, 1, uintptr(p.cptr), 0, 0) + return layers.LinkType(ret) +} + +func (p *Handle) pcapSetDatalink(dlt layers.LinkType) error { + ret, _, _ := syscall.Syscall(pcapSetDatalinkPtr, 2, uintptr(p.cptr), uintptr(dlt), 0) + if pcapCint(ret) < 0 { + return p.pcapGeterr() + } + return nil +} + +func pcapDatalinkValToName(dlt int) string { + err := LoadWinPCAP() + if err != nil { + panic(err) + } + ret, _, _ := syscall.Syscall(pcapDatalinkValToNamePtr, 1, uintptr(dlt), 0, 0) + return bytePtrToString(ret) +} + +func pcapDatalinkValToDescription(dlt int) string { + err := LoadWinPCAP() + if err != nil { + panic(err) + } + ret, _, _ := syscall.Syscall(pcapDatalinkValToDescriptionPtr, 1, uintptr(dlt), 0, 0) + return bytePtrToString(ret) +} + +func pcapDatalinkNameToVal(name string) int { + err := LoadWinPCAP() + if err != nil { + panic(err) + } + cptr, err := syscall.BytePtrFromString(name) + if err != nil { + return 0 + } + ret, _, _ := syscall.Syscall(pcapDatalinkNameToValPtr, 1, uintptr(unsafe.Pointer(cptr)), 0, 0) + return int(pcapCint(ret)) +} + +func pcapLibVersion() string { + err := LoadWinPCAP() + if err != nil { + panic(err) + } + ret, _, _ := syscall.Syscall(pcapLibVersionPtr, 0, 0, 0, 0) + return bytePtrToString(ret) +} + +func (p *Handle) isOpen() bool { + return p.cptr != 0 +} + +type pcapDevices struct { + all, cur *pcapIf +} + +func (p pcapDevices) free() { + syscall.Syscall(pcapFreealldevsPtr, 1, uintptr(unsafe.Pointer(p.all)), 0, 0) +} + +func (p *pcapDevices) next() bool { + if p.cur == nil { + p.cur = p.all + if p.cur == nil { + return false + } + return true + } + if p.cur.Next == nil { + return false + } + p.cur = p.cur.Next + return true +} + +func (p pcapDevices) name() string { + return bytePtrToString(uintptr(unsafe.Pointer(p.cur.Name))) +} + +func (p pcapDevices) description() string { + return bytePtrToString(uintptr(unsafe.Pointer(p.cur.Description))) +} + +func (p pcapDevices) flags() uint32 { + return p.cur.Flags +} + +type pcapAddresses struct { + all, cur *pcapAddr +} + +func (p *pcapAddresses) next() bool { + if p.cur == nil { + p.cur = p.all + if p.cur == nil { + return false + } + return true + } + if p.cur.Next == nil { + return false + } + p.cur = p.cur.Next + return true +} + +func (p pcapAddresses) addr() *syscall.RawSockaddr { + return p.cur.Addr +} + +func (p pcapAddresses) netmask() *syscall.RawSockaddr { + return p.cur.Netmask +} + +func (p pcapAddresses) broadaddr() *syscall.RawSockaddr { + return p.cur.Broadaddr +} + +func (p pcapAddresses) dstaddr() *syscall.RawSockaddr { + return p.cur.Dstaddr +} + +func (p pcapDevices) addresses() pcapAddresses { + return pcapAddresses{all: p.cur.Addresses} +} + +func pcapFindAllDevs() (pcapDevices, error) { + var alldevsp pcapDevices + err := LoadWinPCAP() + if err != nil { + return alldevsp, err + } + + buf := make([]byte, errorBufferSize) + + ret, _, _ := syscall.Syscall(pcapFindalldevsPtr, 2, uintptr(unsafe.Pointer(&alldevsp.all)), uintptr(unsafe.Pointer(&buf[0])), 0) + + if pcapCint(ret) < 0 { + return pcapDevices{}, errors.New(byteSliceToString(buf)) + } + return alldevsp, nil +} + +func (p *Handle) pcapSendpacket(data []byte) error { + ret, _, _ := syscall.Syscall(pcapSendpacketPtr, 3, uintptr(p.cptr), uintptr(unsafe.Pointer(&data[0])), uintptr(len(data))) + if pcapCint(ret) < 0 { + return p.pcapGeterr() + } + return nil +} + +func (p *Handle) pcapSetdirection(direction Direction) error { + status, _, _ := syscall.Syscall(pcapSetdirectionPtr, 2, uintptr(p.cptr), uintptr(direction), 0) + if pcapCint(status) < 0 { + return statusError(pcapCint(status)) + } + return nil +} + +func (p *Handle) pcapSnapshot() int { + ret, _, _ := syscall.Syscall(pcapSnapshotPtr, 1, uintptr(p.cptr), 0, 0) + return int(pcapCint(ret)) +} + +func (t TimestampSource) pcapTstampTypeValToName() string { + err := LoadWinPCAP() + if err != nil { + return err.Error() + } + + //libpcap <1.2 doesn't have pcap_*_tstamp_* functions + if pcapTstampTypeValToNamePtr == 0 { + return "pcap timestamp types not supported" + } + ret, _, _ := syscall.Syscall(pcapTstampTypeValToNamePtr, 1, uintptr(t), 0, 0) + return bytePtrToString(ret) +} + +func pcapTstampTypeNameToVal(s string) (TimestampSource, error) { + err := LoadWinPCAP() + if err != nil { + return 0, err + } + + //libpcap <1.2 doesn't have pcap_*_tstamp_* functions + if pcapTstampTypeNameToValPtr == 0 { + return 0, statusError(pcapCint(pcapError)) + } + cs, err := syscall.BytePtrFromString(s) + if err != nil { + return 0, err + } + ret, _, _ := syscall.Syscall(pcapTstampTypeNameToValPtr, 1, uintptr(unsafe.Pointer(cs)), 0, 0) + t := pcapCint(ret) + if t < 0 { + return 0, statusError(pcapCint(t)) + } + return TimestampSource(t), nil +} + +func (p *InactiveHandle) pcapGeterr() error { + ret, _, _ := syscall.Syscall(pcapGeterrPtr, 1, uintptr(p.cptr), 0, 0) + return errors.New(bytePtrToString(ret)) +} + +func (p *InactiveHandle) pcapActivate() (*Handle, activateError) { + r, _, _ := syscall.Syscall(pcapActivatePtr, 1, uintptr(p.cptr), 0, 0) + ret := activateError(pcapCint(r)) + if ret != aeNoError { + return nil, ret + } + h := &Handle{ + cptr: p.cptr, + } + p.cptr = 0 + return h, ret +} + +func (p *InactiveHandle) pcapClose() { + if p.cptr != 0 { + _, _, _ = syscall.Syscall(pcapClosePtr, 1, uintptr(p.cptr), 0, 0) + } + p.cptr = 0 +} + +func pcapCreate(device string) (*InactiveHandle, error) { + err := LoadWinPCAP() + if err != nil { + return nil, err + } + + buf := make([]byte, errorBufferSize) + dev, err := syscall.BytePtrFromString(device) + if err != nil { + return nil, err + } + cptr, _, _ := syscall.Syscall(pcapCreatePtr, 2, uintptr(unsafe.Pointer(dev)), uintptr(unsafe.Pointer(&buf[0])), 0) + if cptr == 0 { + return nil, errors.New(byteSliceToString(buf)) + } + return &InactiveHandle{cptr: pcapTPtr(cptr)}, nil +} + +func (p *InactiveHandle) pcapSetSnaplen(snaplen int) error { + status, _, _ := syscall.Syscall(pcapSetSnaplenPtr, 2, uintptr(p.cptr), uintptr(snaplen), 0) + if pcapCint(status) < 0 { + return statusError(pcapCint(status)) + } + return nil +} + +func (p *InactiveHandle) pcapSetPromisc(promisc bool) error { + var pro uintptr + if promisc { + pro = 1 + } + status, _, _ := syscall.Syscall(pcapSetPromiscPtr, 2, uintptr(p.cptr), pro, 0) + if pcapCint(status) < 0 { + return statusError(pcapCint(status)) + } + return nil +} + +func (p *InactiveHandle) pcapSetTimeout(timeout time.Duration) error { + status, _, _ := syscall.Syscall(pcapSetTimeoutPtr, 2, uintptr(p.cptr), uintptr(timeoutMillis(timeout)), 0) + + if pcapCint(status) < 0 { + return statusError(pcapCint(status)) + } + return nil +} + +func (p *InactiveHandle) pcapListTstampTypes() (out []TimestampSource) { + //libpcap <1.2 doesn't have pcap_*_tstamp_* functions + if pcapListTstampTypesPtr == 0 { + return + } + var types *pcapCint + ret, _, _ := syscall.Syscall(pcapListTstampTypesPtr, 2, uintptr(p.cptr), uintptr(unsafe.Pointer(&types)), 0) + n := int(pcapCint(ret)) + if n < 0 { + return // public interface doesn't have error :( + } + defer syscall.Syscall(pcapFreeTstampTypesPtr, 1, uintptr(unsafe.Pointer(types)), 0, 0) + typesArray := (*[1 << 28]pcapCint)(unsafe.Pointer(types)) + for i := 0; i < n; i++ { + out = append(out, TimestampSource((*typesArray)[i])) + } + return +} + +func (p *InactiveHandle) pcapSetTstampType(t TimestampSource) error { + //libpcap <1.2 doesn't have pcap_*_tstamp_* functions + if pcapSetTstampTypePtr == 0 { + return statusError(pcapError) + } + status, _, _ := syscall.Syscall(pcapSetTstampTypePtr, 2, uintptr(p.cptr), uintptr(t), 0) + if pcapCint(status) < 0 { + return statusError(pcapCint(status)) + } + return nil +} + +func (p *InactiveHandle) pcapSetRfmon(monitor bool) error { + //winpcap does not support rfmon + if pcapCanSetRfmonPtr == 0 { + return CannotSetRFMon + } + var mon uintptr + if monitor { + mon = 1 + } + canset, _, _ := syscall.Syscall(pcapCanSetRfmonPtr, 1, uintptr(p.cptr), 0, 0) + switch canset { + case 0: + return CannotSetRFMon + case 1: + // success + default: + return statusError(pcapCint(canset)) + } + status, _, _ := syscall.Syscall(pcapSetRfmonPtr, 2, uintptr(p.cptr), mon, 0) + if status != 0 { + return statusError(pcapCint(status)) + } + return nil +} + +func (p *InactiveHandle) pcapSetBufferSize(bufferSize int) error { + status, _, _ := syscall.Syscall(pcapSetBufferSizePtr, 2, uintptr(p.cptr), uintptr(bufferSize), 0) + if pcapCint(status) < 0 { + return statusError(pcapCint(status)) + } + return nil +} + +func (p *InactiveHandle) pcapSetImmediateMode(mode bool) error { + //libpcap <1.5 does not have pcap_set_immediate_mode + if pcapSetImmediateModePtr == 0 { + return statusError(pcapError) + } + var md uintptr + if mode { + md = 1 + } + status, _, _ := syscall.Syscall(pcapSetImmediateModePtr, 2, uintptr(p.cptr), md, 0) + if pcapCint(status) < 0 { + return statusError(pcapCint(status)) + } + return nil +} + +func (p *Handle) setNonBlocking() error { // do nothing return nil } @@ -21,3 +860,26 @@ func (p *Handle) waitForPacket() { // can't use select() so instead just switch goroutines runtime.Gosched() } + +// openOfflineFile returns contents of input file as a *Handle. +func openOfflineFile(file *os.File) (handle *Handle, err error) { + err = LoadWinPCAP() + if err != nil { + return nil, err + } + + buf := make([]byte, errorBufferSize) + cf := file.Fd() + + var cptr uintptr + if pcapOpenOfflineWithTstampPrecisionPtr == 0 { + cptr, _, _ = syscall.Syscall(pcapHopenOfflinePtr, 2, cf, uintptr(unsafe.Pointer(&buf[0])), 0) + } else { + cptr, _, _ = syscall.Syscall(pcapHOpenOfflineWithTstampPrecisionPtr, 3, cf, uintptr(pcapTstampPrecisionNano), uintptr(unsafe.Pointer(&buf[0]))) + } + + if cptr == 0 { + return nil, errors.New(byteSliceToString(buf)) + } + return &Handle{cptr: pcapTPtr(cptr)}, nil +} diff --git a/vendor/github.com/google/gopacket/pcap/pcapnggo_test.go b/vendor/github.com/google/gopacket/pcap/pcapnggo_test.go new file mode 100644 index 0000000000..79b26e4d0a --- /dev/null +++ b/vendor/github.com/google/gopacket/pcap/pcapnggo_test.go @@ -0,0 +1,60 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package pcap + +import ( + "bytes" + "io/ioutil" + "reflect" + "testing" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcapgo" +) + +func TestPCAPGoNgWrite(t *testing.T) { + f, err := ioutil.TempFile("", "pcapnggo") + if err != nil { + t.Fatal(err) + } + data := []byte{0xab, 0xcd, 0xef, 0x01, 0x02, 0x03, 0x04} + ci := gopacket.CaptureInfo{ + Timestamp: time.Unix(12345667, 1234567123), + Length: 700, + CaptureLength: len(data), + } + func() { + defer f.Close() + w, err := pcapgo.NewNgWriter(f, layers.LinkTypeEthernet) + if err != nil { + t.Fatal(err) + } + if err := w.WritePacket(ci, data); err != nil { + t.Fatal(err) + } + if err := w.Flush(); err != nil { + t.Fatal(err) + } + }() + h, err := OpenOffline(f.Name()) + if err != nil { + t.Fatal(err) + } + defer h.Close() + gotData, gotCI, err := h.ReadPacketData() + if err != nil { + t.Fatal("could not read first packet:", err) + } + if !bytes.Equal(gotData, data) { + t.Errorf("byte mismatch:\nwant: %v\n got: %v", data, gotData) + } + if !reflect.DeepEqual(ci, gotCI) { + t.Errorf("CI mismatch:\nwant: %v\n got: %v", ci, gotCI) + } +} diff --git a/vendor/github.com/google/gopacket/pcapgo/capture.go b/vendor/github.com/google/gopacket/pcapgo/capture.go new file mode 100644 index 0000000000..827a366e8f --- /dev/null +++ b/vendor/github.com/google/gopacket/pcapgo/capture.go @@ -0,0 +1,286 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +// +build linux,go1.7 + +package pcapgo + +import ( + "fmt" + "net" + "runtime" + "sync" + "syscall" + "time" + "unsafe" + + "golang.org/x/net/bpf" + "golang.org/x/sys/unix" + + "github.com/google/gopacket" +) + +var hdrLen = unix.CmsgSpace(0) +var auxLen = unix.CmsgSpace(int(unsafe.Sizeof(unix.TpacketAuxdata{}))) +var timensLen = unix.CmsgSpace(int(unsafe.Sizeof(unix.Timespec{}))) +var timeLen = unix.CmsgSpace(int(unsafe.Sizeof(unix.Timeval{}))) + +func htons(data uint16) uint16 { return data<<8 | data>>8 } + +// EthernetHandle holds shared buffers and file descriptor of af_packet socket +type EthernetHandle struct { + fd int + buffer []byte + oob []byte + ancil []interface{} + mu sync.Mutex + intf int + addr net.HardwareAddr +} + +// readOne reads a packet from the handle and returns a capture info + vlan info +func (h *EthernetHandle) readOne() (ci gopacket.CaptureInfo, vlan int, haveVlan bool, err error) { + // we could use unix.Recvmsg, but that does a memory allocation (for the returned sockaddr) :( + var msg unix.Msghdr + var sa unix.RawSockaddrLinklayer + + msg.Name = (*byte)(unsafe.Pointer(&sa)) + msg.Namelen = uint32(unsafe.Sizeof(sa)) + + var iov unix.Iovec + if len(h.buffer) > 0 { + iov.Base = &h.buffer[0] + iov.SetLen(len(h.buffer)) + } + msg.Iov = &iov + msg.Iovlen = 1 + + if len(h.oob) > 0 { + msg.Control = &h.oob[0] + msg.SetControllen(len(h.oob)) + } + + // use msg_trunc so we know packet size without auxdata, which might be missing + n, _, e := syscall.Syscall(unix.SYS_RECVMSG, uintptr(h.fd), uintptr(unsafe.Pointer(&msg)), uintptr(unix.MSG_TRUNC)) + + if e != 0 { + return gopacket.CaptureInfo{}, 0, false, fmt.Errorf("couldn't read packet: %s", e) + } + + if sa.Family == unix.AF_PACKET { + ci.InterfaceIndex = int(sa.Ifindex) + } else { + ci.InterfaceIndex = h.intf + } + + // custom aux parsing so we don't allocate stuff (unix.ParseSocketControlMessage allocates a slice) + // we're getting at most 2 cmsgs anyway and know which ones they are (auxdata + timestamp(ns)) + oob := h.oob[:msg.Controllen] + gotAux := false + + for len(oob) > hdrLen { // > hdrLen, because we also need something after the cmsg header + hdr := (*unix.Cmsghdr)(unsafe.Pointer(&oob[0])) + switch { + case hdr.Level == unix.SOL_PACKET && hdr.Type == unix.PACKET_AUXDATA && len(oob) >= auxLen: + aux := (*unix.TpacketAuxdata)(unsafe.Pointer(&oob[hdrLen])) + ci.CaptureLength = int(n) + ci.Length = int(aux.Len) + vlan = int(aux.Vlan_tci) + haveVlan = (aux.Status & unix.TP_STATUS_VLAN_VALID) != 0 + gotAux = true + case hdr.Level == unix.SOL_SOCKET && hdr.Type == unix.SO_TIMESTAMPNS && len(oob) >= timensLen: + tstamp := (*unix.Timespec)(unsafe.Pointer(&oob[hdrLen])) + ci.Timestamp = time.Unix(int64(tstamp.Sec), int64(tstamp.Nsec)) + case hdr.Level == unix.SOL_SOCKET && hdr.Type == unix.SO_TIMESTAMP && len(oob) >= timeLen: + tstamp := (*unix.Timeval)(unsafe.Pointer(&oob[hdrLen])) + ci.Timestamp = time.Unix(int64(tstamp.Sec), int64(tstamp.Usec)*1000) + } + oob = oob[unix.CmsgSpace(int(hdr.Len))-hdrLen:] + } + + if !gotAux { + // fallback for no aux cmsg + ci.CaptureLength = int(n) + ci.Length = int(n) + haveVlan = false + } + + // fix up capture length if we needed to truncate + if ci.CaptureLength > len(h.buffer) { + ci.CaptureLength = len(h.buffer) + } + + if ci.Timestamp.IsZero() { + // we got no timestamp info -> emulate it + ci.Timestamp = time.Now() + } + + return ci, vlan, haveVlan, nil +} + +// ReadPacketData implements gopacket.PacketDataSource. If this was captured on a vlan, the vlan id will be in the AncillaryData[0] +func (h *EthernetHandle) ReadPacketData() ([]byte, gopacket.CaptureInfo, error) { + h.mu.Lock() + ci, vlan, haveVlan, err := h.readOne() + if err != nil { + h.mu.Unlock() + return nil, gopacket.CaptureInfo{}, fmt.Errorf("couldn't read packet data: %s", err) + } + + b := make([]byte, ci.CaptureLength) + copy(b, h.buffer) + h.mu.Unlock() + + if haveVlan { + ci.AncillaryData = []interface{}{vlan} + + } + + return b, ci, nil +} + +// ZeroCopyReadPacketData implements gopacket.ZeroCopyPacketDataSource. If this was captured on a vlan, the vlan id will be in the AncillaryData[0]. +// This function does not allocate memory. Beware that the next call to ZeroCopyReadPacketData will overwrite existing slices (returned data AND AncillaryData)! +// Due to shared buffers this must not be called concurrently +func (h *EthernetHandle) ZeroCopyReadPacketData() ([]byte, gopacket.CaptureInfo, error) { + ci, vlan, haveVlan, err := h.readOne() + if err != nil { + return nil, gopacket.CaptureInfo{}, fmt.Errorf("couldn't read packet data: %s", err) + } + + if haveVlan { + h.ancil[0] = vlan + ci.AncillaryData = h.ancil + } + + return h.buffer[:ci.CaptureLength], ci, nil +} + +// Close closes the underlying socket +func (h *EthernetHandle) Close() { + if h.fd != -1 { + unix.Close(h.fd) + h.fd = -1 + runtime.SetFinalizer(h, nil) + } +} + +// SetCaptureLength sets the maximum capture length to the given value +func (h *EthernetHandle) SetCaptureLength(len int) error { + if len < 0 { + return fmt.Errorf("illegal capture length %d. Must be at least 0", len) + } + h.buffer = make([]byte, len) + return nil +} + +// GetCaptureLength returns the maximum capture length +func (h *EthernetHandle) GetCaptureLength() int { + return len(h.buffer) +} + +// SetBPF attaches the given BPF filter to the socket. After this, only the packets for which the filter returns a value greater than zero are received. +// If a filter was already attached, it will be overwritten. To remove the filter, provide an empty slice. +func (h *EthernetHandle) SetBPF(filter []bpf.RawInstruction) error { + if len(filter) == 0 { + return unix.SetsockoptInt(h.fd, unix.SOL_SOCKET, unix.SO_DETACH_FILTER, 0) + } + f := make([]unix.SockFilter, len(filter)) + for i := range filter { + f[i].Code = filter[i].Op + f[i].Jf = filter[i].Jf + f[i].Jt = filter[i].Jt + f[i].K = filter[i].K + } + fprog := &unix.SockFprog{ + Len: uint16(len(filter)), + Filter: &f[0], + } + return unix.SetsockoptSockFprog(h.fd, unix.SOL_SOCKET, unix.SO_ATTACH_FILTER, fprog) +} + +// LocalAddr returns the local network address +func (h *EthernetHandle) LocalAddr() net.HardwareAddr { + // Hardware Address might have changed. Fetch new one and fall back to the stored one if fetching interface fails + intf, err := net.InterfaceByIndex(h.intf) + if err == nil { + h.addr = intf.HardwareAddr + } + return h.addr +} + +// SetPromiscuous sets promiscous mode to the required value. If it is enabled, traffic not destined for the interface will also be captured. +func (h *EthernetHandle) SetPromiscuous(b bool) error { + mreq := unix.PacketMreq{ + Ifindex: int32(h.intf), + Type: unix.PACKET_MR_PROMISC, + } + + opt := unix.PACKET_ADD_MEMBERSHIP + if !b { + opt = unix.PACKET_DROP_MEMBERSHIP + } + + return unix.SetsockoptPacketMreq(h.fd, unix.SOL_PACKET, opt, &mreq) +} + +// Stats returns number of packets and dropped packets. This will be the number of packets/dropped packets since the last call to stats (not the cummulative sum!). +func (h *EthernetHandle) Stats() (*unix.TpacketStats, error) { + return unix.GetsockoptTpacketStats(h.fd, unix.SOL_PACKET, unix.PACKET_STATISTICS) +} + +// NewEthernetHandle implements pcap.OpenLive for network devices. +// If you want better performance have a look at github.com/google/gopacket/afpacket. +// SetCaptureLength can be used to limit the maximum capture length. +func NewEthernetHandle(ifname string) (*EthernetHandle, error) { + intf, err := net.InterfaceByName(ifname) + if err != nil { + return nil, fmt.Errorf("couldn't query interface %s: %s", ifname, err) + } + + fd, err := unix.Socket(unix.AF_PACKET, unix.SOCK_RAW, int(htons(unix.ETH_P_ALL))) + if err != nil { + return nil, fmt.Errorf("couldn't open packet socket: %s", err) + } + + addr := unix.SockaddrLinklayer{ + Protocol: htons(unix.ETH_P_ALL), + Ifindex: intf.Index, + } + + if err := unix.Bind(fd, &addr); err != nil { + return nil, fmt.Errorf("couldn't bind to interface %s: %s", ifname, err) + } + + ooblen := 0 + + if err := unix.SetsockoptInt(fd, unix.SOL_PACKET, unix.PACKET_AUXDATA, 1); err != nil { + // we can't get auxdata -> no vlan info + } else { + ooblen += auxLen + } + + if err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_TIMESTAMPNS, 1); err != nil { + // no nanosecond resolution :( -> try ms + if err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_TIMESTAMP, 1); err != nil { + // if this doesn't work we well use time.Now() -> ignore errors here + } else { + ooblen += timeLen + } + } else { + ooblen += timensLen + } + + handle := &EthernetHandle{ + fd: fd, + buffer: make([]byte, intf.MTU), + oob: make([]byte, ooblen), + ancil: make([]interface{}, 1), + intf: intf.Index, + addr: intf.HardwareAddr, + } + runtime.SetFinalizer(handle, (*EthernetHandle).Close) + return handle, nil +} diff --git a/vendor/github.com/google/gopacket/pcapgo/capture_test.go b/vendor/github.com/google/gopacket/pcapgo/capture_test.go new file mode 100644 index 0000000000..b15a2c0677 --- /dev/null +++ b/vendor/github.com/google/gopacket/pcapgo/capture_test.go @@ -0,0 +1,41 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. +// +build linux,go1.7 + +package pcapgo_test + +import ( + "log" + "os" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcapgo" +) + +func Example_captureEthernet() { + f, err := os.Create("/tmp/lo.pcap") + if err != nil { + log.Fatal(err) + } + defer f.Close() + pcapw := pcapgo.NewWriter(f) + if err := pcapw.WriteFileHeader(1600, layers.LinkTypeEthernet); err != nil { + log.Fatalf("WriteFileHeader: %v", err) + } + + handle, err := pcapgo.NewEthernetHandle("lo") + if err != nil { + log.Fatalf("OpenEthernet: %v", err) + } + + pkgsrc := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet) + for packet := range pkgsrc.Packets() { + if err := pcapw.WritePacket(packet.Metadata().CaptureInfo, packet.Data()); err != nil { + log.Fatalf("pcap.WritePacket(): %v", err) + } + } +} diff --git a/vendor/github.com/google/gopacket/pcapgo/doc.go b/vendor/github.com/google/gopacket/pcapgo/doc.go new file mode 100644 index 0000000000..f2e0b95774 --- /dev/null +++ b/vendor/github.com/google/gopacket/pcapgo/doc.go @@ -0,0 +1,63 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +/* +Package pcapgo provides some native PCAP support, not requiring C libpcap to be installed. + +Overview + +This package contains implementations for native PCAP support. Currently supported are + + * pcap-files read/write: Reader, Writer + * pcapng-files read/write: NgReader, NgWriter + * raw socket capture (linux only): EthernetHandle + +Basic Usage pcapng + +Pcapng files can be read and written. Reading supports both big and little endian files, packet blocks, +simple packet blocks, enhanced packets blocks, interface blocks, and interface statistics blocks. All +the options also by Wireshark are supported. The default reader options match libpcap behaviour. Have +a look at NgReaderOptions for more advanced usage. Both ReadPacketData and ZeroCopyReadPacketData is +supported (which means PacketDataSource and ZeroCopyPacketDataSource is supported). + + f, err := os.Open("somefile.pcapng") + if err != nil { + ... + } + defer f.Close() + + r, err := NewNgReader(f, DefaultNgReaderOptions) + if err != nil { + ... + } + + data, ci, err := r.ReadPacketData() + ... + +Write supports only little endian, enhanced packets blocks, interface blocks, and interface statistics +blocks. The same options as with writing are supported. Interface timestamp resolution is fixed to +10^-9s to match time.Time. Any other values are ignored. Upon creating a writer, a section, and an +interface block is automatically written. Additional interfaces can be added at any time. Since +the writer uses a bufio.Writer internally, Flush must be called before closing the file! Have a look +at NewNgWriterInterface for more advanced usage. + + f, err := os.Create("somefile.pcapng") + if err != nil { + ... + } + defer f.Close() + + r, err = NewNgWriter(f, layers.LinkTypeEthernet) + if err != nil { + ... + } + defer r.Flush() + + err = r.WritePacket(ci, data) + ... + +*/ +package pcapgo diff --git a/vendor/github.com/google/gopacket/pcapgo/ngread.go b/vendor/github.com/google/gopacket/pcapgo/ngread.go new file mode 100644 index 0000000000..16aabb9008 --- /dev/null +++ b/vendor/github.com/google/gopacket/pcapgo/ngread.go @@ -0,0 +1,606 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package pcapgo + +import ( + "bufio" + "encoding/binary" + "errors" + "fmt" + "io" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" +) + +// NgReaderOptions holds options for reading a pcapng file +type NgReaderOptions struct { + // WantMixedLinkType enables reading a pcapng file containing multiple interfaces with varying link types. If false all link types must match, which is the libpcap behaviour and LinkType returns the link type of the first interface. + // If true the link type of the packet is also exposed via ci.AncillaryData[0]. + WantMixedLinkType bool + // ErrorOnMismatchingLinkType enables returning an error if a packet with a link type not matching the first interface is encountered and WantMixedLinkType == false. + // If false packets those packets are just silently ignored, which is the libpcap behaviour. + ErrorOnMismatchingLinkType bool + // SkipUnknownVersion enables automatically skipping sections with an unknown version, which is recommended by the pcapng standard. Otherwise ErrVersionMismatch is returned. + SkipUnknownVersion bool + // SectionEndCallback gets called at the end of a section (execept for the last section, which is ends on EOF). The current list of interfaces and additional section information is provided. + // This is a good way to read interface statistics. + SectionEndCallback func([]NgInterface, NgSectionInfo) + // StatisticsCallback is called when a interface statistics block is read. The interface id and the read statistics are provided. + StatisticsCallback func(int, NgInterfaceStatistics) +} + +// DefaultNgReaderOptions provides sane defaults for a pcapng reader. +var DefaultNgReaderOptions = NgReaderOptions{} + +// NgReader wraps an underlying bufio.NgReader to read packet data in pcapng. +type NgReader struct { + r *bufio.Reader + options NgReaderOptions + sectionInfo NgSectionInfo + linkType layers.LinkType + ifaces []NgInterface + currentBlock ngBlock + currentOption ngOption + buf [24]byte + packetBuf []byte + ci gopacket.CaptureInfo + ancil [1]interface{} + blen int + firstSectionFound bool + activeSection bool + bigEndian bool +} + +// NewNgReader initializes a new writer, reads the first section header, and if necessary according to the options the first interface. +func NewNgReader(r io.Reader, options NgReaderOptions) (*NgReader, error) { + ret := &NgReader{ + r: bufio.NewReader(r), + currentOption: ngOption{ + value: make([]byte, 1024), + }, + options: options, + } + + //pcapng _must_ start with a section header + if err := ret.readBlock(); err != nil { + return nil, err + } + if ret.currentBlock.typ != ngBlockTypeSectionHeader { + return nil, fmt.Errorf("Unknown magic %x", ret.currentBlock.typ) + } + + if err := ret.readSectionHeader(); err != nil { + return nil, err + } + + return ret, nil +} + +// First a couple of helper functions to speed things up + +// This is way faster than calling io.ReadFull since io.ReadFull needs an itab lookup, does an additional function call into ReadAtLeast, and ReadAtLeast does additional stuff we don't need +// Additionally this removes the bounds check compared to io.ReadFull due to the use of uint +func (r *NgReader) readBytes(buffer []byte) error { + n := uint(0) + for n < uint(len(buffer)) { + nn, err := r.r.Read(buffer[n:]) + n += uint(nn) + if err != nil { + return err + } + } + return nil +} + +// The following functions make the binary.* functions inlineable (except for getUint64, which is too big, but not in any hot path anyway) +// Compared to storing binary.*Endian in a binary.ByteOrder this shaves off about 20% for (ZeroCopy)ReadPacketData, which is caused by the needed itab lookup + indirect go call +func (r *NgReader) getUint16(buffer []byte) uint16 { + if r.bigEndian { + return binary.BigEndian.Uint16(buffer) + } + return binary.LittleEndian.Uint16(buffer) +} + +func (r *NgReader) getUint32(buffer []byte) uint32 { + if r.bigEndian { + return binary.BigEndian.Uint32(buffer) + } + return binary.LittleEndian.Uint32(buffer) +} + +func (r *NgReader) getUint64(buffer []byte) uint64 { + if r.bigEndian { + return binary.BigEndian.Uint64(buffer) + } + return binary.LittleEndian.Uint64(buffer) +} + +// Now the pcapng implementation + +// readBlock reads a the blocktype and length from the file. If the type is a section header, endianess is also read. +func (r *NgReader) readBlock() error { + if err := r.readBytes(r.buf[0:8]); err != nil { + return err + } + r.currentBlock.typ = ngBlockType(r.getUint32(r.buf[0:4])) + // The next part is a bit fucked up since a section header could change the endianess... + // So first read then length just into a buffer, check if its a section header and then do the endianess part... + if r.currentBlock.typ == ngBlockTypeSectionHeader { + if err := r.readBytes(r.buf[8:12]); err != nil { + return err + } + if binary.BigEndian.Uint32(r.buf[8:12]) == ngByteOrderMagic { + r.bigEndian = true + } else if binary.LittleEndian.Uint32(r.buf[8:12]) == ngByteOrderMagic { + r.bigEndian = false + } else { + return errors.New("Wrong byte order value in Section Header") + } + // Set length to remaining length (length - (type + lengthfield = 8) - 4 for byteOrderMagic) + r.currentBlock.length = r.getUint32(r.buf[4:8]) - 8 - 4 + return nil + } + // Set length to remaining length (length - (type + lengthfield = 8) + r.currentBlock.length = r.getUint32(r.buf[4:8]) - 8 + return nil +} + +// readOption reads a single arbitrary option (type and value). If there is no space left for options and end of options is missing, it is faked. +func (r *NgReader) readOption() error { + if r.currentBlock.length == 4 { + // no more options + r.currentOption.code = ngOptionCodeEndOfOptions + return nil + } + if err := r.readBytes(r.buf[:4]); err != nil { + return err + } + r.currentBlock.length -= 4 + r.currentOption.code = ngOptionCode(r.getUint16(r.buf[:2])) + length := r.getUint16(r.buf[2:4]) + if r.currentOption.code == ngOptionCodeEndOfOptions { + if length != 0 { + return errors.New("End of Options must be zero length") + } + return nil + } + if length != 0 { + if length < uint16(cap(r.currentOption.value)) { + r.currentOption.value = r.currentOption.value[:length] + } else { + r.currentOption.value = make([]byte, length) + } + if err := r.readBytes(r.currentOption.value); err != nil { + return err + } + //consume padding + padding := length % 4 + if padding > 0 { + padding = 4 - padding + if _, err := r.r.Discard(int(padding)); err != nil { + return err + } + } + r.currentBlock.length -= uint32(length + padding) + } + return nil +} + +// readSectionHeader parses the full section header and implements section skipping in case of version mismatch +// if needed, the first interface is read +func (r *NgReader) readSectionHeader() error { + if r.options.SectionEndCallback != nil && r.activeSection { + interfaces := make([]NgInterface, len(r.ifaces)) + for i := range r.ifaces { + interfaces[i] = r.ifaces[i] + } + r.options.SectionEndCallback(interfaces, r.sectionInfo) + } + // clear the interfaces + r.ifaces = r.ifaces[:0] + r.activeSection = false + +RESTART: + // read major, minor, section length + if err := r.readBytes(r.buf[:12]); err != nil { + return err + } + r.currentBlock.length -= 12 + + vMajor := r.getUint16(r.buf[0:2]) + vMinor := r.getUint16(r.buf[2:4]) + if vMajor != ngVersionMajor || vMinor != ngVersionMinor { + if !r.options.SkipUnknownVersion { + // Well the standard actually says to skip unknown version section headers, + // but this would mean user would be kept in the dark about whats going on... + return ErrNgVersionMismatch + } + if _, err := r.r.Discard(int(r.currentBlock.length)); err != nil { + return err + } + if err := r.skipSection(); err != nil { + return err + } + goto RESTART + } + + var section NgSectionInfo + +OPTIONS: + for { + if err := r.readOption(); err != nil { + return err + } + switch r.currentOption.code { + case ngOptionCodeEndOfOptions: + break OPTIONS + case ngOptionCodeComment: + section.Comment = string(r.currentOption.value) + case ngOptionCodeHardware: + section.Hardware = string(r.currentOption.value) + case ngOptionCodeOS: + section.OS = string(r.currentOption.value) + case ngOptionCodeUserApplication: + section.Application = string(r.currentOption.value) + } + } + + if _, err := r.r.Discard(int(r.currentBlock.length)); err != nil { + return err + } + r.activeSection = true + r.sectionInfo = section + + if !r.options.WantMixedLinkType { + // If we don't want mixed link type, we need the first interface to fill Reader.LinkType() + // This handles most of the pcapngs out there, since they start with an IDB + if err := r.firstInterface(); err != nil { + return err + } + } + + return nil +} + +// skipSection skips blocks until the next section +func (r *NgReader) skipSection() error { + for { + if err := r.readBlock(); err != nil { + return err + } + if r.currentBlock.typ == ngBlockTypeSectionHeader { + return nil + } + if _, err := r.r.Discard(int(r.currentBlock.length)); err != nil { + return err + } + } +} + +// SkipSection skips the contents of the rest of the current section and reads the next section header. +func (r *NgReader) SkipSection() error { + if err := r.skipSection(); err != nil { + return err + } + return r.readSectionHeader() +} + +// firstInterface reads the first interface from the section and panics if a packet is encountered. +func (r *NgReader) firstInterface() error { + for { + if err := r.readBlock(); err != nil { + return err + } + switch r.currentBlock.typ { + case ngBlockTypeInterfaceDescriptor: + if err := r.readInterfaceDescriptor(); err != nil { + return err + } + if !r.firstSectionFound { + r.linkType = r.ifaces[0].LinkType + r.firstSectionFound = true + } else if r.linkType != r.ifaces[0].LinkType { + if r.options.ErrorOnMismatchingLinkType { + return ErrNgLinkTypeMismatch + } + continue + } + return nil + case ngBlockTypePacket, ngBlockTypeEnhancedPacket, ngBlockTypeSimplePacket, ngBlockTypeInterfaceStatistics: + return errors.New("A section must have an interface before a packet block") + } + if _, err := r.r.Discard(int(r.currentBlock.length)); err != nil { + return err + } + } +} + +// readInterfaceDescriptor parses an interface descriptor, prepares timing calculation, and adds the interface details to the current list +func (r *NgReader) readInterfaceDescriptor() error { + if err := r.readBytes(r.buf[:8]); err != nil { + return err + } + r.currentBlock.length -= 8 + var intf NgInterface + intf.LinkType = layers.LinkType(r.getUint16(r.buf[:2])) + intf.SnapLength = r.getUint32(r.buf[4:8]) + +OPTIONS: + for { + if err := r.readOption(); err != nil { + return err + } + switch r.currentOption.code { + case ngOptionCodeEndOfOptions: + break OPTIONS + case ngOptionCodeInterfaceName: + intf.Name = string(r.currentOption.value) + case ngOptionCodeComment: + intf.Comment = string(r.currentOption.value) + case ngOptionCodeInterfaceDescription: + intf.Description = string(r.currentOption.value) + case ngOptionCodeInterfaceFilter: + // ignore filter type (first byte) since it is not specified + intf.Filter = string(r.currentOption.value[1:]) + case ngOptionCodeInterfaceOS: + intf.OS = string(r.currentOption.value) + case ngOptionCodeInterfaceTimestampOffset: + intf.TimestampOffset = r.getUint64(r.currentOption.value[:8]) + case ngOptionCodeInterfaceTimestampResolution: + intf.TimestampResolution = NgResolution(r.currentOption.value[0]) + } + } + if _, err := r.r.Discard(int(r.currentBlock.length)); err != nil { + return err + } + if intf.TimestampResolution == 0 { + intf.TimestampResolution = 6 + } + + //parse options + if intf.TimestampResolution.Binary() { + //negative power of 2 + intf.secondMask = 1 << intf.TimestampResolution.Exponent() + } else { + //negative power of 10 + intf.secondMask = 1 + for j := uint8(0); j < intf.TimestampResolution.Exponent(); j++ { + intf.secondMask *= 10 + } + } + intf.scaleDown = 1 + intf.scaleUp = 1 + if intf.secondMask < 1e9 { + intf.scaleUp = 1e9 / intf.secondMask + } else { + intf.scaleDown = intf.secondMask / 1e9 + } + r.ifaces = append(r.ifaces, intf) + return nil +} + +// convertTime adds offset + shifts the given time value according to the given interface +func (r *NgReader) convertTime(ifaceID int, ts uint64) (int64, int64) { + iface := r.ifaces[ifaceID] + return int64(ts/iface.secondMask + iface.TimestampOffset), int64(ts % iface.secondMask * iface.scaleUp / iface.scaleDown) +} + +// readInterfaceStatistics updates the statistics of the given interface +func (r *NgReader) readInterfaceStatistics() error { + if err := r.readBytes(r.buf[:12]); err != nil { + return err + } + r.currentBlock.length -= 12 + ifaceID := int(r.getUint32(r.buf[:4])) + ts := uint64(r.getUint32(r.buf[4:8]))<<32 | uint64(r.getUint32(r.buf[8:12])) + if int(ifaceID) >= len(r.ifaces) { + return fmt.Errorf("Interface id %d not present in section (have only %d interfaces)", ifaceID, len(r.ifaces)) + } + stats := &r.ifaces[ifaceID].Statistics + *stats = ngEmptyStatistics + stats.LastUpdate = time.Unix(r.convertTime(ifaceID, ts)).UTC() + +OPTIONS: + for { + if err := r.readOption(); err != nil { + return err + } + switch r.currentOption.code { + case ngOptionCodeEndOfOptions: + break OPTIONS + case ngOptionCodeComment: + stats.Comment = string(r.currentOption.value) + case ngOptionCodeInterfaceStatisticsStartTime: + ts = uint64(r.getUint32(r.currentOption.value[:4]))<<32 | uint64(r.getUint32(r.currentOption.value[4:8])) + stats.StartTime = time.Unix(r.convertTime(ifaceID, ts)).UTC() + case ngOptionCodeInterfaceStatisticsEndTime: + ts = uint64(r.getUint32(r.currentOption.value[:4]))<<32 | uint64(r.getUint32(r.currentOption.value[4:8])) + stats.EndTime = time.Unix(r.convertTime(ifaceID, ts)).UTC() + case ngOptionCodeInterfaceStatisticsInterfaceReceived: + stats.PacketsReceived = r.getUint64(r.currentOption.value[:8]) + case ngOptionCodeInterfaceStatisticsInterfaceDropped: + stats.PacketsDropped = r.getUint64(r.currentOption.value[:8]) + } + } + if _, err := r.r.Discard(int(r.currentBlock.length)); err != nil { + return err + } + if r.options.StatisticsCallback != nil { + r.options.StatisticsCallback(ifaceID, *stats) + } + return nil +} + +// readPacketHeader looks for a packet (enhanced, simple, or packet) and parses the header. +// If an interface descriptor, an interface statistics block, or a section header is encountered, those are handled accordingly. +// All other block types are skipped. New block types must be added here. +func (r *NgReader) readPacketHeader() error { +RESTART: +FIND_PACKET: + for { + if err := r.readBlock(); err != nil { + return err + } + switch r.currentBlock.typ { + case ngBlockTypeEnhancedPacket: + if err := r.readBytes(r.buf[:20]); err != nil { + return err + } + r.currentBlock.length -= 20 + r.ci.InterfaceIndex = int(r.getUint32(r.buf[:4])) + if r.ci.InterfaceIndex >= len(r.ifaces) { + return fmt.Errorf("Interface id %d not present in section (have only %d interfaces)", r.ci.InterfaceIndex, len(r.ifaces)) + } + r.ci.Timestamp = time.Unix(r.convertTime(r.ci.InterfaceIndex, uint64(r.getUint32(r.buf[4:8]))<<32|uint64(r.getUint32(r.buf[8:12])))).UTC() + r.ci.CaptureLength = int(r.getUint32(r.buf[12:16])) + r.ci.Length = int(r.getUint32(r.buf[16:20])) + break FIND_PACKET + case ngBlockTypeSimplePacket: + if err := r.readBytes(r.buf[:4]); err != nil { + return err + } + r.currentBlock.length -= 4 + r.ci.Timestamp = time.Time{} + r.ci.InterfaceIndex = 0 + r.ci.Length = int(r.getUint32(r.buf[:4])) + r.ci.CaptureLength = r.ci.Length + if len(r.ifaces) == 0 { + return errors.New("At least one Interface is needed for a packet") + } + if r.ifaces[0].SnapLength != 0 && uint32(r.ci.CaptureLength) > r.ifaces[0].SnapLength { + r.ci.CaptureLength = int(r.ifaces[0].SnapLength) + } + break FIND_PACKET + case ngBlockTypeInterfaceDescriptor: + if err := r.readInterfaceDescriptor(); err != nil { + return err + } + case ngBlockTypeInterfaceStatistics: + if err := r.readInterfaceStatistics(); err != nil { + return err + } + case ngBlockTypeSectionHeader: + if err := r.readSectionHeader(); err != nil { + return err + } + case ngBlockTypePacket: + if err := r.readBytes(r.buf[:20]); err != nil { + return err + } + r.currentBlock.length -= 20 + r.ci.InterfaceIndex = int(r.getUint16(r.buf[0:2])) + if r.ci.InterfaceIndex >= len(r.ifaces) { + return fmt.Errorf("Interface id %d not present in section (have only %d interfaces)", r.ci.InterfaceIndex, len(r.ifaces)) + } + r.ci.Timestamp = time.Unix(r.convertTime(r.ci.InterfaceIndex, uint64(r.getUint32(r.buf[4:8]))<<32|uint64(r.getUint32(r.buf[8:12])))).UTC() + r.ci.CaptureLength = int(r.getUint32(r.buf[12:16])) + r.ci.Length = int(r.getUint32(r.buf[16:20])) + break FIND_PACKET + default: + if _, err := r.r.Discard(int(r.currentBlock.length)); err != nil { + return err + } + } + } + if !r.options.WantMixedLinkType { + if r.ifaces[r.ci.InterfaceIndex].LinkType != r.linkType { + if _, err := r.r.Discard(int(r.currentBlock.length)); err != nil { + return err + } + if r.options.ErrorOnMismatchingLinkType { + return ErrNgLinkTypeMismatch + } + goto RESTART + } + return nil + } + r.ancil[0] = r.ifaces[r.ci.InterfaceIndex].LinkType + return nil +} + +// ReadPacketData returns the next packet available from this data source. +// If WantMixedLinkType is true, ci.AncillaryData[0] contains the link type. +func (r *NgReader) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) { + if err = r.readPacketHeader(); err != nil { + return + } + ci = r.ci + if r.options.WantMixedLinkType { + ci.AncillaryData = make([]interface{}, 1) + ci.AncillaryData[0] = r.ancil[0] + } + data = make([]byte, r.ci.CaptureLength) + if err = r.readBytes(data); err != nil { + return + } + // handle options somehow - this would be expensive + _, err = r.r.Discard(int(r.currentBlock.length) - r.ci.CaptureLength) + return +} + +// ZeroCopyReadPacketData returns the next packet available from this data source. +// If WantMixedLinkType is true, ci.AncillaryData[0] contains the link type. +// Warning: Like data, ci.AncillaryData is also reused and overwritten on the next call to ZeroCopyReadPacketData. +// +// It is not true zero copy, as data is still copied from the underlying reader. However, +// this method avoids allocating heap memory for every packet. +func (r *NgReader) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) { + if err = r.readPacketHeader(); err != nil { + return + } + ci = r.ci + if r.options.WantMixedLinkType { + ci.AncillaryData = r.ancil[:] + } + if cap(r.packetBuf) < ci.CaptureLength { + snaplen := int(r.ifaces[ci.InterfaceIndex].SnapLength) + if snaplen < ci.CaptureLength { + snaplen = ci.CaptureLength + } + r.packetBuf = make([]byte, snaplen) + } + data = r.packetBuf[:ci.CaptureLength] + if err = r.readBytes(data); err != nil { + return + } + // handle options somehow - this would be expensive + _, err = r.r.Discard(int(r.currentBlock.length) - ci.CaptureLength) + return +} + +// LinkType returns the link type of the first interface, as a layers.LinkType. This is only valid, if WantMixedLinkType is false. +func (r *NgReader) LinkType() layers.LinkType { + return r.linkType +} + +// SectionInfo returns information about the current section. +func (r *NgReader) SectionInfo() NgSectionInfo { + return r.sectionInfo +} + +// Interface returns interface information and statistics of interface with the given id. +func (r *NgReader) Interface(i int) (NgInterface, error) { + if i >= len(r.ifaces) || i < 0 { + return NgInterface{}, fmt.Errorf("Interface %d invalid. There are only %d interfaces", i, len(r.ifaces)) + } + return r.ifaces[i], nil +} + +// NInterfaces returns the current number of interfaces. +func (r *NgReader) NInterfaces() int { + return len(r.ifaces) +} + +// Resolution returns the timestamp resolution of acquired timestamps before scaling to NanosecondTimestampResolution. +func (r *NgReader) Resolution() gopacket.TimestampResolution { + if r.options.WantMixedLinkType { + return gopacket.TimestampResolution{} + } + return r.ifaces[0].Resolution() +} diff --git a/vendor/github.com/google/gopacket/pcapgo/ngread_test.go b/vendor/github.com/google/gopacket/pcapgo/ngread_test.go new file mode 100644 index 0000000000..4674e37c65 --- /dev/null +++ b/vendor/github.com/google/gopacket/pcapgo/ngread_test.go @@ -0,0 +1,1922 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package pcapgo + +import ( + "bufio" + "bytes" + "encoding/hex" + "io" + "log" + "os" + "path/filepath" + "reflect" + "testing" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" +) + +func ngMustDecode(s string) []byte { + ret, err := hex.DecodeString(s) + if err != nil { + log.Panic("Initialization failed") + } + return ret +} + +var ngPacketSource = [...][]byte{ + ngMustDecode("ffffffffffff000b8201fc4208004500012ca8360000fa11178b00000000ffffffff004400430118591f0101060000003d1d0000000000000000000000000000000000000000000b8201fc4200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000638253633501013d0701000b8201fc4232040000000037040103062aff00000000000000"), + ngMustDecode("000b8201fc42000874adf19b0800450001480445000080110000c0a80001c0a8000a00430044013422330201060000003d1d0000000000000000c0a8000ac0a8000100000000000b8201fc4200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000638253633501020104ffffff003a04000007083b0400000c4e330400000e103604c0a80001ff0000000000000000000000000000000000000000000000000000"), + ngMustDecode("ffffffffffff000b8201fc4208004500012ca8370000fa11178a00000000ffffffff0044004301189fbd0101060000003d1e0000000000000000000000000000000000000000000b8201fc4200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000638253633501033d0701000b8201fc423204c0a8000a3604c0a8000137040103062aff00"), + ngMustDecode("000b8201fc42000874adf19b0800450001480446000080110000c0a80001c0a8000a004300440134dfdb0201060000003d1e0000000000000000c0a8000a0000000000000000000b8201fc4200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000638253633501053a04000007083b0400000c4e330400000e103604c0a800010104ffffff00ff0000000000000000000000000000000000000000000000000000"), + ngMustDecode("02000000450000a4c6ce00004011f147c0a8018bffffffff445c445c0090ba037b22686f73745f696e74223a20343039343531343438332c202276657273696f6e223a205b312c20385d2c2022646973706c61796e616d65223a2022222c2022706f7274223a2031373530302c20226e616d65737061636573223a205b32303532343235372c203633393533393037322c203633393533393333372c203633393533393535355d7d"), +} + +type ngFileReadTestPacket struct { + data []byte + ci gopacket.CaptureInfo + err error +} + +type ngFileReadTestSection struct { + sectionInfo NgSectionInfo + ifaces []NgInterface +} + +type ngFileReadTest struct { + testName string + testContents io.Reader + testType string + wantMixedLinkType bool + errorOnMismatchingLinkType bool + skipUnknownVersion bool + + linkType layers.LinkType + sections []ngFileReadTestSection + packets []ngFileReadTestPacket +} + +func ngRunFileReadTest(test ngFileReadTest, be string, zerocopy bool, t *testing.T) { + var err error + var f io.Reader + if test.testContents == nil { + testf, err := os.Open(filepath.Join("tests", be, test.testName+".pcapng")) + if err != nil { + t.Fatal("Couldn't open file:", err) + } + defer testf.Close() + f = testf + } else { + f = test.testContents + } + + var r *NgReader + + section := 0 + checkInterface := func(intf NgInterface, i int) { + currentInterface := test.sections[section].ifaces[i] + + // fix non-zero defaults + if currentInterface.TimestampResolution == 0 { + currentInterface.TimestampResolution = 6 + } + // clear private values + intf.scaleDown = 0 + intf.scaleUp = 0 + intf.secondMask = 0 + + if !reflect.DeepEqual(intf, currentInterface) { + t.Fatalf("[section %d] interface %d mismatches:\ngot:\n%#v\nwant:\n%#v\n\n", section, i, intf, currentInterface) + } + } + testSection := func(intf []NgInterface, sectionInfo NgSectionInfo) { + currentSection := test.sections[section] + + if !reflect.DeepEqual(sectionInfo, currentSection.sectionInfo) { + t.Fatalf("[section header %d] section info mismatch:\ngot:\n%#v\nwant:\n%#v\n\n", section, sectionInfo, currentSection.sectionInfo) + } + + if intf == nil { + if r.NInterfaces() != len(test.sections[section].ifaces) { + t.Fatalf("[section %d] Expected at least %d interfaces, but got only %d", section, len(test.sections[section].ifaces), r.NInterfaces()) + } + for i := 0; i < r.NInterfaces(); i++ { + in, err := r.Interface(i) + if err != nil { + t.Fatalf("Unexpected error querying interface %d", i) + } + checkInterface(in, i) + } + } else { + if len(intf) != len(test.sections[section].ifaces) { + t.Fatalf("[section %d] Expected at least %d interfaces, but got only %d", section, len(test.sections[section].ifaces), len(intf)) + } + for i, in := range intf { + checkInterface(in, i) + } + } + + section++ + } + + options := DefaultNgReaderOptions + options.ErrorOnMismatchingLinkType = test.errorOnMismatchingLinkType + options.WantMixedLinkType = test.wantMixedLinkType + options.SkipUnknownVersion = test.skipUnknownVersion + if len(test.sections) > 1 { + options.SectionEndCallback = testSection + } + + r, err = NewNgReader(f, options) + if err != nil { + t.Fatal("Couldn't read start of file:", err) + } + + if test.wantMixedLinkType { + if r.LinkType() != 0 { + t.Fatalf("[first interface (section %d)] LinkType should be 0 with WantMixedLinkType, but is %s", section, r.LinkType()) + } + } else { + if r.LinkType() != test.linkType { + t.Fatalf("[first interface (section %d)] LinkType mismatch: Should be %s but is %s", section, test.linkType, r.LinkType()) + } + } + + for i, packet := range test.packets { + var data []byte + var ci gopacket.CaptureInfo + var err error + + if zerocopy { + data, ci, err = r.ZeroCopyReadPacketData() + } else { + data, ci, err = r.ReadPacketData() + } + if err == io.EOF { + t.Fatalf("[packets] Expected %d packets, but got only %d", len(test.packets), i) + } + if err != nil { + if err != packet.err { + t.Fatalf("[packet %d] Expected error %s, but got %s", i, packet.err, err) + } + if err != ErrNgVersionMismatch { + testSection(nil, r.SectionInfo()) + } + return + } + + if bytes.Compare(data, packet.data) != 0 { + t.Log(data) + t.Log(packet.data) + t.Fatalf("[packet %d] data mismatch", i) + } + + if !reflect.DeepEqual(ci, packet.ci) { + t.Fatalf("[packet %d] ci mismatch:\ngot:\n%#v\nwant:\n%#v\n\n", i, ci, packet.ci) + } + } + + if zerocopy { + _, _, err = r.ZeroCopyReadPacketData() + } else { + _, _, err = r.ReadPacketData() + } + if err != io.EOF { + t.Fatalf("[packets] Expected only %d packet(s), but got at least one more!", len(test.packets)) + } + + testSection(nil, r.SectionInfo()) + + if section != len(test.sections) { + t.Fatalf("File should have %d sections, but has %d", len(test.sections), section) + } +} + +var tests = []ngFileReadTest{ + { + testName: "test001", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test001", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 0, + Name: "silly ethernet interface", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: len(ngPacketSource[0]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: len(ngPacketSource[1]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[2], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0).UTC(), + Length: len(ngPacketSource[2]), + CaptureLength: len(ngPacketSource[2]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[3], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0).UTC(), + Length: len(ngPacketSource[3]), + CaptureLength: len(ngPacketSource[3]), + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test002", + wantMixedLinkType: true, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test002", + }, + }, + }, + }, + { + testName: "test003", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test003", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "silly ethernet interface", + }, + }, + }, + }, + }, + { + testName: "test004", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test004", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth0", + }, + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 128, + Name: "en1", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1][:128], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: 128, + InterfaceIndex: 1, + }, + }, + { + data: ngPacketSource[2][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+2000*1000).UTC(), + Length: len(ngPacketSource[2]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[3][:128], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+3000*1000).UTC(), + Length: len(ngPacketSource[3]), + CaptureLength: 128, + InterfaceIndex: 1, + }, + }, + }, + }, + { + testName: "test005", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test005", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth0", + }, + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 128, + Name: "en1", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1][:128], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: 128, + InterfaceIndex: 1, + }, + }, + { + data: ngPacketSource[2][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+2000*1000).UTC(), + Length: len(ngPacketSource[2]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[3][:128], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+3000*1000).UTC(), + Length: len(ngPacketSource[3]), + CaptureLength: 128, + InterfaceIndex: 1, + }, + }, + }, + }, + { + testName: "test006", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test006", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth0", + }, + { + LinkType: layers.LinkTypeNull, + Name: "en1", + }, + }, + }, + }, + + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+2000*1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[2][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+3000*1000).UTC(), + Length: len(ngPacketSource[2]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[3][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+4000*1000).UTC(), + Length: len(ngPacketSource[3]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test006", + testType: "/ErrorOnMismatchingLink", + errorOnMismatchingLinkType: true, + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test006", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth0", + }, + { + LinkType: layers.LinkTypeNull, + Name: "en1", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + {err: ErrNgLinkTypeMismatch}, + }, + }, + { + testName: "test006", + testType: "/WantMixedLinkType", + wantMixedLinkType: true, + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test006", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth0", + }, + { + LinkType: layers.LinkTypeNull, + Name: "en1", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: 96, + InterfaceIndex: 0, + AncillaryData: []interface{}{layers.LinkTypeEthernet}, + }, + }, + { + data: ngPacketSource[4], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + Length: len(ngPacketSource[4]), + CaptureLength: len(ngPacketSource[4]), + InterfaceIndex: 1, + AncillaryData: []interface{}{layers.LinkTypeNull}, + }, + }, + { + data: ngPacketSource[1][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+2000*1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: 96, + InterfaceIndex: 0, + AncillaryData: []interface{}{layers.LinkTypeEthernet}, + }, + }, + { + data: ngPacketSource[2][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+3000*1000).UTC(), + Length: len(ngPacketSource[2]), + CaptureLength: 96, + InterfaceIndex: 0, + AncillaryData: []interface{}{layers.LinkTypeEthernet}, + }, + }, + { + data: ngPacketSource[3][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+4000*1000).UTC(), + Length: len(ngPacketSource[3]), + CaptureLength: 96, + InterfaceIndex: 0, + AncillaryData: []interface{}{layers.LinkTypeEthernet}, + }, + }, + }, + }, + { + testName: "test007", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test007", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth0", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test008", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test008", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth-_0 foo", + Comment: "test008, and more\nfoo\r\nbar", + Description: "silly ethernet interface", + Filter: "tcp port 23 and host 192.0.2.5", + OS: "Microsoft Windows for Workgroups 3.11b\npatch 42", + TimestampResolution: 9, + }, + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 128, + Name: "en1", + Comment: "test008", + Description: "silly ethernet interface 2", + Filter: "tcp port 23 and host 192.0.2.5", + OS: "Novell NetWare 4.11\nbut not using IPX", + TimestampResolution: 9, + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1][:128], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa+1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: 128, + InterfaceIndex: 1, + }, + }, + { + data: ngPacketSource[2][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa+2000).UTC(), + Length: len(ngPacketSource[2]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[3][:128], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa+3000).UTC(), + Length: len(ngPacketSource[3]), + CaptureLength: 128, + InterfaceIndex: 1, + }, + }, + }, + }, + { + testName: "test009", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test009", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 0, + Name: "eth0", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: len(ngPacketSource[0]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: len(ngPacketSource[1]), + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test010", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test010", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 0, + Name: "eth0", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[0]), + CaptureLength: len(ngPacketSource[0]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[1]), + CaptureLength: len(ngPacketSource[1]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[2], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[2]), + CaptureLength: len(ngPacketSource[2]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[3], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[3]), + CaptureLength: len(ngPacketSource[3]), + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test011", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test011", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 0, + Name: "eth0", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[0]), + CaptureLength: len(ngPacketSource[0]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: len(ngPacketSource[1]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[2], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[2]), + CaptureLength: len(ngPacketSource[2]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[3], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+1000*2000).UTC(), + Length: len(ngPacketSource[3]), + CaptureLength: len(ngPacketSource[3]), + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test012", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test012", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 315, + Name: "eth0", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[0]), + CaptureLength: len(ngPacketSource[0]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1][:315], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[1]), + CaptureLength: 315, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[2], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0).UTC(), + Length: len(ngPacketSource[2]), + CaptureLength: len(ngPacketSource[2]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[3][:315], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0).UTC(), + Length: len(ngPacketSource[3]), + CaptureLength: 315, + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test013", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test013", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "silly ethernet interface", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0).UTC(), + StartTime: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + EndTime: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + PacketsDropped: 10, + PacketsReceived: NgNoValue64, + }, + }, + }, + }, + }, + }, + { + testName: "test014", + wantMixedLinkType: true, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test014", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth0", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + StartTime: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + EndTime: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + PacketsDropped: 10, + PacketsReceived: NgNoValue64, + }, + }, + { + LinkType: layers.LinkTypeNull, + SnapLength: 0, + Name: "null1", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + StartTime: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + EndTime: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + PacketsDropped: 10, + PacketsReceived: NgNoValue64, + }, + }, + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 128, + Name: "silly ethernet interface 2", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + StartTime: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + EndTime: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + PacketsDropped: 10, + PacketsReceived: NgNoValue64, + Comment: "test014 ISB", + }, + }, + }, + }, + }, + }, + { + testName: "test015", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test015", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "silly ethernet interface", + Comment: "test015 IDB", + }, + }, + }, + }, + }, + { + testName: "test016", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test016", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 0, + Name: "eth0", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[0]), + CaptureLength: len(ngPacketSource[0]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: len(ngPacketSource[1]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[2], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[2]), + CaptureLength: len(ngPacketSource[2]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[3], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+1000*2000).UTC(), + Length: len(ngPacketSource[3]), + CaptureLength: len(ngPacketSource[3]), + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test017", + wantMixedLinkType: true, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test017", + }, + }, + }, + }, + { + testName: "test018", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test018", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 0, + Name: "eth0", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[0]), + CaptureLength: len(ngPacketSource[0]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: len(ngPacketSource[1]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[2], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[2]), + CaptureLength: len(ngPacketSource[2]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[3], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+1000*2000).UTC(), + Length: len(ngPacketSource[3]), + CaptureLength: len(ngPacketSource[3]), + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test100", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test100", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 0, + Name: "eth0", + }, + { + LinkType: layers.LinkTypeNull, + SnapLength: 0, + Name: "null1", + }, + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 128, + Name: "wifi2?", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[0]), + CaptureLength: len(ngPacketSource[0]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: len(ngPacketSource[1]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[2], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[2]), + CaptureLength: len(ngPacketSource[2]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[3], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+1000*2000).UTC(), + Length: len(ngPacketSource[3]), + CaptureLength: len(ngPacketSource[3]), + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test101", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test101", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth0", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0).UTC(), + PacketsDropped: NgNoValue64, + PacketsReceived: NgNoValue64, + }, + }, + { + LinkType: layers.LinkTypeNull, + SnapLength: 0, + Name: "null1", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0x4c39764ca47aa*1000-1000*1000).UTC(), + PacketsDropped: NgNoValue64, + PacketsReceived: NgNoValue64, + }, + }, + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 128, + Name: "silly ethernet interface 2", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + StartTime: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + EndTime: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + PacketsDropped: 10, + PacketsReceived: NgNoValue64, + Comment: "test101 ISB-2", + }, + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1][:128], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: 128, + InterfaceIndex: 2, + }, + }, + { + data: ngPacketSource[2][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[2]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test102", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test102", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth0", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0).UTC(), + PacketsDropped: NgNoValue64, + PacketsReceived: NgNoValue64, + }, + }, + { + LinkType: layers.LinkTypeNull, + SnapLength: 0, + Name: "null1", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0x4c39764ca47aa*1000-1000*1000).UTC(), + PacketsDropped: NgNoValue64, + PacketsReceived: NgNoValue64, + }, + }, + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 0, + Name: "silly!\r\nethernet interface 2", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + StartTime: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + EndTime: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + PacketsDropped: 10, + PacketsReceived: NgNoValue64, + Comment: "test102 ISB-2", + }, + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: len(ngPacketSource[1]), + InterfaceIndex: 2, + }, + }, + { + data: ngPacketSource[2][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[2]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[3][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000+2000*1000).UTC(), + Length: len(ngPacketSource[3]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test200", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test200", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth0", + }, + }, + }, + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test200", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 0, + Name: "eth0", + }, + }, + }, + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test200", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeNull, + SnapLength: 128, + Name: "null1", + }, + }, + }, + }, + }, + { + testName: "test201", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test201 SHB-0", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth0", + }, + { + LinkType: layers.LinkTypeNull, + SnapLength: 0, + Name: "null1", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + PacketsDropped: NgNoValue64, + PacketsReceived: NgNoValue64, + }, + }, + }, + }, + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test201 SHB-1", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 128, + Name: "silly ethernet interface 2", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + StartTime: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + EndTime: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + PacketsDropped: 10, + PacketsReceived: NgNoValue64, + Comment: "test201 ISB-2", + }, + }, + }, + }, + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test201 SHB-2", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth0", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0).UTC(), + PacketsDropped: NgNoValue64, + PacketsReceived: NgNoValue64, + }, + }, + { + LinkType: layers.LinkTypeNull, + SnapLength: 0, + Name: "null1", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1][:128], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: 128, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[2][:128], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[2]), + CaptureLength: 128, + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test202", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test202 SHB-0", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth0", + }, + { + LinkType: layers.LinkTypeNull, + SnapLength: 0, + Name: "null1", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + PacketsDropped: NgNoValue64, + PacketsReceived: NgNoValue64, + }, + }, + }, + }, + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test202 SHB-1", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 128, + Name: "silly ethernet interface 2", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + StartTime: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + EndTime: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + PacketsDropped: 10, + PacketsReceived: NgNoValue64, + Comment: "test202 ISB-2", + }, + }, + }, + }, + { + sectionInfo: NgSectionInfo{ + Hardware: "Apple MBP", + OS: "OS-X 10.10.5", + Application: "pcap_writer.lua", + Comment: "test202 SHB-2", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 96, + Name: "eth0", + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(0, 0).UTC(), + StartTime: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + EndTime: time.Unix(0, 0x4c39764ca47aa*1000+1000*1000).UTC(), + PacketsReceived: 100, + PacketsDropped: 1, + Comment: "test202 ISB-0", + }, + }, + { + LinkType: layers.LinkTypeNull, + SnapLength: 0, + Name: "null1", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[0][:128], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[0]), + CaptureLength: 128, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[1][:128], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: 128, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[2][:128], + ci: gopacket.CaptureInfo{ + Timestamp: time.Time{}, + Length: len(ngPacketSource[2]), + CaptureLength: 128, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[3][:128], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[3]), + CaptureLength: 128, + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test901", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "my computer", + OS: "linux", + Application: "pcap_writer.lua", + Comment: "test901 SHB-0", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 0, + Name: "eth0", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: len(ngPacketSource[0]), + InterfaceIndex: 0, + }, + }, + {err: ErrNgVersionMismatch}, + }, + }, + { + testName: "test901", + skipUnknownVersion: true, + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "my computer", + OS: "linux", + Application: "pcap_writer.lua", + Comment: "test901 SHB-0", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 0, + Name: "eth0", + }, + }, + }, + { + sectionInfo: NgSectionInfo{ + Hardware: "my computer", + OS: "linux", + Application: "pcap_writer.lua", + Comment: "test901 SHB-2", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 0, + Name: "eth0", + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: len(ngPacketSource[0]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[2], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0x4c39764ca47aa*1000).UTC(), + Length: len(ngPacketSource[2]), + CaptureLength: len(ngPacketSource[2]), + InterfaceIndex: 0, + }, + }, + }, + }, + { + testName: "test902", + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Hardware: "my computer", + OS: "linux", + Application: "pcap_writer.lua", + Comment: "test902", + }, + ifaces: []NgInterface{ + { + LinkType: layers.LinkTypeEthernet, + SnapLength: 0, + Name: "eth0", + TimestampResolution: 0x88, + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(1519128000, 195312500).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: len(ngPacketSource[0]), + InterfaceIndex: 0, + }, + }, + }, + }, +} + +func TestNgFileReadBE(t *testing.T) { + for _, test := range tests { + ngRunFileReadTest(test, "be", false, t) + } +} + +func TestNgFileReadLE(t *testing.T) { + for _, test := range tests { + ngRunFileReadTest(test, "le", false, t) + } +} + +func TestNgFileReadBEZero(t *testing.T) { + for _, test := range tests { + ngRunFileReadTest(test, "be", true, t) + } +} + +func TestNgFileReadLEZero(t *testing.T) { + for _, test := range tests { + ngRunFileReadTest(test, "le", true, t) + } +} + +type endlessNgPacketReader struct { + packet []byte +} + +func (e endlessNgPacketReader) Read(p []byte) (n int, err error) { + n = copy(p, e.packet) + return +} + +func setupNgReadBenchmark(b *testing.B) *NgReader { + header := bytes.NewBuffer([]byte{ + 0x0A, 0x0D, 0x0D, 0x0A, // Section Header + 0, 0, 0, 28, // block total length + 0x1A, 0x2B, 0x3C, 0x4D, // BOM + 0, 1, 0, 0, //Version + 0, 0, 0, 0, //Section length + 0, 0, 0, 0, //Section length + 0, 0, 0, 28, //block total length + + 0, 0, 0, 1, // IDB + 0, 0, 0, 20, // block total length + 0, 1, 0, 0, // Ethernet + 0, 0, 0, 0, // Snap length + 0, 0, 0, 20, // block total length + }) + + packet := endlessNgPacketReader{ + []byte{ + 0, 0, 0, 6, // EPB + 0, 0, 0, 48, // block total length + 0, 0, 0, 0, // interface ID + 0, 0, 0, 0, // time (high) + 0, 0, 0, 0, // time (low) + 0, 0, 0, 16, // capture packet length + 0, 0, 0, 16, // original packet length + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16, + 0, 0, 0, 48, // block total length + 0, 0, 0, 6, // EPB + 0, 0, 0, 40, // block total length + 0, 0, 0, 0, // interface ID + 0, 0, 0, 0, // time (high) + 0, 0, 0, 0, // time (low) + 0, 0, 0, 8, // capture packet length + 0, 0, 0, 8, // original packet length + 8, 7, 6, 5, + 4, 3, 2, 1, + 0, 0, 0, 40, // block total length + }, + } + packetReader := bufio.NewReaderSize(packet, len(packet.packet)) + + r, err := NewNgReader(header, DefaultNgReaderOptions) + + if err != nil { + b.Fatal("Couldn't read header + IDB:", err) + } + r.r = packetReader + return r +} + +func BenchmarkNgReadPacketData(b *testing.B) { + r := setupNgReadBenchmark(b) + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _, _ = r.ReadPacketData() + } +} + +func BenchmarkNgZeroCopyReadPacketData(b *testing.B) { + r := setupNgReadBenchmark(b) + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _, _ = r.ZeroCopyReadPacketData() + } +} diff --git a/vendor/github.com/google/gopacket/pcapgo/ngwrite.go b/vendor/github.com/google/gopacket/pcapgo/ngwrite.go new file mode 100644 index 0000000000..d0787c5697 --- /dev/null +++ b/vendor/github.com/google/gopacket/pcapgo/ngwrite.go @@ -0,0 +1,397 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package pcapgo + +import ( + "bufio" + "encoding/binary" + "fmt" + "io" + "runtime" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" +) + +// NgWriterOptions holds options for creating a pcapng file +type NgWriterOptions struct { + // SectionInfo will be written to the section header + SectionInfo NgSectionInfo +} + +// DefaultNgWriterOptions contain defaults for a pcapng writer used by NewWriter +var DefaultNgWriterOptions = NgWriterOptions{ + SectionInfo: NgSectionInfo{ + Hardware: runtime.GOARCH, + OS: runtime.GOOS, + Application: "gopacket", //spread the word + }, +} + +// DefaultNgInterface contains default interface options used by NewWriter +var DefaultNgInterface = NgInterface{ + Name: "intf0", + OS: runtime.GOOS, + SnapLength: 0, //unlimited + TimestampResolution: 9, +} + +// NgWriter holds the internal state of a pcapng file writer. Internally a bufio.NgWriter is used, therefore Flush must be called before closing the underlying file. +type NgWriter struct { + w *bufio.Writer + options NgWriterOptions + intf uint32 + buf [28]byte +} + +// NewNgWriter initializes and returns a new writer. Additionally, one section and one interface (without statistics) is written to the file. Interface and section options are used from DefaultNgInterface and DefaultNgWriterOptions. +// Flush must be called before the file is closed, or if eventual unwritten information should be written out to the storage device. +// +// Written files are in little endian format. Interface timestamp resolution is fixed to 9 (to match time.Time). +func NewNgWriter(w io.Writer, linkType layers.LinkType) (*NgWriter, error) { + intf := DefaultNgInterface + intf.LinkType = linkType + return NewNgWriterInterface(w, intf, DefaultNgWriterOptions) +} + +// NewNgWriterInterface initializes and returns a new writer. Additionally, one section and one interface (without statistics) is written to the file. +// Flush must be called before the file is closed, or if eventual unwritten information should be written out to the storage device. +// +// Written files are in little endian format. Interface timestamp resolution is fixed to 9 (to match time.Time). +func NewNgWriterInterface(w io.Writer, intf NgInterface, options NgWriterOptions) (*NgWriter, error) { + ret := &NgWriter{ + w: bufio.NewWriter(w), + options: options, + } + if err := ret.writeSectionHeader(); err != nil { + return nil, err + } + + if _, err := ret.AddInterface(intf); err != nil { + return nil, err + } + return ret, nil +} + +// ngOptionLength returns the needed length for one option value (without padding) +func ngOptionLength(option ngOption) int { + switch val := option.raw.(type) { + case []byte: + return len(val) + case string: + return len(val) + case time.Time: + return 8 + case uint64: + return 8 + case uint32: + return 4 + case uint8: + return 1 + default: + panic("This should never happen") + } +} + +// prepareNgOptions fills out the length value of the given options and returns the number of octets needed for all the given options including padding. +func prepareNgOptions(options []ngOption) uint32 { + var ret uint32 + for i, option := range options { + length := ngOptionLength(option) + options[i].length = uint16(length) + length += (4-length&3)&3 + // padding + 4 //header + ret += uint32(length) + } + if ret > 0 { + ret += 4 // end of options + } + return ret +} + +// writeOptions writes the given options to the file. prepareOptions must be called beforehand. +func (w *NgWriter) writeOptions(options []ngOption) error { + if len(options) == 0 { + return nil + } + + var zero [4]byte + for _, option := range options { + binary.LittleEndian.PutUint16(w.buf[0:2], uint16(option.code)) + binary.LittleEndian.PutUint16(w.buf[2:4], option.length) + if _, err := w.w.Write(w.buf[:4]); err != nil { + return err + } + switch val := option.raw.(type) { + case []byte: + if _, err := w.w.Write(val); err != nil { + return err + } + padding := uint8((4 - option.length&3) & 3) + if padding < 4 { + if _, err := w.w.Write(zero[:padding]); err != nil { + return err + } + } + case string: + if _, err := w.w.Write([]byte(val)); err != nil { + return err + } + padding := uint8((4 - option.length&3) & 3) + if padding < 4 { + if _, err := w.w.Write(zero[:padding]); err != nil { + return err + } + } + case time.Time: + ts := val.UnixNano() + binary.LittleEndian.PutUint32(w.buf[:4], uint32(ts>>32)) + binary.LittleEndian.PutUint32(w.buf[4:8], uint32(ts)) + if _, err := w.w.Write(w.buf[:8]); err != nil { + return err + } + case uint64: + binary.LittleEndian.PutUint64(w.buf[:8], val) + if _, err := w.w.Write(w.buf[:8]); err != nil { + return err + } + case uint32: + binary.LittleEndian.PutUint32(w.buf[:4], val) + if _, err := w.w.Write(w.buf[:4]); err != nil { + return err + } + case uint8: + binary.LittleEndian.PutUint32(w.buf[:4], 0) // padding + w.buf[0] = val + if _, err := w.w.Write(w.buf[:4]); err != nil { + return err + } + default: + panic("This should never happen") + } + } + + // options must be folled by an end of options option + binary.LittleEndian.PutUint16(w.buf[0:2], uint16(ngOptionCodeEndOfOptions)) + binary.LittleEndian.PutUint16(w.buf[2:4], 0) + _, err := w.w.Write(w.buf[:4]) + return err +} + +// writeSectionHeader writes a section header to the file +func (w *NgWriter) writeSectionHeader() error { + var scratch [4]ngOption + i := 0 + info := w.options.SectionInfo + if info.Application != "" { + scratch[i].code = ngOptionCodeUserApplication + scratch[i].raw = info.Application + i++ + } + if info.Comment != "" { + scratch[i].code = ngOptionCodeComment + scratch[i].raw = info.Comment + i++ + } + if info.Hardware != "" { + scratch[i].code = ngOptionCodeHardware + scratch[i].raw = info.Hardware + i++ + } + if info.OS != "" { + scratch[i].code = ngOptionCodeOS + scratch[i].raw = info.OS + i++ + } + options := scratch[:i] + + length := prepareNgOptions(options) + + 24 + // header + 4 // trailer + + binary.LittleEndian.PutUint32(w.buf[:4], uint32(ngBlockTypeSectionHeader)) + binary.LittleEndian.PutUint32(w.buf[4:8], length) + binary.LittleEndian.PutUint32(w.buf[8:12], ngByteOrderMagic) + binary.LittleEndian.PutUint16(w.buf[12:14], ngVersionMajor) + binary.LittleEndian.PutUint16(w.buf[14:16], ngVersionMinor) + binary.LittleEndian.PutUint64(w.buf[16:24], 0xFFFFFFFFFFFFFFFF) // unspecified + if _, err := w.w.Write(w.buf[:24]); err != nil { + return err + } + + if err := w.writeOptions(options); err != nil { + return err + } + + binary.LittleEndian.PutUint32(w.buf[0:4], length) + _, err := w.w.Write(w.buf[:4]) + return err +} + +// AddInterface adds the specified interface to the file, excluding statistics. Interface timestamp resolution is fixed to 9 (to match time.Time). Empty values are not written. +func (w *NgWriter) AddInterface(intf NgInterface) (id int, err error) { + id = int(w.intf) + w.intf++ + + var scratch [7]ngOption + i := 0 + if intf.Name != "" { + scratch[i].code = ngOptionCodeInterfaceName + scratch[i].raw = intf.Name + i++ + } + if intf.Comment != "" { + scratch[i].code = ngOptionCodeComment + scratch[i].raw = intf.Comment + i++ + } + if intf.Description != "" { + scratch[i].code = ngOptionCodeInterfaceDescription + scratch[i].raw = intf.Description + i++ + } + if intf.Filter != "" { + scratch[i].code = ngOptionCodeInterfaceFilter + scratch[i].raw = append([]byte{0}, []byte(intf.Filter)...) + i++ + } + if intf.OS != "" { + scratch[i].code = ngOptionCodeInterfaceOS + scratch[i].raw = intf.OS + i++ + } + if intf.TimestampOffset != 0 { + scratch[i].code = ngOptionCodeInterfaceTimestampOffset + scratch[i].raw = intf.TimestampOffset + i++ + } + scratch[i].code = ngOptionCodeInterfaceTimestampResolution + scratch[i].raw = uint8(9) // fix resolution to nanoseconds (time.Time) in decimal + i++ + options := scratch[:i] + + length := prepareNgOptions(options) + + 16 + // header + 4 // trailer + + binary.LittleEndian.PutUint32(w.buf[:4], uint32(ngBlockTypeInterfaceDescriptor)) + binary.LittleEndian.PutUint32(w.buf[4:8], length) + binary.LittleEndian.PutUint16(w.buf[8:10], uint16(intf.LinkType)) + binary.LittleEndian.PutUint16(w.buf[10:12], 0) // reserved value + binary.LittleEndian.PutUint32(w.buf[12:16], intf.SnapLength) + if _, err := w.w.Write(w.buf[:16]); err != nil { + return 0, err + } + + if err := w.writeOptions(options); err != nil { + return 0, err + } + + binary.LittleEndian.PutUint32(w.buf[0:4], length) + _, err = w.w.Write(w.buf[:4]) + return id, err +} + +// WriteInterfaceStats writes the given interface statistics for the given interface id to the file. Empty values are not written. +func (w *NgWriter) WriteInterfaceStats(intf int, stats NgInterfaceStatistics) error { + if intf >= int(w.intf) || intf < 0 { + return fmt.Errorf("Can't send statistics for non existent interface %d; have only %d interfaces", intf, w.intf) + } + + var scratch [4]ngOption + i := 0 + if !stats.StartTime.IsZero() { + scratch[i].code = ngOptionCodeInterfaceStatisticsStartTime + scratch[i].raw = stats.StartTime + i++ + } + if !stats.EndTime.IsZero() { + scratch[i].code = ngOptionCodeInterfaceStatisticsEndTime + scratch[i].raw = stats.EndTime + i++ + } + if stats.PacketsDropped != NgNoValue64 { + scratch[i].code = ngOptionCodeInterfaceStatisticsInterfaceDropped + scratch[i].raw = stats.PacketsDropped + i++ + } + if stats.PacketsReceived != NgNoValue64 { + scratch[i].code = ngOptionCodeInterfaceStatisticsInterfaceReceived + scratch[i].raw = stats.PacketsReceived + i++ + } + options := scratch[:i] + + length := prepareNgOptions(options) + 24 + + ts := stats.LastUpdate.UnixNano() + if stats.LastUpdate.IsZero() { + ts = 0 + } + + binary.LittleEndian.PutUint32(w.buf[:4], uint32(ngBlockTypeInterfaceStatistics)) + binary.LittleEndian.PutUint32(w.buf[4:8], length) + binary.LittleEndian.PutUint32(w.buf[8:12], uint32(intf)) + binary.LittleEndian.PutUint32(w.buf[12:16], uint32(ts>>32)) + binary.LittleEndian.PutUint32(w.buf[16:20], uint32(ts)) + if _, err := w.w.Write(w.buf[:20]); err != nil { + return err + } + + if err := w.writeOptions(options); err != nil { + return err + } + + binary.LittleEndian.PutUint32(w.buf[0:4], length) + _, err := w.w.Write(w.buf[:4]) + return err +} + +// WritePacket writes out packet with the given data and capture info. The given InterfaceIndex must already be added to the file. InterfaceIndex 0 is automatically added by the NewWriter* methods. +func (w *NgWriter) WritePacket(ci gopacket.CaptureInfo, data []byte) error { + if ci.InterfaceIndex >= int(w.intf) || ci.InterfaceIndex < 0 { + return fmt.Errorf("Can't send statistics for non existent interface %d; have only %d interfaces", ci.InterfaceIndex, w.intf) + } + if ci.CaptureLength != len(data) { + return fmt.Errorf("capture length %d does not match data length %d", ci.CaptureLength, len(data)) + } + if ci.CaptureLength > ci.Length { + return fmt.Errorf("invalid capture info %+v: capture length > length", ci) + } + + length := uint32(len(data)) + 32 + padding := (4 - length&3) & 3 + length += padding + + ts := ci.Timestamp.UnixNano() + + binary.LittleEndian.PutUint32(w.buf[:4], uint32(ngBlockTypeEnhancedPacket)) + binary.LittleEndian.PutUint32(w.buf[4:8], length) + binary.LittleEndian.PutUint32(w.buf[8:12], uint32(ci.InterfaceIndex)) + binary.LittleEndian.PutUint32(w.buf[12:16], uint32(ts>>32)) + binary.LittleEndian.PutUint32(w.buf[16:20], uint32(ts)) + binary.LittleEndian.PutUint32(w.buf[20:24], uint32(ci.CaptureLength)) + binary.LittleEndian.PutUint32(w.buf[24:28], uint32(ci.Length)) + + if _, err := w.w.Write(w.buf[:28]); err != nil { + return err + } + + if _, err := w.w.Write(data); err != nil { + return err + } + + binary.LittleEndian.PutUint32(w.buf[:4], 0) + _, err := w.w.Write(w.buf[4-padding : 8]) // padding + length + return err +} + +// Flush writes out buffered data to the storage media. Must be called before closing the underlying file. +func (w *NgWriter) Flush() error { + return w.w.Flush() +} diff --git a/vendor/github.com/google/gopacket/pcapgo/ngwrite_test.go b/vendor/github.com/google/gopacket/pcapgo/ngwrite_test.go new file mode 100644 index 0000000000..8041c1e25b --- /dev/null +++ b/vendor/github.com/google/gopacket/pcapgo/ngwrite_test.go @@ -0,0 +1,239 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package pcapgo + +import ( + "bytes" + "testing" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" +) + +func TestNgWriteSimple(t *testing.T) { + buffer := &bytes.Buffer{} + + w, err := NewNgWriter(buffer, layers.LinkTypeEthernet) + if err != nil { + t.Fatal("Opening file failed with: ", err) + } + ci := gopacket.CaptureInfo{ + Timestamp: time.Unix(0, 0).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: len(ngPacketSource[0]), + InterfaceIndex: 0, + } + err = w.WritePacket(ci, ngPacketSource[0]) + if err != nil { + t.Fatal("Couldn't write packet", err) + } + err = w.Flush() + if err != nil { + t.Fatal("Couldn't flush buffer", err) + } + + interf := DefaultNgInterface + interf.LinkType = layers.LinkTypeEthernet + + test := ngFileReadTest{ + testContents: bytes.NewReader(buffer.Bytes()), + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: DefaultNgWriterOptions.SectionInfo, + ifaces: []NgInterface{ + interf, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0], + ci: ci, + }, + }, + } + + ngRunFileReadTest(test, "", false, t) +} + +func TestNgWriteComplex(t *testing.T) { + test := ngFileReadTest{ + linkType: layers.LinkTypeEthernet, + sections: []ngFileReadTestSection{ + { + sectionInfo: NgSectionInfo{ + Comment: "A test", + }, + ifaces: []NgInterface{ + { + Name: "in0", + Comment: "test0", + Description: "some test interface", + LinkType: layers.LinkTypeEthernet, + TimestampResolution: 3, + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(1519128000, 195312500).UTC(), + StartTime: time.Unix(1519128000-100, 195312500).UTC(), + EndTime: time.Unix(1519128000, 195312500).UTC(), + PacketsReceived: 100, + PacketsDropped: 1, + }, + }, + { + Name: "null0", + Description: "some test interface", + Filter: "none", + OS: "not needed", + LinkType: layers.LinkTypeEthernet, + TimestampOffset: 100, + Statistics: NgInterfaceStatistics{ + LastUpdate: time.Unix(1519128000, 195312500).UTC(), + }, + }, + }, + }, + }, + packets: []ngFileReadTestPacket{ + { + data: ngPacketSource[0], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(1519128000-900, 195312500).UTC(), + Length: len(ngPacketSource[0]), + CaptureLength: len(ngPacketSource[0]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[4], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(1519128000-800, 195312500).UTC(), + Length: len(ngPacketSource[4]), + CaptureLength: len(ngPacketSource[4]), + InterfaceIndex: 1, + }, + }, + { + data: ngPacketSource[1], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(1519128000-500, 195312500).UTC(), + Length: len(ngPacketSource[1]), + CaptureLength: len(ngPacketSource[1]), + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[2][:96], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(1519128000-300, 195312500).UTC(), + Length: len(ngPacketSource[2]), + CaptureLength: 96, + InterfaceIndex: 0, + }, + }, + { + data: ngPacketSource[3], + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(1519128000-200, 195312500).UTC(), + Length: len(ngPacketSource[3]), + CaptureLength: len(ngPacketSource[3]), + InterfaceIndex: 0, + }, + }, + }, + } + + buffer := &bytes.Buffer{} + + options := NgWriterOptions{ + SectionInfo: test.sections[0].sectionInfo, + } + + w, err := NewNgWriterInterface(buffer, test.sections[0].ifaces[0], options) + if err != nil { + t.Fatal("Opening file failed with: ", err) + } + + packets := test.packets + err = w.WritePacket(packets[0].ci, packets[0].data) + if err != nil { + t.Fatal("Couldn't write packet", err) + } + id, err := w.AddInterface(test.sections[0].ifaces[1]) + if err != nil { + t.Fatal("Couldn't add interface", err) + } + if id != 1 { + t.Fatalf("Expected interface id 1, but got %d", id) + } + err = w.WritePacket(packets[1].ci, packets[1].data) + if err != nil { + t.Fatal("Couldn't write packet", err) + } + err = w.WriteInterfaceStats(1, test.sections[0].ifaces[1].Statistics) + if err != nil { + t.Fatal("Couldn't write interface stats", err) + } + err = w.WritePacket(packets[2].ci, packets[2].data) + if err != nil { + t.Fatal("Couldn't write packet", err) + } + err = w.WritePacket(packets[3].ci, packets[3].data) + if err != nil { + t.Fatal("Couldn't write packet", err) + } + err = w.WritePacket(packets[4].ci, packets[4].data) + if err != nil { + t.Fatal("Couldn't write packet", err) + } + err = w.WriteInterfaceStats(0, test.sections[0].ifaces[0].Statistics) + if err != nil { + t.Fatal("Couldn't write interface stats", err) + } + + err = w.Flush() + if err != nil { + t.Fatal("Couldn't flush buffer", err) + } + + // writer fixes resolution to 9 + test.sections[0].ifaces[0].TimestampResolution = 9 + test.sections[0].ifaces[1].TimestampResolution = 9 + + // compensate for offset on interface 1 + test.sections[0].ifaces[1].Statistics.LastUpdate = test.sections[0].ifaces[1].Statistics.LastUpdate.Add(100 * time.Second) + test.packets[1].ci.Timestamp = test.packets[1].ci.Timestamp.Add(100 * time.Second) + + test.testContents = bytes.NewReader(buffer.Bytes()) + + ngRunFileReadTest(test, "", false, t) +} + +type ngDevNull struct{} + +func (w *ngDevNull) Write(p []byte) (n int, err error) { + return len(p), nil +} + +func BenchmarkNgWritePacket(b *testing.B) { + ci := gopacket.CaptureInfo{ + Timestamp: time.Unix(0x01020304, 0xAA*1000), + Length: 0xABCD, + CaptureLength: 10, + } + data := []byte{9, 8, 7, 6, 5, 4, 3, 2, 1, 0} + w, err := NewNgWriter(&ngDevNull{}, layers.LinkTypeEthernet) + if err != nil { + b.Fatal("Failed creating writer:", err) + } + b.ResetTimer() + + for i := 0; i < b.N; i++ { + w.WritePacket(ci, data) + } +} diff --git a/vendor/github.com/google/gopacket/pcapgo/pcapng.go b/vendor/github.com/google/gopacket/pcapgo/pcapng.go new file mode 100644 index 0000000000..2382e199b2 --- /dev/null +++ b/vendor/github.com/google/gopacket/pcapgo/pcapng.go @@ -0,0 +1,187 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package pcapgo + +import ( + "errors" + "math" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" +) + +// ErrNgVersionMismatch gets returned for unknown pcapng section versions. This can only happen if ReaderOptions.SkipUnknownVersion == false +var ErrNgVersionMismatch = errors.New("Unknown pcapng Version in Section Header") + +// ErrNgLinkTypeMismatch gets returned if the link type of an interface is not the same as the link type from the first interface. This can only happen if ReaderOptions.ErrorOnMismatchingLinkType == true && ReaderOptions.WantMixedLinkType == false +var ErrNgLinkTypeMismatch = errors.New("Link type of current interface is different from first one") + +const ( + ngByteOrderMagic = 0x1A2B3C4D + + // We can handle only version 1.0 + ngVersionMajor = 1 + ngVersionMinor = 0 +) + +type ngBlockType uint32 + +const ( + ngBlockTypeInterfaceDescriptor ngBlockType = 1 // Interface description block + ngBlockTypePacket ngBlockType = 2 // Packet block (deprecated) + ngBlockTypeSimplePacket ngBlockType = 3 // Simple packet block + ngBlockTypeInterfaceStatistics ngBlockType = 5 // Interface statistics block + ngBlockTypeEnhancedPacket ngBlockType = 6 // Enhanced packet block + ngBlockTypeSectionHeader ngBlockType = 0x0A0D0D0A // Section header block (same in both endians) +) + +type ngOptionCode uint16 + +const ( + ngOptionCodeEndOfOptions ngOptionCode = iota // end of options. must be at the end of options in a block + ngOptionCodeComment // comment + ngOptionCodeHardware // description of the hardware + ngOptionCodeOS // name of the operating system + ngOptionCodeUserApplication // name of the application +) + +const ( + ngOptionCodeInterfaceName ngOptionCode = iota + 2 // interface name + ngOptionCodeInterfaceDescription // interface description + ngOptionCodeInterfaceIPV4Address // IPv4 network address and netmask for the interface + ngOptionCodeInterfaceIPV6Address // IPv6 network address and prefix length for the interface + ngOptionCodeInterfaceMACAddress // interface hardware MAC address + ngOptionCodeInterfaceEUIAddress // interface hardware EUI address + ngOptionCodeInterfaceSpeed // interface speed in bits/s + ngOptionCodeInterfaceTimestampResolution // timestamp resolution + ngOptionCodeInterfaceTimezone // time zone + ngOptionCodeInterfaceFilter // capture filter + ngOptionCodeInterfaceOS // operating system + ngOptionCodeInterfaceFCSLength // length of the Frame Check Sequence in bits + ngOptionCodeInterfaceTimestampOffset // offset (in seconds) that must be added to packet timestamp +) + +const ( + ngOptionCodeInterfaceStatisticsStartTime ngOptionCode = iota + 2 // Start of capture + ngOptionCodeInterfaceStatisticsEndTime // End of capture + ngOptionCodeInterfaceStatisticsInterfaceReceived // Packets received by physical interface + ngOptionCodeInterfaceStatisticsInterfaceDropped // Packets dropped by physical interface + ngOptionCodeInterfaceStatisticsFilterAccept // Packets accepted by filter + ngOptionCodeInterfaceStatisticsOSDrop // Packets dropped by operating system + ngOptionCodeInterfaceStatisticsDelivered // Packets delivered to user +) + +// ngOption is a pcapng option +type ngOption struct { + code ngOptionCode + value []byte + raw interface{} + length uint16 +} + +// ngBlock is a pcapng block header +type ngBlock struct { + typ ngBlockType + length uint32 // remaining length of block +} + +// NgResolution represents a pcapng timestamp resolution +type NgResolution uint8 + +// Binary returns true if the timestamp resolution is a negative power of two. Otherwise NgResolution is a negative power of 10. +func (r NgResolution) Binary() bool { + if r&0x80 == 0x80 { + return true + } + return false +} + +// Exponent returns the negative exponent of the resolution. +func (r NgResolution) Exponent() uint8 { + return uint8(r) & 0x7f +} + +// ToTimestampResolution converts an NgResolution to a gopaket.TimestampResolution +func (r NgResolution) ToTimestampResolution() (ret gopacket.TimestampResolution) { + if r.Binary() { + ret.Base = 2 + } else { + ret.Base = 10 + } + ret.Exponent = -int(r.Exponent()) + return +} + +// NgNoValue64 is a placeholder for an empty numeric 64 bit value. +const NgNoValue64 = math.MaxUint64 + +// NgInterfaceStatistics hold the statistic for an interface at a single point in time. These values are already supposed to be accumulated. Most pcapng files contain this information at the end of the file/section. +type NgInterfaceStatistics struct { + // LastUpdate is the last time the statistics were updated. + LastUpdate time.Time + // StartTime is the time packet capture started on this interface. This value might be zero if this option is missing. + StartTime time.Time + // EndTime is the time packet capture ended on this interface This value might be zero if this option is missing. + EndTime time.Time + // Comment can be an arbitrary comment. This value might be empty if this option is missing. + Comment string + // PacketsReceived are the number of received packets. This value might be NoValue64 if this option is missing. + PacketsReceived uint64 + // PacketsReceived are the number of received packets. This value might be NoValue64 if this option is missing. + PacketsDropped uint64 +} + +var ngEmptyStatistics = NgInterfaceStatistics{ + PacketsReceived: NgNoValue64, + PacketsDropped: NgNoValue64, +} + +// NgInterface holds all the information of a pcapng interface. +type NgInterface struct { + // Name is the name of the interface. This value might be empty if this option is missing. + Name string + // Comment can be an arbitrary comment. This value might be empty if this option is missing. + Comment string + // Description is a description of the interface. This value might be empty if this option is missing. + Description string + // Filter is the filter used during packet capture. This value might be empty if this option is missing. + Filter string + // OS is the operating system this interface was controlled by. This value might be empty if this option is missing. + OS string + // LinkType is the linktype of the interface. + LinkType layers.LinkType + // TimestampResolution is the timestamp resolution of the packets in the pcapng file belonging to this interface. + TimestampResolution NgResolution + // TimestampResolution is the timestamp offset in seconds of the packets in the pcapng file belonging to this interface. + TimestampOffset uint64 + // SnapLength is the maximum packet length captured by this interface. 0 for unlimited + SnapLength uint32 + // Statistics holds the interface statistics + Statistics NgInterfaceStatistics + + secondMask uint64 + scaleUp uint64 + scaleDown uint64 +} + +// Resolution returns the timestamp resolution of acquired timestamps before scaling to NanosecondTimestampResolution. +func (i NgInterface) Resolution() gopacket.TimestampResolution { + return i.TimestampResolution.ToTimestampResolution() +} + +// NgSectionInfo contains additional information of a pcapng section +type NgSectionInfo struct { + // Hardware is the hardware this file was generated on. This value might be empty if this option is missing. + Hardware string + // OS is the operating system this file was generated on. This value might be empty if this option is missing. + OS string + // Application is the user space application this file was generated with. This value might be empty if this option is missing. + Application string + // Comment can be an arbitrary comment. This value might be empty if this option is missing. + Comment string +} diff --git a/vendor/github.com/google/gopacket/pcapgo/read.go b/vendor/github.com/google/gopacket/pcapgo/read.go index 5acd06f3b8..6ea1643a63 100644 --- a/vendor/github.com/google/gopacket/pcapgo/read.go +++ b/vendor/github.com/google/gopacket/pcapgo/read.go @@ -15,6 +15,7 @@ import ( "bufio" "compress/gzip" + "github.com/google/gopacket" "github.com/google/gopacket/layers" ) @@ -40,6 +41,8 @@ type Reader struct { linkType layers.LinkType // reusable buffer buf [16]byte + // buffer for ZeroCopyReadPacketData + packetBuf []byte } const magicNanoseconds = 0xA1B23C4D @@ -121,7 +124,11 @@ func (r *Reader) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err err return } if ci.CaptureLength > int(r.snaplen) { - err = fmt.Errorf("capture length exceeds snap length: %d > %d", 16+ci.CaptureLength, r.snaplen) + err = fmt.Errorf("capture length exceeds snap length: %d > %d", ci.CaptureLength, r.snaplen) + return + } + if ci.CaptureLength > ci.Length { + err = fmt.Errorf("capture length exceeds original packet length: %d > %d", ci.CaptureLength, ci.Length) return } data = make([]byte, ci.CaptureLength) @@ -129,6 +136,36 @@ func (r *Reader) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err err return data, ci, err } +// ZeroCopyReadPacketData reads next packet from file. The data buffer is owned by the Reader, +// and each call to ZeroCopyReadPacketData invalidates data returned by the previous one. +// +// It is not true zero copy, as data is still copied from the underlying reader. However, +// this method avoids allocating heap memory for every packet. +func (r *Reader) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) { + if ci, err = r.readPacketHeader(); err != nil { + return + } + if ci.CaptureLength > int(r.snaplen) { + err = fmt.Errorf("capture length exceeds snap length: %d > %d", ci.CaptureLength, r.snaplen) + return + } + if ci.CaptureLength > ci.Length { + err = fmt.Errorf("capture length exceeds original packet length: %d > %d", ci.CaptureLength, ci.Length) + return + } + + if cap(r.packetBuf) < ci.CaptureLength { + snaplen := int(r.snaplen) + if snaplen < ci.CaptureLength { + snaplen = ci.CaptureLength + } + r.packetBuf = make([]byte, snaplen) + } + data = r.packetBuf[:ci.CaptureLength] + _, err = io.ReadFull(r.r, data) + return data, ci, err +} + func (r *Reader) readPacketHeader() (ci gopacket.CaptureInfo, err error) { if _, err = io.ReadFull(r.r, r.buf[:]); err != nil { return @@ -149,7 +186,46 @@ func (r *Reader) Snaplen() uint32 { return r.snaplen } +// SetSnaplen sets the snapshot length of the capture file. +// +// This is useful when a pcap file contains packets bigger than then snaplen. +// Pcapgo will error when reading packets bigger than snaplen, then it dumps those +// packets and reads the next 16 bytes, which are part of the "faulty" packet's payload, but pcapgo +// thinks it's the next header, which is probably also faulty because it's not really a packet header. +// This can lead to a lot of faulty reads. +// +// The SetSnaplen function can be used to set a bigger snaplen to prevent those read errors. +// +// This snaplen situation can happen when a pcap writer doesn't truncate packets to the snaplen size while writing packets to file. +// E.g. In Python, dpkt.pcap.Writer sets snaplen by default to 1500 (https://dpkt.readthedocs.io/en/latest/api/api_auto.html#dpkt.pcap.Writer) +// but doesn't enforce this when writing packets (https://dpkt.readthedocs.io/en/latest/_modules/dpkt/pcap.html#Writer.writepkt). +// When reading, tools like tcpdump, tcpslice, mergecap and wireshark ignore the snaplen and use +// their own defined snaplen. +// E.g. When reading packets, tcpdump defines MAXIMUM_SNAPLEN (https://github.com/the-tcpdump-group/tcpdump/blob/6e80fcdbe9c41366df3fa244ffe4ac8cce2ab597/netdissect.h#L290) +// and uses it (https://github.com/the-tcpdump-group/tcpdump/blob/66384fa15b04b47ad08c063d4728df3b9c1c0677/print.c#L343-L358). +// +// For further reading: +// - https://github.com/the-tcpdump-group/tcpdump/issues/389 +// - https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8808 +// - https://www.wireshark.org/lists/wireshark-dev/201307/msg00061.html +// - https://github.com/wireshark/wireshark/blob/bfd51199e707c1d5c28732be34b44a9ee8a91cd8/wiretap/pcap-common.c#L723-L742 +// - https://github.com/wireshark/wireshark/blob/f07fb6cdfc0904905627707b88450054e921f092/wiretap/libpcap.c#L592-L598 +// - https://github.com/wireshark/wireshark/blob/f07fb6cdfc0904905627707b88450054e921f092/wiretap/libpcap.c#L714-L727 +// - https://github.com/the-tcpdump-group/tcpdump/commit/d033c1bc381c76d13e4aface97a4f4ec8c3beca2 +// - https://github.com/the-tcpdump-group/tcpdump/blob/88e87cb2cb74c5f939792171379acd9e0efd8b9a/netdissect.h#L263-L290 +func (r *Reader) SetSnaplen(newSnaplen uint32) { + r.snaplen = newSnaplen +} + // Reader formater func (r *Reader) String() string { return fmt.Sprintf("PcapFile maj: %x min: %x snaplen: %d linktype: %s", r.versionMajor, r.versionMinor, r.snaplen, r.linkType) } + +// Resolution returns the timestamp resolution of acquired timestamps before scaling to NanosecondTimestampResolution. +func (r *Reader) Resolution() gopacket.TimestampResolution { + if r.nanoSecsFactor == 1 { + return gopacket.TimestampResolutionMicrosecond + } + return gopacket.TimestampResolutionNanosecond +} diff --git a/vendor/github.com/google/gopacket/pcapgo/read_test.go b/vendor/github.com/google/gopacket/pcapgo/read_test.go index 87bf7abc25..bdd153e227 100644 --- a/vendor/github.com/google/gopacket/pcapgo/read_test.go +++ b/vendor/github.com/google/gopacket/pcapgo/read_test.go @@ -201,3 +201,41 @@ func TestPacketBufferReuse(t *testing.T) { t.Errorf("buf mismatch:\nwant: %+v\ngot: %+v", want, data2) } } + +func TestPacketZeroCopy(t *testing.T) { + test := []byte{ + 0xd4, 0xc3, 0xb2, 0xa1, 0x02, 0x00, 0x04, 0x00, // magic, maj, min + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // tz, sigfigs + 0xff, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // snaplen, linkType + 0x5A, 0xCC, 0x1A, 0x54, 0x01, 0x00, 0x00, 0x00, // sec, usec + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, // cap len, full len + 0x01, 0x02, 0x03, 0x04, // data + 0x5A, 0xCC, 0x1A, 0x54, 0x01, 0x00, 0x00, 0x00, // sec, usec + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, // cap len, full len + 0x05, 0x06, 0x07, 0x08, // data + } + + buf := bytes.NewBuffer(test) + r, err := NewReader(buf) + + data1, _, err := r.ZeroCopyReadPacketData() + if err != nil { + t.Error(err) + t.FailNow() + } + if want := []byte{1, 2, 3, 4}; !bytes.Equal(data1, want) { + t.Errorf("buf mismatch:\nwant: %+v\ngot: %+v", want, data1) + } + data2, _, err := r.ZeroCopyReadPacketData() + if err != nil { + t.Error(err) + t.FailNow() + } + if want := []byte{5, 6, 7, 8}; !bytes.Equal(data2, want) { + t.Errorf("buf mismatch:\nwant: %+v\ngot: %+v", want, data2) + } + + if &data1[0] != &data2[0] { + t.Error("different buffers returned by subsequent ZeroCopyReadPacketData calls") + } +} diff --git a/vendor/github.com/google/gopacket/pcapgo/write.go b/vendor/github.com/google/gopacket/pcapgo/write.go index bfc312fd5a..46a5f39957 100644 --- a/vendor/github.com/google/gopacket/pcapgo/write.go +++ b/vendor/github.com/google/gopacket/pcapgo/write.go @@ -4,8 +4,6 @@ // that can be found in the LICENSE file in the root of the source // tree. -// Package pcapgo provides some native PCAP support, not requiring -// C libpcap to be installed. package pcapgo import ( @@ -26,6 +24,9 @@ import ( // timestamp resolution and little-endian encoding. type Writer struct { w io.Writer + + // Moving this into the struct seems to save an allocation for each call to writePacketHeader + buf [16]byte } const magicMicroseconds = 0xA1B2C3D4 @@ -71,19 +72,17 @@ func (w *Writer) WriteFileHeader(snaplen uint32, linktype layers.LinkType) error const nanosPerMicro = 1000 func (w *Writer) writePacketHeader(ci gopacket.CaptureInfo) error { - var buf [16]byte - t := ci.Timestamp if t.IsZero() { t = time.Now() } secs := t.Unix() usecs := t.Nanosecond() / nanosPerMicro - binary.LittleEndian.PutUint32(buf[0:4], uint32(secs)) - binary.LittleEndian.PutUint32(buf[4:8], uint32(usecs)) - binary.LittleEndian.PutUint32(buf[8:12], uint32(ci.CaptureLength)) - binary.LittleEndian.PutUint32(buf[12:16], uint32(ci.Length)) - _, err := w.w.Write(buf[:]) + binary.LittleEndian.PutUint32(w.buf[0:4], uint32(secs)) + binary.LittleEndian.PutUint32(w.buf[4:8], uint32(usecs)) + binary.LittleEndian.PutUint32(w.buf[8:12], uint32(ci.CaptureLength)) + binary.LittleEndian.PutUint32(w.buf[12:16], uint32(ci.Length)) + _, err := w.w.Write(w.buf[:]) return err } diff --git a/vendor/github.com/google/gopacket/pcapgo/write_test.go b/vendor/github.com/google/gopacket/pcapgo/write_test.go index 5b87d6a5aa..fa81fc82a9 100644 --- a/vendor/github.com/google/gopacket/pcapgo/write_test.go +++ b/vendor/github.com/google/gopacket/pcapgo/write_test.go @@ -8,9 +8,10 @@ package pcapgo import ( "bytes" - "github.com/google/gopacket" "testing" "time" + + "github.com/google/gopacket" ) func TestWriteHeader(t *testing.T) { @@ -47,6 +48,23 @@ func TestWritePacket(t *testing.T) { } } +func BenchmarkWritePacket(b *testing.B) { + b.StopTimer() + ci := gopacket.CaptureInfo{ + Timestamp: time.Unix(0x01020304, 0xAA*1000), + Length: 0xABCD, + CaptureLength: 10, + } + data := []byte{9, 8, 7, 6, 5, 4, 3, 2, 1, 0} + var buf bytes.Buffer + w := NewWriter(&buf) + b.StartTimer() + + for i := 0; i < b.N; i++ { + w.WritePacket(ci, data) + } +} + func TestCaptureInfoErrors(t *testing.T) { data := []byte{1, 2, 3, 4} ts := time.Unix(0, 0) diff --git a/vendor/github.com/google/gopacket/pfring/pfring.go b/vendor/github.com/google/gopacket/pfring/pfring.go index 1d2fa68605..b9b8fb0abf 100644 --- a/vendor/github.com/google/gopacket/pfring/pfring.go +++ b/vendor/github.com/google/gopacket/pfring/pfring.go @@ -8,22 +8,42 @@ package pfring /* +// lpcap is needed for bpf #cgo LDFLAGS: -lpfring -lpcap #include #include +#include #include +struct metadata { + u_int64_t timestamp_ns; + u_int32_t caplen; + u_int32_t len; + int32_t if_index; +}; + +// In pfring 7.2 pfring_pkthdr struct was changed to packed +// Since this is incompatible with go, copy the values we need to a custom +// struct (struct metadata above). +// Another way to do this, would be to store the struct offsets in defines +// and use encoding/binary in go-land. But this has the downside, that there is +// no native endianess in encoding/binary and storing ByteOrder in a variable +// leads to an expensive itab lookup + call (instead of very fast inlined and +// optimized movs). Using unsafe magic could lead to problems with unaligned +// access. +// Additionally, this does the same uintptr-dance as pcap. int pfring_readpacketdatato_wrapper( pfring* ring, - u_char* buffer, - u_int buffer_len, - struct pfring_pkthdr* hdr) { - // We can't pass a Go pointer to a Go pointer which means we can't pass - // buffer as a uchar**, like pfring_recv wants, for ReadPacketDataTo. So, - // this wrapper does the pointer conversion in C code. Since this isn't - // zero-copy, it turns out that the pointer-to-pointer part of things isn't - // actually used anyway. - return pfring_recv(ring, &buffer, buffer_len, hdr, 1); + uintptr_t buffer, + uintptr_t meta) { + struct metadata* ci = (struct metadata* )meta; + struct pfring_pkthdr hdr; + int ret = pfring_recv(ring, (u_char**)buffer, 0, &hdr, 1); + ci->timestamp_ns = hdr.extended_hdr.timestamp_ns; + ci->caplen = hdr.caplen; + ci->len = hdr.len; + ci->if_index = hdr.extended_hdr.if_index; + return ret; } */ import "C" @@ -36,6 +56,7 @@ import ( "fmt" "net" "os" + "reflect" "strconv" "sync" "time" @@ -48,17 +69,12 @@ const errorBufferSize = 256 // Ring provides a handle to a pf_ring. type Ring struct { - // cptr is the handle for the actual pcap C object. cptr *C.pfring - snaplen int useExtendedPacketHeader bool interfaceIndex int mu sync.Mutex - // Since pointers to these objects are passed into a C function, if - // they're declared locally then the Go compiler thinks they may have - // escaped into C-land, so it allocates them on the heap. This causes a - // huge memory hit, so to handle that we store them here instead. - pkthdr C.struct_pfring_pkthdr + + meta C.struct_metadata bufPtr *C.u_char } @@ -86,7 +102,7 @@ func NewRing(device string, snaplen uint32, flags Flag) (ring *Ring, _ error) { if cptr == nil || err != nil { return nil, fmt.Errorf("pfring NewRing error: %v", err) } - ring = &Ring{cptr: cptr, snaplen: int(snaplen)} + ring = &Ring{cptr: cptr} if flags&FlagLongHeader == FlagLongHeader { ring.useExtendedPacketHeader = true @@ -132,45 +148,77 @@ func (n NextResult) Error() string { return strconv.Itoa(int(n)) } -// ReadPacketDataTo reads packet data into a user-supplied buffer. -// This function ignores snaplen and instead reads up to the length of the -// passed-in slice. -// The number of bytes read into data will be returned in ci.CaptureLength. -func (r *Ring) ReadPacketDataTo(data []byte) (ci gopacket.CaptureInfo, err error) { - // This tricky bufPtr points to the start of our slice data, so pfring_recv - // will actually write directly into our Go slice. Nice! - r.mu.Lock() - r.bufPtr = (*C.u_char)(unsafe.Pointer(&data[0])) - result := NextResult(C.pfring_readpacketdatato_wrapper(r.cptr, r.bufPtr, C.u_int(len(data)), &r.pkthdr)) +// shared code (Read-functions), that fetches a packet + metadata from pf_ring +func (r *Ring) getNextBufPtrLocked(ci *gopacket.CaptureInfo) error { + result := NextResult(C.pfring_readpacketdatato_wrapper(r.cptr, C.uintptr_t(uintptr(unsafe.Pointer(&r.bufPtr))), C.uintptr_t(uintptr(unsafe.Pointer(&r.meta))))) if result != NextOk { - err = result - r.mu.Unlock() - return + return result } - ci.Timestamp = time.Unix(int64(r.pkthdr.ts.tv_sec), - int64(r.pkthdr.ts.tv_usec)*1000) // convert micros to nanos - ci.CaptureLength = int(r.pkthdr.caplen) - ci.Length = int(r.pkthdr.len) + ci.Timestamp = time.Unix(0, int64(r.meta.timestamp_ns)) + ci.CaptureLength = int(r.meta.caplen) + ci.Length = int(r.meta.len) if r.useExtendedPacketHeader { - ci.InterfaceIndex = int(r.pkthdr.extended_hdr.if_index) + ci.InterfaceIndex = int(r.meta.if_index) } else { ci.InterfaceIndex = r.interfaceIndex } + return nil +} + +// ReadPacketDataTo reads packet data into a user-supplied buffer. +// +// Deprecated: This function is provided for legacy code only. Use ReadPacketData or ZeroCopyReadPacketData +// This function does an additional copy, and is therefore slower than ZeroCopyReadPacketData. +// The old implementation did the same inside the pf_ring library. +func (r *Ring) ReadPacketDataTo(data []byte) (ci gopacket.CaptureInfo, err error) { + r.mu.Lock() + err = r.getNextBufPtrLocked(&ci) + if err == nil { + var buf []byte + slice := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) + slice.Data = uintptr(unsafe.Pointer(r.bufPtr)) + slice.Len = ci.CaptureLength + slice.Cap = ci.CaptureLength + copy(data, buf) + } r.mu.Unlock() return } -// ReadPacketData returns the next packet read from the pcap handle, along with an error -// code associated with that packet. If the packet is read successfully, the +// ReadPacketData returns the next packet read from pf_ring, along with an error +// code associated with that packet. If the packet is read successfully, the // returned error is nil. func (r *Ring) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) { - data = make([]byte, r.snaplen) - ci, err = r.ReadPacketDataTo(data) - if err != nil { - data = nil - return + r.mu.Lock() + err = r.getNextBufPtrLocked(&ci) + if err == nil { + data = C.GoBytes(unsafe.Pointer(r.bufPtr), C.int(ci.CaptureLength)) + } + r.mu.Unlock() + return +} + +// ZeroCopyReadPacketData returns the next packet read from pf_ring, along with an error +// code associated with that packet. +// The slice returned by ZeroCopyReadPacketData points to bytes inside a pf_ring +// ring. Each call to ZeroCopyReadPacketData might invalidate any data previously +// returned by ZeroCopyReadPacketData. Care must be taken not to keep pointers +// to old bytes when using ZeroCopyReadPacketData... if you need to keep data past +// the next time you call ZeroCopyReadPacketData, use ReadPacketData, which copies +// the bytes into a new buffer for you. +// data1, _, _ := handle.ZeroCopyReadPacketData() +// // do everything you want with data1 here, copying bytes out of it if you'd like to keep them around. +// data2, _, _ := handle.ZeroCopyReadPacketData() // invalidates bytes in data1 +func (r *Ring) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) { + r.mu.Lock() + err = r.getNextBufPtrLocked(&ci) + if err == nil { + slice := (*reflect.SliceHeader)(unsafe.Pointer(&data)) + slice.Data = uintptr(unsafe.Pointer(r.bufPtr)) + slice.Len = ci.CaptureLength + slice.Cap = ci.CaptureLength } - data = data[:ci.CaptureLength] + r.mu.Unlock() return } @@ -223,6 +271,27 @@ func (r *Ring) SetSamplingRate(rate int) error { return nil } +// SetPollWatermark sets the pfring's poll watermark packet count +func (r *Ring) SetPollWatermark(count uint16) error { + if rv := C.pfring_set_poll_watermark(r.cptr, C.u_int16_t(count)); rv != 0 { + return fmt.Errorf("Unable to set poll watermark, got error code %d", rv) + } + return nil +} + +// SetPriority sets the pfring poll threads CPU usage limit +func (r *Ring) SetPriority(cpu uint16) { + C.pfring_config(C.u_short(cpu)) +} + +// SetPollDuration sets the pfring's poll duration before it yields/returns +func (r *Ring) SetPollDuration(durationMillis uint) error { + if rv := C.pfring_set_poll_duration(r.cptr, C.u_int(durationMillis)); rv != 0 { + return fmt.Errorf("Unable to set poll duration, got error code %d", rv) + } + return nil +} + // SetBPFFilter sets the BPF filter for the ring. func (r *Ring) SetBPFFilter(bpfFilter string) error { filter := C.CString(bpfFilter) diff --git a/vendor/github.com/google/gopacket/pfring/pfring_test.go b/vendor/github.com/google/gopacket/pfring/pfring_test.go new file mode 100644 index 0000000000..e772788143 --- /dev/null +++ b/vendor/github.com/google/gopacket/pfring/pfring_test.go @@ -0,0 +1,70 @@ +// Copyright 2019 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package pfring + +import ( + "flag" + "log" + "testing" +) + +var iface = flag.String("i", "eth0", "Interface to read packets from") + +func BenchmarkPfringRead(b *testing.B) { + var ring *Ring + var err error + if ring, err = NewRing(*iface, 65536, FlagPromisc); err != nil { + log.Fatalln("pfring ring creation error:", err) + } + if err = ring.SetSocketMode(ReadOnly); err != nil { + log.Fatalln("pfring SetSocketMode error:", err) + } else if err = ring.Enable(); err != nil { + log.Fatalln("pfring Enable error:", err) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, ci, _ := ring.ReadPacketData() + b.SetBytes(int64(ci.CaptureLength)) + } +} + +func BenchmarkPfringReadZero(b *testing.B) { + var ring *Ring + var err error + if ring, err = NewRing(*iface, 65536, FlagPromisc); err != nil { + log.Fatalln("pfring ring creation error:", err) + } + if err = ring.SetSocketMode(ReadOnly); err != nil { + log.Fatalln("pfring SetSocketMode error:", err) + } else if err = ring.Enable(); err != nil { + log.Fatalln("pfring Enable error:", err) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, ci, _ := ring.ZeroCopyReadPacketData() + b.SetBytes(int64(ci.CaptureLength)) + } +} + +func BenchmarkPfringReadTo(b *testing.B) { + var ring *Ring + var err error + if ring, err = NewRing(*iface, 65536, FlagPromisc); err != nil { + log.Fatalln("pfring ring creation error:", err) + } + if err = ring.SetSocketMode(ReadOnly); err != nil { + log.Fatalln("pfring SetSocketMode error:", err) + } else if err = ring.Enable(); err != nil { + log.Fatalln("pfring Enable error:", err) + } + buffer := make([]byte, 65536*2) + b.ResetTimer() + for i := 0; i < b.N; i++ { + ci, _ := ring.ReadPacketDataTo(buffer) + b.SetBytes(int64(ci.CaptureLength)) + } +} diff --git a/vendor/github.com/google/gopacket/reassembly/tcpassembly.go b/vendor/github.com/google/gopacket/reassembly/tcpassembly.go index bdf0deb721..f22785a9da 100644 --- a/vendor/github.com/google/gopacket/reassembly/tcpassembly.go +++ b/vendor/github.com/google/gopacket/reassembly/tcpassembly.go @@ -157,12 +157,16 @@ func (rl *reassemblyObject) KeepFrom(offset int) { func (rl *reassemblyObject) CaptureInfo(offset int) gopacket.CaptureInfo { current := 0 - for _, r := range rl.all { + var r byteContainer + for _, r = range rl.all { if current >= offset { return r.captureInfo() } current += r.length() } + if r != nil && current >= offset { + return r.captureInfo() + } // Invalid offset return gopacket.CaptureInfo{} } @@ -358,7 +362,7 @@ func (lp *livePacket) release(*pageCache) int { // 3) Call ReassemblyComplete one time, after which the stream is dereferenced by assembly. type Stream interface { // Tell whether the TCP packet should be accepted, start could be modified to force a start even if no SYN have been seen - Accept(tcp *layers.TCP, ci gopacket.CaptureInfo, dir TCPFlowDirection, ackSeq Sequence, start *bool, ac AssemblerContext) bool + Accept(tcp *layers.TCP, ci gopacket.CaptureInfo, dir TCPFlowDirection, nextSeq Sequence, start *bool, ac AssemblerContext) bool // ReassembledSG is called zero or more times. // ScatterGather is reused after each Reassembled call, @@ -460,6 +464,14 @@ func (c *connection) reset(k key, s Stream, ts time.Time) { c.c2s.dir, c.s2c.dir = TCPDirClientToServer, TCPDirServerToClient } +func (c *connection) lastSeen() time.Time { + if c.c2s.lastSeen.Before(c.s2c.lastSeen) { + return c.s2c.lastSeen + } + + return c.c2s.lastSeen +} + func (c *connection) String() string { return fmt.Sprintf("c2s: %s, s2c: %s", &c.c2s, &c.s2c) } @@ -573,7 +585,7 @@ func NewAssembler(pool *StreamPool) *Assembler { pool.users++ pool.mu.Unlock() return &Assembler{ - ret: make([]byteContainer, assemblerReturnValueInitialSize), + ret: make([]byteContainer, 0, assemblerReturnValueInitialSize), pc: newPageCache(), connPool: pool, AssemblerOptions: DefaultAssemblerOptions, @@ -647,7 +659,13 @@ func (a *Assembler) AssembleWithContext(netFlow gopacket.Flow, t *layers.TCP, ac half.lastSeen = timestamp } a.start = half.nextSeq == invalidSequence && t.SYN - if !half.stream.Accept(t, ci, half.dir, rev.ackSeq, &a.start, ac) { + if *debugLog { + if half.nextSeq < rev.ackSeq { + log.Printf("Delay detected on %v, data is acked but not assembled yet (acked %v, nextSeq %v)", key, rev.ackSeq, half.nextSeq) + } + } + + if !half.stream.Accept(t, ci, half.dir, half.nextSeq, &a.start, ac) { if *debugLog { log.Printf("Ignoring packet") } @@ -655,6 +673,9 @@ func (a *Assembler) AssembleWithContext(netFlow gopacket.Flow, t *layers.TCP, ac } if half.closed { // this way is closed + if *debugLog { + log.Printf("%v got packet on closed half", key) + } return } @@ -897,11 +918,11 @@ func (a *Assembler) dump(text string, half *halfconnection) { } log.Printf(" * a.ret\n") for i, r := range a.ret { - log.Printf("\t%d: %s b:%s\n", i, r.captureInfo(), hex.EncodeToString(r.getBytes())) + log.Printf("\t%d: %v b:%s\n", i, r.captureInfo(), hex.EncodeToString(r.getBytes())) } log.Printf(" * a.cacheSG.all\n") for i, r := range a.cacheSG.all { - log.Printf("\t%d: %s b:%s\n", i, r.captureInfo(), hex.EncodeToString(r.getBytes())) + log.Printf("\t%d: %v b:%s\n", i, r.captureInfo(), hex.EncodeToString(r.getBytes())) } } @@ -924,15 +945,13 @@ func (a *Assembler) overlapExisting(half *halfconnection, start, end Sequence, b half.overlapPackets++ half.overlapBytes += diff } - start = start.Add(diff) s += diff if s >= e { // Completely included in sent s = e } bytes = bytes[s:] - e -= diff - return bytes, start + return bytes, half.nextSeq } // Prepare send or queue @@ -1275,7 +1294,8 @@ func (a *Assembler) flushClose(conn *connection, half *halfconnection, t time.Ti closed = true } } - if !half.closed && half.first == nil && half.lastSeen.Before(tc) { + // Close the connection only if both halfs of the connection last seen before tc. + if !half.closed && half.first == nil && conn.lastSeen().Before(tc) { a.closeHalfConnection(conn, half) closed = true } diff --git a/vendor/github.com/google/gopacket/reassembly/tcpassembly_test.go b/vendor/github.com/google/gopacket/reassembly/tcpassembly_test.go index b29cf2f045..97c0a71e17 100644 --- a/vendor/github.com/google/gopacket/reassembly/tcpassembly_test.go +++ b/vendor/github.com/google/gopacket/reassembly/tcpassembly_test.go @@ -144,7 +144,7 @@ func test(t *testing.T, s []testSequence) { t.Fatalf("test %v:\nwant: %v\n got: %v\n", i, final, fact.reassembly) } if testDebug { - fmt.Printf("test %v passing...(%s)\n", i, final) + fmt.Printf("test %v passing...(%v)\n", i, final) } } } @@ -717,6 +717,166 @@ func TestCacheLargePacket(t *testing.T) { }) } +func testFlush(t *testing.T, s []testSequence, delay time.Duration, flushInterval time.Duration) { + fact := &testFactory{} + p := NewStreamPool(fact) + a := NewAssembler(p) + a.MaxBufferedPagesPerConnection = 10 + port := layers.TCPPort(0) + + simTime := time.Unix(0, 0) + + for i, test := range s { + fact.reassembly = []Reassembly{} + if testDebug { + fmt.Printf("#### test: #%d: sending:%s\n", i, hex.EncodeToString(test.in.BaseLayer.Payload)) + } + + flow := netFlow + if port == 0 { + port = test.in.SrcPort + } + if port != test.in.SrcPort { + flow = flow.Reverse() + } + ctx := assemblerSimpleContext(gopacket.CaptureInfo{Timestamp: simTime}) + a.AssembleWithContext(flow, &test.in, &ctx) + simTime = simTime.Add(delay) + a.FlushCloseOlderThan(simTime.Add(-1 * flushInterval)) + + final := []Reassembly{} + if len(test.want) > 0 { + final = append(final, Reassembly{}) + for _, w := range test.want { + final[0].Bytes = append(final[0].Bytes, w.Bytes...) + if w.End { + final[0].End = true + } + if w.Start { + final[0].Start = true + } + if w.Skip != 0 { + final[0].Skip = w.Skip + } + } + } + + if !reflect.DeepEqual(fact.reassembly, final) { + t.Errorf("test %v:\nwant: %v\n got: %v\n", i, final, fact.reassembly) + } + + if testDebug { + fmt.Printf("test %v passing...(%v)\n", i, final) + } + } +} + +func TestFlush(t *testing.T) { + for _, test := range []struct { + seq []testSequence + delay, flushOlderThan time.Duration + }{ + { + seq: []testSequence{ + { + in: layers.TCP{ + SrcPort: 1, + DstPort: 2, + Seq: 1001, + BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3}}, + }, + want: []Reassembly{ + // flushed after flush interval. + Reassembly{ + Skip: -1, + Bytes: []byte{1, 2, 3}, + }, + }, + }, + { + in: layers.TCP{ + SrcPort: 1, + DstPort: 2, + Seq: 1010, + BaseLayer: layers.BaseLayer{Payload: []byte{4, 5, 6, 7}}, + }, + want: []Reassembly{ + // flushed after flush interval. + Reassembly{ + Skip: -1, + Bytes: []byte{4, 5, 6, 7}, + }, + }, + }, + }, + delay: time.Millisecond * 50, + flushOlderThan: time.Millisecond * 40, + }, + { + // two way stream. + seq: []testSequence{ + { + in: layers.TCP{ + SrcPort: 1, + DstPort: 2, + Seq: 1001, + BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3}}, + }, + want: []Reassembly{}, + }, + { + in: layers.TCP{ + SrcPort: 2, + DstPort: 1, + Seq: 890, + BaseLayer: layers.BaseLayer{Payload: []byte{11, 22, 33}}, + }, + want: []Reassembly{ + // First half is flushed after flush interval. + Reassembly{ + Skip: -1, + Bytes: []byte{1, 2, 3}, + }, + }, + }, + { + in: layers.TCP{ + SrcPort: 2, + DstPort: 1, + Seq: 893, + BaseLayer: layers.BaseLayer{Payload: []byte{44, 55, 66, 77}}, + }, + want: []Reassembly{ + // continues data is flushed. + Reassembly{ + Skip: -1, + Bytes: []byte{11, 22, 33, 44, 55, 66, 77}, + }, + }, + }, + { + in: layers.TCP{ + SrcPort: 1, + DstPort: 2, + Seq: 1004, + BaseLayer: layers.BaseLayer{Payload: []byte{8, 9}}, + }, + want: []Reassembly{ + Reassembly{ + // Should be flushed because is continues. + Bytes: []byte{8, 9}, + }, + }, + }, + }, + delay: time.Millisecond * 50, + flushOlderThan: time.Millisecond * 99, + }, + } { + testFlush(t, test.seq, test.delay, test.flushOlderThan) + } +} + /* * Keep */ diff --git a/vendor/github.com/google/gopacket/reassembly/tcpcheck.go b/vendor/github.com/google/gopacket/reassembly/tcpcheck.go index 4b52abab6e..508359b22e 100644 --- a/vendor/github.com/google/gopacket/reassembly/tcpcheck.go +++ b/vendor/github.com/google/gopacket/reassembly/tcpcheck.go @@ -54,7 +54,7 @@ func NewTCPOptionCheck() TCPOptionCheck { } // Accept checks whether the packet should be accepted by checking TCP options -func (t *TCPOptionCheck) Accept(tcp *layers.TCP, ci gopacket.CaptureInfo, dir TCPFlowDirection, acked Sequence, start *bool) error { +func (t *TCPOptionCheck) Accept(tcp *layers.TCP, ci gopacket.CaptureInfo, dir TCPFlowDirection, nextSeq Sequence, start *bool) error { options := t.getOptions(dir) if tcp.SYN { mss := -1 @@ -78,18 +78,18 @@ func (t *TCPOptionCheck) Accept(tcp *layers.TCP, ci gopacket.CaptureInfo, dir TC options.mss = mss options.scale = scale } else { - if acked != invalidSequence { + if nextSeq != invalidSequence { revOptions := t.getOptions(dir.Reverse()) length := len(tcp.Payload) // Check packet is in the correct window - diff := acked.Difference(Sequence(tcp.Seq)) + diff := nextSeq.Difference(Sequence(tcp.Seq)) if diff == -1 && (length == 1 || length == 0) { // This is probably a Keep-alive // TODO: check byte is ok } else if diff < 0 { return fmt.Errorf("Re-emitted packet (diff:%d,seq:%d,rev-ack:%d)", diff, - tcp.Seq, acked) + tcp.Seq, nextSeq) } else if revOptions.mss > 0 && length > revOptions.mss { return fmt.Errorf("%d > mss (%d)", length, revOptions.mss) } else if revOptions.receiveWindow != 0 && revOptions.scale < 0 && diff > int(revOptions.receiveWindow) { diff --git a/vendor/github.com/google/gopacket/reassembly/tcpcheck_test.go b/vendor/github.com/google/gopacket/reassembly/tcpcheck_test.go index 4c2391dbe6..87da266752 100644 --- a/vendor/github.com/google/gopacket/reassembly/tcpcheck_test.go +++ b/vendor/github.com/google/gopacket/reassembly/tcpcheck_test.go @@ -42,7 +42,7 @@ func testCheckFSM(t *testing.T, options TCPSimpleFSMOptions, s []testCheckFSMSeq } res := fsm.CheckState(&test.tcp, dir) if res != test.expected { - t.Fatalf("#%d: packet rejected (%s): got %s, expected %s. State:%s", i, gopacket.LayerDump(&test.tcp), res, test.expected, fsm.String()) + t.Fatalf("#%d: packet rejected (%v): got %v, expected %v. State:%s", i, gopacket.LayerDump(&test.tcp), res, test.expected, fsm.String()) } } } @@ -247,3 +247,171 @@ func TestCheckFSMmissingSYN(t *testing.T) { }) } } + +/* + * Option tests + */ + +type testCheckOptionsSequence struct { + tcp layers.TCP + ci gopacket.CaptureInfo + dir TCPFlowDirection + nextSeq Sequence + expected bool + start bool +} + +func testCheckOptions(t *testing.T, title string, s []testCheckOptionsSequence) { + opt := NewTCPOptionCheck() + for i, test := range s { + err := opt.Accept(&test.tcp, test.ci, test.dir, test.nextSeq, &test.start) + res := err == nil + if res != test.expected { + t.Fatalf("'%v' #%d: packet rejected (%v): got %v, expected %v.", title, i, gopacket.LayerDump(&test.tcp), res, test.expected) + } + } +} + +func TestCheckOptions(t *testing.T) { + for _, test := range []struct { + title string + sequence []testCheckOptionsSequence + }{ + { + title: "simle valid flow", + sequence: []testCheckOptionsSequence{ + { + dir: TCPDirClientToServer, + nextSeq: -1, // no packets received yet. + tcp: layers.TCP{ + SrcPort: 35721, + DstPort: 80, + Seq: 374511116, + Ack: 0, + BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3}}, + }, + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(1432538521, 566690000), + }, + expected: true, + }, + { + dir: TCPDirServerToClient, + nextSeq: -1, + tcp: layers.TCP{ + SrcPort: 53, + DstPort: 54842, + Seq: 3465787765, + Ack: 374511119, + BaseLayer: layers.BaseLayer{Payload: []byte{}}, + }, + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(1432538521, 590332000), + }, + expected: true, + }, + { + dir: TCPDirClientToServer, + nextSeq: 374511119, + tcp: layers.TCP{ + ACK: true, + SrcPort: 54842, + DstPort: 53, + Seq: 374511119, + Ack: 3465787766, + BaseLayer: layers.BaseLayer{Payload: []byte{2, 3, 4}}, + }, + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(1432538521, 590346000), + }, + expected: true, + }, + }, + }, + { + title: "ack received before data", + sequence: []testCheckOptionsSequence{ + { + dir: TCPDirServerToClient, + nextSeq: -1, + tcp: layers.TCP{ + SrcPort: 53, + DstPort: 54842, + Seq: 3465787765, + Ack: 374511119, + BaseLayer: layers.BaseLayer{Payload: []byte{}}, + }, + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(1432538521, 590332000), + }, + expected: true, + }, + { + dir: TCPDirClientToServer, + nextSeq: 37451116, // this is the next expected sequence. + tcp: layers.TCP{ + SrcPort: 35721, + DstPort: 80, + Seq: 374511116, + Ack: 0, + BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3}}, + }, + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(1432538521, 566690000), + }, + expected: true, + }, + { + dir: TCPDirClientToServer, + nextSeq: 374511119, + tcp: layers.TCP{ + ACK: true, + SrcPort: 54842, + DstPort: 53, + Seq: 374511119, + Ack: 3465787766, + BaseLayer: layers.BaseLayer{Payload: []byte{2, 3, 4}}, + }, + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(1432538521, 590346000), + }, + expected: true, + }, + { + dir: TCPDirClientToServer, + nextSeq: 374511122, // 10 bytes skipped + tcp: layers.TCP{ + ACK: true, + SrcPort: 54842, + DstPort: 53, + Seq: 374511132, + Ack: 3465787766, + BaseLayer: layers.BaseLayer{Payload: []byte{22, 33, 44}}, + }, + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(1432538521, 590346000), + }, + expected: true, + }, + { + dir: TCPDirClientToServer, + nextSeq: 374511132, + tcp: layers.TCP{ + ACK: true, + SrcPort: 54842, + DstPort: 53, + Seq: 374511119, // retransmission of reassembled data. + Ack: 3465787766, + BaseLayer: layers.BaseLayer{Payload: []byte{2, 3, 4}}, + }, + ci: gopacket.CaptureInfo{ + Timestamp: time.Unix(1432538521, 590346000), + }, + expected: false, + }, + }, + }, + } { + testCheckOptions(t, test.title, test.sequence) + } +} diff --git a/vendor/github.com/google/gopacket/tcpassembly/assembly.go b/vendor/github.com/google/gopacket/tcpassembly/assembly.go index 50f64874f4..bde2e9255c 100644 --- a/vendor/github.com/google/gopacket/tcpassembly/assembly.go +++ b/vendor/github.com/google/gopacket/tcpassembly/assembly.go @@ -32,7 +32,7 @@ var memLog = flag.Bool("assembly_memuse_log", false, "If true, the github.com/go var debugLog = flag.Bool("assembly_debug_log", false, "If true, the github.com/google/gopacket/tcpassembly library will log verbose debugging information (at least one line per packet)") const invalidSequence = -1 -const uint32Max = 0xFFFFFFFF +const uint32Size = 1 << 32 // Sequence is a TCP sequence number. It provides a few convenience functions // for handling TCP wrap-around. The sequence should always be in the range @@ -52,17 +52,17 @@ type Sequence int64 // uint32 space to be after any sequence in the last quarter of that space, thus // wrapping the uint32 space. func (s Sequence) Difference(t Sequence) int { - if s > uint32Max-uint32Max/4 && t < uint32Max/4 { - t += uint32Max - } else if t > uint32Max-uint32Max/4 && s < uint32Max/4 { - s += uint32Max + if s > uint32Size-uint32Size/4 && t < uint32Size/4 { + t += uint32Size + } else if t > uint32Size-uint32Size/4 && s < uint32Size/4 { + s += uint32Size } return int(t - s) } // Add adds an integer to a sequence and returns the resulting sequence. func (s Sequence) Add(t int) Sequence { - return (s + Sequence(t)) & uint32Max + return (s + Sequence(t)) & (uint32Size - 1) } // Reassembly objects are passed by an Assembler into Streams using the @@ -148,8 +148,7 @@ func (c *pageCache) next(ts time.Time) (p *page) { p, c.free = c.free[i], c.free[:i] p.prev = nil p.next = nil - p.Seen = ts - p.Bytes = p.buf[:0] + p.Reassembly = Reassembly{Bytes: p.buf[:0], Seen: ts} c.used++ return p } diff --git a/vendor/github.com/google/gopacket/tcpassembly/assembly_test.go b/vendor/github.com/google/gopacket/tcpassembly/assembly_test.go index 1bd2842e34..fed4dd8ff1 100644 --- a/vendor/github.com/google/gopacket/tcpassembly/assembly_test.go +++ b/vendor/github.com/google/gopacket/tcpassembly/assembly_test.go @@ -23,6 +23,12 @@ func init() { layers.NewIPEndpoint(net.IP{5, 6, 7, 8})) } +func TestSequenceOverflow(t *testing.T) { + if want, got := 20, Sequence((1<<32)-10).Difference(Sequence(10)); want != got { + t.Errorf("overflow diff failure: got %d want %d", got, want) + } +} + type testSequence struct { in layers.TCP want []Reassembly diff --git a/vendor/github.com/google/gopacket/tcpassembly/tcpreader/reader.go b/vendor/github.com/google/gopacket/tcpassembly/tcpreader/reader.go index 092b8110c8..377f9c14ff 100644 --- a/vendor/github.com/google/gopacket/tcpassembly/tcpreader/reader.go +++ b/vendor/github.com/google/gopacket/tcpassembly/tcpreader/reader.go @@ -12,7 +12,7 @@ // The io.Reader interface, on the other hand, is used throughout much of Go // code as an easy mechanism for reading in data streams and decoding them. For // example, the net/http package provides the ReadRequest function, which can -// parase an HTTP request from a live data stream, just what we'd want when +// parse an HTTP request from a live data stream, just what we'd want when // sniffing HTTP traffic. Using ReaderStream, this is relatively easy to set // up: // diff --git a/vendor/github.com/google/gopacket/time.go b/vendor/github.com/google/gopacket/time.go new file mode 100644 index 0000000000..6d116cdfbc --- /dev/null +++ b/vendor/github.com/google/gopacket/time.go @@ -0,0 +1,72 @@ +// Copyright 2018 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package gopacket + +import ( + "fmt" + "math" + "time" +) + +// TimestampResolution represents the resolution of timestamps in Base^Exponent. +type TimestampResolution struct { + Base, Exponent int +} + +func (t TimestampResolution) String() string { + return fmt.Sprintf("%d^%d", t.Base, t.Exponent) +} + +// ToDuration returns the smallest representable time difference as a time.Duration +func (t TimestampResolution) ToDuration() time.Duration { + if t.Base == 0 { + return 0 + } + if t.Exponent == 0 { + return time.Second + } + switch t.Base { + case 10: + return time.Duration(math.Pow10(t.Exponent + 9)) + case 2: + if t.Exponent < 0 { + return time.Second >> uint(-t.Exponent) + } + return time.Second << uint(t.Exponent) + default: + // this might loose precision + return time.Duration(float64(time.Second) * math.Pow(float64(t.Base), float64(t.Exponent))) + } +} + +// TimestampResolutionInvalid represents an invalid timestamp resolution +var TimestampResolutionInvalid = TimestampResolution{} + +// TimestampResolutionMillisecond is a resolution of 10^-3s +var TimestampResolutionMillisecond = TimestampResolution{10, -3} + +// TimestampResolutionMicrosecond is a resolution of 10^-6s +var TimestampResolutionMicrosecond = TimestampResolution{10, -6} + +// TimestampResolutionNanosecond is a resolution of 10^-9s +var TimestampResolutionNanosecond = TimestampResolution{10, -9} + +// TimestampResolutionNTP is the resolution of NTP timestamps which is 2^-32 ≈ 233 picoseconds +var TimestampResolutionNTP = TimestampResolution{2, -32} + +// TimestampResolutionCaptureInfo is the resolution used in CaptureInfo, which his currently nanosecond +var TimestampResolutionCaptureInfo = TimestampResolutionNanosecond + +// PacketSourceResolution is an interface for packet data sources that +// support reporting the timestamp resolution of the aqcuired timestamps. +// Returned timestamps will always have NanosecondTimestampResolution due +// to the use of time.Time, but scaling might have occured if acquired +// timestamps have a different resolution. +type PacketSourceResolution interface { + // Resolution returns the timestamp resolution of acquired timestamps before scaling to NanosecondTimestampResolution. + Resolution() TimestampResolution +} diff --git a/vendor/github.com/google/gopacket/time_test.go b/vendor/github.com/google/gopacket/time_test.go new file mode 100644 index 0000000000..c9b99e0bd7 --- /dev/null +++ b/vendor/github.com/google/gopacket/time_test.go @@ -0,0 +1,73 @@ +// Copyright 2019 The GoPacket Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package gopacket + +import ( + "testing" + "time" +) + +func TestToDuration(t *testing.T) { + for i, test := range []struct { + r TimestampResolution + d time.Duration + }{ + { + TimestampResolutionMillisecond, + time.Millisecond, + }, + { + TimestampResolutionMicrosecond, + time.Microsecond, + }, + { + TimestampResolutionNanosecond, + time.Nanosecond, + }, + { + TimestampResolutionNTP, + 0, // this is not representable since it's ~0.233 nanoseconds + }, + { + TimestampResolution{2, -16}, + 15258, + }, + { + TimestampResolution{2, 1}, + 2 * time.Second, + }, + { + TimestampResolution{10, 1}, + 10 * time.Second, + }, + { + TimestampResolution{10, 0}, + time.Second, + }, + { + TimestampResolution{2, 0}, + time.Second, + }, + { + TimestampResolution{0, 0}, + 0, + }, + { + TimestampResolution{3, 2}, + 9 * time.Second, + }, + { + TimestampResolution{3, -2}, + 111111111, + }, + } { + d := test.r.ToDuration() + if d != test.d { + t.Errorf("%d: resolution: %s want: %d got: %d", i, test.r, test.d, d) + } + } +} diff --git a/vendor/github.com/google/gopacket/writer.go b/vendor/github.com/google/gopacket/writer.go index 9e85a926c2..5d303dc4a7 100644 --- a/vendor/github.com/google/gopacket/writer.go +++ b/vendor/github.com/google/gopacket/writer.go @@ -36,6 +36,8 @@ type SerializableLayer interface { // LayerPayload. It just serializes based on struct fields, neither // modifying nor using contents/payload. SerializeTo(b SerializeBuffer, opts SerializeOptions) error + // LayerType returns the type of the layer that is being serialized to the buffer + LayerType() LayerType } // SerializeOptions provides options for behaviors that SerializableLayers may want to @@ -97,12 +99,19 @@ type SerializeBuffer interface { // the byte slice returned by any previous call to Bytes() for this buffer // should be considered invalidated. Clear() error + // Layers returns all the Layers that have been successfully serialized into this buffer + // already. + Layers() []LayerType + // PushLayer adds the current Layer to the list of Layers that have been serialized + // into this buffer. + PushLayer(LayerType) } type serializeBuffer struct { data []byte start int prepended, appended int + layers []LayerType } // NewSerializeBuffer creates a new instance of the default implementation of @@ -171,9 +180,18 @@ func (w *serializeBuffer) AppendBytes(num int) ([]byte, error) { func (w *serializeBuffer) Clear() error { w.start = w.prepended w.data = w.data[:w.start] + w.layers = w.layers[:0] return nil } +func (w *serializeBuffer) Layers() []LayerType { + return w.layers +} + +func (w *serializeBuffer) PushLayer(l LayerType) { + w.layers = append(w.layers, l) +} + // SerializeLayers clears the given write buffer, then writes all layers into it so // they correctly wrap each other. Note that by clearing the buffer, it // invalidates all slices previously returned by w.Bytes() @@ -193,13 +211,14 @@ func SerializeLayers(w SerializeBuffer, opts SerializeOptions, layers ...Seriali if err != nil { return err } + w.PushLayer(layer.LayerType()) } return nil } // SerializePacket is a convenience function that calls SerializeLayers // on packet's Layers(). -// It returns an error if one of the packet layers is not a SerializebleLayer. +// It returns an error if one of the packet layers is not a SerializableLayer. func SerializePacket(buf SerializeBuffer, opts SerializeOptions, packet Packet) error { sls := []SerializableLayer{} for _, layer := range packet.Layers() { diff --git a/vendor/manifest b/vendor/manifest index 5b1e62b535..ff29105553 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -965,7 +965,7 @@ "importpath": "github.com/google/gopacket", "repository": "https://github.com/google/gopacket", "vcs": "git", - "revision": "b4efbcb7f32ff9331ca217f0b4799b39118e28d6", + "revision": "6d3e2615da4ed2ed2a349918fe74e7e6d03482fa", "branch": "master" }, { From 9208e08bf3eaab9d276c53af6db5e9f7d141b4fb Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 20 Sep 2019 14:31:07 +0000 Subject: [PATCH 2/2] Change dns snooper timeout to avoid spinning in pcap The previous code seems to be relying on a 64-bit to 32-bit conversion working in a certain way; when gopacket was changed to cast the value explicitly it starts returning immeditely from pcap. --- probe/endpoint/dns_snooper.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/probe/endpoint/dns_snooper.go b/probe/endpoint/dns_snooper.go index c1151fb09f..e3058ac19e 100644 --- a/probe/endpoint/dns_snooper.go +++ b/probe/endpoint/dns_snooper.go @@ -8,7 +8,6 @@ import ( "bytes" "encoding/binary" "fmt" - "math" "sync" "time" @@ -60,9 +59,10 @@ func newPcapHandle() (*pcap.Handle, error) { return nil, err } defer inactive.CleanUp() - // pcap timeout blackmagic copied from Weave Net to reduce CPU consumption + // Set a long timeout because "pcap.BlockForever" actually spins on a 10ms timeout // see https://github.com/weaveworks/weave/commit/025315363d5ea8b8265f1b3ea800f24df2be51a4 - if err = inactive.SetTimeout(time.Duration(math.MaxInt64)); err != nil { + // (note the value in microseconds has to fit in a 32-bit signed int) + if err = inactive.SetTimeout(time.Minute * 30); err != nil { return nil, err } if err = inactive.SetImmediateMode(true); err != nil {