UDP header is 16 bit but there's actually 24bits - sockets

I am looking to understand UDP header and I see that it's actually 24 bits seen as
struct sockaddr_in {
short sin_family; // e.g. AF_INET //4 bytes
unsigned short sin_port; // e.g. htons(3490) //4 bytes
struct in_addr sin_addr; // see struct in_addr, below //8 bytes
char sin_zero[8]; // zero this if you want to //8 bytes
};
struct in_addr {
unsigned long s_addr; // load with inet_aton()
};
According to this explanation it's 16 bytes. Since sin_zero[8] isn't used anywhere it is 16 bytes ? UDP HEADER The struct size is still 24 bytes. Am I missing something ?
Thanks!

What you have in your question are the C structures for expressing a socket address.
It is a different animal than what actually gets sent on the wire for a UDP header.
Basically the IPv4 header is 20 bytes and the UDP header on top of that is 8 bytes as is also explained by the Geeks for Geeks reference in your question.
I recommend looking at https://en.wikipedia.org/wiki/User_Datagram_Protocol, or installing Wireshark and capturing a UDP packet to see how it looks like.

Related

How to handle fields inside network headers whose length are not multiple of 8 bits

I just started learning socket programming, and I'm trying to implement TCP/UDP protocols using raw sockets.
IP Header
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
|Ver.|IHL|DSCP|ECN| Total length |
+--------+--------+--------+--------+
| Identification |Flags| Offset |
+--------+--------+--------+--------+
| TTL |Protocol| Header Checksum |
+--------+--------+--------+--------+
| Source IP address |
+--------+--------+--------+--------+
| Destination IP address |
+--------+--------+--------+--------+
When writing IP header, the Flags and Offset part, the length of Offset is not multiple of 8 bit. So I take Flags and Offset together as a whole.
uint8 flags = 0;
uint16 offset = htons(6000); // more than 1 byte, so we need to use htons
// in c, we can left(since it's in big endianness) shift offset 3 bit,
// and then convert flags to uint16, and then merge them together
// in some other languages, for example, Haskell,
// htons like functions may return a bytestring which is not an instance of Bit,
// we need to unpack it back into a list of uint8 in order to use bitwise operations.
This method is not very clean, I'm wondering what's the usual way to construct bytestring when its components are of length more than 1 byte and their endianness also needs to be considered.
In C, the usual way would be to declare a uint16_t, uint32_t, or uint64_t temporary variable, use bitwise operators to assemble the bits within that variable, and then use htons() or htonl() to convert the bits into network (aka big-endian) order.
For example, the Flags and Offset fields, taken together, constitute a 16-bit word. So:
uint8_t flags = /* some 3-bit value */;
uint16_t offset = /* some 13-bit value */;
uint16_t flagsAndOffsetBigEndian = htons(flags | (offset << 3));
memcpy(&header[16], &flagsAndOffsetBigEndian, sizeof(uint16_t));

What is difference of the two lengths in pcap's packet header?

Here is the structure of the packet header in pcap:
struct pcap_pkthdr {
struct timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire)*/
};
I wonder what is the real difference between caplen and len? And where are they used?
len is the actual length of the packet on the wire. caplen is the length which is captured and thus present in the pcap file. caplen can be the same but also smaller than len.
How many bytes of a packet will be captured can be specified for example in tcpdump with -s size. While on many system tcpdump will capture up to 64k by default for example on OpenBSD it will only capture 116 bytes by default.

Variable sized i2c reads Raspberry

I am trying to interface A71CH with raspberry PI 3 over i2c, the device requires repeated starts and when a read request is made the first byte the device sends, is always the length of the whole message. When I am trying to make a read, instead of reading a fixed sized message , I want to read the first byte then send NACK signal to the slave after certain amount of bytes have been received that is indicated with the first byte. I used to following code but could not get the results I expected because it only read one byte than sends a NACK signal as you can see below.
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[2];
int r = 0;
int i = 0;
if (bus != I2C_BUS_0) // change if bus 0 is not the correct bus
{
printf("axI2CWriteRead on wrong bus %x (addr %x)\n", bus, addr);
}
messages[0].addr = axSmDevice_addr;
messages[0].flags = 0;
messages[0].len = txLen;
messages[0].buf = pTx;
// NOTE:
// By setting the 'I2C_M_RECV_LEN' bit in 'messages[1].flags' one ensures
// the I2C Block Read feature is used.
messages[1].addr = axSmDevice_addr;
messages[1].flags = I2C_M_RD | I2C_M_RECV_LEN|I2C_M_IGNORE_NAK;
messages[1].len = 256;
messages[1].buf = pRx;
messages[1].buf[0] = 1;
// NOTE:
// By passing the two message structures via the packets structure as
// a parameter to the ioctl call one ensures a Repeated Start is triggered.
packets.msgs = messages;
packets.nmsgs = 2;
// Send the request to the kernel and get the result back
r = ioctl(axSmDevice, I2C_RDWR, &packets);
Is there any way that allows me to make variable sized i2c reads ? What can I do to make it work ? Thanks for looking.
Raspbery doesn't support SMBUS Block Reads, only way to overcome this is to do bitbanging on GPIO pins. As #Ian Abbott mentioned above, I managed to modify bbI2CZip function to fit my need by checking the first byte of the received message and updating the read length afterwards.
I had a similar issue with the rpi3. I wanted to read exactly 32 bytes of data from a register on a slave device, but i2c_smbus_read_block_data() was returning -71 and errno 71 EPROTO.
The solution was to use i2c_smbus_read_i2c_block_data() instead of i2c_smbus_read_block_data().
/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
ask for less than 32 bytes, your code will only work with kernels
2.6.23 and later. */
extern __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length,
__u8 *values);

How to use Int value with specific byte length

Need an Integer property 3 bytes length.
The main goal is I have structure:
packet {
header: UInt8
parameters: 3 bytes
reserve: UInt16
}
Which have to be converted to Data 6 bytes in total!
Guys pls help how can I achive this?

creating a 4Kb Data structure in systemverilog

Creating a 4 kilo bytes of data structure in system-verilog
How to divide this 4 kilo bytes space into 128 bit each location
use, struct type in SystemVerilog.
for example 512 bite data structure of 128 bit,
struct {
bit [127:0] part1;
bit [127:0] part2;
bit [127:0] part3;
bit [127:0] part4;
} largePart_512;
Note that, you have to access this struct with largePart_512,
part1 - largePart_512[127:0]
part2 - largePart_512[255:128]
part3 - largePart_512[383:256]
part4 - largePart_512[511:384]
Create a memory with each word as 128 bits and the depth equal to 4096/128:
logic [127:0] mem [4096/128];