A couple of coding syle updates to follow the re-indent.
[ira/wip.git] / source3 / lib / util_sock.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0.
4    Samba utility functions
5    Copyright (C) Andrew Tridgell 1992-1998
6    Copyright (C) Tim Potter      2000-2001
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24
25 #ifdef WITH_SSL
26 #include <openssl/ssl.h>
27 #undef Realloc  /* SSLeay defines this and samba has a function of this name */
28 extern SSL  *ssl;
29 extern int  sslFd;
30 #endif  /* WITH_SSL */
31
32 /* the last IP received from */
33 struct in_addr lastip;
34
35 /* the last port received from */
36 int lastport=0;
37
38 int smb_read_error = 0;
39
40 /****************************************************************************
41  Determine if a file descriptor is in fact a socket.
42 ****************************************************************************/
43
44 BOOL is_a_socket(int fd)
45 {
46   int v,l;
47   l = sizeof(int);
48   return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
49 }
50
51 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
52
53 typedef struct smb_socket_option
54 {
55   char *name;
56   int level;
57   int option;
58   int value;
59   int opttype;
60 } smb_socket_option;
61
62 smb_socket_option socket_options[] = {
63   {"SO_KEEPALIVE",      SOL_SOCKET,    SO_KEEPALIVE,    0,                 OPT_BOOL},
64   {"SO_REUSEADDR",      SOL_SOCKET,    SO_REUSEADDR,    0,                 OPT_BOOL},
65   {"SO_BROADCAST",      SOL_SOCKET,    SO_BROADCAST,    0,                 OPT_BOOL},
66 #ifdef TCP_NODELAY
67   {"TCP_NODELAY",       IPPROTO_TCP,   TCP_NODELAY,     0,                 OPT_BOOL},
68 #endif
69 #ifdef IPTOS_LOWDELAY
70   {"IPTOS_LOWDELAY",    IPPROTO_IP,    IP_TOS,          IPTOS_LOWDELAY,    OPT_ON},
71 #endif
72 #ifdef IPTOS_THROUGHPUT
73   {"IPTOS_THROUGHPUT",  IPPROTO_IP,    IP_TOS,          IPTOS_THROUGHPUT,  OPT_ON},
74 #endif
75 #ifdef SO_REUSEPORT
76   {"SO_REUSEPORT",      SOL_SOCKET,    SO_REUSEPORT,    0,                 OPT_BOOL},
77 #endif
78 #ifdef SO_SNDBUF
79   {"SO_SNDBUF",         SOL_SOCKET,    SO_SNDBUF,       0,                 OPT_INT},
80 #endif
81 #ifdef SO_RCVBUF
82   {"SO_RCVBUF",         SOL_SOCKET,    SO_RCVBUF,       0,                 OPT_INT},
83 #endif
84 #ifdef SO_SNDLOWAT
85   {"SO_SNDLOWAT",       SOL_SOCKET,    SO_SNDLOWAT,     0,                 OPT_INT},
86 #endif
87 #ifdef SO_RCVLOWAT
88   {"SO_RCVLOWAT",       SOL_SOCKET,    SO_RCVLOWAT,     0,                 OPT_INT},
89 #endif
90 #ifdef SO_SNDTIMEO
91   {"SO_SNDTIMEO",       SOL_SOCKET,    SO_SNDTIMEO,     0,                 OPT_INT},
92 #endif
93 #ifdef SO_RCVTIMEO
94   {"SO_RCVTIMEO",       SOL_SOCKET,    SO_RCVTIMEO,     0,                 OPT_INT},
95 #endif
96   {NULL,0,0,0,0}};
97
98 /****************************************************************************
99  Print socket options.
100 ****************************************************************************/
101 static void print_socket_options(int s)
102 {
103         int value, vlen = 4;
104         smb_socket_option *p = &socket_options[0];
105
106         for (; p->name != NULL; p++) {
107                 if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) {
108                         DEBUG(5,("Could not test socket option %s.\n", p->name));
109                 } else {
110                         DEBUG(5,("socket option %s = %d\n",p->name,value));
111                 }
112         }
113  }
114
115 /****************************************************************************
116  Set user socket options.
117 ****************************************************************************/
118
119 void set_socket_options(int fd, char *options)
120 {
121         fstring tok;
122
123         while (next_token(&options,tok," \t,", sizeof(tok))) {
124                 int ret=0,i;
125                 int value = 1;
126                 char *p;
127                 BOOL got_value = False;
128
129                 if ((p = strchr_m(tok,'='))) {
130                         *p = 0;
131                         value = atoi(p+1);
132                         got_value = True;
133                 }
134
135                 for (i=0;socket_options[i].name;i++)
136                         if (strequal(socket_options[i].name,tok))
137                                 break;
138
139                 if (!socket_options[i].name) {
140                         DEBUG(0,("Unknown socket option %s\n",tok));
141                         continue;
142                 }
143
144                 switch (socket_options[i].opttype) {
145                 case OPT_BOOL:
146                 case OPT_INT:
147                         ret = setsockopt(fd,socket_options[i].level,
148                                                 socket_options[i].option,(char *)&value,sizeof(int));
149                         break;
150
151                 case OPT_ON:
152                         if (got_value)
153                                 DEBUG(0,("syntax error - %s does not take a value\n",tok));
154
155                         {
156                                 int on = socket_options[i].value;
157                                 ret = setsockopt(fd,socket_options[i].level,
158                                                         socket_options[i].option,(char *)&on,sizeof(int));
159                         }
160                         break;    
161                 }
162       
163                 if (ret != 0)
164                         DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) ));
165         }
166
167         print_socket_options(fd);
168 }
169
170 /****************************************************************************
171  Read from a socket.
172 ****************************************************************************/
173
174 ssize_t read_udp_socket(int fd,char *buf,size_t len)
175 {
176         ssize_t ret;
177         struct sockaddr_in sock;
178         socklen_t socklen = sizeof(sock);
179
180         memset((char *)&sock,'\0',socklen);
181         memset((char *)&lastip,'\0',sizeof(lastip));
182         ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
183         if (ret <= 0) {
184                 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
185                 return(0);
186         }
187
188         lastip = sock.sin_addr;
189         lastport = ntohs(sock.sin_port);
190
191         DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
192                         inet_ntoa(lastip), lastport, ret));
193
194         return(ret);
195 }
196
197 /****************************************************************************
198  Read data from a socket with a timout in msec.
199  mincount = if timeout, minimum to read before returning
200  maxcount = number to be read.
201  time_out = timeout in milliseconds
202 ****************************************************************************/
203
204 static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
205 {
206         fd_set fds;
207         int selrtn;
208         ssize_t readret;
209         size_t nread = 0;
210         struct timeval timeout;
211         
212         /* just checking .... */
213         if (maxcnt <= 0)
214                 return(0);
215         
216         smb_read_error = 0;
217         
218         /* Blocking read */
219         if (time_out <= 0) {
220                 if (mincnt == 0) mincnt = maxcnt;
221                 
222                 while (nread < mincnt) {
223 #ifdef WITH_SSL
224                         if (fd == sslFd) {
225                                 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
226                         } else {
227                                 readret = read(fd, buf + nread, maxcnt - nread);
228                         }
229 #else /* WITH_SSL */
230                         readret = read(fd, buf + nread, maxcnt - nread);
231 #endif /* WITH_SSL */
232                         
233                         if (readret == 0) {
234                                 DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
235                                 smb_read_error = READ_EOF;
236                                 return -1;
237                         }
238                         
239                         if (readret == -1) {
240                                 DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) ));
241                                 smb_read_error = READ_ERROR;
242                                 return -1;
243                         }
244                         nread += readret;
245                 }
246                 return((ssize_t)nread);
247         }
248         
249         /* Most difficult - timeout read */
250         /* If this is ever called on a disk file and 
251            mincnt is greater then the filesize then
252            system performance will suffer severely as 
253            select always returns true on disk files */
254         
255         /* Set initial timeout */
256         timeout.tv_sec = (time_t)(time_out / 1000);
257         timeout.tv_usec = (long)(1000 * (time_out % 1000));
258         
259         for (nread=0; nread < mincnt; ) {      
260                 FD_ZERO(&fds);
261                 FD_SET(fd,&fds);
262                 
263                 selrtn = sys_select_intr(fd+1,&fds,&timeout);
264                 
265                 /* Check if error */
266                 if (selrtn == -1) {
267                         /* something is wrong. Maybe the socket is dead? */
268                         DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) ));
269                         smb_read_error = READ_ERROR;
270                         return -1;
271                 }
272                 
273                 /* Did we timeout ? */
274                 if (selrtn == 0) {
275                         DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n"));
276                         smb_read_error = READ_TIMEOUT;
277                         return -1;
278                 }
279                 
280 #ifdef WITH_SSL
281                 if (fd == sslFd) {
282                         readret = SSL_read(ssl, buf + nread, maxcnt - nread);
283                 }else{
284                         readret = read(fd, buf + nread, maxcnt - nread);
285                 }
286 #else /* WITH_SSL */
287                 readret = read(fd, buf+nread, maxcnt-nread);
288 #endif /* WITH_SSL */
289                 
290                 if (readret == 0) {
291                         /* we got EOF on the file descriptor */
292                         DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n"));
293                         smb_read_error = READ_EOF;
294                         return -1;
295                 }
296                 
297                 if (readret == -1) {
298                         /* the descriptor is probably dead */
299                         DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) ));
300                         smb_read_error = READ_ERROR;
301                         return -1;
302                 }
303                 
304                 nread += readret;
305         }
306         
307         /* Return the number we got */
308         return (ssize_t)nread;
309 }
310
311 /****************************************************************************
312  Read data from a fd with a timout in msec.
313  mincount = if timeout, minimum to read before returning
314  maxcount = number to be read.
315  time_out = timeout in milliseconds
316 ****************************************************************************/
317
318 ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
319 {
320         fd_set fds;
321         int selrtn;
322         ssize_t readret;
323         size_t nread = 0;
324         struct timeval timeout;
325         
326         /* just checking .... */
327         if (maxcnt <= 0)
328                 return(0);
329         
330         /* Blocking read */
331         if (time_out <= 0) {
332                 if (mincnt == 0) mincnt = maxcnt;
333                 
334                 while (nread < mincnt) {
335 #ifdef WITH_SSL
336                         if(fd == sslFd){
337                                 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
338                         }else{
339                                 readret = read(fd, buf + nread, maxcnt - nread);
340                         }
341 #else /* WITH_SSL */
342                         readret = read(fd, buf + nread, maxcnt - nread);
343 #endif /* WITH_SSL */
344                         
345                         if (readret <= 0)
346                                 return readret;
347                         
348                         nread += readret;
349                 }
350                 return((ssize_t)nread);
351         }
352         
353         /* Most difficult - timeout read */
354         /* If this is ever called on a disk file and 
355            mincnt is greater then the filesize then
356            system performance will suffer severely as 
357            select always returns true on disk files */
358         
359         /* Set initial timeout */
360         timeout.tv_sec = (time_t)(time_out / 1000);
361         timeout.tv_usec = (long)(1000 * (time_out % 1000));
362         
363         for (nread=0; nread < mincnt; ) {      
364                 FD_ZERO(&fds);
365                 FD_SET(fd,&fds);
366                 
367                 selrtn = sys_select_intr(fd+1,&fds,&timeout);
368                 
369                 if(selrtn <= 0)
370                         return selrtn;
371                 
372 #ifdef WITH_SSL
373                 if(fd == sslFd){
374                         readret = SSL_read(ssl, buf + nread, maxcnt - nread);
375                 }else{
376                         readret = read(fd, buf + nread, maxcnt - nread);
377                 }
378 #else /* WITH_SSL */
379                 readret = read(fd, buf+nread, maxcnt-nread);
380 #endif /* WITH_SSL */
381                 
382                 if (readret <= 0)
383                         return readret;
384                 
385                 nread += readret;
386         }
387         
388         /* Return the number we got */
389         return((ssize_t)nread);
390 }
391
392 /****************************************************************************
393 send a keepalive packet (rfc1002)
394 ****************************************************************************/
395
396 BOOL send_keepalive(int client)
397 {
398   unsigned char buf[4];
399
400   buf[0] = SMBkeepalive;
401   buf[1] = buf[2] = buf[3] = 0;
402
403   return(write_socket_data(client,(char *)buf,4) == 4);
404 }
405
406 /****************************************************************************
407   read data from the client, reading exactly N bytes. 
408 ****************************************************************************/
409
410 ssize_t read_data(int fd,char *buffer,size_t N)
411 {
412   ssize_t  ret;
413   size_t total=0;  
414  
415   smb_read_error = 0;
416
417   while (total < N)
418   {
419 #ifdef WITH_SSL
420     if(fd == sslFd){
421       ret = SSL_read(ssl, buffer + total, N - total);
422     }else{
423       ret = read(fd,buffer + total,N - total);
424     }
425 #else /* WITH_SSL */
426     ret = read(fd,buffer + total,N - total);
427 #endif /* WITH_SSL */
428
429     if (ret == 0)
430     {
431       DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
432       smb_read_error = READ_EOF;
433       return 0;
434     }
435     if (ret == -1)
436     {
437       DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
438       smb_read_error = READ_ERROR;
439       return -1;
440     }
441     total += ret;
442   }
443   return (ssize_t)total;
444 }
445
446 /****************************************************************************
447  Read data from a socket, reading exactly N bytes. 
448 ****************************************************************************/
449
450 static ssize_t read_socket_data(int fd,char *buffer,size_t N)
451 {
452   ssize_t  ret;
453   size_t total=0;  
454  
455   smb_read_error = 0;
456
457   while (total < N)
458   {
459 #ifdef WITH_SSL
460     if(fd == sslFd){
461       ret = SSL_read(ssl, buffer + total, N - total);
462     }else{
463       ret = read(fd,buffer + total,N - total);
464     }
465 #else /* WITH_SSL */
466     ret = read(fd,buffer + total,N - total);
467 #endif /* WITH_SSL */
468
469     if (ret == 0)
470     {
471       DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
472       smb_read_error = READ_EOF;
473       return 0;
474     }
475     if (ret == -1)
476     {
477       DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
478       smb_read_error = READ_ERROR;
479       return -1;
480     }
481     total += ret;
482   }
483   return (ssize_t)total;
484 }
485
486 /****************************************************************************
487  Write data to a fd.
488 ****************************************************************************/
489
490 ssize_t write_data(int fd,char *buffer,size_t N)
491 {
492   size_t total=0;
493   ssize_t ret;
494
495   while (total < N)
496   {
497 #ifdef WITH_SSL
498     if(fd == sslFd){
499       ret = SSL_write(ssl,buffer + total,N - total);
500     }else{
501       ret = write(fd,buffer + total,N - total);
502     }
503 #else /* WITH_SSL */
504     ret = write(fd,buffer + total,N - total);
505 #endif /* WITH_SSL */
506
507     if (ret == -1) {
508       DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
509       return -1;
510     }
511     if (ret == 0) return total;
512
513     total += ret;
514   }
515   return (ssize_t)total;
516 }
517
518 /****************************************************************************
519  Write data to a socket - use send rather than write.
520 ****************************************************************************/
521
522 ssize_t write_socket_data(int fd,char *buffer,size_t N)
523 {
524   size_t total=0;
525   ssize_t ret;
526
527   while (total < N)
528   {
529 #ifdef WITH_SSL
530     if(fd == sslFd){
531       ret = SSL_write(ssl,buffer + total,N - total);
532     }else{
533       ret = send(fd,buffer + total,N - total, 0);
534     }
535 #else /* WITH_SSL */
536     ret = send(fd,buffer + total,N - total,0);
537 #endif /* WITH_SSL */
538
539     if (ret == -1) {
540       DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno) ));
541       return -1;
542     }
543     if (ret == 0) return total;
544
545     total += ret;
546   }
547   return (ssize_t)total;
548 }
549
550 /****************************************************************************
551 write to a socket
552 ****************************************************************************/
553
554 ssize_t write_socket(int fd,char *buf,size_t len)
555 {
556   ssize_t ret=0;
557
558   DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len));
559   ret = write_socket_data(fd,buf,len);
560       
561   DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret));
562   if(ret <= 0)
563     DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", 
564        (int)len, fd, strerror(errno) ));
565
566   return(ret);
567 }
568
569 /****************************************************************************
570 read 4 bytes of a smb packet and return the smb length of the packet
571 store the result in the buffer
572 This version of the function will return a length of zero on receiving
573 a keepalive packet.
574 timeout is in milliseconds.
575 ****************************************************************************/
576
577 static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
578 {
579   ssize_t len=0;
580   int msg_type;
581   BOOL ok = False;
582
583   while (!ok)
584   {
585     if (timeout > 0)
586       ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) == 4);
587     else 
588       ok = (read_socket_data(fd,inbuf,4) == 4);
589
590     if (!ok)
591       return(-1);
592
593     len = smb_len(inbuf);
594     msg_type = CVAL(inbuf,0);
595
596     if (msg_type == SMBkeepalive) 
597       DEBUG(5,("Got keepalive packet\n"));
598   }
599
600   DEBUG(10,("got smb length of %d\n",len));
601
602   return(len);
603 }
604
605 /****************************************************************************
606 read 4 bytes of a smb packet and return the smb length of the packet
607 store the result in the buffer. This version of the function will
608 never return a session keepalive (length of zero).
609 timeout is in milliseconds.
610 ****************************************************************************/
611
612 ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
613 {
614   ssize_t len;
615
616   for(;;)
617   {
618     len = read_smb_length_return_keepalive(fd, inbuf, timeout);
619
620     if(len < 0)
621       return len;
622
623     /* Ignore session keepalives. */
624     if(CVAL(inbuf,0) != SMBkeepalive)
625       break;
626   }
627
628   DEBUG(10,("read_smb_length: got smb length of %d\n",len));
629
630   return len;
631 }
632
633 /****************************************************************************
634   read an smb from a fd. Note that the buffer *MUST* be of size
635   BUFFER_SIZE+SAFETY_MARGIN.
636   The timeout is in milliseconds. 
637   This function will return on a
638   receipt of a session keepalive packet.
639 ****************************************************************************/
640
641 BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
642 {
643         ssize_t len,ret;
644
645         smb_read_error = 0;
646
647         memset(buffer,'\0',smb_size + 100);
648
649         len = read_smb_length_return_keepalive(fd,buffer,timeout);
650         if (len < 0) {
651                 DEBUG(10,("receive_smb: length < 0!\n"));
652                 return(False);
653         }
654
655         /*
656          * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
657      * of header. Don't print the error if this fits.... JRA.
658          */
659
660         if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
661                 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
662                 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) {
663                         smb_read_error = READ_ERROR;
664                         return False;
665                 }
666         }
667
668         if(len > 0) {
669                 ret = read_socket_data(fd,buffer+4,len);
670                 if (ret != len) {
671                         smb_read_error = READ_ERROR;
672                         return False;
673                 }
674         }
675
676         return(True);
677 }
678
679 /****************************************************************************
680   read an smb from a fd ignoring all keepalive packets. Note that the buffer 
681   *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
682   The timeout is in milliseconds
683
684   This is exactly the same as receive_smb except that it never returns
685   a session keepalive packet (just as receive_smb used to do).
686   receive_smb was changed to return keepalives as the oplock processing means this call
687   should never go into a blocking read.
688 ****************************************************************************/
689
690 BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
691 {
692   BOOL ret;
693
694   for(;;)
695   {
696     ret = receive_smb(fd, buffer, timeout);
697
698     if (!ret)
699     {
700       DEBUG(10,("client_receive_smb failed\n"));
701       show_msg(buffer);
702       return ret;
703     }
704
705     /* Ignore session keepalive packets. */
706     if(CVAL(buffer,0) != SMBkeepalive)
707       break;
708   }
709   show_msg(buffer);
710   return ret;
711 }
712
713 /****************************************************************************
714   send an smb to a fd 
715 ****************************************************************************/
716
717 BOOL send_smb(int fd,char *buffer)
718 {
719         size_t len;
720         size_t nwritten=0;
721         ssize_t ret;
722         len = smb_len(buffer) + 4;
723
724         while (nwritten < len) {
725                 ret = write_socket(fd,buffer+nwritten,len - nwritten);
726                 if (ret <= 0) {
727                         DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
728                                 (int)len,(int)ret, strerror(errno) ));
729                         return False;
730                 }
731                 nwritten += ret;
732         }
733
734         return True;
735 }
736
737 /****************************************************************************
738 send a single packet to a port on another machine
739 ****************************************************************************/
740
741 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
742 {
743   BOOL ret;
744   int out_fd;
745   struct sockaddr_in sock_out;
746
747   /* create a socket to write to */
748   out_fd = socket(AF_INET, type, 0);
749   if (out_fd == -1) 
750     {
751       DEBUG(0,("socket failed"));
752       return False;
753     }
754
755   /* set the address and port */
756   memset((char *)&sock_out,'\0',sizeof(sock_out));
757   putip((char *)&sock_out.sin_addr,(char *)&ip);
758   sock_out.sin_port = htons( port );
759   sock_out.sin_family = AF_INET;
760   
761   if (DEBUGLEVEL > 0)
762     DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
763              len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
764         
765   /* send it */
766   ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
767
768   if (!ret)
769     DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
770              inet_ntoa(ip),port,strerror(errno)));
771
772   close(out_fd);
773   return(ret);
774 }
775
776 /****************************************************************************
777  Open a socket of the specified type, port, and address for incoming data.
778 ****************************************************************************/
779
780 int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL rebind )
781 {
782         struct sockaddr_in sock;
783         int res;
784
785         memset( (char *)&sock, '\0', sizeof(sock) );
786
787 #ifdef HAVE_SOCK_SIN_LEN
788         sock.sin_len         = sizeof(sock);
789 #endif
790         sock.sin_port        = htons( port );
791         sock.sin_family      = AF_INET;
792         sock.sin_addr.s_addr = socket_addr;
793
794         res = socket( AF_INET, type, 0 );
795         if( res == -1 ) {
796                 if( DEBUGLVL(0) ) {
797                         dbgtext( "open_socket_in(): socket() call failed: " );
798                         dbgtext( "%s\n", strerror( errno ) );
799                 }
800                 return -1;
801         }
802
803         /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */
804         {
805                 int val = rebind ? 1 : 0;
806                 if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1 ) {
807                         if( DEBUGLVL( dlevel ) ) {
808                                 dbgtext( "open_socket_in(): setsockopt: " );
809                                 dbgtext( "SO_REUSEADDR = %s ", val?"True":"False" );
810                                 dbgtext( "on port %d failed ", port );
811                                 dbgtext( "with error = %s\n", strerror(errno) );
812                         }
813                 }
814 #ifdef SO_REUSEPORT
815                 if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1 ) {
816                         if( DEBUGLVL( dlevel ) ) {
817                                 dbgtext( "open_socket_in(): setsockopt: ");
818                                 dbgtext( "SO_REUSEPORT = %s ", val?"True":"False" );
819                                 dbgtext( "on port %d failed ", port );
820                                 dbgtext( "with error = %s\n", strerror(errno) );
821                         }
822                 }
823 #endif /* SO_REUSEPORT */
824         }
825
826         /* now we've got a socket - we need to bind it */
827         if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) {
828                 if( DEBUGLVL(dlevel) && (port == SMB_PORT || port == NMB_PORT) ) {
829                         dbgtext( "bind failed on port %d ", port );
830                         dbgtext( "socket_addr = %s.\n", inet_ntoa( sock.sin_addr ) );
831                         dbgtext( "Error = %s\n", strerror(errno) );
832                 }
833                 close( res ); 
834                 return( -1 ); 
835         }
836
837         DEBUG( 3, ( "bind succeeded on port %d\n", port ) );
838
839         return( res );
840  }
841
842 /****************************************************************************
843   create an outgoing socket. timeout is in milliseconds.
844   **************************************************************************/
845
846 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
847 {
848   struct sockaddr_in sock_out;
849   int res,ret;
850   int connect_loop = 250; /* 250 milliseconds */
851   int loops = (timeout) / connect_loop;
852
853   /* create a socket to write to */
854   res = socket(PF_INET, type, 0);
855   if (res == -1) 
856     { DEBUG(0,("socket error\n")); return -1; }
857
858   if (type != SOCK_STREAM) return(res);
859   
860   memset((char *)&sock_out,'\0',sizeof(sock_out));
861   putip((char *)&sock_out.sin_addr,(char *)addr);
862   
863   sock_out.sin_port = htons( port );
864   sock_out.sin_family = PF_INET;
865
866   /* set it non-blocking */
867   set_blocking(res,False);
868
869   DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
870   
871   /* and connect it to the destination */
872 connect_again:
873   ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
874
875   /* Some systems return EAGAIN when they mean EINPROGRESS */
876   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
877         errno == EAGAIN) && loops--) {
878     msleep(connect_loop);
879     goto connect_again;
880   }
881
882   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
883          errno == EAGAIN)) {
884       DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
885       close(res);
886       return -1;
887   }
888
889 #ifdef EISCONN
890   if (ret < 0 && errno == EISCONN) {
891     errno = 0;
892     ret = 0;
893   }
894 #endif
895
896   if (ret < 0) {
897     DEBUG(2,("error connecting to %s:%d (%s)\n",
898              inet_ntoa(*addr),port,strerror(errno)));
899     close(res);
900     return -1;
901   }
902
903   /* set it blocking again */
904   set_blocking(res,True);
905
906   return res;
907 }
908
909 /*
910   open a connected UDP socket to host on port
911 */
912 int open_udp_socket(const char *host, int port)
913 {
914         int type = SOCK_DGRAM;
915         struct sockaddr_in sock_out;
916         int res;
917         struct in_addr *addr;
918
919         addr = interpret_addr2(host);
920
921         res = socket(PF_INET, type, 0);
922         if (res == -1) {
923                 return -1;
924         }
925
926         memset((char *)&sock_out,'\0',sizeof(sock_out));
927         putip((char *)&sock_out.sin_addr,(char *)addr);
928         sock_out.sin_port = htons(port);
929         sock_out.sin_family = PF_INET;
930
931         if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
932                 close(res);
933                 return -1;
934         }
935
936         return res;
937 }
938
939
940 /* the following 3 client_*() functions are nasty ways of allowing
941    some generic functions to get info that really should be hidden in
942    particular modules */
943 static int client_fd = -1;
944
945 void client_setfd(int fd)
946 {
947         client_fd = fd;
948 }
949
950 char *client_name(void)
951 {
952         return get_socket_name(client_fd);
953 }
954
955 char *client_addr(void)
956 {
957         return get_socket_addr(client_fd);
958 }
959
960 /*******************************************************************
961  matchname - determine if host name matches IP address. Used to
962  confirm a hostname lookup to prevent spoof attacks
963  ******************************************************************/
964 static BOOL matchname(char *remotehost,struct in_addr  addr)
965 {
966         struct hostent *hp;
967         int     i;
968         
969         if ((hp = sys_gethostbyname(remotehost)) == 0) {
970                 DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", remotehost));
971                 return False;
972         } 
973
974         /*
975          * Make sure that gethostbyname() returns the "correct" host name.
976          * Unfortunately, gethostbyname("localhost") sometimes yields
977          * "localhost.domain". Since the latter host name comes from the
978          * local DNS, we just have to trust it (all bets are off if the local
979          * DNS is perverted). We always check the address list, though.
980          */
981         
982         if (strcasecmp(remotehost, hp->h_name)
983             && strcasecmp(remotehost, "localhost")) {
984                 DEBUG(0,("host name/name mismatch: %s != %s\n",
985                          remotehost, hp->h_name));
986                 return False;
987         }
988         
989         /* Look up the host address in the address list we just got. */
990         for (i = 0; hp->h_addr_list[i]; i++) {
991                 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
992                         return True;
993         }
994         
995         /*
996          * The host name does not map to the original host address. Perhaps
997          * someone has compromised a name server. More likely someone botched
998          * it, but that could be dangerous, too.
999          */
1000         
1001         DEBUG(0,("host name/address mismatch: %s != %s\n",
1002                  inet_ntoa(addr), hp->h_name));
1003         return False;
1004 }
1005
1006  
1007 /*******************************************************************
1008  return the DNS name of the remote end of a socket
1009  ******************************************************************/
1010 char *get_socket_name(int fd)
1011 {
1012         static pstring name_buf;
1013         static fstring addr_buf;
1014         struct hostent *hp;
1015         struct in_addr addr;
1016         char *p;
1017
1018         /* reverse lookups can be *very* expensive, and in many
1019            situations won't work because many networks don't link dhcp
1020            with dns. To avoid the delay we avoid the lookup if
1021            possible */
1022         if (!lp_hostname_lookups()) {
1023                 return get_socket_addr(fd);
1024         }
1025         
1026         p = get_socket_addr(fd);
1027
1028         /* it might be the same as the last one - save some DNS work */
1029         if (strcmp(p, addr_buf) == 0) return name_buf;
1030
1031         pstrcpy(name_buf,"UNKNOWN");
1032         if (fd == -1) return name_buf;
1033
1034         fstrcpy(addr_buf, p);
1035
1036         addr = *interpret_addr2(p);
1037         
1038         /* Look up the remote host name. */
1039         if ((hp = gethostbyaddr((char *)&addr.s_addr, sizeof(addr.s_addr), AF_INET)) == 0) {
1040                 DEBUG(1,("Gethostbyaddr failed for %s\n",p));
1041                 pstrcpy(name_buf, p);
1042         } else {
1043                 pstrcpy(name_buf,(char *)hp->h_name);
1044                 if (!matchname(name_buf, addr)) {
1045                         DEBUG(0,("Matchname failed on %s %s\n",name_buf,p));
1046                         pstrcpy(name_buf,"UNKNOWN");
1047                 }
1048         }
1049
1050         alpha_strcpy(name_buf, name_buf, "_-.", sizeof(name_buf));
1051         if (strstr(name_buf,"..")) {
1052                 pstrcpy(name_buf, "UNKNOWN");
1053         }
1054
1055         return name_buf;
1056 }
1057
1058 /*******************************************************************
1059  return the IP addr of the remote end of a socket as a string 
1060  ******************************************************************/
1061 char *get_socket_addr(int fd)
1062 {
1063         struct sockaddr sa;
1064         struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
1065         int     length = sizeof(sa);
1066         static fstring addr_buf;
1067
1068         fstrcpy(addr_buf,"0.0.0.0");
1069
1070         if (fd == -1) {
1071                 return addr_buf;
1072         }
1073         
1074         if (getpeername(fd, &sa, &length) < 0) {
1075                 DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));
1076                 return addr_buf;
1077         }
1078         
1079         fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
1080         
1081         return addr_buf;
1082 }
1083
1084 /*******************************************************************
1085  opens and connects to a unix pipe socket
1086  ******************************************************************/
1087 int open_pipe_sock(char *path)
1088 {
1089         int sock;
1090         struct sockaddr_un sa;
1091
1092         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1093
1094         if (sock < 0)
1095         {
1096                 DEBUG(0, ("unix socket open failed\n"));
1097                 return sock;
1098         }
1099
1100         ZERO_STRUCT(sa);
1101         sa.sun_family = AF_UNIX;
1102         safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
1103
1104         DEBUG(10, ("socket open succeeded.  file name: %s\n", sa.sun_path));
1105
1106         if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0)
1107         {
1108                 DEBUG(0,("socket connect to %s failed\n", sa.sun_path));
1109                 close(sock);
1110                 return -1;
1111         }
1112
1113         return sock;
1114 }
1115
1116 /*******************************************************************
1117  Create protected unix domain socket.
1118
1119  some unixen cannot set permissions on a ux-dom-sock, so we
1120  have to make sure that the directory contains the protection
1121  permissions, instead.
1122  ******************************************************************/
1123 int create_pipe_sock(const char *socket_dir,
1124                                         const char *socket_name,
1125                                         mode_t dir_perms)
1126 {
1127         struct sockaddr_un sunaddr;
1128         struct stat st;
1129         int sock;
1130         mode_t old_umask;
1131         pstring path;
1132         
1133         /* Create the socket directory or reuse the existing one */
1134         
1135         if (lstat(socket_dir, &st) == -1) {
1136                 
1137                 if (errno == ENOENT) {
1138                         
1139                         /* Create directory */
1140                         
1141                         if (mkdir(socket_dir, dir_perms) == -1) {
1142                                 DEBUG(0, ("error creating socket directory "
1143                                           "%s: %s\n", socket_dir, 
1144                                           strerror(errno)));
1145                                 return -1;
1146                         }
1147                         
1148                 } else {
1149                         
1150                         DEBUG(0, ("lstat failed on socket directory %s: %s\n",
1151                                   socket_dir, strerror(errno)));
1152                         return -1;
1153                 }
1154                 
1155         } else {
1156                 
1157                 /* Check ownership and permission on existing directory */
1158                 
1159                 if (!S_ISDIR(st.st_mode)) {
1160                         DEBUG(0, ("socket directory %s isn't a directory\n",
1161                                   socket_dir));
1162                         return -1;
1163                 }
1164                 
1165                 if ((st.st_uid != sec_initial_uid()) || 
1166                     ((st.st_mode & 0777) != dir_perms)) {
1167                         DEBUG(0, ("invalid permissions on socket directory "
1168                                   "%s\n", socket_dir));
1169                         return -1;
1170                 }
1171         }
1172         
1173         /* Create the socket file */
1174         
1175         old_umask = umask(0);
1176         
1177         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1178         
1179         if (sock == -1) {
1180                 perror("socket");
1181                 umask(old_umask);
1182                 return -1;
1183         }
1184         
1185         snprintf(path, sizeof(path), "%s/%s", socket_dir, socket_name);
1186         
1187         unlink(path);
1188         memset(&sunaddr, 0, sizeof(sunaddr));
1189         sunaddr.sun_family = AF_UNIX;
1190         safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1);
1191         
1192         if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
1193                 DEBUG(0, ("bind failed on pipe socket %s: %s\n",
1194                           path,
1195                           strerror(errno)));
1196                 close(sock);
1197                 umask(old_umask);
1198                 return -1;
1199         }
1200         
1201         if (listen(sock, 5) == -1) {
1202                 DEBUG(0, ("listen failed on pipe socket %s: %s\n",
1203                           path,
1204                           strerror(errno)));
1205                 close(sock);
1206                 umask(old_umask);
1207                 return -1;
1208         }
1209         
1210         umask(old_umask);
1211         
1212         /* Success! */
1213         
1214         return sock;
1215 }
1216
1217 /*******************************************************************
1218 this is like socketpair but uses tcp. It is used by the Samba
1219 regression test code
1220 The function guarantees that nobody else can attach to the socket,
1221 or if they do that this function fails and the socket gets closed
1222 returns 0 on success, -1 on failure
1223 the resulting file descriptors are symmetrical
1224  ******************************************************************/
1225 static int socketpair_tcp(int fd[2])
1226 {
1227         int listener;
1228         struct sockaddr_in sock;
1229         struct sockaddr_in sock2;
1230         socklen_t socklen = sizeof(sock);
1231         int connect_done = 0;
1232         
1233         fd[0] = fd[1] = listener = -1;
1234
1235         memset(&sock, 0, sizeof(sock));
1236         
1237         if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
1238
1239         memset(&sock2, 0, sizeof(sock2));
1240 #ifdef HAVE_SOCK_SIN_LEN
1241         sock2.sin_len = sizeof(sock2);
1242 #endif
1243         sock2.sin_family = PF_INET;
1244
1245         bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
1246
1247         if (listen(listener, 1) != 0) goto failed;
1248
1249         if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
1250
1251         if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
1252
1253         set_blocking(fd[1], 0);
1254
1255         sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1256
1257         if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
1258                 if (errno != EINPROGRESS) goto failed;
1259         } else {
1260                 connect_done = 1;
1261         }
1262
1263         if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
1264
1265         close(listener);
1266         if (connect_done == 0) {
1267                 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
1268                     && errno != EISCONN) goto failed;
1269         }
1270
1271         set_blocking(fd[1], 1);
1272
1273         /* all OK! */
1274         return 0;
1275
1276  failed:
1277         if (fd[0] != -1) close(fd[0]);
1278         if (fd[1] != -1) close(fd[1]);
1279         if (listener != -1) close(listener);
1280         return -1;
1281 }
1282
1283
1284 /*******************************************************************
1285 run a program on a local tcp socket, this is used to launch smbd
1286 when regression testing
1287 the return value is a socket which is attached to a subprocess
1288 running "prog". stdin and stdout are attached. stderr is left
1289 attached to the original stderr
1290  ******************************************************************/
1291 int sock_exec(const char *prog)
1292 {
1293         int fd[2];
1294         if (socketpair_tcp(fd) != 0) {
1295                 DEBUG(0,("socketpair_tcp failed (%s)\n", strerror(errno)));
1296                 return -1;
1297         }
1298         if (fork() == 0) {
1299                 close(fd[0]);
1300                 close(0);
1301                 close(1);
1302                 dup(fd[1]);
1303                 dup(fd[1]);
1304                 exit(system(prog));
1305         }
1306         close(fd[1]);
1307         return fd[0];
1308 }