Home | History | Annotate | Download | only in libvncclient
      1 /*
      2  *  Copyright (C) 2011-2012 Christian Beier <dontmind (at) freeshell.org>
      3  *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
      4  *
      5  *  This is free software; you can redistribute it and/or modify
      6  *  it under the terms of the GNU General Public License as published by
      7  *  the Free Software Foundation; either version 2 of the License, or
      8  *  (at your option) any later version.
      9  *
     10  *  This software is distributed in the hope that it will be useful,
     11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  *  GNU General Public License for more details.
     14  *
     15  *  You should have received a copy of the GNU General Public License
     16  *  along with this software; if not, write to the Free Software
     17  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
     18  *  USA.
     19  */
     20 
     21 /*
     22  * sockets.c - functions to deal with sockets.
     23  */
     24 
     25 #ifdef __STRICT_ANSI__
     26 #define _BSD_SOURCE
     27 #ifdef __linux__
     28 /* Setting this on other systems hides definitions such as INADDR_LOOPBACK.
     29  * The check should be for __GLIBC__ in fact. */
     30 # define _POSIX_SOURCE
     31 #endif
     32 #endif
     33 #include <unistd.h>
     34 #include <errno.h>
     35 #include <fcntl.h>
     36 #include <assert.h>
     37 #include <rfb/rfbclient.h>
     38 #ifdef WIN32
     39 #undef SOCKET
     40 #include <winsock2.h>
     41 #ifdef MINGW32
     42 #define EWOULDBLOCK WSAEWOULDBLOCK
     43 #endif
     44 #define close closesocket
     45 #define read(sock,buf,len) recv(sock,buf,len,0)
     46 #define write(sock,buf,len) send(sock,buf,len,0)
     47 #define socklen_t int
     48 #ifdef LIBVNCSERVER_HAVE_WS2TCPIP_H
     49 #undef socklen_t
     50 #include <ws2tcpip.h>
     51 #endif
     52 #else
     53 #include <sys/socket.h>
     54 #include <netinet/in.h>
     55 #include <sys/un.h>
     56 #include <netinet/tcp.h>
     57 #include <arpa/inet.h>
     58 #include <netdb.h>
     59 #endif
     60 #include "tls.h"
     61 
     62 #ifdef _MSC_VER
     63 #  define snprintf _snprintf
     64 #endif
     65 
     66 void PrintInHex(char *buf, int len);
     67 
     68 rfbBool errorMessageOnReadFailure = TRUE;
     69 
     70 /*
     71  * ReadFromRFBServer is called whenever we want to read some data from the RFB
     72  * server.  It is non-trivial for two reasons:
     73  *
     74  * 1. For efficiency it performs some intelligent buffering, avoiding invoking
     75  *    the read() system call too often.  For small chunks of data, it simply
     76  *    copies the data out of an internal buffer.  For large amounts of data it
     77  *    reads directly into the buffer provided by the caller.
     78  *
     79  * 2. Whenever read() would block, it invokes the Xt event dispatching
     80  *    mechanism to process X events.  In fact, this is the only place these
     81  *    events are processed, as there is no XtAppMainLoop in the program.
     82  */
     83 
     84 rfbBool
     85 ReadFromRFBServer(rfbClient* client, char *out, unsigned int n)
     86 {
     87 #undef DEBUG_READ_EXACT
     88 #ifdef DEBUG_READ_EXACT
     89 	char* oout=out;
     90 	int nn=n;
     91 	rfbClientLog("ReadFromRFBServer %d bytes\n",n);
     92 #endif
     93 
     94   /* Handle attempts to write to NULL out buffer that might occur
     95      when an outside malloc() fails. For instance, memcpy() to NULL
     96      results in undefined behaviour and probably memory corruption.*/
     97   if(!out)
     98     return FALSE;
     99 
    100   if (client->serverPort==-1) {
    101     /* vncrec playing */
    102     rfbVNCRec* rec = client->vncRec;
    103     struct timeval tv;
    104 
    105     if (rec->readTimestamp) {
    106       rec->readTimestamp = FALSE;
    107       if (!fread(&tv,sizeof(struct timeval),1,rec->file))
    108         return FALSE;
    109 
    110       tv.tv_sec = rfbClientSwap32IfLE (tv.tv_sec);
    111       tv.tv_usec = rfbClientSwap32IfLE (tv.tv_usec);
    112 
    113       if (rec->tv.tv_sec!=0 && !rec->doNotSleep) {
    114         struct timeval diff;
    115         diff.tv_sec = tv.tv_sec - rec->tv.tv_sec;
    116         diff.tv_usec = tv.tv_usec - rec->tv.tv_usec;
    117         if(diff.tv_usec<0) {
    118 	  diff.tv_sec--;
    119 	  diff.tv_usec+=1000000;
    120         }
    121 #ifndef WIN32
    122         sleep (diff.tv_sec);
    123         usleep (diff.tv_usec);
    124 #else
    125 	Sleep (diff.tv_sec * 1000 + diff.tv_usec/1000);
    126 #endif
    127       }
    128 
    129       rec->tv=tv;
    130     }
    131 
    132     return (fread(out,1,n,rec->file) != n ? FALSE : TRUE);
    133   }
    134 
    135   if (n <= client->buffered) {
    136     memcpy(out, client->bufoutptr, n);
    137     client->bufoutptr += n;
    138     client->buffered -= n;
    139 #ifdef DEBUG_READ_EXACT
    140     goto hexdump;
    141 #endif
    142     return TRUE;
    143   }
    144 
    145   memcpy(out, client->bufoutptr, client->buffered);
    146 
    147   out += client->buffered;
    148   n -= client->buffered;
    149 
    150   client->bufoutptr = client->buf;
    151   client->buffered = 0;
    152 
    153   if (n <= RFB_BUF_SIZE) {
    154 
    155     while (client->buffered < n) {
    156       int i;
    157       if (client->tlsSession) {
    158         i = ReadFromTLS(client, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered);
    159       } else {
    160         i = read(client->sock, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered);
    161       }
    162       if (i <= 0) {
    163 	if (i < 0) {
    164 #ifdef WIN32
    165 	  errno=WSAGetLastError();
    166 #endif
    167 	  if (errno == EWOULDBLOCK || errno == EAGAIN) {
    168 	    /* TODO:
    169 	       ProcessXtEvents();
    170 	    */
    171 	    WaitForMessage(client, 100000);
    172 	    i = 0;
    173 	  } else {
    174 	    rfbClientErr("read (%d: %s)\n",errno,strerror(errno));
    175 	    return FALSE;
    176 	  }
    177 	} else {
    178 	  if (errorMessageOnReadFailure) {
    179 	    rfbClientLog("VNC server closed connection\n");
    180 	  }
    181 	  return FALSE;
    182 	}
    183       }
    184       client->buffered += i;
    185     }
    186 
    187     memcpy(out, client->bufoutptr, n);
    188     client->bufoutptr += n;
    189     client->buffered -= n;
    190 
    191   } else {
    192 
    193     while (n > 0) {
    194       int i;
    195       if (client->tlsSession) {
    196         i = ReadFromTLS(client, out, n);
    197       } else {
    198         i = read(client->sock, out, n);
    199       }
    200 
    201       if (i <= 0) {
    202 	if (i < 0) {
    203 #ifdef WIN32
    204 	  errno=WSAGetLastError();
    205 #endif
    206 	  if (errno == EWOULDBLOCK || errno == EAGAIN) {
    207 	    /* TODO:
    208 	       ProcessXtEvents();
    209 	    */
    210 	    WaitForMessage(client, 100000);
    211 	    i = 0;
    212 	  } else {
    213 	    rfbClientErr("read (%s)\n",strerror(errno));
    214 	    return FALSE;
    215 	  }
    216 	} else {
    217 	  if (errorMessageOnReadFailure) {
    218 	    rfbClientLog("VNC server closed connection\n");
    219 	  }
    220 	  return FALSE;
    221 	}
    222       }
    223       out += i;
    224       n -= i;
    225     }
    226   }
    227 
    228 #ifdef DEBUG_READ_EXACT
    229 hexdump:
    230   { int ii;
    231     for(ii=0;ii<nn;ii++)
    232       fprintf(stderr,"%02x ",(unsigned char)oout[ii]);
    233     fprintf(stderr,"\n");
    234   }
    235 #endif
    236 
    237   return TRUE;
    238 }
    239 
    240 
    241 /*
    242  * Write an exact number of bytes, and don't return until you've sent them.
    243  */
    244 
    245 rfbBool
    246 WriteToRFBServer(rfbClient* client, char *buf, int n)
    247 {
    248   fd_set fds;
    249   int i = 0;
    250   int j;
    251 
    252   if (client->serverPort==-1)
    253     return TRUE; /* vncrec playing */
    254 
    255   if (client->tlsSession) {
    256     /* WriteToTLS() will guarantee either everything is written, or error/eof returns */
    257     i = WriteToTLS(client, buf, n);
    258     if (i <= 0) return FALSE;
    259 
    260     return TRUE;
    261   }
    262 
    263   while (i < n) {
    264     j = write(client->sock, buf + i, (n - i));
    265     if (j <= 0) {
    266       if (j < 0) {
    267 #ifdef WIN32
    268 	 errno=WSAGetLastError();
    269 #endif
    270 	if (errno == EWOULDBLOCK ||
    271 #ifdef LIBVNCSERVER_ENOENT_WORKAROUND
    272 		errno == ENOENT ||
    273 #endif
    274 		errno == EAGAIN) {
    275 	  FD_ZERO(&fds);
    276 	  FD_SET(client->sock,&fds);
    277 
    278 	  if (select(client->sock+1, NULL, &fds, NULL, NULL) <= 0) {
    279 	    rfbClientErr("select\n");
    280 	    return FALSE;
    281 	  }
    282 	  j = 0;
    283 	} else {
    284 	  rfbClientErr("write\n");
    285 	  return FALSE;
    286 	}
    287       } else {
    288 	rfbClientLog("write failed\n");
    289 	return FALSE;
    290       }
    291     }
    292     i += j;
    293   }
    294   return TRUE;
    295 }
    296 
    297 
    298 
    299 static int initSockets() {
    300 #ifdef WIN32
    301   WSADATA trash;
    302   static rfbBool WSAinitted=FALSE;
    303   if(!WSAinitted) {
    304     int i=WSAStartup(MAKEWORD(2,0),&trash);
    305     if(i!=0) {
    306       rfbClientErr("Couldn't init Windows Sockets\n");
    307       return 0;
    308     }
    309     WSAinitted=TRUE;
    310   }
    311 #endif
    312   return 1;
    313 }
    314 
    315 /*
    316  * ConnectToTcpAddr connects to the given TCP port.
    317  */
    318 
    319 int
    320 ConnectClientToTcpAddr(unsigned int host, int port)
    321 {
    322   int sock;
    323   struct sockaddr_in addr;
    324   int one = 1;
    325 
    326   if (!initSockets())
    327 	  return -1;
    328 
    329   addr.sin_family = AF_INET;
    330   addr.sin_port = htons(port);
    331   addr.sin_addr.s_addr = host;
    332 
    333   sock = socket(AF_INET, SOCK_STREAM, 0);
    334   if (sock < 0) {
    335 #ifdef WIN32
    336     errno=WSAGetLastError();
    337 #endif
    338     rfbClientErr("ConnectToTcpAddr: socket (%s)\n",strerror(errno));
    339     return -1;
    340   }
    341 
    342   if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
    343     rfbClientErr("ConnectToTcpAddr: connect\n");
    344     close(sock);
    345     return -1;
    346   }
    347 
    348   if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
    349 		 (char *)&one, sizeof(one)) < 0) {
    350     rfbClientErr("ConnectToTcpAddr: setsockopt\n");
    351     close(sock);
    352     return -1;
    353   }
    354 
    355   return sock;
    356 }
    357 
    358 int
    359 ConnectClientToTcpAddr6(const char *hostname, int port)
    360 {
    361 #ifdef LIBVNCSERVER_IPv6
    362   int sock;
    363   int n;
    364   struct addrinfo hints, *res, *ressave;
    365   char port_s[10];
    366   int one = 1;
    367 
    368   if (!initSockets())
    369 	  return -1;
    370 
    371   snprintf(port_s, 10, "%d", port);
    372   memset(&hints, 0, sizeof(struct addrinfo));
    373   hints.ai_family = AF_UNSPEC;
    374   hints.ai_socktype = SOCK_STREAM;
    375   if ((n = getaddrinfo(hostname, port_s, &hints, &res)))
    376   {
    377     rfbClientErr("ConnectClientToTcpAddr6: getaddrinfo (%s)\n", gai_strerror(n));
    378     return -1;
    379   }
    380 
    381   ressave = res;
    382   sock = -1;
    383   while (res)
    384   {
    385     sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    386     if (sock >= 0)
    387     {
    388       if (connect(sock, res->ai_addr, res->ai_addrlen) == 0)
    389         break;
    390       close(sock);
    391       sock = -1;
    392     }
    393     res = res->ai_next;
    394   }
    395   freeaddrinfo(ressave);
    396 
    397   if (sock == -1)
    398   {
    399     rfbClientErr("ConnectClientToTcpAddr6: connect\n");
    400     return -1;
    401   }
    402 
    403   if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
    404 		 (char *)&one, sizeof(one)) < 0) {
    405     rfbClientErr("ConnectToTcpAddr: setsockopt\n");
    406     close(sock);
    407     return -1;
    408   }
    409 
    410   return sock;
    411 
    412 #else
    413 
    414   rfbClientErr("ConnectClientToTcpAddr6: IPv6 disabled\n");
    415   return -1;
    416 
    417 #endif
    418 }
    419 
    420 int
    421 ConnectClientToUnixSock(const char *sockFile)
    422 {
    423 #ifdef WIN32
    424   rfbClientErr("Windows doesn't support UNIX sockets\n");
    425   return -1;
    426 #else
    427   int sock;
    428   struct sockaddr_un addr;
    429   addr.sun_family = AF_UNIX;
    430   strcpy(addr.sun_path, sockFile);
    431 
    432   sock = socket(AF_UNIX, SOCK_STREAM, 0);
    433   if (sock < 0) {
    434     rfbClientErr("ConnectToUnixSock: socket (%s)\n",strerror(errno));
    435     return -1;
    436   }
    437 
    438   if (connect(sock, (struct sockaddr *)&addr, sizeof(addr.sun_family) + strlen(addr.sun_path)) < 0) {
    439     rfbClientErr("ConnectToUnixSock: connect\n");
    440     close(sock);
    441     return -1;
    442   }
    443 
    444   return sock;
    445 #endif
    446 }
    447 
    448 
    449 
    450 /*
    451  * FindFreeTcpPort tries to find unused TCP port in the range
    452  * (TUNNEL_PORT_OFFSET, TUNNEL_PORT_OFFSET + 99]. Returns 0 on failure.
    453  */
    454 
    455 int
    456 FindFreeTcpPort(void)
    457 {
    458   int sock, port;
    459   struct sockaddr_in addr;
    460 
    461   addr.sin_family = AF_INET;
    462   addr.sin_addr.s_addr = htonl(INADDR_ANY);
    463 
    464   if (!initSockets())
    465     return -1;
    466 
    467   sock = socket(AF_INET, SOCK_STREAM, 0);
    468   if (sock < 0) {
    469     rfbClientErr(": FindFreeTcpPort: socket\n");
    470     return 0;
    471   }
    472 
    473   for (port = TUNNEL_PORT_OFFSET + 99; port > TUNNEL_PORT_OFFSET; port--) {
    474     addr.sin_port = htons((unsigned short)port);
    475     if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
    476       close(sock);
    477       return port;
    478     }
    479   }
    480 
    481   close(sock);
    482   return 0;
    483 }
    484 
    485 
    486 /*
    487  * ListenAtTcpPort starts listening at the given TCP port.
    488  */
    489 
    490 int
    491 ListenAtTcpPort(int port)
    492 {
    493   return ListenAtTcpPortAndAddress(port, NULL);
    494 }
    495 
    496 
    497 
    498 /*
    499  * ListenAtTcpPortAndAddress starts listening at the given TCP port on
    500  * the given IP address
    501  */
    502 
    503 int
    504 ListenAtTcpPortAndAddress(int port, const char *address)
    505 {
    506   int sock;
    507   int one = 1;
    508 #ifndef LIBVNCSERVER_IPv6
    509   struct sockaddr_in addr;
    510 
    511   addr.sin_family = AF_INET;
    512   addr.sin_port = htons(port);
    513   if (address) {
    514     addr.sin_addr.s_addr = inet_addr(address);
    515   } else {
    516     addr.sin_addr.s_addr = htonl(INADDR_ANY);
    517   }
    518 
    519   if (!initSockets())
    520     return -1;
    521 
    522   sock = socket(AF_INET, SOCK_STREAM, 0);
    523   if (sock < 0) {
    524     rfbClientErr("ListenAtTcpPort: socket\n");
    525     return -1;
    526   }
    527 
    528   if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
    529 		 (const char *)&one, sizeof(one)) < 0) {
    530     rfbClientErr("ListenAtTcpPort: setsockopt\n");
    531     close(sock);
    532     return -1;
    533   }
    534 
    535   if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
    536     rfbClientErr("ListenAtTcpPort: bind\n");
    537     close(sock);
    538     return -1;
    539   }
    540 
    541 #else
    542   int rv;
    543   struct addrinfo hints, *servinfo, *p;
    544   char port_str[8];
    545 
    546   snprintf(port_str, 8, "%d", port);
    547 
    548   memset(&hints, 0, sizeof(hints));
    549   hints.ai_family = AF_UNSPEC;
    550   hints.ai_socktype = SOCK_STREAM;
    551   hints.ai_flags = AI_PASSIVE; /* fill in wildcard address if address == NULL */
    552 
    553   if (!initSockets())
    554     return -1;
    555 
    556   if ((rv = getaddrinfo(address, port_str, &hints, &servinfo)) != 0) {
    557     rfbClientErr("ListenAtTcpPortAndAddress: error in getaddrinfo: %s\n", gai_strerror(rv));
    558     return -1;
    559   }
    560 
    561   /* loop through all the results and bind to the first we can */
    562   for(p = servinfo; p != NULL; p = p->ai_next) {
    563     if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
    564       continue;
    565     }
    566 
    567 #ifdef IPV6_V6ONLY
    568     /* we have seperate IPv4 and IPv6 sockets since some OS's do not support dual binding */
    569     if (p->ai_family == AF_INET6 && setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) {
    570       rfbClientErr("ListenAtTcpPortAndAddress: error in setsockopt IPV6_V6ONLY: %s\n", strerror(errno));
    571       close(sock);
    572       freeaddrinfo(servinfo);
    573       return -1;
    574     }
    575 #endif
    576 
    577     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
    578       rfbClientErr("ListenAtTcpPortAndAddress: error in setsockopt SO_REUSEADDR: %s\n", strerror(errno));
    579       close(sock);
    580       freeaddrinfo(servinfo);
    581       return -1;
    582     }
    583 
    584     if (bind(sock, p->ai_addr, p->ai_addrlen) < 0) {
    585       close(sock);
    586       continue;
    587     }
    588 
    589     break;
    590   }
    591 
    592   if (p == NULL)  {
    593     rfbClientErr("ListenAtTcpPortAndAddress: error in bind: %s\n", strerror(errno));
    594     return -1;
    595   }
    596 
    597   /* all done with this structure now */
    598   freeaddrinfo(servinfo);
    599 #endif
    600 
    601   if (listen(sock, 5) < 0) {
    602     rfbClientErr("ListenAtTcpPort: listen\n");
    603     close(sock);
    604     return -1;
    605   }
    606 
    607   return sock;
    608 }
    609 
    610 
    611 /*
    612  * AcceptTcpConnection accepts a TCP connection.
    613  */
    614 
    615 int
    616 AcceptTcpConnection(int listenSock)
    617 {
    618   int sock;
    619   struct sockaddr_in addr;
    620   socklen_t addrlen = sizeof(addr);
    621   int one = 1;
    622 
    623   sock = accept(listenSock, (struct sockaddr *) &addr, &addrlen);
    624   if (sock < 0) {
    625     rfbClientErr("AcceptTcpConnection: accept\n");
    626     return -1;
    627   }
    628 
    629   if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
    630 		 (char *)&one, sizeof(one)) < 0) {
    631     rfbClientErr("AcceptTcpConnection: setsockopt\n");
    632     close(sock);
    633     return -1;
    634   }
    635 
    636   return sock;
    637 }
    638 
    639 
    640 /*
    641  * SetNonBlocking sets a socket into non-blocking mode.
    642  */
    643 
    644 rfbBool
    645 SetNonBlocking(int sock)
    646 {
    647 #ifdef WIN32
    648   unsigned long block=1;
    649   if(ioctlsocket(sock, FIONBIO, &block) == SOCKET_ERROR) {
    650     errno=WSAGetLastError();
    651 #else
    652   int flags = fcntl(sock, F_GETFL);
    653   if(flags < 0 || fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) {
    654 #endif
    655     rfbClientErr("Setting socket to non-blocking failed: %s\n",strerror(errno));
    656     return FALSE;
    657   }
    658   return TRUE;
    659 }
    660 
    661 
    662 
    663 /*
    664  * SetDSCP sets a socket's IP QoS parameters aka Differentiated Services Code Point field
    665  */
    666 
    667 rfbBool
    668 SetDSCP(int sock, int dscp)
    669 {
    670 #ifdef WIN32
    671   rfbClientErr("Setting of QoS IP DSCP not implemented for Windows\n");
    672   return TRUE;
    673 #else
    674   int level, cmd;
    675   struct sockaddr addr;
    676   socklen_t addrlen = sizeof(addr);
    677 
    678   if(getsockname(sock, &addr, &addrlen) != 0) {
    679     rfbClientErr("Setting socket QoS failed while getting socket address: %s\n",strerror(errno));
    680     return FALSE;
    681   }
    682 
    683   switch(addr.sa_family)
    684     {
    685 #if defined LIBVNCSERVER_IPv6 && defined IPV6_TCLASS
    686     case AF_INET6:
    687       level = IPPROTO_IPV6;
    688       cmd = IPV6_TCLASS;
    689       break;
    690 #endif
    691     case AF_INET:
    692       level = IPPROTO_IP;
    693       cmd = IP_TOS;
    694       break;
    695     default:
    696       rfbClientErr("Setting socket QoS failed: Not bound to IP address");
    697       return FALSE;
    698     }
    699 
    700   if(setsockopt(sock, level, cmd, (void*)&dscp, sizeof(dscp)) != 0) {
    701     rfbClientErr("Setting socket QoS failed: %s\n", strerror(errno));
    702     return FALSE;
    703   }
    704 
    705   return TRUE;
    706 #endif
    707 }
    708 
    709 
    710 
    711 /*
    712  * StringToIPAddr - convert a host string to an IP address.
    713  */
    714 
    715 rfbBool
    716 StringToIPAddr(const char *str, unsigned int *addr)
    717 {
    718   struct hostent *hp;
    719 
    720   if (strcmp(str,"") == 0) {
    721     *addr = htonl(INADDR_LOOPBACK); /* local */
    722     return TRUE;
    723   }
    724 
    725   *addr = inet_addr(str);
    726 
    727   if (*addr != -1)
    728     return TRUE;
    729 
    730   if (!initSockets())
    731 	  return -1;
    732 
    733   hp = gethostbyname(str);
    734 
    735   if (hp) {
    736     *addr = *(unsigned int *)hp->h_addr;
    737     return TRUE;
    738   }
    739 
    740   return FALSE;
    741 }
    742 
    743 
    744 /*
    745  * Test if the other end of a socket is on the same machine.
    746  */
    747 
    748 rfbBool
    749 SameMachine(int sock)
    750 {
    751   struct sockaddr_in peeraddr, myaddr;
    752   socklen_t addrlen = sizeof(struct sockaddr_in);
    753 
    754   getpeername(sock, (struct sockaddr *)&peeraddr, &addrlen);
    755   getsockname(sock, (struct sockaddr *)&myaddr, &addrlen);
    756 
    757   return (peeraddr.sin_addr.s_addr == myaddr.sin_addr.s_addr);
    758 }
    759 
    760 
    761 /*
    762  * Print out the contents of a packet for debugging.
    763  */
    764 
    765 void
    766 PrintInHex(char *buf, int len)
    767 {
    768   int i, j;
    769   char c, str[17];
    770 
    771   str[16] = 0;
    772 
    773   rfbClientLog("ReadExact: ");
    774 
    775   for (i = 0; i < len; i++)
    776     {
    777       if ((i % 16 == 0) && (i != 0)) {
    778 	rfbClientLog("           ");
    779       }
    780       c = buf[i];
    781       str[i % 16] = (((c > 31) && (c < 127)) ? c : '.');
    782       rfbClientLog("%02x ",(unsigned char)c);
    783       if ((i % 4) == 3)
    784 	rfbClientLog(" ");
    785       if ((i % 16) == 15)
    786 	{
    787 	  rfbClientLog("%s\n",str);
    788 	}
    789     }
    790   if ((i % 16) != 0)
    791     {
    792       for (j = i % 16; j < 16; j++)
    793 	{
    794 	  rfbClientLog("   ");
    795 	  if ((j % 4) == 3) rfbClientLog(" ");
    796 	}
    797       str[i % 16] = 0;
    798       rfbClientLog("%s\n",str);
    799     }
    800 
    801   fflush(stderr);
    802 }
    803 
    804 int WaitForMessage(rfbClient* client,unsigned int usecs)
    805 {
    806   fd_set fds;
    807   struct timeval timeout;
    808   int num;
    809 
    810   if (client->serverPort==-1)
    811     /* playing back vncrec file */
    812     return 1;
    813 
    814   timeout.tv_sec=(usecs/1000000);
    815   timeout.tv_usec=(usecs%1000000);
    816 
    817   FD_ZERO(&fds);
    818   FD_SET(client->sock,&fds);
    819 
    820   num=select(client->sock+1, &fds, NULL, NULL, &timeout);
    821   if(num<0) {
    822 #ifdef WIN32
    823     errno=WSAGetLastError();
    824 #endif
    825     rfbClientLog("Waiting for message failed: %d (%s)\n",errno,strerror(errno));
    826   }
    827 
    828   return num;
    829 }
    830 
    831 
    832