コード例 #1
0
ファイル: dns_rcip.c プロジェクト: qsuscs/ezmlm-idx
static int init(char ip[64])
{
  int i;
  unsigned int j;
  int iplen = 0;
  char *x;

  x = env_get("DNSCACHEIP");
  if (x)
    while (iplen <= 60) {
      if (*x == '.')
	++x;
      else {
        i = ip4_scan(x,ip + iplen);
	if (!i) break;
	x += i;
	iplen += 4;
      }
    }

  if (!iplen) {
    i = openreadclose("/etc/resolv.conf",&data,64);
    if (i == -1) return -1;
    if (i) {
      if (!stralloc_append(&data,'\n')) return -1;
      i = 0;
      for (j = 0;j < data.len;++j)
        if (data.s[j] == '\n') {
          if (byte_equal("nameserver ",11,data.s + i) || byte_equal("nameserver\t",11,data.s + i)) {
            i += 10;
            while ((data.s[i] == ' ') || (data.s[i] == '\t'))
              ++i;
            if (iplen <= 60)
              if (ip4_scan(data.s + i,ip + iplen)) {
		if (byte_equal(ip + iplen,4,"\0\0\0\0"))
		  byte_copy(ip + iplen,4,"\177\0\0\1");
                iplen += 4;
	      }
          }
          i = j + 1;
        }
    }
  }

  if (!iplen) {
    byte_copy(ip,4,"\177\0\0\1");
    iplen = 4;
  }
  byte_zero(ip + iplen,64 - iplen);
  return 0;
}
コード例 #2
0
ファイル: server.c プロジェクト: kjseefried/didentd
main()
{
  char *x;
  int udp53;

  x = env_get("IP");
  if (!x)
    strerr_die2x(111,fatal,"$IP not set");
  if (!ip4_scan(x,ip))
    strerr_die3x(111,fatal,"unable to parse IP address ",x);

  udp53 = socket_udp();
  if (udp53 == -1)
    strerr_die2sys(111,fatal,"unable to create UDP socket: ");
  if (socket_bind4_reuse(udp53,ip,53) == -1)
    strerr_die2sys(111,fatal,"unable to bind UDP socket: ");

  droproot(fatal);

  initialize();
  
  ndelay_off(udp53);
  socket_tryreservein(udp53,65536);

  for (;;) {
    len = socket_recv4(udp53,buf,sizeof buf,ip,&port);
    if (len < 0) continue;
    if (!doit()) continue;
    if (response_len > 512) response_tc();
    socket_send4(udp53,response,response_len,ip,port);
    /* may block for buffer space; if it fails, too bad */
  }
}
コード例 #3
0
ファイル: tdlookup.c プロジェクト: gislik/djbdns-1.05g
int tdlookup_init(void)
{
  char *x;
  char ch;
  int i;
  int j;
  int k;

  x = env_get("LAME_A");
  if (x)
    if (!ip4_scan(x,lameip))
      byte_zero(lameip,4);

  x = env_get("LAME_MX");
  if (x)
    if (!dns_domain_fromdot(&lamemx,x,str_len(x)))
      return 0;

  x = env_get("LAME_TXT");
  if (x) {
    i = 0;
    j = str_len(x);
    while (i < j) {
      k = j - i;
      if (k > 255) k = 255;
      ch = k;
      if (!stralloc_append(&lametxt,&ch)) return 0;
      if (!stralloc_catb(&lametxt,x + i,k)) return 0;
      i += k;
    }
  }

  return 1;
}
コード例 #4
0
ファイル: dnsname.c プロジェクト: siddhesh/djbdns
int
main (int argc, char *argv[])
{
    int n = 0;
    char *x = NULL;
    dns_random_init (seed);

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

    while (*argv)
    {
        if (!ip4_scan (*argv, ip))
            errx (-1, "could not parse IP address `%s'", *argv);
        if (dns_name4 (&out, ip) == -1)
            errx (-1, "could not find host name for `%s'", *argv);

        buffer_put (buffer_1, out.s, out.len);
        buffer_puts (buffer_1,"\n");

        ++argv;
    }
    buffer_flush (buffer_1);

    return 0;
}
コード例 #5
0
ファイル: ip46_scan.c プロジェクト: rlonstein/skalibs
unsigned int ip46_scan (char const *s, ip46_t_ref ip)
{
  unsigned int len = ip6_scan(s, ip->ip) ;
  if (len) ip->is6 = 1 ;
  else
  {
    len = ip4_scan(s, ip->ip) ;
    if (len) ip->is6 = 0 ;
  }
  return len ;
}
コード例 #6
0
ファイル: dns_ip6.c プロジェクト: mdornseif/ddns
static int doit(stralloc *out,stralloc *fqdn)
{
  unsigned int i;
  char code;
  char ch;
  char ip[16];

  if (!stralloc_copys(out,"")) return -1;
  if (!stralloc_readyplus(fqdn,1)) return -1;
  fqdn->s[fqdn->len]=0;
  if ((i=ip6_scan(fqdn->s,ip))) {
    if (!fqdn->s[i]) {
      stralloc_copyb(out,ip,16);
      return 0;
    }
  }
  if ((i=ip4_scan(fqdn->s,ip+12))) {
    if (!fqdn->s[i]) {
      byte_zero(ip,10);
      ip[10]=ip[11]=0xff;
      stralloc_copyb(out,ip,16);
      return 0;
    }
  }
  code = 0;
  for (i = 0;i <= fqdn->len;++i) {
    if (i < fqdn->len)
      ch = fqdn->s[i];
    else
      ch = '.';

    if ((ch == '[') || (ch == ']')) continue;
    if (ch == '.') {
      if (!stralloc_append(out,&code)) return -1;
      code = 0;
      continue;
    }
    if ((ch >= '0') && (ch <= '9')) {
      code *= 10;
      code += ch - '0';
      continue;
    }

    if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1;
    if (dns_resolve(q,DNS_T_AAAA) == -1) return -1;
    if (dns_ip6_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1;
    dns_transmit_free(&dns_resolve_tx);
    dns_domain_free(&q);
    return 0;
  }

  out->len &= ~3;
  return 0;
}
コード例 #7
0
unsigned int ip4_scanlist (char *out, unsigned int max, char const *s, unsigned int *num)
{
  unsigned int n = 0, w = 0 ;
  for (; s[w] && (n < max) ; n++)
  {
    register unsigned int i = ip4_scan(s + w, out + (n << 2)) ;
    if (!i) break ;
    w += i ;
    while (byte_chr(",:; \t\r\n", 7, s[w]) < 7) w++ ;
  }
  *num = n ;
  return w ;
}
コード例 #8
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;
    }
  }
}
コード例 #9
0
ファイル: tinydns-get.c プロジェクト: hiro-dSn/djbdns
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);
}
コード例 #10
0
ファイル: dnsname.c プロジェクト: GunioRobot/djbdns
int main(int argc,char **argv)
{
  dns_random_init(seed);

  if (*argv) ++argv;

  while (*argv) {
    if (!ip4_scan(*argv,ip))
      strerr_die3x(111,FATAL,"unable to parse IP address ",*argv);
    if (dns_name4(&out,ip) == -1)
      strerr_die4sys(111,FATAL,"unable to find host name for ",*argv,": ");

    buffer_put(buffer_1,out.s,out.len);
    buffer_puts(buffer_1,"\n");

    ++argv;
  }

  buffer_flush(buffer_1);
  _exit(0);
}
コード例 #11
0
ファイル: vdnsdb.c プロジェクト: malfaux/geoipdns
int main(int argc, char **argv)
{
  int fddata;
	uint32 loc;
	//int v;
	char ipa[4];
	//char ipb[4];
	//ip4_cidr_t *subnets = (ip4_cidr_t *)NULL;
	//unsigned int slen = 0;
	uint32 ipinta = 0U;
	//unsigned int ipintb = 0;
	unsigned short mask;
	uint32 uid = 0;
	uint32  mid = 0;
  int i;
  int j;
  int k;
  char ch;
  unsigned long ttl;
  char ttd[8];
  //uint32 loc;
	unsigned char keyloc[15];
  unsigned long u;
  char ip[4];
	char locp[4];
	//char map[9];
  char type[2];
  char soa[20];
  char buf[4];
  //int namlen = 0;
  umask(022);
  fddata = STDIN_FILENO;
	if (argc != 3) {
    fddata = open_read("data");
		if (fddata == -1) strerr_die2sys(111,FATAL,"unable to open data: ");
		if ( (fdcdb = open_trunc("data.tmp")) == -1) die_datatmp();
	} else {
		fddata = STDIN_FILENO;
		if ( (fdcdb = open_trunc(argv[1])) == -1) die_datatmp();
	}
	
  defaultsoa_init(fddata);

  buffer_init(&b,buffer_unixread,fddata,bspace,sizeof bspace);

  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;
    if (line.s[0] == '#') continue;
    if (line.s[0] == '-') continue;
		//write(1,line.s,line.len);
		//write(1,"\n",1);
    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]) {
#ifdef USE_LOCMAPS
	case '%':
		//locparse(&f[0],loc);
		loc = gethash(f[0].s,f[0].len);
		uint32_pack(locp,loc);
		if (!stralloc_0(&f[1])) nomem();
		if (!stralloc_0(&f[2])) nomem();
		ip4_scan(f[1].s,ipa);
		//ip4_scan(f[2].s,ipb);
		scan_ushort(f[2].s,&mask);
		ip4_num(&ipinta,ipa);
		//ip4_num(&ipintb,ipb);
		//if (ipintb<ipinta) nomem();
		//if (ip4_deaggregate(ipinta,ipintb,&subnets,&slen) <= 0) nomem();
		mid = gethash(f[3].s,f[3].len);
		uid = gethash(f[4].s,f[4].len);
		//for (v = 0; v < slen; v++) {
		ipdb_key4build(keyloc,ipinta,(unsigned char )mask&0xff,mid,uid);
		//ipdb_key_from_uint(keyloc,ipinta,(unsigned char )mask&0xff,0,mid,uid);
		cdb_make_add(&cdb,keyloc,15,locp,4);
		//}
		uid = 0;
		//alloc_free(subnets);
		//subnets = NULL;
		//slen = 0;
		byte_zero(ipa,4);ipinta=0; //byte_zero(ipb,4);ipinta=0;ipintb=0;
		break;
#endif
 	case 'Z':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();

		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&u)) uint32_unpack_big(defaultsoa,&u);
		uint32_pack_big(soa,u);
		if (!stralloc_0(&f[4])) nomem();
		if (!scan_ulong(f[4].s,&u)) uint32_unpack_big(defaultsoa + 4,&u);
		uint32_pack_big(soa + 4,u);
		if (!stralloc_0(&f[5])) nomem();
		if (!scan_ulong(f[5].s,&u)) uint32_unpack_big(defaultsoa + 8,&u);
		uint32_pack_big(soa + 8,u);
		if (!stralloc_0(&f[6])) nomem();
		if (!scan_ulong(f[6].s,&u)) uint32_unpack_big(defaultsoa + 12,&u);
		uint32_pack_big(soa + 12,u);
		if (!stralloc_0(&f[7])) nomem();
		if (!scan_ulong(f[7].s,&u)) uint32_unpack_big(defaultsoa + 16,&u);
		uint32_pack_big(soa + 16,u);

		if (!stralloc_0(&f[8])) nomem();
		if (!scan_ulong(f[8].s,&ttl)) ttl = TTL_NEGATIVE;
		ttdparse(&f[9],ttd);
		loc = gethash(f[10].s,f[10].len);
		mid = gethash(f[11].s,f[11].len);
		uid = gethash(f[12].s,f[12].len);
		rr_addloq(DNS_T_SOA,d1,loc,mid,uid);

		rr_start(DNS_T_SOA,ttl,ttd,loc);
		if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
		rr_addname(d2);
		if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
		rr_addname(d2);
		rr_add(soa,20);
		rr_finish(d1);
		break;

	case '.': case '&':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS;
		ttdparse(&f[4],ttd);
		loc = gethash(f[5].s,f[5].len);
		mid = gethash(f[6].s,f[6].len);
		uid = gethash(f[7].s,f[7].len);

		if (!stralloc_0(&f[1])) nomem();

		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 (line.s[0] == '.') {
			rr_start(DNS_T_SOA,ttl ? TTL_NEGATIVE : 0,ttd,loc);
			rr_addloq(DNS_T_SOA,d1,loc,mid,uid);
			rr_addname(d2);
			rr_add("\12hostmaster",11);
			rr_addname(d1);
			rr_add(defaultsoa,20);
			rr_finish(d1);
		}

		rr_start(DNS_T_NS,ttl,ttd,loc);
		rr_addname(d2);
		rr_addloq(DNS_T_NS,d2,loc,mid,uid);
		rr_finish(d1);

		if (ip4_scan(f[1].s,ip)) {
	  	rr_start(DNS_T_A,ttl,ttd,loc);
			rr_addloq(DNS_T_A,d2,loc,mid,uid);
			rr_add(ip,4);
			rr_finish(d2);
		}

		break;

	case '+': case '=':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[2])) nomem();
		if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[3],ttd);
		loc = gethash(f[4].s,f[4].len);
		mid = gethash(f[5].s,f[5].len);
		uid = gethash(f[6].s,f[6].len);

		if (!stralloc_0(&f[1])) nomem();

		if (ip4_scan(f[1].s,ip)) {
			rr_addloq(DNS_T_A,d1,loc,mid,uid);
			rr_start(DNS_T_A,ttl,ttd,loc);
			//dbger("+addloq:d=%s,loc=%u,uid=%u,mid=%u",d1,loc,uid,mid);
			rr_add(ip,4);
			rr_finish(d1);

			if (line.s[0] == '=') {
				rr_addloq(DNS_T_PTR,d1,loc,mid,uid); //??????????????????/ TODO: checkthis
				dns_name4_domain(dptr,ip);
				rr_start(DNS_T_PTR,ttl,ttd,loc);
				rr_addname(d1);
				rr_finish(dptr);
			}
		}
		break;

	case '@':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[4])) nomem();
		if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[5],ttd);
		loc = gethash(f[6].s,f[6].len);
		mid = gethash(f[7].s,f[7].len);
		uid = gethash(f[8].s,f[8].len);

		if (!stralloc_0(&f[1])) nomem();

		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[3])) nomem();
		if (!scan_ulong(f[3].s,&u)) u = 0;

		rr_addloq(DNS_T_MX,d1,loc,mid,uid);
		rr_start(DNS_T_MX,ttl,ttd,loc);
		uint16_pack_big(buf,u);
		rr_add(buf,2);
		rr_addname(d2);
		rr_finish(d1);

		if (ip4_scan(f[1].s,ip)) {
			rr_addloq(DNS_T_A,d2,loc,mid,uid);
			rr_start(DNS_T_A,ttl,ttd,loc);
			rr_add(ip,4);
			rr_finish(d2);
		}
		break;

	case '^': case 'C':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
		if (!stralloc_0(&f[2])) nomem();
		if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[3],ttd);
		loc = gethash(f[4].s,f[4].len);
		mid = gethash(f[5].s,f[5].len);
		uid = gethash(f[6].s,f[6].len);

		if (line.s[0] == 'C') {
			//rr_addloq(DNS_T_CNAME,d1,loc,mid,uid);
			//dbger("add loq for cname!");
			rr_addloq(DNS_T_A,d1,loc,mid,uid);
			rr_addloq(DNS_T_CNAME,d1,loc,mid,uid);
			rr_start(DNS_T_CNAME,ttl,ttd,loc);
		} else {
			rr_addloq(DNS_T_PTR,d1,loc,mid,uid);
			rr_start(DNS_T_PTR,ttl,ttd,loc);
		}
		rr_addname(d2);
		rr_finish(d1);
		break;

	case '\'':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[2])) nomem();
		if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[3],ttd);
		loc = gethash(f[4].s,f[4].len);
		mid = gethash(f[5].s,f[5].len);
		uid = gethash(f[6].s,f[6].len);

		rr_addloq(DNS_T_TXT,d1,loc,mid,uid);
		rr_start(DNS_T_TXT,ttl,ttd,loc);
		txtparse(&f[1]);
		i = 0;
		while (i < f[1].len) {
			k = f[1].len - i;
			if (k > 127) k = 127;
			ch = k;
			rr_add(&ch,1);
			rr_add(f[1].s + i,k);
			i += k;
		}

		rr_finish(d1);
		break;

	case ':':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[4],ttd);
		loc = gethash(f[5].s,f[5].len);
		mid = gethash(f[6].s,f[6].len);
		uid = gethash(f[7].s,f[7].len);

		if (!stralloc_0(&f[1])) nomem();
		scan_ulong(f[1].s,&u);
		uint16_pack_big(type,u);
		if (byte_equal(type,2,DNS_T_AXFR))
			syntaxerror(": type AXFR prohibited");
		if (byte_equal(type,2,"\0\0"))
			syntaxerror(": type 0 prohibited");
		if (byte_equal(type,2,DNS_T_SOA))
			syntaxerror(": type SOA prohibited");
		if (byte_equal(type,2,DNS_T_NS))
			syntaxerror(": type NS prohibited");
		if (byte_equal(type,2,DNS_T_CNAME))
			syntaxerror(": type CNAME prohibited");
		if (byte_equal(type,2,DNS_T_PTR))
			syntaxerror(": type PTR prohibited");
		if (byte_equal(type,2,DNS_T_MX))
			syntaxerror(": type MX prohibited");
		txtparse(&f[2]);
		rr_addloq(type,d1,loc,mid,uid);
		rr_start(type,ttl,ttd,loc);
		rr_add(f[2].s,f[2].len);
		rr_finish(d1);
		break;
	default:
		dienow("error here: %s\n", line.s);
		syntaxerror(": unrecognized leading character");
}
}

  if (cdb_make_finish(&cdb) == -1) die_datatmp();
  if (fsync(fdcdb) == -1) die_datatmp();
  if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */
	if (argc  == 3) {
		if (rename(argv[1],argv[2]) == -1) strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");
	} else {
		if (rename("data.tmp","data.cdb") == -1) strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");
	}

  _exit(0);
}
コード例 #12
0
ファイル: tinydns-edit.c プロジェクト: axlecrusher/djbdns
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);
}
コード例 #13
0
ファイル: rbldns-data.c プロジェクト: siddhesh/djbdns
int main()
{
    char ip[4];
    unsigned long u;
    unsigned int j;
    unsigned int k;
    char ch;

    umask(022);

    fd = open_read("data");
    if (fd == -1) strerr_die2sys(111,FATAL,"unable to open data: ");
    buffer_init(&b,buffer_unixread,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;

        switch(line.s[0]) {
        default:
            syntaxerror(": unrecognized leading character");
        case '#':
            break;
        case ':':
            j = byte_chr(line.s + 1,line.len - 1,':');
            if (j >= line.len - 1) syntaxerror(": missing colon");
            if (ip4_scan(line.s + 1,ip) != j) syntaxerror(": malformed IP address");
            if (!stralloc_copyb(&tmp,ip,4)) nomem();
            if (!stralloc_catb(&tmp,line.s + j + 2,line.len - j - 2)) nomem();
            if (cdb_make_add(&cdb,"",0,tmp.s,tmp.len) == -1)
                die_datatmp();
            break;
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            if (!stralloc_0(&line)) nomem();
            j = 0;
            if (!stralloc_copys(&tmp,"")) nomem();
            for (;;) {
                k = scan_ulong(line.s + j,&u);
                if (!k) break;
                ch = u;
                if (!stralloc_catb(&tmp,&ch,1)) nomem();
                j += k;
                if (line.s[j] != '.') break;
                ++j;
            }
            if (!stralloc_catb(&tmp,"\0\0\0\0",4)) nomem();
            tmp.len = 4;
            if (line.s[j] == '/')
                scan_ulong(line.s + j + 1,&u);
            else
                u = 32;
            if (u > 32) u = 32;
            ch = u;
            if (!stralloc_catb(&tmp,&ch,1)) nomem();
            if (cdb_make_add(&cdb,tmp.s,tmp.len,"",0) == -1)
                die_datatmp();
            break;
        }
    }

    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: ");

    return 0;
}
コード例 #14
0
ファイル: filedns.c プロジェクト: mdornseif/ddns
/* this is out work routine which is called by DJBs server code */
int respond(char *q, char qtype[2])
{
  int flaga;
  int flagaaaa;
  int flagloc;
  char ip[IP6_FMT];
  stralloc filename = { 0 };
  int fd;
  buffer b;
  char bspace[1024];
  static stralloc line;
  int match = 1;
  unsigned long linenum = 0;
  int data = 0;
  stralloc f[NUMFIELDS] = {{0}};

  /* check what the client is requesting */
  flaga = byte_equal(qtype,2,DNS_T_A);
  flagloc = byte_equal(qtype,2,DNS_T_LOC);
  flagaaaa = byte_equal(qtype,2,DNS_T_AAAA);
  if (byte_equal(qtype,2,DNS_T_ANY)) flaga = flagloc = flagaaaa = 1;
  
  /* find out in which file we should look */
  query2filename(q, &filename);

  buffer_put(buffer_2, filename.s, filename.len);
  buffer_puts(buffer_2, "\n");
  buffer_flush(buffer_2);

  fd = open_read(filename.s);
  if (fd == -1) 
    {
      strerr_warn3("unable to open file: ", filename.s, ": ", &strerr_sys);
      match = 0;
    }
  
  buffer_init(&b, read, fd, bspace, sizeof bspace);

  /* Work through the file and handout the data. */
   while(match) 
    {
      ++linenum;
      if(getln(&b, &line, &match, '\n') == -1)
	{
	  strerr_warn1("unable to read line: ", &strerr_sys);
	  break;
	}
  
      /* clean up line end */
      stralloc_cleanlineend(&line); 
      
      /* skip comments  & empty lines */
      if(line.s[0] == '#') continue;
      if(line.s[0] == 0) continue;
      
      /* seperate fields */
      fieldsep(f, NUMFIELDS, &line, ',');

      /* IPv4 */
      if(f[0].s[0] == '=')
	{
	  if (flaga) 
	    {
	      ip4_scan(f[2].s, ip);
	      data++;
	      /* put type and ttl (60s) */
	      if (!response_rstart(q, DNS_T_A, "\0\0\0\74")) return 0;
	      /* put ip */
	      if (!response_addbytes(ip, 4)) return 0;
	      /* record finished */
	      response_rfinish(RESPONSE_ANSWER);
	    }
	}

      /* IPv6 */
      if(f[0].s[0] == '6')
	{
	  if (flagaaaa) 
	    {
	      ip6_scan(f[0].s, ip);
	      data++;
	      /* put type and ttl (60s) */
	      if (!response_rstart(q, DNS_T_AAAA, "\0\0\0\74")) return 0;
	      /* put ip */
	      if (!response_addbytes(ip, 16)) return 0;
	      /* record finished */
	      response_rfinish(RESPONSE_ANSWER);
	    }
	}

      /* LOC */
      if(f[0].s[0] == 'L')
	{
	  if (flagloc) 
	    {
	      txtparse(&f[2]);
	      if(f[2].len <= 16)
		{		
		  buffer_puts(buffer_2, "filedns: warning: LOC record seems to short\n");
		  buffer_flush(buffer_2);
		}
	      data++;
	      /* put type and ttl (60s) */
	      if (!response_rstart(q, DNS_T_LOC, "\0\0\0\74")) return 0;
	      /* put ip */
	      if (!response_addbytes(f[2].s, 16)) return 0;
	      /* record finished */
	      response_rfinish(RESPONSE_ANSWER);
	    }
	}
    }
  
  /* Disclaimer ;-) */
  if (!response_rstart(q, DNS_T_TXT, "\0\0\0\74")) return 0;
  if (!response_addbytes("this is a response from an alpha quality dns-server", 51)) return 0;
  response_rfinish(RESPONSE_ADDITIONAL);
  if (!response_rstart(q, DNS_T_TXT, "\0\0\0\74")) return 0;
  if (!response_addbytes("filednes 0.00 - if problems arise contact [email protected]", 54)) return 0;
  response_rfinish(RESPONSE_ADDITIONAL);
  
  //  if (flaga || flagptr) 
  //    {
  //      if (dd(q,"",ip) == 4) 
  //	{
  //	  if (flaga) 
  //	    {
  //	      if (!response_rstart(q,DNS_T_A,"\0\12\0\0")) return 0;
  //	      if (!response_addbytes(ip,4)) return 0;
  //	      response_rfinish(RESPONSE_ANSWER);
  //	    }
  //	  return 1;
  //	}
  //      j = dd(q,"\7in-addr\4arpa",ip);
  //      if (j >= 0) 
  //	{
 
  if(data > 0) return 1;

  /* nothing found */
  buffer_puts(buffer_2, "notfound\n");
  buffer_flush(buffer_2);

  // XXX: this is somehow broken
  /* response 0-1 is transaction id */
  /* set response flags */
  /* clear authority bit */
  response[2] &= ~4;
  /* clear last 4 bits */
  response[3] &= ~15;
  /* flag not found */
  response[3] |= 3;
  
  /* response[4..5]:   nr of questions
   * response[6..7]:   nr of answers rr
   * response[8..9]:   nr of authority rr
   * response[10..11]: nr of additional rr
   */

  return 1;
}
コード例 #15
0
ファイル: dnsfilter.c プロジェクト: GunioRobot/djbdns
int main(int argc,char **argv)
{
  struct taia stamp;
  struct taia deadline;
  int opt;
  unsigned long u;
  int i;
  int j;
  int r;

  while ((opt = getopt(argc,argv,"c:l:")) != opteof)
    switch(opt) {
      case 'c':
	scan_ulong(optarg,&u);
	if (u < 1) u = 1;
	if (u > 1000) u = 1000;
	maxactive = u;
	break;
      case 'l':
	scan_ulong(optarg,&u);
	if (u < 1) u = 1;
	if (u > 1000000) u = 1000000;
	xmax = u;
	break;
      default:
	strerr_die1x(111,"dnsfilter: usage: dnsfilter [ -c concurrency ] [ -l lines ]");
    }

  x = (struct line *) alloc(xmax * sizeof(struct line));
  if (!x) nomem();
  byte_zero(x,xmax * sizeof(struct line));

  io = (iopause_fd *) alloc((xmax + 1) * sizeof(iopause_fd)); 
  if (!io) nomem();

  if (!stralloc_copys(&partial,"")) nomem();


  while (flag0 || inbuflen || partial.len || xnum) {
    taia_now(&stamp);
    taia_uint(&deadline,120);
    taia_add(&deadline,&deadline,&stamp);

    iolen = 0;

    if (flag0)
      if (inbuflen < sizeof inbuf) {
        inio = io + iolen++;
        inio->fd = 0;
        inio->events = IOPAUSE_READ;
      }

    for (i = 0;i < xnum;++i)
      if (x[i].flagactive) {
	x[i].io = io + iolen++;
	dns_transmit_io(&x[i].dt,x[i].io,&deadline);
      }

    iopause(io,iolen,&deadline,&stamp);

    if (flag0)
      if (inbuflen < sizeof inbuf)
        if (inio->revents) {
	  r = read(0,inbuf + inbuflen,(sizeof inbuf) - inbuflen);
	  if (r <= 0)
	    flag0 = 0;
	  else
	    inbuflen += r;
        }
    
    for (i = 0;i < xnum;++i)
      if (x[i].flagactive) {
	r = dns_transmit_get(&x[i].dt,x[i].io,&stamp);
	if (r == -1) {
	  errout(i);
	  x[i].flagactive = 0;
	  --numactive;
	}
	else if (r == 1) {
	  if (dns_name_packet(&x[i].middle,x[i].dt.packet,x[i].dt.packetlen) == -1)
	    errout(i);
	  if (x[i].middle.len)
	    if (!stralloc_cats(&x[i].left,"=")) nomem();
	  x[i].flagactive = 0;
	  --numactive;
	}
      }

    for (;;) {

      if (xnum && !x[0].flagactive) {
        buffer_put(buffer_1,x[0].left.s,x[0].left.len);
        buffer_put(buffer_1,x[0].middle.s,x[0].middle.len);
        buffer_put(buffer_1,x[0].right.s,x[0].right.len);
        buffer_flush(buffer_1);
        --xnum;
        tmp = x[0];
        for (i = 0;i < xnum;++i) x[i] = x[i + 1];
        x[xnum] = tmp;
	continue;
      }

      if ((xnum < xmax) && (numactive < maxactive)) {
        i = byte_chr(inbuf,inbuflen,'\n');
        if (inbuflen && (i == inbuflen)) {
	  if (!stralloc_catb(&partial,inbuf,inbuflen)) nomem();
	  inbuflen = 0;
	  continue;
        }

	if ((i < inbuflen) || (!flag0 && partial.len)) {
	  if (i < inbuflen) ++i;
	  if (!stralloc_catb(&partial,inbuf,i)) nomem();
	  inbuflen -= i;
	  for (j = 0;j < inbuflen;++j) inbuf[j] = inbuf[j + i];
  
	  if (partial.len) {
	    i = byte_chr(partial.s,partial.len,'\n');
	    i = byte_chr(partial.s,i,'\t');
	    i = byte_chr(partial.s,i,' ');
    
	    if (!stralloc_copyb(&x[xnum].left,partial.s,i)) nomem();
	    if (!stralloc_copys(&x[xnum].middle,"")) nomem();
	    if (!stralloc_copyb(&x[xnum].right,partial.s + i,partial.len - i)) nomem();
	    x[xnum].flagactive = 0;
  
	    partial.len = i;
	    if (!stralloc_0(&partial)) nomem();
	    if (ip4_scan(partial.s,ip)) {
	      dns_name4_domain(name,ip);
	      if (dns_resolvconfip(servers) == -1)
	        strerr_die2sys(111,FATAL,"unable to read /etc/resolv.conf: ");
	      if (dns_transmit_start(&x[xnum].dt,servers,1,name,DNS_T_PTR,"\0\0\0\0") == -1)
	        errout(xnum);
	      else {
	        x[xnum].flagactive = 1;
	        ++numactive;
	      }
	    }
	    ++xnum;
	  }
  
	  partial.len = 0;
	  continue;
	}
      }

      break;
    }
  }

  _exit(0);
}
コード例 #16
0
ファイル: tinydns-data.c プロジェクト: LordSpacehog/ndjbdns
int
main(int argc, char *argv[])
{
    int fddata = 0;
    unsigned int i = 0, j = 0, k = 0;

    unsigned long u = 0;
    unsigned long ttl = 0;

    char ch = 0;
    char *x = NULL;
    char ttd[8], loc[2];
    char ip[4], type[2];
    char soa[20], buf[4];

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

    umask(022);

    if ((fddata = open_read ("data")) == -1)
        err (-1, "could not open file `data'");
    defaultsoa_init (fddata);

    buffer_init (&b, buffer_unixread, fddata, bspace, sizeof bspace);

    if ((fdcdb = open_trunc ("data.tmp")) == -1)
        err (-1, "could not create file `data.tmp'");
    if (cdb_make_start (&cdb, fdcdb) == -1)
        err (-1, "could not create file `data.tmp'");

    while (match)
    {
        linenum++;
        if (getln (&b, &line, &match, '\n') == -1)
            err (-1, "could not read line: %ld", linenum);

        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;
        if (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 (line.s[0])
        {
        case '%':
            locparse (&f[0], loc);

            if (!stralloc_copyb (&key, "\0%", 2))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            ipprefix_cat (&key, f[1].s);

            if (cdb_make_add(&cdb,key.s,key.len,loc,2) == -1)
                err (-1, "could not create file `data.tmp'");

            break;

        case 'Z':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].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, &u))
                uint32_unpack_big (defaultsoa, (uint32 *)&u);
            uint32_pack_big (soa, u);

            if (!stralloc_0 (&f[4]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[4].s, &u))
                uint32_unpack_big (defaultsoa + 4, (uint32 *)&u);
            uint32_pack_big (soa + 4, u);

            if (!stralloc_0 (&f[5]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[5].s, &u))
                uint32_unpack_big (defaultsoa + 8, (uint32 *)&u);
            uint32_pack_big (soa + 8, u);

            if (!stralloc_0 (&f[6]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[6].s, &u))
                uint32_unpack_big (defaultsoa + 12, (uint32 *)&u);
            uint32_pack_big (soa + 12, u);

            if (!stralloc_0 (&f[7]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[7].s, &u))
                uint32_unpack_big (defaultsoa + 16, (uint32 *)&u);
            uint32_pack_big (soa + 16, u);

            if (!stralloc_0 (&f[8]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong(f[8].s,&ttl))
                ttl = TTL_NEGATIVE;

            ttdparse (&f[9], ttd);
            locparse (&f[10], loc);

            rr_start (DNS_T_SOA, ttl, ttd, loc);
            if (!dns_domain_fromdot (&d2, f[1].s, f[1].len))
                err (-1, "could not allocate enough memory");

            rr_addname (d2);
            if (!dns_domain_fromdot (&d2, f[2].s, f[2].len))
                err (-1, "could not allocate enough memory");

            rr_addname (d2);
            rr_add (soa, 20);
            rr_finish (d1);

            break;

        case '.':
        case '&':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].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;

            ttdparse (&f[4], ttd);
            locparse (&f[5], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            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 (line.s[0] == '.')
            {
                rr_start (DNS_T_SOA, ttl ? TTL_NEGATIVE : 0, ttd, loc);
                rr_addname (d2);

                rr_add ("\12hostmaster", 11);
                rr_addname (d1);

                rr_add (defaultsoa, 20);
                rr_finish (d1);
            }

            rr_start (DNS_T_NS, ttl, ttd, loc);
            rr_addname (d2);
            rr_finish (d1);

            if (ip4_scan (f[1].s, ip))
            {
                rr_start (DNS_T_A, ttl, ttd, loc);
                rr_add (ip, 4);
                rr_finish (d2);
            }

            break;

        case '+':
        case '=':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[2]))
                err (-1, "could not allocate enough memory");

            if (!scan_ulong (f[2].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[3], ttd);
            locparse (&f[4], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            if (ip4_scan (f[1].s, ip))
            {
                rr_start (DNS_T_A, ttl, ttd, loc);
                rr_add (ip, 4);
                rr_finish (d1);

                if (line.s[0] == '=')
                {
                    dns_name4_domain (dptr,ip);
                    rr_start (DNS_T_PTR, ttl, ttd, loc);
                    rr_addname (d1);
                    rr_finish (dptr);
                }
            }
            break;

        case '@':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].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;

            ttdparse (&f[5], ttd);
            locparse (&f[6], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            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[3]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[3].s, &u))
                u = 0;

            rr_start (DNS_T_MX, ttl, ttd, loc);
            uint16_pack_big (buf, u);
            rr_add (buf, 2);
            rr_addname (d2);
            rr_finish (d1);

            if (ip4_scan (f[1].s, ip))
            {
                rr_start (DNS_T_A, ttl, ttd, loc);
                rr_add (ip, 4);
                rr_finish (d2);
            }
            break;

        case '^':
        case 'C':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!dns_domain_fromdot (&d2, f[1].s, f[1].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[2]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[2].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[3], ttd);
            locparse (&f[4], loc);

            if (line.s[0] == 'C')
                rr_start (DNS_T_CNAME, ttl, ttd, loc);
            else
                rr_start (DNS_T_PTR, ttl, ttd, loc);

            rr_addname (d2);
            rr_finish (d1);

            break;

        case '\'':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[2]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[2].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[3], ttd);
            locparse (&f[4], loc);

            rr_start (DNS_T_TXT, ttl, ttd, loc);

            txtparse (&f[1]);
            i = 0;
            while (i < f[1].len)
            {
                k = f[1].len - i;
                if (k > 127)
                    k = 127;
                ch = k;
                rr_add (&ch, 1);
                rr_add (f[1].s + i, k);
                i += k;
            }

            rr_finish (d1);
            break;

        case ':':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].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_POSITIVE;

            ttdparse (&f[4], ttd);
            locparse (&f[5], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");
            scan_ulong (f[1].s, &u);
            uint16_pack_big (type, u);
            if (byte_equal (type, 2, DNS_T_AXFR))
                syntaxerror (": type AXFR prohibited");
            if (byte_equal (type, 2, "\0\0"))
              syntaxerror (": type 0 prohibited");
            if (byte_equal (type, 2, DNS_T_SOA))
              syntaxerror (": type SOA prohibited");
            if (byte_equal (type, 2, DNS_T_NS))
              syntaxerror (": type NS prohibited");
            if (byte_equal (type, 2, DNS_T_CNAME))
              syntaxerror (": type CNAME prohibited");
            if (byte_equal (type, 2, DNS_T_PTR))
              syntaxerror (": type PTR prohibited");
            if (byte_equal (type, 2, DNS_T_MX))
              syntaxerror (": type MX prohibited");

            txtparse (&f[2]);

            rr_start (type, ttl, ttd, loc);
            rr_add (f[2].s, f[2].len);
            rr_finish (d1);

            break;

        default:
            syntaxerror (": unrecognized leading character");
        }
    }

    if (cdb_make_finish (&cdb) == -1)
        err (-1, "could not create file `data.tmp'");
    if (fsync (fdcdb) == -1)
        err (-1, "could not create file `data.tmp'");
    if (close (fdcdb) == -1)
        err (-1, "could not create file `data.tmp'"); /* NFS stupidity */
    if (rename ("data.tmp", "data.cdb") == -1)
        err (-1, "could not move `data.tmp' to `data.cdb'");

    return 0;
}
コード例 #17
0
ファイル: axfrdns.c プロジェクト: carriercomm/ndjbdns
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);
        }
    }
}
コード例 #18
0
ファイル: dnscache.c プロジェクト: rahulsundaram/ndjbdns
int
main (int argc, char *argv[])
{
    int i = 0;
    time_t t = 0;
    struct sigaction sa;
    unsigned long cachesize = 0;
    char *x = NULL, char_seed[128];

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

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

    seed_addtime ();
    seed_adduint32 (getpid ());
    seed_adduint32 (getppid ());
    seed_adduint32 (getuid ());
    seed_adduint32 (getgid ());

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

    if (mode & DAEMON)
    {
        i = fork ();
        if (i == -1)
            err (-1, "could not fork a daemon process");
        if (i > 0)
            return 0;
    }

    time (&t);
    strftime (char_seed, sizeof (char_seed), "%b-%d %Y %T %Z", localtime (&t));
    warnx ("version %s: starting: %s\n", VERSION, char_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);

    if ((x = env_get ("DATALIMIT")))
    {
        struct rlimit r;
        unsigned long dlimit = atol (x);

        if (getrlimit (RLIMIT_DATA,  &r) != 0)
            err (-1, "could not get resource RLIMIT_DATA");

        r.rlim_cur = (dlimit <= r.rlim_max) ? dlimit : r.rlim_max;

        if (setrlimit (RLIMIT_DATA, &r) != 0)
            err (-1, "could not set resource RLIMIT_DATA");

        if (debug_level)
            warnx ("DATALIMIT set to `%ld' bytes", r.rlim_cur);
    }

    if (!(x = env_get ("IP")))
        err (-1, "$IP not set");
    if (!ip4_scan (x, myipincoming))
        err (-1, "could not parse IP address `%s'", x);

    seed_addtime ();
    udp53 = socket_udp ();
    if (udp53 == -1)
        err (-1, "could not open UDP socket");
    if (socket_bind4_reuse (udp53, myipincoming, 53) == -1)
        err (-1, "could not bind UDP socket");

    seed_addtime ();
    tcp53 = socket_tcp ();
    if (tcp53 == -1)
        err (-1, "could not open TCP socket");
    if (socket_bind4_reuse (tcp53, myipincoming, 53) == -1)
        err (-1, "could not bind TCP socket");

    if (mode & DAEMON)
    {
        /* redirect stdout & stderr to a log file */
        redirect_to_log (LOGFILE, STDOUT_FILENO | STDERR_FILENO);

        write_pid (PIDFILE);
    }

    seed_addtime ();
    droproot ();
    if (mode & DAEMON)
        /* crerate a new session & detach from controlling tty */
        if (setsid () < 0)
            err (-1, "could not start a new session for the daemon");

    seed_addtime ();
    socket_tryreservein (udp53, 131072);

    memset (char_seed, 0, sizeof (char_seed));
    for (i = 0, x = (char *)seed; (unsigned)i < sizeof (char_seed); i++, x++)
        char_seed[i] = *x;
    dns_random_init (char_seed);

    if (!(x = env_get ("IPSEND")))
        err (-1, "$IPSEND not set");
    if (!ip4_scan (x, myipoutgoing))
        err (-1, "could not parse IP address `%s'", x);

    if (!(x = env_get ("CACHESIZE")))
        err (-1, "$CACHESIZE not set");
    scan_ulong (x, &cachesize);
    if (!cache_init (cachesize))
        err (-1, "could not allocate `%ld' bytes for cache", cachesize);

    if (env_get ("HIDETTL"))
        response_hidettl ();
    if (env_get ("FORWARDONLY"))
        query_forwardonly ();
    if (env_get ("MERGEQUERIES"))
        dns_enable_merge (log_merge);
    if (!roots_init ())
        err (-1, "could not read servers");
    if (debug_level > 3)
        roots_display();
    if (socket_listen (tcp53, 20) == -1)
        err (-1, "could not listen on TCP socket");
    if (!dbl_init() && debug_level > 1)
        warnx ("could not read dnsbl.cdb");

    doit ();

    return 0;
}
コード例 #19
0
ファイル: server.c プロジェクト: pillarsdotnet/ndjbdns
int
main (int argc, char *argv[])
{
    time_t t = 0;
    char *x = NULL;
    struct sigaction sa;
    iopause_fd *iop = NULL;
    int i = 0, n = 0, *udp53 = NULL;

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

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

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

    i = check_option (argc, argv);
    argc -= i;
    argv += i;

    if (mode & DAEMON)
    {
        i = fork ();
        if (i == -1)
            err (-1, "could not fork a daemon process");
        if (i > 0)
            return 0;
    }

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

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

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

    if ((x = env_get ("DATALIMIT")))
    {
        struct rlimit r;
        unsigned long dlimit = atol (x);

        if (getrlimit (RLIMIT_DATA,  &r) != 0)
            err (-1, "could not get resource RLIMIT_DATA");

        r.rlim_cur = (dlimit <= r.rlim_max) ? dlimit : r.rlim_max;

        if (setrlimit (RLIMIT_DATA, &r) != 0)
            err (-1, "could not set resource RLIMIT_DATA");

        if (debug_level)
            warnx ("DATALIMIT set to `%ld' bytes", r.rlim_cur);
    }

    if (!(x = env_get ("IP")))
        err (-1, "$IP not set");
    for (i = 0; (unsigned)i < strlen (x); i++)
        n = (x[i] == ',') ? n+1 : n;
    if (!(udp53 = calloc (n+1, sizeof (int))))
        err (-1, "could not allocate enough memory for udp53");
    if (!(iop = calloc (n+1, sizeof (iopause_fd))))
        err (-1, "could not allocate enough memory for iop");

    i = n = 0;
    while (x[i])
    {
        unsigned int l = 0;

        if (!(l = ip4_scan(x+i, ip)))
            errx (-1, "could not parse IP address `%s'", x + i);

        udp53[n] = socket_udp();
        if (udp53[n] == -1)
            errx (-1, "could not open UDP socket");
        if (socket_bind4_reuse (udp53[n], ip, server_port) == -1)
            errx (-1, "could not bind UDP socket");

        ndelay_off (udp53[n]);
        socket_tryreservein (udp53[n], 65536);

        iop[n].fd = udp53[n];
        iop[n].events = IOPAUSE_READ;

        n++;
        i += (x[i + l] == ',') ? l + 1 : l;
    }

    droproot ();
    while (1)
    {
        struct taia stamp;
        struct in_addr odst; /* original destination IP */
        struct taia deadline;

        taia_now (&stamp);
        taia_uint (&deadline, 300);
        taia_add (&deadline, &deadline, &stamp);
        iopause (iop, n, &deadline, &stamp);

        for (i = 0; i < n; i++)
        {
            if (!iop[i].revents)
                continue;

            len = socket_recv4 (udp53[i], buf, sizeof (buf), ip, &port, &odst);
            if (len < 0)
                continue;
            if (!doit ())
                continue;
            if (response_len > 512)
                response_tc ();

            /* may block for buffer space; if it fails, too bad */
            len = socket_send4 (udp53[i], response,
                                response_len, ip, port, &odst);
            if (len < 0)
                continue;
            if (debug_level > 1)
                log_querydone(qnum, response, response_len);
        }
    }

    return 0;
}
コード例 #20
0
ファイル: pickdns-data.c プロジェクト: kjseefried/didentd
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);
}
コード例 #21
0
ファイル: didentd.c プロジェクト: kjseefried/didentd
int main()
{
  unsigned char *remotehost, *remoteip, *remoteport, *localip, *localport;
  unsigned char query[256] = {0};
  uint32 uid = 0xffffffff;          // that's our default for "not found"
  int query_len = 0;
  int pos = 0;
  char *problem = "ok";
  stralloc answer = {0};
  char strnum[FMT_ULONG];
  int  proto = 0;
  char *x;
  char lip[16] = {0};
  char rip[16] = {0};
  uint16 lport = 0;
  uint16 rport = 0;

  didentd_init();

  x = env_get("PROTO");
  if(x)
    {
      if(str_equal(x, "TCP")) proto = 4;
      if(str_equal(x, "TCP6")) proto = 6;
    }
  
  if(proto == 0)
    {
      buffer_puts(buffer_2, "warning: can't determine $PROTO\n");
      buffer_flush(buffer_2);
    }

  srandom(((long long) getpid () *
	    (long long) time(0) *
	    (long long) getppid() * 
	    (long long) random() * 
	    (long long) clock()) % 0xffffffff);

  /* since we run under tcpserver, we can get all info 
     about the remote side from the enviroment */
  remotehost = env_get("TCPREMOTEHOST");
  if (!remotehost) remotehost = "unknown";
  remoteport = env_get("TCPREMOTEPORT");  
  if (remoteport) scan_ushort(remoteport, &rport); else remoteport = "0";
  localport = env_get("TCPLOCALPORT");
  if (localport) scan_ushort(localport, &lport); else localport = "0";

  remoteip = env_get("TCPREMOTEIP");
  if (!remoteip) remoteip = "0.0.0.0";
  localip = env_get("TCPLOCALIP");
  if (!localip) localip = "0.0.0.0";
  
  if(proto == 4)
    {
      if(remoteip) 
	ip4_scan(remoteip, rip);

      if(localip) 
	ip4_scan(localip, lip);
      
      /* seed some entropy into the by IPv4 unsused bytes */
      rip[5] = (char) random() & 0xff;
      rip[6] = (char) random() & 0xff;
    }

  if(proto == 6)
    {
      if (remoteip) 
	ip6_scan(remoteip, rip);

      if (localip) 
	ip6_scan(localip, lip);
    }

  /* Read the request from the client and \0-terminate it */
  /* timeout after 60 seconds */
  query_len = timeoutread(60, stdin, query, sizeof(query) - 1);
  query[query_len] = '\0';
     
  /* If there was any data we can go on */
  problem = "empty query";
  if (query_len > 0)
    {
      problem = "illegal query";
      pos = scan_ushort(query, &lport);
      if(query[pos++] == ' ')
	if(query[pos++] == ',')
	  if(query[pos++] == ' ')
	    {
	      pos = scan_ushort(&query[pos], &rport);
	      problem = "ok";
	      
	      if(proto == 4)
		uid = get_connection_info4(lip, lport, rip, rport);
	      if(proto == 6)
		uid = get_connection_info6(lip, lport, rip, rport);
	      
	      stralloc_copyb(&answer, strnum, fmt_ulong(strnum, lport));
	      stralloc_cats(&answer, " , ");
	      stralloc_catb(&answer, strnum, fmt_ulong(strnum, rport));
	      
	      if(uid != 0xffffffff)
		problem = generate_answer(&answer, uid, lip, lport, rip, rport);
	      else
		generate_answer(&answer, uid, lip, lport, rip, rport);
	      
	      buffer_puts(buffer_1, answer.s);
	      buffer_flush(buffer_1);
	    }
    }

  /* Do logging */
  buffer_puts(buffer_2, localip);  
  buffer_puts(buffer_2, ":");
  buffer_put(buffer_2, strnum, fmt_ulong(strnum, lport));
  buffer_puts(buffer_2, " -> ");
  buffer_puts(buffer_2, remoteip);  
  buffer_puts(buffer_2, ":");
  buffer_put(buffer_2, strnum, fmt_ulong(strnum, rport));
  buffer_puts(buffer_2, " [");
  buffer_puts(buffer_2, problem);
  buffer_puts(buffer_2, "] ");
  if(uid < 0xffffffff)
      buffer_put(buffer_2, strnum, fmt_ulong(strnum,uid));
  else
       buffer_puts(buffer_2, "unknown");  
  buffer_puts(buffer_2, "\n");
  buffer_flush(buffer_2);

  return 0;
}
コード例 #22
0
ファイル: tinydns-edit.c プロジェクト: LordSpacehog/ndjbdns
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;
}
コード例 #23
0
ファイル: tinydns-data.c プロジェクト: axlecrusher/djbdns
int main()
{
  int fddata;
  int i;
  int j;
  int k;
  char ch;
  unsigned long ttl;
  char ttd[8];
  char loc[2];
  unsigned long u;
  char ip[4];
  char ip6[16];
  char type[2];
  char soa[20];
  char buf[4];

  umask(022);

  fddata = open_read("data");
  if (fddata == -1)
    strerr_die2sys(111,FATAL,"unable to open data: ");
  defaultsoa_init(fddata);

  buffer_init(&b,buffer_unixread,fddata,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;
    if (line.s[0] == '#') 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(line.s[0]) {

      case '%':
	locparse(&f[0],loc);
	if (!stralloc_copyb(&key,"\0%",2)) nomem();
	if (!stralloc_0(&f[1])) nomem();
	ipprefix_cat(&key,f[1].s);
        if (cdb_make_add(&cdb,key.s,key.len,loc,2) == -1)
          die_datatmp();
	break;

      case 'Z':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();

	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&u)) uint32_unpack_big(defaultsoa,&u);
	uint32_pack_big(soa,u);
	if (!stralloc_0(&f[4])) nomem();
	if (!scan_ulong(f[4].s,&u)) uint32_unpack_big(defaultsoa + 4,&u);
	uint32_pack_big(soa + 4,u);
	if (!stralloc_0(&f[5])) nomem();
	if (!scan_ulong(f[5].s,&u)) uint32_unpack_big(defaultsoa + 8,&u);
	uint32_pack_big(soa + 8,u);
	if (!stralloc_0(&f[6])) nomem();
	if (!scan_ulong(f[6].s,&u)) uint32_unpack_big(defaultsoa + 12,&u);
	uint32_pack_big(soa + 12,u);
	if (!stralloc_0(&f[7])) nomem();
	if (!scan_ulong(f[7].s,&u)) uint32_unpack_big(defaultsoa + 16,&u);
	uint32_pack_big(soa + 16,u);

	if (!stralloc_0(&f[8])) nomem();
	if (!scan_ulong(f[8].s,&ttl)) ttl = TTL_NEGATIVE;
	ttdparse(&f[9],ttd);
	locparse(&f[10],loc);

	rr_start(DNS_T_SOA,ttl,ttd,loc);
	if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
	rr_addname(d2);
	if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
	rr_addname(d2);
	rr_add(soa,20);
	rr_finish(d1);
	break;

      case '.': case '&':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS;
	ttdparse(&f[4],ttd);
	locparse(&f[5],loc);

	if (!stralloc_0(&f[1])) nomem();

	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 (line.s[0] == '.') {
	  rr_start(DNS_T_SOA,ttl ? TTL_NEGATIVE : 0,ttd,loc);
	  rr_addname(d2);
	  rr_add("\12hostmaster",11);
	  rr_addname(d1);
	  rr_add(defaultsoa,20);
	  rr_finish(d1);
	}

	rr_start(DNS_T_NS,ttl,ttd,loc);
	rr_addname(d2);
	rr_finish(d1);

	if (ip4_scan(f[1].s,ip)) {
	  rr_start(DNS_T_A,ttl,ttd,loc);
	  rr_add(ip,4);
	  rr_finish(d2);
	}

	break;

      case '+': case '=':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	if (!stralloc_0(&f[1])) nomem();

	if (ip4_scan(f[1].s,ip)) {
	  rr_start(DNS_T_A,ttl,ttd,loc);
	  rr_add(ip,4);
	  rr_finish(d1);

	  if (line.s[0] == '=') {
	    dns_name4_domain(dptr,ip);
	    rr_start(DNS_T_PTR,ttl,ttd,loc);
	    rr_addname(d1);
	    rr_finish(dptr);
	  }
	}
	break;

      case '6': case '3':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	if (!stralloc_0(&f[1])) nomem();
	if (ip6_scan_flat(f[1].s,ip6)) {
	  rr_start(DNS_T_AAAA,ttl,ttd,loc);
	  rr_add(ip6,16);
	  rr_finish(d1);

	  if (line.s[0] == '6') {	/* emit both .ip6.arpa and .ip6.int */
	    dns_name6_domain(d6ptr,ip6,DNS_IP6_ARPA);
	    rr_start(DNS_T_PTR,ttl,ttd,loc);
	    rr_addname(d1);
	    rr_finish(d6ptr);

	    dns_name6_domain(d6ptr,ip6,DNS_IP6_INT);
	    rr_start(DNS_T_PTR,ttl,ttd,loc);
	    rr_addname(d1);
	    rr_finish(d6ptr);
	  }
	}
	break;

      case '@':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[4])) nomem();
	if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[5],ttd);
	locparse(&f[6],loc);

	if (!stralloc_0(&f[1])) nomem();

	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[3])) nomem();
	if (!scan_ulong(f[3].s,&u)) u = 0;

	rr_start(DNS_T_MX,ttl,ttd,loc);
	uint16_pack_big(buf,u);
	rr_add(buf,2);
	rr_addname(d2);
	rr_finish(d1);

	if (ip4_scan(f[1].s,ip)) {
	  rr_start(DNS_T_A,ttl,ttd,loc);
	  rr_add(ip,4);
	  rr_finish(d2);
	}
	break;

      case '^': case 'C':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	if (line.s[0] == 'C')
	  rr_start(DNS_T_CNAME,ttl,ttd,loc);
	else
	  rr_start(DNS_T_PTR,ttl,ttd,loc);
	rr_addname(d2);
	rr_finish(d1);
	break;

      case '\'':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	rr_start(DNS_T_TXT,ttl,ttd,loc);

	txtparse(&f[1]);
	i = 0;
	while (i < f[1].len) {
	  k = f[1].len - i;
	  if (k > 127) k = 127;
	  ch = k;
	  rr_add(&ch,1);
	  rr_add(f[1].s + i,k);
	  i += k;
	}

	rr_finish(d1);
	break;

      case ':':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[4],ttd);
	locparse(&f[5],loc);

	if (!stralloc_0(&f[1])) nomem();
	scan_ulong(f[1].s,&u);
	uint16_pack_big(type,u);
	if (byte_equal(type,2,DNS_T_AXFR))
	  syntaxerror(": type AXFR prohibited");
	if (byte_equal(type,2,"\0\0"))
	  syntaxerror(": type 0 prohibited");
	if (byte_equal(type,2,DNS_T_SOA))
	  syntaxerror(": type SOA prohibited");
	if (byte_equal(type,2,DNS_T_NS))
	  syntaxerror(": type NS prohibited");
	if (byte_equal(type,2,DNS_T_CNAME))
	  syntaxerror(": type CNAME prohibited");
	if (byte_equal(type,2,DNS_T_PTR))
	  syntaxerror(": type PTR prohibited");
	if (byte_equal(type,2,DNS_T_MX))
	  syntaxerror(": type MX prohibited");

	txtparse(&f[2]);

	rr_start(type,ttl,ttd,loc);
	rr_add(f[2].s,f[2].len);
	rr_finish(d1);
	break;

      default:
        syntaxerror(": unrecognized leading character");
    }
  }

  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);
}
コード例 #24
0
ファイル: getsenderip.c プロジェクト: morettoni/qmail-rblchk
int main (int argc, char* argv[])
{
  char ip[4];
  stralloc partial = {0};
  stralloc out = {0};
  char ip_fmt[IP4_FMT];
  char line[BUF_LEN];
  int r, i, j;
  int inbuflen = 0;
  int flag0 = 1;
  buffer sslist;
  int fdlist = 0;
  char outlist[BUF_LEN];
  unsigned long skip = 0;
  int opt;

  while ((opt = getopt (argc, argv, "s:")) != opteof)
    switch (opt) {
      case 's': scan_ulong (optarg, &skip); break;
      default:  usage ();
    }

  argc -= optind;
  argv += optind;

  if (!argc) usage ();

  fdlist = open_append(argv[0]);
  if (fdlist == -1) 
    strerr_die4sys (111,FATAL,"unable to write ",argv[0],": ");
  buffer_init (&sslist,write,fdlist,outlist,sizeof(outlist));

  if (!stralloc_copys (&partial, "")) nomem ();

  while (flag0 || inbuflen || partial.len) {
    if (flag0)
      if (inbuflen < sizeof line) {
        r = read (0, line+inbuflen, sizeof line-inbuflen);

        if (r <= 0)
          flag0 = 0;
        else
          inbuflen += r;
      }

    while (flag0) {
      i = byte_chr (line, inbuflen, '\n');
      if (inbuflen && (i == inbuflen)) {
        if (!stralloc_catb (&partial, line, inbuflen)) nomem ();
        inbuflen = 0;
        continue;
      }

      if ((i < inbuflen) || (!flag0 && partial.len)) {
        if (i < inbuflen) ++i;
        if (!stralloc_catb (&partial, line, i)) nomem ();

        inbuflen -= i;
        for (j = 0; j < inbuflen; ++j) line[j] = line[j + i];

        /* end of header */
        if (partial.len == 1) {
          inbuflen = partial.len = flag0 = 0;
          break;
        }

        if (partial.len && flag0) {
          if (str_start (partial.s, "Received: from ")) {
            for (j = str_rchr (partial.s, '(')+1; flag0 && j; j--) {
              i = ip4_scan (partial.s+j, ip);

	      if (skip && i) {
                skip--;
                break;
	      }

              if (i) {
                /* write the IP to the output file */
                stralloc_copyb (&out,ip_fmt, ip4_fmt (ip_fmt, ip));
                buffer_put (&sslist, out.s, out.len);
                buffer_puts (&sslist, "\n");
                flag0 = 0;
                inbuflen = 0;
              }
            }
          }
        }

        partial.len = 0;
        continue;
      }

      break;
    }
  }

  /* flush and close output file */
  buffer_flush (&sslist);
  fsync(fdlist);
  close(fdlist);

  _exit (EXIT_OK);
}