Ejemplo n.º 1
0
uint16_t qtype_getcode(const char *name, bool allow_qtype) {
  try {
    uint16_t ret = txt_to_int(name);
    if (!is_common_rr(ret)) throw PException();
    return ret;
  } catch (PException p) {
    if (allow_qtype) {
      if (strcmpi(name, "maila") == 0) return QTYPE_MAILA;
      if (strcmpi(name, "mailb") == 0) return QTYPE_MAILB;
      if (strcmpi(name, "ixfr") == 0) return QTYPE_IXFR;
      if (strcmpi(name, "axfr") == 0) return QTYPE_AXFR;
      if (strcmpi(name, "any") == 0) return QTYPE_ANY;
      if (strcmpi(name, "all") == 0) return QTYPE_ANY;
    }  
    rr_type *t = rrtype_getinfo(name);
    if (!t) throw PException(true, "Qtype %s not supported", name);
    return t->type;
  }
}
Ejemplo n.º 2
0
void rr_read(u_int16 RRTYPE, unsigned char*& RDATA, uint16_t &RDLEN, message_buff &buff, int ix, int len) {
  rr_type *info = rrtype_getinfo(RRTYPE);
  char *ptr;
  stl_string res;
  _domain dom;

  if (ix + len > buff.len) throw PException("RR doesn't fit in DNS message");

  if (info) {
    /* we support the RR type */
    try {
      ptr = info->properties;
      while (*ptr) {
          int x;
          x = rr_len(*ptr, buff, ix, len);
          if (x > len) throw PException("RR item too long!");
          if (*ptr == 'd' || *ptr == 'm') {
              /* domain name: needs to be decompressed */
              dom = dom_uncompress(buff, ix);
              res.append((char*)dom, domlen(dom));
              free(dom);
          } else {
              res.append((char*)buff.msg + ix, x);
          }
          
          ix += x;
          len -= x;
          
          ptr++;
      }
      if (len != 0) throw PException("extra data in RR");
    } catch(PException p) {
      throw PException("Parsing RR failed: ", p);
    }
    if (len != 0) throw PException("RR length too long");
  } else {
    /* we do not support the RR type: just copy it altogether */
    res.append((char*)buff.msg + ix, len);
  }
  RDLEN = res.length();
  RDATA = (unsigned char *)memdup((void *)res.c_str(), res.length());
}
Ejemplo n.º 3
0
char *rrtype_getname(u_int16 type) {
  rr_type *info = rrtype_getinfo(type);
  if (info) return info->name; else return NULL;
}
Ejemplo n.º 4
0
      }
      if (len != 0) throw PException("extra data in RR");
    } catch(PException p) {
      throw PException("Parsing RR failed: ", p);
    }
    if (len != 0) throw PException("RR length too long");
  } else {
    /* we do not support the RR type: just copy it altogether */
    res.append((char*)buff.msg + ix, len);
  }
  RDLEN = res.length();
  RDATA = (unsigned char *)memdup((void *)res.c_str(), res.length());
}

void rr_write(u_int16 RRTYPE, unsigned char *RDATA, uint16_t RDLEN, stl_string &dnsmessage, stl_slist(dom_compr_info) *comprinfo) {
  rr_type *info = rrtype_getinfo(RRTYPE);
  char *ptr;
  int len, ix = 0;
  message_buff rrbuff(RDATA, RDLEN);

  if (!info || !(info->flags & R_COMPRESS) || !comprinfo) {
    dnsmessage.append((char*)RDATA, RDLEN);
    return;
  }

  ptr = info->properties;
  while (*ptr) {
    len = rr_len(*ptr, rrbuff, ix, RDLEN - ix);
    if ((*ptr == 'd' || *ptr == 'm') && comprinfo) {
      /* compress dname */
      dom_write(dnsmessage, RDATA + ix, comprinfo);
Ejemplo n.º 5
0
void read_master_file(const char *file, domainname &znroot, void *userdat,
                      error_callback err, rr_callback rr_cb, rr_literal_callback rrl_cb,
                      comment_callback comm_cb, int flags) {
  bool has_znroot = !(flags&POSLIB_MF_AUTOPROBE), has_soa = false;
  char buff[1024];
  char *ptr, *p2;
  int c;
  bool ttl_given = false; stl_string ttl = "3600";
  domainname origin, nam;
  int linenum = 1, linenum2;
  stl_string str, tmp, t2, t3, nm;
  DnsRR rr;
  rr_type *type = NULL;
  
  FILE *f = try_fopen_r(file);
  if (!f) throw PException(true, "Could not open %s", file);
  
  c = fgetc(f);
  if (c != EOF) ungetc(c, f);
		
	if (has_znroot) origin = znroot;

  try {
  begin:
    while (!feof(f)) {
      /* since the poslib functions will filter out comments, let's do them ourselves */
      if (comm_cb) {
        c = fgetc(f);
        if (c == ';') {
            fgets(buff, 1024, f);
	    ptr = buff + strlen(buff) - 1;
	    while (ptr >= buff && (*ptr == '\n' || *ptr == '\r')) *ptr = '\0';
	    comm_cb(userdat, buff);
	    continue;
        }
        ungetc(c, f);
      }

      try {
        read_line(buff, f, &linenum, &linenum2);
      } catch (PException p) {
        break;
      }

      if (buff[0] == 0) goto begin;
      ptr = buff;
      while (*ptr == ' ' || *ptr == '\t') ptr++;
      if (*ptr == '\0') continue;

      if (buff[0] == '$') {
        if (strncmpi(buff, "$ttl ", 4) == 0) {
          ttl = buff + 5;
          ttl_given = true;
        } else if (strncmpi(buff, "$origin ", 8) == 0) {
          /* origin */
          origin = domainname(buff + 8, znroot);
          if (!has_znroot) {
            /* first entry. this is the zone root */
            znroot = origin;
            has_znroot = true;
          }
        } else err(userdat, file, linenum2,
                   PException(true, "Unknown directive %s", buff).message);
        continue;
      }

      if (!has_znroot) {
        znroot = guess_zone_name(file);
        origin =  znroot;
        has_znroot = true;
      }

      if (buff[0] != ' ' && buff[0] != '\t') {
        nam = domainname(read_entry(ptr).c_str(), origin);
      } else if (!has_soa) {
        err(userdat, file, linenum2, "First record in zone should have a domain name! Using origin instead.");
        nam = origin;
      }

      /* can be class or ttl or rrtype */
      while (1) {
        str = read_entry(ptr);
        if (str == "IN" || str == "HS" || str == "CH" || str == "HS" ||
            str == "in" || str == "hs" || str == "ch" || str == "hs") {
          /* class */
          continue;
        } else if ((type = rrtype_getinfo(str.c_str())) != NULL) {
          break;
        } else {
          try {
            txt_to_int(str.c_str());
            ttl_given = true;
          } catch (PException p) {
            err(userdat, file, linenum2, PException(true, "Invalid TTL/RR type %s!", str.c_str()).message);
            goto begin;
          }
          ttl = str.c_str();
        }
      }

      if (!has_soa) {
        if (type->type != DNS_TYPE_SOA) {
          if (!(flags & POSLIB_MF_NOSOA)) {
            err(userdat, file, linenum2, "First record was no SOA record; using default SOA record instead.");
            if (rr_cb) {
              rr.NAME = znroot;
              rr.TYPE = DNS_TYPE_SOA;
              rr.TTL = 3600;
              tmp = rr_fromstring(DNS_TYPE_SOA, "ns1 hostmaster 1 2h 1h 1d 2h", znroot);
              rr.RDLENGTH = tmp.size();
              rr.RDATA = (unsigned char *)memdup(tmp.c_str(), tmp.size());
              rr_cb(userdat, &rr);
            }
            if (rrl_cb)
              rrl_cb(userdat, "@", "1h", "SOA", "ns1 hostmaster 1 2h 1h 1d 2h", znroot);
          } else if (!ttl_given) {
            err(userdat, file, linenum2, "First record should have TTL value; using 1h for now.");
            ttl = "3600";
            ttl_given = true;
          }
        } else {
          if (!ttl_given) {
            p2 = ptr;
            read_entry(p2); read_entry(p2); read_entry(p2);
            read_entry(p2); read_entry(p2); read_entry(p2);
            t3 = read_entry(p2);
            if (strlen(t3.c_str()) < 32) ttl = t3;
          }
        }
        has_soa = true;
      } else if (type->type == DNS_TYPE_SOA && !(flags & POSLIB_MF_NOSOA)) {
        err(userdat, file, linenum2, "Non-initial SOA record ignored");
        continue;
      }

      if (!(nam >= znroot)) {
        err(userdat, file, linenum2, PException(true, "Ignoring domain name %s outside of zone %s!", nam.tocstr(), znroot.tocstr()).message);
        continue;
      }

      if (rr_cb) {
        try {
          rr.NAME = nam;
          rr.TYPE = type->type;
          rr.TTL = txt_to_int(ttl.c_str());
          tmp = rr_fromstring(type->type, ptr, origin);
          rr.RDLENGTH = tmp.size();
          rr.RDATA = (unsigned char *)memdup(tmp.c_str(), tmp.size());
          rr_cb(userdat, &rr);
        } catch (PException p) {
          err(userdat, file, linenum2, p.message);
        }
      }

      if (rrl_cb) {
        try {
          t2 = ptr;
          nm = nam.torelstring(znroot);
          tmp = rr_fromstring(type->type, ptr, origin);
          if (origin != znroot) t2 = rrdata_convertdoms(type, znroot, origin, ptr);
        } catch (PException p) {
          err(userdat, file, linenum2, p.message);
        }
        rrl_cb(userdat, nm.c_str(), ttl.c_str(), type->name, t2.c_str(), znroot);
      }
    }
  } catch (PException p) {
    fclose(f);
    throw p;
  }
  fclose(f);
}