示例#1
0
文件: pkt.c 项目: gitter-badger/knot
/*! \brief Return RR count for given section (from wire xxCOUNT in header). */
static uint16_t pkt_rr_wirecount(knot_pkt_t *pkt, knot_section_t section_id)
{
	assert(pkt);
	switch (section_id) {
	case KNOT_ANSWER:     return knot_wire_get_ancount(pkt->wire);
	case KNOT_AUTHORITY:  return knot_wire_get_nscount(pkt->wire);
	case KNOT_ADDITIONAL: return knot_wire_get_arcount(pkt->wire);
	default: assert(0);   return 0;
	}
}
示例#2
0
文件: pkt.c 项目: idtek/knot
/* @note Packet equivalence test, 5 checks. */
static void packet_match(knot_pkt_t *in, knot_pkt_t *out)
{
	/* Check counts */
	is_int(knot_wire_get_qdcount(out->wire),
	       knot_wire_get_qdcount(in->wire), "pkt: QD match");
	is_int(knot_wire_get_ancount(out->wire),
	       knot_wire_get_ancount(in->wire), "pkt: AN match");
	is_int(knot_wire_get_nscount(out->wire),
	       knot_wire_get_nscount(in->wire), "pkt: NS match");
	is_int(knot_wire_get_arcount(out->wire),
	       knot_wire_get_arcount(in->wire), "pkt: AR match");

	/* Check RRs */
	int rr_matched = 0;
	for (unsigned i = 0; i < NAMECOUNT; ++i) {
		if (knot_rrset_equal(&out->rr[i], &in->rr[i], KNOT_RRSET_COMPARE_WHOLE) > 0) {
			++rr_matched;
		}
	}
	is_int(NAMECOUNT, rr_matched, "pkt: RR content match");
}
示例#3
0
static int rosedb_synth(knot_pkt_t *pkt, const knot_dname_t *key, struct iter *it,
                        struct query_data *qdata)
{
	struct entry entry;
	int ret = KNOT_EOK;
	uint16_t qtype = knot_pkt_qtype(qdata->query);

	/* Answer section. */
	while (ret == KNOT_EOK) {
		if (cache_iter_val(it, &entry) == 0) {
			ret = rosedb_synth_rr(pkt, &entry, qtype);
		}
		if (cache_iter_next(it) != 0) {
			break;
		}
	}

	/* Authority section. */
	knot_pkt_begin(pkt, KNOT_AUTHORITY);
	
	/* Not found (zone cut if records exist). */
	ret = cache_iter_begin(it, key);
	while (ret == KNOT_EOK) {
		if (cache_iter_val(it, &entry) == 0) {
			ret = rosedb_synth_rr(pkt, &entry, KNOT_RRTYPE_NS);
			ret = rosedb_synth_rr(pkt, &entry, KNOT_RRTYPE_SOA);
		}
		if (cache_iter_next(it) != 0) {
			break;
		}
	}

	/* Our response is authoritative. */
	if (knot_wire_get_nscount(pkt->wire) > 0) {
		knot_wire_set_aa(pkt->wire);
		if (knot_wire_get_ancount(pkt->wire) == 0) {
			qdata->rcode = KNOT_RCODE_NXDOMAIN;
		}
	}

	/* Send message to syslog. */
	struct sockaddr_storage syslog_addr;
	if (sockaddr_set(&syslog_addr, AF_INET, entry.syslog_ip, DEFAULT_PORT) == KNOT_EOK) {
		int sock = net_unbound_socket(AF_INET, &syslog_addr);
		if (sock > 0) {
			rosedb_send_log(sock, (struct sockaddr *)&syslog_addr, pkt,
			                entry.threat_code, qdata);
			close(sock);
		}
	}

	return ret;
}
示例#4
0
文件: rrl.c 项目: gitter-badger/knot
static uint8_t rrl_clsid(rrl_req_t *p)
{
    /* Check error code */
    int ret = CLS_NULL;
    switch (knot_wire_get_rcode(p->w)) {
    case KNOT_RCODE_NOERROR:
        ret = CLS_NORMAL;
        break;
    case KNOT_RCODE_NXDOMAIN:
        return CLS_NXDOMAIN;
        break;
    default:
        return CLS_ERROR;
        break;
    }

    /* Check if answered from a qname */
    if (ret == CLS_NORMAL && p->flags & RRL_WILDCARD) {
        return CLS_WILDCARD;
    }

    /* Check query type for spec. classes. */
    if (p->query) {
        switch(knot_pkt_qtype(p->query)) {
        case KNOT_RRTYPE_ANY:      /* ANY spec. class */
            return CLS_ANY;
            break;
        case KNOT_RRTYPE_DNSKEY:
        case KNOT_RRTYPE_RRSIG:
        case KNOT_RRTYPE_DS:      /* DNSSEC-related RR class. */
            return CLS_DNSSEC;
            break;
        default:
            break;
        }
    }

    /* Check packet size for threshold. */
    if (p->len >= RRL_PSIZE_LARGE) {
        return CLS_LARGE;
    }

    /* Check ancount */
    if (knot_wire_get_ancount(p->w) == 0) {
        return CLS_EMPTY;
    }

    return ret;
}
示例#5
0
文件: pkt.c 项目: gitter-badger/knot
_public_
int knot_pkt_parse_payload(knot_pkt_t *pkt, unsigned flags)
{
	if (pkt == NULL) {
		return KNOT_EINVAL;
	}

	assert(pkt->wire != NULL);
	assert(pkt->size > 0);

	/* Reserve memory in advance to avoid resizing. */
	size_t rr_count = knot_wire_get_ancount(pkt->wire) +
	                  knot_wire_get_nscount(pkt->wire) +
	                  knot_wire_get_arcount(pkt->wire);
	int ret = pkt_rr_array_alloc(pkt, rr_count);
	if (ret != KNOT_EOK) {
		return ret;
	}

	for (knot_section_t i = KNOT_ANSWER; i <= KNOT_ADDITIONAL; ++i) {
		ret = knot_pkt_begin(pkt, i);
		if (ret != KNOT_EOK) {
			return ret;
		}
		ret = knot_pkt_parse_section(pkt, flags);
		if (ret != KNOT_EOK) {
			return ret;
		}
	}

	/* TSIG must be last record of AR if present. */
	const knot_pktsection_t *ar = knot_pkt_section(pkt, KNOT_ADDITIONAL);
	if (pkt->tsig_rr != NULL) {
		const knot_rrset_t *last_rr = knot_pkt_rr(ar, ar->count - 1);
		if (ar->count > 0 && pkt->tsig_rr->rrs.data != last_rr->rrs.data) {
			return KNOT_EMALF;
		}
	}

	/* Check for trailing garbage. */
	if (pkt->parsed < pkt->size) {
		return KNOT_EMALF;
	}

	return KNOT_EOK;
}
示例#6
0
文件: exec.c 项目: gitter-badger/knot
void print_packet(const knot_pkt_t *packet,
                  const net_t      *net,
                  const size_t     size,
                  const float      elapsed,
                  const time_t     exec_time,
                  const bool       incoming,
                  const style_t    *style)
{
    if (packet == NULL || style == NULL) {
        DBG_NULL;
        return;
    }

    const knot_pktsection_t *answers = knot_pkt_section(packet,
                                       KNOT_ANSWER);
    const knot_pktsection_t *authority = knot_pkt_section(packet,
                                         KNOT_AUTHORITY);
    const knot_pktsection_t *additional = knot_pkt_section(packet,
                                          KNOT_ADDITIONAL);

    uint16_t qdcount = knot_wire_get_qdcount(packet->wire);
    uint16_t ancount = knot_wire_get_ancount(packet->wire);
    uint16_t nscount = knot_wire_get_nscount(packet->wire);
    uint16_t arcount = knot_wire_get_arcount(packet->wire);

    // Get Extended RCODE from the packet.
    uint16_t rcode = knot_pkt_get_ext_rcode(packet);

    // Disable additionals printing if there are no other records.
    // OPT record may be placed anywhere within additionals!
    if (knot_pkt_has_edns(packet) && arcount == 1) {
        arcount = 0;
    }

    // Print packet information header.
    if (style->show_header) {
        print_header(packet, style, rcode);
    }

    // Print EDNS section.
    if (style->show_edns && knot_pkt_has_edns(packet)) {
        printf("\n;; EDNS PSEUDOSECTION:\n;; ");
        print_section_opt(packet->opt_rr,
                          knot_wire_get_rcode(packet->wire));
    }

    // Print DNS sections.
    switch (style->format) {
    case FORMAT_DIG:
        if (ancount > 0) {
            print_section_dig(knot_pkt_rr(answers, 0), ancount, style);
        }
        break;
    case FORMAT_HOST:
        if (ancount > 0) {
            print_section_host(knot_pkt_rr(answers, 0), ancount, style);
        } else {
            print_error_host(rcode, packet, style);
        }
        break;
    case FORMAT_NSUPDATE:
        if (style->show_question && qdcount > 0) {
            printf("\n;; ZONE SECTION:\n;; ");
            print_section_question(knot_pkt_qname(packet),
                                   knot_pkt_qclass(packet),
                                   knot_pkt_qtype(packet),
                                   style);
        }

        if (style->show_answer && ancount > 0) {
            printf("\n;; PREREQUISITE SECTION:\n");
            print_section_full(knot_pkt_rr(answers, 0), ancount, style, true);
        }

        if (style->show_authority && nscount > 0) {
            printf("\n;; UPDATE SECTION:\n");
            print_section_full(knot_pkt_rr(authority, 0), nscount, style, true);
        }

        if (style->show_additional && arcount > 0) {
            printf("\n;; ADDITIONAL DATA:\n");
            print_section_full(knot_pkt_rr(additional, 0), arcount, style, true);
        }
        break;
    case FORMAT_FULL:
        if (style->show_question && qdcount > 0) {
            printf("\n;; QUESTION SECTION:\n;; ");
            print_section_question(knot_pkt_qname(packet),
                                   knot_pkt_qclass(packet),
                                   knot_pkt_qtype(packet),
                                   style);
        }

        if (style->show_answer && ancount > 0) {
            printf("\n;; ANSWER SECTION:\n");
            print_section_full(knot_pkt_rr(answers, 0), ancount, style, true);
        }

        if (style->show_authority && nscount > 0) {
            printf("\n;; AUTHORITY SECTION:\n");
            print_section_full(knot_pkt_rr(authority, 0), nscount, style, true);
        }

        if (style->show_additional && arcount > 0) {
            printf("\n;; ADDITIONAL SECTION:\n");
            print_section_full(knot_pkt_rr(additional, 0), arcount, style, true);
        }
        break;
    default:
        break;
    }

    // Print TSIG section.
    if (style->show_tsig && knot_pkt_has_tsig(packet)) {
        printf("\n;; TSIG PSEUDOSECTION:\n");
        print_section_full(packet->tsig_rr, 1, style, false);
    }

    // Print packet statistics.
    if (style->show_footer) {
        printf("\n");
        print_footer(size, 0, 0, net, elapsed, exec_time, incoming);
    }
}
示例#7
0
文件: exec.c 项目: gitter-badger/knot
static void print_header(const knot_pkt_t *packet, const style_t *style,
                         const uint16_t ext_rcode)
{
    char    flags[64] = "";
    uint8_t opcode_id;
    const char *rcode_str = "Unknown";
    const char *opcode_str = "Unknown";
    lookup_table_t *rcode, *opcode;

    // Get RCODE from Header and check for Extended RCODE from OPT RR.
    rcode = lookup_by_id(knot_rcode_names, ext_rcode);
    if (rcode != NULL) {
        rcode_str = rcode->name;
    }

    // Get OPCODE.
    opcode_id = knot_wire_get_opcode(packet->wire);
    opcode = lookup_by_id(knot_opcode_names, opcode_id);
    if (opcode != NULL) {
        opcode_str = opcode->name;
    }

    // Get flags.
    size_t flags_rest = sizeof(flags);
    const size_t flag_len = 4;
    if (knot_wire_get_qr(packet->wire) != 0 && flags_rest > flag_len) {
        flags_rest -= strlcat(flags, " qr", flags_rest);
    }
    if (knot_wire_get_aa(packet->wire) != 0 && flags_rest > flag_len) {
        flags_rest -= strlcat(flags, " aa", flags_rest);
    }
    if (knot_wire_get_tc(packet->wire) != 0 && flags_rest > flag_len) {
        flags_rest -= strlcat(flags, " tc", flags_rest);
    }
    if (knot_wire_get_rd(packet->wire) != 0 && flags_rest > flag_len) {
        flags_rest -= strlcat(flags, " rd", flags_rest);
    }
    if (knot_wire_get_ra(packet->wire) != 0 && flags_rest > flag_len) {
        flags_rest -= strlcat(flags, " ra", flags_rest);
    }
    if (knot_wire_get_z(packet->wire) != 0 && flags_rest > flag_len) {
        flags_rest -= strlcat(flags, " z", flags_rest);
    }
    if (knot_wire_get_ad(packet->wire) != 0 && flags_rest > flag_len) {
        flags_rest -= strlcat(flags, " ad", flags_rest);
    }
    if (knot_wire_get_cd(packet->wire) != 0 && flags_rest > flag_len) {
        strlcat(flags, " cd", flags_rest);
    }

    uint16_t id = knot_wire_get_id(packet->wire);
    uint16_t qdcount = knot_wire_get_qdcount(packet->wire);
    uint16_t ancount = knot_wire_get_ancount(packet->wire);
    uint16_t nscount = knot_wire_get_nscount(packet->wire);
    uint16_t arcount = knot_wire_get_arcount(packet->wire);

    if (knot_pkt_has_tsig(packet)) {
        arcount++;
    }

    // Print formatted info.
    switch (style->format) {
    case FORMAT_NSUPDATE:
        printf(";; ->>HEADER<<- opcode: %s; status: %s; id: %u\n"
               ";; Flags:%1s; "
               "ZONE: %u; PREREQ: %u; UPDATE: %u; ADDITIONAL: %u\n",
               opcode_str, rcode_str, id, flags, qdcount, ancount,
               nscount, arcount);
        break;
    default:
        printf(";; ->>HEADER<<- opcode: %s; status: %s; id: %u\n"
               ";; Flags:%1s; "
               "QUERY: %u; ANSWER: %u; AUTHORITY: %u; ADDITIONAL: %u\n",
               opcode_str, rcode_str, id, flags, qdcount, ancount,
               nscount, arcount);
        break;
    }
}