// 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") } }
// parseICMPMessage parses b as an ICMP message. func parseICMPMessage(b []byte) (*icmpMessage, error) { msglen := len(b) if msglen < 4 { return nil, errors.New("message too short") } m := &icmpMessage{Type: ipv4.ICMPType(b[0]), Code: int(b[1]), Checksum: int(b[2])<<8 | int(b[3])} if msglen > 4 { var err error switch m.Type { case ipv4.ICMPTypeEcho, ipv4.ICMPTypeEchoReply: m.Body, err = parseICMPEcho(b[4:]) if err != nil { return nil, err } } } return m, nil }