Examples needed for ICMP messages function.

1,193 views
Skip to first unread message

stephane....@gmail.com

unread,
Sep 2, 2015, 8:20:55 PM9/2/15
to golang-nuts
Hello,

I am trying to implement a "send ICMP packet" function. And I would like to ask examples for that.

The Golang man page https://godoc.org/golang.org/x/net/icmp has only one example that I don't really understand.

I would like to be able to send a simple message to a given port.

Thank you by advance for your help.

Ian Lance Taylor

unread,
Sep 2, 2015, 8:33:25 PM9/2/15
to stephane....@gmail.com, golang-nuts, Mikio Hara
On Wed, Sep 2, 2015 at 5:01 PM, <stephane....@gmail.com> wrote:
>
> I am trying to implement a "send ICMP packet" function. And I would like to
> ask examples for that.
>
> The Golang man page https://godoc.org/golang.org/x/net/icmp has only one
> example that I don't really understand.
>
> I would like to be able to send a simple message to a given port.

Hmmm, it is a little confusing. I don't see a way to send a packet
without listening for packets.

CC'ing Mikio in case there is a way.

Ian

stephane....@gmail.com

unread,
Sep 3, 2015, 1:57:58 PM9/3/15
to golang-nuts, stephane....@gmail.com, mikioh...@gmail.com
Sorry I did not express myself well.

I would be interested in any illustration of how to send and/or receive ICMP packets, any examples.

Sam Freiberg

unread,
Sep 3, 2015, 2:45:16 PM9/3/15
to stephane....@gmail.com, golang-nuts, mikioh...@gmail.com
I'm currently using go-fastping (https://github.com/tatsushid/go-fastping) for a project that needs to ping other hosts. There is an example in the README.

On Thu, Sep 3, 2015 at 10:57 AM, <stephane....@gmail.com> wrote:
Sorry I did not express myself well.

I would be interested in any illustration of how to send and/or receive ICMP packets, any examples.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

stephane....@gmail.com

unread,
Sep 3, 2015, 6:35:00 PM9/3/15
to golang-nuts, stephane....@gmail.com, mikioh...@gmail.com
Thank you. I have looked at this : https://github.com/tatsushid/go-fastping/blob/master/cmd/ping/ping.go

But it just makes no sense for me. I am beginning in Golang and I am not able to make this mysterious example work. There is only one illustration on the github, but would you have another I could understand better ?

Sam Freiberg

unread,
Sep 3, 2015, 7:12:47 PM9/3/15
to stephane....@gmail.com, golang-nuts, mikioh...@gmail.com
Here's a minimal example that works on Mac OS X. To get the example to work on Linux comment out the section below and run with sudo:

_, err := pinger.Network("udp")
// We shouldn't ever get an error but we're checking anyway
if err != nil {
panic("Error setting network type: " + err.Error())
}


On Thu, Sep 3, 2015 at 3:34 PM, <stephane....@gmail.com> wrote:
Thank you. I have looked at this : https://github.com/tatsushid/go-fastping/blob/master/cmd/ping/ping.go

But it just makes no sense for me. I am beginning in Golang and I am not able to make this mysterious example work. There is only one illustration on the github, but would you have another I could understand better ?

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

stephane....@gmail.com

unread,
Sep 3, 2015, 8:32:21 PM9/3/15
to golang-nuts, stephane....@gmail.com, mikioh...@gmail.com
Thank you very much Sam.

I have taken your code and I start to understand it a bit. My question is, I want to ping regularly my local network and depending on which IP respond to the ping, do more advanced NMAP scans.

So I will leave my Go program running ( in the example for test purpose 200 loops) : http://play.golang.org/p/eV2XvVhjxf

Is there any risk for this program to run out of memory or to get stuck at some point because of all addresses added to the pinger and all the pinger.OnRecv waiting for a response ?

Sam Freiberg

unread,
Sep 4, 2015, 12:15:54 AM9/4/15
to stephane....@gmail.com, golang-nuts, mikioh...@gmail.com
I don't see any memory problems but you should only set pinger.OnRecv once instead of in the for loop.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

stephane....@gmail.com

unread,
Sep 4, 2015, 6:49:44 PM9/4/15
to golang-nuts, stephane....@gmail.com
Thanks for the help. The fast-pinging function worked great on my Mac... but the exact same code does not work on Linux Ubuntu.

This code : http://play.golang.org/p/ZzmbrXmu0N

Works great on Mac, return a []string full of interesting stuff. But the exact same on Ubuntu returns a []string totally empty.

I am desperate

stephane....@gmail.com

unread,
Sep 4, 2015, 8:58:37 PM9/4/15
to golang-nuts, stephane....@gmail.com
With this code :

http://play.golang.org/p/L479GHuszc


I get this error when I call "go run main.go"


panic: listen ip4:icmp <nil>: operation not permitted

goroutine 1 [running]:
runtime.panic(0x52e160, 0xc21004f940)
    /usr/lib/go/src/pkg/runtime/panic.c:266 +0xb6
main.main()
    /home/user/Golang/src/test/main.go:25 +0x152
exit status 2


I get this error when I call "sudo go run main.go"


main.go:8:2: cannot find package "github.com/tatsushid/go-fastping" in any of:
    /usr/lib/go/src/pkg/github.com/tatsushid/go-fastping (from $GOROOT)
    ($GOPATH not set)

(my GOPATH is set, and even if I do "export GOPATH=~/Golang" 20 times I will still get the same error)

James Bardin

unread,
Sep 4, 2015, 9:11:50 PM9/4/15
to golang-nuts, stephane....@gmail.com


On Friday, September 4, 2015 at 8:58:37 PM UTC-4, stephane....@gmail.com wrote:
With this code :

http://play.golang.org/p/L479GHuszc


I get this error when I call "go run main.go"


panic: listen ip4:icmp <nil>: operation not permitted

goroutine 1 [running]:
runtime.panic(0x52e160, 0xc21004f940)
    /usr/lib/go/src/pkg/runtime/panic.c:266 +0xb6
main.main()
    /home/user/Golang/src/test/main.go:25 +0x152
exit status 2


Ping requires root privileges (the ping executable is typically setuid 0)
 

I get this error when I call "sudo go run main.go"


main.go:8:2: cannot find package "github.com/tatsushid/go-fastping" in any of:
    /usr/lib/go/src/pkg/github.com/tatsushid/go-fastping (from $GOROOT)
    ($GOPATH not set)

(my GOPATH is set, and even if I do "export GOPATH=~/Golang" 20 times I will still get the same error)


sudo doesn't preserve environment variables by default. Compile your program and then execute it with sudo.

Matt Harden

unread,
Sep 4, 2015, 10:55:29 PM9/4/15
to James Bardin, golang-nuts, stephane....@gmail.com
Note that with a recent-enough kernel, a nonprivileged user can do icmp ping, if the appropriate kernel sysctl is set: https://lkml.org/lkml/2011/5/18/305

To use this mechanism, run pinger.Network("udp") before pinger.Run().

Alternatively you can give your program CAP_NET_RAW capabilities with `sudo setcap cap_net_raw+ep mypingprogram`, which is potentially safer than running it as root, or setuid-root.


--

Stéphane phenetas

unread,
Sep 7, 2015, 3:11:08 PM9/7/15
to golang-nuts, stephane....@gmail.com
Hello, I am sorry but I am still confused.
I have tried all the weekend long to get this program working but nothing ..

The program is working well on Mac, but once on Linux, it does not.

I have tried to "go clean" "go build" and then "sudo $GOPATH/bin/myprogram"

But no-thing. The ping is still returning me empty slices..
I don't know what to do.

Matt Harden

unread,
Sep 7, 2015, 4:05:39 PM9/7/15
to Stéphane phenetas, golang-nuts, stephane....@gmail.com
"go build" does not install the program in $GOPATH/bin. Use "go install" instead.

--

Stéphane phenetas

unread,
Sep 7, 2015, 4:17:54 PM9/7/15
to golang-nuts, stephane....@gmail.com
Still nothing.

With this exact code : http://play.golang.org/p/Rbi2Ta-crG

And then :

user@user:~/Golang/src/deviceDiscoveryV2$ go clean main.go
user@user:~/Golang/src/deviceDiscoveryV2$ go build main.go
user@user:~/Golang/src/deviceDiscoveryV2$ go install main.go
go install: no install location for .go files listed on command line (GOBIN not set)
user@user:~/Golang/src/deviceDiscoveryV2$ go env
GOARCH="amd64"
GOBIN=""
GOCHAR="6"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/user/Golang/"
GORACE=""
GOROOT="/usr/lib/go"
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
TERM="dumb"
CC="gcc"
GOGCCFLAGS="-g -O2 -fPIC -m64 -pthread"
CXX="g++"
CGO_ENABLED="1"
user@user:~/Golang/src/deviceDiscoveryV2$ export GOBIN=~/Golang/bin/
user@user:~/Golang/src/deviceDiscoveryV2$ go install main.go
user@user:~/Golang/src/deviceDiscoveryV2$ sudo main


Still no output from the ping function :/

Matt Harden

unread,
Sep 7, 2015, 4:37:05 PM9/7/15
to Stéphane phenetas, golang-nuts, stephane....@gmail.com
Unset GOBIN.
Run "go install", *not* "go install main.go".
Run "sudo $GOPATH/bin/deviceDiscoveryV2"


--

Stéphane phenetas

unread,
Sep 7, 2015, 5:17:48 PM9/7/15
to golang-nuts, phen...@gmail.com, stephane....@gmail.com
This changes nothing :/
Fast ping function still returns empty slices

Stéphane phenetas

unread,
Sep 7, 2015, 6:12:53 PM9/7/15
to golang-nuts, stephane....@gmail.com
It looks like the problem is really coming from the ping function.

This is not working :


func main() {
    pinger := fastping.NewPinger()

    for i:=0; i<10; i++ {
        addr, err := net.ResolveIPAddr("ip", "10.11.204.50")
        if err != nil {
            panic("Error resolving IP Address: " + err.Error())
        }

        pinger.AddIPAddr(addr)
    }
   
    pinger.OnRecv = func(addr *net.IPAddr, rtt time.Duration) {
        fmt.Printf("%s time=%v seconds\n", addr, rtt.Seconds())
    }

    if err = pinger.Run(); err != nil {
        panic(err)
    }
}


This is working :

func main() {
    pinger := fastping.NewPinger()

    addr, err := net.ResolveIPAddr("ip", "10.11.204.50")
    if err != nil {
        panic("Error resolving IP Address: " + err.Error())
    }

    pinger.AddIPAddr(addr)
    pinger.OnRecv = func(addr *net.IPAddr, rtt time.Duration) {
        fmt.Printf("%s time=%v seconds\n", addr, rtt.Seconds())
    }

    if err = pinger.Run(); err != nil {
        panic(err)
    }
}



The only difference is the for condition.

What would you do in order to loop to ping an entire local network (255 IPs) ?

Matt Harden

unread,
Sep 7, 2015, 6:14:13 PM9/7/15
to Stéphane phenetas, golang-nuts, stephane....@gmail.com
It can't be the *exact* code from http://play.golang.org/p/Rbi2Ta-crG, because line 20 is missing a closing parentheses. Also, that code never calls pinger.Run(), so I wouldn't expect any result on a Mac either.

On the other hand, this code you posted earlier at http://play.golang.org/p/L479GHuszc, does work on Linux when run as root after setting the IP address to one that is reachable from my machine.

On Mon, Sep 7, 2015 at 4:18 PM Stéphane phenetas <phen...@gmail.com> wrote:
This changes nothing :/
Fast ping function still returns empty slices

--

Matt Harden

unread,
Sep 7, 2015, 6:21:11 PM9/7/15
to Stéphane phenetas, golang-nuts, stephane....@gmail.com
I don't believe that your second example works, for two reasons. First, err is not defined before your line "if err = pinger.Run()...". Second, you don't wait any time after calling pinger.Run(), so there is no chance for the pinger to actually do its work.

Please provide actual code that compiles and demonstrates your problem, including the package statement and any imports.

Stéphane phenetas

unread,
Sep 7, 2015, 6:59:12 PM9/7/15
to golang-nuts, phen...@gmail.com, stephane....@gmail.com
This works perfectly : http://play.golang.org/p/0rBXTeGRgs

When build, installed and called with sudo privileges :

user@user:~/Golang/src/test$ go build
user@user:~/Golang/src/test$ go install
user@user:~/Golang/src/test$ sudo $GOPATH/bin/test
TEST : 10.11.204.50 time=0.050004808000000005 seconds
user@user:~/Golang/src/test$

According to Fast-Ping description on github : "It sends an ICMP packet and wait a response. If it receives a response, it calls "receive" callback. After that, MaxRTT time passed, it calls "idle" callback. For more detail, refer godoc and if you need more example, please see "cmd/ping/ping.go"."
I don't know exactly but there is probably a timer and with no response in a certain time it stop waiting for a response.
I have also tested to turn on the Wi-Fi chip on the device with IP 10.11.204.50 and then the program does not return anything, so it is really working.

This above is working, just tested right now.


So I have got the program to ping 1 IP. But I would like to ping 255. So I am trying on Ubuntu *approximately* the same thing I did on Mac and that is working which is : http://play.golang.org/p/ibn14Ly6Tn
Based on the above's Sam Freiberg's advice : "Here's a minimal example that works on Mac OS X. To get the example to work on Linux comment out the section below and run with sudo:

_, err := pinger.Network("udp")
// We shouldn't ever get an error but we're checking anyway
if err != nil {
panic("Error setting network type: " + err.Error())
}"


So I added a loop : http://play.golang.org/p/joUfr1M39Q

I do the same to build, install and execute this :

user@user:~/Golang/src/test$ go build
user@user:~/Golang/src/test$ go install
user@user:~/Golang/src/test$ sudo $GOPATH/bin/test

This is compiling, 253 IPs are printed on screen as asked on line 24. But no response at all from any of these IPs.

This printed slice on line 41 is empty. And this is my problem.

Matt Harden

unread,
Sep 7, 2015, 8:13:01 PM9/7/15
to Stéphane phenetas, golang-nuts, stephane....@gmail.com
There is no call to pinger.Run in http://play.golang.org/p/joUfr1M39Q. It won't work.

--

Stéphane phenetas

unread,
Sep 9, 2015, 3:06:46 PM9/9/15
to golang-nuts, phen...@gmail.com, stephane....@gmail.com
Thank you Matt you're right. I missed the pinger.Run with all these manipulations and obviously it won't work without it.
Runs great now.

koryl...@gmail.com

unread,
Sep 9, 2015, 11:50:06 PM9/9/15
to golang-nuts, phen...@gmail.com, stephane....@gmail.com
I know I'm a bit late to the conversation, but I have written a generic ICMPv4 library which you might find useful:


There is also github.com/korylprince/go-icmpv4/echo which use the library to make pinging easier.

Both are tested and documented, and the echo package contains a full example for pinging.

Hope someone finds it useful...

Kory
Reply all
Reply to author
Forward
0 new messages