made "hide files" and "veto files" into per-service parameter sections,
[Samba.git] / source / nameservresp.c
blob226a997c5f3673066f7d8d5a82f84700df169318
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
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.
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.
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.
21 Revision History:
23 Module name: nameservresp.c
25 14 jan 96: lkcl@pires.co.uk
26 added multiple workgroup domain master support
28 05 jul 96: lkcl@pires.co.uk
29 created module nameservresp containing NetBIOS response functions
33 #include "includes.h"
35 extern int ClientNMB;
37 extern int DEBUGLEVEL;
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;
46 #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
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)
56 struct nmb_packet *nmb = &p->packet.nmb;
57 char *name = ans_name->name;
58 int type = ans_name->name_type;
60 DEBUG(4,("response name release received\n"));
62 if (nmb->header.rcode == 0 && nmb->answers->rdata)
64 /* IMPORTANT: see expire_netbios_response_entries() */
66 struct in_addr found_ip;
67 putip((char*)&found_ip,&nmb->answers->rdata[2]);
69 /* NOTE: we only release our own names at present */
70 if (ismyip(found_ip))
72 name_unregister_work(d,name,type);
74 else
76 DEBUG(2,("name release for different ip! %s %s\n",
77 inet_ntoa(found_ip), namestr(ans_name)));
80 else
82 DEBUG(2,("name release for %s rejected!\n", namestr(ans_name)));
84 /* XXXX PANIC! what to do if it's one of samba's own names? */
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. */
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)
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;
104 DEBUG(4,("response name registration received!\n"));
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.
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
121 /* IMPORTANT: see expire_netbios_response_entries() */
123 int nb_flags = nmb->answers->rdata[0];
124 int ttl = nmb->answers->ttl;
125 struct in_addr found_ip;
127 putip((char*)&found_ip,&nmb->answers->rdata[2]);
129 name_register_work(d,name,type,nb_flags,ttl,found_ip,bcast);
131 else
133 DEBUG(2,("name registration for %s rejected by ip %s!\n",
134 namestr(ans_name), inet_ntoa(p->ip)));
136 /* oh dear. we have problems. possibly unbecome a master browser. */
137 name_unregister_work(d,name,type);
142 /****************************************************************************
143 response from a name query announce host
144 NAME_QUERY_ANNOUNCE_HOST is dealt with here
145 ****************************************************************************/
146 static void response_announce_host(struct nmb_name *ans_name,
147 struct nmb_packet *nmb,
148 struct response_record *n, struct subnet_record *d)
150 DEBUG(4, ("Name query at %s ip %s - ",
151 namestr(&n->name), inet_ntoa(n->send_ip)));
153 if (!name_equal(&n->name, ans_name))
155 /* someone gave us the wrong name as a reply. oops. */
156 /* XXXX should say to them 'oi! release that name!' */
158 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
159 return;
162 if (nmb->header.rcode == 0 && nmb->answers->rdata)
164 /* we had sent out a name query to the current owner
165 of a name because someone else wanted it. now they
166 have responded saying that they still want the name,
167 so the other host can't have it.
170 /* first check all the details are correct */
172 int nb_flags = nmb->answers->rdata[0];
173 struct in_addr found_ip;
175 putip((char*)&found_ip,&nmb->answers->rdata[2]);
177 if (nb_flags != n->nb_flags)
179 /* someone gave us the wrong nb_flags as a reply. oops. */
180 /* XXXX should say to them 'oi! release that name!' */
182 DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
183 DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
184 return;
187 /* do an announce host */
188 do_announce_host(ANN_HostAnnouncement,
189 n->my_name , 0x00, d->myip,
190 n->name.name, 0x1d, found_ip,
191 n->ttl,
192 n->my_name, n->server_type, n->my_comment);
194 else
196 /* XXXX negative name query response. no master exists. oops */
201 /****************************************************************************
202 response from a name query server check. states of type NAME_QUERY_DOM_SRV_CHK,
203 NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
204 ****************************************************************************/
205 static void response_server_check(struct nmb_name *ans_name,
206 struct response_record *n, struct subnet_record *d)
208 /* issue another state: this time to do a name status check */
210 enum state_type cmd = (n->state == NAME_QUERY_DOM_SRV_CHK) ?
211 NAME_STATUS_DOM_SRV_CHK : NAME_STATUS_SRV_CHK;
213 /* initiate a name status check on the server that replied
214 in addition, the workgroup being checked has been stored
215 in the response_record->my_name (see announce_master) we
216 also propagate this into the same field. */
217 queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
218 ans_name->name, ans_name->name_type,
219 0,0,0,n->my_name,NULL,
220 False,False,n->send_ip,n->reply_to_ip);
224 /****************************************************************************
225 interpret a node status response. this is pretty hacked: we need two bits of
226 info. a) the name of the workgroup b) the name of the server. it will also
227 add all the names it finds into the namelist.
228 ****************************************************************************/
229 static BOOL interpret_node_status(struct subnet_record *d,
230 char *p, struct nmb_name *name,int t,
231 char *serv_name, struct in_addr ip, BOOL bcast)
233 int numnames = CVAL(p,0);
234 BOOL found = False;
236 DEBUG(4,("received %d names\n",numnames));
238 p += 1;
240 if (serv_name) *serv_name = 0;
242 while (numnames--)
244 char qname[17];
245 int type;
246 fstring flags;
247 int nb_flags;
249 BOOL group = False;
250 BOOL add = False;
252 *flags = 0;
254 StrnCpy(qname,p,15);
255 type = CVAL(p,15);
256 nb_flags = p[16];
257 trim_string(qname,NULL," ");
259 p += 18;
261 if (NAME_GROUP (nb_flags)) { strcat(flags,"<GROUP> "); group=True;}
262 if (NAME_BFLAG (nb_flags)) { strcat(flags,"B "); }
263 if (NAME_PFLAG (nb_flags)) { strcat(flags,"P "); }
264 if (NAME_MFLAG (nb_flags)) { strcat(flags,"M "); }
265 if (NAME_HFLAG (nb_flags)) { strcat(flags,"H "); }
266 if (NAME_DEREG (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
267 if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); }
268 if (NAME_ACTIVE (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
269 if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
271 /* I don't think we should be messing with our namelist here... JRA */
272 #if 0
273 /* might as well update our namelist while we're at it */
274 if (add)
276 struct in_addr nameip;
277 enum name_source src;
279 if (ismyip(ip)) {
280 nameip = ipzero;
281 src = SELF;
282 } else {
283 nameip = ip;
284 src = STATUS_QUERY;
286 add_netbios_entry(d,qname,type,nb_flags,2*60*60,src,nameip,True,bcast);
288 #endif /* JRA */
290 /* we want the server name */
291 if (serv_name && !*serv_name && !group && type == 0x20)
293 StrnCpy(serv_name,qname,15);
294 serv_name[15] = 0;
297 /* looking for a name and type? */
298 if (name && !found && (t == type))
300 /* take a guess at some of the name types we're going to ask for.
301 evaluate whether they are group names or no... */
302 if (((t == 0x1b || t == 0x1d || t == 0x20 ) && !group) ||
303 ((t == 0x1c || t == 0x1e ) && group))
305 found = True;
306 make_nmb_name(name,qname,type,scope);
310 DEBUG(4,("\t%s(0x%x)\t%s\n",qname,type,flags));
312 DEBUG(4,("num_good_sends=%d num_good_receives=%d\n",
313 IVAL(p,20),IVAL(p,24)));
314 return found;
318 /****************************************************************************
319 response from a name status check. states of type NAME_STATUS_DOM_SRV_CHK
320 and NAME_STATUS_SRV_CHK dealt with here.
321 ****************************************************************************/
322 static void response_name_status_check(struct in_addr ip,
323 struct nmb_packet *nmb, BOOL bcast,
324 struct response_record *n, struct subnet_record *d)
326 /* NMB_STATUS arrives: contains workgroup name and server name required.
327 amongst other things. */
329 struct nmb_name name;
330 fstring serv_name;
332 if (interpret_node_status(d,nmb->answers->rdata,
333 &name,0x20,serv_name,ip,bcast))
335 if (*serv_name)
337 /* response_record->my_name contains the
338 workgroup name to sync with. See
339 response_server_check() */
340 sync_server(n->state,serv_name,
341 n->my_name,name.name_type, d, n->send_ip);
344 else
346 DEBUG(1,("No 0x20 name type in interpret_node_status()\n"));
351 /****************************************************************************
352 response from a name query for secured WINS registration. a state of
353 NAME_REGISTER_CHALLENGE is dealt with here.
354 ****************************************************************************/
355 static void response_name_query_register(struct nmb_packet *nmb,
356 struct nmb_name *ans_name,
357 struct response_record *n, struct subnet_record *d)
359 struct in_addr register_ip;
360 BOOL new_owner;
362 DEBUG(4, ("Name query at %s ip %s - ",
363 namestr(&n->name), inet_ntoa(n->send_ip)));
365 if (!name_equal(&n->name, ans_name))
367 /* someone gave us the wrong name as a reply. oops. */
368 /* XXXX should say to them 'oi! release that name!' */
370 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
371 return;
374 if (nmb->header.rcode == 0 && nmb->answers->rdata)
376 /* we had sent out a name query to the current owner
377 of a name because someone else wanted it. now they
378 have responded saying that they still want the name,
379 so the other host can't have it.
382 /* first check all the details are correct */
384 int nb_flags = nmb->answers->rdata[0];
385 struct in_addr found_ip;
387 putip((char*)&found_ip,&nmb->answers->rdata[2]);
389 if (nb_flags != n->nb_flags)
391 /* someone gave us the wrong nb_flags as a reply. oops. */
392 /* XXXX should say to them 'oi! release that name!' */
394 DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
395 DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
396 return;
399 if (!ip_equal(n->send_ip, found_ip))
401 /* someone gave us the wrong ip as a reply. oops. */
402 /* XXXX should say to them 'oi! release that name!' */
404 DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
405 DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
406 return;
409 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
411 /* fine: now tell the other host they can't have the name */
412 register_ip = n->send_ip;
413 new_owner = False;
415 else
417 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
419 /* the owner didn't want the name: the other host can have it */
420 register_ip = n->reply_to_ip;
421 new_owner = True;
424 /* register the old or the new owners' ip */
425 add_name_respond(d, n->fd, d->myip, n->response_id,&n->name,n->nb_flags,
426 GET_TTL(0), register_ip,
427 new_owner, n->reply_to_ip);
431 /****************************************************************************
432 response from a name query to sync browse lists or to update our netbios
433 entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM
434 ****************************************************************************/
435 static void response_name_query_sync(struct nmb_packet *nmb,
436 struct nmb_name *ans_name, BOOL bcast,
437 struct response_record *n, struct subnet_record *d)
439 DEBUG(4, ("Name query at %s ip %s - ",
440 namestr(&n->name), inet_ntoa(n->send_ip)));
442 if (!name_equal(&n->name, ans_name))
444 /* someone gave us the wrong name as a reply. oops. */
445 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
446 return;
449 if (nmb->header.rcode == 0 && nmb->answers->rdata)
451 int nb_flags = nmb->answers->rdata[0];
452 struct in_addr found_ip;
454 putip((char*)&found_ip,&nmb->answers->rdata[2]);
456 if (!ip_equal(n->send_ip, found_ip))
458 /* someone gave us the wrong ip as a reply. oops. */
459 DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
460 DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
461 return;
464 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
466 if (n->state == NAME_QUERY_SYNC_LOCAL ||
467 n->state == NAME_QUERY_SYNC_REMOTE)
469 struct work_record *work = NULL;
470 /* We cheat here as we know that the workgroup name has
471 been placed in the my_comment field of the
472 response_record struct by the code in
473 start_sync_browse_entry().
475 if ((work = find_workgroupstruct(d, n->my_comment, False)))
477 BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
479 /* the server is there: sync quick before it (possibly) dies! */
480 sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
481 found_ip, local_list_only);
484 else
486 /* update our netbios name list (re-register it if necessary) */
487 add_netbios_entry(d, ans_name->name, ans_name->name_type,
488 nb_flags,GET_TTL(0),REGISTER,
489 found_ip,False,!bcast);
492 else
494 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
496 if (n->state == NAME_QUERY_CONFIRM)
498 /* XXXX remove_netbios_entry()? */
499 /* lots of things we ought to do, here. if we get here,
500 then we're in a mess: our name database doesn't match
501 reality. sort it out
503 remove_netbios_name(d,n->name.name, n->name.name_type,
504 REGISTER,n->send_ip);
509 /****************************************************************************
510 response from a name query for DOMAIN<1b>
511 NAME_QUERY_DOMAIN is dealt with here - we are trying to become a domain
512 master browser and WINS replied - check it's our address.
513 ****************************************************************************/
514 static void response_name_query_domain(struct nmb_name *ans_name,
515 struct nmb_packet *nmb,
516 struct response_record *n, struct subnet_record *d)
518 DEBUG(4, ("response_name_query_domain: Got %s response from %s for query \
519 for %s\n", nmb->header.rcode == 0 ? "success" : "failure",
520 inet_ntoa(n->send_ip), namestr(ans_name)));
522 /* Check the name is correct and ip address returned is our own. If it is then we
523 just remove the response record.
525 if (name_equal(&n->name, ans_name) && (nmb->header.rcode == 0) && (nmb->answers->rdata))
527 struct in_addr found_ip;
529 putip((char*)&found_ip,&nmb->answers->rdata[2]);
530 /* Samba 1.9.16p11 servers seem to return the broadcast address for this
531 query. */
532 if (ismyip(found_ip) || ip_equal(wins_ip, found_ip) || ip_equal(ipzero, found_ip))
534 DEBUG(4, ("response_name_query_domain: WINS server returned our ip \
535 address. Pretending we never received response.\n"));
536 n->num_msgs = 0;
537 n->repeat_count = 0;
538 n->repeat_time = 0;
540 else
542 DEBUG(0,("response_name_query_domain: WINS server already has a \
543 domain master browser registered %s at address %s\n",
544 namestr(ans_name), inet_ntoa(found_ip)));
547 else
549 /* Negative/incorrect response. No domain master
550 browser was registered - pretend we didn't get this response.
552 n->num_msgs = 0;
553 n->repeat_count = 0;
554 n->repeat_time = 0;
559 /****************************************************************************
560 report the response record type
561 ****************************************************************************/
562 static void debug_rr_type(int rr_type)
564 switch (rr_type)
566 case NMB_STATUS: DEBUG(3,("Name status ")); break;
567 case NMB_QUERY : DEBUG(3,("Name query ")); break;
568 case NMB_REG : DEBUG(3,("Name registration ")); break;
569 case NMB_REL : DEBUG(3,("Name release ")); break;
570 default : DEBUG(1,("wrong response packet type received")); break;
574 /****************************************************************************
575 report the response record nmbd state
576 ****************************************************************************/
577 void debug_state_type(int state)
579 /* report the state type to help debugging */
580 switch (state)
582 case NAME_QUERY_DOM_SRV_CHK : DEBUG(4,("NAME_QUERY_DOM_SRV_CHK\n")); break;
583 case NAME_QUERY_SRV_CHK : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
584 case NAME_QUERY_FIND_MST : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
585 case NAME_QUERY_MST_CHK : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
586 case NAME_QUERY_CONFIRM : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
587 case NAME_QUERY_SYNC_LOCAL : DEBUG(4,("NAME_QUERY_SYNC_LOCAL\n")); break;
588 case NAME_QUERY_SYNC_REMOTE : DEBUG(4,("NAME_QUERY_SYNC_REMOTE\n")); break;
589 case NAME_QUERY_ANNOUNCE_HOST: DEBUG(4,("NAME_QUERY_ANNCE_HOST\n"));break;
590 case NAME_QUERY_DOMAIN : DEBUG(4,("NAME_QUERY_DOMAIN\n")); break;
592 case NAME_REGISTER : DEBUG(4,("NAME_REGISTER\n")); break;
593 case NAME_REGISTER_CHALLENGE : DEBUG(4,("NAME_REGISTER_CHALLENGE\n"));break;
595 case NAME_RELEASE : DEBUG(4,("NAME_RELEASE\n")); break;
597 case NAME_STATUS_DOM_SRV_CHK : DEBUG(4,("NAME_STATUS_DOM_SRV_CHK\n")); break;
598 case NAME_STATUS_SRV_CHK : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
600 default: break;
604 /****************************************************************************
605 report any problems with the fact that a response has been received.
607 (responses for certain types of operations are only expected from one host)
608 ****************************************************************************/
609 static BOOL response_problem_check(struct response_record *n,
610 struct nmb_packet *nmb, char *ans_name)
612 switch (nmb->answers->rr_type)
614 case NMB_REL:
616 if (n->num_msgs > 1)
618 DEBUG(1,("more than one release name response received!\n"));
619 return True;
621 break;
624 case NMB_REG:
626 if (n->num_msgs > 1)
628 DEBUG(1,("more than one register name response received!\n"));
629 return True;
631 break;
634 case NMB_QUERY:
636 if (n->num_msgs > 1)
638 if (nmb->header.rcode == 0 && nmb->answers->rdata)
640 int nb_flags = nmb->answers->rdata[0];
642 if ((!NAME_GROUP(nb_flags)))
644 /* oh dear. more than one person responded to a
645 unique name.
646 there is either a network problem, a
647 configuration problem
648 or a server is mis-behaving */
650 /* XXXX mark the name as in conflict, and then let the
651 person who just responded know that they
652 must also mark it
653 as in conflict, and therefore must NOT use it.
654 see rfc1001.txt 15.1.3.5 */
656 /* this may cause problems for some
657 early versions of nmbd */
659 switch (n->state)
661 case NAME_QUERY_FIND_MST:
663 /* query for ^1^2__MSBROWSE__^2^1 expect
664 lots of responses */
665 return False;
667 case NAME_QUERY_ANNOUNCE_HOST:
668 case NAME_QUERY_DOM_SRV_CHK:
669 case NAME_QUERY_SRV_CHK:
670 case NAME_QUERY_MST_CHK:
672 if (!strequal(ans_name,n->name.name))
674 /* one subnet, one master browser
675 per workgroup */
676 /* XXXX force an election? */
678 DEBUG(3,("more than one master browser replied!\n"));
679 return True;
681 break;
683 default: break;
685 DEBUG(3,("Unique Name conflict detected!\n"));
686 return True;
689 else
691 /* we have received a negative reply,
692 having already received
693 at least one response (pos/neg).
694 something's really wrong! */
696 DEBUG(3,("wierd name query problem detected!\n"));
697 return True;
702 return False;
705 #if 0
706 /****************************************************************************
707 check that the response received is compatible with the response record
708 ****************************************************************************/
709 static BOOL response_compatible(struct response_record *n,
710 struct nmb_packet *nmb)
712 switch (n->state)
714 case NAME_RELEASE:
716 if (nmb->answers->rr_type != 0x20)
718 DEBUG(1,("Name release reply has wrong answer rr_type\n"));
719 return False;
721 break;
724 case NAME_REGISTER:
726 if (nmb->answers->rr_type != 0x20)
728 DEBUG(1,("Name register reply has wrong answer rr_type\n"));
729 return False;
731 break;
734 case NAME_REGISTER_CHALLENGE: /* this is a query: we then do a register */
735 case NAME_QUERY_CONFIRM:
736 case NAME_QUERY_ANNOUNCE_HOST:
737 case NAME_QUERY_SYNC_LOCAL:
738 case NAME_QUERY_SYNC_REMOTE:
739 case NAME_QUERY_DOM_SRV_CHK:
740 case NAME_QUERY_SRV_CHK:
741 case NAME_QUERY_FIND_MST:
742 case NAME_QUERY_MST_CHK:
744 if (nmb->answers->rr_type != 0x20)
746 DEBUG(1,("Name query reply has wrong answer rr_type\n"));
747 return False;
749 break;
752 case NAME_STATUS_DOM_SRV_CHK:
753 case NAME_STATUS_SRV_CHK:
755 if (nmb->answers->rr_type != 0x21)
757 DEBUG(1,("Name status reply has wrong answer rr_type\n"));
758 return False;
760 break;
763 default:
765 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
766 return False;
769 return True;
771 #endif
774 /****************************************************************************
775 process the response packet received
776 ****************************************************************************/
777 static void response_process(struct subnet_record *d, struct packet_struct *p,
778 struct response_record *n, struct nmb_packet *nmb,
779 BOOL bcast, struct nmb_name *ans_name)
781 switch (n->state)
783 case NAME_RELEASE:
785 response_name_release(ans_name, d, p);
786 break;
789 case NAME_REGISTER:
791 response_name_reg(ans_name, d, p);
792 break;
795 case NAME_REGISTER_CHALLENGE:
797 response_name_query_register(nmb, ans_name, n, d);
798 break;
801 case NAME_QUERY_DOM_SRV_CHK:
802 case NAME_QUERY_SRV_CHK:
803 case NAME_QUERY_FIND_MST:
805 response_server_check(ans_name, n, d);
806 break;
809 case NAME_STATUS_DOM_SRV_CHK:
810 case NAME_STATUS_SRV_CHK:
812 response_name_status_check(p->ip, nmb, bcast, n, d);
813 break;
816 case NAME_QUERY_ANNOUNCE_HOST:
818 response_announce_host(ans_name, nmb, n, d);
819 break;
822 case NAME_QUERY_CONFIRM:
823 case NAME_QUERY_SYNC_LOCAL:
824 case NAME_QUERY_SYNC_REMOTE:
826 response_name_query_sync(nmb, ans_name, bcast, n, d);
827 break;
829 case NAME_QUERY_MST_CHK:
831 /* no action required here. it's when NO responses are received
832 that we need to do something. see expire_name_query_entries() */
834 DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
835 namestr(&n->name), inet_ntoa(n->send_ip)));
836 break;
839 case NAME_QUERY_DOMAIN:
841 /* We were asking to be a domain master browser, and someone
842 replied. If it was the WINS server and the IP it is
843 returning is our own - then remove the record and pretend
844 we didn't get a response. Else we do nothing and let
845 dead_netbios_entry deal with it.
846 We can only become domain master browser
847 when no broadcast responses are received and WINS
848 either contains no entry for the DOMAIN<1b> name or
849 contains our IP address.
851 response_name_query_domain(ans_name, nmb, n, d);
852 break;
854 default:
856 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
857 break;
863 /****************************************************************************
864 response from a netbios packet.
865 ****************************************************************************/
866 void response_netbios_packet(struct packet_struct *p)
868 struct nmb_packet *nmb = &p->packet.nmb;
869 struct nmb_name *ans_name = NULL;
870 BOOL bcast = nmb->header.nm_flags.bcast;
871 struct response_record *n;
872 struct subnet_record *d = NULL;
874 if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
875 DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
876 return;
879 if (!d)
881 DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
882 return;
885 /* args wrong way round: spotted by ccm@shentel.net */
886 if (!same_net(d->bcast_ip, p->ip, d->mask_ip)) /* copes with WINS 'subnet' */
888 DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
889 DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
892 if (nmb->answers == NULL)
894 /* hm. the packet received was a response, but with no answer. wierd! */
895 DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
896 inet_ntoa(p->ip), BOOLSTR(bcast)));
897 return;
900 ans_name = &nmb->answers->rr_name;
901 DEBUG(3,("response for %s from %s (bcast=%s)\n",
902 namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
904 debug_rr_type(nmb->answers->rr_type);
906 n->num_msgs++; /* count number of responses received */
907 n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
909 debug_state_type(n->state);
911 /* problem checking: multiple responses etc */
912 if (response_problem_check(n, nmb, ans_name->name))
913 return;
915 /* now deal with the current state */
916 response_process(d, p, n, nmb, bcast, ans_name);