2

By hostname, I mean the name of the PC of the client.

I'm trying to identify each of the connected client of the server.
Like client -> server. Server says: client hostname has connected.
then all the process by that client will be tagged with the hostname. And I don't really know how to.

My client code:

char hostname[1024];

gethostname(hostname, 1023);
send(sock, hostname, hostname, 0);
//now we are done sending the hostname of the client.

My server code (the loop):

void clients (int sock)
{
    int n, p;
    char buffer[256];
    char request;
    FILE *file; 
    file = fopen("process.log","a+");


    //the stuff i added for the identification 
    char hostbuf[256];
    bzero(hostbuf,256);
    n = read(sock,hostbuf,255);
            printf("%s has connected.\n",buffer);


    //after the client has been identified then we tag all communications from that client as its hostname/identification.

    do
    {
    bzero(buffer,256);
    p = read(sock,buffer,255);
    if (p < 0) error("ERROR reading from socket");

    //the output i modified
    printf("%s sent: %s\n",hostbuf,buffer);

    n = write(sock,buffer,sizeof(buffer));

    if (n < 0) error("ERROR writing to socket");
    fprintf(file,"%s\n",buffer); /*writes*/ 

    }while(p == 11);

    fclose(file);
}

----------- edit -----------

Used both suggestions together

Added to code:

socklen_t len;
struct sockaddr_storage addr;
char ipstr[INET_ADDRSTRLEN];
int port;

   len = sizeof addr;
   getpeername(sock, (struct sockaddr*)&addr, &len);

   // deal with both IPv4 and IPv6:
if (addr.ss_family == AF_INET) {
  struct sockaddr_in *s = (struct sockaddr_in *)&addr;
  port = ntohs(s->sin_port);
  inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);
} else { // AF_INET6
  struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr;
  port = ntohs(s->sin6_port);
 inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr);
}


char host[1024];

   getnameinfo(&addr, sizeof addr, host, sizeof host, NULL, NULL, 0);

tried to display it:

printf("%s has connected from %s.", host,ipstr);
    //returned 'myip.myisp.net has connected from *.*.*.*.'
    //i want it to return my PC name.
    //my pc name is SashaGre-PC :))

It works but it doesn't return my PC name but rather the 'ip.ispdomain.net'.

fury.slay
  • 1,202
  • 1
  • 15
  • 26
user1553142
  • 237
  • 1
  • 11
  • 21

3 Answers3

4

Additionally, if you want the host name of the client, use getnameinfo from the server each time you get a new client connection in accept. There are examples here: https://beej.us/guide/bgnet/html/multi/getnameinfoman.html

For windows: http://msdn.microsoft.com/en-us/library/windows/desktop/ms738532(v=vs.85).aspx

Sandburg
  • 757
  • 15
  • 28
rutgersmike
  • 1,183
  • 9
  • 18
  • Thanks. but my client is on win c++ :) only the server is on linux. – user1553142 Nov 25 '12 at 16:22
  • Thanks again. But I want the clients PC name, to be used as the identifier for the socket on the server. – user1553142 Nov 25 '12 at 16:27
  • See edits. You want to grab the client host name in the server code, right? Use the Linux examples. If you want to get the server name, use the windows examples. Its basically the same. If you need the IP from the host name, which is more common on the client, then you want `getaddrinfo()` instead. – rutgersmike Nov 25 '12 at 16:28
  • The host name is the PC name. You give that function the IP address and it gives you the name of the connected PC. – rutgersmike Nov 25 '12 at 16:31
  • Use `getpeername` and pass the empty sockaddr to the second argument, and the socket you accepted to the first argument. If it succeeds, pass the (now populated) sockaddr into `getnameinfo`. Its returning junk right now because you're giving it an empty address structure. Filling it out with `getpeername` will fix it. – rutgersmike Nov 25 '12 at 16:44
  • @RutgersMike Please move the actual code samples into this answer once you get it worked out with the OP. While a great answer, this depends on links that can break .. please look out for visitors a year from now :) – Tim Post Nov 25 '12 at 16:48
  • one last test, i think i got it. – user1553142 Nov 25 '12 at 16:51
  • hmmm. wierd. i got the ip address correctly. now i passed the ip address to getpeername. but its returning '03t sent test'. updated my question. – user1553142 Nov 25 '12 at 16:54
  • What's the return value from `getpeername`, and what is `errno` directly after the call? – rutgersmike Nov 25 '12 at 17:09
  • @Tim Will do- i need to get on my laptop and just write this out in one shot. – rutgersmike Nov 25 '12 at 17:10
  • i got it. but its not returning my PC name. its giving me the myip.myisp.net. i want the PC name though. :) – user1553142 Nov 25 '12 at 17:49
  • Can you ping the client by name from the server, or does it say that it can't resolve it? What if you put `NI_NAMEREQD` in the flags argument of `getnameinfo()`? – rutgersmike Nov 25 '12 at 19:36
  • @RutgersMike The value returned by `gethostname()` is **not** necessarily the same value as any value returned by resolving any of host's network interfaces' ip-address. A host's name can be totaly different from that. A host's name (as also returned by the unix command `hostname`) is not related to ip by definition. Although it could be configured (any commonly is) to match at least one DNS name returned for one of the host's interfaces' ip address. But the latter is just a convention. – alk Nov 26 '12 at 11:30
  • True, but without some kind of network management,our having his client send a string, there's no way to get that. – rutgersmike Nov 26 '12 at 12:48
  • 1
    There is a way. Please see my answer for a possible solution. @RutgersMike – alk Nov 28 '12 at 11:59
2

To query a host for it's NetBIOS name ("PC name" as you call it) you need to perform an NBT query against the host in question. NBT stands for NetBIOS over TCP/IP.

This is not a trivial task.

An implementation already doing so is part of the Samba project.

The library libsmbclient implements a method called node_status_query() which performs NBT queries.

An example on how to use this method could be found by looking up the nmblookup tool's sources. The code path in question is invoked when using nmblookup's option A along with ip address of the host which's NetBIOS name is to be queried.

nmblookup -A <ip-address>

Both, libsmbclient and nmblookup are part of the Samba project.

alk
  • 69,737
  • 10
  • 105
  • 255
1

It sounds like you want to call getpeername on each incoming connection on your server, to identify the source address.

Arvid
  • 10,915
  • 1
  • 32
  • 40