Hey everybody,
What would be a good way to determine if a string contains an IP address. Should I use isdigit()?
Suggestions would be appreciate it.
Thanks
Hey everybody,
What would be a good way to determine if a string contains an IP address. Should I use isdigit()?
Suggestions would be appreciate it.
Thanks
I would use this regular expression (courtesy of Regular Expression Examples):
`\b(?:\d{1,3}\.){3}\d{1,3}\b`
I asked a similar question for C++. You should be able to use a slightly modified (for C) version of what I came up with back then.
bool isValidIpAddress(char *ipAddress)
{
struct sockaddr_in sa;
int result = inet_pton(AF_INET, ipAddress, &(sa.sin_addr));
return result != 0;
}
You'll need to #include <arpa/inet.h>
to use the inet_pton() function.
Update based on comments to the question: If you want to know if a C-style string contains an IP address, then you should combine the two answers given so far. Use a regular expression to find patterns that roughly match an IP address, then use the function above to check the match to see if it's the real deal.
I'll give the "don't want two problems" solution:
#include <string.h>
int isIp_v4( char* ip){
int num;
int flag = 1;
int counter=0;
char* p = strtok(ip,".");
while (p && flag ){
num = atoi(p);
if (num>=0 && num<=255 && (counter++<4)){
flag=1;
p=strtok(NULL,".");
}
else{
flag=0;
break;
}
}
return flag && (counter==3);
}
EDIT: strtok may not be thread safe (credits to Adam Rosenfield)
In the url/uri rfc 3986, the Augmented Backus-Naur Form (ABNF) ipv4 address is defined as:
IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
dec-octet = DIGIT ; 0-9
/ %x31-39 DIGIT ; 10-99
/ "1" 2DIGIT ; 100-199
/ "2" %x30-34 DIGIT ; 200-249
/ "25" %x30-35 ; 250-255
I implemented the check with regexp in the following form:
// Although the RFC says ipv6 octects like 001 are not valid, it would be risky
// not to accept those
#define decoct "([01]?[0-9]?[0-9]|2[0-4][0-0]|25[0-5])"
#define ipv4 "(" decoct "\\." decoct "\\." decoct "\\." decoct ")"
This is a routine I wrote a while ago for an embedded system which generated various suspect patterns on a network. As such, it uses absolutely no fancy stuff like network libraries or even the standard C libraries, preferring to steer clear of all that modern stuff like string tokenizing and (shudder) regular expression libraries :-) To that end, it's suited to just about any environment you could find yourself in, and it was blindingly fast.
Although, if you're in an environment that has something like checkIp4Addess()
, I'd suggest you use that instead. It's an indication of the stuff you sometimes have to put up with when doing embedded stuff (although it is a real solution).
int isValidIp4 (char *str) {
int segs = 0; /* Segment count. */
int chcnt = 0; /* Character count within segment. */
int accum = 0; /* Accumulator for segment. */
/* Catch NULL pointer. */
if (str == NULL)
return 0;
/* Process every character in string. */
while (*str != '\0') {
/* Segment changeover. */
if (*str == '.') {
/* Must have some digits in segment. */
if (chcnt == 0)
return 0;
/* Limit number of segments. */
if (++segs == 4)
return 0;
/* Reset segment values and restart loop. */
chcnt = accum = 0;
str++;
continue;
}
/* Check numeric. */
if ((*str < '0') || (*str > '9'))
return 0;
/* Accumulate and check segment. */
if ((accum = accum * 10 + *str - '0') > 255)
return 0;
/* Advance other segment specific stuff and continue loop. */
chcnt++;
str++;
}
/* Check enough segments and enough characters in last segment. */
if (segs != 3)
return 0;
if (chcnt == 0)
return 0;
/* Address okay. */
return 1;
}
This is my try with a very low level C programming ( actually used in one of my programs for a PIC microcontroller). It does not use of string.h library. It does not use pointers, as this compiler I am using does not work well with them, anyway you could use them. Taking this into account and previosly defining a variable to handle the incoming data buffer like this:
#define isdigit(x) isamong(x,"0123456789")
char IPACK_Buff[IPACK_SIZE];
// Check if string is a valid IP
int IPACK_is_valid_ip(int len)
{
int i = 0;
int j = 0;
int NumDots = 0;
char number[4] = "000\0";
// Check first char is numeric
if (!isdigit(IPACK_Buff[0]))
return 0;
for (i = 0 ; i< len; i++)
{
if (isdigit(IPACK_Buff[i]))
{
number[j] = IPACK_Buff[i];
j++;
if (j>3)
return 0;
}
else if (IPACK_Buff[i] == '.')
{
if (atof(number)> 255) return 0;
memset(number, '\0', 4);
j = 0;
NumDots++;
if(NumDots>3)
return 0;
}
}
if (NumDots == 3)
{
return 1;
}
else
return 0;
}//
I hope this function helps you all. Again, take into account the low level this function is programmed before criticize.