Wrong size of IPv4 packets in DPDK - c

I have these packets saved in pcap file (shown in wireshark)
Iam parsing these packets using DPDK and for some reason i cannot use mbufs. To parse them iam using struct ipv4_hdr and struct ether_hdr as following:
eth_hdr = (struct ether_hdr *) pckt;
ip_hdr = (struct ipv4_hdr *)((unsigned char *) pckt + sizeof(struct ether_hdr));
The total_length in ipv4_hdr is size of ipv4 header + size of data. With size of etherhet header it should be the total length of packet, right?
size = rte_bswap16(ip_hdr->total_length) + sizeof(struct ether_hdr);
which gives me for these 6 packets output:
54, 54, 54, 54, 54, 54
For first, third and fifth packets its correct, but for the others its 6 bytes less than it should be.
Iam asking what these 6 bytes in packets are and how to find out the correct sizes using ipv4 and ether headers:
54, 60, 54, 60, 54, 60
In wireshark all of these packets has total_length 40 bytes and sizeof(ether_hdr) is 14 bytes -> it should be 54.

I guess the root cause is the minimum Ethernet frame length. As Wikipedia says, the minimum frame length is 64 bytes.
At the end of each Ethernet frame we add Frame Check Sequence (FCS, 4 octets), so it makes minimum 60 octets for Ethernet header and payload.
Now answering your questions:
I am asking what these 6 bytes in packets
Those are zero paddings to make ethernet frame (with FCS) at least 64 octets.
For outgoing packets, there are no paddings yet, they will be added later by the driver or NIC itself. So Wireshark shows unpadded frames, i.e. 40 bytes of IP + 14 bytes of Ethernet header (without FCS) makes 54 bytes.
For incoming packets, there are already paddings added by the sending part. So Wireshark shows frames with padding, i.e. 64 octets - 4 octets FCS = 60 octets.
how to find out the correct sizes using ipv4 and ether headers
Your method is completely correct. Those zeros at the end of the frame are just padding and should be ignored. If we really need a correct length, we should take into account the minimum frame length as described above.

Related

How can I return the packets using bpf

I want to filter packets using bpf. I studied the bpf manual and write the filter. This is the last line of my filter:
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 16),
I loaded the ip packet length. Now I want to return sizeof(struct ether_header) plus the length abov.
How can I write this filter?
Here, you load a word from your packet into the accumulator:
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 16),
First, you have to add the size of the ethernet header (14 bytes) to the accumulator:
BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 14),
and then, you return this value in the accumulator to get the data to userspace:
BPF_STMT(BPF_RET+BPF_A, 0)
Note:
If you mean to extract the IP total length, you have to load a halfword in your first statement (the ip total length is only a 16-bit value, so use BPF_H instead of BPF_W)

Linux sound programming. How to determine a buffer size in frames?

I'm experimenting with ALSA and came across with the following configuration parameter in this howto, Section 2:
The unit of the buffersize depends on the function. Sometimes it is
given in bytes, sometimes the number of frames has to be specified.
One frame is the sample data vector for all channels. For 16 Bit
stereo data, one frame has a length of four bytes.
/* Set buffer size (in frames). The resulting latency is given by */
/* latency = periodsize * periods / (rate * bytes_per_frame) */
if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (periodsize * periods)>>2) < 0) {
fprintf(stderr, "Error setting buffersize.\n");
return(-1);
}
I don't understand this For 16 Bit stereo data, one frame has a length
of four bytes
Why is it four? Does it follow by the number of channels: 2? I mean earlier they configured it as follows:
/* Set number of channels */
if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 2) < 0) {
fprintf(stderr, "Error setting channels.\n");
return(-1);
}
How about if my acoustic system contains 4 outputs? Or 6? Does it mean that I have to configre it to 16 Bit * 4 and 16 Bit * 6 correspondingly?
Why is it four? Does it follow by the number of channels: 2?
Yes, according to mentioned earlier:
One frame is the sample data vector for all channels.
So for stereo 16 bit data, there are two (left and right) channels of 16 bits (=2 bytes) each, so that totals to 4 bytes per frame.

Dictionary/LUT implementation in C

I have 500 frames for which I have stored the length of each frame in an array as the frames are in ascending order.
const char header_length = {23,34, 45, 12, 23,56,......,2,4};
Here frame 1 is of length 23 bytes, frame 2 is of length 34 bytes.
Now when I am requested frame with header 4 I would have to reply with frame with header 7, frame with header 8 would require a reply frame with header 60. The co-relation is a constant, header 4 frame will always reply header 7 frame. So I need a look up table sort of implementation here. I plan to implement this using a multidimensional array. Although is there a better way to implement this?
I am answering based on OP's comment above, otherwise OP's question just does not make any sense.
Assuming that the maximum frame size is limited by a considerably small N, then it may be better to just keep another array as the following,
const char header_length[] = {23,34, 45, 12, 23,56,......,2,4};
const int to_be_replied[N+1] = {...,0,...,2,...,0,...,4,...}; /* fill remaining */
/* here are their positions #12 #23 #34 #45 */
and use the following during the reply.
int frame_num, reply_frame_num;
frame_num = get_frame_number(); /* some function */
reply_frame_num = to_be_replied[header_length[frame_num]];

nrpe buffer size exceed

I'm working on nagios nrpe and i am trying to implement my own nrpe plug-ins, the problem is my plugins output has more then 1024 bytes of char, which is more then the nrpe packet buffer size.
A packet carrying the NRPE payload has a fixed layout where in order of occurence in the packet the following fields are defined:
[2 Byte int16_t] – Version number
[2 Byte int16_t] – Type (Query/Response)
[4 Byte u_int32_t] – CRC32 Checksum
[2 Byte int16_t] – result code (OK, WARNING, ERROR, UNKNOWN)
[1024 Byte char] Buffer
Is there any way to increase the size of this buffer??????

Is this a bug in inet_pton with IPv6?

When trying to resolve Facebook's numeric IP address as a test 2620:0:1cfe:face:b00c::3:, if I leave the terminating 0 off the address, inet_pton() barfs. If I put it back on everything works.
Running ubuntu 9.10:
rc = inet_pton(AF_INET6, "2620:0:1cfe:face:b00c::3:0", &ip); -> OK
rc = inet_pton(AF_INET6, "2620:0:1cfe:face:b00c::3:", &ip); -> returns -2
ping6 -n www.v6.facebook.com returns the IP address w/o the trailing 0.
It seems that ping, in it's great wisdom, adds a colon after the IP address like so:
PING maclawran.ca (173.230.128.18) 56(84) bytes of data.
64 bytes from ns.maclawran.ca (173.230.128.18): icmp_seq=1 ttl=51 time=50.3 ms
Of course if you're pinging an IPv6 address, it's already got lots of colons in it:
PING 2620:0:1cfe:face:b00c::3(2620:0:1cfe:face:b00c::3) 56 data bytes
64 bytes from 2620:0:1cfe:face:b00c::3: icmp_seq=1 ttl=52 time=9.44 ms
======================================^ << THANKS PING

Resources