📄 547.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>apue</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center"> ● UNIX网络编程 (BM: clown) </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="537.htm">上一层</a>][<a href="548.htm">下一篇</a>]
<hr><p align="left"><small>发信人: guru (好读书,不求甚解), 信区: UNP <br>
标 题: Packet Capture With libpcap and other (2) <br>
发信站: UNIX编程 (2001年08月04日11:16:00 星期六), 站内信件 <br>
<br>
Capturing Our First Packet <br>
<br>
-------------------------------------------------------------------------------- <br>
(P.S. Hey peeps, sorry this was such a long time coming... graduating and gettin <br>
g a job is a major pain in the ass... as things settle down I will certainly hav <br>
e more time to work on this :-) :-) :-) ) <br>
Well now we sort of know the nature of packet capture, we have identified that w <br>
e do in fact have an interface to pull things from, how about we go ahead and gr <br>
ab a packet! <br>
"Just give me the damn example and let me hack...", you cry <br>
Very well..... Here you go.. download from here.. testpcap1.c or just cut and pa <br>
ste below. <br>
<br>
/*************************************************** <br>
* file: testpcap1.c <br>
* Date: Thu Mar 08 17:14:36 MST 2001 <br>
* Author: Martin Casado <br>
* Location: LAX Airport (hehe) <br>
* <br>
* <br>
* Simple single packet capture program <br>
*****************************************************/ <br>
#include <stdio.h> <br>
#include <stdlib.h> <br>
#include <pcap.h> /* if this gives you an error try pcap/pcap.h */ <br>
#include <errno.h> <br>
#include <sys/socket.h> <br>
#include <netinet/in.h> <br>
#include <arpa/inet.h> <br>
#include <netinet/if_ether.h> /* includes net/ethernet.h */ <br>
<br>
int main(int argc, char **argv) <br>
{ <br>
int i; <br>
char *dev; <br>
char errbuf[PCAP_ERRBUF_SIZE]; <br>
pcap_t* descr; <br>
const u_char *packet; <br>
struct pcap_pkthdr hdr; /* pcap.h */ <br>
struct ether_header *eptr; /* net/ethernet.h */ <br>
<br>
u_char *ptr; /* printing out hardware header info */ <br>
<br>
/* grab a device to peak into... */ <br>
dev = pcap_lookupdev(errbuf); <br>
<br>
if(dev == NULL) <br>
{ <br>
printf("%s\n",errbuf); <br>
exit(1); <br>
} <br>
<br>
printf("DEV: %s\n",dev); <br>
<br>
/* open the device for sniffing. <br>
<br>
pcap_t *pcap_open_live(char *device,int snaplen, int prmisc,int to_ms, <br>
char *ebuf) <br>
<br>
snaplen - maximum size of packets to capture in bytes <br>
promisc - set card in promiscuous mode? <br>
to_ms - time to wait for packets in miliseconds before read <br>
times out <br>
errbuf - if something happens, place error string here <br>
<br>
Note if you change "prmisc" param to anything other than zero, you will <br>
get all packets your device sees, whether they are intendeed for you or <br>
not!! Be sure you know the rules of the network you are running on <br>
before you set your card in promiscuous mode!! */ <br>
<br>
descr = pcap_open_live(dev,BUFSIZ,0,-1,errbuf); <br>
<br>
if(descr == NULL) <br>
{ <br>
printf("pcap_open_live(): %s\n",errbuf); <br>
exit(1); <br>
} <br>
<br>
<br>
/* <br>
grab a packet from descr (yay!) <br>
u_char *pcap_next(pcap_t *p,struct pcap_pkthdr *h) <br>
so just pass in the descriptor we got from <br>
our call to pcap_open_live and an allocated <br>
struct pcap_pkthdr */ <br>
<br>
<br>
packet = pcap_next(descr,&hdr); <br>
<br>
if(packet == NULL) <br>
{/* dinna work *sob* */ <br>
printf("Didn't grab packet\n"); <br>
exit(1); <br>
} <br>
<br>
/* struct pcap_pkthdr { <br>
struct timeval ts; time stamp <br>
bpf_u_int32 caplen; length of portion present <br>
bpf_u_int32; lebgth this packet (off wire) <br>
} <br>
*/ <br>
<br>
printf("Grabbed packet of length %d\n",hdr.len); <br>
printf("Recieved at ..... %s\n",ctime((const time_t*)&hdr.ts.tv_sec)); <br>
printf("Ethernet address length is %d\n",ETHER_HDR_LEN); <br>
<br>
/* lets start with the ether header... */ <br>
eptr = (struct ether_header *) packet; <br>
<br>
<br>
/* Do a couple of checks to see what packet type we have..*/ <br>
if (ntohs (eptr->ether_type) == ETHERTYPE_IP) <br>
{ <br>
printf("Ethernet type hex:%x dec:%d is an IP packet\n", <br>
ntohs(eptr->ether_type), <br>
ntohs(eptr->ether_type)); <br>
}else if (ntohs (eptr->ether_type) == ETHERTYPE_ARP) <br>
{ <br>
printf("Ethernet type hex:%x dec:%d is an ARP packet\n", <br>
ntohs(eptr->ether_type), <br>
ntohs(eptr->ether_type)); <br>
}else { <br>
printf("Ethernet type %x not IP", ntohs(eptr->ether_type)); <br>
exit(1); <br>
} <br>
<br>
/* THANK YOU RICHARD STEVENS!!! RIP*/ <br>
ptr = eptr->ether_dhost; <br>
i = ETHER_ADDR_LEN; <br>
printf(" Destination Address: "); <br>
do{ <br>
printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++); <br>
}while(--i>0); <br>
printf("\n"); <br>
<br>
ptr = eptr->ether_shost; <br>
i = ETHER_ADDR_LEN; <br>
printf(" Source Address: "); <br>
do{ <br>
printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++); <br>
}while(--i>0); <br>
printf("\n"); <br>
<br>
return 0; <br>
} <br>
<br>
Well, that wasn't too bad was it?! Lets give her a test run .. <br>
<br>
[root@pepe libpcap]# ./a.out <br>
DEV: eth0 <br>
Grabbed packet of length 76 <br>
Recieved at time..... Mon Mar 12 22:23:29 2001 <br>
<br>
Ethernet address length is 14 <br>
Ethernet type hex:800 dec:2048 is an IP packet <br>
Destination Address: 0:20:78:d1:e8:1 <br>
Source Address: 0:a0:cc:56:c2:91 <br>
[root@pepe libpcap]# <br>
<br>
After typing a.out I jumped into another terminal and tried to ping www.google.c <br>
om. The output captured the ICMP packet used to ping www.google.com. If you don' <br>
t know exactly what goes on under the covers of a network you may be curios how <br>
the computer <br>
obtained the destination ethernet address. Aha! You don't actually think that th <br>
e destination address of the ethernet packet is the same as the machine at www.g <br>
oogle.com do you!? <br>
"..uhhh of course not",you stammer <br>
The destination address is most likely your gateway... aka the computer that tie <br>
s your network to the internet. The packet must first find its way to your gatew <br>
ay which will then forward it to a router or make its own routing decisions as t <br>
o where the <br>
packet should go next. Lets do a quick sanity check to see if we in fact are sen <br>
ding to the router.... ho hum!! You can use the route command to get your gatewa <br>
ys IP. <br>
[root@pepe libpcap]# /sbin/route <br>
Kernel IP routing table <br>
Destination Gateway Genmask Flags Metric Ref Use Iface <br>
192.168.1.0 * 255.255.255.0 U 0 0 0 eth0 <br>
127.0.0.0 * 255.0.0.0 U 0 0 0 lo <br>
default 192.168.1.1 0.0.0.0 UG 0 0 0 eth0 <br>
<br>
and then use the arpcommand to get the cached ethernet address... <br>
[root@pepe libpcap]# /sbin/arp <br>
Address HWtype HWaddress Flags Mask Iface <br>
192.168.1.1 ether 00:20:78:D1:E8:01 C eth0 <br>
<br>
If your gateway is not in your arp cache, try and telnet to it, and then retry t <br>
he arp command. Hey, by the way, this could certainly be the long, painful, bloo <br>
dy, ignorant way of getting the gateway hardware address but I couldn't think of <br>
another <br>
way... <br>
<br>
Notice that my gateway's address matches the destination address of the packet t <br>
hat I captured. All packets leaving my machine that are not sent to a machine on <br>
my network must go through the gateway. Alas!!!! We have still not answered the <br>
<br>
question... "how did my computer know the gateway hardware address"? Let me then <br>
digress for a moment. My computer knows the IP address of the gateway and is ce <br>
rtainly savy enough to send outbound packets to it. As you can see from the hand <br>
y-dandy arp <br>
command there is an internal table (the arp cache) which maps IP addresses to ha <br>
rdware addresses. "AAAUUGHH!!! BUT HOW DID IT CONSTUCT THE ARP CACHE!!!!", you s <br>
cream! <br>
<br>
Hardware addresses on ethernet are obtained using the Address Resolution Protoco <br>
l or ARP. ARP is is described in RFC826 which can be found... Here! Pretty much <br>
what happenes is when you send a packet, the kernel first checks the arp cache t <br>
o see if <br>
you already have the hardware address for the higher level destination address. <br>
If not, the kernel sends an arp request which is of type... ETHERTYPE_ARP which <br>
is defined in net/ethernet.h as follows. <br>
<br>
#define ETHERTYPE_ARP 0x0806 /* Address resolution */ <br>
<br>
On recieveing the arp packet, the machine with the high level address (in my cas <br>
e the gateway) will reply with an arp reply, basically saying.. I DO! send it he <br>
re! Shall we test it out?! (to bad... I'm gonna do it anyways :-P) <br>
[root@pepe libpcap]# /sbin/arp -n # look at arp cache <br>
Address HWtype HWaddress Flags Mask Iface <br>
192.168.1.1 ether 00:20:78:D1:E8:01 C eth0 <br>
<br>
[root@pepe libpcap]# /sbin/arp -n -d 192.168.1.1 #delete gateqay entrance <br>
[root@pepe libpcap]# /sbin/arp -n #make sure gateway hardware addy is empty <br>
<br>
Address HWtype HWaddress Flags Mask Iface <br>
192.168.1.1 (incomplete) eth0 <br>
[root@pepe libpcap]# ./a.out <br>
DEV: eth0 <br>
Grabbed packet of length 42 <br>
Recieved at time..... Tue Mar 13 00:36:49 2001 <br>
<br>
Ethernet address length is 14 <br>
Ethernet type hex:806 dec:2054 is an ARP packet <br>
Destination Address: ff:ff:ff:ff:ff:ff <br>
Source Address: 0:a0:cc:56:c2:91 <br>
[root@pepe libpcap]#echo YAY <br>
<br>
So as you can see, once the hardware address was removed the the cache, my compu <br>
ter needed to send an arp request to broadcast (i.e. ff:ff:ff:ff:ff:ff) looking <br>
for the owner of the higher level address, in this case IP 192.168.1.1. What do <br>
you think <br>
would happen if you cleared your arp cache and modified testpcap1.c to capture 2 <br>
packets?! Hey I know why don't you try it :-P~~~~ <br>
<br>
Lets now disect the packet by checking out <net/ethernet.h> right now we are not <br>
concerned with the network or transport protocol, we just want to peer into the <br>
ethernet headers.... Lets say that we are runnig at 10Mb/s... <br>
<br>
/* 10Mb/s ethernet header */ <br>
struct ether_header <br>
{ <br>
u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */ <br>
u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */ <br>
u_int16_t ether_type; /* packet type ID field */ <br>
} __attribute__ ((__packed__)); <br>
<br>
So it looks like the first ETH_ALEN bytes are the destination ethernet address ( <br>
look at linux/if_ether.h for the definition of ETH_ALEN :-) of the packet (presu <br>
medly your machine). The next ETH_ALEN bytes are the source. Finally, the last w <br>
ord is the <br>
packet type. Here are the protocol ID's on my machine from net/ethernet.h <br>
<br>
/* Ethernet protocol ID's */ <br>
#define ETHERTYPE_PUP 0x0200 /* Xerox PUP */ <br>
#define ETHERTYPE_IP 0x0800 /* IP */ <br>
#define ETHERTYPE_ARP 0x0806 /* Address resolution */ <br>
#define ETHERTYPE_REVARP 0x8035 /* Reverse ARP */ <br>
<br>
For the purpose of this tutorial I will be focusing on IP and perhaps a little b <br>
it on ARP... the truth is I have no idea what the hell Xerox PUP is. <br>
<br>
Ack! Allright so where are we now? We know the most basic of methods for grabbin <br>
g a packet. We covered how hardware addresses are resolved and what a basic ethe <br>
rnet packet looks like. Still we are using a sad, sad 1% of the functionality of <br>
libpcap, <br>
and we haven't even begun to peer into the packets themselves (other than the ha <br>
rdware headers) so much to do and so little time :-) As you can probably tell by <br>
now, it would be near impossible to do any real protocol analysis with a progra <br>
m that <br>
simply captures one packet at a time. What we really want to do is write a simpl <br>
e packet capturing engine that will nab as many packets as possible while filter <br>
ing out those we dont want. In the next section we will construct a simple packe <br>
t capturing <br>
engine which will aid us in packet dissection (eww, that kinda sounds gross) lat <br>
er on. <br>
<br>
<br>
-------------------------------------------------------------------------------- <br>
<br>
[prev] [socket home ] [next] <br>
-- <br>
telnet apue.dhs.org 2323 or http://apue.dhs.org <br>
APUE:UNIX环境编程 <br>
UNP:UNIX网络编程 <br>
UKP:UNIX内核编程 <br>
BIBLE:高手传经 <br>
FTPDOC:资源共享 <br>
※ 来源:·UNIX编程 www.tiaozhan.com/unixbbs/·[FROM: 202.114.36.176] <br>
</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="537.htm">上一层</a>][<a href="548.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</table>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -