From 3f1edad4e6ba0a7876750aea55507fae14d8badf Mon Sep 17 00:00:00 2001 From: Milan Lenco Date: Wed, 11 Oct 2017 16:40:58 +0200 Subject: ODPM 266: Go-libmemif + 2 examples. Change-Id: Icdb9b9eb2314eff6c96afe7996fcf2728291de4a Signed-off-by: Milan Lenco --- .../google/gopacket/dumpcommand/tcpdump.go | 119 +++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 vendor/github.com/google/gopacket/dumpcommand/tcpdump.go (limited to 'vendor/github.com/google/gopacket/dumpcommand/tcpdump.go') diff --git a/vendor/github.com/google/gopacket/dumpcommand/tcpdump.go b/vendor/github.com/google/gopacket/dumpcommand/tcpdump.go new file mode 100644 index 0000000..2d35722 --- /dev/null +++ b/vendor/github.com/google/gopacket/dumpcommand/tcpdump.go @@ -0,0 +1,119 @@ +// 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. + +// Package dumpcommand implements a run function for pfdump and pcapdump +// with many similar flags/features to tcpdump. This code is split out seperate +// from data sources (pcap/pfring) so it can be used by both. +package dumpcommand + +import ( + "flag" + "fmt" + "log" + "os" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/ip4defrag" + "github.com/google/gopacket/layers" // pulls in all layers decoders +) + +var ( + print = flag.Bool("print", true, "Print out packets, if false only prints out statistics") + maxcount = flag.Int("c", -1, "Only grab this many packets, then exit") + decoder = flag.String("decoder", "Ethernet", "Name of the decoder to use") + dump = flag.Bool("X", false, "If true, dump very verbose info on each packet") + statsevery = flag.Int("stats", 1000, "Output statistics every N packets") + printErrors = flag.Bool("errors", false, "Print out packet dumps of decode errors, useful for checking decoders against live traffic") + lazy = flag.Bool("lazy", false, "If true, do lazy decoding") + defrag = flag.Bool("defrag", false, "If true, do IPv4 defrag") +) + +func Run(src gopacket.PacketDataSource) { + if !flag.Parsed() { + log.Fatalln("Run called without flags.Parse() being called") + } + var dec gopacket.Decoder + var ok bool + if dec, ok = gopacket.DecodersByLayerName[*decoder]; !ok { + log.Fatalln("No decoder named", *decoder) + } + source := gopacket.NewPacketSource(src, dec) + source.Lazy = *lazy + source.NoCopy = true + source.DecodeStreamsAsDatagrams = true + fmt.Fprintln(os.Stderr, "Starting to read packets") + count := 0 + bytes := int64(0) + start := time.Now() + errors := 0 + truncated := 0 + layertypes := map[gopacket.LayerType]int{} + defragger := ip4defrag.NewIPv4Defragmenter() + + for packet := range source.Packets() { + count++ + bytes += int64(len(packet.Data())) + + // defrag the IPv4 packet if required + if *defrag { + ip4Layer := packet.Layer(layers.LayerTypeIPv4) + if ip4Layer == nil { + continue + } + ip4 := ip4Layer.(*layers.IPv4) + l := ip4.Length + + newip4, err := defragger.DefragIPv4(ip4) + if err != nil { + log.Fatalln("Error while de-fragmenting", err) + } else if newip4 == nil { + continue // packet fragment, we don't have whole packet yet. + } + if newip4.Length != l { + fmt.Printf("Decoding re-assembled packet: %s\n", newip4.NextLayerType()) + pb, ok := packet.(gopacket.PacketBuilder) + if !ok { + panic("Not a PacketBuilder") + } + nextDecoder := newip4.NextLayerType() + nextDecoder.Decode(newip4.Payload, pb) + } + } + + if *dump { + fmt.Println(packet.Dump()) + } else if *print { + fmt.Println(packet) + } + if !*lazy || *print || *dump { // if we've already decoded all layers... + for _, layer := range packet.Layers() { + layertypes[layer.LayerType()]++ + } + if packet.Metadata().Truncated { + truncated++ + } + if errLayer := packet.ErrorLayer(); errLayer != nil { + errors++ + if *printErrors { + fmt.Println("Error:", errLayer.Error()) + fmt.Println("--- Packet ---") + fmt.Println(packet.Dump()) + } + } + } + done := *maxcount > 0 && count >= *maxcount + if count%*statsevery == 0 || done { + fmt.Fprintf(os.Stderr, "Processed %v packets (%v bytes) in %v, %v errors and %v truncated packets\n", count, bytes, time.Since(start), errors, truncated) + if len(layertypes) > 0 { + fmt.Fprintf(os.Stderr, "Layer types seen: %+v\n", layertypes) + } + } + if done { + break + } + } +} -- cgit 1.2.3-korg