111 lines
2.4 KiB
Go
111 lines
2.4 KiB
Go
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"log"
|
||
"net"
|
||
"os"
|
||
"os/signal"
|
||
"syscall"
|
||
|
||
"github.com/google/gopacket"
|
||
"github.com/google/gopacket/layers"
|
||
"github.com/google/gopacket/pcap"
|
||
"github.com/google/gopacket/pcapgo"
|
||
)
|
||
|
||
// 打印可用的网络接口信息
|
||
func printAvailableInterfaces() {
|
||
devices, err := pcap.FindAllDevs()
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
fmt.Println("可用的网络接口:")
|
||
for _, device := range devices {
|
||
fmt.Printf("名称: %s\n描述: %s\n地址: %+v\n\n", device.Name, device.Description, device.Addresses)
|
||
}
|
||
}
|
||
|
||
// 判断 IP 是否在链表中
|
||
func isIPInList(ip net.IP) bool {
|
||
for e := ipList.Front(); e != nil; e = e.Next() {
|
||
if e.Value.(net.IP).Equal(ip) {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// 打印捕获到的每个数据包的信息
|
||
func printPacketInfo(packet gopacket.Packet) {
|
||
ipLayer := packet.Layer(layers.LayerTypeIPv4)
|
||
|
||
if ipLayer != nil {
|
||
ip, _ := ipLayer.(*layers.IPv4)
|
||
ipMutex.Lock()
|
||
defer ipMutex.Unlock()
|
||
if !isIPInList(ip.SrcIP) {
|
||
ipList.PushBack(ip.SrcIP)
|
||
log.Printf("已添加源 IP: %s 到链表\n", ip.SrcIP)
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
func startPacketCapture() {
|
||
handle, err := pcap.OpenLive(*interfaceName, 65535, true, pcap.BlockForever)
|
||
if err != nil {
|
||
log.Fatalf("打开网络接口 %s 出错: %v", *interfaceName, err)
|
||
}
|
||
defer handle.Close()
|
||
|
||
defer func() {
|
||
fmt.Println("清理资源...")
|
||
if handle != nil {
|
||
handle.Close()
|
||
}
|
||
}()
|
||
|
||
err = handle.SetBPFFilter(*filter)
|
||
if err != nil {
|
||
log.Fatalf("设置 BPF 过滤器出错: %v", err)
|
||
}
|
||
|
||
var pcapWriter *pcapgo.Writer
|
||
if *outputFile != "" {
|
||
file, err := os.Create(*outputFile)
|
||
if err != nil {
|
||
log.Fatalf("创建输出文件出错: %v", err)
|
||
}
|
||
defer file.Close()
|
||
|
||
pcapWriter = pcapgo.NewWriter(file)
|
||
err = pcapWriter.WriteFileHeader(65535, layers.LinkTypeEthernet)
|
||
if err != nil {
|
||
log.Fatalf("写入全局头部出错: %v", err)
|
||
}
|
||
}
|
||
|
||
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
|
||
fmt.Printf("正在监听网络接口 %s,使用过滤器 '%s'...\n", *interfaceName, *filter)
|
||
|
||
sigChan := make(chan os.Signal, 1)
|
||
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
|
||
|
||
go func() {
|
||
for packet := range packetSource.Packets() {
|
||
printPacketInfo(packet)
|
||
if pcapWriter != nil {
|
||
err := pcapWriter.WritePacket(packet.Metadata().CaptureInfo, packet.Data())
|
||
if err != nil {
|
||
log.Printf("写入数据包出错: %v", err)
|
||
}
|
||
}
|
||
}
|
||
}()
|
||
|
||
<-sigChan
|
||
fmt.Println("\n停止抓包...")
|
||
}
|