最近有个预研工作,涉及到SIP和HTTPS报文的抓包和数据分析,正好可以使用gopacket进行一番实践,在这里记录一下学习心得。

首先从最基本的gopacket抓包开始

 1 func pcapStartLoop(cfg *PcapDataConfigs, packetListener func(packet gopacket.Packet)) {
 2     logger.Info("Try start open-live device for pcap : ", cfg)
 3     handle, err := pcap.OpenLive(cfg.Device, cfg.SnapshotLen, cfg.Promiscuous, cfg.Timeout)
 4  // 参数含义依次为:网卡设备名,可根据ifconfig输出确定;单次抓取报文的存储缓冲区最大长度,比如普通计算机的TCP报文长度为1514字节,若设置为1500,则可能会被截断,因此,需要设置为合适的大小;是否混淆模式,其影响后续再通过试验进行分析;超时时间
 5     if err != nil {
 6         logger.Error(err)
 7         return
 8     }
 9     defer func() {
10         handle.Close()
11         handle = nil
12     }()
13 
14     if cfg.Filters != "" {
15         err = handle.SetBPFFilter(cfg.Filters)//设置过滤规则
16         if err != nil {
17             logger.Error(err)
18             return
19         }
20         logger.Info("Only capturing packets for filters : " + cfg.Filters)
21     }
22 
23     packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
24     for packet := range packetSource.Packets() {
25         packetListener(packet)
26         packetCount++
27         if cfg.MaxPacketCount > 0 && packetCount >= cfg.MaxPacketCount {
28             break
29         }
30     }
31 }

抓到报文后进行解析:

 1 func parsePacket(packet gopacket.Packet) {
 2     for _, layer := range packet.Layers() {
 3         switch layer.LayerType() {
 4         case layers.LayerTypeEthernet:
 5             parseEthernetLayer(layer)
 6         case layers.LayerTypeIPv4:
 7             parseIPV4Layer(layer)
 8         case layers.LayerTypeTCP:
 9             parseTcpLayer(layer)
10         case layers.LayerTypeUDP:
11             parseUdpLayer(layer)
12         default:
13             logger.Info("- ", layer.LayerType())
14         }
15     }
16     //parseEthernetLayer(packet)
17     //parseIPV4Layer(packet)
18 }
19 
20 func parseEthernetLayer(layer gopacket.Layer) {
21     logger.Info("Ethernet layer detected.")
22     ethernetPacket, _ := layer.(*layers.Ethernet)
23     logger.Info("Source MAC: ", ethernetPacket.SrcMAC)
24     logger.Info("Destination MAC: ", ethernetPacket.DstMAC)
25     logger.Info("Ethernet type: ", ethernetPacket.EthernetType)
26 }
27 
28 func parseIPV4Layer(layer gopacket.Layer) {
29     logger.Info("IPv4 layer detected.")
30     ip, _ := layer.(*layers.IPv4)
31 
32     logger.Infof("From %s to %s\n", ip.SrcIP, ip.DstIP)
33     logger.Info("Protocol: ", ip.Protocol)
34 }
35 
36 func parseTcpLayer(layer gopacket.Layer) {
37     logger.Info("TCP layer detected.")
38     tcp, _ := layer.(*layers.TCP)
39 
40     logger.Infof("From %s to %s\n", tcp.SrcPort, tcp.DstPort)
41 
42     //tcpassembly.NewAssembler(nil)
43 
44 }
45 
46 func parseUdpLayer(layer gopacket.Layer) {
47     logger.Info("UDP layer detected.")
48     udp, _ := layer.(*layers.UDP)
49 
50     logger.Infof("From %s to %s\n", udp.SrcPort, udp.DstPort)
51     logger.Infof("UDP payload is %s \n", string(udp.Payload))
52 }

好,到此为止,报文已经可以抓取并打印到控制台上了。

其他见下文。

 

posted on 2022-09-23 16:21  oilamp  阅读(302)  评论(0编辑  收藏  举报