我正在尝试使用 gopacket 向 127.0.0.1 发送一个 UDP 数据包。这是我的代码:
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
}
}
在终端中,我使用 netcat 监听传入的数据包:
nc -ulp 8080 -s 127.0.0.1
当我运行我的代码时,我可以在环回接口(interface)上的wireshark中看到生成的数据包具有正确的校验和,但数据包永远不会到达netcat。可能是什么问题?
最佳答案
如果你看这个diagram ,你会注意到 tcpdump
作用于 Ethernet
层。然后来了,IP
然后 TCP/UDP
,然后 Sockets
. nc
在 TCP/UDP
运营层。
在 IP
级别,数据包可能会被丢弃。很多情况下是Reverse Path Filtering .
因此,您可以看到到达以太网层的数据包,tcpdump
可以看到这些数据包。 ,但未到达 nc
的数据包因为它们可能会被路由到其他地方,或者被丢弃。
因此,最好检查是否禁用 RP filtering
并检查 iptable
规则,有帮助!
更新:
当您在环回接口(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
}
}
我在 macOS Catalina 上运行该程序,如果您看到屏幕截图,它正在运行。
nc
可以接收自定义生成的数据包。如果校验和不正确,那么它将被丢弃。我希望它有帮助!
关于go - 使用 gopacket 向 127.0.0.1 发送 UDP 数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59985676/