一、计算子网原理
1.将IP地址与子网掩码按位与,即可计算出子网地址:
<子网地址> = <IP地址> & <子网掩码>
2.将子网掩码按位非,然后在ip地址按位或运算得出广播地址:
<广播地址> = <IP地址> | (~<子网掩码>)
二、具体实现:
#include<stdio.h>
#include<WinSock2.h>
#include<regex>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
//正则表达式校验ip合法性
bool isValidIP(const char *ip){
if(ip == NULL)
return false;
regex pattern("^(?!^255(\.255){3}$)(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])(\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)){2}\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$");
return regex_match(ip,pattern);
}
//校验子网掩码的合法性
bool isValidMask(const char *mask){
if(mask == NULL)
return false;
regex pattern("^((128|192)|2(24|4[08]|5[245]))(\.(0|(128|192)|2((24)|(4[08])|(5[245])))){3}$");
return regex_match(mask,pattern);
}
bool calculateSubnet(const char *ip,const char *mask){
if(ip == NULL || mask == NULL){
return false;
}
printf("ip = %s\n",ip);
if(!isValidIP(ip)){
printf("invalid ip\n");
getchar();
exit(0);
}
printf("mask = %s\n",mask);
if(!isValidMask(mask)){
printf("invalid mask\n");
getchar();
exit(0);
}
unsigned long netaddr = ntohl(inet_addr(ip));
unsigned long netmask = ntohl(inet_addr(mask));
unsigned long first_netaddr = netaddr & netmask;
unsigned long broadcast = netaddr | (~netmask);
long num = broadcast - first_netaddr - 1;
printf("Number of valid ips: %d\n",num);
for(unsigned long i = first_netaddr + 1; i < broadcast ; i++){
sockaddr_in addr;
addr.sin_addr.S_un.S_addr = ntohl(i);
printf("%s\n",inet_ntoa(addr.sin_addr));
}
return true;
}
int main(){
const char *ip = "192.168.0.55";
const char *mask = "255.255.255.0";
//char ip[32] = {0};
//char mask[32] = {0};
//scanf("%s %s",ip,mask);
calculateSubnet(ip,mask);
getchar();
return 0;
}