如何使用Golang编写原始TCP数据包(使用gopacket)并通过原始套接字发送

2023-11-27

我想使用 gopacket 制作自定义 TCP 数据包,然后 使用原始套接字发送它们。

这是一个简短易读的 go 程序示例 演示了我想做的事情:

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!\n")
}

然而运行这个程序不起作用...... SerializeLayer 失败。 这是恐慌:

恐慌:源 IP 127.0.0.1 无效

goroutine 16 [运行]: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 +0x464

goroutine 19 [终结器等待]:runtime.park(0x413cc0, 0x7bc6c0, 0x7bb189) /home/ human/golang-empire/go/src/pkg/runtime/proc.c:1369 +0x89runtime.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


您的问题是“制作自定义[原文如此] TCP 数据包”,但您的代码清楚地表明您还想制作自定义 IP 第 3 层标头,并且两者之间存在差异。另外,您没有提到 IPv4 与 IPv6,但您的代码似乎又是特定于 IPv4 的。

鉴于您的示例代码,我假设您希望设置完整的 IPv4 标头。

从 Go 1.3.3 和即将发布的 Go 1.4 开始,您无法使用 Core Go 包做您想做的事情。为了实现你的愿望,你需要做两件事:

  1. 您需要在 Go 中创建一个原始套接字。与本网站上的其他错误答案相反,您可以使用以下之一在 Go 中创建原始套接字net.ListenPacket, net.DialIP, or net.ListenIP.

例如:

conn, err := net.ListenIP("ip4:tcp", netaddr)
if err != nil {
    log.Fatalf("ListenIP: %s\n", err)
}

创建一个原始套接字。

  1. 如果您想设置自己的 IPv4 第 3 层标头,则需要设置套接字选项来启用功能。

您的问题没有说明您正在使用什么操作系统和架构。在我运行 Mac OS X 的笔记本电脑上:

% 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.

IP_HDRINCL在 Linux 上也可用。不幸的是,Core Go 没有办法设置IP_HDRINCL套接字选项也没有办法设置其他 IP 套接字选项,例如IP_TTL。我有一组私有补丁可以使用 Core Go 启用此功能,但这对您没有帮助。

我相信以下软件包具有您想要的所有功能ipv4。请注意,这是一个大包装,我自己还没有使用过。我做了 grep 它支持IP_HDRINCL在多个平台上。你想打电话NewRawConn创建一个原始连接,此函数创建一个原始套接字并设置IP_HDRINCL套接字选项。

另请参见此处:原始套接字和他在这里写的代码latency如果您只想设置 TCP 标头,了解一种可能适合您需求的更简单的方法。但是,请注意此代码不允许您在 IPv4 IP 标头中设置 IP 地址,我怀疑您想要这样做。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用Golang编写原始TCP数据包(使用gopacket)并通过原始套接字发送 的相关文章

  • golang从sdin扫描一行数字

    我正在尝试从标准输入读取输入 3 2 1
  • Socket.*Async 方法是线程化的吗?

    我目前正在尝试找出最小化 TCP 主服务器中使用的线程数量的最佳方法 以便最大限度地提高性能 由于我最近阅读了大量 C 5 0 的新异步功能 异步并不一定意味着多线程 这可能意味着将有限状态对象分成较小的块 然后通过交替与其他操作一起进行处
  • Ajax 将文件上传到内容类型为 Multipart 的 GoLang 服务器

    我正在尝试使用多部分表单将音频文件上传到 Golang 服务器 然而 Go 返回错误 multipart NextPart bufio buffer full 我相信这表明我的 Javascript 请求中存在不属于多部分格式的内容 这是我
  • 如何顺序运行 golang 测试?

    当我跑步时go test 我的输出 FAIL TestGETSearchSuccess 0 00s Location drivers api test go 283 Error Not equal 200 expected 204 actu
  • Accept() 是线程安全的吗?

    我目前正在用 C 语言为我正在做的课程编写一个简单的网络服务器 我们的一项要求是实现一个线程池来使用 pthread 处理连接 我知道我将如何粗略地执行此操作 在主线程中调用accept并将文件描述符传递给freee线程 但是我的朋友建议了
  • 无需时间即可生成随机字符串?

    我知道如何使用 Runes 和播种 rand Init 在 go 中生成随机字符串time UnixNano 我的问题是 是否可以 使用 stdlib 在不使用当前时间戳 安全 的情况下播种 rand 此外 我问 因为仅仅依靠时间来为敏感操
  • ReverseProxy取决于golang中的request.Body

    我想构建一个 http 反向代理 它检查 HTTP 主体 然后将 HTTP 请求发送到它的上游服务器 你怎么能在 Go 中做到这一点 初始尝试 如下 失败 因为 ReverseProxy 复制传入请求 修改它并发送 但正文已被读取 func
  • UDP 广播发送失败:在 Linux 2.6.30 上“网络无法访问”

    我用udp广播写了一个程序 代码段如下 struct sockaddr in broadcast addr socklen t sock len sizeof broadcast addr bzero broadcast addr sock
  • 在 Go 中生成随机、固定长度的字节数组

    我有一个字节数组 固定长度为4 token make byte 4 我需要将每个字节设置为随机字节 我怎样才能以最有效的方式做到这一点 这math rand就我而言 方法不提供随机字节函数 也许有一种内置的方法 或者我应该生成一个随机字符串
  • 我想在后端验证来自 golang 前端的时区

    前端在注册期间发送时区以及其他用户详细信息 我需要在时区上放置一个验证器来进行 api 测试 时区数据的格式为 GMT 10 00 Hawaii GMT 08 00 Pacific Time US amp Canada 我所做的是定义数组中
  • 如何在node.js中分离TCP套接字消息

    我正在尝试使用 TCP 套接字 并且对消息如何到达我的应用程序感到困惑 看来他们已经分手了 有人知道我怎样才能最好地将他们重新组合在一起吗 所有消息均以换行符分隔 r n var stream net createConnection po
  • 初始化嵌套匿名结构

    我有一个 json 作为 fields time id status customerId additionalDetail pageInfo start 0 rows 1000 我想将我的结构编组到上面的 json 并创建如下结构 typ
  • 如果是 PrintWriter,为什么我应该在循环中刷新而不是在循环之后刷新?

    我的小演示程序中有一个服务器和客户端 我将一些字符串数据从客户端发送到服务器 然后为客户端重新发送这些数据 客户端也将其写入控制台 我对 PrtintWriter 的刷新方法感到困惑 根据 JAVA 文档 该方法刷新流 经过一些研究 我逐渐
  • 如何使用Python中字符串变量中存储的证书打开ssl套接字

    在Python中 ssl wrap socket可以从文件中读取证书 ssl wrap socket需要证书作为文件路径 如何使用从字符串变量读取的证书启动 SSL 连接 我的主机环境不允许写入文件 并且临时文件模块不起作用我正在使用Pyt
  • 套接字:监听积压并接受

    listen sock backlog 在我看来 参数backlog限制连接数量 这是我的测试代码 server initialize the sockaddr of server server sin family AF INET ser
  • 有没有办法在 VSCode 中保存时运行 go 测试,并将其输出到终端?

    现在我有几个项目在VSCode中运行 运行起来相当繁琐go test每次我编写新代码时 我宁愿立即看看我是否破坏了某些东西 我知道在 Javascript 中我可以在每次保存文件时运行测试 并将输出发送到终端 现在我正在使用 保存时运行 h
  • 展平嵌套结构会导致切片的切片

    所以我有一个像这样的结构 type Bus struct Number string Name string DirectStations Station Station is another struct ReverseStations
  • 我怎么知道我的所有 goroutine 确实正在使用 golang 的同步包等待一个条件

    我有一个应用程序 我正在创建多个 goroutine 来同时执行某个任务 所有工作协程都会等待条件 事件发生 一旦事件被触发 它们就会开始执行 创建完所有goroutines后 主线程在发送广播信号之前应该知道所有goroutines确实处
  • 鸭子在 Go 中打字

    我想写一个Join函数接受任意对象String 方法 package main import fmt strings type myint int func i myint String string return fmt Sprintf
  • TcpClient 在异步读取期间断开连接

    我有几个关于完成 tcp 连接的问题 客户端使用 Tcp 连接到我的服务器 在接受客户端后listener BeginAcceptTcpClient ConnectionEstabilishedCallback null 我开始阅读netw

随机推荐