void ln_displayPTree(struct ln_ptree *tree, int level) { int i; int nChildLit; int nChildField; es_str_t *str; char *cstr; ln_fieldList_t *node; char indent[2048]; if(level > 1023) level = 1023; memset(indent, ' ', level * 2); indent[level * 2] = '\0'; nChildField = 0; for(node = tree->froot ; node != NULL ; node = node->next ) { ++nChildField; } nChildLit = 0; for(i = 0 ; i < 256 ; ++i) { if(tree->subtree[i] != NULL) { nChildLit++; } } str = es_newStr(sizeof(tree->prefix)); es_addBuf(&str, (char*) prefixBase(tree), tree->lenPrefix); cstr = es_str2cstr(str, NULL); es_deleteStr(str); ln_dbgprintf(tree->ctx, "%ssubtree%s %p (prefix: '%s', children: %d literals, %d fields)", indent, tree->flags.isTerminal ? " TERM" : "", tree, cstr, nChildLit, nChildField); free(cstr); /* display char subtrees */ for(i = 0 ; i < 256 ; ++i) { if(tree->subtree[i] != NULL) { ln_dbgprintf(tree->ctx, "%schar %2.2x(%c):", indent, i, i); ln_displayPTree(tree->subtree[i], level + 1); } } /* display field subtrees */ for(node = tree->froot ; node != NULL ; node = node->next ) { cstr = es_str2cstr(node->name, NULL); ln_dbgprintf(tree->ctx, "%sfield %s:", indent, cstr); free(cstr); ln_displayPTree(node->subtree, level + 1); } }
rsRetVal lookupProcessCnf(struct cnfobj *o) { struct cnfparamvals *pvals; lookup_t *lu; short i; DEFiRet; pvals = nvlstGetParams(o->nvlst, &modpblk, NULL); if(pvals == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } DBGPRINTF("lookupProcessCnf params:\n"); cnfparamsPrint(&modpblk, pvals); CHKiRet(lookupNew(&lu)); for(i = 0 ; i < modpblk.nParams ; ++i) { if(!pvals[i].bUsed) continue; if(!strcmp(modpblk.descr[i].name, "file")) { CHKmalloc(lu->filename = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL)); } else if(!strcmp(modpblk.descr[i].name, "name")) { CHKmalloc(lu->name = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL)); } else { dbgprintf("lookup_table: program error, non-handled " "param '%s'\n", modpblk.descr[i].name); } } CHKiRet(lookupReadFile(lu)); DBGPRINTF("lookup table '%s' loaded from file '%s'\n", lu->name, lu->filename); finalize_it: cnfparamvalsDestruct(pvals, &modpblk); RETiRet; }
struct ln_ptree * ln_addPTree(struct ln_ptree *tree, es_str_t *str, size_t offs) { struct ln_ptree *r; struct ln_ptree **parentptr; /**< pointer in parent that needs to be updated */ ln_dbgprintf(tree->ctx, "addPTree: offs %zu", offs); parentptr = &(tree->subtree[es_getBufAddr(str)[offs]]); /* First check if tree node is totaly empty. If so, we can simply add * the prefix to this node. This case is important, because it happens * every time with a new field. */ if(isTrueLeaf(tree)) { if(setPrefix(tree, es_getBufAddr(str), es_strlen(str), offs) != 0) { r = NULL; } else { r = tree; } goto done; } if(tree->ctx->debug) { char *cstr = es_str2cstr(str, NULL); ln_dbgprintf(tree->ctx, "addPTree: add '%s', offs %zu, tree %p", cstr + offs, offs, tree); free(cstr); } if((r = ln_newPTree(tree->ctx, parentptr)) == NULL) goto done; if(setPrefix(r, es_getBufAddr(str) + offs + 1, es_strlen(str) - offs - 1, 0) != 0) { free(r); r = NULL; goto done; } *parentptr = r; done: return r; }
static rsRetVal createListener(struct cnfparamvals* pvals) { instanceConf_t* inst; int i; DEFiRet; CHKiRet(createInstance(&inst)); for(i = 0 ; i < inppblk.nParams ; ++i) { if(!pvals[i].bUsed) { continue; } if(!strcmp(inppblk.descr[i].name, "ruleset")) { inst->pszBindRuleset = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if(!strcmp(inppblk.descr[i].name, "endpoints")) { inst->sockEndpoints = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "beacon")) { inst->beacon = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "beaconport")) { inst->beaconPort = atoi(es_str2cstr(pvals[i].val.d.estr, NULL)); } else if(!strcmp(inppblk.descr[i].name, "socktype")){ char *stringType = es_str2cstr(pvals[i].val.d.estr, NULL); if (!strcmp("SUB", stringType)) { inst->sockType = ZMQ_SUB; } else if (!strcmp("PULL", stringType)) { inst->sockType = ZMQ_PULL; } else if (!strcmp("ROUTER", stringType)) { inst->sockType = ZMQ_ROUTER; } else { errmsg.LogError(0, RS_RET_CONFIG_ERROR, "imczmq: '%s' is invalid sockType", stringType); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } } else if(!strcmp(inppblk.descr[i].name, "topics")) { if (inst->sockType != ZMQ_SUB) { errmsg.LogError(0, RS_RET_CONFIG_ERROR, "topics is invalid unless socktype is SUB"); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } inst->topicList = es_str2cstr(pvals[i].val.d.estr, NULL); } else if(!strcmp(inppblk.descr[i].name, "authtype")) { inst->authType = es_str2cstr(pvals[i].val.d.estr, NULL); /* make sure defined type is supported */ if ((inst->authType != NULL) && strcmp("CURVESERVER", inst->authType) && strcmp("CURVECLIENT", inst->authType)) { errmsg.LogError(0, RS_RET_CONFIG_ERROR, "imczmq: %s is not a valid authType", inst->authType); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } } else if(!strcmp(inppblk.descr[i].name, "clientcertpath")) { inst->clientCertPath = es_str2cstr(pvals[i].val.d.estr, NULL); } else if(!strcmp(inppblk.descr[i].name, "servercertpath")) { inst->serverCertPath = es_str2cstr(pvals[i].val.d.estr, NULL); } else { errmsg.LogError(0, NO_ERRCODE, "imczmq: program error, non-handled " "param '%s'\n", inppblk.descr[i].name); } } finalize_it: RETiRet; }
/** * Recursive step of the normalizer. It walks the parse tree and calls itself * recursively when this is appropriate. It also implements backtracking in * those (hopefully rare) cases where it is required. * * @param[in] tree current tree to process * @param[in] string string to be matched against (the to-be-normalized data) * @param[in] offs start position in input data * @param[in/out] event handle to event that is being created during normalization * @param[out] endNode if a match was found, this is the matching node (undefined otherwise) * * @return number of characters left unparsed by following the subtree, negative if * the to-be-parsed message is shorter than the rule sample by this number of * characters. */ static int ln_normalizeRec(struct ln_ptree *tree, const char *str, size_t strLen, size_t offs, struct json_object *json, struct ln_ptree **endNode) { int r; int localR; size_t i; int left; ln_fieldList_t *node; char *cstr; const char *c; unsigned char *cpfix; unsigned ipfix; size_t parsed; char *namestr; struct json_object *value; if(offs >= strLen) { *endNode = tree; r = -tree->lenPrefix; goto done; } c = str; cpfix = prefixBase(tree); node = tree->froot; r = strLen - offs; /* first we need to check if the common prefix matches (and consume input data while we do) */ ipfix = 0; while(offs < strLen && ipfix < tree->lenPrefix) { ln_dbgprintf(tree->ctx, "%zu: prefix compare '%c', '%c'", offs, c[offs], cpfix[ipfix]); if(c[offs] != cpfix[ipfix]) { r -= ipfix; goto done; } ++offs, ++ipfix; } if(ipfix != tree->lenPrefix) { /* incomplete prefix match --> to-be-normalized string too short */ r = ipfix - tree->lenPrefix; goto done; } r -= ipfix; ln_dbgprintf(tree->ctx, "%zu: prefix compare succeeded, still valid", offs); /* now try the parsers */ while(node != NULL) { if(tree->ctx->debug) { cstr = es_str2cstr(node->name, NULL); ln_dbgprintf(tree->ctx, "%zu:trying parser for field '%s': %p", offs, cstr, node->parser); free(cstr); } i = offs; if(node->isIPTables) { localR = ln_iptablesParser(tree, str, strLen, &i, json); ln_dbgprintf(tree->ctx, "%zu iptables parser return, i=%zu", offs, i); if(localR == 0) { /* potential hit, need to verify */ ln_dbgprintf(tree->ctx, "potential hit, trying subtree"); left = ln_normalizeRec(node->subtree, str, strLen, i, json, endNode); if(left == 0 && (*endNode)->flags.isTerminal) { ln_dbgprintf(tree->ctx, "%zu: parser matches at %zu", offs, i); r = 0; goto done; } ln_dbgprintf(tree->ctx, "%zu nonmatch, backtracking required, left=%d", offs, left); if(left < r) r = left; } } else { value = NULL; localR = node->parser(str, strLen, &i, node, &parsed, &value); ln_dbgprintf(tree->ctx, "parser returns %d, parsed %zu", localR, parsed); if(localR == 0) { /* potential hit, need to verify */ ln_dbgprintf(tree->ctx, "potential hit, trying subtree"); left = ln_normalizeRec(node->subtree, str, strLen, i + parsed, json, endNode); if(left == 0 && (*endNode)->flags.isTerminal) { ln_dbgprintf(tree->ctx, "%zu: parser matches at %zu", offs, i); if(es_strbufcmp(node->name, (unsigned char*)"-", 1)) { /* Store the value here; create json if not already created */ if (value == NULL) { CHKN(cstr = strndup(str + i, parsed)); value = json_object_new_string(cstr); free(cstr); } if (value == NULL) { ln_dbgprintf(tree->ctx, "unable to create json"); goto done; } namestr = ln_es_str2cstr(&node->name); json_object_object_add(json, namestr, value); } else { if (value != NULL) { /* Free the unneeded value */ json_object_put(value); } } r = 0; goto done; } ln_dbgprintf(tree->ctx, "%zu nonmatch, backtracking required, left=%d", offs, left); if (value != NULL) { /* Free the value if it was created */ json_object_put(value); } if(left < r) r = left; } } node = node->next; } if(offs == strLen) { *endNode = tree; r = 0; goto done; } if(offs < strLen) { unsigned char cc = str[offs]; ln_dbgprintf(tree->ctx, "%zu no field, trying subtree char '%c': %p", offs, cc, tree->subtree[cc]); } else { ln_dbgprintf(tree->ctx, "%zu no field, offset already beyond end", offs); } /* now let's see if we have a literal */ if(tree->subtree[(int)str[offs]] != NULL) { left = ln_normalizeRec(tree->subtree[(int)str[offs]], str, strLen, offs + 1, json, endNode); if(left < r) r = left; } done: ln_dbgprintf(tree->ctx, "%zu returns %d", offs, r); return r; }