Beispiel #1
0
func (msg *MessageV3) Unmarshal(b []byte) (rest []byte, err error) {
	var raw asn1.RawValue
	rest, err = asn1.Unmarshal(b, &raw)
	if err != nil {
		return nil, err
	}
	if raw.Class != asn1.ClassUniversal || raw.Tag != asn1.TagSequence || !raw.IsCompound {
		return nil, asn1.StructuralError{fmt.Sprintf(
			"Invalid MessageV3 object - Class [%02x], Tag [%02x] : [%s]",
			raw.FullBytes[0], asn1.TagSequence, ToHexStr(b, " "))}
	}

	next := raw.Bytes

	var version int
	next, err = asn1.Unmarshal(next, &version)
	if err != nil {
		return
	}

	next, err = msg.globalDataV3.Unmarshal(next)
	if err != nil {
		return
	}

	next, err = msg.securityParameterV3.Unmarshal(next)
	if err != nil {
		return
	}

	msg.version = SnmpVersion(version)
	msg.pduBytes = next
	return
}
Beispiel #2
0
func (msg *MessageV1) Unmarshal(b []byte) (rest []byte, err error) {
	var raw asn1.RawValue
	rest, err = asn1.Unmarshal(b, &raw)
	if err != nil {
		return
	}
	if raw.Class != asn1.ClassUniversal || raw.Tag != asn1.TagSequence || !raw.IsCompound {
		return nil, asn1.StructuralError{fmt.Sprintf(
			"Invalid MessageV1 object - Class [%02x], Tag [%02x] : [%s]",
			raw.Class, raw.Tag, ToHexStr(b, " "))}
	}

	next := raw.Bytes

	var version int
	next, err = asn1.Unmarshal(next, &version)
	if err != nil {
		return
	}

	var community []byte
	next, err = asn1.Unmarshal(next, &community)
	if err != nil {
		return
	}

	msg.version = SnmpVersion(version)
	msg.Community = community
	msg.pduBytes = next
	return
}
Beispiel #3
0
func (v *VariableBinding) Unmarshal(b []byte) (rest []byte, err error) {
	var raw asn1.RawValue
	rest, err = asn1.Unmarshal(b, &raw)
	if err != nil {
		return nil, err
	}
	if raw.Class != asn1.ClassUniversal || raw.Tag != asn1.TagSequence || !raw.IsCompound {
		return nil, asn1.StructuralError{fmt.Sprintf(
			"Invalid VariableBinding object - Class [%02x], Tag [%02x] : [%s]",
			raw.Class, raw.Tag, ToHexStr(b, " "))}
	}

	var oid Oid
	next, err := (&oid).Unmarshal(raw.Bytes)
	if err != nil {
		return
	}

	variable, _, err := unmarshalVariable(next)
	if err != nil {
		return
	}

	v.Oid = oid
	v.Variable = variable
	return
}
Beispiel #4
0
func (sec *securityParameterV3) Unmarshal(b []byte) (rest []byte, err error) {
	var raw asn1.RawValue
	rest, err = asn1.Unmarshal(b, &raw)
	if err != nil {
		return
	}

	if raw.Class != asn1.ClassUniversal || raw.Tag != asn1.TagOctetString || raw.IsCompound {
		return nil, asn1.StructuralError{fmt.Sprintf(
			"Invalid SecurityParameter object - Class [%02x], Tag [%02x] : [%s]",
			raw.Class, raw.Tag, ToHexStr(b, " "))}
	}

	_, err = asn1.Unmarshal(raw.Bytes, sec)
	return
}
Beispiel #5
0
func decrypt(msg *MessageV3, proto PrivProtocol, key, privParam []byte) (err error) {
	var raw asn1.RawValue
	_, err = asn1.Unmarshal(msg.PduBytes(), &raw)
	if err != nil {
		return
	}
	if raw.Class != asn1.ClassUniversal || raw.Tag != asn1.TagOctetString || raw.IsCompound {
		return asn1.StructuralError{fmt.Sprintf(
			"Invalid encrypted PDU object - Class [%02x], Tag [%02x] : [%s]",
			raw.Class, raw.Tag, ToHexStr(msg.PduBytes(), " "))}
	}

	var dst []byte
	switch proto {
	case Des:
		dst, err = DecryptDES(raw.Bytes, key, privParam)
	case Aes:
		dst, err = DecryptAES(
			raw.Bytes, key, privParam, int32(msg.AuthEngineBoots), int32(msg.AuthEngineTime))
	default:
		err = errors.New("'" + fmt.Sprint(proto) + "' is unsupported crypto.")
	}

	if err == nil {
		msg.SetPduBytes(dst)
	}
	return
}
Beispiel #6
0
func (v *Oid) Unmarshal(b []byte) (rest []byte, err error) {
	var i asn1.ObjectIdentifier
	rest, err = asn1.Unmarshal(b, &i)
	if err == nil {
		v.Value = []int(i)
	}
	return
}
Beispiel #7
0
func unmarshalEmpty(b []byte, tag byte) (rest []byte, err error) {
	err = validateUnmarshal(b, tag)
	if err != nil {
		return nil, err
	}

	var raw asn1.RawValue
	return asn1.Unmarshal(b, &raw)
}
Beispiel #8
0
func (pdu *ScopedPdu) Unmarshal(b []byte) (rest []byte, err error) {
	var raw asn1.RawValue
	rest, err = asn1.Unmarshal(b, &raw)
	if err != nil {
		return nil, err
	}
	if raw.Class != asn1.ClassUniversal || raw.Tag != asn1.TagSequence || !raw.IsCompound {
		return nil, asn1.StructuralError{fmt.Sprintf(
			"Invalid ScopedPud object - Class [%02x], Tag [%02x] : [%s]",
			raw.Class, raw.Tag, ToHexStr(b, " "))}
	}

	next := raw.Bytes

	var contextEngineId []byte
	next, err = asn1.Unmarshal(next, &contextEngineId)
	if err != nil {
		return
	}

	var contextName []byte
	next, err = asn1.Unmarshal(next, &contextName)
	if err != nil {
		return
	}

	var pduV1 PduV1
	_, err = (&pduV1).Unmarshal(next)
	if err != nil {
		return
	}

	pdu.ContextEngineId = contextEngineId
	pdu.ContextName = contextName
	pdu.PduV1 = pduV1
	return
}
Beispiel #9
0
func unmarshalString(b []byte, tag byte, setter func([]byte)) (rest []byte, err error) {
	err = validateUnmarshal(b, tag)
	if err != nil {
		return nil, err
	}

	temp := b[0]
	b[0] = asn1.TagOctetString
	var s []byte
	rest, err = asn1.Unmarshal(b, &s)
	if err == nil {
		setter(s)
	}
	b[0] = temp
	return
}
Beispiel #10
0
func unmarshalInt(b []byte, tag byte, setter func(*big.Int)) (rest []byte, err error) {
	err = validateUnmarshal(b, tag)
	if err != nil {
		return nil, err
	}

	temp := b[0]
	b[0] = asn1.TagInteger
	var i *big.Int
	rest, err = asn1.Unmarshal(b, &i)
	if err == nil {
		setter(i)
	}
	b[0] = temp
	return
}
Beispiel #11
0
func (h *globalDataV3) Unmarshal(b []byte) (rest []byte, err error) {
	return asn1.Unmarshal(b, h)
}
Beispiel #12
0
func unmarshalVariable(b []byte) (v Variable, rest []byte, err error) {
	var raw asn1.RawValue
	rest, err = asn1.Unmarshal(b, &raw)
	if err != nil {
		return
	}

	switch raw.Class {
	case asn1.ClassUniversal:
		switch raw.Tag {
		case asn1.TagInteger:
			var u Integer
			v = &u
		case asn1.TagOctetString:
			var u OctetString
			v = &u
		case asn1.TagNull:
			var u Null
			v = &u
		case asn1.TagOID:
			var u Oid
			v = &u
		}
	case asn1.ClassApplication:
		switch raw.Tag {
		case asn1.TagIPAddress & tagMask:
			var u Ipaddress
			v = &u
		case asn1.TagCounter32 & tagMask:
			var u Counter32
			v = &u
		case asn1.TagGauge32 & tagMask:
			var u Gauge32
			v = &u
		case asn1.TagTimeticks & tagMask:
			var u TimeTicks
			v = &u
		case asn1.TagOpaque & tagMask:
			var u Opaque
			v = &u
		case asn1.TagCounter64 & tagMask:
			var u Counter64
			v = &u
		}
	case asn1.ClassContextSpecific:
		switch raw.Tag {
		case asn1.TagNoSuchObject & tagMask:
			var u NoSucheObject
			v = &u
		case asn1.TagNoSuchInstance & tagMask:
			var u NoSucheInstance
			v = &u
		case asn1.TagEndOfMibView & tagMask:
			var u EndOfMibView
			v = &u
		}
	}

	if v != nil {
		rest, err = v.Unmarshal(b)
		if err == nil {
			return
		}
	} else {
		err = asn1.StructuralError{fmt.Sprintf(
			"Unknown ASN.1 object : %s", ToHexStr(b, " "))}
	}

	return nil, nil, err
}
Beispiel #13
0
func (v *Integer) Unmarshal(b []byte) (rest []byte, err error) {
	return asn1.Unmarshal(b, &v.Value)
}
Beispiel #14
0
func (self *internal_pinger) serve() {
	defer self.wait.Done()

	cached := make([]byte, 4000)

	for 1 == atomic.LoadInt32(&self.is_running) {
		l, ra, err := self.conn.ReadFrom(cached)
		if err != nil {
			if strings.Contains(err.Error(), "No service is operating") { //Port Unreachable
				continue
			}
			if strings.Contains(err.Error(), "forcibly closed by the remote host") { //Port Unreachable
				continue
			}
			self.ch <- &PingResult{Error: fmt.Errorf("ReadFrom failed: %v, %v", ra, err)}
			continue
		}
		recv_bytes := cached[:l]

		var raw asn1.RawValue
		if _, err = asn1.Unmarshal(recv_bytes, &raw); err != nil {
			log.Printf("[snmp-pinger] Invalid Message object - %s : [%s]",
				err.Error(), ToHexStr(recv_bytes, " "))
			continue
		}

		if raw.Class != asn1.ClassUniversal || raw.Tag != asn1.TagSequence || !raw.IsCompound {
			log.Printf("[snmp-pinger] Invalid Message object - Class [%02x], Tag [%02x] : [%s]",
				raw.FullBytes[0], raw.Tag, ToHexStr(recv_bytes, " "))
			continue
		}

		next := raw.Bytes
		var version int
		next, err = asn1.Unmarshal(next, &version)
		if err != nil {
			log.Printf("[snmp-pinger] Invalid Message object - %s : [%s]",
				err.Error(), ToHexStr(recv_bytes, " "))
			continue
		}

		if SnmpVersion(version) == V3 {
			var managedId int
			next, err = asn1.Unmarshal(next, &managedId)
			if err != nil {
				log.Printf("[snmp-pinger] Failed to Unmarshal message - %s : [%s]",
					err.Error(), ToHexStr(recv_bytes, " "))
				continue
			}

			self.ch <- &PingResult{Id: managedId, Addr: ra, Version: SnmpVersion(version), Timestamp: time.Now()}
		} else {
			pdu := &PduV1{}
			recvMsg := &MessageV1{
				version: SnmpVersion(version),
				pdu:     pdu,
			}
			_, err = recvMsg.Unmarshal(recv_bytes)
			if err != nil {
				log.Printf("[snmp-pinger] Failed to Unmarshal message - %s : [%s]",
					err.Error(), ToHexStr(recv_bytes, " "))
				continue
			}

			_, err = pdu.Unmarshal(recvMsg.PduBytes())
			if err != nil {
				log.Printf("[snmp-pinger] Failed to Unmarshal PDU - %s : [%s]",
					err.Error(), ToHexStr(recv_bytes, " "))
				continue
			}
			self.ch <- &PingResult{Id: pdu.RequestId(),
				Addr:      ra,
				Version:   SnmpVersion(version),
				Community: string(recvMsg.Community),
				Timestamp: time.Now()}
		}

	}
}
Beispiel #15
0
func (pdu *PduV1) Unmarshal(b []byte) (rest []byte, err error) {
	var raw asn1.RawValue
	rest, err = asn1.Unmarshal(b, &raw)
	if err != nil {
		return
	}
	if raw.Class != asn1.ClassContextSpecific || !raw.IsCompound {
		return nil, asn1.StructuralError{fmt.Sprintf(
			"Invalid PDU object - Class [%02x], Tag [%02x] : [%s]",
			raw.Class, raw.Tag, ToHexStr(b, " "))}
	}

	var requestId int
	var errorStatus int
	var errorIndex int
	var enterprise Oid
	var agentAddress Ipaddress
	var genericTrap int
	var specificTrap int
	var timestamp asn1.BitString

	next := raw.Bytes

	// The protocol data unit of SNMP
	// The PduV1 is used by SNMP V1 and V2c, other than the SNMP V1 Trap
	//
	// trap pdu
	// +------------+--------------+------------+----------------+---------------+-------------+---------------------+
	// |  PDU Type  |  enterprise  | agent addr |  generic trap  | specific trap | time stamp  |  variable bindings  |
	// +------------+--------------+------------+----------------+---------------+-------------+---------------------+
	//
	// reponse pdu
	// +------------+--------------+----------------+---------------+----------------------+
	// |  PDU Type  |  request id  |  error status  |  error index  |   variable bindings  |
	// +------------+--------------+----------------+---------------+----------------------+
	//
	// request pdu
	// +------------+--------------+----------------+---------------+----------------------+
	// |  PDU Type  |  request id  |       0        |       0       |   variable bindings  |
	// +------------+--------------+----------------+---------------+----------------------+
	//

	if Trap == PduType(raw.Tag) {
		next, err = enterprise.Unmarshal(next)
		if err != nil {
			return
		}

		next, err = agentAddress.Unmarshal(next)
		if err != nil {
			return
		}

		next, err = asn1.Unmarshal(next, &genericTrap)
		if err != nil {
			return
		}

		next, err = asn1.Unmarshal(next, &specificTrap)
		if err != nil {
			return
		}
		var t asn1.RawValue
		next, err = asn1.Unmarshal(next, &t)
		if err != nil {
			return
		}
	} else {
		next, err = asn1.Unmarshal(next, &requestId)
		if err != nil {
			return
		}

		next, err = asn1.Unmarshal(next, &errorStatus)
		if err != nil {
			return
		}

		next, err = asn1.Unmarshal(next, &errorIndex)
		if err != nil {
			return
		}
	}

	var VariableBindings asn1.RawValue
	_, err = asn1.Unmarshal(next, &VariableBindings)
	if err != nil {
		return
	}
	if VariableBindings.Class != asn1.ClassUniversal || VariableBindings.Tag != asn1.TagSequence || !VariableBindings.IsCompound {
		return nil, asn1.StructuralError{fmt.Sprintf(
			"Invalid VariableBindings object - Class [%02x], Tag [%02x] : [%s]",
			VariableBindings.Class, VariableBindings.Tag, ToHexStr(next, " "))}
	}

	next = VariableBindings.Bytes
	for len(next) > 0 {
		var variableBinding VariableBinding
		next, err = variableBinding.Unmarshal(next)
		if err != nil {
			return
		}
		pdu.variableBindings = append(pdu.variableBindings, variableBinding)
	}

	pdu.pduType = PduType(raw.Tag)
	pdu.requestId = requestId
	pdu.errorStatus = ErrorStatus(errorStatus)
	pdu.errorIndex = errorIndex

	pdu.Enterprise = enterprise
	pdu.AgentAddress = agentAddress
	pdu.GenericTrap = genericTrap
	pdu.SpecificTrap = specificTrap
	pdu.Timestamp = timestamp
	return
}