In that line he typecasts p,a addrinfo pointer, to a sockaddr_in struct, both structures are no where near similar to each other and I am at a total loss as to how they are filled out. Why does p have to be typecasted? Why can't he just use an actual sockaddr_in pointer, rather than a addrinfo pointer that has been typecasted?
There are other times when typecasting seems to make no sense, such as when typecasting a sockaddr_storage to either a sockaddr_in or a sockaddr_in6
Maybe I am not phrasing my question correctly. ipv4 gets the memory location of p->ai_addr. ai_addr is a sockaddr. ipv4 is a sockaddr_in, they are both completely different structures.
Somehow(This is where I am confused) a sockaddr structure is being used to populate a sockaddr_in structure.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
struct sockaddr {
unsignedshort sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};
// IPv4 AF_INET sockets:
struct sockaddr_in {
short sin_family; // e.g. AF_INET, AF_INET6
unsignedshort sin_port; // e.g. htons(3490)
struct in_addr sin_addr; // see struct in_addr, below
char sin_zero[8]; // zero this if you want to
};
struct in_addr {
unsignedlong s_addr; // load with inet_pton()
};
Does it work by just dumping all the data inside sockaddr into sockaddr_in? For example, since a short and unsigned short are essentially the same thing, is the sa_family variable inside sockaddr taken as sin_family when converted to a sockaddr_in? Same thing with the sa_data, is the first(sa_data[0]) character taken as the unsigned short int sin_port? So sa_data[1], sa_data[2], sa_data[3] and sa_data[4] are used as the unsigned long s_addr? Since a long is 4 bytes and characters are one byte each?
It's polymorphism in C. The socket library uses struct sockaddr* as the interface. However, the implementation is IP v4 and that actually uses struct sockaddr_in*. We know we're using IP v4 and so we use struct sockaddr_in*. But you need to cast pass the struct sockaddr* in the interface.
If this were C++ struct sockaddr would be an interface class and struct sockaddr_in would be an concrete class that implements struct sockaddr. But it's not C++, it's C and there's no language support for polymorphism.
Could you explain that to me a bit more thoroughly? I read the page about polymorphism on this website, but I don't see how that has anything to do with what I am asking. I don't know what you mean by interface and concrete classes, would an interface class be the inherited class?
Your post shows the idea behind it, but not how it actually works. I still don't understand how the values inside sockaddr are converted to something readable by sockaddr_in.
EDIT: Just ran some tests now that I have the time, it seems what I thought in my other post is right. It just straight dumps the data inside sockaddr into sockaddr_in or rather, it tries to access the sockaddr data in the memory location by using sockaddr_in types rather than sockaddr. That explains why sin_zero is there I suppose.
//lets say you have a class that looks like this in binary
10101010 10101010
^mem1 ^mem2
//If you cast it to some other type that maybe has 4 4-bit values, you might get this when you access it
10101010 10101010
^m1 ^m2 ^m3 ^m4
Maybe I am not phrasing my question correctly. ipv4 gets the memory location of p->ai_addr. ai_addr is a sockaddr. ipv4 is a sockaddr_in, they are both completely different structures.
No. ai_addr and ipv4 are both POINTERS to structures not actualy structures. After that assignment statement they are both looking at the same 16 bytes of memory they're just looking at it "differently"