ipv4: add string validation function

pull/3112/head
Victor Julien 8 years ago
parent aa2eddfb98
commit 13477d60ee

@ -25,7 +25,7 @@
#include "suricata-common.h" #include "suricata-common.h"
#include "util-decode-mime.h" #include "util-decode-mime.h"
#include "util-ip.h"
#include "util-spm-bs.h" #include "util-spm-bs.h"
#include "util-unittest.h" #include "util-unittest.h"
#include "util-memcmp.h" #include "util-memcmp.h"
@ -911,42 +911,12 @@ static int IsIpv4Host(const uint8_t *urlhost, uint32_t len)
char tempIp[MAX_IP4_CHARS + 1]; char tempIp[MAX_IP4_CHARS + 1];
/* Cut off at '/' */ /* Cut off at '/' */
int alen = 0;
char addr[4][4];
int dots = 0;
uint32_t i = 0; uint32_t i = 0;
for (i = 0; i < len && urlhost[i] != 0; i++) { for ( ; i < len && urlhost[i] != 0; i++) {
if (urlhost[i] == '/') { if (urlhost[i] == '/') {
break; break;
} }
if (!(urlhost[i] == '.' || isdigit(urlhost[i]))) {
return 0;
}
if (urlhost[i] == '.') {
if (dots == 3) {
SCLogDebug("too many dots");
return 0;
}
addr[dots][alen] = '\0';
dots++;
alen = 0;
} else {
if (alen >= 4) {
SCLogDebug("too long");
return 0;
}
addr[dots][alen++] = urlhost[i];
}
}
addr[dots][alen] = '\0';
for (int x = 0; x < 4; x++) {
int a = atoi(addr[x]);
if (a < 0 || a >= 256) {
SCLogDebug("out of range");
return 0;
}
} }
/* Too many chars */ /* Too many chars */
@ -958,6 +928,9 @@ static int IsIpv4Host(const uint8_t *urlhost, uint32_t len)
memcpy(tempIp, urlhost, i); memcpy(tempIp, urlhost, i);
tempIp[i] = '\0'; tempIp[i] = '\0';
if (!IPv4AddressStringIsValid(tempIp))
return 0;
return inet_pton(AF_INET, tempIp, &(sa.sin_addr)); return inet_pton(AF_INET, tempIp, &(sa.sin_addr));
} }

@ -27,6 +27,53 @@
#include "suricata-common.h" #include "suricata-common.h"
#include "util-ip.h" #include "util-ip.h"
/** \brief determine if a string is a valid ipv4 address
* \retval bool is addr valid?
*/
bool IPv4AddressStringIsValid(const char *str)
{
int alen = 0;
char addr[4][4];
int dots = 0;
memset(&addr, 0, sizeof(addr));
uint32_t len = strlen(str);
uint32_t i = 0;
for (i = 0; i < len; i++) {
if (!(str[i] == '.' || isdigit(str[i]))) {
return false;
}
if (str[i] == '.') {
if (dots == 3) {
SCLogDebug("too many dots");
return false;
}
addr[dots][alen] = '\0';
dots++;
alen = 0;
} else {
if (alen >= 4) {
SCLogDebug("too long");
return false;
}
addr[dots][alen++] = str[i];
}
}
if (dots != 3)
return false;
addr[dots][alen] = '\0';
for (int x = 0; x < 4; x++) {
int a = atoi(addr[x]);
if (a < 0 || a >= 256) {
SCLogDebug("out of range");
return false;
}
}
return true;
}
/** /**
* \brief Validates an IPV4 address and returns the network endian arranged * \brief Validates an IPV4 address and returns the network endian arranged
* version of the IPV4 address * version of the IPV4 address
@ -43,6 +90,9 @@ struct in_addr *ValidateIPV4Address(const char *addr_str)
{ {
struct in_addr *addr = NULL; struct in_addr *addr = NULL;
if (!IPv4AddressStringIsValid(addr_str))
return NULL;
if ( (addr = SCMalloc(sizeof(struct in_addr))) == NULL) { if ( (addr = SCMalloc(sizeof(struct in_addr))) == NULL) {
SCLogError(SC_ERR_FATAL, "Fatal error encountered in ValidateIPV4Address. Exiting..."); SCLogError(SC_ERR_FATAL, "Fatal error encountered in ValidateIPV4Address. Exiting...");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

@ -25,6 +25,7 @@
#ifndef __UTIL_IP_H__ #ifndef __UTIL_IP_H__
#define __UTIL_IP_H__ #define __UTIL_IP_H__
bool IPv4AddressStringIsValid(const char *str);
struct in_addr *ValidateIPV4Address(const char *); struct in_addr *ValidateIPV4Address(const char *);
struct in6_addr *ValidateIPV6Address(const char *); struct in6_addr *ValidateIPV6Address(const char *);
void MaskIPNetblock(uint8_t *, int, int); void MaskIPNetblock(uint8_t *, int, int);

Loading…
Cancel
Save