#include #include #include #include #include #include #include "range.h" #include #include #include "errors.h" #ifndef INADDR_NONE # define INADDR_NONE (in_addr_t)-1 #endif extern int quiet; /* is_ip checks if supplied string is an ip address in dotted-decimal notation, and fills both members of range structure with its numerical value (host byte order)/ Returns 1 on success, 0 on failure */ int is_ip(char* string, struct ip_range* range) { unsigned long addr; addr = inet_addr(string); if(addr != INADDR_NONE) { range->start_ip = ntohl(addr); range->end_ip = ntohl(addr); return 1; } else return 0; }; /* is_range1 checks if supplied string is an IP address range in form xxx.xxx.xxx.xxx/xx (as in 192.168.1.2/24) and fills range structure with start and end ip addresses of the interval. Returns 1 on success, 0 on failure */ int is_range1(char* string, struct ip_range* range) { char* separator; unsigned long mask; char* ip; if((ip = (char *)malloc(strlen(string)+1))==NULL) err_die("Malloc failed", quiet); if (strlen(string)>19) return 0; if(separator=(char*)strchr(string,'/')) { separator++; mask=atoi(separator); if(mask<=0 || mask>32) return 0; strcpy(ip, string); ip[abs(string-separator)-1]=0; if((range->start_ip=inet_addr(ip)) == INADDR_NONE) return 0; /* mask=((1<start_ip=ntohl(range->start_ip); // We store ips in host byte order range->start_ip &= mask; range->end_ip = range->start_ip | ( ~ mask); free(ip); return 1; } free(ip); return 0; }; /* next_address function writes next ip address in range after prev_addr to structure pointed by next_addr. Returns 1 if next ip found and 0 otherwise */ int next_address(const struct ip_range* range, const struct in_addr* prev_addr, struct in_addr* next_addr) { unsigned long pa; // previous address, host byte order if(prev_addr) { pa = ntohl(prev_addr->s_addr); if(pa < range->end_ip) { next_addr->s_addr=htonl(++pa); return 1; } else return 0; } else { next_addr->s_addr=htonl(range->start_ip); return 1; }; }; /* is_range2 checks if supplied string is an IP address range in form xxx.xxx.xxx.xxx-xxx (as in 192.168.1.2-15) and fills range structure with start and end ip addresses of the interval. Returns 1 on success, 0 on failure */ int is_range2(char* string, struct ip_range* range) { unsigned long last_octet; /*last octet of last ip in range*/ char* separator; unsigned long addr; char* ip; if((ip = (char *)malloc(strlen(string)+1))==NULL) err_die("Malloc failed", quiet); strcpy(ip,string); if(separator = (char*)strchr(ip,'-')) { *separator=0; separator++; last_octet = atoi(separator); if(last_octet<0 || last_octet > 255) { free(ip); return 0; }; addr = inet_addr(ip); if(addr == INADDR_NONE) { free(ip); return 0; }; range->start_ip = ntohl(addr); range->end_ip = (range->start_ip & 0xffffff00) | last_octet; if (range->end_ip < range->start_ip) { free(ip); return 0; }; free(ip); return 1; } free(ip); return 0; }; int print_range(const struct ip_range* range) { struct in_addr *addr; if((addr = (struct in_addr*)malloc(sizeof(struct in_addr)))==NULL) err_die("Malloc failed", quiet); next_address(range, 0, addr); printf("%s\n",inet_ntoa(*addr)); while(next_address(range, addr, addr)) { printf("%s\n",inet_ntoa(*addr)); }; free(addr); };