C code, url=inet_ntoa(*(struct in_addr *)ip->h_addr); I don’t understand what’s going on

Asked

Viewed 108 times

1

I was studying sockets for this stuff https://www.exploit-db.com/papers/13634/ and I came across a code that I don’t understand what’s going on. That’s the part of the code:

struct hostent *ip;
...
// função da lib netdb.h para converter ai nosso host para IP
  ip = gethostbyname(host);
  url=inet_ntoa(*(struct in_addr *)ip->h_addr);
  strcat(getpage,page);
  printf("%s",getpage);

The line that starts with 'url' is that I don’t understand what’s going on. From what I’ve researched so far I’ve discovered that: struct hostent has the fields

char  *h_name;            /* official name of host */
char **h_aliases;         /* alias list */
int    h_addrtype;        /* host address type */
int    h_length;          /* length of address */
char **h_addr_list; /* list of addresses */

and the countryside h_addr that equals char **h_addr_list[0]; //primeira posiçao do vetor h_addr_list. gethostbyname() returns a hostent(struct! ) for the variable 'ip', then accessing ip->h_addr I am accessing a pointer that is of the type char, but is being cast for pointer struct in_addr:

url=inet_ntoa(*(struct in_addr *)ip->h_addr); but h_addr is not an in_addr struct (which has an unsigned long) and to complete, this * asterisk that comes before (struct in_addr *) What are you doing? I don’t understand this syntax... I researched a lot but I still don’t understand.

1 answer

1


And look, man! All right?

but h_addr is not an in_addr struct (which has an unsigned long)

Exactly, how gethostbyname() can return a hostent.h_addr_list containing addrs of the type in_addr or in6_addr and for this reason hostent.h_addr_list is a **char. this way being necessary the cast.

Obs. to check which type of addr, you can cast to sockaddr and check the field sa_family and cast the corresponding cast.


sockaddr *addr = (struct sockaddr *)ip->h_addr;

if(addr.sa_family == INET_ADDR)
{
  in_addr* ipv4 = (struct in_addr*)addr;
}
else if(addr.sa_family == INET6_ADDR)
{
  in6_addr* ipv6 = (struct in_addr*)addr;
}
else
{
  // erro
}

to complete, this asterisk * that comes before (struct in_addr *) what you are doing?

according to the declaration char *inet_ntoa(struct in_addr in); the parameter in is not a pointer and that is why the * on the pointer is used, to take the instance of the Object and the Object is copied and not referenced.

I hope I was clear.

  • Very clear, congratulations and thank you very much man.

  • Noting that you have a good knowledge on the subject I would just like to ask if you know about any material that covers well sockets and typecasting, because although you understand I haven’t completely mastered how I want that part(typecasting) And I’m learning sockets but some materials I picked up aren’t very good. The only one I consider worthy of those is the Hacking: the art of exploitation. That has a content on C Very good, and is also a tip in thanks.

  • socket and Typecast no, but for socket I have a great material that is this link. If you want to understand better about Typecast, try to understand about memory padding and align. This will give you a good understanding of the subject. link.

  • if my answer was correct, please mark the post as resolved to help other people with the same question (and help with dots! kkk...).

  • user with no experience in stackoverflow here, then forgot to mark kkk but is there marked, and thanks again.

Browser other questions tagged

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