13.8.1 获取ICMP数据

这节,您将学习怎样使用 syscall 库获取原始 ICMP 网络数据,和 syscall.SetsockoptInt() 去设置 socket 选项。牢记发送原始 ICMP 数据是非常困难的,因为您不得不自己构造原始网络包。这个程序的名称是 syscallNet.go,并显示在四个部分中。

syscallNet.go 的第一部分如下:

package main

import(
    "fmt"
    "os"
    "syscall"
)

syscallNet.go 的第二部分包含代码如下:

func main() {
    fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP)
    if err != nil {
        fmt.Println("Error in syscall.Socket:", err)
        return
    }
    f := os.NewFile(uintptr(fd), "captureICMP")
    if f == nil {
        fmt.Println("Error is os.NewFile:", err)
        return
    }

syscall.AF_INET 参数告诉 syscall.Socket() 您想使用 IPv4。 syscall.SOCK_RAW 参数使生成的 socket 成为原始 socket。这最后一个参数,syscall.IPPROTO_ICMP,告诉 syscall.Socket() 您只对 ICMP 通信感兴趣。

syscallNet.go 的第三部分如下:

调用 syscall.SetsockoptInt() 设置 socket 的接收 buffer 大小为 256。syscall.SOL_SOCKET 参数是为了说明您想要在 socket 层级上工作。

syscallNet.go 的其余 Go 代码如下:

由于 for 循环,syscallNet.go 将一直抓取 ICMP 网络包直到您手动终止它。

在 macOS High Sierra 机器上执行 syscallNet.go 将产生如下输出:

在 Debian Linux 机器上运行 syscallNet.go 将产生如下输出:

Last updated

Was this helpful?