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