812 lines · 14.1 KB · C
RawDownload
/* *  convert ndb to zone */#include <u.h>#include <libc.h>#include <bio.h>#include <ndb.h>#include <regexp.h>#include <ip.h> typedef struct Rrtab Rrtab;typedef struct Soatab Soatab;typedef struct Re Re;typedef struct Retab Retab; struct Rrtab {	char		*s;	Ndbtuple	*rr;}; struct Re {	Reprog		*re;	char		*s;	char		flag;}; struct Retab {	Re	*r;	int	nre;	int	nalloc;}; struct Soatab {	char		*s;	Re		*re;	Ndbtuple	*soa;	uchar		ip[IPaddrlen];	uchar		m[IPaddrlen];	int		bits;	Rrtab		*rr;	int		nrr;	int		arr;}; enum {	Fexact	= 1<<0,	Fneg	= 1<<1,}; static	int	flag[127];static	Biobuf	bout;static	Soatab	soatab[128];static	int	soaidx;static	ulong	soamtime; #define	dprint(...)	if(flag['d']) fprint(2, __VA_ARGS__); else {}#pragma	varargck	type	"t"	char* voidusage(void){	fprint(2, "usage: ndb/tozone [-dg] [-f ndbfile] [zone ...]\n");	exits("usage");} /* there is no way to get " or \n in an ndb rr */static intfmtzonequote(Fmt *f){	char *s;	uchar buf[IPaddrlen]; 	s = va_arg(f->args, char*);	if(strpbrk(s, " \t") == nil){		if(parseip(buf, s) == -1)			return fmtprint(f, "%s.", s);		else			return fmtprint(f, "%s", s);	}else		return fmtprint(f, "\"%s\"", s);} static intfmttabpad(Fmt *f){	char *s;	int l, p; 	l = strlen(s = va_arg(f->args, char*));	p = f->prec;	fmtprint(f, "%s", s);	for(; l < p; l += 8)		fmtprint(f, "\t");	return 0;} Ndb*ndbopen1(char *s){	Dir *d;	Ndb *db; 	db = ndbopen(s);	if(db && (d = dirstat(s))){		if(d->mtime > soamtime)			soamtime = d->mtime;		free(d);	}	return db;} Ndbtuple*ndbfcopy0(Ndbtuple *from, char **okrr, int nok){	Ndbtuple *first, *to, *last, *line;	int newline, i; 	newline = 1;	last = nil;	first = nil;	line = nil;	for(; from != nil; from = from->entry){		for(i = 0; i < nok; i++)			if(strcmp(from->attr, okrr[i]) == 0)				break;		if(nok > 0 && i == nok){			newline = from->line != from->entry;			continue;		}		to = ndbnew(from->attr, from->val);		if(newline)			line = to;		else			last->line = to; 		if(last != nil)			last->entry = to;		else {			first = to;			line = to;		}		to->entry = nil;		to->line = line;		last = to;		newline = from->line != from->entry;	}	ndbsetmalloctag(first, getcallerpc(&from));	return first;} Ndbtuple*ndbcopy(Ndbtuple *from){	return ndbfcopy0(from, nil, 0);} static char *glue[] = {	"ip",	"ns",}; Ndbtuple*ndbfcopy(Ndbtuple *from){	return ndbfcopy0(from, glue, nelem(glue));} enum {	Retry,	Expire,	Minttl,	Refresh,	Serial,	Mb,};char *nametab[] = {	"retry",	"expire",	"minttl",	"refresh",	"serial",	"mb",};char *deftab[] = {	"3600",	"86400",	"3600",	"3600",	nil,	nil,};char *rrtab[] = {	"ns",	"cname",	"mx",	"txtrr",	"ip",	"aaaa",	"a6",	"ptr",};char *rrntab[] = {	"ns",	"cname",	"mx",	"txt",	"a",	"aaaa",	"a6",	"ptr",};int rrorigin[] = {	1,	1,	1,	0,	0,	0,	0,	0,}; voidorigin(char *dom, int domsz, char *zone, char *origin, int inzone){	char *p;	int d; 	p = strstr(zone, origin);	if(p != nil && (p[strlen(origin)] != 0 || p > zone && p[-1] != '.'))		p = nil;	if(p == nil){		if(inzone)			sysfatal("%s not subdomain of %s", zone, origin);		snprint(dom, domsz, "%q", zone);		return;	}else		d = p - zone - 1;	if(d >= domsz || d == 0)		sysfatal("bad zone: %s", zone);	if(d == -1){		d = 1;		zone = "@";	}	memcpy(dom, zone, d);	dom[d] = 0;} voidprsoa(Biobuf *b, Soatab *t){	char *tab[Mb + 1], buf[12], dom[128], nm[128], mx[128], val[128];	int i, j, l, lmax;	Ndbtuple *nt, *pt; 	memcpy(tab, deftab, sizeof deftab);	for(nt = t->soa; nt; nt = nt->entry)		for(i = 0; i < nelem(nametab); i++)			if(strcmp(nt->attr, nametab[i]) == 0)				tab[i] = nt->val;	if(tab[Serial] == nil){		snprint(buf, sizeof buf, "%lud", soamtime);		tab[Serial] = buf;	}	if(tab[Mb] == nil){		snprint(nm, sizeof nm, "netmaster@%s", t->s);		tab[Mb] = nm;	} 	Bprint(b, "$ORIGIN %q\n", t->s);	origin(dom, sizeof dom, t->s, t->s, 1);	Bprint(b, "%s\t" "soa %s. %s. (\n", dom, t->s, tab[Mb]);	Bprint(b, "\t\t\t" "%s\n", tab[Serial]);	Bprint(b, "\t\t\t" "%s\n", tab[Refresh]);	Bprint(b, "\t\t\t" "%s\n", tab[Retry]);	Bprint(b, "\t\t\t" "%s\n", tab[Expire]);	Bprint(b, "\t\t\t" "%s\n", tab[Minttl]);	Bprint(b, "\t\t" ")\n");	for(i = 0; i < nelem(rrtab); i++)		for(nt = t->soa; nt; nt = nt->entry)			if(strcmp(nt->attr, rrtab[i]) == 0){				if(strcmp(nt->attr, "mx") == 0){					if(pt = nt->entry)					if(strcmp(pt->attr, "pref") == 0){						origin(mx, sizeof mx, nt->val, t->s, 0);						Bprint(b, "\t\t" "mx\t" "%s %s\n", pt->val, mx);					}				}else if(rrorigin[i]){					origin(dom, sizeof dom, nt->val, t->s, 0);					Bprint(b, "\t\t" "%s\t" "%s\n", rrntab[i], dom);				}else					Bprint(b, "\t\t" "%s\t" "%q\n", rrntab[i], nt->val);			}	lmax = 1;	for(j = 0; j < t->nrr; j++){		origin(dom, sizeof dom, t->rr[j].s, t->s, 1);		l = strlen(dom);		if(l > lmax)			lmax = l;	}//	lmax += 8;	lmax -= lmax%8;	for(j = 0; j < t->nrr; j++){		origin(dom, sizeof dom, t->rr[j].s, t->s, 1);		for(i = 0; i < nelem(rrtab); i++)			for(nt = t->rr[j].rr; nt; nt = nt->entry)				if(strcmp(nt->attr, rrtab[i]) == 0){					origin(val, sizeof val, nt->val, t->s, 0);					Bprint(b, "%.*t" "%s\t" "%s\n", lmax+8, dom, rrntab[i], val);				}	}} char*lower(char *s){	char *p, c; 	for(p = s; c = *p; p++)		if(c >= 'A' && c <= 'Z')			*p = c - ('A' - 'a');	return s;} intiregex(Re *r, char *val, int fmask){	char *s;	int m, f; 	s = lower(strdup(val));	f = r->flag & ~fmask;	if(f & Fexact)		m = strcmp(r->s, s) == 0;	else		m = regexec(r->re, s, 0, 0);	free(s);	if(f & Fneg)		m = !m;	return m;} Re*iregexes(Retab *r, char *val, int fmask){	int i; 	for(i = 0; i < r->nre; i++)		if(iregex(r->r + i, val, fmask))			return r->r + i;	return nil;} void*erealloc(void *a, ulong sz){	if((a = realloc(a, sz)) == nil)		sysfatal("realloc: %r");	return a;} voidaddre(Retab *r, char *s, int flag){	char rebuf[128];	int i; 	if(r->nre == r->nalloc){		r->r = erealloc(r->r, (r->nalloc += 10)*sizeof r->r[0]);		memset(r->r + r->nre, 0, 10*sizeof r->r[0]);	}	snprint(rebuf, sizeof rebuf, "%s$", s);	for(i = r->nre; i > 0 && strlen(s) > strlen(r->r[i - 1].s); i--)		r->r[i] = r->r[i - 1];	r->r[i].re = regcomp(rebuf);	if(r->r[i].re == nil)		sysfatal("regcomp: %r");	r->r[i].s = strdup(s);	if(r->r[i].s == nil)		sysfatal("strdup: %r");	r->r[i].flag = flag;	r->nre++;} voidfreeretab(Retab *r){	int i; 	for(i = 0; i < r->nre; i++){		free(r->r[i].re);		free(r->r[i].s);	}	free(r->r);} static char*bitprint(char *p, char *e, char *fmt, uint i, int, int bits){	if(bits > 8)		bits = 8;	if(bits > 0)		p = seprint(p, e, fmt, i & (1<<bits) - 1);	return p;} static voidrevipmask(char *buf, int bufsz, char *ip, int bits){	char *p, *e;	uchar a[IPaddrlen];	int i; 	p = buf;	e = p + bufsz;	if(parseip(a, ip) == 6){		for(i = 0; i < 16; i++){			bits = 128 - bits;			p = bitprint(p, e, "%x.", a[IPaddrlen - i - 1]>>0, 4, bits);			bits -= 4;			p = bitprint(p, e, "%x.", a[IPaddrlen - i - 1]>>4, 4, bits);			bits -= 4;		}	}else{		bits = 32 - bits;		for(i = 0; i < 4; i++){			p = bitprint(p, e, "%d.", a[IPaddrlen - i - 1]>>0, 4, bits);			bits -= 8;		}	}	if(p > buf && p[-1] == '.')		p--;	p[0] = 0;} intissoa(Ndbtuple *t){	Ndbtuple *nt; 	for(nt = t; nt; nt = nt->entry)		if(strcmp(nt->attr, "soa") == 0)			return 1;	return 0;} Soatab*addrr(Soatab *s, char *v, Ndbtuple *t, int f){	int j; 	dprint("%d: rr %s %s\n", f, s->s, v);	for(j = 0; j < s->nrr; j++)		if(strcmp(s->rr[j].s, v) == 0)			goto found;	if(j >= s->arr){		s->rr = erealloc(s->rr, (s->arr += 20)*sizeof *s->rr);		memset(s->rr + j, 0, sizeof s->rr[j]*20);	}	s->nrr++;	s->rr[j].s = strdup(v);found:	if(f && strcmp(v, s->s) != 0)		s->rr[j].rr = ndbconcatenate(s->rr[j].rr, ndbfcopy(t));	else		s->rr[j].rr = ndbconcatenate(s->rr[j].rr, ndbcopy(t));	return s;} intipmatch(uchar *a, uchar *b, uchar *mask){	uchar m[2][IPaddrlen]; 	maskip(a, mask, m[0]);	maskip(b, mask, m[1]);	return memcmp(m[0], m[1], IPaddrlen) == 0;} voidaddip(Soatab *s, char *v, char *val, int is6){	char rev[256], r2[256];	int bits;	Ndbtuple *rr; 	bits = s->bits;	if(!is6)		bits -= 96;	revipmask(rev, sizeof rev, val, bits);	snprint(r2, sizeof r2, "%s.%s", rev, s->s);	rr = ndbnew("ptr", v);	addrr(s, r2, rr, 0);	ndbfree(rr);} voidlookuprev(char *v, Ndbtuple *t){	uchar a[IPaddrlen];

Lines 1–500 of 812.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t