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