ฉันต้องการทดลองกับแพ็กเก็ต 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 จากเบราว์เซอร์นั้นใช้งานได้ปกติดี และฉันได้สร้างแพ็กเก็ตของฉันให้คล้ายกับที่ส่งโดยเบราว์เซอร์ (checksum, timestamp และ port นั้นแตกต่างกัน)
มีคนคิดว่าปัญหาของฉันคืออะไรหรือสิ่งที่ฉันสามารถค้นหาได้?
แพคเกจหลัก
นำเข้า (
"การเข้ารหัส / ไบนารี"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"บันทึก"
"คณิต/แรนด์"
"สุทธิ"
"เวลา"
)
วาร์ (
สตริงอุปกรณ์ = "lo"
สแนปช็อตLen int32 = 1024
บูลสำส่อน = เท็จ
เกิดข้อผิดพลาด
หมดเวลา time.Duration = 30 * time.Second
ที่จับ *pcap.ที่จับ
บัฟเฟอร์ gopacket.SerializeBuffer
ตัวเลือก gopacket.SerializeOptions= gopacket.SerializeOptions{FixLengths: จริง, ComputeChecksums: จริง}
ethernetLayer เลเยอร์อีเธอร์เน็ต = เลเยอร์อีเธอร์เน็ต{
SrcMAC: net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
DstMAC: net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
EthernetType: Layers.EthernetTypeIPv4,
}
ipLayer เลเยอร์.IPv4 = เลเยอร์.IPv4{
รุ่น: 4,
SrcIP: net.IP{127, 0, 0, 1},
DstIP: net.IP{127,0,0,1},
โปรโตคอล:layers.IPProtocolTCP,
TTL: 64,
FragOffset: 0,
แฟล็ก: Layers.IPv4DontFragment,
}
)
func syn() [] ไบต์ {
rand.Seed(time.Now().UnixMilli())
บัฟเฟอร์ = gopacket.NewSerializeBuffer()
option1 :=layers.TCPOption{layers.TCPOptionKindWindowScale, 3,[]byte{7} }
bs := ทำ ([] ไบต์ 2)
binary.BigEndian.PutUint16(bs,56495)
ตัวเลือก 2 := Layers.TCPOption{layers.TCPOptionKindMSS, 0, bs }
bsTsval := ทำ ([] ไบต์,4)
bsTsecr := ทำ ([] ไบต์,4)
binary.BigEndian.PutUint32(bsTsval,uint32(time.Now().UnixMilli()))
bsTime := ต่อท้าย(bsTsval, bsTsecr...)
ตัวเลือก 3 := Layers.TCPOption{layers.TCPOptionKindTimestamps,0, bsTime}
tcpLayerSYN := &layers.TCP{
SrcPort: Layers.TCPPort(rand.Intn(0xffff-1)+1 ),
DstPort: เลเยอร์ TCPPort (8888),
SYN: จริง,
ลำดับ: rand.Uint32(),
หน้าต่าง: 65495,
ตัวเลือก: []layers.TCPOption{option1, option2, option3},
}
tcpLayerSYN.SetNetworkLayerForChecksum(&ipLayer)
// และสร้างแพ็คเก็ตด้วยเลเยอร์
บัฟเฟอร์ = gopacket.NewSerializeBuffer()
gopacket.SerializeLayers (บัฟเฟอร์ ตัวเลือก
ðernetLayer,
&ipLayer,
tcpLayerSYN,
)
OutgoingPacket := buffer.Bytes()
ส่งคืน Packet ขาออก
}
ฟังก์ชันหลัก () {
// เปิดอุปกรณ์
จัดการ err = pcap.OpenLive (อุปกรณ์, snapshotLen, สำส่อน, หมดเวลา)
ถ้า err != ไม่มี {log.Fatal(err) }
เลื่อนที่จับปิด ()
ข้อผิดพลาด = handle.WritePacketData(syn())
}