用gopacket发送UDP数据包到127.0.0.1。

问题描述 投票:2回答:1

我想用gopacket发送一个UDP包到127.0.0.1。这是我的代码。

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监听传入的数据包。

nc -ulp 8080 -s 127.0.0.1

当我运行我的代码时,我可以在环回接口的wireshark上看到生成的数据包,并有正确的校验和,但是数据包从来没有到达netcat。问题可能出在哪里?

go networking udp gopacket
1个回答
3
投票

如果你看看这个 图谱你会发现 tcpdump 采取行动 Ethernet 层。然后是。IP 然后 TCP/UDP那么 Sockets. nc 运作于 TCP/UDP 层。

IP 级,数据包可能会被丢弃。很多时候,这种情况是 反向路径过滤.

因此,你能够看到到达以太网层的数据包,这可以通过 tcpdump但数据包没有到达 nc 因为它们可能会被路由到其他地方,或者被丢弃。

所以,最好检查一下是否禁用了 RP filtering 和检查 iptable 规则,帮助

更新一下。

由于你在环回接口上操作,

MAC的使用是在最底层的以太网流量, 而且只在一个局域网内使用, 并帮助引导流量在它的周围。在本地网络接口上是不需要的(lo),因为数据包是在内部处理的。

环回地址直接在IP层连接到同一台计算机,而不需要使用任何物理硬件。所以,它可以让你绕过以太网、PPP、其他驱动。

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
    }

}

enter image description here

我在macOS Catalina上运行这个程序,如果你看到截图就可以了。nc 可以收到自定义生成的数据包。万一校验和不对,就会被丢弃。

希望能帮到你

© www.soinside.com 2019 - 2024. All rights reserved.