patch to fix NetServerEnum with multiple workgroup lists kindly supplied.
[Samba.git] / source / nameserv.c
blob557bad73c3cc900d9d1aacef6a7c50b16daf4e26
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
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.
21 Revision History:
23 14 jan 96: lkcl@pires.co.uk
24 added multiple workgroup domain master support
28 #include "includes.h"
30 extern int ClientNMB;
31 extern int ClientDGRAM;
33 #define FIND_SELF 0x01
34 #define FIND_WINS 0x02
35 #define FIND_LOCAL 0x04
37 extern int DEBUGLEVEL;
39 extern pstring scope;
40 extern BOOL CanRecurse;
41 extern pstring myname;
42 extern struct in_addr ipzero;
43 extern struct in_addr ipgrp;
45 extern struct subnet_record *subnetlist;
47 #define WINS_LIST "wins.dat"
49 #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
51 /****************************************************************************
52 finds the appropriate subnet structure. directed packets (non-bcast) are
53 assumed to come from a point-to-point (P or M node), and so the subnet we
54 return in this instance is the WINS 'pseudo-subnet' with ip 255.255.255.255
55 ****************************************************************************/
56 static struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast)
58 if (bcast)
60 /* identify the subnet the broadcast request came from */
61 return find_subnet(*iface_bcast(ip));
63 /* find the subnet under the pseudo-ip of 255.255.255.255 */
64 return find_subnet(ipgrp);
67 /****************************************************************************
68 true if two netbios names are equal
69 ****************************************************************************/
70 static BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
72 if (n1->name_type != n2->name_type) return(False);
74 return(strequal(n1->name,n2->name) && strequal(n1->scope,n2->scope));
77 /****************************************************************************
78 add a netbios name into the namelist
79 **************************************************************************/
80 static void add_name(struct subnet_record *d, struct name_record *n)
82 struct name_record *n2;
84 if (!d) return;
86 if (!d->namelist)
88 d->namelist = n;
89 n->prev = NULL;
90 n->next = NULL;
91 return;
94 for (n2 = d->namelist; n2->next; n2 = n2->next) ;
96 n2->next = n;
97 n->next = NULL;
98 n->prev = n2;
101 /****************************************************************************
102 remove a name from the namelist. The pointer must be an element just
103 retrieved
104 **************************************************************************/
105 void remove_name(struct subnet_record *d, struct name_record *n)
107 struct name_record *nlist;
108 if (!d) return;
110 nlist = d->namelist;
112 while (nlist && nlist != n) nlist = nlist->next;
114 if (nlist)
116 if (nlist->next) nlist->next->prev = nlist->prev;
117 if (nlist->prev) nlist->prev->next = nlist->next;
118 free(nlist);
123 /****************************************************************************
124 find a name in a namelist.
125 **************************************************************************/
126 static struct name_record *find_name(struct name_record *n,
127 struct nmb_name *name,
128 int search, struct in_addr ip)
130 struct name_record *ret;
132 for (ret = n; ret; ret = ret->next)
134 if (name_equal(&ret->name,name))
136 /* self search: self names only */
137 if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
138 continue;
140 /* zero ip is either samba's ip or a way of finding a
141 name without needing to know the ip address */
142 if (zero_ip(ip) || ip_equal(ip, ret->ip))
144 return ret;
148 return NULL;
152 /****************************************************************************
153 find a name in the domain database namelist
154 search can be any of:
155 FIND_SELF - look exclusively for names the samba server has added for itself
156 FIND_LOCAL - look for names in the local subnet record.
157 FIND_WINS - look for names in the WINS record
158 **************************************************************************/
159 static struct name_record *find_name_search(struct subnet_record **d,
160 struct nmb_name *name,
161 int search, struct in_addr ip)
163 if (d == NULL) return NULL; /* bad error! */
165 if ((search & FIND_LOCAL) == FIND_LOCAL)
167 if (*d != NULL)
169 return find_name((*d)->namelist, name, search, ip);
171 else
173 DEBUG(4,("local find_name_search with a NULL subnet pointer\n"));
174 return NULL;
178 if ((search & FIND_WINS) != FIND_WINS) return NULL;
180 if (*d == NULL)
182 /* find WINS subnet record */
183 *d = find_subnet(ipgrp);
186 if (*d == NULL) return NULL;
188 return find_name((*d)->namelist, name, search, ip);
192 /****************************************************************************
193 dump a copy of the name table
194 **************************************************************************/
195 void dump_names(void)
197 struct name_record *n;
198 struct subnet_record *d;
199 fstring fname, fnamenew;
200 time_t t = time(NULL);
202 FILE *f;
204 strcpy(fname,lp_lockdir());
205 trim_string(fname,NULL,"/");
206 strcat(fname,"/");
207 strcat(fname,WINS_LIST);
208 strcpy(fnamenew,fname);
209 strcat(fnamenew,".");
211 f = fopen(fnamenew,"w");
213 if (!f)
215 DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
218 DEBUG(3,("Dump of local name table:\n"));
220 for (d = subnetlist; d; d = d->next)
221 for (n = d->namelist; n; n = n->next)
223 if (f && ip_equal(d->bcast_ip, ipgrp) && n->source == REGISTER)
225 fstring data;
227 /* XXXX i have little imagination as to how to output nb_flags as
228 anything other than as a hexadecimal number :-) */
230 sprintf(data, "%s#%02x %s %ld %2x",
231 n->name.name,n->name.name_type, /* XXXX ignore the scope for now */
232 inet_ntoa(n->ip),
233 n->death_time,
234 n->nb_flags);
235 fprintf(f, "%s\n", data);
238 DEBUG(3,("%15s ", inet_ntoa(d->bcast_ip)));
239 DEBUG(3,("%15s ", inet_ntoa(d->mask_ip)));
240 DEBUG(3,("%s %15s TTL=%15d NBFLAGS=%2x\n",
241 namestr(&n->name),
242 inet_ntoa(n->ip),
243 n->death_time?n->death_time-t:0,
244 n->nb_flags));
247 fclose(f);
248 unlink(fname);
249 chmod(fnamenew,0644);
250 rename(fnamenew,fname);
252 DEBUG(3,("Wrote wins database %s\n",fname));
255 /****************************************************************************
256 load a netbios name database file
257 ****************************************************************************/
258 void load_netbios_names(void)
260 struct subnet_record *d = find_subnet(ipgrp);
261 fstring fname;
263 FILE *f;
264 pstring line;
266 if (!d) return;
268 strcpy(fname,lp_lockdir());
269 trim_string(fname,NULL,"/");
270 strcat(fname,"/");
271 strcat(fname,WINS_LIST);
273 f = fopen(fname,"r");
275 if (!f) {
276 DEBUG(2,("Can't open wins database file %s\n",fname));
277 return;
280 while (!feof(f))
282 pstring name_str, ip_str, ttd_str, nb_flags_str;
284 pstring name;
285 int type = 0;
286 int nb_flags;
287 time_t ttd;
288 struct in_addr ipaddr;
290 enum name_source source;
292 char *ptr;
293 int count = 0;
295 char *p;
297 if (!fgets_slash(line,sizeof(pstring),f)) continue;
299 if (*line == '#') continue;
301 ptr = line;
303 if (next_token(&ptr,name_str ,NULL)) ++count;
304 if (next_token(&ptr,ip_str ,NULL)) ++count;
305 if (next_token(&ptr,ttd_str ,NULL)) ++count;
306 if (next_token(&ptr,nb_flags_str,NULL)) ++count;
308 if (count <= 0) continue;
310 if (count != 4) {
311 DEBUG(0,("Ill formed wins line"));
312 DEBUG(0,("[%s]: name#type ip nb_flags abs_time\n",line));
313 continue;
316 /* netbios name. # divides the name from the type (hex): netbios#xx */
317 strcpy(name,name_str);
319 p = strchr(name,'#');
321 if (p) {
322 *p = 0;
323 sscanf(p+1,"%x",&type);
326 /* decode the netbios flags (hex) and the time-to-die (seconds) */
327 sscanf(nb_flags_str,"%x",&nb_flags);
328 sscanf(ttd_str,"%ld",&ttd);
330 ipaddr = *interpret_addr2(ip_str);
332 if (ip_equal(ipaddr,ipzero)) {
333 source = SELF;
335 else
337 source = REGISTER;
340 DEBUG(4, ("add WINS line: %s#%02x %s %ld %2x\n",
341 name,type, inet_ntoa(ipaddr), ttd, nb_flags));
343 /* add all entries that have 60 seconds or more to live */
344 if (ttd - 10 < time(NULL) || ttd == 0)
346 time_t t = (ttd?ttd-time(NULL):0) / 3;
348 /* add netbios entry read from the wins.dat file. IF it's ok */
349 add_netbios_entry(d,name,type,nb_flags,t,source,ipaddr,True,True);
353 fclose(f);
357 /****************************************************************************
358 remove an entry from the name list
359 ****************************************************************************/
360 void remove_netbios_name(struct subnet_record *d,
361 char *name,int type, enum name_source source,
362 struct in_addr ip)
364 struct nmb_name nn;
365 struct name_record *n;
366 int search = FIND_LOCAL;
368 /* if it's not a special browser name, search the WINS database */
369 if (type != 0x01 && type != 0x1d && type != 0x1e)
370 search |= FIND_WINS;
372 make_nmb_name(&nn, name, type, scope);
373 n = find_name_search(&d, &nn, search, ip);
375 if (n && n->source == source) remove_name(d,n);
379 /****************************************************************************
380 add an entry to the name list.
382 this is a multi-purpose function.
384 it adds samba's own names in to its records on each interface, keeping a
385 record of whether it is a master browser, domain master, or WINS server.
387 it also keeps a record of WINS entries (names of type 0x00, 0x20, 0x03 etc)
389 ****************************************************************************/
390 struct name_record *add_netbios_entry(struct subnet_record *d,
391 char *name, int type, int nb_flags,
392 int ttl, enum name_source source, struct in_addr ip,
393 BOOL new_only,BOOL wins)
395 struct name_record *n;
396 struct name_record *n2=NULL;
397 int search = 0;
398 BOOL self = source == SELF;
400 /* add the name to the WINS list if the name comes from a directed query */
401 search |= wins ? FIND_WINS : FIND_LOCAL;
402 /* search for SELF names only */
403 search |= self ? FIND_SELF : 0;
405 if (!self)
407 if (wins)
409 if (type == 0x01 || type == 0x1d || type == 0x1e)
411 /* XXXX WINS server supposed to ignore special browser names. hm.
412 but is a primary domain controller supposed to ignore special
413 browser names? luke doesn't think so, but can't test it! :-)
415 return NULL;
418 else /* !wins */
420 /* the only broadcast (non-WINS) names we are adding are ours (SELF) */
421 return NULL;
425 n = (struct name_record *)malloc(sizeof(*n));
426 if (!n) return(NULL);
428 bzero((char *)n,sizeof(*n));
430 make_nmb_name(&n->name,name,type,scope);
432 if ((n2 = find_name_search(&d, &n->name, search, new_only?ipzero:ip)))
434 free(n);
435 if (new_only || (n2->source==SELF && source!=SELF)) return n2;
436 n = n2;
439 if (ttl)
440 n->death_time = time(NULL)+ttl*3;
441 n->refresh_time = time(NULL)+GET_TTL(ttl);
443 n->ip = ip;
444 n->nb_flags = nb_flags;
445 n->source = source;
447 if (!n2) add_name(d,n);
449 DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x\n",
450 namestr(&n->name),inet_ntoa(ip),ttl,nb_flags));
452 return(n);
456 /****************************************************************************
457 remove an entry from the name list
458 ****************************************************************************/
459 void remove_name_entry(struct subnet_record *d, char *name,int type)
461 /* XXXX BUG: if samba is offering WINS support, it should still broadcast
462 a de-registration packet to the local subnet before removing the
463 name from its local-subnet name database. */
465 if (lp_wins_support())
467 /* we are a WINS server. */
468 /* XXXX assume that if we are a WINS server that we are therefore
469 not pointing to another WINS server as well. this may later NOT
470 actually be true */
471 remove_netbios_name(d,name,type,SELF,ipzero);
473 else
475 /* not a WINS server: cannot just remove our own names: we have to
476 ask permission from the WINS server, or if no reply is received,
477 _then_ we can remove the name */
479 struct name_record n;
480 struct name_record *n2=NULL;
482 make_nmb_name(&n.name,name,type,scope);
484 if ((n2 = find_name_search(&d, &n.name, FIND_SELF, ipzero)))
486 /* check name isn't already being de-registered */
487 if (NAME_DEREG(n2->nb_flags))
488 return;
490 /* mark the name as in the process of deletion. */
491 n2->nb_flags &= NB_DEREG;
493 queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
494 name, type, 0, 0,
495 False, True, ipzero);
500 /****************************************************************************
501 add an entry to the name list
502 ****************************************************************************/
503 void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
505 BOOL re_reg = False;
506 struct nmb_name n;
508 if (!d) return;
510 /* not that it particularly matters, but if the SELF name already exists,
511 it must be re-registered, rather than just registered */
513 make_nmb_name(&n, name, type, scope);
514 if (find_name(d->namelist, &n, SELF, ipzero))
515 re_reg = True;
517 /* always add our own entries */
518 add_netbios_entry(d,name,type,nb_flags,0,SELF,ipzero,False,lp_wins_support());
520 /* XXXX BUG: if samba is offering WINS support, it should still add the
521 name entry to a local-subnet name database. see rfc1001.txt 15.1.1 p28
522 regarding the point about M-nodes. */
524 if (!lp_wins_support())
526 /* samba isn't supporting WINS itself: register the name using broadcast
527 or with another WINS server.
528 XXXX note: we may support WINS and also know about other WINS servers
529 in the future.
532 queue_netbios_pkt_wins(d,ClientNMB,
533 re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
534 name, type, nb_flags, GET_TTL(0),
535 False, True, ipzero);
540 /****************************************************************************
541 add the magic samba names, useful for finding samba servers
542 **************************************************************************/
543 void add_my_names(void)
545 BOOL wins = lp_wins_support();
546 struct subnet_record *d;
548 struct in_addr ip = ipzero;
550 /* each subnet entry, including WINS pseudo-subnet, has SELF names */
552 /* XXXX if there was a transport layer added to samba (ipx/spx etc) then
553 there would be yet _another_ for-loop, this time on the transport type
556 for (d = subnetlist; d; d = d->next)
558 add_my_name_entry(d, myname,0x20,NB_ACTIVE);
559 add_my_name_entry(d, myname,0x03,NB_ACTIVE);
560 add_my_name_entry(d, myname,0x00,NB_ACTIVE);
561 add_my_name_entry(d, myname,0x1f,NB_ACTIVE);
563 add_netbios_entry(d,"*",0x0,NB_ACTIVE,0,SELF,ip,False,wins);
564 add_netbios_entry(d,"__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False,wins);
565 add_netbios_entry(d,"__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False,wins);
567 if (wins) {
568 /* the 0x1c name gets added by any WINS server it seems */
569 add_my_name_entry(d, my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP);
575 /****************************************************************************
576 remove all the samba names... from a WINS server if necessary.
577 **************************************************************************/
578 void remove_my_names()
580 struct subnet_record *d;
582 for (d = subnetlist; d; d = d->next)
584 struct name_record *n, *next;
586 for (n = d->namelist; n; n = next)
588 next = n->next;
589 if (n->source == SELF)
591 /* get all SELF names removed from the WINS server's database */
592 /* XXXX note: problem occurs if this removes the wrong one! */
594 remove_name_entry(d,n->name.name, n->name.name_type);
601 /*******************************************************************
602 refresh my own names
603 ******************************************************************/
604 void refresh_my_names(time_t t)
606 struct subnet_record *d;
608 for (d = subnetlist; d; d = d->next)
610 struct name_record *n;
612 for (n = d->namelist; n; n = n->next)
614 /* each SELF name has an individual time to be refreshed */
615 if (n->source == SELF && n->refresh_time < time(NULL))
617 add_my_name_entry(d,n->name.name,n->name.name_type,n->nb_flags);
623 /*******************************************************************
624 queries names occasionally. an over-cautious, non-trusting WINS server!
626 this function has been added because nmbd could be restarted. it
627 is generally a good idea to check all the names that have been
628 reloaded from file.
630 XXXX which names to poll and which not can be refined at a later date.
631 ******************************************************************/
632 void query_refresh_names(void)
634 struct name_record *n;
635 struct subnet_record *d = find_subnet(ipgrp);
637 static time_t lasttime = 0;
638 time_t t = time(NULL);
640 int count = 0;
641 int name_refresh_time = NAME_POLL_REFRESH_TIME;
642 int max_count = name_refresh_time * 2 / NAME_POLL_INTERVAL;
643 if (max_count > 10) max_count = 10;
645 name_refresh_time = NAME_POLL_INTERVAL * max_count / 2;
647 /* if (!lp_poll_wins()) return; polling of registered names allowed */
649 if (!d) return;
651 if (t - lasttime < NAME_POLL_INTERVAL) return;
653 for (n = d->namelist; n; n = n->next)
655 /* only do unique, registered names */
657 if (n->source != REGISTER) continue;
658 if (!NAME_GROUP(n->nb_flags)) continue;
660 if (n->refresh_time < t)
662 DEBUG(3,("Polling name %s\n", namestr(&n->name)));
664 queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_CONFIRM,
665 n->name.name, n->name.name_type,
666 0,0,
667 False,False,n->ip);
668 count++;
671 if (count >= max_count)
673 /* don't do too many of these at once, but do enough to
674 cover everyone in the list */
675 return;
678 /* this name will be checked on again, if it's not removed */
679 n->refresh_time += name_refresh_time;
684 /*******************************************************************
685 expires old names in the namelist
686 ******************************************************************/
687 void expire_names(time_t t)
689 struct name_record *n;
690 struct name_record *next;
691 struct subnet_record *d;
693 /* expire old names */
694 for (d = subnetlist; d; d = d->next)
696 for (n = d->namelist; n; n = next)
698 if (n->death_time && n->death_time < t)
700 DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
702 next = n->next;
704 if (n->prev) n->prev->next = n->next;
705 if (n->next) n->next->prev = n->prev;
707 if (d->namelist == n) d->namelist = n->next;
709 free(n);
711 else
713 next = n->next;
720 /****************************************************************************
721 response for a reg release received. samba has asked a WINS server if it
722 could release a name.
723 **************************************************************************/
724 void response_name_release(struct subnet_record *d, struct packet_struct *p)
726 struct nmb_packet *nmb = &p->packet.nmb;
727 char *name = nmb->question.question_name.name;
728 int type = nmb->question.question_name.name_type;
730 DEBUG(4,("response name release received\n"));
732 if (nmb->header.rcode == 0 && nmb->answers->rdata)
734 /* IMPORTANT: see expire_netbios_response_entries() */
736 struct in_addr found_ip;
737 putip((char*)&found_ip,&nmb->answers->rdata[2]);
739 if (ismyip(found_ip))
741 remove_netbios_name(d,name,type,SELF,found_ip);
744 else
746 DEBUG(2,("name release for %s rejected!\n",
747 namestr(&nmb->question.question_name)));
749 /* XXXX do we honestly care if our name release was rejected?
750 only if samba is issuing the release on behalf of some out-of-sync
751 server. if it's one of samba's SELF names, we don't care. */
756 /****************************************************************************
757 reply to a name release
758 ****************************************************************************/
759 void reply_name_release(struct packet_struct *p)
761 struct nmb_packet *nmb = &p->packet.nmb;
762 struct in_addr ip;
763 int rcode=0;
764 int opcode = nmb->header.opcode;
765 int nb_flags = nmb->additional->rdata[0];
766 BOOL bcast = nmb->header.nm_flags.bcast;
767 struct name_record *n;
768 struct subnet_record *d = NULL;
769 char rdata[6];
770 int search = 0;
772 putip((char *)&ip,&nmb->additional->rdata[2]);
774 DEBUG(3,("Name release on name %s rcode=%d\n",
775 namestr(&nmb->question.question_name),rcode));
777 if (!(d = find_req_subnet(p->ip, bcast)))
779 DEBUG(3,("response packet: bcast %s not known\n",
780 inet_ntoa(p->ip)));
781 return;
784 if (bcast)
785 search &= FIND_LOCAL;
786 else
787 search &= FIND_WINS;
789 n = find_name_search(&d, &nmb->question.question_name,
790 search, ip);
792 /* XXXX under what conditions should we reject the removal?? */
793 if (n && n->nb_flags == nb_flags)
795 /* success = True;
796 rcode = 6; */
798 remove_name(d,n);
799 n = NULL;
802 if (bcast) return;
804 rdata[0] = nb_flags;
805 rdata[1] = 0;
806 putip(&rdata[2],(char *)&ip);
808 /* Send a NAME RELEASE RESPONSE */
809 reply_netbios_packet(p,nmb->header.name_trn_id,
810 rcode,opcode,True,
811 &nmb->question.question_name,
812 nmb->question.question_type,
813 nmb->question.question_class,
815 rdata, 6);
819 /****************************************************************************
820 response for a reg request received
821 **************************************************************************/
822 void response_name_reg(struct subnet_record *d, struct packet_struct *p)
824 struct nmb_packet *nmb = &p->packet.nmb;
825 char *name = nmb->question.question_name.name;
826 int type = nmb->question.question_name.name_type;
827 BOOL bcast = nmb->header.nm_flags.bcast;
829 DEBUG(4,("response name registration received!\n"));
831 if (nmb->header.rcode == 0 && nmb->answers->rdata)
833 /* IMPORTANT: see expire_netbios_response_entries() */
835 int nb_flags = nmb->answers->rdata[0];
836 struct in_addr found_ip;
837 int ttl = nmb->answers->ttl;
838 enum name_source source = REGISTER;
840 putip((char*)&found_ip,&nmb->answers->rdata[2]);
842 if (ismyip(found_ip)) source = SELF;
844 add_netbios_entry(d, name,type,nb_flags,ttl,source,found_ip,True,!bcast);
846 else
848 struct work_record *work;
850 DEBUG(1,("name registration for %s rejected!\n",
851 namestr(&nmb->question.question_name)));
853 /* XXXX oh dear. we have problems. must deal with our name having
854 been rejected: e.g if it was our GROUP(1d) name, we must unbecome
855 a master browser. */
857 remove_netbios_name(d,name,type,SELF,ipzero);
859 if (!(work = find_workgroupstruct(d, name, False))) return;
861 if (AM_MASTER(work) && (type == 0x1d || type == 0x1b))
863 int remove_type = 0;
864 if (type == 0x1d) remove_type = SV_TYPE_MASTER_BROWSER;
865 if (type == 0x1b) remove_type = SV_TYPE_DOMAIN_MASTER;
867 become_nonmaster(d, work, remove_type);
873 /****************************************************************************
874 reply to a reg request
875 **************************************************************************/
876 void reply_name_reg(struct packet_struct *p)
878 struct nmb_packet *nmb = &p->packet.nmb;
879 struct nmb_name *question = &nmb->question.question_name;
881 struct nmb_name *reply_name = question;
882 char *qname = question->name;
883 int name_type = question->name_type;
884 int name_class = nmb->question.question_class;
886 BOOL bcast = nmb->header.nm_flags.bcast;
888 int ttl = GET_TTL(nmb->additional->ttl);
889 int nb_flags = nmb->additional->rdata[0];
890 BOOL group = NAME_GROUP(nb_flags);
891 int rcode = 0;
892 int opcode = nmb->header.opcode;
894 struct subnet_record *d = NULL;
895 struct name_record *n = NULL;
896 BOOL success = True;
897 BOOL recurse = True; /* true if samba replies yes/no: false if caller */
898 /* must challenge the current owner of the unique name */
899 char rdata[6];
900 struct in_addr ip, from_ip;
901 int search = 0;
903 putip((char *)&from_ip,&nmb->additional->rdata[2]);
904 ip = from_ip;
906 DEBUG(3,("Name registration for name %s at %s rcode=%d\n",
907 namestr(question),inet_ntoa(ip),rcode));
909 if (group)
911 /* apparently we should return 255.255.255.255 for group queries
912 (email from MS) */
913 ip = ipgrp;
916 if (!(d = find_req_subnet(p->ip, bcast)))
918 DEBUG(3,("response packet: bcast %s not known\n",
919 inet_ntoa(p->ip)));
920 return;
923 if (bcast)
924 search &= FIND_LOCAL;
925 else
926 search &= FIND_WINS;
928 /* see if the name already exists */
929 n = find_name_search(&d, question, search, from_ip);
931 if (n)
933 if (!group) /* unique names */
935 if (n->source == SELF || NAME_GROUP(n->nb_flags))
937 /* no-one can register one of samba's names, nor can they
938 register a name that's a group name as a unique name */
940 rcode = 6;
941 success = False;
943 else if(!ip_equal(ip, n->ip))
945 /* hm. this unique name doesn't belong to them. */
947 /* XXXX rfc1001.txt says:
948 * if we are doing secured WINS, we must send a Wait-Acknowledge
949 * packet (WACK) to the person who wants the name, then do a
950 * name query on the person who currently owns the unique name.
951 * if the current owner still says they own it, the person who wants
952 * the name can't have it. if they do not, or are not alive, they can.
954 * if we are doing non-secured WINS (which is much simpler) then
955 * we send a message to the person wanting the name saying 'he
956 * owns this name: i don't want to hear from you ever again
957 * until you've checked with him if you can have it!'. we then
958 * abandon the registration. once the person wanting the name
959 * has checked with the current owner, they will repeat the
960 * registration packet if the current owner is dead or doesn't
961 * want the name.
964 /* non-secured WINS implementation: caller is responsible
965 for checking with current owner of name, then getting back
966 to us... IF current owner no longer owns the unique name */
968 /* XXXX please note also that samba cannot cope with
969 _receiving_ such redirecting, non-secured registration
970 packets. code to do this needs to be added.
973 rcode = 0;
974 success = False;
975 recurse = False;
977 /* we inform on the current owner to the caller (which is
978 why it's non-secure */
980 reply_name = &n->name;
982 /* name_type = ?;
983 name_class = ?;
984 XXXX sorry, guys: i really can't see what name_type
985 and name_class should be set to according to rfc1001 */
987 else
989 n->ip = ip;
990 n->death_time = ttl?p->timestamp+ttl*3:0;
991 DEBUG(3,("%s owner: %s\n",namestr(&n->name),inet_ntoa(n->ip)));
994 else
996 /* refresh the name */
997 if (n->source != SELF)
999 n->death_time = ttl?p->timestamp + ttl*3:0;
1003 /* XXXX bug reported by terryt@ren.pc.athabascau.ca */
1004 /* names that people have checked for and not found get DNSFAILed.
1005 we need to update the name record if someone then registers */
1007 if (n->source == DNSFAIL)
1008 n->source = REGISTER;
1011 else
1013 /* add the name to our name/subnet, or WINS, database */
1014 n = add_netbios_entry(d,qname,name_type,nb_flags,ttl,REGISTER,ip,
1015 True,!bcast);
1018 /* if samba owns a unique name on a subnet, then it must respond and
1019 disallow the attempted registration. if the registration is
1020 successful by broadcast, only then is there no need to respond
1021 (implicit registration: see rfc1001.txt 15.2.1).
1024 if (bcast || !success) return;
1026 rdata[0] = nb_flags;
1027 rdata[1] = 0;
1028 putip(&rdata[2],(char *)&ip);
1030 /* Send a NAME REGISTRATION RESPONSE (pos/neg)
1031 or an END-NODE CHALLENGE REGISTRATION RESPONSE */
1032 reply_netbios_packet(p,nmb->header.name_trn_id,
1033 rcode,opcode,recurse,
1034 reply_name, name_type, name_class,
1035 ttl,
1036 rdata, 6);
1040 /****************************************************************************
1041 reply to a name status query
1042 ****************************************************************************/
1043 void reply_name_status(struct packet_struct *p)
1045 struct nmb_packet *nmb = &p->packet.nmb;
1046 char *qname = nmb->question.question_name.name;
1047 int ques_type = nmb->question.question_name.name_type;
1048 char rdata[MAX_DGRAM_SIZE];
1049 char *countptr, *buf, *bufend;
1050 int names_added;
1051 struct name_record *n;
1052 struct subnet_record *d = NULL;
1054 BOOL bcast = nmb->header.nm_flags.bcast;
1056 if (!(d = find_req_subnet(p->ip, bcast)))
1058 DEBUG(3,("Name status req: bcast %s not known\n",
1059 inet_ntoa(p->ip)));
1060 return;
1063 DEBUG(3,("Name status for name %s %s\n",
1064 namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
1066 n = find_name_search(&d, &nmb->question.question_name,
1067 FIND_SELF|FIND_LOCAL,
1068 p->ip);
1070 if (!n) return;
1072 /* XXXX hack, we should calculate exactly how many will fit */
1073 bufend = &rdata[MAX_DGRAM_SIZE] - 18;
1074 countptr = buf = rdata;
1075 buf += 1;
1077 names_added = 0;
1079 for (n = d->namelist ; n && buf < bufend; n = n->next)
1081 int name_type = n->name.name_type;
1083 if (n->source != SELF) continue;
1085 /* start with first bit of putting info in buffer: the name */
1087 bzero(buf,18);
1088 sprintf(buf,"%-15.15s",n->name.name);
1089 strupper(buf);
1091 /* now check if we want to exclude other workgroup names
1092 from the response. if we don't exclude them, windows clients
1093 get confused and will respond with an error for NET VIEW */
1095 if (name_type >= 0x1b && name_type <= 0x20 &&
1096 ques_type >= 0x1b && ques_type <= 0x20)
1098 if (!strequal(qname, n->name.name)) continue;
1101 /* carry on putting name info in buffer */
1103 buf[15] = name_type;
1104 buf[16] = n->nb_flags;
1106 buf += 18;
1108 names_added++;
1111 SCVAL(countptr,0,names_added);
1113 /* XXXXXXX we should fill in more fields of the statistics structure */
1114 bzero(buf,64);
1116 extern int num_good_sends,num_good_receives;
1117 SIVAL(buf,20,num_good_sends);
1118 SIVAL(buf,24,num_good_receives);
1121 SIVAL(buf,46,0xFFB8E5); /* undocumented - used by NT */
1123 buf += 64;
1125 /* Send a POSITIVE NAME STATUS RESPONSE */
1126 reply_netbios_packet(p,nmb->header.name_trn_id,
1127 0,0,True,
1128 &nmb->question.question_name,
1129 nmb->question.question_type,
1130 nmb->question.question_class,
1132 rdata,PTR_DIFF(buf,rdata));
1136 /***************************************************************************
1137 reply to a name query
1138 ****************************************************************************/
1139 struct name_record *search_for_name(struct subnet_record **d,
1140 struct nmb_name *question,
1141 struct in_addr ip, int Time, int search)
1143 int name_type = question->name_type;
1144 char *qname = question->name;
1145 BOOL dns_type = name_type == 0x20 || name_type == 0;
1147 struct name_record *n;
1149 DEBUG(3,("Search for %s from %s - ", namestr(question), inet_ntoa(ip)));
1151 /* first look up name in cache */
1152 n = find_name_search(d,question,search,ip);
1154 if (*d == NULL) return NULL;
1156 /* now try DNS lookup. */
1157 if (!n)
1159 struct in_addr dns_ip;
1160 unsigned long a;
1162 /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
1163 if (!dns_type)
1165 DEBUG(3,("types 0x20 0x1b 0x0 only: name not found\n"));
1166 return NULL;
1169 /* look it up with DNS */
1170 a = interpret_addr(qname);
1172 putip((char *)&dns_ip,(char *)&a);
1174 if (!a)
1176 /* no luck with DNS. We could possibly recurse here XXXX */
1177 DEBUG(3,("no recursion.\n"));
1178 /* add the fail to our WINS cache of names. give it 1 hour in the cache */
1179 add_netbios_entry(*d,qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip,
1180 True, True);
1181 return NULL;
1184 /* add it to our WINS cache of names. give it 2 hours in the cache */
1185 n = add_netbios_entry(*d,qname,name_type,NB_ACTIVE,2*60*60,DNS,dns_ip,
1186 True,True);
1188 /* failed to add it? yikes! */
1189 if (!n) return NULL;
1192 /* is our entry already dead? */
1193 if (n->death_time)
1195 if (n->death_time < Time) return False;
1198 /* it may have been an earlier failure */
1199 if (n->source == DNSFAIL)
1201 DEBUG(3,("DNSFAIL\n"));
1202 return NULL;
1205 DEBUG(3,("OK %s\n",inet_ntoa(n->ip)));
1207 return n;
1211 /***************************************************************************
1212 reply to a name query.
1214 with broadcast name queries:
1216 - only reply if the query is for one of YOUR names. all other machines on
1217 the network will be doing the same thing (that is, only replying to a
1218 broadcast query if they own it)
1219 NOTE: broadcast name queries should only be sent out by a machine
1220 if they HAVEN'T been configured to use WINS. this is generally bad news
1221 in a wide area tcp/ip network and should be rectified by the systems
1222 administrator. USE WINS! :-)
1223 - the exception to this is if the query is for a Primary Domain Controller
1224 type name (0x1b), in which case, a reply is sent.
1226 - NEVER send a negative response to a broadcast query. no-one else will!
1228 with directed name queries:
1230 - if you are the WINS server, you are expected to respond with either
1231 a negative response, a positive response, or a wait-for-acknowledgement
1232 packet, and then later on a pos/neg response.
1234 ****************************************************************************/
1235 void reply_name_query(struct packet_struct *p)
1237 struct nmb_packet *nmb = &p->packet.nmb;
1238 struct nmb_name *question = &nmb->question.question_name;
1239 int name_type = question->name_type;
1240 BOOL bcast = nmb->header.nm_flags.bcast;
1241 int ttl=0;
1242 int rcode = 0;
1243 int nb_flags = 0;
1244 struct in_addr retip;
1245 char rdata[6];
1246 struct subnet_record *d = NULL;
1248 BOOL success = True;
1250 struct name_record *n;
1251 int search = 0;
1253 if (name_type == 0x20 || name_type == 0x00 || name_type == 0x1b ||
1254 name_type == 0x1f || name_type == 0x03 || name_type == 0x01 ||
1255 name_type == 0x1c)
1257 /* search for any of the non-'special browser' names, or for a PDC type
1258 (0x1b) name in the WINS database.
1259 XXXX should we include name type 0x1c: WINS server type?
1261 search |= FIND_WINS;
1263 else
1265 /* special browser name types e.g
1266 ^1^2__MSBROWSE__^2^1, GROUP(1d) and GROUP(1e)
1268 name_type == 0x01 || name_type == 0x1d || name_type == 0x1e.
1270 XXXX luke reckons we should be able to search for any SELF name
1271 in the WINS database, if we are a primary domain controller.
1274 if (!(d = find_req_subnet(p->ip, bcast)))
1276 DEBUG(3,("name query: bcast %s not known\n",
1277 inet_ntoa(p->ip)));
1278 success = False;
1281 /* XXXX delete if shouldn't search for SELF names in WINS database */
1282 search |= FIND_WINS;
1285 if (bcast)
1287 /* a name query has been made by a non-WINS configured host. search the
1288 local interface database as well */
1289 search |= FIND_LOCAL;
1292 DEBUG(3,("Name query "));
1294 if (search == 0)
1296 /* eh? no criterion for searching database. help! */
1297 success = False;
1300 if (success && (n = search_for_name(&d,question,p->ip,p->timestamp, search)))
1302 /* don't respond to broadcast queries unless the query is for
1303 a name we own or it is for a Primary Domain Controller name */
1305 if (bcast && n->source != SELF && name_type != 0x1b) {
1306 if (!lp_wins_proxy() || same_net(p->ip,n->ip,*iface_nmask(p->ip))) {
1307 /* never reply with a negative response to broadcast queries */
1308 return;
1312 /* name is directed query, or it's self, or it's a PDC type name, or
1313 we're replying on behalf of a caller because they are on a different
1314 subnet and cannot hear the broadcast. XXXX lp_wins_proxy should be
1315 switched off in environments where broadcasts are forwarded */
1317 /* XXXX note: for proxy servers, we should forward the query on to
1318 another WINS server if the name is not in our database, or we are
1319 not a WINS server ourselves
1321 ttl = n->death_time - p->timestamp;
1322 retip = n->ip;
1323 nb_flags = n->nb_flags;
1325 else
1327 if (bcast) return; /* never reply negative response to bcasts */
1328 success = False;
1331 /* if the IP is 0 then substitute my IP */
1332 if (zero_ip(retip)) retip = *iface_ip(p->ip);
1334 if (success)
1336 rcode = 0;
1337 DEBUG(3,("OK %s\n",inet_ntoa(retip)));
1339 else
1341 rcode = 3;
1342 DEBUG(3,("UNKNOWN\n"));
1345 if (success)
1347 rdata[0] = nb_flags;
1348 rdata[1] = 0;
1349 putip(&rdata[2],(char *)&retip);
1352 reply_netbios_packet(p,nmb->header.name_trn_id,
1353 rcode,0,True,
1354 &nmb->question.question_name,
1355 nmb->question.question_type,
1356 nmb->question.question_class,
1357 ttl,
1358 rdata, success ? 6 : 0);
1362 /****************************************************************************
1363 response from a name query server check. commands of type NAME_QUERY_MST_SRV_CHK,
1364 NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
1365 ****************************************************************************/
1366 static void response_server_check(struct nmb_name *ans_name,
1367 struct response_record *n, struct subnet_record *d)
1369 /* issue another command: this time to do a name status check */
1371 enum cmd_type cmd = (n->cmd_type == NAME_QUERY_MST_SRV_CHK) ?
1372 NAME_STATUS_MASTER_CHECK : NAME_STATUS_CHECK;
1374 /* initiate a name status check on the server that replied */
1375 queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
1376 ans_name->name, ans_name->name_type,
1377 0,0,
1378 False,False,n->to_ip);
1381 /****************************************************************************
1382 response from a name status check. commands of type NAME_STATUS_MASTER_CHECK
1383 and NAME_STATUS_CHECK dealt with here.
1384 ****************************************************************************/
1385 static void response_name_status_check(struct in_addr ip,
1386 struct nmb_packet *nmb, BOOL bcast,
1387 struct response_record *n, struct subnet_record *d)
1389 /* NMB_STATUS arrives: contains workgroup name and server name required.
1390 amongst other things. */
1392 struct nmb_name name;
1393 fstring serv_name;
1395 if (interpret_node_status(d,nmb->answers->rdata,
1396 &name,0x1d,serv_name,ip,bcast))
1398 if (*serv_name)
1400 sync_server(n->cmd_type,serv_name,
1401 name.name,name.name_type, n->to_ip);
1404 else
1406 DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
1411 /****************************************************************************
1412 response from a name query to sync browse lists or to update our netbios
1413 entry. commands of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM
1414 ****************************************************************************/
1415 static void response_name_query_sync(struct nmb_packet *nmb,
1416 struct nmb_name *ans_name, BOOL bcast,
1417 struct response_record *n, struct subnet_record *d)
1419 DEBUG(4, ("Name query at %s ip %s - ",
1420 namestr(&n->name), inet_ntoa(n->to_ip)));
1422 if (!name_equal(n->name, ans_name))
1424 /* someone gave us the wrong name as a reply. oops. */
1425 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
1426 return;
1429 if (nmb->header.rcode == 0 && nmb->answers->rdata)
1431 int nb_flags = nmb->answers->rdata[0];
1432 struct in_addr found_ip;
1434 putip((char*)&found_ip,&nmb->answers->rdata[2]);
1436 if (!ip_equal(n->ip, found_ip))
1438 /* someone gave us the wrong ip as a reply. oops. */
1439 DEBUG(4,("expected ip: %s\n", inet_ntoa(n->ip)));
1440 DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
1441 return;
1444 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
1446 if (n->cmd_type == NAME_QUERY_SYNC)
1448 struct work_record *work = NULL;
1449 if ((work = find_workgroupstruct(d, ans_name->name, False)))
1451 /* the server is there: sync quick before it (possibly) dies! */
1452 sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
1453 found_ip);
1456 else
1458 /* update our netbios name list (re-register it if necessary) */
1459 add_netbios_entry(d, ans_name->name, ans_name->name_type,
1460 nb_flags,GET_TTL(0),REGISTER,
1461 found_ip,False,!bcast);
1464 else
1466 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
1468 if (n->cmd_type == NAME_QUERY_CONFIRM)
1470 /* XXXX remove_netbios_entry()? */
1471 /* lots of things we ought to do, here. if we get here,
1472 then we're in a mess: our name database doesn't match
1473 reality. sort it out
1475 remove_netbios_name(d,n->name.name, n->name.name_type,
1476 REGISTER,n->ip);
1481 /****************************************************************************
1482 report the response record type
1483 ****************************************************************************/
1484 static void debug_rr_type(int rr_type)
1486 switch (rr_type)
1488 case NMB_STATUS: DEBUG(3,("Name status ")); break;
1489 case NMB_QUERY : DEBUG(3,("Name query ")); break;
1490 case NMB_REG : DEBUG(3,("Name registration ")); break;
1491 case NMB_REL : DEBUG(3,("Name release ")); break;
1492 default : DEBUG(1,("wrong response packet type received")); break;
1496 /****************************************************************************
1497 report the response record nmbd command type
1498 ****************************************************************************/
1499 static void debug_cmd_type(int cmd_type)
1501 /* report the command type to help debugging */
1502 switch (cmd_type)
1504 case NAME_QUERY_MST_SRV_CHK : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
1505 case NAME_QUERY_SRV_CHK : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
1506 case NAME_QUERY_FIND_MST : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
1507 case NAME_STATUS_MASTER_CHECK: DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
1508 case NAME_STATUS_CHECK : DEBUG(4,("NAME_STATUS_CHECK\n")); break;
1509 case NAME_QUERY_MST_CHK : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
1510 case NAME_REGISTER : DEBUG(4,("NAME_REGISTER\n")); break;
1511 case NAME_RELEASE : DEBUG(4,("NAME_RELEASE\n")); break;
1512 case NAME_QUERY_CONFIRM : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
1513 case NAME_QUERY_SYNC : DEBUG(4,("NAME_QUERY_SYNC\n")); break;
1514 default: break;
1518 /****************************************************************************
1519 report any problems with the fact that a response has been received.
1521 (responses for certain types of operations are only expected from one host)
1522 ****************************************************************************/
1523 static BOOL response_problem_check(struct response_record *n,
1524 struct nmb_packet *nmb, char *qname)
1526 switch (nmb->answers->rr_type)
1528 case NMB_REL:
1530 if (n->num_msgs > 1)
1532 DEBUG(1,("more than one release name response received!\n"));
1533 return True;
1535 break;
1538 case NMB_REG:
1540 if (n->num_msgs > 1)
1542 DEBUG(1,("more than one register name response received!\n"));
1543 return True;
1545 break;
1548 case NMB_QUERY:
1550 if (n->num_msgs > 1)
1552 if (nmb->header.rcode == 0 && nmb->answers->rdata)
1554 int nb_flags = nmb->answers->rdata[0];
1556 if ((!NAME_GROUP(nb_flags)))
1558 /* oh dear. more than one person responded to a unique name.
1559 there is either a network problem, a configuration problem
1560 or a server is mis-behaving */
1562 /* XXXX mark the name as in conflict, and then let the
1563 person who just responded know that they must also mark it
1564 as in conflict, and therefore must NOT use it.
1565 see rfc1001.txt 15.1.3.5 */
1567 /* this may cause problems for some early versions of nmbd */
1569 switch (n->cmd_type)
1571 case NAME_QUERY_MST_SRV_CHK:
1572 case NAME_QUERY_SRV_CHK:
1573 case NAME_QUERY_MST_CHK:
1574 /* don't do case NAME_QUERY_FIND_MST: MSBROWSE isn't a unique name. */
1576 if (!strequal(qname,n->name.name))
1578 /* one subnet, one master browser per workgroup */
1579 /* XXXX force an election? */
1581 DEBUG(3,("more than one master browser replied!\n"));
1582 return True;
1584 break;
1586 default: break;
1588 DEBUG(3,("Unique Name conflict detected!\n"));
1589 return True;
1592 else
1594 /* we have received a negative reply, having already received
1595 at least one response (pos/neg). something's really wrong! */
1597 DEBUG(3,("wierd name query problem detected!\n"));
1598 return True;
1603 return False;
1606 /****************************************************************************
1607 check that the response received is compatible with the response record
1608 ****************************************************************************/
1609 static BOOL response_compatible(struct response_record *n,
1610 struct nmb_packet *nmb)
1612 switch (n->cmd_type)
1614 case NAME_RELEASE:
1616 if (nmb->answers->rr_type != NMB_REL)
1618 DEBUG(1,("Name release reply has wrong answer rr_type\n"));
1619 return False;
1621 break;
1624 case NAME_REGISTER:
1626 if (nmb->answers->rr_type != NMB_REG)
1628 DEBUG(1,("Name register reply has wrong answer rr_type\n"));
1629 return False;
1631 break;
1634 case NAME_QUERY_CONFIRM:
1635 case NAME_QUERY_SYNC:
1636 case NAME_QUERY_MST_SRV_CHK:
1637 case NAME_QUERY_SRV_CHK:
1638 case NAME_QUERY_FIND_MST:
1639 case NAME_QUERY_MST_CHK:
1641 if (nmb->answers->rr_type != NMB_QUERY)
1643 DEBUG(1,("Name query reply has wrong answer rr_type\n"));
1644 return False;
1646 break;
1649 case NAME_STATUS_MASTER_CHECK:
1650 case NAME_STATUS_CHECK:
1652 if (nmb->answers->rr_type != NMB_STATUS)
1654 DEBUG(1,("Name status reply has wrong answer rr_type\n"));
1655 return False;
1657 break;
1660 default:
1662 DEBUG(0,("unknown command received in response_netbios_packet\n"));
1663 break;
1666 return True;
1670 /****************************************************************************
1671 process the response packet received
1672 ****************************************************************************/
1673 static void response_process(struct subnet_record *d, struct packet_struct *p,
1674 struct response_record *n, struct nmb_packet *nmb,
1675 BOOL bcast, struct nmb_name *ans_name)
1677 switch (n->cmd_type)
1679 case NAME_RELEASE:
1681 response_name_release(d, p);
1682 break;
1685 case NAME_REGISTER:
1687 response_name_reg(d, p);
1688 break;
1691 case NAME_QUERY_MST_SRV_CHK:
1692 case NAME_QUERY_SRV_CHK:
1693 case NAME_QUERY_FIND_MST:
1695 response_server_check(ans_name, n, d);
1696 break;
1699 case NAME_STATUS_MASTER_CHECK:
1700 case NAME_STATUS_CHECK:
1702 response_name_status_check(p->ip, nmb, bcast, n, d);
1703 break;
1706 case NAME_QUERY_CONFIRM:
1707 case NAME_QUERY_SYNC:
1709 response_name_query_sync(nmb, ans_name, bcast, n, d);
1710 break;
1712 case NAME_QUERY_MST_CHK:
1714 /* no action required here. it's when NO responses are received
1715 that we need to do something. see expire_name_query_entries() */
1717 DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
1718 namestr(&n->name), inet_ntoa(n->to_ip)));
1719 break;
1722 default:
1724 DEBUG(0,("unknown command received in response_netbios_packet\n"));
1725 break;
1731 /****************************************************************************
1732 response from a netbios packet.
1733 ****************************************************************************/
1734 static void response_netbios_packet(struct packet_struct *p)
1736 struct nmb_packet *nmb = &p->packet.nmb;
1737 struct nmb_name *question = &nmb->question.question_name;
1738 struct nmb_name *ans_name = NULL;
1739 char *qname = question->name;
1740 BOOL bcast = nmb->header.nm_flags.bcast;
1741 struct response_record *n;
1742 struct subnet_record *d = NULL;
1744 if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
1745 DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
1746 return;
1749 if (!d)
1751 DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
1752 return;
1755 if (!same_net(d->bcast_ip, d->mask_ip, p->ip)) /* copes with WINS 'subnet' */
1757 DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
1758 DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
1759 return;
1762 if (nmb->answers == NULL)
1764 /* hm. the packet received was a response, but with no answer. wierd! */
1765 DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
1766 inet_ntoa(p->ip), BOOLSTR(bcast)));
1767 return;
1770 ans_name = &nmb->answers->rr_name;
1771 DEBUG(3,("response for %s from %s (bcast=%s)\n",
1772 namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
1774 debug_rr_type(nmb->answers->rr_type);
1776 n->num_msgs++; /* count number of responses received */
1777 n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
1779 debug_cmd_type(n->cmd_type);
1781 /* problem checking: multiple responses etc */
1782 if (response_problem_check(n, nmb, qname))
1783 return;
1785 /* now check whether the command has received the correct type of response*/
1786 if (!response_compatible(n, nmb))
1787 return;
1789 /* now deal with the command */
1790 response_process(d, p, n, nmb, bcast, ans_name);
1794 /****************************************************************************
1795 process a nmb packet
1796 ****************************************************************************/
1797 void process_nmb(struct packet_struct *p)
1799 struct nmb_packet *nmb = &p->packet.nmb;
1801 debug_nmb_packet(p);
1803 switch (nmb->header.opcode)
1805 case 8: /* what is this?? */
1806 case NMB_REG:
1807 case NMB_REG_REFRESH:
1809 if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
1810 if (nmb->header.response)
1811 response_netbios_packet(p); /* response to registration dealt with here */
1812 else
1813 reply_name_reg(p);
1814 break;
1817 case 0:
1819 if (nmb->header.response)
1821 switch (nmb->question.question_type)
1823 case 0x0:
1825 response_netbios_packet(p);
1826 break;
1829 return;
1831 else if (nmb->header.qdcount>0)
1833 switch (nmb->question.question_type)
1835 case NMB_QUERY:
1837 reply_name_query(p);
1838 break;
1840 case NMB_STATUS:
1842 reply_name_status(p);
1843 break;
1846 return;
1848 break;
1851 case NMB_REL:
1853 if (nmb->header.qdcount==0 || nmb->header.arcount==0)
1855 DEBUG(2,("netbios release packet rejected\n"));
1856 break;
1859 if (nmb->header.response)
1860 response_netbios_packet(p); /* response to reply dealt with in here */
1861 else
1862 reply_name_release(p);
1863 break;