示例#1
0
func (pdu *V2CPDU) encodePDU(bs []byte, is_dump bool) ([]byte, SnmpError) {
	internal := newNativePdu()
	C.snmp_pdu_init(internal)
	defer func() {
		C.snmp_pdu_free(internal)
		releaseNativePdu(internal)
	}()

	internal.error_status = C.int32_t(pdu.error_status)
	if SNMP_PDU_GETBULK == pdu.op {
		if pdu.variableBindings.Len() < pdu.non_repeaters {
			internal.error_status = C.int32_t(pdu.variableBindings.Len())
		} else {
			internal.error_status = C.int32_t(pdu.non_repeaters)
		}

		if pdu.max_repetitions > 0 {
			internal.error_index = C.int32_t(pdu.max_repetitions)
		} else {
			internal.error_index = C.int32_t(1)
		}
	}

	err := strcpy(&internal.community[0], MAX_COMMUNITY_LEN, pdu.community)
	if nil != err {
		return nil, newError(SNMP_CODE_FAILED, err, "copy community")
	}

	internal.engine.max_msg_size = C.int32_t(pdu.maxMsgSize)
	internal.request_id = C.int32_t(pdu.requestId)
	internal.pdu_type = C.u_int(pdu.op)
	internal.version = uint32(pdu.version)

	err = encodeBindings(internal, pdu.GetVariableBindings())

	if nil != err {
		return nil, newError(SNMP_CODE_FAILED, err, "encode bindings")
	}

	if is_test {
		debug_init_secparams(internal)
	} else {
		C.snmp_pdu_init_secparams(internal)
	}

	if is_dump {
		C.snmp_pdu_dump(internal)
	}

	return encodeNativePdu(bs, internal)
}
示例#2
0
func DecodePDU(send_bytes []byte, priv_type PrivType, priv_key []byte, is_dump bool) (PDU, SnmpError) {
	var buffer C.asn_buf_t
	var pdu C.snmp_pdu_t

	C.set_asn_u_ptr(&buffer.asn_u, (*C.char)(unsafe.Pointer(&send_bytes[0])))
	buffer.asn_len = C.size_t(len(send_bytes))

	err := DecodePDUHeader(&buffer, &pdu)
	if nil != err {
		return nil, err
	}
	defer C.snmp_pdu_free(&pdu)

	err = FillUser(&pdu, SNMP_AUTH_NOAUTH, nil, priv_type, priv_key)
	if nil != err {
		return nil, err
	}
	err = DecodePDUBody(&buffer, &pdu)
	if nil != err {
		return nil, err
	}

	if is_dump {
		C.snmp_pdu_dump(&pdu)
	}

	var ok bool = false
	if uint32(SNMP_V3) == pdu.version {
		var v3 V3PDU
		ok, err = v3.decodePDU(&pdu)
		if ok {
			return &v3, err
		}
		return nil, err
	}
	var v2 V2CPDU

	ok, err = v2.decodePDU(&pdu)
	if ok {
		return &v2, err
	}
	return nil, err
}
示例#3
0
func (pdu *V3PDU) encodePDU(bs []byte, is_dump bool) ([]byte, SnmpError) {
	internal := newNativePdu()
	C.snmp_pdu_init(internal)
	defer func() {
		C.snmp_pdu_free(internal)
		releaseNativePdu(internal)
	}()
	internal.request_id = C.int32_t(pdu.requestId)
	internal.pdu_type = C.u_int(pdu.op)
	internal.version = uint32(SNMP_V3)
	internal.error_status = C.int32_t(pdu.error_status)

	if SNMP_PDU_GETBULK == pdu.op {
		if pdu.variableBindings.Len() < pdu.non_repeaters {
			internal.error_status = C.int32_t(pdu.variableBindings.Len())
		} else {
			internal.error_status = C.int32_t(pdu.non_repeaters)
		}

		if pdu.max_repetitions > 0 {
			internal.error_index = C.int32_t(pdu.max_repetitions)
		} else {
			internal.error_index = C.int32_t(1)
		}
	}

	if pdu.identifier < 0 {
		internal.identifier = C.int32_t(pdu.requestId)
	} else {
		internal.identifier = C.int32_t(pdu.identifier)
	}
	internal.flags = 0

	if nil == pdu.contextEngine {
		internal.context_engine_len = C.uint32_t(0)
	} else {
		err := memcpy(&internal.context_engine[0], SNMP_ENGINE_ID_LEN, pdu.contextEngine)
		if nil != err {
			return nil, context_engine_failed //newError(SNMP_CODE_FAILED, err, "copy context_engine failed")
		}
		internal.context_engine_len = C.uint32_t(len(pdu.contextEngine))
	}

	err := strcpy(&internal.context_name[0], SNMP_CONTEXT_NAME_LEN, pdu.contextName)
	if nil != err {
		return nil, context_name_failed //newError(SNMP_CODE_FAILED, err, "copy context_name failed")
	}

	if nil != pdu.engine {
		err = memcpy(&internal.engine.engine_id[0], SNMP_ENGINE_ID_LEN, pdu.engine.engine_id)
		if nil != err {
			return nil, engine_id_failed //newError(SNMP_CODE_FAILED, err, "copy engine_id failed")
		}
		internal.engine.engine_len = C.uint32_t(len(pdu.engine.engine_id))
		internal.engine.engine_boots = C.int32_t(pdu.engine.engine_boots)
		internal.engine.engine_time = C.int32_t(pdu.engine.engine_time)
	}

	if 0 == pdu.maxMsgSize {
		pdu.maxMsgSize = *maxPDUSize
	}
	internal.engine.max_msg_size = C.int32_t(pdu.maxMsgSize)

	internal.security_model = SNMP_SECMODEL_USM
	if nil == pdu.securityModel {
		return nil, security_model_is_nil //newError(SNMP_CODE_FAILED, nil, "security model is nil")
	}
	err = pdu.securityModel.Write(&internal.user)
	if nil != err {
		return nil, newError(SNMP_CODE_FAILED, err, "fill security model failed")
	}

	err = encodeBindings(internal, pdu.GetVariableBindings())
	if nil != err {
		return nil, newError(SNMP_CODE_FAILED, err, "fill encode bindings failed")
	}

	if is_test {
		debug_init_secparams(internal)
	} else {
		C.snmp_pdu_init_secparams(internal)
	}

	if is_dump {
		C.snmp_pdu_dump(internal)
	}
	return encodeNativePdu(bs, internal)
}
示例#4
0
func (client *UdpClient) handleRecv(recv_bytes []byte) {
	defer func() {
		if e := recover(); nil != e {
			var buffer bytes.Buffer
			buffer.WriteString(fmt.Sprintf("[panic]%v", e))
			for i := 1; ; i += 1 {
				_, file, line, ok := runtime.Caller(i)
				if !ok {
					break
				}
				buffer.WriteString(fmt.Sprintf("    %s:%d\r\n", file, line))
			}
			client.ERROR.Print(client.logCtx, buffer.String())
		}
	}()

	var buffer C.asn_buf_t
	var result PDU
	var req *clientRequest
	var ok bool

	internal := newNativePdu()
	C.snmp_pdu_init(internal)
	defer releaseNativePdu(internal)

	C.set_asn_u_ptr(&buffer.asn_u, (*C.char)(unsafe.Pointer(&recv_bytes[0])))
	buffer.asn_len = C.size_t(len(recv_bytes))

	err := DecodePDUHeader(&buffer, internal)
	if nil != err {
		client.ERROR.Print(client.logCtx, "decode head of pdu failed", err)
		return
	}
	defer C.snmp_pdu_free(internal)

	if uint32(SNMP_V3) == internal.version {
		req, ok = client.pendings[int(internal.identifier)]
		if !ok {
			client.ERROR.Print(client.logCtx, "request with requestId was ", int(internal.identifier), " or ", int(internal.request_id), " is not exists.")

			// for i, _ := range client.pendings {
			// 	client.ERROR.Print(i)
			// }
			return
		}
		delete(client.pendings, int(internal.identifier))

		v3old, ok := req.request.(*V3PDU)
		if !ok {
			err = Error(SNMP_CODE_FAILED, "receive pdu is a v3 pdu.")
			goto complete
		}
		usm, ok := v3old.securityModel.(*USM)
		if !ok {
			err = Error(SNMP_CODE_FAILED, "receive pdu is not usm.")
			goto complete
		}
		err = FillUser(internal, usm.auth_proto, usm.localization_auth_key,
			usm.priv_proto, usm.localization_priv_key)
		if nil != err {
			client.ERROR.Print(client.logCtx, "fill user information failed,", err.Error())
			goto complete
		}

		err, ok = DecodePDUBody2(&buffer, internal)
		if nil != err {
			client.ERROR.Print(client.logCtx, "decode body of pdu failed", err.Error())
			goto complete
		}
		if ok {
			client.ERROR.Print(client.logCtx, "ignored some error", hex.EncodeToString(recv_bytes))
		}

		if client.DEBUG.IsEnabled() {
			C.snmp_pdu_dump(internal)
		}

		var v3 V3PDU
		_, err = v3.decodePDU(internal)
		result = &v3
	} else {
		err, ok = DecodePDUBody2(&buffer, internal)
		if nil != err {
			client.ERROR.Print(client.logCtx, "decode body of pdu failed", err.Error())
			return
		}

		if ok {
			client.ERROR.Print(client.logCtx, "ignored some error", hex.EncodeToString(recv_bytes))
		}

		req, ok = client.pendings[int(internal.request_id)]
		if !ok {
			client.ERROR.Print(client.logCtx, "request with requestId was", int(internal.request_id), "is not exists.")
			return
		}
		delete(client.pendings, int(internal.request_id))

		if client.DEBUG.IsEnabled() {
			C.snmp_pdu_dump(internal)
		}

		v2 := &V2CPDU{}
		_, err = v2.decodePDU(internal)
		result = v2
	}

complete:
	req.reply(result, err)
}