#include<stdio.h>//更改IP地址、自动获取IP地址、显示当前连接、显示所有连接对应的MAC地址。
#include<conio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#define NMAX 256
const char CMD[]="NETSH INTERFACE IP SET ADDRESS",*STATUS[]={"断开","活动","备用"};
char mask[16],gateway[16],*name[NMAX],*ip_addr[NMAX],*mac_addr[NMAX],*s;
int n_nic,status[NMAX];//连接状态标志,有断开、活动、备用三种状态,分别用0、1、2表示。
FILE *fp;
char *FindAndSkip(char *start,char *sub)//查找sub子字符串,返回sub子字符串后第一个字符的位置。
{
int len=strlen(sub);
if(start=strstr(start,sub))//如果找得到sub子字符串。
return start+len;
else
return NULL;//如果找不到sub子字符串则返回空指针。
}
char *SkipFilling(char *p)//跳过无意义填充字符。
{
while(*++p=='.'||*p==' '||*p==':');
return p;
}
void GetText(void)//将文本读入内存。
{
long size;
fp=fopen("Temp.txt","rb");
fseek(fp,0,SEEK_END);
size=ftell(fp);
if(!(s=malloc(sizeof(char)*(size+1))))//分配的内存空间比实际文件大小大1,最后1字节用来存放'\0'。
{
fputs("内存不足!程序即将退出……\n",stderr);
system("PAUSE");
exit(-1);
}
rewind(fp);
fread(s,size,1,fp);
fclose(fp);
system("DEL TEMP.TXT");
*(s+size)='\0';
}
void GetDefaultGateway(void)//获取本机路由表中的默认网关。
{
char *p,*end;
system("ROUTE PRINT >TEMP.TXT");
GetText();//获取本机路由表。
(p=FindAndSkip(s,"IPv4 路由表"))||(p=FindAndSkip(s,"Active Routes"));
if(p=FindAndSkip(p," 0.0.0.0 "))
p=FindAndSkip(p," 0.0.0.0 ");
else
{
*gateway=0;
return;
}
while(!isdigit(*++p));
for(end=p+1;isdigit(*end)||*end=='.';end++);
*end='\0';
strcpy(gateway,p);
}
void GetIPConfig(void)//获取IP配置信息。
{
system("IPCONFIG /ALL >TEMP.TXT");
GetText();
}
void GetName(void)//获取连接名称。
{
char *end=s;
n_nic=0;
while(1)//查找连接。
{
char t,*p;
(p=FindAndSkip(end,"网适配器 "))||(p=FindAndSkip(end,"Ethernet adapter "));
if(!p)
return;
if(*p=='{')//以大括号开头的连接通常是代理连接,非真正本地连接。
{
end=p;
continue;
}
if(!(name[n_nic]=malloc(sizeof(char)*63)))
{
fputs("内存不足!程序即将退出……\n",stderr);
system("PAUSE");
exit(-1);
}
end=strchr(p,':');
t=*end;
*end='\0';
strcpy(name[n_nic],p);
*end=t;//恢复现场。
if(++n_nic==NMAX)
{
puts("已达到最大网络适配器数目!");
return;
}
}
}
void GetStatus(void)//获取连接状态。
{
char *end=s;
int i;
for(i=0;i<n_nic;i++)
{
char t,*p;
end=FindAndSkip(end,name[i]);//end表示连接名称结尾。
if(((p=strstr(end,"媒体已断开"))||(p=strstr(end,"Media disconnected")))&&p-end<50)//在Windows 7/Vista/XP操作系统中,在连接名称后面不远处找到了“媒体已断开”字符串。
{
status[i]=0;
continue;
}
(p=FindAndSkip(end,"默认网关"))||(p=FindAndSkip(end,"Default Gateway"));//如果执行到此处,说明此连接没有断开,连接存在网关地址。
p=SkipFilling(p);
while(1)//跳过IPv6地址,找到IPv4地址。
{
char *q=p;
for(end=strchr(p,'\r');q<end&&*q!=':';q++);
if(q==end)
break;
for(p=end+1;isspace(*p);p++);
}
t=*end;
*end='\0';
if(strcmp(p,gateway))
status[i]=2;//与路由表中的默认网关不一致,是备用连接。
else
status[i]=1;//与路由表中的默认网关一致,是活动连接。
*end=t;//恢复现场。
}
}
void GetIPAddr(void)//获取连接对应的IP地址。
{
char *end=s;
int i;
for(i=0;i<n_nic;i++)
{
char t,*p;
if(!(ip_addr[i]=malloc(sizeof(char)*16)))
{
fputs("内存不足!程序即将退出……\n",stderr);
system("PAUSE");
exit(-1);
}
if(!status[i])//如果连接断开。
{
strcpy(ip_addr[i],"无IP地址");
continue;
}
end=FindAndSkip(end,name[i]);//end表示连接名称结尾。
(p=FindAndSkip(end,"IPv4 地址"))||(p=FindAndSkip(end,"IP Address"));
p=SkipFilling(p);
for(end=p+1;isdigit(*end)||*end=='.';end++);
t=*end;
*end='\0';
strcpy(ip_addr[i],p);
*end=t;//恢复现场。
}
}
int GetChoice(void)
{
int n,flag=1,error;
puts("0.取消");
puts("请输入要配置的网络连接的序号:");
do
{
error=0;
if(n_nic<10)
{
n=getche()-'0';
putchar('\n');
}
else
{
if(flag)
puts("您的网络适配器数目超过了9个,输入完毕后请按回车键结束。");
scanf("%d",&n);
error=getc(stdin)!='\n';
flag=0;
}
fflush(stdin);
if(n>n_nic)
{
error=1;
puts("无效选项!请再次输入选项:");
}
}while(error);
return --n;
}
int ChkIPAddr(char *s,unsigned long *ip_addr_val)//检查IP地址格式。正确返回0,错误返回1。
{
char *p,*end;
int n,flag=1,ct=0,len=0;//flag标识是否是IP地址点分十进制的第一段。
for(p=s;*p;p++)
{
if(*p=='.'&&*(p+1)=='.')//不允许连续点号。
return 1;
if(!isdigit(*p)&&*p!='.')//不允许除数字和点号以外的字符出现。
return 1;
ct+=*p=='.';
len++;
}
if(!isdigit(*s)||!isdigit(*--p)||ct!=3||len>15)//首字符、末字符必须是数字,点号有且只有3个,长度在15个字符以内。
return 1;
*ip_addr_val=0;
for(p=s;end=strchr(p,'.');p=end+1)//检查前三段。
{
char t=*end;
*end='\0';
n=atoi(p);
*ip_addr_val=(*ip_addr_val<<8)+n;
*end=t;//恢复现场。
if(!((flag&&n>0||!flag&&n>=0)&&n<255))//第一段范围必须在1~254,中间两段范围必须在0~254。
return 1;
if(flag)
flag=0;
}
n=atoi(p);
*ip_addr_val=(*ip_addr_val<<8)+n;
return n<1||n>254;//检查最后一段,最后一段范围必须在1~254。正确返回0,错误返回1。
}
int ChkMask(char *s,unsigned long *mask_val)//检查子网掩码格式。正确返回0,错误返回1。
{
const int MASK[]={255,254,252,248,240,224,128,0};//子网掩码必须属于集合{255,254,252,248,240,224,128,0}。
char *p,*end;
int pre=255,cur,i,n,flag=1,ct=0,len=0;//cur标识当前段,pre标识当前段的前一段,flag标识是否为第一段。
for(p=s;*p;p++)
{
if(*p=='.'&&*(p+1)=='.')//不允许连续点号。
return 1;
if(!isdigit(*p)&&*p!='.')//不允许除数字和点号以外的字符出现。
return 1;
ct+=*p=='.';
len++;
}
if(!isdigit(*s)||!isdigit(*--p)||ct!=3||len>15)//首字符、末字符必须是数字,点号有且只有3个,长度在15个字符以内。
return 1;
*mask_val=0;
for(p=s;end=strchr(p,'.');p=end+1)//检查前三段。
{
char t=*end;
*end='\0';
cur=n=atoi(p);
*mask_val=(*mask_val<<8)+n;
*end=t;//恢复现场。
if(flag&&!cur)//第一段不得为0。
return 1;
if(flag)
flag=0;
if(!(pre==255&&cur<=pre||pre!=255&&!cur))//如果前一段是255,当前段必须小于等于前一段;如果前一段小于255,当前段必须为0。
return 1;
pre=cur;
for(i=0;i<8&&n!=MASK[i];i++);
if(i==8)//如果当前段不属于集合{255,254,252,248,240,224,128,0}。
return 1;
}
cur=n=atoi(p);
*mask_val=(*mask_val<<8)+n;
if(!(pre==255&&cur<pre||pre!=255&&!cur))//如果最后一段的前一段是255,最后一段必须小于(不等于)前一段;如果最后一段的前一段小于255,最后一段必须为0。
return 1;
for(i=0;i<8&&n!=MASK[i];i++);//检查最后一段是否属于集合{255,254,252,248,240,224,128,0}。
return i==8;
}
int NDigit(int n)//求一个整数是几位数。
{
int i;
for(i=1;n/=10;i++);
return i;
}
int MaxLen(void)//求网络连接名称的最大长度。
{
int i,max=0;
for(i=0;i<n_nic;i++)
{
int len=strlen(name[i]);
if(len>max)
max=len;
}
return max;
}
void GetMACAddr(void)
{
int i;
char *end=s;
for(i=0;i<n_nic;i++)
{
char t,*p;
if(!(mac_addr[i]=malloc(sizeof(char)*18)))
{
fputs("内存不足!程序即将退出……\n",stderr);
system("PAUSE");
exit(-1);
}
end=FindAndSkip(end,name[i]);
(p=FindAndSkip(end,"物理地址"))||(p=FindAndSkip(end,"Physical Address"));
p=SkipFilling(p);
for(end=p+1;isalnum(*end)||*end=='-';end++);
t=*end;
*end='\0';
strcpy(mac_addr[i],p);
*end=t;//恢复现场。
}
}
void AdjustMACAddr(char *s)//将MAC地址的显示格式调整为每两个字节一条横杠。
{
char *p=s;
int flag=0;
while(p=strchr(p,'-'))
{
flag=!flag;
if(flag)
strcpy(p,p+1);
else
p++;
}
}
void Free(void)//释放动态分配的内存。
{
int i;
for(i=0;i<n_nic;i++)
{
free(name[i]);
free(ip_addr[i]);
}
}
void ShowIPAddr(void)
{
int i,n_digit,len;
GetDefaultGateway();
GetIPConfig();
GetName();
评论1