在Go中使用原始套接字

时间:2013-08-25 09:39:54

标签: go raw-sockets

我正在尝试编写一个接收DHCP发现(UDP)的程序,并使用不同的源IP地址将它们转发到给定的IP地址,具体取决于DHCP数据包中特定字段(GIADDR)的内容。 我可以在接收和发送位工作,但我在使用IP源地址时遇到的问题是本地计算机上没有配置的IP地址。 我相信这只能使用Raw套接字完成;真的吗 ? 在Go中有没有关于如何做到这一点的例子? 我花了几天时间环顾四周但找不到多少。

干杯, 萨尔

1 个答案:

答案 0 :(得分:7)

根据你的建议,有很多障碍可以跳过:

安全

通常,能够为数据包设置源IP地址可能是一个非常危险的安全问题。在linux下,为了使用自定义标头伪造您自己的raw DHCP packets,您需要以root用户身份或使用CAP_NET_RAW capability的应用程序运行您的应用程序(请参阅setcap)。

Go中的原始套接字

标准网络库不提供原始套接字功能,因为它非常专业,并且随着人们开始在愤怒中使用API​​,API可能会发生变化。

go.net子存储库提供了ipv4和ipv6包,前者应该满足您的需求:

http://godoc.org/code.google.com/p/go.net/ipv4#NewRawConn

Header Spoofing

您需要使用ipv4.RawConnReadFrom方法来读取源数据包。然后,您应该能够使用大多数这些字段以及GIADDR逻辑来设置WriteTo调用的标头。它可能看起来像:

for {
  hdr, payload, _, err := conn.ReadFrom(buf)
  if err != nil { ... }
  hdr.ID = 0
  hdr.Checksum = 0
  hdr.Src = ...
  hdr.Dst = ...
  if err := conn.WriteTo(hdr, payload, nil); err != nil { ... }
}