diff --git a/src/detect-engine-iponly.c b/src/detect-engine-iponly.c index 542d6706fa..acd4a8c8ec 100644 --- a/src/detect-engine-iponly.c +++ b/src/detect-engine-iponly.c @@ -75,6 +75,18 @@ IPOnlyCIDRItem *IPOnlyCIDRItemNew() { SCReturnPtr(item, "IPOnlyCIDRItem"); } +uint8_t IPOnlyCIDRItemCompare(IPOnlyCIDRItem *head, + IPOnlyCIDRItem *item) { + uint8_t i = 0; + for (; i < head->netmask / 32 || i < 1; i++) { + if (item->ip[i] < head->ip[i]) + //if (*(uint8_t *)(item->ip + i) < *(uint8_t *)(head->ip + i)) + return 1; + } + return 0; +} + + /** * \brief This function insert a IPOnlyCIDRItem * to a list of IPOnlyCIDRItems sorted by netmask @@ -93,11 +105,17 @@ IPOnlyCIDRItem *IPOnlyCIDRItemInsertReal(IPOnlyCIDRItem *head, return head; /* Compare with the head */ - if (item->netmask <= head->netmask) { + if (item->netmask < head->netmask || (item->netmask == head->netmask && IPOnlyCIDRItemCompare(head, item))) { item->next = head; return item; } + if (item->netmask == head->netmask && !IPOnlyCIDRItemCompare(head, item)) { + item->next = head->next; + head->next = item; + return head; + } + for (prev = it = head; it != NULL && it->netmask < item->netmask; it = it->next) @@ -105,6 +123,7 @@ IPOnlyCIDRItem *IPOnlyCIDRItemInsertReal(IPOnlyCIDRItem *head, if (it == NULL) { prev->next = item; + item->next = NULL; } else { item->next = it; prev->next = item; @@ -138,7 +157,7 @@ IPOnlyCIDRItem *IPOnlyCIDRItemInsert(IPOnlyCIDRItem *head, return head; } - SCLogDebug("Inserting item(%p)->netmast %u head %p", item, item->netmask, head); + SCLogDebug("Inserting item(%p)->netmask %u head %p", item, item->netmask, head); prev = item; while (prev != NULL) { @@ -147,7 +166,11 @@ IPOnlyCIDRItem *IPOnlyCIDRItemInsert(IPOnlyCIDRItem *head, /* Separate from the item list */ prev->next = NULL; + //SCLogDebug("Before:"); + //IPOnlyCIDRListPrint(head); head = IPOnlyCIDRItemInsertReal(head, prev); + //SCLogDebug("After:"); + //IPOnlyCIDRListPrint(head); prev = it; } @@ -1013,14 +1036,14 @@ void IPOnlyPrepare(DetectEngineCtx *de_ctx) { /* Prepare Src radix trees */ for (src = (de_ctx->io_ctx).ip_src; src != NULL; ) { if (src->family == AF_INET) { - /* + /* SCLogDebug("To IPv4"); SCLogDebug("Item has netmask %"PRIu16" negated: %s; IP: %s; " "signum: %"PRIu16, src->netmask, (src->negated) ? "yes":"no", inet_ntoa( *(struct in_addr*)&src->ip[0]), src->signum); - */ + */ if (src->netmask == 32) node = SCRadixFindKeyIPV4ExactMatch((uint8_t *)&src->ip[0], @@ -1090,9 +1113,14 @@ void IPOnlyPrepare(DetectEngineCtx *de_ctx) { (de_ctx->io_ctx).tree_ipv4src, sna, src->netmask); - if (node == NULL) + if (node == NULL) { + char tmpstr[64]; + inet_ntop(src->family, &src->ip[0], tmpstr, sizeof(tmpstr)); SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the" - " src ipv4 radix tree"); + " src ipv4 radix tree ip %s netmask %"PRIu8, tmpstr, src->netmask); + //SCRadixPrintTree((de_ctx->io_ctx).tree_ipv4src); + exit(-1); + } } } else { SCLogDebug("Exact match found"); diff --git a/src/util-radix-tree.c b/src/util-radix-tree.c index 91bc8130d0..c43f15e485 100644 --- a/src/util-radix-tree.c +++ b/src/util-radix-tree.c @@ -754,6 +754,8 @@ static SCRadixNode *SCRadixAddKey(uint8_t *key_stream, uint16_t key_bitlen, } node->netmask_cnt++; + new_node = node; + if ( (node->netmasks = SCRealloc(node->netmasks, (node->netmask_cnt * sizeof(uint8_t)))) == NULL) { SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCRadixAddKey. Mem not allocated..."); @@ -1652,8 +1654,8 @@ void SCRadixPrintNodeInfo(SCRadixNode *node, int level, void (*PrintData)(void* printf("%s%d", (0 == i ? "" : "."), node->prefix->stream[i]); printf(")\n"); + SCRadixUserData *ud = NULL; if (PrintData != NULL) { - SCRadixUserData *ud = NULL; do { ud = node->prefix->user_data; printf(" [%d], ", ud->netmask); @@ -1661,6 +1663,11 @@ void SCRadixPrintNodeInfo(SCRadixNode *node, int level, void (*PrintData)(void* ud = ud->next; } while (ud != NULL); } else { + //ud = node->prefix->user_data; + //while (ud != NULL) { + // printf(" [nm %d with data], ", ud->netmask); + // ud = ud->next; + //} printf("No print function provided"); } printf("\n"); @@ -4149,6 +4156,63 @@ int SCRadixTestIPV4NetblockInsertion25(void) return result; } +/** + * \test SCRadixTestIPV4NetblockInsertion26 insert a node searching on it. + * Should always return true but the purposse of the test is to monitor + * the memory usage to detect memleaks (there was one on searching) + */ +int SCRadixTestIPV4NetblockInsertion26(void) +{ + SCRadixNode *tmp = NULL; + SCRadixTree *tree = NULL; + struct sockaddr_in servaddr; + int result = 1; + char *str = SCStrdup("Hello1"); + + tree = SCRadixCreateRadixTree(free, NULL); + + bzero(&servaddr, sizeof(servaddr)); + if (inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0) + return 0; + tmp = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, str, 0); + if (!tmp) { + printf("Not inserted correctly 1 :"); + result = 0; + goto this_end; + } + str = SCStrdup("Hello1"); + + bzero(&servaddr, sizeof(servaddr)); + if (inet_pton(AF_INET, "176.0.0.1", &servaddr.sin_addr) <= 0) + return 0; + tmp = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, str, 5); + if (!tmp) { + printf("Not inserted correctly 2 :"); + result = 0; + goto this_end; + } + + str = SCStrdup("Hello1"); + bzero(&servaddr, sizeof(servaddr)); + if (inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0) + return 0; + tmp = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, str, 7); + if (!tmp) { + printf("Not inserted correctly 3 :"); + result = 0; + goto this_end; + } + + /* test for the existance of a key */ + //result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree) != NULL); + +this_end: + SCRadixReleaseRadixTree(tree); + + //SCFree(str); + return result; +} + /** * \test SC_RADIX_NODE_USERDATA macro */ @@ -4269,6 +4333,8 @@ void SCRadixRegisterTests(void) SCRadixTestIPV6NetBlocksAndBestSearch24, 1); UtRegisterTest("SCRadixTestIPV4NetblockInsertion25", SCRadixTestIPV4NetblockInsertion25, 1); + UtRegisterTest("SCRadixTestIPV4NetblockInsertion26", + SCRadixTestIPV4NetblockInsertion26, 1); UtRegisterTest("SCRadixTestUserdataMacro01", SCRadixTestUserdataMacro01, 1); UtRegisterTest("SCRadixTestUserdataMacro02",