前言
最近有了一个抓取网络数据包来分析的需求,最近在使用go语言,于是乎,决定是用go语言来进行抓包分析。使用的Google的gopacket包来进行。基于的是libcap包。
github地址:https://github.com/google/gopacket
我并不喜欢GoDoc的行文风格,对于demo可以看着这里的文章。(自备梯子)
http://www.devdungeon.com/content/packet-capture-injection-and-analysis-gopacket
离线pcap包解析
package main
import (
"fmt"
"log"
"reflect"
"strings"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
func main() {
path := "/Users/liruopeng/Downloads/test2.pcap"
handler, err := pcap.OpenOffline(path)
if err != nil {
log.Fatal(err)
}
defer handler.Close()
packetSource := gopacket.NewPacketSource(handler, handler.LinkType())
i := 0
for packet := range packetSource.Packets() {
// if i < 1 {
// fmt.Println(packet)
// // break
// }
i++
if i == 2915 {
printPacketInfo(packet)
}
}
fmt.Println(i)
}
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, some := tcpLayer.(*layers.TCP)
// tcp := tcpLayer
fmt.Println(reflect.TypeOf(tcp), reflect.TypeOf(tcpLayer))
// fmt.Println(tcpLayer)
fmt.Println("some=", some)
// 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", tcpLayer.SrcPort, tcpLayer.DstPort)
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:")