package main
import (
"errors"
"flag"
"fmt"
"log"
"net"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
var (
downStreamDataSize = 0 // 单位时间内下行的总字节数
upStreamDataSize = 0 // 单位时间内上行的总字节数
deviceName = flag.String("i", `eth0`, "network interface device name") // 要监控的网卡名称
)
type IfaceInfo struct {
NPFName string
Description string
NickName string
IPv4 string
}
var ListenNetwork = "Adapter for loopback traffic capture" //监听的网卡
func getTargetDeviceName() string {
ListenNetwork = "Microsoft Network Adapter Multiplexor Driver"
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
}
}
return deviceTarget
}
func main() {
flag.Parse()
deviceName := getTargetDeviceName()
// 获取网卡handler,可用于读取或写入数据包
handle, err := pcap.OpenLive(deviceName, 1024, true, 30*time.Second)
if err != nil {
log.Fatal(err)
}
defer handle.Close()
// 开启子线程,每一秒计算一次该秒内的数据包大小平均值,并将下载、上传总量置零
go monitor()
// 开始抓包
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
// 只获取以太网帧
ethernetLayer := packet.Layer(layers.LayerTypeEthernet)
if ethernetLayer != nil {
ethernet := ethernetLayer.(*layers.Ethernet)
// 如果封包的目的MAC是本机则表示是下行的数据包,否则为上行
if ethernet.DstMAC.String() == getMacAddr() {
downStreamDataSize += len(packet.Data()) // 统计下行封包总大小
} else {
upStreamDataSize += len(packet.Data()) // 统计上行封包总大小
}
}
}
}
// 开启子线程,每一秒计算一次该秒内的数据包大小平均值,并将下载、上传总量置零
func monitor() {
for {
fmt.Printf("\rDown: %.2f kb/s \t Up: %.2f kb/s",
float32(downStreamDataSize)/1024/5, float32(upStreamDataSize)/1024/5)
downStreamDataSize = 0
upStreamDataSize = 0
time.Sleep(5 * time.Second)
}
}
// 获取本机网卡的MAC地址
func getMacAddr() string {
interfaces, err := net.Interfaces()
if err != nil {
panic(err)
}
for _, i := range interfaces {
if i.Name == "wq" {
return i.HardwareAddr.String()
}
}
panic(errors.New("no device found with the given name"))
}