2 Unix SMB/Netbios implementation.
4 NBT netbios routines and daemon - version 2
5 Copyright (C) Andrew Tridgell 1994-1995
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.
23 14 jan 96: lkcl@pires.co.uk
24 added multiple workgroup domain master support
30 extern int DEBUGLEVEL
;
32 extern pstring debugf
;
33 pstring servicesf
= CONFIGFILE
;
40 extern pstring myhostname
;
41 static pstring host_file
;
42 extern pstring myname
;
44 /* are we running as a daemon ? */
45 static BOOL is_daemon
= False
;
47 /* machine comment for host announcements */
48 pstring ServerComment
="";
50 /* what server type are we currently */
52 time_t StartupTime
=0;
54 extern struct in_addr ipzero
;
56 /****************************************************************************
58 ****************************************************************************/
63 DEBUG(0,("Got SIGTERM: going down...\n"));
65 /* write out wins.dat file if samba is a WINS server */
68 /* remove all samba names, with wins server if necessary. */
71 /* announce all server entries as 0 time-to-live, 0 type */
72 /* XXXX don't care if we never receive a response back... yet */
75 /* XXXX other things: if we are a master browser, force an election? */
81 /****************************************************************************
83 ****************************************************************************/
84 static int sig_hup(void)
88 DEBUG(0,("Got SIGHUP (reload not implemented)\n"));
90 reload_services(True
);
95 #ifndef DONT_REINSTALL_SIG
96 signal(SIGHUP
,SIGNAL_CAST sig_hup
);
101 /****************************************************************************
103 ****************************************************************************/
104 static int sig_pipe(void)
108 DEBUG(0,("Got SIGPIPE\n"));
116 /*******************************************************************
117 prepare to dump a core file - carefully!
118 ********************************************************************/
119 static BOOL
dump_core(void)
123 strcpy(dname
,debugf
);
124 if ((p
=strrchr(dname
,'/'))) *p
=0;
125 strcat(dname
,"/corefiles");
127 sys_chown(dname
,getuid(),getgid());
129 if (chdir(dname
)) return(False
);
136 getrlimit(RLIMIT_CORE
, &rlp
);
137 rlp
.rlim_cur
= MAX(4*1024*1024,rlp
.rlim_cur
);
138 setrlimit(RLIMIT_CORE
, &rlp
);
139 getrlimit(RLIMIT_CORE
, &rlp
);
140 DEBUG(3,("Core limits now %d %d\n",rlp
.rlim_cur
,rlp
.rlim_max
));
146 DEBUG(0,("Dumping core in %s\n",dname
));
152 /****************************************************************************
153 possibly continue after a fault
154 ****************************************************************************/
155 static void fault_continue(void)
162 /*******************************************************************
163 expire old names from the namelist and server list
164 ******************************************************************/
165 static void expire_names_and_servers(void)
167 static time_t lastrun
= 0;
168 time_t t
= time(NULL
);
170 if (!lastrun
) lastrun
= t
;
171 if (t
< lastrun
+ 5) return;
178 /*****************************************************************************
179 reload the services file
180 **************************************************************************/
181 BOOL
reload_services(BOOL test
)
184 extern fstring remote_machine
;
186 strcpy(remote_machine
,"nmbd");
191 strcpy(fname
,lp_configfile());
192 if (file_exist(fname
,NULL
) && !strcsequal(fname
,servicesf
))
194 strcpy(servicesf
,fname
);
199 if (test
&& !lp_file_list_changed())
202 ret
= lp_load(servicesf
,True
);
204 /* perhaps the config filename is now set */
206 DEBUG(3,("services not loaded\n"));
207 reload_services(True
);
211 add_subnet_interfaces();
218 /****************************************************************************
219 load a netbios hosts file
220 ****************************************************************************/
221 static void load_hosts_file(char *fname
)
223 FILE *f
= fopen(fname
,"r");
226 DEBUG(2,("Can't open lmhosts file %s\n",fname
));
232 if (!fgets_slash(line
,sizeof(pstring
),f
)) continue;
234 if (*line
== '#') continue;
239 pstring ip
,name
,mask
,flags
,extra
;
243 struct in_addr ipaddr
;
244 struct in_addr ipmask
;
245 enum name_source source
= LMHOSTS
;
255 if (next_token(&ptr
,ip
,NULL
)) ++count
;
256 if (next_token(&ptr
,name
,NULL
)) ++count
;
257 if (next_token(&ptr
,mask
,NULL
)) ++count
;
258 if (next_token(&ptr
,flags
,NULL
)) ++count
;
259 if (next_token(&ptr
,extra
,NULL
)) ++count
;
261 if (count
<= 0) continue;
263 if (count
> 0 && count
< 2) {
264 DEBUG(0,("Ill formed hosts line [%s]\n",line
));
268 /* work out if we need to shuffle the tokens along due to the
269 optional subnet mask argument */
271 if (strchr(mask
, 'G') || strchr(mask
, 'S') || strchr(mask
, 'M')) {
272 strcpy(flags
, mask
);
273 /* default action for no subnet mask */
277 DEBUG(4, ("lmhost entry: %s %s %s %s\n", ip
, name
, mask
, flags
));
279 if (strchr(flags
,'G') || strchr(flags
,'S'))
282 if (strchr(flags
,'M') && !group
) {
287 ipaddr
= *interpret_addr2(ip
);
289 ipmask
= *interpret_addr2(mask
);
291 ipmask
= *iface_nmask(ipaddr
);
294 add_subnet_entry(ipaddr
, ipmask
, name
, True
, True
);
296 struct subnet_record
*d
= find_subnet(ipaddr
);
299 add_netbios_entry(d
,name
,0x20,NB_ACTIVE
,0,source
,ipaddr
,True
,True
);
309 /****************************************************************************
310 The main select loop.
311 ***************************************************************************/
312 static void process(void)
318 time_t t
= time(NULL
);
319 run_election
= check_elections();
320 listen_for_packets(run_election
);
328 /* XXXX what was this stuff supposed to do? It sent
329 ANN_GetBackupListReq packets which I think should only be
330 sent when trying to find out who to browse with */
337 query_refresh_names();
339 expire_names_and_servers();
340 expire_netbios_response_entries();
345 check_master_browser();
350 /****************************************************************************
351 open the socket communication
352 ****************************************************************************/
353 static BOOL
open_sockets(BOOL isdaemon
, int port
)
358 if ((hp
= Get_Hostbyname(myhostname
)) == 0) {
359 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname
));
364 ClientNMB
= open_socket_in(SOCK_DGRAM
, port
,0);
368 ClientDGRAM
= open_socket_in(SOCK_DGRAM
,DGRAM_PORT
,3);
373 signal(SIGPIPE
, SIGNAL_CAST sig_pipe
);
375 set_socket_options(ClientNMB
,"SO_BROADCAST");
376 set_socket_options(ClientDGRAM
,"SO_BROADCAST");
378 DEBUG(3,("Sockets opened.\n"));
383 /****************************************************************************
384 initialise connect, service and file structs
385 ****************************************************************************/
386 static BOOL
init_structs()
388 if (!get_myname(myhostname
,NULL
))
393 strcpy(myname
,myhostname
);
394 p
= strchr(myname
,'.');
401 /****************************************************************************
403 ****************************************************************************/
404 static void usage(char *pname
)
406 DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
408 printf("Usage: %s [-n name] [-B bcast address] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname
);
409 printf("Version %s\n",VERSION
);
410 printf("\t-D become a daemon\n");
411 printf("\t-p port listen on the specified port\n");
412 printf("\t-d debuglevel set the debuglevel\n");
413 printf("\t-l log basename. Basename for log/debug files\n");
414 printf("\t-n netbiosname. the netbios name to advertise for this host\n");
415 printf("\t-B broadcast address the address to use for broadcasts\n");
416 printf("\t-N netmask the netmask to use for subnet determination\n");
417 printf("\t-H hosts file load a netbios hosts file\n");
418 printf("\t-G group name add a group name to be part of\n");
419 printf("\t-I ip-address override the IP address\n");
420 printf("\t-C comment sets the machine comment that appears in browse lists\n");
425 /****************************************************************************
427 **************************************************************************/
428 int main(int argc
,char *argv
[])
439 StartupTime
= time(NULL
);
443 strcpy(debugf
,NMBLOGFILE
);
445 setup_logging(argv
[0],False
);
447 charset_initialise();
450 strcpy(host_file
,LMHOSTSFILE
);
453 /* this is for people who can't start the program correctly */
454 while (argc
> 1 && (*argv
[1] != '-')) {
459 fault_setup(fault_continue
);
461 signal(SIGHUP
,SIGNAL_CAST sig_hup
);
462 signal(SIGTERM
,SIGNAL_CAST sig_term
);
464 while ((opt
= getopt(argc
, argv
, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF
)
469 strcpy(servicesf
,optarg
);
472 strcpy(ServerComment
,optarg
);
475 strcpy(group
,optarg
);
478 strcpy(host_file
,optarg
);
481 iface_set_default(optarg
,NULL
,NULL
);
484 iface_set_default(NULL
,optarg
,NULL
);
487 iface_set_default(NULL
,NULL
,optarg
);
490 strcpy(myname
,optarg
);
493 sprintf(debugf
,"%s.nmb",optarg
);
496 strcpy(scope
,optarg
);
503 DEBUGLEVEL
= atoi(optarg
);
513 if (!is_a_socket(0)) {
520 DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION
));
521 DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
525 if (!reload_services(False
))
531 add_my_subnets(group
);
533 if (!is_daemon
&& !is_a_socket(0)) {
534 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
539 DEBUG(2,("%s becoming a daemon\n",timestring()));
543 DEBUG(3,("Opening sockets %d\n", port
));
545 if (!open_sockets(is_daemon
,port
)) return 1;
548 load_hosts_file(host_file
);
549 DEBUG(3,("Loaded hosts file\n"));
555 strcpy(ServerComment
,"Samba %v");
556 string_sub(ServerComment
,"%v",VERSION
);
557 string_sub(ServerComment
,"%h",myhostname
);
560 add_my_subnets(lp_workgroup());
562 DEBUG(3,("Checked names\n"));
564 load_netbios_names();
566 DEBUG(3,("Loaded names\n"));
570 DEBUG(3,("Dumped names\n"));