Detecting UDP vs. non-UDP packets in PCAP - udp

I'm parsing a Wireshark PCAP file in C++, not using any external libraries.
The Wireshark app shows that most packets in that file are UDP but some are ARP, STP, or other.
I'm only interested in the UDP. Where in the packet (or packet header) does it denote the protocol?
When it is UDP, byte 23 in the packet is set to 17, however in non-UDP, byte 23 doesn't have the same meaning - thus one can't rely on that byte.
Didn't find any docs on that, including PCAP format docs.

When it is UDP, byte 23 in the packet is set to 17, however in non-UDP, byte 23 doesn't have the same meaning
It's more complicated than that.
A pcap file has, in the file header, a field that indicates the type of link-layer header that the packets in the file have. The list of link-layer header types shows what different values in that field mean.
If the field has the value 1, then the packet begins with an Ethernet header, which begins with a 6-byte Ethernet destination address, followed by a 6-byte Ethernet source address, followed by a 2-byte type/length field.
If the type/length field has the value 0x0800, then the packet is an IPv4 packet. IPv4 is described by RFC 791; the header of an IPv4 packet has a 1- byte protocol field, which contains an Internet Protocol Number value. A value of 6 means TCP; a value of 17 means UDP.
In a packet with an Ethernet header that has a type/length field value of 0x0800, the first 14 bytes are an Ethernet header, and the next 20 bytes are the fixed portion of an IPv4 header. The Protocol field in the IPv4 header is an an offset of 9 from the beginning of the IPv4 header, so, in an IPv4-over-Ethernet packet, the Protocol field is an an offset of 14+9 = 23 bytes from the beginning of the packet.
If the packet does not begin with an Ethernet header, then, unless the link-layer header is also 14 bytes long and is immediately followed by the payload, byte 23 is not the IPv4 Protocol field.
Furthermore, if the packet is not an IPv4 packet, even if the packet does begin with an Ethernet header, byte 23 is not the IPv4 Protocol field.
UDP - and TCP, and so on - can also run on top of IPv6. IPv6 is described by RFC 8200. The IPv6 header has a Next Header field, which contains an Internet Protocol Number field. However, there's no guarantee that this will be a value for a protocol such as TCP or UDP; it might be a value for an "extension header". The "extension header" will contain its own Next Header field, which could be for a protocol such as TCP or UDP or for another "extension header". Eventually, there will be a last "extension header", the Next Header field of which will contain a value specifying a protocol such as TCP or UDP.
If the packet has an Ethernet header, and the type/length field has the value 0x86dd, then an IPv6 header, not an IPv4 header, comes after the Ethernet header.
If your network is an Ethernet network with VLANs, then the type/length field may have the value 0x8100, in which case the Ethernet header will be followed by a 2-byte VLAN tag, which is followed by another 2-byte type/length field.
The tcpdump source file with the Ethernet dissector has ~600 lines of source code; the tcpdump source files with the IPv4 dissector and with the IPv6 dissector both have ~500 lines of source code. Wireshark's dissection is even more complicated than that. Writing code to properly analyze raw network packets from a capture file - whether pcap, pcapng, Sniffer, snoop, Microsoft Network Monitor, or another packet analyzer - isn't a simple process.

Didn't find any docs on that, including PCAP format docs.
The pcap format does not by itself include the information about the transport protocol (UDP, TCP, ...). This information is instead part of the packet data contained in the pcap, specifically in the IPv4/IPv6 header. With IPv4 the transport protocol is contained in the Protocol field of the IPv4 header. With IPv6 it is defined by the Next Header field of the IPv6 header.

Related

inspect inner geneve packet using tcpdump

I want to put filters on inner packets encapsulated by geneve.
If I put a filter like
tcpdump -vnn udp -i eth0
It filters all geneve packets as the header above geneve is udp.
How to filter the packets which are inside geneve which has proto field set to udp?
I managed to find a sample capture file online that contains Geneve traffic. It's the geneve.pcap file available at Cloudshark.
I download this file and modified one of the packets so the inner encapsulated protocol was UDP instead of ICMP. I was then able to come up with a capture filter to isolate that packet while testing with tcpdump. Here's the command with capture filter that I used to test this:
tcpdump -r geneve_udp.pcap "(udp port 6081) and (udp[10:2] = 0x6558) and (udp[(8 + (4 * (2 + (udp[8:1] & 0x3f))) + 12):2] = 0x0800) and (udp[8 + (4 * (2 + (udp[8:1] & 0x3f))) + 14 + 9:1] = 17)"
Explanation of the capture filter:
udp port 6081: This part just filters for Geneve packets, as identified by the UDP port number.
udp[10:2] = 0x6558: This part filters for Geneve packets with a Protocol Type of "Transparent Ethernet bridging".
udp[(8 + (4 * (2 + (udp[8:1] & 0x3f))) + 12):2] = 0x0800: This somewhat complicated part filters for encapsulated Ethernet frames having an Ethertype of 0x0800 (IPv4). It does this by:
Skipping the 8 bytes of the UDP header itself.
Skipping the Geneve Header, which is 8 bytes plus 4 times the Opt Len, which we must isolate from the byte because this field is only contained within the lower 6 bits.
Skipping to the Ethertype field of the encapsulated Ethernet header.
And finally comparing the 2-byte value found there to the IPv4-assigned Ethertype of 0x0800.
udp[8 + (4 * (2 + (udp[8:1] & 0x3f))) + 14 + 9:1] = 17: This somewhat complicated part filters for encapsulated IPv4 headers having a Protocol field as 17 (UDP). It does this by:
Skipping the 8 bytes of the UDP header itself.
Skipping the Geneve Header, which is 8 bytes plus 4 times the Opt Len, which we must isolate from the byte because this field is only contained within the lower 6 bits.
Skipping the 14 bytes of the encapsulated Ethernet header.
Skipping the 1st 9 bytes of the encapsulated IP header to get to the proper offset of the IPv4 Protocol field.
And finally comparing the value of that field with the UDP-assigned protocol value of 17.
If the Geneve protocol encapsulates UDP within IPv6 instead of IPv4, then you'll have to modify the capture filter accordingly.
NOTE: I'm not sure if I should just delete my original answer or not? For now, I'll just leave it below ...
I'm not familiar with this Geneve protocol, nor do I have any capture files to test with, but you should be able to use the slice operator (i.e., []) if you know the offset to the field containing the desired value indicating that the inner protocol is UDP.
For illustrative purposes, I'll assume that if the Protocol Type field of the Geneve Header contains the value 17, then this indicates an encapsulated UDP packet. Assuming this is correct, then a filters such as follows may help:
"udp[10:2] = 17"
This filter compares the 2 bytes at offset 10 of the UDP data to the value of 17, which as I understand it, is the location of the Protocol Type field of the Geneve Header. You'll obviously need to adjust the offset if this assumption or my understanding of the protocol isn't correct.
Refer to the pcap-filter man page for more help on the capture filter syntax.

Verifying Checksum value through Wireshark

I'm trying to verify the validity of a checksum value of a UDP packet by checking the packet with Wireshark.
In this specific packet I'm looking at, the values of the UDP headers are as follows:
Source port: 53 (0000 0000 0011 0101)
Destination port: 64992 (1111 1101 1110 0000)
Length: 64 (0000 0000 0100 0000)
Now if these values are added, the sum is 65109 (1111 1110 0101 0101)
So I expect the checksum value to be 426 (0001 1010 1010) which is 1's complement of the sum.
But in Wireshark, the checksum value is 0x63c7, and it says that this checksum is correct.
I'd like to know where I'm mistaken.
Any help or push in the right direction would be greatly appreciated.
Thanks in advance.
If you reference RFC 768, you will find the details you need to properly compute the checksum:
Checksum is the 16-bit one's complement of the one's complement sum of a
pseudo header of information from the IP header, the UDP header, and the
data, padded with zero octets at the end (if necessary) to make a
multiple of two octets.
The pseudo header conceptually prefixed to the UDP header contains the
source address, the destination address, the protocol, and the UDP
length. This information gives protection against misrouted datagrams.
This checksum procedure is the same as is used in TCP.
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| source address |
+--------+--------+--------+--------+
| destination address |
+--------+--------+--------+--------+
| zero |protocol| UDP length |
+--------+--------+--------+--------+
If the computed checksum is zero, it is transmitted as all ones (the
equivalent in one's complement arithmetic). An all zero transmitted
checksum value means that the transmitter generated no checksum (for
debugging or for higher level protocols that don't care).
If you want to see how Wireshark's UDP dissector handles it, you can look at the source code for packet-udp.c. Basically, after setting up the data inputs properly, it essentially just calls the in_cksum() function in the in_cksum.c file to compute it.
You might also want to take a look at RFC 1071, "Computing the Internet Checksum".

THE Size Of Udp Packets

i want to know if we have a simple udp packet that has a string in it how much the size of udp packet will be
for exmaple we have a udp packet that has a string in it
the string is:stackoverflow.com
ok now how much the size of the udp packet will be?
i was thinking that may the size of udp packets that have a text in it be like a size of text file with the same text in packet?
so if the file have this text and the size is 1 kilobites
test
if the packet has same text will the size be same as text file?
The size of a UDP datagram is the size of the data inside it (payload) plus the size of the UDP and IP headers. The payload can be up to 65507 bytes for IPv4 transported over IP with no additional options in the header.
It's up to you how you create the payload. "test" could be as little as 4 bytes using a single-byte character set with no terminator or length indicator. Really, it's up to you to create a payload structure that you are able to decode at your receiver.
Add 8 octets for UDP header, another 12 for IPv4.
It gets a bit more complicated if you need to calculate the lower layer, e.g. ethernet frame

Maximum size of ICMP IPv6 packet

With reference to this question and to ASIO libary, I would like to know what is the maximum size of ICMP v6 reply packet. I'm using ASIO library to listen for and receive ICMPv6 packets, but I don't know what size of buffer to use in order to prevent buffer over flow. I'm confused by IPv6 supporting extension headers.
Ex code:
asio::streambuf replyBuffer;
replyBuffer.consume(replyBuffer.size());
size_t length = icmpV6Socket->receive(replyBuffer.prepare(65536) );
One of the great features of Boost.Asio's buffers is that they provide protection against buffer overruns. Boost.Asio's buffers pair together a handle to the actual memory and the size. Thus, as long as the size is properly set or deduced, then Boost.Asio operations will not produce buffer overruns.
Nevertheless, the details for ICMPv6 sizes are as follows. IPv6 Header is 40 bytes, and reserves 2 bytes to represent the Payload Length. Thus, the max payload for IPv6, including extension headers, is 65,535. This differs from IPv4, where the Total Length included the header itself. The ICMPv6 Echo Reply header is 8 bytes.
Therefore:
The maximum IPv6 packet is 65,575 bytes (max payload of 65,535 + header of 40).
The maximum IPv6 payload is 65,535 bytes.
The maximum ICMPv6 Echo Reply body is 65,527 bytes. (max payload of 65,535 - ICMPv6 Echo Reply Header of 8).

What is the meaning of \x00 and \xff in Websockets?

Why do messages going through websockets always start with \x00 and end with \xff, as in \x00Your message\xff?
This documentation might help...
Excerpt from section 1.2:-
Data is sent in the form of UTF-8 text. Each frame of data starts
with a 0x00 byte and ends with a 0xFF byte, with the UTF-8 text in
between.
The WebSocket protocol uses this framing so that specifications that
use the WebSocket protocol can expose such connections using an
event-based mechanism instead of requiring users of those
specifications to implement buffering and piecing together of
messages manually.
To close the connection cleanly, a frame consisting of just a 0xFF
byte followed by a 0x00 byte is sent from one peer to ask that the
other peer close the connection.
The protocol is designed to support other frame types in future.
Instead of the 0x00 and 0xFF bytes, other bytes might in future be
defined. Frames denoted by bytes that do not have the high bit set
(0x00 to 0x7F) are treated as a stream of bytes terminated by 0xFF.
Frames denoted by bytes that have the high bit set (0x80 to 0xFF)
have a leading length indicator, which is encoded as a series of
7-bit bytes stored in octets with the 8th bit being set for all but
the last byte. The remainder of the frame is then as much data as
was specified. (The closing handshake contains no data and therefore
has a length byte of 0x00.)
The working spec has changed and no longer uses 0x00 and 0xFF as start and end bytes
http://tools.ietf.org/id/draft-ietf-hybi-thewebsocketprotocol-04.html
I am not 100% sure about this but my guess would be to signify the start and end of the message. Since x00 is a single byte representation of 0 and xFF is a single byte representation of 255