示例#1
0
func fill_pdu_for_test_crypt(is_encrypt bool, pt C.enum_snmp_privacy, salt, key, data []byte) ([]byte, error) {
	var digest [100000]byte
	var pdu C.snmp_pdu_t

	C.snmp_pdu_init(&pdu)

	pdu.user.priv_proto = pt

	C.memcpy(unsafe.Pointer(&pdu.user.priv_key[0]), unsafe.Pointer(&key[0]), C.size_t(C.SNMP_PRIV_KEY_SIZ))
	pdu.user.priv_len = C.size_t(16) //C.size_t(C.SNMP_PRIV_KEY_SIZ) //(au == SNMP_PRIV_DES ) ? SNMP_AUTH_HMACMD5_KEY_SIZ : SNMP_AUTH_HMACSHA_KEY_SIZ;

	pdu.engine.engine_boots = 3
	pdu.engine.engine_time = 3
	C.memcpy(unsafe.Pointer(&pdu.msg_salt[0]), unsafe.Pointer(&salt[0]), 8)

	copy(digest[:], data)
	pdu.scoped_ptr = (*C.u_char)(unsafe.Pointer(&digest[0]))
	pdu.scoped_len = C.size_t((len(data) / 8) * 8)
	var ret_code C.enum_snmp_code
	if is_encrypt {
		ret_code = C.snmp_pdu_encrypt(&pdu)
	} else {
		ret_code = C.snmp_pdu_decrypt(&pdu)
	}
	if 0 != ret_code {
		err := errors.New(C.GoString(C.snmp_pdu_get_error(&pdu, ret_code)))
		return nil, err
	}

	return readGoBytes((*C.uint8_t)(pdu.scoped_ptr), C.uint32_t(pdu.scoped_len)), nil
}
示例#2
0
func DecodePDUHeader(buffer *C.asn_buf_t, pdu *C.snmp_pdu_t) SnmpError {
	C.snmp_pdu_init(pdu)

	ret_code := C.snmp_pdu_decode_header(buffer, pdu)
	if 0 != ret_code {
		return Error(SNMP_CODE_FAILED, "decode pdu header failed -"+C.GoString(C.snmp_pdu_get_error(pdu, ret_code)))
	}
	return nil
}
示例#3
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)
}
示例#4
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)
}
示例#5
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)
}