Regarding Pointer to structure in C - c

I am writing a program to implement the virtual software router. My C programming Skills are not that great. When I am going through my skeleton code, I came across this :
struct ip *ippacket = (struct ip*) (packet + sizeof(struct sr_ethernet_hdr));
Can anybody please explain what exactly it means ?

For a good understanding look up "pointer arithmetic."
If 'packet' is a pointer to a packet this is adding the size of a packet header, so the result 'ippacket' would be a pointer to the first byte that follows the packet header.

To answer for certain we would have to know how the variable packet was declared. I'll assume it is a pointer to a type of size 1, for example char* packet.
It appears that packet is expected to point to a block of memory that starts with a struct sr_ethernet_hdr followed by a struct ip, and it is desired that ippacket will point to the struct ip.

Pointer with name ippacket pointing at the adress of a struct ip is initialized to point to the address packet + sizeof(struct sr_ethernet_hdr) after casting that address to the correct type.
You should not be asking this sort of question on stackoverflow, it doesn't contribute to the community and is too basic to be helpful. Also you need to know this sort of thing already if you are writing a virtual router!

Related

Accessing a struct given an unknown pointer to a memory address - C

Suppose I am given a (void*) ptr (my basic understanding is, it represents a pointer to a region of unknown data type) passed through the parameter of a function. I am trying to figure out how to access and check if a struct exists a few addresses behind.
To clarify, I am working with a big char array (not malloced) and the ptr passed into the function should point to an address of an unspecified data type within the array. Located before this data is a struct for which I am trying to access.
void function(void *ptr)
{
void *structPtr = (void*)((void*)ptr - sizeof(struct block));
}
Would this work to get me a pointer to the address of the struct located behind the initial "ptr"? And if so, how could I check if it is the block struct?
Apologizes in advance, I know this code is not specific as I am fairly new to the concepts entirely but also, I am in the process of coming up with an algorithm and not yet implementing it. Any references to possibly useful information are much appreciated.
what you are trying to do is risky as you must be sure that you address a correct place in memory. Usually, we add some magic number in struct block so that we can test here that we are not going anywhere.
This pattern is generally used in memory allocators,
have a look to https://sourceware.org/glibc/wiki/MallocInternals for an example.
The usual way of writing this is something like:
...function(void *ptr) {
struct block *hdr = (struct block *)ptr - 1;
relying on pointer arithmetic automatically scaling by the size of the pointed at type. As long as all the pointers passed in here were originally created by taking a pointer to a valid struct block and adding 1 to it (to get the memory after it), you should be fine.

Casting char array to struct pointer

I am trying to understand the following casting from this code
char out_packet_buffer[4500] ;
struct ip6_hdr *iphdr ;
iphdr = (struct ip6_hdr *) &out_packet_buffer[0];
Is my understanding correct that the member variables of the struct iphdr are stored in char array out_packet_buffer? Later in the code, out_packet_buffer is never used. Instead, iphdr is memcpyied to an uint8_t memory location (ether_frame). But iphdr is not uint8_t.
I'd appreciate any guidance for me to understand what is happening here.
Thanks
Is my understanding correct that the member variables of the struct iphdr are stored in char array out_packet_buffer?
Kind of. What happens in this casting is that we start "looking" at the memory chunk that starts from &out_packet_buffer[0] (or just out_packet_buffer) as a struct ip6_hdr instead of a char[].
Any later usage of iphdr is using the same memory, but splits it into struct ip6_hdr members instead of into char
As #Christian Gibbons said, I also think this violates strict aliasing which is UB
It looks like the code is preparing a packet for transmission over a network. The packet will consist of a header and a payload. The whole packet is, presumably, stored in out_packet_buffer. The ip6_header structure is the first few bytes of this, the data payload follows after. Using a structure for the header makes the code more readable but there’ll probably be a "structure order to network order" function just before it’s sent to a socket.
In any case, the data packet is just a sequence of bytes, so casting it to any 8-bit type is feasible

Does it make any difference using offsetof() instead of sizeof() with sockets?

In socket programming, especially while dealing with Unix domain sockets of type struct sockaddr_un, some people use offsetof() to calculate the size of the sockaddr_un structure like-
struct sockaddr_un {
sa_family_t sun_family; /* AF_UNIX */
char sun_path[108]; /* pathname */
};
size = (offsetof (struct sockaddr_un, sun_path)
+ strlen (name.sun_path));
In some other places, they use
size = sizeof(struct sockaddr_un)
I understand that the first method accounts for shorter path names and the second gives a fixed max size irrespective of the actual path length.
Does it really make a difference to a function like bind which is passed this value? If not, can these 2 be used interchangeably?
offsetof takes into account any padding that the C compiler may have added after the size of the base members. However, if you define network packets using C structures that contain padding added by the C compiler, you have bigger problems! In fact I'd ensure that a test case was added which ensures that both methods return the same size, to guard against incorrect compile options changing padding rules, for example.
In the context of this question, no, it doesn't make any difference to bind.
I would say the offsetof version you posted is incorrect. It should have at least a +1 in it, as the path is defined as a null-terminated string, and that's the length that the kernel returns e.g. from getsockname().
Even with the +1, I don't see the point of using something complex over something simple. It does save a few bytes being transferred to the kernel, but bind() and friends are hardly the rate-determine steps.

C: Copying Pointer data using = (Equal to)

This is my first post here. I tried to find a similar question but couldn't find any and hence I am posting this question.
I am trying to copy the data in a structure pointer to another structure pointer in C as shown below. Looks like using just an '=' did the trick. Could someone please explain how the data in pointer srcStruct got copied to another memory location (pointer by destStruct) without using memcpy()?
Is this a pointer property? or is there any risk in doing this?
struct myTestStruct
{
short variable1;
short variable2;
};
struct myTestStruct *destStruct = (struct myTestStruct *)malloc(sizeof(struct myTestStruct));
struct myTestStruct *srcStruct = (struct myTestStruct *)malloc(sizeof(struct myTestStruct));
srcStruct->variable1 = 11;
srcStruct->variable2 = 12;
*destStruct = *srcStruct;
Thanks in advance.
Regards,
AJK
By using the dereferencing operator *, you are basically treating the data that the pointers point to as regular variables. Structs are copied by value, not by reference, if you aren't copying the pointer, so it's just like copying an int to another int. You are essentially doing the following by using the dereference operator *:
struct myTestStruct destStruct, srcStruct;
srcStruct.variable1 = 11;
destStruct = srcStruct; //this gets copied by value
What you're doing here isn't actually connected to pointers at all; it's a property of structs in general in C that they can be assigned as a whole unit with a single = operation. When you dereference a pointer you're using the pointed-to value directly in the expression, so what you've really got there, with a dereference on both sides, is an assignment from a value struct to another value struct. The pointers have both been "expanded out", leaving the values of the whole structs themselves.
How the value is copied is up to the compiler. It will likely emit custom instructions to do it in the most efficient possible way, but it could also use memcpy if it wanted to. There is absolutely no risk in doing this - structs being assignable is a core element of the C language and not going away! It is perfectly idiomatic, and usually the best way to do whatever you're doing that needs data copied from one struct to another. Certainly better than invoking memcpy unnecessarily.

Explanation of piece of code used in header files for socket programming

Can anybody explain me this piece of code?
/* Pad to size of `struct sockaddr'. */
unsigned char sin_zero[sizeof (struct sockaddr) -
__SOCKADDR_COMMON_SIZE -
sizeof (in_port_t) -
sizeof (struct in_addr)];
here sin_zero is a char array but what is remaining part? It should be some integer. what this sign "-" means? Can anybody explain this to me?
Well, the - is called a "minus" :-) Seriously, everything between the square brackets is meant to calculate the size of sin_zero, which is a so-called padding. It's a member inside struct sockaddr_in, and it's just here to make sure that struct sockaddr_in is exactly of a certain size, most likely 16 bytes. The idea is to ensure that most(*) struct sockaddr variants are of the same size to avoid malloc problems.
Quoting a document I found on the subject:
The POSIX specification requires only three members in the structure: sin_family, sin_addr, and sin_port. It is acceptable for a POSIX-compliant implementation to define additional structure members, and this is normal for an Internet socket address structure. Almost all implementations add the sin_zero member so that all socket address structures are at least 16 bytes in size.
(*) In an earlier version, I wrote all. #MaximYegorushkin correctly noted that this is not true, for example struct sockaddr_un is bigger. If you want the maximum size that fits all types of addresses, use sizeof(struct sockaddr_storage). This struct exists only for this purpose (AFAIK).
sin_zero is a structure member that is used to pad out the structure to a certain minimum size. In this case, the amount of padding is calculated by starting with the desired size (sizeof (struct sockaddr)) and subtracting the space taken up by the other struct members from it.
So, to answer the question: The sign "-" here just means "subtraction".
I run into this question while learning C, too.
For other beginners (like me) it could be interesting to know that it seems to be kind of important clearing *sin_zero* in your programs (more on this topic can be found HERE).
On some systems/architectures it can cause problems and on others it can be fine not explicitly clearing *sin_zero*.
Example for clearing sin_zero:
struct sockaddr_in serversin;
memset(&serversin, 0, sizeof(serversin));
serversin.sin_family = ...;
serversin.sin_addr = ...;
serversin.sin_port = ...;
To prevent some future bugs I think it's best practice to explicitly clear it.
Sockaddr contains some things like in_addr and in_port_t, and it has room for some more. The sin_zero is the remaining size in sockaddr. It is the size of sockaddr which is not filled with something else.
Supposedly the sin_zero variable would be initialised to all null bytes, and set as the last field or at the end of the sockaddr struct. The purpose of this is to set the remaining bytes to null.
sin_zeor is a char array with the size calculated with the formula in the [] brackets
The '-' sign is actually a mathematical minus sign :-)
hth
Mario
It calculates the size of the array based on the size of some structs and a constant. The sign "-" means minus.

Resources