Is tcpdump 100% reliable on outgoing connection? - linux-kernel

I'm working on a server.
Its doing health check to another server, like a simple tcp open connection
Basically my tcpdump says that the packet (the health check tcp sYn packet) is going out of my interface.
But, the Firewall doesnt see anything.
I have doubt if the packet is going outside the server at all, or the problem is on the switch.
Is there a way to be sure about this?

Captured traffic == source of truth
It's possible for tcpdump to have false negatives (i.e. packets are sent but tcpdump doesn't record them). This can be due to hardware (CPU, RAM, disk) being maxed or if tcpdump's buffer size (-B) is too small. Likewise, it's possible your firewall isn't picking it up where it should.
It's highly unlikely for tcpdump to report a false positive. Tcpdump copies bytes from your network interface [0] and summarizes them in a text line (depending on your output options). If firewall rules from e.g. iptables would block traffic, tcpdump won't see the traffic. If tcpdump reports a packet, you can be sure it transited that interface.
[0]: If you're curious how tcpdump works at a lower level, use strace.
Flow-based troubleshooting
Flow-based troubleshooting can be required to figure out where packets get dropped in a network. For your network of server:A <-> B:switch:C <-> D:Firewall, we know that A sends it and D does not receive it. Thus you should check ports B and C to determine where the packet loss occurs. It's also possible that D reports a false negative. You can test both of these things by plugging this server directly into a different firewall that can take packet captures/monitor traffic.

Related

Zero-length packets for USB control transfers

In the context of a DFU driver, I'm trying to respond with a packet of length zero (not ZLP as in multiples of max size, just zero bytes) to a USB control in transfer. However, the host returns with a timeout condition. I tried both, the dfu-util tool and the corresponding protocol, as well as a minimal working example with pyusb just issuing a control in transfer of some length and the device returning no data.
My key question is: Do I achieve this by responding with a NAK or should I set the endpoint valid but without any data? The specs are rather vague about this, imo.
Here are some technical details since I'm not sure where the problem is:
Host: Linux Kernel 5.16.10, dfu-util and pyusb (presumably) both using libusb 0.1.12
Device: STM32L1 with ChibiOS 21.11.1 USB stack (sends NAK in the above situation, I also tried to modify it to send a zero-length packet without success)
It sounds like you are programming the firmware of a device, and you want your device to give a response that is 0 bytes long when the host starts a control read transfer.
You can't simply send a NAK token: that is what the device does when the data isn't ready yet, and it causes the host to try again later to read the data.
Instead, you must actually send a 0-length IN packet to the host. When the host receives this packet, it sees that the packet is shorter than the maximum packet size, so it knows the data phase of the control transfer is done, and it moves on to the status stage.

Embarcadero RAD Studio & Indy. Error message “Package Size Too Big”

I use Embarcadero RAD Studio & Indy and I have a problem.
I am using component IdUDPServer and try to send file via UDP messages.
The file is successfully transferred if it is not large.
However, the error message “Package Size Too Big” appears if the file is large.
My code:
FileAPP->ReadBuffer(Buffer, Size);
IdUDPServer1->SendBuffer("10.6.1.255", 34004, RawToBytes(&Buffer, Size));
I see two ways to solve this problem:
1) Compose small messages and send these messages in a loop.
This is an easy way to solve the problem, however I will need to fix the remote application.
This is currently difficult. I do not have much time.
2)I want to find a condition in the source code where this error message is generated.
Maybe I can fix the condition and it will work for my specific task.
I have added some pictures. This is all the information that I now have.
Screenshots from help file: Picture 1, Picture 2, Picture 3
Error message: Picture 4
Please help me if you know the solution.
"Package Size Too Big" means you tried to send a datagram that is too large for UDP to handle. UDP has an effective max limit of 65507 bytes of payload data per datagram. You can't send a large file in a single datagram, it just won't fit.
So yes, you will have to break up your file into smaller chucks that are sent in separate datagrams. And as such, because UDP is connection-less and does not guarantee delivery, you will also have to solve the issues of lost packets and out-of-order packets. You will have to put a rolling sequence number inside your packets so that the receiver can save packets in the proper order. And you will have to implement a re-transmission mechanism to re-send lost packets that the receiver did not receive.
I would suggest not using TIdUDPClient/TIdUDPServer to implement file transfers manually, if possible. Indy has TIdTrivialFTP/TIdTrivialFTPServer components that implement the standardized UDP-based TFTP protocol, which handles these kind of details for you. By default, TFTP has a limit of ~32MB per file (512 bytes per datagram * 65535 datagrams max), but you can increase that limit using the TIdTrivialFTP.RequestedBlockSize property to request permission from a TFTP server to send more bytes per datagram. RequestedBlockSize is set to 1500 bytes by default, which can accommodate files up to ~93.7MB in size (though in practice it should not be set higher than 1468 bytes so TFTP datagrams won't exceed the MTU size of Ethernet packets, thus limiting the max file size closer to ~91.7MB). The RequestedBlockSize can be set as high as 65464 bytes per datagram to handle files up to ~3.9GB (at the risk of fragmenting UDP packets at the IP layer).
It is also possible for TFTP to handle unlimited file sizes with smaller datagram sizes, though TidTrivialFTP/TIdTrivialFTPServer do not currently implement this, because this behavior is not currently standardized in the TFTP protocol, but is commonly implemented as an extension in 3rd party implementations.
Otherwise, you should consider using TCP instead of UDP for your file transfers. TCP doesn't suffer from these problems.

TCP retransmission for the same packet but with the different TCP payload

I'm developing an Ethernet driver in Linux platform. I found that when a TCP retransmission occurred, the TCP payloads of multiple retransmission packets referring to the same sequence number packets were different. I can't understand why it would happen. In my driver, I just allocated a normal network device without any specific flags. By the way, the TCP checksum field was also wrong in these retransmission packets, however, the checksum in all the other types of TCP packets was right, such as SYNC, ACK, and DUP ACK.
I captured the packets by wireshark, and it means the packets I captured were not handled by my driver, just from the TCP stack in Linux kernel. But when I tested with other Ethernet devices and drivers, this problem didn't happen. So my questions were like the following.
Is there any possible for TCP stack to retransmit the same packets without same payload?
Which kinds of parameters in Linux kernel would cause these problem?
How can my driver cause this problem?
Thx for all your reply.
I found the reason for this problem. It's a very very fool fault.
Due to making all the DMA buffers (in my driver it's skb->data)address aligned to 4bytes, I called a memmove function to do that. Actually, the data referred by the skb->data is shared by all the TCP/IP stack in the Kernel. So after this wrong operation, when the TCP retranmission occurs, the address referred by skb->data in TCP stack still maintains the original one. That's why the checksum based on original data seems wrong in wireshark. The codes in my driver is like the following.
u32 skb_len = skb->len;
u32 align = check_aligned(skb);
if !align
return skb;
skb_push(skb,align);
memmove(skb->data, skb->data+align, skb_len);
skb_trim(skb, skb_len);
return skb;
I hope my experience can help others to avoid this fool fault.

Discovering maximum packet size

I'm working on a network-related project and I am using DTLS (TLS/UDP) to secure communications.
Reading the specifications for DTLS, I've noted that DTLS requires the DF flag (Don't Fragment) to be set.
On my local network if I try to send a message bigger than 1500 bytes, nothing is sent. That makes perfect sense. On Windows the sendto() reports a success but nothing is sent.
I obviously cannot unset the DF flag manually since it is mandatory for DTLS and i'm not sure whether the 1500 bytes limit (MTU ?) could change in some situations. I guess it can.
So, my question is : "Is there a way to discover this limit ?" using APIs ?
If not, what would be the lowest possible value ?
My software runs under UNIX (Linux/MAC OSX) and Windows OSes so different solutions for each OS are welcome ;)
Many thanks.
There is a minimum MTU that must be supported - 576 bytes, including IP headers. So if you keep your packets below that, you don't have to worry about PMTU-D (that's what DNS does).
you probably need to 'auto tune' it by sending a range of packet sizes to the target, and see which arrive. think binary_search ...

SnmpExtensionTrap has a size limit?

I am working on a problem in SNMP extension agent in windows, which is passing traps to snmp.exe via SnmpExtensionTrap callback.
We added a couple of fields to the agent recently, and I am starting to see that some traps are getting lost. When I intercept the call in debugger and reduce the length of some strings, the same traps, that would have been lost, will go through.
I cannot seem to find any references to size limit or anything on the data passed via SnmpExtensionTrap. Does anyone know of one?
I would expect the trap size to be limited by the UDP packet size, since SNMP runs over the datagram-oriented UDP protocol.
The maximum size of a UDP packet is 64Kb but you'll have to take into account the SNMP overhead plus any limitations of the transport you're running over (e.g. ethernet).

Resources