26.07.2018 Views

hacking-the-art-of-exploitation

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Now that <strong>the</strong> headers are defined as structures, we can write a program<br />

to decode <strong>the</strong> layered headers <strong>of</strong> each packet. But before we do, let’s talk<br />

about libpcap for a moment. This library has a function called pcap_loop(),<br />

which is a better way to capture packets than just looping on a pcap_next()<br />

call. Very few programs actually use pcap_next(), because it’s clumsy and<br />

inefficient. The pcap_loop() function uses a callback function. This means<br />

<strong>the</strong> pcap_loop() function is passed a function pointer, which is called every<br />

time a packet is captured. The prototype for pcap_loop() is as follows:<br />

int pcap_loop(pcap_t *handle, int count, pcap_handler callback, u_char *args);<br />

The first argument is <strong>the</strong> pcap’s handle, <strong>the</strong> next one is a count <strong>of</strong> how<br />

many packets to capture, and <strong>the</strong> third is a function pointer to <strong>the</strong> callback<br />

function. If <strong>the</strong> count argument is set to -1, it will loop until <strong>the</strong> program<br />

breaks out <strong>of</strong> it. The final argument is an optional pointer that will get<br />

passed to <strong>the</strong> callback function. Naturally, <strong>the</strong> callback function needs to<br />

follow a certain prototype, since pcap_loop() must call this function. The<br />

callback function can be named whatever you like, but <strong>the</strong> arguments must<br />

be as follows:<br />

void callback(u_char *args, const struct pcap_pkthdr *cap_header, const u_char *packet);<br />

decode_sniff.c<br />

#include <br />

#include "<strong>hacking</strong>.h"<br />

#include "<strong>hacking</strong>-network.h"<br />

The first argument is just <strong>the</strong> optional argument pointer from <strong>the</strong> last<br />

argument to pcap_loop(). It can be used to pass additional information to <strong>the</strong><br />

callback function, but we aren’t going to be using this. The next two arguments<br />

should be familiar from pcap_next(): a pointer to <strong>the</strong> capture header and a<br />

pointer to <strong>the</strong> packet itself.<br />

The following example code uses pcap_loop() with a callback function to<br />

capture packets and our header structures to decode <strong>the</strong>m. This program will<br />

be explained as <strong>the</strong> code is listed.<br />

void pcap_fatal(const char *, const char *);<br />

void decode_e<strong>the</strong>rnet(const u_char *);<br />

void decode_ip(const u_char *);<br />

u_int decode_tcp(const u_char *);<br />

void caught_packet(u_char *, const struct pcap_pkthdr *, const u_char *);<br />

int main() {<br />

struct pcap_pkthdr cap_header;<br />

const u_char *packet, *pkt_data;<br />

char errbuf[PCAP_ERRBUF_SIZE];<br />

char *device;<br />

Networking 235

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!