📄 dns.c
字号:
if (rec->rdata_length != 4)
FRAMERR(frame, "dns: data not 4-bytes long, was %d-bytes instead (class=%d, type=%d, name=%s)\n", rec->rdata_length, rec->clss, rec->type, name);
process_record(seap,
"proto", REC_SZ, "DNS", -1,
"op", REC_SZ, "lookup", -1,
"ip.src", REC_FRAMESRC, frame, -1,
"name", REC_PRINTABLE, name, strlen(name),
"address", REC_IPv4, &ip_address, sizeof(ip_address),
0);
}
break;
case 0x8001:
{
unsigned ip_address = ex32be(px+rec->rdata_offset);
if (rec->rdata_length != 4)
FRAMERR(frame, "dns: data not 4-bytes long, was %d-bytes instead (class=%d, type=%d, name=%s)\n", rec->rdata_length, rec->clss, rec->type, name);
process_record(seap,
"ID-IP", REC_IPv4, &ip_address, sizeof(ip_address),
"name", REC_PRINTABLE, name, strlen(name),
0);
}
break;
default:
FRAMERR(frame, "dns: unknown class=%d (type=%d, name=%s)\n", rec->clss, rec->type, name);
}
break;
case 0x0002: /*NS*/
DECODEANSWER(seap, frame, px, length, dns, rec, "answer");
break;
case 0x0006: /*SOA*/
DECODEANSWER(seap, frame, px, length, dns, rec, "answer");
break;
case 0x001c: /*AAAA = IPv6 address */
switch (rec->clss) {
case 0x0001: /*INTERNET*/
{
const unsigned char *ip_address = px+rec->rdata_offset;
if (rec->rdata_length != 16)
FRAMERR(frame, "dns: data not 16-bytes long, was %d-bytes instead (class=%d, type=%d, name=%s)\n", rec->rdata_length, rec->clss, rec->type, name);
process_record(seap,
"proto", REC_SZ, "DNS", -1,
"op", REC_SZ, "lookup", -1,
"ip.src", REC_FRAMESRC, frame, -1,
"name", REC_PRINTABLE, name, strlen(name),
"address", REC_IPv6, ip_address, 16,
0);
}
break;
case 0x8001:
{
const unsigned char *ip_address = px+rec->rdata_offset;
if (rec->rdata_length != 16)
FRAMERR(frame, "dns: data not 16-bytes long, was %d-bytes instead (class=%d, type=%d, name=%s)\n", rec->rdata_length, rec->clss, rec->type, name);
process_record(seap,
"ID-IP", REC_IPv6, ip_address, 16,
"name", REC_PRINTABLE, name, strlen(name),
0);
}
break;
default:
FRAMERR(frame, "dns: unknown class=%d (type=%d, name=%s)\n", rec->clss, rec->type, name);
}
break;
case 0x000d: /*HINFO*/
switch (rec->clss) {
case 0x8001:
{
unsigned j=0;
const unsigned char *cpu;
unsigned cpu_length;
const unsigned char *os;
unsigned os_length;
j = rec->rdata_offset;
cpu = px+j+1;
cpu_length = px[j];
j += cpu_length + 1;
os = px+j+1;
os_length = px[j];
process_record(seap,
"Bonjour", REC_PRINTABLE, name, strlen(name),
"OS", REC_PRINTABLE, os, os_length,
0);
process_record(seap,
"Bonjour", REC_PRINTABLE, name, strlen(name),
"CPU", REC_PRINTABLE, cpu, cpu_length,
0);
}
break;
default:
FRAMERR(frame, "dns: unknown class=%d (type=%d, name=%s)\n", rec->clss, rec->type, name);
}
break;
case 0x0005: /*CNAME = aliased canonical name */
{
char alias[256];
unsigned ip_address;
dns_extract_name(frame, px, length, rec->rdata_offset, alias, sizeof(alias));
ip_address = dns_resolve_alias(frame, px, length, dns, alias, 0);
if (ip_address != 0)
process_record(seap,
"proto", REC_SZ, "DNS", -1,
"op", REC_SZ, "lookup", -1,
"ip.src", REC_FRAMEDST, frame, -1,
"name", REC_PRINTABLE, name, strlen(name),
"address", REC_IPv4, &ip_address, sizeof(ip_address),
0);
}
break;
case 12: /*PTR = pointer record*/
switch (rec->clss) {
case 0x0001: /*INTERNET*/
if (name_length > 6 && memcmp(name+name_length-6, ".local", 6) == 0) {
process_record(seap,
"ID-IP", REC_FRAMESRC, frame, -1,
"SERVICE", REC_PRINTABLE, name, strlen(name),
0);
/* Extract MAC address */
{
const unsigned char *p_name;
unsigned name_length;
const unsigned char *p_mac = find_mac(px, MIN(length, rec->rdata_offset+rec->rdata_length), rec->rdata_offset, &p_name, &name_length);
if (p_mac) {
process_record(seap,
"ID-IP", REC_FRAMESRC, frame, -1,
"mac", REC_PRINTABLE, p_mac, 19,
0);
process_record(seap,
"ID-IP", REC_FRAMESRC, frame, -1,
"name", REC_PRINTABLE, p_name, name_length,
0);
}
}
} else
FRAMERR(frame, "dns: unknown PTR record\n");
break;
case 0x8001: /*FLUSH*/
break;
default:
FRAMERR(frame, "dns: unknown class=%d (type=%d, name=%s)\n", rec->clss, rec->type, name);
}
break;
case 0x0020: /*NETBIOS */
DECODEANSWER(seap, frame, px, length, dns, rec, "netbios");
break;
case 0x0021: /*NBTSTAT*/
switch (rec->clss) {
case 0x0001: /*INTERNET*/
{
unsigned length2 = rec->rdata_offset + rec->rdata_length;
unsigned number_of_names;
unsigned j;
offset = rec->rdata_offset;
number_of_names = px[offset++];
if (offset >= length || offset >= length2) {
FRAMERR(frame, "dns: truncated\n");
break;
}
/* Grab the names */
for (j=0; j<number_of_names; j++) {
char netbios_name[256];
if (offset+18 > length || offset+18 > length2) {
offset += 18;
FRAMERR(frame, "dns: truncated\n");
break;
}
cleanse_netbios_name(frame, (const char*)px+offset, netbios_name, sizeof(netbios_name));
process_record(seap,
"ID-IP", REC_FRAMEDST, frame, -1,
"netbios", REC_PRINTABLE, netbios_name, strlen(netbios_name),
0);
offset += 18;
}
if (offset+6 > length || offset+18 > length2) {
FRAMERR(frame, "dns: truncated\n");
break;
}
if (memicmp(px+offset, "\0\0\0\0\0\0", 6) != 0) {
process_record(seap,
"ID-IP", REC_FRAMEDST, frame, -1,
"mac", REC_MACADDR, px+offset, 6,
0);
}
offset += 6;
}
break;
}
break;
case 0x0010: /* TXT Record */
switch (rec->clss) {
case 0x8001: /*FLUSH*/
{
unsigned offset = rec->rdata_offset;
unsigned max = rec->rdata_offset + rec->rdata_length;
unsigned b=0;
const unsigned char *bonjour;
unsigned bonjour_length;
if (max > length)
max = length;
/* Grab the Bonjour name */
for (b=0; b<name_length; b++) {
if (name[b] == '.' && b+1<name_length && name[b+1] == '_') {
b++;
break;
}
}
bonjour = (const unsigned char*)name+b;
bonjour_length = name_length-b;
/* For all the <name=value> pairs in the record */
while (offset < max) {
unsigned len = px[offset++];
const unsigned char *tag;
unsigned tag_length;
const unsigned char *value;
unsigned value_length;
unsigned max2 = max;
if (max2 > offset + len)
max2 = offset + len;
tag = px+offset;
for (tag_length=0; offset+tag_length<max2 && tag[tag_length]!='='; tag_length++)
;
offset+=tag_length;
if (offset < max2 && px[offset] == '=')
offset++;
while (offset < max2 && isspace(px[offset]))
offset++;
value = px+offset;
value_length = (max2-offset);
offset = max2;
/* Process the name value pair */
process_record(seap,
"proto", REC_SZ, "Bonjour", -1,
"ip", REC_FRAMESRC, frame, -1,
"service", REC_PRINTABLE, bonjour, bonjour_length,
"tag", REC_PRINTABLE, tag, tag_length,
"value", REC_PRINTABLE, value, value_length,
0);
}
}
break;
default:
FRAMERR(frame, "dns: unknown class=%d (type=%d, name=%s)\n", rec->clss, rec->type, name);
}
break;
default:
FRAMERR(frame, "dns: unknown type=%d (class=%d, name=%s)\n", rec->type, rec->clss, name);
}
}
break;
case 3: /* No such name */
SAMPLE("DNS", "rcode", REC_UNSIGNED, &dns->rcode, sizeof(dns->rcode));
break;
default:
FRAMERR(frame, "dns: unknown rcode=%d (opcode=%d)\n", dns->rcode, dns->opcode);
}
break;
case 0x06: /*release*/
switch (dns->rcode) {
case 0:
for (i=0; i<dns->additional_count; i++) {
char name[256];
unsigned name_length;
struct DNSRECORD *rec = &dns->additionals[i];
if (rec->type == 0x8001)
FRAMERR(frame, "test\n");
name_length = dns_extract_name(frame, px, length, rec->name_offset, name, sizeof(name));
switch (rec->type) {
case 0x0020: /*NETBIOS */
switch (rec->clss) {
case 0x0001: /*INTERNET*/
{
unsigned ip_address = ex32be(px+rec->rdata_offset+2);
char netbios_name[256];
if (rec->rdata_length != 6)
FRAMERR(frame, "dns: data not 4-bytes long, was %d-bytes instead (class=%d, type=%d, name=%s)\n", rec->rdata_length, rec->clss, rec->type, name);
translate_netbios_name(frame, name, netbios_name, sizeof(netbios_name));
process_record(seap,
"proto", REC_SZ, "NETBIOS", -1,
"op", REC_SZ, "release", -1,
"ip.src", REC_FRAMEDST, frame, -1,
"name", REC_PRINTABLE, netbios_name, strlen(netbios_name),
"address", REC_IPv4, &ip_address, sizeof(ip_address),
0);
process_record(seap,
"ID-IP", REC_IPv4, &ip_address, sizeof(ip_address),
"netbios", REC_PRINTABLE, netbios_name, strlen(netbios_name),
0);
}
break;
default:
FRAMERR(frame, "dns: unknown class=%d (type=%d, name=%s)\n", rec->clss, rec->type, name);
}
break;
default:
FRAMERR(frame, "dns: unknown type=%d (class=%d, name=%s)\n", rec->type, rec->clss, name);
}
}
}
break;
case 0x05: /*netbios registration request*/
if (frame->dst_port == 53)
dns_dynamic_update(seap, frame, px, length, dns);
else
process_request_update(seap, frame, px, length, dns);
break;
case 0x08:
for (i=0; i<dns->additional_count; i++)
DECODEANSWER(seap, frame, px, length, dns, &dns->additionals[i], "refresh");
break;
case 0x01: /*inverse query request*/
case 0x11: /*inverse query reqsponse*/
case 0x02: /*status request*/
case 0x12: /*status response*/
case 0x04: /*notify request*/
case 0x14: /*notify response*/
case 0x15: /*update response*/
case 0x0f: /*multi-home registration*/
for (i=0; i<dns->additional_count; i++)
DECODEANSWER(seap, frame, px, length, dns, &dns->additionals[i], "multi-home");
break;
default:
FRAMERR(frame, "dns: unknown opcode %d\n", dns->opcode);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -