自己写的一个通过IP地址和子网掩码计算网段内IP的小程序

由本社区发起的开源项目
回复
头像
CMWang
帖子: 261
注册时间: 2009-11-13 14:53

自己写的一个通过IP地址和子网掩码计算网段内IP的小程序

#1

帖子 CMWang » 2009-11-13 15:12

第一次在ubuntu下写程序,也是第一次写这么长的C程序。那个"Argon"的IDE不错。
在命令行下输入程序名可以查看用法。
格式:subnet <IP地址> <子网掩码|子网掩码位数>

源代码如下,哪里写得不好还请高手指点 :em06
要是编译的话需要用 c99-gcc 编译


#include <stdio.h>
#include <string.h>

int main(int argc,char *argv[])
{
void unzip();
void lastIP();
void firstIP();
void BroadcastIP();
void networkIP();
unsigned int Nmask();
unsigned int zip();
int sub();
int testAdd();
int isError();
//*以上是对本程序中一些函数的声明*/


char ip[16]=""; //字符型的IP地址
char mask[16]=""; //字符型的子网掩码
unsigned int zipIP; //压缩的IP地址(方便进行按位计算)
unsigned int zipMask;//压缩的子网掩码
int ipadd[4]; //IP地址的四位整型表示,用于中间步骤
int maskadd[4]; //子网掩码的整型表示

if(argc < 3)
{//如果命令行参数不正确,给出参数提示
printf("格式:%s <IP地址> <子网掩码|子网掩码位数>\n",argv[0]);
exit(1);
}

strcpy(ip,argv[1]); //将函数的命令行参数接收进来。
strcpy(mask,argv[2]);

if(isError(ip,mask) == 1)
{
exit(1);
}

for(int i=0;i<4;i++)
{//将字符型的子网掩码和IP地址转换为整型表示
ipadd=sub(ip,i+1);
maskadd=sub(mask,i+1);
}

/*将子网掩码和IP地址压缩*/
zipMask = zip(maskadd[0],maskadd[1],maskadd[2],maskadd[3]);
zipIP = zip(ipadd[0],ipadd[1],ipadd[2],ipadd[3]);


/*判断命令行的第二个参数是直接输入的子网掩码还是输入的子网掩码位数*/
if(strlen(argv[2]) > 3 )
{

networkIP(zipIP,zipMask);
firstIP(zipIP,zipMask);
lastIP(zipIP,zipMask);
BroadcastIP(zipIP,zipMask);
}
else
{

int mask = atoi(argv[2]);

networkIP(zipIP,Nmask(mask));
firstIP(zipIP,Nmask(mask));
lastIP(zipIP,Nmask(mask));
BroadcastIP(zipIP,Nmask(mask));
}

return 0;
}

int isOne(char mask[16])
{//检测网段内IP地址是否唯一
int sub();

if(
(
sub(mask,1) ==255 &&
sub(mask,2) ==255 &&
sub(mask,3) ==255 &&
sub(mask,4) ==255)||(
sub(mask,1) ==0 &&
sub(mask,2) ==0 &&
sub(mask,3) ==0 &&
sub(mask,4) ==0)
)
{
return 1;
}
return 0;
}

void networkIP(unsigned int ip,unsigned int mask)
{//计算IP地址的网络部分
void unzip();
unsigned int network = ip&mask;

printf("网络地址:\t\t\t");
unzip(network);

}

void BroadcastIP(unsigned int IP,unsigned int mask)
{//计算该网络地广播地址
void unzip();
unsigned int zip();

unsigned int network = IP&mask;
unsigned int Broadcast = ((network)|(~mask));
printf("广播地址:\t\t\t");
unzip(Broadcast);

}

void firstIP(unsigned int IP,unsigned int mask)
{//计算该网段的第一个可用IP地址
void unzip();

unsigned int network = IP&mask;
unsigned int firstIPAdd = network+1;
printf("可用的第一个IP地址:\t\t");
unzip(firstIPAdd);

}

void lastIP(unsigned int IP,unsigned int mask)
{//计算该网段的最后一个可用IP地址
void unzip();

unsigned int network = IP&mask;
unsigned int lastIPAdd = ((network)|(~mask))-1;
printf("可用的最后一个IP地址:\t\t");
unzip(lastIPAdd);

}

unsigned int zip(int a,int b,int c,int d)
{//将四个int类型表示的IP地址压缩进一个int以便进行按位计算
unsigned int re = 0;

re = re|(unsigned int)a;
re = re<<8;

re = re|(unsigned int)b;
re =re<<8;

re = re|(unsigned int)c;
re = re<<8;

re = re|(unsigned int)d;

return re;
}

void unzip(unsigned int zipc)
{//将压缩的ip地址输出

printf("%d.",zipc>>24);
printf("%d.",(zipc<<8)>>24);
printf("%d.",(zipc<<8<<8)>>24);
printf("%d\n",zipc&255);

}

int sub(char ip[16],int n)
{//提取字符型ip地址中指定部分,如sub("202.99.160.68",1)返回202
int daoat[3];

for(int i=0,j=0;i<16;i++)
{
if(ip == '.')
{
daoat[j] = i;
j++;
}
if(j == 3)
{
break;
}

}

char ipPart[4]="";
if(n==1)
{
return atoi(ip);
}
else if(n==2)
{
for(int j=0,i=1+daoat[0];i<daoat[1];i++,j++)
{
ipPart[j] = ip;
}
}
else if(n == 3)
{
for(int j=0,i=1+daoat[1];i<daoat[2];i++,j++)
{
ipPart[j] = ip;
}
}
else
{
for(int j=0,i=1+daoat[2];i<strlen(ip);i++,j++)
{
ipPart[j] = ip;
}
}

return atoi(ipPart);
}

unsigned int Nmask(int n)
{//通过子网掩码的位数计算子网掩码;

unsigned int re = 0;

if(n == 0)
{
return re;
}
if(n == 32)
{
return ~re;
}

re = re|1; //在计算子网掩码的时候是反着走的,因为这样只需要与1进行或运算;
for(int i=1;i<32-n;i++)
{
re = re<<1;
re = re|1;
}

return ~re;
}

int testAdd(char ip[16])
{//测试地址格式

int counP = 0; //用于数地址中有几个'.'

for(int i=0;i<strlen(ip);i++) //开始数点
{
if(ip == '.')
{
counP++;
}
}

if(counP != 3) //如果不是3个点返回0
{
return 0;
}
//如果是3个点那么接下来判断每部分是否都在0和255之间;

else if(sub(ip,1)<0 || sub(ip,1)>255)
{
return 0;
}
else if(sub(ip,2)<0 || sub(ip,2)>255)
{
return 0;
}
else if(sub(ip,3)<0 || sub(ip,3)>255)
{
return 0;
}

else if(sub(ip,4)<0 || sub(ip,4)>255)
{
return 0;
}

return 1;
}

int testMaskC(int maskC)
{//检测子网掩码位过是否合法
if(maskC<=0 || maskC>32)
{
return 0;
}

return 1;
}

int isNum(char add[16])
{//检查IP地址或子网掩码是否全是数字
for(int i=0;i<strlen(add);i++)
{
if(index(" 1234567890.",add) == 0)
{
return 1;
}
}
return 0;
}

int unMask(char IP[16],char mask[16])
{//测试子网掩码是否合理


if(strlen(mask)>2)
{
unsigned int i = zip(sub(mask,1),sub(mask,2),sub(mask,3),sub(mask,4));
i = ~i;
int c;
for(c=1;c<=32;c++)
{
if((i&1) == 0)
break;
i = i>>1;
}

for(c++;c<=32;c++)
{
if((i&1) == 1)
{
return 1; //子网掩码不连续
}
i = i>>1;
}

}
else
{
unsigned int i = zip(sub(IP,1),sub(IP,2),sub(IP,3),sub(IP,4));
i = i>>(32-atoi(mask));
if(i == 0)
{
return 1; //子网掩码位数过少
}
}

return 0;
}

int isError(char ip[16],char mask[16])
{//判断用户输入的参数是否有误,有则给出提示并返回1

if( isNum(ip) == 1 || isNum(mask) ==1)
{
printf("参数中存在非法字符!\n");
return 1;
}

if(strlen(mask)>2)
{

if(testAdd(ip) == 0)
{
printf("IP地址格式错误!\n");
return 1;
}
else if(testAdd(mask) == 0)
{
printf("子网掩码格式错误!\n");
return 1;
}
else if(unMask(ip,mask) ==1)
{
printf("子网掩码不连续!\n");
return 1;
}
else if(isOne(mask) == 1)
{
printf("唯一的IP地址:%s\n",ip);
return 1;
}
}
else
{

if(testAdd(ip) == 0)
{
printf("IP地址格式错误!\n");
return 1;
}
else if(testMaskC(atoi(mask)) == 0)
{
printf("子网掩码大小错误!\n");
return 1;
}
else if(unMask(ip,mask) ==1)
{
printf("子网掩码位数过少!\n");
return 1;
}
else if((atoi(mask) == 32) || (atoi(mask) ==0) )
{
printf("唯一的IP地址:%s\n",ip);
return 1;
}
}

return 0;
}
以上内容全部来自互联网,本人并不识字,完全复制粘贴。

看帖者请于24小时内自觉、主动、完全忘记。

跟帖行为并不意味本人同意、支持、反对,或了解、知晓文中观点,如有任何疑问请直接联系原作者本人。故本人不对以上内容负法律责任(包括民法、刑法或婚姻法,及文中提及或未提及之法律),请勿跨村、跨乡、跨县、跨市、跨省、跨国、跨地球、跨太阳系、跨时空实施抓捕。

谢谢合作!
头像
CMWang
帖子: 261
注册时间: 2009-11-13 14:53

Re: 自己写的一个通过IP地址和子网掩码计算网段内IP的小程序

#2

帖子 CMWang » 2009-11-13 15:25

更正下 我用的C语言IDE是"Geany"强烈推荐
以上内容全部来自互联网,本人并不识字,完全复制粘贴。

看帖者请于24小时内自觉、主动、完全忘记。

跟帖行为并不意味本人同意、支持、反对,或了解、知晓文中观点,如有任何疑问请直接联系原作者本人。故本人不对以上内容负法律责任(包括民法、刑法或婚姻法,及文中提及或未提及之法律),请勿跨村、跨乡、跨县、跨市、跨省、跨国、跨地球、跨太阳系、跨时空实施抓捕。

谢谢合作!
头像
wlzyan
帖子: 504
注册时间: 2008-08-16 15:09
来自: 没有海一样的胸怀,哪能有海一样的事业.

Re: 自己写的一个通过IP地址和子网掩码计算网段内IP的小程序

#3

帖子 wlzyan » 2009-11-13 16:03

真的好长~
头像
jxhow
帖子: 5859
注册时间: 2008-10-24 22:02
来自: 浙江

Re: 自己写的一个通过IP地址和子网掩码计算网段内IP的小程序

#4

帖子 jxhow » 2009-11-13 16:15

纯支持了
http://sb.google.com/ 提问前 请在右上角搜索一下
头像
Stupid kid
帖子: 416
注册时间: 2006-10-18 12:57

Re: 自己写的一个通过IP地址和子网掩码计算网段内IP的小程序

#5

帖子 Stupid kid » 2009-11-22 14:04

缩到15行大家就使劲顶了 :em04
http://twitter.com/nothining
Mail: bjdfzster@gmail.com
南京的开源活动几乎是0,希望能有人组织下(也可以拉我入伙^_^)
最近在从零开始学习Linux程序设计,加油……
回复