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