Andrew Falanga presented these words - circa 3/13/08 11:11 AM->
On Thu, Mar 13, 2008 at 11:45 AM, Patrick Mahan <[EMAIL PROTECTED]> 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-questions
To unsubscribe, send any mail to "[EMAIL PROTECTED]"