// ParseMessage parses b as an ICMP message. Proto must be // iana.ProtocolICMP or iana.ProtocolIPv6ICMP. func ParseMessage(proto int, b []byte) (*Message, error) { if len(b) < 4 { return nil, errors.New("message too short") } var err error switch proto { case iana.ProtocolICMP: m := &Message{Type: ipv4.ICMPType(b[0]), Code: int(b[1]), Checksum: int(b[2])<<8 | int(b[3])} switch m.Type { case ipv4.ICMPTypeEcho, ipv4.ICMPTypeEchoReply: m.Body, err = parseEcho(b[4:]) if err != nil { return nil, err } default: m.Body = &DefaultMessageBody{Data: b[4:]} } return m, nil case iana.ProtocolIPv6ICMP: m := &Message{Type: ipv6.ICMPType(b[0]), Code: int(b[1]), Checksum: int(b[2])<<8 | int(b[3])} switch m.Type { case ipv6.ICMPTypeEchoRequest, ipv6.ICMPTypeEchoReply: m.Body, err = parseEcho(b[4:]) if err != nil { return nil, err } default: m.Body = &DefaultMessageBody{Data: b[4:]} } return m, nil default: return nil, errors.New("unknown protocol") } }
// ParseMessage parses b as an ICMP message. // Proto must be either the ICMPv4 or ICMPv6 protocol number. func ParseMessage(proto int, b []byte) (*Message, error) { if len(b) < 4 { return nil, errMessageTooShort } var err error m := &Message{Code: int(b[1]), Checksum: int(b[2])<<8 | int(b[3])} switch proto { case iana.ProtocolICMP: m.Type = ipv4.ICMPType(b[0]) case iana.ProtocolIPv6ICMP: m.Type = ipv6.ICMPType(b[0]) default: return nil, syscall.EINVAL } if fn, ok := parseFns[m.Type]; !ok { m.Body, err = parseDefaultMessageBody(b[4:]) } else { m.Body, err = fn(b[4:]) } if err != nil { return nil, err } return m, nil }