比较简单的测试程序实现
判断一个输入的字符串是否为合法的IP地址
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
bool ip_vaild_check(const char *ip)
{
int dots = 0; /*字符.的个数*/
int setions = 0; /*ip每一部分总和(0-255)*/
if (NULL == ip || *ip == '.') { /*排除输入参数为NULL, 或者一个字符为'.'的字符串*/
return false;
}
while (*ip) {
if (*ip == '.') {
dots ++;
if (setions >= 0 && setions <= 255) { /*检查ip是否合法*/
setions = 0;
ip++;
continue;
}
return false;
}
else if (*ip >= '0' && *ip <= '9') { /*判断是不是数字*/
setions = setions * 10 + (*ip - '0'); /*求每一段总和*/
} else
return false;
ip++;
}
//判断IP最后一段是否合法
if (setions >= 0 && setions <= 255) {
if (dots == 3) {
return true;
}
}
return false;
}
void help()
{
printf("Usage: ./test <ip str>\n");
exit(0);
}
int main(int argc, char **argv)
{
if (argc != 2) {
help();
}
if (ip_vaild_check(argv[1])) {
printf("Is Vaild Ip-->[%s]\n", argv[1]);
} else {
printf("Is Invalid Ip-->[%s]\n", argv[1]);
}
return 0;
}
编译执行
gcc ipvailed.c
$ ./a.out
Usage: ./test <ip str>
$ ./a.out 152.256
Is Invalid Ip-->[152.256]
$ ./a.out 192.168.1.10
Is Vaild Ip-->[192.168.1.10]
使用库函数来进行判断
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <winsock2.h>
#else
#include <fcntl.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include
#include <sys/select.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>
#include <sys/un.h>
#include <linux/types.h>
#include <linux/netlink.h>
#include <linux/if.h>
#include <linux/sockios.h>
#include <linuxethtool.h>
#ifdef WIN32
#pragma comment(lib,"wsock32.lib")
#endif
/*参数UINT32都为网络字节顺序。*/
/*IP地址是否合法, 合法返回TURE,失败返回FALSE*/
int netIpIsValid(_UINT32 IP)
{
int i;
struct in_addr addr;
addr.s_addr = IP;
i = inet_addr(inet_ntoa(addr));
if((i == 0)||(i == 0xffffffff))
return FALSE;
else
return TRUE;
}
/*MASK子网掩码是否合法, 合法返回TURE,失败返回FALSE*/
int netMaskIsValid(_UINT32 mask)
{
int i;
unsigned long ii;
i = netIpIsValid(mask);
if(i==TRUE)
{
ii = ntohl(mask);
if((ii|ii-1)==0xffffffff)
{
return TRUE;
}
}
return FALSE;
}
/*MASK子网掩码是否合法, 合法返回TURE,失败返回FALSE*/
int netMaskAndIpIsValid(_UINT32 IP, _UINT32 mask)
{
int i;
int a, b=0, c;
i = netIpIsValid(IP);
if(i!=TRUE)
return FALSE;
i = netMaskIsValid(mask);
if(i!=TRUE)
return FALSE;
a = IP&0x000000ff;
b = ntohl(mask);
/*首先与默认子网掩码比较*/
if(a>0&&a<127)
{
if(mask<0x000000ff)
return FALSE;
if(mask>0x000000ff)
b-=0xff000000;
}
if(a>=128&&a<=191)
{
if(mask<0x0000ffff)
return FALSE;
if(mask>0x0000ffff)
b-=0xffff0000;
}
if(a>=192&&a<=223)
{
if(mask<0x00ffffff)
return FALSE;
if(mask>0x00ffffff)
b-=0xffffff00;
}
/*每个子网段的第一个是网络地址,用来标志这个网络,
最后一个是广播地址,用来代表这个网络上的所有主机.
这两个IP地址被TCP/IP保留,不可分配给主机使用.*/
c = ~ntohl(mask)&ntohl(IP);
if(c==0||c==~ntohl(mask))
return FALSE;
/*RFC 1009中规定划分子网时,子网号不能全为0或1,会导致IP地址的二义性*/
if(b>0)
{
c = b&(ntohl(IP));
if(c==0||c==b)
return FALSE;
}
return TRUE;
}
/*测试主网和子网是否匹配,也可测试两个主机IP是否在同一网段内*/
int netIPAndSubnetValid(_UINT32 IP, _UINT32 subIP, _UINT32 mask)
{
int i;
int addr1, addr2;
i = netMaskAndIpIsValid(IP, mask);
if(i!=TRUE)
return FALSE;
i = netMaskAndIpIsValid(subIP, mask);
if(i!=TRUE)
return FALSE;
addr1 = IP&mask;
addr2 = subIP&mask;
if(addr1!=addr2)
return FALSE;
return TRUE;
}