我想对 TCP 数据包进行一些实验。因此,我使用 gopacket (v1.1.19) 来制作数据包并将它们发送到接口。我有此代码用于创建 SYN 数据包并将其放在环回上并发送到 127.0.0.1:8888,其中我有一个 ncat 服务器正在监听 ( ncat -v -l 127.0.0.1 8888
)。
我可以按预期在 wireshark 上看到我的数据包,但服务器没有发送 SYN/ACK 数据包。从浏览器调用 localhost:8888 完全没问题。而且我已将我的数据包构建为类似于浏览器发送的数据包(校验和、时间戳和端口当然不同)。
有人知道我的问题是什么或者我应该研究什么吗?
package main
import (
"encoding/binary"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"log"
"math/rand"
"net"
"time"
)
var (
device string = "lo"
snapshotLen int32 = 1024
promiscuous bool = false
err error
timeout time.Duration = 30 * time.Second
handle *pcap.Handle
buffer gopacket.SerializeBuffer
options gopacket.SerializeOptions= gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}
ethernetLayer layers.Ethernet = layers.Ethernet{
SrcMAC: net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
DstMAC: net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
EthernetType: layers.EthernetTypeIPv4,
}
ipLayer layers.IPv4 = layers.IPv4{
Version: 4,
SrcIP: net.IP{127, 0, 0, 1},
DstIP: net.IP{127,0,0,1},
Protocol: layers.IPProtocolTCP,
TTL: 64,
FragOffset: 0,
Flags: layers.IPv4DontFragment,
}
)
func syn() []byte {
rand.Seed(time.Now().UnixMilli())
buffer = gopacket.NewSerializeBuffer()
option1 := layers.TCPOption{layers.TCPOptionKindWindowScale, 3,[]byte{7} }
bs := make([]byte, 2)
binary.BigEndian.PutUint16(bs,56495)
option2 := layers.TCPOption{layers.TCPOptionKindMSS, 0, bs }
bsTsval := make([]byte,4)
bsTsecr := make([]byte,4)
binary.BigEndian.PutUint32(bsTsval,uint32(time.Now().UnixMilli()))
bsTime := append(bsTsval, bsTsecr...)
option3 := layers.TCPOption{layers.TCPOptionKindTimestamps,0, bsTime}
tcpLayerSYN := &layers.TCP{
SrcPort: layers.TCPPort(rand.Intn(0xffff-1)+1 ),
DstPort: layers.TCPPort(8888),
SYN: true,
Seq: rand.Uint32(),
Window: 65495,
Options: []layers.TCPOption{option1, option2, option3},
}
tcpLayerSYN.SetNetworkLayerForChecksum(&ipLayer)
// And create the packet with the layers
buffer = gopacket.NewSerializeBuffer()
gopacket.SerializeLayers(buffer, options,
ðernetLayer,
&ipLayer,
tcpLayerSYN,
)
outgoingPacket := buffer.Bytes()
return outgoingPacket
}
func main() {
// Open device
handle, err = pcap.OpenLive(device, snapshotLen, promiscuous, timeout)
if err != nil {log.Fatal(err) }
defer handle.Close()
err = handle.WritePacketData(syn())
}