在Go中使用原始套接字

5
我正在尝试编写一个程序,该程序接收DHCP探测(UDP),并根据DHCP数据包中特定字段(GIADDR)的内容,并使用不同的源IP地址将其转发到给定的IP地址。我已经成功实现了接收和发送部分,但是在使用本地机器上未配置的IP地址作为IP源地址时出现了问题。我相信这只能使用Raw sockets实现,这是真的吗?是否有任何关于如何在Go中完成此操作的示例?我花了几天时间搜索,但是并没有找到太多相关信息。
祝好, Sal

通过原始套接字,您只是指从套接字读写数据,对吧?为什么不使用http://golang.org/pkg/net/呢? - kevmo314
1
这几天你在探索中尝试了什么,取得了什么结果? - Kissaki
1个回答

7

你提出的方案存在一些障碍:

安全性

通常情况下,能够设置数据包源IP地址可能是一个非常危险的安全问题。在Linux下,为了伪造自己的原始DHCP数据包并添加自定义头部,您需要以root身份运行应用程序或从具有CAP_NET_RAW权限的应用程序中运行(请参见setcap)。

Go中的原始套接字

标准的net库不提供原始套接字功能,因为它非常专业化,API可能会因人们开始愤怒地使用它而发生变化。

"

go.net子仓库提供了一个IPv4和一个IPv6包,前者应该适合您的需求:

"

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

头部欺骗

您需要使用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 { ... }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接