2

I am trying to validate IP address input in C. Here is my code

char* messType;

regex_t regex;
int regres;
char msgbuf[100];

/* Compile regular expression */
regres = 
    regcomp(&regex, 
            "^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))."
             "([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))."
             "([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))."
             "([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$", 0);

if (regres)
{
    fprintf(stderr, "Could not compile regex\n");
    exit(1);
}
regres = regexec(&regex, servIP, 0, NULL, 0);

if( regres == REG_NOMATCH )
{
    puts("Invalid IP address");
    exit(EXIT_FAILURE);
}
else
{
    regerror(regres, &regex, msgbuf, sizeof(msgbuf));
    fprintf(stderr, "Regex match failed: %s\n", msgbuf);
    exit(1);
}

However, this failed every IPV4 address I entered.

4
  • 1
    Are you sure your input string doesn't have something like a trailing newline etc? Your regex pattern assumes the string has nothing leading or trailing around the IP. Also, you should escape your . since that's a special character in regex. Commented Feb 4, 2014 at 13:57
  • I don't know what format regcomp uses, but the man page says: '|' is used in an extended regular expression to select this subexpression or another, and the other subexpression matched., so maybe you need to give REG_EXTENDED as third parameter of regcomp? Commented Feb 4, 2014 at 14:01
  • 2
    why don't tokenize the string with strtok and check for the values in between instead? Commented Feb 4, 2014 at 14:02
  • What is the question? Commented Feb 4, 2014 at 20:25

3 Answers 3

3

I would say regular expressions are not the best option to validate IP address. As there is a limit on the valid values between the dots it will be hard to express that with regex. The expression will get quite lenghty and one could easily make an error in this.

And even if above argument is not good enough, try to write a regex for IPv6. It gets even worse...

Sign up to request clarification or add additional context in comments.

2 Comments

I agree with you, but this should probably be a comment, not an answer.
@thegrinner I agree there is no answer in my post. However there is no question in the OP's post so I assumed: "how to verify IP address"(looking at the title). Should the OP include an question, I will add an answer.
1

If I were you, I would separate the syntactic and the semantic validation.

Syntactically, in the context of your question, an IP address is a string made of four decimal numbers separated by dots, so a simple regular expression can be used:

([0-9])\.([0-9])\.([0-9])\.([0-9])

Semantically, an IP address is a 32-bit number so each byte can only be in the range [0, 255].
As soon as you can retrieve each captured sub-pattern, just convert each number string to an integer using for example the atoi function and check whether it is effectively in the range.

The semantical analysis is very useful if you need to check for special IP values, like broadcast addresses (255.255.255.255), or private network addresses (10.x.x.x, etc).

Comments

1

I actually figured out what was wrong with this code.

regcomp(&regex, 
        "^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))."
         "([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))."
         "([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))."
         "([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$", REG_EXTENDED);

The cflag is REG_EXTENDED not 0

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.