Using getnameinfo()

M

Mariano

I have a socket-client application, on the server side I have a file
descriptor for client connection, now I've to know what is the client
name (otherwise IP address). I have tried to write a function, but ->
operator doesn't work. Someone know the solution???

void traccia_user(int fd)
{
int tmp_len;
struct sockaddr_in tmp;
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
unsigned int addrlen=sizeof(tmp);
getpeername(fd,(struct sockaddr*)&tmp,&addrlen);
printf("Client IP: %s\nClient port: %d
\n",inet_ntoa(tmp.sin_addr),tmp.sin_port);
tmp_len = sizeof(tmp);
if (getnameinfo(tmp, tmp->tmp_len, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0)
printf("host=%s, serv=%s", hbuf, sbuf);
}
 
W

Walter Roberson

I have a socket-client application, on the server side I have a file
descriptor for client connection, now I've to know what is the client
name (otherwise IP address). I have tried to write a function, but ->
operator doesn't work. Someone know the solution???

On the surface, your question is really about a number of
items that are not part of the C language. The C language does not
offer sockets or file descriptors and doesn't know about IP addresses.
There are various operating system extensions (such as POSIX) that
offer those things, but discussion of them would then have to
take place in a newsgroup that specializes in those extensions;
this particular newsgroup talks about the C langauge, not about
extensions.

Fortunately, your question can be answered without knowing
anything (much) about those extensions.

void traccia_user(int fd)
{
int tmp_len;
struct sockaddr_in tmp;
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
unsigned int addrlen=sizeof(tmp);
getpeername(fd,(struct sockaddr*)&tmp,&addrlen);
printf("Client IP: %s\nClient port: %d
\n",inet_ntoa(tmp.sin_addr),tmp.sin_port);
tmp_len = sizeof(tmp);

In that statement, you calculate tmp_len based upon the
size of the structure named tmp.
if (getnameinfo(tmp, tmp->tmp_len, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0)

So in this following statement, if you need to pass in the length
of the tmp structure to getnameinfo, just pass in the value
you calculated, tmp_len .

Note that the -> operator is for use with pointers, but tmp is
not a pointer: tmp is the structure itself. If that structure
had a field named tmp_len (which seems unlikely but not impossible)
then you would access that structure field by using the syntax
tmp.tmp_len .

It is somewhat uncommon (but not unheard of) to pass in a complete
structure as a parameter, so we can also speculate that the
first argument, tmp, that you pass to getnameinfo, should instead
be the -address- of the structure, which would be &tmp . You should
check your documentation for your particular getnameinfo() extension
to see whether that is the case. If so, then the adjusted code would be,

if (getnameinfo(&tmp, tmp_len, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0)
printf("host=%s, serv=%s", hbuf, sbuf);
}


Also, as your code does not define NI_MAXHOST or NI_MAXSERV
or NI_NUMERICHOST or NI_NUMERICSERV then we can speculate that the
code would need one of more #include statements to compile at all.
It would likely need to #include <stdio.h> in order for
the fprintf() calls to have a chance of executing properly --
fprintf() is a varadic function, and it is common for compilers to
hae special calling sequences for varadic function .
 
S

santosh

Mariano said:
I have a socket-client application, on the server side I have a file
descriptor for client connection, now I've to know what is the client
name (otherwise IP address). I have tried to write a function, but ->
operator doesn't work. Someone know the solution???

void traccia_user(int fd)
{
int tmp_len;
struct sockaddr_in tmp;
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
unsigned int addrlen=sizeof(tmp);
getpeername(fd,(struct sockaddr*)&tmp,&addrlen);
printf("Client IP: %s\nClient port: %d
\n",inet_ntoa(tmp.sin_addr),tmp.sin_port);
tmp_len = sizeof(tmp);
if (getnameinfo(tmp, tmp->tmp_len, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0)
printf("host=%s, serv=%s", hbuf, sbuf);
}

This is off-topic here. You might want to try comp.unix.programmer, but
you might want to use tmp_len instead of tmp->tmp_len in the call to
getnameinfo.

Also did you check the return value of getpeername? Did it actually
succeed. Did you include all the necessary headers. Why are you using
unsigned int instead of socklen_t for addrlen?
 
B

Boon

Mariano said:
I have a socket-client application, on the server side I have a file
descriptor for client connection, now I've to know what is the client
name (otherwise IP address). I have tried to write a function, but ->
operator doesn't work.

p->f is equivalent to (*p).f
p needs to be a pointer to a struct (or union)
void traccia_user(int fd)
{
int tmp_len;
struct sockaddr_in tmp;
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
unsigned int addrlen=sizeof(tmp);
getpeername(fd,(struct sockaddr*)&tmp,&addrlen);
printf("Client IP: %s\nClient port: %d
\n",inet_ntoa(tmp.sin_addr),tmp.sin_port);
tmp_len = sizeof(tmp);
if (getnameinfo(tmp, tmp->tmp_len, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0)
printf("host=%s, serv=%s", hbuf, sbuf);
}

Try a different newsgroup : comp.unix.programmer
They can help you with getnameinfo.
http://www.kernel.org/doc/man-pages/online/pages/man3/getnameinfo.3.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top