如何监听 ICMP 数据包?

huangapple go评论85阅读模式
英文:

How to listen for ICMP packets?

问题

我正在处理一个由两部分组成的应用程序,其中一侧发送 ICMP 数据包,另一侧监听 ICMP 数据包,并在接收到数据包时采取相应的操作。问题是,我不确定如何使监听器一直保持活动状态(只需让它在循环中等待并在接收到数据包时采取操作)。

目前,我能够使用 go-fastping 库发送和接收数据包,如果是双向通信(我发送数据包,它们回应,我处理远程响应)。问题是如何使其变成非对称的?

我尝试创建一个监听器:

for {
    conn, err := icmp.ListenPacket("ip4:icmp", "192.168.1.8")
    if err != nil {
        fmt.Println(err)
    }
}

但是这并不起作用。我的逻辑是我想要一个 while true 循环来保持监听器活动(在这种情况下是 for {),然后使用 ICMP 的 ListenPacket 监听新的数据包,但是我似乎无法通过这种方法获取任何内容。

如果有任何想法或帮助,将不胜感激。提前感谢您的时间和帮助。

英文:

I'm working on a two part application where one side sends ICMP packets and the other side listens for the ICMP packets and takes action when it receives them. The problem is, I'm not sure how to keep the listener alive indefinitely (just want it sitting there in a loop only taking action when it receives a packet).

Currently, I'm able to use the go-fastping library and can send and receive packets if it's a two way communication (I send it, they respond, I process the remote response). The question is how do I make this asymmetrical?

My attempt at a listener was:

for {
    conn, err := icmp.ListenPacket("ip4:icmp", "192.168.1.8")
    if err != nil {
        fmt.Println(err)
    }
}

but this doesn't work. My logic here was that I want a while true loop to keep the listener alive (in this case that's the for {), then I listen for new packets with ICMP's ListenPacket but I don't seem to be getting anything using this approach.

Any ideas or help would be greatly appreciated. Thanks in advance for your time and assistance.

答案1

得分: 9

icmp.ListenPacket() 创建了一个 *icmp.PacketConn,也就是一个监听器。你正在无限循环中创建监听器!由于你甚至没有关闭它们,你的程序会比你说“ping”更快地报错“too many open files”。

这里是一个工作中的监听器示例:

package main

import (
    "golang.org/x/net/icmp"
    "log"
)

func main() {
    conn, err := icmp.ListenPacket("ip4:icmp", "192.168.0.12")
    if err != nil {
        log.Fatal(err)
    }

    for {
        var msg []byte
        length, sourceIP, err := conn.ReadFrom(msg)
        if err != nil {
            log.Println(err)
            continue
        }

        log.Printf("message = '%s', length = %d, source-ip = %s", string(msg), length, sourceIP)
    }
    _ = conn.Close()
}

这将产生以下输出:

2015/10/26 10:35:00 message = '', length = 0, source-ip = 192.168.0.7
2015/10/26 10:35:00 message = '', length = 0, source-ip = 192.168.0.25
2015/10/26 10:35:01 message = '', length = 0, source-ip = 192.168.0.7
2015/10/26 10:35:01 message = '', length = 0, source-ip = 192.168.0.25
2015/10/26 10:35:02 message = '', length = 0, source-ip = 192.168.0.7
2015/10/26 10:35:02 message = '', length = 0, source-ip = 192.168.0.25

我同时从两个主机对主机进行了ping操作。

如果你想要丢弃传入的消息和其他返回值,你可以选择这样做。

英文:

icmp.ListenPacket() creates a *icmp.PacketConn - in other words a listener. You are creating listeners in an infinite loop! Since you are not even closing them, your program will start complaining about too many open files faster than you can say "ping".

Here is an example of a working listener

<!-- language: lang-golang -->

package main

import (
    &quot;golang.org/x/net/icmp&quot;
    &quot;log&quot;
)

func main() {
    conn, err := icmp.ListenPacket(&quot;ip4:icmp&quot;, &quot;192.168.0.12&quot;)
    if err != nil {
        log.Fatal(err)
    }

    for {
        var msg []byte
        length, sourceIP, err := conn.ReadFrom(msg)
        if err != nil {
            log.Println(err)
            continue
        }

        log.Printf(&quot;message = &#39;%s&#39;, length = %d, source-ip = %s&quot;, string(msg), length, sourceIP)
    }
    _ = conn.Close()
}

This produces:

2015/10/26 10:35:00 message = &#39;&#39;, length = 0, source-ip = 192.168.0.7
2015/10/26 10:35:00 message = &#39;&#39;, length = 0, source-ip = 192.168.0.25
2015/10/26 10:35:01 message = &#39;&#39;, length = 0, source-ip = 192.168.0.7
2015/10/26 10:35:01 message = &#39;&#39;, length = 0, source-ip = 192.168.0.25
2015/10/26 10:35:02 message = &#39;&#39;, length = 0, source-ip = 192.168.0.7
2015/10/26 10:35:02 message = &#39;&#39;, length = 0, source-ip = 192.168.0.25

I was pinging the host from 2 hosts simultaneously.

You can choose to discard the incoming message and other return values if you want.

huangapple
  • 本文由 发表于 2015年10月26日 20:22:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/33345683.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定