コード例 #1
0
ファイル: dig8.c プロジェクト: VargMon/netbsd-cvs-mirror
static int
print_axfr(FILE *file, const u_char *msg, size_t msglen) {
	ns_msg handle;

	if (ns_initparse(msg, msglen, &handle) < 0) {
		fprintf(file, ";; ns_initparse: %s\n", strerror(errno));
		return (ns_r_formerr);
	}
	if (ns_msg_getflag(handle, ns_f_rcode) != ns_r_noerror)
		return (ns_msg_getflag(handle, ns_f_rcode));

	/*
	 * We are looking for info from answer resource records.
	 * If there aren't any, return with an error. We assume
	 * there aren't any question records.
	 */
	if (ns_msg_count(handle, ns_s_an) == 0)
		return (NO_INFO);

#ifdef PROTOCOLDEBUG
	printf(";;; (message of %d octets has %d answers)\n",
	       msglen, ns_msg_count(handle, ns_s_an));
#endif
	for (;;) {
		static char origin[NS_MAXDNAME], name_ctx[NS_MAXDNAME];
		const char *name;
		char buf[2048];		/* XXX need to malloc/realloc. */
		ns_rr rr;

		if (ns_parserr(&handle, ns_s_an, -1, &rr)) {
			if (errno != ENODEV) {
				fprintf(file, ";; ns_parserr: %s\n",
					strerror(errno));
				return (FORMERR);
			}
			break;
		}
		name = ns_rr_name(rr);
		if (origin[0] == '\0' && name[0] != '\0') {
			if (strcmp(name, ".") != 0)
				strcpy(origin, name);
			fprintf(file, "$ORIGIN %s.\n", origin);
			if (strcmp(name, ".") == 0)
				strcpy(origin, name);
			if (res.pfcode & RES_PRF_TRUNC)
				strcpy(name_ctx, "@");
		}
		if (ns_sprintrr(&handle, &rr,
				(res.pfcode & RES_PRF_TRUNC) ? name_ctx : NULL,
				(res.pfcode & RES_PRF_TRUNC) ? origin : NULL,
				buf, sizeof buf) < 0) {
			fprintf(file, ";; ns_sprintrr: %s\n", strerror(errno));
			return (FORMERR);
		}
		strcpy(name_ctx, name);
		fputs(buf, file);
		fputc('\n', file);
	}
	return (SUCCESS);
}
コード例 #2
0
static void test_res_fake_aaaa_query(void **state)
{
    int rv;
    struct __res_state dnsstate;
    unsigned char answer[ANSIZE];
    char addr[INET6_ADDRSTRLEN];
    ns_msg handle;
    ns_rr rr;   /* expanded resource record */

    (void) state; /* unused */

    memset(&dnsstate, 0, sizeof(struct __res_state));
    rv = res_ninit(&dnsstate);
    assert_int_equal(rv, 0);

    rv = res_nquery(&dnsstate, "cwrap6.org", ns_c_in, ns_t_aaaa,
                    answer, sizeof(answer));
    assert_in_range(rv, 1, 100);

    ns_initparse(answer, sizeof(answer), &handle);
    /* The query must finish w/o an error, have one answer and the answer
     * must be a parseable RR of type AAAA and have the address that our
     * fake hosts file contains
     */
    assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
    assert_int_equal(ns_msg_count(handle, ns_s_an), 1);
    assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
    assert_int_equal(ns_rr_type(rr), ns_t_aaaa);
    assert_non_null(inet_ntop(AF_INET6, ns_rr_rdata(rr),
                              addr, sizeof(addr)));
    assert_string_equal(addr, "2a00:1450:4013:c01::63");
}
コード例 #3
0
ファイル: dnsresolv.c プロジェクト: mrmt/enma
/*
 * クエリを投げる.
 * @return
 */
static int
DnsResolver_query(DnsResolver *self, const char *domain, int rrtype)
{
    self->resolver.res_h_errno = 0;
    self->resolv_errno = 0;
    self->resolv_h_errno = NETDB_SUCCESS;
    self->msglen = res_nquery(&self->resolver, domain, ns_c_in, rrtype, self->msgbuf, NS_MAXMSG);
    if (0 > self->msglen) {
        goto queryfail;
    }   // end if
    if (0 > ns_initparse(self->msgbuf, self->msglen, &self->msghanlde)) {
        self->resolver.res_h_errno = NO_RECOVERY;
        goto queryfail;
    }   // end if

    int rcode_flag = ns_msg_getflag(self->msghanlde, ns_f_rcode);
    if (rcode_flag != ns_r_noerror) {
        self->resolver.res_h_errno = DnsResolver_rcode2statcode(rcode_flag);
        goto queryfail;
    }   // end if

    return NETDB_SUCCESS;

  queryfail:
    return DnsResolver_setError(self, self->resolver.res_h_errno);
}   // end function : DnsResolver_query
コード例 #4
0
static void test_res_fake_a_query_case_insensitive(void **state)
{
    int rv;
    struct __res_state dnsstate;
    unsigned char answer[ANSIZE];
    char addr[INET_ADDRSTRLEN];
    ns_msg handle;
    ns_rr rr;   /* expanded resource record */

    (void) state; /* unused */

    memset(&dnsstate, 0, sizeof(struct __res_state));
    rv = res_ninit(&dnsstate);
    assert_int_equal(rv, 0);

    rv = res_nquery(&dnsstate, "CWRAP.ORG", ns_c_in, ns_t_a,
                    answer, sizeof(answer));
    assert_in_range(rv, 1, 100);

    ns_initparse(answer, sizeof(answer), &handle);
    /* The query must finish w/o an error, have one answer and the answer
     * must be a parseable RR of type A and have the address that our
     * fake hosts file contains. Case does not matter.
     */
    assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
    assert_int_equal(ns_msg_count(handle, ns_s_an), 1);
    assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
    assert_int_equal(ns_rr_type(rr), ns_t_a);
    assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr),
                              addr, sizeof(addr)));
    assert_string_equal(addr, "127.0.0.21");

    res_nclose(&dnsstate);
}
コード例 #5
0
ファイル: res_debug.c プロジェクト: hsienchieh/uefilab
static void
do_section(ns_msg *handle, ns_sect section, int pflag, FILE *file) {
    int n, sflag, rrnum;
    ns_opcode opcode;
    ns_rr rr;

    /*
     * Print answer records.
     */
    sflag = (int)(_res.pfcode & pflag);
    if (_res.pfcode && !sflag)
        return;

    opcode = ns_msg_getflag(*handle, ns_f_opcode);
    rrnum = 0;
    for (;;) {
        if (ns_parserr(handle, section, rrnum, &rr)) {
            if (errno != ENODEV)
                fprintf(file, ";; ns_parserr: %s\n",
                    strerror(errno));
            else if (rrnum > 0 && sflag != 0 &&
                 (_res.pfcode & RES_PRF_HEAD1))
                putc('\n', file);
            return;
        }
        if (rrnum == 0 && sflag != 0 && (_res.pfcode & RES_PRF_HEAD1))
            fprintf(file, ";; %s SECTION:\n",
                p_section(section, opcode));
        if (section == ns_s_qd)
            fprintf(file, ";;\t%s, type = %s, class = %s\n",
                ns_rr_name(rr),
                p_type(ns_rr_type(rr)),
                p_class(ns_rr_class(rr)));
        else {
            char *buf;
            buf = (char*)malloc(2024);
            if (buf) {
                n = ns_sprintrr(handle, &rr, NULL, NULL,
                        buf, sizeof buf);
                if (n < 0) {
                    fprintf(file, ";; ns_sprintrr: %s\n",
                        strerror(errno));
                    free(buf);
                    return;
                }
                fputs(buf, file);
                fputc('\n', file);
                free(buf);
            }
        }
        rrnum++;
    }
}
コード例 #6
0
static void test_res_fake_srv_query(void **state)
{
    int rv;
    struct __res_state dnsstate;
    unsigned char answer[ANSIZE];
    ns_msg handle;
    ns_rr rr;   /* expanded resource record */
    const uint8_t *rrdata;
    int prio;
    int weight;
    int port;
    char hostname[MAXDNAME];

    (void) state; /* unused */

    memset(&dnsstate, 0, sizeof(struct __res_state));
    rv = res_ninit(&dnsstate);
    assert_int_equal(rv, 0);

    rv = res_nquery(&dnsstate, "_ldap._tcp.cwrap.org", ns_c_in, ns_t_srv,
                    answer, sizeof(answer));
    assert_in_range(rv, 1, 100);

    ns_initparse(answer, sizeof(answer), &handle);

    /*
     * The query must finish w/o an error, have one answer and the answer
     * must be a parseable RR of type SRV and have the priority, weight,
     * port and hostname as in the fake hosts file
     */
    assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
    assert_int_equal(ns_msg_count(handle, ns_s_an), 1);
    assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
    assert_int_equal(ns_rr_type(rr), ns_t_srv);

    rrdata = ns_rr_rdata(rr);
    NS_GET16(prio, rrdata);
    NS_GET16(weight, rrdata);
    NS_GET16(port, rrdata);

    rv = ns_name_uncompress(ns_msg_base(handle),
                            ns_msg_end(handle),
                            rrdata,
                            hostname, MAXDNAME);
    assert_int_not_equal(rv, -1);

    assert_int_equal(prio, 1);
    assert_int_equal(weight, 5);
    assert_int_equal(port, 389);
    assert_string_equal(hostname, "ldap.cwrap.org");
}
コード例 #7
0
ファイル: res_debug.c プロジェクト: fortek/Fly_IQ_245
static void
do_section(const res_state statp,
	   ns_msg *handle, ns_sect section,
	   int pflag, FILE *file)
{
	int n, sflag, rrnum;
	int buflen = 2048;
	char *buf;
	ns_opcode opcode;
	ns_rr rr;

	/*
	 * Print answer records.
	 */
	sflag = (statp->pfcode & pflag);
	if (statp->pfcode && !sflag)
		return;

	buf = malloc((size_t)buflen);
	if (buf == NULL) {
		fprintf(file, ";; memory allocation failure\n");
		return;
	}

	opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode);
	rrnum = 0;
	for (;;) {
		if (ns_parserr(handle, section, rrnum, &rr)) {
			if (errno != ENODEV)
				fprintf(file, ";; ns_parserr: %s\n",
					strerror(errno));
			else if (rrnum > 0 && sflag != 0 &&
				 (statp->pfcode & RES_PRF_HEAD1))
				putc('\n', file);
			goto cleanup;
		}
		if (rrnum == 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1))
			fprintf(file, ";; %s SECTION:\n",
				p_section(section, opcode));
		if (section == ns_s_qd)
			fprintf(file, ";;\t%s, type = %s, class = %s\n",
				ns_rr_name(rr),
				p_type(ns_rr_type(rr)),
				p_class(ns_rr_class(rr)));
		else if (section == ns_s_ar && ns_rr_type(rr) == ns_t_opt) {
			u_int32_t ttl = ns_rr_ttl(rr);
			fprintf(file,
				"; EDNS: version: %u, udp=%u, flags=%04x\n",
				(ttl>>16)&0xff, ns_rr_class(rr), ttl&0xffff);
		} else {
コード例 #8
0
void
dump_dns(const u_char *payload, size_t paylen,
	  FILE *trace, const char *endline)
{
	u_int opcode, rcode, id;
	const char *sep;
	ns_msg msg;

	fprintf(trace, " %sdns ", endline);
	if (ns_initparse(payload, paylen, &msg) < 0) {
		fputs(strerror(errno), trace);
		return;
	}
	opcode = ns_msg_getflag(msg, ns_f_opcode);
	rcode = ns_msg_getflag(msg, ns_f_rcode);
	id = ns_msg_id(msg);
	fprintf(trace, "%s,%s,%u", p_opcode(opcode), p_rcode(rcode), id);
	sep = ",";
#define FLAG(t,f) if (ns_msg_getflag(msg, f)) { \
			fprintf(trace, "%s%s", sep, t); \
			sep = "|"; \
		  }
	FLAG("qr", ns_f_qr);
	FLAG("aa", ns_f_aa);
	FLAG("tc", ns_f_tc);
	FLAG("rd", ns_f_rd);
	FLAG("ra", ns_f_ra);
	FLAG("z", ns_f_z);
	FLAG("ad", ns_f_ad);
	FLAG("cd", ns_f_cd);
#undef FLAG
	dump_dns_sect(&msg, ns_s_qd, trace, endline);
	dump_dns_sect(&msg, ns_s_an, trace, endline);
	dump_dns_sect(&msg, ns_s_ns, trace, endline);
	dump_dns_sect(&msg, ns_s_ar, trace, endline);
}
コード例 #9
0
static void test_res_fake_aaaa_query_notfound(void **state)
{
    int rv;
    struct __res_state dnsstate;
    unsigned char answer[ANSIZE];
    ns_msg handle;

    (void) state; /* unused */

    memset(&dnsstate, 0, sizeof(struct __res_state));
    rv = res_ninit(&dnsstate);
    assert_int_equal(rv, 0);

    rv = res_nquery(&dnsstate, "nosuchentry.org", ns_c_in, ns_t_aaaa,
                    answer, sizeof(answer));
    assert_in_range(rv, 1, 100);

    ns_initparse(answer, sizeof(answer), &handle);
    /* The query must finish w/o an error and have no answer */
    assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
    assert_int_equal(ns_msg_count(handle, ns_s_an), 0);
}
コード例 #10
0
ファイル: ns_newmsg.c プロジェクト: nielx/haiku-serviceskit
/* Initialize a "newmsg" object by copying an existing parsed message.
 */
int
ns_newmsg_copy(ns_newmsg *handle, ns_msg *msg) {
    ns_flag flag;
    ns_sect sect;

    ns_newmsg_id(handle, ns_msg_id(*msg));
    for (flag = ns_f_qr; flag < ns_f_max; flag++)
        ns_newmsg_flag(handle, flag, ns_msg_getflag(*msg, flag));
    for (sect = ns_s_qd; sect < ns_s_max; sect++) {
        int i, count;

        count = ns_msg_count(*msg, sect);
        for (i = 0; i < count; i++) {
            ns_rr2 rr;
            int x;

            if (ns_parserr2(msg, sect, i, &rr) < 0)
                return (-1);
            if (sect == ns_s_qd)
                x = ns_newmsg_q(handle,
                                ns_rr_nname(rr),
                                ns_rr_type(rr),
                                ns_rr_class(rr));
            else
                x = ns_newmsg_rr(handle, sect,
                                 ns_rr_nname(rr),
                                 ns_rr_type(rr),
                                 ns_rr_class(rr),
                                 ns_rr_ttl(rr),
                                 ns_rr_rdlen(rr),
                                 ns_rr_rdata(rr));
            if (x < 0)
                return (-1);
        }
    }
    return (0);
}
コード例 #11
0
static void test_res_fake_cname_query(void **state)
{
    int rv;
    struct __res_state dnsstate;
    unsigned char answer[ANSIZE];
    ns_msg handle;
    ns_rr rr;   /* expanded resource record */
    const uint8_t *rrdata;
    char cname[MAXDNAME];
    char addr[INET_ADDRSTRLEN];

    (void) state; /* unused */

    memset(&dnsstate, 0, sizeof(struct __res_state));
    rv = res_ninit(&dnsstate);
    assert_int_equal(rv, 0);

    rv = res_nquery(&dnsstate, "rwrap.org", ns_c_in, ns_t_cname,
                    answer, sizeof(answer));
    assert_in_range(rv, 1, 256);

    ns_initparse(answer, 256, &handle);
    ns_initparse(answer, sizeof(answer), &handle);

    /*
     * The query must finish w/o an error, have one answer and the answer
     * must be a parseable RR of type CNAME and have the cname as in the
     * fake hosts file
     */
    assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
    assert_int_equal(ns_msg_count(handle, ns_s_an), 1);
    assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
    assert_int_equal(ns_rr_type(rr), ns_t_cname);

    rrdata = ns_rr_rdata(rr);

    rv = ns_name_uncompress(ns_msg_base(handle),
                            ns_msg_end(handle),
                            rrdata,
                            cname, MAXDNAME);
    assert_int_not_equal(rv, -1);

    assert_string_equal(cname, "web.cwrap.org");

    /* The CNAME points to an A record that's present in the additional
     * section
     */
    assert_int_equal(ns_msg_count(handle, ns_s_ar), 2);

    assert_int_equal(ns_parserr(&handle, ns_s_ar, 0, &rr), 0);
    assert_int_equal(ns_rr_type(rr), ns_t_cname);
    assert_string_equal(ns_rr_name(rr), "web.cwrap.org");
    rrdata = ns_rr_rdata(rr);

    rv = ns_name_uncompress(ns_msg_base(handle),
                            ns_msg_end(handle),
                            rrdata,
                            cname, MAXDNAME);
    assert_int_not_equal(rv, -1);

    assert_string_equal(cname, "www.cwrap.org");

    assert_int_equal(ns_parserr(&handle, ns_s_ar, 1, &rr), 0);
    assert_int_equal(ns_rr_type(rr), ns_t_a);
    assert_string_equal(ns_rr_name(rr), "www.cwrap.org");
    assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr),
                              addr, sizeof(addr)));
    assert_string_equal(addr, "127.0.0.22");
}
コード例 #12
0
static void
do_section(const res_state statp,
	   ns_msg *handle, ns_sect section,
	   int pflag, FILE *file)
{
	int n, sflag, rrnum;
	static int buflen = 2048;
	char *buf;
	ns_opcode opcode;
	ns_rr rr;

	/*
	 * Print answer records.
	 */
	sflag = (statp->pfcode & pflag);
	if (statp->pfcode && !sflag)
		return;

	buf = malloc(buflen);
	if (buf == NULL) {
		fprintf(file, ";; memory allocation failure\n");
		return;
	}

	opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode);
	rrnum = 0;
	for (;;) {
		if (ns_parserr(handle, section, rrnum, &rr)) {
			if (errno != ENODEV)
				fprintf(file, ";; ns_parserr: %s\n",
					strerror(errno));
			else if (rrnum > 0 && sflag != 0 &&
				 (statp->pfcode & RES_PRF_HEAD1))
				putc('\n', file);
			goto cleanup;
		}
		if (rrnum == 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1))
			fprintf(file, ";; %s SECTION:\n",
				p_section(section, opcode));
		if (section == ns_s_qd)
			fprintf(file, ";;\t%s, type = %s, class = %s\n",
				ns_rr_name(rr),
				p_type(ns_rr_type(rr)),
				p_class(ns_rr_class(rr)));
		else if (section == ns_s_ar && ns_rr_type(rr) == ns_t_opt) {
			u_int16_t optcode, optlen, rdatalen = ns_rr_rdlen(rr);
			u_int32_t ttl = ns_rr_ttl(rr);

			fprintf(file,
				"; EDNS: version: %u, udp=%u, flags=%04x\n",
				(ttl>>16)&0xff, ns_rr_class(rr), ttl&0xffff);

			while (rdatalen >= 4) {
				const u_char *cp = ns_rr_rdata(rr);
				int i;

				GETSHORT(optcode, cp);
				GETSHORT(optlen, cp);

				if (optcode == NS_OPT_NSID) {
					fputs("; NSID: ", file);
					if (optlen == 0) {
						fputs("; NSID\n", file);
					} else {
						fputs("; NSID: ", file);
						for (i = 0; i < optlen; i++)
							fprintf(file, "%02x ",
								cp[i]);
						fputs(" (",file);
						for (i = 0; i < optlen; i++)
							fprintf(file, "%c",
								isprint(cp[i])?
								cp[i] : '.');
						fputs(")\n", file);
					}
				} else {
					if (optlen == 0) {
						fprintf(file, "; OPT=%u\n",
							optcode);
					} else {
						fprintf(file, "; OPT=%u: ",
							optcode);
						for (i = 0; i < optlen; i++)
							fprintf(file, "%02x ",
								cp[i]);
						fputs(" (",file);
						for (i = 0; i < optlen; i++)
							fprintf(file, "%c",
								isprint(cp[i]) ?
									cp[i] : '.');
						fputs(")\n", file);
					}
				}
				rdatalen -= 4 + optlen;
			}
		} else {
コード例 #13
0
ファイル: wrapsrv.c プロジェクト: hstern/sie-dns-sensor
int
main(int argc, char **argv) {
	char *qname;
	ns_msg msg;
	int len, rc = 0;
	unsigned char answer[NS_MAXMSG];
	unsigned rcode;
	struct srv *se;

	if (argc < 3)
		usage();

	ISC_LIST_INIT(prio_list);

	srandom(time(NULL));

	res_init();

	qname = argv[1];

	len = res_query(qname, ns_c_in, ns_t_srv, answer, sizeof answer);
	if (len < 0) {
		herror("res_query");
		return (EXIT_FAILURE);
	}

	if (ns_initparse(answer, len, &msg) < 0) {
		perror("ns_initparse");
		return (EXIT_FAILURE);
	}

	rcode = ns_msg_getflag(msg, ns_f_rcode);
	if (rcode != ns_r_noerror) {
		fprintf(stderr, "wrapsrv: query for %s returned rcode %u\n",
			qname, rcode);
		return (EXIT_FAILURE);
	}

	if (ns_msg_count(msg, ns_s_an) == 0) {
		fprintf(stderr, "wrapsrv: query for %s returned no answers\n",
			qname);
		return (EXIT_FAILURE);
	}

	parse_answer_section(&msg);
#ifdef DEBUG
	print_tuples();
	fprintf(stderr, "\n");
#endif

	while ((se = next_tuple()) != NULL) {
		if ((rc = do_cmd(se, argc, argv)) == 0)
			break;
#ifdef DEBUG
		fprintf(stderr, "\n");
#endif
	}

	free_tuples();

	return (rc);
}
コード例 #14
0
ファイル: dns.c プロジェクト: bond/dma
int
dns_get_mx_list(const char *host, int port, struct mx_hostentry **he, int no_mx)
{
	char outname[MAXDNAME];
	ns_msg msg;
	ns_rr rr;
	const char *searchhost;
	const unsigned char *cp;
	unsigned char *ans;
	struct mx_hostentry *hosts = NULL;
	size_t nhosts = 0;
	size_t anssz;
	int pref;
	int cname_recurse;
	int err;
	int i;

	res_init();
	searchhost = host;
	cname_recurse = 0;

	anssz = 65536;
	ans = malloc(anssz);
	if (ans == NULL)
		return (1);

	if (no_mx)
		goto out;

repeat:
	err = res_search(searchhost, ns_c_in, ns_t_mx, ans, anssz);
	if (err < 0) {
		switch (h_errno) {
		case NO_DATA:
			/*
			 * Host exists, but no MX (or CNAME) entry.
			 * Not an error, use host name instead.
			 */
			goto out;
		case TRY_AGAIN:
			/* transient error */
			goto transerr;
		case NO_RECOVERY:
		case HOST_NOT_FOUND:
		default:
			errno = ENOENT;
			goto err;
		}
	}

	if (!ns_initparse(ans, anssz, &msg))
		goto transerr;

	switch (ns_msg_getflag(msg, ns_f_rcode)) {
	case ns_r_noerror:
		break;
	case ns_r_nxdomain:
		goto err;
	default:
		goto transerr;
	}

	for (i = 0; i < ns_msg_count(msg, ns_s_an); i++) {
		if (ns_parserr(&msg, ns_s_an, i, &rr))
			goto transerr;

		cp = ns_rr_rdata(rr);

		switch (ns_rr_type(rr)) {
		case ns_t_mx:
			pref = ns_get16(cp);
			cp += 2;
			err = ns_name_uncompress(ns_msg_base(msg), ns_msg_end(msg),
						 cp, outname, sizeof(outname));
			if (err < 0)
				goto transerr;

			add_host(pref, outname, port, &hosts, &nhosts);
			break;

		case ns_t_cname:
			err = ns_name_uncompress(ns_msg_base(msg), ns_msg_end(msg),
						 cp, outname, sizeof(outname));
			if (err < 0)
				goto transerr;

			/* Prevent a CNAME loop */
			if (cname_recurse++ > 10)
				goto err;

			searchhost = outname;
			goto repeat;

		default:
			break;
		}
	}

out:
	err = 0;
	if (0) {
transerr:
		if (nhosts == 0)
			err = 1;
	}
	if (0) {
err:
		err = -1;
	}

	free(ans);

	if (!err) {
		/*
		 * If we didn't find any MX, use the hostname instead.
		 */
		if (nhosts == 0)
			add_host(0, searchhost, port, &hosts, &nhosts);

		qsort(hosts, nhosts, sizeof(*hosts), sort_pref);
	}

	if (nhosts > 0) {
		/* terminate list */
		*hosts[nhosts].host = 0;
	} else {
		if (hosts != NULL)
			free(hosts);
		hosts = NULL;
	}

	*he = hosts;
	return (err);

	free(ans);
	if (hosts != NULL)
		free(hosts);
	return (err);
}
コード例 #15
0
ファイル: res_debug.c プロジェクト: hsienchieh/uefilab
/*
 * Print the contents of a query.
 * This is intended to be primarily a debugging routine.
 */
void
fp_nquery(const u_char *msg, int len, FILE *file) {
    ns_msg handle;
    int qdcount, ancount, nscount, arcount;
    u_int opcode, rcode, id;

    if ((_res.options & RES_INIT) == 0 && res_init() == -1)
        return;

    if (ns_initparse(msg, len, &handle) < 0) {
        fprintf(file, ";; ns_initparse: %s\n", strerror(errno));
        return;
    }
    opcode = ns_msg_getflag(handle, ns_f_opcode);
    rcode = ns_msg_getflag(handle, ns_f_rcode);
    id = ns_msg_id(handle);
    qdcount = ns_msg_count(handle, ns_s_qd);
    ancount = ns_msg_count(handle, ns_s_an);
    nscount = ns_msg_count(handle, ns_s_ns);
    arcount = ns_msg_count(handle, ns_s_ar);

    /*
     * Print header fields.
     */
    if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || rcode)
        fprintf(file,
            ";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",
            _res_opcodes[opcode], _res_resultcodes[rcode], (int)id);
    if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
        putc(';', file);
    if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
        fprintf(file, "; flags:");
        if (ns_msg_getflag(handle, ns_f_qr))
            fprintf(file, " qr");
        if (ns_msg_getflag(handle, ns_f_aa))
            fprintf(file, " aa");
        if (ns_msg_getflag(handle, ns_f_tc))
            fprintf(file, " tc");
        if (ns_msg_getflag(handle, ns_f_rd))
            fprintf(file, " rd");
        if (ns_msg_getflag(handle, ns_f_ra))
            fprintf(file, " ra");
        if (ns_msg_getflag(handle, ns_f_z))
            fprintf(file, " ??");
        if (ns_msg_getflag(handle, ns_f_ad))
            fprintf(file, " ad");
        if (ns_msg_getflag(handle, ns_f_cd))
            fprintf(file, " cd");
    }
    if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
        fprintf(file, "; %s: %d",
            p_section(ns_s_qd, (int)opcode), qdcount);
        fprintf(file, ", %s: %d",
            p_section(ns_s_an, (int)opcode), ancount);
        fprintf(file, ", %s: %d",
            p_section(ns_s_ns, (int)opcode), nscount);
        fprintf(file, ", %s: %d",
            p_section(ns_s_ar, (int)opcode), arcount);
    }
    if ((!_res.pfcode) || (_res.pfcode &
        (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
        putc('\n',file);
    }
    /*
     * Print the various sections.
     */
    do_section(&handle, ns_s_qd, RES_PRF_QUES, file);
    do_section(&handle, ns_s_an, RES_PRF_ANS, file);
    do_section(&handle, ns_s_ns, RES_PRF_AUTH, file);
    do_section(&handle, ns_s_ar, RES_PRF_ADD, file);
    if (qdcount == 0 && ancount == 0 &&
        nscount == 0 && arcount == 0)
        putc('\n', file);
}
コード例 #16
0
ファイル: nb_dns.c プロジェクト: bro/bro
/* Returns 1 with an answer, 0 when reply was old, -1 on fatal errors */
int
nb_dns_activity(struct nb_dns_info *nd, struct nb_dns_result *nr, char *errstr)
{
	register int msglen, qtype, atype, n, i;
	register struct nb_dns_entry *ne, *lastne;
	socklen_t fromlen;
	struct sockaddr_storage from;
	u_long msg[MAXPACKET / sizeof(u_long)];
	register char *bp, *ep;
	register char **ap, **hap;
	register u_int16_t id;
	register const u_char *rdata;
	register u_int32_t rttl = 0;	// make compiler happy.
	register struct hostent *he;
	register size_t rdlen;
	ns_msg handle;
	ns_rr rr;

	/* This comes from the second half of do_query() */
	fromlen = sizeof(from);
	msglen = recvfrom(nd->s, (char *)msg, sizeof(msg), 0,
	                  (struct sockaddr*)&from, &fromlen);
	if (msglen <= 0) {
		snprintf(errstr, NB_DNS_ERRSIZE, "recvfrom(): %s",
		    my_strerror(errno));
		return (-1);
	}
	if (msglen < HFIXEDSZ) {
		snprintf(errstr, NB_DNS_ERRSIZE, "recvfrom(): undersized: %d",
		    msglen);
		return (-1);
	}
	if (ns_initparse((u_char *)msg, msglen, &handle) < 0) {
		snprintf(errstr, NB_DNS_ERRSIZE, "ns_initparse(): %s",
		    my_strerror(errno));
		nr->host_errno = NO_RECOVERY;
		return (-1);
	}

	/* RES_INSECURE1 style check */
	if (_nb_dns_cmpsockaddr((struct sockaddr*)&nd->server,
	                        (struct sockaddr*)&from, errstr) < 0) {
		nr->host_errno = NO_RECOVERY;
		return (-1);
	}

	/* Search for this request */
	lastne = NULL;
	id = ns_msg_id(handle);
	for (ne = nd->list; ne != NULL; ne = ne->next) {
		if (ne->id == id)
			break;
		lastne = ne;
	}

	/* Not an answer to a question we care about anymore */
	if (ne == NULL)
		return (0);

	/* Unlink this entry */
	if (lastne == NULL)
		nd->list = ne->next;
	else
		lastne->next = ne->next;
	ne->next = NULL;

	/* RES_INSECURE2 style check */
	/* XXX not implemented */

	/* Initialize result struct */
	memset(nr, 0, sizeof(*nr));
	nr->cookie = ne->cookie;
	qtype = ne->qtype;

	/* Deal with various errors */
	switch (ns_msg_getflag(handle, ns_f_rcode)) {

	case ns_r_nxdomain:
		nr->host_errno = HOST_NOT_FOUND;
		free(ne);
		return (1);

	case ns_r_servfail:
		nr->host_errno = TRY_AGAIN;
		free(ne);
		return (1);

	case ns_r_noerror:
		break;

	case ns_r_formerr:
	case ns_r_notimpl:
	case ns_r_refused:
	default:
		nr->host_errno = NO_RECOVERY;
		free(ne);
		return (1);
	}

	/* Loop through records in packet */
	memset(&rr, 0, sizeof(rr));
	memset(&nd->dns_hostent, 0, sizeof(nd->dns_hostent));
	he = &nd->dns_hostent.hostent;
	/* XXX no support for aliases */
	he->h_aliases = nd->dns_hostent.host_aliases;
	he->h_addr_list = nd->dns_hostent.h_addr_ptrs;
	he->h_addrtype = ne->atype;
	he->h_length = ne->asize;
	free(ne);

	bp = nd->dns_hostent.hostbuf;
	ep = bp + sizeof(nd->dns_hostent.hostbuf);
	hap = he->h_addr_list;
	ap = he->h_aliases;

	for (i = 0; i < ns_msg_count(handle, ns_s_an); i++) {
		/* Parse next record */
		if (ns_parserr(&handle, ns_s_an, i, &rr) < 0) {
			if (errno != ENODEV) {
				nr->host_errno = NO_RECOVERY;
				return (1);
			}
			/* All done */
			break;
		}

		/* Ignore records that don't answer our query (e.g. CNAMEs) */
		atype = ns_rr_type(rr);
		if (atype != qtype)
			continue;

		rdata = ns_rr_rdata(rr);
		rdlen = ns_rr_rdlen(rr);
		rttl = ns_rr_ttl(rr);
		switch (atype) {

		case T_A:
		case T_AAAA:
			if (rdlen != (unsigned int) he->h_length) {
				snprintf(errstr, NB_DNS_ERRSIZE,
				    "nb_dns_activity(): bad rdlen %d",
				    (int) rdlen);
				nr->host_errno = NO_RECOVERY;
				return (-1);
			}

			if (bp + rdlen >= ep) {
				snprintf(errstr, NB_DNS_ERRSIZE,
				    "nb_dns_activity(): overflow 1");
				nr->host_errno = NO_RECOVERY;
				return (-1);
			}
			if (nd->dns_hostent.numaddrs + 1 >= MAXADDRS) {
				snprintf(errstr, NB_DNS_ERRSIZE,
				    "nb_dns_activity(): overflow 2");
				nr->host_errno = NO_RECOVERY;
				return (-1);
			}

			memcpy(bp, rdata, rdlen);
			*hap++ = bp;
			bp += rdlen;
			++nd->dns_hostent.numaddrs;

			/* Keep looking for more A records */
			break;

		case T_TXT:
			if (bp + rdlen >= ep) {
				snprintf(errstr, NB_DNS_ERRSIZE,
				    "nb_dns_activity(): overflow 1 for txt");
				nr->host_errno = NO_RECOVERY;
				return (-1);
			}

			memcpy(bp, rdata, rdlen);
			he->h_name = bp+1; /* First char is a control character. */
			nr->hostent = he;
			nr->ttl = rttl;
			return (1);

		case T_PTR:
			n = dn_expand((const u_char *)msg,
			    (const u_char *)msg + msglen, rdata, bp, ep - bp);
			if (n < 0) {
				/* XXX return -1 here ??? */
				nr->host_errno = NO_RECOVERY;
				return (1);
			}
			he->h_name = bp;
			/* XXX check for overflow */
			bp += n;		/* returned len includes EOS */

			/* "Find first satisfactory answer" */
			nr->hostent = he;
			nr->ttl = rttl;
			return (1);
		}
	}

	nr->hostent = he;
	nr->ttl = rttl;
	return (1);
}
コード例 #17
0
ファイル: res_debug.c プロジェクト: bminor/glibc
/*
 * Print the contents of a query.
 * This is intended to be primarily a debugging routine.
 */
void
fp_nquery (const unsigned char *msg, int len, FILE *file)
{
	ns_msg handle;
	int qdcount, ancount, nscount, arcount;
	u_int opcode, rcode, id;

	/* There is no need to initialize _res: If _res is not yet
	   initialized, _res.pfcode is zero.  But initialization will
	   leave it at zero, too.  _res.pfcode is an unsigned long,
	   but the code here assumes that the flags fit into an int,
	   so use that.  */
	int pfcode = _res.pfcode;

	if (ns_initparse(msg, len, &handle) < 0) {
		fprintf(file, ";; ns_initparse: %s\n", strerror(errno));
		return;
	}
	opcode = ns_msg_getflag(handle, ns_f_opcode);
	rcode = ns_msg_getflag(handle, ns_f_rcode);
	id = ns_msg_id(handle);
	qdcount = ns_msg_count(handle, ns_s_qd);
	ancount = ns_msg_count(handle, ns_s_an);
	nscount = ns_msg_count(handle, ns_s_ns);
	arcount = ns_msg_count(handle, ns_s_ar);

	/*
	 * Print header fields.
	 */
	if ((!pfcode) || (pfcode & RES_PRF_HEADX) || rcode)
		fprintf(file,
			";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",
			res_opcodes[opcode], p_rcode(rcode), id);
	if ((!pfcode) || (pfcode & RES_PRF_HEADX))
		putc(';', file);
	if ((!pfcode) || (pfcode & RES_PRF_HEAD2)) {
		fprintf(file, "; flags:");
		if (ns_msg_getflag(handle, ns_f_qr))
			fprintf(file, " qr");
		if (ns_msg_getflag(handle, ns_f_aa))
			fprintf(file, " aa");
		if (ns_msg_getflag(handle, ns_f_tc))
			fprintf(file, " tc");
		if (ns_msg_getflag(handle, ns_f_rd))
			fprintf(file, " rd");
		if (ns_msg_getflag(handle, ns_f_ra))
			fprintf(file, " ra");
		if (ns_msg_getflag(handle, ns_f_z))
			fprintf(file, " ??");
		if (ns_msg_getflag(handle, ns_f_ad))
			fprintf(file, " ad");
		if (ns_msg_getflag(handle, ns_f_cd))
			fprintf(file, " cd");
	}
	if ((!pfcode) || (pfcode & RES_PRF_HEAD1)) {
		fprintf(file, "; %s: %d",
			p_section(ns_s_qd, opcode), qdcount);
		fprintf(file, ", %s: %d",
			p_section(ns_s_an, opcode), ancount);
		fprintf(file, ", %s: %d",
			p_section(ns_s_ns, opcode), nscount);
		fprintf(file, ", %s: %d",
			p_section(ns_s_ar, opcode), arcount);
	}
	if ((!pfcode) || (pfcode &
		(RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
		putc('\n',file);
	}
	/*
	 * Print the various sections.
	 */
	do_section (pfcode, &handle, ns_s_qd, RES_PRF_QUES, file);
	do_section (pfcode, &handle, ns_s_an, RES_PRF_ANS, file);
	do_section (pfcode, &handle, ns_s_ns, RES_PRF_AUTH, file);
	do_section (pfcode, &handle, ns_s_ar, RES_PRF_ADD, file);
	if (qdcount == 0 && ancount == 0 &&
	    nscount == 0 && arcount == 0)
		putc('\n', file);
}
コード例 #18
0
ファイル: res_debug.c プロジェクト: bminor/glibc
static void
do_section (int pfcode, ns_msg *handle, ns_sect section, int pflag, FILE *file)
{
	int n, sflag, rrnum;
	static int buflen = 2048;
	char *buf;
	ns_opcode opcode;
	ns_rr rr;

	/*
	 * Print answer records.
	 */
	sflag = (pfcode & pflag);
	if (pfcode && !sflag)
		return;

	buf = malloc(buflen);
	if (buf == NULL) {
		fprintf(file, ";; memory allocation failure\n");
		return;
	}

	opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode);
	rrnum = 0;
	for (;;) {
		if (ns_parserr(handle, section, rrnum, &rr)) {
			if (errno != ENODEV)
				fprintf(file, ";; ns_parserr: %s\n",
					strerror(errno));
			else if (rrnum > 0 && sflag != 0 &&
				 (pfcode & RES_PRF_HEAD1))
				putc('\n', file);
			goto cleanup;
		}
		if (rrnum == 0 && sflag != 0 && (pfcode & RES_PRF_HEAD1))
			fprintf(file, ";; %s SECTION:\n",
				p_section(section, opcode));
		if (section == ns_s_qd)
			fprintf(file, ";;\t%s, type = %s, class = %s\n",
				ns_rr_name(rr),
				p_type(ns_rr_type(rr)),
				p_class(ns_rr_class(rr)));
		else {
			n = ns_sprintrr(handle, &rr, NULL, NULL,
					buf, buflen);
			if (n < 0) {
				if (errno == ENOSPC) {
					free(buf);
					buf = NULL;
					if (buflen < 131072)
						buf = malloc(buflen += 1024);
					if (buf == NULL) {
						fprintf(file,
					      ";; memory allocation failure\n");
					      return;
					}
					continue;
				}
				fprintf(file, ";; ns_sprintrr: %s\n",
					strerror(errno));
				goto cleanup;
			}
			fputs(buf, file);
			fputc('\n', file);
		}
		rrnum++;
	}
 cleanup:
	free(buf);
}
コード例 #19
0
ファイル: dowse.c プロジェクト: 73616e646572/dowse
void dowse_output(const char *descr, iaddr from, iaddr to, uint8_t proto, int isfrag,
              unsigned sport, unsigned dport, my_bpftimeval ts,
              const u_char *pkt_copy, unsigned olen,
              const u_char *dnspkt, unsigned dnslen) {
    /* dnspkt may be NULL if IP packet does not contain a valid DNS message */

    char output[MAX_OUTPUT];

    if (dnspkt) {

        ns_msg msg;
        int qdcount;
        ns_rr rr;

        int *val;
        char *sval;

        char *extracted;
        char *resolved;
        char *from;
        int res;
        char action = 'A';

        char from_color[16];

        ns_initparse(dnspkt, dnslen, &msg);
        if (!ns_msg_getflag(msg, ns_f_qr)) return;

        /*
         * -- flags --
         * 0    1                5    6    7    8           11               15
         * +----+----------------+----+----+----+-----------+----------------+
         * | QR | Operation Code | AA | TC | RA |   Zero    |    Recode      |
         * +----+----------------+----+----+----+-----------+----------------+
         *
         * Question/Response          : ns_f_qr
         * Operation code             : ns_f_opcode
         * Authoritative Answer       : ns_f_aa
         * Truncation occurred        : ns_f_tc
         * Recursion Desired          : ns_f_rd
         * Recursion Available        : ns_f_ra
         * MBZ                        : ns_f_z
         * Authentic Data (DNSSEC)    : ns_f_ad
         * Checking Disabled (DNSSEC) : ns_f_cd
         * Response code              : ns_f_rcode
         */
        // logerr("msg: %p",msg);
        qdcount = ns_msg_count(msg, ns_s_qd);
        if (qdcount > 0 && 0 == ns_parserr(&msg, ns_s_qd, 0, &rr)) {

            // where the query comes from
            from = ia_resolv(to);

            // if its from ourselves omit it
            if(strncmp(from,hostname,MAX_DOMAIN)==0) return;
            if(own_ipv4) if(strncmp(from,own_ipv4,MAX_DOMAIN)==0) return;
            // not reverse resolved means not known by Dowse, code RED
            if(is_ip(from)) strcpy(from_color,"#FF0000");


            resolved = ns_rr_name(rr);
            // what domain is being looked up
            extracted = extract_domain(resolved);

            res = hashmap_get(visited, extracted, (void**)(&val));
            switch(res) {

            case MAP_MISSING : // never visited
                val = malloc(sizeof(int));
                *val = 1; // just a placeholder for now
                res = hashmap_put(visited, strdup(extracted), val);
                break;

            case MAP_OK: // already visited
                action = 'M';
                break;

                // TODO error checks
            case MAP_FULL:
            case MAP_OMEM:
                break;
            }


            // compose the path of the detected query
            // add category if listed
            if(listpath) { // add known domain list information
                res = hashmap_get(domainlist, extracted, (void**)(&sval));
                switch(res) {

                case MAP_OK:
                    /* render with the category in front of domain */
                    snprintf(output,MAX_OUTPUT,"%lu|%s|%c|%s/%s/%s",
                             ts.tv_sec, from, action, tld, sval, extracted);
                    break;
                default:
                    /* render only the domain in root category */
                    snprintf(output,MAX_OUTPUT,"%lu|%s|%c|%s/%s",
                             ts.tv_sec, from, action, tld, extracted);
                    break;
                }
            } else
                /* render only the domain in root category */
                snprintf(output,MAX_OUTPUT,"%lu|%s|%c|%s/%s",
                         ts.tv_sec, from, action, tld, extracted);



            /* write to file */
            if(fileout) {
                fputs(output, fileout);
                fputc('\n',fileout);
                if(fileout) fflush(fileout);
            }

            /* print fast on console for realtime */
            if(console) {
                puts(output);
                fflush(stdout);
            }

        }


    }

}
コード例 #20
0
static void test_res_fake_soa_query(void **state)
{
    int rv;
    struct __res_state dnsstate;
    unsigned char answer[ANSIZE];
    ns_msg handle;
    ns_rr rr;   /* expanded resource record */
    const uint8_t *rrdata;
    char nameser[MAXDNAME];
    char admin[MAXDNAME];
    int serial;
    int refresh;
    int retry;
    int expire;
    int minimum;

    (void) state; /* unused */

    memset(&dnsstate, 0, sizeof(struct __res_state));
    rv = res_ninit(&dnsstate);
    assert_int_equal(rv, 0);

    rv = res_nquery(&dnsstate, "cwrap.org", ns_c_in, ns_t_soa,
                    answer, sizeof(answer));
    assert_in_range(rv, 1, 100);

    ns_initparse(answer, sizeof(answer), &handle);

    /*
     * The query must finish w/o an error, have one answer and the answer
     * must be a parseable RR of type SOA and have the data as in the fake
     * hosts file
     */
    assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
    assert_int_equal(ns_msg_count(handle, ns_s_an), 1);
    assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
    assert_int_equal(ns_rr_type(rr), ns_t_soa);

    rrdata = ns_rr_rdata(rr);

    rv = ns_name_uncompress(ns_msg_base(handle),
                            ns_msg_end(handle),
                            rrdata,
                            nameser, MAXDNAME);
    assert_int_not_equal(rv, -1);
    rrdata += rv;

    rv = ns_name_uncompress(ns_msg_base(handle),
                            ns_msg_end(handle),
                            rrdata,
                            admin, MAXDNAME);
    assert_int_not_equal(rv, -1);
    rrdata += rv;

    NS_GET32(serial, rrdata);
    NS_GET32(refresh, rrdata);
    NS_GET32(retry, rrdata);
    NS_GET32(expire, rrdata);
    NS_GET32(minimum, rrdata);

    assert_string_equal(nameser, "ns1.cwrap.org");
    assert_string_equal(admin, "admin.cwrap.org");
    assert_int_equal(serial, 2014100457);
    assert_int_equal(refresh, 3600);
    assert_int_equal(retry, 300);
    assert_int_equal(expire, 1814400);
    assert_int_equal(minimum, 600);
}
コード例 #21
0
/*
 * Test the case of a SRV record query where the
 * fake hosts file entry is minimal in the sense
 * that it omits the priority and weight entries.
 * The server then fills in some default values.
 */
static void test_res_fake_srv_query_minimal(void **state)
{
    int rv;
    struct __res_state dnsstate;
    unsigned char answer[ANSIZE];
    ns_msg handle;
    ns_rr rr;   /* expanded resource record */
    const uint8_t *rrdata;
    int prio;
    int weight;
    int port;
    char hostname[MAXDNAME];
    char addr[INET_ADDRSTRLEN];

    (void) state; /* unused */

    memset(&dnsstate, 0, sizeof(struct __res_state));
    rv = res_ninit(&dnsstate);
    assert_int_equal(rv, 0);

    rv = res_nquery(&dnsstate, "_krb5._tcp.cwrap.org", ns_c_in, ns_t_srv,
                    answer, sizeof(answer));
    assert_in_range(rv, 1, 256);

    ns_initparse(answer, sizeof(answer), &handle);

    /*
     * The query must finish w/o an error, have one answer and the answer
     * must be a parseable RR of type SRV and have the priority, weight,
     * port and hostname as in the fake hosts file
     */
    assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
    assert_int_equal(ns_msg_count(handle, ns_s_an), 1);
    assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
    assert_int_equal(ns_rr_type(rr), ns_t_srv);

    rrdata = ns_rr_rdata(rr);
    NS_GET16(prio, rrdata);
    NS_GET16(weight, rrdata);
    NS_GET16(port, rrdata);

    rv = ns_name_uncompress(ns_msg_base(handle),
                            ns_msg_end(handle),
                            rrdata,
                            hostname, MAXDNAME);
    assert_int_not_equal(rv, -1);

    assert_int_equal(prio, 1);
    assert_int_equal(weight, 100);
    assert_int_equal(port, 88);
    assert_string_equal(hostname, "krb5.cwrap.org");

    /* The additional section contains the A record of krb5.cwrap.org */
    assert_int_equal(ns_msg_count(handle, ns_s_ar), 1);
    assert_int_equal(ns_parserr(&handle, ns_s_ar, 0, &rr), 0);
    assert_int_equal(ns_rr_type(rr), ns_t_a);
    assert_string_equal(ns_rr_name(rr), "krb5.cwrap.org");
    assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr),
                              addr, sizeof(addr)));
    assert_string_equal(addr, "127.0.0.23");
}
コード例 #22
0
ファイル: txtout.c プロジェクト: DNS-OARC/dnscap
void txtout_output(const char* descr, iaddr from, iaddr to, uint8_t proto, unsigned flags,
    unsigned sport, unsigned dport, my_bpftimeval ts,
    const u_char* pkt_copy, unsigned olen,
    const u_char* payload, unsigned payloadlen)
{
    /*
     * Short output, only print QTYPE and QNAME for IN records
     */
    if (opt_s) {
        if (flags & DNSCAP_OUTPUT_ISDNS) {
            ns_msg msg;
            int    qdcount, err = 0;
            ns_rr  rr;
            if (ns_initparse(payload, payloadlen, &msg) < 0) {
                if (tcpstate_getcurr && tcpstate_reset)
                    tcpstate_reset(tcpstate_getcurr(), "");
                return;
            }
            qdcount = ns_msg_count(msg, ns_s_qd);

            if (qdcount > 0 && 0 == (err = ns_parserr(&msg, ns_s_qd, 0, &rr)) && ns_rr_class(rr) == 1) {
                fprintf(out, "%s %s\n",
                    p_type(ns_rr_type(rr)),
                    ns_rr_name(rr));
            }
            if (err < 0) {
                if (tcpstate_getcurr && tcpstate_reset)
                    tcpstate_reset(tcpstate_getcurr(), "");
            }
        }
        return;
    }

    /*
     * IP Stuff
     */
    fprintf(out, "%10ld.%06ld", (long)ts.tv_sec, (long)ts.tv_usec);
    fprintf(out, " %s %u", ia_str(from), sport);
    fprintf(out, " %s %u", ia_str(to), dport);
    fprintf(out, " %hhu", proto);

    if (flags & DNSCAP_OUTPUT_ISDNS) {
        ns_msg msg;
        int    qdcount, err = 0;
        ns_rr  rr;
        if (ns_initparse(payload, payloadlen, &msg) < 0) {
            if (tcpstate_getcurr && tcpstate_reset)
                tcpstate_reset(tcpstate_getcurr(), "");
            fprintf(out, "\n");
            return;
        }

        /*
         * DNS Header
         */
        fprintf(out, " %u", ns_msg_id(msg));
        fprintf(out, " %u", ns_msg_getflag(msg, ns_f_opcode));
        fprintf(out, " %u", ns_msg_getflag(msg, ns_f_rcode));
        fprintf(out, " |");
        if (ns_msg_getflag(msg, ns_f_qr))
            fprintf(out, "QR|");
        if (ns_msg_getflag(msg, ns_f_aa))
            fprintf(out, "AA|");
        if (ns_msg_getflag(msg, ns_f_tc))
            fprintf(out, "TC|");
        if (ns_msg_getflag(msg, ns_f_rd))
            fprintf(out, "RD|");
        if (ns_msg_getflag(msg, ns_f_ra))
            fprintf(out, "RA|");
        if (ns_msg_getflag(msg, ns_f_ad))
            fprintf(out, "AD|");
        if (ns_msg_getflag(msg, ns_f_cd))
            fprintf(out, "CD|");

        qdcount = ns_msg_count(msg, ns_s_qd);
        if (qdcount > 0 && 0 == (err = ns_parserr(&msg, ns_s_qd, 0, &rr))) {
            fprintf(out, " %s %s %s",
                p_class(ns_rr_class(rr)),
                p_type(ns_rr_type(rr)),
                ns_rr_name(rr));
        }
        if (err < 0) {
            if (tcpstate_getcurr && tcpstate_reset)
                tcpstate_reset(tcpstate_getcurr(), "");
        }
    }
    /*
     * Done
     */
    fprintf(out, "\n");
}
コード例 #23
0
static void test_res_fake_a_via_cname(void **state)
{
    int rv;
    struct __res_state dnsstate;
    unsigned char answer[ANSIZE];
    ns_msg handle;
    ns_rr rr;   /* expanded resource record */
    const uint8_t *rrdata;
    char cname[MAXDNAME];
    char addr[INET_ADDRSTRLEN];

    (void) state; /* unused */

    memset(&dnsstate, 0, sizeof(struct __res_state));
    rv = res_ninit(&dnsstate);
    assert_int_equal(rv, 0);

    /* Query for A record, but the key is a CNAME. The expected result is
     * that the whole chain of CNAMEs will be included in the answer section
     * along with the resulting A
     */
    rv = res_nquery(&dnsstate, "rwrap.org", ns_c_in, ns_t_a,
                    answer, sizeof(answer));
    assert_in_range(rv, 1, 256);

    ns_initparse(answer, sizeof(answer), &handle);

    /*
     * The query must finish w/o an error, have three answers and the answers
     * must be a parseable RR of type CNAME and have the cname as in the
     * fake hosts file
     */
    assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
    assert_int_equal(ns_msg_count(handle, ns_s_an), 3);

    assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
    assert_int_equal(ns_rr_type(rr), ns_t_cname);

    rrdata = ns_rr_rdata(rr);

    rv = ns_name_uncompress(ns_msg_base(handle),
                            ns_msg_end(handle),
                            rrdata,
                            cname, MAXDNAME);
    assert_int_not_equal(rv, -1);

    assert_string_equal(cname, "web.cwrap.org");

    assert_int_equal(ns_parserr(&handle, ns_s_an, 1, &rr), 0);
    assert_int_equal(ns_rr_type(rr), ns_t_cname);

    rrdata = ns_rr_rdata(rr);

    rv = ns_name_uncompress(ns_msg_base(handle),
                            ns_msg_end(handle),
                            rrdata,
                            cname, MAXDNAME);
    assert_int_not_equal(rv, -1);

    assert_string_equal(cname, "www.cwrap.org");

    assert_int_equal(ns_parserr(&handle, ns_s_an, 2, &rr), 0);
    assert_int_equal(ns_rr_type(rr), ns_t_a);
    assert_string_equal(ns_rr_name(rr), "www.cwrap.org");
    assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr),
                              addr, sizeof(addr)));
    assert_string_equal(addr, "127.0.0.22");
}
コード例 #24
0
ファイル: royparse.c プロジェクト: DNS-OARC/dnscap
void royparse_output(const char* descr, iaddr from, iaddr to, uint8_t proto, unsigned flags,
    unsigned sport, unsigned dport, my_bpftimeval ts,
    const u_char* pkt_copy, unsigned olen,
    const u_char* payload, unsigned payloadlen)
{
    if (flags & DNSCAP_OUTPUT_ISDNS) {
        int    rrmax;
        ns_msg msg;
        ns_rr  rr;
        if (ns_initparse(payload, payloadlen, &msg) < 0) {
            fprintf(r_out, "ERR\n");
            return;
        }
        if (ns_msg_getflag(msg, ns_f_qr) != 0 && sport == 53) {
            fprintf(r_out, "%cD_", ns_msg_getflag(msg, ns_f_rd) ? 'R' : 'N');

            switch (ns_msg_getflag(msg, ns_f_opcode)) {
            case ns_o_query:
                fprintf(r_out, "QUERY");
                break;
            case ns_o_notify:
                fprintf(r_out, "NOTIFY");
                break;
            case ns_o_update:
                fprintf(r_out, "UPDATE");
                break;
            default:
                fprintf(r_out, "ELSE");
            }

            fprintf(r_out, "_%u_%cA_", ns_msg_count(msg, ns_s_an) ? 1 : 0, ns_msg_getflag(msg, ns_f_aa) ? 'A' : 'N');

            switch (ns_msg_getflag(msg, ns_f_rcode)) {
            case ns_r_noerror:
                fprintf(r_out, "NOERROR");
                break;
            case ns_r_formerr:
                fprintf(r_out, "FORMERR");
                break;
            case ns_r_nxdomain:
                fprintf(r_out, "NXDOMAIN");
                break;
            case ns_r_notimpl:
                fprintf(r_out, "NOTIMP");
                break;
            case ns_r_refused:
                fprintf(r_out, "REFUSED");
                break;
            case ns_r_notauth:
                fprintf(r_out, "NOTAUTH");
                break;
            default:
                fprintf(r_out, "ELSE");
            }

            fprintf(r_out, " %s,", royparse_ia_str(to));

            if (ns_msg_count(msg, ns_s_qd) > 0) {
                if (ns_parserr(&msg, ns_s_qd, 0, &rr) == 0) {
                    royparse_normalize(ns_rr_name(rr));
                    fprintf(r_out, "%s%s,%u", ns_rr_name(rr), (ns_rr_name(rr)[0] == '.') ? "" : ".", ns_rr_type(rr));
                } else
                    fprintf(r_out, "ERR,ERR");
            } else
                fprintf(r_out, ",");

            fprintf(r_out, ",%ld,%s%s%s%s", ns_msg_size(msg), ns_msg_id(msg) < 256 ? "-L" : "",
                ns_msg_getflag(msg, ns_f_tc) ? "-TC" : "",
                ns_msg_getflag(msg, ns_f_ad) ? "-AD" : "",
                ns_msg_getflag(msg, ns_f_cd) ? "-CD" : "");
            rrmax = ns_msg_count(msg, ns_s_ar);

            while (rrmax > 0) {
                rrmax--;
                if (ns_parserr(&msg, ns_s_ar, rrmax, &rr) == 0) {
                    if (ns_rr_type(rr) == ns_t_opt) {
                        fprintf(r_out, "-%c", (u_long)ns_rr_ttl(rr) & NS_OPT_DNSSEC_OK ? 'D' : 'E');
                        break;
                    }
                }
            }
            fprintf(r_out, "\n");
        } else if (opt_q != 0 && ns_msg_getflag(msg, ns_f_qr) == 0 && dport == 53) {
            struct pcap_pkthdr h;
            if (flags & DNSCAP_OUTPUT_ISLAYER)
                return;
            memset(&h, 0, sizeof h);
            h.ts  = ts;
            h.len = h.caplen = olen;
            pcap_dump((u_char*)q_out, &h, pkt_copy);
        }
    }
}
コード例 #25
0
ファイル: dowse.c プロジェクト: cryptocurrent/dowse
void dowse_output(const char *descr, iaddr from, iaddr to, uint8_t proto, int isfrag,
              unsigned sport, unsigned dport, my_bpftimeval ts,
              const u_char *pkt_copy, unsigned olen,
              const u_char *dnspkt, unsigned dnslen) {
    /* dnspkt may be NULL if IP packet does not contain a valid DNS message */

    char output[MAX_OUTPUT];

    if (dnspkt) {

        ns_msg msg;
        int qdcount;
        ns_rr rr;

        int *val;
        char *sval;

        char *extracted;
        char *resolved;
        char *from;
        int res;
        char action = 'A';

        char from_color[16];

        ns_initparse(dnspkt, dnslen, &msg);
        if (!ns_msg_getflag(msg, ns_f_qr)) return;

        /*
         * -- flags --
         * 0    1                5    6    7    8           11               15
         * +----+----------------+----+----+----+-----------+----------------+
         * | QR | Operation Code | AA | TC | RA |   Zero    |    Recode      |
         * +----+----------------+----+----+----+-----------+----------------+
         *
         * Question/Response          : ns_f_qr
         * Operation code             : ns_f_opcode
         * Authoritative Answer       : ns_f_aa
         * Truncation occurred        : ns_f_tc
         * Recursion Desired          : ns_f_rd
         * Recursion Available        : ns_f_ra
         * MBZ                        : ns_f_z
         * Authentic Data (DNSSEC)    : ns_f_ad
         * Checking Disabled (DNSSEC) : ns_f_cd
         * Response code              : ns_f_rcode
         */
        // logerr("msg: %p",msg);
        qdcount = ns_msg_count(msg, ns_s_qd);
        if (qdcount > 0 && 0 == ns_parserr(&msg, ns_s_qd, 0, &rr)) {

            // where the query comes from
            from = ia_resolv(to);

            // if its from ourselves omit it
            if(strncmp(from,hostname,MAX_DOMAIN)==0) return;
            if(own_ipv4) if(strncmp(from,own_ipv4,MAX_DOMAIN)==0) return;
            // not reverse resolved means not known by Dowse, code RED
            if(is_ip(from)) strcpy(from_color,"#FF0000");


            resolved = ns_rr_name(rr);
            // what domain is being looked up
            extracted = extract_domain(resolved);

            res = hashmap_get(visited, extracted, (void**)(&val));
            switch(res) {

                // TODO: fix malloc and strdup here as they grow as a leak on long term
            case MAP_MISSING : // never visited

                /* ==13150== 992 bytes in 248 blocks are definitely lost in loss record 45 of 49 */
                /*     ==13150==    at 0x4C28C20: malloc (vg_replace_malloc.c:296) */
                /*     ==13150==    by 0x5C3D326: dowse_output (dowse.c:417) */
                /*     ==13150==    by 0x404CAB: output (dnscap.c:2201) */
                /*     ==13150==    by 0x406779: network_pkt (dnscap.c:2164) */
                /*     ==13150==    by 0x407065: dl_pkt (dnscap.c:1608) */
                /*     ==13150==    by 0x503F5E9: ??? (in /usr/lib/x86_64-linux-gnu/libpcap.so.1.6.2) */
                /*     ==13150==    by 0x5043783: ??? (in /usr/lib/x86_64-linux-gnu/libpcap.so.1.6.2) */
                /*     ==13150==    by 0x4037E0: poll_pcaps (dnscap.c:1344) */
                /*     ==13150==    by 0x4037E0: main (dnscap.c:406) */
                val = malloc(sizeof(int));
                *val = 1; // just a placeholder for now

                /* ==13150== 3,069 bytes in 248 blocks are definitely lost in loss record 47 of 49 */
                /*       ==13150==    at 0x4C28C20: malloc (vg_replace_malloc.c:296) */
                /*       ==13150==    by 0x5511A69: strdup (strdup.c:42) */
                /*       ==13150==    by 0x5C3D34D: dowse_output (dowse.c:419) */
                /*       ==13150==    by 0x404CAB: output (dnscap.c:2201) */
                /*       ==13150==    by 0x406779: network_pkt (dnscap.c:2164) */
                /*       ==13150==    by 0x407065: dl_pkt (dnscap.c:1608) */
                /*       ==13150==    by 0x503F5E9: ??? (in /usr/lib/x86_64-linux-gnu/libpcap.so.1.6.2) */
                /*       ==13150==    by 0x5043783: ??? (in /usr/lib/x86_64-linux-gnu/libpcap.so.1.6.2) */
                /*       ==13150==    by 0x4037E0: poll_pcaps (dnscap.c:1344) */
                /*       ==13150==    by 0x4037E0: main (dnscap.c:406) */
                res = hashmap_put(visited, strdup(extracted), val);
                break;

            case MAP_OK: // already visited
                action = 'M';
                break;

                // TODO error checks
            case MAP_FULL:
            case MAP_OMEM:
                break;
            }


            // compose the path of the detected query
            // add category if listed
            if(listpath) { // add known domain list information
                res = hashmap_get(domainlist, extracted, (void**)(&sval));
                switch(res) {

                case MAP_OK:
                    /* render with the category in front of domain */
                    snprintf(output,MAX_OUTPUT,"%lu|%s|%c|%s/%s/%s",
                             ts2epoch(&ts,NULL), // from our epoch.c
                             from, action, tld, sval, extracted);
                    break;
                default:
                    /* render only the domain in root category */
                    snprintf(output,MAX_OUTPUT,"%lu|%s|%c|%s/%s",
                             ts2epoch(&ts,NULL), // from our epoch.c
                             from, action, tld, extracted);
                    break;
                }
            } else
                /* render only the domain in root category */
                snprintf(output,MAX_OUTPUT,"%lu|%s|%c|%s/%s",
                         ts2epoch(&ts,NULL), // from our epoch.c
                         from, action, tld, extracted);



            /* write to file */
            if(fileout) {
                fputs(output, fileout);
                fputc('\n',fileout);
                if(fileout) fflush(fileout);
            }

            /* print fast on console for realtime */
            if(console) {
                puts(output);
                fflush(stdout);
            }

            if(redis) {
                rreply = redisCommand(redis, "PUBLISH dns-query-channel %s", output);
                logerr("PUBLISH dns-query-channel: %s\n", rreply->str);
                freeReplyObject(rreply);
            }

        }


    }

}