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.
28 static void queue_packet(struct packet_struct *packet);
30 static void dump_names(void);
31 static void announce_request(char *group);
32 void sync_browse_lists(char *name,int name_type,char *myname,
33 char *domain,struct in_addr ip);
35 extern int DEBUGLEVEL;
37 extern pstring debugf;
38 pstring servicesf = CONFIGFILE;
42 extern BOOL CanRecurse;
44 extern struct in_addr myip;
45 extern struct in_addr bcast_ip;
46 extern struct in_addr Netmask;
47 extern pstring myhostname;
48 static pstring host_file;
49 static pstring myname="";
51 static int ClientNMB= -1;
52 static int ClientDGRAM= -1;
54 static BOOL needannounce=True;
56 /* this is our name database */
57 static struct name_record *namelist = NULL;
59 /* list of servers to be returned by NetServerEnum */
60 static struct server_record *serverlist = NULL;
62 /* this is the domain list. For the moment we will assume that our
63 primary domain is the first one listed in this list */
64 static struct domain_record *domainlist = NULL;
66 /* are we running as a daemon ? */
67 static BOOL is_daemon = False;
69 /* machine comment for host announcements */
70 static pstring ServerComment="";
72 static BOOL got_bcast = False;
73 static BOOL got_myip = False;
74 static BOOL got_nmask = False;
76 static BOOL updatedlists = False;
77 static int updatecount=0;
79 /* what server type are we currently */
80 static int ServerType =
81 SV_TYPE_WORKSTATION | SV_TYPE_SERVER | SV_TYPE_TIME_SOURCE |
83 SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER;
85 /* here are my election parameters */
87 /* NTAS uses 2, NT uses 1, WfWg uses 0 */
88 #define MAINTAIN_LIST 1
89 #define ELECTION_VERSION 1
91 static BOOL RunningElection = False;
92 static BOOL needelection = False;
93 static int ElectionCount = 0;
94 static int StartupTime =0;
97 /* WfWg uses 01040b01 */
98 /* Win95 uses 01041501 */
100 static uint32 ElectionCriterion = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8);
102 /* we currently support being the master for just one group. Being the
103 master for more than one group might be tricky as NetServerEnum is
104 often asked for a list without naming the group */
105 static fstring PrimaryGroup="";
107 #define AM_MASTER (PrimaryGroup[0] && (ServerType & SV_TYPE_MASTER_BROWSER))
109 #define MSBROWSE "\001\002__MSBROWSE__\002"
111 #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
113 #define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
115 /****************************************************************************
117 ****************************************************************************/
122 DEBUG(0,("Got SIGHUP (reload not implemented)\n"));
124 reload_services(True);
127 #ifndef DONT_REINSTALL_SIG
128 signal(SIGHUP,SIGNAL_CAST sig_hup);
133 /****************************************************************************
135 ****************************************************************************/
136 static int sig_pipe()
140 DEBUG(0,("Got SIGPIPE\n"));
148 /*******************************************************************
149 prepare to dump a core file - carefully!
150 ********************************************************************/
151 static BOOL dump_core(void)
155 strcpy(dname,debugf);
156 if ((p=strrchr(dname,'/'))) *p=0;
157 strcat(dname,"/corefiles");
159 sys_chown(dname,getuid(),getgid());
161 if (chdir(dname)) return(False);
168 getrlimit(RLIMIT_CORE, &rlp);
169 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
170 setrlimit(RLIMIT_CORE, &rlp);
171 getrlimit(RLIMIT_CORE, &rlp);
172 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
178 DEBUG(0,("Dumping core in %s\n",dname));
184 /****************************************************************************
185 possibly continue after a fault
186 ****************************************************************************/
187 static void fault_continue(void)
189 static int errcount=1;
193 if (is_daemon && errcount)
197 if (dump_core()) return;
204 /*******************************************************************
205 wrapper to get the DC
206 ******************************************************************/
207 static char *domain_controller(void)
209 char *dc = lp_domain_controller();
210 /* so many people mistake this for a bool that we need to handle it. sigh. */
211 if (!*dc || strequal(dc,"yes") || strequal(dc,"true"))
218 /****************************************************************************
219 true if two netbios names are equal
220 ****************************************************************************/
221 static BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
223 if (n1->name_type != n2->name_type) return(False);
225 return(strequal(n1->name,n2->name) && strequal(n1->scope,n2->scope));
228 /****************************************************************************
229 add a netbios name into the namelist
230 **************************************************************************/
231 static void add_name(struct name_record *n)
233 struct name_record *n2;
242 for (n2 = namelist; n2->next; n2 = n2->next) ;
249 /****************************************************************************
250 add a domain into the list
251 **************************************************************************/
252 static void add_domain(struct domain_record *d)
254 struct domain_record *d2;
263 for (d2 = domainlist; d2->next; d2 = d2->next) ;
271 /****************************************************************************
272 add a server into the list
273 **************************************************************************/
274 static void add_server(struct server_record *s)
276 struct server_record *s2;
285 for (s2 = serverlist; s2->next; s2 = s2->next) ;
292 /****************************************************************************
293 remove a name from the namelist. The pointer must be an element just
295 **************************************************************************/
296 static void remove_name(struct name_record *n)
298 struct name_record *nlist = namelist;
299 while (nlist && nlist != n) nlist = nlist->next;
301 if (nlist->next) nlist->next->prev = nlist->prev;
302 if (nlist->prev) nlist->prev->next = nlist->next;
307 /****************************************************************************
308 find a name in the namelist
309 **************************************************************************/
310 static struct name_record *find_name(struct nmb_name *n)
312 struct name_record *ret;
313 for (ret = namelist; ret; ret = ret->next)
314 if (name_equal(&ret->name,n)) return(ret);
319 /****************************************************************************
320 dump a copy of the name table
321 **************************************************************************/
322 static void dump_names(void)
324 time_t t = time(NULL);
325 struct name_record *n;
326 struct domain_record *d;
328 DEBUG(3,("Dump of local name table:\n"));
330 for (n = namelist; n; n = n->next) {
331 DEBUG(3,("%s %s TTL=%d Unique=%s\n",
334 n->death_time?n->death_time-t:0,
335 BOOLSTR(n->unique)));
338 DEBUG(3,("\nDump of domain list:\n"));
339 for (d = domainlist; d; d = d->next)
340 DEBUG(3,("%s %s\n",d->name,inet_ntoa(d->bcast_ip)));
344 /****************************************************************************
345 add a host entry to the name list
346 ****************************************************************************/
347 static struct name_record *add_host_entry(char *name,int type,BOOL unique,int ttl,
348 enum name_source source,
351 struct name_record *n;
352 struct name_record *n2=NULL;
354 n = (struct name_record *)malloc(sizeof(*n));
355 if (!n) return(NULL);
357 bzero((char *)n,sizeof(*n));
359 make_nmb_name(&n->name,name,type,scope);
360 if ((n2=find_name(&n->name))) {
365 if (ttl) n->death_time = time(NULL)+ttl*3;
370 if (!n2) add_name(n);
372 DEBUG(3,("Added host entry %s at %s ttl=%d unique=%s\n",
373 namestr(&n->name),inet_ntoa(ip),ttl,BOOLSTR(unique)));
379 /****************************************************************************
381 ****************************************************************************/
382 static struct domain_record *add_domain_entry(char *name,struct in_addr ip)
384 struct domain_record *d;
386 d = (struct domain_record *)malloc(sizeof(*d));
388 if (!d) return(NULL);
390 bzero((char *)d,sizeof(*d));
392 if (zero_ip(ip)) ip = bcast_ip;
394 StrnCpy(d->name,name,sizeof(d->name)-1);
397 if (!PrimaryGroup[0] && ip_equal(bcast_ip,ip) && name[0] != '*') {
398 strcpy(PrimaryGroup,name);
399 strupper(PrimaryGroup);
400 DEBUG(3,("Setting primary group to %s (%s)\n",PrimaryGroup,inet_ntoa(ip)));
405 ip = *interpret_addr2("255.255.255.255");
406 if (name[0] != '*') add_host_entry(name,0x1e,False,0,SELF,ip);
408 DEBUG(3,("Added domain entry %s at %s\n",
409 name,inet_ntoa(ip)));
414 /****************************************************************************
416 ****************************************************************************/
417 struct server_record *add_server_entry(char *name,int servertype,
418 int ttl,char *comment,BOOL replace)
421 struct server_record *s;
423 for (s = serverlist; s; s = s->next)
424 if (strequal(name,s->name)) break;
427 DEBUG(4,("Not replacing %s\n",name));
435 s = (struct server_record *)malloc(sizeof(*s));
437 if (!s) return(NULL);
439 bzero((char *)s,sizeof(*s));
442 /* update the entry */
443 StrnCpy(s->name,name,sizeof(s->name)-1);
444 StrnCpy(s->comment,comment,sizeof(s->comment)-1);
445 s->servertype = servertype;
446 s->death_time = ttl?time(NULL)+ttl*3:0;
448 if (s->servertype & SV_TYPE_DOMAIN_ENUM) strupper(s->comment);
450 if (!newentry) return(s);
455 DEBUG(3,("Added server entry %s of type %x (%s)\n",
456 name,servertype,comment));
458 DEBUG(3,("Updated server entry %s of type %x (%s)\n",
459 name,servertype,comment));
466 /****************************************************************************
467 add the magic samba names, useful for finding samba servers
468 **************************************************************************/
469 static void add_my_names(void)
473 ip = *interpret_addr2("0.0.0.0");
475 add_host_entry(myname,0x20,True,0,SELF,ip);
476 add_host_entry(myname,0x0,True,0,SELF,ip);
477 add_host_entry(myname,0x1f,True,0,SELF,ip); /* used for chat?? */
478 add_host_entry(myname,0x3,True,0,SELF,ip); /* used for winpopup */
481 add_domain_entry(lp_workgroup(),bcast_ip);
482 add_server_entry(myname,
484 0,ServerComment,True);
486 add_host_entry("__SAMBA__",0x20,True,0,SELF,ip);
487 add_host_entry("__SAMBA__",0x0,True,0,SELF,ip);
489 if (lp_preferred_master()) {
490 DEBUG(3,("Preferred master startup\n"));
492 ElectionCriterion |= (1<<3);
495 ElectionCriterion |= (lp_os_level() << 24);
499 /*******************************************************************
501 ******************************************************************/
502 static void write_browse_list(void)
504 struct server_record *s;
505 pstring fname,fnamenew;
510 strcpy(fname,lp_lockdir());
511 trim_string(fname,NULL,"/");
513 strcat(fname,SERVER_LIST);
514 strcpy(fnamenew,fname);
515 strcat(fnamenew,".");
517 f = fopen(fnamenew,"w");
520 DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
524 for (s=serverlist; s ; s = s->next) {
525 /* don't list domains I don't have a master for */
526 if ((s->servertype & SV_TYPE_DOMAIN_ENUM) && !s->comment[0]) continue;
528 fprintf(f,"\"%s\"\t%08x\t\"%s\"\n",s->name,s->servertype,s->comment);
533 chmod(fnamenew,0644);
535 rename(fnamenew,fname);
536 DEBUG(3,("Wrote browse list %s\n",fname));
539 /*******************************************************************
540 expire old names in the namelist and serverlist
541 ******************************************************************/
542 static void expire_names(void)
544 static time_t lastrun=0;
545 time_t t = time(NULL);
546 struct name_record *n;
547 struct name_record *next;
548 struct server_record *s;
549 struct server_record *nexts;
551 if (!lastrun) lastrun = t;
552 if (t < lastrun + 5) return;
555 /* expire old names */
556 for (n = namelist; n; n = next) {
557 if (n->death_time && n->death_time < t) {
558 DEBUG(3,("Removing dead name %s\n",
561 if (n->prev) n->prev->next = n->next;
562 if (n->next) n->next->prev = n->prev;
563 if (namelist == n) namelist = n->next;
570 /* expire old entries in the serverlist */
571 for (s = serverlist; s; s = nexts) {
572 if (s->death_time && s->death_time < t) {
573 DEBUG(3,("Removing dead server %s\n",s->name));
576 if (s->prev) s->prev->next = s->next;
577 if (s->next) s->next->prev = s->prev;
578 if (serverlist == s) serverlist = s->next;
587 /*******************************************************************
588 delete old names from the namelist
589 ******************************************************************/
590 static void housekeeping(void)
592 time_t t = time(NULL);
596 /* write out the browse.dat database for smbd to get */
599 updatedlists = False;
603 /* occasionally check to see if the master browser is around */
604 static time_t lastrun=0;
605 if (!lastrun) lastrun = t;
606 if (t < lastrun + 5*60) return;
609 if (!AM_MASTER && PrimaryGroup[0] &&
610 !name_query(ClientNMB,PrimaryGroup,0x1d,True,False,
611 bcast_ip,NULL,queue_packet)) {
612 DEBUG(2,("Forcing election on %s\n",PrimaryGroup));
619 /****************************************************************************
620 reload the services file
621 **************************************************************************/
622 BOOL reload_services(BOOL test)
625 extern fstring remote_machine;
627 strcpy(remote_machine,"nmbd");
632 strcpy(fname,lp_configfile());
633 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
635 strcpy(servicesf,fname);
640 if (test && !lp_file_list_changed())
643 ret = lp_load(servicesf,True);
645 /* perhaps the config filename is now set */
647 reload_services(True);
654 /****************************************************************************
655 load a netbios hosts file
656 ****************************************************************************/
657 static void load_hosts_file(char *fname)
659 FILE *f = fopen(fname,"r");
662 DEBUG(2,("Can't open lmhosts file %s\n",fname));
668 if (!fgets_slash(line,sizeof(pstring),f)) continue;
670 if (*line == '#') continue;
674 string ip,name,flags,extra;
677 struct in_addr ipaddr;
678 enum name_source source = LMHOSTS;
680 *ip = *name = *flags = *extra = 0;
684 if (next_token(&ptr,ip,NULL)) ++count;
685 if (next_token(&ptr,name,NULL)) ++count;
686 if (next_token(&ptr,flags,NULL)) ++count;
687 if (next_token(&ptr,extra,NULL)) ++count;
689 if (count <= 0) continue;
691 if (count > 0 && count < 2)
693 DEBUG(0,("Ill formed hosts line [%s]\n",line));
697 if (strchr(flags,'G') || strchr(flags,'S'))
700 if (strchr(flags,'M') && !group) {
705 ipaddr = *interpret_addr2(ip);
708 add_domain_entry(name,ipaddr);
710 add_host_entry(name,0x20,True,0,source,ipaddr);
718 /*******************************************************************
719 check if 2 IPs are on the same net
720 we will assume the local netmask, although this could be wrong XXXX
721 ******************************************************************/
722 static BOOL same_net(struct in_addr ip1,struct in_addr ip2)
724 unsigned long net1,net2,nmask;
726 nmask = ntohl(Netmask.s_addr);
727 net1 = ntohl(ip1.s_addr);
728 net2 = ntohl(ip2.s_addr);
730 return((net1 & nmask) == (net2 & nmask));
733 /****************************************************************************
734 send an election packet
735 **************************************************************************/
736 static void send_election(char *group,uint32 criterion,int timeup,char *name)
741 DEBUG(2,("Sending election to %s for workgroup %s\n",
742 inet_ntoa(bcast_ip),group));
744 bzero(outbuf,sizeof(outbuf));
746 CVAL(p,0) = 8; /* election */
749 CVAL(p,0) = ELECTION_VERSION;
750 SIVAL(p,1,criterion);
751 SIVAL(p,5,timeup*1000); /* ms - despite the spec */
755 p = skip_string(p,1);
757 send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
758 name,group,0,0x1e,bcast_ip,myip);
762 /****************************************************************************
763 send a backup list response
764 **************************************************************************/
765 static void send_backup_list(char *name,int token,struct nmb_name *to,
771 DEBUG(2,("Sending backup list to %s for workgroup %s\n",
772 inet_ntoa(ip),PrimaryGroup));
774 bzero(outbuf,sizeof(outbuf));
776 CVAL(p,0) = 10; /* backup list response */
779 CVAL(p,0) = 1; /* count */
784 p = skip_string(p,1) + 1;
786 send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
787 myname,to->name,0,to->name_type,ip,myip);
791 /*******************************************************************
792 become the master browser
793 ******************************************************************/
794 static void become_master(void)
796 uint32 domain_type = SV_TYPE_DOMAIN_ENUM | SV_TYPE_SERVER_UNIX;
797 DEBUG(2,("Becoming master for %s\n",PrimaryGroup));
799 ServerType |= SV_TYPE_MASTER_BROWSER;
800 ServerType |= SV_TYPE_BACKUP_BROWSER;
801 ElectionCriterion |= 0x5;
803 add_host_entry(PrimaryGroup,0x1d,True,0,SELF,myip);
804 add_host_entry(PrimaryGroup,0x0,False,0,SELF,myip);
805 add_host_entry(MSBROWSE,1,False,0,SELF,myip);
807 if (lp_domain_master()) {
808 add_host_entry(myname,0x1b,True,0,SELF,myip);
809 add_host_entry(PrimaryGroup,0x1b,True,0,SELF,myip);
810 add_host_entry(PrimaryGroup,0x1c,False,0,SELF,myip);
811 ServerType |= SV_TYPE_DOMAIN_MASTER;
812 if (lp_domain_logons()) {
813 ServerType |= SV_TYPE_DOMAIN_CTRL;
814 ServerType |= SV_TYPE_DOMAIN_MEMBER;
815 domain_type |= SV_TYPE_DOMAIN_CTRL;
819 add_server_entry(PrimaryGroup,domain_type,0,myname,True);
820 add_server_entry(myname,ServerType,0,ServerComment,True);
822 announce_request(PrimaryGroup);
828 /*******************************************************************
829 unbecome the master browser
830 ******************************************************************/
831 static void become_nonmaster(void)
833 struct name_record *n;
836 DEBUG(2,("Becoming non-master for %s\n",PrimaryGroup));
838 ServerType &= ~SV_TYPE_MASTER_BROWSER;
839 ServerType &= ~SV_TYPE_DOMAIN_CTRL;
840 ServerType &= ~SV_TYPE_DOMAIN_MASTER;
842 ElectionCriterion &= ~0x4;
844 make_nmb_name(&nn,PrimaryGroup,0x1d,scope);
846 if (n && n->source == SELF) remove_name(n);
848 make_nmb_name(&nn,PrimaryGroup,0x1b,scope);
850 if (n && n->source == SELF) remove_name(n);
852 make_nmb_name(&nn,MSBROWSE,1,scope);
854 if (n && n->source == SELF) remove_name(n);
858 /*******************************************************************
860 ******************************************************************/
861 static void run_election(void)
863 time_t t = time(NULL);
864 static time_t lastime = 0;
866 if (!PrimaryGroup[0] || !RunningElection) return;
868 /* send election packets once a second */
870 t-lastime <= 0) return;
874 send_election(PrimaryGroup,ElectionCriterion,t-StartupTime,myname);
876 if (ElectionCount++ < 4) return;
878 /* I won! now what :-) */
879 RunningElection = False;
880 DEBUG(2,(">>> Won election on %s <<<\n",PrimaryGroup));
885 /****************************************************************************
886 construct a host announcement unicast
887 **************************************************************************/
888 static void announce_host(struct domain_record *d,char *my_name,char *comment)
890 time_t t = time(NULL);
896 uint32 stype = ServerType;
899 /* drop back to a max 3 minute announce - this is to prevent a
900 single lost packet from stuffing things up for too long */
901 d->announce_interval = MIN(d->announce_interval,3*60);
902 d->lastannounce_time = t - (d->announce_interval+1);
905 /* announce every minute at first then progress to every 12 mins */
906 if (d->lastannounce_time &&
907 (t - d->lastannounce_time) < d->announce_interval)
910 if (d->announce_interval < 12*60) d->announce_interval += 60;
911 d->lastannounce_time = t;
913 DEBUG(2,("Sending announcement to %s for workgroup %s\n",
914 inet_ntoa(d->bcast_ip),d->name));
916 if (!strequal(PrimaryGroup,d->name) ||
917 !ip_equal(bcast_ip,d->bcast_ip)) {
918 stype &= ~(SV_TYPE_POTENTIAL_BROWSER | SV_TYPE_MASTER_BROWSER |
919 SV_TYPE_DOMAIN_MASTER | SV_TYPE_BACKUP_BROWSER |
920 SV_TYPE_DOMAIN_CTRL | SV_TYPE_DOMAIN_MEMBER);
923 if (!*comment) comment = "NoComment";
924 if (!*my_name) my_name = "NoName";
926 if (strlen(comment) > 43) comment[43] = 0;
928 bzero(outbuf,sizeof(outbuf));
929 CVAL(outbuf,0) = 1; /* host announce */
932 CVAL(p,0) = updatecount;
933 SIVAL(p,1,d->announce_interval*1000); /* ms - despite the spec */
935 StrnCpy(p+5,my_name,16);
937 CVAL(p,21) = 2; /* major version */
938 CVAL(p,22) = 2; /* minor version */
941 SSVAL(p,27,0xaa55); /* browse signature */
942 SSVAL(p,29,1); /* browse version */
944 strcpy(p+31,comment);
946 p = skip_string(p,1);
948 send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
949 my_name,d->name,0,0x1d,d->bcast_ip,myip);
951 /* if I'm the master then I also need to do a local master and
952 domain announcement */
955 strequal(d->name,PrimaryGroup) &&
956 ip_equal(bcast_ip,d->bcast_ip)) {
958 /* do master announcements as well */
959 SIVAL(stypep,0,ServerType);
961 CVAL(outbuf,0) = 15; /* local master announce */
962 send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
963 my_name,PrimaryGroup,0,0x1e,d->bcast_ip,myip);
965 CVAL(outbuf,0) = 12; /* domain announce */
966 StrnCpy(namep,PrimaryGroup,15);
968 StrnCpy(commentp,myname,15);
970 SIVAL(stypep,0,(unsigned)0x80000000);
971 p = commentp + strlen(commentp) + 1;
973 send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
974 my_name,MSBROWSE,0,1,d->bcast_ip,myip);
979 /****************************************************************************
980 send a announce request to the local net
981 **************************************************************************/
982 static void announce_request(char *group)
987 DEBUG(2,("Sending announce request to %s for workgroup %s\n",
988 inet_ntoa(bcast_ip),group));
990 bzero(outbuf,sizeof(outbuf));
992 CVAL(p,0) = 2; /* announce request */
995 CVAL(p,0) = 0; /* flags?? */
997 StrnCpy(p,myname,16);
999 p = skip_string(p,1);
1001 send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
1002 myname,group,0,0,bcast_ip,myip);
1005 /****************************************************************************
1006 announce myself as a master to the PDC
1007 **************************************************************************/
1008 static void announce_master(char *group)
1010 static time_t last=0;
1011 time_t t = time(NULL);
1014 struct in_addr ip,pdc_ip;
1018 if (strequal(domain_controller(),myname)) return;
1020 if (!AM_MASTER || (last && (t-last < 10*60))) return;
1023 ip = *interpret_addr2(domain_controller());
1025 if (zero_ip(ip)) ip = bcast_ip;
1027 if (!name_query(ClientNMB,PrimaryGroup,
1028 0x1b,False,False,ip,&pdc_ip,queue_packet)) {
1029 DEBUG(2,("Failed to find PDC at %s\n",domain_controller()));
1033 name_status(ClientNMB,PrimaryGroup,0x1b,False,
1034 pdc_ip,NULL,pdcname,queue_packet);
1037 DEBUG(3,("Can't find netbios name of PDC at %s\n",inet_ntoa(pdc_ip)));
1039 sync_browse_lists(pdcname,0x20,myname,PrimaryGroup,pdc_ip);
1043 DEBUG(2,("Sending master announce to %s for workgroup %s\n",
1044 inet_ntoa(pdc_ip),group));
1046 bzero(outbuf,sizeof(outbuf));
1048 CVAL(p,0) = 13; /* announce request */
1051 StrnCpy(p,myname,16);
1053 p = skip_string(p,1);
1055 send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
1056 myname,PrimaryGroup,0x1b,0,pdc_ip,myip);
1060 /*******************************************************************
1061 am I listening on a name. Should check name_type as well
1063 This is primarily used to prevent us gathering server lists from
1064 other workgroups we aren't a part of
1065 ******************************************************************/
1066 static BOOL listening(struct nmb_name *n)
1068 if (!strequal(n->scope,scope)) return(False);
1070 if (strequal(n->name,myname) ||
1071 strequal(n->name,PrimaryGroup) ||
1072 strequal(n->name,MSBROWSE))
1079 /*******************************************************************
1080 process a domain announcement frame
1082 Announce frames come in 3 types. Servers send host announcements
1083 (command=1) to let the master browswer know they are
1084 available. Master browsers send local master announcements
1085 (command=15) to let other masters and backups that they are the
1086 master. They also send domain announcements (command=12) to register
1089 The comment field of domain announcements contains the master
1090 browser name. The servertype is used by NetServerEnum to select
1091 resources. We just have to pass it to smbd (via browser.dat) and let
1092 the client choose using bit masks.
1093 ******************************************************************/
1094 static void process_announce(struct packet_struct *p,int command,char *buf)
1096 struct dgram_packet *dgram = &p->packet.dgram;
1097 int update_count = CVAL(buf,0);
1098 int ttl = IVAL(buf,1)/1000;
1100 int osmajor=CVAL(buf,21);
1101 int osminor=CVAL(buf,22);
1102 uint32 servertype = IVAL(buf,23);
1103 char *comment = buf+31;
1108 DEBUG(3,("Announce(%d) %s count=%d ttl=%d OS=(%d,%d) type=%08x comment=%s\n",
1109 command,name,update_count,ttl,osmajor,osminor,
1110 servertype,comment));
1112 if (strequal(dgram->source_name.name,myname)) return;
1114 if (!listening(&dgram->dest_name)) return;
1118 /* add them to our browse list */
1119 add_server_entry(name,servertype,ttl,comment,True);
1123 /*******************************************************************
1124 process a master announcement frame
1125 ******************************************************************/
1126 static void process_master_announce(struct packet_struct *p,char *buf)
1128 struct dgram_packet *dgram = &p->packet.dgram;
1133 DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(p->ip)));
1135 if (strequal(dgram->source_name.name,myname)) return;
1137 if (!AM_MASTER || !listening(&dgram->dest_name)) return;
1139 /* merge browse lists with them */
1140 if (lp_domain_master())
1141 sync_browse_lists(name,0x20,myname,PrimaryGroup,p->ip);
1145 /*******************************************************************
1146 process a backup list request
1148 A client send a backup list request to ask for a list of servers on
1149 the net that maintain server lists for a domain. A server is then
1150 chosen from this list to send NetServerEnum commands to to list
1153 Currently samba only sends back one name in the backup list, its
1154 wn. For larger nets we'll have to add backups and send "become
1155 backup" requests occasionally.
1156 ******************************************************************/
1157 static void process_backup_list(struct packet_struct *p,char *buf)
1159 struct dgram_packet *dgram = &p->packet.dgram;
1160 int count = CVAL(buf,0);
1161 int token = IVAL(buf,1);
1163 DEBUG(3,("Backup request to %s token=%d\n",
1164 namestr(&dgram->dest_name),
1167 if (strequal(dgram->source_name.name,myname)) return;
1169 if (count <= 0) return;
1172 !strequal(PrimaryGroup,dgram->dest_name.name))
1175 if (!listening(&dgram->dest_name)) return;
1177 send_backup_list(myname,token,
1178 &dgram->source_name,
1183 /*******************************************************************
1184 work out if I win an election
1185 ******************************************************************/
1186 static BOOL win_election(int version,uint32 criterion,int timeup,char *name)
1188 time_t t = time(NULL);
1190 if (version > ELECTION_VERSION) return(False);
1191 if (version < ELECTION_VERSION) return(True);
1193 mycriterion = ElectionCriterion;
1195 if (criterion > mycriterion) return(False);
1196 if (criterion < mycriterion) return(True);
1198 if (timeup > (t - StartupTime)) return(False);
1199 if (timeup < (t - StartupTime)) return(True);
1201 if (strcasecmp(myname,name) > 0) return(False);
1207 /*******************************************************************
1208 process a election packet
1210 An election dynamically decides who will be the master.
1211 ******************************************************************/
1212 static void process_election(struct packet_struct *p,char *buf)
1214 struct dgram_packet *dgram = &p->packet.dgram;
1215 int version = CVAL(buf,0);
1216 uint32 criterion = IVAL(buf,1);
1217 int timeup = IVAL(buf,5)/1000;
1218 char *name = buf+13;
1222 DEBUG(3,("Election request from %s vers=%d criterion=%08x timeup=%d\n",
1223 name,version,criterion,timeup));
1225 if (strequal(dgram->source_name.name,myname)) return;
1227 if (!listening(&dgram->dest_name)) return;
1229 if (win_election(version,criterion,timeup,name)) {
1230 if (!RunningElection) {
1231 needelection = True;
1235 needelection = False;
1236 if (RunningElection) {
1237 RunningElection = False;
1238 DEBUG(3,(">>> Lost election on %s <<<\n",PrimaryGroup));
1240 /* if we are the master then remove our masterly names */
1248 /*******************************************************************
1249 process a announcement request
1251 clients send these when they want everyone to send an announcement
1252 immediately. This can cause quite a storm of packets!
1253 ******************************************************************/
1254 static void process_announce_request(struct packet_struct *p,char *buf)
1256 struct dgram_packet *dgram = &p->packet.dgram;
1257 int flags = CVAL(buf,0);
1262 DEBUG(3,("Announce request from %s flags=0x%X\n",name,flags));
1264 if (strequal(dgram->source_name.name,myname)) return;
1266 needannounce = True;
1270 /****************************************************************************
1271 process a browse frame
1272 ****************************************************************************/
1273 static void process_browse_packet(struct packet_struct *p,char *buf,int len)
1275 int command = CVAL(buf,0);
1278 case 1: /* host announce */
1279 case 12: /* domain announce */
1280 case 15: /* local master announce */
1281 process_announce(p,command,buf+1);
1284 case 2: /* announce request */
1285 process_announce_request(p,buf+1);
1288 case 8: /* election */
1289 process_election(p,buf+1);
1292 case 9: /* get backup list */
1293 process_backup_list(p,buf+1);
1296 case 13: /* master announcement */
1297 process_master_announce(p,buf+1);
1303 /****************************************************************************
1304 process a domain logon packet
1305 **************************************************************************/
1306 static void process_logon_packet(struct packet_struct *p,char *buf,int len)
1310 struct dgram_packet *dgram = &p->packet.dgram;
1313 if (!lp_domain_logons()) {
1314 DEBUG(3,("No domain logons\n"));
1317 if (!listening(&dgram->dest_name)) {
1318 DEBUG(4,("Not listening to that domain\n"));
1323 bzero(outbuf,sizeof(outbuf));
1329 char *machine = buf+2;
1330 char *user = skip_string(machine,1);
1331 logname = skip_string(user,1);
1337 StrnCpy(q,myname,16);
1339 q = skip_string(q,1);
1343 DEBUG(3,("Domain login request from %s(%s) user=%s\n",
1344 machine,inet_ntoa(p->ip),user));
1349 char *machine = buf+2;
1350 logname = skip_string(machine,1);
1354 StrnCpy(q,domain_controller(),16);
1356 q = skip_string(q,1);
1357 q += PutUniCode(q,domain_controller());
1358 q += PutUniCode(q,dgram->dest_name.name);
1362 DEBUG(3,("GETDC request from %s(%s)\n",
1363 machine,inet_ntoa(p->ip)));
1367 DEBUG(3,("Unknown domain request %d\n",code));
1372 send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
1373 myname,&dgram->source_name.name[0],0,0,p->ip,myip);
1376 /****************************************************************************
1377 process udp 138 datagrams
1378 ****************************************************************************/
1379 static void process_dgram(struct packet_struct *p)
1384 struct dgram_packet *dgram = &p->packet.dgram;
1386 if (dgram->header.msg_type != 0x10 &&
1387 dgram->header.msg_type != 0x11 &&
1388 dgram->header.msg_type != 0x12) {
1389 /* don't process error packets etc yet */
1393 buf = &dgram->data[0];
1394 buf -= 4; /* XXXX for the pseudo tcp length -
1395 someday I need to get rid of this */
1397 if (CVAL(buf,smb_com) != SMBtrans) return;
1399 len = SVAL(buf,smb_vwv11);
1400 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1402 DEBUG(3,("datagram from %s to %s for %s of type %d len=%d\n",
1403 namestr(&dgram->source_name),namestr(&dgram->dest_name),
1404 smb_buf(buf),CVAL(buf2,0),len));
1406 if (len <= 0) return;
1408 if (strequal(smb_buf(buf),"\\MAILSLOT\\BROWSE")) {
1409 process_browse_packet(p,buf2,len);
1410 } else if (strequal(smb_buf(buf),"\\MAILSLOT\\NET\\NETLOGON")) {
1411 process_logon_packet(p,buf2,len);
1416 /*******************************************************************
1417 find a workgroup using the specified broadcast
1418 ******************************************************************/
1419 static BOOL find_workgroup(char *name,struct in_addr ip)
1423 struct in_addr ipout;
1425 strcpy(name1,MSBROWSE);
1427 ret = name_query(ClientNMB,name1,0x1,True,False,ip,&ipout,queue_packet);
1428 if (!ret) return(False);
1430 name_status(ClientNMB,name1,0x1,False,ipout,name,NULL,queue_packet);
1432 if (name[0] != '*') {
1433 DEBUG(2,("Found workgroup %s on broadcast %s\n",name,inet_ntoa(ip)));
1435 DEBUG(3,("Failed to find workgroup %s on broadcast %s\n",name,inet_ntoa(ip)));
1437 return(name[0] != '*');
1441 /****************************************************************************
1442 a hook for announce handling - called every minute
1443 **************************************************************************/
1444 static void do_announcements(void)
1446 struct domain_record *d;
1448 for (d = domainlist; d; d = d->next) {
1449 /* if the ip address is 0 then set to the broadcast */
1450 if (zero_ip(d->bcast_ip)) d->bcast_ip = bcast_ip;
1452 /* if the workgroup is '*' then find a workgroup to be part of */
1453 if (d->name[0] == '*') {
1454 if (!find_workgroup(d->name,d->bcast_ip)) continue;
1455 add_host_entry(d->name,0x1e,False,0,SELF,
1456 *interpret_addr2("255.255.255.255"));
1457 if (!PrimaryGroup[0] && ip_equal(bcast_ip,d->bcast_ip)) {
1458 strcpy(PrimaryGroup,d->name);
1459 strupper(PrimaryGroup);
1463 announce_host(d,myname,ServerComment);
1466 /* if I have a domain controller then announce to it */
1468 announce_master(PrimaryGroup);
1473 /*******************************************************************
1474 check if someone still owns a name
1475 ******************************************************************/
1476 static BOOL confirm_name(struct name_record *n)
1478 struct in_addr ipout;
1479 BOOL ret = name_query(ClientNMB,n->name.name,
1480 n->name.name_type,False,
1481 False,n->ip,&ipout,queue_packet);
1482 return(ret && ip_equal(ipout,n->ip));
1485 /****************************************************************************
1486 reply to a name release
1487 ****************************************************************************/
1488 static void reply_name_release(struct packet_struct *p)
1490 struct nmb_packet *nmb = &p->packet.nmb;
1491 struct packet_struct p2;
1492 struct nmb_packet *nmb2;
1493 struct res_rec answer_rec;
1496 int nb_flags = nmb->additional->rdata[0];
1497 BOOL bcast = nmb->header.nm_flags.bcast;
1500 putip((char *)&ip,&nmb->additional->rdata[2]);
1503 struct name_record *n = find_name(&nmb->question.question_name);
1504 if (n && n->unique && n->source == REGISTER &&
1505 ip_equal(ip,n->ip)) {
1506 remove_name(n); n = NULL;
1509 /* XXXX under what conditions should we reject the removal?? */
1512 DEBUG(3,("Name release on name %s rcode=%d\n",
1513 namestr(&nmb->question.question_name),rcode));
1517 /* Send a NAME RELEASE RESPONSE */
1519 nmb2 = &p2.packet.nmb;
1521 nmb2->header.response = True;
1522 nmb2->header.nm_flags.bcast = False;
1523 nmb2->header.nm_flags.recursion_available = CanRecurse;
1524 nmb2->header.nm_flags.trunc = False;
1525 nmb2->header.nm_flags.authoritative = True;
1526 nmb2->header.qdcount = 0;
1527 nmb2->header.ancount = 1;
1528 nmb2->header.nscount = 0;
1529 nmb2->header.arcount = 0;
1530 nmb2->header.rcode = rcode;
1532 nmb2->answers = &answer_rec;
1533 bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
1535 nmb2->answers->rr_name = nmb->question.question_name;
1536 nmb2->answers->rr_type = nmb->question.question_type;
1537 nmb2->answers->rr_class = nmb->question.question_class;
1538 nmb2->answers->ttl = 0;
1539 nmb2->answers->rdlength = 6;
1540 nmb2->answers->rdata[0] = nb_flags;
1541 putip(&nmb2->answers->rdata[2],(char *)&ip);
1546 /****************************************************************************
1547 reply to a reg request
1548 **************************************************************************/
1549 static void reply_name_reg(struct packet_struct *p)
1551 struct nmb_packet *nmb = &p->packet.nmb;
1552 char *qname = nmb->question.question_name.name;
1553 BOOL wildcard = (qname[0] == '*');
1554 BOOL bcast = nmb->header.nm_flags.bcast;
1555 int ttl = GET_TTL(nmb->additional->ttl);
1556 int name_type = nmb->question.question_name.name_type;
1557 int nb_flags = nmb->additional->rdata[0];
1558 struct packet_struct p2;
1559 struct nmb_packet *nmb2;
1560 struct res_rec answer_rec;
1562 BOOL group = (nb_flags&0x80)?True:False;
1565 if (wildcard) return;
1567 putip((char *)&ip,&nmb->additional->rdata[2]);
1570 /* apparently we should return 255.255.255.255 for group queries (email from MS) */
1571 ip = *interpret_addr2("255.255.255.255");
1575 struct name_record *n = find_name(&nmb->question.question_name);
1578 if (!group && !ip_equal(ip,n->ip)) {
1579 /* check if the previous owner still wants it,
1580 if so reject the registration, otherwise change the owner
1582 if (n->source != REGISTER || confirm_name(n)) {
1586 n->death_time = ttl?p->timestamp+ttl*3:0;
1587 DEBUG(3,("%s changed owner to %s\n",
1588 namestr(&n->name),inet_ntoa(n->ip)));
1591 /* refresh the name */
1592 if (n->source != SELF)
1593 n->death_time = ttl?p->timestamp + ttl*3:0;
1596 /* add the name to our database */
1597 n = add_host_entry(qname,name_type,!group,ttl,REGISTER,ip);
1603 DEBUG(3,("Name registration for name %s at %s rcode=%d\n",
1604 namestr(&nmb->question.question_name),
1605 inet_ntoa(ip),rcode));
1607 /* Send a NAME REGISTRATION RESPONSE */
1608 /* a lot of fields get copied from the query. This gives us the IP
1609 and port the reply will be sent to etc */
1611 nmb2 = &p2.packet.nmb;
1613 nmb2->header.opcode = 5;
1614 nmb2->header.response = True;
1615 nmb2->header.nm_flags.bcast = False;
1616 nmb2->header.nm_flags.recursion_available = CanRecurse;
1617 nmb2->header.nm_flags.trunc = False;
1618 nmb2->header.nm_flags.authoritative = True;
1619 nmb2->header.qdcount = 0;
1620 nmb2->header.ancount = 1;
1621 nmb2->header.nscount = 0;
1622 nmb2->header.arcount = 0;
1623 nmb2->header.rcode = rcode;
1625 nmb2->answers = &answer_rec;
1626 bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
1628 nmb2->answers->rr_name = nmb->question.question_name;
1629 nmb2->answers->rr_type = nmb->question.question_type;
1630 nmb2->answers->rr_class = nmb->question.question_class;
1632 nmb2->answers->ttl = ttl;
1633 nmb2->answers->rdlength = 6;
1634 nmb2->answers->rdata[0] = nb_flags;
1635 putip(&nmb2->answers->rdata[2],(char *)&ip);
1641 /****************************************************************************
1642 reply to a name status query
1643 ****************************************************************************/
1644 static void reply_name_status(struct packet_struct *p)
1646 struct nmb_packet *nmb = &p->packet.nmb;
1647 char *qname = nmb->question.question_name.name;
1648 BOOL wildcard = (qname[0] == '*');
1649 struct packet_struct p2;
1650 struct nmb_packet *nmb2;
1651 struct res_rec answer_rec;
1655 struct name_record *n = find_name(&nmb->question.question_name);
1657 DEBUG(3,("Name status for name %s\n",
1658 namestr(&nmb->question.question_name)));
1660 if (!wildcard && (!n || n->source != SELF))
1663 /* Send a POSITIVE NAME STATUS RESPONSE */
1664 /* a lot of fields get copied from the query. This gives us the IP
1665 and port the reply will be sent to etc */
1667 nmb2 = &p2.packet.nmb;
1669 nmb2->header.response = True;
1670 nmb2->header.nm_flags.bcast = False;
1671 nmb2->header.nm_flags.recursion_available = CanRecurse;
1672 nmb2->header.nm_flags.trunc = False;
1673 nmb2->header.nm_flags.authoritative = True; /* WfWg ignores
1674 non-authoritative answers */
1675 nmb2->header.qdcount = 0;
1676 nmb2->header.ancount = 1;
1677 nmb2->header.nscount = 0;
1678 nmb2->header.arcount = 0;
1679 nmb2->header.rcode = rcode;
1681 nmb2->answers = &answer_rec;
1682 bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
1685 nmb2->answers->rr_name = nmb->question.question_name;
1686 nmb2->answers->rr_type = nmb->question.question_type;
1687 nmb2->answers->rr_class = nmb->question.question_class;
1688 nmb2->answers->ttl = 0;
1690 for (count=0, n = namelist ; n; n = n->next) {
1691 if (n->source != SELF) continue;
1695 count = MIN(count,400/18); /* XXXX hack, we should calculate exactly
1696 how many will fit */
1699 buf = &nmb2->answers->rdata[0];
1703 for (n = namelist ; n; n = n->next)
1705 if (n->source != SELF) continue;
1708 strcpy(buf,n->name.name);
1710 buf[15] = n->name.name_type;
1712 buf[0] = 0x4; /* active */
1713 if (!n->unique) buf[0] |= 0x80; /* group */
1718 /* XXXXXXX we should fill in more fields of the statistics structure */
1721 extern int num_good_sends,num_good_receives;
1722 SIVAL(buf,20,num_good_sends);
1723 SIVAL(buf,24,num_good_receives);
1725 SIVAL(buf,46,0xFFB8E5); /* undocumented - used by NT */
1729 nmb2->answers->rdlength = PTR_DIFF(buf,&nmb2->answers->rdata[0]);
1736 /****************************************************************************
1737 reply to a name query
1738 ****************************************************************************/
1739 static void reply_name_query(struct packet_struct *p)
1741 struct nmb_packet *nmb = &p->packet.nmb;
1742 char *qname = nmb->question.question_name.name;
1743 BOOL wildcard = (qname[0] == '*');
1744 BOOL bcast = nmb->header.nm_flags.bcast;
1745 struct in_addr retip;
1746 int name_type = nmb->question.question_name.name_type;
1747 struct packet_struct p2;
1748 struct nmb_packet *nmb2;
1749 struct res_rec answer_rec;
1754 DEBUG(3,("Name query for %s from %s (bcast=%s) - ",
1755 namestr(&nmb->question.question_name),
1763 struct name_record *n = find_name(&nmb->question.question_name);
1769 /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
1770 if (name_type != 0x20 && name_type != 0) {
1771 DEBUG(3,("not found\n"));
1775 /* look it up with DNS */
1776 a = interpret_addr(qname);
1778 putip((char *)&ip,(char *)&a);
1781 /* no luck with DNS. We could possibly recurse here XXXX */
1782 /* if this isn't a bcast then we should send a negative reply XXXX */
1783 DEBUG(3,("no recursion\n"));
1784 add_host_entry(qname,name_type,True,60*60,DNSFAIL,ip);
1788 /* add it to our cache of names. give it 2 hours in the cache */
1789 n = add_host_entry(qname,name_type,True,2*60*60,DNS,ip);
1791 /* failed to add it? yikes! */
1795 /* don't respond to bcast queries for group names unless we own them */
1796 if (bcast && !n->unique && !n->source == SELF) {
1797 DEBUG(3,("no bcast replies\n"));
1801 /* don't respond to bcast queries for addresses on the same net as the
1802 machine doing the querying unless its our IP */
1804 n->source != SELF &&
1805 same_net(n->ip,p->ip)) {
1806 DEBUG(3,("same net\n"));
1810 /* is our entry already dead? */
1811 if (n->death_time) {
1812 if (n->death_time < p->timestamp) return;
1813 ttl = n->death_time - p->timestamp;
1819 /* it may have been an earlier failure */
1820 if (n->source == DNSFAIL) {
1821 DEBUG(3,("DNSFAIL\n"));
1826 /* if the IP is 0 then substitute my IP - we should see which one is on the
1827 right interface for the caller to do this right XXX */
1828 if (zero_ip(retip)) retip = myip;
1830 DEBUG(3,("OK %s rcode=%d\n",inet_ntoa(retip),rcode));
1832 /* a lot of fields get copied from the query. This gives us the IP
1833 and port the reply will be sent to etc */
1835 nmb2 = &p2.packet.nmb;
1837 nmb2->header.response = True;
1838 nmb2->header.nm_flags.bcast = False;
1839 nmb2->header.nm_flags.recursion_available = CanRecurse;
1840 nmb2->header.nm_flags.trunc = False;
1841 nmb2->header.nm_flags.authoritative = True; /* WfWg ignores
1842 non-authoritative answers */
1843 nmb2->header.qdcount = 0;
1844 nmb2->header.ancount = 1;
1845 nmb2->header.nscount = 0;
1846 nmb2->header.arcount = 0;
1847 nmb2->header.rcode = rcode;
1849 nmb2->answers = &answer_rec;
1850 bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
1852 nmb2->answers->rr_name = nmb->question.question_name;
1853 nmb2->answers->rr_type = nmb->question.question_type;
1854 nmb2->answers->rr_class = nmb->question.question_class;
1855 nmb2->answers->ttl = ttl;
1856 nmb2->answers->rdlength = 6;
1857 nmb2->answers->rdata[0] = unique?0:0x80;
1858 nmb2->answers->rdata[1] = 0;
1859 putip(&nmb2->answers->rdata[2],(char *)&retip);
1866 /* the global packet linked-list. incoming entries are added to the
1867 end of this list. it is supposed to remain fairly short so we
1868 won't bother with an end pointer. */
1869 static struct packet_struct *packet_queue = NULL;
1872 /*******************************************************************
1873 queue a packet into the packet queue
1874 ******************************************************************/
1875 static void queue_packet(struct packet_struct *packet)
1877 struct packet_struct *p;
1878 if (!packet_queue) {
1879 packet->prev = NULL;
1880 packet->next = NULL;
1881 packet_queue = packet;
1885 /* find the bottom */
1886 for (p=packet_queue;p->next;p=p->next) ;
1889 packet->next = NULL;
1893 /****************************************************************************
1894 process a nmb packet
1895 ****************************************************************************/
1896 static void process_nmb(struct packet_struct *p)
1898 struct nmb_packet *nmb = &p->packet.nmb;
1900 /* if this is a response then ignore it */
1901 if (nmb->header.response) return;
1903 switch (nmb->header.opcode)
1908 if (nmb->header.qdcount>0 &&
1909 nmb->header.arcount>0) {
1916 if (nmb->header.qdcount>0)
1918 switch (nmb->question.question_type)
1921 reply_name_query(p);
1925 reply_name_status(p);
1933 if (nmb->header.qdcount>0 &&
1934 nmb->header.arcount>0) {
1935 reply_name_release(p);
1945 /*******************************************************************
1946 run elements off the packet queue till its empty
1947 ******************************************************************/
1948 static void run_packet_queue(void)
1950 struct packet_struct *p;
1952 while ((p=packet_queue)) {
1953 switch (p->packet_type)
1964 packet_queue = packet_queue->next;
1965 if (packet_queue) packet_queue->prev = NULL;
1971 /****************************************************************************
1972 The main select loop, listen for packets and respond
1973 ***************************************************************************/
1981 struct timeval timeout;
1983 if (needelection && PrimaryGroup[0] && !RunningElection) {
1984 DEBUG(3,(">>> Starting election on %s <<<\n",PrimaryGroup));
1986 RunningElection = True;
1987 needelection = False;
1991 FD_SET(ClientNMB,&fds);
1992 FD_SET(ClientDGRAM,&fds);
1993 /* during elections we need to send election packets at one
1995 timeout.tv_sec = RunningElection?1:NMBD_SELECT_LOOP;
1996 timeout.tv_usec = 0;
1998 selrtn = sys_select(&fds,&timeout);
2000 if (FD_ISSET(ClientNMB,&fds)) {
2001 struct packet_struct *packet = read_packet(ClientNMB,NMB_PACKET);
2002 if (packet) queue_packet(packet);
2005 if (FD_ISSET(ClientDGRAM,&fds)) {
2006 struct packet_struct *packet = read_packet(ClientDGRAM,DGRAM_PACKET);
2007 if (packet) queue_packet(packet);
2010 if (RunningElection)
2022 /****************************************************************************
2023 open the socket communication
2024 ****************************************************************************/
2025 static BOOL open_sockets(BOOL isdaemon,int port)
2030 if ((hp = Get_Hostbyname(myhostname)) == 0)
2032 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
2037 ClientNMB = open_socket_in(SOCK_DGRAM, port,0);
2041 ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3);
2043 if (ClientNMB == -1)
2046 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2048 set_socket_options(ClientNMB,"SO_BROADCAST");
2049 set_socket_options(ClientDGRAM,"SO_BROADCAST");
2051 DEBUG(3, ("Socket opened.\n"));
2056 /*******************************************************************
2057 check that a IP, bcast and netmask and consistent. Must be a 1s
2059 ******************************************************************/
2060 static BOOL ip_consistent(struct in_addr ip,struct in_addr bcast,
2061 struct in_addr nmask)
2063 unsigned long a_ip,a_bcast,a_nmask;
2065 a_ip = ntohl(ip.s_addr);
2066 a_bcast = ntohl(bcast.s_addr);
2067 a_nmask = ntohl(nmask.s_addr);
2069 /* check the netmask is sane */
2070 if (((a_nmask>>24)&0xFF) != 0xFF) {
2071 DEBUG(0,("Insane netmask %s\n",inet_ntoa(nmask)));
2075 /* check the IP and bcast are on the same net */
2076 if ((a_ip&a_nmask) != (a_bcast&a_nmask)) {
2077 DEBUG(0,("IP and broadcast are on different nets!\n"));
2081 /* check the IP and bcast are on the same net */
2082 if ((a_bcast|a_nmask) != 0xFFFFFFFF) {
2083 DEBUG(0,("Not a ones based broadcast %s\n",inet_ntoa(bcast)));
2090 /****************************************************************************
2091 initialise connect, service and file structs
2092 ****************************************************************************/
2093 static BOOL init_structs(void )
2095 if (!get_myname(myhostname,got_myip?NULL:&myip))
2098 /* Read the broadcast address from the interface */
2100 struct in_addr ip0,ip1,ip2;
2104 if (!(got_bcast && got_nmask))
2106 get_broadcast(&ip0,&ip1,&ip2);
2118 DEBUG(1,("Using IP %s ",inet_ntoa(myip)));
2119 DEBUG(1,("broadcast %s ",inet_ntoa(bcast_ip)));
2120 DEBUG(1,("netmask %s\n",inet_ntoa(Netmask)));
2122 if (!ip_consistent(myip,bcast_ip,Netmask)) {
2123 DEBUG(0,("WARNING: The IP address, broadcast and Netmask are not consistent\n"));
2124 DEBUG(0,("You are likely to experience problems with this setup!\n"));
2130 strcpy(myname,myhostname);
2131 p = strchr(myname,'.');
2136 extern fstring local_machine;
2137 strcpy(local_machine,myname);
2138 strupper(local_machine);
2144 /****************************************************************************
2145 usage on the program
2146 ****************************************************************************/
2147 static void usage(char *pname)
2149 DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
2151 printf("Usage: %s [-n name] [-B bcast address] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
2152 printf("Version %s\n",VERSION);
2153 printf("\t-D become a daemon\n");
2154 printf("\t-p port listen on the specified port\n");
2155 printf("\t-d debuglevel set the debuglevel\n");
2156 printf("\t-l log basename. Basename for log/debug files\n");
2157 printf("\t-n netbiosname. the netbios name to advertise for this host\n");
2158 printf("\t-B broadcast address the address to use for broadcasts\n");
2159 printf("\t-N netmask the netmask to use for subnet determination\n");
2160 printf("\t-H hosts file load a netbios hosts file\n");
2161 printf("\t-I ip-address override the IP address\n");
2162 printf("\t-G group name add a group name to be part of\n");
2163 printf("\t-C comment sets the machine comment that appears in browse lists\n");
2168 /****************************************************************************
2170 **************************************************************************/
2171 int main(int argc,char *argv[])
2173 int port = NMB_PORT;
2176 extern char *optarg;
2184 StartupTime = time(NULL);
2188 strcpy(debugf,NMBLOGFILE);
2190 setup_logging(argv[0],False);
2192 charset_initialise();
2195 strcpy(host_file,LMHOSTSFILE);
2198 /* this is for people who can't start the program correctly */
2199 while (argc > 1 && (*argv[1] != '-'))
2205 fault_setup(fault_continue);
2207 signal(SIGHUP,SIGNAL_CAST sig_hup);
2209 bcast_ip = *interpret_addr2("0.0.0.0");
2210 myip = *interpret_addr2("0.0.0.0");
2212 while ((opt = getopt (argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF)
2216 strcpy(servicesf,optarg);
2219 strcpy(ServerComment,optarg);
2222 add_domain_entry(optarg,bcast_ip);
2225 strcpy(host_file,optarg);
2228 myip = *interpret_addr2(optarg);
2232 bcast_ip = *interpret_addr2(optarg);
2236 Netmask = *interpret_addr2(optarg);
2240 strcpy(myname,optarg);
2243 sprintf(debugf,"%s.nmb",optarg);
2246 strcpy(scope,optarg);
2253 DEBUGLEVEL = atoi(optarg);
2256 port = atoi(optarg);
2263 if (!is_a_socket(0))
2268 DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
2269 DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
2273 if (!reload_services(False))
2278 load_hosts_file(host_file);
2279 DEBUG(3,("Loaded hosts file\n"));
2282 if (!*ServerComment)
2283 strcpy(ServerComment,"Samba %v");
2284 string_sub(ServerComment,"%v",VERSION);
2285 string_sub(ServerComment,"%h",myhostname);
2289 DEBUG(3,("Checked names\n"));
2293 DEBUG(3,("Dumped names\n"));
2295 if (!is_daemon && !is_a_socket(0)) {
2296 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
2302 DEBUG(2,("%s becoming a daemon\n",timestring()));
2307 DEBUG(3,("Opening sockets\n"));
2309 if (open_sockets(is_daemon,port))