Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Mar 2008 22:57:03 -0700
From:      Patrick Mahan <mahan@mahan.org>
To:        Andrew Falanga <af300wsm@gmail.com>
Cc:        FreeBSD Questions <freebsd-questions@freebsd.org>
Subject:   Re: Network programming question
Message-ID:  <47DA13AF.5090804@mahan.org>
In-Reply-To: <340a29540803131111g20315740n629ee146bc2f8602@mail.gmail.com>
References:  <340a29540803130910l2a5badacxe50cd81ace87e1f7@mail.gmail.com>	 <47D9682B.5060402@mahan.org> <340a29540803131111g20315740n629ee146bc2f8602@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help


Andrew Falanga presented these words - circa 3/13/08 11:11 AM->
> On Thu, Mar 13, 2008 at 11:45 AM, Patrick Mahan <mahan@mahan.org> wrote:
>>
>>  Andrew Falanga presented these words - circa 3/13/08 9:10 AM->
>>
>>> Hi,
>>  See man inet_pton . . . for details.
>>
>>  Briefly, inet_pton() doesn't understand sockaddr structures.  Instead,
>>  it only understands in_addr or in6_addr structures which are included
>>  inside the sockaddr structure.  So your above example should be changed
>>  to
>>
> 
> Ok, I should have thought of that when reading the manual.
> 
>>    if ((res = inet_pton(AF_INET, "192.168.0.1", &sa.sin_addr)) < 0)
>>      perror("inet_pton");
>>
>>
>>  Because it is treating the sockaddr_in structure as an in_addr structure
>>  which is clobbering the sin_family field.
>>
> 
> If this is true, then why are my packets sent at all?  The definition
> of sockaddr_in (from /usr/include/netinet/in.h):
> 
> struct sockaddr_in {
> 	uint8_t	sin_len;
> 	sa_family_t	sin_family;
> 	in_port_t	sin_port;
> 	struct	in_addr sin_addr;
> 	char	sin_zero[8];
> };
> 
> 
> The definition of in_addr (from /usr/include/netinet/in.h):
> 
> struct in_addr {
> 	in_addr_t s_addr;
> };
> 
> The definition of in_addr_t (from /usr/include/netinet/in.h):
> typedef	uint32_t		in_addr_t;
> 
> Passing in what I have, the address should indeed (as you've pointed
> out) clobber the sin_family member.  However, since in_addr is
> basically an unsigned integer, i.e. 4 bytes wide, shouldn't
> inet_pton(3) clobber sin_len, sin_family & sin_port before ever
> reaching sin_addr?  The sin_len & sin_family are 8 bit quantities, the
> sin_port is 16 bits, that's 32.  If inet_pton(3) is expecting only an
> in_addr I would think that a call to sendto(2) would fail because the
> address in sin_addr is not filled, correct?

inet_pton() clobbered the fields you pointed out.  In fact the sin_family
field was being set to 0x01 which caused your initial EADDRNOTSUPPORT error
you were seeing.  You quick change fixed that problem.  However, (depending
on how sockaddr_in structure is actually allocated) the sin_addr field was
0.0.0.0.  This is actually an accepted form of the broadcast address for UDP
packets.  I forget exactly who the culprit was (Sun comes to mind) but there
was a need to allow broadcasts to 0.0.0.0 (which is also know as INADDR_ANY).
So, therefore, sendto() succeeded, just not in the way you expected.  Looking
at in_pcbconnect_setup() in the kernel shows that actually the packet is sent
to the local primary interface address.

Let's look at what really happen to that packet -

   "192.168.0.1" after being mangled by inet_pton() gives
   the field sin_addr.s_addr of 0x0100A8C0.  This should make
   your sockaddr_in structure look like -

     sa.sin_len = 0x01
     sa.sin_family = 0x00
     sa.sin_port = 0xA8C0 (which is port 49320)
     sa.sin_addr.s_addr = 0x00000000

So the sendto() call was sending a packet to your local interface for port 49320.
And since UDP is a connectionless protocol, you don't have a way (unless it is
builtin to your application protocol) to determine an error.  For example, TFTP
sends back notification for every dgram received.

I hope this helps with your understanding.  I highly recommend if you are going
to do more network programming that you obtain at least some books on the subject.


Patrick



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?47DA13AF.5090804>