Discussion:
telnet not giving up after RST packet?
(too old to reply)
Josef Moellers
2013-03-10 17:47:12 UTC
Permalink
Hi,

I'm trying to teach a small AtMega32 with an ENC28J60 TCP/IP, to use the
setup as a COM-to-LAN adapter.
I have successfully implemented (rudimentary versions) of DHCP, ARP and
ICMP and have now started to process TCP packets.
Note: I *do* know there's ethersex and friends out there, but I get
greater satisfaction when "suddenly" the ARP-table of my notebook shows
the data of my AtMega ;-) Maybe once this is running, I'll rebase on
ethersex, but, at this time, I'm having lots of fun.

As a first step, I try to just refuse a connection. I process the
request, extract source addresses (MAC and IP) and source and
destination ports and the packet's sequence number and then build a
reply with the correct acknowledgement number (sequence number plus 1)
and RST and ACK set. Wireshark says it's OK.
However, when I telnet to the AtMega, telnet doesn't stop trying to
connect while when I telnet to another Linux box, telnet immediately
gives up after the first ACK|RST and tells me
"telnet: Unable to connect to remote host: Connection refused"

When I compare the two RST packets, I can see no obvious difference,
other than
a) trailing ff's (Linux) vs. trailing 00's (AtMega)
b) an IP "Identification" field of 0 (Linux) vs. 5 (AtMega)

What makes telnet give up on the Linux box and not give up on the AtMega?

Thanks,

Josef
Rick Jones
2013-03-12 19:02:48 UTC
Permalink
Post by Josef Moellers
When I compare the two RST packets, I can see no obvious difference,
other than
a) trailing ff's (Linux) vs. trailing 00's (AtMega)
b) an IP "Identification" field of 0 (Linux) vs. 5 (AtMega)
What makes telnet give up on the Linux box and not give up on the AtMega?
Good question. I suspect though that it isn't so much that telnet
isn't giving up as it is the connect() call being made by telnet isn't
giving up. That is, if you were to try something other than telnet,
you would see the same behaviour. If you could post the full tcpdump
output of the two segments, perhaps folks will see something you might
have missed.

rick jones
--
web2.0 n, the dot.com reunion tour...
these opinions are mine, all mine; HP might not want them anyway... :)
feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...
Josef Moellers
2013-03-12 20:39:36 UTC
Permalink
Post by Rick Jones
Post by Josef Moellers
When I compare the two RST packets, I can see no obvious difference,
other than
a) trailing ff's (Linux) vs. trailing 00's (AtMega)
b) an IP "Identification" field of 0 (Linux) vs. 5 (AtMega)
What makes telnet give up on the Linux box and not give up on the AtMega?
Good question. I suspect though that it isn't so much that telnet
isn't giving up as it is the connect() call being made by telnet isn't
Yep, that's what I saw in the strace: connect() hangs.
Post by Rick Jones
giving up. That is, if you were to try something other than telnet,
you would see the same behaviour. If you could post the full tcpdump
output of the two segments, perhaps folks will see something you might
have missed.
I've found it myself: The TCP header checksum must include parts of the
IP Header! Thus, my checksum was bad and the TCP layer discarded the RST
packet.

Thanks anyway,

Josef
Jorgen Grahn
2013-03-13 12:46:23 UTC
Permalink
On Tue, 2013-03-12, Josef Moellers wrote:
...
Post by Josef Moellers
I've found it myself: The TCP header checksum must include parts of the
IP Header! Thus, my checksum was bad and the TCP layer discarded the RST
packet.
'tcpdump -v' would have told you this, at least on the side receiving
the RST. That side would also have recorded a bad checksum discard in
'netstat -s'.

/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Josef Moellers
2013-03-13 13:47:35 UTC
Permalink
Post by Jorgen Grahn
...
Post by Josef Moellers
I've found it myself: The TCP header checksum must include parts of the
IP Header! Thus, my checksum was bad and the TCP layer discarded the RST
packet.
'tcpdump -v' would have told you this, at least on the side receiving
the RST. That side would also have recorded a bad checksum discard in
'netstat -s'.
I used wireshark, but it only said:

Checksum: 0xf89a [validation disabled]
[Good Checksum: False]
[Bad Checksum: False]

I now (since yesterday afternoon ;-) have Fall/Stevens "TCP/IP
Illustrated 2nd Ed" and it says "The TCP Checksum field covers the TCP
header and data and *some fields in the IP header*, using a
pseudo-header computation ...". I should have taken that more serious
and should have read the RFC more thoroughly. I have added this code
fragement:

checksum = 0;
checksum = update_checksum(checksum, my_IP[0], my_IP[1]);
checksum = update_checksum(checksum, my_IP[2], my_IP[3]);
checksum = update_checksum(checksum, source_IP[0], source_IP[1]);
checksum = update_checksum(checksum, source_IP[2], source_IP[3]);
checksum = update_checksum(checksum, hi8(PROT_TCP), lo8(PROT_TCP));
checksum = update_checksum(checksum, hi8(5*4), lo8(5*4));

setup_TCP_header(destination_port, /* Source Port */
source_port, /* Destination Port */
acknowledgement_number, /* Sequence Number */
sequence_number, /* Acknowledgement Number */
RST | ACK, /* Flags */
checksum); /* No data */
-eoc-

I'll keep "tcpdump" in mind and use it when I take the next steps:
connection establishment and then data transfers. I gather that
maintaining the sequence numbers (seq and ack) will be tricky.

Thanks again,

Josef
Barry Margolin
2013-03-13 16:49:03 UTC
Permalink
Post by Josef Moellers
Post by Jorgen Grahn
...
Post by Josef Moellers
I've found it myself: The TCP header checksum must include parts of the
IP Header! Thus, my checksum was bad and the TCP layer discarded the RST
packet.
'tcpdump -v' would have told you this, at least on the side receiving
the RST. That side would also have recorded a bad checksum discard in
'netstat -s'.
Checksum: 0xf89a [validation disabled]
[Good Checksum: False]
[Bad Checksum: False]
Wireshark is just a graphical version of tcpdump. I think they both
disable validating checksums if your system offloads it to the NIC.
--
Barry Margolin
Arlington, MA
Jorgen Grahn
2013-03-13 19:38:15 UTC
Permalink
Post by Barry Margolin
Post by Josef Moellers
Post by Jorgen Grahn
...
Post by Josef Moellers
I've found it myself: The TCP header checksum must include parts of the
IP Header! Thus, my checksum was bad and the TCP layer discarded the RST
packet.
'tcpdump -v' would have told you this, at least on the side receiving
the RST. That side would also have recorded a bad checksum discard in
'netstat -s'.
Checksum: 0xf89a [validation disabled]
[Good Checksum: False]
[Bad Checksum: False]
That's most likely a setting in Wireshark. Look under the preferences
for IPv4, IPv6, TCP and UDP. You might also want to disable the IPv4
"I will reassemble the fragments for you and pretend there was no
fragmentation" option.
Post by Barry Margolin
Wireshark is just a graphical version of tcpdump. I think they both
disable validating checksums if your system offloads it to the NIC.
Or display an incorrect one. But that's why I specified "at least on
the side receiving". No NIC that I'm aware of messes up the checksums
on Rx traffic, but it's common for Tx checksums to be created in
hardware, long after tcpdump got its preliminary copy of the frame.

/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Loading...