| Summary: | bind(2) erroneously complains EADDRNOTAVAIL | ||
|---|---|---|---|
| Product: | Base System | Reporter: | jan grant <jan.grant> |
| Component: | kern | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | Unspecified | ||
| Hardware: | Any | ||
| OS: | Any | ||
My fault entirely.bzeroing the sockaddr_in first fixes it. State Changed From-To: open->closed Submitter reports pilot error. |
I've got a trivial little ip4-only program which I want to listen on 127.0.0.1.5999 only, as opposed to *.5999 (tcp socket) It fails at the call to bind: complaining that EADDRNOTAVAIL. The same program (modulo sin_len - missing on that system) works on Solaris, which leads me to believe the problem isn't with my source, but with bind. Running the program using INADDR_ANY works correctly. I've marked this as high-priority since there are some programs (named) that need this functionality. How-To-Repeat: Trivial little program repeats the bug: compile with gcc -o test test.cc. Email me for source. #include <stdio.h> #include <sys/types.h> #include <netinet/in.h> /* for struct sockaddr_in */ #include <netdb.h> /* For getprotobyname */ #include <sys/param.h> /* For the ntohs, etc. */ #include <arpa/inet.h> /* For inet_ntoa */ #include <netdb.h> // gethostbyname #include <unistd.h> #include <unistd.h> #include <sys/socket.h> #include <errno.h> //errno, EINTR unsigned short sport = 5999; int main(int argc, char *argv[]) { struct protoent * pep = getprotobyname("tcp"); if (!pep) { perror("cannot getprotobyname tcp"); return 1; } int sd = socket(PF_INET, SOCK_STREAM, pep->p_proto); if (sd == -1) { perror("socket"); return 1; } struct hostent *he = gethostbyname("localhost"); if (!he) { perror("gethostbyname localhost"); return 2; } struct sockaddr_in addr; addr.sin_len = sizeof(addr); addr.sin_family = AF_INET; addr.sin_port = htons(sport); memcpy(&addr.sin_addr.s_addr, he->h_addr_list[0], sizeof(addr.sin_addr.s_addr)); //addr.sin_addr.s_addr = htonl(INADDR_ANY); // this works! printf("%lx\n", addr.sin_addr.s_addr); // quick check int one = 1; if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) { perror("setsockopt"); return 2; } if (bind(sd, (const struct sockaddr *) &addr, sizeof addr)) { perror("bind"); close(sd); return 3; } // ...and listen... if (listen(sd, 5)) { perror("listen"); return 4; } close(sd); return 0; }