示例#1
0
int response_cname(const char *c,const char *d,uint32 ttl)
{
  if (!response_rstart(c,DNS_T_CNAME,ttl)) return 0;
  if (!response_addname(d)) return 0;
  response_rfinish(RESPONSE_ANSWER);
  return 1;
}
示例#2
0
int response_cname(char *c,char *d)
{
  if (!response_rstart(c,DNS_T_CNAME,"\0\0\0\0")) return 0;
  if (!response_addname(d)) return 0;
  response_rfinish(RESPONSE_ANSWER);
  return 1;
}
示例#3
0
int response_rstart(char *d,char type[2],char ttl[4])
{
  if (!response_addname(d)) return 0;
  if (!response_addbytes(type,2)) return 0;
  if (!response_addbytes(DNS_C_IN,2)) return 0;
  if (!response_addbytes(ttl,4)) return 0;
  if (!response_addbytes("\0\0",2)) return 0;
  dpos = response_len;
  return 1;
}
示例#4
0
int response_query(char *q,char qtype[2])
{
  response_len = 0;
  name_num = 0;
  if (!response_addbytes("\0\0\201\200\0\1\0\0\0\0\0\0",12)) return 0;
  if (!response_addname(q)) return 0;
  if (!response_addbytes(qtype,2)) return 0;
  if (!response_addbytes(DNS_C_IN,2)) return 0;
  tctarget = response_len;
  return 1;
}
示例#5
0
int response_rstart(const char *d,const char type[2],uint32 ttl)
{
  char ttlstr[4];
  if (!response_addname(d)) return 0;
  if (!response_addbytes(type,2)) return 0;
  if (!response_addbytes(DNS_C_IN,2)) return 0;
  if (flaghidettl) ttl = 0;
  uint32_pack_big(ttlstr,ttl);
  if (!response_addbytes(ttlstr,4)) return 0;
  if (!response_addbytes("\0\0",2)) return 0;
  dpos = response_len;
  return 1;
}
示例#6
0
int
response_query (const char *q, const char qtype[2], const char qclass[2])
{
    response_len = name_num = 0;

    if (!response_addbytes ("\0\0\201\200\0\1\0\0\0\0\0\0", 12))
        return 0;
    if (!response_addname (q))
        return 0;
    if (!response_addbytes (qtype, 2))
        return 0;
    if (!response_addbytes (qclass, 2))
        return 0;

    tctarget = response_len;

    return 1;
}
示例#7
0
static int doname(void)
{
  dpos = dns_packet_getname(data,dlen,dpos,&d1);
  if (!dpos) return 0;
  return response_addname(d1);
}
示例#8
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) {
      /* q is not within our bailiwick */
      flagfound = 0;
      if (byte_diff(lameip,4,"\0\0\0\0"))
	if (byte_equal(qtype,2,DNS_T_A) || byte_equal(qtype,2,DNS_T_ANY)) {
	  if (!response_rstart(q,DNS_T_A,3600)) return 0;
	  if (!response_addbytes(lameip,4)) return 0;
	  response_rfinish(RESPONSE_ANSWER);
	  flagfound = 1;
	}
      if (lamemx)
	if (byte_equal(qtype,2,DNS_T_MX) || byte_equal(qtype,2,DNS_T_ANY)) {
	  if (!response_rstart(q,DNS_T_MX,3600)) return 0;
	  if (!response_addbytes("\0\0",2)) return 0;
	  if (!response_addname(lamemx)) return 0;
	  response_rfinish(RESPONSE_ANSWER);
	  flagfound = 1;
	}
      if (lametxt.len)
	if (byte_equal(qtype,2,DNS_T_TXT) || byte_equal(qtype,2,DNS_T_ANY)) {
	  if (!response_rstart(q,DNS_T_TXT,3600)) return 0;
	  if (!response_addbytes(lametxt.s,lametxt.len)) return 0;
	  response_rfinish(RESPONSE_ANSWER);
	  flagfound = 1;
	}
      if (flagfound) return 2;
      return 0;
    }
    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;
}