Cast in sockets

Asked

Viewed 108 times

4

Guys wanted to understand what the reason of doing these cast below is just by aesthetics? What does it really affect in the code?

struct iphdr *ip; 

char *buffer    

ip = (struct iphdr*) packet;

icmp = (struct icmphdr*) (packet + sizeof(struct iphdr));

2 answers

6

Why use cast where you don’t seem to need

Only with a passage can not explain much, but it is unlikely that it is only aesthetic, even because I have not seen where it is most beautiful. Cast unnecessary is usually only done by those who do not know how to program (there are exceptions).

Oftentimes the cast does not make any conversion, just informs the compiler that the programmer is aware that the operation there involves the use of information that may originally be different but that he wants to use as a defined type.

Some compilers may not complain, but it is safer to issue at least one Warning that the operation is potentially wrong. Obliging to be explicit is one way to avoid bugs. Luckily today compilers often require that the cast be done to ensure that this is the same intention.

What this code does

This code is reading a TCP/IP package that is no longer a huge sequence of bytes (one buffer) with some significance only for protocol. Aware of the protocol, the programmer understands which are the blocks of this huge sequence that indicate certain information contained within the protocol.

What this code is doing is taking each of these blocks and assigning it to a variable each.

How he does it?

It takes the address of the packet containing the first information, the IP. Then it throws a pointer at the variable ip of the code that will point to the first pack block, that’s where the package IP is.

Since this pointer has no meaning for the code, it may not be what you should do. So the compiler requires that you put the cast to inform you that you want this "arbitrary" pointer to be considered a pointer to the structure iphdr.

The same can be said for cast following for the variable icmp. Ali is making a shift from the address initially obtained to map to another structure (note that the displacement is exactly the size of the first information). That is, it will point to the second block of information contained in the package. The cast serves to indicate to the compiler that this value pointed out in this sequence can be read quietly as a "pointer to a structure icmphdr".

It would not necessarily need to create several isolated variables for each block of protocol information. He could throw this information into a structure specifically designed to receive protocol information. In some scenarios this is the right thing to do. In this case the cast in each item would not even be necessary. The layout of a TCP/IP package is practically a struct ready. Of course, if you are going to perform some conversions you cannot take advantage of the entire package to map directly into the structure, but if you need data conversion, the package cannot be used for pointing.

6


Extracted from the OS response:
https://stackoverflow.com/a/13620771/3134655

The structure iphdr is used to directly access the structure of a package IP.

In the code snippet below (taken from the above reference):

struct iphdr *ip, *ip_reply;
char *packet, *buffer;

packet = malloc(sizeof(struct iphdr) + sizeof(struct icmphdr));
buffer = malloc(sizeof(struct iphdr) + sizeof(struct icmphdr));
ip = (struct iphdr*) packet;
icmp = (struct icmphdr*) (packet + sizeof(struct iphdr));

First, it is necessary to allocate memory with the command malloc.

How this command returns a pointer of the type void * stored in the variable packet, who’s kind char * (a generic buffer), the cast is needed to reference the buffer packet (for example) with the correct type:

struct iphdr *.

Through this reference, it is possible to assign the values correctly to each member of the structure:

ip->ihl         = 5;
ip->version     = 4;
ip->tot_len     = sizeof(struct iphdr) + sizeof(struct icmphdr);
ip->protocol    = IPPROTO_ICMP;
ip->saddr       = inet_addr(src_addr);
ip->daddr       = inet_addr(dst_addr);
ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr)); 

For further reference (in English):

https://beej.us/guide/bgnet/html/

  • Gomiero when I cast as ip = (struct iphdr*) Packet , the Packet variable is modeled with the members of the iphdr structure?

  • @user37361 No. From the beginning: the malloc reserves a space (block) in memory, which is no more than a sequence of bytes. When you make a cast, simply put, you are "explaining" to the compiler C how it will see this block of bytes. Dummy example: the first 4 bytes of the block form an integer (int), the next 8 are a floating point number (double), and so on.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.