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"))
}

发表回复