IP Range To CIDR Convertor
// Convert a given Ip range to CIDR notation.
# cat rangeToCidr
-
-
-
- http://snippets.dzone.com/tag/cidr
-
-
-
-
-
-
- #include<stdio.h>
- #include<unistd.h>
- #include<string.h>
- #include<math.h>
- #include<errno.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
-
-
-
- #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*/
-
-
- void rangeToCidr(uint32_t from ,uint32_t to,
- void (callback)(char *cidrNotation));
- int ipToBin(uint32_t ip , char * pOut);
-
- void printNotation(char *cidrNotation);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- int ipToBin(uint32_t ip , char * pOut)
- {
- char hex[IP_HEX_LENGTH];
- int i;
- int result=0;
- int len;
- char pTmp[2];
- int tmp;
-
-
-
- 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<len;i++)
- {
-
-
- pTmp[0]=hex[i];
-
- errno = 0;
- tmp = strtol(pTmp, 0x0, 16);
-
-
- if (errno != 0)
- {
- memset(pOut,'0',IP_BINARY_LENGTH -1);
- DEBUG ("strtol failed for hex 0x%s\n",pTmp);
- return -1;
- }
-
- result+=sprintf(pOut+result,"%s",binMap[tmp]);
- }
-
- DEBUG("bits %u printed for ip address for hex len %u\n",result,len);
-
-
- if(result < IP_BINARY_LENGTH-1)
- {
- char pSwap[IP_BINARY_LENGTH];
- strncpy(pSwap,pOut,IP_BINARY_LENGTH);
- memset(pOut,'0',IP_BINARY_LENGTH);
- strncpy(pOut+IP_BINARY_LENGTH-1-result,pSwap,result);
- DEBUG("corrected length to 32\n");
- }
-
- else if (result > IP_BINARY_LENGTH-1)
- return -1;
-
-
- return 0;
- }
-
-
-
-
-
-
-
-
- int main (int argc,char **argv)
- {
- long fromIp, toIp;
- struct in_addr addr;
- if(argc !=3 )
- {
- printf("Usage: %s <from> <to>\n",argv[0]);
- return(0);
- }
-
-
- 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;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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 )
- {
-
-
-
-
-
- while(fromIp[cidrStart]==toIp[cidrStart])
- cidrStart ++;
- cidrStart = 32 - cidrStart -1 ;
- DEBUG("cidrStart is %u\n",cidrStart);
-
-
-
-
-
- newfrom = from >> cidrStart +1 << cidrStart +1 ;
-
-
-
-
- while( fromIp[cidrEnd] == '0' && toIp[cidrEnd] == '1')
- cidrEnd --;
-
- cidrEnd = MAX_CIDR_MASK - 1 - cidrEnd;
- DEBUG("cidrEnd is %u\n",cidrEnd);
-
- if(cidrEnd <= cidrStart)
- {
-
-
-
-
-
- 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);
- }
- }
-
-
-
-
-
-
-
-
- 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";
本日志由 flyinweb 于 2011-01-28 11:06:29 发表到 Linux 中,目前已经被浏览 1521 次,评论 0 次;
作者添加了以下标签: rangeToCidr,range2cidr;
首页只显示了部分日志内容,要查看日志的全部内容请阅读全文;