tcpdump to capture socket data - sockets

Can use tcpdump to capture socket data ?. Since , at the listener end i'm freqyently getting some additional info along with send message.
In between client and end listener , one edge server and one application server is running, not sure at which point that additional info is being added. To troubleshoot, I tried to use tcpdump to capture the socket data. But I couln't capture it.
Can someone please tell me, tcpdump is not fit to capture socket data?. if so, then which one is correct one to do this.
Note: I'm Using CentOS

tcpdump can capture data base on port as following:
tcpdump tcp port 23 and host 210.27.48.1 -w temp.pcap
If you still can't capture any data, you can capture data for the interface to ensure your tcpdump is working:
tcpdump -i eth1 -w temp.pcap
ps: If your client and your server are on the same machine, you need to capture the lo interface.

Related

Purported UDP "connection"

My understanding was that UDP doesn't form connections; it just blindly sends packets. However, when I run
nc -u -l 10002
and
nc -u 127.0.0.1 10002
simultaneously (and so can send messages back and forth between terminals), lsof reports two open UDP connections:
nc ... UDP localhost:10002->localhost:35311
nc ... UDP localhost:35311->localhost:10002
If I open a third terminal and do nc -u 127.0.0.1 10002 again, to send another message to the original listener, the listener does not receive (or acknowledge, at least) the message, suggesting it is indeed tied to a specific connection.
If I implement a UDP echo server in Java like this and do sorta the same thing (on 10001), I get
java ... UDP *:10001
nc ... UDP localhost:52295->localhost:10001
aka, Java is just listening on 10001, but nc has formed a connection.
Based on my understanding of UDP, I'd expect both sides to behave like the Java version. What's going on? Can I make the Java version do whatever nc is doing? Is there a benefit to doing so?
I'm on Ubuntu 20.04.3 LTS.
UDP sockets can be connected (after a call to connect) or they can be unconnected. In the first case the socket can only exchange data with the connected peer, while in the second case it can exchange data with arbitrary peers. What you see in lsof is if the socket is connected or not.
My understanding was that UDP doesn't form connections; it just blindly sends packets.
That's a different meaning of the term connection here. TCP has always "real" connections, i.e. an association between two endpoints which has a clear start (SYN based handshake) and end (FIN based teardown). TCP sockets used for data exchange are therefor always connected.
UDP can have associations between two endpoints too, i.e. it can have connected sockets. There is no explicit setup and teardown of such a connection though. And UDP sockets don't need to be connected. From looking at the traffic it can therefore not be determined if connected UDP sockets are in use or unconnected.
Can I make the Java version do whatever nc is doing?
Yes, see What does Java's UDP DatagramSocket.connect() do?
.
Is there a benefit to doing so?
An unconnected UDP socket will receive data from any peer and the application has to check for each received datagram where they came from and if they should be accepted. A connected UDP socket will only receive data from the connected peer, i.e. no checks in the application are needed to check this.
Apart from that it might scale better if different sockets are used for communication with different peers. But if only few packets are exchanged with each peer and/or if one need to communicate with lots of peers at the same time, then using multiple connected sockets instead of a single unconnected one might mean too much overhead.

LTTng live view with port forwarding / tunneling

I have a PC A where LTTng tracing is running with live view
lttng create trace-session --live
# Traces will be output to tcp4://127.0.0.1:5342/ [data: 5343]
Another PC B is directly connected with A with a Ethernet cable. At the same time, B is connected to a local network.
Now how can I view the live trace events from a third PC C, which is in the same local network as B, for example with
babeltrace2 "net://${B_IP}/host/${B_HOSTNAME}/trace-session"
I ran the following command on PC C, to make a tunnel to PC *A.
ssh -L 5342:${A_IP}:5342 -N user_name#${B_IP}
However, it seems not to have worked. I would like to ask:
What have I done wrong here?
What is the standard way to "forward" LTTng live tracing events to be viewed by babeltrace2?
Babeltrace2 connects to lttng-relayd using the live port of the lttng-relayd process not the data and control ports.
When the command line report the following:
# Traces will be output to tcp4://127.0.0.1:5342/ [data: 5343]
It means that the lttng-sessiond and lttng-consumerd process will communicate with a lttng-relayd process listening on the 127.0.0.1:5342 for control message and 127.0.0.1:5343 for trace data exchange. A viewer, in this case Babeltrace2 can connect to the live port of a lttng-relayd process to stream live session. You can take a deeper look at the component graph here.
The default live port is 5344 and the default behavior for the lttng-relayd process is to bind on all interfaces to listen. Naturally Babeltrace2 also default on using that port if none is specified to communicate with the lttng-relayd process.
See the man page of lttng-relayd for more details.
What have I done wrong here?
In your scenario you need to tunnel the 5344 port. Note that I'm not versed in ssh tunneling so I cannot validate the ssh approach here.
ssh -L 5344:${A_IP}:5344 -N user_name#${B_IP}
What is the standard way to "forward" LTTng live tracing events to be viewed by babeltrace2?
Babeltrace2 and lttng-relayd use TCP for communication. Hence, all TCP "forwarding" methods are acceptable here. As you probably noticed, LTTng does not encrypt communication and trace data in any way. I would say that using a ssh tunnel is appropriate here if you need to move data across non-trusted network.

Pod in Kubernetes can not establish a RTSP session, UDP port unreachable

I am trying to make a connection between my pod and a camera through RTSP (using ffmpeg).
My container, when running locally and in the server can establish the connection.
However, in Kubernetes, looks to be able to reach and identify the camera server, but it can not initialize a stream. I did a tcpdump on my container when trying to connect and I received the following:
10:55:37.065954 IP **CAMERA_SERVER_IP** > **POD_NAME**: ICMP **CAMERA_SERVER_IP** udp port 36337 unreachable, length 44
10:55:37.066003 IP **CAMERA_SERVER_IP** > **POD_NAME**: ICMP **CAMERA_SERVER_IP** udp port 36336 unreachable, length 48
**CAMERA_SERVER_IP** -> is the camera server IP addresss
**POD_NAME** -> is my pod's name in kubernetes.
When I try locally, the first UDP port fails too, but the second can establish a connection and stream.
I think this has something to do with port communication, but I am bit lost in what I should try or test.
Thanks!
UPDATE*
Actually I found something strange.
I tried again to start the connection and I analyzed the logs from tcpdump and netstat -tulpn.
When connecting locally, netstat identified the creation of two UDP connections. And tcpdump showed ffmpeg was trying to reach a connection from the server using the same UDP ports from netstat
However, in a pod in Kubernetes, the ports opened on netstat were different from the ports that ffmpeg tried a connection (verified using tcpdump).
I think this is the error, as ffmpeg immediately fails when trying to access a port that is not opened.
I actually made a work around using another ffmpeg server wrapper as I explained here: https://github.com/kubernetes/kubernetes/issues/94561
If someone has a similar problem, specially with Intelbras DVR or those that use DAHUA API, this might be interesting to read.

When will one socket suffice, when do I need to create more?

The "connectionless" aspect of UDP has thrown me for a loop...
If I setup a UDP socket set to INADDR_ANY, then bind that to port 33445 on the local machine, the machine will accept incoming connections from various clients. All of these connections will be serviced by that one socket, since this is not TCP and I cannot spawning a new child sockets to handle each connection directly. I am able to reply to any, some, or all of these connected clients, from their latest message.
So where things get a little fuzzy for me is here...
Am I able to also send out messages at any time to any of these clients? or can I only send messages that in response of recvfrom() ?
Separately, if I wanted that server (while it is serving clients) to connect to another server and have a conversation about something else, I assume I will need to create a new socket for this purpose? I cannot just use the existing server socket and specify a new destination address?
Many thanks to this wonderful community.
Edit: Let me put it another way.. It seems to be that I can only use the bound socket for responding to clients that have previously reached me on that socket. To initiate a conversation with a new host, I cannot simply use the bound socket for that purpose? I must create a new socket in order to reach a server that is listening, correct?
UDP sockets can operate in two different modes:
default not-connected mode: all datagrams sent to the port/address of your process are received; you need to specify destination address for each send you do.
connected mode: only the datagrams sent from the address/port you connected to are received; you don't need to specify destination address on each send.
Here's a small review of connected UDP sockets.
Edit:
Here's a little python UDP server that accepts packets from any client and copies them to a second server. Everything is done with one not-connected UDP socket.
#!/usr/bin/env python
import sys, socket, string
if len( sys.argv ) != 4:
print "Usage: udptee <local-listen-port> <copy-host> <copy-port>"
exit( 1 )
copy = ( sys.argv[2], int( sys.argv[3] ))
s = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
#s.bind(( 'localhost', int( sys.argv[1] )))
s.bind(( '', int( sys.argv[1] )))
print "listening on ", s.getsockname()
print "copying to", copy
while True:
line, addr = s.recvfrom( 1024 )
print "received: ", line, " from ", addr
s.sendto( line, addr ) # echo to source
s.sendto( line, copy ) # copy to tee
if string.strip( line ) == "exit": break
print "Goodbye and thanks for all the fish"
s.close()
Run it in one terminal as:
~$ ./udptee 9090 <IP-of-copy-server> 9999
Then start netcat in server mode in second term. This one will accept copies of the datagrams:
# this used to be "nc -ul 127.0.0.1 9999" which only listened on loopback
~$ nc -ul 9999
Start netcat client in third term to send stuff to the first server:
~$ nc -u <IP-of-tee-server> 9090
Start typing and see both servers echo what you type.
UDP sockets aren't connected to a remote host or client, so all you need to do is to use sendto() using the destination address and the UDP socket you have initialized. So yes, you can send out messages using the UDP socket at any time given that you have set up the UDP socket correctly. Just set the receiving address in the sockaddr struct you are using. If the receiving part have a UDP socket bound on the port you are sending the message, then it will receive it.
On that 2nd question it all depends if the conversation with that 2nd server uses a different port. If it uses the same port then there is no need to create another UDP socket. You just have to separate the messages the server 1 gets from its clients from messages it gets from server 2 somehow.
Ill recommend taking a look at Beej's excellent guide chapter 5.8 and 6.3.
Beej's Guide to Network Programming

General sockets UDP programming question

I have an FPGA device with which my code needs to talk. The protocol is as follows:
I send a single non-zero byte (UDP) to turn on a feature. The FPGA board then begins spewing data on the port from which I sent.
Do you see my dilemma? I know which port I sent the message to, but I do not know from which port I sent (is this port not typically chosen automatically by the OS?).
My best guess for what I'm supposed to do is create a socket with the destination IP and port number and then reuse the socket for receiving. If I do so, will it already be set up to listen on the port from which I sent the original message?
Also, for your information, variations of this code will be written in Python and C#. I can look up specific API's as both follow the BSD socket model.
This is exactly what connect(2) and getsockname(2) are for. As a bonus for connecting the UDP socket you will not have to specify the destination address/port on each send, you will be able to discover unavailable destination port (the ICMP reply from the target will manifest as error on the next send instead of being dropped), and your OS will not have to implicitly connect and disconnect the UDP socket on each send saving some cycles.
You can bind a socket to a specific port, check man bind
you can bind the socket to get the desired port.
The only problem with doing that is that you won't be able to run more then one instance of your program at a time on a computer.
You're using UDP to send/receive data. Simply create a new UDP socket and bind to your desired interface / port. Then instruct your FPGA program to send UDP packets back to the port you bound to. UDP does not require you to listen/set up connections. (only required with TCP)