📄 549.htm
字号:
fprintf(stdout," destination: %s " <br>
,ether_ntoa(eptr->ether_dhost)); <br>
<br>
/* check to see if we have an ip packet */ <br>
if (ntohs (eptr->ether_type) == ETHERTYPE_IP) <br>
{ <br>
fprintf(stdout,"(IP)"); <br>
}else if (ntohs (eptr->ether_type) == ETHERTYPE_ARP) <br>
{ <br>
fprintf(stdout,"(ARP)"); <br>
}else if (ntohs (eptr->ether_type) == ETHERTYPE_REVARP) <br>
{ <br>
fprintf(stdout,"(RARP)"); <br>
}else { <br>
fprintf(stdout,"(?)"); <br>
exit(1); <br>
} <br>
fprintf(stdout,"\n"); <br>
<br>
return eptr->ether_type; <br>
} <br>
<br>
You can download the full code here. <br>
Whew! Ok got that out of the way, currently we have a relatively simple framewor <br>
k to print out an ethernet header (if we want) and then handle the type. Lets st <br>
art by looking at the IP header. <br>
<br>
IP: <br>
OK lets wip out our handy dandy RFC's (791 in this case) and take a look at what <br>
it has to say about IP headers... here is a copy of the section which decsribes <br>
the header. <br>
<br>
<br>
3.1 Internet Header Format <br>
<br>
A summary of the contents of the internet header follows: <br>
<br>
0 1 2 3 <br>
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 <br>
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br>
|Version| IHL |Type of Service| Total Length | <br>
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br>
| Identification |Flags| Fragment Offset | <br>
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br>
| Time to Live | Protocol | Header Checksum | <br>
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br>
| Source Address | <br>
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br>
| Destination Address | <br>
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br>
| Options | Padding | <br>
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br>
<br>
Example Internet Datagram Header <br>
<br>
Figure 4. <br>
<br>
Note that each tick mark represents one bit position. <br>
<br>
Now lets peak at netinet/ip.h <br>
struct ip <br>
{ <br>
#if __BYTE_ORDER == __LITTLE_ENDIAN <br>
unsigned int ip_hl:4; /* header length */ <br>
unsigned int ip_v:4; /* version */ <br>
#endif <br>
#if __BYTE_ORDER == __BIG_ENDIAN <br>
unsigned int ip_v:4; /* version */ <br>
unsigned int ip_hl:4; /* header length */ <br>
#endif <br>
u_int8_t ip_tos; /* type of service */ <br>
u_short ip_len; /* total length */ <br>
u_short ip_id; /* identification */ <br>
u_short ip_off; /* fragment offset field */ <br>
#define IP_RF 0x8000 /* reserved fragment flag */ <br>
#define IP_DF 0x4000 /* dont fragment flag */ <br>
#define IP_MF 0x2000 /* more fragments flag */ <br>
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ <br>
u_int8_t ip_ttl; /* time to live */ <br>
u_int8_t ip_p; /* protocol */ <br>
u_short ip_sum; /* checksum */ <br>
struct in_addr ip_src, ip_dst; /* source and dest address */ <br>
}; <br>
<br>
Cool, they seem to match up perfectly.... this of course would be fine to use, b <br>
ut I prefer to follow the tcpdump method of handling the version and header leng <br>
th. <br>
struct my_ip <br>
u_int8_t ip_vhl; /* header length, version */ <br>
#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4) <br>
#define IP_HL(ip) ((ip)->ip_vhl & 0x0f) <br>
u_int8_t ip_tos; /* type of service */ <br>
u_int16_t ip_len; /* total length */ <br>
u_int16_t ip_id; /* identification */ <br>
u_int16_t ip_off; /* fragment offset field */ <br>
#define IP_DF 0x4000 /* dont fragment flag */ <br>
#define IP_MF 0x2000 /* more fragments flag */ <br>
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ <br>
u_int8_t ip_ttl; /* time to live */ <br>
u_int8_t ip_p; /* protocol */ <br>
u_int16_t ip_sum; /* checksum */ <br>
struct in_addr ip_src,ip_dst; /* source and dest address */ <br>
}; <br>
<br>
Lets take a first stab at peaking into the IP header... consider the following f <br>
unction (full source here). <br>
u_char* handle_IP <br>
(u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* <br>
packet) <br>
{ <br>
const struct my_ip* ip; <br>
u_int length = pkthdr-&len; <br>
u_int hlen,off,version; <br>
int i; <br>
<br>
int len; <br>
<br>
<br>
/* jump pass the ethernet header */ <br>
ip = (struct my_ip*)(packet + sizeof(struct ether_header)); <br>
length -= sizeof(struct ether_header); <br>
<br>
/* check to see we have a packet of valid length */ <br>
if (length < sizeof(struct my_ip)) <br>
{ <br>
printf("truncated ip %d",length); <br>
return NULL; <br>
} <br>
<br>
len = ntohs(ip->ip_len); <br>
hlen = IP_HL(ip); /* header length */ <br>
version = IP_V(ip);/* ip version */ <br>
<br>
/* check version */ <br>
if(version != 4) <br>
{ <br>
fprintf(stdout,"Unknown version %d\n",version); <br>
return NULL; <br>
} <br>
<br>
<br>
/* check header length */ <br>
if(hlen < 5 ) <br>
{ <br>
fprintf(stdout,"bad-hlen %d \n",hlen); <br>
} <br>
<br>
/* see if we have as much packet as we should */ <br>
if(length < len) <br>
printf("\ntruncated IP - %d bytes missing\n",len - length); <br>
<br>
/* Check to see if we have the first fragment */ <br>
off = ntohs(ip->ip_off); <br>
if((off &apm; 0x1fff) == 0 )/* aka no 1's in first 13 bits */ <br>
{/* print SOURCE DESTINATION hlen version len offset */ <br>
fprintf(stdout,"IP: "); <br>
fprintf(stdout,"%s ", <br>
inet_ntoa(ip->ip_src)); <br>
fprintf(stdout,"%s %d %d %d %d\n", <br>
inet_ntoa(ip->ip_dst), <br>
hlen,version,len,off); <br>
} <br>
<br>
<br>
return NULL; <br>
} <br>
<br>
Given a clean arp cache this is what the output looks like on my machine, when I <br>
try to telnet to 134.114.90.1... <br>
[root@localhost libpcap]# ./a.out 5 <br>
ETH: 0:10:a4:8b:d3:b4 ff:ff:ff:ff:ff:ff (ARP) 42 <br>
ETH: 0:20:78:d1:e8:1 0:10:a4:8b:d3:b4 (ARP) 60 <br>
ETH: 0:10:a4:8b:d3:b4 0:20:78:d1:e8:1 (IP) 74 <br>
IP: 192.168.1.100 134.114.90.1 5 4 60 16384 <br>
ETH: 0:20:78:d1:e8:1 0:10:a4:8b:d3:b4 (IP) 60 <br>
IP: 134.114.90.1 192.168.1.100 5 4 40 0 <br>
<br>
Lets try and reconstruct the conversation shall we? <br>
<br>
my computer: Who has the gateways IP (192.168.1.100)? <br>
ETH: 0:10:a4:8b:d3:b4 ff:ff:ff:ff:ff:ff (ARP) 42 <br>
gateway: I do!! <br>
ETH: 0:20:78:d1:e8:1 0:10:a4:8b:d3:b4 (ARP) 60 <br>
my computer(through gateway): Hello Mr. 134.114.90.1 can we talk? <br>
ETH: 0:10:a4:8b:d3:b4 0:20:78:d1:e8:1 (IP) 74 IP: 192.168.1.100 134.114.90.1 5 4 <br>
60 16384 <br>
60 16384 <br>
134.114.90.1: No, piss off, I'm not listening <br>
ETH: 0:20:78:d1:e8:1 0:10:a4:8b:d3:b4 (IP) 60 IP: 134.114.90.1 192.168.1.100 5 4 <br>
40 0 <br>
I have admittedly skipped TONS of information in a rush to provide you with code <br>
to display the IP header (thats all you really wanted anyways wasn't it :-). Th <br>
at said, if you are lost don't worry, I will slow down and attempt to describe w <br>
hat exactly <br>
is going on. All that you really need to know up to this point is.. <br>
<br>
All packets are sent via ethernet <br>
The ethernet header defines the protocol type of the packet it is carrying <br>
IP is one of these types (as well as ARP and RARP) <br>
The IP header is confusing as all hell <br>
So before getting too far into packet dissection it would probably benefit us to <br>
regress a bit and talk about IP... <br>
"awww but.... that sounds boring!",you say. Well if you are really anxious I wou <br>
ld suggest you grab the tcpdump source and take a look at the following methods <br>
... :-) <br>
ether_if_print (print-ether.c) <br>
ip_print (print-ip.c) <br>
tcp_print (print-tcp.c) <br>
udp_print (print-udp.c) <br>
I've also found the sniffit source to be a great read. <br>
<br>
*Note to self... Insert comprehensive, enlightening IP discussion here :-) :-)* <br>
<br>
--------%< ----------------- to be continued..... <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="550.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 + -