Iterate over the packets read in WinDivertReceiveEx in batch- Divert lib - c++

How to iterate over the each packet on the buffer received from WinDivertReceiveEx call, when the bytes are stored contiguously without delimiter? Is there any example which I can refer.
https://reqrypt.org/windivert-doc.html#divert_recv_ex
https://github.com/basil00/Divert
The received packets are packed contiguously (i.e., no gaps) into the
pPacket buffer.
This is from the documentation.

Related

DPDK library packet function query

What is the use case of below functions? kindly give detailed information.
I have allocated the Mbuf and when i have to use below functions
1.rte_pktmbuf_prepend()
2.rte_pktmbuf_append()
3.rte_pktmbuf_adj()
These functions help to mark up mbufs for data manipulations. They care to update mbuf fields data_off, data_len and pkt_len, so that the caller may not worry about that.
When creating an mbuf pool, the user must request that per-mbuf data room be at least RTE_PKTMBUF_HEADROOM bytes long (typically, 128 bytes). And when a new mbuf is allocated from the pool, its default starting position for data (data_off) is set to that RTE_PKTMBUF_HEADROOM. If some entity (in example, a NIC's PMD) writes packet data to an mbuf, then its data_off will still be greater than or equal to RTE_PKTMBUF_HEADROOM. This way, DPDK makes sure to preserve some unused space at the beginning of each mbuf's data buffer so that applications may use it to attach extra (outer) headers to packets they handle.
With above explanation in mind, rte_pktmbuf_prepend is a helper which makes extra room before the existing data start and returns a pointer to the newly claimed space. The application can then copy extra data to that location. For example, when an application receives non-tunnel packets and wants to encapsulate them using a VXLAN header, it may invoke this function to make some space, then fill in the header itself. Another example is VLAN tag insertion. See more examples.
As opposed to rte_pktmbuf_prepend, helper rte_pktmbuf_adj is used to dismiss some amount of data at the beginning of an mbuf. For example, when an application receives encapsulated (tunnel) packets, it may want to drop the outer header by invoking this function. The resulting packets will have their data start positions pointing at the inner headers. See more examples.
As for rte_pktmbuf_append, it finds the last mbuf segment of a packet mbuf and reserves data room after the existing data. For example, it may be used to construct a packet brick by brick: first append an Ethernet header, then append an IP header, etc. Alternatively, one may invoke this method just once to make room for the whole packet right from the start. See more examples.

Sending a part of a byte array

I am reading data from a serial port (in an Arduino) and framing it (syncing on a few bytes). To do that, I am reading the data into a big buffer.
Once I got the frame, I extract data and I want to send it to a different serial port using serial.write (Serial.write(buf, len)) which accepts a byte array and its size.
Since the data size can be random, I need something like a dynamic array (which is not recommended in Arduino). Any ideas?
Since the data size can be random, I need something like a dynamic array
In C you rarely need a dynamic array, because arrays passed to functions do not carry their size with them. That is why all functions that take an array also take length.
Let's say you have your data inside bigBuffer at position startPos, and you wish to send length bytes. All you need to do is
Serial.write(&bigBuffer[startPos], length);
or with pointer arithmetic syntax
Serial.write(bigBuffer+startPos, length);

UDP transfer & maintaining network byte order

So I am having some trouble sending and receiving a custom packet via a client-server program in C++. I have implemented something similar using TCP, however I am having issues converting everything into a single datagram when using UDP.
Currently I have the header consisting of an even number of uint32_t fields. Each of these is stored in network order like so in a header struct:
uint32_t x = htonl (int y);
...
And I am combining the header with a payload in a packet like so:
typedef struct {
450Header header; // 512 bytes consisting of the unint32_t like above
char data[ BLOCKSIZE ]; // 3.5k
// Total Packet Size = 4k
} Packet;
'
The header portion will contain info about the packet, my question how to deal with byte order for strings and the payload. I would ideally like to add some string fields to the header for things like filename, and if I am sending a file larger than the blocksize in the packet I would like to split it up into multiple packets, I need to know how to split the file so it can be interpreted in the right order the receiving end.
I have successfully built a header independently (with all fields in network byte order), do i need to also convert the ordering of the strings if I add them to the header? I assume if i keep the strings at a set size I can still write a checksum function for the header.
If everything is correctly ordered from question 1, do I need to convert them again on the receiving end back to host order?
I have an mmap function which loads the file into a char buffer, can I simply copy this piece by piece to the data buffer in the Packet using something like memcpy and incrementing the offset? Or do I have to worry about network order for the payload data as well?
Do I need to use a checksum on the payload? And how do I do so if it does not use the whole buffer and ends up with an odd number of bytes?
Eventually I want the header to contain sequence number so I can practice implementing procedures if packets are dropped (i.e. go back N), so what I am most worried about is standardizing the order in which everything is sent from the client so it can be interpreted in the right order on the server side.
8bit data (including 8bit integers, Ansi/UTF-8 strings, etc) do not suffer from byte order issues, so you can send/receive them as-is. It is only multi-byte data (like 16bit/32bit integers, 16bit UCS2/UTF-16 strings, etc) that you have to deal with byte ordering. For instance, integers should always be in network byte order, but UTF-16 strings can use either UTF-16LE or UTF-16BE at your discretion (though you should use UTF-8 instead).
If you have to split data into multiple packages, then you need to put information in the packet header to specify the order of the packets. UDP does not guarantee packets arrive in the same order that they are sent, or even guarantee that they arrive at all. So the receiver needs to collect the packets (requesting missing packets as needed) and then re-order them accordingly before then processing the data.
Yes, you should always convert packets to network byte order before sending them, and convert back to host byte order when processing them on the receiving end. Converting to network byte order is only for transmission purposes to ensure a consistent format across platforms.
A checksum is a good idea to ensure the integrity of the data for each packet, but it is not a requirement. You can certain provide a fixed-length checksum for arbitrary-length data, there are plenty of checksum algorithms that support that.

C++ Boost asio get data size?

I am using the boost asio library to read some data using tcp. After using a.accept(*sock);, how to get the size of the 1st packet the client will send?
I use (sock->remote_endpoint().address()).to_string() to get the IP address of the user, so I guess there must be a similar simple way to get the size of the packet, right?
At the application level, it is often far more useful to know the number of bytes currently available for reading, rather than the packet size. The amount of data available for reading may be constructed from one or more TCP segments. In the OSI model, a TCP segment (Layer 4: Transport) may be constructed from one or more IP Layer packets (Layer 3: Network), and each packet may be constructed from one or more Ethernet frames (Layer 2: Data Link).
Therefore, I am going to assume the application is interested in knowing how many bytes to read, rather than knowing lower level details, such as the size of a packet. There are a few solutions to this problem:
Query the socket for how much data is available via socket::available(), then allocate the buffer accordingly.
std::vector<char> data(socket_.available());
boost::asio::read(socket_, boost::asio::buffer(data));
Use a class that Boost.Asio can grow in memory, such as boost::asio::streambuf. Some operations, such as boost::asio::read() accept streambuf objects as their buffer and will allocate memory as is required for the operation. However, a completion condition should be provided; otherwise, the operation will continue until the buffer is full.
boost::asio::streambuf data;
boost::asio::read(socket_, data,
boost::asio::transfer_at_least(socket_.available()));
As Igor R. suggests in the comments, incorporate length as part of the communication protocol. Check the Boost.Asio examples for examples of communication protocols. Focus on the protocol, not necessarily on the Boost.Asio API.
In a fixed length protocol, a constant byte size is used to indicate message boundaries, such as in the Boost.Asio Porthopper example. As the reader knows the size of the message, the reader can allocate a buffer in advance.
In a variable length protocol, such as the one used in the Boost.Asio Chat example, a message is often divided into two parts: a header and a body. One approach is to have a a fixed size header that contains various meta-information, such as the length of the body. This allows an application to read a header into a fixed size buffer, extract the body length, allocate a buffer for the body, then read the body.
// Read fixed header.
std::vector<char> data(fixed_header_size);
boost::asio::read(socket_, boost::asio::buffer(data));
protocol::header header(data);
network_to_local(header); // Handle endianess.
// Read body.
data.resize(header.body_length());
boost::asio::read(socket_, boost::asio::buffer(data));
protocol::body body(data);
network_to_local(body); // Handle endianess.
On the other hand, if I am mistaken, and you do need the total length of a packet, then one can use the basic_raw_socket. Boost.Asio's ICMP example demonstrates reading IPv4 packets from a socket, and extracting the header's field values.

Can TCP data overlap in the buffer

If I keep sending data to a receiver is it possible for the data sent to overlap such that they accumulate in the buffer and so the next read to the buffer reads also the data of another sent data?
I'm using Qt and readAll() to receive data and parse it. This data has some structure in it so I can know if the data is already complete or if it is valid data at all but I'm worried that other data will overlap with others when I call readAll() and so would invalidate this suppose-to-be valid data.
If it can happen, how do I prevent/control it? Or is that something the OS/API worries about instead? I'm worried partly because of how the method is called. lol
TCP is a stream based connection, not a packet based connection, so you may not assume that what is sent in one time will also be received in one time. You still need some kind of protocol to packetize your stream.
For sending strings, you could use the nul-character as separator or you could begin with a header which contains a magic and a length.
According to http://qt-project.org/doc/qt-4.8/qiodevice.html#readAll this function snarfs all the data and returns it as an array. I don't see how the API raises concerns about overlapping data. The array is returned by value, and given that it represents the entire stream, so what would it even overlap with? Are you worried that the returned object actually has reference semantics (i.e. that it just holds pointers to storage that is re-used in other calls to the same function?)
If send and receive buffers overlap in any system, that's a bug, unless special care is taken that the use is completely serialized. (I.e. a buffer is somehow used only for sending and only for receiving, without any mixup.)
Why dont you use a fixed length header followed by variable length packet with the header holding the information of length of packet.
This way you can avoid worrying about packet boundaries. Say for example instead of just sending the string send the length of the string followed by the string. In the receiver end always read the length and then based on the length read the string.