Libpcap - Received vs. Sent packets - c++

I'm using the libpcap for capturing all packets on a specific port. But I need to separate and know clearly which packets my device is sending, and which ones it is receiving.
Actually I use pcap_close() for capturing packets, and it's working well ; but the struct pcap_pkthdr doesn't contain any information if the packet is received or sent.
I have a few options, but I think all of them are not quite good:
I could try getting my own IP and compare it with the IP inside the IP Header, but it's a big heavy to always check my IP and compare it...
I could do two pcap filter with in one src host and the other dest host. But that would make no sense to have two filter like this, and I wouldn't know how to capture with two separate filter.
So, am I wrong ? If not, is there an efficient way to separate received from sent packets ?
Thank you !

Source mac can tell if it is ingress or egress. If packet captured has source Mac of host, it is egress else it is ingress.

Related

Why do I see strange UDP fragmentation on my C++ server?

I have build an UDP server with C++ and I have a couple questions about this.
Goal:
I have incomming TCP trafic and I need to sent this further as UDP trafic. My own UDP server then processes this UDP data.
The size of the TCP packets can vary.
Details:
In my example I have a TCP packet that consists of a total of 2000 bytes (4 random bytes, 1995 'a' (0x61) bytes and the last byte being 'b' (0x62)).
My UDP server has a buffer (recvfrom buffer) with size larger then 2000 bytes.
My MTU size is 1500 everywhere.
My server is receiving this packet correctly. In my UDP server I can see the received packet has a length of 2000 and if I check the last byte buffer[1999], it prints 'b' (0x62), which is correct. But if I open tcpdump -i eth0 I see only one UDP packet: 09:06:01.143207 IP 192.168.1.1.5472 > 192.168.1.2.9000: UDP, bad length 2004 > 1472.
With the tcpdump -i eth0 -X command, I see the data of the packet, but only ~1472 bytes, which does not include the 'b' (0x62) byte.
The ethtool -k eth0 command prints udp-fragmentation-offload: off.
So my questions are:
Why do I only see one packet and not two (fragmented part 1 and 2)?
Why dont I see the 'b' (0x62) byte in the tcpdump?
In my C++ server, what buffer size is best to use? I have it now on 65535 because the incomming TCP packets can be any size.
What will happen if the size exceedes 65535 bytes, will I have to make an own fragmentation scheme before sending the TCP packet as UDP?
OK, circumstances are more complicated as they appear from question, extracted from your comments there's the following information available:
Some client sends data to a server – both not modifiable – via TCP.
In between both resides a firewall, though, only allowing uni-directional communication to server via UDP.
You now intend to implement a proxy consisting of two servers residing in between and tunneling TCP data via UDP.
Not being able for the server to reply backwards does not impose a problem either.
My personal approach would then be as follows:
Let the proxy servers be entirely data unaware! Let the outbound receiver accept (recv or recvfrom depending on a single or multiple clients being available) chunks of data that yet fit into UDP packets and simply forward them as they are.
Apply some means to assure lost data is at least detected, better such that lost data can be reconstructed. As confirmation or re-request messages are impossible due to firewall limitation, only chance to increase reliability is via redundancy, though.
Configure the final target server to listen on loopback only.
Let the inbound proxy connect to the target server via TCP and as long as no (non-recoverable) errors occur just forward any incoming data as is.
To be able to detect lost messages I'd at very least prepend a packet counter to any UDP message sent. If two subsequent messages do not provide consecutive counter values then a message has been lost in between.
As no communication backwards is possible the only way to increase reliability is unconditional redundancy, trading some of your transfer rate for, e.g. by sending every message more than once and ignoring surplus duplicates on reception side.
A more elaborate approach might distribute redundant data over several packets such that a missing one can be reconstructed from the remaining ones – maybe similar to what RAID level 5 does. Admitted, you need to be pretty committed to try that...
Final question would be how routing looks like. There's no guarantee with UDP for packets being received in the same order as they are sent. If there's really only one fix route available from outbound proxy to inbound one via firewall then packets shouldn't overtake one another – you might still want to at least log to file appropriately to monitor the inbound UDP packets and in case of errors occurring apply appropriate means (buffering packets and re-ordering them if need be).
The size of the TCP packets can vary.
While there is no code shown the sentence above and your description suggests that you are working with wrong assumptions of how TCP works.
Contrary to UDP, TCP is not a message based protocol but a byte stream. This especially means that it does not guarantee that single send at the sender will be matched by a single recv in the recipient. Thus even if the send is done with 2000 bytes it might still be that the first recv only gets 1400 bytes while another recv will get the rest - no matter if everything would fit into the socket buffer at once.

Populating source IP address in a raw socket to get a valid response

I am doing some basic network programming using c/c++. What I am trying to do is create packets with headers populated with my own values (instead of kernel) , send packet to some server and get a response. I was able to create the tcp/ip header structures and populate fields such as seq_num etc . As an example, I would send a SYN packet to a host at some port, and check if the host responds with a valid SYN_ACK.
I am wondering what needs to be put in for the source_address and source_port field in the ip/tcp header so that I get a valid response. Using local address (127.0.0.1) won't work right, cause the target machine won't be able to send a response.
I have to use raw_sockets only, can't use SOCK_STREAM etc. Using Linux OS.
The source IP address should be the ip address of interface from which you expect the packet to go out to reach the destination. To make things less complicated the source port can be any free port on your machine.
Also you need to take care of one more thing. Once you get the syn-ack back it will be also handled by the tcp stack of your machine and tcp stack will send a reset in response to that syn-ack. If you are on linux you can use iptables to drop the out going reset.
-MS

Single socket sends and receives over both wlan and eth interface

Using C++ I create a single UDP socket, supplying both an IPv4 address and port. I run this on Ubuntu and have both a wlan0 and eth0 interface up and running. Apparently something decides that both interfaces should be used, I appreciate that. Sending and receiving using a different interface does create a kind of a pickle (NAT traversal???) for me though. Using Wireshark I can see packages coming in, but my application does not register them.
To clarify:
I have a tracker which will supply me with a peer. The tracker will also contact that peer to send me a message. In order to overcome NAT traversal issues, I will send a puncture message.
The problem now is that the puncture messages is sent over wlan (I am testing locally with two machines), whereas the messages from the peer are coming in over eth.
So, I think the simplest solution would be to simply use one interface. (Or both one socket)
EDIT:
I will try what is mentioned here on specifying a single interface.
#Barmar, pointed out that UDP sockets may change interface when sendto is called with a destination address that would benefit from it.
I am still fuzzy on the reason for my problem though. Can someone explain why this is an issue in the first place?
EDIT2:
The above mentioned solution of forcing one interface for the socket bind did not work. Apparently the sendto method will choose to ignore this and still go for the other interface if it feels that that will work better.
Does anyone know how to make sure that socket sticks to the interface it was assigned to?
If you need to ensure that UDP replies come from the same address that the request was sent to, the solution is to use multiple sockets. You open one socket for each IP of the server (this may be more than one socket per interface, because of interface aliases), and bind the socket to that IP. Then you use select() or poll() to wait for requests on all sockets at once. When a request comes in on a particular socket, you send the reply out through that same socket, and its source IP will match the original packet's destination.

Timing sending and receiving the same packet

I would like to time how quickly the latency is of a system by sending a packet with the same dest IP as the source IP. Is this relatively simple to do?
How would you custom-build the packets?
Would setting the two IP addresses achieve what I am after?
What is the best timing method?
Any tips/ideas at a low/high level would be greatly appreciated. I intend to use C/C++ on Unix with the boost libraries and libpcap.
EDIT: I should add I will be doing this on a home network, behind a router. I presume the packet will go to the router and come straight back if I were to use 192.168.2.1 (local IP of my system) for the source and dest addresses.
You can just try ping to your own IP. this will produce ICMP packets. There are libraries which also allows you to do the same from an application.
If you want to create packets for yourself you can use socket API. Remember, you can send the source IP address and destination IP address as same, but the port number needs to be different.
For timing you need can use gettimeofday function.
EDIT:
you can ping from your C++ program. See: http://verplant.org/liboping/ or check out some other forum. The reason i emphasized on ping is because it returns right back from the network stack. If you send a UDP packet on the other hand, expecting the application to return and echo, then the processing time of the packet on the listening server gets added.
If you ping to local machine ip (or even lo) it returns without going to switch or next hop router. It will respond even if you remove your eth cable or wifi.
What you are trying to do is implemented in NTP daemon with NTP protocol though.
You don't need a custom package for this. Just create a socket connecting to the same ip-address as the server, and start sending packages. Note that these packages will never leave the network stack, so what you will be measuring is basically how quick the system copies data between user-space and kernel-space.
For the timing, you can use the clock function, it's probably the one most widely used for such things.

RTSP client in android

I am writing a RTSP client in Android. I am able to receive the Responses for all the requests
i.e.,
DESCRIBE it sends back the 200 OK
SETUP with transport: RTP/AVP:unicast:client_port=4568:4569 got the 200 OK Message back
Sent PLAY, and got the OK Message
After that how to get the audio and video frames?
I have searched on blogs, but all say to listen at client_port but I am not receiving any packets.
Please let me know am I doing correctly.
You may or may not know this, but Android has built in support for RTSP using the VideoView.
http://developer.android.com/reference/android/widget/VideoView.html
This may cut down on your development time...or it may be totally useless if you're trying to roll your own RTSP stack.
RTSP is only used to start the streaming. It gives you an SDP description of the real streams. You have to manage an RTCP connection and a RTP connection per channel (audio / video). The ports to use are the "client_port" ones.
It is pretty complex to code a RTSP/RTCP/RTP stack from scratch. You can have a look at the live555 library that implement such a stack in c++.
Put a sniffer on the network, you should see UDP packet with destination port 4568 targeted at your IP address.
With a decent sniffer, you will be able to see the rtsp dialog. Maybe you are missing something in the answers
You should also check the content of the SETUP response, to see if the port you requested were accepted.
Things to check :
Listening in UDP.
Firewall rules.
Range of the play request : Don't specify any to be sure the server will be playing something.
If you are behind a router or firewall, you probably won't receive anything, because your router / firewall don't know what to do with incoming UDP packets
Try first with a local Darwin Streaming server installed within your LAN.that way Firewall wont matter.Streaming will work.
If you want to try from external server then:
1) Check the client_ports mentioned in the SERVER response,some servers suggest different ports from the one requested.you have to use the ports suggested by server.
2) If the ports are correct, then you can send 64byte empty packets from each of the UDP ports to the server(called "door openers").
3) If the above two don't fix it, check the server side logs.The server might be closing the UDP ports.