使用gopacket将UDP数据包发送到127.0.0.1 [英] Sending UDP packets to 127.0.0.1 with gopacket

查看:167
本文介绍了使用gopacket将UDP数据包发送到127.0.0.1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用gopacket将UDP数据包发送到127.0.0.1.这是我的代码:

 程序包主要进口 ("fmt"网""github.com/google/gopacket""github.com/google/gopacket/layers""github.com/google/gopacket/pcap")func main(){句柄,错误:= pcap.OpenLive("lo",1500,false,pcap.BlockForever)如果err!= nil {fmt.Printf(%s \ n",err.Error())返回}eth:= layers.Ethernet {以太网类型:layers.EthernetTypeIPv4,SrcMAC:net.HardwareAddr {0x00、0x00、0x00、0x00、0x00、0x00},DstMAC:net.HardwareAddr {0x00、0x00、0x00、0x00、0x00、0x00},}ip:= layers.IPv4 {版本:4TTL:64,SrcIP:net.IP {127,0,0,1},DstIP:net.IP {127,0,0,1},协议:layers.IPProtocolUDP,}udp:= layers.UDP {SrcPort:62003,DstPort:8080,}udp.SetNetworkLayerForChecksum(& ip)有效负载:= [] byte {'a','b','c','\ n'}选项:= gopacket.SerializeOptions {ComputeChecksums:是的,FixLengths:正确,}缓冲区:= gopacket.NewSerializeBuffer()err = gopacket.SerializeLayers(buffer,options,& eth,& ip,& udp,gopacket.Payload(有效载荷),)如果err!= nil {fmt.Printf("[-]序列化错误:%s \ n",err.Error())返回}outwardPacket:= buffer.Bytes()err = handle.WritePacketData(outgoingPacket)如果err!= nil {fmt.Printf("[-]发送时出错:%s \ n",err.Error())返回}} 

然后在终端中,我用netcat监听传入的数据包:

  nc -ulp 8080 -s 127.0.0.1 

运行代码时,可以在回送接口上的Wireshark中看到带有正确校验和的生成数据包,但是该数据包永远不会到达netcat.可能是什么问题?

解决方案

如果您查看此

我正在macOS Catalina上运行该程序,如果您看到屏幕截图,它就可以正常工作. nc 可以接收自定义生成的数据包.如果校验和不正确,则将其丢弃.

希望对您有帮助!

I'm trying to send a UDP packet to 127.0.0.1 with gopacket. Here is my code:

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
    }

}

And in a terminal I listen to incoming packets with netcat:

nc -ulp 8080 -s 127.0.0.1

When I run my code, I can see the generated packet in wireshark on loopback interface with correct checksums but the packet never arrives to netcat. What may be the problem?

解决方案

If you look at this diagram, you'll notice tcpdump acts on the Ethernet layer. Then comes, IP then TCP/UDP, then Sockets. nc operates at TCP/UDP layer.

In the IP level, the packets might be getting dropped. Very often the case is Reverse Path Filtering.

So, you are able to see the packets arriving at the ethernet layer which can be seen by tcpdump, but packets are not arriving for nc because they might be routed somewhere else, or dropped.

So, it's better to check if disabling RP filtering and checking iptable rules, helps!

Update:

As you're operating on the loopback interface:

MAC's are used at the lowest level of ethernet traffic, and only within one LAN and help direct traffic around within it. It isn't needed on a local network interface (lo) because packets are being handled internally.

The loopback address connects to the same computer directly in the IP layer without using any physical hardware. So, it lets you bypass Ethernet, PPP, other drivers.

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
    }

}

I'm running the program on macOS Catalina, and if you see the screenshot it's working. nc can receive the custom generated packet. In case the checksum isn't ok, then it would be dropped.

I hope it helps!

这篇关于使用gopacket将UDP数据包发送到127.0.0.1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆