r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text
[Samba/bb.git] / source / nmbd / nmbd_packets.c
blobbaf243cda1fe4337073b849dcbd9cb871e3ffcea
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 3 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, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
25 extern int ClientNMB;
26 extern int ClientDGRAM;
27 extern int global_nmb_port;
29 extern int num_response_packets;
31 extern struct in_addr loopback_ip;
33 static void queue_packet(struct packet_struct *packet);
35 BOOL rescan_listen_set = False;
38 /*******************************************************************
39 The global packet linked-list. Incoming entries are
40 added to the end of this list. It is supposed to remain fairly
41 short so we won't bother with an end pointer.
42 ******************************************************************/
44 static struct packet_struct *packet_queue = NULL;
46 /***************************************************************************
47 Utility function to find the specific fd to send a packet out on.
48 **************************************************************************/
50 static int find_subnet_fd_for_address( struct in_addr local_ip )
52 struct subnet_record *subrec;
54 for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
55 if(ip_equal(local_ip, subrec->myip))
56 return subrec->nmb_sock;
58 return ClientNMB;
61 /***************************************************************************
62 Utility function to find the specific fd to send a mailslot packet out on.
63 **************************************************************************/
65 static int find_subnet_mailslot_fd_for_address( struct in_addr local_ip )
67 struct subnet_record *subrec;
69 for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
70 if(ip_equal(local_ip, subrec->myip))
71 return subrec->dgram_sock;
73 return ClientDGRAM;
76 /***************************************************************************
77 Get/Set problematic nb_flags as network byte order 16 bit int.
78 **************************************************************************/
80 uint16 get_nb_flags(char *buf)
82 return ((((uint16)*buf)&0xFFFF) & NB_FLGMSK);
85 void set_nb_flags(char *buf, uint16 nb_flags)
87 *buf++ = ((nb_flags & NB_FLGMSK) & 0xFF);
88 *buf = '\0';
91 /***************************************************************************
92 Dumps out the browse packet data.
93 **************************************************************************/
95 static void debug_browse_data(char *outbuf, int len)
97 int i,j;
99 DEBUG( 4, ( "debug_browse_data():\n" ) );
100 for (i = 0; i < len; i+= 16) {
101 DEBUGADD( 4, ( "%3x char ", i ) );
103 for (j = 0; j < 16; j++) {
104 unsigned char x;
105 if (i+j >= len)
106 break;
108 x = outbuf[i+j];
109 if (x < 32 || x > 127)
110 x = '.';
112 DEBUGADD( 4, ( "%c", x ) );
115 DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
117 for (j = 0; j < 16; j++) {
118 if (i+j >= len)
119 break;
120 DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
123 DEBUGADD( 4, ("\n") );
127 /***************************************************************************
128 Generates the unique transaction identifier
129 **************************************************************************/
131 static uint16 name_trn_id=0;
133 static uint16 generate_name_trn_id(void)
135 if (!name_trn_id) {
136 name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
138 name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
139 return name_trn_id;
142 /***************************************************************************
143 Either loops back or sends out a completed NetBIOS packet.
144 **************************************************************************/
146 static BOOL send_netbios_packet(struct packet_struct *p)
148 BOOL loopback_this_packet = False;
150 /* Check if we are sending to or from ourselves as a WINS server. */
151 if(ismyip(p->ip) && (p->port == global_nmb_port))
152 loopback_this_packet = True;
154 if(loopback_this_packet) {
155 struct packet_struct *lo_packet = NULL;
156 DEBUG(5,("send_netbios_packet: sending packet to ourselves.\n"));
157 if((lo_packet = copy_packet(p)) == NULL)
158 return False;
159 queue_packet(lo_packet);
160 } else if (!send_packet(p)) {
161 DEBUG(0,("send_netbios_packet: send_packet() to IP %s port %d failed\n",
162 inet_ntoa(p->ip),p->port));
163 return False;
166 return True;
169 /***************************************************************************
170 Sets up the common elements of an outgoing NetBIOS packet.
172 Note: do not attempt to rationalise whether rec_des should be set or not
173 in a particular situation. Just follow rfc_1002 or look at examples from WinXX.
174 It does NOT follow the rule that requests to the wins server always have
175 rec_des true. See for example name releases and refreshes
176 **************************************************************************/
178 static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmbname,
179 BOOL bcast, BOOL rec_des,
180 struct in_addr to_ip)
182 struct packet_struct *packet = NULL;
183 struct nmb_packet *nmb = NULL;
185 /* Allocate the packet_struct we will return. */
186 if((packet = SMB_MALLOC_P(struct packet_struct)) == NULL) {
187 DEBUG(0,("create_and_init_netbios_packet: malloc fail (1) for packet struct.\n"));
188 return NULL;
191 memset((char *)packet,'\0',sizeof(*packet));
193 nmb = &packet->packet.nmb;
195 nmb->header.name_trn_id = generate_name_trn_id();
196 nmb->header.response = False;
197 nmb->header.nm_flags.recursion_desired = rec_des;
198 nmb->header.nm_flags.recursion_available = False;
199 nmb->header.nm_flags.trunc = False;
200 nmb->header.nm_flags.authoritative = False;
201 nmb->header.nm_flags.bcast = bcast;
203 nmb->header.rcode = 0;
204 nmb->header.qdcount = 1;
205 nmb->header.ancount = 0;
206 nmb->header.nscount = 0;
208 nmb->question.question_name = *nmbname;
209 nmb->question.question_type = QUESTION_TYPE_NB_QUERY;
210 nmb->question.question_class = QUESTION_CLASS_IN;
212 packet->ip = to_ip;
213 packet->port = NMB_PORT;
214 packet->fd = ClientNMB;
215 packet->timestamp = time(NULL);
216 packet->packet_type = NMB_PACKET;
217 packet->locked = False;
219 return packet; /* Caller must free. */
222 /***************************************************************************
223 Sets up the common elements of register, refresh or release packet.
224 **************************************************************************/
226 static BOOL create_and_init_additional_record(struct packet_struct *packet,
227 uint16 nb_flags,
228 struct in_addr *register_ip)
230 struct nmb_packet *nmb = &packet->packet.nmb;
232 if((nmb->additional = SMB_MALLOC_P(struct res_rec)) == NULL) {
233 DEBUG(0,("initiate_name_register_packet: malloc fail for additional record.\n"));
234 return False;
237 memset((char *)nmb->additional,'\0',sizeof(struct res_rec));
239 nmb->additional->rr_name = nmb->question.question_name;
240 nmb->additional->rr_type = RR_TYPE_NB;
241 nmb->additional->rr_class = RR_CLASS_IN;
243 /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
244 if (nmb->header.nm_flags.bcast)
245 nmb->additional->ttl = PERMANENT_TTL;
246 else
247 nmb->additional->ttl = lp_max_ttl();
249 nmb->additional->rdlength = 6;
251 set_nb_flags(nmb->additional->rdata,nb_flags);
253 /* Set the address for the name we are registering. */
254 putip(&nmb->additional->rdata[2], register_ip);
257 it turns out that Jeremys code was correct, we are supposed
258 to send registrations from the IP we are registering. The
259 trick is what to do on timeouts! When we send on a
260 non-routable IP then the reply will timeout, and we should
261 treat this as success, not failure. That means we go into
262 our standard refresh cycle for that name which copes nicely
263 with disconnected networks.
265 packet->fd = find_subnet_fd_for_address(*register_ip);
267 return True;
270 /***************************************************************************
271 Sends out a name query.
272 **************************************************************************/
274 static BOOL initiate_name_query_packet( struct packet_struct *packet)
276 struct nmb_packet *nmb = NULL;
278 nmb = &packet->packet.nmb;
280 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
281 nmb->header.arcount = 0;
283 nmb->header.nm_flags.recursion_desired = True;
285 DEBUG(4,("initiate_name_query_packet: sending query for name %s (bcast=%s) to IP %s\n",
286 nmb_namestr(&nmb->question.question_name),
287 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
289 return send_netbios_packet( packet );
292 /***************************************************************************
293 Sends out a name query - from a WINS server.
294 **************************************************************************/
296 static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
298 struct nmb_packet *nmb = NULL;
300 nmb = &packet->packet.nmb;
302 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
303 nmb->header.arcount = 0;
305 nmb->header.nm_flags.recursion_desired = False;
307 DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
308 nmb_namestr(&nmb->question.question_name),
309 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
311 return send_netbios_packet( packet );
314 /***************************************************************************
315 Sends out a name register.
316 **************************************************************************/
318 static BOOL initiate_name_register_packet( struct packet_struct *packet,
319 uint16 nb_flags, struct in_addr *register_ip)
321 struct nmb_packet *nmb = &packet->packet.nmb;
323 nmb->header.opcode = NMB_NAME_REG_OPCODE;
324 nmb->header.arcount = 1;
326 nmb->header.nm_flags.recursion_desired = True;
328 if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
329 return False;
331 DEBUG(4,("initiate_name_register_packet: sending registration for name %s (bcast=%s) to IP %s\n",
332 nmb_namestr(&nmb->additional->rr_name),
333 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
335 return send_netbios_packet( packet );
338 /***************************************************************************
339 Sends out a multihomed name register.
340 **************************************************************************/
342 static BOOL initiate_multihomed_name_register_packet(struct packet_struct *packet,
343 uint16 nb_flags, struct in_addr *register_ip)
345 struct nmb_packet *nmb = &packet->packet.nmb;
346 fstring second_ip_buf;
348 fstrcpy(second_ip_buf, inet_ntoa(packet->ip));
350 nmb->header.opcode = NMB_NAME_MULTIHOMED_REG_OPCODE;
351 nmb->header.arcount = 1;
353 nmb->header.nm_flags.recursion_desired = True;
355 if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
356 return False;
358 DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
359 for name %s IP %s (bcast=%s) to IP %s\n",
360 nmb_namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
361 BOOLSTR(nmb->header.nm_flags.bcast), second_ip_buf ));
363 return send_netbios_packet( packet );
366 /***************************************************************************
367 Sends out a name refresh.
368 **************************************************************************/
370 static BOOL initiate_name_refresh_packet( struct packet_struct *packet,
371 uint16 nb_flags, struct in_addr *refresh_ip)
373 struct nmb_packet *nmb = &packet->packet.nmb;
375 nmb->header.opcode = NMB_NAME_REFRESH_OPCODE_8;
376 nmb->header.arcount = 1;
378 nmb->header.nm_flags.recursion_desired = False;
380 if(create_and_init_additional_record(packet, nb_flags, refresh_ip) == False)
381 return False;
383 DEBUG(4,("initiate_name_refresh_packet: sending refresh for name %s (bcast=%s) to IP %s\n",
384 nmb_namestr(&nmb->additional->rr_name),
385 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
387 return send_netbios_packet( packet );
390 /***************************************************************************
391 Sends out a name release.
392 **************************************************************************/
394 static BOOL initiate_name_release_packet( struct packet_struct *packet,
395 uint16 nb_flags, struct in_addr *release_ip)
397 struct nmb_packet *nmb = &packet->packet.nmb;
399 nmb->header.opcode = NMB_NAME_RELEASE_OPCODE;
400 nmb->header.arcount = 1;
402 nmb->header.nm_flags.recursion_desired = False;
404 if(create_and_init_additional_record(packet, nb_flags, release_ip) == False)
405 return False;
407 DEBUG(4,("initiate_name_release_packet: sending release for name %s (bcast=%s) to IP %s\n",
408 nmb_namestr(&nmb->additional->rr_name),
409 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
411 return send_netbios_packet( packet );
414 /***************************************************************************
415 Sends out a node status.
416 **************************************************************************/
418 static BOOL initiate_node_status_packet( struct packet_struct *packet )
420 struct nmb_packet *nmb = &packet->packet.nmb;
422 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
423 nmb->header.arcount = 0;
425 nmb->header.nm_flags.recursion_desired = False;
427 nmb->question.question_type = QUESTION_TYPE_NB_STATUS;
429 DEBUG(4,("initiate_node_status_packet: sending node status request for name %s to IP %s\n",
430 nmb_namestr(&nmb->question.question_name),
431 inet_ntoa(packet->ip)));
433 return send_netbios_packet( packet );
436 /****************************************************************************
437 Simplification functions for queuing standard packets.
438 These should be the only publicly callable functions for sending
439 out packets.
440 ****************************************************************************/
442 /****************************************************************************
443 Assertion - we should never be sending nmbd packets on the remote
444 broadcast subnet.
445 ****************************************************************************/
447 static BOOL assert_check_subnet(struct subnet_record *subrec)
449 if( subrec == remote_broadcast_subnet) {
450 DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
451 This is a bug.\n"));
452 return True;
454 return False;
457 /****************************************************************************
458 Queue a register name packet to the broadcast address of a subnet.
459 ****************************************************************************/
461 struct response_record *queue_register_name( struct subnet_record *subrec,
462 response_function resp_fn,
463 timeout_response_function timeout_fn,
464 register_name_success_function success_fn,
465 register_name_fail_function fail_fn,
466 struct userdata_struct *userdata,
467 struct nmb_name *nmbname,
468 uint16 nb_flags)
470 struct packet_struct *p;
471 struct response_record *rrec;
473 if(assert_check_subnet(subrec))
474 return NULL;
476 /* note that all name registration requests have RD set (rfc1002 - section 4.2.2 */
477 if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), True,
478 subrec->bcast_ip)) == NULL)
479 return NULL;
481 if(initiate_name_register_packet( p, nb_flags, iface_ip(subrec->bcast_ip)) == False) {
482 p->locked = False;
483 free_packet(p);
484 return NULL;
487 if((rrec = make_response_record(subrec, /* subnet record. */
488 p, /* packet we sent. */
489 resp_fn, /* function to call on response. */
490 timeout_fn, /* function to call on timeout. */
491 (success_function)success_fn, /* function to call on operation success. */
492 (fail_function)fail_fn, /* function to call on operation fail. */
493 userdata)) == NULL) {
494 p->locked = False;
495 free_packet(p);
496 return NULL;
499 return rrec;
502 /****************************************************************************
503 Queue a refresh name packet to the broadcast address of a subnet.
504 ****************************************************************************/
506 void queue_wins_refresh(struct nmb_name *nmbname,
507 response_function resp_fn,
508 timeout_response_function timeout_fn,
509 uint16 nb_flags,
510 struct in_addr refresh_ip,
511 const char *tag)
513 struct packet_struct *p;
514 struct response_record *rrec;
515 struct in_addr wins_ip;
516 struct userdata_struct *userdata;
517 fstring ip_str;
519 wins_ip = wins_srv_ip_tag(tag, refresh_ip);
521 if ((p = create_and_init_netbios_packet(nmbname, False, False, wins_ip)) == NULL) {
522 return;
525 if (!initiate_name_refresh_packet(p, nb_flags, &refresh_ip)) {
526 p->locked = False;
527 free_packet(p);
528 return;
531 fstrcpy(ip_str, inet_ntoa(refresh_ip));
533 DEBUG(6,("Refreshing name %s IP %s with WINS server %s using tag '%s'\n",
534 nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
536 userdata = (struct userdata_struct *)SMB_MALLOC(sizeof(*userdata) + strlen(tag) + 1);
537 if (!userdata) {
538 p->locked = False;
539 free_packet(p);
540 DEBUG(0,("Failed to allocate userdata structure!\n"));
541 return;
543 ZERO_STRUCTP(userdata);
544 userdata->userdata_len = strlen(tag) + 1;
545 strlcpy(userdata->data, tag, userdata->userdata_len);
547 if ((rrec = make_response_record(unicast_subnet,
549 resp_fn, timeout_fn,
550 NULL,
551 NULL,
552 userdata)) == NULL) {
553 p->locked = False;
554 free_packet(p);
555 return;
558 free(userdata);
560 /* we don't want to repeat refresh packets */
561 rrec->repeat_count = 0;
565 /****************************************************************************
566 Queue a multihomed register name packet to a given WINS server IP
567 ****************************************************************************/
569 struct response_record *queue_register_multihomed_name( struct subnet_record *subrec,
570 response_function resp_fn,
571 timeout_response_function timeout_fn,
572 register_name_success_function success_fn,
573 register_name_fail_function fail_fn,
574 struct userdata_struct *userdata,
575 struct nmb_name *nmbname,
576 uint16 nb_flags,
577 struct in_addr register_ip,
578 struct in_addr wins_ip)
580 struct packet_struct *p;
581 struct response_record *rrec;
582 BOOL ret;
584 /* Sanity check. */
585 if(subrec != unicast_subnet) {
586 DEBUG(0,("queue_register_multihomed_name: should only be done on \
587 unicast subnet. subnet is %s\n.", subrec->subnet_name ));
588 return NULL;
591 if(assert_check_subnet(subrec))
592 return NULL;
594 if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL)
595 return NULL;
597 if (nb_flags & NB_GROUP)
598 ret = initiate_name_register_packet( p, nb_flags, &register_ip);
599 else
600 ret = initiate_multihomed_name_register_packet(p, nb_flags, &register_ip);
602 if (ret == False) {
603 p->locked = False;
604 free_packet(p);
605 return NULL;
608 if ((rrec = make_response_record(subrec, /* subnet record. */
609 p, /* packet we sent. */
610 resp_fn, /* function to call on response. */
611 timeout_fn, /* function to call on timeout. */
612 (success_function)success_fn, /* function to call on operation success. */
613 (fail_function)fail_fn, /* function to call on operation fail. */
614 userdata)) == NULL) {
615 p->locked = False;
616 free_packet(p);
617 return NULL;
620 return rrec;
623 /****************************************************************************
624 Queue a release name packet to the broadcast address of a subnet.
625 ****************************************************************************/
627 struct response_record *queue_release_name( struct subnet_record *subrec,
628 response_function resp_fn,
629 timeout_response_function timeout_fn,
630 release_name_success_function success_fn,
631 release_name_fail_function fail_fn,
632 struct userdata_struct *userdata,
633 struct nmb_name *nmbname,
634 uint16 nb_flags,
635 struct in_addr release_ip,
636 struct in_addr dest_ip)
638 struct packet_struct *p;
639 struct response_record *rrec;
641 if(assert_check_subnet(subrec))
642 return NULL;
644 if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False, dest_ip)) == NULL)
645 return NULL;
647 if(initiate_name_release_packet( p, nb_flags, &release_ip) == False) {
648 p->locked = False;
649 free_packet(p);
650 return NULL;
653 if((rrec = make_response_record(subrec, /* subnet record. */
654 p, /* packet we sent. */
655 resp_fn, /* function to call on response. */
656 timeout_fn, /* function to call on timeout. */
657 (success_function)success_fn, /* function to call on operation success. */
658 (fail_function)fail_fn, /* function to call on operation fail. */
659 userdata)) == NULL) {
660 p->locked = False;
661 free_packet(p);
662 return NULL;
666 * For a broadcast release packet, only send once.
667 * This will cause us to remove the name asap. JRA.
670 if (subrec != unicast_subnet) {
671 rrec->repeat_count = 0;
672 rrec->repeat_time = 0;
675 return rrec;
678 /****************************************************************************
679 Queue a query name packet to the broadcast address of a subnet.
680 ****************************************************************************/
682 struct response_record *queue_query_name( struct subnet_record *subrec,
683 response_function resp_fn,
684 timeout_response_function timeout_fn,
685 query_name_success_function success_fn,
686 query_name_fail_function fail_fn,
687 struct userdata_struct *userdata,
688 struct nmb_name *nmbname)
690 struct packet_struct *p;
691 struct response_record *rrec;
692 struct in_addr to_ip;
694 if(assert_check_subnet(subrec))
695 return NULL;
697 to_ip = subrec->bcast_ip;
699 /* queries to the WINS server turn up here as queries to IP 0.0.0.0
700 These need to be handled a bit differently */
701 if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
702 /* What we really need to do is loop over each of our wins
703 * servers and wins server tags here, but that just doesn't
704 * fit our architecture at the moment (userdata may already
705 * be used when we get here). For now we just query the first
706 * active wins server on the first tag.
708 char **tags = wins_srv_tags();
709 if (!tags) {
710 return NULL;
712 to_ip = wins_srv_ip_tag(tags[0], to_ip);
713 wins_srv_tags_free(tags);
716 if(( p = create_and_init_netbios_packet(nmbname,
717 (subrec != unicast_subnet),
718 (subrec == unicast_subnet),
719 to_ip)) == NULL)
720 return NULL;
722 if(lp_bind_interfaces_only()) {
723 int i;
725 DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
726 for(i = 0; i < iface_count(); i++) {
727 struct in_addr *ifip = iface_n_ip(i);
729 if(ifip == NULL) {
730 DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
731 continue;
734 if (ip_equal(*ifip,loopback_ip)) {
735 DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
736 continue;
739 DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
740 p->fd = find_subnet_fd_for_address( *ifip );
741 break;
745 if(initiate_name_query_packet( p ) == False) {
746 p->locked = False;
747 free_packet(p);
748 return NULL;
751 if((rrec = make_response_record(subrec, /* subnet record. */
752 p, /* packet we sent. */
753 resp_fn, /* function to call on response. */
754 timeout_fn, /* function to call on timeout. */
755 (success_function)success_fn, /* function to call on operation success. */
756 (fail_function)fail_fn, /* function to call on operation fail. */
757 userdata)) == NULL) {
758 p->locked = False;
759 free_packet(p);
760 return NULL;
763 return rrec;
766 /****************************************************************************
767 Queue a query name packet to a given address from the WINS subnet.
768 ****************************************************************************/
770 struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
771 response_function resp_fn,
772 timeout_response_function timeout_fn,
773 query_name_success_function success_fn,
774 query_name_fail_function fail_fn,
775 struct userdata_struct *userdata,
776 struct nmb_name *nmbname)
778 struct packet_struct *p;
779 struct response_record *rrec;
781 if ((p = create_and_init_netbios_packet(nmbname, False, False, to_ip)) == NULL)
782 return NULL;
784 if(initiate_name_query_packet_from_wins_server( p ) == False) {
785 p->locked = False;
786 free_packet(p);
787 return NULL;
790 if((rrec = make_response_record(wins_server_subnet, /* subnet record. */
791 p, /* packet we sent. */
792 resp_fn, /* function to call on response. */
793 timeout_fn, /* function to call on timeout. */
794 (success_function)success_fn, /* function to call on operation success. */
795 (fail_function)fail_fn, /* function to call on operation fail. */
796 userdata)) == NULL) {
797 p->locked = False;
798 free_packet(p);
799 return NULL;
802 return rrec;
805 /****************************************************************************
806 Queue a node status packet to a given name and address.
807 ****************************************************************************/
809 struct response_record *queue_node_status( struct subnet_record *subrec,
810 response_function resp_fn,
811 timeout_response_function timeout_fn,
812 node_status_success_function success_fn,
813 node_status_fail_function fail_fn,
814 struct userdata_struct *userdata,
815 struct nmb_name *nmbname,
816 struct in_addr send_ip)
818 struct packet_struct *p;
819 struct response_record *rrec;
821 /* Sanity check. */
822 if(subrec != unicast_subnet) {
823 DEBUG(0,("queue_register_multihomed_name: should only be done on \
824 unicast subnet. subnet is %s\n.", subrec->subnet_name ));
825 return NULL;
828 if(assert_check_subnet(subrec))
829 return NULL;
831 if(( p = create_and_init_netbios_packet(nmbname, False, False, send_ip)) == NULL)
832 return NULL;
834 if(initiate_node_status_packet(p) == False) {
835 p->locked = False;
836 free_packet(p);
837 return NULL;
840 if((rrec = make_response_record(subrec, /* subnet record. */
841 p, /* packet we sent. */
842 resp_fn, /* function to call on response. */
843 timeout_fn, /* function to call on timeout. */
844 (success_function)success_fn, /* function to call on operation success. */
845 (fail_function)fail_fn, /* function to call on operation fail. */
846 userdata)) == NULL) {
847 p->locked = False;
848 free_packet(p);
849 return NULL;
852 return rrec;
855 /****************************************************************************
856 Reply to a netbios name packet. see rfc1002.txt
857 ****************************************************************************/
859 void reply_netbios_packet(struct packet_struct *orig_packet,
860 int rcode, enum netbios_reply_type_code rcv_code, int opcode,
861 int ttl, char *data,int len)
863 struct packet_struct packet;
864 struct nmb_packet *nmb = NULL;
865 struct res_rec answers;
866 struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
867 BOOL loopback_this_packet = False;
868 int rr_type = RR_TYPE_NB;
869 const char *packet_type = "unknown";
871 /* Check if we are sending to or from ourselves. */
872 if(ismyip(orig_packet->ip) && (orig_packet->port == global_nmb_port))
873 loopback_this_packet = True;
875 nmb = &packet.packet.nmb;
877 /* Do a partial copy of the packet. We clear the locked flag and
878 the resource record pointers. */
879 packet = *orig_packet; /* Full structure copy. */
880 packet.locked = False;
881 nmb->answers = NULL;
882 nmb->nsrecs = NULL;
883 nmb->additional = NULL;
885 switch (rcv_code) {
886 case NMB_STATUS:
887 packet_type = "nmb_status";
888 nmb->header.nm_flags.recursion_desired = False;
889 nmb->header.nm_flags.recursion_available = False;
890 rr_type = RR_TYPE_NBSTAT;
891 break;
892 case NMB_QUERY:
893 packet_type = "nmb_query";
894 nmb->header.nm_flags.recursion_desired = True;
895 nmb->header.nm_flags.recursion_available = True;
896 if (rcode) {
897 rr_type = RR_TYPE_NULL;
899 break;
900 case NMB_REG:
901 case NMB_REG_REFRESH:
902 packet_type = "nmb_reg";
903 nmb->header.nm_flags.recursion_desired = True;
904 nmb->header.nm_flags.recursion_available = True;
905 break;
906 case NMB_REL:
907 packet_type = "nmb_rel";
908 nmb->header.nm_flags.recursion_desired = False;
909 nmb->header.nm_flags.recursion_available = False;
910 break;
911 case NMB_WAIT_ACK:
912 packet_type = "nmb_wack";
913 nmb->header.nm_flags.recursion_desired = False;
914 nmb->header.nm_flags.recursion_available = False;
915 rr_type = RR_TYPE_NULL;
916 break;
917 case WINS_REG:
918 packet_type = "wins_reg";
919 nmb->header.nm_flags.recursion_desired = True;
920 nmb->header.nm_flags.recursion_available = True;
921 break;
922 case WINS_QUERY:
923 packet_type = "wins_query";
924 nmb->header.nm_flags.recursion_desired = True;
925 nmb->header.nm_flags.recursion_available = True;
926 if (rcode) {
927 rr_type = RR_TYPE_NULL;
929 break;
930 default:
931 DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
932 packet_type, nmb_namestr(&orig_nmb->question.question_name),
933 inet_ntoa(packet.ip)));
934 return;
937 DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
938 for id %hu\n", packet_type, nmb_namestr(&orig_nmb->question.question_name),
939 inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
941 nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
942 nmb->header.opcode = opcode;
943 nmb->header.response = True;
944 nmb->header.nm_flags.bcast = False;
945 nmb->header.nm_flags.trunc = False;
946 nmb->header.nm_flags.authoritative = True;
948 nmb->header.rcode = rcode;
949 nmb->header.qdcount = 0;
950 nmb->header.ancount = 1;
951 nmb->header.nscount = 0;
952 nmb->header.arcount = 0;
954 memset((char*)&nmb->question,'\0',sizeof(nmb->question));
956 nmb->answers = &answers;
957 memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
959 nmb->answers->rr_name = orig_nmb->question.question_name;
960 nmb->answers->rr_type = rr_type;
961 nmb->answers->rr_class = RR_CLASS_IN;
962 nmb->answers->ttl = ttl;
964 if (data && len) {
965 nmb->answers->rdlength = len;
966 memcpy(nmb->answers->rdata, data, len);
969 packet.packet_type = NMB_PACKET;
970 /* Ensure we send out on the same fd that the original
971 packet came in on to give the correct source IP address. */
972 packet.fd = orig_packet->fd;
973 packet.timestamp = time(NULL);
975 debug_nmb_packet(&packet);
977 if(loopback_this_packet) {
978 struct packet_struct *lo_packet;
979 DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
980 if((lo_packet = copy_packet(&packet)) == NULL)
981 return;
982 queue_packet(lo_packet);
983 } else if (!send_packet(&packet)) {
984 DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
985 inet_ntoa(packet.ip),packet.port));
989 /*******************************************************************
990 Queue a packet into a packet queue
991 ******************************************************************/
993 static void queue_packet(struct packet_struct *packet)
995 struct packet_struct *p;
997 if (!packet_queue) {
998 packet->prev = NULL;
999 packet->next = NULL;
1000 packet_queue = packet;
1001 return;
1004 /* find the bottom */
1005 for (p=packet_queue;p->next;p=p->next)
1008 p->next = packet;
1009 packet->next = NULL;
1010 packet->prev = p;
1013 /****************************************************************************
1014 Try and find a matching subnet record for a datagram port 138 packet.
1015 ****************************************************************************/
1017 static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_struct *p)
1019 struct subnet_record *subrec;
1021 /* Go through all the broadcast subnets and see if the mask matches. */
1022 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1023 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1024 return subrec;
1027 /* If the subnet record is the remote announce broadcast subnet,
1028 hack it here to be the first subnet. This is really gross and
1029 is needed due to people turning on port 137/138 broadcast
1030 forwarding on their routers. May fire and brimstone rain
1031 down upon them...
1034 return FIRST_SUBNET;
1037 /****************************************************************************
1038 Dispatch a browse frame from port 138 to the correct processing function.
1039 ****************************************************************************/
1041 static void process_browse_packet(struct packet_struct *p, char *buf,int len)
1043 struct dgram_packet *dgram = &p->packet.dgram;
1044 int command = CVAL(buf,0);
1045 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1046 char scope[64];
1047 unstring src_name;
1049 /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
1050 pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
1051 if (!strequal(scope, global_scope())) {
1052 DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
1053 mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
1054 return;
1057 pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
1058 if (is_myname(src_name)) {
1059 DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
1060 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1061 return;
1064 switch (command) {
1065 case ANN_HostAnnouncement:
1066 debug_browse_data(buf, len);
1067 process_host_announce(subrec, p, buf+1);
1068 break;
1069 case ANN_DomainAnnouncement:
1070 debug_browse_data(buf, len);
1071 process_workgroup_announce(subrec, p, buf+1);
1072 break;
1073 case ANN_LocalMasterAnnouncement:
1074 debug_browse_data(buf, len);
1075 process_local_master_announce(subrec, p, buf+1);
1076 break;
1077 case ANN_AnnouncementRequest:
1078 debug_browse_data(buf, len);
1079 process_announce_request(subrec, p, buf+1);
1080 break;
1081 case ANN_Election:
1082 debug_browse_data(buf, len);
1083 process_election(subrec, p, buf+1);
1084 break;
1085 case ANN_GetBackupListReq:
1086 debug_browse_data(buf, len);
1087 process_get_backup_list_request(subrec, p, buf+1);
1088 break;
1089 case ANN_GetBackupListResp:
1090 debug_browse_data(buf, len);
1091 /* We never send ANN_GetBackupListReq so we should never get these. */
1092 DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
1093 packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
1094 break;
1095 case ANN_ResetBrowserState:
1096 debug_browse_data(buf, len);
1097 process_reset_browser(subrec, p, buf+1);
1098 break;
1099 case ANN_MasterAnnouncement:
1100 /* Master browser datagrams must be processed on the unicast subnet. */
1101 subrec = unicast_subnet;
1103 debug_browse_data(buf, len);
1104 process_master_browser_announce(subrec, p, buf+1);
1105 break;
1106 case ANN_BecomeBackup:
1108 * We don't currently implement this. Log it just in case.
1110 debug_browse_data(buf, len);
1111 DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
1112 command ANN_BecomeBackup from %s IP %s to %s\n", subrec->subnet_name, nmb_namestr(&dgram->source_name),
1113 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1114 break;
1115 default:
1116 debug_browse_data(buf, len);
1117 DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
1118 command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1119 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1120 break;
1124 /****************************************************************************
1125 Dispatch a LanMan browse frame from port 138 to the correct processing function.
1126 ****************************************************************************/
1128 static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
1130 struct dgram_packet *dgram = &p->packet.dgram;
1131 int command = SVAL(buf,0);
1132 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1133 char scope[64];
1134 unstring src_name;
1136 /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
1138 pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
1139 if (!strequal(scope, global_scope())) {
1140 DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
1141 mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
1142 return;
1145 pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
1146 if (is_myname(src_name)) {
1147 DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
1148 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1149 return;
1152 switch (command) {
1153 case ANN_HostAnnouncement:
1154 debug_browse_data(buf, len);
1155 process_lm_host_announce(subrec, p, buf+1, len > 1 ? len-1 : 0);
1156 break;
1157 case ANN_AnnouncementRequest:
1158 process_lm_announce_request(subrec, p, buf+1, len > 1 ? len-1 : 0);
1159 break;
1160 default:
1161 DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
1162 command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1163 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1164 break;
1168 /****************************************************************************
1169 Determine if a packet is for us on port 138. Note that to have any chance of
1170 being efficient we need to drop as many packets as possible at this
1171 stage as subsequent processing is expensive.
1172 ****************************************************************************/
1174 static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
1176 struct subnet_record *subrec = NULL;
1178 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1179 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1180 break;
1183 if(subrec == NULL)
1184 subrec = unicast_subnet;
1186 return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
1189 /****************************************************************************
1190 Process udp 138 datagrams
1191 ****************************************************************************/
1193 static void process_dgram(struct packet_struct *p)
1195 char *buf;
1196 char *buf2;
1197 int len;
1198 struct dgram_packet *dgram = &p->packet.dgram;
1200 /* If we aren't listening to the destination name then ignore the packet */
1201 if (!listening(p,&dgram->dest_name)) {
1202 unexpected_packet(p);
1203 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
1204 nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
1205 return;
1208 if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) {
1209 unexpected_packet(p);
1210 /* Don't process error packets etc yet */
1211 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
1212 an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
1213 return;
1216 /* Ensure we have a large enough packet before looking inside. */
1217 if (dgram->datasize < (smb_vwv12 - 2)) {
1218 /* That's the offset minus the 4 byte length + 2 bytes of offset. */
1219 DEBUG(0,("process_dgram: ignoring too short dgram packet (%u) sent to name %s from IP %s\n",
1220 (unsigned int)dgram->datasize,
1221 nmb_namestr(&dgram->dest_name),
1222 inet_ntoa(p->ip) ));
1223 return;
1226 buf = &dgram->data[0];
1227 buf -= 4; /* XXXX for the pseudo tcp length - someday I need to get rid of this */
1229 if (CVAL(buf,smb_com) != SMBtrans)
1230 return;
1232 len = SVAL(buf,smb_vwv11);
1233 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1235 if (len <= 0 || len > dgram->datasize) {
1236 DEBUG(0,("process_dgram: ignoring malformed1 (datasize = %d, len = %d) datagram \
1237 packet sent to name %s from IP %s\n",
1238 dgram->datasize,
1239 len,
1240 nmb_namestr(&dgram->dest_name),
1241 inet_ntoa(p->ip) ));
1242 return;
1245 if (buf2 < dgram->data || (buf2 >= dgram->data + dgram->datasize)) {
1246 DEBUG(0,("process_dgram: ignoring malformed2 (datasize = %d, len=%d, off=%d) datagram \
1247 packet sent to name %s from IP %s\n",
1248 dgram->datasize,
1249 len,
1250 (int)PTR_DIFF(buf2, dgram->data),
1251 nmb_namestr(&dgram->dest_name),
1252 inet_ntoa(p->ip) ));
1253 return;
1256 if ((buf2 + len < dgram->data) || (buf2 + len > dgram->data + dgram->datasize)) {
1257 DEBUG(0,("process_dgram: ignoring malformed3 (datasize = %d, len=%d, off=%d) datagram \
1258 packet sent to name %s from IP %s\n",
1259 dgram->datasize,
1260 len,
1261 (int)PTR_DIFF(buf2, dgram->data),
1262 nmb_namestr(&dgram->dest_name),
1263 inet_ntoa(p->ip) ));
1264 return;
1267 DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
1268 nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
1269 inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
1271 /* Datagram packet received for the browser mailslot */
1272 if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
1273 process_browse_packet(p,buf2,len);
1274 return;
1277 /* Datagram packet received for the LAN Manager mailslot */
1278 if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
1279 process_lanman_packet(p,buf2,len);
1280 return;
1283 /* Datagram packet received for the domain logon mailslot */
1284 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
1285 process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
1286 return;
1289 /* Datagram packet received for the NT domain logon mailslot */
1290 if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT)) {
1291 process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
1292 return;
1295 unexpected_packet(p);
1298 /****************************************************************************
1299 Validate a response nmb packet.
1300 ****************************************************************************/
1302 static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
1304 BOOL ignore = False;
1306 switch (nmb->header.opcode) {
1307 case NMB_NAME_REG_OPCODE:
1308 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1309 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1310 if (nmb->header.ancount == 0) {
1311 DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
1312 ignore = True;
1314 break;
1316 case NMB_NAME_QUERY_OPCODE:
1317 if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1)) {
1318 DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
1319 ignore = True;
1321 break;
1323 case NMB_NAME_RELEASE_OPCODE:
1324 if (nmb->header.ancount == 0) {
1325 DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
1326 ignore = True;
1328 break;
1330 case NMB_WACK_OPCODE:
1331 /* Check WACK response here. */
1332 if (nmb->header.ancount != 1) {
1333 DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
1334 ignore = True;
1336 break;
1337 default:
1338 DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
1339 nmb->header.opcode));
1340 return True;
1343 if(ignore)
1344 DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
1346 return ignore;
1349 /****************************************************************************
1350 Validate a request nmb packet.
1351 ****************************************************************************/
1353 static BOOL validate_nmb_packet( struct nmb_packet *nmb )
1355 BOOL ignore = False;
1357 switch (nmb->header.opcode) {
1358 case NMB_NAME_REG_OPCODE:
1359 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1360 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1361 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1362 if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
1363 DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
1364 ignore = True;
1366 break;
1368 case NMB_NAME_QUERY_OPCODE:
1369 if ((nmb->header.qdcount == 0) || ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
1370 (nmb->question.question_type != QUESTION_TYPE_NB_STATUS))) {
1371 DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
1372 ignore = True;
1374 break;
1376 case NMB_NAME_RELEASE_OPCODE:
1377 if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
1378 DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
1379 ignore = True;
1381 break;
1382 default:
1383 DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
1384 nmb->header.opcode));
1385 return True;
1388 if(ignore)
1389 DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
1391 return ignore;
1394 /****************************************************************************
1395 Find a subnet (and potentially a response record) for a packet.
1396 ****************************************************************************/
1398 static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,
1399 struct response_record **pprrec)
1401 struct nmb_packet *nmb = &p->packet.nmb;
1402 struct response_record *rrec = NULL;
1403 struct subnet_record *subrec = NULL;
1405 if(pprrec != NULL)
1406 *pprrec = NULL;
1408 if(nmb->header.response) {
1409 /* It's a response packet. Find a record for it or it's an error. */
1411 rrec = find_response_record( &subrec, nmb->header.name_trn_id);
1412 if(rrec == NULL) {
1413 DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
1414 nmb->header.name_trn_id));
1415 unexpected_packet(p);
1416 return NULL;
1419 if(subrec == NULL) {
1420 DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
1421 nmb->header.name_trn_id));
1422 return NULL;
1425 if(pprrec != NULL)
1426 *pprrec = rrec;
1427 return subrec;
1430 /* Try and see what subnet this packet belongs to. */
1432 /* WINS server ? */
1433 if(packet_is_for_wins_server(p))
1434 return wins_server_subnet;
1436 /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
1437 if(nmb->header.nm_flags.bcast == False)
1438 return unicast_subnet;
1440 /* Go through all the broadcast subnets and see if the mask matches. */
1441 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1442 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1443 return subrec;
1446 /* If none match it must have been a directed broadcast - assign the remote_broadcast_subnet. */
1447 return remote_broadcast_subnet;
1450 /****************************************************************************
1451 Process a nmb request packet - validate the packet and route it.
1452 ****************************************************************************/
1454 static void process_nmb_request(struct packet_struct *p)
1456 struct nmb_packet *nmb = &p->packet.nmb;
1457 struct subnet_record *subrec = NULL;
1459 debug_nmb_packet(p);
1461 /* Ensure we have a good packet. */
1462 if(validate_nmb_packet(nmb))
1463 return;
1465 /* Allocate a subnet to this packet - if we cannot - fail. */
1466 if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
1467 return;
1469 switch (nmb->header.opcode) {
1470 case NMB_NAME_REG_OPCODE:
1471 if(subrec == wins_server_subnet)
1472 wins_process_name_registration_request(subrec, p);
1473 else
1474 process_name_registration_request(subrec, p);
1475 break;
1477 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1478 case NMB_NAME_REFRESH_OPCODE_9:
1479 if(subrec == wins_server_subnet)
1480 wins_process_name_refresh_request(subrec, p);
1481 else
1482 process_name_refresh_request(subrec, p);
1483 break;
1485 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1486 if(subrec == wins_server_subnet) {
1487 wins_process_multihomed_name_registration_request(subrec, p);
1488 } else {
1489 DEBUG(0,("process_nmb_request: Multihomed registration request must be \
1490 directed at a WINS server.\n"));
1492 break;
1494 case NMB_NAME_QUERY_OPCODE:
1495 switch (nmb->question.question_type) {
1496 case QUESTION_TYPE_NB_QUERY:
1497 if(subrec == wins_server_subnet)
1498 wins_process_name_query_request(subrec, p);
1499 else
1500 process_name_query_request(subrec, p);
1501 break;
1502 case QUESTION_TYPE_NB_STATUS:
1503 if(subrec == wins_server_subnet) {
1504 DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
1505 not allowed.\n"));
1506 break;
1507 } else {
1508 process_node_status_request(subrec, p);
1510 break;
1512 break;
1514 case NMB_NAME_RELEASE_OPCODE:
1515 if(subrec == wins_server_subnet)
1516 wins_process_name_release_request(subrec, p);
1517 else
1518 process_name_release_request(subrec, p);
1519 break;
1523 /****************************************************************************
1524 Process a nmb response packet - validate the packet and route it.
1525 to either the WINS server or a normal response.
1526 ****************************************************************************/
1528 static void process_nmb_response(struct packet_struct *p)
1530 struct nmb_packet *nmb = &p->packet.nmb;
1531 struct subnet_record *subrec = NULL;
1532 struct response_record *rrec = NULL;
1534 debug_nmb_packet(p);
1536 if(validate_nmb_response_packet(nmb))
1537 return;
1539 if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
1540 return;
1542 if(rrec == NULL) {
1543 DEBUG(0,("process_nmb_response: response packet received but no response record \
1544 found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));
1545 return;
1548 /* Increment the number of responses received for this record. */
1549 rrec->num_msgs++;
1550 /* Ensure we don't re-send the request. */
1551 rrec->repeat_count = 0;
1553 /* Call the response received function for this packet. */
1554 (*rrec->resp_fn)(subrec, rrec, p);
1557 /*******************************************************************
1558 Run elements off the packet queue till its empty
1559 ******************************************************************/
1561 void run_packet_queue(void)
1563 struct packet_struct *p;
1565 while ((p = packet_queue)) {
1566 packet_queue = p->next;
1567 if (packet_queue)
1568 packet_queue->prev = NULL;
1569 p->next = p->prev = NULL;
1571 switch (p->packet_type) {
1572 case NMB_PACKET:
1573 if(p->packet.nmb.header.response)
1574 process_nmb_response(p);
1575 else
1576 process_nmb_request(p);
1577 break;
1579 case DGRAM_PACKET:
1580 process_dgram(p);
1581 break;
1583 free_packet(p);
1587 /*******************************************************************
1588 Retransmit or timeout elements from all the outgoing subnet response
1589 record queues. NOTE that this code must also check the WINS server
1590 subnet for response records to timeout as the WINS server code
1591 can send requests to check if a client still owns a name.
1592 (Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>).
1593 ******************************************************************/
1595 void retransmit_or_expire_response_records(time_t t)
1597 struct subnet_record *subrec;
1599 for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
1600 struct response_record *rrec, *nextrrec;
1602 for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
1603 nextrrec = rrec->next;
1605 if (rrec->repeat_time <= t) {
1606 if (rrec->repeat_count > 0) {
1607 /* Resend while we have a non-zero repeat_count. */
1608 if(!send_packet(rrec->packet)) {
1609 DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
1610 to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
1612 rrec->repeat_time = t + rrec->repeat_interval;
1613 rrec->repeat_count--;
1614 } else {
1615 DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
1616 on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
1619 * Check the flag in this record to prevent recursion if we end
1620 * up in this function again via the timeout function call.
1623 if(!rrec->in_expiration_processing) {
1626 * Set the recursion protection flag in this record.
1629 rrec->in_expiration_processing = True;
1631 /* Call the timeout function. This will deal with removing the
1632 timed out packet. */
1633 if(rrec->timeout_fn) {
1634 (*rrec->timeout_fn)(subrec, rrec);
1635 } else {
1636 /* We must remove the record ourself if there is
1637 no timeout function. */
1638 remove_response_record(subrec, rrec);
1640 } /* !rrec->in_expitation_processing */
1641 } /* rrec->repeat_count > 0 */
1642 } /* rrec->repeat_time <= t */
1643 } /* end for rrec */
1644 } /* end for subnet */
1647 /****************************************************************************
1648 Create an fd_set containing all the sockets in the subnet structures,
1649 plus the broadcast sockets.
1650 ***************************************************************************/
1652 static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number, int *maxfd)
1654 int *sock_array = NULL;
1655 struct subnet_record *subrec = NULL;
1656 int count = 0;
1657 int num = 0;
1658 fd_set *pset = SMB_MALLOC_P(fd_set);
1660 if(pset == NULL) {
1661 DEBUG(0,("create_listen_fdset: malloc fail !\n"));
1662 return True;
1665 /* Check that we can add all the fd's we need. */
1666 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1667 count++;
1669 if((count*2) + 2 > FD_SETSIZE) {
1670 DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
1671 only use %d.\n", (count*2) + 2, FD_SETSIZE));
1672 SAFE_FREE(pset);
1673 return True;
1676 if((sock_array = SMB_MALLOC_ARRAY(int, (count*2) + 2)) == NULL) {
1677 DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
1678 SAFE_FREE(pset);
1679 return True;
1682 FD_ZERO(pset);
1684 /* Add in the broadcast socket on 137. */
1685 FD_SET(ClientNMB,pset);
1686 sock_array[num++] = ClientNMB;
1687 *maxfd = MAX( *maxfd, ClientNMB);
1689 /* Add in the 137 sockets on all the interfaces. */
1690 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1691 FD_SET(subrec->nmb_sock,pset);
1692 sock_array[num++] = subrec->nmb_sock;
1693 *maxfd = MAX( *maxfd, subrec->nmb_sock);
1696 /* Add in the broadcast socket on 138. */
1697 FD_SET(ClientDGRAM,pset);
1698 sock_array[num++] = ClientDGRAM;
1699 *maxfd = MAX( *maxfd, ClientDGRAM);
1701 /* Add in the 138 sockets on all the interfaces. */
1702 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1703 FD_SET(subrec->dgram_sock,pset);
1704 sock_array[num++] = subrec->dgram_sock;
1705 *maxfd = MAX( *maxfd, subrec->dgram_sock);
1708 *listen_number = (count*2) + 2;
1710 SAFE_FREE(*ppset);
1711 SAFE_FREE(*psock_array);
1713 *ppset = pset;
1714 *psock_array = sock_array;
1716 return False;
1719 /****************************************************************************
1720 Listens for NMB or DGRAM packets, and queues them.
1721 return True if the socket is dead
1722 ***************************************************************************/
1724 BOOL listen_for_packets(BOOL run_election)
1726 static fd_set *listen_set = NULL;
1727 static int listen_number = 0;
1728 static int *sock_array = NULL;
1729 int i;
1730 static int maxfd = 0;
1732 fd_set r_fds;
1733 fd_set w_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 *)&r_fds, (char *)listen_set, sizeof(fd_set));
1749 FD_ZERO(&w_fds);
1751 #ifndef SYNC_DNS
1752 dns_fd = asyncdns_fd();
1753 if (dns_fd != -1) {
1754 FD_SET(dns_fd, &r_fds);
1755 maxfd = MAX( maxfd, dns_fd);
1757 #endif
1760 * During elections and when expecting a netbios response packet we
1761 * need to send election packets at tighter intervals.
1762 * Ideally it needs to be the interval (in ms) between time now and
1763 * the time we are expecting the next netbios packet.
1766 timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
1767 timeout.tv_usec = 0;
1770 struct timeval now = timeval_current();
1771 event_add_to_select_args(nmbd_event_context(), &now,
1772 &r_fds, &w_fds, &timeout, &maxfd);
1775 if (timeval_is_zero(&timeout)) {
1776 /* Process a timed event now... */
1777 if (run_events(nmbd_event_context(), 0, NULL, NULL)) {
1778 return False;
1782 /* Prepare for the select - allow certain signals. */
1784 BlockSignals(False, SIGTERM);
1786 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&timeout);
1788 /* We can only take signals when we are in the select - block them again here. */
1790 BlockSignals(True, SIGTERM);
1792 if(selrtn == -1) {
1793 return False;
1796 if (run_events(nmbd_event_context(), selrtn, &r_fds, &w_fds)) {
1797 return False;
1800 #ifndef SYNC_DNS
1801 if (dns_fd != -1 && FD_ISSET(dns_fd,&r_fds)) {
1802 run_dns_queue();
1804 #endif
1806 for(i = 0; i < listen_number; i++) {
1807 if (i < (listen_number/2)) {
1808 /* Processing a 137 socket. */
1809 if (FD_ISSET(sock_array[i],&r_fds)) {
1810 struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
1811 if (packet) {
1813 * If we got a packet on the broadcast socket and interfaces
1814 * only is set then check it came from one of our local nets.
1816 if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) &&
1817 (!is_local_net(packet->ip))) {
1818 DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
1819 inet_ntoa(packet->ip),packet->port));
1820 free_packet(packet);
1821 } else if ((ip_equal(loopback_ip, packet->ip) ||
1822 ismyip(packet->ip)) && packet->port == global_nmb_port &&
1823 packet->packet.nmb.header.nm_flags.bcast) {
1824 DEBUG(7,("discarding own bcast packet from %s:%d\n",
1825 inet_ntoa(packet->ip),packet->port));
1826 free_packet(packet);
1827 } else {
1828 /* Save the file descriptor this packet came in on. */
1829 packet->fd = sock_array[i];
1830 queue_packet(packet);
1834 } else {
1835 /* Processing a 138 socket. */
1836 if (FD_ISSET(sock_array[i],&r_fds)) {
1837 struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
1838 if (packet) {
1840 * If we got a packet on the broadcast socket and interfaces
1841 * only is set then check it came from one of our local nets.
1843 if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) &&
1844 (!is_local_net(packet->ip))) {
1845 DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
1846 inet_ntoa(packet->ip),packet->port));
1847 free_packet(packet);
1848 } else if ((ip_equal(loopback_ip, packet->ip) ||
1849 ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
1850 DEBUG(7,("discarding own dgram packet from %s:%d\n",
1851 inet_ntoa(packet->ip),packet->port));
1852 free_packet(packet);
1853 } else {
1854 /* Save the file descriptor this packet came in on. */
1855 packet->fd = sock_array[i];
1856 queue_packet(packet);
1860 } /* end processing 138 socket. */
1861 } /* end for */
1862 return False;
1865 /****************************************************************************
1866 Construct and send a netbios DGRAM.
1867 **************************************************************************/
1869 BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
1870 const char *srcname, int src_type,
1871 const char *dstname, int dest_type,
1872 struct in_addr dest_ip,struct in_addr src_ip,
1873 int dest_port)
1875 BOOL loopback_this_packet = False;
1876 struct packet_struct p;
1877 struct dgram_packet *dgram = &p.packet.dgram;
1878 char *ptr,*p2;
1879 char tmp[4];
1881 memset((char *)&p,'\0',sizeof(p));
1883 if(ismyip(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
1884 loopback_this_packet = True;
1886 /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
1888 /* DIRECT GROUP or UNIQUE datagram. */
1889 dgram->header.msg_type = unique ? 0x10 : 0x11;
1890 dgram->header.flags.node_type = M_NODE;
1891 dgram->header.flags.first = True;
1892 dgram->header.flags.more = False;
1893 dgram->header.dgm_id = generate_name_trn_id();
1894 dgram->header.source_ip = src_ip;
1895 dgram->header.source_port = DGRAM_PORT;
1896 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1897 dgram->header.packet_offset = 0;
1899 make_nmb_name(&dgram->source_name,srcname,src_type);
1900 make_nmb_name(&dgram->dest_name,dstname,dest_type);
1902 ptr = &dgram->data[0];
1904 /* Setup the smb part. */
1905 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1906 memcpy(tmp,ptr,4);
1907 set_message(NULL,ptr,17,strlen(mailslot) + 1 + len,True);
1908 memcpy(ptr,tmp,4);
1910 SCVAL(ptr,smb_com,SMBtrans);
1911 SSVAL(ptr,smb_vwv1,len);
1912 SSVAL(ptr,smb_vwv11,len);
1913 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1914 SSVAL(ptr,smb_vwv13,3);
1915 SSVAL(ptr,smb_vwv14,1);
1916 SSVAL(ptr,smb_vwv15,1);
1917 SSVAL(ptr,smb_vwv16,2);
1918 p2 = smb_buf(ptr);
1919 safe_strcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
1920 p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2);
1922 if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
1923 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
1924 return False;
1925 } else {
1926 memcpy(p2,buf,len);
1927 p2 += len;
1930 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1932 p.ip = dest_ip;
1933 p.port = dest_port;
1934 p.fd = find_subnet_mailslot_fd_for_address( src_ip );
1935 p.timestamp = time(NULL);
1936 p.packet_type = DGRAM_PACKET;
1938 DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
1939 nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
1940 DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
1942 debug_browse_data(buf, len);
1944 if(loopback_this_packet) {
1945 struct packet_struct *lo_packet = NULL;
1946 DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
1947 if((lo_packet = copy_packet(&p)) == NULL)
1948 return False;
1949 queue_packet(lo_packet);
1950 return True;
1951 } else {
1952 return(send_packet(&p));