Return to BSD News archive
Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!harbinger.cc.monash.edu.au!msunews!news.mtu.edu!newsxfer.itd.umich.edu!news.mathworks.com!uunet!in2.uu.net!EU.net!sun4nl!sci.kun.nl!polder.ubc.kun.nl!rhialto From: rhialto@polder.ubc.kun.nl (Olaf Seibert) Newsgroups: comp.unix.bsd.netbsd.misc Subject: bind()ing a socket to a specific address? Date: 5 Oct 1995 17:04:24 GMT Organization: University of Nijmegen, The Netherlands Lines: 121 Message-ID: <45136o$6qf@wn1.sci.kun.nl> NNTP-Posting-Host: polder.ubc.kun.nl Organisation: Polderland Language & Speech Technology I am trying to bind() a socket to a specific IP address, but I always get the error EADDRNOTAVAIL: "Can't assign requested address". Nevertheless, as far as I can see, this should be possible. The only address that will work is INADDR_ANY (i.e., 0.0.0.0). I took a quick look in the kernel sources, and what I saw should also allow it. Any hints? I have appended source of my program (not very long). Try it with command line such as a.out localhost 1234 (does not work) or a.out 0 1234 (does work but is not what I want). NB: This is with NetBSD/i386 1.0 but that should hardly make a difference. #include <stdio.h> #include <errno.h> #include <ctype.h> #include <unistd.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> int one = 1; void get_ip(char *name, struct sockaddr_in *addr) { struct hostent *h; h = gethostbyname(name); printf("getting address of %s.\n", name); if (h) { addr->sin_len = sizeof (*addr); addr->sin_family = AF_INET; memcpy(&addr->sin_addr.s_addr, h->h_addr_list[0], h->h_length); return; } fprintf(stderr, "bad host: %s. ", name); herror("gethostbyname: "); exit(1); } int prototosocktype(char *proto) { if (strcmp(proto, "tcp") == 0) return SOCK_STREAM; if (strcmp(proto, "udp") == 0) return SOCK_DGRAM; return -1; } void make_socket(struct sockaddr_in host, char *proto, char *port) { int sock; struct servent *se; sock = socket(AF_INET, prototosocktype(proto), 0); if (sock == -1) { perror("socket"); return; } setsockopt(0, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)); if (isdigit(port[0])) { host.sin_port = htons(atoi(port)); } else { se = getservbyname(port, proto); if (se == NULL) { fprintf(stderr, "bad service: %s. ", port); herror("getservbyname: "); return; } host.sin_port = se->s_port; } if (bind(sock, (struct sockaddr *)&host, sizeof(host))) { printf("binding to port %d host %08lx\n", ntohs(host.sin_port), ntohl(host.sin_addr.s_addr)); perror("bind"); return; } if (listen(sock, 1) == -1) { perror("listen"); } printf("listening on port %d\n", ntohs(host.sin_port)); } int main(int argc, char **argv) { if (argc >= 2) { struct sockaddr_in hostaddr; char *proto = "tcp"; int ac; get_ip(argv[1], &hostaddr); for (ac = 2; ac < argc; ac++) { if (prototosocktype(argv[ac]) != -1) { proto = argv[ac]; continue; } make_socket(hostaddr, proto, argv[ac]); } /* and do nothing else anymore */ select(0, NULL, NULL, NULL, NULL); } } -Olaf. -- ___ Olaf 'Rhialto' Seibert D787B44DFC896063 4CBB95A5BD1DAA96 \X/ There are no lemurs in this post rhialto@polder.ubc.kun.nl