我想使用gopacket制作自定义TCP数据包,然后
使用原始套接字发送它们。
这是一个简短易读的示例go程序,
演示我想做什么:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | package main import ( "code.google.com/p/gopacket" "code.google.com/p/gopacket/examples/util" "code.google.com/p/gopacket/layers" "log" "net" ) func main() { defer util.Run()() // XXX create tcp/ip packet srcIP := net.ParseIP("127.0.0.1") dstIP := net.ParseIP("192.168.0.1") //srcIPaddr := net.IPAddr{ // IP: srcIP, //} dstIPaddr := net.IPAddr{ IP: dstIP, } ipLayer := layers.IPv4{ SrcIP: srcIP, DstIP: dstIP, Protocol: layers.IPProtocolTCP, } tcpLayer := layers.TCP{ SrcPort: layers.TCPPort(666), DstPort: layers.TCPPort(22), SYN: true, } tcpLayer.SetNetworkLayerForChecksum(&ipLayer) buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } err := gopacket.SerializeLayers(buf, opts, &ipLayer, &tcpLayer) if err != nil { panic(err) } // XXX end of packet creation // XXX send packet ipConn, err := net.ListenPacket("ip4:tcp","0.0.0.0") if err != nil { panic(err) } _, err = ipConn.WriteTo(buf.Bytes(), &dstIPaddr) if err != nil { panic(err) } log.Print("packet sent! ") } |
但是,运行该程序不起作用... SerializeLayer失败。
这是恐慌:
panic: invalid src IP 127.0.0.1
goroutine 16 [running]: runtime.panic(0x5bb020, 0xc2090723e0)
/home/human/golang-empire/go/src/pkg/runtime/panic.c:279 +0xf5 main.main()
/home/human/golang-empire/gopkg/src/github.com/david415/HoneyBadger/packetSendTest.go:41 +0x464goroutine 19 [finalizer wait]: runtime.park(0x413cc0, 0x7bc6c0,
0x7bb189)
/home/human/golang-empire/go/src/pkg/runtime/proc.c:1369 +0x89 runtime.parkunlock(0x7bc6c0, 0x7bb189)
/home/human/golang-empire/go/src/pkg/runtime/proc.c:1385 +0x3b runfinq()
/home/human/golang-empire/go/src/pkg/runtime/mgc0.c:2644 +0xcf runtime.goexit()
/home/human/golang-empire/go/src/pkg/runtime/proc.c:1445
- 好的...我修复了"无效的src ip"错误...这是由于ParseIP返回了错误的类型...它需要使用其.To4()方法进行转换;-)
- 目前,我的简单示例是发送精心制作的TCP / IP数据包...但是端口号和其他部分格式错误。 也许TCP端口的"字节序"设置错误? 这里有一个简单的例子:github.com/david415/HoneyBadger/blob/
- 这个新的提交通过将srcPort和dstPort与数据包分解后的期望值进行比较,证明了生成的TCP / IP数据包格式错误:github.com/david415/HoneyBadger/blob/
您的问题是说"制作自定义TCP数据包",但是您的代码清楚地表明,您还希望制作自定义IP第3层标头,两者之间是有区别的。另外,您没有提到IPv4与IPv6,但是同样,您的代码似乎是IPv4特定的。
给定您的示例代码,我假设您想设置完整的IPv4标头。
从Go 1.3.3和即将发布的Go 1.4开始,您将无法使用Core Go软件包来完成您想做的事情。要实现您想要的目标,您需要做两件事:
例如:
1 2 3 4 5 | conn, err := net.ListenIP("ip4:tcp", netaddr) if err != nil { log.Fatalf("ListenIP: %s ", err) } |
创建一个原始套接字。
您的问题没有说明您正在使用什么操作系统和体系结构。在运行Mac OS X的笔记本电脑上:
1 2 3 4 5 | % man ip . . . Outgoing packets automatically have an IP header prepended to them (based on the destination address and the protocol number the socket is created with), unless the IP_HDRINCL option has been set. |
我相信以下软件包具有ipv4所需的所有功能。请注意,这是一个大包装,我自己没有使用过。我做了grep,它在多个平台上支持
另请参见此处:原始套接字和他在此处编写的代码延迟,以感受一种更简单的方法,如果您只想设置TCP标头,它可能会满足您的需求。但是,请注意,此代码不允许您在IPv4 IP标头中设置IP地址,我怀疑您想这样做。
- 谢谢! 是的。 在此提交中正常工作:github.com/david415/HoneyBadger/blob/
- 这是您链接的博客文章的后续文章,该文章下至IP标头级别:darkcoding.net/software/raw-sockets-in-go-link-layer