下面是一个示例代码,演示如何使用 golang 发送 ICMP 广播并过滤回包源 MAC 地址:
package main
import (
"fmt"
"net"
"os"
)
const (
ProtocolICMP = 1
)
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "Usage: %s host\n", os.Args[0])
os.Exit(1)
}
hostname := os.Args[1]
addr, err := net.ResolveIPAddr("ip4", hostname)
if err != nil {
fmt.Println("Resolution error", err.Error())
os.Exit(1)
}
conn, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
if err != nil {
fmt.Println("Listen error:", err.Error())
os.Exit(1)
}
defer conn.Close()
icmp := &net.ICMPv4Echo{
ID: os.Getpid() & 0xffff,
Seq: 1,
Data: []byte("HELLO-R-U-THERE"),
}
// 设置目标地址为子网广播地址
dstIP := net.IPv4bcast
// 发送 ICMP 请求报文
conn.WriteTo(icmp.Marshal(), &net.IPAddr{IP: dstIP})
// 接收 ICMP 回复报文
buffer := make([]byte, 1024)
for {
n, _, err := conn.ReadFrom(buffer)
if err != nil {
fmt.Println(err.Error())
break
}
ipPacket, _ := ipv4.ParseHeader(buffer[:n])
if ipPacket.Protocol == ProtocolICMP && ipPacket.Src.Equal(addr.IP) {
icmpPacket, _ := net.ParseICMPMessage(buffer[:n])
fmt.Printf("Received reply from %v: seq=%v time=%v\n", ipPacket.Src, icmpPacket.Seq, icmpPacket.Rtt)
}
}
}
在上述代码中,我们先使用 net.ResolveIPAddr 函数解析目标主机的 IP 地址。然后通过 net.ListenPacket 函数创建一个监听 ICMP 报文的连接。
接着,我们构造一个 ICMP 请求报文,并将目标地址设置为子网广播地址,即 255.255.255.255。然后发送该报文到网络上。
最后,我们循环读取从网络上收到的数据包。如果收到的是 ICMP 回复报文,并且源 IP 地址与目标主机 IP 地址相同,则打印出回复信息。
注意,在 Windows 操作系统下,需要管理员权限才能发送和接收 ICMP 报文。
内容由零声教学AI助手提供,问题来源于学员提问




