2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Tim Potter 2000-2001
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /****************************************************************************
26 Determine if a file descriptor is in fact a socket.
27 ****************************************************************************/
28 BOOL is_a_socket(int fd)
32 return getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0;
35 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
37 typedef struct smb_socket_option {
45 static const smb_socket_option socket_options[] = {
46 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
47 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
48 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
50 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
53 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
55 #ifdef IPTOS_THROUGHPUT
56 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
59 {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL},
62 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
65 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
68 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
71 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
74 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
77 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
81 /****************************************************************************
83 ****************************************************************************/
85 static void print_socket_options(int s)
88 const smb_socket_option *p = &socket_options[0];
90 for (; p->name != NULL; p++) {
91 if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) {
92 DEBUG(5,("Could not test socket option %s.\n", p->name));
94 DEBUG(5,("socket option %s = %d\n",p->name,value));
99 /****************************************************************************
100 Set user socket options.
101 ****************************************************************************/
103 void set_socket_options(int fd, const char *options)
107 while (next_token(&options,tok," \t,", sizeof(tok))) {
111 BOOL got_value = False;
113 if ((p = strchr_m(tok,'='))) {
119 for (i=0;socket_options[i].name;i++)
120 if (strequal(socket_options[i].name,tok))
123 if (!socket_options[i].name) {
124 DEBUG(0,("Unknown socket option %s\n",tok));
128 switch (socket_options[i].opttype) {
131 ret = setsockopt(fd,socket_options[i].level,
132 socket_options[i].option,(char *)&value,sizeof(int));
137 DEBUG(0,("syntax error - %s does not take a value\n",tok));
140 int on = socket_options[i].value;
141 ret = setsockopt(fd,socket_options[i].level,
142 socket_options[i].option,(char *)&on,sizeof(int));
148 DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) ));
151 print_socket_options(fd);
154 /****************************************************************************
156 ****************************************************************************/
158 ssize_t read_udp_socket(int fd, char *buf, size_t len,
159 struct in_addr *from_addr, int *from_port)
162 struct sockaddr_in sock;
163 socklen_t socklen = sizeof(sock);
165 ret = (ssize_t)sys_recvfrom(fd,buf,len, 0, (struct sockaddr *)&sock, &socklen);
167 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
172 *from_addr = sock.sin_addr;
175 *from_port = ntohs(sock.sin_port);
182 /****************************************************************************
183 read data from the client, reading exactly N bytes.
184 ****************************************************************************/
185 ssize_t read_data(int fd, char *buffer, size_t N)
196 ret = sys_read(fd,buffer + total,N - total);
208 return (ssize_t)total;
212 /****************************************************************************
214 ****************************************************************************/
215 ssize_t write_data(int fd, const char *buffer, size_t N)
226 ret = sys_write(fd, buffer + total, N - total);
239 return (ssize_t)total;
242 /****************************************************************************
244 ****************************************************************************/
246 static BOOL timeout_until(struct timeval *timeout,
247 const struct timeval *endtime)
253 if ((now.tv_sec > endtime->tv_sec) ||
254 ((now.tv_sec == endtime->tv_sec) &&
255 (now.tv_usec > endtime->tv_usec)))
258 timeout->tv_sec = endtime->tv_sec - now.tv_sec;
259 timeout->tv_usec = endtime->tv_usec - now.tv_usec;
264 /****************************************************************************
265 Read data from the client, reading exactly N bytes, with timeout.
266 ****************************************************************************/
268 ssize_t read_data_until(int fd,char *buffer,size_t N,
269 const struct timeval *endtime)
276 if (endtime != NULL) {
278 struct timeval timeout;
284 if (!timeout_until(&timeout, endtime))
287 res = sys_select(fd+1, &r_fds, NULL, NULL, &timeout);
292 ret = sys_read(fd,buffer + total,N - total);
295 DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
300 DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
305 return (ssize_t)total;
308 /****************************************************************************
309 Write data to a fd with timeout.
310 ****************************************************************************/
312 ssize_t write_data_until(int fd,char *buffer,size_t N,
313 const struct timeval *endtime)
320 if (endtime != NULL) {
322 struct timeval timeout;
328 if (!timeout_until(&timeout, endtime))
331 res = sys_select(fd+1, NULL, &w_fds, NULL, &timeout);
336 ret = sys_write(fd,buffer + total,N - total);
339 DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
347 return (ssize_t)total;
351 /****************************************************************************
352 send a keepalive packet (rfc1002)
353 ****************************************************************************/
354 BOOL send_nbt_keepalive(int sock_fd)
358 buf[0] = SMBkeepalive;
359 buf[1] = buf[2] = buf[3] = 0;
361 return write_data(sock_fd,(char *)buf,4) == 4;
365 /****************************************************************************
366 Open a socket of the specified type, port, and address for incoming data.
367 ****************************************************************************/
368 int open_socket_in( int type, int port, int dlevel, uint32_t socket_addr, BOOL rebind )
370 struct sockaddr_in sock;
373 memset( (char *)&sock, '\0', sizeof(sock) );
375 #ifdef HAVE_SOCK_SIN_LEN
376 sock.sin_len = sizeof(sock);
378 sock.sin_port = htons( port );
379 sock.sin_family = AF_INET;
380 sock.sin_addr.s_addr = socket_addr;
382 res = socket( AF_INET, type, 0 );
384 DEBUG(0,("open_socket_in(): socket() call failed: %s\n", strerror(errno)));
388 /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */
390 int val = rebind ? 1 : 0;
391 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val));
393 setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val));
397 /* now we've got a socket - we need to bind it */
398 if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) {
399 DEBUG(0,("bind failed on port %d - %s\n", port, strerror(errno)));
404 DEBUG( 10, ( "bind succeeded on port %d\n", port ) );
410 /****************************************************************************
411 create an outgoing socket. timeout is in milliseconds.
412 **************************************************************************/
413 int open_socket_out(int type, struct in_addr *addr, int port, int timeout)
415 struct sockaddr_in sock_out;
417 int connect_loop = 250; /* 250 milliseconds */
418 int loops = (timeout) / connect_loop;
420 /* create a socket to write to */
421 res = socket(PF_INET, type, 0);
423 { DEBUG(0,("socket error\n")); return -1; }
425 if (type != SOCK_STREAM) return(res);
427 memset((char *)&sock_out,'\0',sizeof(sock_out));
428 putip((char *)&sock_out.sin_addr,(char *)addr);
430 sock_out.sin_port = htons( port );
431 sock_out.sin_family = PF_INET;
433 /* set it non-blocking */
434 set_blocking(res,False);
436 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
438 /* and connect it to the destination */
440 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
442 /* Some systems return EAGAIN when they mean EINPROGRESS */
443 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
444 errno == EAGAIN) && loops--) {
445 msleep(connect_loop);
449 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
451 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
457 if (ret < 0 && errno == EISCONN) {
464 DEBUG(2,("error connecting to %s:%d (%s)\n",
465 inet_ntoa(*addr),port,strerror(errno)));
470 /* set it blocking again */
471 set_blocking(res,True);
477 open a connected UDP socket to host on port
479 int open_udp_socket(const char *host, int port)
481 int type = SOCK_DGRAM;
482 struct sockaddr_in sock_out;
484 struct in_addr *addr;
487 mem_ctx = talloc_init("open_udp_socket");
491 addr = interpret_addr2(mem_ctx, host);
493 res = socket(PF_INET, type, 0);
498 memset((char *)&sock_out,'\0',sizeof(sock_out));
499 putip((char *)&sock_out.sin_addr,(char *)addr);
500 sock_out.sin_port = htons(port);
501 sock_out.sin_family = PF_INET;
503 talloc_destroy(mem_ctx);
505 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
514 /*******************************************************************
515 matchname - determine if host name matches IP address. Used to
516 confirm a hostname lookup to prevent spoof attacks
517 ******************************************************************/
518 static BOOL matchname(char *remotehost, struct in_addr addr)
523 if ((hp = sys_gethostbyname(remotehost)) == 0) {
524 DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", remotehost));
529 * Make sure that gethostbyname() returns the "correct" host name.
530 * Unfortunately, gethostbyname("localhost") sometimes yields
531 * "localhost.domain". Since the latter host name comes from the
532 * local DNS, we just have to trust it (all bets are off if the local
533 * DNS is perverted). We always check the address list, though.
536 if (strcasecmp(remotehost, hp->h_name)
537 && strcasecmp(remotehost, "localhost")) {
538 DEBUG(0,("host name/name mismatch: %s != %s\n",
539 remotehost, hp->h_name));
543 /* Look up the host address in the address list we just got. */
544 for (i = 0; hp->h_addr_list[i]; i++) {
545 if (memcmp(hp->h_addr_list[i], (char *) & addr, sizeof(addr)) == 0)
550 * The host name does not map to the original host address. Perhaps
551 * someone has compromised a name server. More likely someone botched
552 * it, but that could be dangerous, too.
555 DEBUG(0,("host name/address mismatch: %s != %s\n",
556 inet_ntoa(addr), hp->h_name));
561 /*******************************************************************
562 return the DNS name of the remote end of a socket
563 ******************************************************************/
564 char *get_socket_name(TALLOC_CTX *mem_ctx, int fd, BOOL force_lookup)
571 /* reverse lookups can be *very* expensive, and in many
572 situations won't work because many networks don't link dhcp
573 with dns. To avoid the delay we avoid the lookup if
575 if (!lp_hostname_lookups() && (force_lookup == False)) {
576 return get_socket_addr(mem_ctx, fd);
579 p = get_socket_addr(mem_ctx, fd);
581 name_buf = talloc_strdup(mem_ctx, "UNKNOWN");
582 if (fd == -1) return name_buf;
584 addr = *interpret_addr2(mem_ctx, p);
586 /* Look up the remote host name. */
587 if ((hp = gethostbyaddr((char *)&addr.s_addr, sizeof(addr.s_addr), AF_INET)) == 0) {
588 DEBUG(1,("Gethostbyaddr failed for %s\n",p));
589 name_buf = talloc_strdup(mem_ctx, p);
591 name_buf = talloc_strdup(mem_ctx, (char *)hp->h_name);
592 if (!matchname(name_buf, addr)) {
593 DEBUG(0,("Matchname failed on %s %s\n",name_buf,p));
594 name_buf = talloc_strdup(mem_ctx, "UNKNOWN");
598 alpha_strcpy(name_buf, name_buf, "_-.", strlen(name_buf)+1);
599 if (strstr(name_buf,"..")) {
600 name_buf = talloc_strdup(mem_ctx, "UNKNOWN");
606 /*******************************************************************
607 return the IP addr of the remote end of a socket as a string
608 ******************************************************************/
609 char *get_socket_addr(TALLOC_CTX *mem_ctx, int fd)
612 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
613 int length = sizeof(sa);
615 if (fd == -1 || getpeername(fd, &sa, &length) == -1) {
616 return talloc_strdup(mem_ctx, "0.0.0.0");
619 return talloc_strdup(mem_ctx, (char *)inet_ntoa(sockin->sin_addr));
624 /*******************************************************************
625 this is like socketpair but uses tcp. It is used by the Samba
627 The function guarantees that nobody else can attach to the socket,
628 or if they do that this function fails and the socket gets closed
629 returns 0 on success, -1 on failure
630 the resulting file descriptors are symmetrical
631 ******************************************************************/
632 static int socketpair_tcp(int fd[2])
635 struct sockaddr_in sock;
636 struct sockaddr_in sock2;
637 socklen_t socklen = sizeof(sock);
638 int connect_done = 0;
640 fd[0] = fd[1] = listener = -1;
642 memset(&sock, 0, sizeof(sock));
644 if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
646 memset(&sock2, 0, sizeof(sock2));
647 #ifdef HAVE_SOCK_SIN_LEN
648 sock2.sin_len = sizeof(sock2);
650 sock2.sin_family = PF_INET;
652 bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
654 if (listen(listener, 1) != 0) goto failed;
656 if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
658 if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
660 set_blocking(fd[1], 0);
662 sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
664 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
665 if (errno != EINPROGRESS) goto failed;
670 if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
673 if (connect_done == 0) {
674 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
675 && errno != EISCONN) goto failed;
678 set_blocking(fd[1], 1);
684 if (fd[0] != -1) close(fd[0]);
685 if (fd[1] != -1) close(fd[1]);
686 if (listener != -1) close(listener);
691 /*******************************************************************
692 run a program on a local tcp socket, this is used to launch smbd
693 when regression testing
694 the return value is a socket which is attached to a subprocess
695 running "prog". stdin and stdout are attached. stderr is left
696 attached to the original stderr
697 ******************************************************************/
698 int sock_exec(const char *prog)
701 if (socketpair_tcp(fd) != 0) {
702 DEBUG(0,("socketpair_tcp failed (%s)\n", strerror(errno)));
719 determine if a packet is pending for receive on a socket
721 BOOL socket_pending(int fd)
725 struct timeval timeout;
730 /* immediate timeout */
734 /* yes, this is supposed to be a normal select not a sys_select() */
735 selrtn = select(fd+1,&fds,NULL,NULL,&timeout);
738 /* the fd is readable */