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