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 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);
1083 extern pstring global_scope;
1085 /* Drop the packet if it's a different NetBIOS scope, or
1086 the source is from one of our names. */
1088 if (!strequal(dgram->dest_name.scope, global_scope))
1090 DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
1091 mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, global_scope));
1095 if (is_myname(dgram->source_name.name))
1097 DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
1098 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1104 case ANN_HostAnnouncement:
1106 debug_browse_data(buf, len);
1107 process_host_announce(subrec, p, buf+1);
1110 case ANN_DomainAnnouncement:
1112 debug_browse_data(buf, len);
1113 process_workgroup_announce(subrec, p, buf+1);
1116 case ANN_LocalMasterAnnouncement:
1118 debug_browse_data(buf, len);
1119 process_local_master_announce(subrec, p, buf+1);
1122 case ANN_AnnouncementRequest:
1124 debug_browse_data(buf, len);
1125 process_announce_request(subrec, p, buf+1);
1130 debug_browse_data(buf, len);
1131 process_election(subrec, p, buf+1);
1134 case ANN_GetBackupListReq:
1136 debug_browse_data(buf, len);
1137 process_get_backup_list_request(subrec, p, buf+1);
1140 case ANN_GetBackupListResp:
1142 debug_browse_data(buf, len);
1143 /* We never send ANN_GetBackupListReq so we
1144 should never get these. */
1145 DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
1146 packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
1149 case ANN_ResetBrowserState:
1151 debug_browse_data(buf, len);
1152 process_reset_browser(subrec, p, buf+1);
1155 case ANN_MasterAnnouncement:
1157 /* Master browser datagrams must be processed
1158 on the unicast subnet. */
1159 subrec = unicast_subnet;
1161 debug_browse_data(buf, len);
1162 process_master_browser_announce(subrec, p, buf+1);
1165 case ANN_BecomeBackup:
1168 * We don't currently implement this. Log it just in case.
1170 debug_browse_data(buf, len);
1171 DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
1172 command ANN_BecomeBackup from %s IP %s to %s\n",
1173 subrec->subnet_name, nmb_namestr(&dgram->source_name),
1174 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1179 debug_browse_data(buf, len);
1180 DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
1181 command code %d from %s IP %s to %s\n",
1182 subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1183 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1188 /****************************************************************************
1189 Dispatch a LanMan browse frame from port 138 to the correct processing function.
1190 ****************************************************************************/
1191 static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
1193 struct dgram_packet *dgram = &p->packet.dgram;
1194 int command = SVAL(buf,0);
1195 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1196 extern pstring global_scope;
1198 /* Drop the packet if it's a different NetBIOS scope, or
1199 the source is from one of our names. */
1201 if (!strequal(dgram->dest_name.scope, global_scope))
1203 DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
1204 mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, global_scope));
1208 if (is_myname(dgram->source_name.name))
1210 DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
1211 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1217 case ANN_HostAnnouncement:
1219 debug_browse_data(buf, len);
1220 process_lm_host_announce(subrec, p, buf+1);
1223 case ANN_AnnouncementRequest:
1225 process_lm_announce_request(subrec, p, buf+1);
1230 DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
1231 command code %d from %s IP %s to %s\n",
1232 subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1233 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1238 /****************************************************************************
1239 Determine if a packet is for us on port 138. Note that to have any chance of
1240 being efficient we need to drop as many packets as possible at this
1241 stage as subsequent processing is expensive.
1242 ****************************************************************************/
1244 static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
1246 struct subnet_record *subrec = NULL;
1248 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1250 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1255 subrec = unicast_subnet;
1257 return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
1260 /****************************************************************************
1261 Process udp 138 datagrams
1262 ****************************************************************************/
1263 static void process_dgram(struct packet_struct *p)
1268 struct dgram_packet *dgram = &p->packet.dgram;
1270 /* If we aren't listening to the destination name then ignore the packet */
1271 if (!listening(p,&dgram->dest_name))
1273 unexpected_packet(p);
1274 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
1275 nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
1279 if (dgram->header.msg_type != 0x10 &&
1280 dgram->header.msg_type != 0x11 &&
1281 dgram->header.msg_type != 0x12)
1283 unexpected_packet(p);
1284 /* Don't process error packets etc yet */
1285 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
1286 an error packet of type %x\n",
1287 nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
1291 buf = &dgram->data[0];
1292 buf -= 4; /* XXXX for the pseudo tcp length -
1293 someday I need to get rid of this */
1295 if (CVAL(buf,smb_com) != SMBtrans)
1298 len = SVAL(buf,smb_vwv11);
1299 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1304 if (buf2 + len > buf + sizeof(dgram->data)) {
1305 DEBUG(2,("process_dgram: datagram from %s to %s IP %s for %s len=%d too long.\n",
1306 nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
1307 inet_ntoa(p->ip), smb_buf(buf),len));
1308 len = (buf + sizeof(dgram->data)) - buf;
1311 DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
1312 nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
1313 inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
1316 /* Datagram packet received for the browser mailslot */
1317 if (strequal(smb_buf(buf),BROWSE_MAILSLOT))
1319 process_browse_packet(p,buf2,len);
1323 /* Datagram packet received for the LAN Manager mailslot */
1324 if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
1325 process_lanman_packet(p,buf2,len);
1329 /* Datagram packet received for the domain logon mailslot */
1330 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT))
1332 process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
1336 /* Datagram packet received for the NT domain logon mailslot */
1337 if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT))
1339 process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
1343 unexpected_packet(p);
1346 /****************************************************************************
1347 Validate a response nmb packet.
1348 ****************************************************************************/
1350 static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
1352 BOOL ignore = False;
1354 switch (nmb->header.opcode)
1356 case NMB_NAME_REG_OPCODE:
1357 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1358 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1359 if (nmb->header.ancount == 0)
1361 DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
1366 case NMB_NAME_QUERY_OPCODE:
1367 if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1))
1369 DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
1373 case NMB_NAME_RELEASE_OPCODE:
1374 if (nmb->header.ancount == 0)
1376 DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
1380 case NMB_WACK_OPCODE:
1381 /* Check WACK response here. */
1382 if (nmb->header.ancount != 1)
1384 DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
1389 DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
1390 nmb->header.opcode));
1395 DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
1400 /****************************************************************************
1401 Validate a request nmb packet.
1402 ****************************************************************************/
1404 static BOOL validate_nmb_packet( struct nmb_packet *nmb )
1406 BOOL ignore = False;
1408 switch (nmb->header.opcode)
1410 case NMB_NAME_REG_OPCODE:
1411 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1412 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1413 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1414 if (nmb->header.qdcount==0 || nmb->header.arcount==0)
1416 DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
1421 case NMB_NAME_QUERY_OPCODE:
1422 if ((nmb->header.qdcount == 0) ||
1423 ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
1424 (nmb->question.question_type != QUESTION_TYPE_NB_STATUS)))
1426 DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
1431 case NMB_NAME_RELEASE_OPCODE:
1432 if (nmb->header.qdcount==0 || nmb->header.arcount==0)
1434 DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
1439 DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
1440 nmb->header.opcode));
1445 DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
1450 /****************************************************************************
1451 Find a subnet (and potentially a response record) for a packet.
1452 ****************************************************************************/
1454 static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,
1455 struct response_record **pprrec)
1457 struct nmb_packet *nmb = &p->packet.nmb;
1458 struct response_record *rrec = NULL;
1459 struct subnet_record *subrec = NULL;
1464 if(nmb->header.response)
1466 /* It's a response packet. Find a record for it or it's an error. */
1468 rrec = find_response_record( &subrec, nmb->header.name_trn_id);
1471 DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
1472 nmb->header.name_trn_id));
1473 unexpected_packet(p);
1479 DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
1480 nmb->header.name_trn_id));
1489 /* Try and see what subnet this packet belongs to. */
1492 if(packet_is_for_wins_server(p))
1493 return wins_server_subnet;
1495 /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
1496 if(nmb->header.nm_flags.bcast == False)
1497 return unicast_subnet;
1499 /* Go through all the broadcast subnets and see if the mask matches. */
1500 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1502 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1506 /* If none match it must have been a directed broadcast - assign
1507 the remote_broadcast_subnet. */
1508 return remote_broadcast_subnet;
1511 /****************************************************************************
1512 Process a nmb request packet - validate the packet and route it.
1513 ****************************************************************************/
1515 static void process_nmb_request(struct packet_struct *p)
1517 struct nmb_packet *nmb = &p->packet.nmb;
1518 struct subnet_record *subrec = NULL;
1520 debug_nmb_packet(p);
1522 /* Ensure we have a good packet. */
1523 if(validate_nmb_packet(nmb))
1526 /* Allocate a subnet to this packet - if we cannot - fail. */
1527 if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
1530 switch (nmb->header.opcode)
1532 case NMB_NAME_REG_OPCODE:
1533 if(subrec == wins_server_subnet)
1534 wins_process_name_registration_request(subrec, p);
1536 process_name_registration_request(subrec, p);
1539 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1540 case NMB_NAME_REFRESH_OPCODE_9:
1541 if(subrec == wins_server_subnet)
1542 wins_process_name_refresh_request(subrec, p);
1544 process_name_refresh_request(subrec, p);
1547 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1548 if(subrec == wins_server_subnet)
1549 wins_process_multihomed_name_registration_request(subrec, p);
1552 DEBUG(0,("process_nmb_request: Multihomed registration request must be \
1553 directed at a WINS server.\n"));
1557 case NMB_NAME_QUERY_OPCODE:
1558 switch (nmb->question.question_type)
1560 case QUESTION_TYPE_NB_QUERY:
1562 if(subrec == wins_server_subnet)
1563 wins_process_name_query_request(subrec, p);
1565 process_name_query_request(subrec, p);
1568 case QUESTION_TYPE_NB_STATUS:
1570 if(subrec == wins_server_subnet)
1572 DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
1577 process_node_status_request(subrec, p);
1583 case NMB_NAME_RELEASE_OPCODE:
1584 if(subrec == wins_server_subnet)
1585 wins_process_name_release_request(subrec, p);
1587 process_name_release_request(subrec, p);
1592 /****************************************************************************
1593 Process a nmb response packet - validate the packet and route it.
1594 to either the WINS server or a normal response.
1595 ****************************************************************************/
1597 static void process_nmb_response(struct packet_struct *p)
1599 struct nmb_packet *nmb = &p->packet.nmb;
1600 struct subnet_record *subrec = NULL;
1601 struct response_record *rrec = NULL;
1603 debug_nmb_packet(p);
1605 if(validate_nmb_response_packet(nmb))
1608 if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
1613 DEBUG(0,("process_nmb_response: response packet received but no response record \
1614 found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));
1618 /* Increment the number of responses received for this record. */
1620 /* Ensure we don't re-send the request. */
1621 rrec->repeat_count = 0;
1623 /* Call the response received function for this packet. */
1624 (*rrec->resp_fn)(subrec, rrec, p);
1628 /*******************************************************************
1629 Run elements off the packet queue till its empty
1630 ******************************************************************/
1632 void run_packet_queue(void)
1634 struct packet_struct *p;
1636 while ((p = packet_queue))
1638 packet_queue = p->next;
1640 packet_queue->prev = NULL;
1641 p->next = p->prev = NULL;
1643 switch (p->packet_type)
1646 if(p->packet.nmb.header.response)
1647 process_nmb_response(p);
1649 process_nmb_request(p);
1660 /*******************************************************************
1661 Retransmit or timeout elements from all the outgoing subnet response
1662 record queues. NOTE that this code must also check the WINS server
1663 subnet for response records to timeout as the WINS server code
1664 can send requests to check if a client still owns a name.
1665 (Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>).
1666 ******************************************************************/
1668 void retransmit_or_expire_response_records(time_t t)
1670 struct subnet_record *subrec;
1672 for (subrec = FIRST_SUBNET; subrec;
1673 subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec))
1675 struct response_record *rrec, *nextrrec;
1677 for (rrec = subrec->responselist; rrec; rrec = nextrrec)
1679 nextrrec = rrec->next;
1681 if (rrec->repeat_time <= t)
1683 if (rrec->repeat_count > 0)
1685 /* Resend while we have a non-zero repeat_count. */
1686 if(!send_packet(rrec->packet))
1688 DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
1689 to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
1690 subrec->subnet_name));
1692 rrec->repeat_time = t + rrec->repeat_interval;
1693 rrec->repeat_count--;
1697 DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
1698 on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
1699 subrec->subnet_name));
1702 * Check the flag in this record to prevent recursion if we end
1703 * up in this function again via the timeout function call.
1706 if(!rrec->in_expiration_processing)
1710 * Set the recursion protection flag in this record.
1713 rrec->in_expiration_processing = True;
1715 /* Call the timeout function. This will deal with removing the
1716 timed out packet. */
1717 if(rrec->timeout_fn)
1718 (*rrec->timeout_fn)(subrec, rrec);
1721 /* We must remove the record ourself if there is
1722 no timeout function. */
1723 remove_response_record(subrec, rrec);
1725 } /* !rrec->in_expitation_processing */
1726 } /* rrec->repeat_count > 0 */
1727 } /* rrec->repeat_time <= t */
1728 } /* end for rrec */
1729 } /* end for subnet */
1732 /****************************************************************************
1733 Create an fd_set containing all the sockets in the subnet structures,
1734 plus the broadcast sockets.
1735 ***************************************************************************/
1737 static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number)
1739 int *sock_array = NULL;
1740 struct subnet_record *subrec = NULL;
1743 fd_set *pset = (fd_set *)malloc(sizeof(fd_set));
1747 DEBUG(0,("create_listen_fdset: malloc fail !\n"));
1751 /* Check that we can add all the fd's we need. */
1752 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1755 if((count*2) + 2 > FD_SETSIZE)
1757 DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
1758 only use %d.\n", (count*2) + 2, FD_SETSIZE));
1762 if((sock_array = (int *)malloc(((count*2) + 2)*sizeof(int))) == NULL)
1764 DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
1770 /* Add in the broadcast socket on 137. */
1771 FD_SET(ClientNMB,pset);
1772 sock_array[num++] = ClientNMB;
1774 /* Add in the 137 sockets on all the interfaces. */
1775 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1777 FD_SET(subrec->nmb_sock,pset);
1778 sock_array[num++] = subrec->nmb_sock;
1781 /* Add in the broadcast socket on 138. */
1782 FD_SET(ClientDGRAM,pset);
1783 sock_array[num++] = ClientDGRAM;
1785 /* Add in the 138 sockets on all the interfaces. */
1786 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1788 FD_SET(subrec->dgram_sock,pset);
1789 sock_array[num++] = subrec->dgram_sock;
1792 *listen_number = (count*2) + 2;
1795 SAFE_FREE(*psock_array);
1798 *psock_array = sock_array;
1803 /****************************************************************************
1804 Listens for NMB or DGRAM packets, and queues them.
1805 return True if the socket is dead
1806 ***************************************************************************/
1808 BOOL listen_for_packets(BOOL run_election)
1810 static fd_set *listen_set = NULL;
1811 static int listen_number = 0;
1812 static int *sock_array = NULL;
1817 struct timeval timeout;
1822 if(listen_set == NULL || rescan_listen_set)
1824 if(create_listen_fdset(&listen_set, &sock_array, &listen_number))
1826 DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
1829 rescan_listen_set = False;
1832 memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
1835 dns_fd = asyncdns_fd();
1837 FD_SET(dns_fd, &fds);
1843 * During elections and when expecting a netbios response packet we
1844 * need to send election packets at tighter intervals.
1845 * Ideally it needs to be the interval (in ms) between time now and
1846 * the time we are expecting the next netbios packet.
1849 timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
1850 timeout.tv_usec = 0;
1852 /* Prepare for the select - allow certain signals. */
1854 BlockSignals(False, SIGTERM);
1856 selrtn = sys_select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
1858 /* We can only take signals when we are in the select - block them again here. */
1860 BlockSignals(True, SIGTERM);
1867 if (dns_fd != -1 && FD_ISSET(dns_fd,&fds)) {
1872 for(i = 0; i < listen_number; i++) {
1873 if (i < (listen_number/2)) {
1874 /* Processing a 137 socket. */
1875 if (FD_ISSET(sock_array[i],&fds)) {
1876 struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
1879 * If we got a packet on the broadcast socket and interfaces
1880 * only is set then check it came from one of our local nets.
1882 if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) &&
1883 (!is_local_net(packet->ip))) {
1884 DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
1885 inet_ntoa(packet->ip),packet->port));
1886 free_packet(packet);
1887 } else if ((ip_equal(loopback_ip, packet->ip) ||
1888 ismyip(packet->ip)) && packet->port == global_nmb_port &&
1889 packet->packet.nmb.header.nm_flags.bcast) {
1890 DEBUG(7,("discarding own bcast packet from %s:%d\n",
1891 inet_ntoa(packet->ip),packet->port));
1892 free_packet(packet);
1894 /* Save the file descriptor this packet came in on. */
1895 packet->fd = sock_array[i];
1896 queue_packet(packet);
1901 /* Processing a 138 socket. */
1902 if (FD_ISSET(sock_array[i],&fds)) {
1903 struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
1906 * If we got a packet on the broadcast socket and interfaces
1907 * only is set then check it came from one of our local nets.
1909 if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) &&
1910 (!is_local_net(packet->ip))) {
1911 DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
1912 inet_ntoa(packet->ip),packet->port));
1913 free_packet(packet);
1914 } else if ((ip_equal(loopback_ip, packet->ip) ||
1915 ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
1916 DEBUG(7,("discarding own dgram packet from %s:%d\n",
1917 inet_ntoa(packet->ip),packet->port));
1918 free_packet(packet);
1920 /* Save the file descriptor this packet came in on. */
1921 packet->fd = sock_array[i];
1922 queue_packet(packet);
1926 } /* end processing 138 socket. */
1931 /****************************************************************************
1932 Construct and send a netbios DGRAM.
1933 **************************************************************************/
1934 BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
1935 char *srcname, int src_type,
1936 char *dstname, int dest_type,
1937 struct in_addr dest_ip,struct in_addr src_ip,
1940 BOOL loopback_this_packet = False;
1941 struct packet_struct p;
1942 struct dgram_packet *dgram = &p.packet.dgram;
1946 memset((char *)&p,'\0',sizeof(p));
1948 if(ismyip(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
1949 loopback_this_packet = True;
1951 /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
1953 /* DIRECT GROUP or UNIQUE datagram. */
1954 dgram->header.msg_type = unique ? 0x10 : 0x11;
1955 dgram->header.flags.node_type = M_NODE;
1956 dgram->header.flags.first = True;
1957 dgram->header.flags.more = False;
1958 dgram->header.dgm_id = generate_name_trn_id();
1959 dgram->header.source_ip = src_ip;
1960 dgram->header.source_port = DGRAM_PORT;
1961 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1962 dgram->header.packet_offset = 0;
1964 make_nmb_name(&dgram->source_name,srcname,src_type);
1965 make_nmb_name(&dgram->dest_name,dstname,dest_type);
1967 ptr = &dgram->data[0];
1969 /* Setup the smb part. */
1970 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1972 set_message(ptr,17,17 + len,True);
1975 SCVAL(ptr,smb_com,SMBtrans);
1976 SSVAL(ptr,smb_vwv1,len);
1977 SSVAL(ptr,smb_vwv11,len);
1978 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1979 SSVAL(ptr,smb_vwv13,3);
1980 SSVAL(ptr,smb_vwv14,1);
1981 SSVAL(ptr,smb_vwv15,1);
1982 SSVAL(ptr,smb_vwv16,2);
1984 pstrcpy(p2,mailslot);
1985 p2 = skip_string(p2,1);
1990 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1994 p.fd = find_subnet_mailslot_fd_for_address( src_ip );
1995 p.timestamp = time(NULL);
1996 p.packet_type = DGRAM_PACKET;
1998 DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
1999 nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
2000 DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
2002 debug_browse_data(buf, len);
2004 if(loopback_this_packet)
2006 struct packet_struct *lo_packet = NULL;
2007 DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
2008 if((lo_packet = copy_packet(&p)) == NULL)
2010 queue_packet(lo_packet);
2014 return(send_packet(&p));