|
Also in FreeBSD Basics: |
In last week's article, we used the tcpdump utility to capture the packets involved in a telnet session and then examined the resulting dump file. This week, I'd like to continue through the output of this file to see what else we can discover regarding a typical TCP connection.
When we looked at the packets involved in the TCP 3-way handshake, we paid particular attention to the flags field in the TCP header. The only time a packet's SYN flag is set is if it is one of the first two packets involved in the 3-way handshake. This means that whenever a packet arrives with its SYN flag set, someone is trying to create a TCP connection. Notice in today's output that every TCP header has an acknowledgment number and the ACK flag is set; the only
exception to this rule is found in the very first packet involved in the 3-way handshake. That is, if a packet arrives with the SYN flag set but not the ACK flag, that packet is trying to initiate a connection to one of your network services; the destination port field will tell you which service they are trying to connect to.
Let's take one last look at that first packet from last week's 3-way handshake:
tcpshow < dump
<snip to just show this one packet>
-------------------------------------------------------------
Packet 10
TIME: 10:25:36.854420 (6.232947)
LINK: 00:00:B4:3C:56:40 -> 00:50:BA:DE:36:33 type=IP
IP: 10.0.0.2 -> 10.0.0.1 hlen=20 TOS=10 dgramlen=44 id=0013
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=26A7
TCP: port blackjack -> telnet seq=3205630181 ack=0000000000
hlen=24 (data=0) UAPRSF=000010 wnd=16384 cksum=7814 urg=0
DATA: <No data>
--------------------------------------------------------------
Note that this packet has no acknowledgement (ack=0000000000) and the only TCP flag that has been set (UAPRSF=000010) to 1 is the S or SYN flag. This packet came from 10.0.0.2 and it is trying to establish a connection to (->) the telnet port on 10.0.0.1.
TCP also has an established procedure for gracefully ending a TCP connection. As you may have guessed, it involves the use of the FIN flag. Either end of a TCP connection can ask to close the connection at any time. In our example, I typed the word exit as soon as I had established the telnet connection and had successfully logged in. Let's see what packets were involved in this transaction. Again, I've snipped the output of the tcpshow command to just show these packets:
------------------------------------------------------------
Packet 72
TIME: 10:25:43.153131 (1.174173)
LINK: 00:00:B4:3C:56:40 -> 00:50:BA:DE:36:33 type=IP
IP: 10.0.0.2 -> 10.0.0.1 hlen=20 TOS=10 dgramlen=41 id=0037
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=2686
TCP: port blackjack -> telnet seq=3205630360 ack=1746120351
hlen=20 (data=1) UAPRSF=011000 wnd=17520 cksum=0EE3 urg=0
DATA: e
-------------------------------------------------------------
This is the first packet we've seen that actually contains some data. Even though I typed the word exit from the computer 10.0.0.2, each character I typed was sent in a separate packet. The first packet contained the letter "e".
-------------------------------------------------------------
Packet 73
TIME: 10:25:43.153685 (0.000554)
LINK: 00:50:BA:DE:36:33 -> 00:00:B4:3C:56:40 type=IP
IP: 10.0.0.1 -> 10.0.0.2 hlen=20 TOS=10 dgramlen=41 id=956E
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=914E
TCP: port telnet -> blackjack seq=1746120351 ack=3205630361
hlen=20 (data=1) UAPRSF=011000 wnd=17520 cksum=0EE2 urg=0
DATA: e
-------------------------------------------------------------
This is the response from 10.0.0.1. Note that it acknowledged receipt of my packet as it incremented my sequence number by one. Strangely, it also returned the same data; this told the telnet client to echo the letter "e" onto my terminal.
-------------------------------------------------------------
Packet 74
TIME: 10:25:43.248672 (0.094987)
LINK: 00:00:B4:3C:56:40 -> 00:50:BA:DE:36:33 type=IP
IP: 10.0.0.2 -> 10.0.0.1 hlen=20 TOS=10 dgramlen=40 id=0038
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=2686
TCP: port blackjack -> telnet seq=3205630361 ack=1746120352
hlen=20 (data=0) UAPRSF=010000 wnd=17520 cksum=73EA urg=0
DATA: <No data>
-------------------------------------------------------------
Packet 75
TIME: 10:25:43.456449 (0.207777)
LINK: 00:00:B4:3C:56:40 -> 00:50:BA:DE:36:33 type=IP
IP: 10.0.0.2 -> 10.0.0.1 hlen=20 TOS=10 dgramlen=41 id=0039
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=2684
TCP: port blackjack -> telnet seq=3205630361 ack=1746120352
hlen=20 (data=1) UAPRSF=011000 wnd=17520 cksum=FBE0 urg=0
DATA: x
-------------------------------------------------------------
The next two packets again came from me at 10.0.0.2. First, I acknowledged receipt of the packet from 10.0.0.1, then I sent the letter "x" in its own packet. I won't bore you with the outputs of packets 76 to 84 as they simply repeat this process of individually sending and echoing the letters "x", "i", and "t", and acknowledging that each packet was received.
Packet 85 contains data from the telnet application running on 10.0.0.1. This application is now aware that I typed the word exit. It responds by sending me the word logout to be echoed to my terminal:
-------------------------------------------------------------
Packet 85
TIME: 10:25:44.258982 (0.011001)
LINK: 00:50:BA:DE:36:33 -> 00:00:B4:3C:56:40 type=IP
IP: 10.0.0.1 -> 10.0.0.2 hlen=20 TOS=10 dgramlen=48 id=9573
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=9142
TCP: port telnet -> blackjack seq=1746120359 ack=3205630366
hlen=20 (data=8) UAPRSF=011001 wnd=17520 cksum=1D70 urg=0
DATA: logout.
-------------------------------------------------------------
Did you also notice the TCP flags field in this packet? The FIN flag has been set. Not only did the telnet application echo the word logout to my screen, it also indicated that it would "finish up" this TCP connection. At this point, my machine responded with two packets. The first acknowledged receipt of this packet, and the second agreed to the closing of the TCP connection by setting its own FIN flag:
-------------------------------------------------------------
Packet 86
TIME: 10:25:44.259292 (0.000310)
LINK: 00:00:B4:3C:56:40 -> 00:50:BA:DE:36:33 type=IP
IP: 10.0.0.2 -> 10.0.0.1 hlen=20 TOS=10 dgramlen=40 id=003F
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=267F
TCP: port blackjack -> telnet seq=3205630366 ack=1746120368
hlen=20 (data=0) UAPRSF=010000 wnd=17512 cksum=73DD urg=0
DATA: <No data>
-------------------------------------------------------------
Packet 87
TIME: 10:25:44.260137 (0.000845)
LINK: 00:00:B4:3C:56:40 -> 00:50:BA:DE:36:33 type=IP
IP: 10.0.0.2 -> 10.0.0.1 hlen=20 TOS=10 dgramlen=40 id=0040
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=267E
TCP: port blackjack -> telnet seq=3205630366 ack=1746120368
hlen=20 (data=0) UAPRSF=010001 wnd=17520 cksum=73D4 urg=0
DATA: <No data>
-------------------------------------------------------------
The final packet in our dump file was the very last acknowledgment from 10.0.0.1:
-------------------------------------------------------------
Packet 88
TIME: 10:25:44.260231 (0.000094)
LINK: 00:50:BA:DE:36:33 -> 00:00:B4:3C:56:40 type=IP
IP: 10.0.0.1 -> 10.0.0.2 hlen=20 TOS=10 dgramlen=40 id=9574
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=9149
TCP: port telnet -> blackjack seq=1746120368 ack=3205630367
hlen=20 (data=0) UAPRSF=010000 wnd=17519 cksum=73D5 urg=0
DATA: <No data>
-------------------------------------------------------------
|
We've looked at the very beginning and very end of the TCP connection. Now let's take a look at some of the stuff that happened in between. Once the TCP connection had been established, the rest of the packets either contained data from the telnet application or were acknowledgements that the data had been received. For example, packet 21 shows the terminal type being used for this telnet connection:
-------------------------------------------------------------
Packet 21
TIME: 10:25:36.917010 (0.021554)
LINK: 00:00:B4:3C:56:40 -> 00:50:BA:DE:36:33 type=IP
IP: 10.0.0.2 -> 10.0.0.1 hlen=20 TOS=10 dgramlen=77 id=0019
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=2680
TCP: port blackjack -> telnet seq=3205630297 ack=1746119656
hlen=20 (data=37) UAPRSF=011000 wnd=17520 cksum=5F8D urg=0
DATA: .. .115200,115200....'.......CONS25..
-------------------------------------------------------------
The ethereal utility shows even more detail regarding the data that was passed between the telnet daemon and the telnet client. Let's see how this same packet is viewed by ethereal. I've snipped the output of the packet to just show the telnet data:
Telnet
Suboption Begin: Terminal Speed
Here's my Terminal Speed
Value: 115200,115200
Command: Suboption End
Suboption Begin: New Environment Option
Here's my New Environment Option
Value:
Command: Suboption End
Suboption Begin: Terminal Type
Here's my Terminal Type
Value: CONS25
Command: Suboption End
Several other packets were sent between the telnet daemon and the telnet application before the "login" prompt appeared. This data was used to negotiate the various telnet options, window size, terminal type, and terminal speed. Even though this data was never displayed on my screen, it is interesting to note that what was happening behind the scenes was still captured by the tcpdump utility. The tcpshow utility didn't bother to interpret this data, but the ethereal utility did. I've snipped the output of the pertinent packets to indicate who sent the packet and the data that was sent in each packet:
Frame 13 (84 on wire, 84 captured)
Source: biko (10.0.0.2)
Destination: genisis (10.0.0.1)
Telnet
Command: Do Encryption Option
Command: Will Encryption Option
Command: Do Suppress Go Ahead
Command: Will Terminal Type
Command: Will Negotiate About Window Size
Command: Will Terminal Speed
Command: Will Remote Flow Control
Command: Will Linemode
Command: Will New Environment Option
Command: Do Status
Frame 14 (57 on wire, 57 captured)
Source: genisis (10.0.0.1)
Destination: biko (10.0.0.2)
Telnet
Command: Do Authentication Option
Frame 15 (60 on wire, 60 captured)
Source: biko (10.0.0.2)
Destination: genisis (10.0.0.1)
Telnet
Command: Won't Authentication Option
Frame 16 (92 on wire, 92 captured)
Source: genisis (10.0.0.1)
Destination: biko (10.0.0.2)
Telnet
Command: Will Encryption Option
Command: Do Encryption Option
Suboption Begin: Encryption Option
Send your Encryption Option
Command: Suboption End
Command: Will Suppress Go Ahead
Command: Do Terminal Type
Command: Do Negotiate About Window Size
Command: Do Terminal Speed
Command: Do Remote Flow Control
Command: Do Linemode
Command: Do New Environment Option
Command: Will Status
Frame 17 (130 on wire, 130 captured)
Source: biko (10.0.0.2)
Destination: genisis (10.0.0.1)
Telnet
Suboption Begin: Encryption Option
Send your Encryption Option
Command: Suboption End
Suboption Begin: Negotiate About Window Size
Here's my Negotiate About Window Size
Value: P\000\031
Command: Suboption End
Suboption Begin: Linemode
Send your Linemode
Data: \022\000
Command: Suboption End
Command: Do Suppress Go Ahead
Frame 18 (60 on wire, 60 captured)
Source: genisis (10.0.0.1)
Destination: biko (10.0.0.2)
Telnet
Command: Do X Display Location
Command: Do Environment Option
Frame 19 (60 on wire, 60 captured)
Source: biko (10.0.0.2)
Destination: genisis (10.0.0.1)
Telnet
Command: Won't X Display Location
Command: Won't Environment Option
Frame 20 (72 on wire, 72 captured)
Source: genisis (10.0.0.1)
Destination: biko (10.0.0.2)
Telnet
Suboption Begin: Terminal Speed
Send your Terminal Speed
Command: Suboption End
Suboption Begin: New Environment Option
Send your New Environment Option
Command: Suboption End
Suboption Begin: Terminal Type
Send your Terminal Type
Command: Suboption End
Frame 22 (57 on wire, 57 captured)
Source: genisis (10.0.0.1)
Destination: biko (10.0.0.2)
Telnet
Command: Do Echo
Frame 23 (60 on wire, 60 captured)
Source: biko (10.0.0.2)
Destination: genisis (10.0.0.1)
Telnet
Command: Won't Echo
Frame 24 (72 on wire, 72 captured)
Source: genisis (10.0.0.1)
Destination: biko (10.0.0.2)
Telnet
Command: Will Echo
Suboption Begin: Remote Flow Control
Here's my Remote Flow Control
Value:
Command: Suboption End
Suboption Begin: Remote Flow Control
Send your Remote Flow Control
Command: Suboption End
Command: Don't Linemode
Frame 25 (60 on wire, 60 captured)
Source: biko (10.0.0.2)
Destination: genisis (10.0.0.1)
Telnet
Command: Do Echo
Command: Won't Linemode
Frame 26 (110 on wire, 110 captured)
Source: genisis (10.0.0.1)
Destination: biko (10.0.0.2)
Telnet
Suboption Begin: Linemode
Send your Linemode
Data: \022\200
Command: Suboption End
|
You'll remember from last week that when I demonstrated the telnet session, several bits of information were displayed on my screen. Those bits of information came from the telnet application on 10.0.0.1 and we can use the tcpshow utility to see it being sent in the data fields of the following packets:
-------------------------------------------------------------
Packet 28
TIME: 10:25:37.040099 (0.000144)
LINK: 00:50:BA:DE:36:33 -> 00:00:B4:3C:56:40 type=IP
IP: 10.0.0.1 -> 10.0.0.2 hlen=20 TOS=10 dgramlen=90 id=955C
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=912F
TCP: port telnet -> blackjack seq=1746119733 ack=3205630343
hlen=20 (data=50) UAPRSF=011000 wnd=17520 cksum=2DFE urg=0
DATA: ...
FreeBSD/i386 (istar.ca) (ttyp0)...
...
login:
-------------------------------------------------------------
Packet 51
TIME: 10:25:39.140175 (0.012092)
LINK: 00:50:BA:DE:36:33 -> 00:00:B4:3C:56:40 type=IP
IP: 10.0.0.1 -> 10.0.0.2 hlen=20 TOS=10 dgramlen=51 id=9564
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=914E
TCP: port telnet -> blackjack seq=1746119790 ack=3205630352
hlen=20 (data=11) UAPRSF=011000 wnd=17520 cksum=815F urg=0
DATA: .
Password:
-------------------------------------------------------------
Packet 66
TIME: 10:25:41.680125 (0.020455)
LINK: 00:50:BA:DE:36:33 -> 00:00:B4:3C:56:40 type=IP
IP: 10.0.0.1 -> 10.0.0.2 hlen=20 TOS=10 dgramlen=150 id=956B
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=90E4
TCP: port telnet -> blackjack seq=1746119801 ack=3205630360
hlen=20 (data=110) UAPRSF=011000 wnd=17520 cksum=AE21 urg=0
DATA: .
Warning: your password expires on Thu Mar 8 17:31:47 2001.
Last login: Sun Mar 4 10:23:04 from 127.0.0.1.
-------------------------------------------------------------
Packet 68
TIME: 10:25:41.779159 (0.000175)
LINK: 00:50:BA:DE:36:33 -> 00:00:B4:3C:56:40 type=IP
IP: 10.0.0.1 -> 10.0.0.2 hlen=20 TOS=10 dgramlen=283 id=956C
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=905E
TCP: port telnet -> blackjack seq=1746119911 ack=3205630360
hlen=20 (data=243) UAPRSF=011000 wnd=17520 cksum=30D1 urg=0
DATA: Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
.
The Regents of the University of California. All rights re
served..
.
FreeBSD 4.2-RELEASE (SOUND) #0: Tue Dec 12 20:01:29 EST 2000
.
.
Welcome to FreeBSD 4.2!!!.
You have mail..
-------------------------------------------------------------
Packet 70
TIME: 10:25:41.879117 (0.000163)
LINK: 00:50:BA:DE:36:33 -> 00:00:B4:3C:56:40 type=IP
IP: 10.0.0.1 -> 10.0.0.2 hlen=20 TOS=10 dgramlen=237 id=956D
MF/DF=0/1 frag=0 TTL=64 proto=TCP cksum=908B
TCP: port telnet -> blackjack seq=1746120154 ack=3205630360
hlen=20 (data=197) UAPRSF=011000 wnd=17520 cksum=DDC6 urg=0
DATA: .
Everybody is somebody else's weirdo..
-- Dykstra.
.[1mgenisis@~.[m:
-------------------------------------------------------------
You may have noticed there were many packets that I snipped out between Packet 28, which echoed the login prompt; and Packet 51, wwhich echoed the password prompt. These packets required sending the login name of "genisis" one character at a time. Again, each of these characters needed to be individually acknowledged and echoed to my screen.
The packets between Packet 51 and Packet 66 contained my password -- again sent one character at a time. These packets were acknowledged but the characters were not echoed to my terminal. This is one of the reasons why you don't run a tcpdump on someone else's network. If someone happens to login over the network, you will be able to capture and view the packets which contain the login and password prompts followed by the user's login name and password. At that point, it won't matter how good the password policy is on that network.
Finally, Packets 66, 68, and 70 showed the rest of the data from the telnet application that was echoed to my terminal during the session.
So far, we've only examined the packets that contained TCP headers. However, TCP was not the only protocol involved during this telnet session; the protocols ARP and ICMP also played a role.
Let's start with ARP or the Address Resolution Protocol. We've learned that before we can send an IP packet, it must first be encapsulated into a frame, in our case, an Ethernet frame. To create an Ethernet frame, the MAC (Media Access Control) address of the destination NIC must first be determined. A special packet known as an ARP packet is used to determine this MAC address. Since ARP knows the IP address of the destination, it can send out a broadcast packet, meaning all nodes must read the packet, asking for the MAC address associated with that IP address. Running tcpdump with the r switch summarizes this procedure nicely:
tcpdump -r dump
<snip output to just show packets 2 and 3>
10:25:28.608173 arp who-has 10.0.0.1 tell 10.0.0.2
10:25:28.608285 arp reply 10.0.0.1 is-at 0:50:ba:de:36:33
Because 10.0.0.2 wished to initiate a TCP connection with 10.0.0.1, it sent out an ARP request asking who was using that IP address. You'll notice that it received a reply that included the MAC address associated with 10.0.0.1.
Let's look at a more detailed view of these two packets using tcpshow:
tcpshow < dump
<snip to just show packets 2 and 3>
-------------------------------------------------------------
Packet 2
TIME: 10:25:28.608173 (4.305875)
LINK: 00:00:B4:3C:56:40 -> FF:FF:FF:FF:FF:FF type=ARP
ARP: htype=Ethernet ptype=IP hlen=6 plen=4 op=request
sender-MAC-addr=00:00:B4:3C:56:40 sender-IP-address=10.0.0.2
target-MAC-addr=00:00:00:00:00:00 target-IP-address=10.0.0.1
-------------------------------------------------------------
Packet 3
TIME: 10:25:28.608285 (0.000112)
LINK: 00:50:BA:DE:36:33 -> 00:00:B4:3C:56:40 type=ARP
ARP: htype=Ethernet ptype=IP hlen=6 plen=4 op=response
sender-MAC-addr=00:50:BA:DE:36:33 sender-IP-address=10.0.0.1
target-MAC-addr=00:00:B4:3C:56:40 target-IP-address=10.0.0.2
-------------------------------------------------------------
Notice the MAC addresses used in the LINK section of Packet 2. The source address is the MAC address of 10.0.0.2. This is needed so the response can make it back to the correct NIC. Since 10.0.0.2 does not know the MAC address of 10.0.0.1 (finding that MAC address is the whole point of this ARP packet), it uses a MAC address of FF:FF:FF:FF:FF:FF. A MAC address of all Fs indicates a broadcast packet, meaning all NICs must process the packet, but only the NIC the data pertains to should respond.
Also note that an ARP packet is different than an IP packet. It only contains one header and no data. There is a diagram of an ARP packet here.
The hardware type (htype) indicates this ARP request is looking for an Ethernet hardware address, that is, a MAC address. The protocol type (ptype) indicates the protocol address in use is an IP address. The operation (op) field indicates this is an ARP request. It then contains the known MAC and IP addresses. Because the target MAC address is the unknown value, it has been set to all zeros.
Packet 3 contains the response to Packet 2. Its op field indicates that it is a response, and it contains all of the necessary MAC addresses.
Let's wait until next week to see what role ICMP played in our telnet session as the ICMP protocol deserves an article of its own.
Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.
Read more FreeBSD Basics columns.
Return to the BSD DevCenter.
Copyright © 2009 O'Reilly Media, Inc.