标签归档:CIDR

convert a network in CIDR notation

C# code to convert a network in CIDR notation (72.20.10.0/24) to an IP address range

References:

http://stackoverflow.com/questions/218604/whats-the-best-way-to-convert-from-network-bitcount-to-netmask

“Whatmask” C code from http://www.laffeycomputer.com/whatmask.html 继续阅读

IP Range To CIDR Convertor

IP Range To CIDR Convertor

// Convert a given Ip range to CIDR notation.

# cat rangeToCidr
/* rangeToCidr.c - Convert Ip ranges to CIDR */

/*
modification history http://snippets.dzone.com/tag/cidr
--------------------
,17sep08,karn written
*/

/* includes */

#include
#include
#include
#include #include
#include
#include
#include

/* defines */
//#define DBG
#ifdef DBG
#define DEBUG(x) fprintf(stderr,x)
#else
#define DEBUG
#endif /* DBG */

#define IP_BINARY_LENGTH 32+1 /* 32 bits ipv4 address +1 for null */
#define IP_HEX_LENGTH 10
#define MAX_CIDR_MASK 32
#define MAX_CIDR_LEN 18+1 /*255.255.255.255/32*/

/* Forward declaratopms */
void rangeToCidr(uint32_t from ,uint32_t to,
void (callback)(char *cidrNotation));
int ipToBin(uint32_t ip , char * pOut);

void printNotation(char *cidrNotation);

/* Globals */

/*******************************************************************************
*
* ipToBin - convert an ipv4 address to binary representation
* and pads zeros to the beginning of the string if
* the length is not 32
* (Important for ranges like 10.10.0.1 - 20.20.20.20 )
*
* ip - ipv4 address on host order
* pOut - Buffer to store binary.
*
* RETURNS: OK or ERROR
*/

int ipToBin(uint32_t ip , char * pOut)
{
char hex[IP_HEX_LENGTH];
int i;
int result=0;
int len;
char pTmp[2];
int tmp;
/*
* XXX: Could use bit operations instead but was easier to debug
*/
char binMap[16][5] = {
"0000","0001","0010","0011", "0100",
"0101","0110","0111","1000", "1001",
"1010","1011","1100", "1101","1110","1111",
};
pTmp[1]=0x0;
memset(hex,0x0,sizeof(hex));
len=sprintf(hex,"%x",ip);

for(i=0;i IP_BINARY_LENGTH-1)
return -1;

/* Success */
return 0;
}

/*******************************************************************************
* main :
*
* arg1 : Start Ip Address
* arg2 : End Ip address
*/

int main (int argc,char **argv)
{
long fromIp, toIp;
struct in_addr addr;
if(argc !=3 )
{
printf("Usage: %s \n",argv[0]);
return(0);
}

/* All operation on host order */
if (inet_aton(argv[1],&addr) == 0)
goto error;
fromIp = ntohl(addr.s_addr);

if (inet_aton(argv[2],&addr) ==0)
goto error;
toIp = ntohl(addr.s_addr);

rangeToCidr(fromIp,toIp,printNotation);

return 0;
error:
printf("Invalid Argument\n");
return -EINVAL;
}

/*******************************************************************************
*
* rangeToCidr - convert an ip Range to CIDR, and call 'callback' to handle
* the value.
*
* from - IP Range start address
* to - IP Range end address
* callback - Callback function to handle cidr.
* RETURNS: OK or ERROR
*/

void rangeToCidr(uint32_t from ,uint32_t to,
void (callback)(char *cidrNotation))
{
int cidrStart = 0;
int cidrEnd = MAX_CIDR_MASK - 1;
long newfrom;
long mask;
char fromIp[IP_BINARY_LENGTH];
char toIp[IP_BINARY_LENGTH];
struct in_addr addr;
char cidrNotation[MAX_CIDR_LEN];

memset (fromIp,0x0,sizeof(fromIp));
memset (toIp,0x0,sizeof(toIp));

if ( ipToBin(from,fromIp) != 0 )
return;
if ( ipToBin(to,toIp) != 0 )
return;

DEBUG ("from %lu to %lu\n", from,to);
DEBUG("from %s\n",fromIp);
DEBUG("to %s\n",toIp);

if(from < to ) { /* Compare the from and to address ranges to get the first * point of difference */ while(fromIp[cidrStart]==toIp[cidrStart]) cidrStart ++; cidrStart = 32 - cidrStart -1 ; DEBUG("cidrStart is %u\n",cidrStart); /* Starting from the found point of difference make all bits on the * right side zero */ newfrom = from >> cidrStart +1 << cidrStart +1 ; /* Starting from the end iterate reverse direction to find * cidrEnd */ while( fromIp[cidrEnd] == '0' && toIp[cidrEnd] == '1') cidrEnd --; cidrEnd = MAX_CIDR_MASK - 1 - cidrEnd; DEBUG("cidrEnd is %u\n",cidrEnd); if(cidrEnd <= cidrStart) { /* * Make all the bit-shifted bits equal to 1, for * iteration # 1. */ mask = pow (2, cidrStart ) - 1; DEBUG("it1 is %lu \n",newfrom | mask ); rangeToCidr (from , newfrom | mask, callback); DEBUG("it2 is %lu \n",newfrom | 1 << cidrStart); rangeToCidr (newfrom | 1 << cidrStart ,to ,callback); } else { addr.s_addr = htonl(newfrom); sprintf(cidrNotation,"%s/%d", inet_ntoa(addr), MAX_CIDR_MASK-cidrEnd); if (callback != NULL) callback(cidrNotation); } } else { addr.s_addr = htonl(from); sprintf(cidrNotation,"%s/%d",inet_ntoa(addr),MAX_CIDR_MASK); if(callback != NULL) callback(cidrNotation); } } /******************************************************************************* * * printNotation - This is an example callback function to handle cidr notation. * * RETURNS: */ void printNotation(char *cidrNotation) { printf("%s\n",cidrNotation); }
编译:

# gcc rangeToCidr.c -lm -o rang2cidr

Perl版本:

#!/usr/bin/perl -w
# range2cidr.pl

use Net::CIDR;
use Net::CIDR ':all';

if (@ARGV == 0) {
die "Usage Example: $0 192.168.0.0-192.168.255.255 \n";
}

print join("\n", Net::CIDR::range2cidr("$ARGV[0]")) . "\n";

合并CIDR:

#!/usr/bin/perl

use Net::CIDR::Lite;

my $cidr = Net::CIDR::Lite->new;

$cidr->add("202.38.175.0/24");
$cidr->add("202.38.174.0/24");
$cidr->add("202.38.173.0/24");
$cidr->add("202.38.172.0/24");
$cidr->add("202.38.171.0/24");
$cidr->add("202.38.170.0/24");
$cidr->add("202.38.169.0/24");
$cidr->add("202.38.168.0/24");

print "$_\n" for $cidr->list;
// 执行结果:202.38.168.0/21

子网划分

子网划分
Internet组织机构定义了五种IP地址,用于主机的有A、B、C三类地址。其中A类网络有126个,每个A类网络可能有16,777,214台主机,它们处于同一广播域。而在同一广播域中有这么多结点是不可能的,网络会因为广播通信而饱和,结果造成16,777,214个地址大部分没有分配出去,形成了浪费。而另一方面,随着互连网应用的不断扩大,IP地址资源越来越少。为了实现更小的广播域并更好地利用主机地址中的每一位,可以把基于类的IP网络进一步分成更小的网络,每个子网由路由器界定并分配一个新的子网网络地址,子网地址是借用基于类的网络地址的主机部分创建的。划分子网后,通过使用掩码,把子网隐藏起来,使得从外部看网络没有变化,这就是子网掩码。 继续阅读