// readARP watches a handle for incoming ARP responses we might care about, and prints them. // // readARP loops until 'stop' is closed. func readARP(handle *pcap.Handle, iface *net.Interface, stop chan struct{}) { src := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet) in := src.Packets() for { var packet gopacket.Packet select { case <-stop: return case packet = <-in: arpLayer := packet.Layer(layers.LayerTypeARP) if arpLayer == nil { continue } arp := arpLayer.(*layers.ARP) if arp.Operation != layers.ARPReply || bytes.Equal([]byte(iface.HardwareAddr), arp.SourceHwAddress) { // This is a packet I sent. continue } // Note: we might get some packets here that aren't responses to ones we've sent, // if for example someone else sends US an ARP request. Doesn't much matter, though... // all information is good information :) log.Printf("IP %v is at %v", net.IP(arp.SourceProtAddress), net.HardwareAddr(arp.SourceHwAddress)) } } }
func packetSource() *gopacket.PacketSource { if *inputPcap != "" { handle, err := pcap.OpenOffline(*inputPcap) if err != nil { log.Fatalln(err) } fmt.Printf("open pcap file \"%s\"\n", *inputPcap) return gopacket.NewPacketSource(handle, handle.LinkType()) } if *device == "" { *device = autoSelectDev() if *device == "" { log.Fatalln("no device to capture") } } handle, err := pcap.OpenLive(*device, 1024*1024, true, pcap.BlockForever) if err != nil { log.Fatalln(err) } if *bpf != "" { if err = handle.SetBPFFilter(*bpf); err != nil { log.Fatalln("Failed to set BPF filter:", err) } } fmt.Printf("open live on device \"%s\", bpf \"%s\", serves on port %d\n", *device, *bpf, *bindingPort) return gopacket.NewPacketSource(handle, handle.LinkType()) }
func runTestZone(){ fmt.Println("We're in test zone") if handle, err := pcap.OpenOffline("/home/jnankin/Desktop/test.pcap"); err != nil { panic(err) } else { packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { if packet.Layer(layers.LayerTypeTCP) != nil { appLayer := packet.ApplicationLayer() fmt.Println("APP LAYER: \n" + string(appLayer.Payload()) + "\n\n"); sipMessage := sipparser.ParseMsg(string(appLayer.Payload())) fmt.Println("SIP BODY: \n" + sipMessage.Body + "\n\n"); fmt.Println("Content length: \n" + sipMessage.ContentLength + "\n\n"); /*SIP PDU detection: 1st Line contains SIP/2.0 foreach line, if it's a content length, set it. add each line to the current sip message if the line is blank: if I have a content length: add content length more bytes from the message to the current sip message add the current message to the list of messages found if there are still messages in the buffer, the packet is fragmented and we need more messages */ } } } }
func main() { // Open device handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout) if err != nil { log.Fatal(err) } defer handle.Close() bpfInstructions := []pcap.BPFInstruction{ {0x20, 0, 0, 0xfffff038}, // ld rand {0x54, 0, 0, 0x00000004}, {0x15, 0, 1, 0x00000004}, {0x06, 0, 0, 0x0000ffff}, {0x06, 0, 0, 0000000000}, } err = handle.SetBPFInstructionFilter(bpfInstructions) if err != nil { log.Fatal(err) } fmt.Println("Capturing ~4th packet (randomly).") packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { // Do something with a packet here. fmt.Println(packet) } }
func TestNgnet(t *testing.T) { eventChan := make(chan interface{}, 1024) f := NewHttpStreamFactory(eventChan) pool := tcpassembly.NewStreamPool(f) assembler := tcpassembly.NewAssembler(pool) packetCount := 0 fmt.Println("Run") if handle, err := pcap.OpenOffline("dump.pcapng"); err != nil { panic(err) } else { packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { net_layer := packet.NetworkLayer() trans_layer := packet.TransportLayer() if net_layer == nil { continue } if trans_layer == nil { continue } packetCount++ tcp, _ := trans_layer.(*layers.TCP) assembler.AssembleWithTimestamp(net_layer.NetworkFlow(), tcp, packet.Metadata().CaptureInfo.Timestamp) } } assembler.FlushAll() f.Wait() fmt.Println("packet:", packetCount, "http:", len(eventChan)) }
func ProcessPackets(pcapFile string, mongodHost string, mongodPort string) { if handle, err := pcap.OpenOffline(pcapFile); err != nil { panic(err) } else { var connectionWaitGroup sync.WaitGroup packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) firstPacket := <-packetSource.Packets() packetMinTimestamp = GetPacketTime(firstPacket) mapHostConnection = make(map[string]*MongoConnection) SendPacket(firstPacket, &connectionWaitGroup, mongodHost, mongodPort) for packet := range packetSource.Packets() { SendPacket(packet, &connectionWaitGroup, mongodHost, mongodPort) } for _, mConnection := range mapHostConnection { mConnection.EOF() } connectionWaitGroup.Wait() } }
//----- PCAP read from func Read_RAW_Socket_Data() { fmt.Println("|---------------------------------------------------------------|") fmt.Println("| [scanner] Opening Device (PROMISCUOUS_MODE): " + networkDeviceName + "\t\t|") // Open device handle, err = pcap.OpenLive(networkDeviceName, snapshot_len, promiscuous, timeout) if err != nil { fmt.Println("| ----------------=============================-----------------|") fmt.Println("| Looks like there is an error getting live network stream. Try |") fmt.Println("| running it again with 'sudo' command |") fmt.Println("| ----------------=============================-----------------|") log.Fatal(err) } defer handle.Close() // Set filter var filter string = "tcp" err = handle.SetBPFFilter(filter) if err != nil { log.Fatal(err) } fmt.Println("Only capturing TCP port 80 packets.") // Use the handle as a packet source to process all packets packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { process_gopacket(packet) } }
func Startcollect(port int, device string, timesignal <-chan time.Time) { handle, err = pcap.OpenLive(device, snapshotLen, promiscuous, timeout) if err != nil { glog.Info(err.Error()) } defer handle.Close() packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) templocalip, err := checkLocalip(device) localip = templocalip if glog.V(0) { glog.Info(localip) } httpinstancelist = list.New() if err != nil { glog.Info(err.Error()) } A: for packet := range packetSource.Packets() { select { case <-timesignal: break A default: processPacketInfo(packet) } } }
func main() { // Open output pcap file and write header dumpFile, _ := os.Create(dumpFilename) packetWriter := pcapgo.NewWriter(dumpFile) packetWriter.WriteFileHeader(65535, layers.LinkTypeEthernet) defer dumpFile.Close() // Open device for capturing handle, err = pcap.OpenLive(deviceName, snapshotLen, promiscuous, timeout) if err != nil { log.Fatal("Error opening device %s: %v", deviceName, err) } defer handle.Close() packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) // Start processing packets for packet := range packetSource.Packets() { fmt.Println(packet) packetWriter.WritePacket(packet.Metadata().CaptureInfo, packet.Data()) packetCount++ // Only capture 100 packets if packetCount > 100 { break } } }
func main() { flag.Parse() var handle *pcap.Handle var err error if *fname != "" { log.Printf("Reading from pcap dump %q", *fname) handle, err = pcap.OpenOffline(*fname) } else { log.Printf("Starting capture on interface %q", *iface) handle, err = pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) } if err != nil { log.Fatal(err) } if err := handle.SetBPFFilter(*filter); err != nil { log.Fatal(err) } packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { if packet == nil { return } if udpLayer := packet.Layer(layers.LayerTypeUDP); udpLayer != nil { udp, _ := udpLayer.(*layers.UDP) fwdSIPPacket(udp.BaseLayer.Payload) } } }
func main() { if len(os.Args) != 2 { fmt.Printf("Usage: %s pcap\n", os.Args[0]) os.Exit(0) } input, output := os.Args[1], "out.ts" handle, err := pcap.OpenOffline(input) if err != nil { log.Fatal(err) } defer handle.Close() f, err := os.Create(output) if err != nil { log.Fatal(err) } defer f.Close() source := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range source.Packets() { appLayer := packet.ApplicationLayer() if appLayer != nil { payload := appLayer.Payload() if len(payload) == UDPSize { f.Write(payload) } else if len(payload) == HRTPSize { offset := HRTPSize - UDPSize f.Write(payload[offset:HRTPSize]) } } } }
func main() { getLocalAddresses() log.Print(getFilterString()) //if handle, err := pcap.OpenOffline("attack3.pcap"); err != nil { if handle, err := pcap.OpenLive("any", 512, false, pcap.BlockForever); err != nil { panic(err) } else if err := handle.SetBPFFilter(getFilterString()); err != nil { panic(err) } else { //var offset time.Duration packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { /* // delay to simulate actual time span if offset == 0 { offset = time.Now().Sub(packet.Metadata().Timestamp) } sleep := packet.Metadata().Timestamp.Add(offset).Sub(time.Now()) time.Sleep(sleep) */ handlePacket(packet) } } }
func TestTCP(t *testing.T) { handle, err := pcap.OpenOffline("tcptest.pcap") if err != nil { panic(err) } packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) defer handle.Close() tcpPack := make(chan gopacket.Packet, 10) nomalPack := make(chan gopacket.Packet, 5) for input_pack := range packetSource.Packets() { // send tcp package for channel tcpLayer := input_pack.Layer(layers.LayerTypeTCP) if tcpLayer != nil { tcpPack <- input_pack // send packet to tcp ASSEMBLER } } streamFactory := &DNSStreamFactory{normal: nomalPack} streamPool := tcpassembly.NewStreamPool(streamFactory) assembler := tcpassembly.NewAssembler(streamPool) go tcpAssemble(tcpPack, assembler) pack := <-nomalPack udpLayer := pack.Layer(layers.LayerTypeUDP) if udpLayer == nil { t.Errorf("can not fine udp Layer in result") } dns_message := new(dns.Msg) err = dns_message.Unpack(udpLayer.LayerPayload()) if err != nil { t.Errorf("can not parse dns message") } fmt.Printf(dns_message.String()) }
/* FUNCTION: mangleDNS(){ RETURNS: Nothing ARGUMENTS: None ABOUT: Performs the DNS spoofing against the victims machine. Sets all dns traffic to redirect to the host machines IP address. */ func mangleDNS() { var ethernetLayer layers.Ethernet var ipLayer layers.IPv4 var dnsLayer layers.DNS var udpLayer layers.UDP decoder := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ðernetLayer, &ipLayer, &udpLayer, &dnsLayer) decoded := make([]gopacket.LayerType, 0, 4) packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for { packet, err := packetSource.NextPacket() checkError(err) err = decoder.DecodeLayers(packet.Data(), &decoded) checkError(err) if len(decoded) != 4 { fmt.Print("Not enough layers\n") continue } buffer := craftAnswer(ðernetLayer, &ipLayer, &dnsLayer, &udpLayer) if buffer == nil { // if original query was invalid fmt.Print("Buffer error, returned nil.\n") continue } err = handle.WritePacketData(buffer) checkError(err) } }
func main() { defer util.Run()() var handle *pcap.Handle var err error // Set up pcap packet capture if *fname != "" { log.Printf("Reading from pcap dump %q", *fname) handle, err = pcap.OpenOffline(*fname) } else { log.Fatalln("Error: pcap file name is required!") // log.Printf("Starting capture on interface %q", *iface) // handle, err = pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) } if err != nil { log.Fatal(err) } if err := handle.SetBPFFilter(*filter); err != nil { log.Fatal(err) } // Set up assembly streamFactory := &httpStreamFactory{} streamPool := tcpassembly.NewStreamPool(streamFactory) assembler := tcpassembly.NewAssembler(streamPool) log.Println("reading in packets") // Read in packets, pass to assembler. packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) packets := packetSource.Packets() ticker := time.Tick(time.Minute) for { select { case packet := <-packets: // A nil packet indicates the end of a pcap file. if packet == nil { return } if *logAllPackets { log.Println("\npacket:") // log.Println(packet) } if packet.NetworkLayer() == nil || packet.TransportLayer() == nil || packet.TransportLayer().LayerType() != layers.LayerTypeTCP { log.Println("Unusable packet") continue } tcp := packet.TransportLayer().(*layers.TCP) log.Printf("\n.......................................................\n") log.Printf("packet:\n") log.Printf("packet.Metadata().Timestamp=%T=%v=%v:\n%#v\n", packet.Metadata().Timestamp, packet.Metadata().Timestamp, packet.Metadata().Timestamp.UTC(), packet.Metadata().Timestamp) assembler.AssembleWithTimestamp(packet.NetworkLayer().NetworkFlow(), tcp, packet.Metadata().Timestamp) case <-ticker: // Every minute, flush connections that haven't seen activity in the past 2 minutes. assembler.FlushOlderThan(time.Now().Add(time.Minute * -2)) } } }
func process(src gopacket.PacketDataSource) { var dec gopacket.Decoder var ok bool if dec, ok = gopacket.DecodersByLayerName["Ethernet"]; !ok { if dec, ok = gopacket.DecodersByLayerName["Loopback"]; !ok { log.Fatalln("No decoder named", "Ethernet or Loopback") } } source := gopacket.NewPacketSource(src, dec) //source.Lazy = *lazy source.NoCopy = true lastMaxPeriodStart := time.Now() for packet := range source.Packets() { al := packet.ApplicationLayer() if al != nil { payload := al.Payload() if len(payload) < 16 { continue } //fmt.Println("len(payload) == %d", len(payload)) // IMPORTANT // This code is unsafe. It performs no check and will fail miserably if the packet is // not a mongo packet. Pass the proper 'port N' filter to pcap when invoking the program var header messageHeader //fmt.Println(payload) header.MessageLength = getInt32(payload, 0) header.RequestID = getInt32(payload, 4) header.ResponseTo = getInt32(payload, 8) header.OpCode = OpCode(getInt32(payload, 12)) //startTimes[header.RequestID] = time.Now() //fmt.Printf("OpCode == %v\n", header.OpCode) switch header.OpCode { case OpReply: //fmt.Println("reply") r := processReplyPayload(payload, header) rtHistogram.Observe(r) rtSummary.Observe(r) if !sighupped && (r > max || time.Since(lastMaxPeriodStart).Seconds() >= 5) { max = r lastMaxPeriodStart = time.Now() } else if sighupped { max = -0.0005 } rtMax.Set(max) //fmt.Printf("%s,%20.10f\n", time.Now().Format("15:04:05"), rt) default: startTimes[header.RequestID] = time.Now() if verbose { added, aok := debugInfo["added"] if aok { debugInfo["added"] = added + 1 } else { debugInfo["added"] = 1 } } } } } }
func NextPacket() gopacket.Packet { once.Do(func() { packetSource = gopacket.NewPacketSource(pcapHandle, layers.LayerTypeEthernet) in = packetSource.Packets() }) return <-in }
func (t *Listener) readPcapFile() { if handle, err := pcap.OpenOffline(t.addr); err != nil { log.Fatal(err) } else { t.readyCh <- true packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for { packet, err := packetSource.NextPacket() if err == io.EOF { break } else if err != nil { log.Println("Error:", err) continue } var addr, data []byte if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil { tcp, _ := tcpLayer.(*layers.TCP) data = append(tcp.LayerContents(), tcp.LayerPayload()...) if tcp.SrcPort >= 32768 && tcp.SrcPort <= 61000 { copy(data[0:2], []byte{0, 0}) copy(data[2:4], []byte{0, 1}) } else { copy(data[0:2], []byte{0, 1}) copy(data[2:4], []byte{0, 0}) } } else { continue } if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil { ip, _ := ipLayer.(*layers.IPv4) addr = ip.SrcIP } else if ipLayer = packet.Layer(layers.LayerTypeIPv6); ipLayer != nil { ip, _ := ipLayer.(*layers.IPv6) addr = ip.SrcIP } else { // log.Println("Can't find IP layer", packet) continue } dataOffset := (data[12] & 0xF0) >> 4 isFIN := data[13]&0x01 != 0 // We need only packets with data inside // Check that the buffer is larger than the size of the TCP header if len(data) <= int(dataOffset*4) && !isFIN { continue } t.packetsChan <- t.buildPacket(addr, data, packet.Metadata().Timestamp) } } }
func setupPcap(device *string, port *string, rediscommand_ch chan<- redis_protocol.RedisCommand) { var h *pcap.Handle var err error ifs, err_str := pcap.FindAllDevs() if len(ifs) == 0 { fmt.Printf("Warning: no devices found : %s\n", err_str) } h, err = pcap.OpenLive(*device, int32(65535), true, 1000) if h == nil { fmt.Printf("Openlive(%s) failed: %s\n", *device, err) return } defer h.Close() err = h.SetBPFFilter("dst port " + *port) if err != nil { fmt.Println("set filter failed") return } packetSource := gopacket.NewPacketSource(h, h.LinkType()) for pkt := range packetSource.Packets() { applicationLayer := pkt.ApplicationLayer() if applicationLayer == nil { continue } s := string(applicationLayer.Payload()) if s == "" { continue } rediscommand, err := redis_protocol.Parse(s) if err != nil { fmt.Println(err) continue } ipLayer := pkt.Layer(layers.LayerTypeIPv4) if ipLayer != nil { ip, _ := ipLayer.(*layers.IPv4) rediscommand.Ipaddr = []byte(ip.SrcIP.String()) } else { ipLayer := pkt.Layer(layers.LayerTypeIPv6) if ipLayer != nil { ip, _ := ipLayer.(*layers.IPv6) rediscommand.Ipaddr = []byte(ip.SrcIP.String()) } } rediscommand_ch <- *rediscommand } }
func main() { flag.Usage = usage flag.Parse() pcapfile, err := openPcap() if err != nil { glog.Fatalf("%v", err) } bpf := strings.Join(flag.Args(), " ") if err = pcapfile.SetBPFFilter(bpf); err != nil { glog.Fatalf("unable to set BPF: %v", err) } // "Pass this stream factory to an tcpassembly.StreamPool , // start up an tcpassembly.Assembler, and you're good to go!" done := make(chan struct{}) results := make(chan string) go printResults(done, results) wg := &sync.WaitGroup{} rtmp := &rtmpStreamWrapper{wg, results} pool := tcpassembly.NewStreamPool(rtmp) asm := tcpassembly.NewAssembler(pool) asm.MaxBufferedPagesTotal = 4096 // limit gopacket memory allocation source := gopacket.NewPacketSource(pcapfile, pcapfile.LinkType()) var pkt gopacket.Packet for { pkt, err = source.NextPacket() if pkt == nil || err != nil { break } if tcp := pkt.Layer(layers.LayerTypeTCP); tcp != nil { asm.AssembleWithTimestamp( pkt.TransportLayer().TransportFlow(), tcp.(*layers.TCP), pkt.Metadata().Timestamp) } } if err != nil && !errIsEOF(err) { glog.Errorf("packet: %v", err) if err = pcapfile.Error(); err != nil { glog.Errorf("pcap: %v", err) } } asm.FlushAll() // abort any in progress tcp connections wg.Wait() // tcp streams have finished processing close(results) // no more results will be generated by tcp streams <-done // printResults has finished }
func TestPcapFileRead(t *testing.T) { for _, file := range []struct { filename string num int expectedLayers []gopacket.LayerType }{ {"test_loopback.pcap", 24, []gopacket.LayerType{ layers.LayerTypeLoopback, layers.LayerTypeIPv6, layers.LayerTypeTCP, }, }, {"test_ethernet.pcap", 16, []gopacket.LayerType{ layers.LayerTypeEthernet, layers.LayerTypeIPv4, layers.LayerTypeTCP, }, }, {"test_dns.pcap", 10, []gopacket.LayerType{ layers.LayerTypeEthernet, layers.LayerTypeIPv4, layers.LayerTypeUDP, layers.LayerTypeDNS, }, }, } { t.Logf("\n\n\n\nProcessing file %s\n\n\n\n", file.filename) packets := []gopacket.Packet{} if handle, err := OpenOffline(file.filename); err != nil { t.Fatal(err) } else { packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { packets = append(packets, packet) } } if len(packets) != file.num { t.Fatal("Incorrect number of packets, want", file.num, "got", len(packets)) } for i, p := range packets { t.Log(p.Dump()) for _, layertype := range file.expectedLayers { if p.Layer(layertype) == nil { t.Fatal("Packet", i, "has no layer type\n%s", layertype, p.Dump()) } } } } }
/* Utility functions */ func getPacketData(which string) *gopacket.PacketSource { var pcapFile string = "data/" + which + ".pcap" handle, err := pcap.OpenOffline(pcapFile) if err != nil { return nil } return gopacket.NewPacketSource(handle, handle.LinkType()) }
//TODO obviously not a main function, rename it to the caller func parseFile(fileName string) list.List { connections := list.List{} if handle, err := pcap.OpenOffline(fileName); err != nil { panic(err) } else { packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) processPacketsChan(packetSource.Packets(), &connections) } return connections }
func NewSession(c Config) *Session { s := &Session{ Config: c, streams: map[streamID]*stream{}, nextCleaning: time.Now().Add(cleanInterval), } s.source = gopacket.NewPacketSource(s.Handle, s.Handle.LinkType()) s.parser = gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, &s.eth, &s.ip4, &s.ip6, &s.tcp, &s.payload) return s }
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 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{} for packet := range source.Packets() { count++ bytes += int64(len(packet.Data())) 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 } } }
func decodePackets(iface string, producer sarama.AsyncProducer) { // Try to open live packet capture h, err := pcap.OpenLive(iface, spanlen, true, pcap.BlockForever) if err != nil { log.Printf("Couldn't start live packet capture on %s interface", iface) } ps := gopacket.NewPacketSource(h, h.LinkType()) packets := ps.Packets() // Read packets from the channel for { select { case packet := <-packets: if packet.TransportLayer() != nil && packet.NetworkLayer() != nil { pckt := Packt{} // Figure out the application layer protocol // from the destination port var dstPort, srcPort uint16 if packet.TransportLayer().LayerType() == layers.LayerTypeTCP { tcp := packet.TransportLayer().(*layers.TCP) dstPort = uint16(tcp.DstPort) srcPort = uint16(tcp.SrcPort) pckt.Protocol = ianaPort(packet.TransportLayer().LayerType(), dstPort) } else if packet.TransportLayer().LayerType() == layers.LayerTypeUDP { udp := packet.TransportLayer().(*layers.UDP) dstPort = uint16(udp.DstPort) srcPort = uint16(udp.SrcPort) pckt.Protocol = ianaPort(packet.TransportLayer().LayerType(), dstPort) } pckt.DstPort = dstPort pckt.SrcPort = srcPort // Extract the protocol, the source and the destination IP // addresses if packet.NetworkLayer().LayerType() == layers.LayerTypeIPv4 { ipv4 := packet.NetworkLayer().(*layers.IPv4) pckt.SrcIP = ipv4.SrcIP.String() pckt.DstIP = ipv4.DstIP.String() } else { pckt.Protocol = "N/A (IPv6)" } // Emit the packet data to Kafka emitPacket(pckt, producer) } } } }
func main() { handle, err := pcap.OpenOffline("capture/http.pcap") if err != nil { panic(err) } packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { handlePacket(packet) // Do something with a packet here. } }
func (t *Listener) readPcapFile() { if handle, err := pcap.OpenOffline(t.addr); err != nil { log.Fatal(err) } else { t.readyCh <- true packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for { packet, err := packetSource.NextPacket() if err == io.EOF { break } else if err != nil { log.Println("Error:", err) continue } var addr, data []byte if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil { tcp, _ := tcpLayer.(*layers.TCP) data = append(tcp.LayerContents(), tcp.LayerPayload()...) copy(data[2:4], []byte{0, 1}) } else { continue } if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil { ip, _ := ipLayer.(*layers.IPv4) addr = ip.SrcIP } else if ipLayer = packet.Layer(layers.LayerTypeIPv6); ipLayer != nil { ip, _ := ipLayer.(*layers.IPv6) addr = ip.SrcIP } else { // log.Println("Can't find IP layer", packet) continue } dataOffset := (data[12] & 0xF0) >> 4 // We need only packets with data inside // Check that the buffer is larger than the size of the TCP header if len(data) <= int(dataOffset*4) { continue } newBuf := make([]byte, len(data)+16) copy(newBuf[:16], addr) copy(newBuf[16:], data) t.packetsChan <- newBuf } } }
// Sniff captures probe requests using the given handle and writes them to a channel. func Sniff(handle *pcap.Handle) <-chan wifitracker.Request { out := make(chan wifitracker.Request, 0) go func() { defer close(out) packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { handlePacket(packet, out) } }() return out }
// Sniffs packets over the device. func Sniff(device string, snaplen int32, promisc bool, filter string) (<-chan gopacket.Packet, error) { handle, err := pcap.OpenLive(device, snaplen, promisc, pcap.BlockForever) if err != nil { return nil, err } err = handle.SetBPFFilter(filter) if err != nil { return nil, err } source := gopacket.NewPacketSource(handle, handle.LinkType()) return source.Packets(), nil }