一.獲取gopacket
go get github.com/google/gopacket
二.編譯
1.windows
直接編譯即可
2.linux
不能從windows下交叉編譯到linux衬衬,(安裝了MINGW也不行)买猖,所以需要在linux上編譯。
編譯前準(zhǔn)備:(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"http://監(jiān)聽的網(wǎng)卡
var ListenPort ="80"http://監(jiān)聽的端口
func main() {
ptrListenNetwork:= flag.String("i","eth0","監(jiān)聽的網(wǎng)卡")
ptrListenPort:=flag.String("p","80","監(jiān)聽的端口")
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來判斷網(wǎng)卡滋尉,主要是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))
}
}
}
}
注意事項(xiàng)
linux下編譯的包移植到其它機(jī)器運(yùn)行玉控,仍依賴于libpcap,但是不需要libpcap-devel
yum -y install libpcap