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