fixed the freeze on logout bug. The fix has several parts:
[Samba.git] / source / nameservresp.c
blob8de90113fb6bd0b8c6913ac17fb65344d31e8431
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);
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->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 (interpret_node_status(d,nmb->answers->rdata,
273 &name,0x20,serv_name,ip,bcast))
275 if (*serv_name)
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);
284 else
286 DEBUG(1,("No 0x20 name type in interpret_node_status()\n"));
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)
299 struct in_addr register_ip;
300 BOOL new_owner;
302 DEBUG(4, ("Name query at %s ip %s - ",
303 namestr(&n->name), inet_ntoa(n->send_ip)));
305 if (!name_equal(&n->name, ans_name))
307 /* someone gave us the wrong name as a reply. oops. */
308 /* XXXX should say to them 'oi! release that name!' */
310 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
311 return;
314 if (nmb->header.rcode == 0 && nmb->answers->rdata)
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.
322 /* first check all the details are correct */
324 int nb_flags = nmb->answers->rdata[0];
325 struct in_addr found_ip;
327 putip((char*)&found_ip,&nmb->answers->rdata[2]);
329 if (nb_flags != n->nb_flags)
331 /* someone gave us the wrong nb_flags as a reply. oops. */
332 /* XXXX should say to them 'oi! release that name!' */
334 DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
335 DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
336 return;
339 if (!ip_equal(n->send_ip, found_ip))
341 /* someone gave us the wrong ip as a reply. oops. */
342 /* XXXX should say to them 'oi! release that name!' */
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;
349 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
351 /* fine: now tell the other host they can't have the name */
352 register_ip = n->send_ip;
353 new_owner = False;
355 else
357 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
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;
364 /* register the old or the new owners' ip */
365 add_name_respond(d, n->fd, d->myip, n->reply_id,&n->name,n->nb_flags,
366 GET_TTL(0), register_ip,
367 new_owner, n->reply_to_ip);
369 remove_response_record(d,n); /* remove the response record */
373 /****************************************************************************
374 response from a name query to sync browse lists or to update our netbios
375 entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM
376 ****************************************************************************/
377 static void response_name_query_sync(struct nmb_packet *nmb,
378 struct nmb_name *ans_name, BOOL bcast,
379 struct response_record *n, struct subnet_record *d)
381 DEBUG(4, ("Name query at %s ip %s - ",
382 namestr(&n->name), inet_ntoa(n->send_ip)));
384 if (!name_equal(&n->name, ans_name))
386 /* someone gave us the wrong name as a reply. oops. */
387 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
388 return;
391 if (nmb->header.rcode == 0 && nmb->answers->rdata)
393 int nb_flags = nmb->answers->rdata[0];
394 struct in_addr found_ip;
396 putip((char*)&found_ip,&nmb->answers->rdata[2]);
398 if (!ip_equal(n->send_ip, found_ip))
400 /* someone gave us the wrong ip as a reply. oops. */
401 DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
402 DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
403 return;
406 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
408 if (n->state == NAME_QUERY_SYNC_LOCAL ||
409 n->state == NAME_QUERY_SYNC_REMOTE)
411 struct work_record *work = NULL;
412 /* We cheat here as we know that the workgroup name has
413 been placed in the my_comment field of the
414 response_record struct by the code in
415 start_sync_browse_entry().
417 if ((work = find_workgroupstruct(d, n->my_comment, False)))
419 BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
421 /* the server is there: sync quick before it (possibly) dies! */
422 sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
423 found_ip, local_list_only);
426 else
428 /* update our netbios name list (re-register it if necessary) */
429 add_netbios_entry(d, ans_name->name, ans_name->name_type,
430 nb_flags,GET_TTL(0),REGISTER,
431 found_ip,False,!bcast);
434 else
436 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
438 if (n->state == NAME_QUERY_CONFIRM)
440 /* XXXX remove_netbios_entry()? */
441 /* lots of things we ought to do, here. if we get here,
442 then we're in a mess: our name database doesn't match
443 reality. sort it out
445 remove_netbios_name(d,n->name.name, n->name.name_type,
446 REGISTER,n->send_ip);
451 /****************************************************************************
452 response from a name query for DOMAIN<1b>
453 NAME_QUERY_DOMAIN is dealt with here - we are trying to become a domain
454 master browser and WINS replied - check it's our address.
455 ****************************************************************************/
456 static void response_name_query_domain(struct nmb_name *ans_name,
457 struct nmb_packet *nmb,
458 struct response_record *n, struct subnet_record *d)
460 DEBUG(4, ("response_name_query_domain: Got %s response from %s for query \
461 for %s\n", nmb->header.rcode == 0 ? "success" : "failure",
462 inet_ntoa(n->send_ip), namestr(ans_name)));
464 /* Check the name is correct and ip address returned is our own. If it is then we
465 just remove the response record.
467 if (name_equal(&n->name, ans_name) && (nmb->header.rcode == 0) && (nmb->answers->rdata))
469 struct in_addr found_ip;
471 putip((char*)&found_ip,&nmb->answers->rdata[2]);
472 /* Samba 1.9.16p11 servers seem to return the broadcast address for this
473 query. */
474 if (ismyip(found_ip) || ip_equal(wins_ip, found_ip) || ip_equal(ipzero, found_ip))
476 DEBUG(4, ("response_name_query_domain: WINS server returned our ip \
477 address. Pretending we never received response.\n"));
478 n->num_msgs = 0;
479 n->repeat_count = 0;
480 n->repeat_time = 0;
482 else
484 DEBUG(0,("response_name_query_domain: WINS server already has a \
485 domain master browser registered %s at address %s\n",
486 namestr(ans_name), inet_ntoa(found_ip)));
489 else
491 /* Negative/incorrect response. No domain master
492 browser was registered - pretend we didn't get this response.
494 n->num_msgs = 0;
495 n->repeat_count = 0;
496 n->repeat_time = 0;
501 /****************************************************************************
502 report the response record type
503 ****************************************************************************/
504 static void debug_rr_type(int rr_type)
506 switch (rr_type)
508 case NMB_STATUS: DEBUG(3,("Name status ")); break;
509 case NMB_QUERY : DEBUG(3,("Name query ")); break;
510 case NMB_REG : DEBUG(3,("Name registration ")); break;
511 case NMB_REL : DEBUG(3,("Name release ")); break;
512 default : DEBUG(1,("wrong response packet type received")); break;
516 /****************************************************************************
517 report the response record nmbd state
518 ****************************************************************************/
519 void debug_state_type(int state)
521 /* report the state type to help debugging */
522 switch (state)
524 case NAME_QUERY_DOM_SRV_CHK : DEBUG(4,("NAME_QUERY_DOM_SRV_CHK\n")); break;
525 case NAME_QUERY_SRV_CHK : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
526 case NAME_QUERY_FIND_MST : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
527 case NAME_QUERY_MST_CHK : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
528 case NAME_QUERY_CONFIRM : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
529 case NAME_QUERY_SYNC_LOCAL : DEBUG(4,("NAME_QUERY_SYNC_LOCAL\n")); break;
530 case NAME_QUERY_SYNC_REMOTE : DEBUG(4,("NAME_QUERY_SYNC_REMOTE\n")); break;
531 case NAME_QUERY_DOMAIN : DEBUG(4,("NAME_QUERY_DOMAIN\n")); break;
533 case NAME_REGISTER : DEBUG(4,("NAME_REGISTER\n")); break;
534 case NAME_REGISTER_CHALLENGE : DEBUG(4,("NAME_REGISTER_CHALLENGE\n"));break;
536 case NAME_RELEASE : DEBUG(4,("NAME_RELEASE\n")); break;
538 case NAME_STATUS_DOM_SRV_CHK : DEBUG(4,("NAME_STATUS_DOM_SRV_CHK\n")); break;
539 case NAME_STATUS_SRV_CHK : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
541 default: break;
545 /****************************************************************************
546 report any problems with the fact that a response has been received.
548 (responses for certain types of operations are only expected from one host)
549 ****************************************************************************/
550 static BOOL response_problem_check(struct response_record *n,
551 struct nmb_packet *nmb, char *ans_name)
553 switch (nmb->answers->rr_type)
555 case NMB_REL:
557 if (n->num_msgs > 1)
559 DEBUG(1,("more than one release name response received!\n"));
560 return True;
562 break;
565 case NMB_REG:
567 if (n->num_msgs > 1)
569 DEBUG(1,("more than one register name response received!\n"));
570 return True;
572 break;
575 case NMB_QUERY:
577 if (n->num_msgs > 1)
579 if (nmb->header.rcode == 0 && nmb->answers->rdata)
581 int nb_flags = nmb->answers->rdata[0];
583 if ((!NAME_GROUP(nb_flags)))
585 /* oh dear. more than one person responded to a
586 unique name.
587 there is either a network problem, a
588 configuration problem
589 or a server is mis-behaving */
591 /* XXXX mark the name as in conflict, and then let the
592 person who just responded know that they
593 must also mark it
594 as in conflict, and therefore must NOT use it.
595 see rfc1001.txt 15.1.3.5 */
597 /* this may cause problems for some
598 early versions of nmbd */
600 switch (n->state)
602 case NAME_QUERY_FIND_MST:
604 /* query for ^1^2__MSBROWSE__^2^1 expect
605 lots of responses */
606 return False;
608 case NAME_QUERY_DOM_SRV_CHK:
609 case NAME_QUERY_SRV_CHK:
610 case NAME_QUERY_MST_CHK:
612 if (!strequal(ans_name,n->name.name))
614 /* one subnet, one master browser
615 per workgroup */
616 /* XXXX force an election? */
618 DEBUG(3,("more than one master browser replied!\n"));
619 return True;
621 break;
623 default: break;
625 DEBUG(3,("Unique Name conflict detected!\n"));
626 return True;
629 else
631 /* we have received a negative reply,
632 having already received
633 at least one response (pos/neg).
634 something's really wrong! */
636 DEBUG(3,("wierd name query problem detected!\n"));
637 return True;
642 return False;
645 #if 0
646 /****************************************************************************
647 check that the response received is compatible with the response record
648 ****************************************************************************/
649 static BOOL response_compatible(struct response_record *n,
650 struct nmb_packet *nmb)
652 switch (n->state)
654 case NAME_RELEASE:
656 if (nmb->answers->rr_type != 0x20)
658 DEBUG(1,("Name release reply has wrong answer rr_type\n"));
659 return False;
661 break;
664 case NAME_REGISTER:
666 if (nmb->answers->rr_type != 0x20)
668 DEBUG(1,("Name register reply has wrong answer rr_type\n"));
669 return False;
671 break;
674 case NAME_REGISTER_CHALLENGE: /* this is a query: we then do a register */
675 case NAME_QUERY_CONFIRM:
676 case NAME_QUERY_SYNC_LOCAL:
677 case NAME_QUERY_SYNC_REMOTE:
678 case NAME_QUERY_DOM_SRV_CHK:
679 case NAME_QUERY_SRV_CHK:
680 case NAME_QUERY_FIND_MST:
681 case NAME_QUERY_MST_CHK:
683 if (nmb->answers->rr_type != 0x20)
685 DEBUG(1,("Name query reply has wrong answer rr_type\n"));
686 return False;
688 break;
691 case NAME_STATUS_DOM_SRV_CHK:
692 case NAME_STATUS_SRV_CHK:
694 if (nmb->answers->rr_type != 0x21)
696 DEBUG(1,("Name status reply has wrong answer rr_type\n"));
697 return False;
699 break;
702 default:
704 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
705 return False;
708 return True;
710 #endif
713 /****************************************************************************
714 process the response packet received
715 ****************************************************************************/
716 static void response_process(struct subnet_record *d, struct packet_struct *p,
717 struct response_record *n, struct nmb_packet *nmb,
718 BOOL bcast, struct nmb_name *ans_name)
720 switch (n->state)
722 case NAME_RELEASE:
724 response_name_release(ans_name, d, p);
725 break;
728 case NAME_REGISTER:
730 response_name_reg(ans_name, d, p);
731 break;
734 case NAME_REGISTER_CHALLENGE:
736 response_name_query_register(nmb, ans_name, n, d);
737 break;
740 case NAME_QUERY_DOM_SRV_CHK:
741 case NAME_QUERY_SRV_CHK:
742 case NAME_QUERY_FIND_MST:
744 response_server_check(ans_name, n, d, p);
745 break;
748 case NAME_STATUS_DOM_SRV_CHK:
749 case NAME_STATUS_SRV_CHK:
751 response_name_status_check(p->ip, nmb, bcast, n, d);
752 break;
755 case NAME_QUERY_CONFIRM:
756 case NAME_QUERY_SYNC_LOCAL:
757 case NAME_QUERY_SYNC_REMOTE:
759 response_name_query_sync(nmb, ans_name, bcast, n, d);
760 break;
762 case NAME_QUERY_MST_CHK:
764 /* no action required here. it's when NO responses are received
765 that we need to do something. see expire_name_query_entries() */
767 DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
768 namestr(&n->name), inet_ntoa(n->send_ip)));
769 break;
772 case NAME_QUERY_DOMAIN:
774 /* We were asking to be a domain master browser, and someone
775 replied. If it was the WINS server and the IP it is
776 returning is our own - then remove the record and pretend
777 we didn't get a response. Else we do nothing and let
778 dead_netbios_entry deal with it.
779 We can only become domain master browser
780 when no broadcast responses are received and WINS
781 either contains no entry for the DOMAIN<1b> name or
782 contains our IP address.
784 response_name_query_domain(ans_name, nmb, n, d);
785 break;
787 default:
789 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
790 break;
796 /****************************************************************************
797 response from a netbios packet.
798 ****************************************************************************/
799 void response_netbios_packet(struct packet_struct *p)
801 struct nmb_packet *nmb = &p->packet.nmb;
802 struct nmb_name *ans_name = NULL;
803 BOOL bcast = nmb->header.nm_flags.bcast;
804 struct response_record *n;
805 struct subnet_record *d = NULL;
807 if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
808 DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
809 return;
812 if (!d)
814 DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
815 return;
818 /* args wrong way round: spotted by ccm@shentel.net */
819 if (!same_net(d->bcast_ip, p->ip, d->mask_ip)) /* copes with WINS 'subnet' */
821 DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
822 DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
825 if (nmb->answers == NULL)
827 /* hm. the packet received was a response, but with no answer. wierd! */
828 DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
829 inet_ntoa(p->ip), BOOLSTR(bcast)));
830 return;
833 ans_name = &nmb->answers->rr_name;
834 DEBUG(3,("response for %s from %s(%d) (bcast=%s)\n",
835 namestr(ans_name), inet_ntoa(p->ip), p->port, BOOLSTR(bcast)));
837 debug_rr_type(nmb->answers->rr_type);
839 n->num_msgs++; /* count number of responses received */
840 n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
842 debug_state_type(n->state);
844 /* problem checking: multiple responses etc */
845 if (response_problem_check(n, nmb, ans_name->name))
846 return;
848 /* now deal with the current state */
849 response_process(d, p, n, nmb, bcast, ans_name);