Пример #1
0
static void auth_hdr(struct pkt_buff *pkt)
{
	ssize_t hdr_len;
	struct auth_hdr *auth_ops;

	auth_ops = (struct auth_hdr *) pkt_pull(pkt, sizeof(*auth_ops));
	if (auth_ops == NULL)
		return;
	
	hdr_len = (auth_ops->h_payload_len * 4) + 8;

	tprintf(" [ Authentication Header ");
	tprintf("NextHdr (%u), ", auth_ops->h_next_header);
	if (hdr_len > pkt_len(pkt) || hdr_len < 0){
		tprintf("HdrLen (%u, %zd Bytes %s), ",
		      auth_ops->h_payload_len, hdr_len,
		      colorize_start_full(black, red)
		      "invalid" colorize_end());
		      return;
	}
	tprintf("HdrLen (%u, %zd Bytes), ",auth_ops->h_payload_len, hdr_len);
	tprintf("Reserved (0x%x), ", ntohs(auth_ops->h_reserved));
	/* TODO
	 * Upgrade for Extended (64-bit) Sequence Number
	 * http://tools.ietf.org/html/rfc4302#section-2.5.1
	 */
	tprintf("SPI (0x%x), ", ntohl(auth_ops->h_spi));
	tprintf("SNF (0x%x), ", ntohl(auth_ops->h_snf));
	tprintf("ICV 0x");
	for (size_t i = sizeof(struct auth_hdr); i < hdr_len; i++)
		tprintf("%02x", *pkt_pull(pkt, 1));
	tprintf(" ]\n");

	pkt_set_proto(pkt, &eth_lay3, auth_ops->h_next_header);
}
Пример #2
0
static void ipv4_less(struct pkt_buff *pkt)
{
	char src_ip[INET_ADDRSTRLEN];
	char dst_ip[INET_ADDRSTRLEN];
	struct ipv4hdr *ip = (struct ipv4hdr *) pkt_pull(pkt, sizeof(*ip));

	if (!ip)
		return;

	inet_ntop(AF_INET, &ip->h_saddr, src_ip, sizeof(src_ip));
	inet_ntop(AF_INET, &ip->h_daddr, dst_ip, sizeof(dst_ip));

	tprintf(" %s/%s Len %u", src_ip, dst_ip,
		ntohs(ip->h_tot_len));

	/* cut off IP options and everything that is not part of IPv4 payload */
	pkt_pull(pkt, max((uint8_t) ip->h_ihl, sizeof(*ip) / sizeof(uint32_t))
		* sizeof(uint32_t) - sizeof(*ip));
	/* XXX there coul still be an Ethernet trailer included or others */
#if 0
	pkt_trim(pkt, pkt_len(pkt) - min(pkt_len(pkt),
		 (ntohs(ip->h_tot_len) - ip->h_ihl * sizeof(uint32_t))));
#endif
	pkt_set_proto(pkt, &eth_lay3, ip->h_protocol);
}
Пример #3
0
static void routing_less(struct pkt_buff *pkt)
{
	uint16_t hdr_ext_len;
	ssize_t data_len;
	struct routinghdr *routing;

	routing = (struct routinghdr *) pkt_pull(pkt, sizeof(*routing));
	if (routing == NULL)
		return;

	/* Total Header Length in Bytes */
	hdr_ext_len = (routing->h_hdr_ext_len + 1) * 8;
	/* Data length in Bytes */
	data_len = hdr_ext_len - sizeof(*routing);
	if (data_len > pkt_len(pkt) || data_len < 0)
		return;

	tprintf(" Routing ");
	
	switch (routing->h_routing_type) {
	case ROUTING_HEADER_TYPE_0:
		dissect_routinghdr_type_0_less(pkt, &data_len);
		break;
	default:
		tprintf("Type %u is unknown", routing->h_routing_type);
	}

	if (data_len > pkt_len(pkt) || data_len < 0)
		return;

	pkt_pull(pkt, data_len);
	pkt_set_proto(pkt, &eth_lay3, routing->h_next_header);
}
Пример #4
0
static void hop_by_hop(struct pkt_buff *pkt)
{
	uint16_t hdr_ext_len;
	ssize_t opt_len;
	struct hop_by_hophdr *hop_ops;

	hop_ops = (struct hop_by_hophdr *) pkt_pull(pkt, sizeof(*hop_ops));
	if (hop_ops == NULL)
		return;

	/* Total Header Length in Bytes */
	hdr_ext_len = (hop_ops->hdr_len + 1) * 8;
	/* Options length in Bytes */
	opt_len = hdr_ext_len - sizeof(*hop_ops);

	tprintf("\t [ Hop-by-Hop Options ");
	tprintf("NextHdr (%u), ", hop_ops->h_next_header);
	if (opt_len > pkt_len(pkt) || opt_len < 0){
		tprintf("HdrExtLen (%u, %u Bytes, %s)", hop_ops->hdr_len,
		      hdr_ext_len, colorize_start_full(black, red)
		      "invalid" colorize_end());
		      return;
	}
	tprintf("HdrExtLen (%u, %u Bytes)", hop_ops->hdr_len,
		hdr_ext_len);

	dissect_opt_hop(pkt, &opt_len);

	tprintf(" ]\n");

	pkt_pull(pkt, opt_len);
	pkt_set_proto(pkt, &eth_lay3, hop_ops->h_next_header);
}
Пример #5
0
static void auth_hdr_less(struct pkt_buff *pkt)
{
  	ssize_t hdr_len;
	struct auth_hdr *auth_ops;

	auth_ops = (struct auth_hdr *) pkt_pull(pkt, sizeof(*auth_ops));
	if (auth_ops == NULL)
		return;
	
	hdr_len = (auth_ops->h_payload_len * 4) + 8;
	if (hdr_len > pkt_len(pkt) || hdr_len < 0)
		return;

	tprintf(" AH");

	pkt_pull(pkt, hdr_len - sizeof(*auth_ops));
	pkt_set_proto(pkt, &eth_lay3, auth_ops->h_next_header);
}
Пример #6
0
static void routing(struct pkt_buff *pkt)
{
	uint16_t hdr_ext_len;
	ssize_t data_len;
	struct routinghdr *routing;

	routing = (struct routinghdr *) pkt_pull(pkt, sizeof(*routing));
	if (routing == NULL)
		return;

	/* Total Header Length in Bytes */
	hdr_ext_len = (routing->h_hdr_ext_len + 1) * 8;
	/* Data length in Bytes */
	data_len = hdr_ext_len - sizeof(*routing);

	tprintf("\t [ Routing ");
	tprintf("NextHdr (%u), ", routing->h_next_header);
	if (data_len > pkt_len(pkt) || data_len < 0){
		tprintf("HdrExtLen (%u, %u Bytes %s), ", routing->h_hdr_ext_len,
		      hdr_ext_len, colorize_start_full(black, red)
		      "invalid" colorize_end());
		      return;
	}
	tprintf("HdrExtLen (%u, %u Bytes), ", routing->h_hdr_ext_len,
		hdr_ext_len);
	tprintf("Type (%u), ", routing->h_routing_type);
	tprintf("Left (%u), ", routing->h_segments_left);

	switch (routing->h_routing_type) {
	case ROUTING_HEADER_TYPE_0:
		dissect_routinghdr_type_0_norm(pkt, &data_len);
		break;
	default:
		tprintf("Type %u is unknown", routing->h_routing_type);
	}

	tprintf(" ]\n");

	if (data_len > pkt_len(pkt) || data_len < 0)
		return;

	pkt_pull(pkt, data_len);
	pkt_set_proto(pkt, &eth_lay3, routing->h_next_header);
}
Пример #7
0
static void ethernet_less(struct pkt_buff *pkt)
{
	uint8_t *src_mac, *dst_mac;
	struct ethhdr *eth = (struct ethhdr *) pkt_pull(pkt, sizeof(*eth));

	if (eth == NULL)
		return;

	src_mac = eth->h_source;
	dst_mac = eth->h_dest;
	tprintf(" %s => %s ", 
		lookup_vendor((src_mac[0] << 16) | (src_mac[1] << 8) |
			      src_mac[2]),
		lookup_vendor((dst_mac[0] << 16) | (dst_mac[1] << 8) |
			      dst_mac[2]));
	tprintf("%s%s%s", colorize_start(bold), 
		lookup_ether_type(ntohs(eth->h_proto)), colorize_end());

	pkt_set_proto(pkt, &eth_lay2, ntohs(eth->h_proto));
}
Пример #8
0
static void mobility_less(struct pkt_buff *pkt)
{
	uint16_t hdr_ext_len;
	ssize_t message_data_len;
	struct mobilityhdr *mobility;

	mobility = (struct mobilityhdr *) pkt_pull(pkt, sizeof(*mobility));
	if (mobility == NULL)
		return;

	/* Total Header Length in Bytes */
	hdr_ext_len = (mobility->hdr_len + 1) * 8;
	/* Total Message Data length in Bytes*/
	message_data_len = (hdr_ext_len - sizeof(*mobility));
	if (message_data_len > pkt_len(pkt) || message_data_len < 0)
		return;

	tprintf(" Mobility Type (%u), ", mobility->MH_type);

	pkt_pull(pkt, message_data_len);
	pkt_set_proto(pkt, &eth_lay3, mobility->payload_proto);
}
Пример #9
0
static void mobility(struct pkt_buff *pkt)
{
	uint16_t hdr_ext_len;
	ssize_t message_data_len;
	struct mobilityhdr *mobility;

	mobility = (struct mobilityhdr *) pkt_pull(pkt, sizeof(*mobility));
	if (mobility == NULL)
		return;

	/* Total Header Length in Bytes */
	hdr_ext_len = (mobility->hdr_len + 1) * 8;
	/* Total Message Data length in Bytes*/
	message_data_len = (hdr_ext_len - sizeof(*mobility));

	tprintf("\t [ Mobility ");
	tprintf("NextHdr (%u), ", mobility->payload_proto);
	if (message_data_len > pkt_len(pkt) || message_data_len < 0){
		tprintf("HdrExtLen (%u, %u Bytes %s), ", mobility->hdr_len,
				hdr_ext_len, colorize_start_full(black, red)
				"invalid" colorize_end());
		return;
	}
	tprintf("HdrExtLen (%u, %u Bytes), ", mobility->hdr_len,
		hdr_ext_len);
	tprintf("MH Type (%u), ", mobility->MH_type);
	tprintf("Res (0x%x), ", mobility->reserved);
	tprintf("Chks (0x%x), ", ntohs(mobility->chksum));
	tprintf("MH Data ");

	get_mh_type(pkt, &message_data_len, &mobility->MH_type);

	tprintf(" ]\n");

	if (message_data_len > pkt_len(pkt) || message_data_len < 0)
		return;
	pkt_pull(pkt, message_data_len);
	pkt_set_proto(pkt, &eth_lay3, mobility->payload_proto);
}
Пример #10
0
static void hop_by_hop_less(struct pkt_buff *pkt)
{
	uint16_t hdr_ext_len;
	ssize_t opt_len;
	struct hop_by_hophdr *hop_ops;

	hop_ops = (struct hop_by_hophdr *) pkt_pull(pkt, sizeof(*hop_ops));
	if (hop_ops == NULL)
		return;

	/* Total Header Length in Bytes */
	hdr_ext_len = (hop_ops->hdr_len + 1) * 8;
	/* Options length in Bytes */
	opt_len = hdr_ext_len - sizeof(*hop_ops);
	if (opt_len > pkt_len(pkt) || opt_len < 0)
		return;

	tprintf(" Hop Ops");

	pkt_pull(pkt, opt_len);
	pkt_set_proto(pkt, &eth_lay3, hop_ops->h_next_header);
}
Пример #11
0
static void ethernet(struct pkt_buff *pkt)
{
	char *type;
	uint8_t *src_mac, *dst_mac;
	struct ethhdr *eth = (struct ethhdr *) pkt_pull(pkt, sizeof(*eth));

	if (eth == NULL)
		return;

	src_mac = eth->h_source;
	dst_mac = eth->h_dest;

	tprintf(" [ Eth ");
	tprintf("MAC (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x => ",
		src_mac[0], src_mac[1], src_mac[2],
		src_mac[3], src_mac[4], src_mac[5]);
	tprintf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x), ",
		dst_mac[0], dst_mac[1], dst_mac[2],
		dst_mac[3], dst_mac[4], dst_mac[5]);
	tprintf("Proto (0x%.4x", ntohs(eth->h_proto));

	type = lookup_ether_type(ntohs(eth->h_proto));
	if (type)
		tprintf(", %s%s%s", colorize_start(bold), type, colorize_end());

	tprintf(") ]\n");
	tprintf(" [ Vendor ");
	tprintf("(%s => %s)",
		lookup_vendor((src_mac[0] << 16) | (src_mac[1] << 8) |
			      src_mac[2]),
		lookup_vendor((dst_mac[0] << 16) | (dst_mac[1] << 8) |
			      dst_mac[2]));
	tprintf(" ]\n");

	pkt_set_proto(pkt, &eth_lay2, ntohs(eth->h_proto));
}
Пример #12
0
static void ipv4(struct pkt_buff *pkt)
{
	uint16_t csum, frag_off, h_tot_len;
	char src_ip[INET_ADDRSTRLEN];
	char dst_ip[INET_ADDRSTRLEN];
	struct ipv4hdr *ip = (struct ipv4hdr *) pkt_pull(pkt, sizeof(*ip));
	uint8_t *opt, *trailer;
	unsigned int trailer_len = 0;
	ssize_t opts_len, opt_len;
	struct sockaddr_in sas, sad;
	const char *city, *region, *country;

	if (!ip)
		return;

	frag_off = ntohs(ip->h_frag_off);
	h_tot_len = ntohs(ip->h_tot_len);
	csum = calc_csum(ip, ip->h_ihl * 4, 0);

	inet_ntop(AF_INET, &ip->h_saddr, src_ip, sizeof(src_ip));
	inet_ntop(AF_INET, &ip->h_daddr, dst_ip, sizeof(dst_ip));

	if ((pkt_len(pkt) + sizeof(*ip)) > h_tot_len) {
		trailer_len = pkt_len(pkt) + sizeof(*ip) - h_tot_len;
		trailer = pkt->data + h_tot_len + trailer_len;
	}

	if (trailer_len) {
		 tprintf(" [ Eth trailer ");
		 while (trailer_len--) {
			tprintf("%x", *(trailer - trailer_len));
		 }
		 tprintf(" ]\n");
	}

	tprintf(" [ IPv4 ");
	tprintf("Addr (%s => %s), ", src_ip, dst_ip);
	tprintf("Proto (%u), ", ip->h_protocol);
	tprintf("TTL (%u), ", ip->h_ttl);
	tprintf("TOS (%u), ", ip->h_tos);
	tprintf("Ver (%u), ", ip->h_version);
	tprintf("IHL (%u), ", ip->h_ihl);
	tprintf("Tlen (%u), ", ntohs(ip->h_tot_len));
	tprintf("ID (%u), ", ntohs(ip->h_id));
	tprintf("Res (%u), NoFrag (%u), MoreFrag (%u), FragOff (%u), ",
		FRAG_OFF_RESERVED_FLAG(frag_off) ? 1 : 0,
		FRAG_OFF_NO_FRAGMENT_FLAG(frag_off) ? 1 : 0,
		FRAG_OFF_MORE_FRAGMENT_FLAG(frag_off) ? 1 : 0,
		FRAG_OFF_FRAGMENT_OFFSET(frag_off));
	tprintf("CSum (0x%.4x) is %s", ntohs(ip->h_check),
		csum ? colorize_start_full(black, red) "bogus (!)"
		       colorize_end() : "ok");
	if (csum)
		tprintf("%s should be 0x%.4x%s", colorize_start_full(black, red),
			csum_expected(ip->h_check, csum), colorize_end());
	tprintf(" ]\n");

	memset(&sas, 0, sizeof(sas));
	sas.sin_family = PF_INET;
	sas.sin_addr.s_addr = ip->h_saddr;

	memset(&sad, 0, sizeof(sad));
	sad.sin_family = PF_INET;
	sad.sin_addr.s_addr = ip->h_daddr;

	if (geoip_working()) {
		tprintf("\t[ Geo (");
		if ((country = geoip4_country_name(sas))) {
			tprintf("%s", country);
			if ((region = geoip4_region_name(sas)))
				tprintf(" / %s", region);
			if ((city = geoip4_city_name(sas)))
				tprintf(" / %s", city);
		} else {
			tprintf("local");
		}
		tprintf(" => ");
		if ((country = geoip4_country_name(sad))) {
			tprintf("%s", country);
			if ((region = geoip4_region_name(sad)))
				tprintf(" / %s", region);
			if ((city = geoip4_city_name(sad)))
				tprintf(" / %s", city);
		} else {
			tprintf("local");
		}
		tprintf(") ]\n");
	}

	opts_len = max((uint8_t) ip->h_ihl, sizeof(*ip) / sizeof(uint32_t)) *
		   sizeof(uint32_t) - sizeof(*ip);

	for (opt = pkt_pull(pkt, opts_len); opt && opts_len > 0; opt++) {
		tprintf("   [ Option  Copied (%u), Class (%u), Number (%u)",
			IP_OPT_COPIED_FLAG(*opt) ? 1 : 0, IP_OPT_CLASS(*opt),
			IP_OPT_NUMBER(*opt));

		switch (*opt) {
		case IP_OPT_EOOL:
		case IP_OPT_NOP:
			tprintf(" ]\n");
			opts_len--;
			break;
		default:
			/*
			 * Assuming that EOOL and NOP are the only single-byte
			 * options, treat all other options as variable in
			 * length with a minimum of 2.
			 *
			 * TODO: option length might be incorrect in malformed packets,
			 *       check and handle that
			 */
			opt_len = *(++opt);
			if (opt_len > opts_len) {
				tprintf(", Len (%zd, invalid) ]\n", opt_len);
				goto out;
			} else
				tprintf(", Len (%zd) ]\n", opt_len);
			opts_len -= opt_len;
			tprintf("     [ Data hex ");
			for (opt_len -= 2; opt_len > 0; opt_len--)
				tprintf(" %.2x", *(++opt));
			tprintf(" ]\n");
			break;
		}
	}
out:
	/* cut off everything that is not part of IPv4 payload */
	/* XXX there could still be an Ethernet trailer included or others */

	pkt_trim(pkt, pkt_len(pkt) - min(pkt_len(pkt),
		 (ntohs(ip->h_tot_len) - ip->h_ihl * sizeof(uint32_t))));

	pkt_set_proto(pkt, &eth_lay3, ip->h_protocol);
}