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 }
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 }
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) }
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) }
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) }