// 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 handlePacket(packet gopacket.Packet) { // Get the TCP layer from this packet tcpLayer := packet.Layer(layers.LayerTypeTCP) if tcpLayer != nil { // Get actual TCP data from this layer tcp, _ := tcpLayer.(*layers.TCP) fmt.Printf("From: src port %6d\tTo: dst port %6d\t", tcp.SrcPort, tcp.DstPort) fmt.Printf("Ack: %12v\t", tcp.Ack) } // Iterate over all layers, printing out each layer type for _, layer := range packet.Layers() { layerType := layer.LayerType() fmt.Printf("%8v %5v", layerType, len(layer.LayerPayload())) } applicationLayer := packet.ApplicationLayer() if applicationLayer != nil { fmt.Println("Application layer/Payload found.") //fmt.Printf("%s\n", applicationLayer.Payload()) } fmt.Println("") }
// GetDstIP returns the destination ipV4§ as a string func GetDstIP(packet gopacket.Packet) string { if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil { ip, _ := ipLayer.(*layers.IPv4) return ip.DstIP.String() } return "" }
//need work func (f *fragmentList) build(in gopacket.Packet) (gopacket.Packet, error) { var final []byte var currentOffset uint16 = 0 debug.Printf("defrag: building the datagram \n") for e := f.List.Front(); e != nil; e = e.Next() { pack, _ := e.Value.(gopacket.Packet) frag := pack.Layer(layers.LayerTypeIPv6Fragment).(*layers.IPv6Fragment) ip := pack.Layer(layers.LayerTypeIPv6).(*layers.IPv6) if frag.FragmentOffset*8 == currentOffset { debug.Printf("defrag: building - adding %d\n", frag.FragmentOffset*8) final = append(final, frag.Payload...) currentOffset = currentOffset + ip.Length - 8 } else if frag.FragmentOffset*8 < currentOffset { // overlapping fragment - let's take only what we need startAt := currentOffset - frag.FragmentOffset*8 debug.Printf("defrag: building - overlapping, starting at %d\n", startAt) if startAt > ip.Length-8 { return nil, fmt.Errorf("defrag: building - invalid fragment") } final = append(final, frag.Payload[startAt:]...) currentOffset = currentOffset + frag.FragmentOffset*8 } else { // Houston - we have an hole ! debug.Printf("defrag: hole found while building, " + "stopping the defrag process\n") return nil, fmt.Errorf("defrag: building - hole found") } debug.Printf("defrag: building - next is %d\n", currentOffset) } final_ipv6 := in.Layer(layers.LayerTypeIPv6).(*layers.IPv6) final_frag := in.Layer(layers.LayerTypeIPv6Fragment).(*layers.IPv6Fragment) // TODO recompute IP Checksum out := &layers.IPv6{ Version: final_ipv6.Version, TrafficClass: final_ipv6.TrafficClass, FlowLabel: final_ipv6.FlowLabel, Length: f.Highest, NextHeader: final_frag.NextHeader, HopLimit: final_ipv6.HopLimit, SrcIP: final_ipv6.SrcIP, DstIP: final_ipv6.DstIP, HopByHop: final_ipv6.HopByHop, } out.Payload = final v6SerailizeBuffer := gopacket.NewSerializeBuffer() v6Buffer, _ := v6SerailizeBuffer.PrependBytes(len(final)) copy(v6Buffer, final) ops := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } out.SerializeTo(v6SerailizeBuffer, ops) outPacket := gopacket.NewPacket(v6SerailizeBuffer.Bytes(), layers.LayerTypeIPv6, gopacket.Default) outPacket.Metadata().CaptureLength = len(outPacket.Data()) outPacket.Metadata().Length = len(outPacket.Data()) return outPacket, nil }
// newIPv4 returns a new initialized IPv4 Flow func newipv6(packet gopacket.Packet) ipv6 { frag := packet.Layer(layers.LayerTypeIPv6Fragment).(*layers.IPv6Fragment) ip := packet.Layer(layers.LayerTypeIPv6).(*layers.IPv6) return ipv6{ ip6: ip.NetworkFlow(), id: frag.Identification, } }
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 parseForSip(packet gopacket.Packet) *sipparser.SipMsg { ipLayer := packet.Layer(layers.LayerTypeIPv4) appLayer := packet.ApplicationLayer() fmt.Println("PAYLOAD: " + string(appLayer.Payload()) + " - END.") if ipLayer != nil && appLayer != nil && strings.Contains(string(appLayer.Payload()), "SIP") { return sipparser.ParseMsg(string(appLayer.Payload())) } return nil }
//RetrieveSrcPort retrieves the src port of a packet func RetrieveSrcPort(packet gopacket.Packet) (int, error) { iplayers := packet.Layer(layers.LayerTypeTCP) if iplayers != nil { ipc, ok := iplayers.(*layers.TCP) if ok { return int(ipc.SrcPort), nil } } return 0, ErrBadPacket }
//RetrieveSrcIP retrieves the src ip of a packet func RetrieveSrcIP(packet gopacket.Packet) (net.IP, error) { iplayers := packet.Layer(layers.LayerTypeIPv4) if iplayers != nil { ipc, ok := iplayers.(*layers.IPv4) if ok { return ipc.SrcIP, nil } } return nil, ErrBadPacket }
//------ PCAP Print PCAP Data ----- func process_gopacket(packet gopacket.Packet) { // Let's see if the packet is IP (even though the ether type told us) ipLayer := packet.Layer(layers.LayerTypeIPv4) if ipLayer != nil { ip, _ := ipLayer.(*layers.IPv4) register_network_call_with_redis(ip.Protocol, ip.DstIP) } // Check for errors if err := packet.ErrorLayer(); err != nil { fmt.Println("Error decoding some part of the packet:", err) } }
func (d *IPv6Defragmenter) DefragIPv6(in gopacket.Packet) (gopacket.Packet, error) { // check if we need to defrag frag := in.Layer(layers.LayerTypeIPv6Fragment) if frag == nil { return in, nil } v6frag := frag.(*layers.IPv6Fragment) // ok, got a fragment debug.Printf("defrag: got in.Id=%d in.FragOffset=%d", v6frag.Identification, v6frag.FragmentOffset*8) // do we already has seen a flow between src/dst with that Id ipf := newipv6(in) var fl *fragmentList var exist bool d.Lock() fl, exist = d.ipFlows[ipf] if !exist { debug.Printf("defrag: creating a new flow\n") fl = new(fragmentList) d.ipFlows[ipf] = fl } d.Unlock() // insert, and if final build it out, err2 := fl.insert(in) // at last, if we hit the maximum frag list len // without any defrag success, we just drop everything and // raise an error if out == nil && fl.List.Len()+1 > IPv6MaximumFragmentListLen { d.Lock() fl = new(fragmentList) d.ipFlows[ipf] = fl d.Unlock() return nil, fmt.Errorf("defrag: Fragment List hits its maximum"+ "size(%d), without sucess. Flushing the list", IPv6MaximumFragmentListLen) } // if we got a packet, it's a new one, and he is defragmented if out != nil { return out, nil } return nil, err2 }
func (f *fragmentList) insert(in gopacket.Packet) (gopacket.Packet, error) { // TODO: should keep a copy of *in in the list // or not (ie the packet source is reliable) ? fragv6 := in.Layer(layers.LayerTypeIPv6Fragment).(*layers.IPv6Fragment) fragOffset := fragv6.FragmentOffset * 8 if fragOffset >= f.Highest { f.List.PushBack(in) } else { for e := f.List.Front(); e != nil; e = e.Next() { packet, _ := e.Value.(gopacket.Packet) frag := packet.Layer(layers.LayerTypeIPv6Fragment).(*layers.IPv6Fragment) if fragv6.FragmentOffset <= frag.FragmentOffset { debug.Printf("defrag: inserting frag %d before existing frag %d \n", fragOffset, frag.FragmentOffset*8) f.List.InsertBefore(in, e) break } } } // packet.Metadata().Timestamp should have been better, but // we don't have this info there... f.LastSeen = in.Metadata().Timestamp fragLength := in.Layer(layers.LayerTypeIPv6).(*layers.IPv6).Length - 8 // need to conform // After inserting the Fragment, we update the counters if f.Highest < fragOffset+fragLength { f.Highest = fragOffset + fragLength } f.Current = f.Current + fragLength debug.Printf("defrag: insert ListLen: %d Highest:%d Current:%d\n", f.List.Len(), f.Highest, f.Current) // Final Fragment ? if fragv6.MoreFragments == false { f.FinalReceived = true } // Ready to try defrag ? if f.FinalReceived && f.Highest == f.Current { return f.build(in) } return nil, nil }
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 !net.IP(arp.SourceProtAddress).Equal(net.ParseIP("0.0.0.0")) { continue } found := false for mac, fn := range DashMacs { if net.HardwareAddr(arp.SourceHwAddress).String() == mac { if !State[mac] { log.Printf("Click sniffed for %v", mac) State[mac] = true fn() State[mac] = false } found = true } } if !found { log.Printf("FOUND UNKNOWN MAC: %v", net.HardwareAddr(arp.SourceHwAddress)) } } } }
func (this *Sniff) handlePacket(packet gopacket.Packet) { ipLayer := packet.Layer(layers.LayerTypeIPv4) if ipLayer == nil { return } ip, _ := ipLayer.(*layers.IPv4) tcpLayer := packet.Layer(layers.LayerTypeTCP) if tcpLayer == nil { return } tcp, _ := tcpLayer.(*layers.TCP) applicationLayer := packet.ApplicationLayer() if applicationLayer == nil { return } this.Ui.Info(fmt.Sprintf("%s:%s -> %s:%s %dB", ip.SrcIP, tcp.SrcPort, ip.DstIP, tcp.DstPort, len(applicationLayer.Payload()))) this.Ui.Output(fmt.Sprintf("%s", string(applicationLayer.Payload()))) }
//every time get a new packet func processPacketInfo(packet gopacket.Packet) { //get the specified layer tcpLayer := packet.Layer(layers.LayerTypeTCP) if tcpLayer != nil { if glog.V(2) { glog.Info("TCP layer is detected.") } tcphandler, _ := tcpLayer.(*layers.TCP) srcport := tcphandler.SrcPort destport := tcphandler.DstPort //get the specified layer iplayer := packet.Layer(layers.LayerTypeIPv4) httphandler, _ := iplayer.(*layers.IPv4) srcip := httphandler.SrcIP destip := httphandler.DstIP //log.Println(srcip.String()) //send the packet from local machine Srcaddr := &Address{IP: srcip.String(), PORT: srcport.String()} Destaddr := &Address{IP: destip.String(), PORT: destport.String()} if glog.V(2) { glog.Infof("srcaddr %v destaddr %v \n", Srcaddr, Destaddr) } var mutex = &sync.Mutex{} if srcip.String() == localip { mutex.Lock() outputStream(packet, Srcaddr, Destaddr) mutex.Unlock() } //get the packet from the local machine if destip.String() == localip { mutex.Lock() inputStream(packet, Srcaddr, Destaddr) mutex.Unlock() } } }
func getPacketInfo(packet gopacket.Packet) *PacketInfo { ipLayer := packet.Layer(layers.LayerTypeIPv4) var packetInfo PacketInfo if ipLayer != nil { ip, _ := ipLayer.(*layers.IPv4) //Set the ports if ip.Protocol == layers.IPProtocolTCP { protocol, _ := packet.Layer(layers.LayerTypeTCP).(*layers.TCP) packetInfo.srcIP = ip.SrcIP.String() packetInfo.dstIP = ip.DstIP.String() packetInfo.srcPort = strconv.Itoa(int(protocol.SrcPort)) packetInfo.dstPort = strconv.Itoa(int(protocol.DstPort)) } else if ip.Protocol == layers.IPProtocolUDP { protocol, _ := packet.Layer(layers.LayerTypeUDP).(*layers.UDP) packetInfo.srcIP = ip.SrcIP.String() packetInfo.dstIP = ip.DstIP.String() packetInfo.srcPort = strconv.Itoa(int(protocol.SrcPort)) packetInfo.dstPort = strconv.Itoa(int(protocol.DstPort)) } } return &packetInfo }
func handlePacket(packet gopacket.Packet) { probeRequest := ProbeRequest{CaptureDTS: time.Now()} if l1 := packet.Layer(layers.LayerTypeDot11); l1 != nil { dot11, _ := l1.(*layers.Dot11) probeRequest.MAC = dot11.Address2.String() if l2 := packet.Layer(layers.LayerTypeDot11MgmtProbeReq); l2 != nil { dot11p, _ := l2.(*layers.Dot11MgmtProbeReq) probeRequest.decodeProbeRequestLayer(dot11p) if l1 := packet.Layer(layers.LayerTypeRadioTap); l1 != nil { dot11r, _ := l1.(*layers.RadioTap) probeRequest.RSSI = dot11r.DBMAntennaSignal } fmt.Println(probeRequest) } } }
func handlePacket(packet gopacket.Packet, out chan<- wifitracker.Request) { probeRequest := capturedRequest{CaptureDTS: time.Now()} if l1 := packet.Layer(layers.LayerTypeDot11); l1 != nil { dot11, _ := l1.(*layers.Dot11) probeRequest.MAC = dot11.Address2.String() if l2 := packet.Layer(layers.LayerTypeDot11MgmtProbeReq); l2 != nil { dot11p, _ := l2.(*layers.Dot11MgmtProbeReq) probeRequest.decodeProbeRequestLayer(dot11p) if l1 := packet.Layer(layers.LayerTypeRadioTap); l1 != nil { dot11r, _ := l1.(*layers.RadioTap) probeRequest.RSSI = dot11r.DBMAntennaSignal } rq := wifitracker.Request{CaptureDts: probeRequest.CaptureDTS, SignalStrength: 0, SourceMac: probeRequest.MAC, TargetSsid: probeRequest.SSID} out <- rq } } }
func moldudp64Layer(pkt gopacket.Packet) *nasdaq.MoldUDP64 { if l := pkt.Layer(nasdaq.LayerTypeMoldUDP64); l != nil { return l.(*nasdaq.MoldUDP64) } return nil }
func printPacketInfo(packet gopacket.Packet) { // Let's see if the packet is an ethernet packet ethernetLayer := packet.Layer(layers.LayerTypeEthernet) if ethernetLayer != nil { fmt.Println("Ethernet layer detected.") ethernetPacket, _ := ethernetLayer.(*layers.Ethernet) fmt.Println("Source MAC: ", ethernetPacket.SrcMAC) fmt.Println("Destination MAC: ", ethernetPacket.DstMAC) // Ethernet type is typically IPv4 but could be ARP or other fmt.Println("Ethernet type: ", ethernetPacket.EthernetType) fmt.Println() } // Let's see if the packet is IP (even though the ether type told us) ipLayer := packet.Layer(layers.LayerTypeIPv4) if ipLayer != nil { fmt.Println("IPv4 layer detected.") ip, _ := ipLayer.(*layers.IPv4) // IP layer variables: // Version (Either 4 or 6) // IHL (IP Header Length in 32-bit words) // TOS, Length, Id, Flags, FragOffset, TTL, Protocol (TCP?), // Checksum, SrcIP, DstIP fmt.Printf("From %s to %s\n", ip.SrcIP, ip.DstIP) fmt.Println("Protocol: ", ip.Protocol) fmt.Println() } // Let's see if the packet is TCP tcpLayer := packet.Layer(layers.LayerTypeTCP) if tcpLayer != nil { fmt.Println("TCP layer detected.") tcp, _ := tcpLayer.(*layers.TCP) // TCP layer variables: // SrcPort, DstPort, Seq, Ack, DataOffset, Window, Checksum, Urgent // Bool flags: FIN, SYN, RST, PSH, ACK, URG, ECE, CWR, NS fmt.Printf("From port %d to %d\n", tcp.SrcPort, tcp.DstPort) fmt.Println("Sequence number: ", tcp.Seq) fmt.Println() } // Iterate over all layers, printing out each layer type fmt.Println("All packet layers:") for _, layer := range packet.Layers() { fmt.Println("- ", layer.LayerType()) } // When iterating through packet.Layers() above, // if it lists Payload layer then that is the same as // this applicationLayer. applicationLayer contains the payload applicationLayer := packet.ApplicationLayer() if applicationLayer != nil { fmt.Println("Application layer/Payload found.") fmt.Printf("%s\n", applicationLayer.Payload()) // Search for a string inside the payload if strings.Contains(string(applicationLayer.Payload()), "HTTP") { fmt.Println("HTTP found!") } } // Check for errors if err := packet.ErrorLayer(); err != nil { fmt.Println("Error decoding some part of the packet:", err) } }
func gatherPacketLayersInfo(event common.MapStr, packet gopacket.Packet) { // see https://godoc.org/github.com/google/gopacket#hdr-Pointers_To_Known_Layers // Pointers To Known Layers: // During decoding, certain layers are stored in the packet as well-known layer types. // For example, IPv4 and IPv6 are both considered NetworkLayer layers, // while TCP and UDP are both TransportLayer layers. // We support 4 layers, corresponding to the 4 layers of the TCP/IP layering scheme // (roughly anagalous to layers 2, 3, 4, and 7 of the OSI model). // To access these, you can use the: // packet.LinkLayer, // packet.NetworkLayer, // packet.TransportLayer, and // packet.ApplicationLayer functions. // Each of these functions returns a corresponding interface (gopacket.{Link,Network,Transport,Application}Layer). // The first three provide methods for getting src/dst addresses for that particular layer, // while the final layer provides a Payload function to get payload data. // use "packet.Dump()" as a fail-safe to capture all available layers for a packet, // just in case we encounter something unexpected in the unified2 file or we // have neglected to handle a particular layer explicitly event["packet_dump"] = packet.Dump() // "packet.Dump()" is very verbose, i.e. a large amount of text, but that's ok // capture the name of the layers found var packet_layers []string for _, layer := range packet.Layers() { packet_layers = append(packet_layers, fmt.Sprintf("%v", layer.LayerType())) } event["packet_layers"] = packet_layers // Ethernet layer? ethernetLayer := packet.Layer(layers.LayerTypeEthernet) if ethernetLayer != nil { ethernetPacket, _ := ethernetLayer.(*layers.Ethernet) event["ethernet_src_mac"] = fmt.Sprintf("%v", ethernetPacket.SrcMAC) event["ethernet_dst_mac"] = fmt.Sprintf("%v", ethernetPacket.DstMAC) // ethernet type is typically IPv4 but could be ARP or other event["ethernet_type"] = fmt.Sprintf("%v", ethernetPacket.EthernetType) // Length is only set if a length field exists within this header. Ethernet // headers follow two different standards, one that uses an EthernetType, the // other which defines a length the follows with a LLC header (802.3). If the // former is the case, we set EthernetType and Length stays 0. In the latter // case, we set Length and EthernetType = EthernetTypeLLC. event["ethernet_length"] = fmt.Sprintf("%v", ethernetPacket.Length) } // IPv4 layer? ipLayer := packet.Layer(layers.LayerTypeIPv4) if ipLayer != nil { ip, _ := ipLayer.(*layers.IPv4) event["ip_version"] = ip.Version event["ip_ihl"] = ip.IHL event["ip_tos"] = ip.TOS event["ip_length"] = ip.Length event["ip_id"] = ip.Id event["ip_flags"] = ip.Flags event["ip_fragoffset"] = ip.FragOffset event["ip_ttl"] = ip.TTL event["ip_protocol"] = ip.Protocol event["ip_checksum"] = ip.Checksum event["ip_src_ip"] = ip.SrcIP event["ip_dst_ip"] = ip.DstIP event["ip_options"] = ip.Options // maybe? fmt.Sprintf("%v", ip.Options) event["ip_padding"] = ip.Padding } // IPv6 layer? ip6Layer := packet.Layer(layers.LayerTypeIPv6) if ip6Layer != nil { ip6, _ := ip6Layer.(*layers.IPv6) event["ip6_version"] = ip6.Version event["ip6_trafficclass"] = ip6.TrafficClass event["ip6_flowlabel"] = ip6.FlowLabel event["ip6_length"] = ip6.Length event["ip6_nextheader"] = ip6.NextHeader event["ip6_hoplimit"] = ip6.HopLimit event["ip6_src_ip"] = ip6.SrcIP event["ip6_dst_ip"] = ip6.DstIP event["ip6_hopbyhop"] = ip6.HopByHop } // see: gopacket/layers folder ... what layers are needed for Snort/Suricata alerts? // ICMPv4 layer? // ICMPv6 layer? // ARP layer? // UDP layer? udpLayer := packet.Layer(layers.LayerTypeUDP) if udpLayer != nil { udp, _ := udpLayer.(*layers.UDP) event["udp_src_port"] = udp.SrcPort event["udp_dst_port"] = udp.DstPort event["udp_length"] = udp.Length event["udp_checksum"] = udp.Checksum } // TCP layer? tcpLayer := packet.Layer(layers.LayerTypeTCP) if tcpLayer != nil { tcp, _ := tcpLayer.(*layers.TCP) event["tcp_src_port"] = tcp.SrcPort event["tcp_dst_port"] = tcp.DstPort event["tcp_seq"] = tcp.Seq event["tcp_ack"] = tcp.Ack event["tcp_data_offset"] = tcp.DataOffset event["tcp_fin"] = tcp.FIN event["tcp_syn"] = tcp.SYN event["tcp_rst"] = tcp.RST event["tcp_psh"] = tcp.PSH event["tcp_ack"] = tcp.ACK event["tcp_urg"] = tcp.URG event["tcp_ece"] = tcp.ECE event["tcp_cwr"] = tcp.CWR event["tcp_ns"] = tcp.NS event["tcp_window"] = tcp.Window event["tcp_checksum"] = tcp.Checksum event["tcp_urgent"] = tcp.Urgent event["tcp_options"] = tcp.Options // maybe? fmt.Sprintf("%v", tcp.Options) event["tcp_padding"] = tcp.Padding } // note: the Payload layer is the same as this applicationLayer // also, we can get payloads for all packets regardless of their underlying data type: // application layer? (aka packet payload) applicationLayer := packet.ApplicationLayer() if applicationLayer != nil { event["packet_payload"] = fmt.Sprintf("%s", applicationLayer.Payload()) } // errors? if err := packet.ErrorLayer(); err != nil { event["packet_error"] = fmt.Sprintf("Packet decoding error: %v", err) } }
// Handle reads the pcap file into assembled packets for the streamHandler func (p *PacketHandler) Handle(streamHandler StreamHandler, numToHandle int) error { count := int64(0) start := time.Now() if p.Verbose && numToHandle > 0 { userInfoLogger.Logvf(Always, "Processing", numToHandle, "packets") } source := gopacket.NewPacketSource(p.pcap, p.pcap.LinkType()) streamPool := NewStreamPool(streamHandler) assembler := NewAssembler(streamPool) defer func() { if userInfoLogger.isInVerbosity(DebugLow) { userInfoLogger.Logv(DebugLow, "flushing assembler.") userInfoLogger.Logvf(DebugLow, "num flushed/closed: %v", assembler.FlushAll()) userInfoLogger.Logv(DebugLow, "closing stream handler.") } else { assembler.FlushAll() } streamHandler.Close() }() defer func() { if userInfoLogger.isInVerbosity(DebugLow) { userInfoLogger.Logvf(DebugLow, "Dropped %v packets out of %v", p.numDropped, count) runTime := float64(time.Now().Sub(start)) / float64(time.Second) userInfoLogger.Logvf(DebugLow, "Processed %v packets per second", float64(count-p.numDropped)/runTime) } }() ticker := time.Tick(time.Second * 1) var pkt gopacket.Packet var pktCount uint for { select { case pkt = <-source.Packets(): pktCount++ if pkt == nil { // end of pcap file userInfoLogger.Logv(DebugLow, "Reached end of stream") return nil } if tcpLayer := pkt.Layer(layers.LayerTypeTCP); tcpLayer != nil { userInfoLogger.Logv(DebugHigh, "Assembling TCP layer") assembler.AssembleWithTimestamp( pkt.TransportLayer().TransportFlow(), tcpLayer.(*layers.TCP), pkt.Metadata().Timestamp) // TODO: use time.Now() here when running in realtime mode } if count == 0 { if firstSeener, ok := streamHandler.(SetFirstSeener); ok { firstSeener.SetFirstSeen(pkt.Metadata().Timestamp) } } count++ if numToHandle > 0 && count >= int64(numToHandle) { userInfoLogger.Logv(DebugLow, "Count exceeds requested packets, returning.") break } select { case <-ticker: bookkeep(pktCount, pkt, assembler) default: } case <-ticker: bookkeep(pktCount, pkt, assembler) case <-p.stop: return nil } } }
//------ PCAP Print PCAP Data ----- func process_gopacket(packet gopacket.Packet) { ethernetLayer := packet.Layer(layers.LayerTypeEthernet) if ethernetLayer != nil { ethernetPacket, _ := ethernetLayer.(*layers.Ethernet) fmt.Printf("Ethernet layer | Type: %s | Src_MAC: %s Dst_MAC: %s\n", ethernetPacket.EthernetType, ethernetPacket.SrcMAC, ethernetPacket.DstMAC) // Ethernet type is typically IPv4 but could be ARP or other } // Let's see if the packet is IP (even though the ether type told us) ipLayer := packet.Layer(layers.LayerTypeIPv4) if ipLayer != nil { ip, _ := ipLayer.(*layers.IPv4) // fmt.Printf("\tIPv4 | %s | Src: %s Dest: %s \n", ip.Protocol, ip.SrcIP, ip.DstIP) // IP layer variables: // Version (Either 4 or 6) // IHL (IP Header Length in 32-bit words) // TOS, Length, Id, Flags, FragOffset, TTL, Protocol (TCP?), // Checksum, SrcIP, DstIP // register_network_call_with_redis(ip.Protocol, ip.SrcIP, ip.DstIP) } // Let's see if the packet is TCP tcpLayer := packet.Layer(layers.LayerTypeTCP) if tcpLayer != nil { tcp, _ := tcpLayer.(*layers.TCP) fmt.Printf("\tTCP | From port %d to %d", tcp.SrcPort, tcp.DstPort) fmt.Println("| TCP Seq: ", tcp.Seq) // TCP layer variables: // SrcPort, DstPort, Seq, Ack, DataOffset, Window, Checksum, Urgent // Bool flags: FIN, SYN, RST, PSH, ACK, URG, ECE, CWR, NS } // dnsLayer := packet.Layer(layers.LayerTypeDNS) // if dnsLayer != nil { // dns, _ := dnsLayer.(*layers.DNS) // fmt.Println(dns) // } // // Iterate over all layers, printing out each layer type // fmt.Println("All packet layers:") // for _, layer := range packet.Layers() { // fmt.Println("- ", layer.LayerType()) // } // When iterating through packet.Layers() above, // if it lists Payload layer then that is the same as // this applicationLayer. applicationLayer contains the payload // applicationLayer := packet.ApplicationLayer() // if applicationLayer != nil { // fmt.Println("Application layer/Payload found.") // fmt.Printf("%s\n", applicationLayer.Payload()) // // Search for a string inside the payload // if strings.Contains(string(applicationLayer.Payload()), "HTTP") { // fmt.Println("HTTP found!") // } // } // Check for errors if err := packet.ErrorLayer(); err != nil { fmt.Println("Error decoding some part of the packet:", err) } }
//Returns both the source & destination IP. func getSrcDstIP(packet gopacket.Packet) (net.IP, net.IP) { ipLayer := packet.Layer(layers.LayerTypeIPv4) // Get IP data from this layer ip, _ := ipLayer.(*layers.IPv4) return ip.SrcIP, ip.DstIP }
func handlePacket(handle *pcap.Handle, packet gopacket.Packet) { ethLayer := packet.LinkLayer() if ethLayer == nil { return } eth, ok := ethLayer.(*layers.Ethernet) if !ok { return } ipLayer := packet.NetworkLayer() if ipLayer == nil { return } ip, ok := ipLayer.(*layers.IPv4) if !ok { return } tcpLayer := packet.Layer(layers.LayerTypeTCP) if tcpLayer == nil { return } tcp, ok := tcpLayer.(*layers.TCP) if !ok { return } // 服务器回应 SYN 请求 if tcp.SYN == true && tcp.ACK == true { ttl := uint8(0) switch { case ip.TTL > 128: //Solaris/AIX ttl = 254 - ip.TTL case ip.TTL > 64: // windows ttl = 128 - ip.TTL default: // linux ttl = 64 - ip.TTL } switch { case ttl > 10: ttl -= 4 case ttl > 5: ttl -= 2 case ttl > 2: ttl -= 1 default: return } ack := tcp.Seq + uint32(len(tcp.Payload)) + 1 data := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9} seq := tcp.Ack sendPacket(handle, eth.DstMAC, eth.SrcMAC, ip.DstIP, ip.SrcIP, tcp.DstPort, tcp.SrcPort, ip.Id+123, ttl, seq, ack, 258, data) seq += 2048 sendPacket(handle, eth.DstMAC, eth.SrcMAC, ip.DstIP, ip.SrcIP, tcp.DstPort, tcp.SrcPort, ip.Id+123, ttl, seq, ack, 258, nil) //go fmt.Printf("伪重置 %v:%v 的 tcp 连接。\r\n", ip.SrcIP, tcp.SrcPort) } }