/* (c) Steve Parker 22 July 2004 */ #include #include #include char vversion[] = __DATE__ " " __TIME__; struct ip4_addr { unsigned char a, b, c, d; }; struct ip4_addr IP; struct ip4_addr MASK; unsigned char NETMASK; struct ip4_addr dotted_quad_to_ip (char *dottedquad) { struct ip4_addr ip; int a, b, c, d; sscanf (dottedquad, "%d.%d.%d.%d", &a, &b, &c, &d); ip.a = a; ip.b = b; ip.c = c; ip.d = d; return ip; } struct ip4_addr hex_to_ip (char *hex) { struct ip4_addr ip; int a, b, c, d; sscanf (hex, "%02x%02x%02x%02x", &a, &b, &c, &d); ip.a = a; ip.b = b; ip.c = c; ip.d = d; return ip; } void usage () { printf ("Steve's Netmask Calculator (Build : %s)\n", vversion); printf ("Usage: netmask [ ip_address ] netmask\n"); printf (" IP and Netmask can be seperated by space, '/', or both.\n"); printf (" If only a netmask is provided, the leading '/' is required.\n"); printf (" Netmask can be provided in any of three formats:\n"); printf (" /24 or /255.255.255.0 or /ffffff00\n\n"); printf ("e.g.: netmask 192.168.1.1/24\n"); printf (" netmask 192.168.1.1 255.255.255.0\n"); printf (" netmask 192.168.1.1 ffffff00\n"); printf (" netmask /24\n"); printf (" netmask /255.255.255.0\n"); printf (" netmask /ffffff00\n"); printf ("\n"); exit (1); } int ip_to_netmask (struct ip4_addr n) { unsigned char i, m = 0; for (i = 8; i <= 8; i--) { if ((n.a & (1 << i)) != 0) m++; if ((n.b & (1 << i)) != 0) m++; if ((n.c & (1 << i)) != 0) m++; if ((n.d & (1 << i)) != 0) m++; } return m; } struct ip4_addr parse_mask (char *mask) { struct ip4_addr netmask; unsigned char m, n; unsigned char *p; if (strchr (mask, '.') != NULL) { netmask = dotted_quad_to_ip (mask); NETMASK = ip_to_netmask (netmask); } else { NETMASK = atoi (mask); if (NETMASK == 0) { // hex format netmask = hex_to_ip (mask); NETMASK = ip_to_netmask (netmask); } else { // /nn format if (NETMASK > 32) { printf ("ERROR: /nn format must be 1-32\n"); exit (1); } n = NETMASK; netmask.a = netmask.b = netmask.c = netmask.d = 0; p = &netmask.a; if (n > 23) { netmask.a = netmask.b = netmask.c = 255; n -= 24; p = &netmask.d; } if (n > 15) { netmask.a = netmask.b = 255; n -= 16; p = &netmask.c; } if (n > 7) { netmask.a = 255; n -= 8; p = &netmask.b; } for (m = 7; m <= 8; m--) { if (n > 0) { *p += (1 << m); n--; } } } } return netmask; } void get_network () { unsigned char a, b, c, d; a = IP.a & MASK.a; b = IP.b & MASK.b; c = IP.c & MASK.c; d = IP.d & MASK.d; printf ("Network = %03d.%03d.%03d.%03d\n", a, b, c, d); } void get_broadcast () { unsigned char a, b, c, d; a = IP.a | ~MASK.a; b = IP.b | ~MASK.b; c = IP.c | ~MASK.c; d = IP.d | ~MASK.d; printf ("Broadcast = %03d.%03d.%03d.%03d\n", a, b, c, d); } int main (int argc, char *argv[]) { char *slash; char *dot; char *mask; if ((argc != 2) && (argc != 3)) usage (); slash = strchr (argv[1], '/'); dot = strchr (argv[1], '.'); if ((slash == NULL) && (argc == 3)) { slash = argv[2] - sizeof (char); if (strchr (argv[2], '/') != NULL) slash = strchr (argv[2], '/'); } if (dot > slash) dot = NULL; // "dot" implies an IP address, not an x.x.x.x netmask if (slash != NULL) { mask = (char *) slash + sizeof (char); MASK = parse_mask (mask); *slash = '\0'; } if (dot != NULL) { IP = dotted_quad_to_ip (argv[1]); } IP = dotted_quad_to_ip (argv[1]); if (dot != NULL) printf ("IP = %03d.%03d.%03d.%03d\n", IP.a, IP.b, IP.c, IP.d); if (slash != NULL) printf ("Mask = %03d.%03d.%03d.%03d (%02x%02x%02x%02x) - aka /%d\n", MASK.a, MASK.b, MASK.c, MASK.d, MASK.a, MASK.b, MASK.c, MASK.d, NETMASK); if (dot != NULL) { get_network (); get_broadcast (); } return 0; }