
大多数软件工程界的人都听说过 tc++pdump、wireshark 等
您很可能听说过 tcpdump 团队开发的 libpcap1 库,用于捕获流量并由 wireshark 使用。
这个库1提供了一个灵活的接口来捕获来自网络接口的流量并在代码中处理它。它提供了编写高性能代码的灵活性,并包含根据需要收集所需数据的尽可能多的业务逻辑。
最近我发现了一项任务,收集所需的数据包、分析它们并保存以供将来的手动审核是一个好主意。要手动检查,可以使用 wireshak 加载 pcap 文件并使用漂亮的 ui 手动检查收集的数据包。
最重要的部分,为什么是 go? go 是一种足够简单的语言,可以编写代码并由多个团队成员支持。它比 c 和 c++ 安全得多,并且其他人支持它所需的经验要少得多,而不会出现意外的意外。除非我们没有要求,必须使用很多高性能语言(c、c++、rust 等),否则我更喜欢选择 golang。
在我们做某事之前,最好先了解一下,我们想要实现什么结果?让我们定义一个简短的要求列表。
立即学习“go语言免费学习笔记(深入)”;
为了使实现尽可能简单,我们只定义几个点:
这些简单的几点足以了解如何使用 golang 的 libpcap1。
之后,在此基础上添加什么逻辑就只是想象的问题了。
在开始之前,我们先定义一下代码不适合生产。我们的目标是查看最小的示例并测试它是否运行良好。
我们将使用这些库:
在线证件照系统是一套完善的冲印行业解决方案,致力于解决用户线上拍摄证件照,拍摄最美最标准证件照的使命。证件照免费版功能:后台统计:当天制作、当天新增、支持规格、近7日统计规格列表:筛选查看、编辑用户列表:筛选查看常见问题:筛选查看、新增、编辑、删除小程序设置:应用设置、流量主设置小程序跳转:筛选查看、新增、编辑、删除关注公众号:引导设置系统要求:系统:Linux系统(centos x64)运行环境
1
未来代码中的接口将是 eth0,即使您的系统很可能会有不同的接口名称。
这是带有注释的代码,您可以复制并在自己的环境中尝试。
由于我们使用 libpcap1,我们的应用程序将使用 cgo 并且我们需要从 root 用户运行该应用程序。
package main
import (
"bytes"
"log/slog"
"net"
"os"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"github.com/google/gopacket/pcapgo"
)
const (
interfacename = "eth0"
snaplen = 1500
)
func main() {
slog.info("running our applicaiton...")
// get handler attached to an interface.
handle, err := pcap.openlive(interfacename, snaplen, true, pcap.blockforever)
if err != nil {
slog.error("could not openlive", slog.string("err", err.error()))
os.exit(1)
}
iface, err := net.interfacebyname(interfacename)
if err != nil {
slog.error("could not openlive", slog.string("err", err.error()))
os.exit(1)
}
// start new source reader.
source := gopacket.newpacketsource(handle, handle.linktype())
// this is suppose to be a file writer, but we will use memory, just for simplification.
filewriter := bytes.newbuffer(nil)
pcapwriter := pcapgo.newwriternanos(filewriter)
err = pcapwriter.writefileheader(snaplen, handle.linktype())
if err != nil {
slog.error("could not write pcap header", slog.string("err", err.error()))
os.exit(1)
}
// reading packages.
for packet := range source.packets() {
// filter by outcoming traffic only.
// to filter it, we need to compare mac addresses from out interface and source mac.
// to access a mac address we need to get an ethernet layer.
layer := packet.layer(layers.layertypeethernet)
ethernet, ok := layer.(*layers.ethernet)
if !ok {
slog.error("could not get ethernet layer")
continue
}
if !bytes.equal(ethernet.srcmac, iface.hardwareaddr) {
// our interface did not send this packet. it's not outcoming.
continue
}
// now we need to identify ipv4 layer.
layer = packet.layer(layers.layertypeipv4)
ipv4, ok := layer.(*layers.ipv4)
if !ok {
// it's not ipv4 traffic.
continue
}
if ipv4.dstip.isprivate() {
// do not collect private traffic.
continue
}
if ipv4.protocol != layers.ipprotocoludp {
// ignore not udp protocol.
continue
}
err = pcapwriter.writepacket(packet.metadata().captureinfo, packet.data())
if err != nil {
slog.error("could not write a packet to a pcap writer", slog.string("err", err.error()))
continue
}
slog.info("stored packet", slog.any("packet", packet))
// let's collect only 100k bytes, just for example perposes.
if filewriter.len() > 100000 {
break
}
}
slog.info("we have successfuly collected bytes", slog.int("bytes", filewriter.len()))
}
运行后,截断的输出如下所示:
2024/08/31 13:35:36 INFO Running our applicaiton... 2024/08/31 13:37:48 INFO Stored packet packet="PACKET: 105 bytes, wire length 105 cap length 105 ..." ... 2024/08/31 13:37:48 INFO Stored packet packet="PACKET: 1291 bytes, wire length 1291 cap length 1291 ..." 2024/08/31 13:37:48 INFO We have successfuly collected bytes bytes=101018
我希望这个最小的例子能够帮助人们使用 go 开始他们在这个领域的旅程。
如果您在日常任务中遇到任何您不知道如何做的新要求。别急着去问周围的人,私信我,自己研究一下。
研究和沟通是解决所有问题的关键。
libpcap 是一个用于网络流量捕获的便携式 c/c++ 库↩
以上就是使用 Golang 捕获流量的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号