netdev
[Top] [All Lists]

socket() returns "Invalid argument". Why? (part 2 :) )

To: netdev@xxxxxxxxxxx
Subject: socket() returns "Invalid argument". Why? (part 2 :) )
From: Fernando Gont <fernando@xxxxxxxxxxx>
Date: Thu, 10 Jan 2002 00:18:27 -0300
Sender: owner-netdev@xxxxxxxxxxx
Hi!

While I was making some tests with the socket functions, I intentionally called socket() this way:
socket(9999, SOCK_STREAM, 0)

(with a protocol family not supported). I was expecting to get a EPFNOSUPPORT, but I got a EINVAL error code, instead.

After posting a message to comp.protocol.tcp-ip, someone noted that the socket.h header of his Solaris system had a PF_MAX constant, and that it'd be possible that a EINVAL was returned for any protofol family number greater than PF_MAX. I checked my Linux header files, and found in bits/socket.h the following constants definitions:

#define PF_UNSPEC       0       /* Unspecified.  */
#define PF_LOCAL        1       /* Local to host (pipes and file-domain).  */
#define PF_UNIX         PF_LOCAL /* Old BSD name for PF_LOCAL.  */
[....]
#define PF_SNA          22      /* Linux SNA Project */
#define PF_IRDA         23      /* IRDA sockets.  */
#define PF_MAX          32      /* For now..  */

and I got surprised that the PF_MAX constant was *not* defined to be 23 (ie., the highest defined protocol number). Why is PF_MAX defined like this?

I changed my socket() call to:
socket(25, SOCK_STREAM, 0)

(with a protocol familiy lower than PF_MAX) suspecting that perhaps now I'd get a EPFNOSUPPORT. But I still got a EINVAL error code.

So that I had a look at the socket.c source code, and found the following:

int sock_create(int family, int type, int protocol, struct socket **res)
{
        int i;
        struct socket *sock;
        /*
        *       Check protocol is in range
        */
        if(family<0||family>=NPROTO)
                return -EINVAL;

#if defined(CONFIG_KMOD) && defined(CONFIG_NET)
        /* Attempt to load a protocol module if the find failed.
        *
        * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user
        * requested real, full-featured networking support upon configuration.
        * Otherwise module support will break!
        */
        if (net_families[family]==NULL)
        {
                char module_name[30];
                sprintf(module_name,"net-pf-%d",family);
                request_module(module_name);
        }
#endif
        if (net_families[family]==NULL)
                return -EINVAL;



I don't understand why the code says:

        if(family<0||family>=NPROTO)
                return -EINVAL;

instead of:
        if(family<0||family>=PF_MAX)
                return -EPFNOSUPPORT;

(Note that I check "family" against PF_MAX (instead of NPROTO), and that the return value is EPFNOSUPPORT (instead of EINVAL))

I mean:

Why does the code use NPROTO instead of PF_MAX?

What's the point of having PF_MAX (or NPROTO) defined to be a value greater than the highest defined protocol number?

If the TCP/IP stack does not return a EPFNOSUPPORT errror code in this case (the call to socket I pointed out at the beginning of this message), when would it do it?

TIA,

Fernando Gont
e-mail: fernando@xxxxxxxxxxx


<Prev in Thread] Current Thread [Next in Thread>
  • socket() returns "Invalid argument". Why? (part 2 :) ), Fernando Gont <=