原文链接:https://www.devdungeon.com/content/packet-capture-injection-and-analysis-gopacket

接口文档:https://godoc.org/github.com/google/gopacket

Demo1(Find devices):

package main

import (
"fmt"
"log"
"github.com/google/gopacket/pcap"
) func main() {
// Find all devices
devices, err := pcap.FindAllDevs()
if err != nil {
log.Fatal(err)
} // Print device information
fmt.Println("Devices found:")
for _, device := range devices {
fmt.Println("\nName: ", device.Name)
fmt.Println("Description: ", device.Description)
fmt.Println("Devices addresses: ", device.Description)
for _, address := range device.Addresses {
fmt.Println("- IP address: ", address.IP)
fmt.Println("- Subnet mask: ", address.Netmask)
}
}
}

测试结果:

[root@wangjq device]# go run main.go
Devices found: Name: br0
Description:
Devices addresses:
- IP address: 10.95.149.186
- Subnet mask: ffffffc0
- IP address: fe80:::61ff:fe04:81d3
- Subnet mask: ffffffffffffffff0000000000000000 Name: virbr0
Description:
Devices addresses:
- IP address: 192.168.122.1
- Subnet mask: ffffff00 Name: docker0
Description:
Devices addresses:
- IP address: 172.17.0.1
- Subnet mask: ffff0000 Name: nflog
Description: Linux netfilter log (NFLOG) interface
Devices addresses: Linux netfilter log (NFLOG) interface Name: nfqueue
Description: Linux netfilter queue (NFQUEUE) interface
Devices addresses: Linux netfilter queue (NFQUEUE) interface Name: usbmon1
Description: USB bus number
Devices addresses: USB bus number Name: usbmon2
Description: USB bus number
Devices addresses: USB bus number Name: ens3
Description:
Devices addresses: Name: usbmon3
Description: USB bus number
Devices addresses: USB bus number Name: ens4
Description:
Devices addresses:
- IP address: fe80::7f29:1f32:6a3:2a59
- Subnet mask: ffffffffffffffff0000000000000000 Name: usbmon4
Description: USB bus number
Devices addresses: USB bus number Name: any
Description: Pseudo-device that captures on all interfaces
Devices addresses: Pseudo-device that captures on all interfaces Name: lo
Description:
Devices addresses:
- IP address: 127.0.0.1
- Subnet mask: ff000000
- IP address: ::
- Subnet mask: ffffffffffffffffffffffffffffffff

Demo2(Open Device for Live Capture):

package main

import (
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/pcap"
"log"
"time"
) var (
device string = "eth0"
snapshot_len int32 =
promiscuous bool = false
err error
timeout time.Duration = * time.Second
handle *pcap.Handle
) func main() {
// Open device
handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout)
if err != nil {log.Fatal(err) }
defer handle.Close() // Use the handle as a packet source to process all packets
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
// Process packet here
fmt.Println(packet)
}
}

测试结果:

PACKET:  bytes, truncated, wire length  cap length  @ -- ::00.069751 + HKT
- Layer ( bytes) = Ethernet {Contents=[....] Payload=[....] SrcMAC=:::3d::f1 DstMAC=:ea:cb:5d:e4:f7 EthernetType=IPv4 Length=}
- Layer ( bytes) = IPv4 {Contents=[....] Payload=[....] Version= IHL= TOS= Length= Id= Flags=DF FragOffset= TTL= Protocol=TCP Checksum= SrcIP=10.95.149.186 DstIP=172.24.46.56 Options=[] Padding=[]}
- Layer ( bytes) = TCP {Contents=[....] Payload=[....] SrcPort=(ssh) DstPort= Seq= Ack= DataOffset= FIN=false SYN=false RST=false PSH=false ACK=true URG=false ECE=false CWR=false NS=false Window= Checksum= Urgent= Options=[] Padding=[]}
- Layer ( bytes) = Payload byte(s) PACKET: bytes, wire length cap length @ -- ::00.069956 + HKT
- Layer ( bytes) = Ethernet {Contents=[....] Payload=[....] SrcMAC=:ea:cb:5d:e4:f7 DstMAC=:::3d::f1 EthernetType=IPv4 Length=}
- Layer ( bytes) = IPv4 {Contents=[....] Payload=[....] Version= IHL= TOS= Length= Id= Flags=DF FragOffset= TTL= Protocol=TCP Checksum= SrcIP=172.24.46.56 DstIP=10.95.149.186 Options=[] Padding=[]}
- Layer ( bytes) = TCP {Contents=[....] Payload=[] SrcPort= DstPort=(ssh) Seq= Ack= DataOffset= FIN=false SYN=false RST=false PSH=false ACK=true URG=false ECE=false CWR=false NS=false Window= Checksum= Urgent= Options=[] Padding=[]}

Demo3(Write Pcap File):

package main

import (
"fmt"
"os"
"time" "github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"github.com/google/gopacket/pcapgo"
) var (
deviceName string = "eth0"
snapshotLen int32 =
promiscuous bool = false
err error
timeout time.Duration = - * time.Second
handle *pcap.Handle
packetCount int =
) func main() {
// Open output pcap file and write header
f, _ := os.Create("test.pcap")
w := pcapgo.NewWriter(f)
w.WriteFileHeader(snapshotLen, layers.LinkTypeEthernet)
defer f.Close() // Open the device for capturing
handle, err = pcap.OpenLive(deviceName, snapshotLen, promiscuous, timeout)
if err != nil {
fmt.Printf("Error opening device %s: %v", deviceName, err)
os.Exit()
}
defer handle.Close() // Start processing packets
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
// Process packet here
fmt.Println(packet)
w.WritePacket(packet.Metadata().CaptureInfo, packet.Data())
packetCount++ // Only capture 100 and then stop
if packetCount > {
break
}
}
}

Demo4(Open Pcap File):

package main

// Use tcpdump to create a test file
// tcpdump -w test.pcap
// or use the example above for writing pcap files import (
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/pcap"
"log"
) var (
pcapFile string = "test.pcap"
handle *pcap.Handle
err error
) func main() {
// Open file instead of device
handle, err = pcap.OpenOffline(pcapFile)
if err != nil { log.Fatal(err) }
defer handle.Close() // Loop through packets in file
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
fmt.Println(packet)
}
}

Demo5(Setting Filters):

package main

import (
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/pcap"
"log"
"time"
) var (
device string = "eth0"
snapshot_len int32 =
promiscuous bool = false
err error
timeout time.Duration = * time.Second
handle *pcap.Handle
) func main() {
// Open device
handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout)
if err != nil {
log.Fatal(err)
}
defer handle.Close() // Set filter
var filter string = "tcp and port 80"
err = handle.SetBPFFilter(filter)
if err != nil {
log.Fatal(err)
}
fmt.Println("Only capturing TCP port 80 packets.") packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
// Do something with a packet here.
fmt.Println(packet)
} }

Demo6(Decoding Packet Layers):

package main

import (
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"log"
"strings"
"time"
) var (
device string = "eth0"
snapshotLen int32 =
promiscuous bool = false
err error
timeout time.Duration = * time.Second
handle *pcap.Handle
) func main() {
// Open device
handle, err = pcap.OpenLive(device, snapshotLen, promiscuous, timeout)
if err != nil {log.Fatal(err) }
defer handle.Close() packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
printPacketInfo(packet)
}
} func printPacketInfo(packet gopacket.Packet) {
// Let's see if the packet is an ethernet packet
ethernetLayer := packet.Layer(layers.LayerTypeEthernet)
if ethernetLayer != nil {
fmt.Println("Ethernet layer detected.")
ethernetPacket, _ := ethernetLayer.(*layers.Ethernet)
fmt.Println("Source MAC: ", ethernetPacket.SrcMAC)
fmt.Println("Destination MAC: ", ethernetPacket.DstMAC)
// Ethernet type is typically IPv4 but could be ARP or other
fmt.Println("Ethernet type: ", ethernetPacket.EthernetType)
fmt.Println()
} // Let's see if the packet is IP (even though the ether type told us)
ipLayer := packet.Layer(layers.LayerTypeIPv4)
if ipLayer != nil {
fmt.Println("IPv4 layer detected.")
ip, _ := ipLayer.(*layers.IPv4) // IP layer variables:
// Version (Either 4 or 6)
// IHL (IP Header Length in 32-bit words)
// TOS, Length, Id, Flags, FragOffset, TTL, Protocol (TCP?),
// Checksum, SrcIP, DstIP
fmt.Printf("From %s to %s\n", ip.SrcIP, ip.DstIP)
fmt.Println("Protocol: ", ip.Protocol)
fmt.Println()
} // Let's see if the packet is TCP
tcpLayer := packet.Layer(layers.LayerTypeTCP)
if tcpLayer != nil {
fmt.Println("TCP layer detected.")
tcp, _ := tcpLayer.(*layers.TCP) // TCP layer variables:
// SrcPort, DstPort, Seq, Ack, DataOffset, Window, Checksum, Urgent
// Bool flags: FIN, SYN, RST, PSH, ACK, URG, ECE, CWR, NS
fmt.Printf("From port %d to %d\n", tcp.SrcPort, tcp.DstPort)
fmt.Println("Sequence number: ", tcp.Seq)
fmt.Println()
} // Iterate over all layers, printing out each layer type
fmt.Println("All packet layers:")
for _, layer := range packet.Layers() {
fmt.Println("- ", layer.LayerType())
} // When iterating through packet.Layers() above,
// if it lists Payload layer then that is the same as
// this applicationLayer. applicationLayer contains the payload
applicationLayer := packet.ApplicationLayer()
if applicationLayer != nil {
fmt.Println("Application layer/Payload found.")
fmt.Printf("%s\n", applicationLayer.Payload()) // Search for a string inside the payload
if strings.Contains(string(applicationLayer.Payload()), "HTTP") {
fmt.Println("HTTP found!")
}
} // Check for errors
if err := packet.ErrorLayer(); err != nil {
fmt.Println("Error decoding some part of the packet:", err)
}
}

Demo7(Creating and Sending Packets):

package main

import (
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"log"
"net"
"time"
) var (
device string = "eth0"
snapshot_len int32 =
promiscuous bool = false
err error
timeout time.Duration = * time.Second
handle *pcap.Handle
buffer gopacket.SerializeBuffer
options gopacket.SerializeOptions
) func main() {
// Open device
handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout)
if err != nil {log.Fatal(err) }
defer handle.Close() // Send raw bytes over wire
rawBytes := []byte{, , }
err = handle.WritePacketData(rawBytes)
if err != nil {
log.Fatal(err)
} // Create a properly formed packet, just with
// empty details. Should fill out MAC addresses,
// IP addresses, etc.
buffer = gopacket.NewSerializeBuffer()
gopacket.SerializeLayers(buffer, options,
&layers.Ethernet{},
&layers.IPv4{},
&layers.TCP{},
gopacket.Payload(rawBytes),
)
outgoingPacket := buffer.Bytes()
// Send our packet
err = handle.WritePacketData(outgoingPacket)
if err != nil {
log.Fatal(err)
} // This time lets fill out some information
ipLayer := &layers.IPv4{
SrcIP: net.IP{, , , },
DstIP: net.IP{, , , },
}
ethernetLayer := &layers.Ethernet{
SrcMAC: net.HardwareAddr{0xFF, 0xAA, 0xFA, 0xAA, 0xFF, 0xAA},
DstMAC: net.HardwareAddr{0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD},
}
tcpLayer := &layers.TCP{
SrcPort: layers.TCPPort(),
DstPort: layers.TCPPort(),
}
// And create the packet with the layers
buffer = gopacket.NewSerializeBuffer()
gopacket.SerializeLayers(buffer, options,
ethernetLayer,
ipLayer,
tcpLayer,
gopacket.Payload(rawBytes),
)
outgoingPacket = buffer.Bytes()
}

Demo8(More on Creating/Decoding Packets):

package main

import (
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
) func main() {
// If we don't have a handle to a device or a file, but we have a bunch
// of raw bytes, we can try to decode them in to packet information // NewPacket() takes the raw bytes that make up the packet as the first parameter
// The second parameter is the lowest level layer you want to decode. It will
// decode that layer and all layers on top of it. The third layer
// is the type of decoding: default(all at once), lazy(on demand), and NoCopy
// which will not create a copy of the buffer // Create an packet with ethernet, IP, TCP, and payload layers
// We are creating one we know will be decoded properly but
// your byte source could be anything. If any of the packets
// come back as nil, that means it could not decode it in to
// the proper layer (malformed or incorrect packet type)
payload := []byte{, , }
options := gopacket.SerializeOptions{}
buffer := gopacket.NewSerializeBuffer()
gopacket.SerializeLayers(buffer, options,
&layers.Ethernet{},
&layers.IPv4{},
&layers.TCP{},
gopacket.Payload(payload),
)
rawBytes := buffer.Bytes() // Decode an ethernet packet
ethPacket :=
gopacket.NewPacket(
rawBytes,
layers.LayerTypeEthernet,
gopacket.Default,
) // with Lazy decoding it will only decode what it needs when it needs it
// This is not concurrency safe. If using concurrency, use default
ipPacket :=
gopacket.NewPacket(
rawBytes,
layers.LayerTypeIPv4,
gopacket.Lazy,
) // With the NoCopy option, the underlying slices are referenced
// directly and not copied. If the underlying bytes change so will
// the packet
tcpPacket :=
gopacket.NewPacket(
rawBytes,
layers.LayerTypeTCP,
gopacket.NoCopy,
) fmt.Println(ethPacket)
fmt.Println(ipPacket)
fmt.Println(tcpPacket)
}

Demo9(Custom Layers):

package main

import (
"fmt"
"github.com/google/gopacket"
) // Create custom layer structure
type CustomLayer struct {
// This layer just has two bytes at the front
SomeByte byte
AnotherByte byte
restOfData []byte
} // Register the layer type so we can use it
// The first argument is an ID. Use negative
// or 2000+ for custom layers. It must be unique
var CustomLayerType = gopacket.RegisterLayerType(
,
gopacket.LayerTypeMetadata{
"CustomLayerType",
gopacket.DecodeFunc(decodeCustomLayer),
},
) // When we inquire about the type, what type of layer should
// we say it is? We want it to return our custom layer type
func (l CustomLayer) LayerType() gopacket.LayerType {
return CustomLayerType
} // LayerContents returns the information that our layer
// provides. In this case it is a header layer so
// we return the header information
func (l CustomLayer) LayerContents() []byte {
return []byte{l.SomeByte, l.AnotherByte}
} // LayerPayload returns the subsequent layer built
// on top of our layer or raw payload
func (l CustomLayer) LayerPayload() []byte {
return l.restOfData
} // Custom decode function. We can name it whatever we want
// but it should have the same arguments and return value
// When the layer is registered we tell it to use this decode function
func decodeCustomLayer(data []byte, p gopacket.PacketBuilder) error {
// AddLayer appends to the list of layers that the packet has
p.AddLayer(&CustomLayer{data[], data[], data[:]}) // The return value tells the packet what layer to expect
// with the rest of the data. It could be another header layer,
// nothing, or a payload layer. // nil means this is the last layer. No more decoding
// return nil // Returning another layer type tells it to decode
// the next layer with that layer's decoder function
// return p.NextDecoder(layers.LayerTypeEthernet) // Returning payload type means the rest of the data
// is raw payload. It will set the application layer
// contents with the payload
return p.NextDecoder(gopacket.LayerTypePayload)
} func main() {
// If you create your own encoding and decoding you can essentially
// create your own protocol or implement a protocol that is not
// already defined in the layers package. In our example we are just
// wrapping a normal ethernet packet with our own layer.
// Creating your own protocol is good if you want to create
// some obfuscated binary data type that was difficult for others
// to decode // Finally, decode your packets:
rawBytes := []byte{0xF0, 0x0F, , , , , }
packet := gopacket.NewPacket(
rawBytes,
CustomLayerType,
gopacket.Default,
)
fmt.Println("Created packet out of raw bytes.")
fmt.Println(packet) // Decode the packet as our custom layer
customLayer := packet.Layer(CustomLayerType)
if customLayer != nil {
fmt.Println("Packet was successfully decoded with custom layer decoder.")
customLayerContent, _ := customLayer.(*CustomLayer)
// Now we can access the elements of the custom struct
fmt.Println("Payload: ", customLayerContent.LayerPayload())
fmt.Println("SomeByte element:", customLayerContent.SomeByte)
fmt.Println("AnotherByte element:", customLayerContent.AnotherByte)
}
}

Demo10(Decoding Packets Faster):

package main

import (
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"log"
"time"
) var (
device string = "eth0"
snapshot_len int32 =
promiscuous bool = false
err error
timeout time.Duration = * time.Second
handle *pcap.Handle
// Will reuse these for each packet
ethLayer layers.Ethernet
ipLayer layers.IPv4
tcpLayer layers.TCP
) func main() {
// Open device
handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout)
if err != nil {
log.Fatal(err)
}
defer handle.Close() packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
parser := gopacket.NewDecodingLayerParser(
layers.LayerTypeEthernet,
&ethLayer,
&ipLayer,
&tcpLayer,
)
foundLayerTypes := []gopacket.LayerType{} err := parser.DecodeLayers(packet.Data(), &foundLayerTypes)
if err != nil {
fmt.Println("Trouble decoding layers: ", err)
} for _, layerType := range foundLayerTypes {
if layerType == layers.LayerTypeIPv4 {
fmt.Println("IPv4: ", ipLayer.SrcIP, "->", ipLayer.DstIP)
}
if layerType == layers.LayerTypeTCP {
fmt.Println("TCP Port: ", tcpLayer.SrcPort, "->", tcpLayer.DstPort)
fmt.Println("TCP SYN:", tcpLayer.SYN, " | ACK:", tcpLayer.ACK)
}
}
}
}

使用 gopacket 进行数据包捕获,注入和分析的更多相关文章

  1. Wireshark入门与进阶---数据包捕获与保存的最基本流程

    Wireshark入门与进阶系列(一) "君子生非异也.善假于物也"---荀子 本文由CSDN-蚍蜉撼青松 [主页:http://blog.csdn.net/howeverpf]原 ...

  2. Linux 中的网络数据包捕获

    Linux 中的网络数据包捕获 Ashish Chaurasia, 工程师 简介: 本教程介绍了捕获和操纵数据包的不同机制.安全应用程序,如 VPN.防火墙和嗅探器,以及网络应用程序,如路由程序,都依 ...

  3. 基于tcpdump的Android智能移动终端数据包捕获完整解决方案

    如何在Android智能手机上捕获数据包? 本文由CSDN-蚍蜉撼青松[主页:http://blog.csdn.net/howeverpf]原创,转载请注明出处! 当前Android系统越来越流行,无 ...

  4. dpdk数据包捕获技术笔记1

    1 高效捕包技术的重要性 高性能系统需要在很短的时间内,成功的收集和处理大量的数据,目标系统的实时数据需要被收集,管里和控制. 2 传统的数据包捕获机制 Inter指出,影响数据包捕获性能主要原因是系 ...

  5. Bluetooth数据包捕获

    目录 1. 前提 2. 开启功能 3. 抓包 这里介绍一种在Android上捕获蓝牙数据包的方法 1. 前提 首先你要有一部Android手机 然后你的Android系统版本要在4.4及以上 我没有做 ...

  6. 【转】Bluetooth数据包捕获

    原文网址:http://www.cnblogs.com/hzl6255/p/3887013.html 这里介绍一种在Android上捕获蓝牙数据包的方法 1. 前提 首先你要有一部Android手机  ...

  7. 基于DPDK的高效数据包捕获技术分析与应用

    被NFV的论文折磨了两天,今天上午看了两篇DPDK的综述. 传统的包捕获机制 1. BPF 两个组成部分:转发部分和过滤部分. 转发部分负责从链路层提取数据包并转发给过滤部分. 过滤部分根据过滤规则, ...

  8. linux简单的数据包捕获分析

    有时我们会遇到一些问题,需要捕捉数据包分析,当手头有没有专业的抓图工具,您可以使用tcpdump相反,看看(一般版本附带这个工具) 比如,我们要分析eth0与接口192.168.7.188 这个对象I ...

  9. vlc-android对于通过Live555接收到音视频数据包后的处理分析

    通过ndk-gdb跟踪调试vlc-android来分析从连接到RTSP服务器并接收到音视频数据包后的处理过程. 首先,从前面的文章有分析过vlc-android的处理过程通过线程函数Run()(Src ...

随机推荐

  1. ES数据库 常用 java api

    一.获取类api get API允许根据其id从索引中获取类型化的JSON文档. 以下示例从名为twitter的索引中获取一个JSON文档,该索引名为tweet,id值为1: GetResponse ...

  2. IO—》字节流&字符流

    字节流 一.字节输出流OutputStream OutputStream此抽象类,是表示输出字节流的所有类的超类.操作的数据都是字节,定义了输出字节流的基本共性功能方法. FileOutputStre ...

  3. 《Python Web开发实战》|百度网盘免费下载|Python Web开发

    <Python Web开发实战>|百度网盘免费下载|Python Web开发 提取码:rnz4 内容简介 这本书涵盖了Web开发的方方面面,可以分为如下部分: 1. 使用最新的Flask ...

  4. 动态规划入门(dp)

    dp的基本思想,是把大问题转化成一个个小问题,然后递归解决. 所以本质思想的话还是递归. dp最重要的是要找到状态转移方程,也就是把大问题化解的过程. 举个例子 一个数字金字塔 在上面的数字三角形中寻 ...

  5. Seaborn实现回归分析

    import numpy as np import pandas as pd from scipy import stats,integrate import matplotlib.pyplot as ...

  6. NOI On Line 提高组题解

    (话说其实我想填的是去年CSP的坑...但是貌似有一道题我还不会写咕咕咕... 先写一下这一次的题解吧. T1:序列.题意省略. 两种操作.这种题要先分析部分分 给出了全部都是2操作的子任务. 发现A ...

  7. 谁来教我渗透测试——黑客必须掌握的Linux基础

    上一篇我们学习了Windows基础,今天我们来看一看作为一名渗透测试工程师都需要掌握哪些Linux知识.今天的笔记一共分为如下三个部分: Linux系统的介绍 Linux系统目录结构.常用命令 Lin ...

  8. nodeJs + js 大文件分片上传

    简单的文件上传 一.准备文件上传的条件: 1.安装nodejs环境 2.安装vue环境 3.验证环境是否安装成功 二.实现上传步骤 1.前端部分使用 vue-cli 脚手架,搭建一个 demo 版本, ...

  9. Dropwizard+jersey+MDC实现日志跟踪以及接口响应时间统计

    一.实现接口响应时间统计 1.1添加全局请求过滤器并注册 import org.apache.log4j.MDC; import org.slf4j.Logger; import org.slf4j. ...

  10. 迷之自信的Single_User Mode

    Alter database Set Single_User 对于任何DBA来说,恐怕都不陌生.在我们需要获取数据库独占访问权来做一些数据库紧急维护的时候,这可能是大多数DBA的首选,但它真的可以实现 ...