4
\$\begingroup\$

I've written a small helper function that receives a string and checks if it translates to a valid subnet mask value (255.255.255.0 for example).

I would appreciate some peer review!

static bool isValidSubnetMask(IN char *subNetMask)
{
 char *str = NULL;
 char *endptr;
 int counter = 0;
 long int nChainInstance = -1;
 /*Check if string is valid*/
 if (!subNetMask || subNetMask[0] == '0円' || strlen(subNetMask) > 15) {
 return false;
 }
 /*Check string validity*/
 str = strtok(subNetMask, ".");
 while (str != NULL) {
 if (!is_numeric(str)) {
 return false;
 } else {
 /*Save number to be used as entry*/
 nChainInstance = strtol(str, &endptr, 10);
 if (str == endptr) {
 /*Fail to translate string to number*/
 return false;
 }
 if (nChainInstance > 255 || nChainInstance < 0) {
 return false;
 }
 }
 counter++;
 str = strtok(NULL, ".");
 }
 if (counter == 4) {
 return true;
 }
 return false;
}
rolfl
98.1k17 gold badges219 silver badges419 bronze badges
asked Mar 20, 2018 at 14:06
\$\endgroup\$
4
  • 3
    \$\begingroup\$ Your function considers any IPv4 addresses as valid, not just subnet masks. When visualized as 32-bit binary, a valid subnet mask has its n most significant bits set to 1, and all other bits to 0. Your function also accepts "holey" and therefore invalid subnet masks. See the RFC 1878 memo for more details, including a table of all 32 possible subnet masks. \$\endgroup\$ Commented Mar 20, 2018 at 15:25
  • \$\begingroup\$ You'll receive better reviews if you show a complete example. For example, I recommend that you edit to show the necessary #include lines, and a main() that shows how to call your function. It can really help reviewers if they are able to compile and run your program. You seem to be missing definitions for IN and is_numeric(), and possibly others - including them may help you get a more meaningful review. \$\endgroup\$ Commented Mar 20, 2018 at 16:06
  • \$\begingroup\$ Ideally, you would provide a main() that includes your test suite of good and bad netmask strings. \$\endgroup\$ Commented Mar 20, 2018 at 16:08
  • \$\begingroup\$ @wingblade - you are right about "holey". I have a different function checking if the ip is valid or not \$\endgroup\$ Commented Mar 20, 2018 at 18:18

1 Answer 1

2
\$\begingroup\$

Missing includes

#include <stdbool.h>
#include <string.h>

Other test may be needed

@Wingblade

Non-standard function

is_numeric() is not standard C library nor did I find it in Linux.

Questionable signature

I'd expect a function that checks a string's validity to cope with a const char * subNetMask. So using strtok() on the supplied subNetMask is not possible. Code needs to make a copy or otherwise assess the string.

// isValidSubnetMask(IN char *subNetMask)
isValidSubnetMask(IN const char *subNetMask)

Weak functionality

Below are 7 test cases that failed OP's code. Sample working code provided. sscanf() is a bit ponderous, yet useful as a test competitor.

bool is_numeric() { // Added undefined Op's missing function.
 return true;
}
static bool isValidSubnetMask2(const char *subNetMask) {
 int n = 0;
 sscanf(subNetMask, "%*3[0-9].%*3[0-9].%*3[0-9].%*3[0-9]%n", &n);
 if (n == 0 || subNetMask[n]) {
 return false;
 }
 int i[4];
 sscanf(subNetMask, "%d.%d.%d.%d", &i[0], &i[1], &i[2], &i[3]);
 return i[0] <= 255 && i[1] <= 255 && i[2] <= 255 && i[3] <= 255;
}
void test(bool expect, const char *s) {
 char buff[99];
 strcpy(buff, s);
 bool y = isValidSubnetMask(buff);
 if (y != expect) {
 printf("Failed %d <%s>\n", expect, s);
 }
 y = isValidSubnetMask2(s);
 if (y != expect) {
 printf("Oops %d <%s>\n", expect, s);
 }
}
int main() {
 test(1, "255.255.255.0");
 test(1, "255.255.255.123");
 test(1, "0.0.0.0");
 test(0, "455.255.255.0");
 test(0, "255.255.255.-0");
 test(0, "255.255.255. 0");
 test(0, "2.2.5.2.3");
 test(0, "2.2.3");
 test(0, "+2.5.2.3");
 test(0, "A.5.2.3");
 test(0, "2.2.5.2.");
 test(0, "2..2.5.2");
 return 0;
}

Output

Failed 0 <255.255.255.-0>
Failed 0 <255.255.255. 0>
Failed 0 <2.2.5.2.3>
Failed 0 <2.2.3>
Failed 0 <+2.5.2.3>
Failed 0 <2.2.5.2.>
Failed 0 <2..2.5.2>
answered Mar 24, 2018 at 2:06
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.