示例#1
0
int dns_domain_equal(const unsigned char *dn1, const unsigned char *dn2) {

    long long len;

    len = dns_domain_length(dn1);
    if (len != dns_domain_length(dn2)) return 0;
    return !case_diffb(dn1, len, dn2);
}
示例#2
0
int response_addname(char *d)
{
  unsigned int dlen;
  unsigned int i;
  char buf[2];

  dlen = dns_domain_length(d);

  while (*d) {
    for (i = 0;i < name_num;++i)
      if (dns_domain_equal(d,name[i])) {
        uint16_pack_big(buf,49152 + name_ptr[i]);
        return response_addbytes(buf,2);
      }
    if (dlen <= 128)
      if (name_num < NAMES) {
	byte_copy(name[name_num],dlen,d);
	name_ptr[name_num] = response_len;
	++name_num;
      }
    i = (unsigned char) *d;
    ++i;
    if (!response_addbytes(d,i)) return 0;
    d += i;
    dlen -= i;
  }
  return response_addbytes(d,1);
}
示例#3
0
int dns_transmit_start(struct dns_transmit *d,const char servers[64],int flagrecursive,const char *q,const char qtype[2],const char localip[4])
{
  unsigned int len;

  dns_transmit_free(d);
  errno = error_io;

  len = dns_domain_length(q);
  d->querylen = len + 18;
  d->query = alloc(d->querylen);
  if (!d->query) return -1;

  uint16_pack_big(d->query,len + 16);
  byte_copy(d->query + 2,12,flagrecursive ? "\0\0\1\0\0\1\0\0\0\0\0\0" : "\0\0\0\0\0\1\0\0\0\0\0\0gcc-bug-workaround");
  byte_copy(d->query + 14,len,q);
  byte_copy(d->query + 14 + len,2,qtype);
  byte_copy(d->query + 16 + len,2,DNS_C_IN);

  byte_copy(d->qtype,2,qtype);
  d->servers = servers;
  byte_copy(d->localip,4,localip);

  d->udploop = flagrecursive ? 1 : 0;

  if (len + 16 > 512) return firsttcp(d);
  return firstudp(d);
}
示例#4
0
void doname(stralloc *sa)
{
  static char *d;
  dpos = dns_packet_getname(data,dlen,dpos,&d);
  if (!dpos) die_cdbread();
  if (!stralloc_catb(sa,d,dns_domain_length(d))) nomem();
}
示例#5
0
static int doit(char *q,char qtype[2],char ip[4])
{
    int r;
    uint32 dlen;
    unsigned int qlen;

    qlen = dns_domain_length(q);
    if (qlen > 255) return 0; /* impossible */

    if (byte_diff(qtype,2,DNS_T_A) && byte_diff(qtype,2,DNS_T_ANY)) goto REFUSE;

    key[0] = '%';
    byte_copy(key + 1,4,ip);

    r = cdb_find(&c,key,5);
    if (!r) r = cdb_find(&c,key,4);
    if (!r) r = cdb_find(&c,key,3);
    if (!r) r = cdb_find(&c,key,2);
    if (r == -1) return 0;

    key[0] = '+';
    byte_zero(key + 1,2);
    if (r && (cdb_datalen(&c) == 2))
        if (cdb_read(&c,key + 1,2,cdb_datapos(&c)) == -1) return 0;

    byte_copy(key + 3,qlen,q);
    case_lowerb(key + 3,qlen + 3);

    r = cdb_find(&c,key,qlen + 3);
    if (!r) {
        byte_zero(key + 1,2);
        r = cdb_find(&c,key,qlen + 3);
    }
    if (!r) goto REFUSE;
    if (r == -1) return 0;
    dlen = cdb_datalen(&c);

    if (dlen > 512) dlen = 512;
    if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return 0;

    dns_sortip(data,dlen);

    if (dlen > 12) dlen = 12;
    while (dlen >= 4) {
        dlen -= 4;
        if (!response_rstart(q,DNS_T_A,"\0\0\0\5")) return 0;
        if (!response_addbytes(data + dlen,4)) return 0;
        response_rfinish(RESPONSE_ANSWER);
    }

    return 1;


REFUSE:
    response[2] &= ~4;
    response[3] &= ~15;
    response[3] |= 5;
    return 1;
}
示例#6
0
void
doname (stralloc *sa)
{
    static char *d = NULL;

    dpos = dns_packet_getname (data, dlen, dpos, &d);
    if (!dpos)
        err (-1, "could not read from file `data.cdb'");
    if (!stralloc_catb (sa, d, dns_domain_length (d)))
        err (-1, "could not allocate enough memory");
}
示例#7
0
void rr_finish(const char *owner)
{
  if (byte_equal(owner,2,"\1*")) {
    owner += 2;
    result.s[2] -= 19;
  }
  if (!stralloc_copyb(&key,owner,dns_domain_length(owner))) nomem();
  case_lowerb(key.s,key.len);
  if (cdb_make_add(&cdb,key.s,key.len,result.s,result.len) == -1)
    die_datatmp();
}
示例#8
0
static int doit(void)
{
  unsigned int pos;
  char header[12];
  char qtype[2];
  char qclass[2];

  if (len >= sizeof buf) goto NOQ;
  pos = dns_packet_copy(buf,len,0,header,12); if (!pos) goto NOQ;
  if (header[2] & 128) goto NOQ;
  if (header[4]) goto NOQ;
  if (header[5] != 1) goto NOQ;

  pos = dns_packet_getname(buf,len,pos,&q); if (!pos) goto NOQ;
  pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) goto NOQ;
  pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) goto NOQ;

  if (!response_query(q,qtype,qclass)) goto NOQ;
  response_id(header);
  if (byte_equal(qclass,2,DNS_C_IN))
    response[2] |= 4;
  else
    if (byte_diff(qclass,2,DNS_C_ANY)) goto WEIRDCLASS;
  response[3] &= ~128;
  if (!(header[2] & 1)) response[2] &= ~1;

  if (header[2] & 126) goto NOTIMP;
  if (byte_equal(qtype,2,DNS_T_AXFR)) goto NOTIMP;

  case_lowerb(q,dns_domain_length(q));
  if (!respond(q,qtype,ip)) {
    qlog(ip,port,header,q,qtype," - ");
    return 0;
  }
  qlog(ip,port,header,q,qtype," + ");
  return 1;

  NOTIMP:
  response[3] &= ~15;
  response[3] |= 4;
  qlog(ip,port,header,q,qtype," I ");
  return 1;

  WEIRDCLASS:
  response[3] &= ~15;
  response[3] |= 1;
  qlog(ip,port,header,q,qtype," C ");
  return 1;

  NOQ:
  qlog(ip,port,"\0\0","","\0\0"," / ");
  return 0;
}
示例#9
0
int dns_domain_copy(unsigned char **out, const unsigned char *in) {

    long long len;
    unsigned char *x;

    len = dns_domain_length(in);
    x = alloc(len);
    if (!x) return 0;
    byte_copy(x, len, in);
    if (*out) alloc_free(*out);
    *out = x;
    return 1;
}
示例#10
0
文件: roots.c 项目: GunioRobot/djbdns
static int roots_find(char *q)
{
  int i;
  int j;

  i = 0;
  while (i < data.len) {
    j = dns_domain_length(data.s + i);
    if (dns_domain_equal(data.s + i,q)) return i + j;
    i += j;
    i += 64;
  }
  return -1;
}
示例#11
0
void
rr_finish (const char *owner)
{
    if (byte_equal (owner, 2, "\1*"))
    {
        owner += 2;
        result.s[2] -= 19;
    }

    if (!stralloc_copyb (&key, owner, dns_domain_length (owner)))
        err (-1, "could not allocate enough memory");

    case_lowerb (key.s, key.len);

    if (cdb_make_add (&cdb, key.s, key.len, result.s, result.len) == -1)
        errx (-1, "could not create file `data.tmp'");
}
示例#12
0
static int find(char *d,int flagwild)
{
  int r;
  char ch;
  struct tai cutoff;
  char ttd[8];
  char ttlstr[4];
  char recordloc[2];
  double newttl;

  for (;;) {
    r = cdb_findnext(&c,d,dns_domain_length(d));
    if (r <= 0) return r;
    dlen = cdb_datalen(&c);
    if (dlen > sizeof data) return -1;
    if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return -1;
    dpos = dns_packet_copy(data,dlen,0,type,2); if (!dpos) return -1;
    dpos = dns_packet_copy(data,dlen,dpos,&ch,1); if (!dpos) return -1;
    if ((ch == '=' + 1) || (ch == '*' + 1)) {
      --ch;
      dpos = dns_packet_copy(data,dlen,dpos,recordloc,2); if (!dpos) return -1;
      if (byte_diff(recordloc,2,clientloc)) continue;
    }
    if (flagwild != (ch == '*')) continue;
    dpos = dns_packet_copy(data,dlen,dpos,ttlstr,4); if (!dpos) return -1;
    uint32_unpack_big(ttlstr,&ttl);
    dpos = dns_packet_copy(data,dlen,dpos,ttd,8); if (!dpos) return -1;
    if (byte_diff(ttd,8,"\0\0\0\0\0\0\0\0")) {
      tai_unpack(ttd,&cutoff);
      if (ttl == 0) {
	if (tai_less(&cutoff,&now)) continue;
	tai_sub(&cutoff,&cutoff,&now);
	newttl = tai_approx(&cutoff);
	if (newttl <= 2.0) newttl = 2.0;
	if (newttl >= 3600.0) newttl = 3600.0;
	ttl = newttl;
      }
      else
	if (!tai_less(&cutoff,&now)) continue;
    }
    return 1;
  }
}
示例#13
0
文件: roots.c 项目: GunioRobot/djbdns
static int init2(DIR *dir)
{
  direntry *d;
  const char *fqdn;
  static char *q;
  static stralloc text;
  char servers[64];
  int serverslen;
  int i;
  int j;

  for (;;) {
    errno = 0;
    d = readdir(dir);
    if (!d) {
      if (errno) return 0;
      return 1;
    }

    if (d->d_name[0] != '.') {
      if (openreadclose(d->d_name,&text,32) != 1) return 0;
      if (!stralloc_append(&text,"\n")) return 0;

      fqdn = d->d_name;
      if (str_equal(fqdn,"@")) fqdn = ".";
      if (!dns_domain_fromdot(&q,fqdn,str_len(fqdn))) return 0;

      serverslen = 0;
      j = 0;
      for (i = 0;i < text.len;++i)
	if (text.s[i] == '\n') {
	  if (serverslen <= 60)
	    if (ip4_scan(text.s + j,servers + serverslen))
	      serverslen += 4;
	  j = i + 1;
	}
      byte_zero(servers + serverslen,64 - serverslen);

      if (!stralloc_catb(&data,q,dns_domain_length(q))) return 0;
      if (!stralloc_catb(&data,servers,64)) return 0;
    }
  }
}
示例#14
0
int main(int argc,char **argv)
{
  uint16 u16;

  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) {
    if (!ip4_scan(*argv,ip)) usage();
  }

  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 (!response_query(q,type,DNS_C_IN)) oops();
  response[3] &= ~128;
  response[2] &= ~1;
  response[2] |= 4;
  case_lowerb(q,dns_domain_length(q));

  if (byte_equal(type,2,DNS_T_AXFR)) {
    response[3] &= ~15;
    response[3] |= 4;
  }
  else
    if (!respond(q,type,ip)) goto DONE;

  if (!printpacket_cat(&out,response,response_len)) oops();

  DONE:
  buffer_putflush(buffer_1,out.s,out.len);
  _exit(0);
}
示例#15
0
文件: test.c 项目: alexgirao/ipsvd
int main () {
        stralloc out ={0};
        stralloc sa ={0};
        char ip[4];
        char *dn =0;
        
        stralloc_copys(&sa, "abcdefg");

        dns_ip4(&out, &sa);
        dns_ip4_qualify(&out, &sa, &sa);
        dns_name4(&out, ip);
        dns_mx(&out, &sa);
        dns_txt(&out, &sa);

        dns_domain_length(sa.s);
        dns_domain_equal(sa.s, sa.s);
        dns_domain_copy(&dn, sa.s);
        dns_domain_fromdot(&dn, sa.s, sa.len);

        return 0;
}
示例#16
0
文件: vdnsdb.c 项目: malfaux/geoipdns
static void rr_addloq(const char type[2],const char *d, uint32 loc, uint32 mid,uint32 uid)
{
#ifdef USE_LOCMAPS
	char map[8];
	dbger("-addloq: %s,%u (%u),%u,%u",d,loc,NOMATCH_HASH,uid,mid);
	if (loc != NOMATCH_HASH) return;
	dbger("NOMATCH hash found, adding loq records for %s",d);
/*
  if (byte_equal(type,2,DNS_T_A)) {
    dbger("lookup LOQ for A record %s",fqdn_read(out,d));
  }

	dbger("+addloq %s,%u,%u",fqdn_read(out,d),mid,uid);
*/
	if (!stralloc_copyb(&key,"\0?",2)) nomem();
	if (!stralloc_catb(&key,type,2)) nomem();
	if (!stralloc_catb(&key,d,dns_domain_length(d))) nomem();
	uint32_pack(map,mid);
	uint32_pack(map+4,uid);
	cdb_make_add(&cdb,key.s,key.len,map,8);
#endif
	return;
}
示例#17
0
static int doit(char *q,char qtype[2])
{
  unsigned int bpos;
  unsigned int anpos;
  unsigned int aupos;
  unsigned int arpos;
  char *control;
  char *wild;
  int flaggavesoa;
  int flagfound;
  int r;
  int flagns;
  int flagauthoritative;
  char x[20];
  uint16 u16;
  char addr[8][4];
  int addrnum;
  uint32 addrttl;
  int i;

  anpos = response_len;

  control = q;
  for (;;) {
    flagns = 0;
    flagauthoritative = 0;
    cdb_findstart(&c);
    while (r = find(control,0)) {
      if (r == -1) return 0;
      if (byte_equal(type,2,DNS_T_SOA)) flagauthoritative = 1;
      if (byte_equal(type,2,DNS_T_NS)) flagns = 1;
    }
    if (flagns) break;
    if (!*control) return 0; /* q is not within our bailiwick */
    control += *control;
    control += 1;
  }

  if (!flagauthoritative) {
    response[2] &= ~4;
    goto AUTHORITY; /* q is in a child zone */
  }


  flaggavesoa = 0;
  flagfound = 0;
  wild = q;

  for (;;) {
    addrnum = 0;
    addrttl = 0;
    cdb_findstart(&c);
    while (r = find(wild,wild != q)) {
      if (r == -1) return 0;
      flagfound = 1;
      if (flaggavesoa && byte_equal(type,2,DNS_T_SOA)) continue;
      if (byte_diff(type,2,qtype) && byte_diff(qtype,2,DNS_T_ANY) && byte_diff(type,2,DNS_T_CNAME)) continue;
      if (byte_equal(type,2,DNS_T_A) && (dlen - dpos == 4)) {
	addrttl = ttl;
	i = dns_random(addrnum + 1);
	if (i < 8) {
	  if ((i < addrnum) && (addrnum < 8))
	    byte_copy(addr[addrnum],4,addr[i]);
	  byte_copy(addr[i],4,data + dpos);
	}
	if (addrnum < 1000000) ++addrnum;
	continue;
      }
      if (!response_rstart(q,type,ttl)) return 0;
      if (byte_equal(type,2,DNS_T_NS) || byte_equal(type,2,DNS_T_CNAME) || byte_equal(type,2,DNS_T_PTR)) {
	if (!doname()) return 0;
      }
      else if (byte_equal(type,2,DNS_T_MX)) {
	if (!dobytes(2)) return 0;
	if (!doname()) return 0;
      }
      else if (byte_equal(type,2,DNS_T_SOA)) {
	if (!doname()) return 0;
	if (!doname()) return 0;
	if (!dobytes(20)) return 0;
        flaggavesoa = 1;
      }
      else
        if (!response_addbytes(data + dpos,dlen - dpos)) return 0;
      response_rfinish(RESPONSE_ANSWER);
    }
    for (i = 0;i < addrnum;++i)
      if (i < 8) {
	if (!response_rstart(q,DNS_T_A,addrttl)) return 0;
	if (!response_addbytes(addr[i],4)) return 0;
	response_rfinish(RESPONSE_ANSWER);
      }

    if (flagfound) break;
    if (wild == control) break;
    if (!*wild) break; /* impossible */
    wild += *wild;
    wild += 1;
  }

  if (!flagfound)
    response_nxdomain();


  AUTHORITY:
  aupos = response_len;

  if (flagauthoritative && (aupos == anpos)) {
    cdb_findstart(&c);
    while (r = find(control,0)) {
      if (r == -1) return 0;
      if (byte_equal(type,2,DNS_T_SOA)) {
        if (!response_rstart(control,DNS_T_SOA,ttl)) return 0;
	if (!doname()) return 0;
	if (!doname()) return 0;
	if (!dobytes(20)) return 0;
        response_rfinish(RESPONSE_AUTHORITY);
        break;
      }
    }
  }
  else
    if (want(control,DNS_T_NS)) {
      cdb_findstart(&c);
      while (r = find(control,0)) {
        if (r == -1) return 0;
        if (byte_equal(type,2,DNS_T_NS)) {
          if (!response_rstart(control,DNS_T_NS,ttl)) return 0;
	  if (!doname()) return 0;
          response_rfinish(RESPONSE_AUTHORITY);
        }
      }
    }

  arpos = response_len;

  bpos = anpos;
  while (bpos < arpos) {
    bpos = dns_packet_skipname(response,arpos,bpos); if (!bpos) return 0;
    bpos = dns_packet_copy(response,arpos,bpos,x,10); if (!bpos) return 0;
    if (byte_equal(x,2,DNS_T_NS) || byte_equal(x,2,DNS_T_MX)) {
      if (byte_equal(x,2,DNS_T_NS)) {
        if (!dns_packet_getname(response,arpos,bpos,&d1)) return 0;
      }
      else
        if (!dns_packet_getname(response,arpos,bpos + 2,&d1)) return 0;
      case_lowerb(d1,dns_domain_length(d1));
      if (want(d1,DNS_T_A)) {
	cdb_findstart(&c);
	while (r = find(d1,0)) {
          if (r == -1) return 0;
	  if (byte_equal(type,2,DNS_T_A)) {
            if (!response_rstart(d1,DNS_T_A,ttl)) return 0;
	    if (!dobytes(4)) return 0;
            response_rfinish(RESPONSE_ADDITIONAL);
	  }
        }
      }
    }
    uint16_unpack_big(x + 8,&u16);
    bpos += u16;
  }

  if (flagauthoritative && (response_len > 512)) {
    byte_zero(response + RESPONSE_ADDITIONAL,2);
    response_len = arpos;
    if (response_len > 512) {
      byte_zero(response + RESPONSE_AUTHORITY,2);
      response_len = aupos;
    }
  }

  return 1;
}
示例#18
0
main()
{
    struct address t;
    int i;
    int j;
    int k;
    char ch;

    umask(022);

    if (!address_alloc_readyplus(&x,0)) nomem();

    fd = open_read("data");
    if (fd == -1) strerr_die2sys(111,FATAL,"unable to open data: ");
    buffer_init(&b,read,fd,bspace,sizeof bspace);

    fdcdb = open_trunc("data.tmp");
    if (fdcdb == -1) die_datatmp();
    if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp();

    while (match) {
        ++linenum;
        if (getln(&b,&line,&match,'\n') == -1)
            strerr_die2sys(111,FATAL,"unable to read line: ");

        while (line.len) {
            ch = line.s[line.len - 1];
            if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
            --line.len;
        }
        if (!line.len) 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(line.s[0]) {
        default:
            syntaxerror(": unrecognized leading character");
        case '#':
            break;
        case '-':
            break;
        case '+':
            byte_zero(&t,sizeof t);
            if (!dns_domain_fromdot(&t.name,f[0].s,f[0].len)) nomem();
            t.namelen = dns_domain_length(t.name);
            case_lowerb(t.name,t.namelen);
            if (!stralloc_0(&f[1])) nomem();
            if (!ip4_scan(f[1].s,t.ip)) syntaxerror(": malformed IP address");
            if (!stralloc_0(&f[2])) nomem();
            if (!stralloc_0(&f[2])) nomem();
            byte_copy(t.location,2,f[2].s);
            if (!address_alloc_append(&x,&t)) nomem();
            break;
        case '%':
            if (!stralloc_0(&f[0])) nomem();
            if (!stralloc_0(&f[0])) nomem();
            if (!stralloc_copyb(&result,f[0].s,2)) nomem();
            if (!stralloc_0(&f[1])) nomem();
            if (!stralloc_copys(&key,"%")) nomem();
            ipprefix_cat(&key,f[1].s);
            if (cdb_make_add(&cdb,key.s,key.len,result.s,result.len) == -1)
                die_datatmp();
            break;
        }
    }

    close(fd);
    address_sort(x.s,x.len);

    i = 0;
    while (i < x.len) {
        for (j = i + 1; j < x.len; ++j)
            if (address_diff(x.s + i,x.s + j))
                break;
        if (!stralloc_copys(&key,"+")) nomem();
        if (!stralloc_catb(&key,x.s[i].location,2)) nomem();
        if (!stralloc_catb(&key,x.s[i].name,x.s[i].namelen)) nomem();
        if (!stralloc_copys(&result,"")) nomem();
        while (i < j)
            if (!stralloc_catb(&result,x.s[i++].ip,4)) nomem();
        if (cdb_make_add(&cdb,key.s,key.len,result.s,result.len) == -1)
            die_datatmp();
    }

    if (cdb_make_finish(&cdb) == -1) die_datatmp();
    if (fsync(fdcdb) == -1) die_datatmp();
    if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */
    if (rename("data.tmp","data.cdb") == -1)
        strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");

    _exit(0);
}
示例#19
0
void rr_addname(const char *d)
{
  rr_add(d,dns_domain_length(d));
}
示例#20
0
int
build (stralloc *sa, char *q, int flagsoa, char id[2])
{
    char ttl[4];
    char ttd[8];
    char type[2];
    char misc[20];
    char recordloc[2];
    struct tai cutoff;
    unsigned int rdatapos = 0;

    dpos = 0;
    copy (type, 2);
    if (flagsoa)
        if (byte_diff (type, 2, DNS_T_SOA))
            return 0;

    if (!flagsoa)
        if (byte_equal (type, 2, DNS_T_SOA))
            return 0;

    if (!stralloc_copyb (sa, id, 2))
        err (-1, "could not allocate enough memory");
    if (!stralloc_catb (sa, "\204\000\0\0\0\1\0\0\0\0", 10))
        err (-1, "could not allocate enough memory");
    copy (misc, 1);

    if ((misc[0] == '=' + 1) || (misc[0] == '*' + 1))
    {
        --misc[0];
        copy (recordloc, 2);
        if (byte_diff (recordloc, 2, clientloc))
            return 0;
    }
    if (misc[0] == '*')
    {
        if (flagsoa)
            return 0;
        if (!stralloc_catb (sa, "\1*", 2))
            err (-1, "could not allocate enough memory");
    }
    if (!stralloc_catb (sa, q, dns_domain_length (q)))
        err (-1, "could not allocate enough memory");
    if (!stralloc_catb (sa, type, 2))
        err (-1, "could not allocate enough memory");

    copy (ttl, 4);
    copy (ttd, 8);
    if (byte_diff (ttd, 8, "\0\0\0\0\0\0\0\0"))
    {
        tai_unpack (ttd, &cutoff);
        if (byte_equal (ttl, 4, "\0\0\0\0"))
        {
            if (tai_less (&cutoff, &now))
                return 0;
            uint32_pack_big (ttl, 2);
        }
        else
            if (!tai_less (&cutoff, &now))
                return 0;
    }

    if (!stralloc_catb (sa, DNS_C_IN, 2))
        err (-1, "could not allocate enough memory");
    if (!stralloc_catb (sa, ttl, 4))
        err (-1, "could not allocate enough memory");
    if (!stralloc_catb(sa,"\0\0",2))
        err (-1, "could not allocate enough memory");
    rdatapos = sa->len;

    if (byte_equal (type, 2, DNS_T_SOA))
    {
        doname (sa);
        doname (sa);
        copy (misc, 20);
        if (!stralloc_catb (sa, misc, 20))
            err (-1, "could not allocate enough memory");
    }
    else if (byte_equal (type, 2, DNS_T_NS)
             || byte_equal (type, 2, DNS_T_PTR)
             || byte_equal (type, 2, DNS_T_CNAME))
    {
        doname (sa);
    }
    else if (byte_equal (type, 2, DNS_T_MX))
    {
        copy (misc, 2);
        if (!stralloc_catb (sa, misc, 2))
            err (-1, "could not allocate enough memory");
        doname (sa);
    }
    else
    {
        if (!stralloc_catb (sa, data + dpos, dlen - dpos))
            err (-1, "could not allocate enough memory");
    }

    if (sa->len > 65535)
        errx (-1, "could not read from file `data.cdb': format error");
    uint16_pack_big (sa->s + rdatapos - 2, sa->len - rdatapos);

    return 1;
}
示例#21
0
int
main (int argc, char *argv[])
{
    int n = 0;
    time_t t = 0;
    struct sigaction sa;

    char qtype[2];
    char qclass[2];
    char header[12];
    const char *x = NULL;
    unsigned int pos = 0;
    unsigned long long qnum = 0;

    sa.sa_handler = handle_term;
    sigaction (SIGINT, &sa, NULL);
    sigaction (SIGTERM, &sa, NULL);

    sa.sa_handler = SIG_IGN;
    sigaction (SIGPIPE, &sa, NULL);

    prog = strdup ((x = strrchr (argv[0], '/')) != NULL ?  x + 1 : argv[0]);
    n = check_option (argc, argv);
    argc -= n;
    argv += n;

    if (mode & DAEMON)
        /* redirect stderr to a log file */
        redirect_to_log (logfile, STDERR_FILENO);

    time (&t);
    memset (seed, 0, sizeof (seed));
    strftime (seed, sizeof (seed), "%b-%d %Y %T %Z", localtime (&t));
    warnx ("version %s: starting %s\n", VERSION, seed);

    set_timezone ();
    if (debug_level)
        warnx ("TIMEZONE: %s", env_get ("TZ"));

    read_conf (cfgfile);
    if (!debug_level)
        if ((x = env_get ("DEBUG_LEVEL")))
            debug_level = atol (x);
    warnx ("DEBUG_LEVEL set to `%d'", debug_level);

    dns_random_init (seed);

    axfr = env_get ("AXFR");
    if (debug_level)
        warnx ("AXFR set to `%s'", axfr);
    x = env_get ("TCPREMOTEIP");
    if (debug_level)
        warnx ("TCPREMOTEIP set to `%s'", x);
    if (x)
        ip4_scan (x, ip);
    else
        byte_zero (ip, 4);

    x = env_get ("TCPREMOTEPORT");
    if (debug_level)
        warnx ("TCPREMOTEPORT set to `%s'", x);
    if (!x)
        x = "0";
    scan_ulong (x, &port);

    droproot ();
    for (;;)
    {
        netread (tcpheader, 2);
        uint16_unpack_big (tcpheader, &len);
        if (len > 512)
            errx (-1, "excessively large request");
        netread (buf, len);

        pos = dns_packet_copy (buf, len, 0, header, 12);
        if (!pos)
            errx (-1, "truncated request");
        if (header[2] & 254)
            errx (-1, "bogus query");
        if (header[4] || (header[5] != 1))
            errx (-1, "bogus query");

        pos = dns_packet_getname (buf, len, pos, &zone);
        if (!pos)
            errx (-1, "truncated request");
        zonelen = dns_domain_length (zone);
        pos = dns_packet_copy (buf, len, pos, qtype, 2);
        if (!pos)
            errx (-1, "truncated request");
        pos = dns_packet_copy (buf, len, pos, qclass, 2);
        if (!pos)
            errx (-1, "truncated request");

        if (byte_diff(qclass, 2, DNS_C_IN) && byte_diff(qclass, 2, DNS_C_ANY))
            errx (-1, "bogus query: bad class");

        log_query (++qnum, ip, port, header, zone, qtype);
        if (byte_equal(qtype,2,DNS_T_AXFR))
        {
            case_lowerb (zone, zonelen);
            fdcdb = open_read ("data.cdb");
            if (fdcdb == -1)
                errx (-1, "could not read from file `data.cdb'");
            doaxfr (header);
            close (fdcdb);
        }
        else
        {
            if (!response_query (zone, qtype, qclass))
                err (-1, "could not allocate enough memory");
            response[2] |= 4;
            case_lowerb (zone, zonelen);
            response_id (header);
            response[3] &= ~128;
            if (!(header[2] & 1))
                response[2] &= ~1;
            if (!respond (zone, qtype, ip))
                errx (-1, "could not find information in file `data.cdb'");
            print (response, response_len);
        }
    }
}
示例#22
0
int main()
{
  unsigned int pos;
  char header[12];
  char qtype[2];
  char qclass[2];
  const char *x;

  droproot(FATAL);
  dns_random_init(seed);

  axfr = env_get("AXFR");
  
  x = env_get("TCPREMOTEIP");
  if (x && ip6_scan(x,ip))
    ;
  else
    byte_zero(ip,16);

  x = env_get("TCPREMOTEPORT");
  if (!x) x = "0";
  scan_ulong(x,&port);

  for (;;) {
    netread(tcpheader,2);
    uint16_unpack_big(tcpheader,&len);
    if (len > 512) strerr_die2x(111,FATAL,"excessively large request");
    netread(buf,len);

    pos = dns_packet_copy(buf,len,0,header,12); if (!pos) die_truncated();
    if (header[2] & 254) strerr_die2x(111,FATAL,"bogus query");
    if (header[4] || (header[5] != 1)) strerr_die2x(111,FATAL,"bogus query");

    pos = dns_packet_getname(buf,len,pos,&zone); if (!pos) die_truncated();
    zonelen = dns_domain_length(zone);
    pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) die_truncated();
    pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) die_truncated();

    if (byte_diff(qclass,2,DNS_C_IN) && byte_diff(qclass,2,DNS_C_ANY))
      strerr_die2x(111,FATAL,"bogus query: bad class");

    pos = check_edns0(header, buf, len, pos);
    if (!pos) die_truncated();

    qlog(ip,port,header,zone,qtype," ");

    if (byte_equal(qtype,2,DNS_T_AXFR)) {
      case_lowerb(zone,zonelen);
      fdcdb = open_read("data.cdb");
      if (fdcdb == -1) die_cdbread();
      doaxfr(header);
      close(fdcdb);
    }
    else {
      if (!response_query(zone,qtype,qclass)) nomem();
      response[2] |= 4;
      case_lowerb(zone,zonelen);
      response_id(header);
      response[3] &= ~128;
      if (!(header[2] & 1)) response[2] &= ~1;
      if (!respond(zone,qtype,ip)) die_outside();
      print(response,response_len);
    }
  }
}