使用gopacket将UDP数据包发送到127.0.0.1 [英] Sending UDP packets to 127.0.0.1 with gopacket
问题描述
我正在尝试使用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,
ð,
&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,
// ð,
// &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屋!