[GLUE] Rsync SAMBA_3_0 SVN r25598 in order to create the v3-0-test branch.
[Samba.git] / source / nmbd / nmbd_packets.c
blob87a38b9d2a161eca7003aaf4e619d4ce70f4f600
1 /*
2 Unix SMB/CIFS implementation.
3 NBT netbios routines and daemon - version 2
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Luke Kenneth Casson Leighton 1994-1998
6 Copyright (C) Jeremy Allison 1994-2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "includes.h"
26 extern int ClientNMB;
27 extern int ClientDGRAM;
28 extern int global_nmb_port;
30 extern int num_response_packets;
32 extern struct in_addr loopback_ip;
34 static void queue_packet(struct packet_struct *packet);
36 BOOL rescan_listen_set = False;
39 /*******************************************************************
40 The global packet linked-list. Incoming entries are
41 added to the end of this list. It is supposed to remain fairly
42 short so we won't bother with an end pointer.
43 ******************************************************************/
45 static struct packet_struct *packet_queue = NULL;
47 /***************************************************************************
48 Utility function to find the specific fd to send a packet out on.
49 **************************************************************************/
51 static int find_subnet_fd_for_address( struct in_addr local_ip )
53 struct subnet_record *subrec;
55 for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
56 if(ip_equal(local_ip, subrec->myip))
57 return subrec->nmb_sock;
59 return ClientNMB;
62 /***************************************************************************
63 Utility function to find the specific fd to send a mailslot packet out on.
64 **************************************************************************/
66 static int find_subnet_mailslot_fd_for_address( struct in_addr local_ip )
68 struct subnet_record *subrec;
70 for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
71 if(ip_equal(local_ip, subrec->myip))
72 return subrec->dgram_sock;
74 return ClientDGRAM;
77 /***************************************************************************
78 Get/Set problematic nb_flags as network byte order 16 bit int.
79 **************************************************************************/
81 uint16 get_nb_flags(char *buf)
83 return ((((uint16)*buf)&0xFFFF) & NB_FLGMSK);
86 void set_nb_flags(char *buf, uint16 nb_flags)
88 *buf++ = ((nb_flags & NB_FLGMSK) & 0xFF);
89 *buf = '\0';
92 /***************************************************************************
93 Dumps out the browse packet data.
94 **************************************************************************/
96 static void debug_browse_data(char *outbuf, int len)
98 int i,j;
100 DEBUG( 4, ( "debug_browse_data():\n" ) );
101 for (i = 0; i < len; i+= 16) {
102 DEBUGADD( 4, ( "%3x char ", i ) );
104 for (j = 0; j < 16; j++) {
105 unsigned char x;
106 if (i+j >= len)
107 break;
109 x = outbuf[i+j];
110 if (x < 32 || x > 127)
111 x = '.';
113 DEBUGADD( 4, ( "%c", x ) );
116 DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
118 for (j = 0; j < 16; j++) {
119 if (i+j >= len)
120 break;
121 DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
124 DEBUGADD( 4, ("\n") );
128 /***************************************************************************
129 Generates the unique transaction identifier
130 **************************************************************************/
132 static uint16 name_trn_id=0;
134 static uint16 generate_name_trn_id(void)
136 if (!name_trn_id) {
137 name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
139 name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
140 return name_trn_id;
143 /***************************************************************************
144 Either loops back or sends out a completed NetBIOS packet.
145 **************************************************************************/
147 static BOOL send_netbios_packet(struct packet_struct *p)
149 BOOL loopback_this_packet = False;
151 /* Check if we are sending to or from ourselves as a WINS server. */
152 if(ismyip(p->ip) && (p->port == global_nmb_port))
153 loopback_this_packet = True;
155 if(loopback_this_packet) {
156 struct packet_struct *lo_packet = NULL;
157 DEBUG(5,("send_netbios_packet: sending packet to ourselves.\n"));
158 if((lo_packet = copy_packet(p)) == NULL)
159 return False;
160 queue_packet(lo_packet);
161 } else if (!send_packet(p)) {
162 DEBUG(0,("send_netbios_packet: send_packet() to IP %s port %d failed\n",
163 inet_ntoa(p->ip),p->port));
164 return False;
167 return True;
170 /***************************************************************************
171 Sets up the common elements of an outgoing NetBIOS packet.
173 Note: do not attempt to rationalise whether rec_des should be set or not
174 in a particular situation. Just follow rfc_1002 or look at examples from WinXX.
175 It does NOT follow the rule that requests to the wins server always have
176 rec_des true. See for example name releases and refreshes
177 **************************************************************************/
179 static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmbname,
180 BOOL bcast, BOOL rec_des,
181 struct in_addr to_ip)
183 struct packet_struct *packet = NULL;
184 struct nmb_packet *nmb = NULL;
186 /* Allocate the packet_struct we will return. */
187 if((packet = SMB_MALLOC_P(struct packet_struct)) == NULL) {
188 DEBUG(0,("create_and_init_netbios_packet: malloc fail (1) for packet struct.\n"));
189 return NULL;
192 memset((char *)packet,'\0',sizeof(*packet));
194 nmb = &packet->packet.nmb;
196 nmb->header.name_trn_id = generate_name_trn_id();
197 nmb->header.response = False;
198 nmb->header.nm_flags.recursion_desired = rec_des;
199 nmb->header.nm_flags.recursion_available = False;
200 nmb->header.nm_flags.trunc = False;
201 nmb->header.nm_flags.authoritative = False;
202 nmb->header.nm_flags.bcast = bcast;
204 nmb->header.rcode = 0;
205 nmb->header.qdcount = 1;
206 nmb->header.ancount = 0;
207 nmb->header.nscount = 0;
209 nmb->question.question_name = *nmbname;
210 nmb->question.question_type = QUESTION_TYPE_NB_QUERY;
211 nmb->question.question_class = QUESTION_CLASS_IN;
213 packet->ip = to_ip;
214 packet->port = NMB_PORT;
215 packet->fd = ClientNMB;
216 packet->timestamp = time(NULL);
217 packet->packet_type = NMB_PACKET;
218 packet->locked = False;
220 return packet; /* Caller must free. */
223 /***************************************************************************
224 Sets up the common elements of register, refresh or release packet.
225 **************************************************************************/
227 static BOOL create_and_init_additional_record(struct packet_struct *packet,
228 uint16 nb_flags,
229 struct in_addr *register_ip)
231 struct nmb_packet *nmb = &packet->packet.nmb;
233 if((nmb->additional = SMB_MALLOC_P(struct res_rec)) == NULL) {
234 DEBUG(0,("initiate_name_register_packet: malloc fail for additional record.\n"));
235 return False;
238 memset((char *)nmb->additional,'\0',sizeof(struct res_rec));
240 nmb->additional->rr_name = nmb->question.question_name;
241 nmb->additional->rr_type = RR_TYPE_NB;
242 nmb->additional->rr_class = RR_CLASS_IN;
244 /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
245 if (nmb->header.nm_flags.bcast)
246 nmb->additional->ttl = PERMANENT_TTL;
247 else
248 nmb->additional->ttl = lp_max_ttl();
250 nmb->additional->rdlength = 6;
252 set_nb_flags(nmb->additional->rdata,nb_flags);
254 /* Set the address for the name we are registering. */
255 putip(&nmb->additional->rdata[2], register_ip);
258 it turns out that Jeremys code was correct, we are supposed
259 to send registrations from the IP we are registering. The
260 trick is what to do on timeouts! When we send on a
261 non-routable IP then the reply will timeout, and we should
262 treat this as success, not failure. That means we go into
263 our standard refresh cycle for that name which copes nicely
264 with disconnected networks.
266 packet->fd = find_subnet_fd_for_address(*register_ip);
268 return True;
271 /***************************************************************************
272 Sends out a name query.
273 **************************************************************************/
275 static BOOL initiate_name_query_packet( struct packet_struct *packet)
277 struct nmb_packet *nmb = NULL;
279 nmb = &packet->packet.nmb;
281 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
282 nmb->header.arcount = 0;
284 nmb->header.nm_flags.recursion_desired = True;
286 DEBUG(4,("initiate_name_query_packet: sending query for name %s (bcast=%s) to IP %s\n",
287 nmb_namestr(&nmb->question.question_name),
288 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
290 return send_netbios_packet( packet );
293 /***************************************************************************
294 Sends out a name query - from a WINS server.
295 **************************************************************************/
297 static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
299 struct nmb_packet *nmb = NULL;
301 nmb = &packet->packet.nmb;
303 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
304 nmb->header.arcount = 0;
306 nmb->header.nm_flags.recursion_desired = False;
308 DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
309 nmb_namestr(&nmb->question.question_name),
310 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
312 return send_netbios_packet( packet );
315 /***************************************************************************
316 Sends out a name register.
317 **************************************************************************/
319 static BOOL initiate_name_register_packet( struct packet_struct *packet,
320 uint16 nb_flags, struct in_addr *register_ip)
322 struct nmb_packet *nmb = &packet->packet.nmb;
324 nmb->header.opcode = NMB_NAME_REG_OPCODE;
325 nmb->header.arcount = 1;
327 nmb->header.nm_flags.recursion_desired = True;
329 if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
330 return False;
332 DEBUG(4,("initiate_name_register_packet: sending registration for name %s (bcast=%s) to IP %s\n",
333 nmb_namestr(&nmb->additional->rr_name),
334 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
336 return send_netbios_packet( packet );
339 /***************************************************************************
340 Sends out a multihomed name register.
341 **************************************************************************/
343 static BOOL initiate_multihomed_name_register_packet(struct packet_struct *packet,
344 uint16 nb_flags, struct in_addr *register_ip)
346 struct nmb_packet *nmb = &packet->packet.nmb;
347 fstring second_ip_buf;
349 fstrcpy(second_ip_buf, inet_ntoa(packet->ip));
351 nmb->header.opcode = NMB_NAME_MULTIHOMED_REG_OPCODE;
352 nmb->header.arcount = 1;
354 nmb->header.nm_flags.recursion_desired = True;
356 if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
357 return False;
359 DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
360 for name %s IP %s (bcast=%s) to IP %s\n",
361 nmb_namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
362 BOOLSTR(nmb->header.nm_flags.bcast), second_ip_buf ));
364 return send_netbios_packet( packet );
367 /***************************************************************************
368 Sends out a name refresh.
369 **************************************************************************/
371 static BOOL initiate_name_refresh_packet( struct packet_struct *packet,
372 uint16 nb_flags, struct in_addr *refresh_ip)
374 struct nmb_packet *nmb = &packet->packet.nmb;
376 nmb->header.opcode = NMB_NAME_REFRESH_OPCODE_8;
377 nmb->header.arcount = 1;
379 nmb->header.nm_flags.recursion_desired = False;
381 if(create_and_init_additional_record(packet, nb_flags, refresh_ip) == False)
382 return False;
384 DEBUG(4,("initiate_name_refresh_packet: sending refresh for name %s (bcast=%s) to IP %s\n",
385 nmb_namestr(&nmb->additional->rr_name),
386 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
388 return send_netbios_packet( packet );
391 /***************************************************************************
392 Sends out a name release.
393 **************************************************************************/
395 static BOOL initiate_name_release_packet( struct packet_struct *packet,
396 uint16 nb_flags, struct in_addr *release_ip)
398 struct nmb_packet *nmb = &packet->packet.nmb;
400 nmb->header.opcode = NMB_NAME_RELEASE_OPCODE;
401 nmb->header.arcount = 1;
403 nmb->header.nm_flags.recursion_desired = False;
405 if(create_and_init_additional_record(packet, nb_flags, release_ip) == False)
406 return False;
408 DEBUG(4,("initiate_name_release_packet: sending release for name %s (bcast=%s) to IP %s\n",
409 nmb_namestr(&nmb->additional->rr_name),
410 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
412 return send_netbios_packet( packet );
415 /***************************************************************************
416 Sends out a node status.
417 **************************************************************************/
419 static BOOL initiate_node_status_packet( struct packet_struct *packet )
421 struct nmb_packet *nmb = &packet->packet.nmb;
423 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
424 nmb->header.arcount = 0;
426 nmb->header.nm_flags.recursion_desired = False;
428 nmb->question.question_type = QUESTION_TYPE_NB_STATUS;
430 DEBUG(4,("initiate_node_status_packet: sending node status request for name %s to IP %s\n",
431 nmb_namestr(&nmb->question.question_name),
432 inet_ntoa(packet->ip)));
434 return send_netbios_packet( packet );
437 /****************************************************************************
438 Simplification functions for queuing standard packets.
439 These should be the only publicly callable functions for sending
440 out packets.
441 ****************************************************************************/
443 /****************************************************************************
444 Assertion - we should never be sending nmbd packets on the remote
445 broadcast subnet.
446 ****************************************************************************/
448 static BOOL assert_check_subnet(struct subnet_record *subrec)
450 if( subrec == remote_broadcast_subnet) {
451 DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
452 This is a bug.\n"));
453 return True;
455 return False;
458 /****************************************************************************
459 Queue a register name packet to the broadcast address of a subnet.
460 ****************************************************************************/
462 struct response_record *queue_register_name( struct subnet_record *subrec,
463 response_function resp_fn,
464 timeout_response_function timeout_fn,
465 register_name_success_function success_fn,
466 register_name_fail_function fail_fn,
467 struct userdata_struct *userdata,
468 struct nmb_name *nmbname,
469 uint16 nb_flags)
471 struct packet_struct *p;
472 struct response_record *rrec;
474 if(assert_check_subnet(subrec))
475 return NULL;
477 /* note that all name registration requests have RD set (rfc1002 - section 4.2.2 */
478 if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), True,
479 subrec->bcast_ip)) == NULL)
480 return NULL;
482 if(initiate_name_register_packet( p, nb_flags, iface_ip(subrec->bcast_ip)) == False) {
483 p->locked = False;
484 free_packet(p);
485 return NULL;
488 if((rrec = make_response_record(subrec, /* subnet record. */
489 p, /* packet we sent. */
490 resp_fn, /* function to call on response. */
491 timeout_fn, /* function to call on timeout. */
492 (success_function)success_fn, /* function to call on operation success. */
493 (fail_function)fail_fn, /* function to call on operation fail. */
494 userdata)) == NULL) {
495 p->locked = False;
496 free_packet(p);
497 return NULL;
500 return rrec;
503 /****************************************************************************
504 Queue a refresh name packet to the broadcast address of a subnet.
505 ****************************************************************************/
507 void queue_wins_refresh(struct nmb_name *nmbname,
508 response_function resp_fn,
509 timeout_response_function timeout_fn,
510 uint16 nb_flags,
511 struct in_addr refresh_ip,
512 const char *tag)
514 struct packet_struct *p;
515 struct response_record *rrec;
516 struct in_addr wins_ip;
517 struct userdata_struct *userdata;
518 fstring ip_str;
520 wins_ip = wins_srv_ip_tag(tag, refresh_ip);
522 if ((p = create_and_init_netbios_packet(nmbname, False, False, wins_ip)) == NULL) {
523 return;
526 if (!initiate_name_refresh_packet(p, nb_flags, &refresh_ip)) {
527 p->locked = False;
528 free_packet(p);
529 return;
532 fstrcpy(ip_str, inet_ntoa(refresh_ip));
534 DEBUG(6,("Refreshing name %s IP %s with WINS server %s using tag '%s'\n",
535 nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
537 userdata = (struct userdata_struct *)SMB_MALLOC(sizeof(*userdata) + strlen(tag) + 1);
538 if (!userdata) {
539 p->locked = False;
540 free_packet(p);
541 DEBUG(0,("Failed to allocate userdata structure!\n"));
542 return;
544 ZERO_STRUCTP(userdata);
545 userdata->userdata_len = strlen(tag) + 1;
546 strlcpy(userdata->data, tag, userdata->userdata_len);
548 if ((rrec = make_response_record(unicast_subnet,
550 resp_fn, timeout_fn,
551 NULL,
552 NULL,
553 userdata)) == NULL) {
554 p->locked = False;
555 free_packet(p);
556 return;
559 free(userdata);
561 /* we don't want to repeat refresh packets */
562 rrec->repeat_count = 0;
566 /****************************************************************************
567 Queue a multihomed register name packet to a given WINS server IP
568 ****************************************************************************/
570 struct response_record *queue_register_multihomed_name( struct subnet_record *subrec,
571 response_function resp_fn,
572 timeout_response_function timeout_fn,
573 register_name_success_function success_fn,
574 register_name_fail_function fail_fn,
575 struct userdata_struct *userdata,
576 struct nmb_name *nmbname,
577 uint16 nb_flags,
578 struct in_addr register_ip,
579 struct in_addr wins_ip)
581 struct packet_struct *p;
582 struct response_record *rrec;
583 BOOL ret;
585 /* Sanity check. */
586 if(subrec != unicast_subnet) {
587 DEBUG(0,("queue_register_multihomed_name: should only be done on \
588 unicast subnet. subnet is %s\n.", subrec->subnet_name ));
589 return NULL;
592 if(assert_check_subnet(subrec))
593 return NULL;
595 if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL)
596 return NULL;
598 if (nb_flags & NB_GROUP)
599 ret = initiate_name_register_packet( p, nb_flags, &register_ip);
600 else
601 ret = initiate_multihomed_name_register_packet(p, nb_flags, &register_ip);
603 if (ret == False) {
604 p->locked = False;
605 free_packet(p);
606 return NULL;
609 if ((rrec = make_response_record(subrec, /* subnet record. */
610 p, /* packet we sent. */
611 resp_fn, /* function to call on response. */
612 timeout_fn, /* function to call on timeout. */
613 (success_function)success_fn, /* function to call on operation success. */
614 (fail_function)fail_fn, /* function to call on operation fail. */
615 userdata)) == NULL) {
616 p->locked = False;
617 free_packet(p);
618 return NULL;
621 return rrec;
624 /****************************************************************************
625 Queue a release name packet to the broadcast address of a subnet.
626 ****************************************************************************/
628 struct response_record *queue_release_name( struct subnet_record *subrec,
629 response_function resp_fn,
630 timeout_response_function timeout_fn,
631 release_name_success_function success_fn,
632 release_name_fail_function fail_fn,
633 struct userdata_struct *userdata,
634 struct nmb_name *nmbname,
635 uint16 nb_flags,
636 struct in_addr release_ip,
637 struct in_addr dest_ip)
639 struct packet_struct *p;
640 struct response_record *rrec;
642 if(assert_check_subnet(subrec))
643 return NULL;
645 if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False, dest_ip)) == NULL)
646 return NULL;
648 if(initiate_name_release_packet( p, nb_flags, &release_ip) == False) {
649 p->locked = False;
650 free_packet(p);
651 return NULL;
654 if((rrec = make_response_record(subrec, /* subnet record. */
655 p, /* packet we sent. */
656 resp_fn, /* function to call on response. */
657 timeout_fn, /* function to call on timeout. */
658 (success_function)success_fn, /* function to call on operation success. */
659 (fail_function)fail_fn, /* function to call on operation fail. */
660 userdata)) == NULL) {
661 p->locked = False;
662 free_packet(p);
663 return NULL;
667 * For a broadcast release packet, only send once.
668 * This will cause us to remove the name asap. JRA.
671 if (subrec != unicast_subnet) {
672 rrec->repeat_count = 0;
673 rrec->repeat_time = 0;
676 return rrec;
679 /****************************************************************************
680 Queue a query name packet to the broadcast address of a subnet.
681 ****************************************************************************/
683 struct response_record *queue_query_name( struct subnet_record *subrec,
684 response_function resp_fn,
685 timeout_response_function timeout_fn,
686 query_name_success_function success_fn,
687 query_name_fail_function fail_fn,
688 struct userdata_struct *userdata,
689 struct nmb_name *nmbname)
691 struct packet_struct *p;
692 struct response_record *rrec;
693 struct in_addr to_ip;
695 if(assert_check_subnet(subrec))
696 return NULL;
698 to_ip = subrec->bcast_ip;
700 /* queries to the WINS server turn up here as queries to IP 0.0.0.0
701 These need to be handled a bit differently */
702 if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
703 /* What we really need to do is loop over each of our wins
704 * servers and wins server tags here, but that just doesn't
705 * fit our architecture at the moment (userdata may already
706 * be used when we get here). For now we just query the first
707 * active wins server on the first tag.
709 char **tags = wins_srv_tags();
710 if (!tags) {
711 return NULL;
713 to_ip = wins_srv_ip_tag(tags[0], to_ip);
714 wins_srv_tags_free(tags);
717 if(( p = create_and_init_netbios_packet(nmbname,
718 (subrec != unicast_subnet),
719 (subrec == unicast_subnet),
720 to_ip)) == NULL)
721 return NULL;
723 if(lp_bind_interfaces_only()) {
724 int i;
726 DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
727 for(i = 0; i < iface_count(); i++) {
728 struct in_addr *ifip = iface_n_ip(i);
730 if(ifip == NULL) {
731 DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
732 continue;
735 if (ip_equal(*ifip,loopback_ip)) {
736 DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
737 continue;
740 DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
741 p->fd = find_subnet_fd_for_address( *ifip );
742 break;
746 if(initiate_name_query_packet( p ) == False) {
747 p->locked = False;
748 free_packet(p);
749 return NULL;
752 if((rrec = make_response_record(subrec, /* subnet record. */
753 p, /* packet we sent. */
754 resp_fn, /* function to call on response. */
755 timeout_fn, /* function to call on timeout. */
756 (success_function)success_fn, /* function to call on operation success. */
757 (fail_function)fail_fn, /* function to call on operation fail. */
758 userdata)) == NULL) {
759 p->locked = False;
760 free_packet(p);
761 return NULL;
764 return rrec;
767 /****************************************************************************
768 Queue a query name packet to a given address from the WINS subnet.
769 ****************************************************************************/
771 struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
772 response_function resp_fn,
773 timeout_response_function timeout_fn,
774 query_name_success_function success_fn,
775 query_name_fail_function fail_fn,
776 struct userdata_struct *userdata,
777 struct nmb_name *nmbname)
779 struct packet_struct *p;
780 struct response_record *rrec;
782 if ((p = create_and_init_netbios_packet(nmbname, False, False, to_ip)) == NULL)
783 return NULL;
785 if(initiate_name_query_packet_from_wins_server( p ) == False) {
786 p->locked = False;
787 free_packet(p);
788 return NULL;
791 if((rrec = make_response_record(wins_server_subnet, /* subnet record. */
792 p, /* packet we sent. */
793 resp_fn, /* function to call on response. */
794 timeout_fn, /* function to call on timeout. */
795 (success_function)success_fn, /* function to call on operation success. */
796 (fail_function)fail_fn, /* function to call on operation fail. */
797 userdata)) == NULL) {
798 p->locked = False;
799 free_packet(p);
800 return NULL;
803 return rrec;
806 /****************************************************************************
807 Queue a node status packet to a given name and address.
808 ****************************************************************************/
810 struct response_record *queue_node_status( struct subnet_record *subrec,
811 response_function resp_fn,
812 timeout_response_function timeout_fn,
813 node_status_success_function success_fn,
814 node_status_fail_function fail_fn,
815 struct userdata_struct *userdata,
816 struct nmb_name *nmbname,
817 struct in_addr send_ip)
819 struct packet_struct *p;
820 struct response_record *rrec;
822 /* Sanity check. */
823 if(subrec != unicast_subnet) {
824 DEBUG(0,("queue_register_multihomed_name: should only be done on \
825 unicast subnet. subnet is %s\n.", subrec->subnet_name ));
826 return NULL;
829 if(assert_check_subnet(subrec))
830 return NULL;
832 if(( p = create_and_init_netbios_packet(nmbname, False, False, send_ip)) == NULL)
833 return NULL;
835 if(initiate_node_status_packet(p) == False) {
836 p->locked = False;
837 free_packet(p);
838 return NULL;
841 if((rrec = make_response_record(subrec, /* subnet record. */
842 p, /* packet we sent. */
843 resp_fn, /* function to call on response. */
844 timeout_fn, /* function to call on timeout. */
845 (success_function)success_fn, /* function to call on operation success. */
846 (fail_function)fail_fn, /* function to call on operation fail. */
847 userdata)) == NULL) {
848 p->locked = False;
849 free_packet(p);
850 return NULL;
853 return rrec;
856 /****************************************************************************
857 Reply to a netbios name packet. see rfc1002.txt
858 ****************************************************************************/
860 void reply_netbios_packet(struct packet_struct *orig_packet,
861 int rcode, enum netbios_reply_type_code rcv_code, int opcode,
862 int ttl, char *data,int len)
864 struct packet_struct packet;
865 struct nmb_packet *nmb = NULL;
866 struct res_rec answers;
867 struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
868 BOOL loopback_this_packet = False;
869 int rr_type = RR_TYPE_NB;
870 const char *packet_type = "unknown";
872 /* Check if we are sending to or from ourselves. */
873 if(ismyip(orig_packet->ip) && (orig_packet->port == global_nmb_port))
874 loopback_this_packet = True;
876 nmb = &packet.packet.nmb;
878 /* Do a partial copy of the packet. We clear the locked flag and
879 the resource record pointers. */
880 packet = *orig_packet; /* Full structure copy. */
881 packet.locked = False;
882 nmb->answers = NULL;
883 nmb->nsrecs = NULL;
884 nmb->additional = NULL;
886 switch (rcv_code) {
887 case NMB_STATUS:
888 packet_type = "nmb_status";
889 nmb->header.nm_flags.recursion_desired = False;
890 nmb->header.nm_flags.recursion_available = False;
891 rr_type = RR_TYPE_NBSTAT;
892 break;
893 case NMB_QUERY:
894 packet_type = "nmb_query";
895 nmb->header.nm_flags.recursion_desired = True;
896 nmb->header.nm_flags.recursion_available = True;
897 if (rcode) {
898 rr_type = RR_TYPE_NULL;
900 break;
901 case NMB_REG:
902 case NMB_REG_REFRESH:
903 packet_type = "nmb_reg";
904 nmb->header.nm_flags.recursion_desired = True;
905 nmb->header.nm_flags.recursion_available = True;
906 break;
907 case NMB_REL:
908 packet_type = "nmb_rel";
909 nmb->header.nm_flags.recursion_desired = False;
910 nmb->header.nm_flags.recursion_available = False;
911 break;
912 case NMB_WAIT_ACK:
913 packet_type = "nmb_wack";
914 nmb->header.nm_flags.recursion_desired = False;
915 nmb->header.nm_flags.recursion_available = False;
916 rr_type = RR_TYPE_NULL;
917 break;
918 case WINS_REG:
919 packet_type = "wins_reg";
920 nmb->header.nm_flags.recursion_desired = True;
921 nmb->header.nm_flags.recursion_available = True;
922 break;
923 case WINS_QUERY:
924 packet_type = "wins_query";
925 nmb->header.nm_flags.recursion_desired = True;
926 nmb->header.nm_flags.recursion_available = True;
927 if (rcode) {
928 rr_type = RR_TYPE_NULL;
930 break;
931 default:
932 DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
933 packet_type, nmb_namestr(&orig_nmb->question.question_name),
934 inet_ntoa(packet.ip)));
935 return;
938 DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
939 for id %hu\n", packet_type, nmb_namestr(&orig_nmb->question.question_name),
940 inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
942 nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
943 nmb->header.opcode = opcode;
944 nmb->header.response = True;
945 nmb->header.nm_flags.bcast = False;
946 nmb->header.nm_flags.trunc = False;
947 nmb->header.nm_flags.authoritative = True;
949 nmb->header.rcode = rcode;
950 nmb->header.qdcount = 0;
951 nmb->header.ancount = 1;
952 nmb->header.nscount = 0;
953 nmb->header.arcount = 0;
955 memset((char*)&nmb->question,'\0',sizeof(nmb->question));
957 nmb->answers = &answers;
958 memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
960 nmb->answers->rr_name = orig_nmb->question.question_name;
961 nmb->answers->rr_type = rr_type;
962 nmb->answers->rr_class = RR_CLASS_IN;
963 nmb->answers->ttl = ttl;
965 if (data && len) {
966 nmb->answers->rdlength = len;
967 memcpy(nmb->answers->rdata, data, len);
970 packet.packet_type = NMB_PACKET;
971 /* Ensure we send out on the same fd that the original
972 packet came in on to give the correct source IP address. */
973 packet.fd = orig_packet->fd;
974 packet.timestamp = time(NULL);
976 debug_nmb_packet(&packet);
978 if(loopback_this_packet) {
979 struct packet_struct *lo_packet;
980 DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
981 if((lo_packet = copy_packet(&packet)) == NULL)
982 return;
983 queue_packet(lo_packet);
984 } else if (!send_packet(&packet)) {
985 DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
986 inet_ntoa(packet.ip),packet.port));
990 /*******************************************************************
991 Queue a packet into a packet queue
992 ******************************************************************/
994 static void queue_packet(struct packet_struct *packet)
996 struct packet_struct *p;
998 if (!packet_queue) {
999 packet->prev = NULL;
1000 packet->next = NULL;
1001 packet_queue = packet;
1002 return;
1005 /* find the bottom */
1006 for (p=packet_queue;p->next;p=p->next)
1009 p->next = packet;
1010 packet->next = NULL;
1011 packet->prev = p;
1014 /****************************************************************************
1015 Try and find a matching subnet record for a datagram port 138 packet.
1016 ****************************************************************************/
1018 static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_struct *p)
1020 struct subnet_record *subrec;
1022 /* Go through all the broadcast subnets and see if the mask matches. */
1023 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1024 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1025 return subrec;
1028 /* If the subnet record is the remote announce broadcast subnet,
1029 hack it here to be the first subnet. This is really gross and
1030 is needed due to people turning on port 137/138 broadcast
1031 forwarding on their routers. May fire and brimstone rain
1032 down upon them...
1035 return FIRST_SUBNET;
1038 /****************************************************************************
1039 Dispatch a browse frame from port 138 to the correct processing function.
1040 ****************************************************************************/
1042 static void process_browse_packet(struct packet_struct *p, char *buf,int len)
1044 struct dgram_packet *dgram = &p->packet.dgram;
1045 int command = CVAL(buf,0);
1046 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1047 char scope[64];
1048 unstring src_name;
1050 /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
1051 pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
1052 if (!strequal(scope, global_scope())) {
1053 DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
1054 mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
1055 return;
1058 pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
1059 if (is_myname(src_name)) {
1060 DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
1061 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1062 return;
1065 switch (command) {
1066 case ANN_HostAnnouncement:
1067 debug_browse_data(buf, len);
1068 process_host_announce(subrec, p, buf+1);
1069 break;
1070 case ANN_DomainAnnouncement:
1071 debug_browse_data(buf, len);
1072 process_workgroup_announce(subrec, p, buf+1);
1073 break;
1074 case ANN_LocalMasterAnnouncement:
1075 debug_browse_data(buf, len);
1076 process_local_master_announce(subrec, p, buf+1);
1077 break;
1078 case ANN_AnnouncementRequest:
1079 debug_browse_data(buf, len);
1080 process_announce_request(subrec, p, buf+1);
1081 break;
1082 case ANN_Election:
1083 debug_browse_data(buf, len);
1084 process_election(subrec, p, buf+1);
1085 break;
1086 case ANN_GetBackupListReq:
1087 debug_browse_data(buf, len);
1088 process_get_backup_list_request(subrec, p, buf+1);
1089 break;
1090 case ANN_GetBackupListResp:
1091 debug_browse_data(buf, len);
1092 /* We never send ANN_GetBackupListReq so we should never get these. */
1093 DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
1094 packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
1095 break;
1096 case ANN_ResetBrowserState:
1097 debug_browse_data(buf, len);
1098 process_reset_browser(subrec, p, buf+1);
1099 break;
1100 case ANN_MasterAnnouncement:
1101 /* Master browser datagrams must be processed on the unicast subnet. */
1102 subrec = unicast_subnet;
1104 debug_browse_data(buf, len);
1105 process_master_browser_announce(subrec, p, buf+1);
1106 break;
1107 case ANN_BecomeBackup:
1109 * We don't currently implement this. Log it just in case.
1111 debug_browse_data(buf, len);
1112 DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
1113 command ANN_BecomeBackup from %s IP %s to %s\n", subrec->subnet_name, nmb_namestr(&dgram->source_name),
1114 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1115 break;
1116 default:
1117 debug_browse_data(buf, len);
1118 DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
1119 command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1120 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1121 break;
1125 /****************************************************************************
1126 Dispatch a LanMan browse frame from port 138 to the correct processing function.
1127 ****************************************************************************/
1129 static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
1131 struct dgram_packet *dgram = &p->packet.dgram;
1132 int command = SVAL(buf,0);
1133 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1134 char scope[64];
1135 unstring src_name;
1137 /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
1139 pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
1140 if (!strequal(scope, global_scope())) {
1141 DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
1142 mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
1143 return;
1146 pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
1147 if (is_myname(src_name)) {
1148 DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
1149 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1150 return;
1153 switch (command) {
1154 case ANN_HostAnnouncement:
1155 debug_browse_data(buf, len);
1156 process_lm_host_announce(subrec, p, buf+1, len > 1 ? len-1 : 0);
1157 break;
1158 case ANN_AnnouncementRequest:
1159 process_lm_announce_request(subrec, p, buf+1, len > 1 ? len-1 : 0);
1160 break;
1161 default:
1162 DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
1163 command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1164 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1165 break;
1169 /****************************************************************************
1170 Determine if a packet is for us on port 138. Note that to have any chance of
1171 being efficient we need to drop as many packets as possible at this
1172 stage as subsequent processing is expensive.
1173 ****************************************************************************/
1175 static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
1177 struct subnet_record *subrec = NULL;
1179 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1180 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1181 break;
1184 if(subrec == NULL)
1185 subrec = unicast_subnet;
1187 return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
1190 /****************************************************************************
1191 Process udp 138 datagrams
1192 ****************************************************************************/
1194 static void process_dgram(struct packet_struct *p)
1196 char *buf;
1197 char *buf2;
1198 int len;
1199 struct dgram_packet *dgram = &p->packet.dgram;
1201 /* If we aren't listening to the destination name then ignore the packet */
1202 if (!listening(p,&dgram->dest_name)) {
1203 unexpected_packet(p);
1204 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
1205 nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
1206 return;
1209 if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) {
1210 unexpected_packet(p);
1211 /* Don't process error packets etc yet */
1212 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
1213 an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
1214 return;
1217 /* Ensure we have a large enough packet before looking inside. */
1218 if (dgram->datasize < (smb_vwv12 - 2)) {
1219 /* That's the offset minus the 4 byte length + 2 bytes of offset. */
1220 DEBUG(0,("process_dgram: ignoring too short dgram packet (%u) sent to name %s from IP %s\n",
1221 (unsigned int)dgram->datasize,
1222 nmb_namestr(&dgram->dest_name),
1223 inet_ntoa(p->ip) ));
1224 return;
1227 buf = &dgram->data[0];
1228 buf -= 4; /* XXXX for the pseudo tcp length - someday I need to get rid of this */
1230 if (CVAL(buf,smb_com) != SMBtrans)
1231 return;
1233 len = SVAL(buf,smb_vwv11);
1234 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1236 if (len <= 0 || len > dgram->datasize) {
1237 DEBUG(0,("process_dgram: ignoring malformed1 (datasize = %d, len = %d) datagram \
1238 packet sent to name %s from IP %s\n",
1239 dgram->datasize,
1240 len,
1241 nmb_namestr(&dgram->dest_name),
1242 inet_ntoa(p->ip) ));
1243 return;
1246 if (buf2 < dgram->data || (buf2 >= dgram->data + dgram->datasize)) {
1247 DEBUG(0,("process_dgram: ignoring malformed2 (datasize = %d, len=%d, off=%d) datagram \
1248 packet sent to name %s from IP %s\n",
1249 dgram->datasize,
1250 len,
1251 (int)PTR_DIFF(buf2, dgram->data),
1252 nmb_namestr(&dgram->dest_name),
1253 inet_ntoa(p->ip) ));
1254 return;
1257 if ((buf2 + len < dgram->data) || (buf2 + len > dgram->data + dgram->datasize)) {
1258 DEBUG(0,("process_dgram: ignoring malformed3 (datasize = %d, len=%d, off=%d) datagram \
1259 packet sent to name %s from IP %s\n",
1260 dgram->datasize,
1261 len,
1262 (int)PTR_DIFF(buf2, dgram->data),
1263 nmb_namestr(&dgram->dest_name),
1264 inet_ntoa(p->ip) ));
1265 return;
1268 DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
1269 nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
1270 inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
1272 /* Datagram packet received for the browser mailslot */
1273 if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
1274 process_browse_packet(p,buf2,len);
1275 return;
1278 /* Datagram packet received for the LAN Manager mailslot */
1279 if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
1280 process_lanman_packet(p,buf2,len);
1281 return;
1284 /* Datagram packet received for the domain logon mailslot */
1285 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
1286 process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
1287 return;
1290 /* Datagram packet received for the NT domain logon mailslot */
1291 if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT)) {
1292 process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
1293 return;
1296 unexpected_packet(p);
1299 /****************************************************************************
1300 Validate a response nmb packet.
1301 ****************************************************************************/
1303 static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
1305 BOOL ignore = False;
1307 switch (nmb->header.opcode) {
1308 case NMB_NAME_REG_OPCODE:
1309 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1310 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1311 if (nmb->header.ancount == 0) {
1312 DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
1313 ignore = True;
1315 break;
1317 case NMB_NAME_QUERY_OPCODE:
1318 if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1)) {
1319 DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
1320 ignore = True;
1322 break;
1324 case NMB_NAME_RELEASE_OPCODE:
1325 if (nmb->header.ancount == 0) {
1326 DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
1327 ignore = True;
1329 break;
1331 case NMB_WACK_OPCODE:
1332 /* Check WACK response here. */
1333 if (nmb->header.ancount != 1) {
1334 DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
1335 ignore = True;
1337 break;
1338 default:
1339 DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
1340 nmb->header.opcode));
1341 return True;
1344 if(ignore)
1345 DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
1347 return ignore;
1350 /****************************************************************************
1351 Validate a request nmb packet.
1352 ****************************************************************************/
1354 static BOOL validate_nmb_packet( struct nmb_packet *nmb )
1356 BOOL ignore = False;
1358 switch (nmb->header.opcode) {
1359 case NMB_NAME_REG_OPCODE:
1360 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1361 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1362 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1363 if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
1364 DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
1365 ignore = True;
1367 break;
1369 case NMB_NAME_QUERY_OPCODE:
1370 if ((nmb->header.qdcount == 0) || ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
1371 (nmb->question.question_type != QUESTION_TYPE_NB_STATUS))) {
1372 DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
1373 ignore = True;
1375 break;
1377 case NMB_NAME_RELEASE_OPCODE:
1378 if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
1379 DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
1380 ignore = True;
1382 break;
1383 default:
1384 DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
1385 nmb->header.opcode));
1386 return True;
1389 if(ignore)
1390 DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
1392 return ignore;
1395 /****************************************************************************
1396 Find a subnet (and potentially a response record) for a packet.
1397 ****************************************************************************/
1399 static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,
1400 struct response_record **pprrec)
1402 struct nmb_packet *nmb = &p->packet.nmb;
1403 struct response_record *rrec = NULL;
1404 struct subnet_record *subrec = NULL;
1406 if(pprrec != NULL)
1407 *pprrec = NULL;
1409 if(nmb->header.response) {
1410 /* It's a response packet. Find a record for it or it's an error. */
1412 rrec = find_response_record( &subrec, nmb->header.name_trn_id);
1413 if(rrec == NULL) {
1414 DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
1415 nmb->header.name_trn_id));
1416 unexpected_packet(p);
1417 return NULL;
1420 if(subrec == NULL) {
1421 DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
1422 nmb->header.name_trn_id));
1423 return NULL;
1426 if(pprrec != NULL)
1427 *pprrec = rrec;
1428 return subrec;
1431 /* Try and see what subnet this packet belongs to. */
1433 /* WINS server ? */
1434 if(packet_is_for_wins_server(p))
1435 return wins_server_subnet;
1437 /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
1438 if(nmb->header.nm_flags.bcast == False)
1439 return unicast_subnet;
1441 /* Go through all the broadcast subnets and see if the mask matches. */
1442 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1443 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1444 return subrec;
1447 /* If none match it must have been a directed broadcast - assign the remote_broadcast_subnet. */
1448 return remote_broadcast_subnet;
1451 /****************************************************************************
1452 Process a nmb request packet - validate the packet and route it.
1453 ****************************************************************************/
1455 static void process_nmb_request(struct packet_struct *p)
1457 struct nmb_packet *nmb = &p->packet.nmb;
1458 struct subnet_record *subrec = NULL;
1460 debug_nmb_packet(p);
1462 /* Ensure we have a good packet. */
1463 if(validate_nmb_packet(nmb))
1464 return;
1466 /* Allocate a subnet to this packet - if we cannot - fail. */
1467 if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
1468 return;
1470 switch (nmb->header.opcode) {
1471 case NMB_NAME_REG_OPCODE:
1472 if(subrec == wins_server_subnet)
1473 wins_process_name_registration_request(subrec, p);
1474 else
1475 process_name_registration_request(subrec, p);
1476 break;
1478 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1479 case NMB_NAME_REFRESH_OPCODE_9:
1480 if(subrec == wins_server_subnet)
1481 wins_process_name_refresh_request(subrec, p);
1482 else
1483 process_name_refresh_request(subrec, p);
1484 break;
1486 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1487 if(subrec == wins_server_subnet) {
1488 wins_process_multihomed_name_registration_request(subrec, p);
1489 } else {
1490 DEBUG(0,("process_nmb_request: Multihomed registration request must be \
1491 directed at a WINS server.\n"));
1493 break;
1495 case NMB_NAME_QUERY_OPCODE:
1496 switch (nmb->question.question_type) {
1497 case QUESTION_TYPE_NB_QUERY:
1498 if(subrec == wins_server_subnet)
1499 wins_process_name_query_request(subrec, p);
1500 else
1501 process_name_query_request(subrec, p);
1502 break;
1503 case QUESTION_TYPE_NB_STATUS:
1504 if(subrec == wins_server_subnet) {
1505 DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
1506 not allowed.\n"));
1507 break;
1508 } else {
1509 process_node_status_request(subrec, p);
1511 break;
1513 break;
1515 case NMB_NAME_RELEASE_OPCODE:
1516 if(subrec == wins_server_subnet)
1517 wins_process_name_release_request(subrec, p);
1518 else
1519 process_name_release_request(subrec, p);
1520 break;
1524 /****************************************************************************
1525 Process a nmb response packet - validate the packet and route it.
1526 to either the WINS server or a normal response.
1527 ****************************************************************************/
1529 static void process_nmb_response(struct packet_struct *p)
1531 struct nmb_packet *nmb = &p->packet.nmb;
1532 struct subnet_record *subrec = NULL;
1533 struct response_record *rrec = NULL;
1535 debug_nmb_packet(p);
1537 if(validate_nmb_response_packet(nmb))
1538 return;
1540 if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
1541 return;
1543 if(rrec == NULL) {
1544 DEBUG(0,("process_nmb_response: response packet received but no response record \
1545 found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));
1546 return;
1549 /* Increment the number of responses received for this record. */
1550 rrec->num_msgs++;
1551 /* Ensure we don't re-send the request. */
1552 rrec->repeat_count = 0;
1554 /* Call the response received function for this packet. */
1555 (*rrec->resp_fn)(subrec, rrec, p);
1558 /*******************************************************************
1559 Run elements off the packet queue till its empty
1560 ******************************************************************/
1562 void run_packet_queue(void)
1564 struct packet_struct *p;
1566 while ((p = packet_queue)) {
1567 packet_queue = p->next;
1568 if (packet_queue)
1569 packet_queue->prev = NULL;
1570 p->next = p->prev = NULL;
1572 switch (p->packet_type) {
1573 case NMB_PACKET:
1574 if(p->packet.nmb.header.response)
1575 process_nmb_response(p);
1576 else
1577 process_nmb_request(p);
1578 break;
1580 case DGRAM_PACKET:
1581 process_dgram(p);
1582 break;
1584 free_packet(p);
1588 /*******************************************************************
1589 Retransmit or timeout elements from all the outgoing subnet response
1590 record queues. NOTE that this code must also check the WINS server
1591 subnet for response records to timeout as the WINS server code
1592 can send requests to check if a client still owns a name.
1593 (Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>).
1594 ******************************************************************/
1596 void retransmit_or_expire_response_records(time_t t)
1598 struct subnet_record *subrec;
1600 for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
1601 struct response_record *rrec, *nextrrec;
1603 for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
1604 nextrrec = rrec->next;
1606 if (rrec->repeat_time <= t) {
1607 if (rrec->repeat_count > 0) {
1608 /* Resend while we have a non-zero repeat_count. */
1609 if(!send_packet(rrec->packet)) {
1610 DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
1611 to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
1613 rrec->repeat_time = t + rrec->repeat_interval;
1614 rrec->repeat_count--;
1615 } else {
1616 DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
1617 on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
1620 * Check the flag in this record to prevent recursion if we end
1621 * up in this function again via the timeout function call.
1624 if(!rrec->in_expiration_processing) {
1627 * Set the recursion protection flag in this record.
1630 rrec->in_expiration_processing = True;
1632 /* Call the timeout function. This will deal with removing the
1633 timed out packet. */
1634 if(rrec->timeout_fn) {
1635 (*rrec->timeout_fn)(subrec, rrec);
1636 } else {
1637 /* We must remove the record ourself if there is
1638 no timeout function. */
1639 remove_response_record(subrec, rrec);
1641 } /* !rrec->in_expitation_processing */
1642 } /* rrec->repeat_count > 0 */
1643 } /* rrec->repeat_time <= t */
1644 } /* end for rrec */
1645 } /* end for subnet */
1648 /****************************************************************************
1649 Create an fd_set containing all the sockets in the subnet structures,
1650 plus the broadcast sockets.
1651 ***************************************************************************/
1653 static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number, int *maxfd)
1655 int *sock_array = NULL;
1656 struct subnet_record *subrec = NULL;
1657 int count = 0;
1658 int num = 0;
1659 fd_set *pset = SMB_MALLOC_P(fd_set);
1661 if(pset == NULL) {
1662 DEBUG(0,("create_listen_fdset: malloc fail !\n"));
1663 return True;
1666 /* Check that we can add all the fd's we need. */
1667 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1668 count++;
1670 if((count*2) + 2 > FD_SETSIZE) {
1671 DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
1672 only use %d.\n", (count*2) + 2, FD_SETSIZE));
1673 SAFE_FREE(pset);
1674 return True;
1677 if((sock_array = SMB_MALLOC_ARRAY(int, (count*2) + 2)) == NULL) {
1678 DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
1679 SAFE_FREE(pset);
1680 return True;
1683 FD_ZERO(pset);
1685 /* Add in the broadcast socket on 137. */
1686 FD_SET(ClientNMB,pset);
1687 sock_array[num++] = ClientNMB;
1688 *maxfd = MAX( *maxfd, ClientNMB);
1690 /* Add in the 137 sockets on all the interfaces. */
1691 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1692 FD_SET(subrec->nmb_sock,pset);
1693 sock_array[num++] = subrec->nmb_sock;
1694 *maxfd = MAX( *maxfd, subrec->nmb_sock);
1697 /* Add in the broadcast socket on 138. */
1698 FD_SET(ClientDGRAM,pset);
1699 sock_array[num++] = ClientDGRAM;
1700 *maxfd = MAX( *maxfd, ClientDGRAM);
1702 /* Add in the 138 sockets on all the interfaces. */
1703 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1704 FD_SET(subrec->dgram_sock,pset);
1705 sock_array[num++] = subrec->dgram_sock;
1706 *maxfd = MAX( *maxfd, subrec->dgram_sock);
1709 *listen_number = (count*2) + 2;
1711 SAFE_FREE(*ppset);
1712 SAFE_FREE(*psock_array);
1714 *ppset = pset;
1715 *psock_array = sock_array;
1717 return False;
1720 /****************************************************************************
1721 Listens for NMB or DGRAM packets, and queues them.
1722 return True if the socket is dead
1723 ***************************************************************************/
1725 BOOL listen_for_packets(BOOL run_election)
1727 static fd_set *listen_set = NULL;
1728 static int listen_number = 0;
1729 static int *sock_array = NULL;
1730 int i;
1731 static int maxfd = 0;
1733 fd_set fds;
1734 int selrtn;
1735 struct timeval timeout;
1736 #ifndef SYNC_DNS
1737 int dns_fd;
1738 #endif
1740 if(listen_set == NULL || rescan_listen_set) {
1741 if(create_listen_fdset(&listen_set, &sock_array, &listen_number, &maxfd)) {
1742 DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
1743 return True;
1745 rescan_listen_set = False;
1748 memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
1750 #ifndef SYNC_DNS
1751 dns_fd = asyncdns_fd();
1752 if (dns_fd != -1) {
1753 FD_SET(dns_fd, &fds);
1754 maxfd = MAX( maxfd, dns_fd);
1756 #endif
1759 * During elections and when expecting a netbios response packet we
1760 * need to send election packets at tighter intervals.
1761 * Ideally it needs to be the interval (in ms) between time now and
1762 * the time we are expecting the next netbios packet.
1765 timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
1766 timeout.tv_usec = 0;
1768 /* Prepare for the select - allow certain signals. */
1770 BlockSignals(False, SIGTERM);
1772 selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&timeout);
1774 /* We can only take signals when we are in the select - block them again here. */
1776 BlockSignals(True, SIGTERM);
1778 if(selrtn == -1) {
1779 return False;
1782 #ifndef SYNC_DNS
1783 if (dns_fd != -1 && FD_ISSET(dns_fd,&fds)) {
1784 run_dns_queue();
1786 #endif
1788 for(i = 0; i < listen_number; i++) {
1789 if (i < (listen_number/2)) {
1790 /* Processing a 137 socket. */
1791 if (FD_ISSET(sock_array[i],&fds)) {
1792 struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
1793 if (packet) {
1795 * If we got a packet on the broadcast socket and interfaces
1796 * only is set then check it came from one of our local nets.
1798 if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) &&
1799 (!is_local_net(packet->ip))) {
1800 DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
1801 inet_ntoa(packet->ip),packet->port));
1802 free_packet(packet);
1803 } else if ((ip_equal(loopback_ip, packet->ip) ||
1804 ismyip(packet->ip)) && packet->port == global_nmb_port &&
1805 packet->packet.nmb.header.nm_flags.bcast) {
1806 DEBUG(7,("discarding own bcast packet from %s:%d\n",
1807 inet_ntoa(packet->ip),packet->port));
1808 free_packet(packet);
1809 } else {
1810 /* Save the file descriptor this packet came in on. */
1811 packet->fd = sock_array[i];
1812 queue_packet(packet);
1816 } else {
1817 /* Processing a 138 socket. */
1818 if (FD_ISSET(sock_array[i],&fds)) {
1819 struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
1820 if (packet) {
1822 * If we got a packet on the broadcast socket and interfaces
1823 * only is set then check it came from one of our local nets.
1825 if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) &&
1826 (!is_local_net(packet->ip))) {
1827 DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
1828 inet_ntoa(packet->ip),packet->port));
1829 free_packet(packet);
1830 } else if ((ip_equal(loopback_ip, packet->ip) ||
1831 ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
1832 DEBUG(7,("discarding own dgram packet from %s:%d\n",
1833 inet_ntoa(packet->ip),packet->port));
1834 free_packet(packet);
1835 } else {
1836 /* Save the file descriptor this packet came in on. */
1837 packet->fd = sock_array[i];
1838 queue_packet(packet);
1842 } /* end processing 138 socket. */
1843 } /* end for */
1844 return False;
1847 /****************************************************************************
1848 Construct and send a netbios DGRAM.
1849 **************************************************************************/
1851 BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
1852 const char *srcname, int src_type,
1853 const char *dstname, int dest_type,
1854 struct in_addr dest_ip,struct in_addr src_ip,
1855 int dest_port)
1857 BOOL loopback_this_packet = False;
1858 struct packet_struct p;
1859 struct dgram_packet *dgram = &p.packet.dgram;
1860 char *ptr,*p2;
1861 char tmp[4];
1863 memset((char *)&p,'\0',sizeof(p));
1865 if(ismyip(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
1866 loopback_this_packet = True;
1868 /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
1870 /* DIRECT GROUP or UNIQUE datagram. */
1871 dgram->header.msg_type = unique ? 0x10 : 0x11;
1872 dgram->header.flags.node_type = M_NODE;
1873 dgram->header.flags.first = True;
1874 dgram->header.flags.more = False;
1875 dgram->header.dgm_id = generate_name_trn_id();
1876 dgram->header.source_ip = src_ip;
1877 dgram->header.source_port = DGRAM_PORT;
1878 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1879 dgram->header.packet_offset = 0;
1881 make_nmb_name(&dgram->source_name,srcname,src_type);
1882 make_nmb_name(&dgram->dest_name,dstname,dest_type);
1884 ptr = &dgram->data[0];
1886 /* Setup the smb part. */
1887 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1888 memcpy(tmp,ptr,4);
1889 set_message(ptr,17,strlen(mailslot) + 1 + len,True);
1890 memcpy(ptr,tmp,4);
1892 SCVAL(ptr,smb_com,SMBtrans);
1893 SSVAL(ptr,smb_vwv1,len);
1894 SSVAL(ptr,smb_vwv11,len);
1895 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1896 SSVAL(ptr,smb_vwv13,3);
1897 SSVAL(ptr,smb_vwv14,1);
1898 SSVAL(ptr,smb_vwv15,1);
1899 SSVAL(ptr,smb_vwv16,2);
1900 p2 = smb_buf(ptr);
1901 safe_strcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
1902 p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2);
1904 if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
1905 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
1906 return False;
1907 } else {
1908 memcpy(p2,buf,len);
1909 p2 += len;
1912 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1914 p.ip = dest_ip;
1915 p.port = dest_port;
1916 p.fd = find_subnet_mailslot_fd_for_address( src_ip );
1917 p.timestamp = time(NULL);
1918 p.packet_type = DGRAM_PACKET;
1920 DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
1921 nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
1922 DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
1924 debug_browse_data(buf, len);
1926 if(loopback_this_packet) {
1927 struct packet_struct *lo_packet = NULL;
1928 DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
1929 if((lo_packet = copy_packet(&p)) == NULL)
1930 return False;
1931 queue_packet(lo_packet);
1932 return True;
1933 } else {
1934 return(send_packet(&p));