[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