summaryrefslogtreecommitdiffstats
path: root/src/detect-engine-address.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/detect-engine-address.c')
-rw-r--r--src/detect-engine-address.c5212
1 files changed, 5212 insertions, 0 deletions
diff --git a/src/detect-engine-address.c b/src/detect-engine-address.c
new file mode 100644
index 0000000..ac10e14
--- /dev/null
+++ b/src/detect-engine-address.c
@@ -0,0 +1,5212 @@
+/* Copyright (C) 2007-2022 Open Information Security Foundation
+ *
+ * You can copy, redistribute or modify this Program under the terms of
+ * the GNU General Public License version 2 as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * \file
+ *
+ * \author Victor Julien <victor@inliniac.net>
+ *
+ * Address part of the detection engine.
+ */
+
+#include "suricata-common.h"
+#include "decode.h"
+#include "detect.h"
+#include "flow-var.h"
+
+#include "util-cidr.h"
+#include "util-unittest.h"
+#include "util-rule-vars.h"
+#include "conf.h"
+#include "conf-yaml-loader.h"
+
+#include "detect-engine-siggroup.h"
+#include "detect-engine-address.h"
+#include "detect-engine-address-ipv4.h"
+#include "detect-engine-address-ipv6.h"
+#include "detect-engine-port.h"
+
+#include "util-debug.h"
+#include "util-byte.h"
+#include "util-print.h"
+#include "util-var.h"
+
+/* prototypes */
+#ifdef DEBUG
+static void DetectAddressPrint(DetectAddress *);
+#else
+#define DetectAddressPrint(...)
+#endif
+static int DetectAddressCutNot(DetectAddress *, DetectAddress **);
+static int DetectAddressCut(DetectEngineCtx *, DetectAddress *, DetectAddress *,
+ DetectAddress **);
+static int DetectAddressParse2(const DetectEngineCtx *de_ctx, DetectAddressHead *gh,
+ DetectAddressHead *ghn, const char *s, int negate, ResolvedVariablesList *var_list,
+ int recur);
+
+int DetectAddressMergeNot(DetectAddressHead *gh, DetectAddressHead *ghn);
+
+/**
+ * \brief Creates and returns a new instance of a DetectAddress.
+ *
+ * \retval ag Pointer to the newly created DetectAddress on success;
+ * NULL on failure.
+ */
+DetectAddress *DetectAddressInit(void)
+{
+ DetectAddress *ag = SCCalloc(1, sizeof(DetectAddress));
+ if (unlikely(ag == NULL))
+ return NULL;
+ return ag;
+}
+
+/**
+ * \brief Frees a DetectAddress instance.
+ *
+ * \param ag Pointer to the DetectAddress instance to be freed.
+ */
+void DetectAddressFree(DetectAddress *ag)
+{
+ if (ag == NULL)
+ return;
+
+ SCFree(ag);
+ return;
+}
+
+/**
+ * \internal
+ * \brief Returns a new instance of DetectAddressHead.
+ *
+ * \retval gh Pointer to the new instance of DetectAddressHead.
+ */
+static DetectAddressHead *DetectAddressHeadInit(void)
+{
+ DetectAddressHead *gh = SCCalloc(1, sizeof(DetectAddressHead));
+ if (unlikely(gh == NULL))
+ return NULL;
+ return gh;
+}
+
+/**
+ * \internal
+ * \brief Frees a DetectAddressHead instance.
+ *
+ * \param gh Pointer to the DetectAddressHead instance to be freed.
+ */
+static void DetectAddressHeadFree(DetectAddressHead *gh)
+{
+ if (gh != NULL) {
+ DetectAddressHeadCleanup(gh);
+ SCFree(gh);
+ }
+}
+
+/**
+ * \brief copy a DetectAddress
+ *
+ * \param orig Pointer to the instance of DetectAddress that contains the
+ * address data to be copied to the new instance.
+ *
+ * \retval ag Pointer to the new instance of DetectAddress that contains the
+ * copied address.
+ */
+DetectAddress *DetectAddressCopy(DetectAddress *orig)
+{
+ DetectAddress *ag = DetectAddressInit();
+ if (ag == NULL)
+ return NULL;
+
+ ag->flags = orig->flags;
+ COPY_ADDRESS(&orig->ip, &ag->ip);
+ COPY_ADDRESS(&orig->ip2, &ag->ip2);
+ return ag;
+}
+
+#ifdef DEBUG
+/**
+ * \brief Prints the address data information for all the DetectAddress
+ * instances in the DetectAddress list sent as the argument.
+ *
+ * \param head Pointer to a list of DetectAddress instances.
+ */
+void DetectAddressPrintList(DetectAddress *head)
+{
+ SCLogInfo("list:");
+ for (DetectAddress *cur = head; cur != NULL; cur = cur->next) {
+ DetectAddressPrint(cur);
+ }
+ SCLogInfo("endlist");
+}
+#endif
+
+/**
+ * \internal
+ * \brief Frees a list of DetectAddress instances.
+ *
+ * \param head Pointer to a list of DetectAddress instances to be freed.
+ */
+static void DetectAddressCleanupList(DetectAddress *head)
+{
+ for (DetectAddress *cur = head; cur != NULL; ) {
+ DetectAddress *next = cur->next;
+ cur->next = NULL;
+ DetectAddressFree(cur);
+ cur = next;
+ }
+}
+
+/**
+ * \internal
+ * \brief Helper function for DetectAddressInsert. Sets one of the
+ * DetectAddressHead head pointers, to the DetectAddress argument
+ * based on its address family.
+ *
+ * \param gh Pointer to the DetectAddressHead.
+ * \param newhead Pointer to the DetectAddress.
+ *
+ * \retval 0 On success.
+ * \retval -1 On failure.
+ */
+static int SetHeadPtr(DetectAddressHead *gh, DetectAddress *newhead)
+{
+ if (newhead->ip.family == AF_INET) {
+ gh->ipv4_head = newhead;
+ } else if (newhead->ip.family == AF_INET6) {
+ gh->ipv6_head = newhead;
+ } else {
+ SCLogDebug("newhead->family %u not supported", newhead->ip.family);
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * \internal
+ * \brief Returns the DetectAddress head from the DetectAddressHeads,
+ * based on the address family of the incoming DetectAddress arg.
+ *
+ * \param gh Pointer to the DetectAddressHead.
+ * \param new Pointer to the DetectAddress.
+ *
+ * \retval head Pointer to the DetectAddress(the head from
+ * DetectAddressHead).
+ */
+static DetectAddress *GetHeadPtr(DetectAddressHead *gh, DetectAddress *new)
+{
+ DetectAddress *head = NULL;
+
+ if (new->ip.family == AF_INET)
+ head = gh->ipv4_head;
+ else if (new->ip.family == AF_INET6)
+ head = gh->ipv6_head;
+
+ return head;
+}
+
+/**
+ * \internal
+ * \brief insert DetectAddress into a DetectAddressHead
+ *
+ * \param de_ctx Pointer to the detection engine context.
+ * \param gh Pointer to the DetectAddressHead list to which it has to
+ * be inserted.
+ * \param new Pointer to the DetectAddress, that has to be inserted.
+ *
+ * \retval 1 On successfully inserting it.
+ * \retval -1 On error.
+ * \retval 0 Not inserted, memory of new is freed.
+ */
+static int DetectAddressInsert(DetectEngineCtx *de_ctx, DetectAddressHead *gh,
+ DetectAddress *new)
+{
+ DetectAddress *head = NULL;
+ DetectAddress *cur = NULL;
+ DetectAddress *c = NULL;
+ int r = 0;
+
+ if (new == NULL)
+ return 0;
+
+ /* get our head ptr based on the address we want to insert */
+ head = GetHeadPtr(gh, new);
+
+ /* see if it already exists or overlaps with existing ag's */
+ if (head != NULL) {
+ cur = NULL;
+
+ for (cur = head; cur != NULL; cur = cur->next) {
+ r = DetectAddressCmp(new, cur);
+ BUG_ON(r == ADDRESS_ER);
+
+ /* if so, handle that */
+ if (r == ADDRESS_EQ) {
+ /* exact overlap/match */
+ if (cur != new) {
+ DetectAddressFree(new);
+ return 0;
+ }
+
+ return 1;
+ } else if (r == ADDRESS_GT) {
+ /* only add it now if we are bigger than the last group.
+ * Otherwise we'll handle it later. */
+ if (cur->next == NULL) {
+ /* put in the list */
+ new->prev = cur;
+ cur->next = new;
+
+ return 1;
+ }
+ } else if (r == ADDRESS_LT) {
+ /* see if we need to insert the ag anywhere put in the list */
+ if (cur->prev != NULL)
+ cur->prev->next = new;
+ new->prev = cur->prev;
+ new->next = cur;
+ cur->prev = new;
+
+ /* update head if required */
+ if (head == cur) {
+ head = new;
+
+ if (SetHeadPtr(gh, head) < 0)
+ goto error;
+ }
+
+ return 1;
+ /* alright, those were the simple cases, lets handle the more
+ * complex ones now */
+ } else if (r == ADDRESS_ES) {
+ c = NULL;
+ r = DetectAddressCut(de_ctx, cur, new, &c);
+ if (r == -1)
+ goto error;
+
+ DetectAddressInsert(de_ctx, gh, new);
+ if (c != NULL)
+ DetectAddressInsert(de_ctx, gh, c);
+
+ return 1;
+ } else if (r == ADDRESS_EB) {
+ c = NULL;
+ r = DetectAddressCut(de_ctx, cur, new, &c);
+ if (r == -1)
+ goto error;
+
+ DetectAddressInsert(de_ctx, gh, new);
+ if (c != NULL)
+ DetectAddressInsert(de_ctx, gh, c);
+
+ return 1;
+ } else if (r == ADDRESS_LE) {
+ c = NULL;
+ r = DetectAddressCut(de_ctx, cur, new, &c);
+ if (r == -1)
+ goto error;
+
+ DetectAddressInsert(de_ctx, gh, new);
+ if (c != NULL)
+ DetectAddressInsert(de_ctx, gh, c);
+
+ return 1;
+ } else if (r == ADDRESS_GE) {
+ c = NULL;
+ r = DetectAddressCut(de_ctx, cur,new,&c);
+ if (r == -1)
+ goto error;
+
+ DetectAddressInsert(de_ctx, gh, new);
+ if (c != NULL)
+ DetectAddressInsert(de_ctx, gh, c);
+
+ return 1;
+ }
+ }
+
+ /* head is NULL, so get a group and set head to it */
+ } else {
+ head = new;
+ if (SetHeadPtr(gh, head) < 0) {
+ SCLogDebug("SetHeadPtr failed");
+ goto error;
+ }
+ }
+
+ return 1;
+
+error:
+ /* XXX */
+ return -1;
+}
+
+/**
+ * \brief Checks if two address group lists are equal.
+ *
+ * \param list1 Pointer to the first address group list.
+ * \param list2 Pointer to the second address group list.
+ *
+ * \retval true On success.
+ * \retval false On failure.
+ */
+bool DetectAddressListsAreEqual(DetectAddress *list1, DetectAddress *list2)
+{
+ DetectAddress *item = list1;
+ DetectAddress *it = list2;
+
+ // First, compare items one by one.
+ while (item != NULL && it != NULL) {
+ if (DetectAddressCmp(item, it) != ADDRESS_EQ) {
+ return false;
+ }
+
+ item = item->next;
+ it = it->next;
+ }
+
+ // Are the lists of the same size?
+ if (!(item == NULL && it == NULL)) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * \internal
+ * \brief Parses an ipv4/ipv6 address string and updates the result into the
+ * DetectAddress instance sent as the argument.
+ *
+ * \param dd Pointer to the DetectAddress instance which should be updated with
+ * the address range details from the parsed ip string.
+ * \param str Pointer to address string that has to be parsed.
+ *
+ * \retval 0 On successfully parsing the address string.
+ * \retval -1 On failure.
+ */
+static int DetectAddressParseString(DetectAddress *dd, const char *str)
+{
+ char *ip = NULL;
+ char *ip2 = NULL;
+ char *mask = NULL;
+ int r = 0;
+ char ipstr[256];
+
+ /* shouldn't see 'any' here */
+ BUG_ON(strcasecmp(str, "any") == 0);
+
+ strlcpy(ipstr, str, sizeof(ipstr));
+ SCLogDebug("str %s", str);
+
+ /* we work with a copy so that we can put a
+ * nul-termination in it later */
+ ip = ipstr;
+
+ /* handle the negation case */
+ if (ip[0] == '!') {
+ dd->flags |= ADDRESS_FLAG_NOT;
+ ip++;
+ }
+
+ /* see if the address is an ipv4 or ipv6 address */
+ if ((strchr(str, ':')) == NULL) {
+ /* IPv4 Address */
+ struct in_addr in;
+
+ dd->ip.family = AF_INET;
+
+ if ((mask = strchr(ip, '/')) != NULL) {
+ /* 1.2.3.4/xxx format (either dotted or cidr notation */
+ ip[mask - ip] = '\0';
+ mask++;
+ uint32_t ip4addr = 0;
+ uint32_t netmask = 0;
+
+ if ((strchr (mask, '.')) == NULL) {
+ /* 1.2.3.4/24 format */
+
+ for (size_t u = 0; u < strlen(mask); u++) {
+ if(!isdigit((unsigned char)mask[u]))
+ goto error;
+ }
+
+ int cidr;
+ if (StringParseI32RangeCheck(&cidr, 10, 0, (const char *)mask, 0, 32) < 0)
+ goto error;
+ netmask = CIDRGet(cidr);
+ } else {
+ /* 1.2.3.4/255.255.255.0 format */
+ r = inet_pton(AF_INET, mask, &in);
+ if (r <= 0)
+ goto error;
+
+ netmask = in.s_addr;
+
+ /* validate netmask */
+ int cidr = CIDRFromMask(netmask);
+ if (cidr < 0) {
+ SCLogError(
+ "netmask \"%s\" is not usable. Only netmasks that are compatible with "
+ "CIDR notation are supported. See ticket #5168.",
+ mask);
+ goto error;
+ }
+ }
+
+ r = inet_pton(AF_INET, ip, &in);
+ if (r <= 0)
+ goto error;
+
+ ip4addr = in.s_addr;
+
+ dd->ip.addr_data32[0] = dd->ip2.addr_data32[0] = ip4addr & netmask;
+ dd->ip2.addr_data32[0] |=~ netmask;
+ } else if ((ip2 = strchr(ip, '-')) != NULL) {
+ /* 1.2.3.4-1.2.3.6 range format */
+ ip[ip2 - ip] = '\0';
+ ip2++;
+
+ r = inet_pton(AF_INET, ip, &in);
+ if (r <= 0)
+ goto error;
+ dd->ip.addr_data32[0] = in.s_addr;
+
+ r = inet_pton(AF_INET, ip2, &in);
+ if (r <= 0)
+ goto error;
+ dd->ip2.addr_data32[0] = in.s_addr;
+
+ /* a > b is illegal, a = b is ok */
+ if (SCNtohl(dd->ip.addr_data32[0]) > SCNtohl(dd->ip2.addr_data32[0]))
+ goto error;
+ } else {
+ /* 1.2.3.4 format */
+ r = inet_pton(AF_INET, ip, &in);
+ if (r <= 0)
+ goto error;
+ /* single host */
+ dd->ip.addr_data32[0] = in.s_addr;
+ dd->ip2.addr_data32[0] = in.s_addr;
+ }
+ } else {
+ /* IPv6 Address */
+ struct in6_addr in6, mask6;
+ uint32_t ip6addr[4], netmask[4];
+
+ dd->ip.family = AF_INET6;
+
+ if ((mask = strchr(ip, '/')) != NULL) {
+ ip[mask - ip] = '\0';
+ mask++;
+
+ int cidr;
+ if (StringParseI32RangeCheck(&cidr, 10, 0, (const char *)mask, 0, 128) < 0)
+ goto error;
+
+ r = inet_pton(AF_INET6, ip, &in6);
+ if (r <= 0)
+ goto error;
+ memcpy(&ip6addr, &in6.s6_addr, sizeof(ip6addr));
+
+ CIDRGetIPv6(cidr, &mask6);
+ memcpy(&netmask, &mask6.s6_addr, sizeof(netmask));
+
+ dd->ip2.addr_data32[0] = dd->ip.addr_data32[0] = ip6addr[0] & netmask[0];
+ dd->ip2.addr_data32[1] = dd->ip.addr_data32[1] = ip6addr[1] & netmask[1];
+ dd->ip2.addr_data32[2] = dd->ip.addr_data32[2] = ip6addr[2] & netmask[2];
+ dd->ip2.addr_data32[3] = dd->ip.addr_data32[3] = ip6addr[3] & netmask[3];
+
+ dd->ip2.addr_data32[0] |=~ netmask[0];
+ dd->ip2.addr_data32[1] |=~ netmask[1];
+ dd->ip2.addr_data32[2] |=~ netmask[2];
+ dd->ip2.addr_data32[3] |=~ netmask[3];
+ } else if ((ip2 = strchr(ip, '-')) != NULL) {
+ /* 2001::1-2001::4 range format */
+ ip[ip2 - ip] = '\0';
+ ip2++;
+
+ r = inet_pton(AF_INET6, ip, &in6);
+ if (r <= 0)
+ goto error;
+ memcpy(&dd->ip.address, &in6.s6_addr, sizeof(ip6addr));
+
+ r = inet_pton(AF_INET6, ip2, &in6);
+ if (r <= 0)
+ goto error;
+ memcpy(&dd->ip2.address, &in6.s6_addr, sizeof(ip6addr));
+
+ /* a > b is illegal, a=b is ok */
+ if (AddressIPv6Gt(&dd->ip, &dd->ip2))
+ goto error;
+ } else {
+ r = inet_pton(AF_INET6, ip, &in6);
+ if (r <= 0)
+ goto error;
+
+ memcpy(&dd->ip.address, &in6.s6_addr, sizeof(dd->ip.address));
+ memcpy(&dd->ip2.address, &in6.s6_addr, sizeof(dd->ip2.address));
+ }
+
+ }
+
+ BUG_ON(dd->ip.family == 0);
+
+ return 0;
+
+error:
+ return -1;
+}
+
+/**
+ * \internal
+ * \brief Simply parse an address and return a DetectAddress instance containing
+ * the address ranges of the parsed ip addressstring
+ *
+ * \param str Pointer to a character string containing the ip address
+ *
+ * \retval dd Pointer to the DetectAddress instance containing the address
+ * range details from the parsed ip string
+ */
+static DetectAddress *DetectAddressParseSingle(const char *str)
+{
+ SCLogDebug("str %s", str);
+
+ DetectAddress *dd = DetectAddressInit();
+ if (dd == NULL)
+ return NULL;
+
+ if (DetectAddressParseString(dd, str) < 0) {
+ SCLogDebug("AddressParse failed");
+ DetectAddressFree(dd);
+ return NULL;
+ }
+
+ return dd;
+}
+
+/**
+ * \brief Setup a single address string, parse it and add the resulting
+ * Address-Range(s) to the AddressHead(DetectAddressHead instance).
+ *
+ * \param gh Pointer to the Address-Head(DetectAddressHead) to which the
+ * resulting Address-Range(s) from the parsed ip string has to
+ * be added.
+ * \param s Pointer to the ip address string to be parsed.
+ *
+ * \retval 0 On success.
+ * \retval -1 On failure.
+ */
+static int DetectAddressSetup(DetectAddressHead *gh, const char *s)
+{
+ SCLogDebug("gh %p, s %s", gh, s);
+
+ while (*s != '\0' && isspace(*s))
+ s++;
+
+ if (strcasecmp(s, "any") == 0) {
+ SCLogDebug("adding 0.0.0.0/0 and ::/0 as we\'re handling \'any\'");
+
+ DetectAddress *ad = DetectAddressParseSingle("0.0.0.0/0");
+ if (ad == NULL)
+ return -1;
+
+ BUG_ON(ad->ip.family == 0);
+
+ if (DetectAddressInsert(NULL, gh, ad) < 0) {
+ SCLogDebug("DetectAddressInsert failed");
+ DetectAddressFree(ad);
+ return -1;
+ }
+
+ ad = DetectAddressParseSingle("::/0");
+ if (ad == NULL)
+ return -1;
+
+ BUG_ON(ad->ip.family == 0);
+
+ if (DetectAddressInsert(NULL, gh, ad) < 0) {
+ SCLogDebug("DetectAddressInsert failed");
+ DetectAddressFree(ad);
+ return -1;
+ }
+ return 0;
+ }
+
+ /* parse the address */
+ DetectAddress *ad = DetectAddressParseSingle(s);
+ if (ad == NULL) {
+ SCLogError("failed to parse address \"%s\"", s);
+ return -1;
+ }
+
+ /* handle the not case, we apply the negation then insert the part(s) */
+ if (ad->flags & ADDRESS_FLAG_NOT) {
+ DetectAddress *ad2 = NULL;
+
+ if (DetectAddressCutNot(ad, &ad2) < 0) {
+ SCLogDebug("DetectAddressCutNot failed");
+ DetectAddressFree(ad);
+ return -1;
+ }
+
+ /* normally a 'not' will result in two ad's unless the 'not' is on the start or end
+ * of the address space (e.g. 0.0.0.0 or 255.255.255.255). */
+ if (ad2 != NULL) {
+ if (DetectAddressInsert(NULL, gh, ad2) < 0) {
+ SCLogDebug("DetectAddressInsert failed");
+ DetectAddressFree(ad);
+ DetectAddressFree(ad2);
+ return -1;
+ }
+ }
+ }
+
+ int r = DetectAddressInsert(NULL, gh, ad);
+ if (r < 0) {
+ SCLogDebug("DetectAddressInsert failed");
+ DetectAddressFree(ad);
+ return -1;
+ }
+ SCLogDebug("r %d",r);
+ return 0;
+}
+
+/**
+ * \brief Parses an address string and updates the 2 address heads with the
+ * address data.
+ *
+ * Note that this function should only be called by the wrapping function
+ * DetectAddressParse2. The wrapping function provides long address handling
+ * when the address size exceeds a threshold value.
+ *
+ * \todo We don't seem to be handling negated cases, like [addr,![!addr,addr]],
+ * since we pass around negate without keeping a count of ! with depth.
+ * Can solve this by keeping a count of the negations with depth, so that
+ * an even no of negations would count as no negation and an odd no of
+ * negations would count as a negation.
+ *
+ * \param gh Pointer to the address head that should hold address ranges
+ * that are not negated.
+ * \param ghn Pointer to the address head that should hold address ranges
+ * that are negated.
+ * \param s Pointer to the character string holding the address to be
+ * parsed.
+ * \param negate Flag that indicates if the received address string is negated
+ * or not. 0 if it is not, 1 it it is.
+ *
+ * \retval 0 On successfully parsing.
+ * \retval -1 On failure.
+ */
+static int DetectAddressParseInternal(const DetectEngineCtx *de_ctx, DetectAddressHead *gh,
+ DetectAddressHead *ghn, const char *s, int negate, ResolvedVariablesList *var_list,
+ int recur, char *address, size_t address_length)
+{
+ size_t x = 0;
+ size_t u = 0;
+ int o_set = 0, n_set = 0, d_set = 0;
+ int depth = 0;
+ const char *rule_var_address = NULL;
+ char *temp_rule_var_address = NULL;
+
+ if (++recur > 64) {
+ SCLogError("address block recursion "
+ "limit reached (max 64)");
+ goto error;
+ }
+
+ SCLogDebug("s %s negate %s", s, negate ? "true" : "false");
+
+ size_t size = strlen(s);
+ for (u = 0, x = 0; u < size && x < address_length; u++) {
+ if (x == (address_length - 1)) {
+ SCLogError("Hit the address buffer"
+ " limit for the supplied address. Invalidating sig. "
+ "Please file a bug report on this.");
+ goto error;
+ }
+ address[x] = s[u];
+ x++;
+
+ if (!o_set && s[u] == '!') {
+ n_set = 1;
+ x--;
+ } else if (s[u] == '[') {
+ if (!o_set) {
+ o_set = 1;
+ x = 0;
+ }
+ depth++;
+ } else if (s[u] == ']') {
+ if (depth == 1) {
+ address[x - 1] = '\0';
+ x = 0;
+ SCLogDebug("address %s negate %d, n_set %d", address, negate, n_set);
+ if (((negate + n_set) % 2) == 0) {
+ /* normal block */
+ SCLogDebug("normal block");
+
+ if (DetectAddressParse2(de_ctx, gh, ghn, address, (negate + n_set) % 2, var_list, recur) < 0)
+ goto error;
+ } else {
+ /* negated block
+ *
+ * Extra steps are necessary. First consider it as a normal
+ * (non-negated) range. Merge the + and - ranges if
+ * applicable. Then insert the result into the ghn list. */
+ SCLogDebug("negated block");
+
+ DetectAddressHead tmp_gh = { NULL, NULL };
+ DetectAddressHead tmp_ghn = { NULL, NULL };
+
+ if (DetectAddressParse2(de_ctx, &tmp_gh, &tmp_ghn, address, 0, var_list, recur) < 0) {
+ DetectAddressHeadCleanup(&tmp_gh);
+ DetectAddressHeadCleanup(&tmp_ghn);
+ goto error;
+ }
+
+ DetectAddress *tmp_ad;
+ DetectAddress *tmp_ad2;
+#ifdef DEBUG
+ SCLogDebug("tmp_gh: IPv4");
+ for (tmp_ad = tmp_gh.ipv4_head; tmp_ad; tmp_ad = tmp_ad->next) {
+ DetectAddressPrint(tmp_ad);
+ }
+ SCLogDebug("tmp_ghn: IPv4");
+ for (tmp_ad = tmp_ghn.ipv4_head; tmp_ad; tmp_ad = tmp_ad->next) {
+ DetectAddressPrint(tmp_ad);
+ }
+ SCLogDebug("tmp_gh: IPv6");
+ for (tmp_ad = tmp_gh.ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) {
+ DetectAddressPrint(tmp_ad);
+ }
+ SCLogDebug("tmp_ghn: IPv6");
+ for (tmp_ad = tmp_ghn.ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) {
+ DetectAddressPrint(tmp_ad);
+ }
+#endif
+ if (DetectAddressMergeNot(&tmp_gh, &tmp_ghn) < 0) {
+ DetectAddressHeadCleanup(&tmp_ghn);
+ DetectAddressHeadCleanup(&tmp_gh);
+ goto error;
+ }
+ DetectAddressHeadCleanup(&tmp_ghn);
+
+ SCLogDebug("merged successfully");
+
+ /* insert the IPv4 addresses into the negated list */
+ for (tmp_ad = tmp_gh.ipv4_head; tmp_ad; tmp_ad = tmp_ad->next) {
+ /* work with a copy of the address group */
+ tmp_ad2 = DetectAddressCopy(tmp_ad);
+ if (tmp_ad2 == NULL) {
+ SCLogDebug("DetectAddressCopy failed");
+ DetectAddressHeadCleanup(&tmp_gh);
+ goto error;
+ }
+ DetectAddressPrint(tmp_ad2);
+ DetectAddressInsert(NULL, ghn, tmp_ad2);
+ }
+
+ /* insert the IPv6 addresses into the negated list */
+ for (tmp_ad = tmp_gh.ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) {
+ /* work with a copy of the address group */
+ tmp_ad2 = DetectAddressCopy(tmp_ad);
+ if (tmp_ad2 == NULL) {
+ SCLogDebug("DetectAddressCopy failed");
+ DetectAddressHeadCleanup(&tmp_gh);
+ goto error;
+ }
+ DetectAddressPrint(tmp_ad2);
+ DetectAddressInsert(NULL, ghn, tmp_ad2);
+ }
+
+ DetectAddressHeadCleanup(&tmp_gh);
+ }
+ n_set = 0;
+ }
+ depth--;
+ } else if (depth == 0 && s[u] == ',') {
+ if (o_set == 1) {
+ o_set = 0;
+ } else if (d_set == 1) {
+ address[x - 1] = '\0';
+
+ rule_var_address = SCRuleVarsGetConfVar(de_ctx, address,
+ SC_RULE_VARS_ADDRESS_GROUPS);
+ if (rule_var_address == NULL)
+ goto error;
+
+ if (strlen(rule_var_address) == 0) {
+ SCLogError("variable %s resolved "
+ "to nothing. This is likely a misconfiguration. "
+ "Note that a negated address needs to be quoted, "
+ "\"!$HOME_NET\" instead of !$HOME_NET. See issue #295.",
+ s);
+ goto error;
+ }
+
+ SCLogDebug("rule_var_address %s", rule_var_address);
+ if ((negate + n_set) % 2) {
+ temp_rule_var_address = SCMalloc(strlen(rule_var_address) + 3);
+ if (unlikely(temp_rule_var_address == NULL))
+ goto error;
+ snprintf(temp_rule_var_address, strlen(rule_var_address) + 3,
+ "[%s]", rule_var_address);
+ } else {
+ temp_rule_var_address = SCStrdup(rule_var_address);
+ if (unlikely(temp_rule_var_address == NULL))
+ goto error;
+ }
+
+ if (DetectAddressParse2(de_ctx, gh, ghn, temp_rule_var_address,
+ (negate + n_set) % 2, var_list, recur) < 0) {
+ if (temp_rule_var_address != rule_var_address)
+ SCFree(temp_rule_var_address);
+ goto error;
+ }
+ d_set = 0;
+ n_set = 0;
+ SCFree(temp_rule_var_address);
+ } else {
+ address[x - 1] = '\0';
+
+ if (!((negate + n_set) % 2)) {
+ SCLogDebug("DetectAddressSetup into gh, %s", address);
+ if (DetectAddressSetup(gh, address) < 0)
+ goto error;
+ } else {
+ SCLogDebug("DetectAddressSetup into ghn, %s", address);
+ if (DetectAddressSetup(ghn, address) < 0)
+ goto error;
+ }
+ n_set = 0;
+ }
+ x = 0;
+ } else if (depth == 0 && s[u] == '$') {
+ d_set = 1;
+ } else if (depth == 0 && u == size - 1) {
+ if (x == address_length) {
+ address[x - 1] = '\0';
+ } else {
+ address[x] = '\0';
+ }
+ x = 0;
+
+ if (AddVariableToResolveList(var_list, address) == -1) {
+ SCLogError("Found a loop in a address "
+ "groups declaration. This is likely a misconfiguration.");
+ goto error;
+ }
+
+ if (d_set == 1) {
+ rule_var_address = SCRuleVarsGetConfVar(de_ctx, address,
+ SC_RULE_VARS_ADDRESS_GROUPS);
+ if (rule_var_address == NULL)
+ goto error;
+
+ if (strlen(rule_var_address) == 0) {
+ SCLogError("variable %s resolved "
+ "to nothing. This is likely a misconfiguration. "
+ "Note that a negated address needs to be quoted, "
+ "\"!$HOME_NET\" instead of !$HOME_NET. See issue #295.",
+ s);
+ goto error;
+ }
+
+ SCLogDebug("rule_var_address %s", rule_var_address);
+ if ((negate + n_set) % 2) {
+ temp_rule_var_address = SCMalloc(strlen(rule_var_address) + 3);
+ if (unlikely(temp_rule_var_address == NULL))
+ goto error;
+ snprintf(temp_rule_var_address, strlen(rule_var_address) + 3,
+ "[%s]", rule_var_address);
+ } else {
+ temp_rule_var_address = SCStrdup(rule_var_address);
+ if (unlikely(temp_rule_var_address == NULL))
+ goto error;
+ }
+
+ if (DetectAddressParse2(de_ctx, gh, ghn, temp_rule_var_address,
+ (negate + n_set) % 2, var_list, recur) < 0) {
+ SCLogDebug("DetectAddressParse2 hates us");
+ if (temp_rule_var_address != rule_var_address)
+ SCFree(temp_rule_var_address);
+ goto error;
+ }
+ d_set = 0;
+ SCFree(temp_rule_var_address);
+ } else {
+ if (!((negate + n_set) % 2)) {
+ SCLogDebug("DetectAddressSetup into gh, %s", address);
+ if (DetectAddressSetup(gh, address) < 0) {
+ SCLogDebug("DetectAddressSetup gh fail");
+ goto error;
+ }
+ } else {
+ SCLogDebug("DetectAddressSetup into ghn, %s", address);
+ if (DetectAddressSetup(ghn, address) < 0) {
+ SCLogDebug("DetectAddressSetup ghn fail");
+ goto error;
+ }
+ }
+ }
+ n_set = 0;
+ }
+ }
+ if (depth > 0) {
+ SCLogError("not every address block was "
+ "properly closed in \"%s\", %d missing closing brackets (]). "
+ "Note: problem might be in a variable.",
+ s, depth);
+ goto error;
+ } else if (depth < 0) {
+ SCLogError("not every address block was "
+ "properly opened in \"%s\", %d missing opening brackets ([). "
+ "Note: problem might be in a variable.",
+ s, depth * -1);
+ goto error;
+ }
+
+ return 0;
+
+error:
+
+ return -1;
+}
+
+/**
+ * \internal
+ * \brief Wrapper function for address parsing to minimize heap allocs during address parsing.
+ *
+ * \retval Return value from DetectAddressParseInternal
+ */
+static int DetectAddressParse2(const DetectEngineCtx *de_ctx, DetectAddressHead *gh,
+ DetectAddressHead *ghn, const char *s, int negate, ResolvedVariablesList *var_list,
+ int recur)
+{
+ int rc;
+#define MAX_ADDRESS_LENGTH 8192
+
+ size_t address_length = strlen(s);
+ if (address_length > (MAX_ADDRESS_LENGTH - 1)) {
+ char *address = SCCalloc(1, address_length);
+ if (address == NULL) {
+ SCLogError("Unable to allocate"
+ " memory for address parsing.");
+ return -1;
+ }
+ rc = DetectAddressParseInternal(
+ de_ctx, gh, ghn, s, negate, var_list, recur, address, address_length);
+ SCFree(address);
+ } else {
+ char address[MAX_ADDRESS_LENGTH] = "";
+ rc = DetectAddressParseInternal(
+ de_ctx, gh, ghn, s, negate, var_list, recur, address, MAX_ADDRESS_LENGTH);
+ }
+ return rc;
+}
+
+/**
+ * \internal
+ * \brief See if the addresses and ranges in an address head cover the
+ * entire ip space.
+ *
+ * \param gh Pointer to the DetectAddressHead to check.
+ *
+ * \retval 0 No.
+ * \retval 1 Yes.
+ *
+ * \todo do the same for IPv6
+ */
+static int DetectAddressIsCompleteIPSpace(DetectAddressHead *gh)
+{
+ int r = DetectAddressIsCompleteIPSpaceIPv4(gh->ipv4_head);
+ if (r == 1)
+ return 1;
+
+ return 0;
+}
+
+/**
+ * \brief Merge the + and the - list (+ positive match, - 'not' match)
+ *
+ * \param gh Pointer to the address head containing the non-NOT groups.
+ * \param ghn Pointer to the address head containing the NOT groups.
+ *
+ * \retval 0 On success.
+ * \retval -1 On failure.
+ */
+int DetectAddressMergeNot(DetectAddressHead *gh, DetectAddressHead *ghn)
+{
+ DetectAddress *ad;
+ DetectAddress *ag, *ag2;
+ int r = 0;
+
+ SCLogDebug("gh->ipv4_head %p, ghn->ipv4_head %p", gh->ipv4_head,
+ ghn->ipv4_head);
+
+ /* check if the negated list covers the entire ip space. If so
+ * the user screwed up the rules/vars. */
+ if (DetectAddressIsCompleteIPSpace(ghn) == 1) {
+ SCLogError("Complete IP space negated. "
+ "Rule address range is NIL. Probably have a !any or "
+ "an address range that supplies a NULL address range");
+ goto error;
+ }
+
+ /* step 0: if the gh list is empty, but the ghn list isn't we have a pure
+ * not thingy. In that case we add a 0.0.0.0/0 first. */
+ if (gh->ipv4_head == NULL && ghn->ipv4_head != NULL) {
+ r = DetectAddressSetup(gh, "0.0.0.0/0");
+ if (r < 0) {
+ SCLogDebug("DetectAddressSetup for 0.0.0.0/0 failed");
+ goto error;
+ }
+ }
+ /* ... or ::/0 for ipv6 */
+ if (gh->ipv6_head == NULL && ghn->ipv6_head != NULL) {
+ r = DetectAddressSetup(gh, "::/0");
+ if (r < 0) {
+ SCLogDebug("DetectAddressSetup for ::/0 failed");
+ goto error;
+ }
+ }
+
+ /* step 1: insert our ghn members into the gh list */
+ for (ag = ghn->ipv4_head; ag != NULL; ag = ag->next) {
+ /* work with a copy of the ad so we can easily clean up the ghn group
+ * later. */
+ ad = DetectAddressCopy(ag);
+ if (ad == NULL) {
+ SCLogDebug("DetectAddressCopy failed");
+ goto error;
+ }
+
+ r = DetectAddressInsert(NULL, gh, ad);
+ if (r < 0) {
+ SCLogDebug("DetectAddressInsert failed");
+ goto error;
+ }
+ }
+ /* ... and the same for ipv6 */
+ for (ag = ghn->ipv6_head; ag != NULL; ag = ag->next) {
+ /* work with a copy of the ad so we can easily clean up the ghn group
+ * later. */
+ ad = DetectAddressCopy(ag);
+ if (ad == NULL) {
+ SCLogDebug("DetectAddressCopy failed");
+ goto error;
+ }
+
+ r = DetectAddressInsert(NULL, gh, ad);
+ if (r < 0) {
+ SCLogDebug("DetectAddressInsert failed");
+ goto error;
+ }
+ }
+#ifdef DEBUG
+ DetectAddress *tmp_ad;
+ for (tmp_ad = gh->ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) {
+ DetectAddressPrint(tmp_ad);
+ }
+#endif
+ int ipv4_applied = 0;
+ int ipv6_applied = 0;
+
+ /* step 2: pull the address blocks that match our 'not' blocks */
+ for (ag = ghn->ipv4_head; ag != NULL; ag = ag->next) {
+ SCLogDebug("ag %p", ag);
+ DetectAddressPrint(ag);
+
+ int applied = 0;
+ for (ag2 = gh->ipv4_head; ag2 != NULL; ) {
+ SCLogDebug("ag2 %p", ag2);
+ DetectAddressPrint(ag2);
+
+ r = DetectAddressCmp(ag, ag2);
+ /* XXX more ??? */
+ if (r == ADDRESS_EQ || r == ADDRESS_EB) {
+ if (ag2->prev != NULL)
+ ag2->prev->next = ag2->next;
+ if (ag2->next != NULL)
+ ag2->next->prev = ag2->prev;
+ if (gh->ipv4_head == ag2)
+ gh->ipv4_head = ag2->next;
+ /* store the next ptr and remove the group */
+ DetectAddress *next_ag2 = ag2->next;
+ DetectAddressFree(ag2);
+ ag2 = next_ag2;
+ applied = 1;
+ } else {
+ ag2 = ag2->next;
+ }
+ }
+
+ if (applied) {
+ ipv4_applied++;
+ }
+ }
+ /* ... and the same for ipv6 */
+ for (ag = ghn->ipv6_head; ag != NULL; ag = ag->next) {
+ int applied = 0;
+ for (ag2 = gh->ipv6_head; ag2 != NULL; ) {
+ r = DetectAddressCmp(ag, ag2);
+ if (r == ADDRESS_EQ || r == ADDRESS_EB) { /* XXX more ??? */
+ if (ag2->prev != NULL)
+ ag2->prev->next = ag2->next;
+ if (ag2->next != NULL)
+ ag2->next->prev = ag2->prev;
+ if (gh->ipv6_head == ag2)
+ gh->ipv6_head = ag2->next;
+ /* store the next ptr and remove the group */
+ DetectAddress *next_ag2 = ag2->next;
+ DetectAddressFree(ag2);
+ ag2 = next_ag2;
+
+ SCLogDebug("applied");
+ applied = 1;
+ } else {
+ ag2 = ag2->next;
+ }
+ }
+ if (applied) {
+ ipv6_applied++;
+ }
+ }
+#ifdef DEBUG
+ for (tmp_ad = gh->ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) {
+ DetectAddressPrint(tmp_ad);
+ }
+ for (tmp_ad = ghn->ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) {
+ DetectAddressPrint(tmp_ad);
+ }
+#endif
+ if (ghn->ipv4_head != NULL || ghn->ipv6_head != NULL) {
+ int cnt = 0;
+ for (ad = ghn->ipv4_head; ad; ad = ad->next)
+ cnt++;
+
+ if (ipv4_applied != cnt) {
+ SCLogError("not all IPv4 negations "
+ "could be applied: %d != %d",
+ cnt, ipv4_applied);
+ goto error;
+ }
+
+ cnt = 0;
+ for (ad = ghn->ipv6_head; ad; ad = ad->next)
+ cnt++;
+
+ if (ipv6_applied != cnt) {
+ SCLogError("not all IPv6 negations "
+ "could be applied: %d != %d",
+ cnt, ipv6_applied);
+ goto error;
+ }
+ }
+
+ /* if the result is that we have no addresses we return error */
+ if (gh->ipv4_head == NULL && gh->ipv6_head == NULL) {
+ SCLogError("no addresses left after "
+ "merging addresses and negated addresses");
+ goto error;
+ }
+
+ return 0;
+
+error:
+ return -1;
+}
+
+int DetectAddressTestConfVars(void)
+{
+ SCLogDebug("Testing address conf vars for any misconfigured values");
+
+ ResolvedVariablesList var_list = TAILQ_HEAD_INITIALIZER(var_list);
+
+ ConfNode *address_vars_node = ConfGetNode("vars.address-groups");
+ if (address_vars_node == NULL) {
+ return 0;
+ }
+
+ DetectAddressHead *gh = NULL;
+ DetectAddressHead *ghn = NULL;
+
+ ConfNode *seq_node;
+ TAILQ_FOREACH(seq_node, &address_vars_node->head, next) {
+ SCLogDebug("Testing %s - %s", seq_node->name, seq_node->val);
+
+ gh = DetectAddressHeadInit();
+ if (gh == NULL) {
+ goto error;
+ }
+ ghn = DetectAddressHeadInit();
+ if (ghn == NULL) {
+ goto error;
+ }
+
+ if (seq_node->val == NULL) {
+ SCLogError("Address var \"%s\" probably has a sequence(something "
+ "in brackets) value set without any quotes. Please "
+ "quote it using \"..\".",
+ seq_node->name);
+ goto error;
+ }
+
+ int r = DetectAddressParse2(
+ NULL, gh, ghn, seq_node->val, /* start with negate no */ 0, &var_list, 0);
+
+ CleanVariableResolveList(&var_list);
+
+ if (r < 0) {
+ SCLogError("failed to parse address var \"%s\" with value \"%s\". "
+ "Please check its syntax",
+ seq_node->name, seq_node->val);
+ goto error;
+ }
+
+ if (DetectAddressIsCompleteIPSpace(ghn)) {
+ SCLogError("address var - \"%s\" has the complete IP space negated "
+ "with its value \"%s\". Rule address range is NIL. "
+ "Probably have a !any or an address range that supplies "
+ "a NULL address range",
+ seq_node->name, seq_node->val);
+ goto error;
+ }
+
+ DetectAddressHeadFree(gh);
+ DetectAddressHeadFree(ghn);
+ ghn = NULL;
+ }
+
+ return 0;
+ error:
+ if (gh != NULL)
+ DetectAddressHeadFree(gh);
+ if (ghn != NULL)
+ DetectAddressHeadFree(ghn);
+ return -1;
+}
+
+#include "util-hash-lookup3.h"
+
+typedef struct DetectAddressMap_ {
+ char *string;
+ DetectAddressHead *address;
+ bool contains_negation;
+} DetectAddressMap;
+
+static uint32_t DetectAddressMapHashFunc(HashListTable *ht, void *data, uint16_t datalen)
+{
+ const DetectAddressMap *map = (DetectAddressMap *)data;
+ uint32_t hash = 0;
+
+ hash = hashlittle_safe(map->string, strlen(map->string), 0);
+ hash %= ht->array_size;
+
+ return hash;
+}
+
+static char DetectAddressMapCompareFunc(void *data1, uint16_t len1, void *data2,
+ uint16_t len2)
+{
+ DetectAddressMap *map1 = (DetectAddressMap *)data1;
+ DetectAddressMap *map2 = (DetectAddressMap *)data2;
+
+ char r = (strcmp(map1->string, map2->string) == 0);
+ return r;
+}
+
+static void DetectAddressMapFreeFunc(void *data)
+{
+ DetectAddressMap *map = (DetectAddressMap *)data;
+ if (map != NULL) {
+ DetectAddressHeadFree(map->address);
+ SCFree(map->string);
+ }
+ SCFree(map);
+}
+
+int DetectAddressMapInit(DetectEngineCtx *de_ctx)
+{
+ de_ctx->address_table = HashListTableInit(4096, DetectAddressMapHashFunc,
+ DetectAddressMapCompareFunc,
+ DetectAddressMapFreeFunc);
+ if (de_ctx->address_table == NULL)
+ return -1;
+
+ return 0;
+}
+
+void DetectAddressMapFree(DetectEngineCtx *de_ctx)
+{
+ if (de_ctx->address_table == NULL)
+ return;
+
+ HashListTableFree(de_ctx->address_table);
+ de_ctx->address_table = NULL;
+ return;
+}
+
+static int DetectAddressMapAdd(DetectEngineCtx *de_ctx, const char *string,
+ DetectAddressHead *address, bool contains_negation)
+{
+ DetectAddressMap *map = SCCalloc(1, sizeof(*map));
+ if (map == NULL)
+ return -1;
+
+ map->string = SCStrdup(string);
+ if (map->string == NULL) {
+ SCFree(map);
+ return -1;
+ }
+ map->address = address;
+ map->contains_negation = contains_negation;
+
+ BUG_ON(HashListTableAdd(de_ctx->address_table, (void *)map, 0) != 0);
+ return 0;
+}
+
+static const DetectAddressMap *DetectAddressMapLookup(DetectEngineCtx *de_ctx,
+ const char *string)
+{
+ DetectAddressMap map = { (char *)string, NULL, false };
+
+ const DetectAddressMap *res = HashListTableLookup(de_ctx->address_table,
+ &map, 0);
+ return res;
+}
+
+/**
+ * \brief Parses an address group sent as a character string and updates the
+ * DetectAddressHead sent as the argument with the relevant address
+ * ranges from the parsed string.
+ *
+ * \param de_ctx Pointer to the detection engine context
+ * \param gh Pointer to the DetectAddressHead.
+ * \param str Pointer to the character string containing the address group
+ * that has to be parsed.
+ *
+ * \retval 1 On success. Contained negation.
+ * \retval 0 On success. Did not contain negation.
+ * \retval -1 On failure.
+ */
+int DetectAddressParse(const DetectEngineCtx *de_ctx,
+ DetectAddressHead *gh, const char *str)
+{
+ SCLogDebug("gh %p, str %s", gh, str);
+
+ if (str == NULL) {
+ SCLogDebug("DetectAddressParse can not be run with NULL address");
+ return -1;
+ }
+
+ DetectAddressHead *ghn = DetectAddressHeadInit();
+ if (ghn == NULL) {
+ SCLogDebug("DetectAddressHeadInit for ghn failed");
+ return -1;
+ }
+
+ int r = DetectAddressParse2(de_ctx, gh, ghn, str, /* start with negate no */ 0, NULL, 0);
+ if (r < 0) {
+ SCLogDebug("DetectAddressParse2 returned %d", r);
+ DetectAddressHeadFree(ghn);
+ return -1;
+ }
+
+ SCLogDebug("gh->ipv4_head %p, ghn->ipv4_head %p", gh->ipv4_head,
+ ghn->ipv4_head);
+
+ bool contains_negation = (ghn->ipv4_head != NULL || ghn->ipv6_head != NULL);
+
+ /* merge the 'not' address groups */
+ if (DetectAddressMergeNot(gh, ghn) < 0) {
+ SCLogDebug("DetectAddressMergeNot failed");
+ DetectAddressHeadFree(ghn);
+ return -1;
+ }
+
+ /* free the temp negate head */
+ DetectAddressHeadFree(ghn);
+ return contains_negation ? 1 : 0;
+}
+
+const DetectAddressHead *DetectParseAddress(DetectEngineCtx *de_ctx,
+ const char *string, bool *contains_negation)
+{
+ const DetectAddressMap *res = DetectAddressMapLookup(de_ctx, string);
+ if (res != NULL) {
+ SCLogDebug("found: %s :: %p", string, res);
+ *contains_negation = res->contains_negation;
+ return res->address;
+ }
+
+ SCLogDebug("%s not found", string);
+
+ DetectAddressHead *head = DetectAddressHeadInit();
+ if (head == NULL)
+ return NULL;
+
+ const int r = DetectAddressParse(de_ctx, head, string);
+ if (r < 0) {
+ DetectAddressHeadFree(head);
+ return NULL;
+ } else if (r == 1) {
+ *contains_negation = true;
+ } else {
+ *contains_negation = false;
+ }
+
+ DetectAddressMapAdd((DetectEngineCtx *)de_ctx, string, head,
+ *contains_negation);
+ return head;
+}
+
+/**
+ * \brief Cleans a DetectAddressHead. The functions frees the address
+ * group heads(ipv4 and ipv6) inside the DetectAddressHead
+ * instance.
+ *
+ * \param gh Pointer to the DetectAddressHead instance that has to be
+ * cleaned.
+ */
+void DetectAddressHeadCleanup(DetectAddressHead *gh)
+{
+ if (gh != NULL) {
+ if (gh->ipv4_head != NULL) {
+ DetectAddressCleanupList(gh->ipv4_head);
+ gh->ipv4_head = NULL;
+ }
+ if (gh->ipv6_head != NULL) {
+ DetectAddressCleanupList(gh->ipv6_head);
+ gh->ipv6_head = NULL;
+ }
+ }
+
+ return;
+}
+
+/**
+ * \brief Dispatcher function that calls the ipv4 and ipv6 address cut functions.
+ * Have a look at DetectAddressCutIPv4() and DetectAddressCutIPv6() for
+ * explanations on what these functions do.
+ *
+ * \param de_ctx Pointer to the DetectEngineCtx.
+ * \param a Pointer to the first address to be cut.
+ * \param b Pointer to the second address to be cut.
+ * \param c Pointer to a pointer to a third DetectAddressData, in case the
+ * ranges from a and b, demand a third address range.
+ *
+ * \retval 0 On success.
+ * \retval -1 On failure.
+ */
+int DetectAddressCut(DetectEngineCtx *de_ctx, DetectAddress *a,
+ DetectAddress *b, DetectAddress **c)
+{
+ if (a->ip.family == AF_INET)
+ return DetectAddressCutIPv4(de_ctx, a, b, c);
+ else if (a->ip.family == AF_INET6)
+ return DetectAddressCutIPv6(de_ctx, a, b, c);
+
+ return -1;
+}
+
+/**
+ * \brief Cuts a negated address range with respect to the entire ip range, and
+ * supplies with the address range that doesn't belong to the negated
+ * address range.
+ *
+ * There are 2 cases here -
+ *
+ * The first case includes the address being located at the extreme ends
+ * of the ip space, in which we get a single range.
+ * For example: !0.0.0.0, in which case we get 0.0.0.1 to 255.255.255.255.
+ *
+ * The second case includes the address not present at either of the
+ * ip space extremes, in which case we get 2 ranges. The second range
+ * would be supplied back with the argument "b" supplied to this function.
+ * For example: !10.20.30.40, in which case we the 2 ranges, 0.0.0.0 -
+ * 10.20.30.39 and 10.20.30.41 - 255.255.255.255.
+ *
+ * The above negation cases can similarly be extended to ranges, i.e.
+ * ![0.0.0.0 - 10.20.30.40], ![255.255.240.240 - 255.255.255.255] and
+ * ![10.20.30.40 - 10.20.30.50].
+ *
+ *
+ * \param a Pointer to the DetectAddressData instance, that contains the negated
+ * address range that has to be cut.
+ * \param b Pointer to a pointer to a DetectAddressData instance, that should be
+ * filled with the address range, if the argument "a", doesn't fall at
+ * the extreme ends of the ip address space.
+ *
+ * \retval 0 On success.
+ * \retval -1 On failure.
+ */
+int DetectAddressCutNot(DetectAddress *a, DetectAddress **b)
+{
+ if (a->ip.family == AF_INET)
+ return DetectAddressCutNotIPv4(a, b);
+ else if (a->ip.family == AF_INET6)
+ return DetectAddressCutNotIPv6(a, b);
+
+ return -1;
+}
+
+/**
+ * \brief Used to compare 2 address ranges.
+ *
+ * \param a Pointer to the first DetectAddressData to be compared.
+ * \param b Pointer to the second DetectAddressData to be compared.
+ */
+int DetectAddressCmp(DetectAddress *a, DetectAddress *b)
+{
+ if (a->ip.family != b->ip.family)
+ return ADDRESS_ER;
+
+ if (a->ip.family == AF_INET)
+ return DetectAddressCmpIPv4(a, b);
+ else if (a->ip.family == AF_INET6)
+ return DetectAddressCmpIPv6(a, b);
+
+ return ADDRESS_ER;
+}
+
+/**
+ * \brief Match a packets address against a signatures addrs array
+ *
+ * \param addrs array of DetectMatchAddressIPv4's
+ * \param addrs_cnt array size in members
+ * \param a packets address
+ *
+ * \retval 0 no match
+ * \retval 1 match
+ *
+ * \note addresses in addrs are in host order
+ *
+ * \todo array should be ordered, so we can break out of the loop
+ */
+int DetectAddressMatchIPv4(const DetectMatchAddressIPv4 *addrs,
+ uint16_t addrs_cnt, const Address *a)
+{
+ SCEnter();
+
+ if (addrs == NULL || addrs_cnt == 0) {
+ SCReturnInt(0);
+ }
+
+ uint32_t match_addr = SCNtohl(a->addr_data32[0]);
+ for (uint16_t idx = 0; idx < addrs_cnt; idx++) {
+ if (match_addr >= addrs[idx].ip && match_addr <= addrs[idx].ip2) {
+ SCReturnInt(1);
+ }
+ }
+
+ SCReturnInt(0);
+}
+
+/**
+ * \brief Match a packets address against a signatures addrs array
+ *
+ * \param addrs array of DetectMatchAddressIPv6's
+ * \param addrs_cnt array size in members
+ * \param a packets address
+ *
+ * \retval 0 no match
+ * \retval 1 match
+ *
+ * \note addresses in addrs are in host order
+ *
+ * \todo array should be ordered, so we can break out of the loop
+ */
+int DetectAddressMatchIPv6(const DetectMatchAddressIPv6 *addrs,
+ uint16_t addrs_cnt, const Address *a)
+{
+ SCEnter();
+
+ if (addrs == NULL || addrs_cnt == 0) {
+ SCReturnInt(0);
+ }
+
+ uint32_t match_addr[4];
+ match_addr[0] = SCNtohl(a->addr_data32[0]);
+ match_addr[1] = SCNtohl(a->addr_data32[1]);
+ match_addr[2] = SCNtohl(a->addr_data32[2]);
+ match_addr[3] = SCNtohl(a->addr_data32[3]);
+
+ /* See if the packet address is within the range of any entry in the
+ * signature's address match array.
+ */
+ for (uint16_t idx = 0; idx < addrs_cnt; idx++) {
+ uint16_t result1 = 0, result2 = 0;
+
+ /* See if packet address equals either limit. Return 1 if true. */
+ if (0 == memcmp(match_addr, addrs[idx].ip, sizeof(match_addr))) {
+ SCReturnInt(1);
+ }
+ if (0 == memcmp(match_addr, addrs[idx].ip2, sizeof(match_addr))) {
+ SCReturnInt(1);
+ }
+
+ /* See if packet address is greater than lower limit
+ * of the current signature address match pair.
+ */
+ for (int i = 0; i < 4; i++) {
+ if (match_addr[i] > addrs[idx].ip[i]) {
+ result1 = 1;
+ break;
+ }
+ if (match_addr[i] < addrs[idx].ip[i]) {
+ result1 = 0;
+ break;
+ }
+ }
+
+ /* If not greater than lower limit, try next address match entry */
+ if (result1 == 0)
+ continue;
+
+ /* See if packet address is less than upper limit
+ * of the current signature address match pair.
+ */
+ for (int i = 0; i < 4; i++) {
+ if (match_addr[i] < addrs[idx].ip2[i]) {
+ result2 = 1;
+ break;
+ }
+ if (match_addr[i] > addrs[idx].ip2[i]) {
+ result2 = 0;
+ break;
+ }
+ }
+
+ /* Return a match if packet address is between the two
+ * signature address match limits.
+ */
+ if (result1 == 1 && result2 == 1)
+ SCReturnInt(1);
+ }
+
+ SCReturnInt(0);
+}
+
+/**
+ * \brief Check if a particular address(ipv4 or ipv6) matches the address
+ * range in the DetectAddress instance.
+ *
+ * We basically check that the address falls in between the address
+ * range in DetectAddress.
+ *
+ * \param dd Pointer to the DetectAddress instance.
+ * \param a Pointer to an Address instance.
+ *
+ * \param 1 On a match.
+ * \param 0 On no match.
+ */
+static int DetectAddressMatch(DetectAddress *dd, Address *a)
+{
+ SCEnter();
+
+ if (dd->ip.family != a->family) {
+ SCReturnInt(0);
+ }
+
+ //DetectAddressPrint(dd);
+ //AddressDebugPrint(a);
+
+ switch (a->family) {
+ case AF_INET:
+
+ /* XXX figure out a way to not need to do this SCNtohl if we switch to
+ * Address inside DetectAddressData we can do uint8_t checks */
+ if (SCNtohl(a->addr_data32[0]) >= SCNtohl(dd->ip.addr_data32[0]) &&
+ SCNtohl(a->addr_data32[0]) <= SCNtohl(dd->ip2.addr_data32[0]))
+ {
+ SCReturnInt(1);
+ } else {
+ SCReturnInt(0);
+ }
+
+ break;
+ case AF_INET6:
+ if (AddressIPv6Ge(a, &dd->ip) == 1 &&
+ AddressIPv6Le(a, &dd->ip2) == 1)
+ {
+ SCReturnInt(1);
+ } else {
+ SCReturnInt(0);
+ }
+
+ break;
+ default:
+ SCLogDebug("What other address type can we have :-/");
+ break;
+ }
+
+ SCReturnInt(0);
+}
+
+#ifdef DEBUG
+/**
+ * \brief Prints the address data held by the DetectAddress. If the address
+ * data family is IPv4, we print the ipv4 address and mask, and
+ * if the address data family is IPv6, we print the ipv6 address and
+ * mask.
+ *
+ * \param ad Pointer to the DetectAddress instance to be printed.
+ */
+static void DetectAddressPrint(DetectAddress *gr)
+{
+ if (gr == NULL)
+ return;
+
+ if (gr->ip.family == AF_INET) {
+ struct in_addr in;
+ char ip[16], mask[16];
+
+ memcpy(&in, &gr->ip.addr_data32[0], sizeof(in));
+ PrintInet(AF_INET, &in, ip, sizeof(ip));
+ memcpy(&in, &gr->ip2.addr_data32[0], sizeof(in));
+ PrintInet(AF_INET, &in, mask, sizeof(mask));
+
+ SCLogDebug("%s/%s", ip, mask);
+// printf("%s/%s", ip, mask);
+ } else if (gr->ip.family == AF_INET6) {
+ struct in6_addr in6;
+ char ip[66], mask[66];
+
+ memcpy(&in6, &gr->ip.addr_data32, sizeof(in6));
+ PrintInet(AF_INET6, &in6, ip, sizeof(ip));
+ memcpy(&in6, &gr->ip2.addr_data32, sizeof(in6));
+ PrintInet(AF_INET6, &in6, mask, sizeof(mask));
+
+ SCLogDebug("%s/%s", ip, mask);
+// printf("%s/%s", ip, mask);
+ }
+
+ return;
+}
+#endif
+
+/**
+ * \brief Find the group matching address in a group head.
+ *
+ * \param gh Pointer to the address group head(DetectAddressHead instance).
+ * \param a Pointer to an Address instance.
+ *
+ * \retval g On success pointer to an DetectAddress if we find a match
+ * for the Address "a", in the DetectAddressHead "gh".
+ */
+DetectAddress *DetectAddressLookupInHead(const DetectAddressHead *gh, Address *a)
+{
+ SCEnter();
+
+ DetectAddress *g = NULL;
+
+ if (gh == NULL) {
+ SCReturnPtr(NULL, "DetectAddress");
+ }
+
+ /* XXX should we really do this check every time we run this function? */
+ if (a->family == AF_INET) {
+ SCLogDebug("IPv4");
+ g = gh->ipv4_head;
+ } else if (a->family == AF_INET6) {
+ SCLogDebug("IPv6");
+ g = gh->ipv6_head;
+ }
+
+ for ( ; g != NULL; g = g->next) {
+ if (DetectAddressMatch(g,a) == 1) {
+ SCReturnPtr(g, "DetectAddress");
+ }
+ }
+
+ SCReturnPtr(NULL, "DetectAddress");
+}
+
+/********************************Unittests*************************************/
+
+#ifdef UNITTESTS
+
+static int UTHValidateDetectAddress(DetectAddress *ad, const char *one, const char *two)
+{
+ char str1[46] = "", str2[46] = "";
+
+ if (ad == NULL)
+ return FALSE;
+
+ switch(ad->ip.family) {
+ case AF_INET:
+ PrintInet(AF_INET, (const void *)&ad->ip.addr_data32[0], str1, sizeof(str1));
+ SCLogDebug("%s", str1);
+ PrintInet(AF_INET, (const void *)&ad->ip2.addr_data32[0], str2, sizeof(str2));
+ SCLogDebug("%s", str2);
+
+ if (strcmp(str1, one) != 0) {
+ SCLogInfo("%s != %s", str1, one);
+ return FALSE;
+ }
+
+ if (strcmp(str2, two) != 0) {
+ SCLogInfo("%s != %s", str2, two);
+ return FALSE;
+ }
+
+ return TRUE;
+ break;
+
+ case AF_INET6:
+ PrintInet(AF_INET6, (const void *)&ad->ip.addr_data32[0], str1, sizeof(str1));
+ SCLogDebug("%s", str1);
+ PrintInet(AF_INET6, (const void *)&ad->ip2.addr_data32[0], str2, sizeof(str2));
+ SCLogDebug("%s", str2);
+
+ if (strcmp(str1, one) != 0) {
+ SCLogInfo("%s != %s", str1, one);
+ return FALSE;
+ }
+
+ if (strcmp(str2, two) != 0) {
+ SCLogInfo("%s != %s", str2, two);
+ return FALSE;
+ }
+
+ return TRUE;
+ break;
+ }
+
+ return FALSE;
+}
+
+typedef struct UTHValidateDetectAddressHeadRange_ {
+ const char *one;
+ const char *two;
+} UTHValidateDetectAddressHeadRange;
+
+static int UTHValidateDetectAddressHead(DetectAddressHead *gh, int nranges, UTHValidateDetectAddressHeadRange *expectations)
+{
+ int expect = nranges;
+ int have = 0;
+
+ if (gh == NULL)
+ return FALSE;
+
+ DetectAddress *ad = NULL;
+ ad = gh->ipv4_head;
+ if (ad == NULL)
+ ad = gh->ipv6_head;
+ while (have < expect) {
+ if (ad == NULL) {
+ printf("bad head: have %d ranges, expected %d: ", have, expect);
+ return FALSE;
+ }
+
+ if (UTHValidateDetectAddress(ad, expectations[have].one, expectations[have].two) == FALSE)
+ return FALSE;
+
+ ad = ad->next;
+ have++;
+ }
+
+ return TRUE;
+}
+
+static int AddressTestParse01(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("1.2.3.4");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse02(void)
+{
+ int result = 1;
+ DetectAddress *dd = DetectAddressParseSingle("1.2.3.4");
+
+ if (dd) {
+ if (dd->ip2.addr_data32[0] != SCNtohl(16909060) ||
+ dd->ip.addr_data32[0] != SCNtohl(16909060)) {
+ result = 0;
+ }
+
+ printf("ip %"PRIu32", ip2 %"PRIu32"\n", dd->ip.addr_data32[0], dd->ip2.addr_data32[0]);
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse03(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("1.2.3.4/255.255.255.0");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse04(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("1.2.3.4/255.255.255.0");
+ FAIL_IF_NULL(dd);
+
+ char left[16], right[16];
+ PrintInet(AF_INET, (const void *)&dd->ip.addr_data32[0], left, sizeof(left));
+ PrintInet(AF_INET, (const void *)&dd->ip2.addr_data32[0], right, sizeof(right));
+ SCLogDebug("left %s right %s", left, right);
+ FAIL_IF_NOT(dd->ip.addr_data32[0] == SCNtohl(16909056));
+ FAIL_IF_NOT(dd->ip2.addr_data32[0] == SCNtohl(16909311));
+ FAIL_IF_NOT(strcmp(left, "1.2.3.0") == 0);
+ FAIL_IF_NOT(strcmp(right, "1.2.3.255") == 0);
+
+ DetectAddressFree(dd);
+ PASS;
+}
+
+/** \test that address range sets proper start address */
+static int AddressTestParse04bug5081(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("1.2.3.64/26");
+ FAIL_IF_NULL(dd);
+
+ char left[16], right[16];
+ PrintInet(AF_INET, (const void *)&dd->ip.addr_data32[0], left, sizeof(left));
+ PrintInet(AF_INET, (const void *)&dd->ip2.addr_data32[0], right, sizeof(right));
+ SCLogDebug("left %s right %s", left, right);
+ FAIL_IF_NOT(strcmp(left, "1.2.3.64") == 0);
+ FAIL_IF_NOT(strcmp(right, "1.2.3.127") == 0);
+
+ DetectAddressFree(dd);
+ PASS;
+}
+
+static int AddressTestParse05(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("1.2.3.4/24");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse06(void)
+{
+ int result = 1;
+ DetectAddress *dd = DetectAddressParseSingle("1.2.3.4/24");
+
+ if (dd) {
+ if (dd->ip2.addr_data32[0] != SCNtohl(16909311) ||
+ dd->ip.addr_data32[0] != SCNtohl(16909056)) {
+ result = 0;
+ }
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse07(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("2001::/3");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse08(void)
+{
+ int result = 1;
+ DetectAddress *dd = DetectAddressParseSingle("2001::/3");
+
+ if (dd) {
+ if (dd->ip.addr_data32[0] != SCNtohl(536870912) || dd->ip.addr_data32[1] != 0x00000000 ||
+ dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 ||
+
+ dd->ip2.addr_data32[0] != SCNtohl(1073741823) || dd->ip2.addr_data32[1] != 0xFFFFFFFF ||
+ dd->ip2.addr_data32[2] != 0xFFFFFFFF || dd->ip2.addr_data32[3] != 0xFFFFFFFF) {
+ DetectAddressPrint(dd);
+ result = 0;
+ }
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse09(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("2001::1/128");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse10(void)
+{
+ int result = 1;
+ DetectAddress *dd = DetectAddressParseSingle("2001::/128");
+
+ if (dd) {
+ if (dd->ip.addr_data32[0] != SCNtohl(536936448) || dd->ip.addr_data32[1] != 0x00000000 ||
+ dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 ||
+
+ dd->ip2.addr_data32[0] != SCNtohl(536936448) || dd->ip2.addr_data32[1] != 0x00000000 ||
+ dd->ip2.addr_data32[2] != 0x00000000 || dd->ip2.addr_data32[3] != 0x00000000) {
+ DetectAddressPrint(dd);
+ result = 0;
+ }
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse11(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("2001::/48");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse12(void)
+{
+ int result = 1;
+ DetectAddress *dd = DetectAddressParseSingle("2001::/48");
+
+ if (dd) {
+ if (dd->ip.addr_data32[0] != SCNtohl(536936448) || dd->ip.addr_data32[1] != 0x00000000 ||
+ dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 ||
+
+ dd->ip2.addr_data32[0] != SCNtohl(536936448) || dd->ip2.addr_data32[1] != SCNtohl(65535) ||
+ dd->ip2.addr_data32[2] != 0xFFFFFFFF || dd->ip2.addr_data32[3] != 0xFFFFFFFF) {
+ DetectAddressPrint(dd);
+ result = 0;
+ }
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+static int AddressTestParse13(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("2001::/16");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse14(void)
+{
+ int result = 1;
+ DetectAddress *dd = DetectAddressParseSingle("2001::/16");
+
+ if (dd) {
+ if (dd->ip.addr_data32[0] != SCNtohl(536936448) || dd->ip.addr_data32[1] != 0x00000000 ||
+ dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 ||
+
+ dd->ip2.addr_data32[0] != SCNtohl(537001983) || dd->ip2.addr_data32[1] != 0xFFFFFFFF ||
+ dd->ip2.addr_data32[2] != 0xFFFFFFFF || dd->ip2.addr_data32[3] != 0xFFFFFFFF) {
+ result = 0;
+ }
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse15(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("2001::/0");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse16(void)
+{
+ int result = 1;
+ DetectAddress *dd = DetectAddressParseSingle("2001::/0");
+
+ if (dd) {
+ if (dd->ip.addr_data32[0] != 0x00000000 || dd->ip.addr_data32[1] != 0x00000000 ||
+ dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 ||
+
+ dd->ip2.addr_data32[0] != 0xFFFFFFFF || dd->ip2.addr_data32[1] != 0xFFFFFFFF ||
+ dd->ip2.addr_data32[2] != 0xFFFFFFFF || dd->ip2.addr_data32[3] != 0xFFFFFFFF) {
+ result = 0;
+ }
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse17(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("1.2.3.4-1.2.3.6");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse18(void)
+{
+ int result = 1;
+ DetectAddress *dd = DetectAddressParseSingle("1.2.3.4-1.2.3.6");
+
+ if (dd) {
+ if (dd->ip2.addr_data32[0] != SCNtohl(16909062) ||
+ dd->ip.addr_data32[0] != SCNtohl(16909060)) {
+ result = 0;
+ }
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse19(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("1.2.3.6-1.2.3.4");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int AddressTestParse20(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("2001::1-2001::4");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse21(void)
+{
+ int result = 1;
+ DetectAddress *dd = DetectAddressParseSingle("2001::1-2001::4");
+
+ if (dd) {
+ if (dd->ip.addr_data32[0] != SCNtohl(536936448) || dd->ip.addr_data32[1] != 0x00000000 ||
+ dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != SCNtohl(1) ||
+
+ dd->ip2.addr_data32[0] != SCNtohl(536936448) || dd->ip2.addr_data32[1] != 0x00000000 ||
+ dd->ip2.addr_data32[2] != 0x00000000 || dd->ip2.addr_data32[3] != SCNtohl(4)) {
+ result = 0;
+ }
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse22(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("2001::4-2001::1");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int AddressTestParse23(void)
+{
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ FAIL_IF_NULL(gh);
+ int r = DetectAddressParse(NULL, gh, "any");
+ FAIL_IF_NOT(r == 0);
+ DetectAddressHeadFree(gh);
+ PASS;
+}
+
+static int AddressTestParse24(void)
+{
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ FAIL_IF_NULL(gh);
+ int r = DetectAddressParse(NULL, gh, "Any");
+ FAIL_IF_NOT(r == 0);
+ DetectAddressHeadFree(gh);
+ PASS;
+}
+
+static int AddressTestParse25(void)
+{
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ FAIL_IF_NULL(gh);
+ int r = DetectAddressParse(NULL, gh, "ANY");
+ FAIL_IF_NOT(r == 0);
+ DetectAddressHeadFree(gh);
+ PASS;
+}
+
+/** \test recursion limit */
+static int AddressTestParse26(void)
+{
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ FAIL_IF_NULL(gh);
+ /* exactly 64: should pass */
+ int r = DetectAddressParse(NULL, gh,
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "1.2.3.4"
+ "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
+ );
+ FAIL_IF_NOT(r == 0);
+ DetectAddressHeadFree(gh);
+ gh = DetectAddressHeadInit();
+ FAIL_IF_NULL(gh);
+ /* exactly 65: should fail */
+ r = DetectAddressParse(NULL, gh,
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "1.2.3.4"
+ "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
+ );
+ FAIL_IF(r == 0);
+ DetectAddressHeadFree(gh);
+ PASS;
+}
+
+static int AddressTestParse27(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("!192.168.0.1");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse28(void)
+{
+ int result = 0;
+ DetectAddress *dd = DetectAddressParseSingle("!1.2.3.4");
+
+ if (dd) {
+ if (dd->flags & ADDRESS_FLAG_NOT &&
+ dd->ip.addr_data32[0] == SCNtohl(16909060)) {
+ result = 1;
+ }
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse29(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("!1.2.3.0/24");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse30(void)
+{
+ int result = 0;
+ DetectAddress *dd = DetectAddressParseSingle("!1.2.3.4/24");
+
+ if (dd) {
+ if (dd->flags & ADDRESS_FLAG_NOT &&
+ dd->ip.addr_data32[0] == SCNtohl(16909056) &&
+ dd->ip2.addr_data32[0] == SCNtohl(16909311)) {
+ result = 1;
+ }
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+/**
+ * \test make sure !any is rejected
+ */
+static int AddressTestParse31(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("!any");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int AddressTestParse32(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("!2001::1");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse33(void)
+{
+ int result = 0;
+ DetectAddress *dd = DetectAddressParseSingle("!2001::1");
+
+ if (dd) {
+ if (dd->flags & ADDRESS_FLAG_NOT &&
+ dd->ip.addr_data32[0] == SCNtohl(536936448) && dd->ip.addr_data32[1] == 0x00000000 &&
+ dd->ip.addr_data32[2] == 0x00000000 && dd->ip.addr_data32[3] == SCNtohl(1)) {
+ result = 1;
+ }
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse34(void)
+{
+ DetectAddress *dd = DetectAddressParseSingle("!2001::/16");
+
+ if (dd) {
+ DetectAddressFree(dd);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse35(void)
+{
+ int result = 0;
+ DetectAddress *dd = DetectAddressParseSingle("!2001::/16");
+
+ if (dd) {
+ if (dd->flags & ADDRESS_FLAG_NOT &&
+ dd->ip.addr_data32[0] == SCNtohl(536936448) && dd->ip.addr_data32[1] == 0x00000000 &&
+ dd->ip.addr_data32[2] == 0x00000000 && dd->ip.addr_data32[3] == 0x00000000 &&
+
+ dd->ip2.addr_data32[0] == SCNtohl(537001983) && dd->ip2.addr_data32[1] == 0xFFFFFFFF &&
+ dd->ip2.addr_data32[2] == 0xFFFFFFFF && dd->ip2.addr_data32[3] == 0xFFFFFFFF) {
+ result = 1;
+ }
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse36(void)
+{
+ int result = 1;
+ DetectAddress *dd = DetectAddressParseSingle("ffff::/16");
+
+ if (dd) {
+ if (dd->ip.addr_data32[0] != SCNtohl(0xFFFF0000) || dd->ip.addr_data32[1] != 0x00000000 ||
+ dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 ||
+
+ dd->ip2.addr_data32[0] != 0xFFFFFFFF || dd->ip2.addr_data32[1] != 0xFFFFFFFF ||
+ dd->ip2.addr_data32[2] != 0xFFFFFFFF || dd->ip2.addr_data32[3] != 0xFFFFFFFF) {
+
+ DetectAddressPrint(dd);
+ result = 0;
+ }
+ DetectAddressPrint(dd);
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestParse37(void)
+{
+ int result = 1;
+ DetectAddress *dd = DetectAddressParseSingle("::/0");
+
+ if (dd) {
+ if (dd->ip.addr_data32[0] != 0x00000000 || dd->ip.addr_data32[1] != 0x00000000 ||
+ dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 ||
+
+ dd->ip2.addr_data32[0] != 0xFFFFFFFF || dd->ip2.addr_data32[1] != 0xFFFFFFFF ||
+ dd->ip2.addr_data32[2] != 0xFFFFFFFF || dd->ip2.addr_data32[3] != 0xFFFFFFFF) {
+ DetectAddressPrint(dd);
+ result = 0;
+ }
+ DetectAddressPrint(dd);
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestMatch01(void)
+{
+ DetectAddress *dd = NULL;
+ int result = 1;
+ struct in_addr in;
+ Address a;
+
+ if (inet_pton(AF_INET, "1.2.3.4", &in) != 1)
+ return 0;
+ memset(&a, 0, sizeof(Address));
+ a.family = AF_INET;
+ a.addr_data32[0] = in.s_addr;
+
+ dd = DetectAddressParseSingle("1.2.3.4/24");
+ if (dd) {
+ if (DetectAddressMatch(dd, &a) == 0)
+ result = 0;
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestMatch02(void)
+{
+ DetectAddress *dd = NULL;
+ int result = 1;
+ struct in_addr in;
+ Address a;
+
+ if (inet_pton(AF_INET, "1.2.3.127", &in) != 1)
+ return 0;
+ memset(&a, 0, sizeof(Address));
+ a.family = AF_INET;
+ a.addr_data32[0] = in.s_addr;
+
+ dd = DetectAddressParseSingle("1.2.3.4/25");
+ if (dd) {
+ if (DetectAddressMatch(dd, &a) == 0)
+ result = 0;
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestMatch03(void)
+{
+ DetectAddress *dd = NULL;
+ int result = 1;
+ struct in_addr in;
+ Address a;
+
+ if (inet_pton(AF_INET, "1.2.3.128", &in) != 1)
+ return 0;
+ memset(&a, 0, sizeof(Address));
+ a.family = AF_INET;
+ a.addr_data32[0] = in.s_addr;
+
+ dd = DetectAddressParseSingle("1.2.3.4/25");
+ if (dd) {
+ if (DetectAddressMatch(dd, &a) == 1)
+ result = 0;
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestMatch04(void)
+{
+ DetectAddress *dd = NULL;
+ int result = 1;
+ struct in_addr in;
+ Address a;
+
+ if (inet_pton(AF_INET, "1.2.2.255", &in) != 1)
+ return 0;
+ memset(&a, 0, sizeof(Address));
+ a.family = AF_INET;
+ a.addr_data32[0] = in.s_addr;
+
+ dd = DetectAddressParseSingle("1.2.3.4/25");
+ if (dd) {
+ if (DetectAddressMatch(dd, &a) == 1)
+ result = 0;
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestMatch05(void)
+{
+ DetectAddress *dd = NULL;
+ int result = 1;
+ struct in_addr in;
+ Address a;
+
+ if (inet_pton(AF_INET, "1.2.3.4", &in) != 1)
+ return 0;
+ memset(&a, 0, sizeof(Address));
+ a.family = AF_INET;
+ a.addr_data32[0] = in.s_addr;
+
+ dd = DetectAddressParseSingle("1.2.3.4/32");
+ if (dd) {
+ if (DetectAddressMatch(dd, &a) == 0)
+ result = 0;
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestMatch06(void)
+{
+ DetectAddress *dd = NULL;
+ int result = 1;
+ struct in_addr in;
+ Address a;
+
+ if (inet_pton(AF_INET, "1.2.3.4", &in) != 1)
+ return 0;
+ memset(&a, 0, sizeof(Address));
+ a.family = AF_INET;
+ a.addr_data32[0] = in.s_addr;
+
+ dd = DetectAddressParseSingle("0.0.0.0/0.0.0.0");
+ if (dd) {
+ if (DetectAddressMatch(dd, &a) == 0)
+ result = 0;
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestMatch07(void)
+{
+ DetectAddress *dd = NULL;
+ int result = 1;
+ struct in6_addr in6;
+ Address a;
+
+ if (inet_pton(AF_INET6, "2001::1", &in6) != 1)
+ return 0;
+ memset(&a, 0, sizeof(Address));
+ a.family = AF_INET6;
+ memcpy(&a.addr_data32, &in6.s6_addr, sizeof(in6.s6_addr));
+
+ dd = DetectAddressParseSingle("2001::/3");
+ if (dd) {
+ if (DetectAddressMatch(dd, &a) == 0)
+ result = 0;
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestMatch08(void)
+{
+ DetectAddress *dd = NULL;
+ int result = 1;
+ struct in6_addr in6;
+ Address a;
+
+ if (inet_pton(AF_INET6, "1999:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &in6) != 1)
+ return 0;
+ memset(&a, 0, sizeof(Address));
+ a.family = AF_INET6;
+ memcpy(&a.addr_data32, &in6.s6_addr, sizeof(in6.s6_addr));
+
+ dd = DetectAddressParseSingle("2001::/3");
+ if (dd) {
+ if (DetectAddressMatch(dd, &a) == 1)
+ result = 0;
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestMatch09(void)
+{
+ DetectAddress *dd = NULL;
+ int result = 1;
+ struct in6_addr in6;
+ Address a;
+
+ if (inet_pton(AF_INET6, "2001::2", &in6) != 1)
+ return 0;
+ memset(&a, 0, sizeof(Address));
+ a.family = AF_INET6;
+ memcpy(&a.addr_data32, &in6.s6_addr, sizeof(in6.s6_addr));
+
+ dd = DetectAddressParseSingle("2001::1/128");
+ if (dd) {
+ if (DetectAddressMatch(dd, &a) == 1)
+ result = 0;
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestMatch10(void)
+{
+ DetectAddress *dd = NULL;
+ int result = 1;
+ struct in6_addr in6;
+ Address a;
+
+ if (inet_pton(AF_INET6, "2001::2", &in6) != 1)
+ return 0;
+ memset(&a, 0, sizeof(Address));
+ a.family = AF_INET6;
+ memcpy(&a.addr_data32, &in6.s6_addr, sizeof(in6.s6_addr));
+
+ dd = DetectAddressParseSingle("2001::1/126");
+ if (dd) {
+ if (DetectAddressMatch(dd, &a) == 0)
+ result = 0;
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestMatch11(void)
+{
+ DetectAddress *dd = NULL;
+ int result = 1;
+ struct in6_addr in6;
+ Address a;
+
+ if (inet_pton(AF_INET6, "2001::3", &in6) != 1)
+ return 0;
+ memset(&a, 0, sizeof(Address));
+ a.family = AF_INET6;
+ memcpy(&a.addr_data32, &in6.s6_addr, sizeof(in6.s6_addr));
+
+ dd = DetectAddressParseSingle("2001::1/127");
+ if (dd) {
+ if (DetectAddressMatch(dd, &a) == 1)
+ result = 0;
+
+ DetectAddressFree(dd);
+ return result;
+ }
+
+ return 0;
+}
+
+static int AddressTestCmp01(void)
+{
+ DetectAddress *da = NULL, *db = NULL;
+ int result = 1;
+
+ da = DetectAddressParseSingle("192.168.0.0/255.255.255.0");
+ if (da == NULL) goto error;
+ db = DetectAddressParseSingle("192.168.0.0/255.255.255.0");
+ if (db == NULL) goto error;
+
+ if (DetectAddressCmp(da, db) != ADDRESS_EQ)
+ result = 0;
+
+ DetectAddressFree(da);
+ DetectAddressFree(db);
+ return result;
+
+error:
+ if (da) DetectAddressFree(da);
+ if (db) DetectAddressFree(db);
+ return 0;
+}
+
+static int AddressTestCmp02(void)
+{
+ DetectAddress *da = NULL, *db = NULL;
+ int result = 1;
+
+ da = DetectAddressParseSingle("192.168.0.0/255.255.0.0");
+ if (da == NULL) goto error;
+ db = DetectAddressParseSingle("192.168.0.0/255.255.255.0");
+ if (db == NULL) goto error;
+
+ if (DetectAddressCmp(da, db) != ADDRESS_EB)
+ result = 0;
+
+ DetectAddressFree(da);
+ DetectAddressFree(db);
+ return result;
+
+error:
+ if (da) DetectAddressFree(da);
+ if (db) DetectAddressFree(db);
+ return 0;
+}
+
+static int AddressTestCmp03(void)
+{
+ DetectAddress *da = NULL, *db = NULL;
+ int result = 1;
+
+ da = DetectAddressParseSingle("192.168.0.0/255.255.255.0");
+ if (da == NULL) goto error;
+ db = DetectAddressParseSingle("192.168.0.0/255.255.0.0");
+ if (db == NULL) goto error;
+
+ if (DetectAddressCmp(da, db) != ADDRESS_ES)
+ result = 0;
+
+ DetectAddressFree(da);
+ DetectAddressFree(db);
+ return result;
+
+error:
+ if (da) DetectAddressFree(da);
+ if (db) DetectAddressFree(db);
+ return 0;
+}
+
+static int AddressTestCmp04(void)
+{
+ DetectAddress *da = NULL, *db = NULL;
+ int result = 1;
+
+ da = DetectAddressParseSingle("192.168.0.0/255.255.255.0");
+ if (da == NULL) goto error;
+ db = DetectAddressParseSingle("192.168.1.0/255.255.255.0");
+ if (db == NULL) goto error;
+
+ if (DetectAddressCmp(da, db) != ADDRESS_LT)
+ result = 0;
+
+ DetectAddressFree(da);
+ DetectAddressFree(db);
+ return result;
+
+error:
+ if (da) DetectAddressFree(da);
+ if (db) DetectAddressFree(db);
+ return 0;
+}
+
+static int AddressTestCmp05(void)
+{
+ DetectAddress *da = NULL, *db = NULL;
+ int result = 1;
+
+ da = DetectAddressParseSingle("192.168.1.0/255.255.255.0");
+ if (da == NULL) goto error;
+ db = DetectAddressParseSingle("192.168.0.0/255.255.255.0");
+ if (db == NULL) goto error;
+
+ if (DetectAddressCmp(da, db) != ADDRESS_GT)
+ result = 0;
+
+ DetectAddressFree(da);
+ DetectAddressFree(db);
+ return result;
+
+error:
+ if (da) DetectAddressFree(da);
+ if (db) DetectAddressFree(db);
+ return 0;
+}
+
+static int AddressTestCmp06(void)
+{
+ DetectAddress *da = NULL, *db = NULL;
+ int result = 1;
+
+ da = DetectAddressParseSingle("192.168.1.0/255.255.0.0");
+ if (da == NULL) goto error;
+ db = DetectAddressParseSingle("192.168.0.0/255.255.0.0");
+ if (db == NULL) goto error;
+
+ if (DetectAddressCmp(da, db) != ADDRESS_EQ)
+ result = 0;
+
+ DetectAddressFree(da);
+ DetectAddressFree(db);
+ return result;
+
+error:
+ if (da) DetectAddressFree(da);
+ if (db) DetectAddressFree(db);
+ return 0;
+}
+
+static int AddressTestCmpIPv407(void)
+{
+ DetectAddress *da = NULL, *db = NULL;
+ int result = 1;
+
+ da = DetectAddressParseSingle("192.168.1.0/255.255.255.0");
+ if (da == NULL) goto error;
+ db = DetectAddressParseSingle("192.168.1.128-192.168.2.128");
+ if (db == NULL) goto error;
+
+ if (DetectAddressCmp(da, db) != ADDRESS_LE)
+ result = 0;
+
+ DetectAddressFree(da);
+ DetectAddressFree(db);
+ return result;
+
+error:
+ if (da) DetectAddressFree(da);
+ if (db) DetectAddressFree(db);
+ return 0;
+}
+
+static int AddressTestCmpIPv408(void)
+{
+ DetectAddress *da = NULL, *db = NULL;
+ int result = 1;
+
+ da = DetectAddressParseSingle("192.168.1.128-192.168.2.128");
+ if (da == NULL) goto error;
+ db = DetectAddressParseSingle("192.168.1.0/255.255.255.0");
+ if (db == NULL) goto error;
+
+ if (DetectAddressCmp(da, db) != ADDRESS_GE)
+ result = 0;
+
+ DetectAddressFree(da);
+ DetectAddressFree(db);
+ return result;
+
+error:
+ if (da) DetectAddressFree(da);
+ if (db) DetectAddressFree(db);
+ return 0;
+}
+
+static int AddressTestCmp07(void)
+{
+ DetectAddress *da = NULL, *db = NULL;
+ int result = 1;
+
+ da = DetectAddressParseSingle("2001::/3");
+ if (da == NULL) goto error;
+ db = DetectAddressParseSingle("2001::1/3");
+ if (db == NULL) goto error;
+
+ if (DetectAddressCmp(da, db) != ADDRESS_EQ)
+ result = 0;
+
+ DetectAddressFree(da);
+ DetectAddressFree(db);
+ return result;
+
+error:
+ if (da) DetectAddressFree(da);
+ if (db) DetectAddressFree(db);
+ return 0;
+}
+
+static int AddressTestCmp08(void)
+{
+ DetectAddress *da = NULL, *db = NULL;
+ int result = 1;
+
+ da = DetectAddressParseSingle("2001::/3");
+ if (da == NULL) goto error;
+ db = DetectAddressParseSingle("2001::/8");
+ if (db == NULL) goto error;
+
+ if (DetectAddressCmp(da, db) != ADDRESS_EB)
+ result = 0;
+
+ DetectAddressFree(da);
+ DetectAddressFree(db);
+ return result;
+
+error:
+ if (da) DetectAddressFree(da);
+ if (db) DetectAddressFree(db);
+ return 0;
+}
+
+static int AddressTestCmp09(void)
+{
+ DetectAddress *da = NULL, *db = NULL;
+ int result = 1;
+
+ da = DetectAddressParseSingle("2001::/8");
+ if (da == NULL) goto error;
+ db = DetectAddressParseSingle("2001::/3");
+ if (db == NULL) goto error;
+
+ if (DetectAddressCmp(da, db) != ADDRESS_ES)
+ result = 0;
+
+ DetectAddressFree(da);
+ DetectAddressFree(db);
+ return result;
+
+error:
+ if (da) DetectAddressFree(da);
+ if (db) DetectAddressFree(db);
+ return 0;
+}
+
+static int AddressTestCmp10(void)
+{
+ DetectAddress *da = NULL, *db = NULL;
+ int result = 1;
+
+ da = DetectAddressParseSingle("2001:1:2:3:0:0:0:0/64");
+ if (da == NULL) goto error;
+ db = DetectAddressParseSingle("2001:1:2:4:0:0:0:0/64");
+ if (db == NULL) goto error;
+
+ if (DetectAddressCmp(da, db) != ADDRESS_LT)
+ result = 0;
+
+ DetectAddressFree(da);
+ DetectAddressFree(db);
+ return result;
+
+error:
+ if (da) DetectAddressFree(da);
+ if (db) DetectAddressFree(db);
+ return 0;
+}
+
+static int AddressTestCmp11(void)
+{
+ DetectAddress *da = NULL, *db = NULL;
+ int result = 1;
+
+ da = DetectAddressParseSingle("2001:1:2:4:0:0:0:0/64");
+ if (da == NULL) goto error;
+ db = DetectAddressParseSingle("2001:1:2:3:0:0:0:0/64");
+ if (db == NULL) goto error;
+
+ if (DetectAddressCmp(da, db) != ADDRESS_GT)
+ result = 0;
+
+ DetectAddressFree(da);
+ DetectAddressFree(db);
+ return result;
+
+error:
+ if (da) DetectAddressFree(da);
+ if (db) DetectAddressFree(db);
+ return 0;
+}
+
+static int AddressTestCmp12(void)
+{
+ DetectAddress *da = NULL, *db = NULL;
+ int result = 1;
+
+ da = DetectAddressParseSingle("2001:1:2:3:1:0:0:0/64");
+ if (da == NULL) goto error;
+ db = DetectAddressParseSingle("2001:1:2:3:2:0:0:0/64");
+ if (db == NULL) goto error;
+
+ if (DetectAddressCmp(da, db) != ADDRESS_EQ)
+ result = 0;
+
+ DetectAddressFree(da);
+ DetectAddressFree(db);
+ return result;
+
+error:
+ if (da) DetectAddressFree(da);
+ if (db) DetectAddressFree(db);
+ return 0;
+}
+
+static int AddressTestAddressGroupSetup01(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "1.2.3.4");
+ if (r == 0)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup02(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "1.2.3.4");
+ if (r == 0 && gh->ipv4_head != NULL)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup03(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "1.2.3.4");
+ if (r == 0 && gh->ipv4_head != NULL) {
+ DetectAddress *prev_head = gh->ipv4_head;
+
+ r = DetectAddressParse(NULL, gh, "1.2.3.3");
+ if (r == 0 && gh->ipv4_head != prev_head &&
+ gh->ipv4_head != NULL && gh->ipv4_head->next == prev_head) {
+ result = 1;
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup04(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "1.2.3.4");
+ if (r == 0 && gh->ipv4_head != NULL) {
+ DetectAddress *prev_head = gh->ipv4_head;
+
+ r = DetectAddressParse(NULL, gh, "1.2.3.3");
+ if (r == 0 && gh->ipv4_head != prev_head &&
+ gh->ipv4_head != NULL && gh->ipv4_head->next == prev_head) {
+ DetectAddress *ph = gh->ipv4_head;
+
+ r = DetectAddressParse(NULL, gh, "1.2.3.2");
+ if (r == 0 && gh->ipv4_head != ph &&
+ gh->ipv4_head != NULL && gh->ipv4_head->next == ph) {
+ result = 1;
+ }
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup05(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "1.2.3.2");
+ if (r == 0 && gh->ipv4_head != NULL) {
+ DetectAddress *prev_head = gh->ipv4_head;
+
+ r = DetectAddressParse(NULL, gh, "1.2.3.3");
+ if (r == 0 && gh->ipv4_head == prev_head &&
+ gh->ipv4_head != NULL && gh->ipv4_head->next != prev_head) {
+ DetectAddress *ph = gh->ipv4_head;
+
+ r = DetectAddressParse(NULL, gh, "1.2.3.4");
+ if (r == 0 && gh->ipv4_head == ph &&
+ gh->ipv4_head != NULL && gh->ipv4_head->next != ph) {
+ result = 1;
+ }
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup06(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "1.2.3.2");
+ if (r == 0 && gh->ipv4_head != NULL) {
+ DetectAddress *prev_head = gh->ipv4_head;
+
+ r = DetectAddressParse(NULL, gh, "1.2.3.2");
+ if (r == 0 && gh->ipv4_head == prev_head &&
+ gh->ipv4_head != NULL && gh->ipv4_head->next == NULL) {
+ result = 1;
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup07(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "10.0.0.0/8");
+ if (r == 0 && gh->ipv4_head != NULL) {
+ r = DetectAddressParse(NULL, gh, "10.10.10.10");
+ if (r == 0 && gh->ipv4_head != NULL &&
+ gh->ipv4_head->next != NULL &&
+ gh->ipv4_head->next->next != NULL) {
+ result = 1;
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup08(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "10.10.10.10");
+ if (r == 0 && gh->ipv4_head != NULL) {
+ r = DetectAddressParse(NULL, gh, "10.0.0.0/8");
+ if (r == 0 && gh->ipv4_head != NULL &&
+ gh->ipv4_head->next != NULL &&
+ gh->ipv4_head->next->next != NULL) {
+ result = 1;
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup09(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "10.10.10.0/24");
+ if (r == 0 && gh->ipv4_head != NULL) {
+ r = DetectAddressParse(NULL, gh, "10.10.10.10-10.10.11.1");
+ if (r == 0 && gh->ipv4_head != NULL &&
+ gh->ipv4_head->next != NULL &&
+ gh->ipv4_head->next->next != NULL) {
+ result = 1;
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup10(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "10.10.10.10-10.10.11.1");
+ if (r == 0 && gh->ipv4_head != NULL) {
+ r = DetectAddressParse(NULL, gh, "10.10.10.0/24");
+ if (r == 0 && gh->ipv4_head != NULL &&
+ gh->ipv4_head->next != NULL &&
+ gh->ipv4_head->next->next != NULL) {
+ result = 1;
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup11(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "10.10.10.10-10.10.11.1");
+ if (r == 0) {
+ r = DetectAddressParse(NULL, gh, "10.10.10.0/24");
+ if (r == 0) {
+ r = DetectAddressParse(NULL, gh, "0.0.0.0/0");
+ if (r == 0) {
+ DetectAddress *one = gh->ipv4_head, *two = one->next,
+ *three = two->next, *four = three->next,
+ *five = four->next;
+
+ /* result should be:
+ * 0.0.0.0/10.10.9.255
+ * 10.10.10.0/10.10.10.9
+ * 10.10.10.10/10.10.10.255
+ * 10.10.11.0/10.10.11.1
+ * 10.10.11.2/255.255.255.255
+ */
+ if (one->ip.addr_data32[0] == 0x00000000 && one->ip2.addr_data32[0] == SCNtohl(168430079) &&
+ two->ip.addr_data32[0] == SCNtohl(168430080) && two->ip2.addr_data32[0] == SCNtohl(168430089) &&
+ three->ip.addr_data32[0] == SCNtohl(168430090) && three->ip2.addr_data32[0] == SCNtohl(168430335) &&
+ four->ip.addr_data32[0] == SCNtohl(168430336) && four->ip2.addr_data32[0] == SCNtohl(168430337) &&
+ five->ip.addr_data32[0] == SCNtohl(168430338) && five->ip2.addr_data32[0] == 0xFFFFFFFF) {
+ result = 1;
+ }
+ }
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup12 (void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "10.10.10.10-10.10.11.1");
+ if (r == 0) {
+ r = DetectAddressParse(NULL, gh, "0.0.0.0/0");
+ if (r == 0) {
+ r = DetectAddressParse(NULL, gh, "10.10.10.0/24");
+ if (r == 0) {
+ DetectAddress *one = gh->ipv4_head, *two = one->next,
+ *three = two->next, *four = three->next,
+ *five = four->next;
+
+ /* result should be:
+ * 0.0.0.0/10.10.9.255
+ * 10.10.10.0/10.10.10.9
+ * 10.10.10.10/10.10.10.255
+ * 10.10.11.0/10.10.11.1
+ * 10.10.11.2/255.255.255.255
+ */
+ if (one->ip.addr_data32[0] == 0x00000000 && one->ip2.addr_data32[0] == SCNtohl(168430079) &&
+ two->ip.addr_data32[0] == SCNtohl(168430080) && two->ip2.addr_data32[0] == SCNtohl(168430089) &&
+ three->ip.addr_data32[0] == SCNtohl(168430090) && three->ip2.addr_data32[0] == SCNtohl(168430335) &&
+ four->ip.addr_data32[0] == SCNtohl(168430336) && four->ip2.addr_data32[0] == SCNtohl(168430337) &&
+ five->ip.addr_data32[0] == SCNtohl(168430338) && five->ip2.addr_data32[0] == 0xFFFFFFFF) {
+ result = 1;
+ }
+ }
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup13(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "0.0.0.0/0");
+ if (r == 0) {
+ r = DetectAddressParse(NULL, gh, "10.10.10.10-10.10.11.1");
+ if (r == 0) {
+ r = DetectAddressParse(NULL, gh, "10.10.10.0/24");
+ if (r == 0) {
+ DetectAddress *one = gh->ipv4_head, *two = one->next,
+ *three = two->next, *four = three->next,
+ *five = four->next;
+
+ /* result should be:
+ * 0.0.0.0/10.10.9.255
+ * 10.10.10.0/10.10.10.9
+ * 10.10.10.10/10.10.10.255
+ * 10.10.11.0/10.10.11.1
+ * 10.10.11.2/255.255.255.255
+ */
+ if (one->ip.addr_data32[0] == 0x00000000 && one->ip2.addr_data32[0] == SCNtohl(168430079) &&
+ two->ip.addr_data32[0] == SCNtohl(168430080) && two->ip2.addr_data32[0] == SCNtohl(168430089) &&
+ three->ip.addr_data32[0] == SCNtohl(168430090) && three->ip2.addr_data32[0] == SCNtohl(168430335) &&
+ four->ip.addr_data32[0] == SCNtohl(168430336) && four->ip2.addr_data32[0] == SCNtohl(168430337) &&
+ five->ip.addr_data32[0] == SCNtohl(168430338) && five->ip2.addr_data32[0] == 0xFFFFFFFF) {
+ result = 1;
+ }
+ }
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetupIPv414(void)
+{
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ FAIL_IF_NULL(gh);
+
+ int r = DetectAddressParse(NULL, gh, "!1.2.3.4");
+ FAIL_IF_NOT(r == 1);
+
+ DetectAddress *one = gh->ipv4_head;
+ FAIL_IF_NULL(one);
+ DetectAddress *two = one->next;
+ FAIL_IF_NULL(two);
+
+ /* result should be:
+ * 0.0.0.0/1.2.3.3
+ * 1.2.3.5/255.255.255.255
+ */
+ FAIL_IF_NOT(one->ip.addr_data32[0] == 0x00000000);
+ FAIL_IF_NOT(one->ip2.addr_data32[0] == SCNtohl(16909059));
+ FAIL_IF_NOT(two->ip.addr_data32[0] == SCNtohl(16909061));
+ FAIL_IF_NOT(two->ip2.addr_data32[0] == 0xFFFFFFFF);
+ DetectAddressHeadFree(gh);
+
+ PASS;
+}
+
+static int AddressTestAddressGroupSetupIPv415(void)
+{
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ FAIL_IF_NULL(gh);
+
+ int r = DetectAddressParse(NULL, gh, "!0.0.0.0");
+ FAIL_IF_NOT(r == 1);
+
+ DetectAddress *one = gh->ipv4_head;
+ FAIL_IF_NULL(one);
+ FAIL_IF_NOT_NULL(one->next);
+
+ /* result should be:
+ * 0.0.0.1/255.255.255.255
+ */
+ FAIL_IF_NOT(one->ip.addr_data32[0] == SCNtohl(1));
+ FAIL_IF_NOT(one->ip2.addr_data32[0] == 0xFFFFFFFF);
+
+ DetectAddressHeadFree(gh);
+ PASS;
+}
+
+static int AddressTestAddressGroupSetupIPv416(void)
+{
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ FAIL_IF_NULL(gh);
+
+ int r = DetectAddressParse(NULL, gh, "!255.255.255.255");
+ FAIL_IF_NOT(r == 1);
+
+ DetectAddress *one = gh->ipv4_head;
+ FAIL_IF_NULL(one);
+ FAIL_IF_NOT_NULL(one->next);
+
+ /* result should be:
+ * 0.0.0.0/255.255.255.254
+ */
+ FAIL_IF_NOT(one->ip.addr_data32[0] == 0x00000000);
+ FAIL_IF_NOT(one->ip2.addr_data32[0] == SCNtohl(4294967294));
+
+ DetectAddressHeadFree(gh);
+ PASS;
+}
+
+static int AddressTestAddressGroupSetup14(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "2001::1");
+ if (r == 0)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup15(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "2001::1");
+ if (r == 0 && gh->ipv6_head != NULL)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup16(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "2001::4");
+ if (r == 0 && gh->ipv6_head != NULL) {
+ DetectAddress *prev_head = gh->ipv6_head;
+
+ r = DetectAddressParse(NULL, gh, "2001::3");
+ if (r == 0 && gh->ipv6_head != prev_head &&
+ gh->ipv6_head != NULL && gh->ipv6_head->next == prev_head) {
+ result = 1;
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup17(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "2001::4");
+ if (r == 0 && gh->ipv6_head != NULL) {
+ DetectAddress *prev_head = gh->ipv6_head;
+
+ r = DetectAddressParse(NULL, gh, "2001::3");
+ if (r == 0 && gh->ipv6_head != prev_head &&
+ gh->ipv6_head != NULL && gh->ipv6_head->next == prev_head) {
+ DetectAddress *ph = gh->ipv6_head;
+
+ r = DetectAddressParse(NULL, gh, "2001::2");
+ if (r == 0 && gh->ipv6_head != ph &&
+ gh->ipv6_head != NULL && gh->ipv6_head->next == ph) {
+ result = 1;
+ }
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup18(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "2001::2");
+ if (r == 0 && gh->ipv6_head != NULL) {
+ DetectAddress *prev_head = gh->ipv6_head;
+
+ r = DetectAddressParse(NULL, gh, "2001::3");
+ if (r == 0 && gh->ipv6_head == prev_head &&
+ gh->ipv6_head != NULL && gh->ipv6_head->next != prev_head) {
+ DetectAddress *ph = gh->ipv6_head;
+
+ r = DetectAddressParse(NULL, gh, "2001::4");
+ if (r == 0 && gh->ipv6_head == ph &&
+ gh->ipv6_head != NULL && gh->ipv6_head->next != ph) {
+ result = 1;
+ }
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup19(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "2001::2");
+ if (r == 0 && gh->ipv6_head != NULL) {
+ DetectAddress *prev_head = gh->ipv6_head;
+
+ r = DetectAddressParse(NULL, gh, "2001::2");
+ if (r == 0 && gh->ipv6_head == prev_head &&
+ gh->ipv6_head != NULL && gh->ipv6_head->next == NULL) {
+ result = 1;
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup20(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "2000::/3");
+ if (r == 0 && gh->ipv6_head != NULL) {
+ r = DetectAddressParse(NULL, gh, "2001::4");
+ if (r == 0 && gh->ipv6_head != NULL &&
+ gh->ipv6_head->next != NULL &&
+ gh->ipv6_head->next->next != NULL) {
+ result = 1;
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup21(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "2001::4");
+ if (r == 0 && gh->ipv6_head != NULL) {
+ r = DetectAddressParse(NULL, gh, "2000::/3");
+ if (r == 0 && gh->ipv6_head != NULL &&
+ gh->ipv6_head->next != NULL &&
+ gh->ipv6_head->next->next != NULL) {
+ result = 1;
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup22(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "2000::/3");
+ if (r == 0 && gh->ipv6_head != NULL) {
+ r = DetectAddressParse(NULL, gh, "2001::4-2001::6");
+ if (r == 0 && gh->ipv6_head != NULL &&
+ gh->ipv6_head->next != NULL &&
+ gh->ipv6_head->next->next != NULL) {
+ result = 1;
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup23(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "2001::4-2001::6");
+ if (r == 0 && gh->ipv6_head != NULL) {
+ r = DetectAddressParse(NULL, gh, "2000::/3");
+ if (r == 0 && gh->ipv6_head != NULL &&
+ gh->ipv6_head->next != NULL &&
+ gh->ipv6_head->next->next != NULL) {
+ result = 1;
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup24(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "2001::4-2001::6");
+ if (r == 0) {
+ r = DetectAddressParse(NULL, gh, "2001::/3");
+ if (r == 0) {
+ r = DetectAddressParse(NULL, gh, "::/0");
+ if (r == 0) {
+ DetectAddress *one = gh->ipv6_head, *two = one->next,
+ *three = two->next, *four = three->next,
+ *five = four->next;
+ if (one->ip.addr_data32[0] == 0x00000000 &&
+ one->ip.addr_data32[1] == 0x00000000 &&
+ one->ip.addr_data32[2] == 0x00000000 &&
+ one->ip.addr_data32[3] == 0x00000000 &&
+ one->ip2.addr_data32[0] == SCNtohl(536870911) &&
+ one->ip2.addr_data32[1] == 0xFFFFFFFF &&
+ one->ip2.addr_data32[2] == 0xFFFFFFFF &&
+ one->ip2.addr_data32[3] == 0xFFFFFFFF &&
+
+ two->ip.addr_data32[0] == SCNtohl(536870912) &&
+ two->ip.addr_data32[1] == 0x00000000 &&
+ two->ip.addr_data32[2] == 0x00000000 &&
+ two->ip.addr_data32[3] == 0x00000000 &&
+ two->ip2.addr_data32[0] == SCNtohl(536936448) &&
+ two->ip2.addr_data32[1] == 0x00000000 &&
+ two->ip2.addr_data32[2] == 0x00000000 &&
+ two->ip2.addr_data32[3] == SCNtohl(3) &&
+
+ three->ip.addr_data32[0] == SCNtohl(536936448) &&
+ three->ip.addr_data32[1] == 0x00000000 &&
+ three->ip.addr_data32[2] == 0x00000000 &&
+ three->ip.addr_data32[3] == SCNtohl(4) &&
+ three->ip2.addr_data32[0] == SCNtohl(536936448) &&
+ three->ip2.addr_data32[1] == 0x00000000 &&
+ three->ip2.addr_data32[2] == 0x00000000 &&
+ three->ip2.addr_data32[3] == SCNtohl(6) &&
+
+ four->ip.addr_data32[0] == SCNtohl(536936448) &&
+ four->ip.addr_data32[1] == 0x00000000 &&
+ four->ip.addr_data32[2] == 0x00000000 &&
+ four->ip.addr_data32[3] == SCNtohl(7) &&
+ four->ip2.addr_data32[0] == SCNtohl(1073741823) &&
+ four->ip2.addr_data32[1] == 0xFFFFFFFF &&
+ four->ip2.addr_data32[2] == 0xFFFFFFFF &&
+ four->ip2.addr_data32[3] == 0xFFFFFFFF &&
+
+ five->ip.addr_data32[0] == SCNtohl(1073741824) &&
+ five->ip.addr_data32[1] == 0x00000000 &&
+ five->ip.addr_data32[2] == 0x00000000 &&
+ five->ip.addr_data32[3] == 0x00000000 &&
+ five->ip2.addr_data32[0] == 0xFFFFFFFF &&
+ five->ip2.addr_data32[1] == 0xFFFFFFFF &&
+ five->ip2.addr_data32[2] == 0xFFFFFFFF &&
+ five->ip2.addr_data32[3] == 0xFFFFFFFF) {
+ result = 1;
+ }
+ }
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup25(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "2001::4-2001::6");
+ if (r == 0) {
+ r = DetectAddressParse(NULL, gh, "::/0");
+ if (r == 0) {
+ r = DetectAddressParse(NULL, gh, "2001::/3");
+ if (r == 0) {
+ DetectAddress *one = gh->ipv6_head, *two = one->next,
+ *three = two->next, *four = three->next,
+ *five = four->next;
+ if (one->ip.addr_data32[0] == 0x00000000 &&
+ one->ip.addr_data32[1] == 0x00000000 &&
+ one->ip.addr_data32[2] == 0x00000000 &&
+ one->ip.addr_data32[3] == 0x00000000 &&
+ one->ip2.addr_data32[0] == SCNtohl(536870911) &&
+ one->ip2.addr_data32[1] == 0xFFFFFFFF &&
+ one->ip2.addr_data32[2] == 0xFFFFFFFF &&
+ one->ip2.addr_data32[3] == 0xFFFFFFFF &&
+
+ two->ip.addr_data32[0] == SCNtohl(536870912) &&
+ two->ip.addr_data32[1] == 0x00000000 &&
+ two->ip.addr_data32[2] == 0x00000000 &&
+ two->ip.addr_data32[3] == 0x00000000 &&
+ two->ip2.addr_data32[0] == SCNtohl(536936448) &&
+ two->ip2.addr_data32[1] == 0x00000000 &&
+ two->ip2.addr_data32[2] == 0x00000000 &&
+ two->ip2.addr_data32[3] == SCNtohl(3) &&
+
+ three->ip.addr_data32[0] == SCNtohl(536936448) &&
+ three->ip.addr_data32[1] == 0x00000000 &&
+ three->ip.addr_data32[2] == 0x00000000 &&
+ three->ip.addr_data32[3] == SCNtohl(4) &&
+ three->ip2.addr_data32[0] == SCNtohl(536936448) &&
+ three->ip2.addr_data32[1] == 0x00000000 &&
+ three->ip2.addr_data32[2] == 0x00000000 &&
+ three->ip2.addr_data32[3] == SCNtohl(6) &&
+
+ four->ip.addr_data32[0] == SCNtohl(536936448) &&
+ four->ip.addr_data32[1] == 0x00000000 &&
+ four->ip.addr_data32[2] == 0x00000000 &&
+ four->ip.addr_data32[3] == SCNtohl(7) &&
+ four->ip2.addr_data32[0] == SCNtohl(1073741823) &&
+ four->ip2.addr_data32[1] == 0xFFFFFFFF &&
+ four->ip2.addr_data32[2] == 0xFFFFFFFF &&
+ four->ip2.addr_data32[3] == 0xFFFFFFFF &&
+
+ five->ip.addr_data32[0] == SCNtohl(1073741824) &&
+ five->ip.addr_data32[1] == 0x00000000 &&
+ five->ip.addr_data32[2] == 0x00000000 &&
+ five->ip.addr_data32[3] == 0x00000000 &&
+ five->ip2.addr_data32[0] == 0xFFFFFFFF &&
+ five->ip2.addr_data32[1] == 0xFFFFFFFF &&
+ five->ip2.addr_data32[2] == 0xFFFFFFFF &&
+ five->ip2.addr_data32[3] == 0xFFFFFFFF) {
+ result = 1;
+ }
+ }
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup26(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "::/0");
+ if (r == 0) {
+ r = DetectAddressParse(NULL, gh, "2001::4-2001::6");
+ if (r == 0) {
+ r = DetectAddressParse(NULL, gh, "2001::/3");
+ if (r == 0) {
+ DetectAddress *one = gh->ipv6_head, *two = one->next,
+ *three = two->next, *four = three->next,
+ *five = four->next;
+ if (one->ip.addr_data32[0] == 0x00000000 &&
+ one->ip.addr_data32[1] == 0x00000000 &&
+ one->ip.addr_data32[2] == 0x00000000 &&
+ one->ip.addr_data32[3] == 0x00000000 &&
+ one->ip2.addr_data32[0] == SCNtohl(536870911) &&
+ one->ip2.addr_data32[1] == 0xFFFFFFFF &&
+ one->ip2.addr_data32[2] == 0xFFFFFFFF &&
+ one->ip2.addr_data32[3] == 0xFFFFFFFF &&
+
+ two->ip.addr_data32[0] == SCNtohl(536870912) &&
+ two->ip.addr_data32[1] == 0x00000000 &&
+ two->ip.addr_data32[2] == 0x00000000 &&
+ two->ip.addr_data32[3] == 0x00000000 &&
+ two->ip2.addr_data32[0] == SCNtohl(536936448) &&
+ two->ip2.addr_data32[1] == 0x00000000 &&
+ two->ip2.addr_data32[2] == 0x00000000 &&
+ two->ip2.addr_data32[3] == SCNtohl(3) &&
+
+ three->ip.addr_data32[0] == SCNtohl(536936448) &&
+ three->ip.addr_data32[1] == 0x00000000 &&
+ three->ip.addr_data32[2] == 0x00000000 &&
+ three->ip.addr_data32[3] == SCNtohl(4) &&
+ three->ip2.addr_data32[0] == SCNtohl(536936448) &&
+ three->ip2.addr_data32[1] == 0x00000000 &&
+ three->ip2.addr_data32[2] == 0x00000000 &&
+ three->ip2.addr_data32[3] == SCNtohl(6) &&
+
+ four->ip.addr_data32[0] == SCNtohl(536936448) &&
+ four->ip.addr_data32[1] == 0x00000000 &&
+ four->ip.addr_data32[2] == 0x00000000 &&
+ four->ip.addr_data32[3] == SCNtohl(7) &&
+ four->ip2.addr_data32[0] == SCNtohl(1073741823) &&
+ four->ip2.addr_data32[1] == 0xFFFFFFFF &&
+ four->ip2.addr_data32[2] == 0xFFFFFFFF &&
+ four->ip2.addr_data32[3] == 0xFFFFFFFF &&
+
+ five->ip.addr_data32[0] == SCNtohl(1073741824) &&
+ five->ip.addr_data32[1] == 0x00000000 &&
+ five->ip.addr_data32[2] == 0x00000000 &&
+ five->ip.addr_data32[3] == 0x00000000 &&
+ five->ip2.addr_data32[0] == 0xFFFFFFFF &&
+ five->ip2.addr_data32[1] == 0xFFFFFFFF &&
+ five->ip2.addr_data32[2] == 0xFFFFFFFF &&
+ five->ip2.addr_data32[3] == 0xFFFFFFFF) {
+ result = 1;
+ }
+ }
+ }
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup27(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[1.2.3.4]");
+ if (r == 0)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup28(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[1.2.3.4,4.3.2.1]");
+ if (r == 0)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup29(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[1.2.3.4,4.3.2.1,10.10.10.10]");
+ if (r == 0)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup30(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[[1.2.3.4,2.3.4.5],4.3.2.1,[10.10.10.10,11.11.11.11]]");
+ if (r == 0)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup31(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[[1.2.3.4,[2.3.4.5,3.4.5.6]],4.3.2.1,[10.10.10.10,[11.11.11.11,12.12.12.12]]]");
+ if (r == 0)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup32(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[[1.2.3.4,[2.3.4.5,[3.4.5.6,4.5.6.7]]],4.3.2.1,[10.10.10.10,[11.11.11.11,[12.12.12.12,13.13.13.13]]]]");
+ if (r == 0)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup33(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "![1.1.1.1,[2.2.2.2,[3.3.3.3,4.4.4.4]]]");
+ if (r == 1)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup34(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[1.0.0.0/8,![1.1.1.1,[1.2.1.1,1.3.1.1]]]");
+ if (r == 1)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup35(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[1.0.0.0/8,[2.0.0.0/8,![1.1.1.1,2.2.2.2]]]");
+ if (r == 1)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup36 (void)
+{
+ int result = 0;
+
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[1.0.0.0/8,[2.0.0.0/8,[3.0.0.0/8,!1.1.1.1]]]");
+ if (r == 1)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup37(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[0.0.0.0/0,::/0]");
+ if (r == 0)
+ result = 1;
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup38(void)
+{
+ UTHValidateDetectAddressHeadRange expectations[3] = {
+ { "0.0.0.0", "192.167.255.255" },
+ { "192.168.14.0", "192.168.14.255" },
+ { "192.169.0.0", "255.255.255.255" } };
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "![192.168.0.0/16,!192.168.14.0/24]");
+ if (r == 1) {
+ if (UTHValidateDetectAddressHead(gh, 3, expectations) == TRUE)
+ result = 1;
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup39(void)
+{
+ UTHValidateDetectAddressHeadRange expectations[3] = {
+ { "0.0.0.0", "192.167.255.255" },
+ { "192.168.14.0", "192.168.14.255" },
+ { "192.169.0.0", "255.255.255.255" } };
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[![192.168.0.0/16,!192.168.14.0/24]]");
+ if (r == 1) {
+ if (UTHValidateDetectAddressHead(gh, 3, expectations) == TRUE)
+ result = 1;
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup40(void)
+{
+ UTHValidateDetectAddressHeadRange expectations[3] = {
+ { "0.0.0.0", "192.167.255.255" },
+ { "192.168.14.0", "192.168.14.255" },
+ { "192.169.0.0", "255.255.255.255" } };
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[![192.168.0.0/16,[!192.168.14.0/24]]]");
+ if (r == 1) {
+ if (UTHValidateDetectAddressHead(gh, 3, expectations) == TRUE)
+ result = 1;
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup41(void)
+{
+ UTHValidateDetectAddressHeadRange expectations[3] = {
+ { "0.0.0.0", "192.167.255.255" },
+ { "192.168.14.0", "192.168.14.255" },
+ { "192.169.0.0", "255.255.255.255" } };
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[![192.168.0.0/16,![192.168.14.0/24]]]");
+ if (r == 1) {
+ if (UTHValidateDetectAddressHead(gh, 3, expectations) == TRUE)
+ result = 1;
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup42(void)
+{
+ UTHValidateDetectAddressHeadRange expectations[1] = {
+ { "2000:0000:0000:0000:0000:0000:0000:0000", "3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" } };
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[2001::/3]");
+ if (r == 0) {
+ if (UTHValidateDetectAddressHead(gh, 1, expectations) == TRUE)
+ result = 1;
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup43(void)
+{
+ UTHValidateDetectAddressHeadRange expectations[2] = {
+ { "2000:0000:0000:0000:0000:0000:0000:0000", "2fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" },
+ { "3800:0000:0000:0000:0000:0000:0000:0000", "3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" } };
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[2001::/3,!3000::/5]");
+ if (r == 1) {
+ if (UTHValidateDetectAddressHead(gh, 2, expectations) == TRUE)
+ result = 1;
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup44(void)
+{
+ UTHValidateDetectAddressHeadRange expectations[2] = {
+ { "3ffe:ffff:7654:feda:1245:ba98:0000:0000", "3ffe:ffff:7654:feda:1245:ba98:ffff:ffff" }};
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "3ffe:ffff:7654:feda:1245:ba98:3210:4562/96");
+ if (r == 0) {
+ if (UTHValidateDetectAddressHead(gh, 1, expectations) == TRUE)
+ result = 1;
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup45(void)
+{
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[192.168.1.3,!192.168.0.0/16]");
+ if (r != 0) {
+ result = 1;
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestAddressGroupSetup46(void)
+{
+ UTHValidateDetectAddressHeadRange expectations[4] = {
+ { "0.0.0.0", "192.167.255.255" },
+ { "192.168.1.0", "192.168.1.255" },
+ { "192.168.3.0", "192.168.3.255" },
+ { "192.169.0.0", "255.255.255.255" } };
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[![192.168.0.0/16,![192.168.1.0/24,192.168.3.0/24]]]");
+ if (r == 1) {
+ if (UTHValidateDetectAddressHead(gh, 4, expectations) == TRUE)
+ result = 1;
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+/** \test net with some negations, then all negated */
+static int AddressTestAddressGroupSetup47(void)
+{
+ UTHValidateDetectAddressHeadRange expectations[5] = {
+ { "0.0.0.0", "192.167.255.255" },
+ { "192.168.1.0", "192.168.1.255" },
+ { "192.168.3.0", "192.168.3.255" },
+ { "192.168.5.0", "192.168.5.255" },
+ { "192.169.0.0", "255.255.255.255" } };
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[![192.168.0.0/16,![192.168.1.0/24,192.168.3.0/24],!192.168.5.0/24]]");
+ if (r == 1) {
+ if (UTHValidateDetectAddressHead(gh, 5, expectations) == TRUE)
+ result = 1;
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+/** \test same as AddressTestAddressGroupSetup47, but not negated */
+static int AddressTestAddressGroupSetup48(void)
+{
+ UTHValidateDetectAddressHeadRange expectations[4] = {
+ { "192.168.0.0", "192.168.0.255" },
+ { "192.168.2.0", "192.168.2.255" },
+ { "192.168.4.0", "192.168.4.255" },
+ { "192.168.6.0", "192.168.255.255" } };
+ int result = 0;
+ DetectAddressHead *gh = DetectAddressHeadInit();
+ if (gh != NULL) {
+ int r = DetectAddressParse(NULL, gh, "[192.168.0.0/16,![192.168.1.0/24,192.168.3.0/24],!192.168.5.0/24]");
+ if (r == 1) {
+ if (UTHValidateDetectAddressHead(gh, 4, expectations) == TRUE)
+ result = 1;
+ }
+
+ DetectAddressHeadFree(gh);
+ }
+ return result;
+}
+
+static int AddressTestCutIPv401(void)
+{
+ DetectAddress *c;
+ DetectAddress *a = DetectAddressParseSingle("1.2.3.0/255.255.255.0");
+ FAIL_IF_NULL(a);
+ DetectAddress *b = DetectAddressParseSingle("1.2.2.0-1.2.3.4");
+ FAIL_IF_NULL(b);
+
+ FAIL_IF(DetectAddressCut(NULL, a, b, &c) == -1);
+
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ PASS;
+}
+
+static int AddressTestCutIPv402(void)
+{
+ DetectAddress *a, *b, *c;
+ a = DetectAddressParseSingle("1.2.3.0/255.255.255.0");
+ b = DetectAddressParseSingle("1.2.2.0-1.2.3.4");
+
+ if (DetectAddressCut(NULL, a, b, &c) == -1)
+ goto error;
+
+ if (c == NULL)
+ goto error;
+
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 1;
+
+error:
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 0;
+}
+
+static int AddressTestCutIPv403(void)
+{
+ DetectAddress *a, *b, *c;
+ a = DetectAddressParseSingle("1.2.3.0/255.255.255.0");
+ b = DetectAddressParseSingle("1.2.2.0-1.2.3.4");
+
+ if (DetectAddressCut(NULL, a, b, &c) == -1)
+ goto error;
+
+ if (c == NULL)
+ goto error;
+
+ if (a->ip.addr_data32[0] != SCNtohl(16908800) || a->ip2.addr_data32[0] != SCNtohl(16909055))
+ goto error;
+ if (b->ip.addr_data32[0] != SCNtohl(16909056) || b->ip2.addr_data32[0] != SCNtohl(16909060))
+ goto error;
+ if (c->ip.addr_data32[0] != SCNtohl(16909061) || c->ip2.addr_data32[0] != SCNtohl(16909311))
+ goto error;
+
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 1;
+
+error:
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 0;
+}
+
+static int AddressTestCutIPv404(void)
+{
+ DetectAddress *a, *b, *c;
+ a = DetectAddressParseSingle("1.2.3.3-1.2.3.6");
+ b = DetectAddressParseSingle("1.2.3.0-1.2.3.5");
+
+ if (DetectAddressCut(NULL, a, b, &c) == -1)
+ goto error;
+
+ if (c == NULL)
+ goto error;
+
+ if (a->ip.addr_data32[0] != SCNtohl(16909056) || a->ip2.addr_data32[0] != SCNtohl(16909058))
+ goto error;
+ if (b->ip.addr_data32[0] != SCNtohl(16909059) || b->ip2.addr_data32[0] != SCNtohl(16909061))
+ goto error;
+ if (c->ip.addr_data32[0] != SCNtohl(16909062) || c->ip2.addr_data32[0] != SCNtohl(16909062))
+ goto error;
+
+
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 1;
+
+error:
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 0;
+}
+
+static int AddressTestCutIPv405(void)
+{
+ DetectAddress *a, *b, *c;
+ a = DetectAddressParseSingle("1.2.3.3-1.2.3.6");
+ b = DetectAddressParseSingle("1.2.3.0-1.2.3.9");
+
+ if (DetectAddressCut(NULL, a, b, &c) == -1)
+ goto error;
+
+ if (c == NULL)
+ goto error;
+
+ if (a->ip.addr_data32[0] != SCNtohl(16909056) || a->ip2.addr_data32[0] != SCNtohl(16909058))
+ goto error;
+ if (b->ip.addr_data32[0] != SCNtohl(16909059) || b->ip2.addr_data32[0] != SCNtohl(16909062))
+ goto error;
+ if (c->ip.addr_data32[0] != SCNtohl(16909063) || c->ip2.addr_data32[0] != SCNtohl(16909065))
+ goto error;
+
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 1;
+
+error:
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 0;
+}
+
+static int AddressTestCutIPv406(void)
+{
+ DetectAddress *a, *b, *c;
+ a = DetectAddressParseSingle("1.2.3.0-1.2.3.9");
+ b = DetectAddressParseSingle("1.2.3.3-1.2.3.6");
+
+ if (DetectAddressCut(NULL, a, b, &c) == -1)
+ goto error;
+
+ if (c == NULL)
+ goto error;
+
+ if (a->ip.addr_data32[0] != SCNtohl(16909056) || a->ip2.addr_data32[0] != SCNtohl(16909058))
+ goto error;
+ if (b->ip.addr_data32[0] != SCNtohl(16909059) || b->ip2.addr_data32[0] != SCNtohl(16909062))
+ goto error;
+ if (c->ip.addr_data32[0] != SCNtohl(16909063) || c->ip2.addr_data32[0] != SCNtohl(16909065))
+ goto error;
+
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 1;
+
+error:
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 0;
+}
+
+static int AddressTestCutIPv407(void)
+{
+ DetectAddress *a, *b, *c;
+ a = DetectAddressParseSingle("1.2.3.0-1.2.3.6");
+ b = DetectAddressParseSingle("1.2.3.0-1.2.3.9");
+
+ if (DetectAddressCut(NULL, a, b, &c) == -1)
+ goto error;
+
+ if (c != NULL)
+ goto error;
+
+ if (a->ip.addr_data32[0] != SCNtohl(16909056) || a->ip2.addr_data32[0] != SCNtohl(16909062))
+ goto error;
+ if (b->ip.addr_data32[0] != SCNtohl(16909063) || b->ip2.addr_data32[0] != SCNtohl(16909065))
+ goto error;
+
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 1;
+
+error:
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 0;
+}
+
+static int AddressTestCutIPv408(void)
+{
+ DetectAddress *a, *b, *c;
+ a = DetectAddressParseSingle("1.2.3.3-1.2.3.9");
+ b = DetectAddressParseSingle("1.2.3.0-1.2.3.9");
+
+ if (DetectAddressCut(NULL, a, b, &c) == -1)
+ goto error;
+
+ if (c != NULL)
+ goto error;
+
+ if (a->ip.addr_data32[0] != SCNtohl(16909056) || a->ip2.addr_data32[0] != SCNtohl(16909058))
+ goto error;
+ if (b->ip.addr_data32[0] != SCNtohl(16909059) || b->ip2.addr_data32[0] != SCNtohl(16909065))
+ goto error;
+
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 1;
+
+error:
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 0;
+}
+
+static int AddressTestCutIPv409(void)
+{
+ DetectAddress *a, *b, *c;
+ a = DetectAddressParseSingle("1.2.3.0-1.2.3.9");
+ b = DetectAddressParseSingle("1.2.3.0-1.2.3.6");
+
+ if (DetectAddressCut(NULL, a, b, &c) == -1)
+ goto error;
+
+ if (c != NULL)
+ goto error;
+
+ if (a->ip.addr_data32[0] != SCNtohl(16909056) || a->ip2.addr_data32[0] != SCNtohl(16909062))
+ goto error;
+ if (b->ip.addr_data32[0] != SCNtohl(16909063) || b->ip2.addr_data32[0] != SCNtohl(16909065))
+ goto error;
+
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 1;
+
+error:
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 0;
+}
+
+static int AddressTestCutIPv410(void)
+{
+ DetectAddress *a, *b, *c;
+ a = DetectAddressParseSingle("1.2.3.0-1.2.3.9");
+ b = DetectAddressParseSingle("1.2.3.3-1.2.3.9");
+
+ if (DetectAddressCut(NULL, a, b, &c) == -1)
+ goto error;
+
+ if (c != NULL)
+ goto error;
+
+ if (a->ip.addr_data32[0] != SCNtohl(16909056) || a->ip2.addr_data32[0] != SCNtohl(16909058))
+ goto error;
+ if (b->ip.addr_data32[0] != SCNtohl(16909059) || b->ip2.addr_data32[0] != SCNtohl(16909065))
+ goto error;
+
+ printf("ip %u ip2 %u ", (uint32_t)htonl(a->ip.addr_data32[0]), (uint32_t)htonl(a->ip2.addr_data32[0]));
+
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 1;
+
+error:
+ DetectAddressFree(a);
+ DetectAddressFree(b);
+ DetectAddressFree(c);
+ return 0;
+}
+
+static int AddressTestParseInvalidMask01(void)
+{
+ int result = 1;
+ DetectAddress *dd = NULL;
+
+ dd = DetectAddressParseSingle("192.168.2.0/33");
+ if (dd != NULL) {
+ DetectAddressFree(dd);
+ result = 0;
+ }
+ return result;
+}
+
+static int AddressTestParseInvalidMask02(void)
+{
+ int result = 1;
+ DetectAddress *dd = NULL;
+
+ dd = DetectAddressParseSingle("192.168.2.0/255.255.257.0");
+ if (dd != NULL) {
+ DetectAddressFree(dd);
+ result = 0;
+ }
+ return result;
+}
+
+static int AddressTestParseInvalidMask03(void)
+{
+ int result = 1;
+ DetectAddress *dd = NULL;
+
+ dd = DetectAddressParseSingle("192.168.2.0/blue");
+ if (dd != NULL) {
+ DetectAddressFree(dd);
+ result = 0;
+ }
+ return result;
+}
+
+static int AddressConfVarsTest01(void)
+{
+ static const char *dummy_conf_string =
+ "%YAML 1.1\n"
+ "---\n"
+ "\n"
+ "vars:\n"
+ "\n"
+ " address-groups:\n"
+ "\n"
+ " HOME_NET: \"any\"\n"
+ "\n"
+ " EXTERNAL_NET: \"!any\"\n"
+ "\n"
+ " port-groups:\n"
+ "\n"
+ " HTTP_PORTS: \"any\"\n"
+ "\n"
+ " SHELLCODE_PORTS: \"!any\"\n"
+ "\n";
+
+ int result = 0;
+
+ ConfCreateContextBackup();
+ ConfInit();
+ ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string));
+
+ if (DetectAddressTestConfVars() < 0 && DetectPortTestConfVars() < 0)
+ result = 1;
+
+ ConfDeInit();
+ ConfRestoreContextBackup();
+
+ return result;
+}
+
+static int AddressConfVarsTest02(void)
+{
+ static const char *dummy_conf_string =
+ "%YAML 1.1\n"
+ "---\n"
+ "\n"
+ "vars:\n"
+ "\n"
+ " address-groups:\n"
+ "\n"
+ " HOME_NET: \"any\"\n"
+ "\n"
+ " EXTERNAL_NET: \"any\"\n"
+ "\n"
+ " port-groups:\n"
+ "\n"
+ " HTTP_PORTS: \"any\"\n"
+ "\n"
+ " SHELLCODE_PORTS: \"!any\"\n"
+ "\n";
+
+ int result = 0;
+
+ ConfCreateContextBackup();
+ ConfInit();
+ ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string));
+
+ if (DetectAddressTestConfVars() == 0 && DetectPortTestConfVars() < 0)
+ result = 1;
+
+ ConfDeInit();
+ ConfRestoreContextBackup();
+
+ return result;
+}
+
+static int AddressConfVarsTest03(void)
+{
+ static const char *dummy_conf_string =
+ "%YAML 1.1\n"
+ "---\n"
+ "\n"
+ "vars:\n"
+ "\n"
+ " address-groups:\n"
+ "\n"
+ " HOME_NET: \"any\"\n"
+ "\n"
+ " EXTERNAL_NET: \"!$HOME_NET\"\n"
+ "\n"
+ " port-groups:\n"
+ "\n"
+ " HTTP_PORTS: \"any\"\n"
+ "\n"
+ " SHELLCODE_PORTS: \"!$HTTP_PORTS\"\n"
+ "\n";
+
+ int result = 0;
+
+ ConfCreateContextBackup();
+ ConfInit();
+ ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string));
+
+ if (DetectAddressTestConfVars() < 0 && DetectPortTestConfVars() < 0)
+ result = 1;
+
+ ConfDeInit();
+ ConfRestoreContextBackup();
+
+ return result;
+}
+
+static int AddressConfVarsTest04(void)
+{
+ static const char *dummy_conf_string =
+ "%YAML 1.1\n"
+ "---\n"
+ "\n"
+ "vars:\n"
+ "\n"
+ " address-groups:\n"
+ "\n"
+ " HOME_NET: \"any\"\n"
+ "\n"
+ " EXTERNAL_NET: \"$HOME_NET\"\n"
+ "\n"
+ " port-groups:\n"
+ "\n"
+ " HTTP_PORTS: \"any\"\n"
+ "\n"
+ " SHELLCODE_PORTS: \"$HTTP_PORTS\"\n"
+ "\n";
+
+ int result = 0;
+
+ ConfCreateContextBackup();
+ ConfInit();
+ ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string));
+
+ if (DetectAddressTestConfVars() == 0 && DetectPortTestConfVars() == 0)
+ result = 1;
+
+ ConfDeInit();
+ ConfRestoreContextBackup();
+
+ return result;
+}
+
+static int AddressConfVarsTest05(void)
+{
+ static const char *dummy_conf_string =
+ "%YAML 1.1\n"
+ "---\n"
+ "\n"
+ "vars:\n"
+ "\n"
+ " address-groups:\n"
+ "\n"
+ " HOME_NET: \"any\"\n"
+ "\n"
+ " EXTERNAL_NET: [192.168.0.1]\n"
+ "\n"
+ " port-groups:\n"
+ "\n"
+ " HTTP_PORTS: \"any\"\n"
+ "\n"
+ " SHELLCODE_PORTS: [80]\n"
+ "\n";
+
+ int result = 0;
+
+ ConfCreateContextBackup();
+ ConfInit();
+ ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string));
+
+ if (DetectAddressTestConfVars() != -1 && DetectPortTestConfVars() != -1)
+ goto end;
+
+ result = 1;
+
+ end:
+ ConfDeInit();
+ ConfRestoreContextBackup();
+
+ return result;
+}
+
+static int AddressConfVarsTest06(void)
+{
+ // HOME_NET value size = 10261 bytes
+ static const char *dummy_conf_string =
+ "%YAML 1.1\n"
+ "---\n"
+ "\n"
+ "vars:\n"
+ "\n"
+ " address-groups:\n"
+ "\n"
+ " HOME_NET: "
+ "\"[2002:0000:3238:DFE1:63:0000:0000:FEFB,2002:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2004:0000:3238:DFE1:63:0000:0000:FEFB,2005:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2006:0000:3238:DFE1:63:0000:0000:FEFB,2007:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB,"
+ "2002:0000:3238:DFE1:63:0000:0000:FEFB,2003:0000:3238:DFE1:63:0000:0000:FEFB]\"\n"
+ "\n"
+ " EXTERNAL_NET: \"any\"\n"
+ "\n";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string));
+
+ FAIL_IF(0 != DetectAddressTestConfVars());
+
+ ConfDeInit();
+ ConfRestoreContextBackup();
+
+ PASS;
+}
+
+#endif /* UNITTESTS */
+
+void DetectAddressTests(void)
+{
+#ifdef UNITTESTS
+ DetectAddressIPv4Tests();
+ DetectAddressIPv6Tests();
+
+ UtRegisterTest("AddressTestParse01", AddressTestParse01);
+ UtRegisterTest("AddressTestParse02", AddressTestParse02);
+ UtRegisterTest("AddressTestParse03", AddressTestParse03);
+ UtRegisterTest("AddressTestParse04", AddressTestParse04);
+ UtRegisterTest("AddressTestParse04bug5081", AddressTestParse04bug5081);
+ UtRegisterTest("AddressTestParse05", AddressTestParse05);
+ UtRegisterTest("AddressTestParse06", AddressTestParse06);
+ UtRegisterTest("AddressTestParse07", AddressTestParse07);
+ UtRegisterTest("AddressTestParse08", AddressTestParse08);
+ UtRegisterTest("AddressTestParse09", AddressTestParse09);
+ UtRegisterTest("AddressTestParse10", AddressTestParse10);
+ UtRegisterTest("AddressTestParse11", AddressTestParse11);
+ UtRegisterTest("AddressTestParse12", AddressTestParse12);
+ UtRegisterTest("AddressTestParse13", AddressTestParse13);
+ UtRegisterTest("AddressTestParse14", AddressTestParse14);
+ UtRegisterTest("AddressTestParse15", AddressTestParse15);
+ UtRegisterTest("AddressTestParse16", AddressTestParse16);
+ UtRegisterTest("AddressTestParse17", AddressTestParse17);
+ UtRegisterTest("AddressTestParse18", AddressTestParse18);
+ UtRegisterTest("AddressTestParse19", AddressTestParse19);
+ UtRegisterTest("AddressTestParse20", AddressTestParse20);
+ UtRegisterTest("AddressTestParse21", AddressTestParse21);
+ UtRegisterTest("AddressTestParse22", AddressTestParse22);
+ UtRegisterTest("AddressTestParse23", AddressTestParse23);
+ UtRegisterTest("AddressTestParse24", AddressTestParse24);
+ UtRegisterTest("AddressTestParse25", AddressTestParse25);
+ UtRegisterTest("AddressTestParse26", AddressTestParse26);
+ UtRegisterTest("AddressTestParse27", AddressTestParse27);
+ UtRegisterTest("AddressTestParse28", AddressTestParse28);
+ UtRegisterTest("AddressTestParse29", AddressTestParse29);
+ UtRegisterTest("AddressTestParse30", AddressTestParse30);
+ UtRegisterTest("AddressTestParse31", AddressTestParse31);
+ UtRegisterTest("AddressTestParse32", AddressTestParse32);
+ UtRegisterTest("AddressTestParse33", AddressTestParse33);
+ UtRegisterTest("AddressTestParse34", AddressTestParse34);
+ UtRegisterTest("AddressTestParse35", AddressTestParse35);
+ UtRegisterTest("AddressTestParse36", AddressTestParse36);
+ UtRegisterTest("AddressTestParse37", AddressTestParse37);
+
+ UtRegisterTest("AddressTestMatch01", AddressTestMatch01);
+ UtRegisterTest("AddressTestMatch02", AddressTestMatch02);
+ UtRegisterTest("AddressTestMatch03", AddressTestMatch03);
+ UtRegisterTest("AddressTestMatch04", AddressTestMatch04);
+ UtRegisterTest("AddressTestMatch05", AddressTestMatch05);
+ UtRegisterTest("AddressTestMatch06", AddressTestMatch06);
+ UtRegisterTest("AddressTestMatch07", AddressTestMatch07);
+ UtRegisterTest("AddressTestMatch08", AddressTestMatch08);
+ UtRegisterTest("AddressTestMatch09", AddressTestMatch09);
+ UtRegisterTest("AddressTestMatch10", AddressTestMatch10);
+ UtRegisterTest("AddressTestMatch11", AddressTestMatch11);
+
+ UtRegisterTest("AddressTestCmp01", AddressTestCmp01);
+ UtRegisterTest("AddressTestCmp02", AddressTestCmp02);
+ UtRegisterTest("AddressTestCmp03", AddressTestCmp03);
+ UtRegisterTest("AddressTestCmp04", AddressTestCmp04);
+ UtRegisterTest("AddressTestCmp05", AddressTestCmp05);
+ UtRegisterTest("AddressTestCmp06", AddressTestCmp06);
+ UtRegisterTest("AddressTestCmpIPv407", AddressTestCmpIPv407);
+ UtRegisterTest("AddressTestCmpIPv408", AddressTestCmpIPv408);
+
+ UtRegisterTest("AddressTestCmp07", AddressTestCmp07);
+ UtRegisterTest("AddressTestCmp08", AddressTestCmp08);
+ UtRegisterTest("AddressTestCmp09", AddressTestCmp09);
+ UtRegisterTest("AddressTestCmp10", AddressTestCmp10);
+ UtRegisterTest("AddressTestCmp11", AddressTestCmp11);
+ UtRegisterTest("AddressTestCmp12", AddressTestCmp12);
+
+ UtRegisterTest("AddressTestAddressGroupSetup01",
+ AddressTestAddressGroupSetup01);
+ UtRegisterTest("AddressTestAddressGroupSetup02",
+ AddressTestAddressGroupSetup02);
+ UtRegisterTest("AddressTestAddressGroupSetup03",
+ AddressTestAddressGroupSetup03);
+ UtRegisterTest("AddressTestAddressGroupSetup04",
+ AddressTestAddressGroupSetup04);
+ UtRegisterTest("AddressTestAddressGroupSetup05",
+ AddressTestAddressGroupSetup05);
+ UtRegisterTest("AddressTestAddressGroupSetup06",
+ AddressTestAddressGroupSetup06);
+ UtRegisterTest("AddressTestAddressGroupSetup07",
+ AddressTestAddressGroupSetup07);
+ UtRegisterTest("AddressTestAddressGroupSetup08",
+ AddressTestAddressGroupSetup08);
+ UtRegisterTest("AddressTestAddressGroupSetup09",
+ AddressTestAddressGroupSetup09);
+ UtRegisterTest("AddressTestAddressGroupSetup10",
+ AddressTestAddressGroupSetup10);
+ UtRegisterTest("AddressTestAddressGroupSetup11",
+ AddressTestAddressGroupSetup11);
+ UtRegisterTest("AddressTestAddressGroupSetup12",
+ AddressTestAddressGroupSetup12);
+ UtRegisterTest("AddressTestAddressGroupSetup13",
+ AddressTestAddressGroupSetup13);
+ UtRegisterTest("AddressTestAddressGroupSetupIPv414",
+ AddressTestAddressGroupSetupIPv414);
+ UtRegisterTest("AddressTestAddressGroupSetupIPv415",
+ AddressTestAddressGroupSetupIPv415);
+ UtRegisterTest("AddressTestAddressGroupSetupIPv416",
+ AddressTestAddressGroupSetupIPv416);
+
+ UtRegisterTest("AddressTestAddressGroupSetup14",
+ AddressTestAddressGroupSetup14);
+ UtRegisterTest("AddressTestAddressGroupSetup15",
+ AddressTestAddressGroupSetup15);
+ UtRegisterTest("AddressTestAddressGroupSetup16",
+ AddressTestAddressGroupSetup16);
+ UtRegisterTest("AddressTestAddressGroupSetup17",
+ AddressTestAddressGroupSetup17);
+ UtRegisterTest("AddressTestAddressGroupSetup18",
+ AddressTestAddressGroupSetup18);
+ UtRegisterTest("AddressTestAddressGroupSetup19",
+ AddressTestAddressGroupSetup19);
+ UtRegisterTest("AddressTestAddressGroupSetup20",
+ AddressTestAddressGroupSetup20);
+ UtRegisterTest("AddressTestAddressGroupSetup21",
+ AddressTestAddressGroupSetup21);
+ UtRegisterTest("AddressTestAddressGroupSetup22",
+ AddressTestAddressGroupSetup22);
+ UtRegisterTest("AddressTestAddressGroupSetup23",
+ AddressTestAddressGroupSetup23);
+ UtRegisterTest("AddressTestAddressGroupSetup24",
+ AddressTestAddressGroupSetup24);
+ UtRegisterTest("AddressTestAddressGroupSetup25",
+ AddressTestAddressGroupSetup25);
+ UtRegisterTest("AddressTestAddressGroupSetup26",
+ AddressTestAddressGroupSetup26);
+
+ UtRegisterTest("AddressTestAddressGroupSetup27",
+ AddressTestAddressGroupSetup27);
+ UtRegisterTest("AddressTestAddressGroupSetup28",
+ AddressTestAddressGroupSetup28);
+ UtRegisterTest("AddressTestAddressGroupSetup29",
+ AddressTestAddressGroupSetup29);
+ UtRegisterTest("AddressTestAddressGroupSetup30",
+ AddressTestAddressGroupSetup30);
+ UtRegisterTest("AddressTestAddressGroupSetup31",
+ AddressTestAddressGroupSetup31);
+ UtRegisterTest("AddressTestAddressGroupSetup32",
+ AddressTestAddressGroupSetup32);
+ UtRegisterTest("AddressTestAddressGroupSetup33",
+ AddressTestAddressGroupSetup33);
+ UtRegisterTest("AddressTestAddressGroupSetup34",
+ AddressTestAddressGroupSetup34);
+ UtRegisterTest("AddressTestAddressGroupSetup35",
+ AddressTestAddressGroupSetup35);
+ UtRegisterTest("AddressTestAddressGroupSetup36",
+ AddressTestAddressGroupSetup36);
+ UtRegisterTest("AddressTestAddressGroupSetup37",
+ AddressTestAddressGroupSetup37);
+ UtRegisterTest("AddressTestAddressGroupSetup38",
+ AddressTestAddressGroupSetup38);
+ UtRegisterTest("AddressTestAddressGroupSetup39",
+ AddressTestAddressGroupSetup39);
+ UtRegisterTest("AddressTestAddressGroupSetup40",
+ AddressTestAddressGroupSetup40);
+ UtRegisterTest("AddressTestAddressGroupSetup41",
+ AddressTestAddressGroupSetup41);
+ UtRegisterTest("AddressTestAddressGroupSetup42",
+ AddressTestAddressGroupSetup42);
+ UtRegisterTest("AddressTestAddressGroupSetup43",
+ AddressTestAddressGroupSetup43);
+ UtRegisterTest("AddressTestAddressGroupSetup44",
+ AddressTestAddressGroupSetup44);
+ UtRegisterTest("AddressTestAddressGroupSetup45",
+ AddressTestAddressGroupSetup45);
+ UtRegisterTest("AddressTestAddressGroupSetup46",
+ AddressTestAddressGroupSetup46);
+ UtRegisterTest("AddressTestAddressGroupSetup47",
+ AddressTestAddressGroupSetup47);
+ UtRegisterTest("AddressTestAddressGroupSetup48",
+ AddressTestAddressGroupSetup48);
+
+ UtRegisterTest("AddressTestCutIPv401", AddressTestCutIPv401);
+ UtRegisterTest("AddressTestCutIPv402", AddressTestCutIPv402);
+ UtRegisterTest("AddressTestCutIPv403", AddressTestCutIPv403);
+ UtRegisterTest("AddressTestCutIPv404", AddressTestCutIPv404);
+ UtRegisterTest("AddressTestCutIPv405", AddressTestCutIPv405);
+ UtRegisterTest("AddressTestCutIPv406", AddressTestCutIPv406);
+ UtRegisterTest("AddressTestCutIPv407", AddressTestCutIPv407);
+ UtRegisterTest("AddressTestCutIPv408", AddressTestCutIPv408);
+ UtRegisterTest("AddressTestCutIPv409", AddressTestCutIPv409);
+ UtRegisterTest("AddressTestCutIPv410", AddressTestCutIPv410);
+
+ UtRegisterTest("AddressTestParseInvalidMask01",
+ AddressTestParseInvalidMask01);
+ UtRegisterTest("AddressTestParseInvalidMask02",
+ AddressTestParseInvalidMask02);
+ UtRegisterTest("AddressTestParseInvalidMask03",
+ AddressTestParseInvalidMask03);
+
+ UtRegisterTest("AddressConfVarsTest01 ", AddressConfVarsTest01);
+ UtRegisterTest("AddressConfVarsTest02 ", AddressConfVarsTest02);
+ UtRegisterTest("AddressConfVarsTest03 ", AddressConfVarsTest03);
+ UtRegisterTest("AddressConfVarsTest04 ", AddressConfVarsTest04);
+ UtRegisterTest("AddressConfVarsTest05 ", AddressConfVarsTest05);
+ UtRegisterTest("AddressConfVarsTest06 ", AddressConfVarsTest06);
+#endif /* UNITTESTS */
+}