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 = 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);
183 /****************************************************************************
185 ****************************************************************************/
187 static BOOL timeout_until(struct timeval *timeout,
188 const struct timeval *endtime)
194 if ((now.tv_sec > endtime->tv_sec) ||
195 ((now.tv_sec == endtime->tv_sec) &&
196 (now.tv_usec > endtime->tv_usec)))
199 timeout->tv_sec = endtime->tv_sec - now.tv_sec;
200 timeout->tv_usec = endtime->tv_usec - now.tv_usec;
205 /****************************************************************************
206 Read data from the client, reading exactly N bytes, with timeout.
207 ****************************************************************************/
209 ssize_t read_data_until(int fd,char *buffer,size_t N,
210 const struct timeval *endtime)
217 if (endtime != NULL) {
219 struct timeval timeout;
225 if (!timeout_until(&timeout, endtime))
228 res = sys_select(fd+1, &r_fds, NULL, NULL, &timeout);
233 ret = sys_read(fd,buffer + total,N - total);
236 DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
241 DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
246 return (ssize_t)total;
249 /****************************************************************************
250 Write data to a fd with timeout.
251 ****************************************************************************/
253 ssize_t write_data_until(int fd,char *buffer,size_t N,
254 const struct timeval *endtime)
261 if (endtime != NULL) {
263 struct timeval timeout;
269 if (!timeout_until(&timeout, endtime))
272 res = sys_select(fd+1, NULL, &w_fds, NULL, &timeout);
277 ret = sys_write(fd,buffer + total,N - total);
280 DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
288 return (ssize_t)total;
292 /****************************************************************************
293 Open a socket of the specified type, port, and address for incoming data.
294 ****************************************************************************/
295 int open_socket_in( int type, int port, int dlevel, uint32_t socket_addr, BOOL rebind )
297 struct sockaddr_in sock;
300 memset( (char *)&sock, '\0', sizeof(sock) );
302 #ifdef HAVE_SOCK_SIN_LEN
303 sock.sin_len = sizeof(sock);
305 sock.sin_port = htons( port );
306 sock.sin_family = AF_INET;
307 sock.sin_addr.s_addr = socket_addr;
309 res = socket( AF_INET, type, 0 );
311 DEBUG(0,("open_socket_in(): socket() call failed: %s\n", strerror(errno)));
315 /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */
317 int val = rebind ? 1 : 0;
318 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val));
320 setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val));
324 /* now we've got a socket - we need to bind it */
325 if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) {
326 DEBUG(0,("bind failed on port %d - %s\n", port, strerror(errno)));
331 DEBUG( 10, ( "bind succeeded on port %d\n", port ) );
337 /****************************************************************************
338 create an outgoing socket. timeout is in milliseconds.
339 **************************************************************************/
340 int open_socket_out(int type, struct in_addr *addr, int port, int timeout)
342 struct sockaddr_in sock_out;
344 int connect_loop = 250; /* 250 milliseconds */
345 int loops = (timeout) / connect_loop;
347 /* create a socket to write to */
348 res = socket(PF_INET, type, 0);
350 { DEBUG(0,("socket error\n")); return -1; }
352 if (type != SOCK_STREAM) return(res);
354 memset((char *)&sock_out,'\0',sizeof(sock_out));
355 putip((char *)&sock_out.sin_addr,(char *)addr);
357 sock_out.sin_port = htons( port );
358 sock_out.sin_family = PF_INET;
360 /* set it non-blocking */
361 set_blocking(res,False);
363 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
365 /* and connect it to the destination */
367 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
369 /* Some systems return EAGAIN when they mean EINPROGRESS */
370 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
371 errno == EAGAIN) && loops--) {
372 msleep(connect_loop);
376 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
378 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
384 if (ret < 0 && errno == EISCONN) {
391 DEBUG(2,("error connecting to %s:%d (%s)\n",
392 inet_ntoa(*addr),port,strerror(errno)));
397 /* set it blocking again */
398 set_blocking(res,True);
404 open a connected UDP socket to host on port
406 int open_udp_socket(const char *host, int port)
408 int type = SOCK_DGRAM;
409 struct sockaddr_in sock_out;
414 mem_ctx = talloc_init("open_udp_socket");
418 addr = interpret_addr2(host);
420 res = socket(PF_INET, type, 0);
425 memset((char *)&sock_out,'\0',sizeof(sock_out));
426 putip((char *)&sock_out.sin_addr,(char *)&addr);
427 sock_out.sin_port = htons(port);
428 sock_out.sin_family = PF_INET;
430 talloc_destroy(mem_ctx);
432 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
441 /*******************************************************************
442 matchname - determine if host name matches IP address. Used to
443 confirm a hostname lookup to prevent spoof attacks
444 ******************************************************************/
445 static BOOL matchname(char *remotehost, struct in_addr addr)
450 if ((hp = sys_gethostbyname(remotehost)) == 0) {
451 DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", remotehost));
456 * Make sure that gethostbyname() returns the "correct" host name.
457 * Unfortunately, gethostbyname("localhost") sometimes yields
458 * "localhost.domain". Since the latter host name comes from the
459 * local DNS, we just have to trust it (all bets are off if the local
460 * DNS is perverted). We always check the address list, though.
463 if (strcasecmp(remotehost, hp->h_name)
464 && strcasecmp(remotehost, "localhost")) {
465 DEBUG(0,("host name/name mismatch: %s != %s\n",
466 remotehost, hp->h_name));
470 /* Look up the host address in the address list we just got. */
471 for (i = 0; hp->h_addr_list[i]; i++) {
472 if (memcmp(hp->h_addr_list[i], (char *) & addr, sizeof(addr)) == 0)
477 * The host name does not map to the original host address. Perhaps
478 * someone has compromised a name server. More likely someone botched
479 * it, but that could be dangerous, too.
482 DEBUG(0,("host name/address mismatch: %s != %s\n",
483 inet_ntoa(addr), hp->h_name));
488 /*******************************************************************
489 return the DNS name of the remote end of a socket
490 ******************************************************************/
491 char *get_socket_name(TALLOC_CTX *mem_ctx, int fd, BOOL force_lookup)
498 /* reverse lookups can be *very* expensive, and in many
499 situations won't work because many networks don't link dhcp
500 with dns. To avoid the delay we avoid the lookup if
502 if (!lp_hostname_lookups() && (force_lookup == False)) {
503 return get_socket_addr(mem_ctx, fd);
506 p = get_socket_addr(mem_ctx, fd);
508 name_buf = talloc_strdup(mem_ctx, "UNKNOWN");
509 if (fd == -1) return name_buf;
511 addr = interpret_addr2(p);
513 /* Look up the remote host name. */
514 if ((hp = gethostbyaddr((char *)&addr.s_addr, sizeof(addr.s_addr), AF_INET)) == 0) {
515 DEBUG(1,("Gethostbyaddr failed for %s\n",p));
516 name_buf = talloc_strdup(mem_ctx, p);
518 name_buf = talloc_strdup(mem_ctx, (char *)hp->h_name);
519 if (!matchname(name_buf, addr)) {
520 DEBUG(0,("Matchname failed on %s %s\n",name_buf,p));
521 name_buf = talloc_strdup(mem_ctx, "UNKNOWN");
525 alpha_strcpy(name_buf, name_buf, "_-.", strlen(name_buf)+1);
526 if (strstr(name_buf,"..")) {
527 name_buf = talloc_strdup(mem_ctx, "UNKNOWN");
533 /*******************************************************************
534 return the IP addr of the remote end of a socket as a string
535 ******************************************************************/
536 char *get_socket_addr(TALLOC_CTX *mem_ctx, int fd)
539 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
540 int length = sizeof(sa);
542 if (fd == -1 || getpeername(fd, &sa, &length) == -1) {
543 return talloc_strdup(mem_ctx, "0.0.0.0");
546 return talloc_strdup(mem_ctx, (char *)inet_ntoa(sockin->sin_addr));
551 /*******************************************************************
552 this is like socketpair but uses tcp. It is used by the Samba
554 The function guarantees that nobody else can attach to the socket,
555 or if they do that this function fails and the socket gets closed
556 returns 0 on success, -1 on failure
557 the resulting file descriptors are symmetrical
558 ******************************************************************/
559 static int socketpair_tcp(int fd[2])
562 struct sockaddr_in sock;
563 struct sockaddr_in sock2;
564 socklen_t socklen = sizeof(sock);
565 int connect_done = 0;
567 fd[0] = fd[1] = listener = -1;
569 memset(&sock, 0, sizeof(sock));
571 if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
573 memset(&sock2, 0, sizeof(sock2));
574 #ifdef HAVE_SOCK_SIN_LEN
575 sock2.sin_len = sizeof(sock2);
577 sock2.sin_family = PF_INET;
579 bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
581 if (listen(listener, 1) != 0) goto failed;
583 if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
585 if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
587 set_blocking(fd[1], 0);
589 sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
591 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
592 if (errno != EINPROGRESS) goto failed;
597 if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
600 if (connect_done == 0) {
601 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
602 && errno != EISCONN) goto failed;
605 set_blocking(fd[1], 1);
611 if (fd[0] != -1) close(fd[0]);
612 if (fd[1] != -1) close(fd[1]);
613 if (listener != -1) close(listener);
618 /*******************************************************************
619 run a program on a local tcp socket, this is used to launch smbd
620 when regression testing
621 the return value is a socket which is attached to a subprocess
622 running "prog". stdin and stdout are attached. stderr is left
623 attached to the original stderr
624 ******************************************************************/
625 int sock_exec(const char *prog)
628 if (socketpair_tcp(fd) != 0) {
629 DEBUG(0,("socketpair_tcp failed (%s)\n", strerror(errno)));
646 determine if a packet is pending for receive on a socket
648 BOOL socket_pending(int fd)
652 struct timeval timeout;
657 /* immediate timeout */
661 /* yes, this is supposed to be a normal select not a sys_select() */
662 selrtn = select(fd+1,&fds,NULL,NULL,&timeout);
665 /* the fd is readable */