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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 protocol 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?

Greetings, Fernando (fernando@gont.com.ar)

"I believe it is a Human impossibility to obtain complete peace of mind
  in this dimension. There's too much suffering and pain -- particularly
  for children."  -Dolores O'Riordan


-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux