1. 程式人生 > >golang gopacket網路抓包和分析

golang gopacket網路抓包和分析

gopacket 是golang語言使用的網路資料抓取和分析的工具包。
本文簡單介紹如何使用gopacket進行網路抓包。

下載gopacket

# go get [email protected]:google/gopacket.git

Demo

程式碼中,抓取與埠3306相關的資料,也就是mysql通訊資料。

package main

import(
    "fmt"
    "net"
    "strings"

    "github.com/google/gopacket"
    "github.com/google/gopacket/layers"
    "github.com/google/gopacket/pcap"
)

func main() {

    fmt.Println("packet start...")

    deviceName := "eth0" 
    snapLen := int32(65535)
    port := uint16(3306)
    filter := getFilter(port) 
    fmt.Printf("device:%v, snapLen:%v, port:%v\n", deviceName, snapLen, port)
    fmt.Println("filter:", filter)

    //開啟網路介面,抓取線上資料
    handle, err := pcap.OpenLive(deviceName, snapLen, true, pcap.BlockForever)
    if err != nil {
        fmt.Printf("pcap open live failed: %v", err)
        return
    }

    // 設定過濾器
    if err := handle.SetBPFFilter(filter); err != nil {
        fmt.Printf("set bpf filter failed: %v", err)
        return
    }
    defer handle.Close()

    // 抓包
    packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
    packetSource.NoCopy = true
    for packet := range packetSource.Packets() {
        if packet.NetworkLayer() == nil || packet.TransportLayer() == nil || packet.TransportLayer().LayerType() != layers.LayerTypeTCP {
            fmt.Println("unexpected packet")
            continue
        }
        
        fmt.Printf("packet:%v\n",packet)

        // tcp 層
        tcp := packet.TransportLayer().(*layers.TCP)
        fmt.Printf("tcp:%v\n", tcp)     
        // tcp payload,也即是tcp傳輸的資料
        fmt.Printf("tcp payload:%v\n", tcp.Payload)
    }
}

//定義過濾器
func getFilter(port uint16) string {
    filter := fmt.Sprintf("tcp and ((src port %v) or (dst port %v))",  port, port)
    return filter
}

抓取到的資料包

packet start...
device:lo0, snapLen:65535, port:3306
filter: tcp and ((src port 3306) or (dst port 3306))

packet:PACKET: 75 bytes, wire length 75 cap length 75 @ 2018-10-20 11:13:00.106452 +0800 CST
- Layer 1 (04 bytes) = Loopback {Contents=[2, 0, 0, 0] Payload=[..71..] Family=IPv4}
- Layer 2 (20 bytes) = IPv4 {Contents=[..20..] Payload=[..51..] Version=4 IHL=5 TOS=0 Length=71 Id=0 Flags=DF FragOffset=0 TTL=64 Protocol=TCP Checksum=0 SrcIP=172.16.1.103 DstIP=172.16.1.103 Options=[] Padding=[]}
- Layer 3 (32 bytes) = TCP  {Contents=[..32..] Payload=[..19..] SrcPort=50351 DstPort=3306(mysql) Seq=110592366 Ack=3116315438 DataOffset=8 FIN=false SYN=false RST=false PSH=true ACK=true URG=false ECE=false CWR=false NS=false Window=12753 Checksum=23336 Urgent=0 Options=[TCPOption(NOP:), TCPOption(NOP:), TCPOption(Timestamps:1064185591/1064170040 0x3f6e2ef73f6df238)] Padding=[]}
- Layer 4 (19 bytes) = Payload  19 byte(s)

tcp:&{{[196 175 12 234 6 151 129 110 185 191 51 46 128 24 49 209 91 40 0 0 1 1 8 10 63 110 46 247 63 109 242 56] [15 0 0 0 3 115 104 111 119 32 100 97 116 97 98 97 115 101 115]} 50351 3306(mysql) 110592366 3116315438 8 false false false true true false false false false 12753 23336 0 [196 175] [12 234] [TCPOption(NOP:) TCPOption(NOP:) TCPOption(Timestamps:1064185591/1064170040 0x3f6e2ef73f6df238)] [] [{1 1 []} {1 1 []} {8 10 [63 110 46 247 63 109 242 56]} {0 0 []}] {<nil>}}
tcp payload:[15 0 0 0 3 115 104 111 119 32 100 97 116 97 98 97 115 101 115]
。。。

對抓取到的mysql資料感興趣的同學,可以參考Mysql 通訊協議抓包分析

參考

github

https://github.com/google/gopacket

文件godoc

https://godoc.org/github.com/google/gopacket

go抓包分析demo

https://blog.lab99.org/post/golang-2017-09-23-video-packet-capture-analysis-with-go.html

https://blog.csdn.net/ptmozhu/article/details/72652310