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 if (!lp_proxy_name_resolution() && n->source != SELF) {
1802 DEBUG(3,("no proxy resolution\n"));
1806 /* don't respond to bcast queries for addresses on the same net as the
1807 machine doing the querying unless its our IP */
1809 n->source != SELF &&
1810 same_net(n->ip,p->ip)) {
1811 DEBUG(3,("same net\n"));
1815 /* is our entry already dead? */
1816 if (n->death_time) {
1817 if (n->death_time < p->timestamp) return;
1818 ttl = n->death_time - p->timestamp;
1824 /* it may have been an earlier failure */
1825 if (n->source == DNSFAIL) {
1826 DEBUG(3,("DNSFAIL\n"));
1831 /* if the IP is 0 then substitute my IP - we should see which one is on the
1832 right interface for the caller to do this right XXX */
1833 if (zero_ip(retip)) retip = myip;
1835 DEBUG(3,("OK %s rcode=%d\n",inet_ntoa(retip),rcode));
1837 /* a lot of fields get copied from the query. This gives us the IP
1838 and port the reply will be sent to etc */
1840 nmb2 = &p2.packet.nmb;
1842 nmb2->header.response = True;
1843 nmb2->header.nm_flags.bcast = False;
1844 nmb2->header.nm_flags.recursion_available = CanRecurse;
1845 nmb2->header.nm_flags.trunc = False;
1846 nmb2->header.nm_flags.authoritative = True; /* WfWg ignores
1847 non-authoritative answers */
1848 nmb2->header.qdcount = 0;
1849 nmb2->header.ancount = 1;
1850 nmb2->header.nscount = 0;
1851 nmb2->header.arcount = 0;
1852 nmb2->header.rcode = rcode;
1854 nmb2->answers = &answer_rec;
1855 bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
1857 nmb2->answers->rr_name = nmb->question.question_name;
1858 nmb2->answers->rr_type = nmb->question.question_type;
1859 nmb2->answers->rr_class = nmb->question.question_class;
1860 nmb2->answers->ttl = ttl;
1861 nmb2->answers->rdlength = 6;
1862 nmb2->answers->rdata[0] = unique?0:0x80;
1863 nmb2->answers->rdata[1] = 0;
1864 putip(&nmb2->answers->rdata[2],(char *)&retip);
1871 /* the global packet linked-list. incoming entries are added to the
1872 end of this list. it is supposed to remain fairly short so we
1873 won't bother with an end pointer. */
1874 static struct packet_struct *packet_queue = NULL;
1877 /*******************************************************************
1878 queue a packet into the packet queue
1879 ******************************************************************/
1880 static void queue_packet(struct packet_struct *packet)
1882 struct packet_struct *p;
1883 if (!packet_queue) {
1884 packet->prev = NULL;
1885 packet->next = NULL;
1886 packet_queue = packet;
1890 /* find the bottom */
1891 for (p=packet_queue;p->next;p=p->next) ;
1894 packet->next = NULL;
1898 /****************************************************************************
1899 process a nmb packet
1900 ****************************************************************************/
1901 static void process_nmb(struct packet_struct *p)
1903 struct nmb_packet *nmb = &p->packet.nmb;
1905 /* if this is a response then ignore it */
1906 if (nmb->header.response) return;
1908 switch (nmb->header.opcode)
1913 if (nmb->header.qdcount>0 &&
1914 nmb->header.arcount>0) {
1921 if (nmb->header.qdcount>0)
1923 switch (nmb->question.question_type)
1926 reply_name_query(p);
1930 reply_name_status(p);
1938 if (nmb->header.qdcount>0 &&
1939 nmb->header.arcount>0) {
1940 reply_name_release(p);
1950 /*******************************************************************
1951 run elements off the packet queue till its empty
1952 ******************************************************************/
1953 static void run_packet_queue(void)
1955 struct packet_struct *p;
1957 while ((p=packet_queue)) {
1958 switch (p->packet_type)
1969 packet_queue = packet_queue->next;
1970 if (packet_queue) packet_queue->prev = NULL;
1976 /****************************************************************************
1977 The main select loop, listen for packets and respond
1978 ***************************************************************************/
1986 struct timeval timeout;
1988 if (needelection && PrimaryGroup[0] && !RunningElection) {
1989 DEBUG(3,(">>> Starting election on %s <<<\n",PrimaryGroup));
1991 RunningElection = True;
1992 needelection = False;
1996 FD_SET(ClientNMB,&fds);
1997 FD_SET(ClientDGRAM,&fds);
1998 /* during elections we need to send election packets at one
2000 timeout.tv_sec = RunningElection?1:NMBD_SELECT_LOOP;
2001 timeout.tv_usec = 0;
2003 selrtn = sys_select(&fds,&timeout);
2005 if (FD_ISSET(ClientNMB,&fds)) {
2006 struct packet_struct *packet = read_packet(ClientNMB,NMB_PACKET);
2007 if (packet) queue_packet(packet);
2010 if (FD_ISSET(ClientDGRAM,&fds)) {
2011 struct packet_struct *packet = read_packet(ClientDGRAM,DGRAM_PACKET);
2012 if (packet) queue_packet(packet);
2015 if (RunningElection)
2027 /****************************************************************************
2028 open the socket communication
2029 ****************************************************************************/
2030 static BOOL open_sockets(BOOL isdaemon,int port)
2035 if ((hp = Get_Hostbyname(myhostname)) == 0)
2037 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
2042 ClientNMB = open_socket_in(SOCK_DGRAM, port,0);
2046 ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3);
2048 if (ClientNMB == -1)
2051 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2053 set_socket_options(ClientNMB,"SO_BROADCAST");
2054 set_socket_options(ClientDGRAM,"SO_BROADCAST");
2056 DEBUG(3, ("Socket opened.\n"));
2061 /*******************************************************************
2062 check that a IP, bcast and netmask and consistent. Must be a 1s
2064 ******************************************************************/
2065 static BOOL ip_consistent(struct in_addr ip,struct in_addr bcast,
2066 struct in_addr nmask)
2068 unsigned long a_ip,a_bcast,a_nmask;
2070 a_ip = ntohl(ip.s_addr);
2071 a_bcast = ntohl(bcast.s_addr);
2072 a_nmask = ntohl(nmask.s_addr);
2074 /* check the netmask is sane */
2075 if (((a_nmask>>24)&0xFF) != 0xFF) {
2076 DEBUG(0,("Insane netmask %s\n",inet_ntoa(nmask)));
2080 /* check the IP and bcast are on the same net */
2081 if ((a_ip&a_nmask) != (a_bcast&a_nmask)) {
2082 DEBUG(0,("IP and broadcast are on different nets!\n"));
2086 /* check the IP and bcast are on the same net */
2087 if ((a_bcast|a_nmask) != 0xFFFFFFFF) {
2088 DEBUG(0,("Not a ones based broadcast %s\n",inet_ntoa(bcast)));
2095 /****************************************************************************
2096 initialise connect, service and file structs
2097 ****************************************************************************/
2098 static BOOL init_structs(void )
2100 if (!get_myname(myhostname,got_myip?NULL:&myip))
2103 /* Read the broadcast address from the interface */
2105 struct in_addr ip0,ip1,ip2;
2109 if (!(got_bcast && got_nmask))
2111 get_broadcast(&ip0,&ip1,&ip2);
2123 DEBUG(1,("Using IP %s ",inet_ntoa(myip)));
2124 DEBUG(1,("broadcast %s ",inet_ntoa(bcast_ip)));
2125 DEBUG(1,("netmask %s\n",inet_ntoa(Netmask)));
2127 if (!ip_consistent(myip,bcast_ip,Netmask)) {
2128 DEBUG(0,("WARNING: The IP address, broadcast and Netmask are not consistent\n"));
2129 DEBUG(0,("You are likely to experience problems with this setup!\n"));
2135 strcpy(myname,myhostname);
2136 p = strchr(myname,'.');
2141 extern fstring local_machine;
2142 strcpy(local_machine,myname);
2143 strupper(local_machine);
2149 /****************************************************************************
2150 usage on the program
2151 ****************************************************************************/
2152 static void usage(char *pname)
2154 DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
2156 printf("Usage: %s [-n name] [-B bcast address] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
2157 printf("Version %s\n",VERSION);
2158 printf("\t-D become a daemon\n");
2159 printf("\t-p port listen on the specified port\n");
2160 printf("\t-d debuglevel set the debuglevel\n");
2161 printf("\t-l log basename. Basename for log/debug files\n");
2162 printf("\t-n netbiosname. the netbios name to advertise for this host\n");
2163 printf("\t-B broadcast address the address to use for broadcasts\n");
2164 printf("\t-N netmask the netmask to use for subnet determination\n");
2165 printf("\t-H hosts file load a netbios hosts file\n");
2166 printf("\t-I ip-address override the IP address\n");
2167 printf("\t-G group name add a group name to be part of\n");
2168 printf("\t-C comment sets the machine comment that appears in browse lists\n");
2173 /****************************************************************************
2175 **************************************************************************/
2176 int main(int argc,char *argv[])
2178 int port = NMB_PORT;
2181 extern char *optarg;
2189 StartupTime = time(NULL);
2193 strcpy(debugf,NMBLOGFILE);
2195 setup_logging(argv[0],False);
2197 charset_initialise();
2200 strcpy(host_file,LMHOSTSFILE);
2203 /* this is for people who can't start the program correctly */
2204 while (argc > 1 && (*argv[1] != '-'))
2210 fault_setup(fault_continue);
2212 signal(SIGHUP,SIGNAL_CAST sig_hup);
2214 bcast_ip = *interpret_addr2("0.0.0.0");
2215 myip = *interpret_addr2("0.0.0.0");
2217 while ((opt = getopt (argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF)
2221 strcpy(servicesf,optarg);
2224 strcpy(ServerComment,optarg);
2227 add_domain_entry(optarg,bcast_ip);
2230 strcpy(host_file,optarg);
2233 myip = *interpret_addr2(optarg);
2237 bcast_ip = *interpret_addr2(optarg);
2241 Netmask = *interpret_addr2(optarg);
2245 strcpy(myname,optarg);
2248 sprintf(debugf,"%s.nmb",optarg);
2251 strcpy(scope,optarg);
2258 DEBUGLEVEL = atoi(optarg);
2261 port = atoi(optarg);
2268 if (!is_a_socket(0))
2273 DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
2274 DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
2278 if (!reload_services(False))
2283 load_hosts_file(host_file);
2284 DEBUG(3,("Loaded hosts file\n"));
2287 if (!*ServerComment)
2288 strcpy(ServerComment,"Samba %v");
2289 string_sub(ServerComment,"%v",VERSION);
2290 string_sub(ServerComment,"%h",myhostname);
2294 DEBUG(3,("Checked names\n"));
2298 DEBUG(3,("Dumped names\n"));
2300 if (!is_daemon && !is_a_socket(0)) {
2301 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
2307 DEBUG(2,("%s becoming a daemon\n",timestring()));
2312 DEBUG(3,("Opening sockets\n"));
2314 if (open_sockets(is_daemon,port))