예제 #1
0
// IP解包函数
int decode_ip(char *ipbuf, int protocol)
{
	switch(protocol)
	{
	case IPPROTO_TCP: // TCP类型数据包
		decode_tcp(ipbuf);
		break;
	case IPPROTO_UDP: // UDP类型数据包
		decode_udp(ipbuf);
		break;
	case IPPROTO_ICMP: // ICMP类型数据包
		decode_icmp(ipbuf);
		break;
	default:
		break;
	}
	return true;
}
예제 #2
0
void decode_ip6(const u_char * packet) {
  char str_sip[INET6_ADDRSTRLEN];
  char str_dip[INET6_ADDRSTRLEN];
  char buffer[128];

  char * yellow_plen, *yellow_nxt, *b_sip, *b_dip;
	const struct ip6_hdr * ip_t;
	ip_t = (struct ip6_hdr *)(packet);

  inet_ntop(AF_INET6, &(ip_t->ip6_src), str_sip, INET6_ADDRSTRLEN);
  inet_ntop(AF_INET6, &(ip_t->ip6_dst), str_dip, INET6_ADDRSTRLEN);

  b_sip = bold(str_sip);
  b_dip = bold(str_dip);

  sprintf(buffer, "%d", htons(ip_t->ip6_ctlun.ip6_un1.ip6_un1_plen));
  yellow_plen = yellow(buffer);
  sprintf(buffer, "%x", ip_t->ip6_ctlun.ip6_un1.ip6_un1_plen);
  yellow_nxt = yellow(buffer);

	V(1, "IPv6 - %s --> %s\n", b_sip, b_dip);
	uint32_t flow = htonl(ip_t->ip6_ctlun.ip6_un1.ip6_un1_flow);
	VV(1, "Payload Length : %s - Next Header : %s\n", yellow_plen, yellow_nxt);
			/* htons(ip_t->ip6_ctlun.ip6_un1.ip6_un1_plen), ip_t->ip6_ctlun.ip6_un1.ip6_un1_nxt); */
	VVV(1,"Version : %d - Traffic Class : %x - Flow Label : %x - Hop Limit : %d\n",
			flow >> 28, (flow & 0x0ff00000) >> 20, flow & 0x000fffff,	ip_t->ip6_ctlun.ip6_un1.ip6_un1_hlim);

	int offset = sizeof(struct ip6_hdr);
	switch(ip_t->ip6_ctlun.ip6_un1.ip6_un1_nxt) {
		case 0x06:
			decode_tcp(packet + offset);
			break;
		case 0x11:
			decode_udp(packet + offset);
			break;
	}

  free(yellow_plen);
  free(yellow_nxt);
  free(b_sip);
  free(b_dip);
}
예제 #3
0
파일: procpkt.c 프로젝트: jarrocha/psockets
/* main processing function */
void proc_packet(const u_char *data, u_int size)
{	
	struct ip_stat istat;
	u_int data_offs;
	u_int tcp_hdr_sz;
	u_int udp_hdr_sz;
	
	/* print captured bytes */
	printf("\n\nBytes Captured = [ %d ]\n", size);
	
	/* print L2 information */
	decode_ethernet(data);

	/* obtain IP protocol number for further decoding */
	decode_ip(data + ETHER_HDR_LEN, &istat);
	
	switch(istat.ip_prot) {
	case 1:
		decode_icmp(data + ETHER_HDR_LEN + istat.ip_len);
		data_offs = ETHER_HDR_LEN + istat.ip_len;
		break;
	case 6:
		tcp_hdr_sz = decode_tcp(data + ETHER_HDR_LEN + istat.ip_len);
		data_offs = ETHER_HDR_LEN + istat.ip_len + tcp_hdr_sz;
		break;
	case 17:
		udp_hdr_sz = decode_udp(data + ETHER_HDR_LEN + istat.ip_len);
		data_offs = ETHER_HDR_LEN + istat.ip_len + udp_hdr_sz;
		break;
	default:
		break;
	}


	/* print raw encapsulated data */
	praw(data + data_offs, size);
				

}
예제 #4
0
static void decode_ip  (const uint8_t *packet, size_t pk_len, int pk_layer) {
	union {
		const struct myiphdr *i;
		const uint8_t *d;
	} i_u;
	uint16_t fragoff=0, totlen=0, ipid=0, chksum=0, c_chksum=0;
	uint32_t saddr=0, daddr=0;
	size_t opt_len=0;
	int bad_cksum=0;

	i_u.d=packet;
	r_u.i.flags=0;

	if (pk_len < sizeof(struct myiphdr)) {
		ERR("short ip packet");
		return;
	}

	if (i_u.i->ihl < 5) {
		ERR("ihl is less than 5, this packet is likely confused/damaged");
		return;
	}

	ipid=ntohs(i_u.i->id);
	fragoff=ntohs(i_u.i->frag_off);
	totlen=ntohs(i_u.i->tot_len);
	chksum=ntohs(i_u.i->check);
	/* XXX everything expects addresses in network order */
	saddr=i_u.i->saddr;
	daddr=i_u.i->daddr;

	/* precalculated ip-pseudo header for transport layer checksumming */
	ipph.saddr=saddr;
	ipph.daddr=daddr;
	ipph.zero=0;
	ipph.proto=i_u.i->protocol;
	ipph.len=0;

	opt_len=(i_u.i->ihl - (sizeof(struct myiphdr) / 4)) * 4;

	if (fragoff & IP_OFFMASK) {
		ERR("likely bad: (is DF set? perhaps we need it) ignoring fragmented packet");
		return;
	}

	if (totlen > pk_len && pk_layer == 1) {
		/* this packet has an incorrect ip packet length, stop processing */
		ERR("likely bad: packet has incorrect ip length, skipping it [ip total length claims %u and we have " STFMT, totlen, pk_len);
		return;
	}
	else if (pk_layer == 3 && totlen > pk_len) {
		totlen=pk_len;
	}

	if (pk_len > totlen) {
		/*
		 * there is trailing junk past the end of the ip packet, save a pointer to it,
		 * and its length, then update pk_len
		 */
		DBG(M_PKT, "packet has trailing junk, saving a pointer to it and its length " STFMT, pk_len - totlen);
		trailgarbage=packet + totlen;
		trailgarbage_len=pk_len - totlen;
		pk_len=totlen;
	}

	if ((opt_len + sizeof(struct myiphdr)) > pk_len) {
		DBG(M_PKT, "IP options seem to overlap the packet size, truncating and assuming no ip options");
		opt_len=0; /* must be a trick, assume no options then, in case this is a damaged ip header is under a icmp reply */
	}

	if ((c_chksum=do_ipchksum(packet, opt_len + sizeof(struct myiphdr))) != 0) {
		DBG(M_PKT, "bad cksum, ipchksum returned %u", c_chksum);
		bad_cksum=1;
	}

	if (ISDBG(M_PKT) || GET_SNIFF()) {
		char frag_flags[32];
		char src_addr[32], dst_addr[32];
		struct in_addr ia;

		ia.s_addr=saddr;
		sprintf(src_addr, "%s", inet_ntoa(ia));

		ia.s_addr=daddr;
		sprintf(dst_addr, "%s", inet_ntoa(ia));

		CLEAR(frag_flags);
		if (fragoff & IP_DF) {
			strcat(frag_flags, "DF ");
		}
		if (fragoff & IP_MF) {
			strcat(frag_flags, "MF ");
		}
		if (fragoff & IP_RF) {
			strcat(frag_flags, "RF ");
		}

		INF("IP  : ihl %u (opt len " STFMT ") size " STFMT " version %u tos 0x%02x tot_len %u ipid %u frag_off %04x %s",
		i_u.i->ihl, opt_len, pk_len, i_u.i->version, i_u.i->tos, totlen, ipid, fragoff & IP_OFFMASK, frag_flags);
		INF("IP  : ttl %u protocol `%s' chksum 0x%04x%s IP SRC %s IP DST %s",
		i_u.i->ttl, str_ipproto(i_u.i->protocol), chksum, (bad_cksum == 1 ? " [bad cksum]" : " [cksum ok]"), src_addr, dst_addr);
	}

	if (pk_layer == 1) {
		r_u.i.proto=i_u.i->protocol;
		r_u.i.host_addr=saddr;
		r_u.i.trace_addr=saddr;
		r_u.i.send_addr=daddr;
		r_u.i.ttl=i_u.i->ttl;
		if (bad_cksum) {
			r_u.i.flags |= REPORT_BADNETWORK_CKSUM;
		}
	}
	else if (pk_layer == 3) { /* this is a ip header within an icmp header normally */
		/*
		 * this was the _original host_ we sent to according
		 * to the icmp error reflection
		 */
		r_u.i.host_addr=daddr;
	}
	else {
		ERR("decode IP at unknown layer %d", pk_layer);
		return;
	}

	if (opt_len > 0) {
		decode_ipopts(packet + sizeof(struct myiphdr), opt_len);
	}

	pk_len -= sizeof(struct myiphdr) + opt_len;
	packet += sizeof(struct myiphdr) + opt_len;

	if (pk_len) {
		switch (i_u.i->protocol) {
			case IPPROTO_TCP:
				decode_tcp(packet, pk_len, ++pk_layer);
				break;

			case IPPROTO_UDP:
				decode_udp(packet, pk_len, ++pk_layer);
				break;

			case IPPROTO_ICMP:
				decode_icmp(packet, pk_len, ++pk_layer);
				break;

			default:
				ERR("filter is broken?");
				break;
		}
	}

	return;
}