#include #include #include #define NALLOC 8 typedef struct { int *lo; /* List of lower range limits */ int *hi; /* List of upper range limits */ int *code; /* Int label for each range */ int n; /* Number of ranges */ int nalloc; /* Maximum number of ranges for current memory allocation */ int nallocint; /* Number of ranges to allocate when increasing storage */ } ip_range_t; /* Test routine to dump ip range */ void dump_range (ip_range_t *ipr) { int i; if (ipr==NULL) return; for (i=0;in;i++) { printf ("lo (0x%x) hi (0x%x) code (%d)\n", ipr->lo[i], ipr->hi[i], ipr->code[i]); } } /* Convert strings like "138.99.201.5" or "137.99.26" to int ipaddress */ void str2ip (char *ipstr, int *ipout, int *mask) { int ip[4]; int n = sscanf (ipstr, "%d.%d.%d.%d", ip, ip+1, ip+2, ip+3); int i; *ipout = 0; for (i=0;i<4;i++) { *ipout = *ipout<<8; if (i> (8*n); /* for reasons unknown 0xffffffff >> 32 -> -1, so set to 0 */ if (*mask==-1) *mask=0; } /* Allocate memory for iprange structure */ ip_range_t *alloc_iprange (int nallocint) { ip_range_t *ip = (ip_range_t *) malloc (sizeof(ip_range_t)); ip->lo = (int *) calloc(nallocint, sizeof(ip->lo [0])); ip->hi = (int *) calloc(nallocint, sizeof(ip->hi [0])); ip->code = (int *) calloc(nallocint, sizeof(ip->code[0])); ip->n = 0; ip->nalloc = nallocint; ip->nallocint = nallocint; return ip; } /* Add a single range to iprange structure */ void add_iprange (ip_range_t **iprange, int code, int lo, int hi) { ip_range_t *ip = *iprange; if (ip==NULL) ip = alloc_iprange(NALLOC); if (ip->n==ip->nalloc) { ip->nalloc += ip->nallocint; ip->lo = (int *) realloc (ip->lo, ip->nalloc*sizeof(ip->lo[0])); ip->hi = (int *) realloc (ip->hi, ip->nalloc*sizeof(ip->hi[0])); ip->code = (int *) realloc (ip->code, ip->nalloc*sizeof(ip->code[0])); } ip->lo[ip->n] = lo; ip->hi[ip->n] = hi; ip->code[ip->n] = code; ip->n++; *iprange = ip; } /* Store ip range in *arg_in into structure *ip associated with * Manages storage for ip (initial allocation and re-allocation) */ void process_iprange (ip_range_t **iprange, int code, char *arg_in) { char *arg_cpy = strdup(arg_in); char *ipstr = strdup(arg_in); char *netstr = strdup(arg_in); char *range1, *range2; int ip1, ip2, mask, net; range2 = arg_cpy; /* break strings into separate ranges */ while (NULL!=range2) { /* Break are into (1st range):(remaining ranges) */ range1 = range2; range2 = strpbrk(range1, ": "); if (NULL!=range2) *range2++ = '\0'; /* Look for range expressed as (lo ip)-(hi ip) */ if (2==sscanf (range1, "%[0-9.]-%[0-9.]", ipstr, netstr)) { str2ip(ipstr, &ip1, &mask); str2ip(netstr, &ip2, &mask); /* break range into (ip)/(net) */ } else if (2==sscanf (range1, "%[0-9.]/%[0-9]", ipstr, netstr)) { /* read ip address */ str2ip (ipstr, &ip1, &mask); net = atoi(netstr); if (net<0) net=0; else if (net>32) net=32; mask = 0xfffffff >> net; if (mask==-1) mask = 0; ip2 = ip1 | mask; /* Look for single ip address */ } else if (sscanf (range1, "%[0-9.].%[0-9].", ipstr, netstr)) { str2ip (ipstr, &ip1, &mask); ip2 = ip1 | mask; /* Bad input format */ } else { fprintf (stderr, "ERROR: Ignoring invalid network range argument (%s)\n", arg_in); return; } /* Store results */ add_iprange (iprange, code, ip1, ip2); } free (netstr); free (ipstr); free (arg_cpy); } /* Return code value for iprange containing ip */ int get_range_code (int ip, ip_range_t *iprange) { int i; for (i=0; in; i++) { if (iprange->lo[i]<=ip && ip<=iprange->hi[i]) return iprange->code[i]; } return 0; } #define NBUFF 256 int main (int argc, char *argv[]) { ip_range_t *iprange = NULL; #if 0 char *ipstr = "137.99.20.5"; #endif char ipstr[NBUFF]; int ip, mask, code, nread; char buffer[NBUFF]; FILE *fin = NULL; if (argc<3) { printf ("Usage: iprange \n"); return 0; } fin = fopen (argv[1], "rt"); if (fin==NULL) { printf ("Cannot open file <%s>\n", argv[1]); return 1; } while (fgets(buffer,NBUFF,fin)) { nread = sscanf (buffer, "%s %i", ipstr, &code); /*test*/ printf ("ipstr <%s> code <%i>\n", ipstr, code); /* end test*/ if (nread<2) continue; process_iprange (&iprange, code, ipstr); } dump_range (iprange); str2ip (argv[2], &ip, &mask); code = get_range_code (ip, iprange); printf ("code for ip (%s)(0x%x) (%d)\n", argv[2], ip, code); return 0; #if 0 code = get_range_code(ip, iprange); process_iprange (&iprange, 2, "137.99.20.0/24"); str2ip (ipstr, &ip, &mask); code = get_range_code (ip, iprange); printf ("code for (%s) (%d)\n", ipstr, code); return 0; #endif }