/* * 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. Load more
/* * 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* void usage(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 int fmtzonequote(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 int fmttabpad(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, }; void origin(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; } void prsoa(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; } int iregex(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; } void addre(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++; } void freeretab(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 void revipmask(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; } int issoa(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; } int ipmatch(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; } void addip(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); } void lookuprev(char *v, Ndbtuple *t) { uchar a[IPaddrlen];