Go version

go version go1.24.3 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/root/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1142805223=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/workspaces/vxlan-cni/go.mod'
GOMODCACHE='/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/root/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.24.3'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

When reading ICMP messages via PacketConn.ReadFrom, ICMP message data is silently dropped if the provided buffer is not large enough to contain both the ICMP header and the IP header. This is not documented anywhere, and the function is only supposed to load the buffer with ICMP message data, not any IP header data. Currently, to use this function properly, the buffer size must be maximum IP header size + maximum ICMP message size. Even though this works around the issue, the additional space in the buffer is still completely wasted.

See https://github.com/solidDoWant/repro-go-bugs/blob/icmp-buffer-1/main.go for a step by step minimal reproduction and explanation. Just clone, go run ., and review the output.

What did you see happen?

I wrote a short program to reproduce this issue. It creates a very basic ICMP message listener, and logs the buffer contents for ICMP echo requests. A pipe (|) is inserted after the last byte reportedly returned by the ReadFrom function. The program calls ping via the exec package to send ICMP echo requests to the loopback address.

All errors are checked, and the program will panic if one occurs.

$ go run .
IP datagram of 63 bytes, one under the buffer size.
This has a 20 byte IP header, 8 byte ICMP header, and 35 byte payload.

Received an ICMP echo request with 43 bytes (header + payload) from 127.0.0.1:

0000: 00 00 c5 4d 00 4c 00 01 dc 3e 6b 68 00 00 00 00 
0010: e4 80 05 00 00 00 00 00 cd ef ab cd ef ab cd ef 
0020: ab cd ef ab cd ef ab cd ef ab cd|00 cd ef ab cd 
0030: ef ab cd ef ab cd ef ab cd ef ab cd ef ab cd 00 

------------------------------------------------------------
IP datagram of 64 bytes, exactly the buffer size.
This has a 20 byte IP header, 8 byte ICMP header, and 36 byte payload.

Received an ICMP echo request with 44 bytes (header + payload) from 127.0.0.1:

0000: 00 00 95 59 00 4d 00 01 dc 3e 6b 68 00 00 00 00 
0010: 13 85 05 00 00 00 00 00 cd ef ab cd ef ab cd ef 
0020: ab cd ef ab cd ef ab cd ef ab cd ef|cd ef ab cd 
0030: ef ab cd ef ab cd ef ab cd ef ab cd ef ab cd ef 

------------------------------------------------------------
IP datagram of 65 bytes, one over the buffer size.
This has a 20 byte IP header, 8 byte ICMP header, and 37 byte payload.
Notice that the reported message size is 44 bytes, and an error is not reported (there is no panic).

Received an ICMP echo request with 44 bytes (header + payload) from 127.0.0.1:

0000: 00 00 9c 53 00 4e 00 01 dc 3e 6b 68 00 00 00 00 
0010: 61 89 05 00 00 00 00 00 cd ef ab cd ef ab cd ef 
0020: ab cd ef ab cd ef ab cd ef ab cd ef|cd ef ab cd 
0030: ef ab cd ef ab cd ef ab cd ef ab cd ef ab cd ef 

Notice that when the ICMP message is increased above the buffer size, the remaining bytes are silently dropped. A tcpdump capture confirms that the ping utility is sending messages exactly as expected.

What did you expect to see?

There are two issues here: * The buffer size must be larger than the ICMP message received. * When the buffer is not large enough to hold the ICMP message, there's no way to tell. No error is returned, and the IP datagram size is not provided.

I would expect that the buffer only needs to be as large as the received ICMP message, and that if it is not large enough, an error is returned.

Comment From: gabyhelp

Related Issues

Related Discussions

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)