#include <u.h>#include <libc.h>#include <ip.h>#include <bio.h> char flag[127];char *fil;uint lin; intparsecidr(uchar *addr, uchar *mask, char *from){ char *p, buf[50]; int i, bits, z; vlong v; uchar *a; strecpy(buf, buf+sizeof buf, from); if(p = strchr(buf, '/')) *p = 0; v = parseip(addr, buf); if(v == -1) return -1; switch((ulong)v){ default: bits = 32; z = 96; break; case 6: bits = 128; z = 0; break; } if(p){ i = strtoul(p+1, &p, 0); if(i > bits) i = bits; i += z; memset(mask, 0, 128/8); for(a = mask; i >= 8; i -= 8) *a++ = 0xff; if(i > 0) *a = ~((1<<(8-i))-1); }else memset(mask, 0xff, IPaddrlen); return 0;} /* * match x.y.z.w to ~?x1.y1.z1.w1/m */intcidrmatch(char *x, char *y){ uchar r, a[IPaddrlen], b[IPaddrlen], m[IPaddrlen]; r = *y == '~'; if(parseip(a, x) == -1) return 0; parsecidr(b, m, y+r); maskip(a, m, a); maskip(b, m, b); if(!memcmp(a, b, IPaddrlen) ^ r) return 1; return 0;} Biobuf*patopen(char *s){ Biobuf *b; lin = 0; b = Bopen(fil = s, OREAD); if(b == nil) sysfatal("open: %r"); return b;} char*nextpat(Biobuf *b){ char *q; static char *s, *p; b1: if(p == nil || *p == 0){ free(s); p = s = Brdstr(b, '\n', 1); lin++; } if(p == nil) return nil; p += strspn(p, " \t\r"); if(*p == '#' || *p == 0){ *p = 0; goto b1; } q = p; p += strcspn(p, " \t\r"); if(*p != 0) *p++ = 0; return q;} voidprmatch(char *s){ if(flag['s'] == 0){ if(flag['n']) print("%s:%ud: %s\n", fil, lin, s); else print("%s\n", s); }} voidusage(void){ fprint(2, "cidr [-clLnrsv] ip [-f ipfile] file ...\n"); exits("usage");} voidmain(int argc, char **argv){ char *pat, *file, **tab; int i, j, c, c0, n, ntab; Biobuf *b; file = nil; ARGBEGIN{ case 'f': file = EARGF(usage()); case 'c': case 'l': case 'L': case 'n': case 'r': case 's': case 'v': flag[ARGC()] = 1; break; default: usage(); }ARGEND if(flag['l'] || flag['L'] || flag['c']) flag['s'] = 1; ntab = 1; tab = malloc(1 * sizeof *tab); if(tab == nil) sysfatal("malloc: %r"); if(!flag['f']){ if(argc == 0) usage(); tab[0] = strdup(*argv++); argc--; }else{ b = patopen(file); for(i = 0; tab[i] = nextpat(b); i++){ if((tab[i] = strdup(tab[i])) == nil) sysfatal("strdup: %r"); if(i + 1 == ntab){ ntab <<= 2; tab = realloc(tab, ntab*sizeof *tab); if(tab == nil) sysfatal("realloc: %r"); } } Bterm(b); ntab = i; } if(argc == 0) argv[argc++] = "/fd/0"; c = 0; for(i = 0; i < argc; i++){ b = patopen(argv[i]); c0 = c; while((pat = nextpat(b)) != nil){ for(j = 0; j < ntab; j++){ if(flag['r']) n = cidrmatch(tab[j], pat); else n = cidrmatch(pat, tab[j]); if(n ^ flag['v']){ prmatch(pat); c++; break; } } } Bterm(b); if(c0 == c && flag['L'] || c0 != c&& flag['l']) print("%s\n", argv[i]); } for(i = 0; i < ntab; i++) free(tab[i]); free(tab); if(flag['c']) print("%d\n", c); exits(c>0? nil: "no matches");}
#include <u.h>
#include <libc.h>
#include <ip.h>
#include <bio.h>
char flag[127];
char *fil;
uint lin;
int
parsecidr(uchar *addr, uchar *mask, char *from)
{
char *p, buf[50];
int i, bits, z;
vlong v;
uchar *a;
strecpy(buf, buf+sizeof buf, from);
if(p = strchr(buf, '/'))
*p = 0;
v = parseip(addr, buf);
if(v == -1)
return -1;
switch((ulong)v){
default:
bits = 32;
z = 96;
break;
case 6:
bits = 128;
z = 0;
break;
}
if(p){
i = strtoul(p+1, &p, 0);
if(i > bits)
i = bits;
i += z;
memset(mask, 0, 128/8);
for(a = mask; i >= 8; i -= 8)
*a++ = 0xff;
if(i > 0)
*a = ~((1<<(8-i))-1);
}else
memset(mask, 0xff, IPaddrlen);
return 0;
}
/*
* match x.y.z.w to ~?x1.y1.z1.w1/m
*/
int
cidrmatch(char *x, char *y)
{
uchar r, a[IPaddrlen], b[IPaddrlen], m[IPaddrlen];
r = *y == '~';
if(parseip(a, x) == -1)
return 0;
parsecidr(b, m, y+r);
maskip(a, m, a);
maskip(b, m, b);
if(!memcmp(a, b, IPaddrlen) ^ r)
return 1;
return 0;
}
Biobuf*
patopen(char *s)
{
Biobuf *b;
lin = 0;
b = Bopen(fil = s, OREAD);
if(b == nil)
sysfatal("open: %r");
return b;
}
char*
nextpat(Biobuf *b)
{
char *q;
static char *s, *p;
b1:
if(p == nil || *p == 0){
free(s);
p = s = Brdstr(b, '\n', 1);
lin++;
}
if(p == nil)
return nil;
p += strspn(p, " \t\r");
if(*p == '#' || *p == 0){
*p = 0;
goto b1;
}
q = p;
p += strcspn(p, " \t\r");
if(*p != 0)
*p++ = 0;
return q;
}
void
prmatch(char *s)
{
if(flag['s'] == 0){
if(flag['n'])
print("%s:%ud: %s\n", fil, lin, s);
else
print("%s\n", s);
}
}
void
usage(void)
{
fprint(2, "cidr [-clLnrsv] ip [-f ipfile] file ...\n");
exits("usage");
}
void
main(int argc, char **argv)
{
char *pat, *file, **tab;
int i, j, c, c0, n, ntab;
Biobuf *b;
file = nil;
ARGBEGIN{
case 'f':
file = EARGF(usage());
case 'c':
case 'l':
case 'L':
case 'n':
case 'r':
case 's':
case 'v':
flag[ARGC()] = 1;
break;
default:
usage();
}ARGEND
if(flag['l'] || flag['L'] || flag['c'])
flag['s'] = 1;
ntab = 1;
tab = malloc(1 * sizeof *tab);
if(tab == nil)
sysfatal("malloc: %r");
if(!flag['f']){
if(argc == 0)
usage();
tab[0] = strdup(*argv++);
argc--;
}else{
b = patopen(file);
for(i = 0; tab[i] = nextpat(b); i++){
if((tab[i] = strdup(tab[i])) == nil)
sysfatal("strdup: %r");
if(i + 1 == ntab){
ntab <<= 2;
tab = realloc(tab, ntab*sizeof *tab);
if(tab == nil)
sysfatal("realloc: %r");
}
}
Bterm(b);
ntab = i;
}
if(argc == 0)
argv[argc++] = "/fd/0";
c = 0;
for(i = 0; i < argc; i++){
b = patopen(argv[i]);
c0 = c;
while((pat = nextpat(b)) != nil){
for(j = 0; j < ntab; j++){
if(flag['r'])
n = cidrmatch(tab[j], pat);
else
n = cidrmatch(pat, tab[j]);
if(n ^ flag['v']){
prmatch(pat);
c++;
break;
}
}
}
Bterm(b);
if(c0 == c && flag['L'] || c0 != c&& flag['l'])
print("%s\n", argv[i]);
}
for(i = 0; i < ntab; i++)
free(tab[i]);
free(tab);
if(flag['c'])
print("%d\n", c);
exits(c>0? nil: "no matches");
}