#!/usr/bin/gawk -f # # # ipmatch ... # # print best matchings network from list of networks stored in # for # function ipval(str, i, n, x, val) { if ((n = split(str, x, ".")) != 4) return (0); val = x[1]; for (i=2; i<=4; i++) val = lshift(val, 8) + x[i]; return (val); } function ipmask(str, val) { if (index(str, ".") == 0) { str = str + 0; if (str < 0 || str > 32) str = 32; val = (str == 0)? 0: lshift(compl(0), 32 - str); } else { val = ipval(str); if (val == 0) val = compl(0); } return (val); } function ipstr(val, i, str) { str = sprintf ("%d", and(val, 255)); for (i=2; i<=4; i++) { val = rshift(val, 8); str = sprintf ("%d", and(val, 255)) "." str; } return (str); } BEGIN { STDERR = "/dev/stderr"; networks = ARGV[1]; ARGV[1] = ""; while (getline 0) { sub(/#.*$/, "", $0); if (NF == 0) continue; net = $1; if (index(net, "/") == 0) net = net "/32"; k = index(net, "/"); ip = ipval(substr(net, 1, k-1)); mask = ipmask(substr(net, k+1)); first[net] = and(ip, mask); last[net] = or(ip, compl(mask)); size[net] = last[net] - first[net] + 1; rec[net] = $0; } k = 2; while (k < ARGC) { ipnum = ARGV[k]; ARGV[k++] = ""; ip = ipval(ipnum); net = ""; for (n in rec) { if (first[n] <= ip && ip <= last[n]) { if (net == "") net = n; else { if (size[n] < size[net]) net = n; } } } if (net != "") printf ("%s %s\n", ipnum, rec[net]); } exit (0); }