|
List Info
Thread: Network programming question
|
|
| Network programming question |

|
2008-03-13 11:10:01 |
Hi,
I'd like to know why the inet_pton(3) doesn't fill in the
address
family of the proper structure passed into it. I'm at a
complete loss
for why. Here's the prototype:
int inet_pton(int af, const char * restrict src, void *
restrict dst);
Three arguments only. The address family, hm, I'm passing
it in; the
address string in printable ASCII text, and a void pointer
to the
address structure to put the address into, presumably one of
the
sockaddr_* family structures for AF_INET or AF_INET6
(further, the man
page says that this function is only valid for these two
families now
anyway).
>From some coding for a program, I did find that this
function,
inet_pton(3), *does* in fact mangle the sin_family member of
the
sockaddr_in structure, so why not "mangle" it to
what it should be? I
was doing something like this:
// valid code above
sockaddr_in sa;
sa.sin_family = AF_INET;
sa.sin_port = htons(3252);
inet_pton(AF_INET, "192.168.0.1", &sa);
sendto(sa, msg, strlen(msg), 0, (struct sockaddr*)&sa,
sizeof(sa));
The call to sendto is wrapped in an if an was failing for
errno code
47, Address family not supported by protocol (I was using
UDP). I
changed the assignment of AF_INET to the sa.sin_family
member to
*after* the call to inet_pton(3) and suddenly everything
worked. Why?
Since the address family was used by inet_pton(3) to figure
out how
to read the address and assign it to sa.sin_addr.s_addr, why
not
simply assign AF_INET to the address family member in
inet_pton(3)?
I'm not trying to be argumentative. I'm just curious. It
seems like
redundancy. I've used the address family to tell
inet_pton(3) how to
operate, and then this function can't assign it to the
sockaddr_in
structure passed to it? This makes little sense. In case
it's
because I'm using older FBSD libraries that had a flaw
fixed, I'm
using FreeBSD 6.2-RELEASE-p4. Is this because that's how
POSIX
defined it to work? Is this the right venue or should I try
one of
the other mailing lists?
Thanks,
Andy
--
A: Because it messes up the order in which people normally
read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
| Re: Network programming question |
  United States |
2008-03-13 12:45:15 |
Andrew Falanga presented these words - circa 3/13/08 9:10
AM->
> Hi,
>
> I'd like to know why the inet_pton(3) doesn't fill in
the address
> family of the proper structure passed into it. I'm at
a complete loss
> for why. Here's the prototype:
>
> int inet_pton(int af, const char * restrict src, void *
restrict dst);
>
>
> Three arguments only. The address family, hm, I'm
passing it in; the
> address string in printable ASCII text, and a void
pointer to the
> address structure to put the address into, presumably
one of the
> sockaddr_* family structures for AF_INET or AF_INET6
(further, the man
> page says that this function is only valid for these
two families now
> anyway).
>
>>From some coding for a program, I did find that this
function,
> inet_pton(3), *does* in fact mangle the sin_family
member of the
> sockaddr_in structure, so why not "mangle" it
to what it should be? I
> was doing something like this:
>
> // valid code above
> sockaddr_in sa;
>
> sa.sin_family = AF_INET;
> sa.sin_port = htons(3252);
>
> inet_pton(AF_INET, "192.168.0.1", &sa);
>
> sendto(sa, msg, strlen(msg), 0, (struct
sockaddr*)&sa, sizeof(sa));
>
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
// valid code above
sockaddr_in sa;
int res;
sa.sin_family = AF_INET;
sa.sin_port = htons(3252);
if ((res = inet_pton(AF_INET, "192.168.0.1",
&sa.sin_addr)) < 0)
perror("inet_pton");
if (!res) // error occurred
fprintf(stderr, "Address notation incorrect for
AF_INET addressn");
>
> The call to sendto is wrapped in an if an was failing
for errno code
> 47, Address family not supported by protocol (I was
using UDP). I
> changed the assignment of AF_INET to the sa.sin_family
member to
> *after* the call to inet_pton(3) and suddenly
everything worked. Why?
> Since the address family was used by inet_pton(3) to
figure out how
> to read the address and assign it to
sa.sin_addr.s_addr, why not
> simply assign AF_INET to the address family member in
inet_pton(3)?
>
Because it is treating the sockaddr_in structure as an
in_addr structure
which is clobbering the sin_family field.
> I'm not trying to be argumentative. I'm just curious.
It seems like
> redundancy. I've used the address family to tell
inet_pton(3) how to
> operate, and then this function can't assign it to the
sockaddr_in
> structure passed to it? This makes little sense. In
case it's
> because I'm using older FBSD libraries that had a flaw
fixed, I'm
> using FreeBSD 6.2-RELEASE-p4. Is this because that's
how POSIX
> defined it to work? Is this the right venue or should
I try one of
> the other mailing lists?
>
RTM,
Patrick
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
| Re: Network programming question |

|
2008-03-13 13:11:28 |
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?
Andy
--
A: Because it messes up the order in which people normally
read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
| Re: Network programming question |
  United States |
2008-03-14 00:57:03 |
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
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
| Re: Network programming question |

|
2008-03-14 10:23:59 |
On Thu, Mar 13, 2008 at 11:57 PM, Patrick Mahan
<mahan mahan.org> wrote:
>
>
>
> 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
>
Thanks much for this explanation. Books would be good, yes.
I guys
got to learn somehow. Thanks for taking the time to explain
it.
That's interesting that a broadcast may be sent to 0.0.0.0.
I knew
that 0.0.0.0 is equal to INADDR_ANY. However, I thought it
wasn't
possible to send to that address, only to bind to it locally
for a
server application.
Andy
--
A: Because it messes up the order in which people normally
read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
[1-5]
|
|