⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dns.c

📁 FERRET - a broadcast analysis tool This tool is designed to demonstrate the problem of "data seap
💻 C
📖 第 1 页 / 共 3 页
字号:
							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 + -