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-1998
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.
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;
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;
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);
92 /***************************************************************************
93 Dumps out the browse packet data.
94 **************************************************************************/
96 static void debug_browse_data(char *outbuf, int len)
100 DEBUG( 4, ( "debug_browse_data():\n" ) );
101 for (i = 0; i < len; i+= 16)
103 DEBUGADD( 4, ( "%3x char ", i ) );
105 for (j = 0; j < 16; j++)
112 if (x < 32 || x > 127)
115 DEBUGADD( 4, ( "%c", x ) );
118 DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
120 for (j = 0; j < 16; j++)
124 DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
127 DEBUGADD( 4, ("\n") );
131 /***************************************************************************
132 Generates the unique transaction identifier
133 **************************************************************************/
135 static uint16 name_trn_id=0;
137 static uint16 generate_name_trn_id(void)
142 name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
144 name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
148 /***************************************************************************
149 Either loops back or sends out a completed NetBIOS packet.
150 **************************************************************************/
152 static BOOL send_netbios_packet(struct packet_struct *p)
154 BOOL loopback_this_packet = False;
156 /* Check if we are sending to or from ourselves as a WINS server. */
157 if(ismyip(p->ip) && (p->port == global_nmb_port))
158 loopback_this_packet = True;
160 if(loopback_this_packet)
162 struct packet_struct *lo_packet = NULL;
163 DEBUG(5,("send_netbios_packet: sending packet to ourselves.\n"));
164 if((lo_packet = copy_packet(p)) == NULL)
166 queue_packet(lo_packet);
168 else if (!send_packet(p))
170 DEBUG(0,("send_netbios_packet: send_packet() to IP %s port %d failed\n",
171 inet_ntoa(p->ip),p->port));
178 /***************************************************************************
179 Sets up the common elements of an outgoing NetBIOS packet.
181 Note: do not attempt to rationalise whether rec_des should be set or not
182 in a particular situation. Just follow rfc_1002 or look at examples from WinXX.
183 It does NOT follow the rule that requests to the wins server always have
184 rec_des true. See for example name releases and refreshes
185 **************************************************************************/
187 static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmbname,
188 BOOL bcast, BOOL rec_des,
189 struct in_addr to_ip)
191 struct packet_struct *packet = NULL;
192 struct nmb_packet *nmb = NULL;
194 /* Allocate the packet_struct we will return. */
195 if((packet = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
197 DEBUG(0,("create_and_init_netbios_packet: malloc fail (1) for packet struct.\n"));
201 memset((char *)packet,'\0',sizeof(*packet));
203 nmb = &packet->packet.nmb;
205 nmb->header.name_trn_id = generate_name_trn_id();
206 nmb->header.response = False;
207 nmb->header.nm_flags.recursion_desired = rec_des;
208 nmb->header.nm_flags.recursion_available = False;
209 nmb->header.nm_flags.trunc = False;
210 nmb->header.nm_flags.authoritative = False;
211 nmb->header.nm_flags.bcast = bcast;
213 nmb->header.rcode = 0;
214 nmb->header.qdcount = 1;
215 nmb->header.ancount = 0;
216 nmb->header.nscount = 0;
218 nmb->question.question_name = *nmbname;
219 nmb->question.question_type = QUESTION_TYPE_NB_QUERY;
220 nmb->question.question_class = QUESTION_CLASS_IN;
223 packet->port = NMB_PORT;
224 packet->fd = ClientNMB;
225 packet->timestamp = time(NULL);
226 packet->packet_type = NMB_PACKET;
227 packet->locked = False;
229 return packet; /* Caller must free. */
232 /***************************************************************************
233 Sets up the common elements of register, refresh or release packet.
234 **************************************************************************/
236 static BOOL create_and_init_additional_record(struct packet_struct *packet,
238 struct in_addr *register_ip)
240 struct nmb_packet *nmb = &packet->packet.nmb;
242 if((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) {
243 DEBUG(0,("initiate_name_register_packet: malloc fail for additional record.\n"));
247 memset((char *)nmb->additional,'\0',sizeof(struct res_rec));
249 nmb->additional->rr_name = nmb->question.question_name;
250 nmb->additional->rr_type = RR_TYPE_NB;
251 nmb->additional->rr_class = RR_CLASS_IN;
253 /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
254 if (nmb->header.nm_flags.bcast)
255 nmb->additional->ttl = PERMANENT_TTL;
257 nmb->additional->ttl = lp_max_ttl();
259 nmb->additional->rdlength = 6;
261 set_nb_flags(nmb->additional->rdata,nb_flags);
263 /* Set the address for the name we are registering. */
264 putip(&nmb->additional->rdata[2], register_ip);
267 it turns out that Jeremys code was correct, we are supposed
268 to send registrations from the IP we are registering. The
269 trick is what to do on timeouts! When we send on a
270 non-routable IP then the reply will timeout, and we should
271 treat this as success, not failure. That means we go into
272 our standard refresh cycle for that name which copes nicely
273 with disconnected networks.
275 packet->fd = find_subnet_fd_for_address(*register_ip);
280 /***************************************************************************
281 Sends out a name query.
282 **************************************************************************/
284 static BOOL initiate_name_query_packet( struct packet_struct *packet)
286 struct nmb_packet *nmb = NULL;
288 nmb = &packet->packet.nmb;
290 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
291 nmb->header.arcount = 0;
293 nmb->header.nm_flags.recursion_desired = True;
295 DEBUG(4,("initiate_name_query_packet: sending query for name %s (bcast=%s) to IP %s\n",
296 nmb_namestr(&nmb->question.question_name),
297 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
299 return send_netbios_packet( packet );
302 /***************************************************************************
303 Sends out a name query - from a WINS server.
304 **************************************************************************/
306 static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
308 struct nmb_packet *nmb = NULL;
310 nmb = &packet->packet.nmb;
312 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
313 nmb->header.arcount = 0;
315 nmb->header.nm_flags.recursion_desired = False;
317 DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
318 nmb_namestr(&nmb->question.question_name),
319 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
321 return send_netbios_packet( packet );
324 /***************************************************************************
325 Sends out a name register.
326 **************************************************************************/
328 static BOOL initiate_name_register_packet( struct packet_struct *packet,
329 uint16 nb_flags, struct in_addr *register_ip)
331 struct nmb_packet *nmb = &packet->packet.nmb;
333 nmb->header.opcode = NMB_NAME_REG_OPCODE;
334 nmb->header.arcount = 1;
336 nmb->header.nm_flags.recursion_desired = True;
338 if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
341 DEBUG(4,("initiate_name_register_packet: sending registration for name %s (bcast=%s) to IP %s\n",
342 nmb_namestr(&nmb->additional->rr_name),
343 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
345 return send_netbios_packet( packet );
348 /***************************************************************************
349 Sends out a multihomed name register.
350 **************************************************************************/
352 static BOOL initiate_multihomed_name_register_packet(struct packet_struct *packet,
353 uint16 nb_flags, struct in_addr *register_ip)
355 struct nmb_packet *nmb = &packet->packet.nmb;
356 fstring second_ip_buf;
358 fstrcpy(second_ip_buf, inet_ntoa(packet->ip));
360 nmb->header.opcode = NMB_NAME_MULTIHOMED_REG_OPCODE;
361 nmb->header.arcount = 1;
363 nmb->header.nm_flags.recursion_desired = True;
365 if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
368 DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
369 for name %s IP %s (bcast=%s) to IP %s\n",
370 nmb_namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
371 BOOLSTR(nmb->header.nm_flags.bcast), second_ip_buf ));
373 return send_netbios_packet( packet );
376 /***************************************************************************
377 Sends out a name refresh.
378 **************************************************************************/
380 static BOOL initiate_name_refresh_packet( struct packet_struct *packet,
381 uint16 nb_flags, struct in_addr *refresh_ip)
383 struct nmb_packet *nmb = &packet->packet.nmb;
385 nmb->header.opcode = NMB_NAME_REFRESH_OPCODE_8;
386 nmb->header.arcount = 1;
388 nmb->header.nm_flags.recursion_desired = False;
390 if(create_and_init_additional_record(packet, nb_flags, refresh_ip) == False)
393 DEBUG(4,("initiate_name_refresh_packet: sending refresh for name %s (bcast=%s) to IP %s\n",
394 nmb_namestr(&nmb->additional->rr_name),
395 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
397 return send_netbios_packet( packet );
400 /***************************************************************************
401 Sends out a name release.
402 **************************************************************************/
404 static BOOL initiate_name_release_packet( struct packet_struct *packet,
405 uint16 nb_flags, struct in_addr *release_ip)
407 struct nmb_packet *nmb = &packet->packet.nmb;
409 nmb->header.opcode = NMB_NAME_RELEASE_OPCODE;
410 nmb->header.arcount = 1;
412 nmb->header.nm_flags.recursion_desired = False;
414 if(create_and_init_additional_record(packet, nb_flags, release_ip) == False)
417 DEBUG(4,("initiate_name_release_packet: sending release for name %s (bcast=%s) to IP %s\n",
418 nmb_namestr(&nmb->additional->rr_name),
419 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
421 return send_netbios_packet( packet );
424 /***************************************************************************
425 Sends out a node status.
426 **************************************************************************/
428 static BOOL initiate_node_status_packet( struct packet_struct *packet )
430 struct nmb_packet *nmb = &packet->packet.nmb;
432 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
433 nmb->header.arcount = 0;
435 nmb->header.nm_flags.recursion_desired = False;
437 nmb->question.question_type = QUESTION_TYPE_NB_STATUS;
439 DEBUG(4,("initiate_node_status_packet: sending node status request for name %s to IP %s\n",
440 nmb_namestr(&nmb->question.question_name),
441 inet_ntoa(packet->ip)));
443 return send_netbios_packet( packet );
446 /****************************************************************************
447 Simplification functions for queuing standard packets.
448 These should be the only publicly callable functions for sending
450 ****************************************************************************/
452 /****************************************************************************
453 Assertion - we should never be sending nmbd packets on the remote
455 ****************************************************************************/
457 static BOOL assert_check_subnet(struct subnet_record *subrec)
459 if( subrec == remote_broadcast_subnet)
461 DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
468 /****************************************************************************
469 Queue a register name packet to the broadcast address of a subnet.
470 ****************************************************************************/
472 struct response_record *queue_register_name( struct subnet_record *subrec,
473 response_function resp_fn,
474 timeout_response_function timeout_fn,
475 register_name_success_function success_fn,
476 register_name_fail_function fail_fn,
477 struct userdata_struct *userdata,
478 struct nmb_name *nmbname,
481 struct packet_struct *p;
482 struct response_record *rrec;
484 if(assert_check_subnet(subrec))
487 /* note that all name registration requests have RD set (rfc1002 -
489 if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), True,
490 subrec->bcast_ip)) == NULL)
493 if(initiate_name_register_packet( p, nb_flags,
494 iface_ip(subrec->bcast_ip)) == False)
501 if((rrec = make_response_record(subrec, /* subnet record. */
502 p, /* packet we sent. */
503 resp_fn, /* function to call on response. */
504 timeout_fn, /* function to call on timeout. */
505 (success_function)success_fn, /* function to call on operation success. */
506 (fail_function)fail_fn, /* function to call on operation fail. */
518 /****************************************************************************
519 Queue a refresh name packet to the broadcast address of a subnet.
520 ****************************************************************************/
521 void queue_wins_refresh(struct nmb_name *nmbname,
522 response_function resp_fn,
523 timeout_response_function timeout_fn,
525 struct in_addr refresh_ip,
528 struct packet_struct *p;
529 struct response_record *rrec;
530 struct in_addr wins_ip;
531 struct userdata_struct *userdata;
534 wins_ip = wins_srv_ip_tag(tag, refresh_ip);
536 if ((p = create_and_init_netbios_packet(nmbname, False, False, wins_ip)) == NULL) {
540 if (!initiate_name_refresh_packet(p, nb_flags, &refresh_ip)) {
546 fstrcpy(ip_str, inet_ntoa(refresh_ip));
548 DEBUG(6,("Refreshing name %s IP %s with WINS server %s using tag '%s'\n",
549 nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
551 userdata = (struct userdata_struct *)malloc(sizeof(*userdata) + strlen(tag) + 1);
553 DEBUG(0,("Failed to allocate userdata structure!\n"));
556 ZERO_STRUCTP(userdata);
557 userdata->userdata_len = strlen(tag) + 1;
558 strlcpy(userdata->data, tag, userdata->userdata_len);
560 if ((rrec = make_response_record(unicast_subnet,
565 userdata)) == NULL) {
573 /* we don't want to repeat refresh packets */
574 rrec->repeat_count = 0;
578 /****************************************************************************
579 Queue a multihomed register name packet to a given WINS server IP
580 ****************************************************************************/
582 struct response_record *queue_register_multihomed_name( struct subnet_record *subrec,
583 response_function resp_fn,
584 timeout_response_function timeout_fn,
585 register_name_success_function success_fn,
586 register_name_fail_function fail_fn,
587 struct userdata_struct *userdata,
588 struct nmb_name *nmbname,
590 struct in_addr register_ip,
591 struct in_addr wins_ip)
593 struct packet_struct *p;
594 struct response_record *rrec;
598 if(subrec != unicast_subnet) {
599 DEBUG(0,("queue_register_multihomed_name: should only be done on \
600 unicast subnet. subnet is %s\n.", subrec->subnet_name ));
604 if(assert_check_subnet(subrec))
607 if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL)
610 if (nb_flags & NB_GROUP)
611 ret = initiate_name_register_packet( p, nb_flags, ®ister_ip);
613 ret = initiate_multihomed_name_register_packet(p, nb_flags, ®ister_ip);
621 if ((rrec = make_response_record(subrec, /* subnet record. */
622 p, /* packet we sent. */
623 resp_fn, /* function to call on response. */
624 timeout_fn, /* function to call on timeout. */
625 (success_function)success_fn, /* function to call on operation success. */
626 (fail_function)fail_fn, /* function to call on operation fail. */
627 userdata)) == NULL) {
636 /****************************************************************************
637 Queue a release name packet to the broadcast address of a subnet.
638 ****************************************************************************/
640 struct response_record *queue_release_name( struct subnet_record *subrec,
641 response_function resp_fn,
642 timeout_response_function timeout_fn,
643 release_name_success_function success_fn,
644 release_name_fail_function fail_fn,
645 struct userdata_struct *userdata,
646 struct nmb_name *nmbname,
648 struct in_addr release_ip,
649 struct in_addr dest_ip)
651 struct packet_struct *p;
652 struct response_record *rrec;
654 if(assert_check_subnet(subrec))
657 if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False,
661 if(initiate_name_release_packet( p, nb_flags, &release_ip) == False)
668 if((rrec = make_response_record(subrec, /* subnet record. */
669 p, /* packet we sent. */
670 resp_fn, /* function to call on response. */
671 timeout_fn, /* function to call on timeout. */
672 (success_function)success_fn, /* function to call on operation success. */
673 (fail_function)fail_fn, /* function to call on operation fail. */
682 * For a broadcast release packet, only send once.
683 * This will cause us to remove the name asap. JRA.
686 if (subrec != unicast_subnet) {
687 rrec->repeat_count = 0;
688 rrec->repeat_time = 0;
694 /****************************************************************************
695 Queue a query name packet to the broadcast address of a subnet.
696 ****************************************************************************/
698 struct response_record *queue_query_name( struct subnet_record *subrec,
699 response_function resp_fn,
700 timeout_response_function timeout_fn,
701 query_name_success_function success_fn,
702 query_name_fail_function fail_fn,
703 struct userdata_struct *userdata,
704 struct nmb_name *nmbname)
706 struct packet_struct *p;
707 struct response_record *rrec;
708 struct in_addr to_ip;
710 if(assert_check_subnet(subrec))
713 to_ip = subrec->bcast_ip;
715 /* queries to the WINS server turn up here as queries to IP 0.0.0.0
716 These need to be handled a bit differently */
717 if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
718 /* what we really need to do is loop over each of our wins
719 * servers and wins server tags here, but that just doesn't
720 * fit our architecture at the moment (userdata may already
721 * be used when we get here). For now we just query the first
722 * active wins server on the first tag. */
723 char **tags = wins_srv_tags();
727 to_ip = wins_srv_ip_tag(tags[0], to_ip);
728 wins_srv_tags_free(tags);
731 if(( p = create_and_init_netbios_packet(nmbname,
732 (subrec != unicast_subnet),
733 (subrec == unicast_subnet),
737 if(lp_bind_interfaces_only()) {
740 DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
741 for(i = 0; i < iface_count(); i++) {
742 struct in_addr *ifip = iface_n_ip(i);
745 DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
749 if (ip_equal(*ifip,loopback_ip)) {
750 DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
754 DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
755 p->fd = find_subnet_fd_for_address( *ifip );
760 if(initiate_name_query_packet( p ) == False) {
766 if((rrec = make_response_record(subrec, /* subnet record. */
767 p, /* packet we sent. */
768 resp_fn, /* function to call on response. */
769 timeout_fn, /* function to call on timeout. */
770 (success_function)success_fn, /* function to call on operation success. */
771 (fail_function)fail_fn, /* function to call on operation fail. */
782 /****************************************************************************
783 Queue a query name packet to a given address from the WINS subnet.
784 ****************************************************************************/
786 struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
787 response_function resp_fn,
788 timeout_response_function timeout_fn,
789 query_name_success_function success_fn,
790 query_name_fail_function fail_fn,
791 struct userdata_struct *userdata,
792 struct nmb_name *nmbname)
794 struct packet_struct *p;
795 struct response_record *rrec;
797 if ((p = create_and_init_netbios_packet(nmbname, False, False, to_ip)) == NULL)
800 if(initiate_name_query_packet_from_wins_server( p ) == False)
807 if((rrec = make_response_record(wins_server_subnet, /* subnet record. */
808 p, /* packet we sent. */
809 resp_fn, /* function to call on response. */
810 timeout_fn, /* function to call on timeout. */
811 (success_function)success_fn, /* function to call on operation success. */
812 (fail_function)fail_fn, /* function to call on operation fail. */
823 /****************************************************************************
824 Queue a node status packet to a given name and address.
825 ****************************************************************************/
827 struct response_record *queue_node_status( struct subnet_record *subrec,
828 response_function resp_fn,
829 timeout_response_function timeout_fn,
830 node_status_success_function success_fn,
831 node_status_fail_function fail_fn,
832 struct userdata_struct *userdata,
833 struct nmb_name *nmbname,
834 struct in_addr send_ip)
836 struct packet_struct *p;
837 struct response_record *rrec;
840 if(subrec != unicast_subnet)
842 DEBUG(0,("queue_register_multihomed_name: should only be done on \
843 unicast subnet. subnet is %s\n.", subrec->subnet_name ));
847 if(assert_check_subnet(subrec))
850 if(( p = create_and_init_netbios_packet(nmbname, False, False,
854 if(initiate_node_status_packet(p) == False)
861 if((rrec = make_response_record(subrec, /* subnet record. */
862 p, /* packet we sent. */
863 resp_fn, /* function to call on response. */
864 timeout_fn, /* function to call on timeout. */
865 (success_function)success_fn, /* function to call on operation success. */
866 (fail_function)fail_fn, /* function to call on operation fail. */
877 /****************************************************************************
878 Reply to a netbios name packet. see rfc1002.txt
879 ****************************************************************************/
881 void reply_netbios_packet(struct packet_struct *orig_packet,
882 int rcode, enum netbios_reply_type_code rcv_code, int opcode,
883 int ttl, char *data,int len)
885 struct packet_struct packet;
886 struct nmb_packet *nmb = NULL;
887 struct res_rec answers;
888 struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
889 BOOL loopback_this_packet = False;
890 const char *packet_type = "unknown";
892 /* Check if we are sending to or from ourselves. */
893 if(ismyip(orig_packet->ip) && (orig_packet->port == global_nmb_port))
894 loopback_this_packet = True;
896 nmb = &packet.packet.nmb;
898 /* Do a partial copy of the packet. We clear the locked flag and
899 the resource record pointers. */
900 packet = *orig_packet; /* Full structure copy. */
901 packet.locked = False;
904 nmb->additional = NULL;
910 packet_type = "nmb_status";
911 nmb->header.nm_flags.recursion_desired = False;
912 nmb->header.nm_flags.recursion_available = False;
917 packet_type = "nmb_query";
918 nmb->header.nm_flags.recursion_desired = True;
919 nmb->header.nm_flags.recursion_available = True;
923 case NMB_REG_REFRESH:
925 packet_type = "nmb_reg";
926 nmb->header.nm_flags.recursion_desired = True;
927 nmb->header.nm_flags.recursion_available = True;
932 packet_type = "nmb_rel";
933 nmb->header.nm_flags.recursion_desired = False;
934 nmb->header.nm_flags.recursion_available = False;
939 packet_type = "nmb_wack";
940 nmb->header.nm_flags.recursion_desired = False;
941 nmb->header.nm_flags.recursion_available = False;
946 packet_type = "wins_reg";
947 nmb->header.nm_flags.recursion_desired = True;
948 nmb->header.nm_flags.recursion_available = True;
953 packet_type = "wins_query";
954 nmb->header.nm_flags.recursion_desired = True;
955 nmb->header.nm_flags.recursion_available = True;
961 DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
962 packet_type, nmb_namestr(&orig_nmb->question.question_name),
963 inet_ntoa(packet.ip)));
969 DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
971 packet_type, nmb_namestr(&orig_nmb->question.question_name),
972 inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
974 nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
975 nmb->header.opcode = opcode;
976 nmb->header.response = True;
977 nmb->header.nm_flags.bcast = False;
978 nmb->header.nm_flags.trunc = False;
979 nmb->header.nm_flags.authoritative = True;
981 nmb->header.rcode = rcode;
982 nmb->header.qdcount = 0;
983 nmb->header.ancount = 1;
984 nmb->header.nscount = 0;
985 nmb->header.arcount = 0;
987 memset((char*)&nmb->question,'\0',sizeof(nmb->question));
989 nmb->answers = &answers;
990 memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
992 nmb->answers->rr_name = orig_nmb->question.question_name;
993 nmb->answers->rr_type = orig_nmb->question.question_type;
994 nmb->answers->rr_class = orig_nmb->question.question_class;
995 nmb->answers->ttl = ttl;
999 nmb->answers->rdlength = len;
1000 memcpy(nmb->answers->rdata, data, len);
1003 packet.packet_type = NMB_PACKET;
1004 /* Ensure we send out on the same fd that the original
1005 packet came in on to give the correct source IP address. */
1006 packet.fd = orig_packet->fd;
1007 packet.timestamp = time(NULL);
1009 debug_nmb_packet(&packet);
1011 if(loopback_this_packet)
1013 struct packet_struct *lo_packet;
1014 DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
1015 if((lo_packet = copy_packet(&packet)) == NULL)
1017 queue_packet(lo_packet);
1019 else if (!send_packet(&packet))
1021 DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
1022 inet_ntoa(packet.ip),packet.port));
1026 /*******************************************************************
1027 Queue a packet into a packet queue
1028 ******************************************************************/
1029 static void queue_packet(struct packet_struct *packet)
1031 struct packet_struct *p;
1035 packet->prev = NULL;
1036 packet->next = NULL;
1037 packet_queue = packet;
1041 /* find the bottom */
1042 for (p=packet_queue;p->next;p=p->next)
1046 packet->next = NULL;
1050 /****************************************************************************
1051 Try and find a matching subnet record for a datagram port 138 packet.
1052 ****************************************************************************/
1054 static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_struct *p)
1056 struct subnet_record *subrec;
1058 /* Go through all the broadcast subnets and see if the mask matches. */
1059 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1061 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1065 /* If the subnet record is the remote announce broadcast subnet,
1066 hack it here to be the first subnet. This is really gross and
1067 is needed due to people turning on port 137/138 broadcast
1068 forwarding on their routers. May fire and brimstone rain
1072 return FIRST_SUBNET;
1075 /****************************************************************************
1076 Dispatch a browse frame from port 138 to the correct processing function.
1077 ****************************************************************************/
1078 static void process_browse_packet(struct packet_struct *p, char *buf,int len)
1080 struct dgram_packet *dgram = &p->packet.dgram;
1081 int command = CVAL(buf,0);
1082 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1084 /* Drop the packet if it's a different NetBIOS scope, or
1085 the source is from one of our names. */
1087 if (!strequal(dgram->dest_name.scope, global_scope()))
1089 DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
1090 mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, global_scope()));
1094 if (is_myname(dgram->source_name.name))
1096 DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
1097 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1103 case ANN_HostAnnouncement:
1105 debug_browse_data(buf, len);
1106 process_host_announce(subrec, p, buf+1);
1109 case ANN_DomainAnnouncement:
1111 debug_browse_data(buf, len);
1112 process_workgroup_announce(subrec, p, buf+1);
1115 case ANN_LocalMasterAnnouncement:
1117 debug_browse_data(buf, len);
1118 process_local_master_announce(subrec, p, buf+1);
1121 case ANN_AnnouncementRequest:
1123 debug_browse_data(buf, len);
1124 process_announce_request(subrec, p, buf+1);
1129 debug_browse_data(buf, len);
1130 process_election(subrec, p, buf+1);
1133 case ANN_GetBackupListReq:
1135 debug_browse_data(buf, len);
1136 process_get_backup_list_request(subrec, p, buf+1);
1139 case ANN_GetBackupListResp:
1141 debug_browse_data(buf, len);
1142 /* We never send ANN_GetBackupListReq so we
1143 should never get these. */
1144 DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
1145 packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
1148 case ANN_ResetBrowserState:
1150 debug_browse_data(buf, len);
1151 process_reset_browser(subrec, p, buf+1);
1154 case ANN_MasterAnnouncement:
1156 /* Master browser datagrams must be processed
1157 on the unicast subnet. */
1158 subrec = unicast_subnet;
1160 debug_browse_data(buf, len);
1161 process_master_browser_announce(subrec, p, buf+1);
1164 case ANN_BecomeBackup:
1167 * We don't currently implement this. Log it just in case.
1169 debug_browse_data(buf, len);
1170 DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
1171 command ANN_BecomeBackup from %s IP %s to %s\n",
1172 subrec->subnet_name, nmb_namestr(&dgram->source_name),
1173 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1178 debug_browse_data(buf, len);
1179 DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
1180 command code %d from %s IP %s to %s\n",
1181 subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1182 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1187 /****************************************************************************
1188 Dispatch a LanMan browse frame from port 138 to the correct processing function.
1189 ****************************************************************************/
1190 static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
1192 struct dgram_packet *dgram = &p->packet.dgram;
1193 int command = SVAL(buf,0);
1194 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1196 /* Drop the packet if it's a different NetBIOS scope, or
1197 the source is from one of our names. */
1199 if (!strequal(dgram->dest_name.scope, global_scope()))
1201 DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
1202 mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, global_scope()));
1206 if (is_myname(dgram->source_name.name))
1208 DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
1209 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1215 case ANN_HostAnnouncement:
1217 debug_browse_data(buf, len);
1218 process_lm_host_announce(subrec, p, buf+1);
1221 case ANN_AnnouncementRequest:
1223 process_lm_announce_request(subrec, p, buf+1);
1228 DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
1229 command code %d from %s IP %s to %s\n",
1230 subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1231 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1236 /****************************************************************************
1237 Determine if a packet is for us on port 138. Note that to have any chance of
1238 being efficient we need to drop as many packets as possible at this
1239 stage as subsequent processing is expensive.
1240 ****************************************************************************/
1242 static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
1244 struct subnet_record *subrec = NULL;
1246 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1248 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1253 subrec = unicast_subnet;
1255 return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
1258 /****************************************************************************
1259 Process udp 138 datagrams
1260 ****************************************************************************/
1261 static void process_dgram(struct packet_struct *p)
1266 struct dgram_packet *dgram = &p->packet.dgram;
1268 /* If we aren't listening to the destination name then ignore the packet */
1269 if (!listening(p,&dgram->dest_name))
1271 unexpected_packet(p);
1272 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
1273 nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
1277 if (dgram->header.msg_type != 0x10 &&
1278 dgram->header.msg_type != 0x11 &&
1279 dgram->header.msg_type != 0x12)
1281 unexpected_packet(p);
1282 /* Don't process error packets etc yet */
1283 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
1284 an error packet of type %x\n",
1285 nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
1289 buf = &dgram->data[0];
1290 buf -= 4; /* XXXX for the pseudo tcp length -
1291 someday I need to get rid of this */
1293 if (CVAL(buf,smb_com) != SMBtrans)
1296 len = SVAL(buf,smb_vwv11);
1297 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1302 if (buf2 + len > buf + sizeof(dgram->data)) {
1303 DEBUG(2,("process_dgram: datagram from %s to %s IP %s for %s len=%d too long.\n",
1304 nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
1305 inet_ntoa(p->ip), smb_buf(buf),len));
1306 len = (buf + sizeof(dgram->data)) - buf;
1309 DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
1310 nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
1311 inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
1314 /* Datagram packet received for the browser mailslot */
1315 if (strequal(smb_buf(buf),BROWSE_MAILSLOT))
1317 process_browse_packet(p,buf2,len);
1321 /* Datagram packet received for the LAN Manager mailslot */
1322 if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
1323 process_lanman_packet(p,buf2,len);
1327 /* Datagram packet received for the domain logon mailslot */
1328 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT))
1330 process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
1334 /* Datagram packet received for the NT domain logon mailslot */
1335 if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT))
1337 process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
1341 unexpected_packet(p);
1344 /****************************************************************************
1345 Validate a response nmb packet.
1346 ****************************************************************************/
1348 static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
1350 BOOL ignore = False;
1352 switch (nmb->header.opcode)
1354 case NMB_NAME_REG_OPCODE:
1355 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1356 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1357 if (nmb->header.ancount == 0)
1359 DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
1364 case NMB_NAME_QUERY_OPCODE:
1365 if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1))
1367 DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
1371 case NMB_NAME_RELEASE_OPCODE:
1372 if (nmb->header.ancount == 0)
1374 DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
1378 case NMB_WACK_OPCODE:
1379 /* Check WACK response here. */
1380 if (nmb->header.ancount != 1)
1382 DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
1387 DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
1388 nmb->header.opcode));
1393 DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
1398 /****************************************************************************
1399 Validate a request nmb packet.
1400 ****************************************************************************/
1402 static BOOL validate_nmb_packet( struct nmb_packet *nmb )
1404 BOOL ignore = False;
1406 switch (nmb->header.opcode)
1408 case NMB_NAME_REG_OPCODE:
1409 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1410 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1411 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1412 if (nmb->header.qdcount==0 || nmb->header.arcount==0)
1414 DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
1419 case NMB_NAME_QUERY_OPCODE:
1420 if ((nmb->header.qdcount == 0) ||
1421 ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
1422 (nmb->question.question_type != QUESTION_TYPE_NB_STATUS)))
1424 DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
1429 case NMB_NAME_RELEASE_OPCODE:
1430 if (nmb->header.qdcount==0 || nmb->header.arcount==0)
1432 DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
1437 DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
1438 nmb->header.opcode));
1443 DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
1448 /****************************************************************************
1449 Find a subnet (and potentially a response record) for a packet.
1450 ****************************************************************************/
1452 static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,
1453 struct response_record **pprrec)
1455 struct nmb_packet *nmb = &p->packet.nmb;
1456 struct response_record *rrec = NULL;
1457 struct subnet_record *subrec = NULL;
1462 if(nmb->header.response)
1464 /* It's a response packet. Find a record for it or it's an error. */
1466 rrec = find_response_record( &subrec, nmb->header.name_trn_id);
1469 DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
1470 nmb->header.name_trn_id));
1471 unexpected_packet(p);
1477 DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
1478 nmb->header.name_trn_id));
1487 /* Try and see what subnet this packet belongs to. */
1490 if(packet_is_for_wins_server(p))
1491 return wins_server_subnet;
1493 /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
1494 if(nmb->header.nm_flags.bcast == False)
1495 return unicast_subnet;
1497 /* Go through all the broadcast subnets and see if the mask matches. */
1498 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1500 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1504 /* If none match it must have been a directed broadcast - assign
1505 the remote_broadcast_subnet. */
1506 return remote_broadcast_subnet;
1509 /****************************************************************************
1510 Process a nmb request packet - validate the packet and route it.
1511 ****************************************************************************/
1513 static void process_nmb_request(struct packet_struct *p)
1515 struct nmb_packet *nmb = &p->packet.nmb;
1516 struct subnet_record *subrec = NULL;
1518 debug_nmb_packet(p);
1520 /* Ensure we have a good packet. */
1521 if(validate_nmb_packet(nmb))
1524 /* Allocate a subnet to this packet - if we cannot - fail. */
1525 if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
1528 switch (nmb->header.opcode)
1530 case NMB_NAME_REG_OPCODE:
1531 if(subrec == wins_server_subnet)
1532 wins_process_name_registration_request(subrec, p);
1534 process_name_registration_request(subrec, p);
1537 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1538 case NMB_NAME_REFRESH_OPCODE_9:
1539 if(subrec == wins_server_subnet)
1540 wins_process_name_refresh_request(subrec, p);
1542 process_name_refresh_request(subrec, p);
1545 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1546 if(subrec == wins_server_subnet)
1547 wins_process_multihomed_name_registration_request(subrec, p);
1550 DEBUG(0,("process_nmb_request: Multihomed registration request must be \
1551 directed at a WINS server.\n"));
1555 case NMB_NAME_QUERY_OPCODE:
1556 switch (nmb->question.question_type)
1558 case QUESTION_TYPE_NB_QUERY:
1560 if(subrec == wins_server_subnet)
1561 wins_process_name_query_request(subrec, p);
1563 process_name_query_request(subrec, p);
1566 case QUESTION_TYPE_NB_STATUS:
1568 if(subrec == wins_server_subnet)
1570 DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
1575 process_node_status_request(subrec, p);
1581 case NMB_NAME_RELEASE_OPCODE:
1582 if(subrec == wins_server_subnet)
1583 wins_process_name_release_request(subrec, p);
1585 process_name_release_request(subrec, p);
1590 /****************************************************************************
1591 Process a nmb response packet - validate the packet and route it.
1592 to either the WINS server or a normal response.
1593 ****************************************************************************/
1595 static void process_nmb_response(struct packet_struct *p)
1597 struct nmb_packet *nmb = &p->packet.nmb;
1598 struct subnet_record *subrec = NULL;
1599 struct response_record *rrec = NULL;
1601 debug_nmb_packet(p);
1603 if(validate_nmb_response_packet(nmb))
1606 if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
1611 DEBUG(0,("process_nmb_response: response packet received but no response record \
1612 found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));
1616 /* Increment the number of responses received for this record. */
1618 /* Ensure we don't re-send the request. */
1619 rrec->repeat_count = 0;
1621 /* Call the response received function for this packet. */
1622 (*rrec->resp_fn)(subrec, rrec, p);
1626 /*******************************************************************
1627 Run elements off the packet queue till its empty
1628 ******************************************************************/
1630 void run_packet_queue(void)
1632 struct packet_struct *p;
1634 while ((p = packet_queue))
1636 packet_queue = p->next;
1638 packet_queue->prev = NULL;
1639 p->next = p->prev = NULL;
1641 switch (p->packet_type)
1644 if(p->packet.nmb.header.response)
1645 process_nmb_response(p);
1647 process_nmb_request(p);
1658 /*******************************************************************
1659 Retransmit or timeout elements from all the outgoing subnet response
1660 record queues. NOTE that this code must also check the WINS server
1661 subnet for response records to timeout as the WINS server code
1662 can send requests to check if a client still owns a name.
1663 (Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>).
1664 ******************************************************************/
1666 void retransmit_or_expire_response_records(time_t t)
1668 struct subnet_record *subrec;
1670 for (subrec = FIRST_SUBNET; subrec;
1671 subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec))
1673 struct response_record *rrec, *nextrrec;
1675 for (rrec = subrec->responselist; rrec; rrec = nextrrec)
1677 nextrrec = rrec->next;
1679 if (rrec->repeat_time <= t)
1681 if (rrec->repeat_count > 0)
1683 /* Resend while we have a non-zero repeat_count. */
1684 if(!send_packet(rrec->packet))
1686 DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
1687 to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
1688 subrec->subnet_name));
1690 rrec->repeat_time = t + rrec->repeat_interval;
1691 rrec->repeat_count--;
1695 DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
1696 on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
1697 subrec->subnet_name));
1700 * Check the flag in this record to prevent recursion if we end
1701 * up in this function again via the timeout function call.
1704 if(!rrec->in_expiration_processing)
1708 * Set the recursion protection flag in this record.
1711 rrec->in_expiration_processing = True;
1713 /* Call the timeout function. This will deal with removing the
1714 timed out packet. */
1715 if(rrec->timeout_fn)
1716 (*rrec->timeout_fn)(subrec, rrec);
1719 /* We must remove the record ourself if there is
1720 no timeout function. */
1721 remove_response_record(subrec, rrec);
1723 } /* !rrec->in_expitation_processing */
1724 } /* rrec->repeat_count > 0 */
1725 } /* rrec->repeat_time <= t */
1726 } /* end for rrec */
1727 } /* end for subnet */
1730 /****************************************************************************
1731 Create an fd_set containing all the sockets in the subnet structures,
1732 plus the broadcast sockets.
1733 ***************************************************************************/
1735 static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number)
1737 int *sock_array = NULL;
1738 struct subnet_record *subrec = NULL;
1741 fd_set *pset = (fd_set *)malloc(sizeof(fd_set));
1745 DEBUG(0,("create_listen_fdset: malloc fail !\n"));
1749 /* Check that we can add all the fd's we need. */
1750 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1753 if((count*2) + 2 > FD_SETSIZE)
1755 DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
1756 only use %d.\n", (count*2) + 2, FD_SETSIZE));
1760 if((sock_array = (int *)malloc(((count*2) + 2)*sizeof(int))) == NULL)
1762 DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
1768 /* Add in the broadcast socket on 137. */
1769 FD_SET(ClientNMB,pset);
1770 sock_array[num++] = ClientNMB;
1772 /* Add in the 137 sockets on all the interfaces. */
1773 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1775 FD_SET(subrec->nmb_sock,pset);
1776 sock_array[num++] = subrec->nmb_sock;
1779 /* Add in the broadcast socket on 138. */
1780 FD_SET(ClientDGRAM,pset);
1781 sock_array[num++] = ClientDGRAM;
1783 /* Add in the 138 sockets on all the interfaces. */
1784 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1786 FD_SET(subrec->dgram_sock,pset);
1787 sock_array[num++] = subrec->dgram_sock;
1790 *listen_number = (count*2) + 2;
1793 SAFE_FREE(*psock_array);
1796 *psock_array = sock_array;
1801 /****************************************************************************
1802 Listens for NMB or DGRAM packets, and queues them.
1803 return True if the socket is dead
1804 ***************************************************************************/
1806 BOOL listen_for_packets(BOOL run_election)
1808 static fd_set *listen_set = NULL;
1809 static int listen_number = 0;
1810 static int *sock_array = NULL;
1815 struct timeval timeout;
1820 if(listen_set == NULL || rescan_listen_set)
1822 if(create_listen_fdset(&listen_set, &sock_array, &listen_number))
1824 DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
1827 rescan_listen_set = False;
1830 memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
1833 dns_fd = asyncdns_fd();
1835 FD_SET(dns_fd, &fds);
1841 * During elections and when expecting a netbios response packet we
1842 * need to send election packets at tighter intervals.
1843 * Ideally it needs to be the interval (in ms) between time now and
1844 * the time we are expecting the next netbios packet.
1847 timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
1848 timeout.tv_usec = 0;
1850 /* Prepare for the select - allow certain signals. */
1852 BlockSignals(False, SIGTERM);
1854 selrtn = sys_select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
1856 /* We can only take signals when we are in the select - block them again here. */
1858 BlockSignals(True, SIGTERM);
1865 if (dns_fd != -1 && FD_ISSET(dns_fd,&fds)) {
1870 for(i = 0; i < listen_number; i++) {
1871 if (i < (listen_number/2)) {
1872 /* Processing a 137 socket. */
1873 if (FD_ISSET(sock_array[i],&fds)) {
1874 struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
1877 * If we got a packet on the broadcast socket and interfaces
1878 * only is set then check it came from one of our local nets.
1880 if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) &&
1881 (!is_local_net(packet->ip))) {
1882 DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
1883 inet_ntoa(packet->ip),packet->port));
1884 free_packet(packet);
1885 } else if ((ip_equal(loopback_ip, packet->ip) ||
1886 ismyip(packet->ip)) && packet->port == global_nmb_port &&
1887 packet->packet.nmb.header.nm_flags.bcast) {
1888 DEBUG(7,("discarding own bcast packet from %s:%d\n",
1889 inet_ntoa(packet->ip),packet->port));
1890 free_packet(packet);
1892 /* Save the file descriptor this packet came in on. */
1893 packet->fd = sock_array[i];
1894 queue_packet(packet);
1899 /* Processing a 138 socket. */
1900 if (FD_ISSET(sock_array[i],&fds)) {
1901 struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
1904 * If we got a packet on the broadcast socket and interfaces
1905 * only is set then check it came from one of our local nets.
1907 if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) &&
1908 (!is_local_net(packet->ip))) {
1909 DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
1910 inet_ntoa(packet->ip),packet->port));
1911 free_packet(packet);
1912 } else if ((ip_equal(loopback_ip, packet->ip) ||
1913 ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
1914 DEBUG(7,("discarding own dgram packet from %s:%d\n",
1915 inet_ntoa(packet->ip),packet->port));
1916 free_packet(packet);
1918 /* Save the file descriptor this packet came in on. */
1919 packet->fd = sock_array[i];
1920 queue_packet(packet);
1924 } /* end processing 138 socket. */
1929 /****************************************************************************
1930 Construct and send a netbios DGRAM.
1931 **************************************************************************/
1932 BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf,int len,
1933 const char *srcname, int src_type,
1934 const char *dstname, int dest_type,
1935 struct in_addr dest_ip,struct in_addr src_ip,
1938 BOOL loopback_this_packet = False;
1939 struct packet_struct p;
1940 struct dgram_packet *dgram = &p.packet.dgram;
1944 memset((char *)&p,'\0',sizeof(p));
1946 if(ismyip(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
1947 loopback_this_packet = True;
1949 /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
1951 /* DIRECT GROUP or UNIQUE datagram. */
1952 dgram->header.msg_type = unique ? 0x10 : 0x11;
1953 dgram->header.flags.node_type = M_NODE;
1954 dgram->header.flags.first = True;
1955 dgram->header.flags.more = False;
1956 dgram->header.dgm_id = generate_name_trn_id();
1957 dgram->header.source_ip = src_ip;
1958 dgram->header.source_port = DGRAM_PORT;
1959 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1960 dgram->header.packet_offset = 0;
1962 make_nmb_name(&dgram->source_name,srcname,src_type);
1963 make_nmb_name(&dgram->dest_name,dstname,dest_type);
1965 ptr = &dgram->data[0];
1967 /* Setup the smb part. */
1968 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1970 set_message(ptr,17,23 + len,True);
1973 SCVAL(ptr,smb_com,SMBtrans);
1974 SSVAL(ptr,smb_vwv1,len);
1975 SSVAL(ptr,smb_vwv11,len);
1976 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1977 SSVAL(ptr,smb_vwv13,3);
1978 SSVAL(ptr,smb_vwv14,1);
1979 SSVAL(ptr,smb_vwv15,1);
1980 SSVAL(ptr,smb_vwv16,2);
1982 pstrcpy(p2,mailslot);
1983 p2 = skip_string(p2,1);
1988 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1992 p.fd = find_subnet_mailslot_fd_for_address( src_ip );
1993 p.timestamp = time(NULL);
1994 p.packet_type = DGRAM_PACKET;
1996 DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
1997 nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
1998 DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
2000 debug_browse_data(buf, len);
2002 if(loopback_this_packet)
2004 struct packet_struct *lo_packet = NULL;
2005 DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
2006 if((lo_packet = copy_packet(&p)) == NULL)
2008 queue_packet(lo_packet);
2012 return(send_packet(&p));