1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
12 icmpv6EchoRequest
= 128
16 // icmpMessage represents an ICMP message.
17 type icmpMessage
struct {
20 Checksum
int // checksum
21 Body icmpMessageBody
// body
24 // icmpMessageBody represents an ICMP message body.
25 type icmpMessageBody
interface {
27 Marshal() ([]byte, error
)
30 // Marshal returns the binary enconding of the ICMP echo request or
32 func (m
*icmpMessage
) Marshal() ([]byte, error
) {
33 b
:= []byte{byte(m
.Type
), byte(m
.Code
), 0, 0}
34 if m
.Body
!= nil && m
.Body
.Len() != 0 {
35 mb
, err
:= m
.Body
.Marshal()
42 case icmpv6EchoRequest
, icmpv6EchoReply
:
45 csumcv
:= len(b
) - 1 // checksum coverage
47 for i
:= 0; i
< csumcv
; i
+= 2 {
48 s
+= uint32(b
[i
+1])<<8 |
uint32(b
[i
])
51 s
+= uint32(b
[csumcv
])
55 // Place checksum back in header; using ^= avoids the
56 // assumption the checksum bytes are zero.
62 // parseICMPMessage parses b as an ICMP message.
63 func parseICMPMessage(b
[]byte) (*icmpMessage
, error
) {
66 return nil, errors
.New("message too short")
68 m
:= &icmpMessage
{Type
: int(b
[0]), Code
: int(b
[1]), Checksum
: int(b
[2])<<8 |
int(b
[3])}
72 case icmpv4EchoRequest
, icmpv4EchoReply
, icmpv6EchoRequest
, icmpv6EchoReply
:
73 m
.Body
, err
= parseICMPEcho(b
[4:])
82 // imcpEcho represenets an ICMP echo request or reply message body.
83 type icmpEcho
struct {
85 Seq
int // sequence number
89 func (p
*icmpEcho
) Len() int {
93 return 4 + len(p
.Data
)
96 // Marshal returns the binary enconding of the ICMP echo request or
97 // reply message body p.
98 func (p
*icmpEcho
) Marshal() ([]byte, error
) {
99 b
:= make([]byte, 4+len(p
.Data
))
100 b
[0], b
[1] = byte(p
.ID
>>8), byte(p
.ID
)
101 b
[2], b
[3] = byte(p
.Seq
>>8), byte(p
.Seq
)
106 // parseICMPEcho parses b as an ICMP echo request or reply message
108 func parseICMPEcho(b
[]byte) (*icmpEcho
, error
) {
110 p
:= &icmpEcho
{ID
: int(b
[0])<<8 |
int(b
[1]), Seq
: int(b
[2])<<8 |
int(b
[3])}
112 p
.Data
= make([]byte, bodylen
-4)