LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-04-2011, 08:52 PM   #1
golden_boy615
Member
 
Registered: Dec 2008
Distribution: Ubuntu Fedora
Posts: 445

Rep: Reputation: 18
why I have to cast sockaddr_un and sockaddr_in to sockaddr * in bind()


hello
I am new in socket programming and may be my question is some how silly but it really confused me I want to know why I have to define sockaddr_un or sockaddr_un in my program but when I want to send it to bind() I have to cast them in to sockaddr* ,I know that bind accept sockaddr* but I mean why we do not define a vriable in sockaddr* itself format in our program without defining sockaddr_un or sockaddr_in . does it have technical reason or historical reason ?
 
Old 08-05-2011, 01:33 AM   #2
JohnGraham
Member
 
Registered: Oct 2009
Posts: 467

Rep: Reputation: 139Reputation: 139
A sockaddr is used to refer to any type of address. a sockaddr_in or a sockaddr_un are used to refer to specific types of address (in this case an IPv4 address and a UNIX local addresses, respectively). This allows bind() (and other system calls) to present a protocol-independent API.
 
Old 08-06-2011, 12:09 AM   #3
golden_boy615
Member
 
Registered: Dec 2008
Distribution: Ubuntu Fedora
Posts: 445

Original Poster
Rep: Reputation: 18
thank you for answering but I don't think this is a good answer because it (sockaddr) could be initialized itself for each type without casting, why they design it like this. This is like that I create function with float argument but always define integer in my programs main() and pass it to that function by casting to float which I can define float variable itself not integer.
 
Old 08-06-2011, 10:30 AM   #4
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by golden_boy615 View Post
thank you for answering but I don't think this is a good answer because it (sockaddr) could be initialized itself for each type without casting, why they design it like this.
I don't think that's true, at least not using explicit data-member names. struct sockaddr does have data members, but they're abstractions of the struct sockaddr_* members. Here are the requirements for each:
http://pubs.opengroup.org/onlinepubs...ssocket.h.html
http://pubs.opengroup.org/onlinepubs...inet/in.h.html
http://pubs.opengroup.org/onlinepubs.../sys/un.h.html

I'm sure an implementation of libc could specify all of the members of struct sockaddr as the unions of the respective members of struct sockaddr_*, but struct sockaddr isn't meant to be manipulated directly.
Kevin Barry
 
Old 08-06-2011, 05:46 PM   #5
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Quote:
Q: Why I have to cast sockaddr_un and sockaddr_in to sockaddr *?
Because that's just the way it is . Get over it.

http://theinspirationroom.com/daily/...the-way-it-is/

PS:
Can you think of a better way to define a struct that's not "opaque", but is extensible, and can handle an arbitrary number of different extensions (family-interet, family-unix, family-appletalk, family-ipv6, etc etc)? Remember - the "void" keyword (and, for that matter, much of the "C" language as we know it today) wasn't even *invented* when Bill Joy created sockets in the late 1970's

Last edited by paulsm4; 08-06-2011 at 05:49 PM.
 
Old 12-16-2011, 03:26 PM   #6
golden_boy615
Member
 
Registered: Dec 2008
Distribution: Ubuntu Fedora
Posts: 445

Original Poster
Rep: Reputation: 18
still looking for logical and better answer....
 
Old 12-17-2011, 07:34 PM   #7
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by golden_boy615 View Post
still looking for logical and better answer....
Please post it with a reference when you find it...
Kevin Barry
 
1 members found this post helpful.
Old 06-26-2018, 08:25 PM   #8
RichardWicks
LQ Newbie
 
Registered: Jun 2018
Posts: 1

Rep: Reputation: Disabled
Frankly, because they screwed up...

Functions in the BSD socket interface operate on many different types of sockets, for example IPV4, IPV6, Unix sockets, etc but you're wondering why you have to CAST.

Well, frankly, because they screwed up on the interface. They should have made a union to allow clean casting. For example the sockaddr structure (the generic structure) can be any of the following:

Code:
struct sockaddr
struct sockaddr_in
struct sockaddr_storage
struct sockaddr_in6
struct sockaddr_un
struct sockaddr_dl
struct sockaddr_storage
And probably a few I missed. The correct way to have done this is within each structure, for example the sockaddr_in structure, should have been defined something like this:

Code:
struct correct_sockaddr_in
{
  union
  {
    struct
    {
      sa_family_t    sin_family; /* address family: AF_INET */
      in_port_t      sin_port;   /* port in network byte order */
      struct in_addr sin_addr;   /* internet address */
    };
    struct sockaddr generic;     /* shares the memory with the sin_family, sin_port, sin_addr */
  };
};
This original interface was created back in 1982, so it's possible that C didn't support anonymous structures or unions at the time - but if it did, this is a major error in my opinion. Basically, the rule is, if you're using a BSD socket that takes a sockaddr, you can cast anything that is sockaddr_<anything> to sockaddr. Typically, I just use a C++/C wrapper around all the functions, so I don't have to worry about making casting errors, which I tend to do, a lot - when I've been away from the interface for any length of time.

On a modern compiler wrappers add little or no overhead, and almost always no overhead - so make use of them. Small functions are automatically inlined unless you specifically request absolutely no optimization, even in C - even if you're calling a statically linked library function. It's not 1982 anymore...

What's worse, is this interface is part of the POSIX standard, which means, basically, it's never going to go away, but at the same time, there's no reason not to have a better interface that exists on top of it, that does what I described. I've done it often enough. The IPV6 interface is 100% compatible with IPV4, so I recommend if you're doing any socket programing - use that. If you start working with IPV6, you're going to have to learn about zones (aka scopes) if your using what is called a "link local address". IPV6 is a little different, and in some ways, more work - but if you're using IPV4 address, it works pretty much the same.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
sockaddr_in and sockaddr_un: difference? cleopard Programming 4 09-20-2011 07:41 AM
Typecast struct sockaddr in struct sockaddr_in sudhansu Linux - Kernel 1 02-17-2009 10:33 AM
sockaddr_un ?? blackzone Programming 1 08-13-2004 06:36 AM
sockaddr_in and sockaddr AquamaN Programming 4 05-02-2004 03:52 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:11 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration