Esempio n. 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;
}
Esempio n. 2
0
/* 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);
				

}
Esempio n. 3
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;
}
Esempio n. 4
0
int main(int argc, char *argv[])
{
   IPHEADER *ip_header = NULL;
   int      optval = 1;
   DWORD    dwLen = 0;
   char     packet[LS_MAX_PACKET_SIZE];
   int      iRet = 0;
   int      ip_header_size = 0;
   char     ipSrc[20], ipDest[20], thisIP[20];
   BOOL     bShowTCP = TRUE, bShowICMP = TRUE;

   // Check arguments
   if ( _argc > 1 )
   {
      if ( !_stricmp(argv[1], "icmp") )
         bShowTCP = FALSE;
      else if ( !_stricmp(argv[1], "tcp") )
         bShowICMP = FALSE;
      else
      {
         printf( "\nUsage lsniff [ICMP|TCP]\n" );
         exit(0);
      }
    }

    USocket us;
    us.init();

    us.create(AF_INET, SOCK_RAW, IPPROTO_IP);

     memset( thisIP, 0x00, sizeof(thisIP) );
     get_this_machine_ip(thisIP);
    struct   sockaddr_in sock_sniff;
    sock_sniff.sin_family = AF_INET;
    sock_sniff.sin_port = htons(0);
   // If your machine has more than one IP you might put another one instead thisIP value
    sock_sniff.sin_addr.s_addr = inet_addr(thisIP);

    us.bind((struct sockaddr *)&sock_sniff);

      // Set socket to promiscuous mode
    // setsockopt wont work ... dont even try it
    if ( WSAIoctl( us,
                  SIO_RCVALL,
                  &optval,
                  sizeof(optval),
                  NULL,
                  0,
                  &dwLen,
                  NULL,
                  NULL ) == SOCKET_ERROR )

    {
        printf( "Error: WSAIoctl  = %ld\n", WSAGetLastError() );
        exit(-3);
    }

    while ( TRUE )
    {
        memset( packet, 0x00, sizeof(packet) );

        iRet = us.recv( packet, LS_MAX_PACKET_SIZE);
        if ( iRet < sizeof(IPHEADER) )
            continue;

        ip_header = (IPHEADER *)packet;

        // I only want IPv4 not IPv6
        if ( LS_HI_PART(ip_header->ver_ihl) != 4 )
            continue;

        ip_header_size = LS_LO_PART(ip_header->ver_ihl);
        ip_header_size *= sizeof(DWORD); // size in 32 bits words

        // Checks the protocol IP is encapsulating
        memset( ipSrc, 0x00, sizeof(ipSrc) );
        memset( ipDest, 0x00, sizeof(ipDest) );
        translate_ip(ip_header->source_ip, ipSrc);
        translate_ip(ip_header->destination_ip, ipDest);

        // Read http://www.ietf.org/rfc/rfc1700.txt?number=1700
        switch( ip_header->protocol )
        {
            case 1: // ICMP
                if ( bShowICMP )
                {
                    printf("\n -------------------- // -------------------- ");
                    printf("\n IP Header:");
                    printf("\n   Source      IP: %s", ipSrc);
                    printf("\n   Destination IP: %s", ipDest);
                    printf("\n      ICMP Header:");

                    decode_icmp(&packet[ip_header_size]);
                }
                break;

            case 6: // TCP
                if ( bShowTCP )
                {
                    printf("\n -------------------- // -------------------- ");
                    printf("\n IP Header:");
                    printf("\n   Source      IP: %s", ipSrc);
                    printf("\n   Destination IP: %s", ipDest);
                    printf("\n      TCP Header:");

                    decode_tcp(&packet[ip_header_size]);
                }
                break;

            case 17: // UDP
                break;

            default:
                break;
        }

    } // end-while

    us.cleanup();

    getchar();

    return 0;
}