func (b PCAPBackend) ExtractIps(reader io.Reader, ips *ipset.Set) (uint64, error) { packets := uint64(0) pr, err := pcapgo.NewReader(reader) if err != nil { return 0, err } var eth layers.Ethernet var dot1q layers.Dot1Q var ip4 layers.IPv4 var ip6 layers.IPv6 var tcp layers.TCP parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ð, &dot1q, &ip4, &ip6, &tcp) decoded := []gopacket.LayerType{} for { packetData, _, err := pr.ReadPacketData() packets++ if err == io.EOF { break } if err != nil { return packets, err } err = parser.DecodeLayers(packetData, &decoded) for _, layerType := range decoded { switch layerType { case layers.LayerTypeIPv6: ips.AddIP(ip6.SrcIP) ips.AddIP(ip6.DstIP) case layers.LayerTypeIPv4: ips.AddIP(ip4.SrcIP) ips.AddIP(ip4.DstIP) } } } return packets, nil }
func PCAP2SFlowReplay(addr string, port int, file string, pps uint32, ppflow uint32) error { var nbPackets, packetsBytes, sflowSampleSeq, sflowSeq, droppedPackets uint32 if pps < minPPS { return fmt.Errorf("Minimal packet per seconds is %d", minPPS) } conn, err := newUDPConnection(addr, port) if err != nil { return fmt.Errorf("UDP connection error: %s", err.Error()) } conn.SetWriteBuffer(256 * 1024) f, err := os.Open(file) if err != nil { return fmt.Errorf("PCAP OpenOffline error(\"%s\"): %s", file, err.Error()) } defer f.Close() handleRead, err := pcapgo.NewReader(f) if err != nil { return fmt.Errorf("PCAP OpenOffline error(handle to read packet): %s", err.Error()) } var running atomic.Value running.Store(true) var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() ticker := time.NewTicker(1 * time.Second) defer ticker.Stop() oldNbPackets := atomic.LoadUint32(&nbPackets) for running.Load() == true { <-ticker.C nb := atomic.LoadUint32(&nbPackets) dpkts := nb - oldNbPackets oldNbPackets = nb dropped := atomic.LoadUint32(&droppedPackets) logging.GetLogger().Debugf("%d packets replayed, pps %d, nbSFlowMsgDropped %d", nb, dpkts, dropped) } }() throt := throttle{maxHitPerSecond: pps} var packets [][]byte for { data, _, err := handleRead.ReadPacketData() if err != nil && err != io.EOF { logging.GetLogger().Debug("Capture file has been cut in the middle of a packet", err.Error()) break } else if err == io.EOF { logging.GetLogger().Debug("End of capture file") break } else { atomic.AddUint32(&nbPackets, 1) atomic.AddUint32(&packetsBytes, uint32(len(data))) dataCopy := make([]byte, len(data)) copy(dataCopy, data) packets = append(packets, dataCopy) if (atomic.LoadUint32(&nbPackets) % ppflow) != 0 { continue } throt.startHook(ppflow) sendPackets(conn, &packets, &sflowSampleSeq, &sflowSeq, &droppedPackets) throt.endHook() } } if len(packets) > 0 { sendPackets(conn, &packets, &sflowSampleSeq, &sflowSeq, &droppedPackets) } running.Store(false) wg.Wait() logging.GetLogger().Info("PCAP Trace replay finished") return nil }
func main() { pcaptrace := flag.String("trace", "", "PCAP trace file to read") pps := flag.Uint("pps", 1000, "Packets per second") PktsPerFlow := flag.Uint("pktspersflow", 5, "Number of Packets per SFlow Datagram") flag.CommandLine.Usage = usage flag.Parse() if *pcaptrace == "" { usage() os.Exit(1) } if *pps < MinPPS { logging.GetLogger().Fatal("Minimal packet per seconds is ", MinPPS) } sflowAgent := strings.Split(os.Args[len(os.Args)-1], ":") AgentAddr := sflowAgent[0] AgentPort := 6345 if len(sflowAgent) == 2 { var err error AgentPort, err = strconv.Atoi(sflowAgent[1]) if err != nil { logging.GetLogger().Fatal("Can't parse UDP port ", err) } } conn, err := NewUDPConnection(AgentAddr, AgentPort) if err != nil { logging.GetLogger().Fatal("UDP connection error ", err) } conn.SetWriteBuffer(256 * 1024) f, err := os.Open(*pcaptrace) if err != nil { logging.GetLogger().Fatal("PCAP OpenOffline error (", *pcaptrace, ")", err) } defer f.Close() handleRead, err := pcapgo.NewReader(f) if err != nil { logging.GetLogger().Fatal("PCAP OpenOffline error (handle to read packet)", err) } go AsyncProgressInfo() throttle := Throttle{MaxHitPerSecond: *pps} var packets [][]byte for { data, _, err := handleRead.ReadPacketData() if err != nil && err != io.EOF { logging.GetLogger().Debug("Capture file has been cut in the middle of a packet", err.Error()) break } else if err == io.EOF { logging.GetLogger().Debug("End of capture file") break } else { NbPackets++ PacketsBytes += uint(len(data)) dataCopy := make([]byte, len(data)) copy(dataCopy, data) packets = append(packets, dataCopy) if (NbPackets % *PktsPerFlow) != 0 { continue } throttle.StartHook(*PktsPerFlow) sendPackets(conn, &packets) throttle.EndHook() } } if len(packets) > 0 { sendPackets(conn, &packets) } logging.GetLogger().Info("PCAP Trace replay finished") return }