Пример #1
0
void fs_add_ip_fields(fieldset_t *fs, struct iphdr *ip)
{
	fs_add_string(fs, "saddr", make_ip_str(ip->saddr), 1);
	fs_add_string(fs, "daddr", make_ip_str(ip->daddr), 1);
	fs_add_uint64(fs, "ipid", ntohl(ip->id));
	fs_add_uint64(fs, "ttl", ntohl(ip->ttl));
}
Пример #2
0
void fs_add_ip_fields(fieldset_t *fs, struct ip *ip)
{
	// WARNING: you must update fs_ip_fields_len  as well
	// as the definitions set (ip_fiels) if you
	// change the fields added below:
	fs_add_string(fs, "saddr", make_ip_str(ip->ip_src.s_addr), 1);
	fs_add_uint64(fs, "saddr_raw", (uint64_t) ip->ip_src.s_addr);
	fs_add_string(fs, "daddr", make_ip_str(ip->ip_dst.s_addr), 1);
	fs_add_uint64(fs, "daddr_raw", (uint64_t) ip->ip_dst.s_addr);
	fs_add_uint64(fs, "ipid", ntohs(ip->ip_id));
	fs_add_uint64(fs, "ttl", ip->ip_ttl);
}
Пример #3
0
void dns_process_packet(const u_char *packet, uint32_t len, fieldset_t *fs,
		uint32_t *validation) 
{	
	struct ip *ip_hdr = (struct ip *) &packet[sizeof(struct ether_header)];
	if (ip_hdr->ip_p == IPPROTO_UDP) {
		struct udphdr *udp_hdr = (struct udphdr *) ((char *) ip_hdr + 
				ip_hdr->ip_hl * 4);
		uint16_t udp_len = ntohs(udp_hdr->uh_ulen);
		assert(udp_len >= dns_packet_len); 
		char* qname_p = NULL;
		dns_question_tail* tail_p = NULL;
		bool is_valid = 0;
		dns_header* dns_header_p = (dns_header*) &udp_hdr[1];
		// verify our dns transaction id
		if (dns_header_p->id == (validation[2] & 0xFFFF)) {
			// Verify our question
			qname_p = (char*) dns_header_p + sizeof(dns_header);
			tail_p = (dns_question_tail*)(dns_packet + sizeof(dns_header) + 
					qname_len);
			// Verify our qname
			if (strcmp(qname, qname_p) == 0) {
				// Verify the qtype and qclass.
				if (tail_p->qtype == htons(qtype) && tail_p->qclass \
						== htons(0x01)) {
					is_valid = 1;
				}
			}
		}
		dns_header* dns_hdr = (dns_header*) &udp_hdr[1];
		uint16_t qr = dns_hdr->qr;
		uint16_t rcode = dns_hdr->rcode;
		// Success: Has the right validation bits and the right Q
		// App success: has qr and rcode bits right
		// Any app level parsing issues: dns_parse_err

		// High level info
		fs_add_string(fs, "classification", (char*) "dns", 0);
		fs_add_uint64(fs, "success", is_valid);
		fs_add_uint64(fs, "app_success", 
				is_valid && (qr == DNS_QR_ANSWER) && (rcode == DNS_RCODE_NOERR));
		// UDP info
		fs_add_uint64(fs, "sport", ntohs(udp_hdr->uh_sport));
		fs_add_uint64(fs, "dport", ntohs(udp_hdr->uh_dport));
		fs_add_uint64(fs, "udp_len", udp_len);
		// ICMP info
		fs_add_null(fs, "icmp_responder");
		fs_add_null(fs, "icmp_type");
		fs_add_null(fs, "icmp_code");
		fs_add_null(fs, "icmp_unreach_str");
	        // DNS data	
		if (!is_valid) {
			// DNS header
			fs_add_null(fs, "dns_id"); 
			fs_add_null(fs, "dns_rd"); 
			fs_add_null(fs, "dns_tc"); 
			fs_add_null(fs, "dns_aa"); 
			fs_add_null(fs, "dns_opcode"); 
			fs_add_null(fs, "dns_qr"); 
			fs_add_null(fs, "dns_rcode"); 
			fs_add_null(fs, "dns_cd"); 
			fs_add_null(fs, "dns_ad"); 
			fs_add_null(fs, "dns_z"); 
			fs_add_null(fs, "dns_ra"); 
			fs_add_null(fs, "dns_qdcount"); 
			fs_add_null(fs, "dns_ancount"); 
			fs_add_null(fs, "dns_nscount"); 
			fs_add_null(fs, "dns_arcount"); 

			fs_add_repeated(fs, "dns_questions", fs_new_repeated_fieldset());
			fs_add_repeated(fs, "dns_answers", fs_new_repeated_fieldset());
			fs_add_repeated(fs, "dns_authorities", fs_new_repeated_fieldset());
			fs_add_repeated(fs, "dns_additionals", fs_new_repeated_fieldset());

			fs_add_uint64(fs, "dns_unconsumed_bytes", 0); 
			fs_add_uint64(fs, "dns_parse_err", 1); 
		} else {
			// DNS header
			fs_add_uint64(fs, "dns_id", ntohs(dns_hdr->id)); 
			fs_add_uint64(fs, "dns_rd", dns_hdr->rd); 
			fs_add_uint64(fs, "dns_tc", dns_hdr->tc); 
			fs_add_uint64(fs, "dns_aa", dns_hdr->aa); 
			fs_add_uint64(fs, "dns_opcode", dns_hdr->opcode); 
			fs_add_uint64(fs, "dns_qr", qr); 
			fs_add_uint64(fs, "dns_rcode", rcode); 
			fs_add_uint64(fs, "dns_cd", dns_hdr->cd); 
			fs_add_uint64(fs, "dns_ad", dns_hdr->ad); 
			fs_add_uint64(fs, "dns_z", dns_hdr->z); 
			fs_add_uint64(fs, "dns_ra", dns_hdr->ra); 
			fs_add_uint64(fs, "dns_qdcount", ntohs(dns_hdr->qdcount)); 
			fs_add_uint64(fs, "dns_ancount", ntohs(dns_hdr->ancount)); 
			fs_add_uint64(fs, "dns_nscount", ntohs(dns_hdr->nscount)); 
			fs_add_uint64(fs, "dns_arcount", ntohs(dns_hdr->arcount)); 
			// And now for the complicated part. Hierarchical data. 
			char* data = ((char*)dns_hdr) + sizeof(dns_header);
			uint16_t data_len = udp_len - sizeof(udp_hdr) - sizeof(dns_header);
			bool err = 0;
			// Questions
			fieldset_t *list = fs_new_repeated_fieldset();
			for (int i = 0; i < ntohs(dns_hdr->qdcount) && !err; i++) {
				err = process_response_question(&data, &data_len, (char*)dns_hdr, 
							udp_len, list);    
			}
			fs_add_repeated(fs, "dns_questions", list);
			// Answers
			list = fs_new_repeated_fieldset();
			for (int i = 0; i < ntohs(dns_hdr->ancount) && !err; i++) {
				err = process_response_answer(&data, &data_len, (char*)dns_hdr,
						 udp_len, list); 
			}
			fs_add_repeated(fs, "dns_answers", list);
			// Authorities
			list = fs_new_repeated_fieldset();
			for (int i = 0; i < ntohs(dns_hdr->nscount) && !err; i++) {
				err = process_response_answer(&data, &data_len, (char*)dns_hdr, 
						udp_len, list);  
			}
			fs_add_repeated(fs, "dns_authorities", list);

			// Additionals
			list = fs_new_repeated_fieldset();
			for (int i = 0; i < ntohs(dns_hdr->arcount) && !err; i++) {
				err = process_response_answer(&data, &data_len, (char*)dns_hdr, 
						udp_len, list);
			}
			fs_add_repeated(fs, "dns_additionals", list);
			// Do we have unconsumed data?
			fs_add_uint64(fs, "dns_unconsumed_bytes", data_len); 
			if (data_len != 0) {
				err = 1;
			}
			// Did we parse OK?
			fs_add_uint64(fs, "dns_parse_err", err); 
		}
		// Now the raw stuff.
		fs_add_binary(fs, "raw_data", (udp_len - sizeof(struct udphdr)),
				(void*) &udp_hdr[1], 0);
		return;
	} else if (ip_hdr->ip_p == IPPROTO_ICMP) {
		struct icmp *icmp = (struct icmp*) ((char *) ip_hdr + 4*ip_hdr->ip_hl);
		struct ip *ip_inner = (struct ip*) ((char *) icmp + 
				ICMP_UNREACH_HEADER_SIZE);
		
		// This is the packet we sent
		struct udphdr *udp_hdr = (struct udphdr *) ((char*) ip_inner + 
				4*ip_inner->ip_hl);
		
		uint16_t udp_len = ntohs(udp_hdr->uh_ulen);
		// High level info	  
		fs_add_string(fs, "classification", (char*) "icmp-unreach", 0);
		fs_add_uint64(fs, "success", 0);
		fs_add_uint64(fs, "app_success", 0);
		// UDP info
		fs_add_uint64(fs, "sport", ntohs(udp_hdr->uh_sport));
		fs_add_uint64(fs, "dport", ntohs(udp_hdr->uh_dport));
		fs_add_uint64(fs, "udp_len", udp_len);
		// ICMP info
		// XXX This is legacy. not well tested.
		fs_add_string(fs, "icmp_responder", make_ip_str(ip_hdr->ip_src.s_addr), 1);
		fs_add_uint64(fs, "icmp_type", icmp->icmp_type);
		fs_add_uint64(fs, "icmp_code", icmp->icmp_code);
		if (icmp->icmp_code <= ICMP_UNREACH_PRECEDENCE_CUTOFF) {
			fs_add_string(fs, "icmp_unreach_str",
				(char *) udp_unreach_strings[icmp->icmp_code], 0);
		} else {
			fs_add_string(fs, "icmp_unreach_str", (char *) "unknown", 0);
		}
		// DNS header
		fs_add_null(fs, "dns_id"); 
		fs_add_null(fs, "dns_rd"); 
		fs_add_null(fs, "dns_tc"); 
		fs_add_null(fs, "dns_aa"); 
		fs_add_null(fs, "dns_opcode"); 
		fs_add_null(fs, "dns_qr"); 
		fs_add_null(fs, "dns_rcode"); 
		fs_add_null(fs, "dns_cd"); 
		fs_add_null(fs, "dns_ad"); 
		fs_add_null(fs, "dns_z"); 
		fs_add_null(fs, "dns_ra"); 
		fs_add_null(fs, "dns_qdcount"); 
		fs_add_null(fs, "dns_ancount"); 
		fs_add_null(fs, "dns_nscount"); 
		fs_add_null(fs, "dns_arcount"); 

		fs_add_repeated(fs, "dns_questions", fs_new_repeated_fieldset());
		fs_add_repeated(fs, "dns_answers", fs_new_repeated_fieldset());
		fs_add_repeated(fs, "dns_authorities", fs_new_repeated_fieldset());
		fs_add_repeated(fs, "dns_additionals", fs_new_repeated_fieldset());

		fs_add_uint64(fs, "dns_unconsumed_bytes", 0); 
		fs_add_uint64(fs, "dns_parse_err", 1); 
		fs_add_binary(fs, "raw_data", len, (char*)packet, 0);
		
		return;

	} else {
		// This should not happen. Both the pcap filter and validate
		// packet prevent this.
		log_fatal("dns", "Die. This can only happen if you "
				"change the pcap filter and don't update the "
				"process function.");
		return;
	}
}