Пример #1
0
static int
rdata_services_to_string(buffer_type *output, rdata_atom_type rdata,
	rr_type* ATTR_UNUSED(rr))
{
	int result = 0;
	buffer_type packet;

	buffer_create_from(
		&packet, rdata_atom_data(rdata), rdata_atom_size(rdata));

	if (buffer_available(&packet, 1)) {
		uint8_t protocol_number = buffer_read_u8(&packet);
		ssize_t bitmap_size = buffer_remaining(&packet);
		uint8_t *bitmap = buffer_current(&packet);
		struct protoent *proto = getprotobynumber(protocol_number);

		if (proto) {
			int i;

			buffer_printf(output, "%s", proto->p_name);

			for (i = 0; i < bitmap_size * 8; ++i) {
				if (get_bit(bitmap, i)) {
					struct servent *service = getservbyport((int)htons(i), proto->p_name);
					if (service) {
						buffer_printf(output, " %s", service->s_name);
					} else {
						buffer_printf(output, " %d", i);
					}
				}
			}
			buffer_skip(&packet, bitmap_size);
			result = 1;
		}
	}
	return result;
}
Пример #2
0
/** find soa serial (if any) */
static int
udb_zone_get_serial(udb_base* udb, udb_ptr* zone, uint32_t* serial)
{
	udb_ptr domain, rrset, rr;
	buffer_type buffer;
	if(!udb_domain_find(udb, zone, ZONE(zone)->name, ZONE(zone)->namelen,
		&domain))
		return 0;
	if(!udb_rrset_find(udb, &domain, TYPE_SOA, &rrset)) {
		udb_ptr_unlink(&domain, udb);
		return 0;
	}
	/* got SOA rrset, use first RR */
	if(!RRSET(&rrset)->rrs.data) {
		udb_ptr_unlink(&domain, udb);
		udb_ptr_unlink(&rrset, udb);
		return 0;
	}
	udb_ptr_new(&rr, udb, &RRSET(&rrset)->rrs);
	udb_ptr_unlink(&domain, udb);
	udb_ptr_unlink(&rrset, udb);
	/* find serial */
	buffer_create_from(&buffer, RR(&rr)->wire, RR(&rr)->len);
	/* skip two dnames */
	if(!packet_skip_dname(&buffer) || !packet_skip_dname(&buffer)) {
		udb_ptr_unlink(&rr, udb);
		return 0;
	}
	if(!buffer_available(&buffer, 4*5)) { /* soa rdata u32s */
		udb_ptr_unlink(&rr, udb);
		return 0;
	}
	*serial = buffer_read_u32(&buffer);
	udb_ptr_unlink(&rr, udb);
	return 1;
}
Пример #3
0
static void
handle_dns_query(const uint8_t *raw_data,
                 uint16_t data_len,
                 socket_t *client_socket,
                 const addr_t *client_addr,
                 void *arg)
{
    //header is 12 octets, wire name is 1 octets,
    //class is 2 octets, type is 2 octets
    if (data_len < 12 + 4 + 1)
    {
        log_warning(QUERY_LOG, "get invalid query package\n");
        return;
    }

    if (dns_header_get_opt(raw_data) != QUERY_STAND)
    {
        log_warning(QUERY_LOG, "get non-query package\n");
        return;
    }

    zipper_t *zipper = (zipper_t *)arg;

    query_session_t *session = memorypool_alloc_node(zipper->query_session_pool_);
    if (session == NULL)
    {
        log_warning(QUERY_LOG, "no memory left to handle more query\n");
        return;
    }

    memcpy(session->query_raw_data_, raw_data, data_len);
    session->query_data_len_ = data_len;
    session->zipper_ = zipper;
    session->client_socket_ = *client_socket;
    session->client_addr_ = *client_addr;

    char ip_addr_str[MAX_IP_STR_LEN];
    addr_get_ip(client_addr, ip_addr_str);
    log_debug(QUERY_LOG, "get query from ip [%s]\n", ip_addr_str);

    session->location_info_ = ipstore_get_location_use_int(zipper->ip_store_,
                                                 addr_get_v4_addr(client_addr));
    if (!session->location_info_)
    {
        log_warning(QUERY_LOG, "get ip failed\n");
        goto BAD_QUERY;
    }

    buffer_t buf;
    buffer_create_from(&buf, (void *)(raw_data + 12), data_len - 12 - 4);
    session->query_wire_name_ = wire_name_from_wire(&buf);
    if (session->query_wire_name_)
    {
        buffer_t name_buf;
        char str_name[MAX_DOMAIN_NAME_LEN] = {0};
        buffer_create_from(&name_buf, str_name, MAX_DOMAIN_NAME_LEN);
        wire_name_to_text(session->query_wire_name_, &name_buf); 
        log_debug(QUERY_LOG, "handle query name [%s]\n", str_name);
                                                
        char view_name[MAX_VIEW_NAME_LEN];
        rule_store_get_view(zipper->rule_store_, session->query_wire_name_,
                                                 session->location_info_, view_name);
        query_named_with_view(view_name, session); 
        wire_name_delete(session->query_wire_name_);
    }
    else
    {
        wire_name_delete(session->query_wire_name_);
        log_warning(QUERY_LOG, "get invalid query name\n");
        goto BAD_QUERY;
    }
    return;

BAD_QUERY:
    memorypool_free_node(zipper->query_session_pool_, session);
}