Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Get "Can't assign requested address" error on binding a socket to an ip address

590 views
Skip to first unread message

V Humphrey

unread,
Sep 7, 2003, 5:27:01 AM9/7/03
to
I am a newbie on the BSD system and recently I tried to run a program with
the following code segment:

char hostname[64];
struct hostent *hp;
register int i, s, ns;
struct sockaddr_in sin, fsin;

strcpy( hostname, "localhost" );
if ((hp = gethostbyname(hostname)) == NULL) {
fprintf(stderr, "%s: unknown host.\n", hostname);
exit(1);
}

if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("server: socket");
exit(1);
}

sin.sin_family = AF_INET;
sin.sin_port = htons(80);
bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);

if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
perror("server: bind");
exit(1);
}

The program compiles OK. But when I run it as root, I get 'Can't assigned
requested address" error.
I have tried to change the port number to 9999, still the same error.
I have used similar codes to connect to port 80 of a remote machine, and it
works. So it seems to me that it is a problem about security settings. But I
have installed my FreeBSD 4.5 by selecting all defaults. Does the default
system require some thing to be done before root is allowed to start a
server process? Please give me some advice.

V.H.

Per Hedeland

unread,
Sep 7, 2003, 6:21:36 AM9/7/03
to
In article <bjeul1$1vp$1...@news.hgc.com.hk> "V Humphrey"

<VicentH...@hotmail.com> writes:
>I am a newbie on the BSD system and recently I tried to run a program with
>the following code segment:

[snip]

> strcpy( hostname, "localhost" );
> if ((hp = gethostbyname(hostname)) == NULL) {
> fprintf(stderr, "%s: unknown host.\n", hostname);
> exit(1);
> }
>
> if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
> perror("server: socket");
> exit(1);
> }

You should really zero out the 'sin' struct here, but that's probably
not your problem.

> sin.sin_family = AF_INET;
> sin.sin_port = htons(80);
> bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);

Try putting a

printf("Trying to bind to address %s\n", inet_ntoa(sin.sin_addr));

here.

> if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
> perror("server: bind");
> exit(1);
> }
>
>The program compiles OK. But when I run it as root, I get 'Can't assigned
>requested address" error.
>I have tried to change the port number to 9999, still the same error.

The error message really is a complaint specifically about the address,
regardless of the port - from the bind(2) man page:

[EADDRNOTAVAIL] The specified address is not available from the local
machine.

For a port already in use, or one that you otherwise aren't allowed to
bind to, you'd get "Address already in use" (EADDRINUSE), or "Permission
denied" (EACCES), respectively.

The most likely cause of your problem is that your name resolution is
messed up, such that a lookup of "localhost" doesn't actually return
127.0.0.1 but some non-local address - e.g. perhaps this one:

localhost.com. 1D IN A 10.11.12.13

--Per Hedeland
p...@hedeland.org

Ludek Frybort

unread,
Sep 7, 2003, 9:07:05 AM9/7/03
to
Per Hedeland wrote:
>
> In article <bjeul1$1vp$1...@news.hgc.com.hk> "V Humphrey"
> <VicentH...@hotmail.com> writes:
> >I am a newbie on the BSD system and recently I tried to run a program with
> >the following code segment:
>
> [snip]
>
> > strcpy( hostname, "localhost" );
> > if ((hp = gethostbyname(hostname)) == NULL) {
> > fprintf(stderr, "%s: unknown host.\n", hostname);
> > exit(1);
> > }
> >
> > if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
> > perror("server: socket");
> > exit(1);
> > }
>
> You should really zero out the 'sin' struct here, but that's probably
> not your problem.
> [snip]

Or it may very well be. Once I've run into this very same error and
found out that forgetting to zero out the sin structure was, indeed, the
cause. I think it must have something to do with the "MUST BE ZERO"
array sin_zero[8] in the structure...

Ludek

Per Hedeland

unread,
Sep 7, 2003, 2:52:51 PM9/7/03
to

Agreed - it's definitely a bug to not do it, and a very nasty one since
it may work "most of the time". My comment above was purely "pragmatic",
simply because it *does* work most of the time...:-) I.e. it definitely
needs fixing, but the probability that this is the actual problem is
semi-low...

--Per Hedeland
p...@hedeland.org

Ludek Frybort

unread,
Sep 7, 2003, 5:01:38 PM9/7/03
to
Well, I must have been lucky then, because in my case bind failed
everytime. Which really helped with debugging, so the word "lucky" in
previous sentence is no sarcasm at all.

Ludek

Per Hedeland

unread,
Sep 7, 2003, 6:40:45 PM9/7/03
to

Well, seems it's OS&version-dependant - a quick unscientific survey:

FreeBSD 4.1.1 - requires zeroing
FreeBSD 4.4 - requires zeroing
FreeBSD 5.0 - "works" without
RedHat 7.3 - "works" without
Solaris 2.6 - "works" without

Of course even in the '"works" without' cases, it could probably fail
depending on what was on the stack before, or at some library/kernel
upgrade or other. Anyway, as the OP was running FBSD 4.5, based on the
above survey it seems quite likely that this *is* the problem (or at
least one of the problems:-).

--Per Hedeland
p...@hedeland.org

V Humphrey

unread,
Sep 8, 2003, 11:25:52 AM9/8/03
to

"Per Hedeland" <p...@hedeland.org> 在郵件 news:bjgc5d$2v5c$1...@hedeland.org
撰寫...

Putting
bzero( &sin, sizeof(sin) );
before filling in details in sin does solve my problem.

Thank you for the advices I have received.

V Humphrey


0 new messages