IP address legality detection and subnet matching in C Language
# Include
# Include
# Ifdef WIN32 # include
# Else # include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Ifdef WIN32 # pragma comment (lib, "wsock32.lib") # endif/* The UINT32 parameter is in the network byte order. * // * Check whether the IP address is valid. If the IP address is valid, true is returned. If the IP address fails, 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 = 0 xffffffff) return FALSE; else return TRUE ;} /* Whether the MASK subnet mask is valid, valid returns true, failure returns FALSE */int netMaskIsValid (_ UINT32 mask) {int I; unsigned long ii; I = netIpIsValid (MASK ); if (I = TRUE) {ii = ntohl (mask); if (ii | II-1) = 0 xffffffff) {return TRUE ;}} Return FALSE;}/* Whether the MASK subnet mask is valid; true is returned; FALSE is returned if a failure occurs */int netMaskAndIpIsValid (_ UINT32 IP, _ UINT32 MASK) {int I; int, 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);/* First compares it with the default subnet 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;}/* The first of each subnet segment is the network address, which is used to mark this network, the last one is the broadcast address, which is used to represent all hosts on the network. these two IP addresses The address is reserved by TCP/IP and cannot be assigned to the host. */c = ~ Ntohl (mask) & ntohl (IP); if (c = 0 | c = ~ Ntohl (mask) return FALSE;/* When RFC 1009 specifies that the subnet is divided, the subnet number cannot be all 0 or 1, this will lead to the ambiguity of IP addresses */if (B> 0) {c = B & (ntohl (IP); if (c = 0 | c = B) return FALSE;} return TRUE;}/* test whether the master network and subnet match, or whether the IP addresses of the two hosts are in the same network segment */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 ;}
Technical implementation and functions:
1. Implemented in C Language
2. Check whether the IP address is valid
3. Determine whether the MASK is valid
4. Check whether the combination of MASK and IP address is legal
Test:
Test environment: win7 VC ++;
Test results:
1. test whether the IP address is valid:
The input IP address is 0xFFFFFFFF, that is, 255.255.255.255. The result is invalid;
The input IP address is 0x00000000, that is, 0.0.0.0. The result is invalid;
The input IP address is 0x00000000 -- 0xFFFFFFFF, which is between 0.0.0.0 -- 255.255.255.255 (except for all 0 and 1). The result is valid.
2. test whether the subnet mask is valid:
Enter 0x00C0FFFF (1111 1111.1111 1111.1100 0000). The result is valid;
Enter an unsigned int number. The binary format is left-side full 1 and right-side full 0. The result is valid, and other forms are invalid.
3. test whether the subnet mask and IP address match:
The input IP address is 0x0000aa8c0, that is, 192.168.10.65 (Class c ip address), and the input subnet mask is 0xC0FFFFFF. The results are matched. The input subnet mask less than 0x00FFFFFF does not match;
The input IP address is 0x0141A885, that is, 133.168.65.1 (Class B IP address), and the input subnet mask is 0x00C0FFFF. The result matches. The input subnet mask less than 0x0000FFFF does not match;
The input IP address is 0x0100413F, that is, 63.65.0.1 (Class a ip address), and the input subnet mask is 0x0000C0FF. The results are matched. If the input is less than 0x000000FF, The subnet mask does not match.
The first and last IP addresses in the subnet segment cannot be allocated. All subnets with subnet numbers 0 or 1 are unavailable, and the results do not match.
4. Test whether two IP addresses are in the same subnet segment:
Enter two IP addresses: 0x0C81C480 0x118FC480, and the input subnet mask is 0x00C0FFFF. The result is that the two IP addresses are in the same network segment;
Enter 0x0C81C480 0x117FC480 and 0x00C0FFFF as the subnet mask.
Note: The test data is of the unsigned int type and the network byte sequence.
Additional knowledge:
Generally, a 32-bit IP address is divided into two parts: the network number and the host number. We call them the "inter-network part" and "local part" of the IP address respectively ". The subnet addressing technology further divides the local part into "physical network" and "host". The "physical network" is used to identify different physical networks under the same IP address, that is, "subnet ".
Class a ip segments 0.0.0.0 to 127.255.255.255
Class B IP segments 128.0.0.0 to 191.255.255.255
C-type IP segments 192.0.0.0 to 223.255.255.255
The default subnet mask allocated by XP is only 255 or 0 for each segment.
Class A default subnet mask 255.0.0.0 A subnet can accommodate up to 16.77 million computers
Default subnet mask of type B 255.255.0.0 a subnet can accommodate a maximum of 60 thousand computers
Class C default subnet mask 255.255.255.0 a subnet can accommodate a maximum of 254 computers
Take Class C address as an example. The first three bytes in the IP address indicate the network number. The last byte indicates both the subnet number and the host number, and whether the two IP addresses belong to one network segment. If they belong to the same network range, the information exchange between the two addresses will not pass through the router. If it is not in the same network range, that is, the subnet number is different, the information exchange between the two addresses will be carried out through the router.
Let's look at an example:
IP address of A: 111000000,101000, 00000000,00000101
Subnet Mask: 11111111,11111111, 11111111,00000000
IP address of B: 11000000,101000, 00000000,00010110
Looking at the above content, the subnet mask has a total of 24 bits on the left, which means that if the first 24 bits of the two IP addresses are the same, the two IP addresses are in the same CIDR block. If the IP addresses A and B marked in red are the same, it means that A and B are in the same CIDR block.
Let's look at another example. If data from address A is sent to address C, IP address C is 192.168.56.21.
IP address of A: 111000000,101000, 00000000,00000101
Subnet Mask: 11111111,11111111, 11111111,00000000
IP address of C: 111000000,101000, 00111000,00010101
According to the subnet mask requirements of A and C above, if the first 24 bits of C and the first 24 bits of A are the same, then A and C are in the same network segment, looking at the address C above, I use blue to mark different digits so that A and C are not in the same CIDR block, the router cannot directly send the data that A wants to send to C through A router, in this way, the router first forwards the data of A to another router (if one router fails, it will continue sending) and then sends it to C.
● Byte sequence Conversion Function
Htons converts the unsigned short type from host to Network
Htonl converts the unsigned long type from the host sequence to the network Sequence
Ntohs converts the unsigned short type from the network sequence to the host Sequence
Ntohl converts the unsigned long type from the network sequence to the host Sequence
These functions are easy to remember. For example, hton in htons represents host to network, and s represents unsigned short.
Char FAR * inet_ntoa (struct in_addr in );
Converts an IP address into a string in the standard dot-point format of the Internet.
In_addr_t inet_addr (const char * cp );
Converts an IP address in dotted-decimal format to a long integer (u_long type ). The returned value is in the byte sequence of the network and can be directly used as an internet address.
The return value of a function is TRUE or FALSE. When only the two return values are returned, if (I = TRUE) or if (I = FALSE) is used instead of if (I) if (! I) programming specifications.
The string returned by inet_ntoa () is temporarily packed in a static allocated buffer. The buffer will be overwritten when this function is called next time.