When use create a socket of type AF_INET / SOCK_DGRAM, the operating system processes the Ethernet, IP, and UDP headers and strips them off before passing them to you. What you see in buffer is what immediately follows the UDP header.
The fifth parameter to recvfrom
gives you the source IP and source port of the incoming packet. If you want to see more than just that you need to use a packet capture library like libpcap.
Edit:
It seems that this data packet contains IP addresses as part of sflow data. You were trying to parse it as if it was a raw Ethernet frame. What you instead need to do is look at the sflow datagram definition and use that to figure out how the packet is laid out and parse accordingly. You don’t need to use memcpy
to do that, just use pointers to the relevant structs to point to the proper place in the buffer. This is the same basic technique you were using before, just with a different set of structs.
Edit 2:
It looks like we’re way off on what the data looks like. I took the bytes from the packet listed above, read them into a buffer and sent it out in a UDP packet. I fired up Wireshark, which gave us this:
So the packet contains:
- The sflow version, 32-bit (5)
- an 32 bit int (value=1)
- a
struct sample_datagram_v5
- the number of samples (32-bit int, value=6)
- six samples
The first sample contains:
- The sample type as a
data_format
(in this case a flow sample) - a
struct flow_sample
- the number of flow samples (32-bit int, value=2)
The first flow in the first sample:
- The flow type as a
data_format
(int this case a raw packet sample, so…) - the flow data length (32-bit int, value=144)
- a
struct sampled_header
- 4 bytes that are skipped as per the value of
sampled_header.stripped
- ethernet header
- IP header (payload=TCP)
- TCP header (port=80)
- data bytes (62)
The second flow in the first sample:
- The flow type as a
data_format
(int this case extended switch data) - the flow data length (32-bit int, value=16)
- a
struct extended_switch
Then five more samples. In this case, all the samples contain a raw packet header and extended switch data.
So this should give you a better idea of what you need to do. Since each data packet will be different, you’ll need to figure our how many samples you have. Then for each sample, you’ll need to figure out the type, and based on that figure out how to parse the individual flows.
If you need more examples I’d strongly suggest using Wireshark to capture these sflow packets so you can see exactly what’s in them to validate that your parser works for all expected input.
Related question for reference: use of memcpy to store data from buffer into struct