Exemplo 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")
	}
}
Exemplo n.º 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: ipv6.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 ipv6.ICMPTypeEchoRequest, ipv6.ICMPTypeEchoReply:
			m.Body, err = parseICMPEcho(b[4:])
			if err != nil {
				return nil, err
			}
		}
	}
	return m, nil
}
Exemplo n.º 3
0
Arquivo: main.go Projeto: CBiX/fahrrad
// method handleND parses arbitrary ICMPv6 messages, currently only router solicitations
func handleND(src net.Addr, body []byte) {
	t := ipv6.ICMPType(body[0])
	fmt.Printf("%v from %v\n", t, src)
	switch t {
	case ipv6.ICMPTypeRouterSolicitation:
		// parse ND options
		options, err := parseOptions(body[8:])
		if err != nil {
			fmt.Println(err)
		}

		// check if any of the options is a source LLA
		var lla *NDOptionLLA = nil
		for _, o := range options {
			if o == nil {
				continue
			}
			llaopt, ok := (*o).(*NDOptionLLA)
			if !ok {
				continue
			}
			lla = llaopt
			if int(lla.OptionType) != 1 {
				continue
			}
		}
		if lla == nil {
			fmt.Println("no source LLA option given")
			return
		}
		lladdr := make(net.HardwareAddr, len(lla.Addr))
		copy(lladdr, lla.Addr)
		rschan <- routerSolicitation{src, lladdr}
	default:
		return
	}
}
Exemplo n.º 4
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
}
Exemplo n.º 5
0
func (i *ICMPv6) ICMPType() ipv6.ICMPType { return ipv6.ICMPType(i.Type) }