void image_pvr_f_encode(INT32 args) { struct object *imgo; struct mapping *optm = NULL; struct image *alpha = NULL, *img; INT32 gbix=0, sz, attr=0; int has_gbix=0, twiddle=0, compress = 0; struct pike_string *res; unsigned char *dst; struct gla_state *gla_st = NULL; get_all_args("Image.PVR.encode", args, (args>1 && !UNSAFE_IS_ZERO(&sp[1-args])? "%o%m":"%o"), &imgo, &optm); if((img=(struct image*)get_storage(imgo, image_program))==NULL) Pike_error("Image.PVR.encode: illegal argument 1\n"); if(optm != NULL) { struct svalue *s; if((s = simple_mapping_string_lookup(optm, "alpha"))!=NULL && !UNSAFE_IS_ZERO(s)) if(s->type != T_OBJECT || (alpha=(struct image*)get_storage(s->u.object, image_program))==NULL) Pike_error("Image.PVR.encode: option (arg 2) \"alpha\" has illegal type\n"); if((s = simple_mapping_string_lookup(optm, "global_index"))!=NULL && !IS_UNDEFINED(s)) { if(s->type == T_INT) { gbix = s->u.integer; has_gbix=1; } else Pike_error("Image.PVR.encode: option (arg 2) \"global_index\" has illegal type\n"); } if((s = simple_mapping_string_lookup(optm, "vq"))!=NULL && !UNSAFE_IS_ZERO(s)) compress = 1; } if (!img->img) Pike_error("Image.PVR.encode: no image\n"); if (alpha && !alpha->img) Pike_error("Image.PVR.encode: no alpha image\n"); if (alpha && (alpha->xsize != img->xsize || alpha->ysize != img->ysize)) Pike_error("Image.PVR.encode: alpha and image size differ\n"); if(compress) sz=8+256*4*2+(img->xsize>>1)*(img->ysize>>1); else
int yr_execute_code( YR_RULES* rules, EVALUATION_CONTEXT* context, int timeout, time_t start_time) { int64_t r1; int64_t r2; int64_t r3; int64_t mem[MEM_SIZE]; int64_t stack[STACK_SIZE]; int32_t sp = 0; uint8_t* ip = rules->code_start; YR_RULE* rule; YR_STRING* string; YR_MATCH* match; YR_EXTERNAL_VARIABLE* external; int i; int found; int count; int result; int flags; int cycle = 0; int tidx = yr_get_tidx(); while(1) { switch(*ip) { case HALT: // When the halt instruction is reached the stack // should be empty. assert(sp == 0); return ERROR_SUCCESS; case PUSH: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); push(r1); break; case POP: pop(r1); break; case CLEAR_M: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); mem[r1] = 0; break; case ADD_M: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); pop(r2); mem[r1] += r2; break; case INCR_M: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); mem[r1]++; break; case PUSH_M: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); push(mem[r1]); break; case POP_M: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); pop(mem[r1]); break; case SWAPUNDEF: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); pop(r2); if (r2 != UNDEFINED) push(r2); else push(mem[r1]); break; case JNUNDEF: pop(r1); push(r1); if (r1 != UNDEFINED) { ip = *(uint8_t**)(ip + 1); // ip will be incremented at the end of the loop, // decrement it here to compensate. ip--; } else { ip += sizeof(uint64_t); } break; case JLE: pop(r2); pop(r1); push(r1); push(r2); if (r1 <= r2) { ip = *(uint8_t**)(ip + 1); // ip will be incremented at the end of the loop, // decrement it here to compensate. ip--; } else { ip += sizeof(uint64_t); } break; case AND: pop(r2); pop(r1); push(r1 & r2); break; case OR: pop(r2); pop(r1); push(r1 | r2); break; case NOT: pop(r1); push(!r1); break; case LT: pop(r2); pop(r1); push(comparison(<, r1, r2)); break; case GT: pop(r2); pop(r1); push(comparison(>, r1, r2)); break; case LE: pop(r2); pop(r1); push(comparison(<=, r1, r2)); break; case GE: pop(r2); pop(r1); push(comparison(>=, r1, r2)); break; case EQ: pop(r2); pop(r1); push(comparison(==, r1, r2)); break; case NEQ: pop(r2); pop(r1); push(comparison(!=, r1, r2)); break; case ADD: pop(r2); pop(r1); push(operation(+, r1, r2)); break; case SUB: pop(r2); pop(r1); push(operation(-, r1, r2)); break; case MUL: pop(r2); pop(r1); push(operation(*, r1, r2)); break; case DIV: pop(r2); pop(r1); push(operation(/, r1, r2)); break; case MOD: pop(r2); pop(r1); push(operation(%, r1, r2)); break; case NEG: pop(r1); push(IS_UNDEFINED(r1) ? UNDEFINED : ~r1); break; case SHR: pop(r2); pop(r1); push(operation(>>, r1, r2)); break; case SHL: pop(r2); pop(r1); push(operation(<<, r1, r2)); break; case XOR: pop(r2); pop(r1); push(operation(^, r1, r2)); break; case RULE_PUSH: rule = *(YR_RULE**)(ip + 1); ip += sizeof(uint64_t); push(rule->t_flags[tidx] & RULE_TFLAGS_MATCH ? 1 : 0); break; case RULE_POP: pop(r1); rule = *(YR_RULE**)(ip + 1); ip += sizeof(uint64_t); if (r1) rule->t_flags[tidx] |= RULE_TFLAGS_MATCH; break; case EXT_INT: external = *(YR_EXTERNAL_VARIABLE**)(ip + 1); ip += sizeof(uint64_t); push(external->integer); break; case EXT_STR: external = *(YR_EXTERNAL_VARIABLE**)(ip + 1); ip += sizeof(uint64_t); push(PTR_TO_UINT64(external->string)); break; case EXT_BOOL: external = *(YR_EXTERNAL_VARIABLE**)(ip + 1); ip += sizeof(uint64_t); if (external->type == EXTERNAL_VARIABLE_TYPE_FIXED_STRING || external->type == EXTERNAL_VARIABLE_TYPE_MALLOC_STRING) push(external->string[0] != '\0'); else push(external->integer); break; case SFOUND: pop(r1); string = UINT64_TO_PTR(YR_STRING*, r1); push(string->matches[tidx].tail != NULL ? 1 : 0); break; case SFOUND_AT: pop(r2); pop(r1); if (IS_UNDEFINED(r1)) { push(0); break; } string = UINT64_TO_PTR(YR_STRING*, r2); match = string->matches[tidx].head; found = 0; while (match != NULL) { if (r1 == match->offset) { push(1); found = 1; break; } if (r1 < match->offset) break; match = match->next; } if (!found) push(0); break; case SFOUND_IN: pop(r3); pop(r2); pop(r1); if (IS_UNDEFINED(r1) || IS_UNDEFINED(r2)) { push(0); break; } string = UINT64_TO_PTR(YR_STRING*, r3); match = string->matches[tidx].head; found = FALSE; while (match != NULL && !found) { if (match->offset >= r1 && match->offset <= r2) { push(1); found = TRUE; } if (match->offset > r2) break; match = match->next; } if (!found) push(0); break; case SCOUNT: pop(r1); string = UINT64_TO_PTR(YR_STRING*, r1); match = string->matches[tidx].head; found = 0; while (match != NULL) { found++; match = match->next; } push(found); break; case SOFFSET: pop(r2); pop(r1); if (IS_UNDEFINED(r1)) { push(UNDEFINED); break; } string = UINT64_TO_PTR(YR_STRING*, r2); match = string->matches[tidx].head; i = 1; found = FALSE; while (match != NULL && !found) { if (r1 == i) { push(match->offset); found = TRUE; } i++; match = match->next; } if (!found) push(UNDEFINED); break; case OF: found = 0; count = 0; pop(r1); while (r1 != UNDEFINED) { string = UINT64_TO_PTR(YR_STRING*, r1); if (string->matches[tidx].tail != NULL) found++; count++; pop(r1); } pop(r2); if (r2 != UNDEFINED) push(found >= r2 ? 1 : 0); else push(found >= count ? 1 : 0); break; case SIZE: push(context->file_size); break; case ENTRYPOINT: push(context->entry_point); break; case INT8: pop(r1); push(read_int8_t(context->mem_block, r1)); break; case INT16: pop(r1); push(read_int16_t(context->mem_block, r1)); break; case INT32: pop(r1); push(read_int32_t(context->mem_block, r1)); break; case UINT8: pop(r1); push(read_uint8_t(context->mem_block, r1)); break; case UINT16: pop(r1); push(read_uint16_t(context->mem_block, r1)); break; case UINT32: pop(r1); push(read_uint32_t(context->mem_block, r1)); break; case CONTAINS: pop(r2); pop(r1); push(strstr(UINT64_TO_PTR(char*, r1), UINT64_TO_PTR(char*, r2)) != NULL); break; case MATCHES: pop(r3); pop(r2); pop(r1); flags = (int) r3; count = strlen(UINT64_TO_PTR(char*, r1)); if (count == 0) { push(FALSE); break; } result = yr_re_exec( UINT64_TO_PTR(uint8_t*, r2), UINT64_TO_PTR(uint8_t*, r1), count, flags | RE_FLAGS_SCAN, NULL, NULL); push(result >= 0); break; default: // Unknown instruction, this shouldn't happen. assert(FALSE); } if (timeout > 0) // timeout == 0 means no timeout { // Check for timeout every 10 instruction cycles. if (++cycle == 10) { if (difftime(time(NULL), start_time) > timeout) return ERROR_SCAN_TIMEOUT; cycle = 0; } } ip++; } // After executing the code the stack should be empty. assert(sp == 0); return ERROR_SUCCESS; }
int yr_execute_code( YR_RULES* rules, YR_SCAN_CONTEXT* context, int timeout, time_t start_time) { int64_t r1; int64_t r2; int64_t r3; int64_t mem[MEM_SIZE]; int64_t stack[STACK_SIZE]; int64_t args[MAX_FUNCTION_ARGS]; int32_t sp = 0; uint8_t* ip = rules->code_start; YR_RULE* rule; YR_STRING* string; YR_MATCH* match; YR_OBJECT* object; YR_OBJECT_FUNCTION* function; char* identifier; char* args_fmt; int i; int found; int count; int result; int cycle = 0; int tidx = yr_get_tidx(); #ifdef PROFILING_ENABLED clock_t start = clock(); #endif while(1) { switch(*ip) { case OP_HALT: // When the halt instruction is reached the stack // should be empty. assert(sp == 0); return ERROR_SUCCESS; case OP_PUSH: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); push(r1); break; case OP_POP: pop(r1); break; case OP_CLEAR_M: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); mem[r1] = 0; break; case OP_ADD_M: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); pop(r2); mem[r1] += r2; break; case OP_INCR_M: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); mem[r1]++; break; case OP_PUSH_M: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); push(mem[r1]); break; case OP_POP_M: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); pop(mem[r1]); break; case OP_SWAPUNDEF: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); pop(r2); if (r2 != UNDEFINED) push(r2); else push(mem[r1]); break; case OP_JNUNDEF: pop(r1); push(r1); if (r1 != UNDEFINED) { ip = *(uint8_t**)(ip + 1); // ip will be incremented at the end of the loop, // decrement it here to compensate. ip--; } else { ip += sizeof(uint64_t); } break; case OP_JLE: pop(r2); pop(r1); push(r1); push(r2); if (r1 <= r2) { ip = *(uint8_t**)(ip + 1); // ip will be incremented at the end of the loop, // decrement it here to compensate. ip--; } else { ip += sizeof(uint64_t); } break; case OP_AND: pop(r2); pop(r1); if (IS_UNDEFINED(r1) || IS_UNDEFINED(r2)) push(0); else push(r1 && r2); break; case OP_OR: pop(r2); pop(r1); if (IS_UNDEFINED(r1)) push(r2); else if (IS_UNDEFINED(r2)) push(r1); else push(r1 || r2); break; case OP_NOT: pop(r1); if (IS_UNDEFINED(r1)) push(UNDEFINED); else push(!r1); break; case OP_LT: pop(r2); pop(r1); push(COMPARISON(<, r1, r2)); break; case OP_GT: pop(r2); pop(r1); push(COMPARISON(>, r1, r2)); break; case OP_LE: pop(r2); pop(r1); push(COMPARISON(<=, r1, r2)); break; case OP_GE: pop(r2); pop(r1); push(COMPARISON(>=, r1, r2)); break; case OP_EQ: pop(r2); pop(r1); push(COMPARISON(==, r1, r2)); break; case OP_NEQ: pop(r2); pop(r1); push(COMPARISON(!=, r1, r2)); break; case OP_SZ_EQ: pop(r2); pop(r1); if (IS_UNDEFINED(r1) || IS_UNDEFINED(r2)) push(UNDEFINED); else push(strcmp(UINT64_TO_PTR(char*, r1), UINT64_TO_PTR(char*, r2)) == 0); break; case OP_SZ_NEQ: pop(r2); pop(r1); if (IS_UNDEFINED(r1) || IS_UNDEFINED(r2)) push(UNDEFINED); else push(strcmp(UINT64_TO_PTR(char*, r1), UINT64_TO_PTR(char*, r2)) != 0); break; case OP_SZ_TO_BOOL: pop(r1); if (IS_UNDEFINED(r1)) push(UNDEFINED); else push(strlen(UINT64_TO_PTR(char*, r1)) > 0); break; case OP_ADD: pop(r2); pop(r1); push(OPERATION(+, r1, r2)); break; case OP_SUB: pop(r2); pop(r1); push(OPERATION(-, r1, r2)); break; case OP_MUL: pop(r2); pop(r1); push(OPERATION(*, r1, r2)); break; case OP_DIV: pop(r2); pop(r1); push(OPERATION(/, r1, r2)); break; case OP_MOD: pop(r2); pop(r1); push(OPERATION(%, r1, r2)); break; case OP_SHR: pop(r2); pop(r1); push(OPERATION(>>, r1, r2)); break; case OP_SHL: pop(r2); pop(r1); push(OPERATION(<<, r1, r2)); break; case OP_BITWISE_NOT: pop(r1); push(IS_UNDEFINED(r1) ? UNDEFINED : ~r1); break; case OP_BITWISE_AND: pop(r2); pop(r1); push(OPERATION(&, r1, r2)); break; case OP_BITWISE_OR: pop(r2); pop(r1); push(OPERATION(|, r1, r2)); break; case OP_BITWISE_XOR: pop(r2); pop(r1); push(OPERATION(^, r1, r2)); break; case OP_PUSH_RULE: rule = *(YR_RULE**)(ip + 1); ip += sizeof(uint64_t); push(rule->t_flags[tidx] & RULE_TFLAGS_MATCH ? 1 : 0); break; case OP_MATCH_RULE: pop(r1); rule = *(YR_RULE**)(ip + 1); ip += sizeof(uint64_t); if (!IS_UNDEFINED(r1) && r1) rule->t_flags[tidx] |= RULE_TFLAGS_MATCH; #ifdef PROFILING_ENABLED rule->clock_ticks += clock() - start; start = clock(); #endif break; case OP_OBJ_LOAD: identifier = *(char**)(ip + 1); ip += sizeof(uint64_t); object = (YR_OBJECT*) yr_hash_table_lookup( context->objects_table, identifier, NULL); assert(object != NULL); push(PTR_TO_UINT64(object)); break; case OP_OBJ_FIELD: pop(r1); identifier = *(char**)(ip + 1); ip += sizeof(uint64_t); if (IS_UNDEFINED(r1)) { push(UNDEFINED); break; } object = UINT64_TO_PTR(YR_OBJECT*, r1); object = yr_object_lookup_field(object, identifier); assert(object != NULL); push(PTR_TO_UINT64(object)); break; case OP_OBJ_VALUE: pop(r1); if (IS_UNDEFINED(r1)) { push(UNDEFINED); break; } object = UINT64_TO_PTR(YR_OBJECT*, r1); switch(object->type) { case OBJECT_TYPE_INTEGER: push(((YR_OBJECT_INTEGER*) object)->value); break; case OBJECT_TYPE_STRING: if (((YR_OBJECT_STRING*) object)->value != NULL) push(PTR_TO_UINT64(((YR_OBJECT_STRING*) object)->value)); else push(UNDEFINED); break; default: assert(FALSE); } break; case OP_INDEX_ARRAY: pop(r1); // index pop(r2); // array if (IS_UNDEFINED(r1)) { push(UNDEFINED); break; } object = UINT64_TO_PTR(YR_OBJECT*, r2); assert(object->type == OBJECT_TYPE_ARRAY); object = yr_object_array_get_item(object, 0, r1); if (object != NULL) push(PTR_TO_UINT64(object)); else push(UNDEFINED); break; case OP_LOOKUP_DICT: pop(r1); // key pop(r2); // dictionary if (IS_UNDEFINED(r1)) { push(UNDEFINED); break; } object = UINT64_TO_PTR(YR_OBJECT*, r2); assert(object->type == OBJECT_TYPE_DICTIONARY); object = yr_object_dict_get_item( object, 0, UINT64_TO_PTR(const char*, r1)); if (object != NULL) push(PTR_TO_UINT64(object)); else push(UNDEFINED); break; case OP_CALL: args_fmt = *(char**)(ip + 1); ip += sizeof(uint64_t); i = strlen(args_fmt); // pop arguments from stack and copy them to args array while (i > 0) { pop(args[i - 1]); i--; } pop(r2); function = UINT64_TO_PTR(YR_OBJECT_FUNCTION*, r2); result = ERROR_INTERNAL_FATAL_ERROR; for (i = 0; i < MAX_OVERLOADED_FUNCTIONS; i++) { if (function->prototypes[i].arguments_fmt == NULL) break; if (strcmp(function->prototypes[i].arguments_fmt, args_fmt) == 0) { result = function->prototypes[i].code( (void*) args, context, function); break; } } assert(i < MAX_OVERLOADED_FUNCTIONS); if (result == ERROR_SUCCESS) push(PTR_TO_UINT64(function->return_obj)); else return result; break; case OP_STR_FOUND: pop(r1); string = UINT64_TO_PTR(YR_STRING*, r1); push(string->matches[tidx].tail != NULL ? 1 : 0); break; case OP_STR_FOUND_AT: pop(r2); pop(r1); if (IS_UNDEFINED(r1)) { push(0); break; } string = UINT64_TO_PTR(YR_STRING*, r2); match = string->matches[tidx].head; found = 0; while (match != NULL) { if (r1 == match->base + match->offset) { push(1); found = 1; break; } if (r1 < match->base + match->offset) break; match = match->next; } if (!found) push(0); break; case OP_STR_FOUND_IN: pop(r3); pop(r2); pop(r1); if (IS_UNDEFINED(r1) || IS_UNDEFINED(r2)) { push(UNDEFINED); break; } string = UINT64_TO_PTR(YR_STRING*, r3); match = string->matches[tidx].head; found = FALSE; while (match != NULL && !found) { if (match->base + match->offset >= r1 && match->base + match->offset <= r2) { push(1); found = TRUE; } if (match->base + match->offset > r2) break; match = match->next; } if (!found) push(0); break; case OP_STR_COUNT: pop(r1); string = UINT64_TO_PTR(YR_STRING*, r1); push(string->matches[tidx].count); break; case OP_STR_OFFSET: pop(r2); pop(r1); if (IS_UNDEFINED(r1)) { push(UNDEFINED); break; } string = UINT64_TO_PTR(YR_STRING*, r2); match = string->matches[tidx].head; i = 1; found = FALSE; while (match != NULL && !found) { if (r1 == i) { push(match->base + match->offset); found = TRUE; } i++; match = match->next; } if (!found) push(UNDEFINED); break; case OP_OF: found = 0; count = 0; pop(r1); while (r1 != UNDEFINED) { string = UINT64_TO_PTR(YR_STRING*, r1); if (string->matches[tidx].tail != NULL) found++; count++; pop(r1); } pop(r2); if (r2 != UNDEFINED) push(found >= r2 ? 1 : 0); else push(found >= count ? 1 : 0); break; case OP_FILESIZE: push(context->file_size); break; case OP_ENTRYPOINT: push(context->entry_point); break; case OP_INT8: pop(r1); push(read_int8_t(context->mem_block, r1)); break; case OP_INT16: pop(r1); push(read_int16_t(context->mem_block, r1)); break; case OP_INT32: pop(r1); push(read_int32_t(context->mem_block, r1)); break; case OP_UINT8: pop(r1); push(read_uint8_t(context->mem_block, r1)); break; case OP_UINT16: pop(r1); push(read_uint16_t(context->mem_block, r1)); break; case OP_UINT32: pop(r1); push(read_uint32_t(context->mem_block, r1)); break; case OP_CONTAINS: pop(r2); pop(r1); if (IS_UNDEFINED(r1) || IS_UNDEFINED(r2)) push(UNDEFINED); else push(strstr(UINT64_TO_PTR(char*, r1), UINT64_TO_PTR(char*, r2)) != NULL); break; case OP_IMPORT: r1 = *(uint64_t*)(ip + 1); ip += sizeof(uint64_t); FAIL_ON_ERROR(yr_modules_load( UINT64_TO_PTR(char*, r1), context)); break; case OP_MATCHES: pop(r2); pop(r1); count = strlen(UINT64_TO_PTR(char*, r1)); if (count == 0) { push(FALSE); break; } result = yr_re_exec( UINT64_TO_PTR(uint8_t*, r2), UINT64_TO_PTR(uint8_t*, r1), count, RE_FLAGS_SCAN, NULL, NULL); push(result >= 0); break; default: // Unknown instruction, this shouldn't happen. assert(FALSE); } if (timeout > 0) // timeout == 0 means no timeout { // Check for timeout every 10 instruction cycles. if (++cycle == 10) { if (difftime(time(NULL), start_time) > timeout) return ERROR_SCAN_TIMEOUT; cycle = 0; } } ip++; } // After executing the code the stack should be empty. assert(sp == 0); return ERROR_SUCCESS; }
/*! \fn char *snmp_get_multi(host_t *current_host, snmp_oids_t *snmp_oids, int num_oids) * \brief performs multiple OID snmp_get's in a single network call * * This function will a group of snmp OID's for a host. The host snmp * session must already be established. The function will modify elements of * the snmp_oids array with the results from the snmp api call. * */ void snmp_get_multi(host_t *current_host, snmp_oids_t *snmp_oids, int num_oids) { struct snmp_pdu *pdu = NULL; struct snmp_pdu *response = NULL; struct variable_list *vars = NULL; int status; int i; int max_repetitions = 1; int non_repeaters = 0; int array_count; int index_count; /* get rid of some compiler warnings */ errstat = 0; errindex = 0; struct nameStruct { oid name[MAX_OID_LEN]; size_t name_len; } *name, *namep; /* load up oids */ namep = name = (struct nameStruct *) calloc(num_oids, sizeof(*name)); pdu = snmp_pdu_create(SNMP_MSG_GET); for (i = 0; i < num_oids; i++) { namep->name_len = MAX_OID_LEN; if (!snmp_parse_oid(snmp_oids[i].oid, namep->name, &namep->name_len)) { SPINE_LOG(("Host[%i] ERROR: Problems parsing Multi SNMP OID! (oid: %s)\n", current_host->id, snmp_oids[i].oid)); /* Mark this OID as "bad" */ SET_UNDEFINED(snmp_oids[i].result); }else{ snmp_add_null_var(pdu, namep->name, namep->name_len); } namep++; } status = STAT_DESCRIP_ERROR; /* execute the multi-get request */ retry: status = snmp_sess_synch_response(current_host->snmp_session, pdu, &response); /* liftoff, successful poll, process it!! */ if (status == STAT_SUCCESS) { if (response == NULL) { SPINE_LOG(("ERROR: An internal Net-Snmp error condition detected in Cacti snmp_get_multi\n")); status = STAT_ERROR; }else{ if (response->errstat == SNMP_ERR_NOERROR) { vars = response->variables; for(i = 0; i < num_oids && vars; i++) { if (!IS_UNDEFINED(snmp_oids[i].result)) { #ifdef USE_NET_SNMP snmp_snprint_value(snmp_oids[i].result, RESULTS_BUFFER, vars->name, vars->name_length, vars); #else sprint_value(snmp_oids[i].result, vars->name, vars->name_length, vars); #endif vars = vars->next_variable; } } }else{ if (response->errindex != 0) { index_count = 1; array_count = 0; /* Find our index against errindex */ while (array_count < num_oids) { if (IS_UNDEFINED(snmp_oids[array_count].result) ) { array_count++; }else{ /* if we have found our error, exit */ if (index_count == response->errindex) { SET_UNDEFINED(snmp_oids[array_count].result); break; } array_count++; index_count++; } } /* remote the invalid OID from the PDU */ pdu = snmp_fix_pdu(response, SNMP_MSG_GET); /* free the previous response */ snmp_free_pdu(response); response = NULL; if (pdu != NULL) { /* retry the request */ goto retry; }else{ /* all OID's errored out so exit cleanly */ status = STAT_SUCCESS; } }else{ status = STAT_DESCRIP_ERROR; } } } } if (status != STAT_SUCCESS) { current_host->ignore_host = 1; for (i = 0; i < num_oids; i++) { SET_UNDEFINED(snmp_oids[i].result); } } if (response != NULL) { snmp_free_pdu(response); } }
/*! \fn char *snmp_get_multi(host_t *current_host, snmp_oids_t *snmp_oids, int num_oids) * \brief performs multiple OID snmp_get's in a single network call * * This function will a group of snmp OID's for a host. The host snmp * session must already be established. The function will modify elements of * the snmp_oids array with the results from the snmp api call. * */ void snmp_get_multi(host_t *current_host, snmp_oids_t *snmp_oids, int num_oids) { struct snmp_pdu *pdu = NULL; struct snmp_pdu *response = NULL; struct variable_list *vars = NULL; int status; int i; int max_repetitions = 1; int non_repeaters = 0; struct nameStruct { oid name[MAX_OID_LEN]; size_t name_len; } *name, *namep; /* load up oids */ namep = name = (struct nameStruct *) calloc(num_oids, sizeof(*name)); pdu = snmp_pdu_create(SNMP_MSG_GET); for (i = 0; i < num_oids; i++) { namep->name_len = MAX_OID_LEN; if (!snmp_parse_oid(snmp_oids[i].oid, namep->name, &namep->name_len)) { CACTID_LOG(("Host[%i] ERROR: Problems parsing Multi SNMP OID! (oid: %s)\n", current_host->id, snmp_oids[i].oid)); /* Mark this OID as "bad" */ SET_UNDEFINED(snmp_oids[i].result); }else{ snmp_add_null_var(pdu, namep->name, namep->name_len); } namep++; } status = STAT_DESCRIP_ERROR; /* execute the multi-get request */ retry: status = snmp_sess_synch_response(current_host->snmp_session, pdu, &response); /* liftoff, successful poll, process it!! */ if (status == STAT_SUCCESS) { if (response == NULL) { CACTID_LOG(("ERROR: An internal Net-Snmp error condition detected in Cacti snmp_get_multi\n")); status = STAT_ERROR; }else{ if (response->errstat == SNMP_ERR_NOERROR) { vars = response->variables; for(i = 0; i < num_oids && vars; i++) { if (!IS_UNDEFINED(snmp_oids[i].result)) { #ifdef USE_NET_SNMP snmp_snprint_value(snmp_oids[i].result, sizeof(snmp_oids[i].result), vars->name, vars->name_length, vars); #else sprint_value(snmp_oids[i].result, vars->name, vars->name_length, vars); #endif vars = vars->next_variable; } } }else{ if (response->errindex != 0) { /* removed errored OID and then retry */ int count; /* Find our index against errindex */ count = 0; for(i = 0; i < num_oids && count < response->errindex; i++) { if ( ! IS_UNDEFINED(snmp_oids[i].result) ) { count++; } } i--; SET_UNDEFINED(snmp_oids[i].result); for (count = 1, vars = response->variables; vars && count != response->errindex; vars = vars->next_variable, count++) { } pdu = snmp_fix_pdu(response, SNMP_MSG_GET); snmp_free_pdu(response); response = NULL; if (pdu != NULL) { goto retry; }else{ status = STAT_DESCRIP_ERROR; } }else{ status = STAT_DESCRIP_ERROR; } } } } if (status != STAT_SUCCESS) { current_host->ignore_host = 1; for (i = 0; i < num_oids; i++) { SET_UNDEFINED(snmp_oids[i].result); } } if (response != NULL) { snmp_free_pdu(response); } }
long long evaluate(TERM* term, EVALUATION_CONTEXT* context) { size_t offs, hi_bound, lo_bound; long long op1; long long op2; long long index; unsigned int i; unsigned int needed; unsigned int satisfied; int ovector[3]; int rc; STRING* string; STRING* saved_anonymous_string; TERM_CONST* term_const = ((TERM_CONST*) term); TERM_UNARY_OPERATION* term_unary = ((TERM_UNARY_OPERATION*) term); TERM_BINARY_OPERATION* term_binary = ((TERM_BINARY_OPERATION*) term); TERM_TERNARY_OPERATION* term_ternary = ((TERM_TERNARY_OPERATION*) term); TERM_STRING* term_string = ((TERM_STRING*) term); TERM_VARIABLE* term_variable = ((TERM_VARIABLE*) term); TERM_STRING_OPERATION* term_string_operation = ((TERM_STRING_OPERATION*) term); TERM_INTEGER_FOR* term_integer_for; MATCH* match; TERM* item; TERM_RANGE* range; TERM_ITERABLE* items; TERM_STRING* t; switch(term->type) { case TERM_TYPE_CONST: return term_const->value; case TERM_TYPE_FILESIZE: return context->file_size; case TERM_TYPE_ENTRYPOINT: return context->entry_point; case TERM_TYPE_RULE: return evaluate(term_binary->op1, context); case TERM_TYPE_STRING: if (term_string->string == NULL) /* it's an anonymous string */ { string = context->current_string; } else { string = term_string->string; } return string->flags & STRING_FLAGS_FOUND; case TERM_TYPE_STRING_AT: if (term_string->string == NULL) /* it's an anonymous string */ { string = context->current_string; } else { string = term_string->string; } if (string->flags & STRING_FLAGS_FOUND) { offs = evaluate(term_string->offset, context); match = string->matches_head; while (match != NULL) { if (match->offset == offs) return 1; match = match->next; } return 0; } else return 0; case TERM_TYPE_STRING_IN_RANGE: if (term_string->string == NULL) /* it's an anonymous string */ { string = context->current_string; } else { string = term_string->string; } if (string->flags & STRING_FLAGS_FOUND) { range = (TERM_RANGE*) term_string->range; lo_bound = evaluate(range->min, context); hi_bound = evaluate(range->max, context); match = string->matches_head; while (match != NULL) { if (match->offset >= lo_bound && match->offset <= hi_bound) return 1; match = match->next; } return 0; } else return 0; case TERM_TYPE_STRING_IN_SECTION_BY_NAME: return 0; /*TODO: Implementar section by name*/ case TERM_TYPE_STRING_COUNT: i = 0; if (term_string->string == NULL) /* it's an anonymous string */ { string = context->current_string; } else { string = term_string->string; } match = string->matches_head; while (match != NULL) { i++; match = match->next; } return i; case TERM_TYPE_STRING_OFFSET: i = 1; index = evaluate(term_string->index, context); if (term_string->string == NULL) /* it's an anonymous string */ { string = context->current_string; } else { string = term_string->string; } match = string->matches_head; while (match != NULL && i < index) { match = match->next; i++; } if (match != NULL && i == index) { return match->offset; } return UNDEFINED; case TERM_TYPE_AND: if (evaluate(term_binary->op1, context)) return evaluate(term_binary->op2, context); else return 0; case TERM_TYPE_OR: if (evaluate(term_binary->op1, context)) return 1; else return evaluate(term_binary->op2, context); case TERM_TYPE_NOT: return !evaluate(term_unary->op, context); case TERM_TYPE_ADD: ARITHMETIC_OPERATOR(+, term_binary, context); case TERM_TYPE_SUB: ARITHMETIC_OPERATOR(-, term_binary, context); case TERM_TYPE_MUL: ARITHMETIC_OPERATOR(*, term_binary, context); case TERM_TYPE_DIV: ARITHMETIC_OPERATOR(/, term_binary, context); case TERM_TYPE_BITWISE_AND: ARITHMETIC_OPERATOR(&, term_binary, context); case TERM_TYPE_BITWISE_OR: ARITHMETIC_OPERATOR(|, term_binary, context); case TERM_TYPE_SHIFT_LEFT: ARITHMETIC_OPERATOR(<<, term_binary, context); case TERM_TYPE_SHIFT_RIGHT: ARITHMETIC_OPERATOR(>>, term_binary, context); case TERM_TYPE_BITWISE_NOT: op1 = evaluate(term_unary->op, context); if (IS_UNDEFINED(op1)) return UNDEFINED; else return ~op1; case TERM_TYPE_GT: COMPARISON_OPERATOR(>, term_binary, context); case TERM_TYPE_LT: COMPARISON_OPERATOR(<, term_binary, context); case TERM_TYPE_GE: COMPARISON_OPERATOR(>=, term_binary, context); case TERM_TYPE_LE: COMPARISON_OPERATOR(<=, term_binary, context); case TERM_TYPE_EQ: COMPARISON_OPERATOR(==, term_binary, context); case TERM_TYPE_NOT_EQ: COMPARISON_OPERATOR(!=, term_binary, context); case TERM_TYPE_OF: t = (TERM_STRING*) term_binary->op2; needed = evaluate(term_binary->op1, context); satisfied = 0; i = 0; while (t != NULL) { if (evaluate((TERM*) t, context)) { satisfied++; } t = t->next; i++; } if (needed == 0) /* needed == 0 means ALL*/ needed = i; return (satisfied >= needed); case TERM_TYPE_STRING_FOR: t = (TERM_STRING*) term_ternary->op2; needed = evaluate(term_ternary->op1, context); satisfied = 0; i = 0; while (t != NULL) { saved_anonymous_string = context->current_string; context->current_string = t->string; if (evaluate(term_ternary->op3, context)) { satisfied++; } context->current_string = saved_anonymous_string; t = t->next; i++; } if (needed == 0) /* needed == 0 means ALL*/ needed = i; return (satisfied >= needed); case TERM_TYPE_INTEGER_FOR: term_integer_for = (TERM_INTEGER_FOR*) term; items = term_integer_for->items; needed = evaluate(term_integer_for->count, context); satisfied = 0; i = 0; item = items->first(items, evaluate, context); while (item != NULL) { term_integer_for->variable->integer = evaluate(item, context); if (evaluate(term_integer_for->expression, context)) { satisfied++; } item = items->next(items, evaluate, context); i++; } if (needed == 0) /* needed == 0 means ALL*/ needed = i; return (satisfied >= needed); case TERM_TYPE_UINT8_AT_OFFSET: return read_uint8(context->mem_block, evaluate(term_unary->op, context)); case TERM_TYPE_UINT16_AT_OFFSET: return read_uint16(context->mem_block, evaluate(term_unary->op, context)); case TERM_TYPE_UINT32_AT_OFFSET: return read_uint32(context->mem_block, evaluate(term_unary->op, context)); case TERM_TYPE_INT8_AT_OFFSET: return read_int8(context->mem_block, evaluate(term_unary->op, context)); case TERM_TYPE_INT16_AT_OFFSET: return read_int16(context->mem_block, evaluate(term_unary->op, context)); case TERM_TYPE_INT32_AT_OFFSET: return read_int32(context->mem_block, evaluate(term_unary->op, context)); case TERM_TYPE_VARIABLE: if (term_variable->variable->type == VARIABLE_TYPE_STRING) { return ( term_variable->variable->string != NULL && *term_variable->variable->string != '\0'); } else { return term_variable->variable->integer; } case TERM_TYPE_STRING_MATCH: rc = regex_exec(&(term_string_operation->re), FALSE, term_string_operation->variable->string, strlen(term_string_operation->variable->string)); return (rc >= 0); case TERM_TYPE_STRING_CONTAINS: return (strstr(term_string_operation->variable->string, term_string_operation->string) != NULL); default: return 0; } }