I am facing a problem with TCP and I suspect that the checksum calculated by Wireshark for TCP is not right, so I would need something which allows me to calculate the checksum for the packets captured. Is there something to do that?
Thanks.
You can use scapy.
Load the packets from your pcap file
packets = rdpcap("tst.pcap")
Select one packet
packet = packets[0]
Select the TCP segment
tcpSegment = packet[TCP]
Read the stored checksum
hex(tcpSegment.chksum)
Then to compute the checksum, delete the stored checksum
del tcpSegment.chksum
And show the new computed checksum
tcpSegment.show2()
Related
When a packet is sent from source to destination,it has to pass by through several routers and each router decreases the value of TTL of packet by 1. So header checksum is to be recomputed at each router since one of the header field i.e. TTL surely changes. Then how does the destination verifies the presence of error by calculating the checksum ,though the checksum it got has changed than that of checksum of source side?
When the packet leaves the source, it has some initial TTL and (hopefully) a valid checksum.
When the packet arrives at a router, the router checks only the IPv4 header checksum. If it is incorrect, it drops the packet. If it is correct, it (1) decrements the TTL; (2) checks that the TTL is higher than zero (otherwise the packet is dropped) and (3) computes and fills in the new IP header checksum.
Interestingly, the new checksum can be computed directly from the old checksum and the old and new value of the TTL, with some clever math: https://www.rfc-editor.org/rfc/rfc1624 so reading the whole IPv4 header again is not necessary.
Note that IPv6 has a hop limit (which works like the TTL) but no header checksum.
Every router calculates and verifies the checksum before routing, if there is a mismatch the router drops the datagram.
I'm new to LUA and have successfully written a dissector to dissect a custom protocol over TCP (for data being sent over network between 2 modules in my application) for non-fragmented TCP case.
But this doesn't work when the TCP data is sent split into multiple packets. After some research, found out that the only way to do this in lua script is to use pkt.desegment_len and pkt.desegment_offset. But with modified code, when I open a given pcap in wireshark (with this dissector lua script plugged in) I see those pkt info of those packets as - [TCP segment of a reassembled PDU] and nothing else in the details (tree) section.
My protocol contains few header fields, where 6th and 7th bytes denote the length of given packet.
Here is my code, let me know if I'm missing something or can somebody give me a sample working script for this reassembled TCP packet handling.
function p_Kod_CALLP_MED.dissector (buf, pkt, root)
local desiredPacketLen = buf(5,2):uint()
-- if not enough data indicate how much more we need
if desiredPacketLen > buf:len() then
pkt.desegment_len = desiredPacketLen - buf:len()
pkt.desegment_offset = 0
return
end
-- have more than needed so set offset for next dissection
if buf:len() >= desiredPacketLength then
pkt.desegment_len = DESEGMENT_ONE_MORE_SEGMENT
pkt.desegment_offset = desiredPacketLength
end
-- Remaining logic like adding to the tree etc
How do TCP knows which is the last packet of a large file (that was segmented by tcp) in the scenario that the connection is kept-established. (like ftp or sending mp3 on yahoo messenger)
I mean how does it know which packet carries data of one.mp3 and which packet carries data of another.mp3 ??
Anyone ?
Thank you
There are at least 2 possible approaches.
Declare upfront how much data you're going to send. Something like a packet that declares Sending a message that's 4008 bytes long
The second approach is to use a terminating sequence (nastier to process)
So the receiver:
Tries to read the declared amount or
Scans for the terminating sequence
TCP is a stream protocol and fragmentation should be transparent to a TCP application. It operates on streams of data, never packets. A stream is assembled to its intended order using the sequence numbers. The sequence of bytes send by application is encapsulated in tcp segments. The stream is recreated on the receiver side before data is delivered to the application.
The IP protocol can do fragmentation.
Each TCP segment goes to the IP layer and may be fragmented there. Segment is reassembled by collecting all of the packets and offset field from the header is used to put it in the right place.
What is the need for having checksum at various layers ? For eg, there is a checksum in TCP layer and again in IP layer and also Ethernet layer has it.
Is not it sufficient to have checksum at one layer ?
All three layers are needed, for multiple reasons:
IP does not always run over ethernet (imagine IP over RS-232 serial, something every Cisco and Unix box can do)
IP does not checksum the data
TCP packets can be reassembled incorrectly from IP packets and fragments that each have perfect checksums
Even if reassembled correctly, software or other errors could be introduced in the layers between IP and TCP
Even if all software functions correctly, and TCP/IP is over ethernet, the limited size of the checksums can be accidently correct (and will be at some point, given enough packets) in the face of persistent errors, so having more than one checksum is helpful.
Every time a new header is introduced there is more to checksum, and the new layer can't see the header bits of the layer below.
Ethernet checksum is a hop to hop checksum - meaning that it is recomputed everytime the Ethernet header fields change. TCP/UDP checksum is a end-to-end checksum meaning it is computed by the sender and verified by the receiver. TCP/UDP checksums cover the entire segment. IP checksum covers only the header. Ethernet CRC covers the entire frame.
The designers of IPv6 decided it's not necessary at all those layers and removed it in favor of checksums at other layers (such as those you mentioned).
I understood that the tcp checksum calculates automaticly if we write 0 in the function libnet_build_tcp, so why do we need libnet_do_checksum?
I have an error, when I am trying to build a new packet. A regulat TCP packet(SYN,ACK) works fine, but an HTTP packet don't work, beacuse a tcp checksum error.
Do I have to use libnet_do_checksum?
You use libnet_do_checksum() when you want to manually calculate the checksum, so you can check it before sending, for example.
Are you sure the packet carrying HTTP data has a checksum error? It can happen that the OS is using checksum offloading. Wireshark would report a bad checksum on the origin machine but the network card will compute it before sending the packet on the wire.