分类: 系统运维
2005-05-09 20:50:32
/* (c) Steve Parker 22 July 2004
* Written for NetOps staff to help with cluster planning, networking, etc
*/
#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) ", vversion);
printf ("Usage: netmask [ ip_address ] netmask ");
printf (" IP and Netmask can be seperated by space, '/', or both. ");
printf (" If only a netmask is provided, the leading '/' is required. ");
printf (" Netmask can be provided in any of three formats: ");
printf (" /24 or /255.255.255.0 or /ffffff00 ");
printf ("e.g.: netmask 192.168.1.1/24 ");
printf (" netmask 192.168.1.1 255.255.255.0 ");
printf (" netmask 192.168.1.1 ffffff00 ");
printf (" netmask /24 ");
printf (" netmask /255.255.255.0 ");
printf (" netmask /ffffff00 ");
printf (" ");
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 ");
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 ", 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 ", 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 = ' ';
}
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 ", IP.a, IP.b, IP.c, IP.d);
if (slash != NULL)
printf ("Mask = %03d.%03d.%03d.%03d (%02x%02x%02x%02x) - aka /%d ",
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;
}