Re: Network programming question
On Thu, Mar 13, 2008 at 11:57 PM, Patrick Mahan [EMAIL PROTECTED] 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 = 0x 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-questions To unsubscribe, send any mail to [EMAIL PROTECTED]
Network programming question
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-questions To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: Network programming question
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 address\n); 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-questions To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: Network programming question
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; charsin_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_tin_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-questions To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: Network programming question
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; charsin_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_tin_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 = 0x 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]