mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
221 lines
6.0 KiB
C
221 lines
6.0 KiB
C
/* Address part of the detection engine.
|
|
*
|
|
* Copyright (c) 2008 Victor Julien
|
|
*/
|
|
|
|
#include "decode.h"
|
|
#include "detect.h"
|
|
#include "flow-var.h"
|
|
|
|
#include "util-cidr.h"
|
|
#include "util-unittest.h"
|
|
|
|
#include "detect-address.h"
|
|
|
|
int AddressCmpIPv4(DetectAddressData *a, DetectAddressData *b) {
|
|
u_int32_t a_ip1 = ntohl(a->ip[0]);
|
|
u_int32_t a_ip2 = ntohl(a->ip2[0]);
|
|
u_int32_t b_ip1 = ntohl(b->ip[0]);
|
|
u_int32_t b_ip2 = ntohl(b->ip2[0]);
|
|
|
|
/* ADDRESS_EQ */
|
|
if (a_ip1 == b_ip1 && a_ip2 == b_ip2) {
|
|
//printf("ADDRESS_EQ\n");
|
|
return ADDRESS_EQ;
|
|
/* ADDRESS_ES */
|
|
} else if (a_ip1 >= b_ip1 && a_ip1 < b_ip2 && a_ip2 <= b_ip2) {
|
|
//printf("ADDRESS_ES\n");
|
|
return ADDRESS_ES;
|
|
/* ADDRESS_EB */
|
|
} else if (a_ip1 <= b_ip1 && a_ip2 >= b_ip2) {
|
|
//printf("ADDRESS_EB\n");
|
|
return ADDRESS_EB;
|
|
} else if (a_ip1 < b_ip1 && a_ip2 < b_ip2 && a_ip2 > b_ip1) {
|
|
//printf("ADDRESS_LE\n");
|
|
return ADDRESS_LE;
|
|
} else if (a_ip1 < b_ip1 && a_ip2 < b_ip2) {
|
|
//printf("ADDRESS_LT\n");
|
|
return ADDRESS_LT;
|
|
} else if (a_ip1 > b_ip1 && a_ip1 < b_ip2 && a_ip2 > b_ip2) {
|
|
//printf("ADDRESS_GE\n");
|
|
return ADDRESS_GE;
|
|
} else if (a_ip1 > b_ip2) {
|
|
//printf("ADDRESS_GT\n");
|
|
return ADDRESS_GT;
|
|
} else {
|
|
/* should be unreachable */
|
|
printf("Internal Error: should be unreachable\n");
|
|
}
|
|
|
|
return ADDRESS_ER;
|
|
}
|
|
|
|
/* a = 1.2.3.4, b = 1.2.3.4-1.2.3.5
|
|
* must result in: a == 1.2.3.4, b == 1.2.3.5, c == NULL
|
|
*
|
|
* a = 1.2.3.4, b = 1.2.3.3-1.2.3.5
|
|
* must result in: a == 1.2.3.3, b == 1.2.3.4, c == 1.2.3.5
|
|
*
|
|
* a = 1.2.3.0/24 b = 1.2.3.128-1.2.4.10
|
|
* must result in: a == 1.2.3.0/24, b == 1.2.4.0-1.2.4.10, c == NULL
|
|
*
|
|
* a = 1.2.3.4, b = 1.2.3.0/24
|
|
* must result in: a == 1.2.3.0-1.2.3.3, b == 1.2.3.4, c == 1.2.3.5-1.2.3.255
|
|
*/
|
|
int AddressCutIPv4(DetectAddressData *a, DetectAddressData *b, DetectAddressData **c) {
|
|
u_int32_t a_ip1 = ntohl(a->ip[0]);
|
|
u_int32_t a_ip2 = ntohl(a->ip2[0]);
|
|
u_int32_t b_ip1 = ntohl(b->ip[0]);
|
|
u_int32_t b_ip2 = ntohl(b->ip2[0]);
|
|
|
|
/* default to NULL */
|
|
*c = NULL;
|
|
|
|
int r = AddressCmpIPv4(a,b);
|
|
if (r != ADDRESS_ES && r != ADDRESS_EB && r != ADDRESS_LE && r != ADDRESS_GE) {
|
|
goto error;
|
|
}
|
|
|
|
/* we have 3 parts: [aaa[abab]bbb]
|
|
* part a: a_ip1 <-> b_ip1 - 1
|
|
* part b: b_ip1 <-> a_ip2
|
|
* part c: a_ip2 + 1 <-> b_ip2
|
|
*/
|
|
if (r == ADDRESS_LE) {
|
|
a->ip[0] = htonl(a_ip1);
|
|
a->ip2[0] = htonl(b_ip1 - 1);
|
|
|
|
b->ip[0] = htonl(b_ip1);
|
|
b->ip2[0] = htonl(a_ip2);
|
|
|
|
DetectAddressData *tmp_c;
|
|
tmp_c = malloc(sizeof(DetectAddressData));
|
|
if (tmp_c == NULL) {
|
|
goto error;
|
|
}
|
|
tmp_c->family = AF_INET;
|
|
tmp_c->ip[0] = htonl(a_ip2 + 1);
|
|
tmp_c->ip2[0] = htonl(b_ip2);
|
|
*c = tmp_c;
|
|
|
|
/* we have 3 parts: [bbb[baba]aaa]
|
|
* part a: b_ip1 <-> a_ip1 - 1
|
|
* part b: a_ip1 <-> b_ip2
|
|
* part c: b_ip2 + 1 <-> a_ip2
|
|
*/
|
|
} else if (r == ADDRESS_GE) {
|
|
a->ip[0] = htonl(b_ip1);
|
|
a->ip2[0] = htonl(a_ip1 - 1);
|
|
|
|
b->ip[0] = htonl(a_ip1);
|
|
b->ip2[0] = htonl(b_ip2);
|
|
|
|
DetectAddressData *tmp_c;
|
|
tmp_c = malloc(sizeof(DetectAddressData));
|
|
if (tmp_c == NULL) {
|
|
goto error;
|
|
}
|
|
tmp_c->family = AF_INET;
|
|
tmp_c->ip[0] = htonl(b_ip2 + 1);
|
|
tmp_c->ip2[0] = htonl(a_ip2);
|
|
*c = tmp_c;
|
|
|
|
/* we have 2 or three parts:
|
|
*
|
|
* 2 part: [[abab]bbb] or [bbb[baba]]
|
|
* part a: a_ip1 <-> a_ip2
|
|
* part b: a_ip2 + 1 <-> b_ip2
|
|
*
|
|
* part a: b_ip1 <-> a_ip1 - 1
|
|
* part b: a_ip1 <-> a_ip2
|
|
*
|
|
* 3 part [bbb[aaa]bbb]
|
|
* part a: b_ip1 <-> a_ip1 - 1
|
|
* part b: a_ip1 <-> a_ip2
|
|
* part c: a_ip2 + 1 <-> b_ip2
|
|
*/
|
|
} else if (r == ADDRESS_ES) {
|
|
if (a_ip1 == b_ip1) {
|
|
a->ip[0] = htonl(a_ip1);
|
|
a->ip2[0] = htonl(a_ip2);
|
|
|
|
b->ip[0] = htonl(a_ip2 + 1);
|
|
b->ip2[0] = htonl(b_ip2);
|
|
} else if (a_ip2 == b_ip2) {
|
|
a->ip[0] = htonl(b_ip1);
|
|
a->ip2[0] = htonl(a_ip1 - 1);
|
|
|
|
b->ip[0] = htonl(a_ip1);
|
|
b->ip2[0] = htonl(a_ip2);
|
|
} else {
|
|
a->ip[0] = htonl(b_ip1);
|
|
a->ip2[0] = htonl(a_ip1 - 1);
|
|
|
|
b->ip[0] = htonl(a_ip1);
|
|
b->ip2[0] = htonl(a_ip2);
|
|
|
|
DetectAddressData *tmp_c;
|
|
tmp_c = malloc(sizeof(DetectAddressData));
|
|
if (tmp_c == NULL) {
|
|
goto error;
|
|
}
|
|
tmp_c->family = AF_INET;
|
|
tmp_c->ip[0] = htonl(a_ip2 + 1);
|
|
tmp_c->ip2[0] = htonl(b_ip2);
|
|
*c = tmp_c;
|
|
}
|
|
/* we have 2 or three parts:
|
|
*
|
|
* 2 part: [[baba]aaa] or [aaa[abab]]
|
|
* part a: b_ip1 <-> b_ip2
|
|
* part b: b_ip2 + 1 <-> a_ip2
|
|
*
|
|
* part a: a_ip1 <-> b_ip1 - 1
|
|
* part b: b_ip1 <-> b_ip2
|
|
*
|
|
* 3 part [aaa[bbb]aaa]
|
|
* part a: a_ip1 <-> b_ip2 - 1
|
|
* part b: b_ip1 <-> b_ip2
|
|
* part c: b_ip2 + 1 <-> a_ip2
|
|
*/
|
|
} else if (r == ADDRESS_EB) {
|
|
if (a_ip1 == b_ip1) {
|
|
a->ip[0] = htonl(b_ip1);
|
|
a->ip2[0] = htonl(b_ip2);
|
|
|
|
b->ip[0] = htonl(b_ip2 + 1);
|
|
b->ip2[0] = htonl(a_ip2);
|
|
} else if (a_ip2 == b_ip2) {
|
|
a->ip[0] = htonl(a_ip1);
|
|
a->ip2[0] = htonl(b_ip1 - 1);
|
|
|
|
b->ip[0] = htonl(b_ip1);
|
|
b->ip2[0] = htonl(b_ip2);
|
|
} else {
|
|
a->ip[0] = htonl(a_ip1);
|
|
a->ip2[0] = htonl(b_ip1 - 1);
|
|
|
|
b->ip[0] = htonl(b_ip1);
|
|
b->ip2[0] = htonl(b_ip2);
|
|
|
|
DetectAddressData *tmp_c;
|
|
tmp_c = malloc(sizeof(DetectAddressData));
|
|
if (tmp_c == NULL) {
|
|
goto error;
|
|
}
|
|
tmp_c->family = AF_INET;
|
|
tmp_c->ip[0] = htonl(b_ip2 + 1);
|
|
tmp_c->ip2[0] = htonl(a_ip2);
|
|
*c = tmp_c;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
|
|
error:
|
|
return -1;
|
|
}
|
|
|
|
|
|
|