diff options
| author | liuwentan <[email protected]> | 2024-02-28 08:07:55 +0000 |
|---|---|---|
| committer | liuwentan <[email protected]> | 2024-02-28 08:07:55 +0000 |
| commit | 877b94f48de3bd0fff87634587d1ea03998768cc (patch) | |
| tree | 75b8a4e371571c7a7e030afe3ad6dc708a106771 | |
| parent | 0fdca1d9ff83765a355a12e18c806303bdc8488f (diff) | |
[DNS_DECODER]first tcp/udp dns unit_test
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/dns_decoder/CMakeLists.txt | 13 | ||||
| -rw-r--r-- | src/dns_decoder/dns_decoder.c | 1317 | ||||
| -rw-r--r-- | src/dns_decoder/dns_decoder.h | 271 | ||||
| -rw-r--r-- | test/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | test/dns_decoder/CMakeLists.txt | 44 | ||||
| -rw-r--r-- | test/dns_decoder/dns_decoder_gtest.cpp | 280 | ||||
| -rw-r--r-- | test/dns_decoder/dns_pcap/dns_tcp_simple.pcap | bin | 0 -> 2361 bytes | |||
| -rw-r--r-- | test/dns_decoder/dns_pcap/dns_udp_simple.pcap | bin | 0 -> 1624 bytes | |||
| -rw-r--r-- | test/dns_decoder/test_env/conflist.inf | 9 | ||||
| -rw-r--r-- | test/dns_decoder/test_env/sapp4.el8.x86_64.rpm | bin | 0 -> 1052968 bytes | |||
| -rw-r--r-- | test/dns_decoder/test_env/spec.toml | 12 | ||||
| -rw-r--r-- | test/dns_decoder/test_env/start_loader.inf | 17 | ||||
| -rw-r--r-- | test/dns_decoder/test_env/tsg_l7_protocol.conf | 57 | ||||
| -rw-r--r-- | test/dns_decoder/test_result_json/dns_tcp_simple.json | 58 | ||||
| -rw-r--r-- | test/dns_decoder/test_result_json/dns_udp_simple.json | 25 | ||||
| -rw-r--r-- | test/http_decoder/test_env/spec.toml | 2 |
17 files changed, 2106 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 90bef99..9a8b8ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,7 @@ add_subdirectory(deps/toml) add_subdirectory(src/adapter) add_subdirectory(src/stellar_on_sapp) add_subdirectory(src/http_decoder) +add_subdirectory(src/dns_decoder) add_subdirectory(examples/sapp_plugin) add_subdirectory(examples/stellar_plugin) diff --git a/src/dns_decoder/CMakeLists.txt b/src/dns_decoder/CMakeLists.txt new file mode 100644 index 0000000..da7c4c3 --- /dev/null +++ b/src/dns_decoder/CMakeLists.txt @@ -0,0 +1,13 @@ +add_definitions(-fPIC) + +include_directories(/opt/MESA/include/) +include_directories(${PROJECT_SOURCE_DIR}/deps/) + +aux_source_directory(${PROJECT_SOURCE_DIR}/deps/mempool DEPS_SRC) +aux_source_directory(${PROJECT_SOURCE_DIR}/deps/toml DEPS_SRC) + +set(DNS_SRC ${DEPS_SRC} dns_decoder.c) + +add_library(dns_decoder SHARED ${DNS_SRC}) +#set_target_properties(dns_decoder_shared PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_LIST_DIR}/version.map") +set_target_properties(dns_decoder PROPERTIES PREFIX "")
\ No newline at end of file diff --git a/src/dns_decoder/dns_decoder.c b/src/dns_decoder/dns_decoder.c new file mode 100644 index 0000000..3e76d03 --- /dev/null +++ b/src/dns_decoder/dns_decoder.c @@ -0,0 +1,1317 @@ +/* +********************************************************************************************** +* File: dns_decoder.c +* Description: +* Authors: Liu WenTan <[email protected]> +* Date: 2024-02-07 +* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved. +*********************************************************************************************** +*/ + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "stellar/utils.h" +#include "stellar/session.h" +#include "stellar/stellar.h" +#include "stellar/session_mq.h" +#include "stellar/session_exdata.h" +#include "dns_decoder.h" + +#define DNS_HEADER_SIZE 12 + +#define NS_INT16SZ 2 +#define NS_INT32SZ 4 + +#define NS_GET16(s, cp) do { \ + register uint8_t *t_cp = (uint8_t *)(cp); \ + (s) = ((uint16_t)t_cp[0] << 8) \ + | ((uint16_t)t_cp[1]); \ + (cp) += NS_INT16SZ; \ +} while (0) + +#define NS_GET32(l, cp) do { \ + register uint8_t *t_cp = (uint8_t *)(cp); \ + (l) = ((uint32_t)t_cp[0] << 24) \ + | ((uint32_t)t_cp[1] << 16) \ + | ((uint32_t)t_cp[2] << 8) \ + | ((uint32_t)t_cp[3]); \ + (cp) += NS_INT32SZ; \ +} while (0) + +const char *dns_decoder_topic = "DNS_DECODER_MESSAGE"; + +struct dns_message { + enum dns_message_type type; + union { + struct dns_query query; + struct dns_response response; + }; +}; + +struct dns_decoder_context { + int plugin_id; + int topic_id; + int ex_data_idx; + struct stellar *st; +}; + +struct dns_decoder_exdata { + char *cache_ptr; + int one_byte_len; + size_t cache_len; + size_t cache_capacity; +}; + +struct dns_header { + uint16_t id; +#if __BYTE_ORDER == __LITTLE_ENDIAN + uint8_t rd:1; + uint8_t tc:1; + uint8_t aa:1; + uint8_t opcode:4; + uint8_t qr:1; + uint8_t rcode:4; + uint8_t z:3; + uint8_t ra:1; +#elif __BYTE_ORDER == __BIG_ENDIAN + uint8_t qr:1; + uint8_t opcode:4; + uint8_t aa:1; + uint8_t tc:1; + uint8_t rd:1; + uint8_t ra:1; + uint8_t z:3; + uint8_t rcode:4; +#endif + uint16_t qdcount; + uint16_t ancount; + uint16_t aucount; //authority count + uint16_t adcount; //additional count +}; + +struct dns_message * +dns_message_new(enum dns_message_type type) +{ + struct dns_message *msg = CALLOC(struct dns_message, 1); + + msg->type = type; + + return msg; +} + +static void dns_message_free(void *dns_msg, void *cb_arg) +{ + if (NULL == dns_msg) { + return; + } + + struct dns_message *msg = (struct dns_message *)dns_msg; + if (msg->type == DNS_MESSAGE_RESPONSE) { + if (msg->response.answer_rr != NULL) { + FREE(msg->response.answer_rr); + } + + if (msg->response.authority_rr != NULL) { + FREE(msg->response.authority_rr); + } + + if (msg->response.additional_rr != NULL) { + FREE(msg->response.additional_rr); + } + } + + FREE(msg); +} + +enum dns_message_type dns_message_type(struct dns_message *msg) { + if (NULL == msg) { + return DNS_MESSAGE_MAX; + } + + return msg->type; +} + +int dns_message_get_query(struct dns_message *msg, struct dns_query *query) +{ + if (NULL == msg || msg->type != DNS_MESSAGE_QUERY || NULL == query) { + return -1; + } + + *query = msg->query; + return 0; +} + +int dns_message_get_response(struct dns_message *msg, + struct dns_response *response) +{ + if (NULL == msg || msg->type != DNS_MESSAGE_RESPONSE || + NULL == response) { + return -1; + } + *response = msg->response; + return 0; +} + +int dns_serialize_query(uint8_t **buff, size_t *buff_len, struct dns_query *query) +{ + return 0; +} + +int dns_serialize_response(uint8_t **buff, size_t *buff_len, struct dns_response *response) +{ + return 0; +} + +static void +dns_decoder_ex_data_free(struct session *s, int idx, void *ex_data, void *arg) +{ + +} + +static void _dns_decoder_context_free(struct dns_decoder_context *ctx) +{ + if (NULL == ctx) { + return; + } + + if (ctx->topic_id >= 0) { + session_mq_destroy_topic(ctx->st, ctx->topic_id); + ctx->topic_id = -1; + } + + FREE(ctx); +} + +static void populate_dns_header(struct dns_header *dns_hdr, const uint8_t *payload) +{ + struct dns_header *tmp = (struct dns_header *)payload; + + dns_hdr->qr = tmp->qr; + dns_hdr->opcode= tmp->opcode; + dns_hdr->aa = tmp->aa; + dns_hdr->tc = tmp->tc; + dns_hdr->rd = tmp->rd; + dns_hdr->ra = tmp->ra; + dns_hdr->z = tmp->z; + dns_hdr->rcode = tmp->rcode; + + dns_hdr->id = ntohs(tmp->id); + dns_hdr->qdcount = ntohs(tmp->qdcount); + dns_hdr->ancount = ntohs(tmp->ancount); + dns_hdr->aucount = ntohs(tmp->aucount); + dns_hdr->adcount = ntohs(tmp->adcount); +} + +static int validate_dns_header(struct dns_header *dns_hdr) +{ + + return 0; +} + +static int +get_decompressed_name(uint8_t *dns_payload, size_t dns_payload_len, + uint8_t **cur_pos, uint8_t *buf, size_t buf_len) +{ + size_t index = 0; + size_t len = 0; + size_t tot_len = 0; + uint8_t np = 0; + uint8_t *cursor = *cur_pos; + uint8_t *dns_payload_end = dns_payload + dns_payload_len - 1; + *cur_pos = NULL; + + while (cursor <= dns_payload_end) { + if (0 == cursor[0]) { + break; + } + + if (0x0c0 == (cursor[0] & 0x0c0)) { + if(cursor + 1 > dns_payload_end) { + return -1; + } + + /* udp payload offset */ + len = ((cursor[0] & 0x03f) << 8) + cursor[1]; + + if (NULL == *cur_pos) { + tot_len += 2; + *cur_pos = cursor + 2; + } + + /* udp payload offset = dns_header (12bytes) + dns_payload */ + cursor = dns_payload + len - 12; + if (cursor > dns_payload_end) { + return -1; + } + + /* too many pointers. */ + if (np++ > 16) { + return -1; + } + + continue; + } + + len = cursor[0]; + cursor++; + tot_len++; + + if (cursor + len - 1 > dns_payload_end) { + return -1; + } + + if (index + len >= (buf_len - 1)) { + return -1; + } + + memcpy(buf + index, cursor, len); + index += len; + buf[index++] = '.'; + cursor += len; + tot_len += len; + } + + if (NULL == *cur_pos) { + *cur_pos = cursor + 1; + tot_len++; + } + + /* omit last '.' */ + if (index > 0) { + buf[index - 1] = '\0'; + } else { + buf[0] = '\0'; + } + + return tot_len; +} + +static int get_rr_domain(uint8_t *dns_payload, size_t dns_payload_len, + uint8_t **cur_pos, uint8_t *buf, size_t buf_len) +{ + return get_decompressed_name(dns_payload, dns_payload_len, + cur_pos, buf, buf_len); +} + +static int +parse_dns_query_question(struct dns_query_question *question, + uint8_t *dns_payload, size_t dns_payload_len, + uint8_t **cur_pos) +{ + *cur_pos = dns_payload; + uint8_t *dns_payload_end = dns_payload + dns_payload_len - 1; + + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + question->qname, DNS_NAME_MAX) <= 0) { + return -1; + } + + if (*cur_pos + 1 > dns_payload_end) { + return -1; + } + NS_GET16(question->qtype, *cur_pos); + + if (*cur_pos + 1 > dns_payload_end) { + return -1; + } + NS_GET16(question->qclass, *cur_pos); + + return 0; +} + +static void dns_flag_copy(struct dns_flag *flag, struct dns_header *dns_hdr) +{ + flag->qr = dns_hdr->qr; + flag->opcode = dns_hdr->opcode; + flag->aa = dns_hdr->aa; + flag->tc = dns_hdr->tc; + flag->rd = dns_hdr->rd; + flag->ra = dns_hdr->ra; + flag->z = dns_hdr->z; + flag->rcode = dns_hdr->rcode; +} + +static int +parse_dns_query(struct dns_query *query, struct dns_header *dns_hdr, + uint8_t *dns_payload, size_t dns_payload_len) +{ + query->transaction_id = dns_hdr->id; + + //dns query flag + dns_flag_copy(&query->flag, dns_hdr); + + query->n_question = dns_hdr->qdcount; + + uint8_t *cur_pos = NULL; + int ret = parse_dns_query_question(&query->query_question, dns_payload, + dns_payload_len, &cur_pos); + if (ret < 0) { + fprintf(stderr, "parse dns query question failed.\n"); + return -1; + } + + return 0; +} + +static void +dns_response_init(struct dns_response *response, struct dns_header *dns_hdr) +{ + struct dns_query *query = &response->query; + + query->transaction_id = dns_hdr->id; + dns_flag_copy(&query->flag, dns_hdr); + + query->n_question = dns_hdr->qdcount; + + response->n_answer_rr = dns_hdr->ancount; + response->n_authority_rr = dns_hdr->aucount; + response->n_additional_rr = dns_hdr->adcount; + + if (response->n_answer_rr > 0) { + response->answer_rr = CALLOC(struct dns_rr, response->n_answer_rr); + } + + if (response->n_authority_rr > 0) { + response->authority_rr = CALLOC(struct dns_rr, response->n_authority_rr); + } + + if (response->n_additional_rr > 0) { + response->additional_rr = CALLOC(struct dns_rr, response->n_additional_rr); + } +} + +static int +get_rr_common_field(uint8_t *dns_payload, size_t dns_payload_len, + uint8_t **cur_pos, struct dns_rr *dns_rr) +{ + uint8_t *dns_payload_end = dns_payload + dns_payload_len - 1; + + if (NULL == *cur_pos) { + return -1; + } + + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->name, DNS_NAME_MAX) <= 0) { + return -1; + } + + if (NULL == *cur_pos || (*cur_pos + 1) > dns_payload_end) { + return -1; + } + NS_GET16(dns_rr->type, *cur_pos); + + if (dns_rr->type == DNS_RR_TYPE_OPT) { + return 0; + } + + if (NULL == *cur_pos || (*cur_pos + 1) > dns_payload_end) { + return -1; + } + NS_GET16(dns_rr->rr_class, *cur_pos); + + if (NULL == *cur_pos || (*cur_pos + 3) > dns_payload_end) { + return -1; + } + NS_GET32(dns_rr->ttl, *cur_pos); + + if (NULL == *cur_pos || (*cur_pos + 1) > dns_payload_end) { + return -1; + } + NS_GET16(dns_rr->rdlength, *cur_pos); + + if (NULL == *cur_pos || + (*cur_pos + dns_rr->rdlength - 1) > dns_payload_end) { + return -1; + } + + return 0; +} + +static int get_rr_type_info(uint8_t **cur_pos, struct rdata_hinfo *hinfo) +{ + hinfo->cpu_len = (*cur_pos)[0]; + *cur_pos += 1; + + uint8_t length = MIN(hinfo->cpu_len, sizeof(hinfo->cpu) - 1); + if (length > 0) { + memcpy(hinfo->cpu, *cur_pos, length); + hinfo->cpu[length] = '\0'; + } else { + hinfo->cpu[0] = '\0'; + } + + *cur_pos += hinfo->cpu_len; + hinfo->cpu_len = (length > 0 ? length : 0); + + hinfo->os_len = (*cur_pos)[0]; + *cur_pos += 1; + + length = MIN(hinfo->os_len, sizeof(hinfo->os) - 1); + if (length > 0) { + memcpy(hinfo->os, *cur_pos, length); + hinfo->os[length] = '\0'; + } else { + hinfo->os[0] = '\0'; + } + + *cur_pos += hinfo->os_len; + hinfo->os_len = (length > 0 ? length : 0); + + return 0; +} + +static int +get_rr_type_soa(uint8_t *dns_payload, size_t dns_payload_len, + uint8_t **cur_pos, struct rdata_soa *soa) +{ + uint8_t *dns_payload_end = dns_payload + dns_payload_len - 1; + + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + soa->mname, sizeof(soa->mname)) <= 0) { + return -1; + } + + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + soa->rname, sizeof(soa->rname)) <= 0) { + return -1; + } + + if ((*cur_pos + 3) > dns_payload_end) { + return -1; + } + NS_GET32(soa->serial, *cur_pos); + + if ((*cur_pos + 3) > dns_payload_end) { + return -1; + } + NS_GET32(soa->refresh, *cur_pos); + + if ((*cur_pos + 3) > dns_payload_end) { + return -1; + } + NS_GET32(soa->retry, *cur_pos); + + if ((*cur_pos + 3) > dns_payload_end) { + return -1; + } + NS_GET32(soa->expire, *cur_pos); + + if ((*cur_pos + 3) > dns_payload_end) { + return -1; + } + NS_GET32(soa->minimum, *cur_pos); + + return 0; +} + +static int +get_rr_type_wks(uint8_t **cur_pos, struct rdata_wks *wks, + const uint8_t *dns_payload_end) +{ + if ((*cur_pos + 3) > dns_payload_end) { + return -1; + } + NS_GET32(wks->addr, *cur_pos); + + if ((*cur_pos + 1) > dns_payload_end) { + return -1; + } + + wks->protocol = **cur_pos; + *cur_pos += 1; + wks->bitmap = *cur_pos; + + return 0; +} + +static int +get_rr_type_rrsig(uint8_t **cur_pos, struct rdata_rrsig *rrsig, + const uint8_t *dns_payload_end) +{ + if ((*cur_pos + 1) > dns_payload_end) { + return -1; + } + NS_GET16(rrsig->type_covered, *cur_pos); + + rrsig->algo = **cur_pos; + *cur_pos += 1; + rrsig->labels = **cur_pos; + *cur_pos += 1; + + if ((*cur_pos + 13) > dns_payload_end) { + return -1; + } + + NS_GET32(rrsig->original_ttl, *cur_pos); + NS_GET32(rrsig->sig_expiration, *cur_pos); + NS_GET32(rrsig->sig_inception, *cur_pos); + NS_GET16(rrsig->key_tag, *cur_pos); + + return 0; +} + +static int +dissect_type_bitmap(uint8_t *cur_pos, size_t rr_len, uint8_t *maps_buff, + uint16_t *maps_len) +{ + size_t cur_offset = 0; + size_t map_offset = 0; + + if (NULL == cur_pos || 0 == rr_len) { + *maps_len = 0; + return 0; + } + + while ((rr_len - cur_offset) > 0) { + if (map_offset + 2 > *maps_len) { + break; + } + + maps_buff[map_offset++] = cur_pos[cur_offset++]; + maps_buff[map_offset++] = cur_pos[cur_offset]; + size_t blocksize = cur_pos[cur_offset++]; + + size_t length = MIN(*maps_len - map_offset, blocksize); + if (length == 0 || blocksize > (rr_len - cur_offset)) { + break; + } + + memcpy(maps_buff + map_offset, cur_pos + cur_offset, length); + cur_offset += blocksize; + map_offset += length; + } + + *maps_len = map_offset; + + return cur_offset; +} + +static int +get_rr_type_nsec3(uint8_t **cur_pos, struct rdata_nsec3 *nsec3, + const uint8_t *dns_payload_end) +{ + if ((*cur_pos + 4) > dns_payload_end) { + return -1; + } + + nsec3->hash_algo = **cur_pos; + *cur_pos += 1; + nsec3->flags= **cur_pos; + *cur_pos += 1; + + NS_GET16(nsec3->iteration, *cur_pos); + + nsec3->salt_len = **cur_pos; + *cur_pos += 1; + + if (nsec3->salt_len > 0) { + if ((*cur_pos + nsec3->salt_len) > dns_payload_end) { + return -1; + } + + nsec3->salt_value = *cur_pos; + *cur_pos += nsec3->salt_len; /* jump salt_value */ + } + + nsec3->hash_len = **cur_pos; + *cur_pos += 1; + + if (nsec3->hash_len > 0) { + if ((*cur_pos + nsec3->hash_len) > dns_payload_end) { + return -1; + } + + nsec3->next_hash_owner = *cur_pos; + *cur_pos += nsec3->hash_len; /* jump next_hash_owner */ + } + + return 0; +} + +static int +get_one_rr(uint8_t *dns_payload, size_t dns_payload_len, uint8_t **cur_pos, + struct dns_rr *dns_rr) +{ + int len = 0; + uint8_t *original_ptr = NULL; + uint8_t *dns_payload_end =dns_payload + dns_payload_len - 1; + + switch(dns_rr->type) { + case DNS_RR_TYPE_CNAME: + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.cname, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.cname[0] = '\0'; + return -1; + } + + break; + case DNS_RR_TYPE_HINFO: + if (get_rr_type_info(cur_pos, &(dns_rr->rdata.hinfo)) != 0) { + memset(&(dns_rr->rdata.hinfo), 0, sizeof(struct rdata_hinfo)); + return -1; + } + break; + case DNS_RR_TYPE_MB: + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.mb, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.mb[0] = '\0'; + return -1; + } + + break; + case DNS_RR_TYPE_MD: + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.md, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.md[0] = '\0'; + return -1; + } + + break; + case DNS_RR_TYPE_MF: + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.mf, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.mf[0] = '\0'; + return -1; + } + + break; + case DNS_RR_TYPE_MG: + if(get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.mg, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.mg[0] = '\0'; + return -1; + } + + break; + case DNS_RR_TYPE_MINFO: + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.minfo.rmailbx, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.minfo.rmailbx[0] = '\0'; + return -1; + } + + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.minfo.emailbx, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.minfo.emailbx[0] = '\0'; + return -1; + } + break; + case DNS_RR_TYPE_MR: + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.mr, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.mr[0] = '\0'; + return -1; + } + break; + case DNS_RR_TYPE_MX: + if((*cur_pos + 1) > dns_payload_end) { + return -1; + } + + NS_GET16(dns_rr->rdata.mx.preference, *cur_pos); + + if ((dns_rr->rdlength - 2) < (*cur_pos)[0]) { + if (dns_rr->rdlength < 2) { + *cur_pos += dns_rr->rdlength; + break; + } + + len = MIN(DNS_NAME_MAX - 2, dns_rr->rdlength - 2);/*size=1byte*/ + memcpy(dns_rr->rdata.mx.exchange, *cur_pos, len); /* error labels */ + dns_rr->rdata.mx.exchange[len] = '\0'; + *cur_pos += dns_rr->rdlength - 2; + } else { + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.mx.exchange, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.mx.exchange[0] = '\0'; + return -1; + } + } + break; + case DNS_RR_TYPE_NS: + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.ns, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.ns[0] = '\0'; + return -1; + } + break; + case DNS_RR_TYPE_PTR: + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.ptr, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.ptr[0] = '\0'; + return -1; + } + break; + case DNS_RR_TYPE_SOA: + original_ptr = *cur_pos; + if (get_rr_type_soa(dns_payload, dns_payload_len, cur_pos, + &(dns_rr->rdata.soa)) != 0) { + memset(&(dns_rr->rdata.soa), 0, sizeof(struct rdata_soa)); + return -1; + } + + if(original_ptr + dns_rr->rdlength != *cur_pos) { + *cur_pos = original_ptr + dns_rr->rdlength; + } + break; + case DNS_RR_TYPE_A: + if ((*cur_pos + 3) > dns_payload_end) { + return -1; + } + + memcpy(dns_rr->rdata.a, *cur_pos, NS_INT32SZ); + (*cur_pos) += NS_INT32SZ; + break; + case DNS_RR_TYPE_AAAA: + if((*cur_pos + 15) > dns_payload_end) { + return -1; + } + + memcpy(dns_rr->rdata.aaaa, *cur_pos, 16); + (*cur_pos) += 16; + break; + case DNS_RR_TYPE_DNAME: + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.dname, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.dname[0] = '\0'; + return -1; + } + break; + case DNS_RR_TYPE_ISDN: + memcpy(dns_rr->rdata.isdn, *cur_pos, sizeof(uint8_t)); + (*cur_pos) += 1; + break; + case DNS_RR_TYPE_TXT: + len = MIN(DNS_NAME_MAX - 2, dns_rr->rdlength - 1); /*size=1byte*/ + memcpy(dns_rr->rdata.txt.txt, *cur_pos + 1, len); + dns_rr->rdata.txt.size = len; + *cur_pos += dns_rr->rdlength; + break; + case DNS_RR_TYPE_RP: + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.rp.mailbox, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.rp.mailbox[0] = '\0'; + return -1; + } + + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.rp.txt_rr, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.rp.txt_rr[0] = '\0'; + return -1; + } + break; + case DNS_RR_TYPE_NULL: + len = MIN(DNS_NAME_MAX-2, dns_rr->rdlength - 1); /*size=1byte*/ + memcpy(dns_rr->rdata.null.null, *cur_pos + 1, len); + dns_rr->rdata.null.size = len; + *cur_pos += dns_rr->rdlength; + break; + case DNS_RR_TYPE_WKS: + if (get_rr_type_wks(cur_pos, &(dns_rr->rdata.wks), dns_payload_end) != 0) { + memset(&(dns_rr->rdata.wks), 0, sizeof(struct rdata_wks)); + return -1; + } + + dns_rr->rdata.wks.size = dns_rr->rdlength - 5; + if (0 == dns_rr->rdata.wks.size) { + dns_rr->rdata.wks.size = 0; + dns_rr->rdata.wks.bitmap = NULL; + + } + *cur_pos += dns_rr->rdlength - 5; + case DNS_RR_TYPE_SRV: + NS_GET16(dns_rr->rdata.srv.priority, *cur_pos); + NS_GET16(dns_rr->rdata.srv.weight, *cur_pos); + NS_GET16(dns_rr->rdata.srv.port, *cur_pos); + if (get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.srv.target, DNS_NAME_MAX) <= 0) { + dns_rr->rdata.srv.target[0] = '\0'; + return -1; + } + break; + case DNS_RR_TYPE_OPT: + break; + case DNS_RR_TYPE_DS: + case DNS_RR_TYPE_DLV: + if ((*cur_pos + 3) > dns_payload_end) { + return -1; + } + + NS_GET16(dns_rr->rdata.ds.key_tag, *cur_pos); + dns_rr->rdata.ds.algo = **cur_pos; + *cur_pos += 1; + dns_rr->rdata.ds.digest_type = **cur_pos; + *cur_pos += 1; + dns_rr->rdata.ds.digest = *cur_pos; + dns_rr->rdata.ds.digest_len = dns_rr->rdlength - 4; + if (dns_rr->rdata.ds.digest_len == 0) { + dns_rr->rdata.ds.digest = NULL; + dns_rr->rdata.ds.digest_len = 0; + } + *cur_pos += dns_rr->rdlength - 4; + break; + case DNS_RR_TYPE_RRSIG: + if((*cur_pos + 17) > dns_payload_end) { + return -1; + } + + memset(&(dns_rr->rdata.rrsig), 0, sizeof(struct rdata_rrsig)); + get_rr_type_rrsig(cur_pos, &(dns_rr->rdata.rrsig), dns_payload_end); + len = get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.rrsig.signer_name, DNS_NAME_MAX); + if (len <= 0) { + dns_rr->rdata.rrsig.signer_name[0] = '\0'; + return -1; + } + + dns_rr->rdata.rrsig.signature = *cur_pos; + dns_rr->rdata.rrsig.signature_len = dns_rr->rdlength - 18 - len; + if (dns_rr->rdata.rrsig.signature_len == 0) { + dns_rr->rdata.rrsig.signature = NULL; + dns_rr->rdata.rrsig.signature_len = 0; + } + *cur_pos += dns_rr->rdlength - 18 - len; + break; + case DNS_RR_TYPE_NSEC: + original_ptr = *cur_pos; + len = get_rr_domain(dns_payload, dns_payload_len, cur_pos, + dns_rr->rdata.nsec.next_domain, DNS_NAME_MAX); + if (len <= 0) { + dns_rr->rdata.nsec.next_domain[0] = '\0'; + return -1; + } + + if ((int)(dns_rr->rdlength - len) < (int)(sizeof(dns_rr->rdata.nsec.type_bit_maps))) { + dns_rr->rdata.nsec.maps_len = DNS_NAME_MAX; + dissect_type_bitmap(*cur_pos, dns_rr->rdlength - len, + (dns_rr->rdata.nsec.type_bit_maps), + &(dns_rr->rdata.nsec.maps_len)); + } + *cur_pos = original_ptr + dns_rr->rdlength; + break; + case DNS_RR_TYPE_DNSKEY: + if((*cur_pos + 3) > dns_payload_end) { + return -1; + } + + NS_GET16(dns_rr->rdata.dnskey.flags, *cur_pos); + dns_rr->rdata.dnskey.protocol = **cur_pos; + *cur_pos += 1; + dns_rr->rdata.dnskey.algo = **cur_pos; + *cur_pos += 1; + dns_rr->rdata.dnskey.public_key = *cur_pos; + dns_rr->rdata.dnskey.public_key_len = dns_rr->rdlength - 4; /* sizeof(flags)+sizeof(protocol)+sizeof(algo) */ + if (dns_rr->rdata.dnskey.public_key_len == 0) { + dns_rr->rdata.dnskey.public_key = NULL; + dns_rr->rdata.dnskey.public_key_len = 0; + } + *cur_pos += dns_rr->rdlength - 4; /* todo add log */ + break; + case DNS_RR_TYPE_NSEC3: + original_ptr = *cur_pos; + if (get_rr_type_nsec3(cur_pos, &(dns_rr->rdata.nsec3), dns_payload_end) < 0) { + return -1; + } + + len = *cur_pos - original_ptr; + if ((int)(dns_rr->rdlength - len) < (int)(sizeof(dns_rr->rdata.nsec3.type_bit_maps))) { + dns_rr->rdata.nsec3.maps_len = DNS_NAME_MAX; + dissect_type_bitmap(*cur_pos, dns_rr->rdlength - len, + (dns_rr->rdata.nsec3.type_bit_maps), + &(dns_rr->rdata.nsec3.maps_len)); + } + *cur_pos = original_ptr + dns_rr->rdlength; + break; + case DNS_RR_TYPE_NSEC3PARAM: + dns_rr->rdata.nsec3param.hash_algo = **cur_pos; + *cur_pos += 1; + + dns_rr->rdata.nsec3param.flags = **cur_pos; + *cur_pos += 1; + + NS_GET16(dns_rr->rdata.nsec3param.iteration, *cur_pos); + + dns_rr->rdata.nsec3param.salt_len = dns_rr->rdlength - 4 - 1; + *cur_pos += 1; + + if (dns_rr->rdata.nsec3param.salt_len == 0) { + dns_rr->rdata.nsec3param.salt_value = NULL; + dns_rr->rdata.nsec3param.salt_len = 0; + } else { + dns_rr->rdata.nsec3param.salt_value = *cur_pos; + } + *cur_pos += dns_rr->rdlength - 5; + break; + case DNS_RR_TYPE_UNKNOWN: + len = MIN(dns_rr->rdlength, sizeof(dns_rr->rdata.unknown_data) - 1); + memcpy(dns_rr->rdata.unknown_data, *cur_pos, len); + dns_rr->rdata.unknown_data[len] = '\0'; + (*cur_pos) += dns_rr->rdlength; + break; + default: + *cur_pos += dns_rr->rdlength; + fprintf(stderr, "No support dns rr type, type: %d", dns_rr->type); + break; + } + + return 0; +} + +static int +parse_common_dns_rr(uint8_t *dns_payload, size_t dns_payload_len, + uint8_t **cur_pos, struct dns_rr *rr, size_t n_rr) +{ + uint8_t *dns_payload_end = dns_payload + dns_payload_len - 1; + + for (size_t i = 0; i < n_rr; i++) { + if (*cur_pos < dns_payload || *cur_pos >= dns_payload_end) { + return -1; + } + + if (get_rr_common_field(dns_payload, dns_payload_len, + cur_pos, &rr[i]) < 0) { + return -1; + } + + if (get_one_rr(dns_payload, dns_payload_len, cur_pos, &rr[i]) < 0) { + return -1; + } + } + + return 0; +} + +static int parse_dns_rr(struct dns_response *response, uint8_t *dns_payload, + size_t dns_payload_len, uint8_t *cur_pos) +{ + size_t i = 0; + uint8_t *dns_payload_end = dns_payload + dns_payload_len - 1; + + /* parse answer */ + int ret = parse_common_dns_rr(dns_payload, dns_payload_len, &cur_pos, + response->answer_rr, response->n_answer_rr); + if (ret < 0) { + return -1; + } + + ret = parse_common_dns_rr(dns_payload, dns_payload_len, &cur_pos, + response->authority_rr, response->n_authority_rr); + if (ret < 0) { + return -1; + } + + ret = parse_common_dns_rr(dns_payload, dns_payload_len, &cur_pos, + response->additional_rr, response->n_additional_rr); + if (ret < 0) { + return -1; + } + + return 0; +} + +static int +parse_dns_response(struct dns_response *response, struct dns_header *dns_hdr, + uint8_t *dns_payload, size_t dns_payload_len) +{ + dns_response_init(response, dns_hdr); + + uint8_t *cur_pos = NULL; + int ret = parse_dns_query_question(&response->query.query_question, + dns_payload, dns_payload_len, &cur_pos); + if (ret < 0) { + fprintf(stderr, "parse dns response question failed.\n"); + return -1; + } + + ret = parse_dns_rr(response, dns_payload, dns_payload_len, cur_pos); + if (ret < 0) { + fprintf(stderr, "parse dns reponse resource record failed.\n"); + return -1; + } + + return 0; +} + +static int +udp_dns_decoder_entry(struct session *sess, int events, const struct packet *pkt, + struct dns_decoder_context *ctx) +{ + size_t udp_payload_len = 0; + + const uint8_t *udp_payload = + session_get0_current_payload(sess, &udp_payload_len); + if (udp_payload_len < DNS_HEADER_SIZE) { + //Non dns packet + return 0; + } + + struct dns_header dns_hdr = {0}; + populate_dns_header(&dns_hdr, udp_payload); + + int ret = validate_dns_header(&dns_hdr); + if (ret < 0) { + return 0; + } + + uint8_t *dns_payload = udp_payload + DNS_HEADER_SIZE; + size_t dns_payload_len = udp_payload_len - DNS_HEADER_SIZE; + + struct dns_message *msg = NULL; + if (0 == dns_hdr.qr) { + //query + msg = dns_message_new(DNS_MESSAGE_QUERY); + ret = parse_dns_query(&msg->query, &dns_hdr, dns_payload, + dns_payload_len); + if (ret < 0) { + dns_message_free(msg, NULL); + return -1; + } + } else { + //response + msg = dns_message_new(DNS_MESSAGE_RESPONSE); + ret = parse_dns_response(&msg->response, &dns_hdr, dns_payload, + dns_payload_len); + if (ret < 0) { + dns_message_free(msg, NULL); + return -1; + } + } + + session_mq_publish_message(sess, ctx->topic_id, msg); + + return 0; +} + +static void +dns_decoder_exdata_free(struct dns_decoder_exdata *ex_data) +{ + if (NULL == ex_data) { + return; + } + + if (ex_data->cache_ptr != NULL) { + FREE(ex_data->cache_ptr); + } + + FREE(ex_data); +} + +static int +tcp_dns_decoder_entry(struct session *sess, int events, const struct packet *pkt, + struct dns_decoder_context *ctx) +{ + struct dns_decoder_exdata *ex_data = + session_get_ex_data(sess, ctx->ex_data_idx); + + if (events & SESS_EV_CLOSING) { + if (ex_data != NULL) { + dns_decoder_exdata_free(ex_data); + session_set_ex_data(sess, ctx->ex_data_idx, NULL); + } + + return 0; + } + + size_t tcp_payload_len = 0; + const uint8_t *tcp_payload = + session_get0_current_payload(sess, &tcp_payload_len); + if (0 == tcp_payload_len) { + return 0; + } + + uint8_t *buff = NULL; + size_t buff_len = 0; + + if (NULL == ex_data) { + if (1 == tcp_payload_len) { + //cache this byte + ex_data = CALLOC(struct dns_decoder_exdata, 1); + ex_data->one_byte_len = *(uint8_t *)tcp_payload; + session_set_ex_data(sess, ctx->ex_data_idx, ex_data); + return 0; + } else { + uint16_t dns_len = ntohs(*(uint16_t *)tcp_payload); + if (dns_len > (tcp_payload_len - 2)) { + ex_data = CALLOC(struct dns_decoder_exdata, 1); + ex_data->one_byte_len = -1; + ex_data->cache_ptr = CALLOC(char, dns_len); + ex_data->cache_len = tcp_payload_len - 2; + ex_data->cache_capacity = dns_len; + memcpy(ex_data->cache_ptr, tcp_payload, ex_data->cache_len); + session_set_ex_data(sess, ctx->ex_data_idx, ex_data); + + return 0; + } else { + //goto dns parser + buff = tcp_payload + 2; + buff_len = tcp_payload_len - 2; + goto next; + } + } + } else { + // SESS_EV_PACKET + if (ex_data->one_byte_len == -1) { + if (tcp_payload_len < ex_data->cache_capacity - ex_data->cache_len) { + memcpy(ex_data->cache_ptr + ex_data->cache_len, tcp_payload, + tcp_payload_len); + ex_data->cache_len += tcp_payload_len; + return 0; + } else if (tcp_payload_len == ex_data->cache_capacity - ex_data->cache_len) { + memcpy(ex_data->cache_ptr + ex_data->cache_len, tcp_payload, + tcp_payload_len); + ex_data->cache_len += tcp_payload_len; + buff = ex_data->cache_ptr; + buff_len = ex_data->cache_len; + } else { + assert(0); + } + } else { + // + uint8_t tmp_len[2] = {0}; + tmp_len[0] = ex_data->one_byte_len; + tmp_len[1] = *(uint8_t *)tcp_payload; + uint16_t dns_len = ntohs(*(uint16_t *)tmp_len); + if (dns_len > (tcp_payload_len - 1)) { + memcpy(ex_data->cache_ptr + ex_data->cache_len, tcp_payload + 1, + tcp_payload_len - 1); + ex_data->cache_len += tcp_payload_len - 1; + return 0; + } else { + buff = tcp_payload + 1; + buff_len = tcp_payload_len - 1; + } + } + } + + struct dns_header dns_hdr = {0}; +next: + populate_dns_header(&dns_hdr, buff); + + int ret = validate_dns_header(&dns_hdr); + if (ret < 0) { + return 0; + } + + uint8_t *dns_payload = buff + DNS_HEADER_SIZE; + size_t dns_payload_len = buff_len - DNS_HEADER_SIZE; + + struct dns_message *msg = NULL; + if (0 == dns_hdr.qr) { + //query + msg = dns_message_new(DNS_MESSAGE_QUERY); + ret = parse_dns_query(&msg->query, &dns_hdr, dns_payload, + dns_payload_len); + if (ret < 0) { + dns_message_free(msg, NULL); + return -1; + } + } else { + //response + msg = dns_message_new(DNS_MESSAGE_RESPONSE); + ret = parse_dns_response(&msg->response, &dns_hdr, dns_payload, + dns_payload_len); + if (ret < 0) { + dns_message_free(msg, NULL); + return -1; + } + } + + session_mq_publish_message(sess, ctx->topic_id, msg); + + return 0; +} + +int dns_decoder_entry(struct session *sess, int events, + const struct packet *pkt, void *cb_arg) +{ + struct dns_decoder_context *ctx = (struct dns_decoder_context *)cb_arg; + uint64_t inner_flag = 0; + + int ret = session_is_inner_most(sess, &inner_flag); + if (0 == ret) { + return 0; + } + + enum session_addr_type sess_addr_type = SESSION_ADDR_TYPE_UNKNOWN; + struct session_addr *sess_addr = session_get0_addr(sess, &sess_addr_type); + + if (sess_addr_type == SESSION_ADDR_TYPE_IPV4_TCP || + sess_addr_type == SESSION_ADDR_TYPE_IPV4_UDP) { + if (ntohs(sess_addr->ipv4.dport) != 53 && + ntohs(sess_addr->ipv4.sport) != 53) { + return 0; + } + } else if (sess_addr_type == SESSION_ADDR_TYPE_IPV6_TCP || + sess_addr_type == SESSION_ADDR_TYPE_IPV6_UDP) { + if (ntohs(sess_addr->ipv6.dport) != 53 && + ntohs(sess_addr->ipv6.sport) != 53) { + return 0; + } + } else { + return 0; + } + + if (session_get_type(sess) == SESSION_TYPE_TCP) { + // tcp + ret = tcp_dns_decoder_entry(sess, events, pkt, ctx); + } else { + // udp + ret = udp_dns_decoder_entry(sess, events, pkt, ctx); + } + + return ret; +} + +void *dns_decoder_init(struct stellar *st) +{ + int plugin_id = -1; + int topic_id = -1; + int ex_data_idx = -1; + + struct dns_decoder_context *ctx = CALLOC(struct dns_decoder_context, 1); + + ctx->st = st; + ex_data_idx = stellar_session_get_ex_new_index(st, "DNS_DECODER", + dns_decoder_ex_data_free, + NULL); + if (ex_data_idx < 0) { + goto failed; + } + ctx->ex_data_idx = ex_data_idx; + + plugin_id = stellar_plugin_register(st, SESS_EV_TCP | SESS_EV_UDP, + dns_decoder_entry, ctx); + if (plugin_id < 0) { + goto failed; + } + ctx->plugin_id = plugin_id; + + topic_id = session_mq_get_topic_id(st, dns_decoder_topic); + if (topic_id < 0) { + topic_id = session_mq_create_topic(st, dns_decoder_topic, + dns_message_free, NULL); + } + ctx->topic_id = topic_id; + + printf("dns_decoder_init: ex_data_idx:%d, plugin_id:%d, topic_id:%d\n", + ctx->ex_data_idx, ctx->plugin_id, ctx->topic_id); + + return ctx; + +failed: + _dns_decoder_context_free(ctx); + return NULL; +} + +void dns_decoder_exit(void *decoder_ctx) +{ + if (NULL == decoder_ctx) { + return; + } + + struct dns_decoder_context *ctx = (struct dns_decoder_context *)decoder_ctx; + + _dns_decoder_context_free(ctx); +}
\ No newline at end of file diff --git a/src/dns_decoder/dns_decoder.h b/src/dns_decoder/dns_decoder.h new file mode 100644 index 0000000..5ee1fdc --- /dev/null +++ b/src/dns_decoder/dns_decoder.h @@ -0,0 +1,271 @@ +/* +********************************************************************************************** +* File: dns_decoder.h +* Description: dns decoder api +* Authors: Liu WenTan <[email protected]> +* Date: 2024-02-07 +* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved. +*********************************************************************************************** +*/ + +#ifndef _DNS_DECODER_H_ +#define _DNS_DECODER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <stdint.h> +#include <linux/limits.h> +#include <stddef.h> + +#define DNS_NAME_MAX (NAME_MAX + 1) +#define HINFO_NAME_MAX (40 + 1) /* https://www.ietf.org/rfc/rfc1010.txt */ + +enum dns_message_type { + DNS_MESSAGE_QUERY, + DNS_MESSAGE_RESPONSE, + DNS_MESSAGE_MAX +}; + +/* RR(resource record) type, defined in https://www.ietf.org/rfc/rfc1035.txt */ +enum dns_rr_type { + DNS_RR_TYPE_A = 1, + DNS_RR_TYPE_NS, + DNS_RR_TYPE_MD, /* Obsolete - use MX, rfc973 */ + DNS_RR_TYPE_MF, /* Obsolete - use MX, rfc973 */ + DNS_RR_TYPE_CNAME, + DNS_RR_TYPE_SOA, + DNS_RR_TYPE_MB, /* EXPERIMENTAL, rfc883,rfc2505 */ + DNS_RR_TYPE_MG, /* EXPERIMENTAL, rfc883,rfc2505 */ + DNS_RR_TYPE_MR, /* EXPERIMENTAL, rfc883 */ + DNS_RR_TYPE_NULL, /* EXPERIMENTAL, rfc1035 */ + DNS_RR_TYPE_WKS, /* Not to be relied upon, rfc1123 */ + DNS_RR_TYPE_PTR, + DNS_RR_TYPE_HINFO, + DNS_RR_TYPE_MINFO, + DNS_RR_TYPE_MX, + DNS_RR_TYPE_TXT, + DNS_RR_TYPE_RP, + DNS_RR_TYPE_ISDN = 20, + DNS_RR_TYPE_AAAA = 28, /* dns_ipv6 */ + DNS_RR_TYPE_SRV = 33, + DNS_RR_TYPE_DNAME = 39, + DNS_RR_TYPE_OPT = 41, + DNS_RR_TYPE_DS = 43, + DNS_RR_TYPE_RRSIG = 46, + DNS_RR_TYPE_NSEC, + DNS_RR_TYPE_DNSKEY, + DNS_RR_TYPE_NSEC3 = 50, + DNS_RR_TYPE_NSEC3PARAM, + DNS_RR_TYPE_HTTPS = 65, + DNS_RR_TYPE_AXFR = 252, + DNS_RR_TYPE_MAILB, + DNS_RR_TYPE_MAILA, /* Obsolete - see MX */ + DNS_RR_TYPE_ANY, + DNS_RR_TYPE_DLV = 32769, /* DSNSEC Lokkaside Validation */ + DNS_RR_TYPE_UNKNOWN = 65534 +}; + +struct dns_flag { + uint8_t qr:1; + uint8_t opcode:4; + uint8_t aa:1; + uint8_t tc:1; + uint8_t rd:1; + uint8_t ra:1; + uint8_t z:3; + uint8_t rcode:4; +}; + +struct dns_query_question { + uint16_t qtype; + uint16_t qclass; + uint8_t qname[DNS_NAME_MAX]; +}; + +struct rdata_hinfo { + uint8_t os_len; + uint8_t cpu_len; + uint8_t cpu[HINFO_NAME_MAX]; + uint8_t os[HINFO_NAME_MAX]; +}; + +struct rdata_minfo { + uint8_t rmailbx[DNS_NAME_MAX]; + uint8_t emailbx[DNS_NAME_MAX]; +}; + +struct rdata_mx { + uint16_t preference; + uint8_t exchange[DNS_NAME_MAX]; +}; + +struct rdata_soa { + uint8_t mname[DNS_NAME_MAX]; + uint8_t rname[DNS_NAME_MAX]; + uint32_t serial; + uint32_t refresh; + uint32_t retry; + uint32_t expire; + uint32_t minimum; +}; + +struct rdata_txt { + uint8_t txt[DNS_NAME_MAX]; + uint8_t size; +}; + +struct rdata_rp { + uint8_t mailbox[DNS_NAME_MAX]; + uint8_t txt_rr[DNS_NAME_MAX]; +}; + +struct rdata_null { + uint8_t null[DNS_NAME_MAX]; + uint8_t size; +}; + +struct rdata_wks { + uint8_t protocol; + uint32_t addr; + uint32_t size; + uint8_t *bitmap; +}; + +struct rdata_srv { + uint16_t priority; + uint16_t weight; + uint16_t port; + uint8_t target[DNS_NAME_MAX]; +}; + +struct rdata_ds { + uint16_t key_tag; + uint8_t algo; + uint8_t digest_type; + uint32_t digest_len; + uint8_t *digest; +}; + +struct rdata_rrsig { + uint16_t type_covered; + uint8_t algo; + uint8_t labels; + uint32_t original_ttl; + uint32_t sig_expiration; + uint32_t sig_inception; + uint32_t key_tag; + uint32_t signature_len; + uint8_t signer_name[DNS_NAME_MAX]; + uint8_t *signature; +}; + +struct rdata_nsec { + uint16_t maps_len; + uint8_t next_domain[DNS_NAME_MAX]; + uint8_t type_bit_maps[DNS_NAME_MAX]; +}; + +struct rdata_dnskey { + uint16_t flags; + uint8_t protocol; + uint8_t algo; + uint32_t public_key_len; + uint8_t *public_key; +}; + +struct rdata_nsec3 { + uint8_t hash_algo; + uint8_t flags; + uint8_t salt_len; + uint8_t hash_len; + uint16_t iteration; + uint16_t maps_len; + uint8_t *salt_value; + uint8_t *next_hash_owner; + uint8_t type_bit_maps[DNS_NAME_MAX]; +}; + +struct rdata_nsec3param { + uint8_t hash_algo; + uint8_t flags; + uint8_t salt_len; + uint16_t iteration; + uint8_t *salt_value; +}; + +/* rr is short for resource record */ +struct dns_rr { + uint8_t name[DNS_NAME_MAX]; + uint16_t type; + uint16_t rr_class; + uint32_t ttl; /* 1byte: extended RCODE; 1byte: version; 2bytes: Z(upper bit) if type is OPT */ + uint16_t rdlength; + union { + uint8_t cname[DNS_NAME_MAX]; + uint8_t mb[DNS_NAME_MAX]; + uint8_t md[DNS_NAME_MAX]; + uint8_t mf[DNS_NAME_MAX]; + uint8_t mg[DNS_NAME_MAX]; + uint8_t mr[DNS_NAME_MAX]; + uint8_t ns[DNS_NAME_MAX]; + uint8_t ptr[DNS_NAME_MAX]; + uint8_t a[DNS_NAME_MAX]; + uint8_t aaaa[DNS_NAME_MAX]; + uint8_t dname[DNS_NAME_MAX]; + uint8_t isdn[DNS_NAME_MAX]; + uint8_t unknown_data[DNS_NAME_MAX]; + struct rdata_hinfo hinfo; + struct rdata_minfo minfo; + struct rdata_mx mx; + struct rdata_soa soa; + struct rdata_txt txt; + struct rdata_rp rp; + struct rdata_null null; + struct rdata_wks wks; + struct rdata_srv srv; + struct rdata_ds ds; + struct rdata_rrsig rrsig; + struct rdata_nsec nsec; + struct rdata_dnskey dnskey; + struct rdata_nsec3 nsec3; + struct rdata_nsec3param nsec3param; + } rdata; +}; + +struct dns_query { + uint16_t transaction_id; + struct dns_flag flag; + uint16_t n_question; + struct dns_query_question query_question; +}; + +struct dns_response { + struct dns_query query; + uint16_t n_answer_rr; + uint16_t n_authority_rr; + uint16_t n_additional_rr; + struct dns_rr *answer_rr; + struct dns_rr *authority_rr; + struct dns_rr *additional_rr; +}; + +struct dns_message; + +enum dns_message_type dns_message_type(struct dns_message *msg); + +int dns_message_get_query(struct dns_message *msg, struct dns_query *query); + +int dns_message_get_response(struct dns_message *msg, struct dns_response *response); + +int dns_serialize_query(uint8_t **buff, size_t *buff_len, struct dns_query *query); + +int dns_serialize_response(uint8_t **buff, size_t *buff_len, struct dns_response *response); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b7beeaa..2df4ad3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -11,6 +11,7 @@ target_link_libraries( ) add_subdirectory(http_decoder) +add_subdirectory(dns_decoder) include(GoogleTest) gtest_discover_tests(gtest_stellar)
\ No newline at end of file diff --git a/test/dns_decoder/CMakeLists.txt b/test/dns_decoder/CMakeLists.txt new file mode 100644 index 0000000..b9477ce --- /dev/null +++ b/test/dns_decoder/CMakeLists.txt @@ -0,0 +1,44 @@ +set(DECODER_NAME dns_decoder) + +add_library(${DECODER_NAME}_test SHARED dns_decoder_gtest.cpp) +add_dependencies(${DECODER_NAME}_test ${DECODER_NAME}) +target_link_libraries(${DECODER_NAME}_test MESA_prof_load cjson) +set_target_properties(${DECODER_NAME}_test PROPERTIES PREFIX "") + +set(TEST_RUN_DIR ${CMAKE_CURRENT_BINARY_DIR}/sapp) +set(TEST_MAIN ${TEST_RUN_DIR}/plugin_test_main) + +# assemble test env +add_test(NAME INSTALL_TEST_MAIN COMMAND sh -c "rpm -i ${CMAKE_CURRENT_SOURCE_DIR}/test_env/sapp4.el8.x86_64.rpm --prefix=${CMAKE_CURRENT_BINARY_DIR}/sapp --force --nodeps") + +add_test(NAME COPY_TEST_MAIN COMMAND sh -c "cp ${TEST_RUN_DIR}/tools/plugin_test_main ${TEST_RUN_DIR}/plugin_test_main") +add_test(NAME COPY_CONF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/tsgconf/ && cp ${CMAKE_CURRENT_SOURCE_DIR}/test_env/tsg_l7_protocol.conf ${TEST_RUN_DIR}/tsgconf/tsg_l7_protocol.conf") +add_test(NAME COPY_SPEC COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/stellar_plugin/ && cp ${CMAKE_CURRENT_SOURCE_DIR}/test_env/spec.toml ${TEST_RUN_DIR}/stellar_plugin/spec.toml") +add_test(NAME COPY_CONFLIST COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/plug/ && cp ${CMAKE_CURRENT_SOURCE_DIR}/test_env/conflist.inf ${TEST_RUN_DIR}/plug/conflist.inf") +add_test(NAME COPY_INF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/plug/stellar_on_sapp && cp ${CMAKE_CURRENT_SOURCE_DIR}/test_env/start_loader.inf ${TEST_RUN_DIR}/plug/stellar_on_sapp/start_loader.inf") + +# update config files +add_test(NAME UPDATE_SAPP_LOG COMMAND bash -c "sed -i 's/sapp_log.fatal/sapp_log.info/' ${TEST_RUN_DIR}/etc/sapp_log.conf") +add_test(NAME UPDATE_SAPP_SYN_MODE COMMAND bash -c "sed -i 's/syn_mandatory=1/syn_mandatory=0/' ${TEST_RUN_DIR}/etc/sapp.toml") +add_test(NAME UPDATE_SAPP_REORDER COMMAND bash -c "sed -i 's/reorder_pkt_max=32/reorder_pkt_max=5/' ${TEST_RUN_DIR}/etc/sapp.toml") + +# update plugin to be tested +add_test(NAME UPDATE_STELLAR_ON_SAPP_SO COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/src/stellar_on_sapp/stellar_on_sapp.so ${TEST_RUN_DIR}/plug/stellar_on_sapp/stellar_on_sapp.so") +add_test(NAME UPDATE_PLUG_SO COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/src/${DECODER_NAME}/${DECODER_NAME}.so ${TEST_RUN_DIR}/stellar_plugin/${DECODER_NAME}.so") +add_test(NAME UPDATE_TEST_SO COMMAND sh -c "cp ${CMAKE_CURRENT_BINARY_DIR}/${DECODER_NAME}_test.so ${TEST_RUN_DIR}/stellar_plugin/${DECODER_NAME}_test.so") + +set_tests_properties(INSTALL_TEST_MAIN COPY_TEST_MAIN COPY_CONF COPY_SPEC COPY_CONFLIST COPY_INF + UPDATE_SAPP_LOG UPDATE_SAPP_SYN_MODE UPDATE_SAPP_REORDER + UPDATE_STELLAR_ON_SAPP_SO UPDATE_PLUG_SO UPDATE_TEST_SO + PROPERTIES FIXTURES_SETUP TestFixture) + +# run tests +add_test(NAME DNS_UDP_SIMPLE_TEST COMMAND ${TEST_MAIN} ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/dns_udp_simple.json + -f "find ${CMAKE_CURRENT_SOURCE_DIR}/dns_pcap/ -name dns_udp_simple.pcap|sort -V" WORKING_DIRECTORY ${TEST_RUN_DIR}) + +add_test(NAME DNS_TCP_SIMPLE_TEST COMMAND ${TEST_MAIN} ${CMAKE_CURRENT_SOURCE_DIR}/test_result_json/dns_tcp_simple.json + -f "find ${CMAKE_CURRENT_SOURCE_DIR}/dns_pcap/ -name dns_tcp_simple.pcap|sort -V" WORKING_DIRECTORY ${TEST_RUN_DIR}) + +set_tests_properties(DNS_UDP_SIMPLE_TEST + DNS_TCP_SIMPLE_TEST + PROPERTIES FIXTURES_REQUIRED TestFixture)
\ No newline at end of file diff --git a/test/dns_decoder/dns_decoder_gtest.cpp b/test/dns_decoder/dns_decoder_gtest.cpp new file mode 100644 index 0000000..6e3a9c4 --- /dev/null +++ b/test/dns_decoder/dns_decoder_gtest.cpp @@ -0,0 +1,280 @@ +/* +********************************************************************************************** +* File: dns_decoder_gtest.cpp +* Description: +* Authors: Liu WenTan <[email protected]> +* Date: 2023-12-15 +* Copyright: (c) Since 2023 Geedge Networks, Ltd. All rights reserved. +*********************************************************************************************** +*/ + +#include <stdio.h> +#include <time.h> +#include <unistd.h> +#include <assert.h> +#include <string.h> +#include <arpa/inet.h> + +#include "../../src/dns_decoder/dns_decoder.h" + +#ifdef __cplusplus +extern "C" +{ + +#include "cJSON.h" + +#include "stellar/utils.h" +#include "stellar/stellar.h" +#include "stellar/session_exdata.h" +#include "stellar/session_mq.h" + +int commit_test_result_json(cJSON *node, const char *name); +} +#endif + +#define DD_IPV4 4 +#define DD_IPV6 6 + +#define MAX_KEY_STR_LEN 2048 + +static int g_result_count = 1; +int g_topic_id = 0; + +typedef void rr_printer_fn(uint8_t *in_data, size_t in_data_len, + char *out_data, size_t out_data_len); + +struct rr_printer { + int rr_type; + rr_printer_fn *fn; +}; + +void print_rr_a(uint8_t *in_data, size_t in_data_len, + char *out_data, size_t out_data_len) +{ + inet_ntop(AF_INET, in_data, out_data, out_data_len); +} + +void print_rr_aaaa(uint8_t *in_data, size_t in_data_len, + char *out_data, size_t out_data_len) +{ + inet_ntop(AF_INET6, in_data, out_data, out_data_len); +} + +void print_rr_str(uint8_t *in_data, size_t in_data_len, + char *out_data, size_t out_data_len) +{ + memcpy(out_data, in_data, out_data_len); +} + +void print_rr_soa(uint8_t *in_data, size_t in_data_len, + char *out_data, size_t out_data_len) +{ + memcpy(out_data, in_data, out_data_len); +} + +struct rr_printer rr_printers[] = { + {-1, NULL}, + {DNS_RR_TYPE_A, print_rr_a}, + {DNS_RR_TYPE_NS, print_rr_str}, + {DNS_RR_TYPE_MD, NULL}, + {DNS_RR_TYPE_MF, NULL}, + {DNS_RR_TYPE_CNAME, NULL}, + {DNS_RR_TYPE_SOA, print_rr_soa}, + {DNS_RR_TYPE_MB, NULL}, + {DNS_RR_TYPE_MG, NULL}, + {DNS_RR_TYPE_MR, NULL}, + {DNS_RR_TYPE_NULL, NULL}, + {DNS_RR_TYPE_WKS, NULL}, + {DNS_RR_TYPE_PTR, NULL}, + {DNS_RR_TYPE_HINFO, NULL}, + {DNS_RR_TYPE_MINFO, NULL}, + {DNS_RR_TYPE_MX, print_rr_str}, + {DNS_RR_TYPE_AAAA, print_rr_aaaa} +}; + +static int +dns_field_to_json(cJSON *object, const char *key, char *val, size_t val_len) +{ + if (NULL == object || NULL == key || NULL == val || 0 == val_len) { + return -1; + } + + char *tmp = CALLOC(char, val_len + 1); + memcpy(tmp, val, val_len); + cJSON_AddStringToObject(object, key, tmp); + FREE(tmp); + + return 0; +} + +static void dns_query_to_json(cJSON *ctx, struct dns_query *query) +{ + char buff[64] = {0}; + sprintf(buff, "%x", query->transaction_id); + dns_field_to_json(ctx, "transaction_id", buff, strlen(buff)); + + memset(buff, 0, sizeof(buff)); + sprintf(buff, "%s", "query"); + dns_field_to_json(ctx, "dns_type", buff, strlen(buff)); + + memset(buff, 0, sizeof(buff)); + sprintf(buff, "%s", query->query_question.qname); + dns_field_to_json(ctx, "qname", buff, strlen(buff)); +} + +static void rr_data_to_buff(struct dns_rr *dns_rr, char *buff, size_t buff_len) +{ + char tmp_buff[1024] = {0}; + + switch (dns_rr->type) { + case DNS_RR_TYPE_CNAME: + memcpy(buff, dns_rr->rdata.cname, buff_len); + break; + case DNS_RR_TYPE_HINFO: + sprintf(tmp_buff, "%c%c%s%s", dns_rr->rdata.hinfo.os_len, + dns_rr->rdata.hinfo.cpu_len, dns_rr->rdata.hinfo.cpu, + dns_rr->rdata.hinfo.os); + memcpy(buff, tmp_buff, buff_len); + break; + case DNS_RR_TYPE_MB: + memcpy(buff, dns_rr->rdata.mb, buff_len); + break; + case DNS_RR_TYPE_MD: + memcpy(buff, dns_rr->rdata.md, buff_len); + break; + case DNS_RR_TYPE_MF: + memcpy(buff, dns_rr->rdata.mf, buff_len); + break; + case DNS_RR_TYPE_MG: + memcpy(buff, dns_rr->rdata.mg, buff_len); + break; + case DNS_RR_TYPE_MR: + memcpy(buff, dns_rr->rdata.mr, buff_len); + break; + case DNS_RR_TYPE_NS: + memcpy(buff, dns_rr->rdata.ns, buff_len); + break; + case DNS_RR_TYPE_MINFO: + sprintf(tmp_buff, "%s%s", dns_rr->rdata.minfo.rmailbx, + dns_rr->rdata.minfo.emailbx); + memcpy(buff, tmp_buff, buff_len); + break; + case DNS_RR_TYPE_SOA: + sprintf(tmp_buff, "%s%s%u%u%u%u%u", dns_rr->rdata.soa.mname, + dns_rr->rdata.soa.rname, dns_rr->rdata.soa.serial, + dns_rr->rdata.soa.refresh, dns_rr->rdata.soa.retry, + dns_rr->rdata.soa.expire, dns_rr->rdata.soa.minimum); + memcpy(buff, tmp_buff, buff_len); + break; + case DNS_RR_TYPE_A: + inet_ntop(AF_INET, dns_rr->rdata.a, tmp_buff, 1024); + memcpy(buff, tmp_buff, strlen(tmp_buff)); + break; + } +} + +static void dns_response_to_json(cJSON *ctx, struct dns_response *response) +{ + char key[64] = {0}; + char buff[64] = {0}; + + sprintf(buff, "%s", "response"); + dns_field_to_json(ctx, "dns_type", buff, strlen(buff)); + + size_t printer_num = sizeof(rr_printers) / sizeof(struct rr_printer); + + for (size_t i = 0; i < response->n_answer_rr; i++) { + memset(key, 0, sizeof(key)); + memset(buff, 0, sizeof(buff)); + + sprintf(key, "ans_rr%zu", i); + rr_data_to_buff(&response->answer_rr[i], buff, sizeof(buff)); + dns_field_to_json(ctx, key, buff, sizeof(buff)); + } + + for (size_t i = 0; i < response->n_authority_rr; i++) { + memset(key, 0, sizeof(key)); + memset(buff, 0, sizeof(buff)); + + sprintf(key, "auth_rr%zu", i); + rr_data_to_buff(&response->authority_rr[i], buff, sizeof(buff)); + dns_field_to_json(ctx, key, buff, strlen(buff)); + } + + for (size_t i = 0; i < response->n_additional_rr; i++) { + memset(key, 0, sizeof(key)); + memset(buff, 0, sizeof(buff)); + + sprintf(key, "addt_rr%zu", i); + rr_data_to_buff(&response->additional_rr[i], buff, sizeof(buff)); + dns_field_to_json(ctx, key, buff, strlen(buff)); + } +} + +static int +dns_decoder_test_entry(struct session *sess, int topic_id, const void *data, + void *cb_arg) +{ + int exdata_idx = 0; + struct dns_message *msg = (struct dns_message *)data; + + cJSON *json = cJSON_CreateObject(); + cJSON_AddStringToObject(json, "Tuple4", session_get0_readable_addr(sess)); + + enum dns_message_type type = dns_message_type(msg); + struct dns_query query; + struct dns_response response; + + switch (type) { + case DNS_MESSAGE_QUERY: + dns_message_get_query(msg, &query); + dns_query_to_json(json, &query); + break; + case DNS_MESSAGE_RESPONSE: + dns_message_get_response(msg, &response); + dns_response_to_json(json, &response); + break; + default: + break; + } + + char result_name[MAX_KEY_STR_LEN] = {0}; + sprintf(result_name, "DNS_DECODER_RESULT_%d", g_result_count); + commit_test_result_json(json, result_name); + g_result_count++; + + return 0; +} + +static void +dns_decoder_test_exdata_free(struct session *sess, int idx, void *ex_ptr, void *arg) +{ + if (ex_ptr != NULL) { + cJSON_Delete((cJSON *)ex_ptr); + } +} + +extern "C" void *dns_decoder_test_init(struct stellar *st) +{ + g_topic_id = session_mq_get_topic_id(st, "DNS_DECODER_MESSAGE"); + if (g_topic_id < 0) { + printf("[%s:%d]: can't get dns_decoder topic id !!!\n", + __FUNCTION__, __LINE__); + exit(-1); + } + + session_mq_subscribe_topic(st, g_topic_id, dns_decoder_test_entry, NULL); + printf("dns_decoder_test_init OK!\n"); + + return NULL; + +} + +extern "C" void dns_decoder_test_exit(void *test_ctx) +{ + if (test_ctx != NULL) { + FREE(test_ctx); + } + + printf("dns_decoder_test_exit OK!\n"); +}
\ No newline at end of file diff --git a/test/dns_decoder/dns_pcap/dns_tcp_simple.pcap b/test/dns_decoder/dns_pcap/dns_tcp_simple.pcap Binary files differnew file mode 100644 index 0000000..c1ff33a --- /dev/null +++ b/test/dns_decoder/dns_pcap/dns_tcp_simple.pcap diff --git a/test/dns_decoder/dns_pcap/dns_udp_simple.pcap b/test/dns_decoder/dns_pcap/dns_udp_simple.pcap Binary files differnew file mode 100644 index 0000000..95ac41d --- /dev/null +++ b/test/dns_decoder/dns_pcap/dns_udp_simple.pcap diff --git a/test/dns_decoder/test_env/conflist.inf b/test/dns_decoder/test_env/conflist.inf new file mode 100644 index 0000000..2e8144d --- /dev/null +++ b/test/dns_decoder/test_env/conflist.inf @@ -0,0 +1,9 @@ +[platform] +./plug/stellar_on_sapp/start_loader.inf + + +[protocol] + + +[business] +#./plug/stellar_on_sapp/defer_loader.inf diff --git a/test/dns_decoder/test_env/sapp4.el8.x86_64.rpm b/test/dns_decoder/test_env/sapp4.el8.x86_64.rpm Binary files differnew file mode 100644 index 0000000..e43fe2f --- /dev/null +++ b/test/dns_decoder/test_env/sapp4.el8.x86_64.rpm diff --git a/test/dns_decoder/test_env/spec.toml b/test/dns_decoder/test_env/spec.toml new file mode 100644 index 0000000..5b90d1d --- /dev/null +++ b/test/dns_decoder/test_env/spec.toml @@ -0,0 +1,12 @@ +# stellar_plugin.toml +# + +[[plugin]] +path = "./stellar_plugin/dns_decoder.so" +init = "dns_decoder_init" +exit = "dns_decoder_exit" + +[[plugin]] +path = "./stellar_plugin/dns_decoder_test.so" +init = "dns_decoder_test_init" +exit = "dns_decoder_test_exit"
\ No newline at end of file diff --git a/test/dns_decoder/test_env/start_loader.inf b/test/dns_decoder/test_env/start_loader.inf new file mode 100644 index 0000000..89b2f94 --- /dev/null +++ b/test/dns_decoder/test_env/start_loader.inf @@ -0,0 +1,17 @@ +[PLUGINFO] +PLUGNAME=stellar_start_loader +SO_PATH=./plug/stellar_on_sapp/stellar_on_sapp.so +INIT_FUNC=STELLAR_START_LOADER_INIT +DESTROY_FUNC=STELLAR_START_LOADER_EXIT + +#[TCP_ALL] +#FUNC_FLAG=ALL +#FUNC_NAME=stellar_on_sapp_tcpall_entry + +[TCP] +FUNC_FLAG=ALL +FUNC_NAME=stellar_on_sapp_tcp_entry + +[UDP] +FUNC_FLAG=ALL +FUNC_NAME=stellar_on_sapp_udp_entry
\ No newline at end of file diff --git a/test/dns_decoder/test_env/tsg_l7_protocol.conf b/test/dns_decoder/test_env/tsg_l7_protocol.conf new file mode 100644 index 0000000..1075a8f --- /dev/null +++ b/test/dns_decoder/test_env/tsg_l7_protocol.conf @@ -0,0 +1,57 @@ +#TYPE:1:UCHAR,2:USHORT,3:USTRING,4:ULOG,5:USTRING,6:FILE,7:UBASE64,8:PACKET +#TYPE FIELD VALUE +STRING UNCATEGORIZED 8000 +#STRING UNCATEGORIZED 8001 +#STRING UNKNOWN_OTHER 8002 +STRING DNS 32 +STRING FTP 45 +STRING FTPS 751 +STRING HTTP 67 +STRING HTTPS 68 +STRING ICMP 70 +STRING IKE 8003 +STRING MAIL 8004 +STRING IMAP 75 +STRING IMAPS 76 +STRING IPSEC 85 +STRING XMPP 94 +STRING L2TP 98 +STRING NTP 137 +STRING POP3 147 +STRING POP3S 148 +STRING PPTP 153 +STRING QUIC 2521 +STRING SIP 182 +STRING SMB 185 +STRING SMTP 186 +STRING SMTPS 187 +STRING SPDY 1469 +STRING SSH 198 +STRING SSL 199 +STRING SOCKS 8005 +STRING TELNET 209 +STRING DHCP 29 +STRING RADIUS 158 +STRING OPENVPN 336 +STRING STUN 201 +STRING TEREDO 555 +STRING DTLS 1291 +STRING DoH 8006 +STRING ISAKMP 92 +STRING MDNS 3835 +STRING NETBIOS 129 +STRING NETFLOW 130 +STRING RDP 150 +STRING RTCP 174 +STRING RTP 175 +STRING SLP 8007 +STRING SNMP 190 +STRING SSDP 197 +STRING TFTP 211 +STRING BJNP 2481 +STRING LDAP 100 +STRING RTMP 337 +STRING RTSP 176 +STRING ESNI 8008 +STRING QQ 156 +STRING WeChat 1296 diff --git a/test/dns_decoder/test_result_json/dns_tcp_simple.json b/test/dns_decoder/test_result_json/dns_tcp_simple.json new file mode 100644 index 0000000..5271b83 --- /dev/null +++ b/test/dns_decoder/test_result_json/dns_tcp_simple.json @@ -0,0 +1,58 @@ +[ + { + "Tuple4": "10.180.156.141.49342>10.2.95.39.53", + "transaction_id": "5e63", + "dns_type": "query", + "qname": "google.com", + "name": "DNS_DECODER_RESULT_1" + }, + { + "Tuple4": "10.180.156.141.49342>10.2.95.39.53", + "dns_type": "response", + "ans_rr0": "74.125.228.46", + "ans_rr1": "74.125.228.32", + "ans_rr2": "74.125.228.33", + "ans_rr3": "74.125.228.34", + "ans_rr4": "74.125.228.35", + "ans_rr5": "74.125.228.36", + "ans_rr6": "74.125.228.37", + "ans_rr7": "74.125.228.38", + "ans_rr8": "74.125.228.39", + "ans_rr9": "74.125.228.40", + "ans_rr10": "74.125.228.41", + "auth_rr0": "ns4.google.com", + "auth_rr1": "ns2.google.com", + "auth_rr2": "ns3.google.com", + "auth_rr3": "ns1.google.com", + "addt_rr0": "216.239.32.10", + "addt_rr1": "216.239.36.10", + "addt_rr2": "216.239.38.10", + "addt_rr3": "216.239.34.10", + "name": "DNS_DECODER_RESULT_2" + }, + { + "Tuple4": "10.180.156.141.49343>10.2.95.39.53", + "transaction_id": "e2ec", + "dns_type": "query", + "qname": "aol.com", + "name": "DNS_DECODER_RESULT_3" + }, + { + "Tuple4": "10.180.156.141.49343>10.2.95.39.53", + "dns_type": "response", + "ans_rr0": "205.188.100.58", + "ans_rr1": "205.188.101.58", + "ans_rr2": "207.200.74.38", + "ans_rr3": "64.12.79.57", + "ans_rr4": "64.12.89.186", + "auth_rr0": "dns-01.ns.aol.com", + "auth_rr1": "dns-02.ns.aol.com", + "auth_rr2": "dns-06.ns.aol.com", + "auth_rr3": "dns-07.ns.aol.com", + "addt_rr0": "64.236.1.107", + "addt_rr1": "207.200.73.80", + "addt_rr2": "64.12.51.132", + "addt_rr3": "205.188.157.232", + "name": "DNS_DECODER_RESULT_4" + } +]
\ No newline at end of file diff --git a/test/dns_decoder/test_result_json/dns_udp_simple.json b/test/dns_decoder/test_result_json/dns_udp_simple.json new file mode 100644 index 0000000..232785c --- /dev/null +++ b/test/dns_decoder/test_result_json/dns_udp_simple.json @@ -0,0 +1,25 @@ +[ + { + "Tuple4": "192.168.1.52.54585>8.8.8.8.53", + "transaction_id": "3", + "dns_type": "query", + "qname": "google.com", + "name": "DNS_DECODER_RESULT_1" + }, + { + "Tuple4": "192.168.1.52.54585>8.8.8.8.53", + "dns_type": "response", + "ans_rr0": "74.125.236.35", + "ans_rr1": "74.125.236.37", + "ans_rr2": "74.125.236.39", + "ans_rr3": "74.125.236.32", + "ans_rr4": "74.125.236.40", + "ans_rr5": "74.125.236.33", + "ans_rr6": "74.125.236.41", + "ans_rr7": "74.125.236.34", + "ans_rr8": "74.125.236.36", + "ans_rr9": "74.125.236.46", + "ans_rr10": "74.125.236.38", + "name": "DNS_DECODER_RESULT_2" + } +]
\ No newline at end of file diff --git a/test/http_decoder/test_env/spec.toml b/test/http_decoder/test_env/spec.toml index 626f85b..b8c7eb9 100644 --- a/test/http_decoder/test_env/spec.toml +++ b/test/http_decoder/test_env/spec.toml @@ -8,4 +8,4 @@ exit = "http_decoder_exit" [[plugin]] path = "./stellar_plugin/http_decoder_test.so" init = "http_decoder_test_init" -exit = "http_decoder_test_exit" +exit = "http_decoder_test_exit"
\ No newline at end of file |
