IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Go语言解析pcap包,提取http请求 -> 正文阅读

[网络协议]Go语言解析pcap包,提取http请求

使用gopacket包对pcap流量包进行解析。

go get github.com/google/gopacket

首先打开一个pcap流量包文件,然后过滤tcp流量中的每一个包,遍历每一个包进行下一步处理。

针对每一个包,首先从以太网层可以获取到ip协议是ipv4还是ipv6,只需要ipv4的,同时还能获取到源MAC地址,目的MAC地址,源ip和目的ip。

?ethernetLayer := packet.Layer(layers.LayerTypeEthernet)
?fmt.Println("Source MAC: ", ethernetPacket.SrcMAC)
?fmt.Println("Destination MAC: ", ethernetPacket.DstMAC)
?fmt.Println("Ethernet type: ", ethernetPacket.EthernetType)
?fmt.Printf("From %s to %s\n", ip.SrcIP, ip.DstIP)
?fmt.Println("Protocol: ", ip.Protocol)
?fmt.Printf("From port %d to %d\n", tcp.SrcPort, tcp.DstPort)
?fmt.Println("Sequence number: ", tcp.Seq)

然后从包的应用层获取到payload,解析payload内容,判断是不是以“GET ”或者“POST ”开头的字符串,如果是的话就判定为http请求。然后使用正则表达式匹配出payload中的uri和host字段,并拼接出url。

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/layers"
	"github.com/google/gopacket/pcap"
	"log"
	"regexp"
	"strings"
)

var (
	pcapFile string = "http2.pcapng"
	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()

	// Set filter
	var filter string = "tcp"
	err = handle.SetBPFFilter(filter)
	if err != nil {
		log.Fatal(err)
	}

	packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
	for packet := range packetSource.Packets() {
		// Do something with a packet here.
		//println(packet)
		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 {
		ethernetPacket, _ := ethernetLayer.(*layers.Ethernet)

		//fmt.Println(reflect.TypeOf(ethernetPacket.EthernetType))
		if ethernetPacket.EthernetType.String() == "IPv4" {
			ipLayer := packet.Layer(layers.LayerTypeIPv4)
			if ipLayer != nil {
				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

				tcpLayer := packet.Layer(layers.LayerTypeTCP)
				if tcpLayer != nil {
					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

					applicationLayer := packet.ApplicationLayer()

					if applicationLayer != nil {
						payload := string(applicationLayer.Payload())
						if strings.HasPrefix(payload, "GET") || strings.HasPrefix(payload, "POST") {
							fmt.Println("--------------------------------------------------------------------")
							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.Printf("From %s to %s\n", ip.SrcIP, ip.DstIP)
							fmt.Println("Protocol: ", ip.Protocol)
							fmt.Printf("From port %d to %d\n", tcp.SrcPort, tcp.DstPort)
							fmt.Println("Sequence number: ", tcp.Seq)

							//fmt.Printf("%s\n", applicationLayer.Payload())
							//a := packet.TransportLayer().TransportFlow()
							//fmt.Println(a.EndpointType())
							//fmt.Println("HTTP found!")
							//fmt.Println(payload)
							//解释正则表达式
							reg := regexp.MustCompile(`(?s)(GET|POST) (.*?) HTTP.*Host: (.*?)\n`)
							if reg == nil {
								fmt.Println("MustCompile err")
								return
							}
							//提取关键信息
							result := reg.FindStringSubmatch(payload)
							//fmt.Println(result)
							//fmt.Println(len(result))
							//fmt.Println(result[2], result[3])
							if len(result) == 4 {
								strings.TrimSpace(result[2])
								url := "http://" + strings.TrimSpace(result[3]) + strings.TrimSpace(result[2])
								fmt.Println("url:", url)
								fmt.Println("host:", result[3])
							} else {
								fmt.Println("error===================")
							}

						}

					}
				}
			}
		}
	}

}

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-08-27 12:13:42  更:2021-08-27 12:15:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 21:24:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码