Windows和Linux下使用Gopacket监控网卡流量
2020-04-04 本文已影响0人
星落纷纷
一.获取gopacket
go get github.com/google/gopacket
二.编译
1.windows
直接编译即可
2.linux
不能从windows下交叉编译到linux,(安装了MINGW也不行),所以需要在linux上编译。
编译前准备:(Centos示例)
yum -y install gcc
yum -y install gcc-c++
yum -y install libpcap
yum -y install libpcap-devel
三.示例代码
var ListenNetwork = "Adapter for loopback traffic capture"//监听的网卡
var ListenPort ="80"//监听的端口
func main() {
ptrListenNetwork:= flag.String("i","eth0","监听的网卡")
ptrListenPort:=flag.String("p","80","监听的端口")
flag.Parse()
ListenNetwork=*ptrListenNetwork
ListenPort=*ptrListenPort
var deviceTarget=""
devices, err := pcap.FindAllDevs()
if err!=nil{
panic(err.Error())
}
for _,v:=range devices{
fmt.Println(v.Name,v.Description)
if v.Description==ListenNetwork{//win10 这里用Description来判断网卡,主要是Name太乱了
deviceTarget=v.Name
break
}
if v.Name==ListenNetwork{//linux
deviceTarget=v.Name
break
}
}
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGHUP, syscall.SIGINT, syscall.SIGKILL)
ctx, cancel := context.WithCancel(context.Background())
if deviceTarget!=""{
go listenPacket(deviceTarget,ctx)
for {
select {
case <-signalChan:
cancel()
return
}
}
}
}
func listenPacket(iface string, ctx context.Context) {
handle,err:=pcap.OpenLive(iface,65536,true,-time.Millisecond * 10)
if err!=nil{
fmt.Println(err.Error())
return
}
defer handle.Close()
err=handle.SetBPFFilter(fmt.Sprintf("(src port %s) or (dst port %s)",listenPort,listenPort))
if err!=nil{
fmt.Println(err.Error())
return
}
ps := gopacket.NewPacketSource(handle, handle.LinkType())
var rxLen int64
var txLen int64
var packId int64
fmt.Println(fmt.Sprintf("listen device:%s,port:%s",iface,ListenPort))
for {
select {
case <-ctx.Done():
return
case p := <-ps.Packets():
//fmt.Println(p.Metadata().CaptureInfo.Timestamp,p.Metadata().CaptureInfo.Length)
//fmt.Println(p.NetworkLayer().NetworkFlow().String())
//fmt.Println(p.TransportLayer().TransportFlow().Endpoints())
srcEndpoint,dstEndpoint:=p.TransportLayer().TransportFlow().Endpoints()
srcPort,dstPort:=srcEndpoint.String(),dstEndpoint.String()
flag1:=false
if srcPort==ListenPort{
packId++
flag1=true
l:=p.Metadata().Length
txLen+=int64(l)
fmt.Println(fmt.Sprintf("PackId:%d,Port:%s send package,len:%d,stats[RX:%d,TX:%d]",packId,ListenPort,l,rxLen,txLen))
}
if dstPort==ListenPort{
if !flag1{
packId++
}
l:=p.Metadata().Length
rxLen+=int64(l)
fmt.Println(fmt.Sprintf("PackId:%d,Port:%s get package,len:%d,stats[RX:%d,TX:%d]",packId,ListenPort,l,rxLen,txLen))
}
}
}
}
注意事项
linux下编译的包移植到其它机器运行,仍依赖于libpcap,但是不需要libpcap-devel
yum -y install libpcap