@@ -115,17 +115,18 @@ func (f *icmpForwarder) reply4(id stack.TransportEndpointID, pkt *stack.PacketBu
115115 defer pkt .DecRef ()
116116
117117 if ! f .h .Ping (data , src , dst ) { // unreachable
118- // make unreachable icmp packet for req and l7
119118 err = f .icmpErr4 (pkt , header .ICMPv4DstUnreachable , header .ICMPv4HostUnreachable )
120119 } else { // reachable
121120 newOptions := f .ipOpts (pkt , ipHdr )
122- // if unhandled by the handler, send a reply ourselves
121+
122+ // Correct IP header length (IHL in 32-bit words).
123123 replyHeaderLength := uint8 (header .IPv4MinimumSize + len (newOptions ))
124124 replyIPHdrView := buffer .NewView (int (replyHeaderLength ))
125125 replyIPHdrView .Write (ipHdr [:header .IPv4MinimumSize ])
126126 replyIPHdrView .Write (newOptions )
127+
127128 replyIPHdr := header .IPv4 (replyIPHdrView .AsSlice ())
128- replyIPHdr .SetHeaderLength (replyHeaderLength )
129+ replyIPHdr .SetHeaderLength (replyHeaderLength >> 2 ) // IHL in 32-bit words.
129130 replyIPHdr .SetSourceAddress (route .LocalAddress ())
130131 replyIPHdr .SetDestinationAddress (route .RemoteAddress ())
131132 replyIPHdr .SetTTL (route .DefaultTTL ())
@@ -135,6 +136,7 @@ func (f *icmpForwarder) reply4(id stack.TransportEndpointID, pkt *stack.PacketBu
135136
136137 replyICMPHdr := header .ICMPv4 (replyData .AsSlice ())
137138 replyICMPHdr .SetType (header .ICMPv4EchoReply )
139+ replyICMPHdr .SetCode (0 ) // EchoReply must have Code=0.
138140 replyICMPHdr .SetChecksum (0 )
139141 replyICMPHdr .SetChecksum (^ checksum .Checksum (replyData .AsSlice (), 0 ))
140142
0 commit comments