📄 165.htm
字号:
the ARP messages sent from hosts. <br>
<br>
Reconstruction of end to end sessions. tcpshow attempts <br>
to do this, but more sophisticated examples are the array <br>
of security tools which try to keep tabs on network <br>
connections. <br>
<br>
Monitoring network load. Probably one of the most <br>
practical uses, a lot of commercial products usualy use <br>
specialized hardware to accomplish this. <br>
<br>
2) RAW socket questions: <br>
------------------------ <br>
<br>
2.1) What is a RAW socket? <br>
<br>
<br>
The BSD socket API allows one to open a raw socket and bypass <br>
layers in the TCP/IP stack. Be warned that if an OS doesn't <br>
support correct BSD semantics (correct is used loosely here), <br>
you're going to have a hard time making it work. Below, an <br>
attempt is made to address some of the bugs or surprises <br>
you're in store for. On almost all sane systems only root <br>
(superuser) can open a raw socket. <br>
<br>
2.2) How do I use a raw socket? <br>
<br>
2.2.1) How do I send a TCP/IP packet through a raw <br>
socket? <br>
<br>
Depending on what you want to send, you initially open a <br>
socket and give it its type. <br>
<br>
sockd = socket(AF_INET,SOCK_RAW,<protocol>); <br>
<br>
You can choose from any protocol including IPPROTO_RAW. <br>
The protocol number goes into the IP header verbatim. <br>
IPPROTO_RAW places 0 in the IP header. <br>
<br>
<br>
Most systems have a socket option IP_HDRINCL which allows <br>
you to include your own IP header along with the rest of <br>
the packet. If your system doesn't have this option, you <br>
may or may not be able to include your own IP header. If <br>
it is available, you should use it as such: <br>
<br>
<br>
char on = 1; <br>
setsockopt(sockd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on)); <br>
<br>
Of course, if you don't want to include an IP header, you <br>
can always specify a protocol in the creation of the <br>
socket and slip your transport level header under it. <br>
<br>
You then build the packet and use a normal sendto(). <br>
<br>
2.2.2) How do I build a TCP/IP packet? <br>
<br>
Examples can be found at http://www.whitefang.com/rin/ <br>
which attempt to illustrate the details involved. They <br>
also illustrate some of the bugs mentioned below. <br>
<br>
<br>
Briefly, you need to actually write the packet out in <br>
memory and hand it over to the socket where it will <br>
hopefully fire it away and await more packets. <br>
<br>
2.2.3) How can I listen for packets with a raw socket? <br>
<br>
Traditionally the BSD socket API did not allow you to <br>
listen to just any incoming packet via a raw socket. <br>
Although Linux (2.0.30 was the last version I had a look <br>
at), did allow this, it has to do with their own <br>
implementation of the TCP/IP stack. Correct BSD semantics <br>
allow you to get some packets which match a certain <br>
category (see below). <br>
<br>
There's a logical reason behind this; for example TCP <br>
packets are always handled by the kernel. If the port is <br>
open, send a SYN-ACK and establish the connection, or <br>
send back a RST. On the other hand, some types of ICMP (I <br>
compiled a small list below), the kernel can't handle. <br>
Like an ICMP echo reply, is passed to a matching raw <br>
socket, since it was meant for a user program to receive <br>
it. <br>
<br>
The solution is to firewall that particular port if it <br>
was a UDP or TCP packet, and sniff it with a packet <br>
capturing API (a list is mentioned above). This prevents <br>
the TCP/IP stack from handling the packet, thus it will <br>
be ignored and you can handle it yourself without <br>
intervention. <br>
<br>
If you dont firewall it, and reply yourself you'll wind <br>
up having additional responses from your operating <br>
system! <br>
<br>
Here's a concise explanation of the semantics of a raw <br>
BSD socket, taken from a Usenet post by W. Richard <br>
Stevens <br>
<br>
From <rstevens@kohala.com> (Sun Jul 6 12:07:07 1997) : <br>
<br>
"The semantics of BSD raw sockets are: <br>
<br>
- TCP and UDP: no one other than the kernel gets these. <br>
<br>
<br>
- ICMP: a copy of each ICMP gets passed to each matching raw <br>
socket, except for a few that the kernel generates the reply <br>
for: ICMP echo request, timestamp request, and mask request. <br>
<br>
- IGMP: all of these get passed to all matching raw sockets. <br>
<br>
- all other protocols that the kernel doesn't deal with (OSPF, <br>
etc.): these all get passed to all matching raw sockets." <br>
<br>
After looking at the icmp_input() routine from the <br>
BSD4.4's TCP/IP stack, it seems the following ICMP types <br>
will be passed to matching raw sockets: <br>
<br>
Echo Reply: (0) <br>
<br>
Router Advertisement (9) <br>
<br>
Time Stamp Reply (13) <br>
<br>
Mask Reply (18) <br>
<br>
<br>
<br>
2.3) What bugs should I look out for when using a raw <br>
socket? <br>
<br>
2.3.1) IP header length/offset host/network byte <br>
(feature/bug?) <br>
<br>
Systems derived from 4.4BSD have a bug in which the <br>
ip_len and ip_off members of the ip header have to be <br>
set in host byte order rather than network byte order. <br>
Some systems may have fixed this. I've confirmed this <br>
bug has been fixed on OpenBSD 2.1. <br>
<br>
2.3.2) Transport header on Solaris 2.4/2.5 checksum <br>
weirdness. <br>
<br>
The previous workaround for this bug wasn't accurate, <br>
Michael Masino <mmasino@mitre.org> mailed me with his <br>
more accurate description of the work around. The <br>
following is a condensed version of his email (Thu, 19 <br>
Feb 1998): <br>
<br>
"I discovered that Solaris 2.5 attempts to calculate <br>
the TCP or UDP checksum when sending data via a raw <br>
socket. I also noted that if I filled in the correct <br>
checksum in the field, the transmitted packet had a <br>
checksum equal to the length of the data checksummed. <br>
If I was to tack a byte to the data portion, the <br>
checksum would go up by 1. However, if I set the <br>
checksum to 0, the transmitted packet had a TCP <br>
checksum of correct checksum + checksum length. <br>
<br>
The bottom line is, in order to send out a correct <br>
checksum, you have to fill in the checksum field with <br>
the length of the checksummed data. The previous work <br>
around mentioned in the FAQ, which was to set it to <br>
sizeof(struct tcphdr), wouldn't work if you had data in <br>
the packet. You must fill in the length of the TCP <br>
header (not the pseudo header), and the length of the <br>
data portion." <br>
<br>
I've yet to find an official document from SUN which <br>
describes this as a known bug, and/or mentions when it <br>
was fixed. <br>
<br>
<br>
I have had reports, that this does not occur in Solaris <br>
2.6 <br>
<br>
2.3.3) Further IP packet processing by Solaris 2.x and <br>
Irix 6.x. <br>
<br>
---------------------------------------------------------------- <br>
<br>
<br>
(Bug report from Lamont Granquist <br>
<lamontg@hitl.washington.edu> ) <br>
<br>
"SOCK_RAW on Irix 6.x and Solaris 2.x (2.5.1 and 2.6) <br>
both do some unwanted processing to IP packets before <br>
sticking them on the wire. Specifically, it forces the <br>
IP_DF (Don't Fragment) flag on, assigns a different IP <br>
id#, assigns a different TCP seq# and ack# and <br>
recomputes the checksums. I tried hacking your example <br>
code to include the IP_DF flag and it still assigns <br>
ID/seq/ack#'s and recomputes checksums." <br>
<br>
2.4) What are raw sockets commonly used for? <br>
-------------------------------------------- <br>
<br>
Various UNIX utilities use raw sockets, among them are: <br>
traceroute, ping, arp. Also, a lot of Internet security <br>
tools make use of raw sockets. However in the long run, <br>
raw sockets have proven bug ridden, unportable and <br>
limited in use. <br>
<br>
3) libpcap (A Portable Packet Capturing Library) <br>
------------------------------------------------ <br>
<br>
3.1) Why should I use libpcap, instead of using the <br>
native API on my operating system for packet capturing? <br>
<br>
libpcap was written so that applications could do <br>
packet capturing portably. Since it's system <br>
independent and supports numerous operating systems, <br>
your packet capturing application becomes more portable <br>
to various other systems. <br>
<br>
3.2) Does libpcap have any disadvantages, which I <br>
should be aware of? <br>
<br>
Yes, libpcap will only use in-kernel packet filtering <br>
when using BPF, which is found on BSD derived systems. <br>
This means any packet filters used on other operating <br>
systems which don't use BPF will be done in user space, <br>
thus losing out on a lot of speed and efficiency. This <br>
is not what you want, because packet loss can increase <br>
when sniffing a busy network. <br>
<br>
DEC OSF/1 has an API which has been extended to support <br>
BPF-style filters; libpcap does utilize this. <br>
<br>
In the future, libpcap may translate BPF style filters <br>
to other packet capturing facilities, but this has not <br>
been implemented yet as of version 0.3 <br>
<br>
Refer to question 1.4 to see how packet filters help in <br>
reliably monitoring your network. <br>
<br>
3.3) Where can I find example libpcap source code? <br>
<br>
A lot of the source code found at LBNL's ftp archive <br>
ftp://ftp.ee.lbl.gov/ uses libpcap. More specifically, <br>
ftp://ftp.ee.lbl.gov/tcpdump.tar.Z probably <br>
demonstrates libpcap to a large extent. <br>
<br>
4) List of contributors. <br>
------------------------ <br>
<br>
Thamer Al-Herbish <shadows@whitefang.com> <br>
W. Richard Stevens <rstevens@kohala.com> <br>
John W. Temples (III) <john@whitefang.com> <br>
Michael Masino <mmasino@mitre.org> <br>
Lamont Granquist <lamontg@hitl.washington.edu> <br>
Michael T. Stolarchuk <mts@rare.net> <br>
<br>
-- <br>
#################### <br>
# 遥 眺 淑 女 # <br>
####################################### <br>
# 君 子 好 球 # <br>
#################### <br>
</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="155.htm">上一层</a>][<a href="166.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 + -