首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用gopacket将UDP数据包发送到127.0.0.1

用gopacket将UDP数据包发送到127.0.0.1
EN

Stack Overflow用户
提问于 2020-01-30 12:05:09
回答 1查看 2.4K关注 0票数 5

我试图用gopacket将UDP数据包发送到127.0.0.1。这是我的代码:

代码语言:javascript
复制
package main

import (
    "fmt"
    "net"

    "github.com/google/gopacket"
    "github.com/google/gopacket/layers"
    "github.com/google/gopacket/pcap"
)

func main() {
    handle, err := pcap.OpenLive("lo", 1500, false, pcap.BlockForever)
    if err != nil {
        fmt.Printf("%s\n", err.Error())
        return
    }

    eth := layers.Ethernet{
        EthernetType: layers.EthernetTypeIPv4,
        SrcMAC:       net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        DstMAC:       net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    }

    ip := layers.IPv4{
        Version:  4,
        TTL:      64,
        SrcIP:    net.IP{127, 0, 0, 1},
        DstIP:    net.IP{127, 0, 0, 1},
        Protocol: layers.IPProtocolUDP,
    }

    udp := layers.UDP{
        SrcPort: 62003,
        DstPort: 8080,
    }
    udp.SetNetworkLayerForChecksum(&ip)

    payload := []byte{'a', 'b', 'c', '\n'}

    options := gopacket.SerializeOptions{
        ComputeChecksums: true,
        FixLengths:       true,
    }

    buffer := gopacket.NewSerializeBuffer()

    err = gopacket.SerializeLayers(buffer, options,
        &eth,
        &ip,
        &udp,
        gopacket.Payload(payload),
    )
    if err != nil {
        fmt.Printf("[-] Serialize error: %s\n", err.Error())
        return
    }
    outgoingPacket := buffer.Bytes()

    err = handle.WritePacketData(outgoingPacket)
    if err != nil {
        fmt.Printf("[-] Error while sending: %s\n", err.Error())
        return
    }

}

在一个终端里,我用netcat监听传入的数据包:

代码语言:javascript
复制
nc -ulp 8080 -s 127.0.0.1

当我运行我的代码时,我可以在具有正确校验和的回环接口上看到在wireshark中生成的数据包,但是数据包永远不会到达netcat。可能出了什么问题?

EN

回答 1

Stack Overflow用户

发布于 2020-06-04 11:30:41

如果您查看这个图解,您将注意到tcpdumpEthernet层上的作用。然后是IP然后是TCP/UDP,然后是SocketsncTCP/UDP层运行。

IP级别,数据包可能会被丢弃。通常情况下,情况是反向路径滤波

因此,您可以看到到达以太网层的数据包,这些数据包可以被tcpdump看到,但是数据包不会到达nc,因为它们可能被路由到其他地方,或者被丢弃。

所以,最好检查禁用RP filtering和检查iptable规则是否有帮助!

更新:

当您在环回界面上操作时:

MAC在以太网流量的最低级别上使用,并且只在一个LAN内使用,并帮助引导其内部的通信。在本地网络接口(lo)上不需要它,因为包是在内部处理的。 环回地址直接连接到IP层中的同一台计算机,而不使用任何物理硬件。所以,它可以让你绕过以太网,PPP,其他驱动程序。

代码语言:javascript
复制
package main

import (
    "fmt"
    "net"

    "github.com/google/gopacket"
    "github.com/google/gopacket/layers"
    "github.com/google/gopacket/pcap"
)

func main() {
    handle, err := pcap.OpenLive("lo0", 1500, false, pcap.BlockForever)
    if err != nil {
        fmt.Printf("%s\n", err.Error())
        return
    }

    eth := layers.Ethernet{
        EthernetType: layers.EthernetTypeIPv4,
        SrcMAC:       net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        DstMAC:       net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    }

    _ = eth // Ignore. Use where ethernet interface is used

    // Used for loopback interface
    lo := layers.Loopback{
        Family: layers.ProtocolFamilyIPv4,
    }

    ip := layers.IPv4{
        Version:  4,
        TTL:      64,
        SrcIP:    net.IP{127, 0, 0, 1},
        DstIP:    net.IP{127, 0, 0, 1},
        Protocol: layers.IPProtocolUDP,
    }

    udp := layers.UDP{
        SrcPort: 62003,
        DstPort: 9000,
    }
    udp.SetNetworkLayerForChecksum(&ip)

    payload := []byte{'a', 'b', 'c', '\n'}

    options := gopacket.SerializeOptions{
        ComputeChecksums: true,
        FixLengths:       true,
    }

    buffer := gopacket.NewSerializeBuffer()

    // if err = gopacket.SerializeLayers(buffer, options,
    //  &eth,
    //  &ip,
    //  &udp,
    //  gopacket.Payload(payload),
    // ); err != nil {
    //  fmt.Printf("[-] Serialize error: %s\n", err.Error())
    //  return
    // }
    if err = gopacket.SerializeLayers(buffer, options,
        &lo,
        &ip,
        &udp,
        gopacket.Payload(payload),
    ); err != nil {
        fmt.Printf("[-] Serialize error: %s\n", err.Error())
        return
    }
    outgoingPacket := buffer.Bytes()

    if err = handle.WritePacketData(outgoingPacket); err != nil {
        fmt.Printf("[-] Error while sending: %s\n", err.Error())
        return
    }

}

我在macOS Catalina上运行这个程序,如果你看到屏幕截图,它就开始工作了。nc可以接收自定义生成的数据包。如果校验和不确定,那么它将被删除。

希望能帮上忙!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59985676

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档