code for validating IPv4 address

Q

qazmlp

What is the best & fastest way of validating an IPv4 address?
Basically, the input can be either in IPAddressv4 or IPAddressv4:port
format.

Currently I have the following code to validate the first format. Does
anybody have any comment on this? Also, please suggest a mechanism to
validate the second format(address:port) also.

Thanks!

-----------------------------
#define INVALID -1
#define VALID 0

int validateIP(char *ipadd)
{
unsigned b1, b2, b3, b4;
unsigned char c;

if (sscanf(ipadd, "%3u.%3u.%3u.%3u%c", &b1, &b2, &b3, &b4, &c) != 4)
return INVALID;

if ((b1 | b2 | b3 | b4) > 255) return INVALID;
if (strspn(ipadd, "0123456789.") < strlen(ipadd)) return INVALID;
return VALID;
}
 
B

Burne C

qazmlp said:
What is the best & fastest way of validating an IPv4 address?
Basically, the input can be either in IPAddressv4 or IPAddressv4:port
format.

Currently I have the following code to validate the first format. Does
anybody have any comment on this? Also, please suggest a mechanism to
validate the second format(address:port) also.

Thanks!

-----------------------------
#define INVALID -1
#define VALID 0

int validateIP(char *ipadd)
{
unsigned b1, b2, b3, b4;

I didn't see this kind of declaration before, you just used "unsigned" in here and no type
specifier. However, I compiled your code with no error in my. Is it legal for using "unsigned" alone
?
 
M

MG

qazmlp said:
What is the best & fastest way of validating an IPv4 address?
Basically, the input can be either in IPAddressv4 or IPAddressv4:port
format.

Currently I have the following code to validate the first format. Does
anybody have any comment on this? Also, please suggest a mechanism to
validate the second format(address:port) also.

Thanks!

-----------------------------
#define INVALID -1
#define VALID 0

int validateIP(char *ipadd)
{
unsigned b1, b2, b3, b4;
unsigned char c;

if (sscanf(ipadd, "%3u.%3u.%3u.%3u%c", &b1, &b2, &b3, &b4, &c) != 4)
return INVALID;

if ((b1 | b2 | b3 | b4) > 255) return INVALID;
if (strspn(ipadd, "0123456789.") < strlen(ipadd)) return INVALID;
return VALID;
}

just an add on..
depending upon the situation, you might require some add on checks of the
reserved IP address...

MG
 
R

Rouben Rostamian

What is the best & fastest way of validating an IPv4 address?
Basically, the input can be either in IPAddressv4 or IPAddressv4:port
format.

Currently I have the following code to validate the first format. Does
anybody have any comment on this? Also, please suggest a mechanism to
validate the second format(address:port) also.

[code snipped]
if ((b1 | b2 | b3 | b4) > 255) return INVALID;


That's not good. Surely you meant:

if (b1 > 255 || b2 > 255 || b3 > 255 || b4 > 255 ) return INVALID;
 
E

Emmanuel Delahaye

Burne C said:
I didn't see this kind of declaration before, you just used "unsigned"
in here and no type specifier. However, I compiled your code with no
error in my. Is it legal for using "unsigned" alone ?

Yes, 'unsigned' a short name for 'unsigned int', like 'long' is a shortname
for 'long int' etc.
 
C

Cael

Rouben Rostamian said:
What is the best & fastest way of validating an IPv4 address?
Basically, the input can be either in IPAddressv4 or IPAddressv4:port
format.

Currently I have the following code to validate the first format. Does
anybody have any comment on this? Also, please suggest a mechanism to
validate the second format(address:port) also.

[code snipped]
if ((b1 | b2 | b3 | b4) > 255) return INVALID;


That's not good. Surely you meant:

if (b1 > 255 || b2 > 255 || b3 > 255 || b4 > 255 ) return INVALID;

I think the statement (b1 | b2 | b3 | b4) > 255 is very effective, the
result of bitwise OR (b1 | b2 | b3 | b4) is bigger than 255 if any of them
is bigger than 255.
 
Q

qazmlp

What is the best & fastest way of validating an IPv4 address?
Basically, the input can be either in IPAddressv4 or IPAddressv4:port
format.

Currently I have the following code to validate the first format. Does
anybody have any comment on this? Also, please suggest a mechanism to
validate the second format(address:port) also.

Thanks!

-----------------------------
#define INVALID -1
#define VALID 0

int validateIP(char *ipadd)
{
unsigned b1, b2, b3, b4;
unsigned char c;

if (sscanf(ipadd, "%3u.%3u.%3u.%3u%c", &b1, &b2, &b3, &b4, &c) != 4)
return INVALID;

if ((b1 | b2 | b3 | b4) > 255) return INVALID;
if (strspn(ipadd, "0123456789.") < strlen(ipadd)) return INVALID;
return VALID;
}

I am expecting your suggestions for validating the 'address:port' format.

Thanks!
 
D

Dan Pop

In said:
What is the best & fastest way of validating an IPv4 address?
Basically, the input can be either in IPAddressv4 or IPAddressv4:port
format.

Currently I have the following code to validate the first format. Does
anybody have any comment on this? Also, please suggest a mechanism to
validate the second format(address:port) also.

#define INVALID -1
#define VALID 0

int validateIP(char *ipadd)
{
unsigned b1, b2, b3, b4;
unsigned char c;

if (sscanf(ipadd, "%3u.%3u.%3u.%3u%c", &b1, &b2, &b3, &b4, &c) != 4)
return INVALID;

if ((b1 | b2 | b3 | b4) > 255) return INVALID;
if (strspn(ipadd, "0123456789.") < strlen(ipadd)) return INVALID;
return VALID;
}

This looks exactly like code I've posted a couple of years ago. The more
paranoid check at the end was added in response to some criticism from
Tak-Shing :)

Extending it for IPAddressv4:port shouldn't be that difficult to anyone
who has understood how the current version works (which, of course,
excludes qazmlp).

#define PORTMAX 65535 /* or whatever appropriate */

int validateIP(char *ipadd)
{
unsigned b1, b2, b3, b4, port = 0;
unsigned char c;
int rc;

rc = sscanf(ipadd, "%3u.%3u.%3u.%3u:%u%c",
&b1, &b2, &b3, &b4, &port, &c);
if (rc != 4 && rc != 5) return INVALID;
if ((b1 | b2 | b3 | b4) > 255 || port > PORTMAX) return INVALID;
if (strspn(ipadd, "0123456789.:") < strlen(ipadd)) return INVALID;
return VALID;
}

Trivia quiz: what is the purpose of the last check?

Dan
 
D

Dan Pop

I didn't see this kind of declaration before, you just used "unsigned" in here and no type
specifier. However, I compiled your code with no error in my. Is it legal for using "unsigned" alone
?

Here's the complete list of C99 type "aliases":

- short, signed short, short int, or signed short int
- unsigned short, or unsigned short int
- int, signed, or signed int
- unsigned, or unsigned int
- long, signed long, long int, or signed long int
- unsigned long, or unsigned long int
- long long, signed long long, long long int, or signed long long int
- unsigned long long, or unsigned long long int

Dan
 
D

Dan Pop

In said:
On 28 Jul 2003 13:49:08 GMT, (e-mail address removed) (Dan Pop) wrote:
[snip]
#define PORTMAX 65535 /* or whatever appropriate */

int validateIP(char *ipadd)
{
unsigned b1, b2, b3, b4, port = 0;
unsigned char sep, c;
int rc;

rc = sscanf(ipadd, "%3u.%3u.%3u.%3u:%u%c",
&b1, &b2, &b3, &b4, &port, &c);
if (rc != 4 && rc != 5) return INVALID;
if ((b1 | b2 | b3 | b4) > 255 || port > PORTMAX) return INVALID;
if (strspn(ipadd, "0123456789.:") < strlen(ipadd)) return INVALID;
return VALID;
}

Trivia quiz: what is the purpose of the last check?

Well, I won't profess to know the purpose of the last check, but it /will/
reject an IP address string of "1.2.3.4=", where the prior tests would not.

The original version, as posted by the OP, would catch "1.2.3.4=" because
scanf would return 5 instead of 4. Yet, the test is still there.

This points out a bug in my version above: "1.2.3.4.5" will not be
identified as an invalid IP address. So, back to the drawing board:

rc = sscanf(ipadd, "%3u.%3u.%3u.%3u%c%u%c",
&b1, &b2, &b3, &b4, &sep, &port, &c);
if (rc != 4 && rc != 6) return INVALID;
if (rc == 6 && sep != ':') return INVALID;
if ((b1 | b2 | b3 | b4) > 255 || port > PORTMAX) return INVALID;
if (strspn(ipadd, "0123456789.:") < strlen(ipadd)) return INVALID;
return VALID;

Why is the last check still there?

Dan
 
J

James Antill

The original version, as posted by the OP, would catch "1.2.3.4=" because
scanf would return 5 instead of 4. Yet, the test is still there.

This points out a bug in my version above: "1.2.3.4.5" will not be
identified as an invalid IP address. So, back to the drawing board:

rc = sscanf(ipadd, "%3u.%3u.%3u.%3u%c%u%c",
&b1, &b2, &b3, &b4, &sep, &port, &c);
if (rc != 4 && rc != 6) return INVALID;
if (rc == 6 && sep != ':') return INVALID;
if ((b1 | b2 | b3 | b4) > 255 || port > PORTMAX) return INVALID;
if (strspn(ipadd, "0123456789.:") < strlen(ipadd)) return INVALID;
return VALID;

Why is the last check still there?

I'll assume because strtoul() doens't do any checking on input, which
makes "-0" valid as an unsidnged number.

You could also argue that because of locale's the above will catch...

0.0.0.0:1,000

....but it won't if the thousands seperator is '.' (which it is in germany
for instance) ... so it doesn't catch that.

The truley strict versions I've seen/written don't use scanf().
 
Q

qazmlp

This looks exactly like code I've posted a couple of years ago. The more
paranoid check at the end was added in response to some criticism from
Tak-Shing :)

Extending it for IPAddressv4:port shouldn't be that difficult to anyone
who has understood how the current version works (which, of course,
excludes qazmlp).

#define PORTMAX 65535 /* or whatever appropriate */

int validateIP(char *ipadd)
{
unsigned b1, b2, b3, b4, port = 0;
unsigned char c;
int rc;

rc = sscanf(ipadd, "%3u.%3u.%3u.%3u:%u%c",
&b1, &b2, &b3, &b4, &port, &c);
if (rc != 4 && rc != 5) return INVALID;
if ((b1 | b2 | b3 | b4) > 255 || port > PORTMAX) return INVALID;
if (strspn(ipadd, "0123456789.:") < strlen(ipadd)) return INVALID;
return VALID;
}
As I mentioned in my original post, the same function should handle
the input which can either be in 'ipaddress' or 'ipaddress:port'. Is
this possible with a single sscanf? Or, should I do like this:
call strchr() to find ':'
If found, call the 2-nd version of validateIP() which handles
ipaddress:port' format.
else, call the 1st version of validateIP() which handles 'ipaddress'
format.
 
D

Dan Pop

In said:
As I mentioned in my original post, the same function should handle
the input which can either be in 'ipaddress' or 'ipaddress:port'. Is
this possible with a single sscanf?

If you were not the idiot you actually are, you'd have noticed that this
is exactly what the code I've posted is supposed to do.

Dan
 
D

Dan Pop

In said:
I'll assume because strtoul() doens't do any checking on input, which
makes "-0" valid as an unsidnged number.

Even simpler, +12 is a valid unsigned number. The other issue is embedded
white space: "+12. 34. 56. 78" would pass all the other tests, yet it
hardly looks like a valid IP address.
You could also argue that because of locale's the above will catch...

The code was meant to be used in the C locale...

Dan
 
D

Default User

Dan Pop wrote:
If you were not the idiot you actually are, you'd have noticed that this
is exactly what the code I've posted is supposed to do.


I still can't figure out if this guy (quasilump or whatever) is an
elaborate troll or the world's slowest-learning programmer. At least in
this thread he actually interacted a bit with the respondents. Usually
he declines to respond to any comments or questions.




Brian Rodenborn
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,059
Latest member
cryptoseoagencies

Latest Threads

Top