TSG-1531 TFE 新增 DOH 插件
1.DOH 协议解析 2.DOH 协议还原 3.DOH POST请求 early response 4.DOH 策略扫描 5.tfe plugin 支持多个 bussiness 插件调用 6.Maat_feather 的创建从 pangu 剥离(涉及pangu/doh/ssl-policy) 7.增加 kafka 日志 8.增加测试用例
This commit is contained in:
898
plugin/business/doh/test/dns_test.cpp
Normal file
898
plugin/business/doh/test/dns_test.cpp
Normal file
@@ -0,0 +1,898 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../src/pub.h"
|
||||
#include "../src/dns.h"
|
||||
|
||||
#define ERROR(str) \
|
||||
{ \
|
||||
printf(str); \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int len;
|
||||
const char *data;
|
||||
} str_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *desc;
|
||||
str_t req;
|
||||
str_t rsp;
|
||||
} package_t;
|
||||
|
||||
static package_t package_arry[] = {
|
||||
{
|
||||
"dig @127.0.0.1 www.baidu.com a",
|
||||
{56, "TDwBIAABAAAAAAABA3d3dwViYWlkdQNjb20AAAEAAQAAKRAAAAAAAAAA"},
|
||||
{136, "TDyBgAABAAMAAAABA3d3dwViYWlkdQNjb20AAAEAAcAMAAUAAQAAACoADwN3d3cBYQZzaGlmZW7AFsArAAEAAQAAACoABLY9yAfAKwABAAEAAAAqAAS2PcgGAAApEAAAAAAAAAA="},
|
||||
},
|
||||
{
|
||||
"dig @127.0.0.1 baidu.com ns",
|
||||
{52, "M00BIAABAAAAAAABBWJhaWR1A2NvbQAAAgABAAApEAAAAAAAAAA="},
|
||||
{172, "M02BgAABAAUAAAABBWJhaWR1A2NvbQAAAgABwAwAAgABAAAcJwAGA25zNMAMwAwAAgABAAAcJwAGA25zMsAMwAwAAgABAAAcJwAGA25zN8AMwAwAAgABAAAcJwAGA2Ruc8AMwAwAAgABAAAcJwAGA25zM8AMAAApEAAAAAAAAAA="},
|
||||
},
|
||||
{
|
||||
"dig @127.0.0.1 www.baidu.com cname",
|
||||
{56, "LAMBIAABAAAAAAABA3d3dwViYWlkdQNjb20AAAUAAQAAKRAAAAAAAAAA"},
|
||||
{92, "LAOBgAABAAEAAAABA3d3dwViYWlkdQNjb20AAAUAAcAMAAUAAQAAAGYADwN3d3cBYQZzaGlmZW7AFgAAKRAAAAAAAAAA"},
|
||||
},
|
||||
{
|
||||
"dig @127.0.0.1 www.baidu.com soa",
|
||||
{56, "9D8BIAABAAAAAAABA3d3dwViYWlkdQNjb20AAAYAAQAAKRAAAAAAAAAA"},
|
||||
{168, "9D+BgAABAAEAAQABA3d3dwViYWlkdQNjb20AAAYAAcAMAAUAAQAAAhcADwN3d3cBYQZzaGlmZW7AFsAvAAYAAQAAAmIALQNuczHALxBiYWlkdV9kbnNfbWFzdGVywBB3hAIjAAAABQAAAAUAJ40AAAAOEAAAKRAAAAAAAAAA"},
|
||||
},
|
||||
{
|
||||
"dig @127.0.0.1 -x 192.30.252.153",
|
||||
{76, "G+4BIAABAAAAAAABAzE1MwMyNTICMzADMTkyB2luLWFkZHIEYXJwYQAADAABAAApEAAAAAAAAAA="},
|
||||
{136, "G+6BgAABAAEAAAABAzE1MwMyNTICMzADMTkyB2luLWFkZHIEYXJwYQAADAABwAwADAABAAAOEAAiFWxiLTE5Mi0zMC0yNTItMTUzLWlhZAZnaXRodWIDY29tAAAAKRAAAAAAAAAA"},
|
||||
},
|
||||
{
|
||||
"dig @127.0.0.1 163.com mx",
|
||||
{48, "iRMBIAABAAAAAAABAzE2MwNjb20AAA8AAQAAKRAAAAAAAAAA"},
|
||||
{196, "iROBgAABAAQAAAABAzE2MwNjb20AAA8AAcAMAA8AAQAADnQAGwAKBzE2M214MDEGbXhtYWlsB25ldGVhc2XAEMAMAA8AAQAADnQADAAyBzE2M214MDDAL8AMAA8AAQAADnQADAAKBzE2M214MDPAL8AMAA8AAQAADnQADAAKBzE2M214MDLALwAAKRAAAAAAAAAA"},
|
||||
},
|
||||
{
|
||||
"dig @127.0.0.1 baidu.com txt",
|
||||
{52, "A6kBIAABAAAAAAABBWJhaWR1A2NvbQAAEAABAAApEAAAAAAAAAA="},
|
||||
{296, "A6mBgAABAAIAAAABBWJhaWR1A2NvbQAAEAABwAwAEAABAAAIKgBFRGdvb2dsZS1zaXRlLXZlcmlmaWNhdGlvbj1HSGI5OC02bXNxeXhfcXFqR2w1ZVJhdEQzUVRIeVZCNi14UTNnSkI1VXdNwAwAEAABAAAIKgBaWXY9c3BmMSBpbmNsdWRlOnNwZjEuYmFpZHUuY29tIGluY2x1ZGU6c3BmMi5iYWlkdS5jb20gaW5jbHVkZTpzcGYzLmJhaWR1LmNvbSBhIG14IHB0ciAtYWxsAAApEAAAAAAAAAA="},
|
||||
},
|
||||
{
|
||||
"dig @127.0.0.1 www.taobao.com aaaa",
|
||||
{60, "0qQBIAABAAAAAAABA3d3dwZ0YW9iYW8DY29tAAAcAAEAACkQAAAAAAAAAA=="},
|
||||
{640, "0qSBgAABAA8AAAABA3d3dwZ0YW9iYW8DY29tAAAcAAHADAAFAAEAAAG2ACEDd3d3BnRhb2JhbwNjb20HZGFudW95aQd0YmNhY2hlwBfALAAcAAEAAAA8ABAkDgCxmAEEAAADAAAAAAP5wCwAHAABAAAAPAAQJA4AsZgBBAkAAwAAAAAD+cAsABwAAQAAADwAECQOALGYAQQAAAMAAAAAA/rALAAcAAEAAAA8ABAkDglA4AEAAQADAAAAAAP5wCwAHAABAAAAPAAQJA4AsZgBBAgAAwAAAAAD+sAsABwAAQAAADwAECQOCUDgAQABAAMAAAAAA/rALAAcAAEAAAA8ABAkDglA4AEABQADAAAAAAP5wCwAHAABAAAAPAAQJA4AsaggAAAAAwAAAAAD9cAsABwAAQAAADwAECQOALGoIAAAAAMAAAAAA/bALAAcAAEAAAA8ABAkDgCxmAEECQADAAAAAAP6wCwAHAABAAAAPAAQJA4JQOABAAQAAwAAAAAD+cAsABwAAQAAADwAECQOCUDgAQAEAAMAAAAAA/rALAAcAAEAAAA8ABAkDgCxmAEECAADAAAAAAP5wCwAHAABAAAAPAAQJA4JQOABAAUAAwAAAAAD+gAAKRAAAAAAAAAA"},
|
||||
},
|
||||
{
|
||||
"dig @127.0.0.1 com ds",
|
||||
{44, "94UBIAABAAAAAAABA2NvbQAAKwABAAApEAAAAAAAAAA="},
|
||||
{108, "94WBgAABAAEAAAABA2NvbQAAKwABwAwAKwABAAB/zgAkeL0IAuLTyRb23urHMpToJo+1iFBEqDP8VFlYj0qRhM/EGldmAAApEAAAAAAAAAA="},
|
||||
},
|
||||
{
|
||||
"dig @127.0.0.1 com rrsig",
|
||||
{44, "ETMBIAABAAAAAAABA2NvbQAALgABAAApEAAAAAAAAAA="},
|
||||
{948, "ETOBgAABAAMAAAABA2NvbQAALgABwAwALgABAAABjgC3AAYIAQAAA4RexfcOXrysJpukA2NvbQAJCiOw6MPHup5mJVrn65fULwvBJoy5mR1IYTJSEzv7PXsT+B/3lp+5Gnfds89MvligsnUWkQvOUiCOkY5ahPwO5fQSB4dDPZJXahG44IR2QtNDHLfFNxcRROwdLmmSe9F+sU5ZL4YtmXu4+trwUycbo34f19o3xRS5D6UBV1clWPp0yK9rQafhMY5UBIZz83txHKumVVjwlnsA2d7w1Qi7wDMALgABAAEBrwETACsIAQABUYBezYNQXrxRwL8HAF4VVK323NSvS//r44sD6QQDSa9aNBCPlimQWZUbjmAh2Z/RkwTAuK0T3ngOw5flW8rHaopbNfIQ4UZSNqzcbzXtJ/F2u2DG4/Xo26LRbF1jHBZOGChGMeug4kVVepPuQvxEoSBUY9FgdGXMZ551kxO/xf3kK6xMhmjQjOQn1xJzZEGtcqV+5pKymT4MNdfPdhpJIDQRnN33bvk8su7wPiaJmGsKGdGHBKlsyMJgLCoJrMvSQIEiQj560Rwy1n1qq3Mlk6CkydQ62mZp2u32d4wBTE3UTs+aDBRfTSQmg6Dofh9x2DJgK5mFISt7rYgvacxpRfqBkD4tDdKUQlrszbjAMwAuAAEAAk6gALcAAggBAAKjAF7AwkJet3dam6QDY29tAJK2SHQgAOJ0UOxt+9f55rJHx5vzvSuuuTsaM06kaK8zhK6Xo0IRqWtu12EHehn3UiPoTGEdUK/KK2ZXmdb8yJ/H+L4BRG9AafN7xaHPAf4GbXr0pV4yOl+HoTEstZmL3JgXHPFMRLl66UYbNGBDFE6B1f1MNZlBvk6c3NjeMSN29DOIZRoajZlDKv3IRhOrRJghwLr5vhlODIwm58lTbI0AACkQAAAAAAAAAA=="},
|
||||
},
|
||||
{
|
||||
"dig @127.0.0.1 com dnskey",
|
||||
{44, "FJwBIAABAAAAAAABA2NvbQAAMAABAAApEAAAAAAAAAA="},
|
||||
{648, "FJyBgAABAAIAAAABA2NvbQAAMAABwAwAMAABAAAL5wEGAQEDCAEDw85XTZjL2RV+DXDSdLhJyg4O7Zr/xdzMkEdJaQZlXDXLCLM8TRcbAXyjVvSWAmKqYpPN+uixO1WyHDUc36dofTjvB0Zfh/hNPM2rivJO3r1hJrv+qHftm6IID6IhHxjcrzT2kiOxTiK6A7J8P7WoIMx0V9We0jojoj1jzSMElMljme/VZnENRi5AujZWLxtx8GJsp0L+qBcBr/yhC0sO2Una200NB172W6jFCOwWjLJJr4JtRu6CmdWIhezvYqFTXNPuwEm6pmTe2ffBBlP0IdivwYFHvB7NF1XHTyq7cmJ6EB3dspyj3DDJUxIodv9hwx40TydmssCKSjZ7+KD6P8AMADAAAQAAC+cAqAEAAwgDAQABtsVzV+OQEJLJyG3tqH155FqW2csMraxXKjGSMLrMHOb/lIaB8Mb8fpcS6lPty2AK+ep7FqKdMh9ryecFgI60B5zsZ3W9voT/dJeSCINoxQleZ23wTuhu1VmqMWU3ZA2dOWN8yIQKfXqtleW9ciLbnlPXAWRa2nn4tQKK5+wtN4pz3FtDDvLS5yxH4YrPjIRK1tiL3x+cHmc7PNaFFRyV/QAAKRAAAAAAAAAA"},
|
||||
},
|
||||
{
|
||||
"dig @127.0.0.1 com nsec3param",
|
||||
{44, "s48BIAABAAAAAAABA2NvbQAAMwABAAApEAAAAAAAAAA="},
|
||||
{68, "s4+BgAABAAEAAAABA2NvbQAAMwABwAwAMwABAABFmwAFAQAAAAAAACkQAAAAAAAAAA=="},
|
||||
},
|
||||
{
|
||||
"dig @127.0.0.1 _sip._udp.sip.voice.google.com srv",
|
||||
{80, "9OoBIAABAAAAAAABBF9zaXAEX3VkcANzaXAFdm9pY2UGZ29vZ2xlA2NvbQAAIQABAAApEAAAAAAAAAA="},
|
||||
{212, "9OqBgAABAAIAAAABBF9zaXAEX3VkcANzaXAFdm9pY2UGZ29vZ2xlA2NvbQAAIQABwAwAIQABAAAAxAAmAAoAARPEDXNpcC1hbnljYXN0LTEFdm9pY2UGZ29vZ2xlA2NvbQDADAAhAAEAAADEACYAFAABE8QNc2lwLWFueWNhc3QtMgV2b2ljZQZnb29nbGUDY29tAAAAKRAAAAAAAAAA"},
|
||||
},
|
||||
{
|
||||
"dig @127.0.0.1 . nsec",
|
||||
{40, "3HUBIAABAAAAAAABAAAvAAEAACkQAAAAAAAAAA=="},
|
||||
{72, "3HWBgAABAAEAAAABAAAvAAEAAC8AAQABUSUADgNhYWEAAAciAAAAAAOAAAApEAAAAAAAAAA="},
|
||||
}};
|
||||
|
||||
static int package_arry_size = sizeof(package_arry) / sizeof(package_t);
|
||||
|
||||
static int dns_print(dns_info_t *dns_info, const char *filename)
|
||||
{
|
||||
int i = 0, j = 0;
|
||||
int used_len = 0, len = 0;
|
||||
FILE *fp = NULL;
|
||||
char dns_header[256];
|
||||
char question[1024];
|
||||
char rr_buf[4096];
|
||||
char ip_str[128];
|
||||
char tmp_buf[2048];
|
||||
char maps[2048];
|
||||
char salt_value[2048];
|
||||
dns_rr_t *dns_rr = NULL;
|
||||
char *buf = NULL;
|
||||
int buflen = sizeof(rr_buf);
|
||||
buf = rr_buf;
|
||||
cJSON *dns_info_object = cJSON_CreateObject();
|
||||
cJSON *dns_hdr_object = cJSON_CreateObject();
|
||||
cJSON *dns_flags_object = cJSON_CreateObject();
|
||||
cJSON *dns_question_array = cJSON_CreateArray();
|
||||
cJSON *dns_rr_array = cJSON_CreateArray();
|
||||
|
||||
memset(dns_header, 0, sizeof(dns_header));
|
||||
|
||||
fp = fopen(filename, "a+");
|
||||
if (fp == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
used_len = snprintf(dns_header, sizeof(dns_header),
|
||||
"hdr_info: <id=0X%02x, QR=%d, OPCODE=%d, AA=%d, TC=%d, RD=%d, RA=%d,Z=%d, RCODE=%d, qdcount=%d, ancount=%d, aucount=%d, adcount=%d>\n",
|
||||
dns_info->hdr_info.id,
|
||||
dns_info->hdr_info.qr,
|
||||
dns_info->hdr_info.opcode,
|
||||
dns_info->hdr_info.aa,
|
||||
dns_info->hdr_info.tc,
|
||||
dns_info->hdr_info.rd,
|
||||
dns_info->hdr_info.ra,
|
||||
dns_info->hdr_info.z,
|
||||
dns_info->hdr_info.rcode,
|
||||
dns_info->hdr_info.qdcount,
|
||||
dns_info->hdr_info.ancount,
|
||||
dns_info->hdr_info.aucount,
|
||||
dns_info->hdr_info.adcount);
|
||||
|
||||
cJSON_AddNumberToObject(dns_hdr_object, "id", dns_info->hdr_info.id);
|
||||
cJSON_AddNumberToObject(dns_hdr_object, "qdcount", dns_info->hdr_info.qdcount);
|
||||
cJSON_AddNumberToObject(dns_hdr_object, "ancount", dns_info->hdr_info.ancount);
|
||||
cJSON_AddNumberToObject(dns_hdr_object, "aucount", dns_info->hdr_info.aucount);
|
||||
cJSON_AddNumberToObject(dns_hdr_object, "adcount", dns_info->hdr_info.adcount);
|
||||
|
||||
cJSON_AddNumberToObject(dns_flags_object, "qr", dns_info->hdr_info.qr);
|
||||
cJSON_AddNumberToObject(dns_flags_object, "opcode", dns_info->hdr_info.opcode);
|
||||
cJSON_AddNumberToObject(dns_flags_object, "aa", dns_info->hdr_info.aa);
|
||||
cJSON_AddNumberToObject(dns_flags_object, "tc", dns_info->hdr_info.tc);
|
||||
cJSON_AddNumberToObject(dns_flags_object, "rd", dns_info->hdr_info.rd);
|
||||
cJSON_AddNumberToObject(dns_flags_object, "ra", dns_info->hdr_info.ra);
|
||||
cJSON_AddNumberToObject(dns_flags_object, "z", dns_info->hdr_info.z);
|
||||
cJSON_AddNumberToObject(dns_flags_object, "rcode", dns_info->hdr_info.rcode);
|
||||
|
||||
fwrite(dns_header, used_len, 1, fp);
|
||||
|
||||
cJSON_AddItemToObject(dns_info_object, "hdr", dns_hdr_object);
|
||||
cJSON_AddItemToObject(dns_info_object, "flags", dns_flags_object);
|
||||
cJSON_AddItemToObject(dns_info_object, "question", dns_question_array);
|
||||
|
||||
used_len = snprintf(question, sizeof(question), "question: <qtype: %d, qclass: %d, qname: %s>\n",
|
||||
dns_info->query_question.qtype,
|
||||
dns_info->query_question.qclass,
|
||||
dns_info->query_question.qname);
|
||||
|
||||
cJSON *dns_question_object = cJSON_CreateObject();
|
||||
cJSON_AddItemToArray(dns_question_array, dns_question_object);
|
||||
|
||||
cJSON_AddNumberToObject(dns_question_object, "qtype", dns_info->query_question.qtype);
|
||||
cJSON_AddNumberToObject(dns_question_object, "qclass", dns_info->query_question.qclass);
|
||||
cJSON_AddStringToObject(dns_question_object, "qname", (const char *)dns_info->query_question.qname);
|
||||
|
||||
fwrite(question, used_len, 1, fp);
|
||||
|
||||
used_len = snprintf(rr_buf, sizeof(rr_buf), "RRS count: %d\n", dns_info->rr_count);
|
||||
fwrite(rr_buf, used_len, 1, fp);
|
||||
|
||||
cJSON_AddItemToObject(dns_info_object, "rr", dns_rr_array);
|
||||
|
||||
for (i = 0; i < dns_info->rr_count; i++)
|
||||
{
|
||||
cJSON *dns_rr_object = cJSON_CreateObject();
|
||||
cJSON_AddItemToArray(dns_rr_array, dns_rr_object);
|
||||
|
||||
used_len = 0;
|
||||
dns_rr = &(dns_info->rr[i]);
|
||||
memset(rr_buf, 0, sizeof(rr_buf));
|
||||
|
||||
if (dns_rr->type == DNS_TYPE_OPT)
|
||||
{
|
||||
used_len += snprintf(rr_buf, sizeof(rr_buf), "RRS%d OPT <name: %s, type: %d, udp_payload: %d, extended RCODE: %d, version: %d, Z; 0X%x, rdlength: %d>\n",
|
||||
i,
|
||||
dns_rr->name,
|
||||
dns_rr->type,
|
||||
dns_rr->rr_class,
|
||||
dns_rr->ttl >> 24,
|
||||
(dns_rr->ttl >> 16) & 0xFF,
|
||||
dns_rr->ttl && 0xFFFF,
|
||||
dns_rr->rdlength);
|
||||
|
||||
cJSON_AddStringToObject(dns_rr_object, "name", (const char *)(dns_rr->name));
|
||||
cJSON_AddNumberToObject(dns_rr_object, "type", dns_rr->type);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "udp_payload", dns_rr->rr_class);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "rcode", (int)(dns_rr->ttl >> 24));
|
||||
cJSON_AddNumberToObject(dns_rr_object, "version", (int)((dns_rr->ttl >> 16) & 0xFF));
|
||||
cJSON_AddNumberToObject(dns_rr_object, "Z", (int)(dns_rr->ttl && 0xFFFF));
|
||||
cJSON_AddNumberToObject(dns_rr_object, "rdlength", dns_rr->rdlength);
|
||||
}
|
||||
else
|
||||
{
|
||||
used_len += snprintf(rr_buf, sizeof(rr_buf), "RRS%d <name: %s, type: %d, rr_class: %d, ttl: %d, rdlength: %d>",
|
||||
i,
|
||||
dns_rr->name,
|
||||
dns_rr->type,
|
||||
dns_rr->rr_class,
|
||||
dns_rr->ttl,
|
||||
dns_rr->rdlength);
|
||||
|
||||
cJSON_AddStringToObject(dns_rr_object, "name", (const char *)(dns_rr->name));
|
||||
cJSON_AddNumberToObject(dns_rr_object, "type", dns_rr->type);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "class", dns_rr->rr_class);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "ttl", dns_rr->ttl);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "rdlength", dns_rr->rdlength);
|
||||
}
|
||||
|
||||
switch (dns_rr->type)
|
||||
{
|
||||
case DNS_TYPE_A:
|
||||
inet_ntop(AF_INET, (void *)(dns_rr->rdata.a), ip_str, sizeof(ip_str));
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[A: %s]\n", ip_str);
|
||||
cJSON_AddStringToObject(dns_rr_object, "a", ip_str);
|
||||
break;
|
||||
case DNS_TYPE_NS:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[NS: %s]\n", dns_rr->rdata.ns);
|
||||
cJSON_AddStringToObject(dns_rr_object, "ns", (const char *)(dns_rr->rdata.ns));
|
||||
break;
|
||||
case DNS_TYPE_MD:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[MD: %s]\n", dns_rr->rdata.md);
|
||||
cJSON_AddStringToObject(dns_rr_object, "md", (const char *)(dns_rr->rdata.md));
|
||||
break;
|
||||
case DNS_TYPE_MF:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[MF: %s]\n", dns_rr->rdata.mf);
|
||||
cJSON_AddStringToObject(dns_rr_object, "mf", (const char *)(dns_rr->rdata.mf));
|
||||
break;
|
||||
case DNS_TYPE_CNAME:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[CNAME: %s]\n", dns_rr->rdata.cname);
|
||||
cJSON_AddStringToObject(dns_rr_object, "cname", (const char *)(dns_rr->rdata.cname));
|
||||
break;
|
||||
case DNS_TYPE_SOA:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len,
|
||||
"[SOA mname: %s, rname: %s, serial: %u, refresh: %u, retry: %u, expire: %u, minimum: %u]\n",
|
||||
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);
|
||||
|
||||
cJSON_AddStringToObject(dns_rr_object, "mname", (const char *)(dns_rr->rdata.soa.mname));
|
||||
cJSON_AddStringToObject(dns_rr_object, "rname", (const char *)(dns_rr->rdata.soa.rname));
|
||||
cJSON_AddNumberToObject(dns_rr_object, "serial", dns_rr->rdata.soa.serial);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "refresh", dns_rr->rdata.soa.refresh);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "retry", dns_rr->rdata.soa.retry);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "cname", dns_rr->rdata.soa.expire);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "minimum", dns_rr->rdata.soa.minimum);
|
||||
break;
|
||||
case DNS_TYPE_MB:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[MB: %s]\n", dns_rr->rdata.mb);
|
||||
cJSON_AddStringToObject(dns_rr_object, "mb", (const char *)(dns_rr->rdata.mb));
|
||||
break;
|
||||
case DNS_TYPE_MG:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[MG: %s]\n", dns_rr->rdata.mg);
|
||||
cJSON_AddStringToObject(dns_rr_object, "mg", (const char *)(dns_rr->rdata.mg));
|
||||
break;
|
||||
case DNS_TYPE_MR:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[MR: %s]\n", dns_rr->rdata.mr);
|
||||
cJSON_AddStringToObject(dns_rr_object, "mr", (const char *)(dns_rr->rdata.mr));
|
||||
break;
|
||||
case DNS_TYPE_NULL:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[null size: %u, null: %s]\n",
|
||||
dns_rr->rdata.null.size, dns_rr->rdata.null.null);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "size", dns_rr->rdata.null.size);
|
||||
cJSON_AddStringToObject(dns_rr_object, "null", (const char *)(dns_rr->rdata.null.null));
|
||||
break;
|
||||
case DNS_TYPE_WKS:
|
||||
inet_ntop(AF_INET, &(dns_rr->rdata.wks.addr), ip_str, sizeof(ip_str));
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[WKS addr: %s, protocol: %u, bitmap: %s, size: %u]\n",
|
||||
ip_str, dns_rr->rdata.wks.protocol, dns_rr->rdata.wks.bitmap, dns_rr->rdata.wks.size);
|
||||
|
||||
cJSON_AddStringToObject(dns_rr_object, "addr", ip_str);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "protocol", dns_rr->rdata.wks.protocol);
|
||||
cJSON_AddStringToObject(dns_rr_object, "bitmap", (const char *)(dns_rr->rdata.wks.bitmap));
|
||||
cJSON_AddNumberToObject(dns_rr_object, "size", dns_rr->rdata.wks.size);
|
||||
break;
|
||||
case DNS_TYPE_PTR:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[PTR: %s]\n", dns_rr->rdata.ptr);
|
||||
cJSON_AddStringToObject(dns_rr_object, "ptr", (const char *)(dns_rr->rdata.ptr));
|
||||
break;
|
||||
case DNS_TYPE_HINFO:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[HINFO cpu: %s, os: %s]\n",
|
||||
dns_rr->rdata.hinfo.cpu, dns_rr->rdata.hinfo.os);
|
||||
|
||||
cJSON_AddStringToObject(dns_rr_object, "cpu", (const char *)(dns_rr->rdata.hinfo.cpu));
|
||||
cJSON_AddStringToObject(dns_rr_object, "os", (const char *)(dns_rr->rdata.hinfo.os));
|
||||
break;
|
||||
case DNS_TYPE_MINFO:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[MINFO rmailbx: %s, emailbx: %s]\n",
|
||||
dns_rr->rdata.minfo.rmailbx, dns_rr->rdata.minfo.emailbx);
|
||||
|
||||
cJSON_AddStringToObject(dns_rr_object, "rmailbx", (const char *)(dns_rr->rdata.minfo.rmailbx));
|
||||
cJSON_AddStringToObject(dns_rr_object, "emailbx", (const char *)(dns_rr->rdata.minfo.emailbx));
|
||||
break;
|
||||
case DNS_TYPE_MX:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[MX preference: %u, exchange: %s]\n",
|
||||
dns_rr->rdata.mx.preference, dns_rr->rdata.mx.exchange);
|
||||
|
||||
cJSON_AddStringToObject(dns_rr_object, "exchange", (const char *)(dns_rr->rdata.mx.exchange));
|
||||
cJSON_AddNumberToObject(dns_rr_object, "preference", dns_rr->rdata.mx.preference);
|
||||
break;
|
||||
case DNS_TYPE_TXT:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[TXT size: %u, txt: %s]\n",
|
||||
dns_rr->rdata.txt.size, dns_rr->rdata.txt.txt);
|
||||
|
||||
cJSON_AddStringToObject(dns_rr_object, "txt", (const char *)(dns_rr->rdata.txt.txt));
|
||||
cJSON_AddNumberToObject(dns_rr_object, "size", dns_rr->rdata.txt.size);
|
||||
break;
|
||||
case DNS_TYPE_RP:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[mailbox: %s, txt_rr: %s]\n",
|
||||
dns_rr->rdata.rp.mailbox, dns_rr->rdata.rp.txt_rr);
|
||||
|
||||
cJSON_AddStringToObject(dns_rr_object, "mailbox", (const char *)(dns_rr->rdata.rp.mailbox));
|
||||
cJSON_AddStringToObject(dns_rr_object, "txt_rr", (const char *)(dns_rr->rdata.rp.txt_rr));
|
||||
break;
|
||||
case DNS_TYPE_AAAA:
|
||||
inet_ntop(AF_INET6, dns_rr->rdata.aaaa, ip_str, sizeof(ip_str));
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[AAAA: %s]\n", ip_str);
|
||||
cJSON_AddStringToObject(dns_rr_object, "aaaa", ip_str);
|
||||
break;
|
||||
case DNS_TYPE_OPT:
|
||||
break;
|
||||
case DNS_TYPE_DS:
|
||||
len = 0;
|
||||
assert(dns_rr->rdata.ds.digest_len * 2 < sizeof(tmp_buf));
|
||||
for (j = 0; j < (int)(dns_rr->rdata.ds.digest_len); j++)
|
||||
{
|
||||
len += snprintf(tmp_buf + len, sizeof(tmp_buf) - len, "%02x", dns_rr->rdata.ds.digest[j]);
|
||||
}
|
||||
used_len += snprintf(buf + used_len, buflen - used_len,
|
||||
"[DS key_tag: %u, algo: %u, digest_type: %u, digest: %s]\n",
|
||||
dns_rr->rdata.ds.key_tag, dns_rr->rdata.ds.algo,
|
||||
dns_rr->rdata.ds.digest_type, tmp_buf);
|
||||
|
||||
cJSON_AddNumberToObject(dns_rr_object, "key_tag", dns_rr->rdata.ds.key_tag);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "algo", dns_rr->rdata.ds.algo);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "digest_type", dns_rr->rdata.ds.digest_type);
|
||||
cJSON_AddStringToObject(dns_rr_object, "digest", tmp_buf);
|
||||
break;
|
||||
case DNS_TYPE_RRSIG:
|
||||
len = 0;
|
||||
assert(dns_rr->rdata.rrsig.signature_len * 2 < sizeof(tmp_buf));
|
||||
for (j = 0; j < (int)(dns_rr->rdata.rrsig.signature_len); j++)
|
||||
{
|
||||
len += snprintf(tmp_buf + len, sizeof(tmp_buf) - len, "%02x", dns_rr->rdata.rrsig.signature[j]);
|
||||
}
|
||||
used_len += snprintf(buf + used_len, buflen - used_len,
|
||||
"[RRSIG type_covered: %u, algo: %u, labels: %u, original_ttl: %u, sig_expiration: %u, sig_inception: %u, key_tag: %u, signer_name: %s, signature: %s]\n",
|
||||
dns_rr->rdata.rrsig.type_covered, dns_rr->rdata.rrsig.algo,
|
||||
dns_rr->rdata.rrsig.labels, dns_rr->rdata.rrsig.original_ttl,
|
||||
dns_rr->rdata.rrsig.sig_expiration, dns_rr->rdata.rrsig.sig_inception,
|
||||
dns_rr->rdata.rrsig.key_tag, dns_rr->rdata.rrsig.signer_name, tmp_buf);
|
||||
|
||||
cJSON_AddNumberToObject(dns_rr_object, "type_covered", dns_rr->rdata.rrsig.type_covered);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "algo", dns_rr->rdata.rrsig.algo);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "labels", dns_rr->rdata.rrsig.labels);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "original_ttl", dns_rr->rdata.rrsig.original_ttl);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "sig_expiration", dns_rr->rdata.rrsig.sig_expiration);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "sig_inception", dns_rr->rdata.rrsig.sig_inception);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "key_tag", dns_rr->rdata.rrsig.key_tag);
|
||||
cJSON_AddStringToObject(dns_rr_object, "signer_name", (const char *)(dns_rr->rdata.rrsig.signer_name));
|
||||
cJSON_AddStringToObject(dns_rr_object, "signature", tmp_buf);
|
||||
break;
|
||||
case DNS_TYPE_NSEC:
|
||||
len = 0;
|
||||
for (j = 0; j < (int)(dns_rr->rdata.nsec.maps_len); j++)
|
||||
{
|
||||
len += snprintf(maps + len, sizeof(maps) - len, "%02x", dns_rr->rdata.nsec.type_bit_maps[j]);
|
||||
}
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[NSEC next_domain: %s, type_bit_maps: %s]\n", dns_rr->rdata.nsec.next_domain, maps);
|
||||
|
||||
cJSON_AddStringToObject(dns_rr_object, "next_domain", (const char *)(dns_rr->rdata.nsec.next_domain));
|
||||
cJSON_AddStringToObject(dns_rr_object, "type_bit_maps", maps);
|
||||
break;
|
||||
case DNS_TYPE_DNSKEY:
|
||||
len = 0;
|
||||
assert(dns_rr->rdata.dnskey.public_key_len * 2 < sizeof(tmp_buf));
|
||||
for (j = 0; j < (int)(dns_rr->rdata.dnskey.public_key_len); j++)
|
||||
{
|
||||
len += snprintf(tmp_buf + len, sizeof(tmp_buf) - len, "%02x", dns_rr->rdata.dnskey.public_key[j]);
|
||||
}
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[DNSKEY flags: %u, protocol: %u, algo: %u, public_key: %s]\n",
|
||||
dns_rr->rdata.dnskey.flags, dns_rr->rdata.dnskey.protocol, dns_rr->rdata.dnskey.algo, tmp_buf);
|
||||
|
||||
cJSON_AddNumberToObject(dns_rr_object, "flags", dns_rr->rdata.dnskey.flags);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "protocol", dns_rr->rdata.dnskey.protocol);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "algo", dns_rr->rdata.dnskey.algo);
|
||||
cJSON_AddStringToObject(dns_rr_object, "public_key", tmp_buf);
|
||||
break;
|
||||
case DNS_TYPE_NSEC3:
|
||||
memset(tmp_buf, 0, sizeof(tmp_buf));
|
||||
memset(maps, 0, sizeof(maps));
|
||||
len = 0;
|
||||
assert(dns_rr->rdata.nsec3.hash_len * 2 < sizeof(tmp_buf));
|
||||
for (j = 0; j < (int)(dns_rr->rdata.nsec3.hash_len); j++)
|
||||
{
|
||||
len += snprintf(tmp_buf + len, sizeof(tmp_buf) - len, "%02x", dns_rr->rdata.nsec3.next_hash_owner[j]);
|
||||
}
|
||||
len = 0;
|
||||
for (j = 0; j < (int)(dns_rr->rdata.nsec3.maps_len); j++)
|
||||
{
|
||||
len += snprintf(maps + len, sizeof(maps) - len, "%02x", dns_rr->rdata.nsec3.type_bit_maps[j]);
|
||||
}
|
||||
len = 0;
|
||||
for (j = 0; j < (int)(dns_rr->rdata.nsec3.salt_len); j++)
|
||||
{
|
||||
len += snprintf(salt_value + len, sizeof(salt_value) - len, "%02x", dns_rr->rdata.nsec3.salt_value[j]);
|
||||
}
|
||||
|
||||
used_len += snprintf(buf + used_len, buflen - used_len,
|
||||
"[NSEC3 hash_algo: %u, flags: %u, iteration: %u, salt_len: %u, hash_len: %u, salt_value: %s, next_hash_owner: %s, type_bit_maps: %s]\n",
|
||||
dns_rr->rdata.nsec3.hash_algo, dns_rr->rdata.nsec3.flags,
|
||||
dns_rr->rdata.nsec3.iteration, dns_rr->rdata.nsec3.salt_len,
|
||||
dns_rr->rdata.nsec3.hash_len, salt_value, tmp_buf, maps);
|
||||
|
||||
cJSON_AddNumberToObject(dns_rr_object, "hash_algo", dns_rr->rdata.nsec3.hash_algo);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "flags", dns_rr->rdata.nsec3.flags);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "iteration", dns_rr->rdata.nsec3.iteration);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "salt_len", dns_rr->rdata.nsec3.salt_len);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "hash_len", dns_rr->rdata.nsec3.hash_len);
|
||||
cJSON_AddStringToObject(dns_rr_object, "salt_value", salt_value);
|
||||
cJSON_AddStringToObject(dns_rr_object, "next_hash_owner", tmp_buf);
|
||||
cJSON_AddStringToObject(dns_rr_object, "type_bit_maps", maps);
|
||||
break;
|
||||
case DNS_TYPE_NSEC3PARAM:
|
||||
len = 0;
|
||||
assert(dns_rr->rdata.nsec3param.salt_len * 2 < sizeof(tmp_buf));
|
||||
for (j = 0; j < (int)(dns_rr->rdata.nsec3param.salt_len); j++)
|
||||
{
|
||||
len += snprintf(tmp_buf + len, sizeof(tmp_buf) - len, "%02x", dns_rr->rdata.nsec3param.salt_value[j]);
|
||||
}
|
||||
|
||||
used_len += snprintf(buf + used_len, buflen - used_len,
|
||||
"[NSEC3PARAM hash_algo: %u, flags: %u, iteration: %u, salt_len: %u, salt_value: %s]\n",
|
||||
dns_rr->rdata.nsec3param.hash_algo, dns_rr->rdata.nsec3param.flags,
|
||||
dns_rr->rdata.nsec3param.iteration, dns_rr->rdata.nsec3param.salt_len,
|
||||
tmp_buf);
|
||||
|
||||
cJSON_AddNumberToObject(dns_rr_object, "hash_algo", dns_rr->rdata.nsec3param.hash_algo);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "flags", dns_rr->rdata.nsec3param.flags);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "iteration", dns_rr->rdata.nsec3param.iteration);
|
||||
cJSON_AddNumberToObject(dns_rr_object, "salt_len", dns_rr->rdata.nsec3param.salt_len);
|
||||
cJSON_AddStringToObject(dns_rr_object, "salt_value", tmp_buf);
|
||||
break;
|
||||
case DNS_TYPE_UNKNOWN:
|
||||
used_len += snprintf(buf + used_len, buflen - used_len, "[data: %s]\n", dns_rr->rdata.unknown_data);
|
||||
cJSON_AddStringToObject(dns_rr_object, "data", (const char *)(dns_rr->rdata.unknown_data));
|
||||
break;
|
||||
case DNS_QTYPE_AXFR:
|
||||
continue;
|
||||
break;
|
||||
case DNS_QTYPE_MAILB:
|
||||
continue;
|
||||
break;
|
||||
case DNS_QTYPE_MAILA:
|
||||
continue;
|
||||
break;
|
||||
case DNS_QTYPE_ANY:
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
fwrite(buf, used_len, 1, fp);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
|
||||
//char *question_array=cJSON_Print(dns_info_object);
|
||||
//char *rr_array=cJSON_Print(dns_info_object);
|
||||
|
||||
//cJSON_AddArrayToObject(dns_info_object, question_array);
|
||||
//cJSON_AddArrayToObject(dns_info_object, rr_array);
|
||||
|
||||
char *outout1 = cJSON_PrintUnformatted(dns_info_object);
|
||||
char *outout2 = cJSON_Print(dns_info_object);
|
||||
|
||||
printf("%s\n", outout1);
|
||||
printf("%s\n", outout2);
|
||||
free(outout1);
|
||||
free(outout2);
|
||||
cJSON_Delete(dns_info_object);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void util_dump_dns(const char *data, int len, int is_req)
|
||||
{
|
||||
int en_len;
|
||||
int de_len;
|
||||
int out_len;
|
||||
char en_buff[102400] = {0};
|
||||
char de_buff[102400] = {0};
|
||||
char out_buff[102400 * 2] = {0};
|
||||
|
||||
en_len = base64_encode(en_buff, sizeof(en_buff), data, len);
|
||||
if (en_len == MS_ERROR)
|
||||
{
|
||||
ERROR("base64_encode() failed\n");
|
||||
}
|
||||
|
||||
de_len = base64_decode(de_buff, sizeof(de_buff), en_buff, en_len);
|
||||
if (de_len == MS_ERROR)
|
||||
{
|
||||
ERROR("base64_encode() failed\n");
|
||||
}
|
||||
|
||||
if (de_len != len || strncmp(data, de_buff, de_len) != 0)
|
||||
{
|
||||
ERROR("base64_encode() != base64_decode()\n");
|
||||
}
|
||||
|
||||
FILE *fp = fopen("dns_test_base64.log", "a+");
|
||||
if (fp == NULL)
|
||||
{
|
||||
ERROR("fopen() failed\n");
|
||||
}
|
||||
out_len = snprintf(out_buff, sizeof(out_buff), "dir:%s len:%04d, data:%s\n", is_req ? "req" : "rsp", en_len, en_buff);
|
||||
printf("%s", out_buff);
|
||||
fwrite(out_buff, out_len, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static int util_proxy_dns(char *req_buff, int req_len, char *rsp_buff, int rsp_size)
|
||||
{
|
||||
int ret;
|
||||
int clientfd;
|
||||
struct sockaddr_in saddr;
|
||||
socklen_t addrlen = sizeof(struct sockaddr_in);
|
||||
|
||||
clientfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (clientfd == -1)
|
||||
{
|
||||
ERROR("socket() failed\n");
|
||||
}
|
||||
|
||||
memset(&saddr, 0, sizeof(saddr));
|
||||
saddr.sin_family = PF_INET;
|
||||
saddr.sin_port = htons(53);
|
||||
saddr.sin_addr.s_addr = inet_addr("114.114.114.114");
|
||||
|
||||
ret = sendto(clientfd, req_buff, req_len, 0, (struct sockaddr *)&saddr, addrlen);
|
||||
if (ret < 0)
|
||||
{
|
||||
ERROR("sendto() failed\n");
|
||||
}
|
||||
|
||||
ret = recvfrom(clientfd, rsp_buff, rsp_size, 0, (struct sockaddr *)&saddr, &addrlen);
|
||||
if (ret < 0)
|
||||
{
|
||||
ERROR("recvfrom() failed\n");
|
||||
}
|
||||
|
||||
close(clientfd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int util_parser_dns(const char *buff, int len, char *out_buff, int size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dns_info_t *parser = dns_new();
|
||||
dns_info_t *package = dns_new();
|
||||
assert(parser);
|
||||
assert(package);
|
||||
|
||||
// buff to struct
|
||||
ret = dns_parser(parser, (char *)buff, len);
|
||||
if (ret == -1)
|
||||
{
|
||||
ERROR("dns_parser() failed\n");
|
||||
}
|
||||
|
||||
// struct to buff
|
||||
ret = dns_package(parser, out_buff, size);
|
||||
if (ret == -1)
|
||||
{
|
||||
ERROR("dns_package() failed\n");
|
||||
}
|
||||
|
||||
if (dns_parser(package, out_buff, ret) == -1)
|
||||
{
|
||||
ERROR("dns_parser() failed\n");
|
||||
}
|
||||
|
||||
printf("dns first parser\n");
|
||||
dns_print(parser, "./dns_test_parser1.log");
|
||||
printf("dns second parser\n");
|
||||
dns_print(package, "./dns_test_parser2.log");
|
||||
|
||||
if (len != ret || strncmp(buff, out_buff, len) != 0)
|
||||
{
|
||||
printf("==================================\n"
|
||||
"first parser != second parser\n"
|
||||
"==================================\n");
|
||||
}
|
||||
|
||||
dns_free(parser);
|
||||
dns_free(package);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void test_as_dns_proxy_not_cheat_respone(void)
|
||||
{
|
||||
int len;
|
||||
int ret;
|
||||
int listenfd = -1;
|
||||
int reuseaddr = 1;
|
||||
char req_buff[10240];
|
||||
char rsp_buff[10240];
|
||||
char req_pacakge[10240];
|
||||
char rsp_package[10240];
|
||||
|
||||
struct sockaddr_in saddr;
|
||||
struct sockaddr_in caddr;
|
||||
socklen_t addrlen = sizeof(struct sockaddr_in);
|
||||
|
||||
listenfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (listenfd == -1)
|
||||
{
|
||||
ERROR("socket() failed\n");
|
||||
}
|
||||
|
||||
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr)) == -1)
|
||||
{
|
||||
ERROR("setsockopt() failed\n");
|
||||
}
|
||||
|
||||
memset(&saddr, 0, sizeof(saddr));
|
||||
saddr.sin_family = PF_INET;
|
||||
saddr.sin_port = htons(53);
|
||||
saddr.sin_addr.s_addr = INADDR_ANY;
|
||||
if (bind(listenfd, (struct sockaddr *)&saddr, sizeof(struct sockaddr)) == -1)
|
||||
{
|
||||
ERROR("bind() failed\n");
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
memset(req_buff, 0, sizeof(req_buff));
|
||||
memset(rsp_buff, 0, sizeof(rsp_buff));
|
||||
ret = recvfrom(listenfd, req_buff, sizeof(req_buff), 0, (struct sockaddr *)&caddr, &addrlen);
|
||||
if (ret < 0)
|
||||
{
|
||||
ERROR("recvfrom() failed\n");
|
||||
}
|
||||
|
||||
// DNS 请求包 dump
|
||||
util_dump_dns(req_buff, ret, 1);
|
||||
|
||||
// DNS 请求包 解析/封装 测试
|
||||
printf("============ parser req ============\n");
|
||||
len = util_parser_dns(req_buff, ret, req_pacakge, sizeof(req_pacakge));
|
||||
|
||||
ret = util_proxy_dns(req_buff, ret, rsp_buff, sizeof(rsp_buff));
|
||||
|
||||
// DNS 响应包 dump
|
||||
util_dump_dns(rsp_buff, ret, 0);
|
||||
|
||||
// DNS 响应包 解析/封装 测试
|
||||
printf("============ parser rsp ============\n");
|
||||
len = util_parser_dns(rsp_buff, ret, rsp_package, sizeof(rsp_package));
|
||||
|
||||
ret = sendto(listenfd, rsp_package, len, 0, (struct sockaddr *)&caddr, addrlen);
|
||||
if (ret < 0)
|
||||
{
|
||||
ERROR("sendto() failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_as_dns_proxy_but_cheat_respone(void)
|
||||
{
|
||||
int ret;
|
||||
int listenfd = -1;
|
||||
int reuseaddr = 1;
|
||||
char req_buff[10240];
|
||||
char rsp_buff[10240];
|
||||
|
||||
struct sockaddr_in saddr;
|
||||
struct sockaddr_in caddr;
|
||||
socklen_t addrlen = sizeof(struct sockaddr_in);
|
||||
|
||||
listenfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (listenfd == -1)
|
||||
{
|
||||
ERROR("socket() failed\n");
|
||||
}
|
||||
|
||||
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr)) == -1)
|
||||
{
|
||||
ERROR("setsockopt() failed\n");
|
||||
}
|
||||
|
||||
memset(&saddr, 0, sizeof(saddr));
|
||||
saddr.sin_family = PF_INET;
|
||||
saddr.sin_port = htons(53);
|
||||
saddr.sin_addr.s_addr = INADDR_ANY;
|
||||
if (bind(listenfd, (struct sockaddr *)&saddr, sizeof(struct sockaddr)) == -1)
|
||||
{
|
||||
ERROR("bind() failed\n");
|
||||
}
|
||||
|
||||
cheat_pkt_opt_t cheat_opt[32];
|
||||
memset(cheat_opt, 0, sizeof(cheat_opt));
|
||||
|
||||
// DNS_TYPE_A
|
||||
cheat_opt[0].res_type = DNS_TYPE_A;
|
||||
cheat_opt[0].ttl = 30;
|
||||
cheat_opt[0].res_len = 4;
|
||||
inet_pton(AF_INET, "192.168.1.1", cheat_opt[0].res_info);
|
||||
|
||||
// DNS_TYPE_AAAA
|
||||
cheat_opt[1].res_type = DNS_TYPE_AAAA;
|
||||
cheat_opt[1].ttl = 60;
|
||||
cheat_opt[1].res_len = 16;
|
||||
inet_pton(AF_INET6, "fe80::230:64ff:fe57:4a15", cheat_opt[1].res_info);
|
||||
|
||||
// DNS_TYPE_CNAME
|
||||
cheat_opt[2].res_type = DNS_TYPE_CNAME;
|
||||
cheat_opt[2].ttl = 90;
|
||||
cheat_opt[2].res_len = sizeof("www.cname1.com");
|
||||
memcpy(cheat_opt[2].res_info, "www.cname1.com", cheat_opt[2].res_len);
|
||||
|
||||
// DNS_TYPE_NS
|
||||
cheat_opt[3].res_type = DNS_TYPE_NS;
|
||||
cheat_opt[3].ttl = 90;
|
||||
cheat_opt[3].res_len = sizeof("www.ns.com");
|
||||
memcpy(cheat_opt[3].res_info, "www.ns.com", cheat_opt[3].res_len);
|
||||
|
||||
while (1)
|
||||
{
|
||||
memset(req_buff, 0, sizeof(req_buff));
|
||||
memset(rsp_buff, 0, sizeof(rsp_buff));
|
||||
ret = recvfrom(listenfd, req_buff, sizeof(req_buff), 0, (struct sockaddr *)&caddr, &addrlen);
|
||||
if (ret < 0)
|
||||
{
|
||||
ERROR("recvfrom() failed\n");
|
||||
}
|
||||
|
||||
// DNS 请求包 dump
|
||||
util_dump_dns(req_buff, ret, 1);
|
||||
|
||||
// 解析 DNS 请求包
|
||||
dns_info_t *parser = dns_new();
|
||||
assert(parser);
|
||||
ret = dns_parser(parser, req_buff, ret);
|
||||
if (ret == -1)
|
||||
{
|
||||
ERROR("dns_parser() failed\n");
|
||||
}
|
||||
|
||||
// 扫描策略
|
||||
|
||||
// 若命中策略,根据策略信息伪造 DNS 响应
|
||||
|
||||
// 伪造 DNS 响应包
|
||||
ret = dns_cheat_response(parser, cheat_opt, 4, rsp_buff, sizeof(rsp_buff));
|
||||
if (ret == -1)
|
||||
{
|
||||
ERROR("dns_cheat_response() failed\n");
|
||||
}
|
||||
dns_free(parser);
|
||||
|
||||
// DNS 响应包 dump
|
||||
util_dump_dns(rsp_buff, ret, 0);
|
||||
|
||||
ret = sendto(listenfd, rsp_buff, ret, 0, (struct sockaddr *)&caddr, addrlen);
|
||||
if (ret < 0)
|
||||
{
|
||||
ERROR("sendto() failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_use_offline_package(void)
|
||||
{
|
||||
int i;
|
||||
int req_len;
|
||||
int rsp_len;
|
||||
char req_buff[102400] = {0};
|
||||
char rsp_buff[102400] = {0};
|
||||
char out_buff[102400 * 2] = {0};
|
||||
|
||||
for (i = 0; i < package_arry_size; i++)
|
||||
{
|
||||
printf("test[%d]: %s\n", i, package_arry[i].desc);
|
||||
req_len = base64_decode(req_buff, sizeof(req_buff), package_arry[i].req.data, package_arry[i].req.len);
|
||||
if (req_len == MS_ERROR)
|
||||
{
|
||||
ERROR("base64_encode() failed\n");
|
||||
}
|
||||
printf("============ parser req ============\n");
|
||||
util_parser_dns(req_buff, req_len, out_buff, sizeof(out_buff));
|
||||
|
||||
rsp_len = base64_decode(rsp_buff, sizeof(rsp_buff), package_arry[i].rsp.data, package_arry[i].rsp.len);
|
||||
if (rsp_len == MS_ERROR)
|
||||
{
|
||||
ERROR("base64_encode() failed\n");
|
||||
}
|
||||
printf("============ parser rsp ============\n");
|
||||
util_parser_dns(rsp_buff, rsp_len, out_buff, sizeof(out_buff));
|
||||
}
|
||||
}
|
||||
|
||||
static void test_use_stdin_package(char *package)
|
||||
{
|
||||
int req_len;
|
||||
char req_buff[102400] = {0};
|
||||
char out_buff[102400 * 2] = {0};
|
||||
|
||||
req_len = base64_decode(req_buff, sizeof(req_buff), package, strlen(package));
|
||||
if (req_len == MS_ERROR)
|
||||
{
|
||||
ERROR("base64_encode() failed\n");
|
||||
}
|
||||
util_parser_dns(req_buff, req_len, out_buff, sizeof(out_buff));
|
||||
}
|
||||
|
||||
static void usage(char *name)
|
||||
{
|
||||
printf("Usage: %s [option]\n"
|
||||
" -p : test as dns proxy not cheat respone (dig @127.0.0.1 www.baidu.com a) dump data in base64\n"
|
||||
" -c : test as dns proxy but cheat respone (dig @127.0.0.1 www.baidu.com a) dump data in base64\n"
|
||||
"\n"
|
||||
" -o : test use offline dns package\n"
|
||||
" -b ${base64_pack} : test use stdin dns package\n",
|
||||
name);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2 && argc != 3)
|
||||
{
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
if (argc == 2 && (strncmp(argv[1], "-o", 2) != 0 && strncmp(argv[1], "-p", 2) != 0 && strncmp(argv[1], "-c", 2) != 0))
|
||||
{
|
||||
usage(argv[0]);
|
||||
}
|
||||
if (argc == 3 && strncmp(argv[1], "-b", 2) != 0)
|
||||
{
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
if (strncmp(argv[1], "-p", 2) == 0)
|
||||
{
|
||||
test_as_dns_proxy_not_cheat_respone();
|
||||
}
|
||||
else if (strncmp(argv[1], "-c", 2) == 0)
|
||||
{
|
||||
test_as_dns_proxy_but_cheat_respone();
|
||||
}
|
||||
else if (strncmp(argv[1], "-o", 2) == 0)
|
||||
{
|
||||
test_use_offline_package();
|
||||
}
|
||||
else if (strncmp(argv[1], "-b", 2) == 0)
|
||||
{
|
||||
test_use_stdin_package(argv[2]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user