golang用字符串数据生成http的pcap文件

因为我有的只是pyload里面的字符串数据。没有协议头的部分,所以只能自己创建协议头的数据。
主要使用的就是go的gopacket和gopcap包。下面直接上代码

package main

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"log"
	"math/rand"
	"time"

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

// writeToPCAP_HTTP 函数用于将HTTP数据包写入到 PCAP 文件中
func writeToPCAP_HTTP(w *pcapgo.Writer, requestData []byte, responseData []byte) error {
	// 每个请求随机选择本地端口号
	srcPort := layers.TCPPort(rand.Intn(16383) + 49152) // 49152 - 65535 是动态/私有端口范围
	dstPort := layers.TCPPort(80)
	// 创建以太网帧
	ethernetLayer := &layers.Ethernet{
		SrcMAC:       []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
		DstMAC:       []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
		EthernetType: layers.EthernetTypeIPv4,
	}

	// 创建IP数据包(请求)
	requestIP := &layers.IPv4{
		Version:  4,
		IHL:      5,
		TTL:      64,
		Protocol: layers.IPProtocolTCP,
		SrcIP:    []byte{127, 0, 0, 1},
		DstIP:    []byte{127, 0, 0, 1},
	}
	// 计算IP数据包长度(请求)
	//requestIP.Length = uint16(len(requestData) + 40) // IP header length (20 bytes) + TCP header length (20 bytes) + request payload length

	// 创建TCP数据包(请求)
	requestTCP := &layers.TCP{
		SrcPort: srcPort,
		DstPort: dstPort,
		Seq:     rand.Uint32(), // 生成随机的 Sequence Number
		Ack:     0,
		Window:  16384,
		ACK:     false,
		SYN:     true,
	}
	requestTCP.SetNetworkLayerForChecksum(requestIP)
	// 保存请求数据包的 Sequence Number 和 Acknowledgment Number
	requestSeq := requestTCP.Seq
	requestAck := requestTCP.Ack

	// 序列化并写入请求数据包
	buffer := gopacket.NewSerializeBuffer()
	//这个是重点!!!!不然你生成的pcap包很可能打不开
	options := gopacket.SerializeOptions{
		FixLengths:       true,	// 修复数据包长度
		ComputeChecksums: true,	// 计算checksum值
	}
	if err := gopacket.SerializeLayers(buffer, options, ethernetLayer, requestIP, requestTCP, gopacket.Payload(requestData)); err != nil {
		return fmt.Errorf("error serializing request packet: %v", err)
	}
	if err := w.WritePacket(gopacket.CaptureInfo{
		Timestamp:     time.Now(),
		Length:        len(buffer.Bytes()),
		CaptureLength: len(buffer.Bytes()),
	}, buffer.Bytes()); err != nil {
		return fmt.Errorf("error writing request packet: %v", err)
	}

	// 创建IP数据包(响应)
	responseIP := &layers.IPv4{
		Version:  4,
		IHL:      5,
		TTL:      64,
		Protocol: layers.IPProtocolTCP,
		SrcIP:    []byte{127, 0, 0, 1},
		DstIP:    []byte{127, 0, 0, 1},
	}
	// 计算IP数据包长度(响应)
	// responseIP.Length = uint16(len(responseData) + 40) // IP header length (20 bytes) + TCP header length (20 bytes) + response payload length

	// 创建TCP数据包(响应)
	responseTCP := &layers.TCP{
		SrcPort: dstPort,
		DstPort: srcPort,
		Seq:     requestAck,                            // 使用请求数据包的 Acknowledgment Number 作为响应数据包的 Sequence Number
		Ack:     requestSeq + uint32(len(requestData)), // 使用请求数据包的 Sequence Number 加上请求数据长度 作为响应数据包的 Acknowledgment Number
		Window:  16384,
		ACK:     true,
		SYN:     false,
	}
	responseTCP.SetNetworkLayerForChecksum(responseIP)
	// 序列化并写入响应数据包
	buffer = gopacket.NewSerializeBuffer()
	if err := gopacket.SerializeLayers(buffer, options, ethernetLayer, responseIP, responseTCP, gopacket.Payload(responseData)); err != nil {
		return fmt.Errorf("error serializing response packet: %v", err)
	}
	if err := w.WritePacket(gopacket.CaptureInfo{
		Timestamp:     time.Now(),
		Length:        len(buffer.Bytes()),
		CaptureLength: len(buffer.Bytes()),
	}, buffer.Bytes()); err != nil {
		return fmt.Errorf("error writing response packet: %v", err)
	}

	return nil
}

func main() {
	// 创建一个字节缓冲区,用于存储 pcap 文件内容
	var buf bytes.Buffer
	// 创建一个 pcap writer,并将文件头数据写入到字节缓冲区中
	w := pcapgo.NewWriter(&buf)
	w.WriteFileHeader(65536, layers.LinkTypeEthernet)

	// HTTP请求数据1
	requestPayload := []byte("GET /mehmet.txt HTTP/1.1\r\nHost: 127.0.0.1\r\nUser-Agent: curl/7.55.1\r\nAccept: */*\r\n\r\n")

	// HTTP响应数据1
	responsePayload := []byte("HTTP/1.1 200 OK\r\nDate: Sun, 15 Oct 2017 21:58:29 GMT\r\nServer: Apache/2.4.27 (Debian)\r\nLast-Modified: Sun, 15 Oct 2017 21:57:37 GMT\r\nETag: \"12-55b9cfa5dd94e\"\r\nAccept-Ranges: bytes\r\nContent-Length: 18\r\nContent-Type: text/plain\r\n\r\nbest hacker ever.\n")

	// 将请求和响应数据写入到 PCAP 文件中
	if err := writeToPCAP_HTTP(w, requestPayload, responsePayload); err != nil {
		log.Fatal(err)
	}

	// HTTP请求数据2
	requestPayload = []byte("GET /hahhaha.txt HTTP/1.1\r\nHost: 127.0.0.1\r\nUser-Agent: curl/7.55.1\r\nAccept: */*\r\n\r\n")

	// HTTP响应数据2
	responsePayload = []byte("HTTP/1.1 200 OK\r\nDate: Sun, 15 Oct 2017 21:58:29 GMT\r\nServer: Apache/2.4.27 (Debian)\r\nLast-Modified: Sun, 15 Oct 2017 21:57:37 GMT\r\nETag: \"12-55b9cfa5dd94e\"\r\nAccept-Ranges: bytes\r\nContent-Length: 18\r\nContent-Type: text/plain\r\n\r\n1111 hacker ever.\n")
	// 将请求和响应数据写入到 PCAP 文件中
	if err := writeToPCAP_HTTP(w, requestPayload, responsePayload); err != nil {
		log.Fatal(err)
	}
	// 将pcap文件内容以Base64编码输出到控制台
	encoded := base64.StdEncoding.EncodeToString(buf.Bytes())
	fmt.Println(encoded)
}

你可能感兴趣的:(golang,http,开发语言)