IP Only cleanup: make most functions static. Add error message on address parsing issues.

remotes/origin/master-1.2.x
Victor Julien 14 years ago
parent e0cf2ccb91
commit c1a40447c1

@ -65,7 +65,7 @@
*
* \retval IPOnlyCIDRItem address of the new instance
*/
IPOnlyCIDRItem *IPOnlyCIDRItemNew() {
static IPOnlyCIDRItem *IPOnlyCIDRItemNew() {
SCEnter();
IPOnlyCIDRItem *item = NULL;
@ -77,7 +77,7 @@ IPOnlyCIDRItem *IPOnlyCIDRItemNew() {
SCReturnPtr(item, "IPOnlyCIDRItem");
}
uint8_t IPOnlyCIDRItemCompare(IPOnlyCIDRItem *head,
static uint8_t IPOnlyCIDRItemCompare(IPOnlyCIDRItem *head,
IPOnlyCIDRItem *item) {
uint8_t i = 0;
for (; i < head->netmask / 32 || i < 1; i++) {
@ -88,6 +88,232 @@ uint8_t IPOnlyCIDRItemCompare(IPOnlyCIDRItem *head,
return 0;
}
/**
* \internal
* \brief Parses an ipv4/ipv6 address string and updates the result into the
* IPOnlyCIDRItem instance sent as the argument.
*
* \param dd Pointer to the IPOnlyCIDRItem instance which should be updated with
* the address (in cidr) 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 IPOnlyCIDRItemParseSingle(IPOnlyCIDRItem *dd, char *str)
{
char *ipdup = SCStrdup(str);
char *ip = NULL;
char *ip2 = NULL;
char *mask = NULL;
int r = 0;
SCLogDebug("str %s", str);
/* first handle 'any' */
if (strcasecmp(str, "any") == 0) {
/* if any, insert 0.0.0.0/0 and ::/0 as well */
SCLogDebug("adding 0.0.0.0/0 and ::/0 as we\'re handling \'any\'");
IPOnlyCIDRItemParseSingle(dd, "0.0.0.0/0");
BUG_ON(dd->family == 0);
dd->next = IPOnlyCIDRItemNew();
if (dd->next == NULL)
goto error;
IPOnlyCIDRItemParseSingle(dd->next, "::/0");
BUG_ON(dd->family == 0);
SCFree(ipdup);
SCLogDebug("address is \'any\'");
return 0;
}
/* we dup so we can put a nul-termination in it later */
ip = ipdup;
if (ip == NULL) {
goto error;
}
/* handle the negation case */
if (ip[0] == '!') {
dd->negated = (dd->negated)? 0 : 1;
ip++;
}
/* see if the address is an ipv4 or ipv6 address */
if ((strchr(str, ':')) == NULL) {
/* IPv4 Address */
struct in_addr in;
dd->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 netmask = 0;
size_t u = 0;
if ((strchr (mask, '.')) == NULL) {
/* 1.2.3.4/24 format */
for (u = 0; u < strlen(mask); u++) {
if(!isdigit(mask[u]))
goto error;
}
int cidr = atoi(mask);
if (cidr < 0 || cidr > 32)
goto error;
dd->netmask = 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;
/* Extract cidr netmask */
while ((0x01 & netmask) == 0) {
dd->netmask++;
netmask = netmask >> 1;
}
dd->netmask = 32 - dd->netmask;
}
r = inet_pton(AF_INET, ip, &in);
if (r <= 0)
goto error;
dd->ip[0] = in.s_addr;
} else if ((ip2 = strchr(ip, '-')) != NULL) {
/* 1.2.3.4-1.2.3.6 range format */
ip[ip2 - ip] = '\0';
ip2++;
uint32_t tmp_ip[4];
uint32_t tmp_ip2[4];
uint32_t first, last;
r = inet_pton(AF_INET, ip, &in);
if (r <= 0)
goto error;
tmp_ip[0] = in.s_addr;
r = inet_pton(AF_INET, ip2, &in);
if (r <= 0)
goto error;
tmp_ip2[0] = in.s_addr;
/* a > b is illegal, a = b is ok */
if (ntohl(tmp_ip[0]) > ntohl(tmp_ip2[0]))
goto error;
first = ntohl(tmp_ip[0]);
last = ntohl(tmp_ip2[0]);
dd->netmask = 32;
dd->ip[0] =htonl(first);
if (first < last) {
for (first++; first <= last; first++) {
IPOnlyCIDRItem *new = IPOnlyCIDRItemNew();
if (new == NULL)
goto error;
dd->next = new;
new->negated = dd->negated;
new->family= dd->family;
new->netmask = dd->netmask;
new->ip[0] = htonl(first);
dd = dd->next;
}
}
} else {
/* 1.2.3.4 format */
r = inet_pton(AF_INET, ip, &in);
if (r <= 0)
goto error;
/* single host */
dd->ip[0] = in.s_addr;
dd->netmask = 32;
}
} else {
/* IPv6 Address */
struct in6_addr in6;
uint32_t ip6addr[4];
dd->family = AF_INET6;
if ((mask = strchr(ip, '/')) != NULL) {
mask[0] = '\0';
mask++;
r = inet_pton(AF_INET6, ip, &in6);
if (r <= 0)
goto error;
/* Format is cidr val */
dd->netmask = atoi(mask);
memcpy(dd->ip, &in6.s6_addr, sizeof(ip6addr));
} else {
r = inet_pton(AF_INET6, ip, &in6);
if (r <= 0)
goto error;
memcpy(dd->ip, &in6.s6_addr, sizeof(dd->ip));
dd->netmask = 128;
}
}
SCFree(ipdup);
BUG_ON(dd->family == 0);
return 0;
error:
if (ipdup)
SCFree(ipdup);
return -1;
}
/**
* \brief Setup a single address string, parse it and add the resulting
* Address items in cidr format to the list of gh
*
* \param gh Pointer to the IPOnlyCIDRItem list Head 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 IPOnlyCIDRItemSetup(IPOnlyCIDRItem *gh, char *s) {
SCLogDebug("gh %p, s %s", gh, s);
/* parse the address */
if (IPOnlyCIDRItemParseSingle(gh, s) == -1) {
SCLogError(SC_ERR_ADDRESS_ENGINE_GENERIC,
"DetectAddressParse error \"%s\"", s);
goto error;
}
return 0;
error:
return -1;
}
/**
* \brief This function insert a IPOnlyCIDRItem
@ -98,7 +324,7 @@ uint8_t IPOnlyCIDRItemCompare(IPOnlyCIDRItem *head,
*
* \retval IPOnlyCIDRItem address of the new head if apply
*/
IPOnlyCIDRItem *IPOnlyCIDRItemInsertReal(IPOnlyCIDRItem *head,
static IPOnlyCIDRItem *IPOnlyCIDRItemInsertReal(IPOnlyCIDRItem *head,
IPOnlyCIDRItem *item)
{
IPOnlyCIDRItem *it, *prev = NULL;
@ -143,7 +369,7 @@ IPOnlyCIDRItem *IPOnlyCIDRItemInsertReal(IPOnlyCIDRItem *head,
*
* \retval IPOnlyCIDRItem address of the new head if apply
*/
IPOnlyCIDRItem *IPOnlyCIDRItemInsert(IPOnlyCIDRItem *head,
static IPOnlyCIDRItem *IPOnlyCIDRItemInsert(IPOnlyCIDRItem *head,
IPOnlyCIDRItem *item)
{
IPOnlyCIDRItem *it, *prev = NULL;
@ -216,7 +442,7 @@ void IPOnlyCIDRListFree(IPOnlyCIDRItem *tmphead) {
* \param tmphead Pointer to the list
* \param i number of signature internal id
*/
void IPOnlyCIDRListSetSigNum(IPOnlyCIDRItem *tmphead, SigIntId i) {
static void IPOnlyCIDRListSetSigNum(IPOnlyCIDRItem *tmphead, SigIntId i) {
while (tmphead != NULL) {
tmphead->signum = i;
tmphead = tmphead->next;
@ -227,7 +453,7 @@ void IPOnlyCIDRListSetSigNum(IPOnlyCIDRItem *tmphead, SigIntId i) {
* \brief This function print a IPOnlyCIDRItem list
* \param tmphead Pointer to the head of IPOnlyCIDRItems list
*/
void IPOnlyCIDRListPrint(IPOnlyCIDRItem *tmphead) {
static void IPOnlyCIDRListPrint(IPOnlyCIDRItem *tmphead) {
uint32_t i = 0;
while (tmphead != NULL) {
@ -246,7 +472,7 @@ void IPOnlyCIDRListPrint(IPOnlyCIDRItem *tmphead) {
* radix tree print function to help debugging
* \param tmp Pointer to the head of SigNumArray
*/
void SigNumArrayPrint(void *tmp) {
static void SigNumArrayPrint(void *tmp) {
SigNumArray *sna = (SigNumArray *)tmp;
uint32_t u;
@ -273,7 +499,7 @@ void SigNumArrayPrint(void *tmp) {
*
* \retval SigNumArray address of the new instance
*/
SigNumArray *SigNumArrayNew(DetectEngineCtx *de_ctx,
static SigNumArray *SigNumArrayNew(DetectEngineCtx *de_ctx,
DetectEngineIPOnlyCtx *io_ctx)
{
SigNumArray *new = SCMalloc(sizeof(SigNumArray));
@ -305,7 +531,7 @@ SigNumArray *SigNumArrayNew(DetectEngineCtx *de_ctx,
*
* \retval SigNumArray address of the new instance
*/
SigNumArray *SigNumArrayCopy(SigNumArray *orig) {
static SigNumArray *SigNumArrayCopy(SigNumArray *orig) {
SigNumArray *new = SCMalloc(sizeof(SigNumArray));
if (new == NULL) {
@ -329,7 +555,7 @@ SigNumArray *SigNumArrayCopy(SigNumArray *orig) {
* \brief This function free() a SigNumArray
* \param orig Pointer to the original SigNumArray to copy
*/
void SigNumArrayFree(void *tmp) {
static void SigNumArrayFree(void *tmp) {
SigNumArray *sna = (SigNumArray *)tmp;
if (sna == NULL)
@ -351,7 +577,7 @@ void SigNumArrayFree(void *tmp) {
* \retval 0 if success
* \retval -1 if fails
*/
IPOnlyCIDRItem *IPOnlyCIDRListParse2(char *s, int negate)
static IPOnlyCIDRItem *IPOnlyCIDRListParse2(char *s, int negate)
{
size_t x = 0;
size_t u = 0;
@ -521,7 +747,7 @@ error:
* \retval 0 On success.
* \retval -1 On failure.
*/
int IPOnlyCIDRListParse(IPOnlyCIDRItem **gh, char *str)
static int IPOnlyCIDRListParse(IPOnlyCIDRItem **gh, char *str)
{
SCLogDebug("gh %p, str %s", gh, str);
@ -597,234 +823,7 @@ int IPOnlySigParseAddress(Signature *s, const char *addrstr, char flag)
return 0;
error:
return -1;
}
/**
* \internal
* \brief Parses an ipv4/ipv6 address string and updates the result into the
* IPOnlyCIDRItem instance sent as the argument.
*
* \param dd Pointer to the IPOnlyCIDRItem instance which should be updated with
* the address (in cidr) 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.
*/
int IPOnlyCIDRItemParseSingle(IPOnlyCIDRItem *dd, char *str)
{
char *ipdup = SCStrdup(str);
char *ip = NULL;
char *ip2 = NULL;
char *mask = NULL;
int r = 0;
SCLogDebug("str %s", str);
/* first handle 'any' */
if (strcasecmp(str, "any") == 0) {
/* if any, insert 0.0.0.0/0 and ::/0 as well */
SCLogDebug("adding 0.0.0.0/0 and ::/0 as we\'re handling \'any\'");
IPOnlyCIDRItemParseSingle(dd, "0.0.0.0/0");
BUG_ON(dd->family == 0);
dd->next = IPOnlyCIDRItemNew();
if (dd->next == NULL)
goto error;
IPOnlyCIDRItemParseSingle(dd->next, "::/0");
BUG_ON(dd->family == 0);
SCFree(ipdup);
SCLogDebug("address is \'any\'");
return 0;
}
/* we dup so we can put a nul-termination in it later */
ip = ipdup;
if (ip == NULL) {
goto error;
}
/* handle the negation case */
if (ip[0] == '!') {
dd->negated = (dd->negated)? 0 : 1;
ip++;
}
/* see if the address is an ipv4 or ipv6 address */
if ((strchr(str, ':')) == NULL) {
/* IPv4 Address */
struct in_addr in;
dd->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 netmask = 0;
size_t u = 0;
if ((strchr (mask, '.')) == NULL) {
/* 1.2.3.4/24 format */
for (u = 0; u < strlen(mask); u++) {
if(!isdigit(mask[u]))
goto error;
}
int cidr = atoi(mask);
if (cidr < 0 || cidr > 32)
goto error;
dd->netmask = 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;
/* Extract cidr netmask */
while ((0x01 & netmask) == 0) {
dd->netmask++;
netmask = netmask >> 1;
}
dd->netmask = 32 - dd->netmask;
}
r = inet_pton(AF_INET, ip, &in);
if (r <= 0)
goto error;
dd->ip[0] = in.s_addr;
} else if ((ip2 = strchr(ip, '-')) != NULL) {
/* 1.2.3.4-1.2.3.6 range format */
ip[ip2 - ip] = '\0';
ip2++;
uint32_t tmp_ip[4];
uint32_t tmp_ip2[4];
uint32_t first, last;
r = inet_pton(AF_INET, ip, &in);
if (r <= 0)
goto error;
tmp_ip[0] = in.s_addr;
r = inet_pton(AF_INET, ip2, &in);
if (r <= 0)
goto error;
tmp_ip2[0] = in.s_addr;
/* a > b is illegal, a = b is ok */
if (ntohl(tmp_ip[0]) > ntohl(tmp_ip2[0]))
goto error;
first = ntohl(tmp_ip[0]);
last = ntohl(tmp_ip2[0]);
dd->netmask = 32;
dd->ip[0] =htonl(first);
if (first < last) {
for (first++; first <= last; first++) {
IPOnlyCIDRItem *new = IPOnlyCIDRItemNew();
if (new == NULL)
goto error;
dd->next = new;
new->negated = dd->negated;
new->family= dd->family;
new->netmask = dd->netmask;
new->ip[0] = htonl(first);
dd = dd->next;
}
}
} else {
/* 1.2.3.4 format */
r = inet_pton(AF_INET, ip, &in);
if (r <= 0)
goto error;
/* single host */
dd->ip[0] = in.s_addr;
dd->netmask = 32;
}
} else {
/* IPv6 Address */
struct in6_addr in6;
uint32_t ip6addr[4];
dd->family = AF_INET6;
if ((mask = strchr(ip, '/')) != NULL) {
mask[0] = '\0';
mask++;
r = inet_pton(AF_INET6, ip, &in6);
if (r <= 0)
goto error;
/* Format is cidr val */
dd->netmask = atoi(mask);
memcpy(dd->ip, &in6.s6_addr, sizeof(ip6addr));
} else {
r = inet_pton(AF_INET6, ip, &in6);
if (r <= 0)
goto error;
memcpy(dd->ip, &in6.s6_addr, sizeof(dd->ip));
dd->netmask = 128;
}
}
SCFree(ipdup);
BUG_ON(dd->family == 0);
return 0;
error:
if (ipdup)
SCFree(ipdup);
return -1;
}
/**
* \brief Setup a single address string, parse it and add the resulting
* Address items in cidr format to the list of gh
*
* \param gh Pointer to the IPOnlyCIDRItem list Head 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.
*/
int IPOnlyCIDRItemSetup(IPOnlyCIDRItem *gh, char *s) {
SCLogDebug("gh %p, s %s", gh, s);
/* parse the address */
if (IPOnlyCIDRItemParseSingle(gh, s) == -1) {
SCLogError(SC_ERR_ADDRESS_ENGINE_GENERIC,
"DetectAddressParse error \"%s\"", s);
goto error;
}
return 0;
error:
SCLogError(SC_ERR_ADDRESS_ENGINE_GENERIC, "IPOnlyCIDRItemSetup error");
/* XXX cleanup */
SCLogError(SC_ERR_ADDRESS_ENGINE_GENERIC, "failed to parse addresses");
return -1;
}

@ -33,24 +33,10 @@
typedef struct SigNumArray_ {
uint8_t *array; /* bit array of sig nums */
uint32_t size; /* size in bytes of the array */
}SigNumArray;
IPOnlyCIDRItem *IPOnlyCIDRItemNew();
IPOnlyCIDRItem *IPOnlyCIDRItemInsertReal(IPOnlyCIDRItem *head, IPOnlyCIDRItem *item);
IPOnlyCIDRItem *IPOnlyCIDRItemInsert(IPOnlyCIDRItem *head, IPOnlyCIDRItem *item);
} SigNumArray;
void IPOnlyCIDRListFree(IPOnlyCIDRItem *tmphead);
void IPOnlyCIDRListPrint(IPOnlyCIDRItem *tmphead);
IPOnlyCIDRItem *IPOnlyCIDRListParse2(char *s, int negate);
int IPOnlyCIDRListParse(IPOnlyCIDRItem **gh, char *str);
int IPOnlySigParseAddress(Signature *s, const char *addrstr, char flag);
int IPOnlyCIDRItemParseSingle(IPOnlyCIDRItem *dd, char *str);
int IPOnlyCIDRItemSetup(IPOnlyCIDRItem *gh, char *s);
void IPOnlyCIDRListPrint(IPOnlyCIDRItem *);
int IPOnlySigParseAddress(Signature *, const char *, char);
void IPOnlyMatchPacket(ThreadVars *tv, DetectEngineCtx *,
DetectEngineThreadCtx *, DetectEngineIPOnlyCtx *,
DetectEngineIPOnlyThreadCtx *, Packet *);

Loading…
Cancel
Save