Example #1
0
// 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")
	}
}
Example #2
0
// 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
}