Return to BSD News archive
Newsgroups: comp.unix.bsd.netbsd.misc
Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!harbinger.cc.monash.edu.au!simtel!chi-news.cic.net!news.midplains.net!gw2.att.com!nntpa!news
From: "J.T. Holmes x7683" <jtholmes>
Subject: Re: bind()ing a socket to a specific address?
Content-Type: text/plain
Message-ID: <DG73yw.EGq@nntpa.cb.att.com>
To: jtholmes@alphlz.att.com
Sender: news@nntpa.cb.att.com (Netnews Administration)
Nntp-Posting-Host: nmg3-gw.alph.att.com
Content-Transfer-Encoding: 7bit
Organization: AT&T
References: <45136o$6qf@wn1.sci.kun.nl>
Mime-Version: 1.0
Date: Mon, 9 Oct 1995 19:11:20 GMT
X-Mailer: Mozilla 1.1 (X11; U; SunOS 4.1.3_DB sun4c)
X-Url: news:45136o$6qf@wn1.sci.kun.nl
Lines: 129
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
Message-ID: <45136o$6qf@wn1.sci.kun.nl>
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