1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "range.h"
#include <string.h>
#include <stdlib.h>
#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<<mask)-1)<<(sizeof(mask)*8-mask);
range->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);
};
|