int dns_mx_packet(stralloc *out,const char *buf,unsigned int len) { unsigned int pos; char header[12]; char pref[2]; uint16 numanswers; uint16 datalen; if (!stralloc_copys(out,"")) return -1; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; uint16_unpack_big(header + 6,&numanswers); pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos += 4; while (numanswers--) { pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; uint16_unpack_big(header + 8,&datalen); if (byte_equal(header,2,DNS_T_MX)) if (byte_equal(header + 2,2,DNS_C_IN)) { if (!dns_packet_copy(buf,len,pos,pref,2)) return -1; if (!dns_packet_getname(buf,len,pos + 2,&q)) return -1; if (!stralloc_catb(out,pref,2)) return -1; if (!dns_domain_todot_cat(out,q)) return -1; if (!stralloc_0(out)) return -1; } pos += datalen; } return 0; }
int dns_domain_prependb2(char **out, const char *d, const char *s1, unsigned int n1, const char *s2, unsigned int n2) { static stralloc sa; if (!stralloc_copyb(&sa, s1, n1)) return 0; if (s2 && n2) if (!stralloc_catb(&sa, s2, n2)) return 0; if (!dns_domain_todot_cat(&sa, d)) return 0; if (!dns_domain_fromdot(out, sa.s, sa.len)) return 0; return 1; }
int main(int argc,char **argv) { uint16 u16; dns_random_init(seed); if (!*argv) usage(); if (!*++argv) usage(); if (!parsetype(*argv,type)) usage(); if (!*++argv) usage(); if (!dns_domain_fromdot(&q,*argv,str_len(*argv))) oops(); if (!*++argv) usage(); if (!stralloc_copys(&out,*argv)) oops(); if (dns_ip6_qualify(&ip,&fqdn,&out) == -1) oops(); if (ip.len >= 256) ip.len = 256; byte_zero(servers,256); byte_copy(servers,ip.len,ip.s); if (!stralloc_copys(&out,"")) oops(); uint16_unpack_big(type,&u16); if (!stralloc_catulong0(&out,u16,0)) oops(); if (!stralloc_cats(&out," ")) oops(); if (!dns_domain_todot_cat(&out,q)) oops(); if (!stralloc_cats(&out,":\n")) oops(); if (resolve(q,type,servers) == -1) { if (!stralloc_cats(&out,error_str(errno))) oops(); if (!stralloc_cats(&out,"\n")) oops(); } else { if (!printpacket_cat(&out,tx.packet,tx.packetlen)) oops(); } buffer_putflush(buffer_1,out.s,out.len); _exit(0); }
int main(int argc,char **argv) { unsigned long ttl; struct stat st; int i; int j; int k; char ch; if (!*argv) die_usage(); if (!*++argv) die_usage(); fn = *argv; if (!*++argv) die_usage(); fnnew = *argv; if (!*++argv) die_usage(); if (str_diff(*argv,"add")) die_usage(); if (!*++argv) die_usage(); if (str_equal(*argv,"ns")) mode = '.'; else if (str_equal(*argv,"childns")) mode = '&'; else if (str_equal(*argv,"host")) mode = '='; else if (str_equal(*argv,"host6")) mode = '6'; else if (str_equal(*argv,"alias")) mode = '+'; else if (str_equal(*argv,"alias6")) mode = '3'; else if (str_equal(*argv,"mx")) mode = '@'; else die_usage(); if (!*++argv) die_usage(); if (!dns_domain_fromdot(&target,*argv,str_len(*argv))) nomem(); if (!*++argv) die_usage(); if (mode == '6' || mode == '3') { if (!ip6_scan(*argv,targetip6)) die_usage(); } else { if (!ip4_scan(*argv,targetip)) die_usage(); } umask(077); fd = open_read(fn); if (fd == -1) die_read(); if (fstat(fd,&st) == -1) die_read(); buffer_init(&b,buffer_unixread,fd,bspace,sizeof bspace); fdnew = open_trunc(fnnew); if (fdnew == -1) die_write(); if (fchmod(fdnew,st.st_mode & 0644) == -1) die_write(); buffer_init(&bnew,buffer_unixwrite,fdnew,bnewspace,sizeof bnewspace); switch(mode) { case '.': case '&': ttl = TTL_NS; for (i = 0;i < 26;++i) { ch = 'a' + i; if (!stralloc_copyb(&f[0],&ch,1)) nomem(); if (!stralloc_cats(&f[0],".ns.")) nomem(); if (!dns_domain_todot_cat(&f[0],target)) nomem(); if (!dns_domain_fromdot(&names[i],f[0].s,f[0].len)) nomem(); } break; case '+': case '=': case '6': case '3': ttl = TTL_POSITIVE; break; case '@': ttl = TTL_POSITIVE; for (i = 0;i < 26;++i) { ch = 'a' + i; if (!stralloc_copyb(&f[0],&ch,1)) nomem(); if (!stralloc_cats(&f[0],".mx.")) nomem(); if (!dns_domain_todot_cat(&f[0],target)) nomem(); if (!dns_domain_fromdot(&names[i],f[0].s,f[0].len)) nomem(); } break; } while (match) { if (getln(&b,&line,&match,'\n') == -1) die_read(); put(line.s,line.len); if (line.len && !match) put("\n",1); while (line.len) { ch = line.s[line.len - 1]; if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break; --line.len; } if (!line.len) continue; if (line.s[0] == '#') continue; j = 1; for (i = 0;i < NUMFIELDS;++i) { if (j >= line.len) { if (!stralloc_copys(&f[i],"")) nomem(); } else { k = byte_chr(line.s + j,line.len - j,':'); if (!stralloc_copyb(&f[i],line.s + j,k)) nomem(); j += k + 1; } } switch(mode) { case '.': case '&': if (line.s[0] == mode) { if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (dns_domain_equal(d1,target)) { if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) { if (!stralloc_cats(&f[2],".ns.")) nomem(); if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem(); } if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem(); if (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS; for (i = 0;i < 26;++i) if (dns_domain_equal(d2,names[i])) { used[i] = 1; break; } } } break; case '=': if (line.s[0] == '=') { if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (dns_domain_equal(d1,target)) strerr_die2x(100,FATAL,"host name already used"); if (!stralloc_0(&f[1])) nomem(); if (ip4_scan(f[1].s,ip)) if (byte_equal(ip,4,targetip)) strerr_die2x(100,FATAL,"IP address already used"); } break; case '6': if (line.s[0] == '6') { if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (dns_domain_equal(d1,target)) strerr_die2x(100,FATAL,"host name already used"); if (!stralloc_0(&f[1])) nomem(); if (ip6_scan(f[1].s,ip6)) if (byte_equal(ip,16,targetip6)) strerr_die2x(100,FATAL,"IPv6 address already used"); } break; case '@': if (line.s[0] == '@') { if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (dns_domain_equal(d1,target)) { if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) { if (!stralloc_cats(&f[2],".mx.")) nomem(); if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem(); } if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem(); if (!stralloc_0(&f[4])) nomem(); if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE; for (i = 0;i < 26;++i) if (dns_domain_equal(d2,names[i])) { used[i] = 1; break; } } } break; } } if (!stralloc_copyb(&f[0],&mode,1)) nomem(); if (!dns_domain_todot_cat(&f[0],target)) nomem(); if (!stralloc_cats(&f[0],":")) nomem(); if (mode == '6' || mode == '3') { if (!stralloc_catb(&f[0],ip6str,ip6_fmt_flat(ip6str,targetip6))) nomem(); } else { if (!stralloc_catb(&f[0],ipstr,ip4_fmt(ipstr,targetip))) nomem(); } switch(mode) { case '.': case '&': case '@': for (i = 0;i < 26;++i) if (!used[i]) break; if (i >= 26) strerr_die2x(100,FATAL,"too many records for that domain"); ch = 'a' + i; if (!stralloc_cats(&f[0],":")) nomem(); if (!stralloc_catb(&f[0],&ch,1)) nomem(); if (mode == '@') if (!stralloc_cats(&f[0],":")) nomem(); break; } if (!stralloc_cats(&f[0],":")) nomem(); if (!stralloc_catb(&f[0],strnum,fmt_ulong(strnum,ttl))) nomem(); if (!stralloc_cats(&f[0],"\n")) nomem(); put(f[0].s,f[0].len); if (buffer_flush(&bnew) == -1) die_write(); if (fsync(fdnew) == -1) die_write(); if (close(fdnew) == -1) die_write(); /* NFS dorks */ if (rename(fnnew,fn) == -1) strerr_die6sys(111,FATAL,"unable to move ",fnnew," to ",fn,": "); _exit(0); }
int main (int argc, char *argv[]) { char ch = 0; struct stat st; unsigned long ttl = 0; unsigned i = 0, j = 0, k = 0; prog = strdup ((d1 = strrchr (argv[0], '/')) != NULL ? d1 + 1 : argv[0]); i = check_option (argc, argv); argv += i; argc -= i; d1 = NULL; if (argc < 6) { usage (); return -1; } fn = *argv; argv++; fnnew = *argv; argv++; if (str_diff (*argv, "add")) { usage (); return -1; } argv++; if (str_equal (*argv, "ns")) mode = '.'; else if (str_equal (*argv, "childns")) mode = '&'; else if (str_equal (*argv, "host")) mode = '='; else if (str_equal (*argv, "alias")) mode = '+'; else if (str_equal (*argv, "mx")) mode = '@'; else errx (-1, "invalid record type `%s'", *argv); argv++; if (!dns_domain_fromdot (&target, *argv, str_len (*argv))) err (-1, "could not allocate enough memory"); argv++; if (!ip4_scan (*argv, targetip)) errx (-1, "could not parse IP `%s'", *argv); umask(077); fd = open_read (fn); if (fd == -1) err (-1, "could not read from `%s'", fn); if (fstat (fd, &st) == -1) err (-1, "could not read from `%s'", fn); buffer_init (&b, buffer_unixread, fd, bspace, sizeof bspace); fdnew = open_trunc (fnnew); if (fdnew == -1) err (-1, "could not write to `%s'", fnnew); if (fchmod (fdnew, st.st_mode & 0644) == -1) err (-1, "could not write to `%s'", fnnew); buffer_init (&bnew, buffer_unixwrite, fdnew, bnewspace, sizeof bnewspace); switch (mode) { case '.': case '&': ttl = TTL_NS; for (i = 0; i < 26; i++) { ch = 'a' + i; if (!stralloc_copyb (&f[0], &ch, 1)) err (-1, "could not allocate enough memory"); if (!stralloc_cats (&f[0], ".ns.")) err (-1, "could not allocate enough memory"); if (!dns_domain_todot_cat (&f[0], target)) err (-1, "could not allocate enough memory"); if (!dns_domain_fromdot (&names[i], f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); } break; case '+': case '=': ttl = TTL_POSITIVE; break; case '@': ttl = TTL_POSITIVE; for (i = 0; i < 26; i++) { ch = 'a' + i; if (!stralloc_copyb (&f[0], &ch, 1)) err (-1, "could not allocate enough memory"); if (!stralloc_cats (&f[0], ".mx.")) err (-1, "could not allocate enough memory"); if (!dns_domain_todot_cat (&f[0], target)) err (-1, "could not allocate enough memory"); if (!dns_domain_fromdot (&names[i], f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); } break; } while (match) { if (getln (&b, &line, &match, '\n') == -1) err (-1, "could not read from `%s'", fn); put (line.s, line.len); if (line.len && !match) put ("\n", 1); while (line.len) { ch = line.s[line.len - 1]; if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break; --line.len; } if (!line.len || line.s[0] == '#') continue; j = 1; for (i = 0; i < NUMFIELDS; i++) { if (j >= line.len) { if (!stralloc_copys (&f[i], "")) err (-1, "could not allocate enough memory"); } else { k = byte_chr (line.s + j, line.len - j, ':'); if (!stralloc_copyb (&f[i], line.s + j, k)) err (-1, "could not allocate enough memory"); j += k + 1; } } switch(mode) { case '.': case '&': if (line.s[0] == mode) { if (!dns_domain_fromdot (&d1, f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); if (dns_domain_equal (d1, target)) { if (byte_chr (f[2].s, f[2].len, '.') >= f[2].len) { if (!stralloc_cats (&f[2], ".ns.")) err (-1, "could not allocate enough memory"); if (!stralloc_catb (&f[2], f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); } if (!dns_domain_fromdot (&d2, f[2].s, f[2].len)) err (-1, "could not allocate enough memory"); if (!stralloc_0 (&f[3])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[3].s, &ttl)) ttl = TTL_NS; for (i = 0; i < 26; i++) { if (dns_domain_equal (d2, names[i])) { used[i] = 1; break; } } } } break; case '=': if (line.s[0] == '=') { if (!dns_domain_fromdot (&d1, f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); if (dns_domain_equal (d1, target)) errx (-1, "host name is already used"); if (!stralloc_0 (&f[1])) err (-1, "could not allocate enough memory"); if (ip4_scan (f[1].s, ip)) if (byte_equal(ip, 4, targetip)) errx (-1, "IP address is already used"); } break; case '@': if (line.s[0] == '@') { if (!dns_domain_fromdot (&d1, f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); if (dns_domain_equal (d1, target)) { if (byte_chr (f[2].s, f[2].len, '.') >= f[2].len) { if (!stralloc_cats (&f[2], ".mx.")) err (-1, "could not allocate enough memory"); if (!stralloc_catb (&f[2], f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); } if (!dns_domain_fromdot (&d2, f[2].s, f[2].len)) err (-1, "could not allocate enough memory"); if (!stralloc_0 (&f[4])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[4].s, &ttl)) ttl = TTL_POSITIVE; for (i = 0; i < 26; i++) { if (dns_domain_equal (d2, names[i])) { used[i] = 1; break; } } } } break; } } if (!stralloc_copyb (&f[0], &mode, 1)) err (-1, "could not allocate enough memory"); if (!dns_domain_todot_cat (&f[0], target)) err (-1, "could not allocate enough memory"); if (!stralloc_cats (&f[0], ":")) err (-1, "could not allocate enough memory"); if (!stralloc_catb (&f[0], ipstr, ip4_fmt (ipstr, targetip))) err (-1, "could not allocate enough memory"); switch (mode) { case '.': case '&': case '@': for (i = 0; i < 26; i++) { if (!used[i]) break; } if (i >= 26) errx (-1, "too many records for domain `%s'", target); ch = 'a' + i; if (!stralloc_cats (&f[0], ":")) err (-1, "could not allocate enough memory"); if (!stralloc_catb (&f[0], &ch, 1)) err (-1, "could not allocate enough memory"); if (mode == '@') if (!stralloc_cats (&f[0], ":")) err (-1, "could not allocate enough memory"); break; } if (!stralloc_cats (&f[0], ":")) err (-1, "could not allocate enough memory"); if (!stralloc_catb (&f[0], strnum, fmt_ulong (strnum, ttl))) err (-1, "could not allocate enough memory"); if (!stralloc_cats (&f[0], "\n")) err (-1, "could not allocate enough memory"); put (f[0].s, f[0].len); if (buffer_flush (&bnew) == -1) err (-1, "could not write to `%s'", fnnew); if (fsync (fdnew) == -1) err (-1, "could not write to `%s'", fnnew); if (close (fdnew) == -1) err (-1, "could not write to `%s'", fnnew); /* NFS dorks */ if (rename (fnnew, fn) == -1) err (-1, "could not move `%s' to `%s'", fnnew, fn); return 0; }
void printdomain(const char *d) { if (!stralloc_copys(&tmp,"")) nomem(); if (!dns_domain_todot_cat(&tmp,d)) nomem(); buffer_put(buffer_1,tmp.s,tmp.len); }
void testit(const char* data) { str result = {0}; debugstrfn(dns_domain_todot_cat(&result, data), &result); }
unsigned int printrecord_cat(stralloc *out,char *buf,unsigned int len,unsigned int pos,char *q,char qtype[2]) { char *x; char misc[20]; uint16 datalen; uint16 u16; uint32 u32; unsigned int newpos; int i; unsigned char ch; pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; pos = dns_packet_copy(buf,len,pos,misc,10); if (!pos) return 0; uint16_unpack_big(misc + 8,&datalen); newpos = pos + datalen; if (q) { if (!dns_domain_equal(d,q)) return newpos; if (byte_diff(qtype,2,misc) && byte_diff(qtype,2,DNS_T_ANY)) return newpos; } if (!dns_domain_todot_cat(out,d)) return 0; if (!stralloc_cats(out," ")) return 0; uint32_unpack_big(misc + 4,&u32); if (!stralloc_catulong0(out,u32,0)) return 0; if (byte_diff(misc + 2,2,DNS_C_IN)) { if (!stralloc_cats(out," weird class\n")) return 0; return newpos; } x = 0; if (byte_equal(misc,2,DNS_T_NS)) x = " NS "; if (byte_equal(misc,2,DNS_T_PTR)) x = " PTR "; if (byte_equal(misc,2,DNS_T_CNAME)) x = " CNAME "; if (x) { pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; if (!stralloc_cats(out,x)) return 0; if (!dns_domain_todot_cat(out,d)) return 0; } else if (byte_equal(misc,2,DNS_T_MX)) { if (!stralloc_cats(out," MX ")) return 0; pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0; pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; uint16_unpack_big(misc,&u16); if (!stralloc_catulong0(out,u16,0)) return 0; if (!stralloc_cats(out," ")) return 0; if (!dns_domain_todot_cat(out,d)) return 0; } else if (byte_equal(misc,2,DNS_T_SOA)) { if (!stralloc_cats(out," SOA ")) return 0; pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; if (!dns_domain_todot_cat(out,d)) return 0; if (!stralloc_cats(out," ")) return 0; pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; if (!dns_domain_todot_cat(out,d)) return 0; pos = dns_packet_copy(buf,len,pos,misc,20); if (!pos) return 0; for (i = 0;i < 5;++i) { if (!stralloc_cats(out," ")) return 0; uint32_unpack_big(misc + 4 * i,&u32); if (!stralloc_catulong0(out,u32,0)) return 0; } } else if (byte_equal(misc,2,DNS_T_A)) { if (datalen != 4) { errno = error_proto; return 0; } if (!stralloc_cats(out," A ")) return 0; pos = dns_packet_copy(buf,len,pos,misc,4); if (!pos) return 0; for (i = 0;i < 4;++i) { ch = misc[i]; if (i) if (!stralloc_cats(out,".")) return 0; if (!stralloc_catulong0(out,ch,0)) return 0; } } else if (byte_equal(misc,2,DNS_T_AAAA)) { char ip6str[IP6_FMT]; int stringlen; if (datalen != 16) { errno = error_proto; return 0; } if (!stralloc_cats(out," AAAA ")) return 0; pos = dns_packet_copy(buf,len,pos,misc,16); if (!pos) return 0; stringlen=ip6_fmt(ip6str,misc); if (!stralloc_cats(out,ip6str)) return 0; } else { if (!stralloc_cats(out," ")) return 0; uint16_unpack_big(misc,&u16); if (!stralloc_catulong0(out,u16,0)) return 0; if (!stralloc_cats(out," ")) return 0; while (datalen--) { pos = dns_packet_copy(buf,len,pos,misc,1); if (!pos) return 0; if ((misc[0] >= 33) && (misc[0] <= 126) && (misc[0] != '\\')) { if (!stralloc_catb(out,misc,1)) return 0; } else { ch = misc[0]; misc[3] = '0' + (7 & ch); ch >>= 3; misc[2] = '0' + (7 & ch); ch >>= 3; misc[1] = '0' + (7 & ch); misc[0] = '\\'; if (!stralloc_catb(out,misc,4)) return 0; } } } if (!stralloc_cats(out,"\n")) return 0; if (pos != newpos) { errno = error_proto; return 0; } return newpos; }