- remove some incorrect prototypes from server.c
[kai/samba.git] / source3 / nameserv.c
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
6    
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.
11    
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.
16    
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.
20    
21    Revision History:
22
23    14 jan 96: lkcl@pires.co.uk
24    added multiple workgroup domain master support
25
26 */
27
28 #include "includes.h"
29 #include "loadparm.h"
30 #include "localnet.h"
31
32
33 enum name_search { FIND_SELF, FIND_GLOBAL };
34
35 extern int DEBUGLEVEL;
36
37 extern pstring scope;
38 extern BOOL CanRecurse;
39 extern pstring myname;
40 extern struct in_addr ipzero;
41
42 /* netbios names database */
43 struct name_record *namelist;
44
45 #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
46
47
48 /****************************************************************************
49   true if two netbios names are equal
50 ****************************************************************************/
51 static BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
52 {
53   if (n1->name_type != n2->name_type) return(False);
54
55   return(strequal(n1->name,n2->name) && strequal(n1->scope,n2->scope));
56 }
57
58 /****************************************************************************
59   add a netbios name into the namelist
60   **************************************************************************/
61 static void add_name(struct name_record *n)
62 {
63   struct name_record *n2;
64
65   if (!namelist)
66   {
67     namelist = n;
68     n->prev = NULL;
69     n->next = NULL;
70     return;
71   }
72
73   for (n2 = namelist; n2->next; n2 = n2->next) ;
74
75   n2->next = n;
76   n->next = NULL;
77   n->prev = n2;
78 }
79
80 /****************************************************************************
81   remove a name from the namelist. The pointer must be an element just 
82   retrieved
83   **************************************************************************/
84 void remove_name(struct name_record *n)
85 {
86   struct name_record *nlist = namelist;
87
88   while (nlist && nlist != n) nlist = nlist->next;
89
90   if (nlist)
91   {
92     if (nlist->next) nlist->next->prev = nlist->prev;
93     if (nlist->prev) nlist->prev->next = nlist->next;
94     free(nlist);
95   }
96 }
97
98 /****************************************************************************
99   find a name in the domain database namelist 
100   search can be:
101   FIND_SELF   - look for names the samba server has added for itself
102   FIND_GLOBAL - the name can be anyone. first look on the client's
103                 subnet, then the server's subnet, then all subnets.
104   **************************************************************************/
105 static struct name_record *find_name_search(struct nmb_name *name, enum name_search search,
106                                             struct in_addr ip)
107 {
108         struct name_record *ret;
109
110         /* any number of winpopup names can be added. must search by ip as well */
111         if (name->name_type != 0x3) ip = ipzero;
112
113         for (ret = namelist; ret; ret = ret->next)
114         {
115                 if (name_equal(&ret->name,name))
116                 {
117                         /* self search: self names only */
118                         if (search == FIND_SELF && ret->source != SELF) continue;
119
120                         if (zero_ip(ip) || ip_equal(ip, ret->ip))
121                         {
122                                 return ret;
123                         }
124                 }
125         }
126
127         return NULL;
128 }
129
130
131 /****************************************************************************
132   dump a copy of the name table
133   **************************************************************************/
134 void dump_names(void)
135 {
136         struct name_record *n;
137         time_t t = time(NULL);
138
139         DEBUG(3,("Dump of local name table:\n"));
140
141         for (n = namelist; n; n = n->next)
142         {
143                 DEBUG(3,("%s %s TTL=%d NBFLAGS=%2x\n",
144                         namestr(&n->name),
145                         inet_ntoa(n->ip),
146                         n->death_time?n->death_time-t:0,
147                                 n->nb_flags));
148         }
149 }
150
151
152 /****************************************************************************
153   remove an entry from the name list
154   ****************************************************************************/
155 void remove_netbios_name(char *name,int type, enum name_source source,
156                          struct in_addr ip)
157 {
158         struct nmb_name nn;
159         struct name_record *n;
160
161         make_nmb_name(&nn, name, type, scope);
162         n = find_name_search(&nn, FIND_GLOBAL, ip);
163
164         if (n && n->source == source) remove_name(n);
165 }
166
167
168 /****************************************************************************
169   add an entry to the name list
170   ****************************************************************************/
171 struct name_record *add_netbios_entry(char *name, int type, int nb_flags, int ttl,
172                                       enum name_source source, struct in_addr ip)
173 {
174   struct name_record *n;
175   struct name_record *n2=NULL;
176
177   n = (struct name_record *)malloc(sizeof(*n));
178   if (!n) return(NULL);
179
180   bzero((char *)n,sizeof(*n));
181
182   make_nmb_name(&n->name,name,type,scope);
183
184   if ((n2 = find_name_search(&n->name, FIND_GLOBAL, ip)))
185   {
186     free(n);
187     n = n2;
188   }
189
190   if (ttl) n->death_time = time(NULL)+ttl*3;
191   n->ip = ip;
192   n->nb_flags = nb_flags;
193   n->source = source;
194   
195   if (!n2) add_name(n);
196
197   DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x\n",
198                 namestr(&n->name),inet_ntoa(ip),ttl,nb_flags));
199
200   return(n);
201 }
202
203
204 /****************************************************************************
205   remove an entry from the name list
206   ****************************************************************************/
207 void remove_name_entry(char *name,int type)
208 {
209   if (lp_wins_support())
210     {
211       /* we are a WINS server. */
212       remove_netbios_name(name,type,SELF,myip);
213     }
214   else
215     {
216       struct in_addr ip;
217       ip = ipzero;
218       
219       queue_netbios_pkt_wins(ClientNMB,NMB_REL,NAME_RELEASE,
220                              name, type, 0,
221                              False, True, ip);
222     }
223 }
224
225
226 /****************************************************************************
227   add an entry to the name list
228   ****************************************************************************/
229 void add_name_entry(char *name,int type,int nb_flags)
230 {
231   /* always add our own entries */
232   add_netbios_entry(name,type,nb_flags,0,SELF,myip);
233
234   if (!lp_wins_support())
235     {
236       struct in_addr ip;
237       ip = ipzero;
238       
239       queue_netbios_pkt_wins(ClientNMB,NMB_REG,NAME_REGISTER,
240                              name, type, nb_flags,
241                              False, True, ip);
242     }
243 }
244
245
246 /****************************************************************************
247   add the magic samba names, useful for finding samba servers
248   **************************************************************************/
249 void add_my_names(void)
250 {
251   struct in_addr ip;
252
253   ip = ipzero;
254   
255   add_name_entry(myname,0x20,NB_ACTIVE);
256   add_name_entry(myname,0x03,NB_ACTIVE);
257   add_name_entry(myname,0x00,NB_ACTIVE);
258   add_name_entry(myname,0x1f,NB_ACTIVE);
259   
260   add_netbios_entry("*",0x0,NB_ACTIVE,0,SELF,ip);
261   add_netbios_entry("__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip);
262   add_netbios_entry("__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip);
263   
264   if (lp_wins_support()) {
265     add_netbios_entry(inet_ntoa(myip),0x01,NB_ACTIVE,0,SELF,ip); /* nt as? */
266   }
267 }
268
269 /*******************************************************************
270   refresh my own names
271   ******************************************************************/
272 void refresh_my_names(time_t t)
273 {
274   static time_t lasttime = 0;
275
276   if (t - lasttime < REFRESH_TIME) 
277     return;
278   lasttime = t;
279
280   add_my_names();
281 }
282
283 /*******************************************************************
284   expires old names in the namelist
285   ******************************************************************/
286 void expire_names(time_t t)
287 {
288   struct name_record *n;
289   struct name_record *next;
290   
291   /* expire old names */
292   for (n = namelist; n; n = next)
293     {
294       if (n->death_time && n->death_time < t)
295         {
296           DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
297           
298           next = n->next;
299           
300           if (n->prev) n->prev->next = n->next;
301           if (n->next) n->next->prev = n->prev;
302           
303           if (namelist == n) namelist = n->next; 
304           
305           free(n);
306         }
307       else
308         {
309           next = n->next;
310         }
311     }
312 }
313
314
315 /****************************************************************************
316 response for a reg release received
317 **************************************************************************/
318 void response_name_release(struct packet_struct *p)
319 {
320   struct nmb_packet *nmb = &p->packet.nmb;
321   char *name = nmb->question.question_name.name;
322   int   type = nmb->question.question_name.name_type;
323   
324   DEBUG(4,("response name release received\n"));
325   
326   if (nmb->header.rcode == 0 && nmb->answers->rdata)
327     {
328       struct in_addr found_ip;
329       putip((char*)&found_ip,&nmb->answers->rdata[2]);
330       
331       if (ip_equal(found_ip, myip))
332         {
333           remove_netbios_name(name,type,SELF,found_ip);
334         }
335     }
336   else
337     {
338       DEBUG(1,("name registration for %s rejected!\n",
339                namestr(&nmb->question.question_name)));
340     }
341 }
342
343
344 /****************************************************************************
345 reply to a name release
346 ****************************************************************************/
347 void reply_name_release(struct packet_struct *p)
348 {
349   struct nmb_packet *nmb = &p->packet.nmb;
350   struct in_addr ip;
351   int rcode=0;
352   int opcode = nmb->header.opcode;  
353   int nb_flags = nmb->additional->rdata[0];
354   BOOL bcast = nmb->header.nm_flags.bcast;
355   struct name_record *n;
356   char rdata[6];
357   
358   putip((char *)&ip,&nmb->additional->rdata[2]);  
359   
360   DEBUG(3,("Name release on name %s rcode=%d\n",
361            namestr(&nmb->question.question_name),rcode));
362   
363   n = find_name_search(&nmb->question.question_name, FIND_GLOBAL, ip);
364   
365   /* XXXX under what conditions should we reject the removal?? */
366   if (n && n->nb_flags == nb_flags && ip_equal(n->ip,ip))
367     {
368       /* success = True;
369          rcode = 6; */
370       
371       remove_name(n);
372       n = NULL;
373     }
374   
375   if (bcast) return;
376   
377   /*if (success)*/
378   {
379     rdata[0] = nb_flags;
380     rdata[1] = 0;
381     putip(&rdata[2],(char *)&ip);
382   }
383   
384   /* Send a NAME RELEASE RESPONSE */
385   reply_netbios_packet(p,nmb->header.name_trn_id,rcode,opcode,
386                        &nmb->question.question_name,
387                        nmb->question.question_type,
388                        nmb->question.question_class,
389                        0,
390                        rdata, 6 /*success ? 6 : 0*/);
391   /* XXXX reject packet never tested: cannot tell what to do */
392 }
393
394
395 /****************************************************************************
396 response for a reg request received
397 **************************************************************************/
398 void response_name_reg(struct packet_struct *p)
399 {
400   struct nmb_packet *nmb = &p->packet.nmb;
401   char *name = nmb->question.question_name.name;
402   int   type = nmb->question.question_name.name_type;
403   
404   DEBUG(4,("response name registration received!\n"));
405   
406   if (nmb->header.rcode == 0 && nmb->answers->rdata)
407     {
408       int nb_flags = nmb->answers->rdata[0];
409       struct in_addr found_ip;
410       int ttl = nmb->answers->ttl;
411       enum name_source source = REGISTER;
412       
413       putip((char*)&found_ip,&nmb->answers->rdata[2]);
414       
415       if (ip_equal(found_ip, myip)) source = SELF;
416       
417       add_netbios_entry(name,type,nb_flags,ttl,source,found_ip);
418     }
419   else
420     {
421       DEBUG(1,("name registration for %s rejected!\n",
422                namestr(&nmb->question.question_name)));
423     }
424 }
425
426
427 /****************************************************************************
428 reply to a reg request
429 **************************************************************************/
430 void reply_name_reg(struct packet_struct *p)
431 {
432   struct nmb_packet *nmb = &p->packet.nmb;
433   struct nmb_name *question = &nmb->question.question_name;
434   char *qname = nmb->question.question_name.name;
435   int name_type = nmb->question.question_name.name_type;
436   
437   BOOL bcast = nmb->header.nm_flags.bcast;
438   
439   int ttl = GET_TTL(nmb->additional->ttl);
440   int nb_flags = nmb->additional->rdata[0];
441   BOOL group = (nb_flags&0x80);
442   int rcode = 0;  
443   int opcode = nmb->header.opcode;  
444   struct name_record *n = NULL;
445   int success = True;
446   char rdata[6];
447   struct in_addr ip, from_ip;
448   
449   putip((char *)&from_ip,&nmb->additional->rdata[2]);
450   ip = from_ip;
451   
452   DEBUG(3,("Name registration for name %s at %s rcode=%d\n",
453            namestr(question),inet_ntoa(ip),rcode));
454   
455   if (group)
456     {
457       /* apparently we should return 255.255.255.255 for group queries
458          (email from MS) */
459       ip = *interpret_addr2("255.255.255.255");
460     }
461   
462   /* see if the name already exists */
463   n = find_name_search(question, FIND_GLOBAL, from_ip);
464   
465   if (n)
466     {
467       if (!group && !ip_equal(ip,n->ip) && question->name_type != 0x3)
468         {
469           if (n->source == SELF)
470             {
471               rcode = 6;
472               success = False;
473             }
474           else
475             {
476               n->ip = ip;
477               n->death_time = ttl?p->timestamp+ttl*3:0;
478               DEBUG(3,("%s changed owner to %s\n",
479                        namestr(&n->name),inet_ntoa(n->ip)));
480             }
481         }
482       else
483         {
484           /* refresh the name */
485           if (n->source != SELF)
486             {
487               n->death_time = ttl?p->timestamp + ttl*3:0;
488             }
489         }
490     }
491   else
492     {
493       /* add the name to our subnet/name database */
494       n = add_netbios_entry(qname,name_type,nb_flags,ttl,REGISTER,ip);
495     }
496   
497   if (bcast) return;
498   
499   update_from_reg(nmb->question.question_name.name,
500                   nmb->question.question_name.name_type, from_ip);
501   
502   /* XXXX don't know how to reject a name register: stick info in anyway
503      and guess that it doesn't matter if info is there! */
504   /*if (success)*/
505   {
506     rdata[0] = nb_flags;
507     rdata[1] = 0;
508     putip(&rdata[2],(char *)&ip);
509   }
510   
511   /* Send a NAME REGISTRATION RESPONSE */
512   reply_netbios_packet(p,nmb->header.name_trn_id,rcode,opcode,
513                        &nmb->question.question_name,
514                        nmb->question.question_type,
515                        nmb->question.question_class,
516                        ttl,
517                        rdata, 6 /*success ? 6 : 0*/);
518 }
519
520
521 /****************************************************************************
522 reply to a name status query
523 ****************************************************************************/
524 void reply_name_status(struct packet_struct *p)
525 {
526   struct nmb_packet *nmb = &p->packet.nmb;
527   char *qname   = nmb->question.question_name.name;
528   int ques_type = nmb->question.question_name.name_type;
529   BOOL wildcard = (qname[0] == '*'); 
530   char rdata[MAX_DGRAM_SIZE];
531   char *countptr, *buf;
532   int count, names_added;
533   struct name_record *n;
534   
535   DEBUG(3,("Name status for name %s %s\n",
536            namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
537   
538   /* find a name: if it's a wildcard, search the entire database.
539      if not, search for source SELF names only */
540   n = find_name_search(&nmb->question.question_name,
541                        wildcard ? FIND_GLOBAL : FIND_SELF, p->ip);
542   
543   if (!wildcard && (!n || n->source != SELF)) return;
544   
545   for (count=0, n = namelist ; n; n = n->next)
546     {
547       int name_type = n->name.name_type;
548       
549       if (n->source != SELF) continue;
550       
551       if (name_type >= 0x1b && name_type <= 0x20 && 
552           ques_type >= 0x1b && ques_type <= 0x20)
553         {
554           if (!strequal(qname, n->name.name)) continue;
555         }
556       
557       count++;
558     }
559   
560   /* XXXX hack, we should calculate exactly how many will fit */
561   count = MIN(count,(sizeof(rdata) - 64) / 18);
562   
563   countptr = buf = rdata;
564   buf += 1;
565   
566   names_added = 0;
567   
568   for (n = namelist ; n && count >= 0; n = n->next) 
569     {
570       int name_type = n->name.name_type;
571       
572       if (n->source != SELF) continue;
573       
574       /* start with first bit of putting info in buffer: the name */
575       
576       bzero(buf,18);
577       StrnCpy(buf,n->name.name,15);
578       strupper(buf);
579       
580       /* now check if we want to exclude other workgroup names
581          from the response. if we don't exclude them, windows clients
582          get confused and will respond with an error for NET VIEW */
583       
584       if (name_type >= 0x1b && name_type <= 0x20 && 
585           ques_type >= 0x1b && ques_type <= 0x20)
586         {
587           if (!strequal(qname, n->name.name)) continue;
588         }
589       
590       /* carry on putting name info in buffer */
591       
592       buf[15] = name_type;
593       buf[16]  = n->nb_flags;
594       
595       buf += 18;
596       
597       count--;
598       names_added++;
599     }
600   
601   if (count < 0)
602     {
603       DEBUG(3, (("too many names: missing a few!\n")));
604     }
605   
606   SCVAL(countptr,0,names_added);
607   
608   /* XXXXXXX we should fill in more fields of the statistics structure */
609   bzero(buf,64);
610   {
611     extern int num_good_sends,num_good_receives;
612     SIVAL(buf,20,num_good_sends);
613     SIVAL(buf,24,num_good_receives);
614   }
615   
616   SIVAL(buf,46,0xFFB8E5); /* undocumented - used by NT */
617   
618   buf += 64;
619   
620   /* Send a POSITIVE NAME STATUS RESPONSE */
621   reply_netbios_packet(p,nmb->header.name_trn_id,0,0,
622                        &nmb->question.question_name,
623                        nmb->question.question_type,
624                        nmb->question.question_class,
625                        0,
626                        rdata,PTR_DIFF(buf,rdata));
627 }
628
629
630 /***************************************************************************
631 reply to a name query
632 ****************************************************************************/
633 struct name_record *search_for_name(struct nmb_name *question,
634                                     struct in_addr ip, int Time, int search)
635 {
636   int name_type = question->name_type;
637   char *qname = question->name;
638   BOOL dns_type = name_type == 0x20 || name_type == 0;
639   
640   struct name_record *n;
641   
642   DEBUG(3,("Search for %s from %s - ", namestr(question), inet_ntoa(ip)));
643   
644   /* first look up name in cache */
645   n = find_name_search(question,search,ip);
646   
647   /* now try DNS lookup. */
648   if (!n)
649     {
650       struct in_addr dns_ip;
651       unsigned long a;
652       
653       /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
654       if (!dns_type)
655         {
656           DEBUG(3,("types 0x20 0x1b 0x0 only: name not found\n"));
657           return NULL;
658         }
659       
660       /* look it up with DNS */      
661       a = interpret_addr(qname);
662       
663       putip((char *)&dns_ip,(char *)&a);
664       
665       if (!a)
666         {
667           /* no luck with DNS. We could possibly recurse here XXXX */
668           /* if this isn't a bcast then we should send a negative reply XXXX */
669           DEBUG(3,("no recursion\n"));
670           add_netbios_entry(qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip);
671           return NULL;
672         }
673       
674       /* add it to our cache of names. give it 2 hours in the cache */
675       n = add_netbios_entry(qname,name_type,NB_ACTIVE,2*60*60,DNS,dns_ip);
676       
677       /* failed to add it? yikes! */
678       if (!n) return NULL;
679     }
680   
681   /* is our entry already dead? */
682   if (n->death_time)
683     {
684       if (n->death_time < Time) return False;
685     }
686   
687   /* it may have been an earlier failure */
688   if (n->source == DNSFAIL)
689     {
690       DEBUG(3,("DNSFAIL\n"));
691       return NULL;
692     }
693   
694   DEBUG(3,("OK %s\n",inet_ntoa(n->ip)));      
695   
696   return n;
697 }
698
699
700 /***************************************************************************
701 reply to a name query.
702
703 with broadcast name queries:
704
705         - only reply if the query is for one of YOUR names. all other machines on
706           the network will be doing the same thing (that is, only replying to a
707           broadcast query if they own it)
708           NOTE: broadcast name queries should only be sent out by a machine
709           if they HAVEN'T been configured to use WINS. this is generally bad news
710           in a wide area tcp/ip network and should be rectified by the systems
711           administrator. USE WINS! :-)
712         - the exception to this is if the query is for a Primary Domain Controller
713           type name (0x1b), in which case, a reply is sent.
714
715         - NEVER send a negative response to a broadcast query. no-one else will!
716
717 with directed name queries:
718
719         - if you are the WINS server, you are expected to 
720 ****************************************************************************/
721 extern void reply_name_query(struct packet_struct *p)
722 {
723   struct nmb_packet *nmb = &p->packet.nmb;
724   struct nmb_name *question = &nmb->question.question_name;
725   int name_type = question->name_type;
726   BOOL dns_type = name_type == 0x20 || name_type == 0;
727   BOOL bcast = nmb->header.nm_flags.bcast;
728   int ttl=0;
729   int rcode = 0;
730   int nb_flags = 0;
731   struct in_addr retip;
732   char rdata[6];
733   
734   struct in_addr gp_ip = *interpret_addr2("255.255.255.255");
735   BOOL success = True;
736   
737   struct name_record *n;
738   enum name_search search = dns_type || name_type == 0x1b ?
739     FIND_GLOBAL : FIND_SELF;
740   
741   DEBUG(3,("Name query "));
742   
743   if ((n = search_for_name(question,p->ip,p->timestamp, search)))
744     {
745       /* don't respond to broadcast queries unless the query is for
746          a name we own or it is for a Primary Domain Controller name */
747       if (bcast && n->source != SELF && name_type != 0x1b)
748         {
749           if (!lp_wins_proxy() || same_net(p->ip,n->ip,Netmask)) {
750             /* never reply with a negative response to broadcast queries */
751             return;
752           }
753         }
754       
755       /* we will reply */
756       ttl = n->death_time - p->timestamp;
757       retip = n->ip;
758       nb_flags = n->nb_flags;
759     }
760   else
761     {
762       if (bcast) return; /* never reply negative response to bcasts */
763       success = False;
764     }
765   
766   /* if asking for a group name (type 0x1e) return 255.255.255.255 */
767   if (ip_equal(retip, gp_ip) && name_type == 0x1e) retip = gp_ip;
768
769   /* if the IP is 0 then substitute my IP - we should see which one is on the 
770      right interface for the caller to do this right XXX */
771   if (zero_ip(retip)) retip = myip;
772
773   if (success)
774     {
775       rcode = 0;
776       DEBUG(3,("OK %s\n",inet_ntoa(retip)));      
777     }
778   else
779     {
780       rcode = 3;
781       DEBUG(3,("UNKNOWN\n"));      
782     }
783   
784   if (success)
785     {
786       rdata[0] = nb_flags;
787       rdata[1] = 0;
788       putip(&rdata[2],(char *)&retip);
789     }
790   
791   reply_netbios_packet(p,nmb->header.name_trn_id,rcode,0,
792                        &nmb->question.question_name,
793                        nmb->question.question_type,
794                        nmb->question.question_class,
795                        ttl,
796                        rdata, success ? 6 : 0);
797 }
798
799
800 /****************************************************************************
801 response from a name query
802 ****************************************************************************/
803 static void response_netbios_packet(struct packet_struct *p)
804 {
805   struct nmb_packet *nmb = &p->packet.nmb;
806   struct nmb_name *question = &nmb->question.question_name;
807   char *qname = question->name;
808   BOOL bcast = nmb->header.nm_flags.bcast;
809   struct name_response_record *n;
810
811   if (nmb->answers == NULL)
812     {
813       DEBUG(3,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
814                inet_ntoa(p->ip),
815                BOOLSTR(bcast)));
816       return;
817     }
818   
819   if (nmb->answers->rr_type == NMB_STATUS) {
820     DEBUG(3,("Name status "));
821   }
822
823   if (nmb->answers->rr_type == NMB_QUERY)       {
824     DEBUG(3,("Name query "));
825   }
826
827   if (nmb->answers->rr_type == NMB_REG) {
828     DEBUG(3,("Name registration "));
829   }
830
831   if (nmb->answers->rr_type == NMB_REL) {
832     DEBUG(3,("Name release "));
833   }
834
835   DEBUG(3,("response for %s from %s (bcast=%s)\n",
836            namestr(&nmb->answers->rr_name),
837            inet_ntoa(p->ip),
838            BOOLSTR(bcast)));
839   
840   if (!(n = find_name_query(nmb->header.name_trn_id))) {
841     DEBUG(3,("unknown response (received too late or from nmblookup?)\n"));
842     return;
843   }
844
845   n->num_msgs++; /* count number of responses received */
846
847   switch (n->cmd_type)
848     {
849     case MASTER_SERVER_CHECK     : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
850     case SERVER_CHECK            : DEBUG(4,("SERVER_CHECK\n")); break;
851     case FIND_MASTER             : DEBUG(4,("FIND_MASTER\n")); break;
852     case NAME_STATUS_MASTER_CHECK: DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
853     case NAME_STATUS_CHECK       : DEBUG(4,("NAME_STATUS_CHECK\n")); break;
854     case CHECK_MASTER            : DEBUG(4,("CHECK_MASTER\n")); break;
855     case NAME_CONFIRM_QUERY      : DEBUG(4,("NAME_CONFIRM_QUERY\n")); break;
856     default: break;
857     }
858   switch (n->cmd_type)
859     {
860     case MASTER_SERVER_CHECK:
861     case SERVER_CHECK:
862     case FIND_MASTER:
863       {
864         if (nmb->answers->rr_type == NMB_QUERY)
865           {
866             enum cmd_type cmd = (n->cmd_type == MASTER_SERVER_CHECK) ?
867               NAME_STATUS_MASTER_CHECK :
868               NAME_STATUS_CHECK;
869             if (n->num_msgs > 1 && !strequal(qname,n->name.name))
870               {
871                 /* one subnet, one master browser per workgroup */
872                 /* XXXX force an election? */
873                 DEBUG(1,("more than one master browser replied!\n"));
874               }
875             
876             /* initiate a name status check on the server that replied */
877             queue_netbios_packet(ClientNMB,NMB_STATUS, cmd,
878                                  nmb->answers->rr_name.name,
879                                  nmb->answers->rr_name.name_type,0,
880                                  False,False,n->to_ip);
881           }
882         else
883           {
884             DEBUG(1,("Name query reply has wrong answer rr_type\n"));
885           }
886         break;
887       }
888       
889     case NAME_STATUS_MASTER_CHECK:
890     case NAME_STATUS_CHECK:
891       {
892         if (nmb->answers->rr_type == NMB_STATUS)
893           {
894             /* NMB_STATUS arrives: contains the workgroup name 
895                and server name we require */
896             struct nmb_name name;
897             fstring serv_name;
898             
899             if (interpret_node_status(nmb->answers->rdata,
900                                       &name,0x1d,serv_name,n->to_ip))
901               {
902                 if (*serv_name)
903                   {
904                     sync_server(n->cmd_type,serv_name,
905                                 name.name,name.name_type,
906                                 n->to_ip);
907                   }
908               }
909             else
910               {
911                 DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
912               }
913           }
914         else
915           {
916             DEBUG(1,("Name status reply has wrong answer rr_type\n"));
917           }
918         break;
919       }
920       
921     case CHECK_MASTER:
922       {
923         /* no action required here. it's when NO responses are received
924            that we need to do something (see expire_name_query_entries) */
925         
926         DEBUG(4, ("Master browser exists for %s at %s\n",
927                   namestr(&n->name),
928                   inet_ntoa(n->to_ip)));
929         if (n->num_msgs > 1)
930           {
931             DEBUG(1,("more than one master browser!\n"));
932           }
933         if (nmb->answers->rr_type != NMB_QUERY)
934           {
935             DEBUG(1,("Name query reply has wrong answer rr_type\n"));
936           }
937         break;
938       }
939     case NAME_CONFIRM_QUERY:
940       {
941         DEBUG(4, ("Name query at WINS server: %s at %s - ",
942                   namestr(&n->name),
943                   inet_ntoa(n->to_ip)));
944         if (nmb->header.rcode == 0 && nmb->answers->rdata)
945           {
946             int nb_flags = nmb->answers->rdata[0];
947             struct in_addr found_ip;
948             putip((char*)&found_ip,&nmb->answers->rdata[2]);
949             
950             DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
951             add_netbios_entry(nmb->answers->rr_name.name,
952                               nmb->answers->rr_name.name_type,
953                               nb_flags,GET_TTL(0),STATUS_QUERY,found_ip);
954           }
955         else
956           {
957             DEBUG(4, (" NEGATIVE RESPONSE\n"));
958           }
959         
960         break;
961       }
962     default:
963       {
964         DEBUG(0,("unknown command received in response_netbios_packet\n"));
965         break;
966       }
967     }
968 }
969
970
971 /****************************************************************************
972   process a nmb packet
973   ****************************************************************************/
974 void process_nmb(struct packet_struct *p)
975 {
976         struct nmb_packet *nmb = &p->packet.nmb;
977
978         debug_nmb_packet(p);
979
980         switch (nmb->header.opcode) 
981         {
982                 case 5:
983                 case 8:
984                 case 9:
985                 {
986                         if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
987                         if (nmb->header.response)
988                                 response_name_reg(p);
989                         else
990                                 reply_name_reg(p);
991                         break;
992                 }
993
994                 case 0:
995                 {
996                         if (nmb->header.response)
997                         {
998                                 switch (nmb->question.question_type)
999                                 {
1000                                         case 0x0:
1001                                         {
1002                                                 response_netbios_packet(p);
1003                                                 break;
1004                                         }
1005                                 }
1006                                 return;
1007                         }
1008                         else if (nmb->header.qdcount>0) 
1009                         {
1010                                 switch (nmb->question.question_type)
1011                                 {
1012                                         case NMB_QUERY:
1013                                         {
1014                                                 reply_name_query(p);
1015                                                 break;
1016                                         }
1017                                         case NMB_STATUS:
1018                                         {
1019                                                 reply_name_status(p);
1020                                                 break;
1021                                         }
1022                                 }
1023                                 return;
1024                         }
1025                         break;
1026                 }
1027
1028                 case 6:
1029                 {
1030                         if (nmb->header.qdcount==0 || nmb->header.arcount==0)
1031                         {
1032                                 DEBUG(2,("netbios release packet rejected\n"));
1033                                 break;
1034                         }
1035
1036                         if (nmb->header.response)
1037                                 response_name_release(p);
1038                         else
1039                                 reply_name_release(p);
1040                         break;
1041                 }
1042         }
1043
1044 }
1045