[Winpcap-users] Retriving the data from UDP packet

Guy Harris guy at alum.mit.edu
Sat Sep 22 00:06:35 GMT 2007


On Sep 21, 2007, at 11:32 AM, Prashant Kasal wrote:

>        I was wondering could anybody help me out to solve my issue  
> as I'm new to networking programming using WinPcap. My task is to  
> retrieve the IPv4 header information and UDP header information and  
> also data of the UDP packet. I'm using WinPCap library for doing the  
> above task, fortunately I found a sample code in WinPcap site  
> regarding this problem( http://www.winpcap.org/docs/docs_41b/html/group__wpcap__tut4.html) 
>  but the code outputs only the header information of both UDP and  
> IPv4 address,

That's at

	http://www.winpcap.org/docs/docs_41b/html/group__wpcap__tut6.html

not at

	http://www.winpcap.org/docs/docs_41b/html/group__wpcap__tut4.html
	
>  along with these info I need data also.

The data is whatever follows the UDP header.

> When I debugged the code I came across pcap_next_ex() API where I am  
> supposed to get packet data also, but it returns empty string.

The routines in libpcap/WinPcap that provide packet data (pcap_loop()  
and pcap_dispatch(), which call your callback routine and pass it a  
pointer to packet data; pcap_next(), which returns a pointer to packet  
data; and pcap_next_ex(), which fills in a pointed-to variable with a  
pointer to packet data) provide you with the raw packet data, which  
isn't the "data of the UDP packet", in the sense of the UDP payload,  
it's the entire link-layer packet, including any link-layer pseudo- 
header or header, the IP header if it's an IP packet, the UDP header  
if it's a UDP packet, etc..

I.e., what pcap_next_ex() fills in is exactly the same as what  
pcap_loop() and pcap_dispatch() pass to the callback, and what  
pcap_next() returns; you have to do the same link-layer header  
processing, IP header processing, and UDP header processing with the  
data you get from pcap_next_ex() that you have to do with the data  
passed to a callback from pcap_loop() or pcap_dispatch().

In addition, the UDP data is *not* necessarily a string; it's an array  
of raw bytes, which might or might not be a text string (it probably  
isn't - most protocols that run over UDP aren't text protocols; for  
that matter).

At

	http://www.tcpdump.org/pcap.htm

is another tutorial example.  It handles TCP, rather than UDP; to  
handle UDP, you'd want to change the got_packet() routine to

	static int count = 1;                   /* packet counter */
	
	/* declare pointers to packet headers */
	const struct sniff_ethernet *ethernet;  /* The ethernet header [1] */
	const struct sniff_ip *ip;              /* The IP header */
	const struct sniff_udp *udp;            /* The UDP header */
	const char *payload;                    /* Packet payload */

	int size_ip;
	int size_payload;
	
	printf("\nPacket number %d:\n", count);
	count++;
	
	/* define ethernet header */
	ethernet = (struct sniff_ethernet*)(packet);
	
	/* define/compute ip header offset */
	ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
	size_ip = IP_HL(ip)*4;
	if (size_ip < 20) {
		printf("   * Invalid IP header length: %u bytes\n", size_ip);
		return;
	}

	/* print source and destination IP addresses */
	printf("       From: %s\n", inet_ntoa(ip->ip_src));
	printf("         To: %s\n", inet_ntoa(ip->ip_dst));
	
	/* determine protocol */	
	switch(ip->ip_p) {
		case IPPROTO_TCP:
			printf("   Protocol: TCP\n");
			return;
		case IPPROTO_UDP:
			printf("   Protocol: UDP\n");
			break;
		case IPPROTO_ICMP:
			printf("   Protocol: ICMP\n");
			return;
		case IPPROTO_IP:
			printf("   Protocol: IP\n");
			return;
		default:
			printf("   Protocol: unknown\n");
			return;
	}
	
	/*
	 *  OK, this packet is UDP.
	 */
	
	/* define/compute tcp header offset */
	udp = (struct sniff_udp*)(packet + SIZE_ETHERNET + SIZE_UDP);
	
	printf("   Src port: %d\n", ntohs(udp->uh_sport));
	printf("   Dst port: %d\n", ntohs(udp->uh_dport));
	
	/* define/compute udp payload (segment) offset */
	payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + SIZE_UDP);
	
	/* compute udp payload (segment) size */
	size_payload = ntohs(ip->ip_len) - (size_ip + SIZE_UDP);
         if (size_payload > ntohs(udp->uh_ulen))
                 size_payload = ntohs(udp->uh_ulen);
	
	/*
	 * Print payload data; it might be binary, so don't just
	 * treat it as a string.
	 */
	if (size_payload > 0) {
		printf("   Payload (%d bytes):\n", size_payload);
		print_payload(payload, size_payload);
	}

	return;

and replace the "struct sniff_tcp" structure with

/* UDP header */

struct sniff_udp {
         u_short uh_sport;               /* source port */
         u_short uh_dport;               /* destination port */
         u_short uh_ulen;                /* udp length */
         u_short uh_sum;                 /* udp checksum */

};

#define SIZE_UDP        8               /* length of UDP header */		


More information about the Winpcap-users mailing list