In which cases, the TCP checksum will not detect an error? - tcp

I have a question related to computer networks, the question is in which of the following case the TCP checksum will not find an error:
1) a single bit flip occurs in the 10th byte (i.e., one bit in the 10th byte goes from 0 to 1, or from 1 to 0)
2) the first byte of the payload that was originally 00000001 becomes 00000000 and the third byte of the payload that was originally 00000000 becomes 00000001
3) the third bit of the first byte of the payload flips from 1 to 0, AND the third bit of the second byte of the payload flips from 0 to 1
4) the first byte of the payload that was originally 00000001 becomes 00000000, and the second byte of the payload that was originally 00000000 becomes 00000001

RFC 793 says:
The checksum field is the 16 bit one's complement of the one's
complement sum of all 16 bit words in the header and text.
1) A single bit flip change the checksum.
2) As the sum is on 16 bit words, this will leave the checksum unchanged.
3) The two bit changes will not sum up and will change the checksum.
4) Same as 3)
Only the second case will leave the checksum unchanged.

Related

In the TCP Header, why is the Urgent pointer 16 bits long when it points to a sequence number of 32 bits

In the TCP Header, why is the Urgent pointer field 16 bits long when it points to a sequence number of 32 bits
Don't think of it as pointing to a sequence number. It's true that the sequence numbers are used to count the total number of bytes transferred, that they are 32 bits in length, and that they can wrap around; the Urgent pointer, however, is a pointer into the data.
The urgent pointer indicates the offset from the sequence number of the received TCP segment with the urgent bit set. Therefore, it's not necessary for it to represent a 32 bit number, but it also means that the urgent data must be within the 64k following that sequence number.

The structure of Deflate compressed block

I have troubles with understanding Deflate algorithm (RFC 1951).
TL; DR How to parse Deflate compressed block 4be4 0200?
I created a file with a letter and newline a\n in it, and run gzip a.txt. Resultant file a.txt.gz:
1f8b 0808 fe8b eb55 0003 612e 7478 7400
4be4 0200
07a1 eadd 0200 0000
I understand that first line is header with additional information, and last line is CRC32 plus size of input (RFC 1951). These two gives no trouble to me.
But how do I interpret the compressed block itself (the middle line)?
Here's hexadecimal and binary representation of it:
4be4 0200
0100 1011
1110 0100
0000 0010
0000 0000
As far as I understood, somehow these ones:
Each block of compressed data begins with 3 header bits containing the following data:
first bit BFINAL
next 2 bits BTYPE
...actually ended up at the end of first byte: 0100 1011. (I'll skip the question why would anyone call "header" something which is actually at the tail of something else.)
RFC contains something that as far as I understand is supposed to be an explanation to this:
Data elements are packed into bytes in order of
increasing bit number within the byte, i.e., starting
with the least-significant bit of the byte.
Data elements other than Huffman codes are packed
starting with the least-significant bit of the data
element.
Huffman codes are packed starting with the most-
significant bit of the code.
In other words, if one were to print out the compressed data as
a sequence of bytes, starting with the first byte at the
right margin and proceeding to the left, with the most-
significant bit of each byte on the left as usual, one would be
able to parse the result from right to left, with fixed-width
elements in the correct MSB-to-LSB order and Huffman codes in
bit-reversed order (i.e., with the first bit of the code in the
relative LSB position).
But sadly I don't understand that explanation.
Returning to my data. OK, so BFINAL is set, and BTYPE is what? 10 or 01?
How do I interpret the rest of the data in that compressed block?
First lets look at the hexadecimal representation of the compressed data as a series of bytes (instead of a series of 16-bit big-endian values as in your question):
4b e4 02 00
Now lets convert those hexadecimal bytes to binary:
01001011 11100100 00000010 000000000
According to the RFC, the bits are packed "starting with the least-significant bit of the byte". The least-significant bit of a byte is the right-most bit of the byte. So first bit of the first byte is this one:
01001011 11100100 00000010 000000000
^
first bit
The second bit is this one:
01001011 11100100 00000010 000000000
^
second bit
The third bit:
01001011 11100100 00000010 000000000
^
third bit
And so on. Once you gone through all the bits in the first byte, you then start on the least-significant bit of the second byte. So the ninth bit is this one:
01001011 11100100 00000010 000000000
^
ninth bit
And finally the last-bit, the thirty-second bit, is this one:
01001011 11100100 00000010 000000000
^
last bit
The BFINAL value is the first bit in the compressed data, and so is contained in the single bit marked "first bit" above. It's value is 1, which indicates that this is last block in compressed data.
The BTYPE value is stored in the next two bits in data. These are the bits marked "second bit" and "third bit" above. The only question is which bit of the two is the least-significant bit and which is the most-significant bit. According to the RFC, "Data elements other than Huffman codes are packed
starting with the least-significant bit of the data element." That means the first of these two bits, the one marked "second bit", is the least-significant bit. This means the value of BTYPE is 01 in binary. and so indicates that the block is compressed using fixed Huffman codes.
And that's the easy part done. Decoding the rest of the compressed block is more difficult (and with a more realistic example, much more difficult). Properly explaining how do that would be make this answer far too long (and your question too broad) for this site. I'll given you a hint though, the next three elements in the data are the Huffman codes 10010001 ('a'), 00111010 ('\n') and 0000000 (end of stream). The remaining 6 bits are unused, and aren't part of the compressed data.
Note to understand how to decode deflate compressed data you're going to have to understand what Huffman codes are. The RFC you're following assumes that you do. You should also know how LZ77 compression works, though the document more or less explains what you need to know.

Decode SNMP PDUs - Where to Start? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Hello my first ever question on here, in need of bit of guidance.
I'm working on a packet sniffer mainly to decode SNMP PDUs, however I am not entirely sure where to go with it.
Simply put my packet sniffer can extract information from packets however I am interested in the data payload field. It is written in C++ and I am using winsock.
What way should I go about this? Are the SNMP fields encoded in basic encoding rules or will I have to delve into ASN.1?
I am only looking to decode those SNMP fields within the data payload field into human readable form. They are going to be dumped into a text file. So I will be looking at decoding OIDs also. I am verifying everything as I go along with Wireshark and using GETIF to query my SNMP node.
Any guidance is appreciated.
EDIT:
Thanks user1793963 very well explained. Sorry to all who have marked this as too broad.
To elaborate on my original question could anyone explain the initial part of the PDU itself.
Example: My program outputs these hex values 30 82 00 A3 02 01 00, which is SEQUENCE (30), LENGTH (82) and two other values. This is from a GetRequest PDU.
The GetResponse PDU shows these values 30 81 B7 02 01 00, SEQUENCE, 81 in LENGTH and another value.
Could someone explain the values marked in bold. If it uses the simple TLV structure what are the values representing? What I know is the start of the sequence (30) and the total PDU length (which is 82 and 81) and I know 02 01 00 are INTEGER 1 in LENGTH and VERSION 0 however I do not understand 00 A3 (GetRequest) and B7 (GetResponse). What do these values represent?
Many thanks.
I am also using Wireshark to check values, however they do not state the start of the PDU sequence
Update, 9 years later :-)
30 82 00 A3 and 30 81 B7 02 the 30 is data type = sequence. Following that are (long) length fields (> 127 bytes).
The rule for large numbers is that only the lower 7 bits in the byte are used for holding the value (0-127). The highest order bit is used as a flag
to let the recipient know that this number spans more than one byte. If more than two bytes are required to encode the number, all will have the top bit set apart from the last byte. Any number over 127 must be encoded using more than one byte.
SNMP packets are encoded in ASN.1, but it's a very simple protocol (at least for SNMP v1 and v2.c, I do not have a lot of experience with v3). It uses a simple TLV structure: type, length, value. For example the bytes 0x4 0x6 0x70 0x75 0x62 0x6c 0x63 are a string (type 4) with length 6 and value "public". You can find a list of types here.
I find it useful to write out packages like this:
1. 0x30 0x34
2. 0x2 0x1 0x1
3. 0x4 0x6 0x70 0x75 0x62 0x6c 0x63
4. 0xa2 0x27
5. 0x2 0x4 0x1 0x2 0x3 0x4
6. 0x2 0x1 0x0
7. 0x2 0x1 0x0
8. 0x30 0x19
9. 0x30 0x17
10. 0x6 0x8 0x2b 0x6 0x1 0x2 0x1 0x1 0x2 0x0
11. 0x6 0xb 0x2b 0x6 0x1 0x4 0x1 0x85 0x22 0xd5 0xf 0x97 0x54
This is a response on a get request where I requested the OID 1.3.6.1.2.1.1.2.0 (sysObjectID).
A list (type 0x30) with a length of 52 bytes
The version: SNMPv2.c (0=v1, 1=v2.c)
The community string: "public". (note how this is send in cleartext)
A SNMP get-response with length 39
The request ID, a 32 bit integer.
The error code, 0 means no error.
The error index.
A list with length 25
A list with length 23
An OID with length 8: 1.3.6.1.2.1.1.2.0
An OID with length 11: 1.3.6.1.4.1.674.10895.3028
As you can see integers and strings are easy, but OIDs are a bit trickier. First of all the first two parts ("1.3") are represented as a single byte (0x2b). They did this to make each message a few bytes shorter.
The second problem is representing numbers larger than 255. To do this SNMP uses only the 7 least significant bits to store data, the most significant bit is a flag to signal that the data continues in the next byte. Numbers lower than 128 are stored in a single byte.
0x7f
= 0 111 1111
= 127
0x85 0x22
= 1 000 0101, 0 010 0010
= 000 0101 010 0010
= 674
0xc0 0x80 0x80 0x80
= 1 100 0000, 1 000 0000, 1 000 0000, 0 000 0000
= 100 0000 000 0000 000 0000 000 0000
= 0x8000000
This method is also used if the length of a TLV field is larger than 127.
RFC1592 describes the structure of the messages, take a look at page 11 for a similar example.
I can also recommend using Wireshark to analyze packets, it does an excellent job of translating them to something readable.

Calculating range of IPs from subnet mask

Say, I have a subnet of 255.255.255.242 and I have a known IP within that subnet say 192.168.1.101.
Now the way I calculate the range of IPs is this:
In the subnet mask, find the first octet that is not a 255. In my example, its the 4th octet, and its 242. So take 256 and subtract 242, which gives us 14. So we now know that these networks, the 192.168.1.x networks, all have a range of 14. So just start listing them...
192.168.1.0
192.168.1.14
192.168.1.28
....42
....56
....70
....84
....98
....112
Here we can stop. My address, 192.168.1.101 falls into the .98 network. .98 encompasses all ip addresses from 192.168.1.98 to 192.168.1.111, because we know that 192.168.1.112 starts the next network.
I want to confirm, whether this is the right and the easiest process to do so.
A netmask is a series of 1 bits. The bits must be sequential with no 0 gaps. Anything using a 1 bit is part of the network, anything remaining is valid for host assignment within that network. A 255.255.255.224 has 27 "1" bits, which means it's a /27 network.
To calculate this right, you need to convert IPs to a numeric representation. For example, 255.255.255.224 is 11111111 11111111 11111111 11100000 which is 4294967264. 192.168.1.101 is 3232235877 (11000000 10101000 00000001 01100101).
If you take the IP and bitwise AND it with the netmask, that gives you the network address. This is the bottom end of the range:
11111111 11111111 11111111 11100000 (mask)
11000000 10101000 00000001 01100101 (ip)
-----------------------------------
11000000 10101000 00000001 01100000 = 192.168.1.96 (network address)
The complement (bitwise NOT) of the mask gives you the size of the range:
00000000 00000000 00000000 00011111 = 31
Thus, the range for that IP is between 192.168.1.96 - 192.168.1.127. (127 = 96 + 31)
Thanks to both of you Joe and dig_123 but, Joe's answer could have been clarified with a /28 subnetinstead of the stated /27 witch would have been closer to his example and fallen between 92-112.
so, Joe if I get your point right you are saying that you take the subnetted octet; determine the increment bit value and add it to the subnet value in the SN octet, this should give the range and provide the values for the Network, first host, last host, and broadcast addresses. Is that correct? i.e. in my example the 4th octet would be a 240 and the increment would be 16. Since the value in the 4th octet is 96, it falls within the calculated range for a 16 bit increment, in fact it falls between 96 and 112 which is one of the 16 bit ranges so we can conclude that our network address for this example is:
0-15
15-31
32-47
48-63
64-79
80-95
96-111
112-127
128
NW 192.168.1.96 /28
1st 192.168.1.97 /28
Last 192.168.1.110 /28
Bcast 192.168.1.111 /28
To add something to Joe's answer: if you want to do the operations more programmatically (assumes knowledge on bitwise operators).
You already know that only the last number will change, but this method could be used in a slightly different way for other cases as I show later.
Number from mask: 224
Number from IP: 101
Using e.g. python or your favourite calculator program:
Start address byte: 224 & 101 = 96
End address byte: (~224 & 255) | 96 = 127
(~224 & 255) just sets to one every bit that wasn't one in 244 (that is, the last 5 bits); OR'ing the result with 96 just copies the first 3 bits from the first address.
So, the result is the expected: 192.168.1.96 - 192.168.1.127.
If the mask ends before the last number there is a very similar procedure; let's do an example:
Let's use 255.224.0.0 as mask, and the same IP address (192.168.1.101).
Again there is only one number to take care of, which is now the one in second position: 168.
Start address byte: 224 & 168 = 160
End address byte: (~224 & 255) | 160 = 191
Now, the number on the left (first position) remains the same (192) and the rest of the numbers on the right range from 0 to 255 (depending on what they ask, it may also be from 1 to 254).
So the solution would be: 192.160.0.0 - 192.191.255.255

TCP sequence number question

This is more of a theoretical question than an actual problem I have.
If I understand correctly, the sequence number in the TCP header of a packet is the index of the first byte in the packet in the whole stream, correct? If that is the case, since the sequence number is an unsigned 32-bit integer, then what happens after more than FFFFFFFF = 4294967295 bytes are transferred? Will the sequence number wrap around, or will the sender send a SYN packet to restart at 0?
The sequence number loops back to 0. Source:
TCP sequence numbers and receive
windows behave very much like a clock.
The receive window shifts each time
the receiver receives and acknowledges
a new segment of data. Once it runs
out of sequence numbers, the sequence
number loops back to 0.
Also see chapter 4 of RFC 1323.
It wraps. RFC 793:
It is essential to remember that the actual sequence number space is finite, though very large. This space ranges from 0 to 2**32 - 1. Since the space is finite, all arithmetic dealing with sequence numbers must be performed modulo 2**32. This unsigned arithmetic preserves the relationship of sequence numbers as they cycle from 2**32 - 1 to 0 again. There are some subtleties to computer modulo arithmetic, so great care should be taken in programming the comparison of such values. The symbol "=<" means "less than or equal" (modulo 2**32).
Read more: http://www.faqs.org/rfcs/rfc793.html#ixzz0lcD37K7J
The sequence number is not actually the "index of the first byte in the packet in the whole stream" since sequence numbers deliberately start at a random value (this is to stop a form of attack known as the TCP Sequence Prediction Attack).
No SYN is required, the sequence number simply loops back to zero again once it gets to the limit.

Resources