root/src/vfs/smbfs/helpers/lib/util_sock.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. is_a_socket
  2. set_socket_options
  3. close_sockets
  4. write_socket
  5. read_udp_socket
  6. read_with_timeout
  7. send_keepalive
  8. read_data
  9. write_data
  10. read_smb_length_return_keepalive
  11. read_smb_length
  12. receive_smb
  13. client_receive_smb
  14. send_null_session_msg
  15. send_smb
  16. send_one_packet
  17. open_socket_in
  18. open_socket_out
  19. client_name
  20. client_addr

   1 /*
   2    Unix SMB/Netbios implementation.
   3    Version 1.9.
   4    Samba utility functions
   5 
   6    Copyright (C) Andrew Tridgell 1992-1998
   7 
   8    Copyright (C) 2011-2019
   9    Free Software Foundation, Inc.
  10 
  11    This file is part of the Midnight Commander.
  12 
  13    The Midnight Commander is free software: you can redistribute it
  14    and/or modify it under the terms of the GNU General Public License as
  15    published by the Free Software Foundation, either version 3 of the License,
  16    or (at your option) any later version.
  17 
  18    The Midnight Commander is distributed in the hope that it will be useful,
  19    but WITHOUT ANY WARRANTY; without even the implied warranty of
  20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21    GNU General Public License for more details.
  22 
  23    You should have received a copy of the GNU General Public License
  24    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  25  */
  26 
  27 #include "includes.h"
  28 
  29 const char *unix_error_string (int error_num);
  30 
  31 #ifdef WITH_SSL
  32 #include <ssl.h>
  33 #undef Realloc                  /* SSLeay defines this and samba has a function of this name */
  34 extern SSL *ssl;
  35 extern int sslFd;
  36 #endif /* WITH_SSL */
  37 
  38 extern int DEBUGLEVEL;
  39 
  40 BOOL passive = False;
  41 
  42 /* the client file descriptor */
  43 int Client = -1;
  44 
  45 /* the last IP received from */
  46 struct in_addr lastip;
  47 
  48 /* the last port received from */
  49 int lastport = 0;
  50 
  51 
  52 int smb_read_error = 0;
  53 
  54 #if 0
  55 /****************************************************************************
  56 determine if a file descriptor is in fact a socket
  57 ****************************************************************************/
  58 BOOL
  59 is_a_socket (int fd)
     /* [previous][next][first][last][top][bottom][index][help]  */
  60 {
  61     int v;
  62     unsigned int l;
  63     l = sizeof (int);
  64     return (getsockopt (fd, SOL_SOCKET, SO_TYPE, (char *) &v, &l) == 0);
  65 }
  66 #endif /* 0 */
  67 
  68 enum SOCK_OPT_TYPES
  69 { OPT_BOOL, OPT_INT, OPT_ON };
  70 
  71 static const struct
  72 {
  73     const char *name;
  74     int level;
  75     int option;
  76     int value;
  77     int opttype;
  78 } socket_options[] =
  79 {
  80     {
  81     "SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
  82     {
  83     "SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
  84     {
  85     "SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
  86 #ifdef TCP_NODELAY
  87     {
  88     "TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
  89 #endif
  90 #ifdef IPTOS_LOWDELAY
  91     {
  92     "IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
  93 #endif
  94 #ifdef IPTOS_THROUGHPUT
  95     {
  96     "IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
  97 #endif
  98 #ifdef SO_SNDBUF
  99     {
 100     "SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
 101 #endif
 102 #ifdef SO_RCVBUF
 103     {
 104     "SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
 105 #endif
 106 #ifdef SO_SNDLOWAT
 107     {
 108     "SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
 109 #endif
 110 #ifdef SO_RCVLOWAT
 111     {
 112     "SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
 113 #endif
 114 #ifdef SO_SNDTIMEO
 115     {
 116     "SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
 117 #endif
 118 #ifdef SO_RCVTIMEO
 119     {
 120     "SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
 121 #endif
 122     {
 123 NULL, 0, 0, 0, 0}};
 124 
 125 
 126 
 127 /****************************************************************************
 128 set user socket options
 129 ****************************************************************************/
 130 void
 131 set_socket_options (int fd, char *options)
     /* [previous][next][first][last][top][bottom][index][help]  */
 132 {
 133     fstring tok;
 134 
 135     while (next_token (&options, tok, " \t,", sizeof (tok)))
 136     {
 137         int ret = 0, i;
 138         int value = 1;
 139         char *p;
 140         BOOL got_value = False;
 141 
 142         if ((p = strchr (tok, '=')))
 143         {
 144             *p = 0;
 145             value = atoi (p + 1);
 146             got_value = True;
 147         }
 148 
 149         for (i = 0; socket_options[i].name; i++)
 150             if (strequal (socket_options[i].name, tok))
 151                 break;
 152 
 153         if (!socket_options[i].name)
 154         {
 155             DEBUG (0, ("Unknown socket option %s\n", tok));
 156             continue;
 157         }
 158 
 159         switch (socket_options[i].opttype)
 160         {
 161         case OPT_BOOL:
 162         case OPT_INT:
 163             ret = setsockopt (fd, socket_options[i].level,
 164                               socket_options[i].option, (char *) &value, sizeof (int));
 165             break;
 166 
 167         case OPT_ON:
 168             if (got_value)
 169                 DEBUG (0, ("syntax error - %s does not take a value\n", tok));
 170 
 171             {
 172                 int on = socket_options[i].value;
 173                 ret = setsockopt (fd, socket_options[i].level,
 174                                   socket_options[i].option, (char *) &on, sizeof (int));
 175             }
 176             break;
 177         }
 178 
 179         if (ret != 0)
 180             DEBUG (0, ("Failed to set socket option %s\n", tok));
 181     }
 182 }
 183 
 184 
 185 
 186 /****************************************************************************
 187   close the socket communication
 188 ****************************************************************************/
 189 void
 190 close_sockets (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 191 {
 192 #ifdef WITH_SSL
 193     sslutil_disconnect (Client);
 194 #endif /* WITH_SSL */
 195 
 196     close (Client);
 197     Client = -1;
 198 }
 199 
 200 
 201 
 202 /****************************************************************************
 203 write to a socket
 204 ****************************************************************************/
 205 ssize_t
 206 write_socket (int fd, char *buf, size_t len)
     /* [previous][next][first][last][top][bottom][index][help]  */
 207 {
 208     ssize_t ret = 0;
 209 
 210     if (passive)
 211         return (len);
 212     DEBUG (6, ("write_socket(%d,%d)\n", fd, (int) len));
 213     ret = write_data (fd, buf, len);
 214 
 215     DEBUG (6, ("write_socket(%d,%d) wrote %d\n", fd, (int) len, (int) ret));
 216     if (ret <= 0)
 217         DEBUG (1, ("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
 218                    (int) len, fd, unix_error_string (errno)));
 219 
 220     return (ret);
 221 }
 222 
 223 /****************************************************************************
 224 read from a socket
 225 ****************************************************************************/
 226 ssize_t
 227 read_udp_socket (int fd, char *buf, size_t len)
     /* [previous][next][first][last][top][bottom][index][help]  */
 228 {
 229     ssize_t ret;
 230     struct sockaddr_in sock;
 231     unsigned int socklen;
 232 
 233     socklen = sizeof (sock);
 234     memset ((char *) &sock, '\0', socklen);
 235     memset ((char *) &lastip, '\0', sizeof (lastip));
 236     ret = (ssize_t) recvfrom (fd, buf, len, 0, (struct sockaddr *) &sock, &socklen);
 237     if (ret <= 0)
 238     {
 239         DEBUG (2, ("read socket failed. ERRNO=%s\n", unix_error_string (errno)));
 240         return (0);
 241     }
 242 
 243     lastip = sock.sin_addr;
 244     lastport = ntohs (sock.sin_port);
 245 
 246     DEBUG (10, ("read_udp_socket: lastip %s lastport %d read: %d\n",
 247                 inet_ntoa (lastip), lastport, (int) ret));
 248 
 249     return (ret);
 250 }
 251 
 252 
 253 /****************************************************************************
 254 read data from a device with a timout in msec.
 255 mincount = if timeout, minimum to read before returning
 256 maxcount = number to be read.
 257 time_out = timeout in milliseconds
 258 ****************************************************************************/
 259 
 260 ssize_t
 261 read_with_timeout (int fd, char *buf, size_t mincnt, size_t maxcnt, unsigned int time_out)
     /* [previous][next][first][last][top][bottom][index][help]  */
 262 {
 263     fd_set fds;
 264     int selrtn;
 265     ssize_t readret;
 266     size_t nread = 0;
 267     struct timeval timeout;
 268 
 269     /* just checking .... */
 270     if (maxcnt <= 0)
 271         return (0);
 272 
 273     smb_read_error = 0;
 274 
 275     /* Blocking read */
 276     if (time_out <= 0)
 277     {
 278         if (mincnt == 0)
 279             mincnt = maxcnt;
 280 
 281         while (nread < mincnt)
 282         {
 283 #ifdef WITH_SSL
 284             if (fd == sslFd)
 285             {
 286                 readret = SSL_read (ssl, buf + nread, maxcnt - nread);
 287             }
 288             else
 289             {
 290                 readret = read (fd, buf + nread, maxcnt - nread);
 291             }
 292 #else /* WITH_SSL */
 293             readret = read (fd, buf + nread, maxcnt - nread);
 294 #endif /* WITH_SSL */
 295 
 296             if (readret == 0)
 297             {
 298                 DEBUG (5, ("read_with_timeout: blocking read. EOF from client.\n"));
 299                 smb_read_error = READ_EOF;
 300                 return -1;
 301             }
 302 
 303             if (readret == -1)
 304             {
 305                 DEBUG (0, ("read_with_timeout: read error = %s.\n", unix_error_string (errno)));
 306                 smb_read_error = READ_ERROR;
 307                 return -1;
 308             }
 309             nread += readret;
 310         }
 311         return ((ssize_t) nread);
 312     }
 313 
 314     /* Most difficult - timeout read */
 315     /* If this is ever called on a disk file and 
 316        mincnt is greater than the filesize then
 317        system performance will suffer severely as 
 318        select always returns true on disk files */
 319 
 320     /* Set initial timeout */
 321     timeout.tv_sec = (time_t) (time_out / 1000);
 322     timeout.tv_usec = (long) (1000 * (time_out % 1000));
 323 
 324     for (nread = 0; nread < mincnt;)
 325     {
 326         FD_ZERO (&fds);
 327         FD_SET (fd, &fds);
 328 
 329         selrtn = sys_select (fd + 1, &fds, &timeout);
 330 
 331         /* Check if error */
 332         if (selrtn == -1)
 333         {
 334             /* something is wrong. Maybe the socket is dead? */
 335             DEBUG (0,
 336                    ("read_with_timeout: timeout read. select error = %s.\n",
 337                     unix_error_string (errno)));
 338             smb_read_error = READ_ERROR;
 339             return -1;
 340         }
 341 
 342         /* Did we timeout ? */
 343         if (selrtn == 0)
 344         {
 345             DEBUG (10, ("read_with_timeout: timeout read. select timed out.\n"));
 346             smb_read_error = READ_TIMEOUT;
 347             return -1;
 348         }
 349 
 350 #ifdef WITH_SSL
 351         if (fd == sslFd)
 352         {
 353             readret = SSL_read (ssl, buf + nread, maxcnt - nread);
 354         }
 355         else
 356         {
 357             readret = read (fd, buf + nread, maxcnt - nread);
 358         }
 359 #else /* WITH_SSL */
 360         readret = read (fd, buf + nread, maxcnt - nread);
 361 #endif /* WITH_SSL */
 362 
 363         if (readret == 0)
 364         {
 365             /* we got EOF on the file descriptor */
 366             DEBUG (5, ("read_with_timeout: timeout read. EOF from client.\n"));
 367             smb_read_error = READ_EOF;
 368             return -1;
 369         }
 370 
 371         if (readret == -1)
 372         {
 373             /* the descriptor is probably dead */
 374             DEBUG (0,
 375                    ("read_with_timeout: timeout read. read error = %s.\n",
 376                     unix_error_string (errno)));
 377             smb_read_error = READ_ERROR;
 378             return -1;
 379         }
 380 
 381         nread += readret;
 382     }
 383 
 384     /* Return the number we got */
 385     return ((ssize_t) nread);
 386 }
 387 
 388 #if 0
 389 /****************************************************************************
 390 send a keepalive packet (rfc1002)
 391 ****************************************************************************/
 392 BOOL
 393 send_keepalive (int client)
     /* [previous][next][first][last][top][bottom][index][help]  */
 394 {
 395     unsigned char buf[4];
 396 
 397     buf[0] = 0x85;
 398     buf[1] = buf[2] = buf[3] = 0;
 399 
 400     return (write_data (client, (char *) buf, 4) == 4);
 401 }
 402 #endif /* 0 */
 403 
 404 
 405 /****************************************************************************
 406   read data from the client, reading exactly N bytes. 
 407 ****************************************************************************/
 408 ssize_t
 409 read_data (int fd, char *buffer, size_t N)
     /* [previous][next][first][last][top][bottom][index][help]  */
 410 {
 411     ssize_t ret;
 412     size_t total = 0;
 413 
 414     smb_read_error = 0;
 415 
 416     while (total < N)
 417     {
 418 #ifdef WITH_SSL
 419         if (fd == sslFd)
 420         {
 421             ret = SSL_read (ssl, buffer + total, N - total);
 422         }
 423         else
 424         {
 425             ret = read (fd, buffer + total, N - total);
 426         }
 427 #else /* WITH_SSL */
 428         ret = read (fd, buffer + total, N - total);
 429 #endif /* WITH_SSL */
 430 
 431         if (ret == 0)
 432         {
 433             DEBUG (10,
 434                    ("read_data: read of %d returned 0. Error = %s\n", (int) (N - total),
 435                     unix_error_string (errno)));
 436             smb_read_error = READ_EOF;
 437             return 0;
 438         }
 439         if (ret == -1)
 440         {
 441             DEBUG (0,
 442                    ("read_data: read failure for %d. Error = %s\n", (int) (N - total),
 443                     unix_error_string (errno)));
 444             smb_read_error = READ_ERROR;
 445             return -1;
 446         }
 447         total += ret;
 448     }
 449     return (ssize_t) total;
 450 }
 451 
 452 
 453 /****************************************************************************
 454   write data to a fd 
 455 ****************************************************************************/
 456 ssize_t
 457 write_data (int fd, char *buffer, size_t N)
     /* [previous][next][first][last][top][bottom][index][help]  */
 458 {
 459     size_t total = 0;
 460     ssize_t ret;
 461 
 462     while (total < N)
 463     {
 464 #ifdef WITH_SSL
 465         if (fd == sslFd)
 466         {
 467             ret = SSL_write (ssl, buffer + total, N - total);
 468         }
 469         else
 470         {
 471             ret = write (fd, buffer + total, N - total);
 472         }
 473 #else /* WITH_SSL */
 474         ret = write (fd, buffer + total, N - total);
 475 #endif /* WITH_SSL */
 476 
 477         if (ret == -1)
 478         {
 479             DEBUG (1, ("write_data: write failure. Error = %s\n", unix_error_string (errno)));
 480             return -1;
 481         }
 482         if (ret == 0)
 483             return total;
 484 
 485         total += ret;
 486     }
 487     return (ssize_t) total;
 488 }
 489 
 490 
 491 
 492 /****************************************************************************
 493 read 4 bytes of a smb packet and return the smb length of the packet
 494 store the result in the buffer
 495 This version of the function will return a length of zero on receiving
 496 a keepalive packet.
 497 timeout is in milliseconds.
 498 ****************************************************************************/
 499 static ssize_t
 500 read_smb_length_return_keepalive (int fd, char *inbuf, unsigned int timeout)
     /* [previous][next][first][last][top][bottom][index][help]  */
 501 {
 502     ssize_t len = 0;
 503     int msg_type;
 504     BOOL ok = False;
 505 
 506     while (!ok)
 507     {
 508         if (timeout > 0)
 509             ok = (read_with_timeout (fd, inbuf, 4, 4, timeout) == 4);
 510         else
 511             ok = (read_data (fd, inbuf, 4) == 4);
 512 
 513         if (!ok)
 514             return (-1);
 515 
 516         len = smb_len (inbuf);
 517         msg_type = CVAL (inbuf, 0);
 518 
 519         if (msg_type == 0x85)
 520             DEBUG (5, ("Got keepalive packet\n"));
 521     }
 522 
 523     DEBUG (10, ("got smb length of %d\n", (int) len));
 524 
 525     return (len);
 526 }
 527 
 528 #if 0
 529 /****************************************************************************
 530 read 4 bytes of a smb packet and return the smb length of the packet
 531 store the result in the buffer. This version of the function will
 532 never return a session keepalive (length of zero).
 533 timeout is in milliseconds.
 534 ****************************************************************************/
 535 ssize_t
 536 read_smb_length (int fd, char *inbuf, unsigned int timeout)
     /* [previous][next][first][last][top][bottom][index][help]  */
 537 {
 538     ssize_t len;
 539 
 540     for (;;)
 541     {
 542         len = read_smb_length_return_keepalive (fd, inbuf, timeout);
 543 
 544         if (len < 0)
 545             return len;
 546 
 547         /* Ignore session keepalives. */
 548         if (CVAL (inbuf, 0) != 0x85)
 549             break;
 550     }
 551 
 552     DEBUG (10, ("read_smb_length: got smb length of %d\n", len));
 553 
 554     return len;
 555 }
 556 #endif /* 0 */
 557 /****************************************************************************
 558   read an smb from a fd. Note that the buffer *MUST* be of size
 559   BUFFER_SIZE+SAFETY_MARGIN.
 560   The timeout is in milliseconds. 
 561   This function will return on a
 562   receipt of a session keepalive packet.
 563 ****************************************************************************/
 564 BOOL
 565 receive_smb (int fd, char *buffer, unsigned int timeout)
     /* [previous][next][first][last][top][bottom][index][help]  */
 566 {
 567     ssize_t len, ret;
 568 
 569     smb_read_error = 0;
 570 
 571     memset (buffer, '\0', smb_size + 100);
 572 
 573     len = read_smb_length_return_keepalive (fd, buffer, timeout);
 574     if (len < 0)
 575     {
 576         DEBUG (10, ("receive_smb: length < 0!\n"));
 577         return (False);
 578     }
 579 
 580     if (len > BUFFER_SIZE)
 581     {
 582         DEBUG (0, ("Invalid packet length! (%d bytes).\n", (int) len));
 583         if (len > BUFFER_SIZE + (SAFETY_MARGIN / 2))
 584         {
 585             exit (1);
 586         }
 587     }
 588 
 589     if (len > 0)
 590     {
 591         ret = read_data (fd, buffer + 4, len);
 592         if (ret != len)
 593         {
 594             smb_read_error = READ_ERROR;
 595             return False;
 596         }
 597     }
 598     return (True);
 599 }
 600 
 601 /****************************************************************************
 602   read an smb from a fd ignoring all keepalive packets. Note that the buffer 
 603   *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
 604   The timeout is in milliseconds
 605 
 606   This is exactly the same as receive_smb except that it never returns
 607   a session keepalive packet (just as receive_smb used to do).
 608   receive_smb was changed to return keepalives as the oplock processing means this call
 609   should never go into a blocking read.
 610 ****************************************************************************/
 611 
 612 BOOL
 613 client_receive_smb (int fd, char *buffer, unsigned int timeout)
     /* [previous][next][first][last][top][bottom][index][help]  */
 614 {
 615     BOOL ret;
 616 
 617     for (;;)
 618     {
 619         ret = receive_smb (fd, buffer, timeout);
 620 
 621         if (!ret)
 622         {
 623             DEBUG (10, ("client_receive_smb failed\n"));
 624             show_msg (buffer);
 625             return ret;
 626         }
 627 
 628         /* Ignore session keepalive packets. */
 629         if (CVAL (buffer, 0) != 0x85)
 630             break;
 631     }
 632     show_msg (buffer);
 633     return ret;
 634 }
 635 
 636 /****************************************************************************
 637   send an null session message to a fd
 638 ****************************************************************************/
 639 #if 0
 640 BOOL
 641 send_null_session_msg (int fd)
     /* [previous][next][first][last][top][bottom][index][help]  */
 642 {
 643     ssize_t ret;
 644     uint32 blank = 0;
 645     size_t len = 4;
 646     size_t nwritten = 0;
 647     char *buffer = (char *) &blank;
 648 
 649     while (nwritten < len)
 650     {
 651         ret = write_socket (fd, buffer + nwritten, len - nwritten);
 652         if (ret <= 0)
 653         {
 654             DEBUG (0,
 655                    ("send_null_session_msg: Error writing %d bytes to client. %d. Exiting\n",
 656                     (int) len, (int) ret));
 657             close_sockets ();
 658             exit (1);
 659         }
 660         nwritten += ret;
 661     }
 662 
 663     DEBUG (10, ("send_null_session_msg: sent 4 null bytes to client.\n"));
 664     return True;
 665 }
 666 
 667 /****************************************************************************
 668   send an smb to a fd 
 669 ****************************************************************************/
 670 BOOL
 671 send_smb (int fd, char *buffer)
     /* [previous][next][first][last][top][bottom][index][help]  */
 672 {
 673     size_t len;
 674     size_t nwritten = 0;
 675     ssize_t ret;
 676     len = smb_len (buffer) + 4;
 677 
 678     while (nwritten < len)
 679     {
 680         ret = write_socket (fd, buffer + nwritten, len - nwritten);
 681         if (ret <= 0)
 682         {
 683             DEBUG (0, ("Error writing %d bytes to client. %d. Exiting\n", (int) len, (int) ret));
 684             close_sockets ();
 685             exit (1);
 686         }
 687         nwritten += ret;
 688     }
 689 
 690     return True;
 691 }
 692 
 693 
 694 
 695 /****************************************************************************
 696 send a single packet to a port on another machine
 697 ****************************************************************************/
 698 BOOL
 699 send_one_packet (char *buf, int len, struct in_addr ip, int port, int type)
     /* [previous][next][first][last][top][bottom][index][help]  */
 700 {
 701     BOOL ret;
 702     int out_fd;
 703     struct sockaddr_in sock_out;
 704 
 705     if (passive)
 706         return (True);
 707 
 708     /* create a socket to write to */
 709     out_fd = socket (AF_INET, type, 0);
 710     if (out_fd == -1)
 711     {
 712         DEBUG (0, ("socket failed"));
 713         return False;
 714     }
 715 
 716     /* set the address and port */
 717     memset ((char *) &sock_out, '\0', sizeof (sock_out));
 718     putip ((char *) &sock_out.sin_addr, (char *) &ip);
 719     sock_out.sin_port = htons (port);
 720     sock_out.sin_family = AF_INET;
 721 
 722     if (DEBUGLEVEL > 0)
 723         DEBUG (3, ("sending a packet of len %d to (%s) on port %d of type %s\n",
 724                    len, inet_ntoa (ip), port, type == SOCK_DGRAM ? "DGRAM" : "STREAM"));
 725 
 726     /* send it */
 727     ret = (sendto (out_fd, buf, len, 0, (struct sockaddr *) &sock_out, sizeof (sock_out)) >= 0);
 728 
 729     if (!ret)
 730         DEBUG (0, ("Packet send to %s(%d) failed ERRNO=%s\n",
 731                    inet_ntoa (ip), port, unix_error_string (errno)));
 732 
 733     close (out_fd);
 734     return (ret);
 735 }
 736 #endif /* 0 */
 737 
 738 /****************************************************************************
 739 open a socket of the specified type, port and address for incoming data
 740 ****************************************************************************/
 741 int
 742 open_socket_in (int type, int port, int dlevel, uint32 socket_addr, BOOL rebind)
     /* [previous][next][first][last][top][bottom][index][help]  */
 743 {
 744     struct hostent *hp;
 745     struct sockaddr_in sock;
 746     pstring host_name;
 747     int res;
 748 
 749     /* get my host name */
 750     if (gethostname (host_name, MAXHOSTNAMELEN) == -1)
 751     {
 752         DEBUG (0, ("gethostname failed\n"));
 753         return -1;
 754     }
 755 
 756     /* get host info */
 757     if ((hp = Get_Hostbyname (host_name)) == 0)
 758     {
 759         DEBUG (0, ("Get_Hostbyname: Unknown host %s\n", host_name));
 760         return -1;
 761     }
 762 
 763     memset ((char *) &sock, '\0', sizeof (sock));
 764     memcpy ((char *) &sock.sin_addr, (char *) hp->h_addr, hp->h_length);
 765 
 766 #ifdef HAVE_SOCK_SIN_LEN
 767     sock.sin_len = sizeof (sock);
 768 #endif
 769     sock.sin_port = htons (port);
 770     sock.sin_family = hp->h_addrtype;
 771     sock.sin_addr.s_addr = socket_addr;
 772     res = socket (hp->h_addrtype, type, 0);
 773     if (res == -1)
 774     {
 775         DEBUG (0, ("socket failed\n"));
 776         return -1;
 777     }
 778 
 779     {
 780         int val = 1;
 781         if (rebind)
 782             val = 1;
 783         else
 784             val = 0;
 785         setsockopt (res, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof (val));
 786     }
 787 
 788     /* now we've got a socket - we need to bind it */
 789     if (bind (res, (struct sockaddr *) &sock, sizeof (sock)) < 0)
 790     {
 791         if (port)
 792         {
 793             if (port == SMB_PORT || port == NMB_PORT)
 794                 DEBUG (dlevel, ("bind failed on port %d socket_addr=%s (%s)\n",
 795                                 port, inet_ntoa (sock.sin_addr), unix_error_string (errno)));
 796             close (res);
 797 
 798             if (dlevel > 0 && port < 1000)
 799                 port = 7999;
 800 
 801             if (port >= 1000 && port < 9000)
 802                 return (open_socket_in (type, port + 1, dlevel, socket_addr, rebind));
 803         }
 804 
 805         return (-1);
 806     }
 807     DEBUG (3, ("bind succeeded on port %d\n", port));
 808 
 809     return res;
 810 }
 811 
 812 
 813 /****************************************************************************
 814   create an outgoing socket. timeout is in milliseconds.
 815   **************************************************************************/
 816 int
 817 open_socket_out (int type, struct in_addr *addr, int port, int timeout)
     /* [previous][next][first][last][top][bottom][index][help]  */
 818 {
 819     struct sockaddr_in sock_out;
 820     int res, ret;
 821     int connect_loop = 250;     /* 250 milliseconds */
 822     int loops = (timeout) / connect_loop;
 823 
 824     /* create a socket to write to */
 825     res = socket (PF_INET, type, 0);
 826     if (res == -1)
 827     {
 828         DEBUG (0, ("socket error\n"));
 829         return -1;
 830     }
 831 
 832     if (type != SOCK_STREAM)
 833         return (res);
 834 
 835     memset ((char *) &sock_out, '\0', sizeof (sock_out));
 836     putip ((char *) &sock_out.sin_addr, (char *) addr);
 837 
 838     sock_out.sin_port = htons (port);
 839     sock_out.sin_family = PF_INET;
 840 
 841     /* set it non-blocking */
 842     set_blocking (res, False);
 843 
 844     DEBUG (3, ("Connecting to %s at port %d\n", inet_ntoa (*addr), port));
 845 
 846     /* and connect it to the destination */
 847   connect_again:
 848     ret = connect (res, (struct sockaddr *) &sock_out, sizeof (sock_out));
 849 
 850     /* Some systems return EAGAIN when they mean EINPROGRESS */
 851     if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || errno == EAGAIN) && loops--)
 852     {
 853         msleep (connect_loop);
 854         goto connect_again;
 855     }
 856 
 857     if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || errno == EAGAIN))
 858     {
 859         DEBUG (1, ("timeout connecting to %s:%d\n", inet_ntoa (*addr), port));
 860         close (res);
 861         return -1;
 862     }
 863 
 864 #ifdef EISCONN
 865     if (ret < 0 && errno == EISCONN)
 866     {
 867         errno = 0;
 868         ret = 0;
 869     }
 870 #endif
 871 
 872     if (ret < 0)
 873     {
 874         DEBUG (1, ("error connecting to %s:%d (%s)\n",
 875                    inet_ntoa (*addr), port, unix_error_string (errno)));
 876         close (res);
 877         return -1;
 878     }
 879 
 880     /* set it blocking again */
 881     set_blocking (res, True);
 882 
 883     return res;
 884 }
 885 
 886 
 887 /*******************************************************************
 888  Reset the 'done' variables so after a client process is created
 889  from a fork call these calls will be re-done. This should be
 890  expanded if more variables need reseting.
 891  ******************************************************************/
 892 
 893 static BOOL global_client_name_done = False;
 894 static BOOL global_client_addr_done = False;
 895 
 896 /*******************************************************************
 897  return the DNS name of the client 
 898  ******************************************************************/
 899 char *
 900 client_name (int fd)
     /* [previous][next][first][last][top][bottom][index][help]  */
 901 {
 902     struct sockaddr sa;
 903     struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
 904     unsigned int length = sizeof (sa);
 905     static pstring name_buf;
 906     struct hostent *hp;
 907     static int last_fd = -1;
 908 
 909     if (global_client_name_done && last_fd == fd)
 910         return name_buf;
 911 
 912     last_fd = fd;
 913     global_client_name_done = False;
 914 
 915     pstrcpy (name_buf, "UNKNOWN");
 916 
 917     if (fd == -1)
 918     {
 919         return name_buf;
 920     }
 921 
 922     if (getpeername (fd, &sa, &length) < 0)
 923     {
 924         DEBUG (0, ("getpeername failed. Error was %s\n", unix_error_string (errno)));
 925         return name_buf;
 926     }
 927 
 928     /* Look up the remote host name. */
 929     if ((hp = gethostbyaddr ((char *) &sockin->sin_addr, sizeof (sockin->sin_addr), AF_INET)) == 0)
 930     {
 931         DEBUG (1, ("Gethostbyaddr failed for %s\n", client_addr (fd)));
 932         StrnCpy (name_buf, client_addr (fd), sizeof (name_buf) - 1);
 933     }
 934     else
 935     {
 936         StrnCpy (name_buf, (char *) hp->h_name, sizeof (name_buf) - 1);
 937         if (!matchname (name_buf, sockin->sin_addr))
 938         {
 939             DEBUG (0, ("Matchname failed on %s %s\n", name_buf, client_addr (fd)));
 940             pstrcpy (name_buf, "UNKNOWN");
 941         }
 942     }
 943     global_client_name_done = True;
 944     return name_buf;
 945 }
 946 
 947 /*******************************************************************
 948  return the IP addr of the client as a string 
 949  ******************************************************************/
 950 char *
 951 client_addr (int fd)
     /* [previous][next][first][last][top][bottom][index][help]  */
 952 {
 953     struct sockaddr sa;
 954     struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
 955     unsigned int length = sizeof (sa);
 956     static fstring addr_buf;
 957     static int last_fd = -1;
 958 
 959     if (global_client_addr_done && fd == last_fd)
 960         return addr_buf;
 961 
 962     last_fd = fd;
 963     global_client_addr_done = False;
 964 
 965     fstrcpy (addr_buf, "0.0.0.0");
 966 
 967     if (fd == -1)
 968     {
 969         return addr_buf;
 970     }
 971 
 972     if (getpeername (fd, &sa, &length) < 0)
 973     {
 974         DEBUG (0, ("getpeername failed. Error was %s\n", unix_error_string (errno)));
 975         return addr_buf;
 976     }
 977 
 978     fstrcpy (addr_buf, (char *) inet_ntoa (sockin->sin_addr));
 979 
 980     global_client_addr_done = True;
 981     return addr_buf;
 982 }

/* [previous][next][first][last][top][bottom][index][help]  */