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;
57 /****************************************************************************
59 ****************************************************************************/
64 DEBUG(0,("Got SIGTERM: going down...\n"));
67 reload_services(True);
69 /* remove all samba names, with wins server if necessary. */
72 /* XXXX don't care if we never receive a response back... yet */
73 /* XXXX other things: if we are a master browser, force an election? */
79 /****************************************************************************
81 ****************************************************************************/
82 static int sig_hup(void)
86 DEBUG(0,("Got SIGHUP (reload not implemented)\n"));
88 reload_services(True);
91 #ifndef DONT_REINSTALL_SIG
92 signal(SIGHUP,SIGNAL_CAST sig_hup);
97 /****************************************************************************
99 ****************************************************************************/
100 static int sig_pipe(void)
104 DEBUG(0,("Got SIGPIPE\n"));
112 /*******************************************************************
113 prepare to dump a core file - carefully!
114 ********************************************************************/
115 static BOOL dump_core(void)
119 strcpy(dname,debugf);
120 if ((p=strrchr(dname,'/'))) *p=0;
121 strcat(dname,"/corefiles");
123 sys_chown(dname,getuid(),getgid());
125 if (chdir(dname)) return(False);
132 getrlimit(RLIMIT_CORE, &rlp);
133 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
134 setrlimit(RLIMIT_CORE, &rlp);
135 getrlimit(RLIMIT_CORE, &rlp);
136 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
142 DEBUG(0,("Dumping core in %s\n",dname));
148 /****************************************************************************
149 possibly continue after a fault
150 ****************************************************************************/
151 static void fault_continue(void)
158 /*******************************************************************
159 expire old names from the namelist and server list
160 ******************************************************************/
161 static void expire_names_and_servers(void)
163 static time_t lastrun = 0;
164 time_t t = time(NULL);
166 if (!lastrun) lastrun = t;
167 if (t < lastrun + 5) return;
174 /*****************************************************************************
175 reload the services file
176 **************************************************************************/
177 BOOL reload_services(BOOL test)
180 extern fstring remote_machine;
182 strcpy(remote_machine,"nmbd");
187 strcpy(fname,lp_configfile());
188 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
190 strcpy(servicesf,fname);
195 if (test && !lp_file_list_changed())
198 ret = lp_load(servicesf,True);
200 /* perhaps the config filename is now set */
202 DEBUG(3,("services not loaded\n"));
203 reload_services(True);
213 /****************************************************************************
214 load a netbios hosts file
215 ****************************************************************************/
216 static void load_hosts_file(char *fname)
218 FILE *f = fopen(fname,"r");
221 DEBUG(2,("Can't open lmhosts file %s\n",fname));
227 if (!fgets_slash(line,sizeof(pstring),f)) continue;
229 if (*line == '#') continue;
234 pstring ip,name,mask,flags,extra;
238 struct in_addr ipaddr;
239 struct in_addr ipmask;
240 enum name_source source = LMHOSTS;
250 if (next_token(&ptr,ip ,NULL)) ++count;
251 if (next_token(&ptr,name ,NULL)) ++count;
252 if (next_token(&ptr,mask ,NULL)) ++count;
253 if (next_token(&ptr,flags,NULL)) ++count;
254 if (next_token(&ptr,extra,NULL)) ++count;
256 if (count <= 0) continue;
258 if (count > 0 && count < 2) {
259 DEBUG(0,("Ill formed hosts line [%s]\n",line));
263 /* work out if we need to shuffle the tokens along due to the
264 optional subnet mask argument */
266 if (strchr(mask, 'G') || strchr(mask, 'S') || strchr(mask, 'M')) {
267 strcpy(flags, mask );
268 /* default action for no subnet mask */
272 DEBUG(4, ("lmhost entry: %s %s %s %s\n", ip, name, mask, flags));
274 if (strchr(flags,'G') || strchr(flags,'S'))
277 if (strchr(flags,'M') && !group) {
282 ipaddr = *interpret_addr2(ip);
284 ipmask = *interpret_addr2(mask);
286 ipmask = *iface_nmask(ipaddr);
289 add_subnet_entry(ipaddr, ipmask, name, True);
291 add_netbios_entry(name,0x20,NB_ACTIVE,0,source,ipaddr,True);
300 /****************************************************************************
301 The main select loop.
302 ***************************************************************************/
303 static void process(void)
309 time_t t = time(NULL);
310 run_election = check_elections();
311 listen_for_packets(run_election);
319 /* what was this stuff supposed to do? It sent
320 ANN_GetBackupListReq packets which I think should only be
321 sent when trying to find out who to browse with */
327 expire_names_and_servers();
328 expire_netbios_response_entries(t-10);
333 check_master_browser();
338 /****************************************************************************
339 open the socket communication
340 ****************************************************************************/
341 static BOOL open_sockets(BOOL isdaemon, int port)
346 if ((hp = Get_Hostbyname(myhostname)) == 0) {
347 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
352 ClientNMB = open_socket_in(SOCK_DGRAM, port,0);
356 ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3);
361 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
363 set_socket_options(ClientNMB,"SO_BROADCAST");
364 set_socket_options(ClientDGRAM,"SO_BROADCAST");
366 DEBUG(3,("Sockets opened.\n"));
371 /****************************************************************************
372 initialise connect, service and file structs
373 ****************************************************************************/
374 static BOOL init_structs()
376 if (!get_myname(myhostname,NULL))
381 strcpy(myname,myhostname);
382 p = strchr(myname,'.');
389 /****************************************************************************
391 ****************************************************************************/
392 static void usage(char *pname)
394 DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
396 printf("Usage: %s [-n name] [-B bcast address] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
397 printf("Version %s\n",VERSION);
398 printf("\t-D become a daemon\n");
399 printf("\t-p port listen on the specified port\n");
400 printf("\t-d debuglevel set the debuglevel\n");
401 printf("\t-l log basename. Basename for log/debug files\n");
402 printf("\t-n netbiosname. the netbios name to advertise for this host\n");
403 printf("\t-B broadcast address the address to use for broadcasts\n");
404 printf("\t-N netmask the netmask to use for subnet determination\n");
405 printf("\t-H hosts file load a netbios hosts file\n");
406 printf("\t-G group name add a group name to be part of\n");
407 printf("\t-I ip-address override the IP address\n");
408 printf("\t-C comment sets the machine comment that appears in browse lists\n");
413 /****************************************************************************
415 **************************************************************************/
416 int main(int argc,char *argv[])
427 StartupTime = time(NULL);
431 strcpy(debugf,NMBLOGFILE);
433 setup_logging(argv[0],False);
435 charset_initialise();
438 strcpy(host_file,LMHOSTSFILE);
441 /* this is for people who can't start the program correctly */
442 while (argc > 1 && (*argv[1] != '-')) {
447 fault_setup(fault_continue);
449 signal(SIGHUP,SIGNAL_CAST sig_hup);
450 signal(SIGTERM,SIGNAL_CAST sig_term);
452 while ((opt = getopt(argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF)
457 strcpy(servicesf,optarg);
460 strcpy(ServerComment,optarg);
463 strcpy(group,optarg);
466 strcpy(host_file,optarg);
469 iface_set_default(optarg,NULL,NULL);
472 iface_set_default(NULL,optarg,NULL);
475 iface_set_default(NULL,NULL,optarg);
478 strcpy(myname,optarg);
481 sprintf(debugf,"%s.nmb",optarg);
484 strcpy(scope,optarg);
491 DEBUGLEVEL = atoi(optarg);
501 if (!is_a_socket(0)) {
508 DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
509 DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
513 if (!reload_services(False))
517 add_my_domains(group);
519 if (!is_daemon && !is_a_socket(0)) {
520 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
525 DEBUG(2,("%s becoming a daemon\n",timestring()));
529 DEBUG(3,("Opening sockets %d\n", port));
531 if (!open_sockets(is_daemon,port)) return 1;
534 load_hosts_file(host_file);
535 DEBUG(3,("Loaded hosts file\n"));
539 strcpy(ServerComment,"Samba %v");
540 string_sub(ServerComment,"%v",VERSION);
541 string_sub(ServerComment,"%h",myhostname);
544 add_my_domains(lp_workgroup());
546 DEBUG(3,("Checked names\n"));
550 DEBUG(3,("Dumped names\n"));