wrong answer response resource record type expected, so the response packet
[kai/samba.git] / source3 / nameservresp.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-1996
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    Module name: nameservresp.c
24
25    14 jan 96: lkcl@pires.co.uk
26    added multiple workgroup domain master support
27
28    05 jul 96: lkcl@pires.co.uk
29    created module nameservresp containing NetBIOS response functions
30
31 */
32
33 #include "includes.h"
34
35 extern int ClientNMB;
36
37 extern int DEBUGLEVEL;
38
39 extern pstring scope;
40 extern struct in_addr ipzero;
41
42 #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
43
44
45 /****************************************************************************
46   response for a reg release received. samba has asked a WINS server if it
47   could release a name.
48   **************************************************************************/
49 static void response_name_release(struct subnet_record *d,
50                                                                 struct packet_struct *p)
51 {
52   struct nmb_packet *nmb = &p->packet.nmb;
53   char *name = nmb->question.question_name.name;
54   int   type = nmb->question.question_name.name_type;
55   
56   DEBUG(4,("response name release received\n"));
57   
58   if (nmb->header.rcode == 0 && nmb->answers->rdata)
59   {
60     /* IMPORTANT: see expire_netbios_response_entries() */
61
62     struct in_addr found_ip;
63     putip((char*)&found_ip,&nmb->answers->rdata[2]);
64       
65     /* NOTE: we only release our own names at present */
66     if (ismyip(found_ip))
67     {
68       name_unregister_work(d,name,type);
69     }
70     else
71     {
72       DEBUG(2,("name release for different ip! %s %s\n",
73                   inet_ntoa(found_ip),
74                   namestr(&nmb->question.question_name)));
75     }
76   }
77   else
78   {
79     DEBUG(2,("name release for %s rejected!\n",
80                namestr(&nmb->question.question_name)));
81
82     /* XXXX PANIC! what to do if it's one of samba's own names? */
83
84     /* XXXX do we honestly care if our name release was rejected? 
85        only if samba is issuing the release on behalf of some out-of-sync
86        server. if it's one of samba's SELF names, we don't care. */
87   }
88 }
89
90
91 /****************************************************************************
92 response for a reg request received
93 **************************************************************************/
94 static void response_name_reg(struct subnet_record *d, struct packet_struct *p)
95 {
96   struct nmb_packet *nmb = &p->packet.nmb;
97   char *name = nmb->question.question_name.name;
98   int   type = nmb->question.question_name.name_type;
99   BOOL bcast = nmb->header.nm_flags.bcast;
100   
101   DEBUG(4,("response name registration received!\n"));
102   
103   if (nmb->header.rcode == 0 && nmb->answers->rdata)
104   {
105     /* IMPORTANT: see expire_netbios_response_entries() */
106
107     int nb_flags = nmb->answers->rdata[0];
108     int ttl = nmb->answers->ttl;
109     struct in_addr found_ip;
110
111     putip((char*)&found_ip,&nmb->answers->rdata[2]);
112       
113     name_register_work(d,name,type,nb_flags,ttl,found_ip,bcast);
114   }
115   else
116   {
117     DEBUG(1,("name registration for %s rejected!\n",
118                namestr(&nmb->question.question_name)));
119
120         /* oh dear. we have problems. possibly unbecome a master browser. */
121     name_unregister_work(d,name,type);
122   }
123 }
124
125
126 /****************************************************************************
127   response from a name query announce host
128   NAME_QUERY_ANNOUNCE_HOST is dealt with here
129   ****************************************************************************/
130 static void response_announce_host(struct nmb_name *ans_name, 
131                 struct nmb_packet *nmb, 
132                 struct response_record *n, struct subnet_record *d)
133 {
134         DEBUG(4, ("Name query at %s ip %s - ",
135                   namestr(&n->name), inet_ntoa(n->send_ip)));
136
137         if (!name_equal(&n->name, ans_name))
138         {
139                 /* someone gave us the wrong name as a reply. oops. */
140                 /* XXXX should say to them 'oi! release that name!' */
141
142                 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
143                 return;
144         }
145
146         if (nmb->header.rcode == 0 && nmb->answers->rdata)
147     {
148                 /* we had sent out a name query to the current owner
149                    of a name because someone else wanted it. now they
150                    have responded saying that they still want the name,
151                    so the other host can't have it.
152                  */
153
154                 /* first check all the details are correct */
155
156                 int nb_flags = nmb->answers->rdata[0];
157                 struct in_addr found_ip;
158
159                 putip((char*)&found_ip,&nmb->answers->rdata[2]);
160
161                 if (nb_flags != n->nb_flags)
162                 {
163                         /* someone gave us the wrong nb_flags as a reply. oops. */
164                         /* XXXX should say to them 'oi! release that name!' */
165
166                         DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
167                         DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
168                         return;
169                 }
170
171         /* do an announce host */
172         do_announce_host(ANN_HostAnnouncement,
173                                 n->my_name  , 0x00, d->myip,
174                                 n->name.name, 0x1d, found_ip,
175                                 n->ttl,
176                                 n->my_name, n->server_type, n->my_comment);
177         }
178         else
179         {
180                 /* XXXX negative name query response. no master exists. oops */
181         }
182 }
183
184
185 /****************************************************************************
186   response from a name query server check. states of type NAME_QUERY_DOM_SRV_CHK,
187   NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
188   ****************************************************************************/
189 static void response_server_check(struct nmb_name *ans_name, 
190                 struct response_record *n, struct subnet_record *d)
191 {
192     /* issue another state: this time to do a name status check */
193
194     enum state_type cmd = (n->state == NAME_QUERY_DOM_SRV_CHK) ?
195               NAME_STATUS_DOM_SRV_CHK : NAME_STATUS_SRV_CHK;
196
197     /* initiate a name status check on the server that replied */
198     queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
199                                 ans_name->name, ans_name->name_type,
200                                 0,0,0,NULL,NULL,
201                                 False,False,n->send_ip,n->reply_to_ip);
202 }
203
204
205 /****************************************************************************
206   interpret a node status response. this is pretty hacked: we need two bits of
207   info. a) the name of the workgroup b) the name of the server. it will also
208   add all the names it finds into the namelist.
209 ****************************************************************************/
210 static BOOL interpret_node_status(struct subnet_record *d,
211                                 char *p, struct nmb_name *name,int t,
212                            char *serv_name, struct in_addr ip, BOOL bcast)
213 {
214   int numnames = CVAL(p,0);
215   BOOL found = False;
216
217   DEBUG(4,("received %d names\n",numnames));
218
219   p += 1;
220
221   if (serv_name) *serv_name = 0;
222
223   while (numnames--)
224     {
225       char qname[17];
226       int type;
227       fstring flags;
228       int nb_flags;
229       
230       BOOL group = False;
231       BOOL add   = False;
232       
233       *flags = 0;
234       
235       StrnCpy(qname,p,15);
236       type = CVAL(p,15);
237       nb_flags = p[16];
238       trim_string(qname,NULL," ");
239       
240       p += 18;
241       
242       if (NAME_GROUP    (nb_flags)) { strcat(flags,"<GROUP> "); group=True;}
243       if (NAME_BFLAG    (nb_flags)) { strcat(flags,"B "); }
244       if (NAME_PFLAG    (nb_flags)) { strcat(flags,"P "); }
245       if (NAME_MFLAG    (nb_flags)) { strcat(flags,"M "); }
246       if (NAME_HFLAG    (nb_flags)) { strcat(flags,"H "); }
247       if (NAME_DEREG    (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
248       if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); add=True;}
249       if (NAME_ACTIVE   (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
250       if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
251       
252       /* might as well update our namelist while we're at it */
253       if (add)
254         {
255           struct in_addr nameip;
256           enum name_source src;
257           
258           if (ismyip(ip)) {
259             nameip = ipzero;
260             src = SELF;
261           } else {
262             nameip = ip;
263             src = STATUS_QUERY;
264           }
265           add_netbios_entry(d,qname,type,nb_flags,2*60*60,src,nameip,True,bcast);
266         } 
267
268       /* we want the server name */
269       if (serv_name && !*serv_name && !group && t == 0)
270         {
271           StrnCpy(serv_name,qname,15);
272           serv_name[15] = 0;
273         }
274       
275       /* looking for a name and type? */
276       if (name && !found && (t == type))
277         {
278           /* take a guess at some of the name types we're going to ask for.
279              evaluate whether they are group names or no... */
280           if (((t == 0x1b || t == 0x1d             ) && !group) ||
281               ((t == 0x20 || t == 0x1c || t == 0x1e) &&  group))
282             {
283               found = True;
284               make_nmb_name(name,qname,type,scope);
285             }
286         }
287       
288       DEBUG(4,("\t%s(0x%x)\t%s\n",qname,type,flags));
289     }
290   DEBUG(4,("num_good_sends=%d num_good_receives=%d\n",
291                IVAL(p,20),IVAL(p,24)));
292   return found;
293 }
294
295
296 /****************************************************************************
297   response from a name status check. states of type NAME_STATUS_DOM_SRV_CHK
298   and NAME_STATUS_SRV_CHK dealt with here.
299   ****************************************************************************/
300 static void response_name_status_check(struct in_addr ip,
301                 struct nmb_packet *nmb, BOOL bcast,
302                 struct response_record *n, struct subnet_record *d)
303 {
304         /* NMB_STATUS arrives: contains workgroup name and server name required.
305        amongst other things. */
306
307         struct nmb_name name;
308         fstring serv_name;
309
310         if (interpret_node_status(d,nmb->answers->rdata,
311                                   &name,name.name_type,serv_name,ip,bcast))
312         {
313                 if (*serv_name)
314                 {
315                         sync_server(n->state,serv_name,
316                                     name.name,name.name_type, n->send_ip);
317                 }
318         }
319         else
320         {
321                 DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
322         }
323 }
324
325
326 /****************************************************************************
327   response from a name query for secured WINS registration. a state of
328   NAME_REGISTER_CHALLENGE is dealt with here.
329   ****************************************************************************/
330 static void response_name_query_register(struct nmb_packet *nmb, 
331                 struct nmb_name *ans_name, 
332                 struct response_record *n, struct subnet_record *d)
333 {
334         struct in_addr register_ip;
335         BOOL new_owner;
336
337         DEBUG(4, ("Name query at %s ip %s - ",
338                   namestr(&n->name), inet_ntoa(n->send_ip)));
339
340         if (!name_equal(&n->name, ans_name))
341         {
342                 /* someone gave us the wrong name as a reply. oops. */
343                 /* XXXX should say to them 'oi! release that name!' */
344
345                 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
346                 return;
347         }
348
349         if (nmb->header.rcode == 0 && nmb->answers->rdata)
350     {
351                 /* we had sent out a name query to the current owner
352                    of a name because someone else wanted it. now they
353                    have responded saying that they still want the name,
354                    so the other host can't have it.
355                  */
356
357                 /* first check all the details are correct */
358
359                 int nb_flags = nmb->answers->rdata[0];
360                 struct in_addr found_ip;
361
362                 putip((char*)&found_ip,&nmb->answers->rdata[2]);
363
364                 if (nb_flags != n->nb_flags)
365                 {
366                         /* someone gave us the wrong nb_flags as a reply. oops. */
367                         /* XXXX should say to them 'oi! release that name!' */
368
369                         DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
370                         DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
371                         return;
372                 }
373
374                 if (!ip_equal(n->send_ip, found_ip))
375                 {
376                         /* someone gave us the wrong ip as a reply. oops. */
377                         /* XXXX should say to them 'oi! release that name!' */
378
379                         DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
380                         DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
381                         return;
382                 }
383
384                 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
385
386                 /* fine: now tell the other host they can't have the name */
387                 register_ip = n->send_ip;
388                 new_owner = False;
389         }
390         else
391         {
392                 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
393
394                 /* the owner didn't want the name: the other host can have it */
395                 register_ip = n->reply_to_ip;
396                 new_owner = True;
397         }
398
399         /* register the old or the new owners' ip */
400         add_name_respond(d, n->fd, d->myip, n->response_id,&n->name,n->nb_flags,
401                                         GET_TTL(0), register_ip,
402                                         new_owner, n->reply_to_ip);
403 }
404
405
406 /****************************************************************************
407   response from a name query to sync browse lists or to update our netbios
408   entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM 
409   ****************************************************************************/
410 static void response_name_query_sync(struct nmb_packet *nmb, 
411                 struct nmb_name *ans_name, BOOL bcast,
412                 struct response_record *n, struct subnet_record *d)
413 {
414         DEBUG(4, ("Name query at %s ip %s - ",
415                   namestr(&n->name), inet_ntoa(n->send_ip)));
416
417         if (!name_equal(&n->name, ans_name))
418         {
419                 /* someone gave us the wrong name as a reply. oops. */
420                 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
421                 return;
422         }
423
424         if (nmb->header.rcode == 0 && nmb->answers->rdata)
425     {
426                 int nb_flags = nmb->answers->rdata[0];
427                 struct in_addr found_ip;
428
429                 putip((char*)&found_ip,&nmb->answers->rdata[2]);
430
431                 if (!ip_equal(n->send_ip, found_ip))
432                 {
433                         /* someone gave us the wrong ip as a reply. oops. */
434                         DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
435                         DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
436                         return;
437                 }
438
439                 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
440
441                 if (n->state == NAME_QUERY_SYNC_LOCAL ||
442                     n->state == NAME_QUERY_SYNC_REMOTE)
443                 {
444                         struct work_record *work = NULL;
445                         if ((work = find_workgroupstruct(d, ans_name->name, False)))
446                         {
447                                 BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
448
449                                 /* the server is there: sync quick before it (possibly) dies! */
450                                 sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
451                                                         found_ip, local_list_only);
452                         }
453                 }
454                 else
455                 {
456                         /* update our netbios name list (re-register it if necessary) */
457                         add_netbios_entry(d, ans_name->name, ans_name->name_type,
458                                                                 nb_flags,GET_TTL(0),REGISTER,
459                                                                 found_ip,False,!bcast);
460                 }
461         }
462         else
463         {
464                 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
465
466                 if (n->state == NAME_QUERY_CONFIRM)
467                 {
468                         /* XXXX remove_netbios_entry()? */
469                         /* lots of things we ought to do, here. if we get here,
470                            then we're in a mess: our name database doesn't match
471                            reality. sort it out
472              */
473                 remove_netbios_name(d,n->name.name, n->name.name_type,
474                                                                 REGISTER,n->send_ip);
475                 }
476         }
477 }
478
479
480 /****************************************************************************
481   report the response record type
482   ****************************************************************************/
483 static void debug_rr_type(int rr_type)
484 {
485   switch (rr_type)
486   {
487       case NMB_STATUS: DEBUG(3,("Name status ")); break;
488           case NMB_QUERY : DEBUG(3,("Name query ")); break;
489           case NMB_REG   : DEBUG(3,("Name registration ")); break;
490           case NMB_REL   : DEBUG(3,("Name release ")); break;
491       default        : DEBUG(1,("wrong response packet type received")); break;
492   }
493 }
494
495 /****************************************************************************
496   report the response record nmbd state
497   ****************************************************************************/
498 void debug_state_type(int state)
499 {
500   /* report the state type to help debugging */
501   switch (state)
502   {
503     case NAME_QUERY_DOM_SRV_CHK  : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
504     case NAME_QUERY_SRV_CHK      : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
505     case NAME_QUERY_FIND_MST     : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
506     case NAME_QUERY_MST_CHK      : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
507     case NAME_QUERY_CONFIRM      : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
508     case NAME_QUERY_SYNC_LOCAL   : DEBUG(4,("NAME_QUERY_SYNC_LOCAL\n")); break;
509     case NAME_QUERY_SYNC_REMOTE  : DEBUG(4,("NAME_QUERY_SYNC_REMOTE\n")); break;
510     case NAME_QUERY_ANNOUNCE_HOST: DEBUG(4,("NAME_QUERY_ANNCE_HOST\n"));break;
511
512     case NAME_REGISTER           : DEBUG(4,("NAME_REGISTER\n")); break;
513     case NAME_REGISTER_CHALLENGE : DEBUG(4,("NAME_REGISTER_CHALLENGE\n"));break;
514
515     case NAME_RELEASE            : DEBUG(4,("NAME_RELEASE\n")); break;
516
517     case NAME_STATUS_DOM_SRV_CHK : DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
518     case NAME_STATUS_SRV_CHK     : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
519
520     default: break;
521   }
522 }
523
524 /****************************************************************************
525   report any problems with the fact that a response has been received.
526
527   (responses for certain types of operations are only expected from one host)
528   ****************************************************************************/
529 static BOOL response_problem_check(struct response_record *n,
530                         struct nmb_packet *nmb, char *qname)
531 {
532   switch (nmb->answers->rr_type)
533   {
534     case NMB_REL:
535     {
536         if (n->num_msgs > 1)
537         {
538             DEBUG(1,("more than one release name response received!\n"));
539             return True;
540         }
541         break;
542     }
543
544     case NMB_REG:
545     {
546         if (n->num_msgs > 1)
547         {
548             DEBUG(1,("more than one register name response received!\n"));
549             return True;
550         }
551         break;
552     }
553
554     case NMB_QUERY:
555     { 
556       if (n->num_msgs > 1)
557       {
558                   if (nmb->header.rcode == 0 && nmb->answers->rdata)
559                   {
560                         int nb_flags = nmb->answers->rdata[0];
561
562                         if ((!NAME_GROUP(nb_flags)))
563                         {
564                            /* oh dear. more than one person responded to a unique name.
565                                   there is either a network problem, a configuration problem
566                                   or a server is mis-behaving */
567
568                            /* XXXX mark the name as in conflict, and then let the
569                                   person who just responded know that they must also mark it
570                                   as in conflict, and therefore must NOT use it.
571                   see rfc1001.txt 15.1.3.5 */
572                                         
573                /* this may cause problems for some early versions of nmbd */
574
575                switch (n->state)
576                {
577                 case NAME_QUERY_FIND_MST:
578                 {
579                   /* query for ^1^2__MSBROWSE__^2^1 expect lots of responses */
580                   return False;
581                 }
582                         case NAME_QUERY_ANNOUNCE_HOST:
583                         case NAME_QUERY_DOM_SRV_CHK:
584                 case NAME_QUERY_SRV_CHK:
585                 case NAME_QUERY_MST_CHK:
586                 {
587                       if (!strequal(qname,n->name.name))
588                       {
589                              /* one subnet, one master browser per workgroup */
590                              /* XXXX force an election? */
591
592                              DEBUG(3,("more than one master browser replied!\n"));
593                                  return True;
594                           }
595                    break;
596                 }
597                 default: break;
598                }
599                DEBUG(3,("Unique Name conflict detected!\n"));
600                            return True;
601                         }
602                   }
603                   else
604                   {
605              /* we have received a negative reply, having already received
606                 at least one response (pos/neg). something's really wrong! */
607
608                  DEBUG(3,("wierd name query problem detected!\n"));
609                      return True;
610                   }
611        }
612     }
613   }
614   return False;
615 }
616
617 /****************************************************************************
618   check that the response received is compatible with the response record
619   ****************************************************************************/
620 static BOOL response_compatible(struct response_record *n,
621                         struct nmb_packet *nmb)
622 {
623   switch (n->state)
624   {
625     case NAME_RELEASE:
626     {
627                 if (nmb->answers->rr_type != 0x20)
628                 {
629                         DEBUG(1,("Name release reply has wrong answer rr_type\n"));
630                         return False;
631                 }
632         break;
633     }
634
635     case NAME_REGISTER:
636     {
637                 if (nmb->answers->rr_type != 0x20)
638                 {
639                         DEBUG(1,("Name register reply has wrong answer rr_type\n"));
640                         return False;
641                 }
642         break;
643     }
644
645     case NAME_REGISTER_CHALLENGE: /* this is a query: we then do a register */
646     case NAME_QUERY_CONFIRM:
647     case NAME_QUERY_ANNOUNCE_HOST:
648     case NAME_QUERY_SYNC_LOCAL:
649     case NAME_QUERY_SYNC_REMOTE:
650     case NAME_QUERY_DOM_SRV_CHK:
651     case NAME_QUERY_SRV_CHK:
652     case NAME_QUERY_FIND_MST:
653     case NAME_QUERY_MST_CHK:
654     {
655                 if (nmb->answers->rr_type != 0x20)
656                 {
657                         DEBUG(1,("Name query reply has wrong answer rr_type\n"));
658                         return False;
659                 }
660                 break;
661     }
662       
663     case NAME_STATUS_DOM_SRV_CHK:
664     case NAME_STATUS_SRV_CHK:
665     {
666                 if (nmb->answers->rr_type != 0x21)
667                 {
668                         DEBUG(1,("Name status reply has wrong answer rr_type\n"));
669                         return False;
670                 }
671                 break;
672     }
673       
674     default:
675     {
676                 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
677                 return False;
678     }
679   }
680   return True;
681 }
682
683
684 /****************************************************************************
685   process the response packet received
686   ****************************************************************************/
687 static void response_process(struct subnet_record *d, struct packet_struct *p,
688                                 struct response_record *n, struct nmb_packet *nmb,
689                                 BOOL bcast, struct nmb_name *ans_name)
690 {
691   switch (n->state)
692   {
693     case NAME_RELEASE:
694     {
695         response_name_release(d, p);
696         break;
697     }
698
699     case NAME_REGISTER:
700     {
701         response_name_reg(d, p);
702         break;
703     }
704
705     case NAME_REGISTER_CHALLENGE:
706     {
707         response_name_query_register(nmb, ans_name, n, d);
708         break;
709     }
710
711     case NAME_QUERY_DOM_SRV_CHK:
712     case NAME_QUERY_SRV_CHK:
713     case NAME_QUERY_FIND_MST:
714     {
715                 response_server_check(ans_name, n, d);
716                 break;
717     }
718       
719     case NAME_STATUS_DOM_SRV_CHK:
720     case NAME_STATUS_SRV_CHK:
721     {
722                 response_name_status_check(p->ip, nmb, bcast, n, d);
723                 break;
724     }
725       
726     case NAME_QUERY_ANNOUNCE_HOST:
727     {
728                 response_announce_host(ans_name, nmb, n, d);
729                 break;
730     }
731       
732     case NAME_QUERY_CONFIRM:
733     case NAME_QUERY_SYNC_LOCAL:
734     case NAME_QUERY_SYNC_REMOTE:
735     {
736                 response_name_query_sync(nmb, ans_name, bcast, n, d);
737                 break;
738     }
739     case NAME_QUERY_MST_CHK:
740     {
741                 /* no action required here. it's when NO responses are received
742                    that we need to do something. see expire_name_query_entries() */
743         
744                 DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
745                                         namestr(&n->name), inet_ntoa(n->send_ip)));
746                 break;
747     }
748
749     default:
750     {
751                 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
752                 break;
753     }
754   }
755 }
756
757
758 /****************************************************************************
759   response from a netbios packet.
760   ****************************************************************************/
761 void response_netbios_packet(struct packet_struct *p)
762 {
763   struct nmb_packet *nmb = &p->packet.nmb;
764   struct nmb_name *question = &nmb->question.question_name;
765   struct nmb_name *ans_name = NULL;
766   char *qname = question->name;
767   BOOL bcast = nmb->header.nm_flags.bcast;
768   struct response_record *n;
769   struct subnet_record *d = NULL;
770
771   if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
772     DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
773     return;
774   }
775
776   if (!d)
777   {
778     DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
779     return;
780   }
781
782   /* args wrong way round: spotted by ccm@shentel.net */
783   if (!same_net(d->bcast_ip, p->ip, d->mask_ip)) /* copes with WINS 'subnet' */
784   {
785     DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
786     DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
787     return;
788   }
789
790   if (nmb->answers == NULL)
791   {
792       /* hm. the packet received was a response, but with no answer. wierd! */
793       DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
794                inet_ntoa(p->ip), BOOLSTR(bcast)));
795       return;
796   }
797
798   ans_name = &nmb->answers->rr_name;
799   DEBUG(3,("response for %s from %s (bcast=%s)\n",
800            namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
801   
802   debug_rr_type(nmb->answers->rr_type);
803
804   n->num_msgs++; /* count number of responses received */
805   n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
806
807   debug_state_type(n->state);
808
809   /* problem checking: multiple responses etc */
810   if (response_problem_check(n, nmb, qname))
811     return;
812
813   /* now deal with the current state */
814   response_process(d, p, n, nmb, bcast, ans_name);
815 }
816
817