Ejemplo n.º 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")
	}
}
Ejemplo n.º 2
0
// 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
}