fix the handling of negative name query responses and the handling of
[Samba.git] / source / nameservresp.c
blobdeb56c0850e2b09eb125679b392cc7e1bc920fdc
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 && 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 && nmb->answers->rdata))
117 #else
118 if (nmb->header.rcode == 0 && nmb->answers && 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);
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)
148 struct nmb_packet *nmb = &p->packet.nmb;
149 struct in_addr send_ip;
150 enum state_type cmd;
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.
157 if (nmb->header.rcode == 0 && nmb->answers && nmb->answers->rdata)
158 putip((char*)&send_ip,&nmb->answers->rdata[2]);
159 else
162 DEBUG(2,("response_server_check: name query for %s failed\n",
163 namestr(ans_name)));
164 return;
167 /* issue another state: this time to do a name status check */
169 cmd = (n->state == NAME_QUERY_DOM_SRV_CHK) ?
170 NAME_STATUS_DOM_SRV_CHK : NAME_STATUS_SRV_CHK;
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, 0);
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)
192 int numnames = CVAL(p,0);
193 BOOL found = False;
195 DEBUG(4,("received %d names\n",numnames));
197 p += 1;
199 if (serv_name) *serv_name = 0;
201 while (numnames--)
203 char qname[17];
204 int type;
205 fstring flags;
206 int nb_flags;
208 BOOL group = False;
209 BOOL add = False;
211 *flags = 0;
213 StrnCpy(qname,p,15);
214 type = CVAL(p,15);
215 nb_flags = p[16];
216 trim_string(qname,NULL," ");
218 p += 18;
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;}
230 /* we want the server name */
231 if (serv_name && !*serv_name && !group && type == 0x20)
233 StrnCpy(serv_name,qname,15);
234 serv_name[15] = 0;
237 /* looking for a name and type? */
238 if (name && !found && (t == type))
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))
245 found = True;
246 make_nmb_name(name,qname,type,scope);
250 DEBUG(4,("\t%s(0x%x)\t%s\n",qname,type,flags));
252 DEBUG(4,("num_good_sends=%d num_good_receives=%d\n",
253 IVAL(p,20),IVAL(p,24)));
254 return found;
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)
266 /* NMB_STATUS arrives: contains workgroup name and server name required.
267 amongst other things. */
269 struct nmb_name name;
270 fstring serv_name;
272 if (nmb->answers &&
273 interpret_node_status(d,nmb->answers->rdata,
274 &name,0x20,serv_name,ip,bcast))
276 if (*serv_name)
278 /* response_record->my_name contains the
279 workgroup name to sync with. See
280 response_server_check() */
281 sync_server(n->state,serv_name,
282 n->my_name,name.name_type, d, n->send_ip);
285 else
287 DEBUG(1,("No 0x20 name type in interpret_node_status()\n"));
292 /****************************************************************************
293 response from a name query for secured WINS registration. a state of
294 NAME_REGISTER_CHALLENGE is dealt with here.
295 ****************************************************************************/
296 static void response_name_query_register(struct nmb_packet *nmb,
297 struct nmb_name *ans_name,
298 struct response_record *n, struct subnet_record *d)
300 struct in_addr register_ip;
301 BOOL new_owner;
303 DEBUG(4, ("Name query at %s ip %s - ",
304 namestr(&n->name), inet_ntoa(n->send_ip)));
306 if (!name_equal(&n->name, ans_name))
308 /* someone gave us the wrong name as a reply. oops. */
309 /* XXXX should say to them 'oi! release that name!' */
311 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
312 return;
315 if (nmb->header.rcode == 0 && nmb->answers && nmb->answers->rdata)
317 /* we had sent out a name query to the current owner
318 of a name because someone else wanted it. now they
319 have responded saying that they still want the name,
320 so the other host can't have it.
323 /* first check all the details are correct */
325 int nb_flags = nmb->answers->rdata[0];
326 struct in_addr found_ip;
328 putip((char*)&found_ip,&nmb->answers->rdata[2]);
330 if (nb_flags != n->nb_flags)
332 /* someone gave us the wrong nb_flags as a reply. oops. */
333 /* XXXX should say to them 'oi! release that name!' */
335 DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
336 DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
337 return;
340 if (!ip_equal(n->send_ip, found_ip))
342 /* someone gave us the wrong ip as a reply. oops. */
343 /* XXXX should say to them 'oi! release that name!' */
345 DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
346 DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
347 return;
350 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
352 /* fine: now tell the other host they can't have the name */
353 register_ip = n->send_ip;
354 new_owner = False;
356 else
358 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
360 /* the owner didn't want the name: the other host can have it */
361 register_ip = n->reply_to_ip;
362 new_owner = True;
365 /* register the old or the new owners' ip */
366 add_name_respond(d, n->fd, d->myip, n->reply_id,&n->name,n->nb_flags,
367 GET_TTL(0), register_ip,
368 new_owner, n->reply_to_ip);
370 remove_response_record(d,n); /* remove the response record */
374 /****************************************************************************
375 response from a name query to sync browse lists or to update our netbios
376 entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM
377 ****************************************************************************/
378 static void response_name_query_sync(struct nmb_packet *nmb,
379 struct nmb_name *ans_name, BOOL bcast,
380 struct response_record *n, struct subnet_record *d)
382 DEBUG(4, ("Name query at %s ip %s - ",
383 namestr(&n->name), inet_ntoa(n->send_ip)));
385 if (!name_equal(&n->name, ans_name))
387 /* someone gave us the wrong name as a reply. oops. */
388 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
389 return;
392 if (nmb->header.rcode == 0 && nmb->answers && nmb->answers->rdata)
394 int nb_flags = nmb->answers->rdata[0];
395 struct in_addr found_ip;
397 putip((char*)&found_ip,&nmb->answers->rdata[2]);
399 if (!ip_equal(n->send_ip, found_ip))
401 /* someone gave us the wrong ip as a reply. oops. */
402 DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
403 DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
404 return;
407 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
409 if (n->state == NAME_QUERY_SYNC_LOCAL ||
410 n->state == NAME_QUERY_SYNC_REMOTE)
412 struct work_record *work = NULL;
413 /* We cheat here as we know that the workgroup name has
414 been placed in the my_comment field of the
415 response_record struct by the code in
416 start_sync_browse_entry().
418 if ((work = find_workgroupstruct(d, n->my_comment, False)))
420 BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
422 /* the server is there: sync quick before it (possibly) dies! */
423 sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
424 found_ip, local_list_only);
427 else
429 /* update our netbios name list (re-register it if necessary) */
430 add_netbios_entry(d, ans_name->name, ans_name->name_type,
431 nb_flags,GET_TTL(0),REGISTER,
432 found_ip,False,!bcast);
435 else
437 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
439 if (n->state == NAME_QUERY_CONFIRM)
441 /* XXXX remove_netbios_entry()? */
442 /* lots of things we ought to do, here. if we get here,
443 then we're in a mess: our name database doesn't match
444 reality. sort it out
446 remove_netbios_name(d,n->name.name, n->name.name_type,
447 REGISTER,n->send_ip);
452 /****************************************************************************
453 response from a name query for DOMAIN<1b>
454 NAME_QUERY_DOMAIN is dealt with here - we are trying to become a domain
455 master browser and WINS replied - check it's our address.
456 ****************************************************************************/
457 static void response_name_query_domain(struct nmb_name *ans_name,
458 struct nmb_packet *nmb,
459 struct response_record *n, struct subnet_record *d)
461 DEBUG(4, ("response_name_query_domain: Got %s response from %s for query \
462 for %s\n", nmb->header.rcode == 0 ? "success" : "failure",
463 inet_ntoa(n->send_ip), namestr(ans_name)));
465 /* Check the name is correct and ip address returned is our own. If it is then we
466 just remove the response record.
468 if (name_equal(&n->name, ans_name) && (nmb->header.rcode == 0) && nmb->answers && (nmb->answers->rdata))
470 struct in_addr found_ip;
472 putip((char*)&found_ip,&nmb->answers->rdata[2]);
473 /* Samba 1.9.16p11 servers seem to return the broadcast address for this
474 query. */
475 if (ismyip(found_ip) || ip_equal(wins_ip, found_ip) || ip_equal(ipzero, found_ip))
477 DEBUG(4, ("response_name_query_domain: WINS server returned our ip \
478 address. Pretending we never received response.\n"));
479 n->num_msgs = 0;
480 n->repeat_count = 0;
481 n->repeat_time = 0;
483 else
485 DEBUG(0,("response_name_query_domain: WINS server already has a \
486 domain master browser registered %s at address %s\n",
487 namestr(ans_name), inet_ntoa(found_ip)));
490 else
492 /* Negative/incorrect response. No domain master
493 browser was registered - pretend we didn't get this response.
495 n->num_msgs = 0;
496 n->repeat_count = 0;
497 n->repeat_time = 0;
502 /****************************************************************************
503 report the response record type
504 ****************************************************************************/
505 static void debug_rr_type(int rr_type)
507 switch (rr_type)
509 case NMB_STATUS: DEBUG(3,("Name status ")); break;
510 case NMB_QUERY : DEBUG(3,("Name query ")); break;
511 case NMB_REG : DEBUG(3,("Name registration ")); break;
512 case NMB_REL : DEBUG(3,("Name release ")); break;
513 default : DEBUG(1,("wrong response packet type received")); break;
517 /****************************************************************************
518 report the response record nmbd state
519 ****************************************************************************/
520 void debug_state_type(int state)
522 /* report the state type to help debugging */
523 switch (state)
525 case NAME_QUERY_DOM_SRV_CHK : DEBUG(4,("NAME_QUERY_DOM_SRV_CHK\n")); break;
526 case NAME_QUERY_SRV_CHK : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
527 case NAME_QUERY_FIND_MST : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
528 case NAME_QUERY_MST_CHK : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
529 case NAME_QUERY_CONFIRM : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
530 case NAME_QUERY_SYNC_LOCAL : DEBUG(4,("NAME_QUERY_SYNC_LOCAL\n")); break;
531 case NAME_QUERY_SYNC_REMOTE : DEBUG(4,("NAME_QUERY_SYNC_REMOTE\n")); break;
532 case NAME_QUERY_DOMAIN : DEBUG(4,("NAME_QUERY_DOMAIN\n")); break;
534 case NAME_REGISTER : DEBUG(4,("NAME_REGISTER\n")); break;
535 case NAME_REGISTER_CHALLENGE : DEBUG(4,("NAME_REGISTER_CHALLENGE\n"));break;
537 case NAME_RELEASE : DEBUG(4,("NAME_RELEASE\n")); break;
539 case NAME_STATUS_DOM_SRV_CHK : DEBUG(4,("NAME_STATUS_DOM_SRV_CHK\n")); break;
540 case NAME_STATUS_SRV_CHK : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
542 default: break;
546 /****************************************************************************
547 report any problems with the fact that a response has been received.
549 (responses for certain types of operations are only expected from one host)
550 ****************************************************************************/
551 static BOOL response_problem_check(struct response_record *n,
552 struct nmb_packet *nmb, char *ans_name)
554 switch (nmb->answers->rr_type)
556 case NMB_REL:
558 if (n->num_msgs > 1)
560 DEBUG(1,("more than one release name response received!\n"));
561 return True;
563 break;
566 case NMB_REG:
568 if (n->num_msgs > 1)
570 DEBUG(1,("more than one register name response received!\n"));
571 return True;
573 break;
576 case NMB_QUERY:
578 if (n->num_msgs > 1)
580 if (nmb->header.rcode == 0 && nmb->answers && nmb->answers->rdata)
582 int nb_flags = nmb->answers->rdata[0];
584 if ((!NAME_GROUP(nb_flags)))
586 /* oh dear. more than one person responded to a
587 unique name.
588 there is either a network problem, a
589 configuration problem
590 or a server is mis-behaving */
592 /* XXXX mark the name as in conflict, and then let the
593 person who just responded know that they
594 must also mark it
595 as in conflict, and therefore must NOT use it.
596 see rfc1001.txt 15.1.3.5 */
598 /* this may cause problems for some
599 early versions of nmbd */
601 switch (n->state)
603 case NAME_QUERY_FIND_MST:
605 /* query for ^1^2__MSBROWSE__^2^1 expect
606 lots of responses */
607 return False;
609 case NAME_QUERY_DOM_SRV_CHK:
610 case NAME_QUERY_SRV_CHK:
611 case NAME_QUERY_MST_CHK:
613 if (!strequal(ans_name,n->name.name))
615 /* one subnet, one master browser
616 per workgroup */
617 /* XXXX force an election? */
619 DEBUG(3,("more than one master browser replied!\n"));
620 return True;
622 break;
624 default: break;
626 DEBUG(3,("Unique Name conflict detected!\n"));
627 return True;
630 else
632 /* we have received a negative reply,
633 having already received
634 at least one response (pos/neg).
635 something's really wrong! */
637 DEBUG(3,("wierd name query problem detected!\n"));
638 return True;
643 return False;
646 #if 0
647 /****************************************************************************
648 check that the response received is compatible with the response record
649 ****************************************************************************/
650 static BOOL response_compatible(struct response_record *n,
651 struct nmb_packet *nmb)
653 switch (n->state)
655 case NAME_RELEASE:
657 if (nmb->answers->rr_type != 0x20)
659 DEBUG(1,("Name release reply has wrong answer rr_type\n"));
660 return False;
662 break;
665 case NAME_REGISTER:
667 if (nmb->answers->rr_type != 0x20)
669 DEBUG(1,("Name register reply has wrong answer rr_type\n"));
670 return False;
672 break;
675 case NAME_REGISTER_CHALLENGE: /* this is a query: we then do a register */
676 case NAME_QUERY_CONFIRM:
677 case NAME_QUERY_SYNC_LOCAL:
678 case NAME_QUERY_SYNC_REMOTE:
679 case NAME_QUERY_DOM_SRV_CHK:
680 case NAME_QUERY_SRV_CHK:
681 case NAME_QUERY_FIND_MST:
682 case NAME_QUERY_MST_CHK:
684 if (nmb->answers->rr_type != 0x20)
686 DEBUG(1,("Name query reply has wrong answer rr_type\n"));
687 return False;
689 break;
692 case NAME_STATUS_DOM_SRV_CHK:
693 case NAME_STATUS_SRV_CHK:
695 if (nmb->answers->rr_type != 0x21)
697 DEBUG(1,("Name status reply has wrong answer rr_type\n"));
698 return False;
700 break;
703 default:
705 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
706 return False;
709 return True;
711 #endif
714 /****************************************************************************
715 process the response packet received
716 ****************************************************************************/
717 static void response_process(struct subnet_record *d, struct packet_struct *p,
718 struct response_record *n, struct nmb_packet *nmb,
719 BOOL bcast, struct nmb_name *ans_name)
721 switch (n->state)
723 case NAME_RELEASE:
725 response_name_release(ans_name, d, p);
726 break;
729 case NAME_REGISTER:
731 response_name_reg(ans_name, d, p);
732 break;
735 case NAME_REGISTER_CHALLENGE:
737 response_name_query_register(nmb, ans_name, n, d);
738 break;
741 case NAME_QUERY_DOM_SRV_CHK:
742 case NAME_QUERY_SRV_CHK:
743 case NAME_QUERY_FIND_MST:
745 response_server_check(ans_name, n, d, p);
746 break;
749 case NAME_STATUS_DOM_SRV_CHK:
750 case NAME_STATUS_SRV_CHK:
752 response_name_status_check(p->ip, nmb, bcast, n, d);
753 break;
756 case NAME_QUERY_CONFIRM:
757 case NAME_QUERY_SYNC_LOCAL:
758 case NAME_QUERY_SYNC_REMOTE:
760 response_name_query_sync(nmb, ans_name, bcast, n, d);
761 break;
763 case NAME_QUERY_MST_CHK:
765 /* no action required here. it's when NO responses are received
766 that we need to do something. see expire_name_query_entries() */
768 DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
769 namestr(&n->name), inet_ntoa(n->send_ip)));
770 break;
773 case NAME_QUERY_DOMAIN:
775 /* We were asking to be a domain master browser, and someone
776 replied. If it was the WINS server and the IP it is
777 returning is our own - then remove the record and pretend
778 we didn't get a response. Else we do nothing and let
779 dead_netbios_entry deal with it.
780 We can only become domain master browser
781 when no broadcast responses are received and WINS
782 either contains no entry for the DOMAIN<1b> name or
783 contains our IP address.
785 response_name_query_domain(ans_name, nmb, n, d);
786 break;
788 default:
790 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
791 break;
797 /****************************************************************************
798 response from a netbios packet.
799 ****************************************************************************/
800 void response_netbios_packet(struct packet_struct *p)
802 struct nmb_packet *nmb = &p->packet.nmb;
803 struct nmb_name *ans_name = NULL;
804 BOOL bcast = nmb->header.nm_flags.bcast;
805 struct response_record *n;
806 struct subnet_record *d = NULL;
808 if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
809 DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
810 return;
813 if (!d)
815 DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
816 return;
819 /* args wrong way round: spotted by ccm@shentel.net */
820 if (!same_net(d->bcast_ip, p->ip, d->mask_ip)) /* copes with WINS 'subnet' */
822 DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
823 DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
826 if (nmb->answers == NULL) {
827 /* if there is no name is the response then the name is the one
828 we queried on */
829 ans_name = &n->name;
830 } else {
831 ans_name = &nmb->answers->rr_name;
832 debug_rr_type(nmb->answers->rr_type);
835 DEBUG(3,("response for %s from %s(%d) (bcast=%s)\n",
836 namestr(ans_name), inet_ntoa(p->ip), p->port, BOOLSTR(bcast)));
838 n->num_msgs++; /* count number of responses received */
839 n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
841 debug_state_type(n->state);
843 /* problem checking: multiple responses etc */
844 if (nmb->answers && response_problem_check(n, nmb, ans_name->name))
845 return;
847 /* now deal with the current state */
848 response_process(d, p, n, nmb, bcast, ans_name);