Пример #1
0
void update_tree_row(int row, GtkTreeIter *iter)
{
  ip_t *addr;
  char str[256], *name;

  addr = net_addr(row);
  name = "???";
  if ( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) {
    name = dns_lookup(addr);
    if(!name) {
      sprintf(str, "%s", strlongip( addr ));
      name = str;
    }
  }

  gtk_list_store_set(ReportStore, iter,
    COL_HOSTNAME, name,
    COL_LOSS, (float)(net_loss(row)/1000.0),

    COL_RCV, net_returned(row),
    COL_SNT, net_xmit(row),

    COL_LAST, net_last(row)/1000,
    COL_BEST, net_best(row)/1000,
    COL_AVG, net_avg(row)/1000,
    COL_WORST, net_worst(row)/1000,
    COL_STDEV, (float)(net_stdev(row)/1000.0),
    
    COL_COLOR, net_up(row) ? "black" : "red",

    -1);
}
Пример #2
0
int dkim_exim_query_dns_txt(char *name, char *answer) {
  dns_answer dnsa;
  dns_scan   dnss;
  dns_record *rr;

  if (dns_lookup(&dnsa, (uschar *)name, T_TXT, NULL) != DNS_SUCCEED) return PDKIM_FAIL;

  /* Search for TXT record */
  for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
       rr != NULL;
       rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
    if (rr->type == T_TXT) break;

  /* Copy record content to the answer buffer */
  if (rr != NULL) {
    int rr_offset = 0;
    int answer_offset = 0;
    while (rr_offset < rr->size) {
      uschar len = (rr->data)[rr_offset++];
      snprintf(answer+(answer_offset),
               PDKIM_DNS_TXT_MAX_RECLEN-(answer_offset),
               "%.*s", (int)len, (char *)((rr->data)+rr_offset));
      rr_offset+=len;
      answer_offset+=len;
      if (answer_offset >= PDKIM_DNS_TXT_MAX_RECLEN) {
        return PDKIM_FAIL;
      }
    }
  }
  else return PDKIM_FAIL;

  return PDKIM_OK;
}
Пример #3
0
int lmtp_client_connect_tcp(struct lmtp_client *client,
			    enum lmtp_client_protocol protocol,
			    const char *host, unsigned int port)
{
	struct dns_lookup_settings dns_lookup_set;

	client->input_state = LMTP_INPUT_STATE_GREET;
	client->host = p_strdup(client->pool, host);
	client->port = port;
	client->protocol = protocol;

	if (*host == '\0') {
		i_error("lmtp client: host not given");
		return -1;
	}

	memset(&dns_lookup_set, 0, sizeof(dns_lookup_set));
	dns_lookup_set.dns_client_socket_path =
		client->set.dns_client_socket_path;
	dns_lookup_set.timeout_msecs = LMTP_CLIENT_DNS_LOOKUP_TIMEOUT_MSECS;

	if (net_addr2ip(host, &client->ip) < 0) {
		if (dns_lookup(host, &dns_lookup_set,
			       lmtp_client_dns_done, client) < 0)
			return -1;
	} else {
		if (lmtp_client_connect(client) < 0)
			return -1;
	}
	return 0;
}
Пример #4
0
void mtr_curses_graph(int startstat, int cols) 
{
	int max, at, y, x;
	ip_t * addr;
	char* name;

	max = net_max();

	for (at = display_offset; at < max; at++) {
		printw("%2d. ", at+1);

		addr = net_addr(at);
		if (!addr) {
			printw("???\n");
			continue;
		}

		if (! net_up(at))
			attron(A_BOLD);
		name = dns_lookup(addr);
		if (name) {
			printw("%s", name);
		} else {
			printw("%s", strlongip( addr ) );
		}
		attroff(A_BOLD);

		getyx(stdscr, y, x);
		move(y, startstat);

		printw(" ");
		mtr_fill_graph(at, cols);
		printw("\n");
	}
}
Пример #5
0
int     main(int argc, char **argv)
{
    DNS_RR *rr;
    MAI_HOSTADDR_STR hostaddr;
    VSTRING *why;
    int     type;

    myname = argv[0];
    if (argc < 3)
	usage();
    why = vstring_alloc(1);

    while (*++argv) {
	if (argv[1] == 0)
	    usage();
	if ((type = dns_type(argv[0])) == 0)
	    usage();
	if (dns_lookup(argv[1], type, 0, &rr, (VSTRING *) 0, why) != DNS_OK)
	    msg_fatal("%s: %s", argv[1], vstring_str(why));
	if (dns_rr_to_pa(rr, &hostaddr) == 0)
	    msg_fatal("dns_rr_to_sa: %m");
	vstream_printf("%s -> %s\n", argv[1], hostaddr.buf);
	vstream_fflush(VSTREAM_OUT);
	argv += 1;
	dns_rr_free(rr);
    }
    vstring_free(why);
    return (0);
}
Пример #6
0
static int
dns_find_realm(krb5_context context,
	       const char *domain,
	       krb5_realm **realms)
{
    static char *default_labels[] = { "_kerberos", NULL };
    char dom[MAXHOSTNAMELEN];
    struct dns_reply *r;
    char **labels;
    int i, ret;
    
    labels = krb5_config_get_strings(context, NULL, "libdefaults",
	"dns_lookup_realm_labels", NULL);
    if(labels == NULL)
	labels = default_labels;
    if(*domain == '.')
	domain++;
    for (i = 0; labels[i] != NULL; i++) {
	ret = snprintf(dom, sizeof(dom), "%s.%s.", labels[i], domain);
	if(ret < 0 || ret >= sizeof(dom))
	    return -1;
    	r = dns_lookup(dom, "TXT");
    	if(r != NULL) {
	    ret = copy_txt_to_realms (r->head, realms);
	    dns_free_data(r);
	    if(ret == 0)
		return 0;
	}
    }
    return -1;
}
Пример #7
0
void split_redraw(void) 
{
  int   max;
  int   at;
  ip_t *addr;
  char  newLine[MAX_LINE_SIZE];
  int   i;

#if DEBUG
  fprintf(stderr, "split_redraw()\n"); 
#endif

  /* 
   * If there is less lines than last time, we delete them
   * TEST THIS PLEASE
   */
  max = net_max();
  for (i=LineCount; i>max; i--) {
    printf("-%d\n", i);
    LineCount--;
  }

  /*
   * For each line, we compute the new one and we compare it to the old one
   */
  for(at = 0; at < max; at++) {
    addr = net_addr(at);
    if(addrcmp((void*)addr, (void*)&unspec_addr, af)) {
      char str[256], *name;
      if (!(name = dns_lookup(addr)))
        name = strlongip(addr);
      if (show_ips) {
        snprintf(str, sizeof(str), "%s %s", name, strlongip(addr));
        name = str;
      }
      /* May be we should test name's length */
      snprintf(newLine, sizeof(newLine), "%s %d %d %d %d %d %d", name,
               net_loss(at),
               net_returned(at), net_xmit(at),
               net_best(at) /1000, net_avg(at)/1000,
               net_worst(at)/1000);
    } else {
      sprintf(newLine, "???");
    }

    if (strcmp(newLine, Lines[at]) == 0) {
      /* The same, so do nothing */
#if DEBUG
      printf("SAME LINE\n");
#endif
    } else {
      printf("%d %s\n", at+1, newLine);
      fflush(stdout);
      strcpy(Lines[at], newLine);
      if (LineCount < (at+1)) {
	LineCount = at+1;
      }
    }
  }
}
Пример #8
0
static evutil_socket_t
connect_chunk_server (ChunkServer *cs)
{
    struct sockaddr_in sa;
    ev_socklen_t sa_len;
    evutil_socket_t data_fd;
    ev_socklen_t optlen;

    if (dns_lookup (cs->addr, &sa, &sa_len) < 0) {
        return -1;
    }

    sa.sin_family = AF_INET;
    sa.sin_port = htons(cs->port);

    data_fd = socket (AF_INET, SOCK_STREAM, 0);
    if (data_fd < 0) {
        seaf_warning ("socket error: %s.\n", strerror(errno));
        return -1;
    }

#ifdef WIN32
    /* Set large enough TCP buffer size.
     * This greatly enhances sync speed for high latency network.
     * Windows by default use 8KB buffers, which is too small for such case.
     * Linux has auto-tuning for TCP buffers, so don't need to set manually.
     * OSX is TBD.
     */

#define DEFAULT_SNDBUF_SIZE (1 << 16) /* 64KB */

    /* Set send buffer size. */
    int sndbuf_size;
    optlen = sizeof(int);
    getsockopt (data_fd, SOL_SOCKET, SO_SNDBUF, (char *)&sndbuf_size, &optlen);

    if (sndbuf_size < DEFAULT_SNDBUF_SIZE) {
        sndbuf_size = DEFAULT_SNDBUF_SIZE;
        optlen = sizeof(int);
        setsockopt (data_fd, SOL_SOCKET, SO_SNDBUF, (char *)&sndbuf_size, optlen);
    }
#endif

    /* Disable Nagle's algorithm. */
    int val = 1;
    optlen = sizeof(int);
    setsockopt (data_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, optlen);

    if (connect (data_fd, (struct sockaddr *)&sa, sa_len) < 0) {
        seaf_warning ("connect error: %s.\n",
                      evutil_socket_error_to_string(evutil_socket_geterror(data_fd)));
        evutil_closesocket (data_fd);
        return -1;
    }

    return data_fd;
}
Пример #9
0
void dns_addtocache(myconn_t *rec, char *ip)
{
	xymon_sqldb_dns_updatecache(dns_lookup_sequence[rec->netparams.af_index-1], rec->netparams.lookupstring, ip);

	if (strcmp(ip, "-") != 0) 
		/* Got an IP, we're done */
		dns_return_lookupdata(rec, ip);
	else
		/* Look for an IP in the next address family by re-doing the dns_lookup() call */
		dns_lookup(rec);
}
Пример #10
0
int lmtp_client_connect_tcp(struct lmtp_client *client,
			    enum lmtp_client_protocol protocol,
			    const char *host, unsigned int port)
{
	struct dns_lookup_settings dns_lookup_set;
	struct ip_addr *ips;
	unsigned int ips_count;
	int ret;

	client->input_state = LMTP_INPUT_STATE_GREET;
	client->host = p_strdup(client->pool, host);
	client->port = port;
	client->protocol = protocol;

	if (*host == '\0') {
		i_error("lmtp client: host not given");
		return -1;
	}

	memset(&dns_lookup_set, 0, sizeof(dns_lookup_set));
	dns_lookup_set.dns_client_socket_path =
		client->set.dns_client_socket_path;
	dns_lookup_set.timeout_msecs = LMTP_CLIENT_DNS_LOOKUP_TIMEOUT_MSECS;

	if (net_addr2ip(host, &client->ip) == 0) {
		/* IP address */
	} else if (dns_lookup_set.dns_client_socket_path == NULL) {
		/* no dns-client, use blocking lookup */
		ret = net_gethostbyname(host, &ips, &ips_count);
		if (ret != 0) {
			i_error("lmtp client: DNS lookup of %s failed: %s",
				client->host, net_gethosterror(ret));
			return -1;
		}
		client->ip = ips[0];
	} else {
		if (dns_lookup(host, &dns_lookup_set,
			       lmtp_client_dns_done, client,
			       &client->dns_lookup) < 0)
			return -1;
		client->running = TRUE;
		return 0;
	}

	if (lmtp_client_connect(client) < 0)
		return -1;
	return 0;
}
Пример #11
0
void pop3c_client_run(struct pop3c_client *client)
{
	struct ioloop *ioloop, *prev_ioloop = current_ioloop;
	bool timeout_added = FALSE, failed = FALSE;

	i_assert(client->fd != -1 ||
		 client->state == POP3C_CLIENT_STATE_CONNECTING);

	ioloop = io_loop_create();
	pop3c_client_ioloop_changed(client);

	if (client->ip.family == 0) {
		/* we're connecting, start DNS lookup after our ioloop
		   is created */
		struct dns_lookup_settings dns_set;

		i_assert(client->state == POP3C_CLIENT_STATE_CONNECTING);
		memset(&dns_set, 0, sizeof(dns_set));
		dns_set.dns_client_socket_path =
			client->set.dns_client_socket_path;
		dns_set.timeout_msecs = POP3C_DNS_LOOKUP_TIMEOUT_MSECS;
		if (dns_lookup(client->set.host, &dns_set,
			       pop3c_dns_callback, client,
			       &client->dns_lookup) < 0)
			failed = TRUE;
	} else if (client->to == NULL) {
		client->to = timeout_add(POP3C_COMMAND_TIMEOUT_MSECS,
					 pop3c_client_timeout, client);
		timeout_added = TRUE;
	}

	if (!failed) {
		client->running = TRUE;
		io_loop_run(ioloop);
		client->running = FALSE;
	}

	if (timeout_added && client->to != NULL)
		timeout_remove(&client->to);

	current_ioloop = prev_ioloop;
	pop3c_client_ioloop_changed(client);
	current_ioloop = ioloop;
	io_loop_destroy(&ioloop);
}
Пример #12
0
SXSocketRef SXCreateClientSocketByHostname(const char * hostname,
                                           const char * service,
                                           struct addrinfo * hint,
                                           SXError * err_ret) {
    SXSocketRef sockPtr = (SXSocketRef)sx_calloc(1, sizeof(sx_socket_t));
    sx_obj_init(&sockPtr->obj, &SXFreeSocket);
    *err_ret = dns_lookup(sockPtr, hostname, service, hint);
    if ((sockPtr->sockfd = socket(sockPtr->domain, sockPtr->type, sockPtr->protocol)) == -1) {
        perror("socket");
        ERR_RET(SX_ERROR_SYS_SOCKET);
    }
    int yes = 1;
    if (setsockopt(sockPtr->sockfd, SOL_SOCKET, SO_NOSIGPIPE, &yes, sizeof(int)) == -1) {
        perror("setsockopt");
        ERR_RET(SX_ERROR_SYS_SETSOCKOPT);
    }
    return SX_SUCCESS;
}
Пример #13
0
int main(int argc, char *argv[])
{
	char  ch;
	char  dns_ip[64], domain[128];
	int   dns_port = 53, ret;
	ACL_VSTRING *sbuf;

	dns_ip[0] = 0;
	domain[0] = 0;

	while ((ch = getopt(argc, argv, "h:p:d:")) > 0) {
		switch (ch) {
		case 'h':
			ACL_SAFE_STRNCPY(dns_ip, optarg, sizeof(dns_ip));
			break;
		case 'p':
			dns_port = atoi(optarg);
			break;
		case 'd':
			ACL_SAFE_STRNCPY(domain, optarg, sizeof(domain));
			break;
		default:
			usage(argv[0]);
			return (0);
		}
	}

	if (dns_ip[0] == 0 || domain[0] == 0) {
		usage(argv[0]);
		return (0);
	}

	sbuf = acl_vstring_alloc(128);
	ret = dns_lookup(domain, dns_ip, dns_port, sbuf);
	if (ret < 0) {
		printf("dns lookup(%s) error(%s)\r\n", domain, acl_vstring_str(sbuf));
		acl_vstring_free(sbuf);
		return (0);
	}

	printf("domain: %s\r\n%s", domain, acl_vstring_str(sbuf));
	acl_vstring_free(sbuf);
	return (0);
}
Пример #14
0
void fill_hostinfo(int at, ip_t *addr) {
	int l, len = 0;
	char *p = buf;
	int sz;
#ifdef IPINFO
	if (enable_ipinfo) {
		sz = 2 * STARTSTAT;
		l = snprintf(p, sz, "%s", fmt_ipinfo(addr));
		if (l < 0)
			sz = 0;
		else if (l < sz)
			sz = l;
		else
			sz -= 1;
		len += sz;
		p += sz;
	}
#endif
	sz = STARTSTAT;
	char *name = dns_lookup(addr);
	if (name) {
		if (show_ips)
			l = snprintf(p, sz, "%s (%s)", name, strlongip(addr));
		else
			l = snprintf(p, sz, "%s", name);
	} else
		l = snprintf(p, sz, "%s", strlongip(addr));

	if (l < 0)
		sz = 0;
	else if (l < sz)
		sz = l;
	else
		sz -= 1;
	len += sz;

	if ((at + 1) >= display_offset)
		if (len > hostinfo_max)
			hostinfo_max = len;
}
Пример #15
0
int     main(int argc, char **argv)
{
    DNS_RR *rr;
    MAI_HOSTADDR_STR hostaddr;
    MAI_SERVPORT_STR portnum;
    struct sockaddr_storage ss;
    struct sockaddr *sa = (struct sockaddr *) &ss;
    SOCKADDR_SIZE sa_length = sizeof(ss);
    VSTRING *why;
    int     type;
    int     port;

    myname = argv[0];
    if (argc < 4)
	usage();
    why = vstring_alloc(1);

    while (*++argv) {
	if (argv[1] == 0 || argv[2] == 0)
	    usage();
	if ((type = dns_type(argv[0])) == 0)
	    usage();
	if (!alldig(argv[2]) || (port = atoi(argv[2])) > 65535)
	    usage();
	if (dns_lookup(argv[1], type, 0, &rr, (VSTRING *) 0, why) != DNS_OK)
	    msg_fatal("%s: %s", argv[1], vstring_str(why));
	sa_length = sizeof(ss);
	if (dns_rr_to_sa(rr, htons(port), sa, &sa_length) != 0)
	    msg_fatal("dns_rr_to_sa: %m");
	SOCKADDR_TO_HOSTADDR(sa, sa_length, &hostaddr, &portnum, 0);
	vstream_printf("%s %s -> %s %s\n",
		       argv[1], argv[2], hostaddr.buf, portnum.buf);
	vstream_fflush(VSTREAM_OUT);
	argv += 2;
	dns_rr_free(rr);
    }
    vstring_free(why);
    return (0);
}
Пример #16
0
static int
dkim_exim_query_dns_txt(char *name, char *answer)
{
dns_answer dnsa;
dns_scan dnss;
dns_record *rr;

lookup_dnssec_authenticated = NULL;
if (dns_lookup(&dnsa, US name, T_TXT, NULL) != DNS_SUCCEED)
  return PDKIM_FAIL;

/* Search for TXT record */

for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
     rr;
     rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
  if (rr->type == T_TXT)
    {
    int rr_offset = 0;
    int answer_offset = 0;

    /* Copy record content to the answer buffer */

    while (rr_offset < rr->size)
      {
      uschar len = rr->data[rr_offset++];
      snprintf(answer + answer_offset,
		PDKIM_DNS_TXT_MAX_RECLEN - answer_offset,
		"%.*s", (int)len, (char *) (rr->data + rr_offset));
      rr_offset += len;
      answer_offset += len;
      if (answer_offset >= PDKIM_DNS_TXT_MAX_RECLEN)
	return PDKIM_FAIL;
      }
    return PDKIM_OK;
    }

return PDKIM_FAIL;
}
Пример #17
0
void mtr_curses_graph(int startstat, int cols) 
{
	int max, at, y;
	ip_t * addr;
	char* name;

	max = net_max();

	for (at = display_offset; at < max; at++) {
		printw("%2d. ", at+1);

		addr = net_addr(at);
		if (!addr) {
			printw("???\n");
			continue;
		}

		if (! net_up(at))
			attron(A_BOLD);
		if (addrcmp((void *) addr, (void *) &unspec_addr, af)) {
#ifdef IPINFO
			if (is_printii())
				printw(fmt_ipinfo(addr));
#endif
			name = dns_lookup(addr);
			printw("%s", name?name:strlongip(addr));
		} else
			printw("???");
		attroff(A_BOLD);

		getyx(stdscr, y, __unused_int);
		move(y, startstat);

		printw(" ");
		mtr_fill_graph(at, cols);
		printw("\n");
	}
}
Пример #18
0
int main(int argc, char **argv)
{
    dns_handle_t dns = dns_open(NULL);
    uint16_t dnstype = 0;
    if (dns_type_number("TXT", &dnstype) != 0) {
        fprintf(stderr, "Don't know what TXT type means.\n");
        exit(1);
    }
    uint16_t dnsclass = 0;
    if (dns_class_number("IN", &dnsclass) != 0) {
        fprintf(stderr, "Don't know what IN class means.\n");
        exit(1);
    }
    fprintf(stderr, "Doing lookup\n");
    dns_reply_t *reply = dns_lookup(dns, argv[1], dnsclass, dnstype);
    if (reply == NULL) {
        fprintf(stderr, "Couldn't find %s\n", argv[1]);
        exit(1);
    }
    fprintf(stderr, "Printing reply: %p (status=%d)\n", reply, reply->status);
    for (int i = 0; reply->answer[i]; i++) {
        dns_resource_record_t *rr = reply->answer[i];
        fprintf(stderr, "answer rr %p\n", rr);
        fprintf(stdout, "  Type:  %s (%d)\n", dns_type_string(rr->dnstype),
                rr->dnstype);
        if (rr->dnstype == dnstype) {
            fprintf(stderr, "  Data:  ");
            for (int j = 0; j < rr->data.TXT->string_count; j++) {
                if (j > 0) {
                    fprintf(stderr, ", ");
                }
                fprintf(stderr, "\"%s\"", rr->data.TXT->strings[j]);
            }
            fprintf(stderr, "\n");
        }
    }
}
Пример #19
0
static krb5_error_code
srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count, 
	       const char *realm, const char *dns_type,
	       const char *proto, const char *service, int port)
{
    char domain[1024];
    struct dns_reply *r;
    struct resource_record *rr;
    int num_srv;
    int proto_num;
    int def_port;

    *res = NULL;
    *count = 0;

    proto_num = string_to_proto(proto);
    if(proto_num < 0) {
	krb5_set_error_string(context, "unknown protocol `%s'", proto);
	return EINVAL;
    }

    if(proto_num == KRB5_KRBHST_HTTP)
	def_port = ntohs(krb5_getportbyname (context, "http", "tcp", 80));
    else if(port == 0)
	def_port = ntohs(krb5_getportbyname (context, service, proto, 88));
    else
	def_port = port;

    snprintf(domain, sizeof(domain), "_%s._%s.%s.", service, proto, realm);

    r = dns_lookup(domain, dns_type);
    if(r == NULL)
	return KRB5_KDC_UNREACH;

    for(num_srv = 0, rr = r->head; rr; rr = rr->next) 
	if(rr->type == T_SRV)
	    num_srv++;

    *res = malloc(num_srv * sizeof(**res));
    if(*res == NULL) {
	dns_free_data(r);
	krb5_set_error_string(context, "malloc: out of memory");
	return ENOMEM;
    }

    dns_srv_order(r);

    for(num_srv = 0, rr = r->head; rr; rr = rr->next) 
	if(rr->type == T_SRV) {
	    krb5_krbhst_info *hi;
	    size_t len = strlen(rr->u.srv->target);

	    hi = calloc(1, sizeof(*hi) + len);
	    if(hi == NULL) {
		dns_free_data(r);
		while(--num_srv >= 0)
		    free((*res)[num_srv]);
		free(*res);
		*res = NULL;
		return ENOMEM;
	    }
	    (*res)[num_srv++] = hi;

	    hi->proto = proto_num;
	    
	    hi->def_port = def_port;
	    if (port != 0)
		hi->port = port;
	    else
		hi->port = rr->u.srv->port;

	    strlcpy(hi->hostname, rr->u.srv->target, len + 1);
	}

    *count = num_srv;
	    
    dns_free_data(r);
    return 0;
}
Пример #20
0
eDnsStatus dnscache_lookup (dnscache_t *dnscache, const char *dname, int type, size_t max_hosts, off_t *index, time_t current_time)
{
	dnscache_entry_t *record;
	rr_t *rr_list;
	buffer_t name;
	unsigned int position;
	int min_ttl;
	int lookup;
	size_t len;
	size_t i;

	if (max_hosts > MAX_HOSTS) {
		return DNS_ERROR;
	}

	if (search (dnscache, dname, type, &position) < 0) {
		/* DNS cache miss. */
		buffer_init (&name, 64);
		len = strlen (dname);
		if (buffer_allocate (&name, len + 1) < 0) {
			buffer_free (&name);
			return DNS_ERROR;
		}

		memcpy (name.data, dname, len + 1);
		name.used = len + 1;

		if (allocate (dnscache) < 0) {
			buffer_free (&name);
			return DNS_ERROR;
		}

		/* We might have emptied the cache. */
		if (dnscache->used == 0) {
			position = 0;
		}

		record = &(dnscache->records[dnscache->used]);

		memcpy (&record->name, &name, sizeof (buffer_t));
		record->type = type;
		record->timestamp = current_time;
		rr_list_init (record->rr_list, MAX_HOSTS);
		record->nhosts = 0;

		record->status = dns_lookup (dname, type, max_hosts, record->rr_list, &record->nhosts);

		*index = dnscache->used;

		if (position < dnscache->used) {
			memmove (&(dnscache->index[position + 1]), &(dnscache->index[position]), (dnscache->used - position) * sizeof (off_t));
		}

		dnscache->index[position] = dnscache->used++;

		return record->status;
	}

	*index = dnscache->index[position];
	record = &(dnscache->records[*index]);
	rr_list = record->rr_list;

	if ((record->status == DNS_HOST_NOT_FOUND) || (record->status == DNS_NO_DATA)) {
		if (record->timestamp + QUERY_MIN_INTERVAL >= current_time) {
			return record->status;
		}

		lookup = 1;
	} else if (record->status != DNS_SUCCESS) {
		lookup = 1;
	} else {
		/* Compute the minimum TTL. */
		min_ttl = rr_list[0].ttl;
		for (i = 1; i < record->nhosts; i++) {
			if (rr_list[i].ttl < min_ttl) {
				min_ttl = rr_list[i].ttl;
			}
		}

		/* If the TTL has already expired... */
		if (record->timestamp + min_ttl < current_time) {
			lookup = 1;
		} else {
			lookup = 0;
		}
	}

	if (lookup) {
		rr_list_free (rr_list, MAX_HOSTS);

		record->status = dns_lookup (dname, type, max_hosts, rr_list, &record->nhosts);
		record->timestamp = current_time;
	}

	return record->status;
}
Пример #21
0
void mtr_curses_hosts(int startstat) 
{
  int max;
  int at;
  struct mplslen *mpls, *mplss;
  ip_t *addr, *addrs;
  int y;
  char *name;

  char *country,*province,*city,*district,*isp,*type,*desc;
  int icountry,iprovince,icity,idistrict,iisp,itype,idesc;

  int i, j, k;
  int hd_len;
  char buf[1024];

  max = net_max();

  for(at = net_min () + display_offset; at < max; at++) {
    printw("%2d. ", at + 1);
    addr = net_addr(at);
    mpls = net_mpls(at);

    if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) {
      name = dns_lookup(addr);
      if (! net_up(at))
	attron(A_BOLD);
#ifdef IPINFO
      if (is_printii())
        printw(fmt_ipinfo(addr));
#endif
      if(name != NULL) {
        if (show_ips) printw("%s (%s)", name, strlongip(addr));
        else printw("%s", name);
      } else {
	printw("%s", strlongip( addr ) );
      }
      attroff(A_BOLD);

      getyx(stdscr, y, __unused_int);

#ifdef ENABLE_BILIIP
      if (ip_resolve) {
      long key = biliip_query(biliip,ntohl(*(unsigned long *)addr));
      if (key != 0)
      {
        if (biliip->index_ptr[key] == 0)
        {
          biliip->ptr = BILIIP_BASE_PTR+(biliip->nCount*2+key-1)*sizeof(int);
          biliip->index_ptr[key] = htonl(*(int *)(biliip->mmap+biliip->ptr));
        }
        biliip->ptr = biliip->index_ptr[key]+4;

        country = biliip_getstr(biliip,&icountry);
        province = biliip_getstr(biliip,&iprovince);
        city = biliip_getstr(biliip,&icity);
        district = biliip_getstr(biliip,&idistrict);
        isp = biliip_getstr(biliip,&iisp);
        type = biliip_getstr(biliip,&itype);
        desc = biliip_getstr(biliip,&idesc);

        char biliip_buf[64];
        char *biliip_last = biliip_buf;

        if (startstat > 70) {
            if (icountry > 0 && country) {
              biliip_last += sprintf(biliip_last, "%.*s", icountry, country);
            }
            move(y, startstat - 50);

            attron(A_BOLD | COLOR_PAIR(4));
            printw("%s", biliip_buf);
            attroff(A_BOLD | COLOR_PAIR(4));

            biliip_last = biliip_buf;
            *biliip_last = '\0';

            if (iprovince > 0 && province) {
              biliip_last += sprintf(biliip_last, " %.*s", iprovince, province);
              while (biliip_last > biliip_buf && *(biliip_last-1) == ' ') *--biliip_last = '\0';
              printw("%s", biliip_buf);
              biliip_last = biliip_buf;
              *biliip_last = '\0';
            }
            if (icity > 0 && city && (iprovince != icity || strncmp(province, city, icity) != 0)) {
              biliip_last += sprintf(biliip_last, " %.*s", icity, city);
              while (biliip_last > biliip_buf && *(biliip_last-1) == ' ') *--biliip_last = '\0';
              printw("%s", biliip_buf);
              biliip_last = biliip_buf;
              *biliip_last = '\0';
            }
        }

        if (iisp > 0 && isp) {
          biliip_last += sprintf(biliip_last, "%.*s", iisp, isp);
          while (biliip_last > biliip_buf && *(biliip_last-1) == ' ') *--biliip_last = '\0';
        }
        if (idesc > 0 && desc) {
          biliip_last += sprintf(biliip_last, " %.*s", idesc, desc);
          while (biliip_last > biliip_buf && *(biliip_last-1) == ' ') *--biliip_last = '\0';
        }
        move(y, startstat - 25);
        attron(A_BOLD | COLOR_PAIR(7));
        printw("%s", biliip_buf);
        attroff(A_BOLD | COLOR_PAIR(7));
      }
    }
#endif
      move(y, startstat);

      /* net_xxx returns times in usecs. Just display millisecs */
      hd_len = 0;
      for( i=0; i<MAXFLD; i++ ) {
	/* Ignore options that don't exist */
	/* On the other hand, we now check the input side. Shouldn't happen, 
	   can't be careful enough. */
	j = fld_index[fld_active[i]];
	if (j == -1) continue; 

	/* temporay hack for stats usec to ms... */
	if( index( data_fields[j].format, 'f' ) ) {
	  sprintf(buf + hd_len, data_fields[j].format,
		data_fields[j].net_xxx(at) /1000.0 );
	} else {
	  sprintf(buf + hd_len, data_fields[j].format,
		data_fields[j].net_xxx(at) );
	}
	hd_len +=  data_fields[j].length;
      }
      buf[hd_len] = 0;
      printw("%s", buf);

      for (k=0; k < mpls->labels && enablempls; k++) {
        if((k+1 < mpls->labels) || (mpls->labels == 1)) {
           /* if we have more labels */
           printw("\n    [MPLS: Lbl %lu Exp %u S %u TTL %u]", mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]);
        } else {
           /* bottom label */
           printw("\n    [MPLS: Lbl %lu Exp %u S %u TTL %u]", mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]);
        }
      }

// printw("aasdfasdf");
      /* Multi path */
      for (i=0; i < MAXPATH; i++ ) {
        addrs = net_addrs(at, i);
        mplss = net_mplss(at, i);
	if ( addrcmp( (void *) addrs, (void *) addr, af ) == 0 ) continue;
	if ( addrcmp( (void *) addrs, (void *) &unspec_addr, af ) == 0 ) break;

        name = dns_lookup(addrs);
        if (! net_up(at)) attron(A_BOLD);
        printw("\n    ");
#ifdef IPINFO
        if (is_printii())
          printw(fmt_ipinfo(addrs));
#endif
        if (name != NULL) {
	  if (show_ips) printw("%s (%s)", name, strlongip(addrs));
	  else printw("%s", name);
        } else {
	  printw("%s", strlongip( addrs ) );
        }
        for (k=0; k < mplss->labels && enablempls; k++) {
          printw("\n    [MPLS: Lbl %lu Exp %u S %u TTL %u]", mplss->label[k], mplss->exp[k], mplss->s[k], mplss->ttl[k]);
        }
        attroff(A_BOLD);
      }

    } else {
      printw("???");
    }

    printw("\n");
  }
  move(2, 0);
}
Пример #22
0
int
dns_special_lookup(dns_answer *dnsa, const uschar *name, int type,
  const uschar **fully_qualified_name)
{
switch (type)
  {
  /* The "mx hosts only" type doesn't require any special action here */
  case T_MXH:
    return dns_lookup(dnsa, name, T_MX, fully_qualified_name);

  /* Find nameservers for the domain or the nearest enclosing zone, excluding
  the root servers. */
  case T_ZNS:
    type = T_NS;
    /* FALLTHROUGH */
  case T_SOA:
    {
    const uschar *d = name;
    while (d != 0)
      {
      int rc = dns_lookup(dnsa, d, type, fully_qualified_name);
      if (rc != DNS_NOMATCH && rc != DNS_NODATA) return rc;
      while (*d != 0 && *d != '.') d++;
      if (*d++ == 0) break;
      }
    return DNS_NOMATCH;
    }

  /* Try to look up the Client SMTP Authorization SRV record for the name. If
  there isn't one, search from the top downwards for a CSA record in a parent
  domain, which might be making assertions about subdomains. If we find a record
  we set fully_qualified_name to whichever lookup succeeded, so that the caller
  can tell whether to look at the explicit authorization field or the subdomain
  assertion field. */
  case T_CSA:
    {
    uschar *srvname, *namesuff, *tld, *p;
    int priority, weight, port;
    int limit, rc, i;
    BOOL ipv6;
    dns_record *rr;
    dns_scan dnss;

    DEBUG(D_dns) debug_printf("CSA lookup of %s\n", name);

    srvname = string_sprintf("_client._smtp.%s", name);
    rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
    if (rc == DNS_SUCCEED || rc == DNS_AGAIN)
      {
      if (rc == DNS_SUCCEED) *fully_qualified_name = string_copy(name);
      return rc;
      }

    /* Search for CSA subdomain assertion SRV records from the top downwards,
    starting with the 2nd level domain. This order maximizes cache-friendliness.
    We skip the top level domains to avoid loading their nameservers and because
    we know they'll never have CSA SRV records. */

    namesuff = Ustrrchr(name, '.');
    if (namesuff == NULL) return DNS_NOMATCH;
    tld = namesuff + 1;
    ipv6 = FALSE;
    limit = dns_csa_search_limit;

    /* Use more appropriate search parameters if we are in the reverse DNS. */

    if (strcmpic(namesuff, US".arpa") == 0)
      if (namesuff - 8 > name && strcmpic(namesuff - 8, US".in-addr.arpa") == 0)
	{
	namesuff -= 8;
	tld = namesuff + 1;
	limit = 3;
	}
      else if (namesuff - 4 > name && strcmpic(namesuff - 4, US".ip6.arpa") == 0)
	{
	namesuff -= 4;
	tld = namesuff + 1;
	ipv6 = TRUE;
	limit = 3;
	}

    DEBUG(D_dns) debug_printf("CSA TLD %s\n", tld);

    /* Do not perform the search if the top level or 2nd level domains do not
    exist. This is quite common, and when it occurs all the search queries would
    go to the root or TLD name servers, which is not friendly. So we check the
    AUTHORITY section; if it contains the root's SOA record or the TLD's SOA then
    the TLD or the 2LD (respectively) doesn't exist and we can skip the search.
    If the TLD and the 2LD exist but the explicit CSA record lookup failed, then
    the AUTHORITY SOA will be the 2LD's or a subdomain thereof. */

    if (rc == DNS_NOMATCH)
      {
      /* This is really gross. The successful return value from res_search() is
      the packet length, which is stored in dnsa->answerlen. If we get a
      negative DNS reply then res_search() returns -1, which causes the bounds
      checks for name decompression to fail when it is treated as a packet
      length, which in turn causes the authority search to fail. The correct
      packet length has been lost inside libresolv, so we have to guess a
      replacement value. (The only way to fix this properly would be to
      re-implement res_search() and res_query() so that they don't muddle their
      success and packet length return values.) For added safety we only reset
      the packet length if the packet header looks plausible. */

      HEADER *h = (HEADER *)dnsa->answer;
      if (h->qr == 1 && h->opcode == QUERY && h->tc == 0
	  && (h->rcode == NOERROR || h->rcode == NXDOMAIN)
	  && ntohs(h->qdcount) == 1 && ntohs(h->ancount) == 0
	  && ntohs(h->nscount) >= 1)
	    dnsa->answerlen = MAXPACKET;

      for (rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
	   rr;
	   rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)
	  )
	if (rr->type != T_SOA) continue;
	else if (strcmpic(rr->name, US"") == 0 ||
		 strcmpic(rr->name, tld) == 0) return DNS_NOMATCH;
	else break;
      }

    for (i = 0; i < limit; i++)
      {
      if (ipv6)
	{
	/* Scan through the IPv6 reverse DNS in chunks of 16 bits worth of IP
	address, i.e. 4 hex chars and 4 dots, i.e. 8 chars. */
	namesuff -= 8;
	if (namesuff <= name) return DNS_NOMATCH;
	}
      else
	/* Find the start of the preceding domain name label. */
	do
	  if (--namesuff <= name) return DNS_NOMATCH;
	while (*namesuff != '.');

      DEBUG(D_dns) debug_printf("CSA parent search at %s\n", namesuff + 1);

      srvname = string_sprintf("_client._smtp.%s", namesuff + 1);
      rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
      if (rc == DNS_AGAIN) return rc;
      if (rc != DNS_SUCCEED) continue;

      /* Check that the SRV record we have found is worth returning. We don't
      just return the first one we find, because some lower level SRV record
      might make stricter assertions than its parent domain. */

      for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
	   rr;
	   rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
	{
	if (rr->type != T_SRV) continue;

	/* Extract the numerical SRV fields (p is incremented) */
	p = rr->data;
	GETSHORT(priority, p);
	GETSHORT(weight, p);	weight = weight; /* compiler quietening */
	GETSHORT(port, p);

	/* Check the CSA version number */
	if (priority != 1) continue;

	/* If it's making an interesting assertion, return this response. */
	if (port & 1)
	  {
	  *fully_qualified_name = namesuff + 1;
	  return DNS_SUCCEED;
	  }
	}
      }
    return DNS_NOMATCH;
    }

  default:
    if (type >= 0)
      return dns_lookup(dnsa, name, type, fully_qualified_name);
  }

/* Control should never reach here */

return DNS_FAIL;
}
Пример #23
0
static int http_fileop_open(void **ref,void *fsctx_arg,char *filename,int mode)
{
    http_fsctx_t *fsctx;
    http_file_t *file;
    char temp[200];
    char *hostname, *filen;
    int hlen;
    int termidx;
    int res;
    int err = 0;
    char *hptr;
    char *tok;
    uint8_t hostaddr[IP_ADDR_LEN];
    uint8_t termstr[4];
    uint8_t b;

    if (mode != FILE_MODE_READ) return CFE_ERR_UNSUPPORTED;

    fsctx = (http_fsctx_t *) fsctx_arg;

    file = KMALLOC(sizeof(http_file_t),0);
    if (!file) {
	return CFE_ERR_NOMEM;
	}

    file->http_filename = lib_strdup(filename);
    if (!file->http_filename) {
	KFREE(file);
	return CFE_ERR_NOMEM;
	}

    lib_chop_filename(file->http_filename,&hostname,&filen);

    /*
     * Look up remote host
     */

    res = dns_lookup(hostname,hostaddr);
    if (res < 0) {
	KFREE(file);
	return res;
	}

    file->http_socket = tcp_socket();
    if (file->http_socket < 0) {
	KFREE(file->http_filename);
	KFREE(file);
	return -1;
	}

    /*
     * Connect to remote host.
     */

    tcp_setflags(file->http_socket,0);	/* set socket to blocking */
    res = tcp_connect(file->http_socket,hostaddr,80);

    if (res < 0) {
	tcp_close(file->http_socket);
	KFREE(file->http_filename);
	KFREE(file);
	return res;
	}

    /*
     * Send GET command.  Supply the hostname (for HTTP 1.1 requirements)
     * and set the connection to close as soon as all the data is received.
     */

    hlen = sprintf(temp,"GET /%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n",filen,hostname);

    res = tcp_send(file->http_socket,temp,hlen);
    if (res < 0) {
	tcp_close(file->http_socket);
	KFREE(file->http_filename);
	KFREE(file);
	return res;
	}

    /*
     * Read bytes until we either reach EOF or we see "\r\n\r\n"
     * This is the server's status string.
     */

    termstr[0] = '\r'; termstr[1] = '\n';
    termstr[2] = '\r'; termstr[3] = '\n';
    termidx = 0;

    file->http_offset = 0;
    file->http_blen = 0;
    file->http_bptr = file->http_buffer;

    res = 0;
    for (;;) {
	res = tcp_recv(file->http_socket,&b,1);
	if (res < 0) break;
	if (b == termstr[termidx]) {
	    termidx++;
	    if (termidx == 4) break;
	    }
	else {
	    termidx = 0;
	    }

	/*
	 * Save the bytes from the header up to our buffer
	 * size.  It's okay if we don't save it all,
	 * since all we want is the result code which comes
	 * first.
	 */

	if (file->http_blen < (HTTP_BUFSIZE-1)) {
	    *(file->http_bptr) = b;
	    file->http_bptr++;
	    file->http_blen++;
	    }
	}

    /*
     * Premature EOFs are not good, bail now.
     */

    if (res < 0) {
	err = CFE_ERR_EOF;
	goto protocolerr;
	}

    /*
     * Skip past the HTTP response header and grab the result code.
     * Sanity check it a little.
     */

    *(file->http_bptr) = 0;

    hptr = file->http_buffer;
    tok = lib_gettoken(&hptr);
    if (!tok || (memcmp(tok,"HTTP",4) != 0)) {
	err = CFE_ERR_PROTOCOLERR;
	goto protocolerr;
	}

    tok = lib_gettoken(&hptr);
    if (!tok) {
	err = CFE_ERR_PROTOCOLERR;
	goto protocolerr;
	}

    switch (lib_atoi(tok)) {
	case 200:
	    err = 0;
	    break;
	case 404:
	    err = CFE_ERR_FILENOTFOUND;
	    break;

	}

    /*
     * If we get to here, the file is okay and we're about to receive data.
     */

    if (err == 0) {
	*ref = file;
	return 0;
	}

protocolerr:
    tcp_close(file->http_socket);
    KFREE(file->http_filename);
    KFREE(file);
    *ref = NULL;
    return err;
}
static int _tftp_open(tftp_info_t *info,char *hostname,char *filename,int mode)
{
    ebuf_t *buf = NULL;
    const char *datamode = "octet";
    uint16_t type,error,block;
    int res;
    int retries;

    /*
     * Look up the remote host's IP address
     */

    res = dns_lookup(hostname,info->tftp_ipaddr);
    if (res < 0) return res;

    /*
     * Open a UDP socket to the TFTP server
     */    

    info->tftp_socket = udp_socket(UDP_PROTO_TFTP);
    info->tftp_lastblock = 0;
    info->tftp_error = 0;
    info->tftp_filemode = mode;

    /*
     * Try to send the RRQ packet to open the file
     */

    for (retries = 0; retries < tftp_max_retries; retries++) {

	buf = udp_alloc();
	if (!buf) break;

	if (info->tftp_filemode == FILE_MODE_READ) {
	    ebuf_append_u16_be(buf,TFTP_OP_RRQ);	/* read file */
	    }
	else {
	    ebuf_append_u16_be(buf,TFTP_OP_WRQ);	/* write file */
	    }
	ebuf_append_bytes(buf,filename,strlen(filename)+1);
	ebuf_append_bytes(buf,datamode,strlen(datamode)+1);

	udp_send(info->tftp_socket,buf,info->tftp_ipaddr);

	buf = udp_recv_with_timeout(info->tftp_socket,tftp_rrq_timeout);
	if (buf) break;
	}

    /*
     * If we got no response, bail now.
     */

    if (!buf) {
	udp_close(info->tftp_socket);
	info->tftp_socket = -1;
	return CFE_ERR_TIMEOUT;
	}

    /*
     * Otherwise, process the response.
     */

    ebuf_get_u16_be(buf,type);

    switch (type) {
	case TFTP_OP_ACK:
	    /*
	     * Acks are what we get back on a WRQ command,
	     * but are otherwise unexpected.
	     */
	    if (info->tftp_filemode == FILE_MODE_WRITE) {
		udp_connect(info->tftp_socket,(uint16_t) buf->eb_usrdata);
		info->tftp_blknum = 1;
		info->tftp_blklen = 0;
		udp_free(buf);
		return 0;
		break;
		}
	    /* fall through */
	case TFTP_OP_RRQ:
	case TFTP_OP_WRQ:
	default:
	    /* 
	     * we aren't expecting any of these messages
	     */
	    udp_free(buf);
	    udp_close(info->tftp_socket);
	    info->tftp_socket = -1;
	    return CFE_ERR_PROTOCOLERR;

	case TFTP_OP_ERROR:
	    ebuf_get_u16_be(buf,error);
	    xprintf("TFTP error %d: %s\n",error,ebuf_ptr(buf));
	    udp_free(buf);
	    udp_close(info->tftp_socket);
	    info->tftp_socket = -1;
	    return CFE_ERR_PROTOCOLERR;

	case TFTP_OP_DATA:
	    /*
	     * Yay, we've got data!  Store the first block.
	     */
	    ebuf_get_u16_be(buf,block);
	    udp_connect(info->tftp_socket,(uint16_t) buf->eb_usrdata);
	    info->tftp_blknum = block;
	    info->tftp_blklen = ebuf_length(buf);
	    ebuf_get_bytes(buf,info->tftp_data,ebuf_length(buf));
	    udp_free(buf);
	    if (info->tftp_blklen < TFTP_BLOCKSIZE) {
		info->tftp_lastblock = 1;		/* EOF */
		}
	    return 0;
	    break;
	    
	}
}
Пример #25
0
void* http_job::run()
{
	char  addr[256];
	if (acl::http_utils::get_addr(url_, addr, sizeof(addr)) == false)
	{
		logger_error("invalid url: %s", url_.c_str());
		return NULL;
	}

	char* domain = addr, *ptr = strchr(domain, ':');
	int   port;
	if (ptr == NULL)
		port = 80;
	else
	{
		*ptr++ = 0;
		port = atoi(ptr);
	}

	std::vector<acl::string> ips;

	struct timeval begin, end;

	gettimeofday(&begin, NULL);

	// 查询域名的 IP 列表
	if (dns_lookup(domain, ips) == false)
	{
		delete this;
		return NULL;
	}

	gettimeofday(&end, NULL);

	// 计算 DNS 的查询耗时
	double spent = util::stamp_sub(&end, &begin);

	std::vector<acl::thread*> threads;

	// 遍历 IP 地址列表,每一个 IP 创建一个 HTTP 客户端线程
	std::vector<acl::string>::const_iterator cit = ips.begin();
	for (; cit != ips.end(); ++cit)
	{
		// 创建并启动一个线程对象
		acl::thread* thr = new http_thread(domain, (*cit).c_str(),
				port, url_.c_str(), spent);
		thr->set_detachable(false);  // 设置线程为非分离状态
		thr->start();
		threads.push_back(thr);
	}

	// 等待所有 HTTP 工作线程执行完毕
	std::vector<acl::thread*>::iterator it = threads.begin();
	for (; it != threads.end(); ++it)
	{
		acl::thread* thr = (*it);
		thr->wait();
		delete thr;
	}

	delete this;  // 自销毁
	return NULL;
}
struct hostent *gethostbyname_nsd(const char *name, const char *SourceIp)
{
	static struct hostent h;
	static char namebuf[256];
	static struct in_addr in;
	static struct in_addr *addr_list[2];
	struct hostent *hp;
	unsigned char *packet;
	struct resolv_answer a;
	int i;
	int nest = 0;

	open_nameservers();

	if (!name)
		return 0;

	if ((hp = get_hosts_byname(name, AF_INET))) /* do /etc/hosts first */
		return(hp);

	memset(&h, 0, sizeof(h));

	addr_list[0] = &in;
	addr_list[1] = 0;
	
	strncpy(namebuf, name, sizeof(namebuf));

	/* First check if this is already an address */
	if (inet_aton(name, &in)) {
	    h.h_name = namebuf;
	    h.h_addrtype = AF_INET;
	    h.h_length = sizeof(in);
	    h.h_addr_list = (char **) addr_list;
	    return &h;
	}

	for (;;) {

		i = dns_lookup(namebuf, 1, nameservers, nameserver, &packet, &a, SourceIp);

		if (i < 0)
			return 0;

		strncpy(namebuf, a.dotted, sizeof(namebuf));
		free(a.dotted);


		if (a.atype == T_CNAME) {		/* CNAME */
			DPRINTF("Got a CNAME in gethostbyname()\n");
			i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf));
			free(packet);

			if (i < 0)
				return 0;
			if (++nest > MAX_RECURSE)
				return 0;
			continue;
		} else if (a.atype == T_A) {	/* ADDRESS */
			memcpy(&in, a.rdata, sizeof(in));
			h.h_name = namebuf;
			h.h_addrtype = AF_INET;
			h.h_length = sizeof(in);
			h.h_addr_list = (char **) addr_list;
			free(packet);
			break;
		} else {
			free(packet);
			return 0;
		}
	}

	return &h;
}
Пример #27
0
void split_redraw(void) 
{
  int   max;
  int   at;
  ip_t *addr, *addrs;
  char  newLine[MAX_LINE_SIZE];
  int   i;

#if DEBUG
  SPLIT_PRINT(("split_redraw()"));
#endif

  /* 
   * If there is less lines than last time, we delete them
   * TEST THIS PLEASE
   */
  max = net_max();
  for (i=LineCount; i>max; i--) {
    SPLIT_PRINT(("-%d", i));
    LineCount--;
  }

  /*
   * For each line, we compute the new one and we compare it to the old one
   */
  for(at = 0; at < max; at++) {
    addr = net_addr(at);
    if(addrcmp((void*)addr, (void*)&unspec_addr, af)) {
      char str[256], *name;
      if (!(name = dns_lookup(addr)))
        name = strlongip(addr);
      if (show_ips) {
        snprintf(str, sizeof(str), "%s\t%s", name, strlongip(addr));
        name = str;
      }
      /* May be we should test name's length */
      snprintf(newLine, sizeof(newLine), "%s\t%s\t%.1f\t%d\t%d\t%.1f\t%.1f\t%.1f\t%.1f", name, fmt_ipinfo(addr),
               net_loss(at)/1000.0,
               net_returned(at), net_xmit(at),
               net_best(at) /1000.0, net_avg(at)/1000.0,
               net_worst(at)/1000.0,
               net_stdev(at)/1000.0);
    } else {
      sprintf(newLine, "???");
    }

    if (strcmp(newLine, Lines[at]) == 0) {
      /* The same, so do nothing */
#if DEBUG
      SPLIT_PRINT(("SAME LINE"));
#endif
    } else {
      SPLIT_PRINT(("%d\t%s", at+1, newLine));

      if (strcmp(newLine, "???") != 0) {
        /* Multi path */
        for (i=0; i < MAXPATH; i++ ) {
          addrs = net_addrs(at, i);
          if ( addrcmp( (void *) addrs, (void *) addr, af ) == 0 ) continue;
          if ( addrcmp( (void *) addrs, (void *) &unspec_addr, af ) == 0 ) break;
          char *name;
 
          if (!(name = dns_lookup(addrs)))
            name = strlongip(addrs);
          if (show_ips) {
            SPLIT_PRINT(("-\t%d\t%d\t%s\t%s\t%s", at+1, i+1, name, strlongip(addrs), fmt_ipinfo(addrs)));
          } else {
            SPLIT_PRINT(("-\t%d\t%d\t%s\t%s", at+1, i+1, name, fmt_ipinfo(addrs)));
          }
        }
      }
 
      fflush(stdout);
      strcpy(Lines[at], newLine);
      if (LineCount < (at+1)) {
	LineCount = at+1;
      }
    }
  }
}
Пример #28
0
void mtr_curses_hosts(int startstat) 
{
  int max;
  int at;
  struct mplslen *mpls, *mplss;
  ip_t *addr, *addrs;
  int y;
  char *name;

  int i, j, k;
  int hd_len;
  char buf[1024];

  max = net_max();

  for(at = net_min () + display_offset; at < max; at++) {
    printw("%2d. ", at + 1);
    addr = net_addr(at);
    mpls = net_mpls(at);

    if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) {
      name = dns_lookup(addr);
      if (! net_up(at))
	attron(A_BOLD);
#ifdef IPINFO
      if (is_printii())
        printw(fmt_ipinfo(addr));
#endif
      if(name != NULL) {
        if (show_ips) printw("%s (%s)", name, strlongip(addr));
        else printw("%s", name);
      } else {
	printw("%s", strlongip( addr ) );
      }
      attroff(A_BOLD);

      getyx(stdscr, y, __unused_int);
      move(y, startstat);

      /* net_xxx returns times in usecs. Just display millisecs */
      hd_len = 0;
      for( i=0; i<MAXFLD; i++ ) {
	/* Ignore options that don't exist */
	/* On the other hand, we now check the input side. Shouldn't happen, 
	   can't be careful enough. */
	j = fld_index[fld_active[i]];
	if (j == -1) continue; 

	/* temporay hack for stats usec to ms... */
	if( index( data_fields[j].format, 'f' ) ) {
	  sprintf(buf + hd_len, data_fields[j].format,
		data_fields[j].net_xxx(at) /1000.0 );
	} else {
	  sprintf(buf + hd_len, data_fields[j].format,
		data_fields[j].net_xxx(at) );
	}
	hd_len +=  data_fields[j].length;
      }
      buf[hd_len] = 0;
      printw("%s", buf);

      for (k=0; k < mpls->labels && enablempls; k++) {
        if((k+1 < mpls->labels) || (mpls->labels == 1)) {
           /* if we have more labels */
           printw("\n    [MPLS: Lbl %lu Exp %u S %u TTL %u]", mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]);
        } else {
           /* bottom label */
           printw("\n    [MPLS: Lbl %lu Exp %u S %u TTL %u]", mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]);
        }
      }

      /* Multi path */
      for (i=0; i < MAXPATH; i++ ) {
        addrs = net_addrs(at, i);
        mplss = net_mplss(at, i);
	if ( addrcmp( (void *) addrs, (void *) addr, af ) == 0 ) continue;
	if ( addrcmp( (void *) addrs, (void *) &unspec_addr, af ) == 0 ) break;

        name = dns_lookup(addrs);
        if (! net_up(at)) attron(A_BOLD);
        printw("\n    ");
#ifdef IPINFO
        if (is_printii())
          printw(fmt_ipinfo(addrs));
#endif
        if (name != NULL) {
	  if (show_ips) printw("%s (%s)", name, strlongip(addrs));
	  else printw("%s", name);
        } else {
	  printw("%s", strlongip( addrs ) );
        }
        for (k=0; k < mplss->labels && enablempls; k++) {
          printw("\n    [MPLS: Lbl %lu Exp %u S %u TTL %u]", mplss->label[k], mplss->exp[k], mplss->s[k], mplss->ttl[k]);
        }
        attroff(A_BOLD);
      }

    } else {
      printw("???");
    }

    printw("\n");
  }
  move(2, 0);
}
Пример #29
0
listhead_t *run_net_tests(int concurrency, char *sourceip4, char *sourceip6)
{
	int maxfd;

	list_shuffle(pendingtests);

	/* 
	 * Determine how many tests can run in parallel.
	 * If no --concurrency set by user, default to (FD_SETSIZE / 4) - typically 256.
	 * But never go above the ressource limit that is set, or above FD_SETSIZE.
	 * And we save some fd's - 20 - for stdio, libs etc.
	 */
	{
		int absmaxconcurrency = (FD_SETSIZE - 20);
		struct rlimit lim;

		getrlimit(RLIMIT_NOFILE, &lim);
		if ((lim.rlim_cur > 20) && ((lim.rlim_cur - 20) < absmaxconcurrency)) absmaxconcurrency = (lim.rlim_cur - 20);

		if (concurrency == 0) concurrency = (FD_SETSIZE / 4);
		if (concurrency > absmaxconcurrency) concurrency = absmaxconcurrency;
	}

	/* Loop to process data */
	do {
		fd_set fdread, fdwrite;
		int n;
		struct timeval tmo;
		myconn_t *rec;
		listitem_t *pcur, *pnext;
		int lookupsposted = 0;

		dbgprintf("*** Starting test loop ***\n");
		/* Start some more tests */
		pcur = pendingtests->head;
		while (pcur && (activetests->len < concurrency) && (lookupsposted < concurrency)) {
			rec = (myconn_t *)pcur->data;

			dbgprintf("  Test: %s\n", rec->testspec);

			/* 
			 * Must save the pointer to the next pending test now, 
			 * since we may move the current item from the pending
			 * list to the active list before going to the next
			 * item in the pending-list.
			 */
			pnext = pcur->next;

			if (rec->netparams.lookupstatus == LOOKUP_NEEDED) {
				dbgprintf("    LOOKUP_NEEDED\n");
				lookupsposted++;
				dns_lookup(rec);
			}

			if ((rec->netparams.lookupstatus == LOOKUP_ACTIVE) || (rec->netparams.lookupstatus == LOOKUP_NEEDED)) {
				/* DNS lookup in progress, skip this test until lookup completes */
				dbgprintf("    lookup in progress: %s\n", (rec->netparams.lookupstatus == LOOKUP_ACTIVE) ? "ACTIVE" : "NEEDED");
				pcur = pnext;
				continue;
			}
			else if (rec->netparams.lookupstatus == LOOKUP_FAILED) {
				/* DNS lookup determined that this host does not have a valid IP. */
				dbgprintf("    LOOKUP_FAILED\n");
				switch (dnsstrategy) {
				  case DNS_STRATEGY_HOSTNAME:
					/* DNS failed -> test failed */
					list_item_move(donetests, pcur, rec->testspec);
					rec->talkresult = TALK_CANNOT_RESOLVE;
					break;
				  case DNS_STRATEGY_STANDARD:
				  case DNS_STRATEGY_IP:	/* This one cannot really happen */
					/* Use IP from hosts.cfg, if it is valid */
					if (!conn_null_ip(xmh_item(rec->hostinfo, XMH_IP))) {
						xfree(rec->netparams.destinationip);
						rec->netparams.destinationip = strdup(xmh_item(rec->hostinfo, XMH_IP));
						rec->netparams.lookupstatus = LOOKUP_COMPLETED;
					}
					else {
						list_item_move(donetests, pcur, rec->testspec);
						rec->talkresult = TALK_CANNOT_RESOLVE;
					}
					break;
				}
				pcur = pnext;
				continue;
			}

			switch (rec->talkprotocol) {
			  case TALK_PROTO_PLAIN:
			  case TALK_PROTO_HTTP:
			  case TALK_PROTO_NTP:
			  case TALK_PROTO_LDAP:
			  case TALK_PROTO_EXTERNAL:
				if (!rec->teststarttime) rec->teststarttime = getcurrenttime(NULL);
				dbgprintf("    conn_prepare_connection()\n");
				if (!rec->netparams.sourceip && (sourceip4 || sourceip6)) {
					switch (conn_is_ip(rec->netparams.destinationip)) {
					  case 4: rec->netparams.sourceip = sourceip4; break;
					  case 6: rec->netparams.sourceip = sourceip6; break;
					}
				}
				if (conn_prepare_connection(rec->netparams.destinationip, 
							rec->netparams.destinationport, 
							rec->netparams.socktype,
							rec->netparams.sourceip, 
							rec->netparams.sslhandling, rec->netparams.sslname, rec->netparams.sslcertfn, rec->netparams.sslkeyfn, 
							rec->timeout*1000000,
							rec->netparams.callback, rec)) {
					dbgprintf("\tmoved to activetests, target %s, timeout %d\n", 
						  rec->netparams.destinationip, rec->timeout);
					list_item_move(activetests, pcur, rec->testspec);
				}
				else {
					dbgprintf("\tmoved to failedtests\n");
					rec->talkresult = TALK_CONN_FAILED;
					list_item_move(donetests, pcur, rec->testspec);
				}
				break;

			  case TALK_PROTO_DNSQUERY:
				dbgprintf("    dns_start_query()\n");
				if (dns_start_query(rec, rec->netparams.destinationip)) {
					dbgprintf("\tmoved to activetests\n");
					list_item_move(activetests, pcur, rec->testspec);
				}
				else {
					dbgprintf("\tmoved to failedtests\n");
					rec->talkresult = TALK_CONN_FAILED;
					list_item_move(donetests, pcur, rec->testspec);
				}
				break;

			  case TALK_PROTO_PING:
				dbgprintf("    PING test, queued\n");
				rec->talkresult = TALK_OK;
				list_item_move(donetests, pcur, rec->testspec);
				break;

			  default:
				dbgprintf("    Huh?\n");
				break;
			}

			pcur = pnext;
		}

		maxfd = conn_fdset(&fdread, &fdwrite);
		// dbgprintf("Setting up select - conn_fdset has maxfd=%d\n", maxfd);
		dns_add_active_fds(activetests, &maxfd, &fdread, &fdwrite);
		// dbgprintf("Setting up select - dns_add_active_fds set maxfd=%d\n", maxfd);

		if (maxfd > 0) {
			tmo.tv_sec = 1; tmo.tv_usec = 0;
			n = select(maxfd+1, &fdread, &fdwrite, NULL, &tmo);
			if (n < 0) {
				if (errno != EINTR) {
					errprintf("FATAL: select() returned error %s\n", strerror(errno));
					return NULL;
				}
			}

			conn_process_active(&fdread, &fdwrite);
			dns_process_active(activetests, &fdread, &fdwrite);
		}

		conn_trimactive();
		dns_finish_queries(activetests);
		dbgprintf("Active: %d, pending: %d\n", activetests->len, pendingtests->len);
	}
	while ((activetests->len + pendingtests->len) > 0);

	dns_finish_queries(donetests);

	return donetests;
}
Пример #30
0
DNS_RR *smtp_domain_addr(char *name, int misc_flags, DSN_BUF *why,
                         int *found_myself)
{
    DNS_RR *mx_names;
    DNS_RR *addr_list = 0;
    DNS_RR *self = 0;
    unsigned best_pref;
    unsigned best_found;

    dsb_reset(why);				/* Paranoia */

    /*
     * Preferences from DNS use 0..32767, fall-backs use 32768+.
     */
#define IMPOSSIBLE_PREFERENCE	(~0)

    /*
     * Sanity check.
     */
    if (var_disable_dns)
        msg_panic("smtp_domain_addr: DNS lookup is disabled");

    /*
     * Look up the mail exchanger hosts listed for this name. Sort the
     * results by preference. Look up the corresponding host addresses, and
     * truncate the list so that it contains only hosts that are more
     * preferred than myself. When no MX resource records exist, look up the
     * addresses listed for this name.
     *
     * According to RFC 974: "It is possible that the list of MXs in the
     * response to the query will be empty.  This is a special case.  If the
     * list is empty, mailers should treat it as if it contained one RR, an
     * MX RR with a preference value of 0, and a host name of REMOTE.  (I.e.,
     * REMOTE is its only MX).  In addition, the mailer should do no further
     * processing on the list, but should attempt to deliver the message to
     * REMOTE."
     *
     * Normally it is OK if an MX host cannot be found in the DNS; we'll just
     * use a backup one, and silently ignore the better MX host. However, if
     * the best backup that we can find in the DNS is the local machine, then
     * we must remember that the local machine is not the primary MX host, or
     * else we will claim that mail loops back.
     *
     * XXX Optionally do A lookups even when the MX lookup didn't complete.
     * Unfortunately with some DNS servers this is not a transient problem.
     *
     * XXX Ideally we would perform A lookups only as far as needed. But as long
     * as we're looking up all the hosts, it would be better to look up the
     * least preferred host first, so that DNS lookup error messages make
     * more sense.
     *
     * XXX 2821: RFC 2821 says that the sender must shuffle equal-preference MX
     * hosts, whereas multiple A records per hostname must be used in the
     * order as received. They make the bogus assumption that a hostname with
     * multiple A records corresponds to one machine with multiple network
     * interfaces.
     *
     * XXX 2821: Postfix recognizes the local machine by looking for its own IP
     * address in the list of mail exchangers. RFC 2821 says one has to look
     * at the mail exchanger hostname as well, making the bogus assumption
     * that an IP address is listed only under one hostname. However, looking
     * at hostnames provides a partial solution for MX hosts behind a NAT
     * gateway.
     */
    switch (dns_lookup(name, T_MX, 0, &mx_names, (VSTRING *) 0, why->reason)) {
    default:
        dsb_status(why, "4.4.3");
        if (var_ign_mx_lookup_err)
            addr_list = smtp_host_addr(name, misc_flags, why);
        break;
    case DNS_INVAL:
        dsb_status(why, "5.4.4");
        if (var_ign_mx_lookup_err)
            addr_list = smtp_host_addr(name, misc_flags, why);
        break;
    case DNS_FAIL:
        dsb_status(why, "5.4.3");
        if (var_ign_mx_lookup_err)
            addr_list = smtp_host_addr(name, misc_flags, why);
        break;
    case DNS_OK:
        mx_names = dns_rr_sort(mx_names, dns_rr_compare_pref_any);
        best_pref = (mx_names ? mx_names->pref : IMPOSSIBLE_PREFERENCE);
        addr_list = smtp_addr_list(mx_names, why);
        dns_rr_free(mx_names);
        if (addr_list == 0) {
            /* Text does not change. */
            if (var_smtp_defer_mxaddr) {
                /* Don't clobber the null terminator. */
                if (SMTP_HAS_HARD_DSN(why))
                    SMTP_SET_SOFT_DSN(why);	/* XXX */
                /* Require some error status. */
                else if (!SMTP_HAS_SOFT_DSN(why))
                    msg_panic("smtp_domain_addr: bad status");
            }
            msg_warn("no MX host for %s has a valid address record", name);
            break;
        }
        best_found = (addr_list ? addr_list->pref : IMPOSSIBLE_PREFERENCE);
        if (msg_verbose)
            smtp_print_addr(name, addr_list);
        if ((misc_flags & SMTP_MISC_FLAG_LOOP_DETECT)
                && (self = smtp_find_self(addr_list)) != 0) {
            addr_list = smtp_truncate_self(addr_list, self->pref);
            if (addr_list == 0) {
                if (best_pref != best_found) {
                    dsb_simple(why, "4.4.4",
                               "unable to find primary relay for %s", name);
                } else {
                    dsb_simple(why, "5.4.6", "mail for %s loops back to myself",
                               name);
                }
            }
        }
#define SMTP_COMPARE_ADDR(flags) \
	(((flags) & SMTP_MISC_FLAG_PREF_IPV6) ? dns_rr_compare_pref_ipv6 : \
	 ((flags) & SMTP_MISC_FLAG_PREF_IPV4) ? dns_rr_compare_pref_ipv4 : \
	 dns_rr_compare_pref_any)

        if (addr_list && addr_list->next && var_smtp_rand_addr) {
            addr_list = dns_rr_shuffle(addr_list);
            addr_list = dns_rr_sort(addr_list, SMTP_COMPARE_ADDR(misc_flags));
        }
        break;
    case DNS_NOTFOUND:
        addr_list = smtp_host_addr(name, misc_flags, why);
        break;
    }

    /*
     * Clean up.
     */
    *found_myself |= (self != 0);
    return (addr_list);
}