r2260: merging from 3.0 (and updating WHATSNEW)
[Samba.git] / source / nmbd / nmbd_packets.c
blob96de4911dc587057f5d4087e856b9b802ca62579
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 = (struct packet_struct *)malloc(sizeof(*packet))) == 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 = (struct res_rec *)malloc(sizeof(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 *)malloc(sizeof(*userdata) + strlen(tag) + 1);
538 if (!userdata) {
539 DEBUG(0,("Failed to allocate userdata structure!\n"));
540 return;
542 ZERO_STRUCTP(userdata);
543 userdata->userdata_len = strlen(tag) + 1;
544 strlcpy(userdata->data, tag, userdata->userdata_len);
546 if ((rrec = make_response_record(unicast_subnet,
548 resp_fn, timeout_fn,
549 NULL,
550 NULL,
551 userdata)) == NULL) {
552 p->locked = False;
553 free_packet(p);
554 return;
557 free(userdata);
559 /* we don't want to repeat refresh packets */
560 rrec->repeat_count = 0;
564 /****************************************************************************
565 Queue a multihomed register name packet to a given WINS server IP
566 ****************************************************************************/
568 struct response_record *queue_register_multihomed_name( struct subnet_record *subrec,
569 response_function resp_fn,
570 timeout_response_function timeout_fn,
571 register_name_success_function success_fn,
572 register_name_fail_function fail_fn,
573 struct userdata_struct *userdata,
574 struct nmb_name *nmbname,
575 uint16 nb_flags,
576 struct in_addr register_ip,
577 struct in_addr wins_ip)
579 struct packet_struct *p;
580 struct response_record *rrec;
581 BOOL ret;
583 /* Sanity check. */
584 if(subrec != unicast_subnet) {
585 DEBUG(0,("queue_register_multihomed_name: should only be done on \
586 unicast subnet. subnet is %s\n.", subrec->subnet_name ));
587 return NULL;
590 if(assert_check_subnet(subrec))
591 return NULL;
593 if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL)
594 return NULL;
596 if (nb_flags & NB_GROUP)
597 ret = initiate_name_register_packet( p, nb_flags, &register_ip);
598 else
599 ret = initiate_multihomed_name_register_packet(p, nb_flags, &register_ip);
601 if (ret == False) {
602 p->locked = False;
603 free_packet(p);
604 return NULL;
607 if ((rrec = make_response_record(subrec, /* subnet record. */
608 p, /* packet we sent. */
609 resp_fn, /* function to call on response. */
610 timeout_fn, /* function to call on timeout. */
611 (success_function)success_fn, /* function to call on operation success. */
612 (fail_function)fail_fn, /* function to call on operation fail. */
613 userdata)) == NULL) {
614 p->locked = False;
615 free_packet(p);
616 return NULL;
619 return rrec;
622 /****************************************************************************
623 Queue a release name packet to the broadcast address of a subnet.
624 ****************************************************************************/
626 struct response_record *queue_release_name( struct subnet_record *subrec,
627 response_function resp_fn,
628 timeout_response_function timeout_fn,
629 release_name_success_function success_fn,
630 release_name_fail_function fail_fn,
631 struct userdata_struct *userdata,
632 struct nmb_name *nmbname,
633 uint16 nb_flags,
634 struct in_addr release_ip,
635 struct in_addr dest_ip)
637 struct packet_struct *p;
638 struct response_record *rrec;
640 if(assert_check_subnet(subrec))
641 return NULL;
643 if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False, dest_ip)) == NULL)
644 return NULL;
646 if(initiate_name_release_packet( p, nb_flags, &release_ip) == False) {
647 p->locked = False;
648 free_packet(p);
649 return NULL;
652 if((rrec = make_response_record(subrec, /* subnet record. */
653 p, /* packet we sent. */
654 resp_fn, /* function to call on response. */
655 timeout_fn, /* function to call on timeout. */
656 (success_function)success_fn, /* function to call on operation success. */
657 (fail_function)fail_fn, /* function to call on operation fail. */
658 userdata)) == NULL) {
659 p->locked = False;
660 free_packet(p);
661 return NULL;
665 * For a broadcast release packet, only send once.
666 * This will cause us to remove the name asap. JRA.
669 if (subrec != unicast_subnet) {
670 rrec->repeat_count = 0;
671 rrec->repeat_time = 0;
674 return rrec;
677 /****************************************************************************
678 Queue a query name packet to the broadcast address of a subnet.
679 ****************************************************************************/
681 struct response_record *queue_query_name( struct subnet_record *subrec,
682 response_function resp_fn,
683 timeout_response_function timeout_fn,
684 query_name_success_function success_fn,
685 query_name_fail_function fail_fn,
686 struct userdata_struct *userdata,
687 struct nmb_name *nmbname)
689 struct packet_struct *p;
690 struct response_record *rrec;
691 struct in_addr to_ip;
693 if(assert_check_subnet(subrec))
694 return NULL;
696 to_ip = subrec->bcast_ip;
698 /* queries to the WINS server turn up here as queries to IP 0.0.0.0
699 These need to be handled a bit differently */
700 if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
701 /* What we really need to do is loop over each of our wins
702 * servers and wins server tags here, but that just doesn't
703 * fit our architecture at the moment (userdata may already
704 * be used when we get here). For now we just query the first
705 * active wins server on the first tag.
707 char **tags = wins_srv_tags();
708 if (!tags) {
709 return NULL;
711 to_ip = wins_srv_ip_tag(tags[0], to_ip);
712 wins_srv_tags_free(tags);
715 if(( p = create_and_init_netbios_packet(nmbname,
716 (subrec != unicast_subnet),
717 (subrec == unicast_subnet),
718 to_ip)) == NULL)
719 return NULL;
721 if(lp_bind_interfaces_only()) {
722 int i;
724 DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
725 for(i = 0; i < iface_count(); i++) {
726 struct in_addr *ifip = iface_n_ip(i);
728 if(ifip == NULL) {
729 DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
730 continue;
733 if (ip_equal(*ifip,loopback_ip)) {
734 DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
735 continue;
738 DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
739 p->fd = find_subnet_fd_for_address( *ifip );
740 break;
744 if(initiate_name_query_packet( p ) == False) {
745 p->locked = False;
746 free_packet(p);
747 return NULL;
750 if((rrec = make_response_record(subrec, /* subnet record. */
751 p, /* packet we sent. */
752 resp_fn, /* function to call on response. */
753 timeout_fn, /* function to call on timeout. */
754 (success_function)success_fn, /* function to call on operation success. */
755 (fail_function)fail_fn, /* function to call on operation fail. */
756 userdata)) == NULL) {
757 p->locked = False;
758 free_packet(p);
759 return NULL;
762 return rrec;
765 /****************************************************************************
766 Queue a query name packet to a given address from the WINS subnet.
767 ****************************************************************************/
769 struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
770 response_function resp_fn,
771 timeout_response_function timeout_fn,
772 query_name_success_function success_fn,
773 query_name_fail_function fail_fn,
774 struct userdata_struct *userdata,
775 struct nmb_name *nmbname)
777 struct packet_struct *p;
778 struct response_record *rrec;
780 if ((p = create_and_init_netbios_packet(nmbname, False, False, to_ip)) == NULL)
781 return NULL;
783 if(initiate_name_query_packet_from_wins_server( p ) == False) {
784 p->locked = False;
785 free_packet(p);
786 return NULL;
789 if((rrec = make_response_record(wins_server_subnet, /* subnet record. */
790 p, /* packet we sent. */
791 resp_fn, /* function to call on response. */
792 timeout_fn, /* function to call on timeout. */
793 (success_function)success_fn, /* function to call on operation success. */
794 (fail_function)fail_fn, /* function to call on operation fail. */
795 userdata)) == NULL) {
796 p->locked = False;
797 free_packet(p);
798 return NULL;
801 return rrec;
804 /****************************************************************************
805 Queue a node status packet to a given name and address.
806 ****************************************************************************/
808 struct response_record *queue_node_status( struct subnet_record *subrec,
809 response_function resp_fn,
810 timeout_response_function timeout_fn,
811 node_status_success_function success_fn,
812 node_status_fail_function fail_fn,
813 struct userdata_struct *userdata,
814 struct nmb_name *nmbname,
815 struct in_addr send_ip)
817 struct packet_struct *p;
818 struct response_record *rrec;
820 /* Sanity check. */
821 if(subrec != unicast_subnet) {
822 DEBUG(0,("queue_register_multihomed_name: should only be done on \
823 unicast subnet. subnet is %s\n.", subrec->subnet_name ));
824 return NULL;
827 if(assert_check_subnet(subrec))
828 return NULL;
830 if(( p = create_and_init_netbios_packet(nmbname, False, False, send_ip)) == NULL)
831 return NULL;
833 if(initiate_node_status_packet(p) == False) {
834 p->locked = False;
835 free_packet(p);
836 return NULL;
839 if((rrec = make_response_record(subrec, /* subnet record. */
840 p, /* packet we sent. */
841 resp_fn, /* function to call on response. */
842 timeout_fn, /* function to call on timeout. */
843 (success_function)success_fn, /* function to call on operation success. */
844 (fail_function)fail_fn, /* function to call on operation fail. */
845 userdata)) == NULL) {
846 p->locked = False;
847 free_packet(p);
848 return NULL;
851 return rrec;
854 /****************************************************************************
855 Reply to a netbios name packet. see rfc1002.txt
856 ****************************************************************************/
858 void reply_netbios_packet(struct packet_struct *orig_packet,
859 int rcode, enum netbios_reply_type_code rcv_code, int opcode,
860 int ttl, char *data,int len)
862 struct packet_struct packet;
863 struct nmb_packet *nmb = NULL;
864 struct res_rec answers;
865 struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
866 BOOL loopback_this_packet = False;
867 const char *packet_type = "unknown";
869 /* Check if we are sending to or from ourselves. */
870 if(ismyip(orig_packet->ip) && (orig_packet->port == global_nmb_port))
871 loopback_this_packet = True;
873 nmb = &packet.packet.nmb;
875 /* Do a partial copy of the packet. We clear the locked flag and
876 the resource record pointers. */
877 packet = *orig_packet; /* Full structure copy. */
878 packet.locked = False;
879 nmb->answers = NULL;
880 nmb->nsrecs = NULL;
881 nmb->additional = NULL;
883 switch (rcv_code) {
884 case NMB_STATUS:
885 packet_type = "nmb_status";
886 nmb->header.nm_flags.recursion_desired = False;
887 nmb->header.nm_flags.recursion_available = False;
888 break;
889 case NMB_QUERY:
890 packet_type = "nmb_query";
891 nmb->header.nm_flags.recursion_desired = True;
892 nmb->header.nm_flags.recursion_available = True;
893 break;
894 case NMB_REG:
895 case NMB_REG_REFRESH:
896 packet_type = "nmb_reg";
897 nmb->header.nm_flags.recursion_desired = True;
898 nmb->header.nm_flags.recursion_available = True;
899 break;
900 case NMB_REL:
901 packet_type = "nmb_rel";
902 nmb->header.nm_flags.recursion_desired = False;
903 nmb->header.nm_flags.recursion_available = False;
904 break;
905 case NMB_WAIT_ACK:
906 packet_type = "nmb_wack";
907 nmb->header.nm_flags.recursion_desired = False;
908 nmb->header.nm_flags.recursion_available = False;
909 break;
910 case WINS_REG:
911 packet_type = "wins_reg";
912 nmb->header.nm_flags.recursion_desired = True;
913 nmb->header.nm_flags.recursion_available = True;
914 break;
915 case WINS_QUERY:
916 packet_type = "wins_query";
917 nmb->header.nm_flags.recursion_desired = True;
918 nmb->header.nm_flags.recursion_available = True;
919 break;
920 default:
921 DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
922 packet_type, nmb_namestr(&orig_nmb->question.question_name),
923 inet_ntoa(packet.ip)));
924 return;
927 DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
928 for id %hu\n", packet_type, nmb_namestr(&orig_nmb->question.question_name),
929 inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
931 nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
932 nmb->header.opcode = opcode;
933 nmb->header.response = True;
934 nmb->header.nm_flags.bcast = False;
935 nmb->header.nm_flags.trunc = False;
936 nmb->header.nm_flags.authoritative = True;
938 nmb->header.rcode = rcode;
939 nmb->header.qdcount = 0;
940 nmb->header.ancount = 1;
941 nmb->header.nscount = 0;
942 nmb->header.arcount = 0;
944 memset((char*)&nmb->question,'\0',sizeof(nmb->question));
946 nmb->answers = &answers;
947 memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
949 nmb->answers->rr_name = orig_nmb->question.question_name;
950 nmb->answers->rr_type = orig_nmb->question.question_type;
951 nmb->answers->rr_class = orig_nmb->question.question_class;
952 nmb->answers->ttl = ttl;
954 if (data && len) {
955 nmb->answers->rdlength = len;
956 memcpy(nmb->answers->rdata, data, len);
959 packet.packet_type = NMB_PACKET;
960 /* Ensure we send out on the same fd that the original
961 packet came in on to give the correct source IP address. */
962 packet.fd = orig_packet->fd;
963 packet.timestamp = time(NULL);
965 debug_nmb_packet(&packet);
967 if(loopback_this_packet) {
968 struct packet_struct *lo_packet;
969 DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
970 if((lo_packet = copy_packet(&packet)) == NULL)
971 return;
972 queue_packet(lo_packet);
973 } else if (!send_packet(&packet)) {
974 DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
975 inet_ntoa(packet.ip),packet.port));
979 /*******************************************************************
980 Queue a packet into a packet queue
981 ******************************************************************/
983 static void queue_packet(struct packet_struct *packet)
985 struct packet_struct *p;
987 if (!packet_queue) {
988 packet->prev = NULL;
989 packet->next = NULL;
990 packet_queue = packet;
991 return;
994 /* find the bottom */
995 for (p=packet_queue;p->next;p=p->next)
998 p->next = packet;
999 packet->next = NULL;
1000 packet->prev = p;
1003 /****************************************************************************
1004 Try and find a matching subnet record for a datagram port 138 packet.
1005 ****************************************************************************/
1007 static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_struct *p)
1009 struct subnet_record *subrec;
1011 /* Go through all the broadcast subnets and see if the mask matches. */
1012 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1013 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1014 return subrec;
1017 /* If the subnet record is the remote announce broadcast subnet,
1018 hack it here to be the first subnet. This is really gross and
1019 is needed due to people turning on port 137/138 broadcast
1020 forwarding on their routers. May fire and brimstone rain
1021 down upon them...
1024 return FIRST_SUBNET;
1027 /****************************************************************************
1028 Dispatch a browse frame from port 138 to the correct processing function.
1029 ****************************************************************************/
1031 static void process_browse_packet(struct packet_struct *p, char *buf,int len)
1033 struct dgram_packet *dgram = &p->packet.dgram;
1034 int command = CVAL(buf,0);
1035 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1036 char scope[64];
1037 unstring src_name;
1039 /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
1040 pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
1041 if (!strequal(scope, global_scope())) {
1042 DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
1043 mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
1044 return;
1047 pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
1048 if (is_myname(src_name)) {
1049 DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
1050 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1051 return;
1054 switch (command) {
1055 case ANN_HostAnnouncement:
1056 debug_browse_data(buf, len);
1057 process_host_announce(subrec, p, buf+1);
1058 break;
1059 case ANN_DomainAnnouncement:
1060 debug_browse_data(buf, len);
1061 process_workgroup_announce(subrec, p, buf+1);
1062 break;
1063 case ANN_LocalMasterAnnouncement:
1064 debug_browse_data(buf, len);
1065 process_local_master_announce(subrec, p, buf+1);
1066 break;
1067 case ANN_AnnouncementRequest:
1068 debug_browse_data(buf, len);
1069 process_announce_request(subrec, p, buf+1);
1070 break;
1071 case ANN_Election:
1072 debug_browse_data(buf, len);
1073 process_election(subrec, p, buf+1);
1074 break;
1075 case ANN_GetBackupListReq:
1076 debug_browse_data(buf, len);
1077 process_get_backup_list_request(subrec, p, buf+1);
1078 break;
1079 case ANN_GetBackupListResp:
1080 debug_browse_data(buf, len);
1081 /* We never send ANN_GetBackupListReq so we should never get these. */
1082 DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
1083 packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
1084 break;
1085 case ANN_ResetBrowserState:
1086 debug_browse_data(buf, len);
1087 process_reset_browser(subrec, p, buf+1);
1088 break;
1089 case ANN_MasterAnnouncement:
1090 /* Master browser datagrams must be processed on the unicast subnet. */
1091 subrec = unicast_subnet;
1093 debug_browse_data(buf, len);
1094 process_master_browser_announce(subrec, p, buf+1);
1095 break;
1096 case ANN_BecomeBackup:
1098 * We don't currently implement this. Log it just in case.
1100 debug_browse_data(buf, len);
1101 DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
1102 command ANN_BecomeBackup from %s IP %s to %s\n", subrec->subnet_name, nmb_namestr(&dgram->source_name),
1103 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1104 break;
1105 default:
1106 debug_browse_data(buf, len);
1107 DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
1108 command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1109 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1110 break;
1114 /****************************************************************************
1115 Dispatch a LanMan browse frame from port 138 to the correct processing function.
1116 ****************************************************************************/
1118 static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
1120 struct dgram_packet *dgram = &p->packet.dgram;
1121 int command = SVAL(buf,0);
1122 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1123 char scope[64];
1124 unstring src_name;
1126 /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
1128 pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
1129 if (!strequal(scope, global_scope())) {
1130 DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
1131 mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
1132 return;
1135 pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
1136 if (is_myname(src_name)) {
1137 DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
1138 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1139 return;
1142 switch (command) {
1143 case ANN_HostAnnouncement:
1144 debug_browse_data(buf, len);
1145 process_lm_host_announce(subrec, p, buf+1);
1146 break;
1147 case ANN_AnnouncementRequest:
1148 process_lm_announce_request(subrec, p, buf+1);
1149 break;
1150 default:
1151 DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
1152 command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1153 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1154 break;
1158 /****************************************************************************
1159 Determine if a packet is for us on port 138. Note that to have any chance of
1160 being efficient we need to drop as many packets as possible at this
1161 stage as subsequent processing is expensive.
1162 ****************************************************************************/
1164 static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
1166 struct subnet_record *subrec = NULL;
1168 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1169 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1170 break;
1173 if(subrec == NULL)
1174 subrec = unicast_subnet;
1176 return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
1179 /****************************************************************************
1180 Process udp 138 datagrams
1181 ****************************************************************************/
1183 static void process_dgram(struct packet_struct *p)
1185 char *buf;
1186 char *buf2;
1187 int len;
1188 struct dgram_packet *dgram = &p->packet.dgram;
1190 /* If we aren't listening to the destination name then ignore the packet */
1191 if (!listening(p,&dgram->dest_name)) {
1192 unexpected_packet(p);
1193 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
1194 nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
1195 return;
1198 if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) {
1199 unexpected_packet(p);
1200 /* Don't process error packets etc yet */
1201 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
1202 an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
1203 return;
1206 /* Ensure we have a large enough packet before looking inside. */
1207 if (dgram->datasize < (smb_vwv12 - 2)) {
1208 /* That's the offset minus the 4 byte length + 2 bytes of offset. */
1209 DEBUG(0,("process_dgram: ignoring too short dgram packet (%u) sent to name %s from IP %s\n",
1210 (unsigned int)dgram->datasize,
1211 nmb_namestr(&dgram->dest_name),
1212 inet_ntoa(p->ip) ));
1213 return;
1216 buf = &dgram->data[0];
1217 buf -= 4; /* XXXX for the pseudo tcp length - someday I need to get rid of this */
1219 if (CVAL(buf,smb_com) != SMBtrans)
1220 return;
1222 len = SVAL(buf,smb_vwv11);
1223 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1225 if (len <= 0 || len > dgram->datasize) {
1226 DEBUG(0,("process_dgram: ignoring malformed1 (datasize = %d, len = %d) datagram \
1227 packet sent to name %s from IP %s\n",
1228 dgram->datasize,
1229 len,
1230 nmb_namestr(&dgram->dest_name),
1231 inet_ntoa(p->ip) ));
1232 return;
1235 if (buf2 < dgram->data || (buf2 >= dgram->data + dgram->datasize)) {
1236 DEBUG(0,("process_dgram: ignoring malformed2 (datasize = %d, len=%d, off=%d) datagram \
1237 packet sent to name %s from IP %s\n",
1238 dgram->datasize,
1239 len,
1240 PTR_DIFF(buf2, dgram->data),
1241 nmb_namestr(&dgram->dest_name),
1242 inet_ntoa(p->ip) ));
1243 return;
1246 if ((buf2 + len < dgram->data) || (buf2 + len > dgram->data + dgram->datasize)) {
1247 DEBUG(0,("process_dgram: ignoring malformed3 (datasize = %d, len=%d, off=%d) datagram \
1248 packet sent to name %s from IP %s\n",
1249 dgram->datasize,
1250 len,
1251 PTR_DIFF(buf2, dgram->data),
1252 nmb_namestr(&dgram->dest_name),
1253 inet_ntoa(p->ip) ));
1254 return;
1257 DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
1258 nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
1259 inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
1261 /* Datagram packet received for the browser mailslot */
1262 if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
1263 process_browse_packet(p,buf2,len);
1264 return;
1267 /* Datagram packet received for the LAN Manager mailslot */
1268 if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
1269 process_lanman_packet(p,buf2,len);
1270 return;
1273 /* Datagram packet received for the domain logon mailslot */
1274 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
1275 process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
1276 return;
1279 /* Datagram packet received for the NT domain logon mailslot */
1280 if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT)) {
1281 process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
1282 return;
1285 unexpected_packet(p);
1288 /****************************************************************************
1289 Validate a response nmb packet.
1290 ****************************************************************************/
1292 static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
1294 BOOL ignore = False;
1296 switch (nmb->header.opcode) {
1297 case NMB_NAME_REG_OPCODE:
1298 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1299 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1300 if (nmb->header.ancount == 0) {
1301 DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
1302 ignore = True;
1304 break;
1306 case NMB_NAME_QUERY_OPCODE:
1307 if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1)) {
1308 DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
1309 ignore = True;
1311 break;
1313 case NMB_NAME_RELEASE_OPCODE:
1314 if (nmb->header.ancount == 0) {
1315 DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
1316 ignore = True;
1318 break;
1320 case NMB_WACK_OPCODE:
1321 /* Check WACK response here. */
1322 if (nmb->header.ancount != 1) {
1323 DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
1324 ignore = True;
1326 break;
1327 default:
1328 DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
1329 nmb->header.opcode));
1330 return True;
1333 if(ignore)
1334 DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
1336 return ignore;
1339 /****************************************************************************
1340 Validate a request nmb packet.
1341 ****************************************************************************/
1343 static BOOL validate_nmb_packet( struct nmb_packet *nmb )
1345 BOOL ignore = False;
1347 switch (nmb->header.opcode) {
1348 case NMB_NAME_REG_OPCODE:
1349 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1350 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1351 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1352 if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
1353 DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
1354 ignore = True;
1356 break;
1358 case NMB_NAME_QUERY_OPCODE:
1359 if ((nmb->header.qdcount == 0) || ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
1360 (nmb->question.question_type != QUESTION_TYPE_NB_STATUS))) {
1361 DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
1362 ignore = True;
1364 break;
1366 case NMB_NAME_RELEASE_OPCODE:
1367 if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
1368 DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
1369 ignore = True;
1371 break;
1372 default:
1373 DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
1374 nmb->header.opcode));
1375 return True;
1378 if(ignore)
1379 DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
1381 return ignore;
1384 /****************************************************************************
1385 Find a subnet (and potentially a response record) for a packet.
1386 ****************************************************************************/
1388 static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,
1389 struct response_record **pprrec)
1391 struct nmb_packet *nmb = &p->packet.nmb;
1392 struct response_record *rrec = NULL;
1393 struct subnet_record *subrec = NULL;
1395 if(pprrec != NULL)
1396 *pprrec = NULL;
1398 if(nmb->header.response) {
1399 /* It's a response packet. Find a record for it or it's an error. */
1401 rrec = find_response_record( &subrec, nmb->header.name_trn_id);
1402 if(rrec == NULL) {
1403 DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
1404 nmb->header.name_trn_id));
1405 unexpected_packet(p);
1406 return NULL;
1409 if(subrec == NULL) {
1410 DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
1411 nmb->header.name_trn_id));
1412 return NULL;
1415 if(pprrec != NULL)
1416 *pprrec = rrec;
1417 return subrec;
1420 /* Try and see what subnet this packet belongs to. */
1422 /* WINS server ? */
1423 if(packet_is_for_wins_server(p))
1424 return wins_server_subnet;
1426 /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
1427 if(nmb->header.nm_flags.bcast == False)
1428 return unicast_subnet;
1430 /* Go through all the broadcast subnets and see if the mask matches. */
1431 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1432 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1433 return subrec;
1436 /* If none match it must have been a directed broadcast - assign the remote_broadcast_subnet. */
1437 return remote_broadcast_subnet;
1440 /****************************************************************************
1441 Process a nmb request packet - validate the packet and route it.
1442 ****************************************************************************/
1444 static void process_nmb_request(struct packet_struct *p)
1446 struct nmb_packet *nmb = &p->packet.nmb;
1447 struct subnet_record *subrec = NULL;
1449 debug_nmb_packet(p);
1451 /* Ensure we have a good packet. */
1452 if(validate_nmb_packet(nmb))
1453 return;
1455 /* Allocate a subnet to this packet - if we cannot - fail. */
1456 if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
1457 return;
1459 switch (nmb->header.opcode) {
1460 case NMB_NAME_REG_OPCODE:
1461 if(subrec == wins_server_subnet)
1462 wins_process_name_registration_request(subrec, p);
1463 else
1464 process_name_registration_request(subrec, p);
1465 break;
1467 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1468 case NMB_NAME_REFRESH_OPCODE_9:
1469 if(subrec == wins_server_subnet)
1470 wins_process_name_refresh_request(subrec, p);
1471 else
1472 process_name_refresh_request(subrec, p);
1473 break;
1475 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1476 if(subrec == wins_server_subnet) {
1477 wins_process_multihomed_name_registration_request(subrec, p);
1478 } else {
1479 DEBUG(0,("process_nmb_request: Multihomed registration request must be \
1480 directed at a WINS server.\n"));
1482 break;
1484 case NMB_NAME_QUERY_OPCODE:
1485 switch (nmb->question.question_type) {
1486 case QUESTION_TYPE_NB_QUERY:
1487 if(subrec == wins_server_subnet)
1488 wins_process_name_query_request(subrec, p);
1489 else
1490 process_name_query_request(subrec, p);
1491 break;
1492 case QUESTION_TYPE_NB_STATUS:
1493 if(subrec == wins_server_subnet) {
1494 DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
1495 not allowed.\n"));
1496 break;
1497 } else {
1498 process_node_status_request(subrec, p);
1500 break;
1502 break;
1504 case NMB_NAME_RELEASE_OPCODE:
1505 if(subrec == wins_server_subnet)
1506 wins_process_name_release_request(subrec, p);
1507 else
1508 process_name_release_request(subrec, p);
1509 break;
1513 /****************************************************************************
1514 Process a nmb response packet - validate the packet and route it.
1515 to either the WINS server or a normal response.
1516 ****************************************************************************/
1518 static void process_nmb_response(struct packet_struct *p)
1520 struct nmb_packet *nmb = &p->packet.nmb;
1521 struct subnet_record *subrec = NULL;
1522 struct response_record *rrec = NULL;
1524 debug_nmb_packet(p);
1526 if(validate_nmb_response_packet(nmb))
1527 return;
1529 if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
1530 return;
1532 if(rrec == NULL) {
1533 DEBUG(0,("process_nmb_response: response packet received but no response record \
1534 found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));
1535 return;
1538 /* Increment the number of responses received for this record. */
1539 rrec->num_msgs++;
1540 /* Ensure we don't re-send the request. */
1541 rrec->repeat_count = 0;
1543 /* Call the response received function for this packet. */
1544 (*rrec->resp_fn)(subrec, rrec, p);
1547 /*******************************************************************
1548 Run elements off the packet queue till its empty
1549 ******************************************************************/
1551 void run_packet_queue(void)
1553 struct packet_struct *p;
1555 while ((p = packet_queue)) {
1556 packet_queue = p->next;
1557 if (packet_queue)
1558 packet_queue->prev = NULL;
1559 p->next = p->prev = NULL;
1561 switch (p->packet_type) {
1562 case NMB_PACKET:
1563 if(p->packet.nmb.header.response)
1564 process_nmb_response(p);
1565 else
1566 process_nmb_request(p);
1567 break;
1569 case DGRAM_PACKET:
1570 process_dgram(p);
1571 break;
1573 free_packet(p);
1577 /*******************************************************************
1578 Retransmit or timeout elements from all the outgoing subnet response
1579 record queues. NOTE that this code must also check the WINS server
1580 subnet for response records to timeout as the WINS server code
1581 can send requests to check if a client still owns a name.
1582 (Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>).
1583 ******************************************************************/
1585 void retransmit_or_expire_response_records(time_t t)
1587 struct subnet_record *subrec;
1589 for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
1590 struct response_record *rrec, *nextrrec;
1592 for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
1593 nextrrec = rrec->next;
1595 if (rrec->repeat_time <= t) {
1596 if (rrec->repeat_count > 0) {
1597 /* Resend while we have a non-zero repeat_count. */
1598 if(!send_packet(rrec->packet)) {
1599 DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
1600 to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
1602 rrec->repeat_time = t + rrec->repeat_interval;
1603 rrec->repeat_count--;
1604 } else {
1605 DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
1606 on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
1609 * Check the flag in this record to prevent recursion if we end
1610 * up in this function again via the timeout function call.
1613 if(!rrec->in_expiration_processing) {
1616 * Set the recursion protection flag in this record.
1619 rrec->in_expiration_processing = True;
1621 /* Call the timeout function. This will deal with removing the
1622 timed out packet. */
1623 if(rrec->timeout_fn) {
1624 (*rrec->timeout_fn)(subrec, rrec);
1625 } else {
1626 /* We must remove the record ourself if there is
1627 no timeout function. */
1628 remove_response_record(subrec, rrec);
1630 } /* !rrec->in_expitation_processing */
1631 } /* rrec->repeat_count > 0 */
1632 } /* rrec->repeat_time <= t */
1633 } /* end for rrec */
1634 } /* end for subnet */
1637 /****************************************************************************
1638 Create an fd_set containing all the sockets in the subnet structures,
1639 plus the broadcast sockets.
1640 ***************************************************************************/
1642 static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number)
1644 int *sock_array = NULL;
1645 struct subnet_record *subrec = NULL;
1646 int count = 0;
1647 int num = 0;
1648 fd_set *pset = (fd_set *)malloc(sizeof(fd_set));
1650 if(pset == NULL) {
1651 DEBUG(0,("create_listen_fdset: malloc fail !\n"));
1652 return True;
1655 /* Check that we can add all the fd's we need. */
1656 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1657 count++;
1659 if((count*2) + 2 > FD_SETSIZE) {
1660 DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
1661 only use %d.\n", (count*2) + 2, FD_SETSIZE));
1662 return True;
1665 if((sock_array = (int *)malloc(((count*2) + 2)*sizeof(int))) == NULL) {
1666 DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
1667 return True;
1670 FD_ZERO(pset);
1672 /* Add in the broadcast socket on 137. */
1673 FD_SET(ClientNMB,pset);
1674 sock_array[num++] = ClientNMB;
1676 /* Add in the 137 sockets on all the interfaces. */
1677 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1678 FD_SET(subrec->nmb_sock,pset);
1679 sock_array[num++] = subrec->nmb_sock;
1682 /* Add in the broadcast socket on 138. */
1683 FD_SET(ClientDGRAM,pset);
1684 sock_array[num++] = ClientDGRAM;
1686 /* Add in the 138 sockets on all the interfaces. */
1687 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1688 FD_SET(subrec->dgram_sock,pset);
1689 sock_array[num++] = subrec->dgram_sock;
1692 *listen_number = (count*2) + 2;
1694 SAFE_FREE(*ppset);
1695 SAFE_FREE(*psock_array);
1697 *ppset = pset;
1698 *psock_array = sock_array;
1700 return False;
1703 /****************************************************************************
1704 Listens for NMB or DGRAM packets, and queues them.
1705 return True if the socket is dead
1706 ***************************************************************************/
1708 BOOL listen_for_packets(BOOL run_election)
1710 static fd_set *listen_set = NULL;
1711 static int listen_number = 0;
1712 static int *sock_array = NULL;
1713 int i;
1715 fd_set fds;
1716 int selrtn;
1717 struct timeval timeout;
1718 #ifndef SYNC_DNS
1719 int dns_fd;
1720 #endif
1722 if(listen_set == NULL || rescan_listen_set) {
1723 if(create_listen_fdset(&listen_set, &sock_array, &listen_number)) {
1724 DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
1725 return True;
1727 rescan_listen_set = False;
1730 memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
1732 #ifndef SYNC_DNS
1733 dns_fd = asyncdns_fd();
1734 if (dns_fd != -1) {
1735 FD_SET(dns_fd, &fds);
1737 #endif
1740 * During elections and when expecting a netbios response packet we
1741 * need to send election packets at tighter intervals.
1742 * Ideally it needs to be the interval (in ms) between time now and
1743 * the time we are expecting the next netbios packet.
1746 timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
1747 timeout.tv_usec = 0;
1749 /* Prepare for the select - allow certain signals. */
1751 BlockSignals(False, SIGTERM);
1753 selrtn = sys_select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
1755 /* We can only take signals when we are in the select - block them again here. */
1757 BlockSignals(True, SIGTERM);
1759 if(selrtn == -1) {
1760 return False;
1763 #ifndef SYNC_DNS
1764 if (dns_fd != -1 && FD_ISSET(dns_fd,&fds)) {
1765 run_dns_queue();
1767 #endif
1769 for(i = 0; i < listen_number; i++) {
1770 if (i < (listen_number/2)) {
1771 /* Processing a 137 socket. */
1772 if (FD_ISSET(sock_array[i],&fds)) {
1773 struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
1774 if (packet) {
1776 * If we got a packet on the broadcast socket and interfaces
1777 * only is set then check it came from one of our local nets.
1779 if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) &&
1780 (!is_local_net(packet->ip))) {
1781 DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
1782 inet_ntoa(packet->ip),packet->port));
1783 free_packet(packet);
1784 } else if ((ip_equal(loopback_ip, packet->ip) ||
1785 ismyip(packet->ip)) && packet->port == global_nmb_port &&
1786 packet->packet.nmb.header.nm_flags.bcast) {
1787 DEBUG(7,("discarding own bcast packet from %s:%d\n",
1788 inet_ntoa(packet->ip),packet->port));
1789 free_packet(packet);
1790 } else {
1791 /* Save the file descriptor this packet came in on. */
1792 packet->fd = sock_array[i];
1793 queue_packet(packet);
1797 } else {
1798 /* Processing a 138 socket. */
1799 if (FD_ISSET(sock_array[i],&fds)) {
1800 struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
1801 if (packet) {
1803 * If we got a packet on the broadcast socket and interfaces
1804 * only is set then check it came from one of our local nets.
1806 if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) &&
1807 (!is_local_net(packet->ip))) {
1808 DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
1809 inet_ntoa(packet->ip),packet->port));
1810 free_packet(packet);
1811 } else if ((ip_equal(loopback_ip, packet->ip) ||
1812 ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
1813 DEBUG(7,("discarding own dgram packet from %s:%d\n",
1814 inet_ntoa(packet->ip),packet->port));
1815 free_packet(packet);
1816 } else {
1817 /* Save the file descriptor this packet came in on. */
1818 packet->fd = sock_array[i];
1819 queue_packet(packet);
1823 } /* end processing 138 socket. */
1824 } /* end for */
1825 return False;
1828 /****************************************************************************
1829 Construct and send a netbios DGRAM.
1830 **************************************************************************/
1832 BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
1833 const char *srcname, int src_type,
1834 const char *dstname, int dest_type,
1835 struct in_addr dest_ip,struct in_addr src_ip,
1836 int dest_port)
1838 BOOL loopback_this_packet = False;
1839 struct packet_struct p;
1840 struct dgram_packet *dgram = &p.packet.dgram;
1841 char *ptr,*p2;
1842 char tmp[4];
1844 memset((char *)&p,'\0',sizeof(p));
1846 if(ismyip(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
1847 loopback_this_packet = True;
1849 /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
1851 /* DIRECT GROUP or UNIQUE datagram. */
1852 dgram->header.msg_type = unique ? 0x10 : 0x11;
1853 dgram->header.flags.node_type = M_NODE;
1854 dgram->header.flags.first = True;
1855 dgram->header.flags.more = False;
1856 dgram->header.dgm_id = generate_name_trn_id();
1857 dgram->header.source_ip = src_ip;
1858 dgram->header.source_port = DGRAM_PORT;
1859 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1860 dgram->header.packet_offset = 0;
1862 make_nmb_name(&dgram->source_name,srcname,src_type);
1863 make_nmb_name(&dgram->dest_name,dstname,dest_type);
1865 ptr = &dgram->data[0];
1867 /* Setup the smb part. */
1868 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1869 memcpy(tmp,ptr,4);
1870 set_message(ptr,17,strlen(mailslot) + 1 + len,True);
1871 memcpy(ptr,tmp,4);
1873 SCVAL(ptr,smb_com,SMBtrans);
1874 SSVAL(ptr,smb_vwv1,len);
1875 SSVAL(ptr,smb_vwv11,len);
1876 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1877 SSVAL(ptr,smb_vwv13,3);
1878 SSVAL(ptr,smb_vwv14,1);
1879 SSVAL(ptr,smb_vwv15,1);
1880 SSVAL(ptr,smb_vwv16,2);
1881 p2 = smb_buf(ptr);
1882 safe_strcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
1883 p2 = skip_string(p2,1);
1885 if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
1886 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
1887 return False;
1888 } else {
1889 memcpy(p2,buf,len);
1890 p2 += len;
1893 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1895 p.ip = dest_ip;
1896 p.port = dest_port;
1897 p.fd = find_subnet_mailslot_fd_for_address( src_ip );
1898 p.timestamp = time(NULL);
1899 p.packet_type = DGRAM_PACKET;
1901 DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
1902 nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
1903 DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
1905 debug_browse_data(buf, len);
1907 if(loopback_this_packet) {
1908 struct packet_struct *lo_packet = NULL;
1909 DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
1910 if((lo_packet = copy_packet(&p)) == NULL)
1911 return False;
1912 queue_packet(lo_packet);
1913 return True;
1914 } else {
1915 return(send_packet(&p));