Using getnameinfo()

Discussion in 'C Programming' started by Mariano, Jun 30, 2008.

  1. Mariano

    Mariano Guest

    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);
    }
     
    Mariano, Jun 30, 2008
    #1
    1. Advertising

  2. In article <>,
    Mariano <> wrote:
    >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 .
    --
    "Man's life is but a jest,
    A dream, a shadow, bubble, air, a vapor at the best."
    -- George Walter Thornbury
     
    Walter Roberson, Jun 30, 2008
    #2
    1. Advertising

  3. Mariano

    santosh Guest

    Mariano wrote:

    > 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?
     
    santosh, Jun 30, 2008
    #3
  4. Mariano

    Boon Guest

    Mariano wrote:

    > 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
     
    Boon, Jun 30, 2008
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. William F. Robertson, Jr.
    Replies:
    1
    Views:
    999
    Kathy Burke
    Jun 25, 2003
  2. pete
    Replies:
    1
    Views:
    3,012
    Jon Yates
    Aug 29, 2003
  3. timmso
    Replies:
    1
    Views:
    574
    Alex Papadimoulis
    Dec 12, 2003
  4. Bradley, Todd
    Replies:
    0
    Views:
    335
    Bradley, Todd
    Nov 16, 2004
  5. A. S. Bradbury
    Replies:
    5
    Views:
    328
    Eric Hodel
    Sep 8, 2006
Loading...

Share This Page