waf/buildtools: use /bin/sh instead of /bin/bash and put ^ in quotes
[Samba/gbeck.git] / source3 / nmbd / nmbd_packets.c
blob401eb2526724590e8674b9aef202d2017186dc91
1 /*
2 Unix SMB/CIFS implementation.
3 NBT netbios routines and daemon - version 2
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Luke Kenneth Casson Leighton 1994-1998
6 Copyright (C) Jeremy Allison 1994-2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "nmbd/nmbd.h"
25 #include "../lib/util/select.h"
27 extern int ClientNMB;
28 extern int ClientDGRAM;
29 extern int global_nmb_port;
31 extern int num_response_packets;
33 bool rescan_listen_set = False;
36 /*******************************************************************
37 The global packet linked-list. Incoming entries are
38 added to the end of this list. It is supposed to remain fairly
39 short so we won't bother with an end pointer.
40 ******************************************************************/
42 static struct packet_struct *packet_queue = NULL;
44 /***************************************************************************
45 Utility function to find the specific fd to send a packet out on.
46 **************************************************************************/
48 static int find_subnet_fd_for_address( struct in_addr local_ip )
50 struct subnet_record *subrec;
52 for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
53 if(ip_equal_v4(local_ip, subrec->myip))
54 return subrec->nmb_sock;
56 return ClientNMB;
59 /***************************************************************************
60 Utility function to find the specific fd to send a mailslot packet out on.
61 **************************************************************************/
63 static int find_subnet_mailslot_fd_for_address( struct in_addr local_ip )
65 struct subnet_record *subrec;
67 for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
68 if(ip_equal_v4(local_ip, subrec->myip))
69 return subrec->dgram_sock;
71 return ClientDGRAM;
74 /***************************************************************************
75 Get/Set problematic nb_flags as network byte order 16 bit int.
76 **************************************************************************/
78 uint16 get_nb_flags(char *buf)
80 return ((((uint16)*buf)&0xFFFF) & NB_FLGMSK);
83 void set_nb_flags(char *buf, uint16 nb_flags)
85 *buf++ = ((nb_flags & NB_FLGMSK) & 0xFF);
86 *buf = '\0';
89 /***************************************************************************
90 Dumps out the browse packet data.
91 **************************************************************************/
93 static void debug_browse_data(char *outbuf, int len)
95 int i,j;
97 DEBUG( 4, ( "debug_browse_data():\n" ) );
98 for (i = 0; i < len; i+= 16) {
99 DEBUGADD( 4, ( "%3x char ", i ) );
101 for (j = 0; j < 16; j++) {
102 unsigned char x;
103 if (i+j >= len)
104 break;
106 x = outbuf[i+j];
107 if (x < 32 || x > 127)
108 x = '.';
110 DEBUGADD( 4, ( "%c", x ) );
113 DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
115 for (j = 0; j < 16; j++) {
116 if (i+j >= len)
117 break;
118 DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
121 DEBUGADD( 4, ("\n") );
125 /***************************************************************************
126 Generates the unique transaction identifier
127 **************************************************************************/
129 static uint16 name_trn_id=0;
131 static uint16 generate_name_trn_id(void)
133 if (!name_trn_id) {
134 name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
136 name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
137 return name_trn_id;
140 /***************************************************************************
141 Either loops back or sends out a completed NetBIOS packet.
142 **************************************************************************/
144 static bool send_netbios_packet(struct packet_struct *p)
146 bool loopback_this_packet = False;
148 /* Check if we are sending to or from ourselves as a WINS server. */
149 if(ismyip_v4(p->ip) && (p->port == global_nmb_port))
150 loopback_this_packet = True;
152 if(loopback_this_packet) {
153 struct packet_struct *lo_packet = NULL;
154 DEBUG(5,("send_netbios_packet: sending packet to ourselves.\n"));
155 if((lo_packet = copy_packet(p)) == NULL)
156 return False;
157 queue_packet(lo_packet);
158 } else if (!send_packet(p)) {
159 DEBUG(0,("send_netbios_packet: send_packet() to IP %s port %d failed\n",
160 inet_ntoa(p->ip),p->port));
161 return False;
164 return True;
167 /***************************************************************************
168 Sets up the common elements of an outgoing NetBIOS packet.
170 Note: do not attempt to rationalise whether rec_des should be set or not
171 in a particular situation. Just follow rfc_1002 or look at examples from WinXX.
172 It does NOT follow the rule that requests to the wins server always have
173 rec_des true. See for example name releases and refreshes
174 **************************************************************************/
176 static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmbname,
177 bool bcast, bool rec_des,
178 struct in_addr to_ip)
180 struct packet_struct *packet = NULL;
181 struct nmb_packet *nmb = NULL;
183 /* Allocate the packet_struct we will return. */
184 if((packet = SMB_MALLOC_P(struct packet_struct)) == NULL) {
185 DEBUG(0,("create_and_init_netbios_packet: malloc fail (1) for packet struct.\n"));
186 return NULL;
189 memset((char *)packet,'\0',sizeof(*packet));
191 nmb = &packet->packet.nmb;
193 nmb->header.name_trn_id = generate_name_trn_id();
194 nmb->header.response = False;
195 nmb->header.nm_flags.recursion_desired = rec_des;
196 nmb->header.nm_flags.recursion_available = False;
197 nmb->header.nm_flags.trunc = False;
198 nmb->header.nm_flags.authoritative = False;
199 nmb->header.nm_flags.bcast = bcast;
201 nmb->header.rcode = 0;
202 nmb->header.qdcount = 1;
203 nmb->header.ancount = 0;
204 nmb->header.nscount = 0;
206 nmb->question.question_name = *nmbname;
207 nmb->question.question_type = QUESTION_TYPE_NB_QUERY;
208 nmb->question.question_class = QUESTION_CLASS_IN;
210 packet->ip = to_ip;
211 packet->port = NMB_PORT;
212 packet->recv_fd = -1;
213 packet->send_fd = ClientNMB;
214 packet->timestamp = time(NULL);
215 packet->packet_type = NMB_PACKET;
216 packet->locked = False;
218 return packet; /* Caller must free. */
221 /***************************************************************************
222 Sets up the common elements of register, refresh or release packet.
223 **************************************************************************/
225 static bool create_and_init_additional_record(struct packet_struct *packet,
226 uint16 nb_flags,
227 const struct in_addr *register_ip)
229 struct nmb_packet *nmb = &packet->packet.nmb;
231 if((nmb->additional = SMB_MALLOC_P(struct res_rec)) == NULL) {
232 DEBUG(0,("create_and_init_additional_record: malloc fail for additional record.\n"));
233 return False;
236 memset((char *)nmb->additional,'\0',sizeof(struct res_rec));
238 nmb->additional->rr_name = nmb->question.question_name;
239 nmb->additional->rr_type = RR_TYPE_NB;
240 nmb->additional->rr_class = RR_CLASS_IN;
242 /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
243 if (nmb->header.nm_flags.bcast)
244 nmb->additional->ttl = PERMANENT_TTL;
245 else
246 nmb->additional->ttl = lp_max_ttl();
248 nmb->additional->rdlength = 6;
250 set_nb_flags(nmb->additional->rdata,nb_flags);
252 /* Set the address for the name we are registering. */
253 putip(&nmb->additional->rdata[2], register_ip);
256 it turns out that Jeremys code was correct, we are supposed
257 to send registrations from the IP we are registering. The
258 trick is what to do on timeouts! When we send on a
259 non-routable IP then the reply will timeout, and we should
260 treat this as success, not failure. That means we go into
261 our standard refresh cycle for that name which copes nicely
262 with disconnected networks.
264 packet->recv_fd = -1;
265 packet->send_fd = find_subnet_fd_for_address(*register_ip);
267 return True;
270 /***************************************************************************
271 Sends out a name query.
272 **************************************************************************/
274 static bool initiate_name_query_packet( struct packet_struct *packet)
276 struct nmb_packet *nmb = NULL;
278 nmb = &packet->packet.nmb;
280 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
281 nmb->header.arcount = 0;
283 nmb->header.nm_flags.recursion_desired = True;
285 DEBUG(4,("initiate_name_query_packet: sending query for name %s (bcast=%s) to IP %s\n",
286 nmb_namestr(&nmb->question.question_name),
287 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
289 return send_netbios_packet( packet );
292 /***************************************************************************
293 Sends out a name query - from a WINS server.
294 **************************************************************************/
296 static bool initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
298 struct nmb_packet *nmb = NULL;
300 nmb = &packet->packet.nmb;
302 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
303 nmb->header.arcount = 0;
305 nmb->header.nm_flags.recursion_desired = False;
307 DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
308 nmb_namestr(&nmb->question.question_name),
309 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
311 return send_netbios_packet( packet );
314 /***************************************************************************
315 Sends out a name register.
316 **************************************************************************/
318 static bool initiate_name_register_packet( struct packet_struct *packet,
319 uint16 nb_flags, const struct in_addr *register_ip)
321 struct nmb_packet *nmb = &packet->packet.nmb;
323 nmb->header.opcode = NMB_NAME_REG_OPCODE;
324 nmb->header.arcount = 1;
326 nmb->header.nm_flags.recursion_desired = True;
328 if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
329 return False;
331 DEBUG(4,("initiate_name_register_packet: sending registration for name %s (bcast=%s) to IP %s\n",
332 nmb_namestr(&nmb->additional->rr_name),
333 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
335 return send_netbios_packet( packet );
338 /***************************************************************************
339 Sends out a multihomed name register.
340 **************************************************************************/
342 static bool initiate_multihomed_name_register_packet(struct packet_struct *packet,
343 uint16 nb_flags, struct in_addr *register_ip)
345 struct nmb_packet *nmb = &packet->packet.nmb;
346 fstring second_ip_buf;
348 fstrcpy(second_ip_buf, inet_ntoa(packet->ip));
350 nmb->header.opcode = NMB_NAME_MULTIHOMED_REG_OPCODE;
351 nmb->header.arcount = 1;
353 nmb->header.nm_flags.recursion_desired = True;
355 if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
356 return False;
358 DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
359 for name %s IP %s (bcast=%s) to IP %s\n",
360 nmb_namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
361 BOOLSTR(nmb->header.nm_flags.bcast), second_ip_buf ));
363 return send_netbios_packet( packet );
366 /***************************************************************************
367 Sends out a name refresh.
368 **************************************************************************/
370 static bool initiate_name_refresh_packet( struct packet_struct *packet,
371 uint16 nb_flags, struct in_addr *refresh_ip)
373 struct nmb_packet *nmb = &packet->packet.nmb;
375 nmb->header.opcode = NMB_NAME_REFRESH_OPCODE_8;
376 nmb->header.arcount = 1;
378 nmb->header.nm_flags.recursion_desired = False;
380 if(create_and_init_additional_record(packet, nb_flags, refresh_ip) == False)
381 return False;
383 DEBUG(4,("initiate_name_refresh_packet: sending refresh for name %s (bcast=%s) to IP %s\n",
384 nmb_namestr(&nmb->additional->rr_name),
385 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
387 return send_netbios_packet( packet );
390 /***************************************************************************
391 Sends out a name release.
392 **************************************************************************/
394 static bool initiate_name_release_packet( struct packet_struct *packet,
395 uint16 nb_flags, struct in_addr *release_ip)
397 struct nmb_packet *nmb = &packet->packet.nmb;
399 nmb->header.opcode = NMB_NAME_RELEASE_OPCODE;
400 nmb->header.arcount = 1;
402 nmb->header.nm_flags.recursion_desired = False;
404 if(create_and_init_additional_record(packet, nb_flags, release_ip) == False)
405 return False;
407 DEBUG(4,("initiate_name_release_packet: sending release for name %s (bcast=%s) to IP %s\n",
408 nmb_namestr(&nmb->additional->rr_name),
409 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
411 return send_netbios_packet( packet );
414 /***************************************************************************
415 Sends out a node status.
416 **************************************************************************/
418 static bool initiate_node_status_packet( struct packet_struct *packet )
420 struct nmb_packet *nmb = &packet->packet.nmb;
422 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
423 nmb->header.arcount = 0;
425 nmb->header.nm_flags.recursion_desired = False;
427 nmb->question.question_type = QUESTION_TYPE_NB_STATUS;
429 DEBUG(4,("initiate_node_status_packet: sending node status request for name %s to IP %s\n",
430 nmb_namestr(&nmb->question.question_name),
431 inet_ntoa(packet->ip)));
433 return send_netbios_packet( packet );
436 /****************************************************************************
437 Simplification functions for queuing standard packets.
438 These should be the only publicly callable functions for sending
439 out packets.
440 ****************************************************************************/
442 /****************************************************************************
443 Assertion - we should never be sending nmbd packets on the remote
444 broadcast subnet.
445 ****************************************************************************/
447 static bool assert_check_subnet(struct subnet_record *subrec)
449 if( subrec == remote_broadcast_subnet) {
450 DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
451 This is a bug.\n"));
452 return True;
454 return False;
457 /****************************************************************************
458 Queue a register name packet to the broadcast address of a subnet.
459 ****************************************************************************/
461 struct response_record *queue_register_name( struct subnet_record *subrec,
462 response_function resp_fn,
463 timeout_response_function timeout_fn,
464 register_name_success_function success_fn,
465 register_name_fail_function fail_fn,
466 struct userdata_struct *userdata,
467 struct nmb_name *nmbname,
468 uint16 nb_flags)
470 struct packet_struct *p;
471 struct response_record *rrec;
472 struct sockaddr_storage ss;
473 const struct sockaddr_storage *pss = NULL;
474 if(assert_check_subnet(subrec))
475 return NULL;
477 /* note that all name registration requests have RD set (rfc1002 - section 4.2.2 */
478 if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), True,
479 subrec->bcast_ip)) == NULL)
480 return NULL;
482 in_addr_to_sockaddr_storage(&ss, subrec->bcast_ip);
483 pss = iface_ip((struct sockaddr *)&ss);
484 if (!pss || pss->ss_family != AF_INET) {
485 p->locked = False;
486 free_packet(p);
487 return NULL;
490 if(initiate_name_register_packet(p, nb_flags,
491 &((const struct sockaddr_in *)pss)->sin_addr) == False) {
492 p->locked = False;
493 free_packet(p);
494 return NULL;
497 if((rrec = make_response_record(subrec, /* subnet record. */
498 p, /* packet we sent. */
499 resp_fn, /* function to call on response. */
500 timeout_fn, /* function to call on timeout. */
501 (success_function)success_fn, /* function to call on operation success. */
502 (fail_function)fail_fn, /* function to call on operation fail. */
503 userdata)) == NULL) {
504 p->locked = False;
505 free_packet(p);
506 return NULL;
509 return rrec;
512 /****************************************************************************
513 Queue a refresh name packet to the broadcast address of a subnet.
514 ****************************************************************************/
516 void queue_wins_refresh(struct nmb_name *nmbname,
517 response_function resp_fn,
518 timeout_response_function timeout_fn,
519 uint16 nb_flags,
520 struct in_addr refresh_ip,
521 const char *tag)
523 struct packet_struct *p;
524 struct response_record *rrec;
525 struct in_addr wins_ip;
526 struct userdata_struct *userdata;
527 fstring ip_str;
529 wins_ip = wins_srv_ip_tag(tag, refresh_ip);
531 if ((p = create_and_init_netbios_packet(nmbname, False, False, wins_ip)) == NULL) {
532 return;
535 if (!initiate_name_refresh_packet(p, nb_flags, &refresh_ip)) {
536 p->locked = False;
537 free_packet(p);
538 return;
541 fstrcpy(ip_str, inet_ntoa(refresh_ip));
543 DEBUG(6,("Refreshing name %s IP %s with WINS server %s using tag '%s'\n",
544 nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
546 userdata = (struct userdata_struct *)SMB_MALLOC(sizeof(*userdata) + strlen(tag) + 1);
547 if (!userdata) {
548 p->locked = False;
549 free_packet(p);
550 DEBUG(0,("Failed to allocate userdata structure!\n"));
551 return;
553 ZERO_STRUCTP(userdata);
554 userdata->userdata_len = strlen(tag) + 1;
555 strlcpy(userdata->data, tag, userdata->userdata_len);
557 if ((rrec = make_response_record(unicast_subnet,
559 resp_fn, timeout_fn,
560 NULL,
561 NULL,
562 userdata)) == NULL) {
563 p->locked = False;
564 free_packet(p);
565 return;
568 free(userdata);
570 /* we don't want to repeat refresh packets */
571 rrec->repeat_count = 0;
575 /****************************************************************************
576 Queue a multihomed register name packet to a given WINS server IP
577 ****************************************************************************/
579 struct response_record *queue_register_multihomed_name( struct subnet_record *subrec,
580 response_function resp_fn,
581 timeout_response_function timeout_fn,
582 register_name_success_function success_fn,
583 register_name_fail_function fail_fn,
584 struct userdata_struct *userdata,
585 struct nmb_name *nmbname,
586 uint16 nb_flags,
587 struct in_addr register_ip,
588 struct in_addr wins_ip)
590 struct packet_struct *p;
591 struct response_record *rrec;
592 bool ret;
594 /* Sanity check. */
595 if(subrec != unicast_subnet) {
596 DEBUG(0,("queue_register_multihomed_name: should only be done on \
597 unicast subnet. subnet is %s\n.", subrec->subnet_name ));
598 return NULL;
601 if(assert_check_subnet(subrec))
602 return NULL;
604 if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL)
605 return NULL;
607 if (nb_flags & NB_GROUP)
608 ret = initiate_name_register_packet( p, nb_flags, &register_ip);
609 else
610 ret = initiate_multihomed_name_register_packet(p, nb_flags, &register_ip);
612 if (ret == False) {
613 p->locked = False;
614 free_packet(p);
615 return NULL;
618 if ((rrec = make_response_record(subrec, /* subnet record. */
619 p, /* packet we sent. */
620 resp_fn, /* function to call on response. */
621 timeout_fn, /* function to call on timeout. */
622 (success_function)success_fn, /* function to call on operation success. */
623 (fail_function)fail_fn, /* function to call on operation fail. */
624 userdata)) == NULL) {
625 p->locked = False;
626 free_packet(p);
627 return NULL;
630 return rrec;
633 /****************************************************************************
634 Queue a release name packet to the broadcast address of a subnet.
635 ****************************************************************************/
637 struct response_record *queue_release_name( struct subnet_record *subrec,
638 response_function resp_fn,
639 timeout_response_function timeout_fn,
640 release_name_success_function success_fn,
641 release_name_fail_function fail_fn,
642 struct userdata_struct *userdata,
643 struct nmb_name *nmbname,
644 uint16 nb_flags,
645 struct in_addr release_ip,
646 struct in_addr dest_ip)
648 struct packet_struct *p;
649 struct response_record *rrec;
651 if(assert_check_subnet(subrec))
652 return NULL;
654 if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False, dest_ip)) == NULL)
655 return NULL;
657 if(initiate_name_release_packet( p, nb_flags, &release_ip) == False) {
658 p->locked = False;
659 free_packet(p);
660 return NULL;
663 if((rrec = make_response_record(subrec, /* subnet record. */
664 p, /* packet we sent. */
665 resp_fn, /* function to call on response. */
666 timeout_fn, /* function to call on timeout. */
667 (success_function)success_fn, /* function to call on operation success. */
668 (fail_function)fail_fn, /* function to call on operation fail. */
669 userdata)) == NULL) {
670 p->locked = False;
671 free_packet(p);
672 return NULL;
676 * For a broadcast release packet, only send once.
677 * This will cause us to remove the name asap. JRA.
680 if (subrec != unicast_subnet) {
681 rrec->repeat_count = 0;
682 rrec->repeat_time = 0;
685 return rrec;
688 /****************************************************************************
689 Queue a query name packet to the broadcast address of a subnet.
690 ****************************************************************************/
692 struct response_record *queue_query_name( struct subnet_record *subrec,
693 response_function resp_fn,
694 timeout_response_function timeout_fn,
695 query_name_success_function success_fn,
696 query_name_fail_function fail_fn,
697 struct userdata_struct *userdata,
698 struct nmb_name *nmbname)
700 struct packet_struct *p;
701 struct response_record *rrec;
702 struct in_addr to_ip;
704 if(assert_check_subnet(subrec))
705 return NULL;
707 to_ip = subrec->bcast_ip;
709 /* queries to the WINS server turn up here as queries to IP 0.0.0.0
710 These need to be handled a bit differently */
711 if (subrec->type == UNICAST_SUBNET && is_zero_ip_v4(to_ip)) {
712 /* What we really need to do is loop over each of our wins
713 * servers and wins server tags here, but that just doesn't
714 * fit our architecture at the moment (userdata may already
715 * be used when we get here). For now we just query the first
716 * active wins server on the first tag.
718 char **tags = wins_srv_tags();
719 if (!tags) {
720 return NULL;
722 to_ip = wins_srv_ip_tag(tags[0], to_ip);
723 wins_srv_tags_free(tags);
726 if(( p = create_and_init_netbios_packet(nmbname,
727 (subrec != unicast_subnet),
728 (subrec == unicast_subnet),
729 to_ip)) == NULL)
730 return NULL;
732 if(lp_bind_interfaces_only()) {
733 int i;
735 DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
736 for(i = 0; i < iface_count(); i++) {
737 const struct in_addr *ifip = iface_n_ip_v4(i);
739 if (ifip == NULL) {
740 DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
741 continue;
744 if (is_loopback_ip_v4(*ifip)) {
745 DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
746 continue;
749 DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
750 p->send_fd = find_subnet_fd_for_address( *ifip );
751 break;
755 if(initiate_name_query_packet( p ) == False) {
756 p->locked = False;
757 free_packet(p);
758 return NULL;
761 if((rrec = make_response_record(subrec, /* subnet record. */
762 p, /* packet we sent. */
763 resp_fn, /* function to call on response. */
764 timeout_fn, /* function to call on timeout. */
765 (success_function)success_fn, /* function to call on operation success. */
766 (fail_function)fail_fn, /* function to call on operation fail. */
767 userdata)) == NULL) {
768 p->locked = False;
769 free_packet(p);
770 return NULL;
773 return rrec;
776 /****************************************************************************
777 Queue a query name packet to a given address from the WINS subnet.
778 ****************************************************************************/
780 struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
781 response_function resp_fn,
782 timeout_response_function timeout_fn,
783 query_name_success_function success_fn,
784 query_name_fail_function fail_fn,
785 struct userdata_struct *userdata,
786 struct nmb_name *nmbname)
788 struct packet_struct *p;
789 struct response_record *rrec;
791 if ((p = create_and_init_netbios_packet(nmbname, False, False, to_ip)) == NULL)
792 return NULL;
794 if(initiate_name_query_packet_from_wins_server( p ) == False) {
795 p->locked = False;
796 free_packet(p);
797 return NULL;
800 if((rrec = make_response_record(wins_server_subnet, /* subnet record. */
801 p, /* packet we sent. */
802 resp_fn, /* function to call on response. */
803 timeout_fn, /* function to call on timeout. */
804 (success_function)success_fn, /* function to call on operation success. */
805 (fail_function)fail_fn, /* function to call on operation fail. */
806 userdata)) == NULL) {
807 p->locked = False;
808 free_packet(p);
809 return NULL;
812 return rrec;
815 /****************************************************************************
816 Queue a node status packet to a given name and address.
817 ****************************************************************************/
819 struct response_record *queue_node_status( struct subnet_record *subrec,
820 response_function resp_fn,
821 timeout_response_function timeout_fn,
822 node_status_success_function success_fn,
823 node_status_fail_function fail_fn,
824 struct userdata_struct *userdata,
825 struct nmb_name *nmbname,
826 struct in_addr send_ip)
828 struct packet_struct *p;
829 struct response_record *rrec;
831 /* Sanity check. */
832 if(subrec != unicast_subnet) {
833 DEBUG(0,("queue_register_multihomed_name: should only be done on \
834 unicast subnet. subnet is %s\n.", subrec->subnet_name ));
835 return NULL;
838 if(assert_check_subnet(subrec))
839 return NULL;
841 if(( p = create_and_init_netbios_packet(nmbname, False, False, send_ip)) == NULL)
842 return NULL;
844 if(initiate_node_status_packet(p) == False) {
845 p->locked = False;
846 free_packet(p);
847 return NULL;
850 if((rrec = make_response_record(subrec, /* subnet record. */
851 p, /* packet we sent. */
852 resp_fn, /* function to call on response. */
853 timeout_fn, /* function to call on timeout. */
854 (success_function)success_fn, /* function to call on operation success. */
855 (fail_function)fail_fn, /* function to call on operation fail. */
856 userdata)) == NULL) {
857 p->locked = False;
858 free_packet(p);
859 return NULL;
862 return rrec;
865 /****************************************************************************
866 Reply to a netbios name packet. see rfc1002.txt
867 ****************************************************************************/
869 void reply_netbios_packet(struct packet_struct *orig_packet,
870 int rcode, enum netbios_reply_type_code rcv_code, int opcode,
871 int ttl, char *data,int len)
873 struct packet_struct packet;
874 struct nmb_packet *nmb = NULL;
875 struct res_rec answers;
876 struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
877 bool loopback_this_packet = False;
878 int rr_type = RR_TYPE_NB;
879 const char *packet_type = "unknown";
881 /* Check if we are sending to or from ourselves. */
882 if(ismyip_v4(orig_packet->ip) && (orig_packet->port == global_nmb_port))
883 loopback_this_packet = True;
885 nmb = &packet.packet.nmb;
887 /* Do a partial copy of the packet. We clear the locked flag and
888 the resource record pointers. */
889 packet = *orig_packet; /* Full structure copy. */
890 packet.locked = False;
891 nmb->answers = NULL;
892 nmb->nsrecs = NULL;
893 nmb->additional = NULL;
895 switch (rcv_code) {
896 case NMB_STATUS:
897 packet_type = "nmb_status";
898 nmb->header.nm_flags.recursion_desired = False;
899 nmb->header.nm_flags.recursion_available = False;
900 rr_type = RR_TYPE_NBSTAT;
901 break;
902 case NMB_QUERY:
903 packet_type = "nmb_query";
904 nmb->header.nm_flags.recursion_desired = True;
905 nmb->header.nm_flags.recursion_available = True;
906 if (rcode) {
907 rr_type = RR_TYPE_NULL;
909 break;
910 case NMB_REG:
911 case NMB_REG_REFRESH:
912 packet_type = "nmb_reg";
913 nmb->header.nm_flags.recursion_desired = True;
914 nmb->header.nm_flags.recursion_available = True;
915 break;
916 case NMB_REL:
917 packet_type = "nmb_rel";
918 nmb->header.nm_flags.recursion_desired = False;
919 nmb->header.nm_flags.recursion_available = False;
920 break;
921 case NMB_WAIT_ACK:
922 packet_type = "nmb_wack";
923 nmb->header.nm_flags.recursion_desired = False;
924 nmb->header.nm_flags.recursion_available = False;
925 rr_type = RR_TYPE_NULL;
926 break;
927 case WINS_REG:
928 packet_type = "wins_reg";
929 nmb->header.nm_flags.recursion_desired = True;
930 nmb->header.nm_flags.recursion_available = True;
931 break;
932 case WINS_QUERY:
933 packet_type = "wins_query";
934 nmb->header.nm_flags.recursion_desired = True;
935 nmb->header.nm_flags.recursion_available = True;
936 if (rcode) {
937 rr_type = RR_TYPE_NULL;
939 break;
940 default:
941 DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
942 packet_type, nmb_namestr(&orig_nmb->question.question_name),
943 inet_ntoa(packet.ip)));
944 return;
947 DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
948 for id %hu\n", packet_type, nmb_namestr(&orig_nmb->question.question_name),
949 inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
951 nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
952 nmb->header.opcode = opcode;
953 nmb->header.response = True;
954 nmb->header.nm_flags.bcast = False;
955 nmb->header.nm_flags.trunc = False;
956 nmb->header.nm_flags.authoritative = True;
958 nmb->header.rcode = rcode;
959 nmb->header.qdcount = 0;
960 nmb->header.ancount = 1;
961 nmb->header.nscount = 0;
962 nmb->header.arcount = 0;
964 memset((char*)&nmb->question,'\0',sizeof(nmb->question));
966 nmb->answers = &answers;
967 memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
969 nmb->answers->rr_name = orig_nmb->question.question_name;
970 nmb->answers->rr_type = rr_type;
971 nmb->answers->rr_class = RR_CLASS_IN;
972 nmb->answers->ttl = ttl;
974 if (data && len) {
975 if (len < 0 || len > sizeof(nmb->answers->rdata)) {
976 DEBUG(5,("reply_netbios_packet: "
977 "invalid packet len (%d)\n",
978 len ));
979 return;
981 nmb->answers->rdlength = len;
982 memcpy(nmb->answers->rdata, data, len);
985 packet.packet_type = NMB_PACKET;
986 packet.recv_fd = -1;
987 /* Ensure we send out on the same fd that the original
988 packet came in on to give the correct source IP address. */
989 if (orig_packet->send_fd != -1) {
990 packet.send_fd = orig_packet->send_fd;
991 } else {
992 packet.send_fd = orig_packet->recv_fd;
994 packet.timestamp = time(NULL);
996 debug_nmb_packet(&packet);
998 if(loopback_this_packet) {
999 struct packet_struct *lo_packet;
1000 DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
1001 if((lo_packet = copy_packet(&packet)) == NULL)
1002 return;
1003 queue_packet(lo_packet);
1004 } else if (!send_packet(&packet)) {
1005 DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
1006 inet_ntoa(packet.ip),packet.port));
1010 /*******************************************************************
1011 Queue a packet into a packet queue
1012 ******************************************************************/
1014 void queue_packet(struct packet_struct *packet)
1016 DLIST_ADD_END(packet_queue, packet, struct packet_struct *);
1019 /****************************************************************************
1020 Try and find a matching subnet record for a datagram port 138 packet.
1021 ****************************************************************************/
1023 static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_struct *p)
1025 struct subnet_record *subrec;
1027 /* Go through all the broadcast subnets and see if the mask matches. */
1028 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1029 if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
1030 return subrec;
1033 /* If the subnet record is the remote announce broadcast subnet,
1034 hack it here to be the first subnet. This is really gross and
1035 is needed due to people turning on port 137/138 broadcast
1036 forwarding on their routers. May fire and brimstone rain
1037 down upon them...
1040 return FIRST_SUBNET;
1043 /****************************************************************************
1044 Dispatch a browse frame from port 138 to the correct processing function.
1045 ****************************************************************************/
1047 static void process_browse_packet(struct packet_struct *p, char *buf,int len)
1049 struct dgram_packet *dgram = &p->packet.dgram;
1050 int command = CVAL(buf,0);
1051 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1052 char scope[64];
1053 unstring src_name;
1055 /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
1056 pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
1057 if (!strequal(scope, global_scope())) {
1058 DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
1059 mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
1060 return;
1063 pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
1064 if (is_myname(src_name)) {
1065 DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Source name \
1066 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1067 return;
1070 switch (command) {
1071 case ANN_HostAnnouncement:
1072 debug_browse_data(buf, len);
1073 process_host_announce(subrec, p, buf+1);
1074 break;
1075 case ANN_DomainAnnouncement:
1076 debug_browse_data(buf, len);
1077 process_workgroup_announce(subrec, p, buf+1);
1078 break;
1079 case ANN_LocalMasterAnnouncement:
1080 debug_browse_data(buf, len);
1081 process_local_master_announce(subrec, p, buf+1);
1082 break;
1083 case ANN_AnnouncementRequest:
1084 debug_browse_data(buf, len);
1085 process_announce_request(subrec, p, buf+1);
1086 break;
1087 case ANN_Election:
1088 debug_browse_data(buf, len);
1089 process_election(subrec, p, buf+1);
1090 break;
1091 case ANN_GetBackupListReq:
1092 debug_browse_data(buf, len);
1093 process_get_backup_list_request(subrec, p, buf+1);
1094 break;
1095 case ANN_GetBackupListResp:
1096 debug_browse_data(buf, len);
1097 /* We never send ANN_GetBackupListReq so we should never get these. */
1098 DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
1099 packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
1100 break;
1101 case ANN_ResetBrowserState:
1102 debug_browse_data(buf, len);
1103 process_reset_browser(subrec, p, buf+1);
1104 break;
1105 case ANN_MasterAnnouncement:
1106 /* Master browser datagrams must be processed on the unicast subnet. */
1107 subrec = unicast_subnet;
1109 debug_browse_data(buf, len);
1110 process_master_browser_announce(subrec, p, buf+1);
1111 break;
1112 case ANN_BecomeBackup:
1114 * We don't currently implement this. Log it just in case.
1116 debug_browse_data(buf, len);
1117 DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
1118 command ANN_BecomeBackup from %s IP %s to %s\n", subrec->subnet_name, nmb_namestr(&dgram->source_name),
1119 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1120 break;
1121 default:
1122 debug_browse_data(buf, len);
1123 DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
1124 command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1125 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1126 break;
1130 /****************************************************************************
1131 Dispatch a LanMan browse frame from port 138 to the correct processing function.
1132 ****************************************************************************/
1134 static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
1136 struct dgram_packet *dgram = &p->packet.dgram;
1137 int command = SVAL(buf,0);
1138 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1139 char scope[64];
1140 unstring src_name;
1142 /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
1144 pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
1145 if (!strequal(scope, global_scope())) {
1146 DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
1147 mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
1148 return;
1151 pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
1152 if (is_myname(src_name)) {
1153 DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
1154 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1155 return;
1158 switch (command) {
1159 case ANN_HostAnnouncement:
1160 debug_browse_data(buf, len);
1161 process_lm_host_announce(subrec, p, buf+1, len > 1 ? len-1 : 0);
1162 break;
1163 case ANN_AnnouncementRequest:
1164 process_lm_announce_request(subrec, p, buf+1, len > 1 ? len-1 : 0);
1165 break;
1166 default:
1167 DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
1168 command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1169 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1170 break;
1174 /****************************************************************************
1175 Determine if a packet is for us on port 138. Note that to have any chance of
1176 being efficient we need to drop as many packets as possible at this
1177 stage as subsequent processing is expensive.
1178 ****************************************************************************/
1180 static bool listening(struct packet_struct *p,struct nmb_name *nbname)
1182 struct subnet_record *subrec = NULL;
1184 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1185 if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
1186 break;
1189 if(subrec == NULL)
1190 subrec = unicast_subnet;
1192 return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
1195 /****************************************************************************
1196 Process udp 138 datagrams
1197 ****************************************************************************/
1199 static void process_dgram(struct packet_struct *p)
1201 char *buf;
1202 char *buf2;
1203 int len;
1204 struct dgram_packet *dgram = &p->packet.dgram;
1206 /* If we aren't listening to the destination name then ignore the packet */
1207 if (!listening(p,&dgram->dest_name)) {
1208 unexpected_packet(p);
1209 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
1210 nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
1211 return;
1214 if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) {
1215 unexpected_packet(p);
1216 /* Don't process error packets etc yet */
1217 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
1218 an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
1219 return;
1222 /* Ensure we have a large enough packet before looking inside. */
1223 if (dgram->datasize < (smb_vwv12 - 2)) {
1224 /* That's the offset minus the 4 byte length + 2 bytes of offset. */
1225 DEBUG(0,("process_dgram: ignoring too short dgram packet (%u) sent to name %s from IP %s\n",
1226 (unsigned int)dgram->datasize,
1227 nmb_namestr(&dgram->dest_name),
1228 inet_ntoa(p->ip) ));
1229 return;
1232 buf = &dgram->data[0];
1233 buf -= 4; /* XXXX for the pseudo tcp length - someday I need to get rid of this */
1235 if (CVAL(buf,smb_com) != SMBtrans)
1236 return;
1238 len = SVAL(buf,smb_vwv11);
1239 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1241 if (len <= 0 || len > dgram->datasize) {
1242 DEBUG(0,("process_dgram: ignoring malformed1 (datasize = %d, len = %d) datagram \
1243 packet sent to name %s from IP %s\n",
1244 dgram->datasize,
1245 len,
1246 nmb_namestr(&dgram->dest_name),
1247 inet_ntoa(p->ip) ));
1248 return;
1251 if (buf2 < dgram->data || (buf2 >= dgram->data + dgram->datasize)) {
1252 DEBUG(0,("process_dgram: ignoring malformed2 (datasize = %d, len=%d, off=%d) datagram \
1253 packet sent to name %s from IP %s\n",
1254 dgram->datasize,
1255 len,
1256 (int)PTR_DIFF(buf2, dgram->data),
1257 nmb_namestr(&dgram->dest_name),
1258 inet_ntoa(p->ip) ));
1259 return;
1262 if ((buf2 + len < dgram->data) || (buf2 + len > dgram->data + dgram->datasize)) {
1263 DEBUG(0,("process_dgram: ignoring malformed3 (datasize = %d, len=%d, off=%d) datagram \
1264 packet sent to name %s from IP %s\n",
1265 dgram->datasize,
1266 len,
1267 (int)PTR_DIFF(buf2, dgram->data),
1268 nmb_namestr(&dgram->dest_name),
1269 inet_ntoa(p->ip) ));
1270 return;
1273 DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
1274 nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
1275 inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
1277 /* Datagram packet received for the browser mailslot */
1278 if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
1279 process_browse_packet(p,buf2,len);
1280 return;
1283 /* Datagram packet received for the LAN Manager mailslot */
1284 if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
1285 process_lanman_packet(p,buf2,len);
1286 return;
1289 /* Datagram packet received for the domain logon mailslot */
1290 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
1291 process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
1292 return;
1295 /* Datagram packet received for the NT domain logon mailslot */
1296 if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT)) {
1297 process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
1298 return;
1301 unexpected_packet(p);
1304 /****************************************************************************
1305 Validate a response nmb packet.
1306 ****************************************************************************/
1308 static bool validate_nmb_response_packet( struct nmb_packet *nmb )
1310 bool ignore = False;
1312 switch (nmb->header.opcode) {
1313 case NMB_NAME_REG_OPCODE:
1314 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1315 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1316 if (nmb->header.ancount == 0) {
1317 DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
1318 ignore = True;
1320 break;
1322 case NMB_NAME_QUERY_OPCODE:
1323 if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1)) {
1324 DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
1325 ignore = True;
1327 break;
1329 case NMB_NAME_RELEASE_OPCODE:
1330 if (nmb->header.ancount == 0) {
1331 DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
1332 ignore = True;
1334 break;
1336 case NMB_WACK_OPCODE:
1337 /* Check WACK response here. */
1338 if (nmb->header.ancount != 1) {
1339 DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
1340 ignore = True;
1342 break;
1343 default:
1344 DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
1345 nmb->header.opcode));
1346 return True;
1349 if(ignore)
1350 DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
1352 return ignore;
1355 /****************************************************************************
1356 Validate a request nmb packet.
1357 ****************************************************************************/
1359 static bool validate_nmb_packet( struct nmb_packet *nmb )
1361 bool ignore = False;
1363 switch (nmb->header.opcode) {
1364 case NMB_NAME_REG_OPCODE:
1365 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1366 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1367 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1368 if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
1369 DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
1370 ignore = True;
1372 break;
1374 case NMB_NAME_QUERY_OPCODE:
1375 if ((nmb->header.qdcount == 0) || ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
1376 (nmb->question.question_type != QUESTION_TYPE_NB_STATUS))) {
1377 DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
1378 ignore = True;
1380 break;
1382 case NMB_NAME_RELEASE_OPCODE:
1383 if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
1384 DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
1385 ignore = True;
1387 break;
1388 default:
1389 DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
1390 nmb->header.opcode));
1391 return True;
1394 if(ignore)
1395 DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
1397 return ignore;
1400 /****************************************************************************
1401 Find a subnet (and potentially a response record) for a packet.
1402 ****************************************************************************/
1404 static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,
1405 struct response_record **pprrec)
1407 struct nmb_packet *nmb = &p->packet.nmb;
1408 struct response_record *rrec = NULL;
1409 struct subnet_record *subrec = NULL;
1411 if(pprrec != NULL)
1412 *pprrec = NULL;
1414 if(nmb->header.response) {
1415 /* It's a response packet. Find a record for it or it's an error. */
1417 rrec = find_response_record( &subrec, nmb->header.name_trn_id);
1418 if(rrec == NULL) {
1419 DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
1420 nmb->header.name_trn_id));
1421 unexpected_packet(p);
1422 return NULL;
1425 if(subrec == NULL) {
1426 DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
1427 nmb->header.name_trn_id));
1428 return NULL;
1431 if(pprrec != NULL)
1432 *pprrec = rrec;
1433 return subrec;
1436 /* Try and see what subnet this packet belongs to. */
1438 /* WINS server ? */
1439 if(packet_is_for_wins_server(p))
1440 return wins_server_subnet;
1442 /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
1443 if(nmb->header.nm_flags.bcast == False)
1444 return unicast_subnet;
1446 /* Go through all the broadcast subnets and see if the mask matches. */
1447 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1448 if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
1449 return subrec;
1452 /* If none match it must have been a directed broadcast - assign the remote_broadcast_subnet. */
1453 return remote_broadcast_subnet;
1456 /****************************************************************************
1457 Process a nmb request packet - validate the packet and route it.
1458 ****************************************************************************/
1460 static void process_nmb_request(struct packet_struct *p)
1462 struct nmb_packet *nmb = &p->packet.nmb;
1463 struct subnet_record *subrec = NULL;
1465 debug_nmb_packet(p);
1467 /* Ensure we have a good packet. */
1468 if(validate_nmb_packet(nmb))
1469 return;
1471 /* Allocate a subnet to this packet - if we cannot - fail. */
1472 if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
1473 return;
1475 switch (nmb->header.opcode) {
1476 case NMB_NAME_REG_OPCODE:
1477 if(subrec == wins_server_subnet)
1478 wins_process_name_registration_request(subrec, p);
1479 else
1480 process_name_registration_request(subrec, p);
1481 break;
1483 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1484 case NMB_NAME_REFRESH_OPCODE_9:
1485 if(subrec == wins_server_subnet)
1486 wins_process_name_refresh_request(subrec, p);
1487 else
1488 process_name_refresh_request(subrec, p);
1489 break;
1491 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1492 if(subrec == wins_server_subnet) {
1493 wins_process_multihomed_name_registration_request(subrec, p);
1494 } else {
1495 DEBUG(0,("process_nmb_request: Multihomed registration request must be \
1496 directed at a WINS server.\n"));
1498 break;
1500 case NMB_NAME_QUERY_OPCODE:
1501 switch (nmb->question.question_type) {
1502 case QUESTION_TYPE_NB_QUERY:
1503 if(subrec == wins_server_subnet)
1504 wins_process_name_query_request(subrec, p);
1505 else
1506 process_name_query_request(subrec, p);
1507 break;
1508 case QUESTION_TYPE_NB_STATUS:
1509 if(subrec == wins_server_subnet) {
1510 DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
1511 not allowed.\n"));
1512 break;
1513 } else {
1514 process_node_status_request(subrec, p);
1516 break;
1518 break;
1520 case NMB_NAME_RELEASE_OPCODE:
1521 if(subrec == wins_server_subnet)
1522 wins_process_name_release_request(subrec, p);
1523 else
1524 process_name_release_request(subrec, p);
1525 break;
1529 /****************************************************************************
1530 Process a nmb response packet - validate the packet and route it.
1531 to either the WINS server or a normal response.
1532 ****************************************************************************/
1534 static void process_nmb_response(struct packet_struct *p)
1536 struct nmb_packet *nmb = &p->packet.nmb;
1537 struct subnet_record *subrec = NULL;
1538 struct response_record *rrec = NULL;
1540 debug_nmb_packet(p);
1542 if(validate_nmb_response_packet(nmb))
1543 return;
1545 if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
1546 return;
1548 if(rrec == NULL) {
1549 DEBUG(0,("process_nmb_response: response packet received but no response record \
1550 found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));
1551 return;
1554 /* Increment the number of responses received for this record. */
1555 rrec->num_msgs++;
1556 /* Ensure we don't re-send the request. */
1557 rrec->repeat_count = 0;
1559 /* Call the response received function for this packet. */
1560 (*rrec->resp_fn)(subrec, rrec, p);
1563 /*******************************************************************
1564 Run elements off the packet queue till its empty
1565 ******************************************************************/
1567 void run_packet_queue(void)
1569 struct packet_struct *p;
1571 while ((p = packet_queue)) {
1572 DLIST_REMOVE(packet_queue, p);
1574 switch (p->packet_type) {
1575 case NMB_PACKET:
1576 if(p->packet.nmb.header.response)
1577 process_nmb_response(p);
1578 else
1579 process_nmb_request(p);
1580 break;
1582 case DGRAM_PACKET:
1583 process_dgram(p);
1584 break;
1586 free_packet(p);
1590 /*******************************************************************
1591 Retransmit or timeout elements from all the outgoing subnet response
1592 record queues. NOTE that this code must also check the WINS server
1593 subnet for response records to timeout as the WINS server code
1594 can send requests to check if a client still owns a name.
1595 (Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>).
1596 ******************************************************************/
1598 void retransmit_or_expire_response_records(time_t t)
1600 struct subnet_record *subrec;
1602 for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
1603 struct response_record *rrec, *nextrrec;
1605 restart:
1607 for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
1608 nextrrec = rrec->next;
1610 if (rrec->repeat_time <= t) {
1611 if (rrec->repeat_count > 0) {
1612 /* Resend while we have a non-zero repeat_count. */
1613 if(!send_packet(rrec->packet)) {
1614 DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
1615 to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
1617 rrec->repeat_time = t + rrec->repeat_interval;
1618 rrec->repeat_count--;
1619 } else {
1620 DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
1621 on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
1624 * Check the flag in this record to prevent recursion if we end
1625 * up in this function again via the timeout function call.
1628 if(!rrec->in_expiration_processing) {
1631 * Set the recursion protection flag in this record.
1634 rrec->in_expiration_processing = True;
1636 /* Call the timeout function. This will deal with removing the
1637 timed out packet. */
1638 if(rrec->timeout_fn) {
1639 (*rrec->timeout_fn)(subrec, rrec);
1640 } else {
1641 /* We must remove the record ourself if there is
1642 no timeout function. */
1643 remove_response_record(subrec, rrec);
1645 /* We have changed subrec->responselist,
1646 * restart from the beginning of this list. */
1647 goto restart;
1648 } /* !rrec->in_expitation_processing */
1649 } /* rrec->repeat_count > 0 */
1650 } /* rrec->repeat_time <= t */
1651 } /* end for rrec */
1652 } /* end for subnet */
1655 /****************************************************************************
1656 Create an fd_set containing all the sockets in the subnet structures,
1657 plus the broadcast sockets.
1658 ***************************************************************************/
1660 static bool create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number, int *maxfd)
1662 int *sock_array = NULL;
1663 struct subnet_record *subrec = NULL;
1664 int count = 0;
1665 int num = 0;
1666 fd_set *pset = SMB_MALLOC_P(fd_set);
1668 if(pset == NULL) {
1669 DEBUG(0,("create_listen_fdset: malloc fail !\n"));
1670 return True;
1673 /* The Client* sockets */
1674 count++;
1676 /* Check that we can add all the fd's we need. */
1677 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1678 count++;
1680 /* each interface gets 4 sockets */
1681 count *= 4;
1683 if(count > FD_SETSIZE) {
1684 DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
1685 only use %d.\n", count, FD_SETSIZE));
1686 SAFE_FREE(pset);
1687 return True;
1690 if((sock_array = SMB_MALLOC_ARRAY(int, count)) == NULL) {
1691 DEBUG(0,("create_listen_fdset: malloc fail for socket array. size %d\n", count));
1692 SAFE_FREE(pset);
1693 return True;
1696 FD_ZERO(pset);
1698 /* Add in the lp_socket_address() interface on 137. */
1699 FD_SET(ClientNMB,pset);
1700 sock_array[num++] = ClientNMB;
1701 *maxfd = MAX( *maxfd, ClientNMB);
1703 /* the lp_socket_address() interface has only one socket */
1704 sock_array[num++] = -1;
1706 /* Add in the 137 sockets on all the interfaces. */
1707 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1708 FD_SET(subrec->nmb_sock,pset);
1709 sock_array[num++] = subrec->nmb_sock;
1710 *maxfd = MAX( *maxfd, subrec->nmb_sock);
1712 sock_array[num++] = subrec->nmb_bcast;
1713 if (subrec->nmb_bcast != -1) {
1714 FD_SET(subrec->nmb_bcast,pset);
1715 *maxfd = MAX( *maxfd, subrec->nmb_bcast);
1719 /* Add in the lp_socket_address() interface on 138. */
1720 FD_SET(ClientDGRAM,pset);
1721 sock_array[num++] = ClientDGRAM;
1722 *maxfd = MAX( *maxfd, ClientDGRAM);
1724 /* the lp_socket_address() interface has only one socket */
1725 sock_array[num++] = -1;
1727 /* Add in the 138 sockets on all the interfaces. */
1728 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1729 FD_SET(subrec->dgram_sock,pset);
1730 sock_array[num++] = subrec->dgram_sock;
1731 *maxfd = MAX( *maxfd, subrec->dgram_sock);
1733 sock_array[num++] = subrec->dgram_bcast;
1734 if (subrec->dgram_bcast != -1) {
1735 FD_SET(subrec->dgram_bcast,pset);
1736 *maxfd = MAX( *maxfd, subrec->dgram_bcast);
1740 *listen_number = count;
1742 SAFE_FREE(*ppset);
1743 SAFE_FREE(*psock_array);
1745 *ppset = pset;
1746 *psock_array = sock_array;
1748 return False;
1751 /****************************************************************************
1752 List of packets we're processing this select.
1753 ***************************************************************************/
1755 struct processed_packet {
1756 struct processed_packet *next;
1757 struct processed_packet *prev;
1758 enum packet_type packet_type;
1759 struct in_addr ip;
1760 int packet_id;
1763 /****************************************************************************
1764 Have we seen this before ?
1765 ***************************************************************************/
1767 static bool is_processed_packet(struct processed_packet *processed_packet_list,
1768 struct packet_struct *packet)
1770 struct processed_packet *p = NULL;
1772 for (p = processed_packet_list; p; p = p->next) {
1773 if (ip_equal_v4(p->ip, packet->ip) && p->packet_type == packet->packet_type) {
1774 if ((p->packet_type == NMB_PACKET) &&
1775 (p->packet_id ==
1776 packet->packet.nmb.header.name_trn_id)) {
1777 return true;
1778 } else if ((p->packet_type == DGRAM_PACKET) &&
1779 (p->packet_id ==
1780 packet->packet.dgram.header.dgm_id)) {
1781 return true;
1785 return false;
1788 /****************************************************************************
1789 Keep a list of what we've seen before.
1790 ***************************************************************************/
1792 static bool store_processed_packet(struct processed_packet **pp_processed_packet_list,
1793 struct packet_struct *packet)
1795 struct processed_packet *p = SMB_MALLOC_P(struct processed_packet);
1796 if (!p) {
1797 return false;
1799 p->packet_type = packet->packet_type;
1800 p->ip = packet->ip;
1801 if (packet->packet_type == NMB_PACKET) {
1802 p->packet_id = packet->packet.nmb.header.name_trn_id;
1803 } else if (packet->packet_type == DGRAM_PACKET) {
1804 p->packet_id = packet->packet.dgram.header.dgm_id;
1805 } else {
1806 return false;
1809 DLIST_ADD(*pp_processed_packet_list, p);
1810 return true;
1813 /****************************************************************************
1814 Throw away what we've seen before.
1815 ***************************************************************************/
1817 static void free_processed_packet_list(struct processed_packet **pp_processed_packet_list)
1819 struct processed_packet *p = NULL, *next = NULL;
1821 for (p = *pp_processed_packet_list; p; p = next) {
1822 next = p->next;
1823 DLIST_REMOVE(*pp_processed_packet_list, p);
1824 SAFE_FREE(p);
1828 /****************************************************************************
1829 Listens for NMB or DGRAM packets, and queues them.
1830 return True if the socket is dead
1831 ***************************************************************************/
1833 bool listen_for_packets(bool run_election)
1835 static fd_set *listen_set = NULL;
1836 static int listen_number = 0;
1837 static int *sock_array = NULL;
1838 int i;
1839 static int maxfd = 0;
1841 fd_set r_fds;
1842 fd_set w_fds;
1843 int selrtn = 0;
1844 struct timeval timeout;
1845 #ifndef SYNC_DNS
1846 int dns_fd;
1847 #endif
1848 struct processed_packet *processed_packet_list = NULL;
1850 if(listen_set == NULL || rescan_listen_set) {
1851 if(create_listen_fdset(&listen_set, &sock_array, &listen_number, &maxfd)) {
1852 DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
1853 return True;
1855 rescan_listen_set = False;
1858 memcpy((char *)&r_fds, (char *)listen_set, sizeof(fd_set));
1859 FD_ZERO(&w_fds);
1861 #ifndef SYNC_DNS
1862 dns_fd = asyncdns_fd();
1863 if (dns_fd != -1) {
1864 FD_SET(dns_fd, &r_fds);
1865 maxfd = MAX( maxfd, dns_fd);
1867 #endif
1869 /* Process a signal and timer events now... */
1870 if (run_events(nmbd_event_context(), &selrtn, NULL, NULL)) {
1871 return False;
1875 * During elections and when expecting a netbios response packet we
1876 * need to send election packets at tighter intervals.
1877 * Ideally it needs to be the interval (in ms) between time now and
1878 * the time we are expecting the next netbios packet.
1881 timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
1882 timeout.tv_usec = 0;
1885 struct timeval now = timeval_current();
1886 event_add_to_select_args(nmbd_event_context(), &now,
1887 &r_fds, &w_fds, &timeout, &maxfd);
1890 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&timeout);
1892 if (run_events(nmbd_event_context(), &selrtn, &r_fds, &w_fds)) {
1893 return False;
1896 if (selrtn == -1) {
1897 return False;
1900 #ifndef SYNC_DNS
1901 if (dns_fd != -1 && FD_ISSET(dns_fd,&r_fds)) {
1902 run_dns_queue();
1904 #endif
1906 for(i = 0; i < listen_number; i++) {
1907 enum packet_type packet_type;
1908 struct packet_struct *packet;
1909 const char *packet_name;
1910 int client_fd;
1911 int client_port;
1912 bool is_requested_send_reply = false;
1914 if (sock_array[i] == -1) {
1915 continue;
1918 if (!FD_ISSET(sock_array[i],&r_fds)) {
1919 continue;
1922 if (i < (listen_number/2)) {
1923 /* Port 137 */
1924 packet_type = NMB_PACKET;
1925 packet_name = "nmb";
1926 client_fd = ClientNMB;
1927 client_port = global_nmb_port;
1928 } else {
1929 /* Port 138 */
1930 packet_type = DGRAM_PACKET;
1931 packet_name = "dgram";
1932 client_fd = ClientDGRAM;
1933 client_port = DGRAM_PORT;
1936 packet = read_packet(sock_array[i], packet_type);
1937 if (!packet) {
1938 continue;
1941 is_requested_send_reply = is_requested_send_packet(packet);
1944 * If we got a packet on the broadcast socket and interfaces
1945 * only is set then check it came from one of our local nets.
1947 if (lp_bind_interfaces_only() &&
1948 (sock_array[i] == client_fd) &&
1949 (!is_local_net_v4(packet->ip))) {
1950 DEBUG(7,("discarding %s packet sent to broadcast socket from %s:%d\n",
1951 packet_name, inet_ntoa(packet->ip), packet->port));
1952 free_packet(packet);
1953 continue;
1956 if (!is_requested_send_reply &&
1957 (is_loopback_ip_v4(packet->ip) || ismyip_v4(packet->ip)) &&
1958 packet->port == client_port)
1960 if (client_port == DGRAM_PORT) {
1961 DEBUG(7,("discarding own dgram packet from %s:%d\n",
1962 inet_ntoa(packet->ip),packet->port));
1963 free_packet(packet);
1964 continue;
1967 if (packet->packet.nmb.header.nm_flags.bcast) {
1968 DEBUG(7,("discarding own nmb bcast packet from %s:%d\n",
1969 inet_ntoa(packet->ip),packet->port));
1970 free_packet(packet);
1971 continue;
1975 if (is_processed_packet(processed_packet_list, packet)) {
1976 DEBUG(7,("discarding duplicate packet from %s:%d\n",
1977 inet_ntoa(packet->ip),packet->port));
1978 free_packet(packet);
1979 continue;
1982 store_processed_packet(&processed_packet_list, packet);
1985 * 0,2,4,... are unicast sockets
1986 * 1,3,5,... are broadcast sockets
1988 * on broadcast socket we only receive packets
1989 * and send replies via the unicast socket.
1991 * 0,1 and 2,3 and ... belong together.
1993 if ((i % 2) != 0) {
1994 /* this is a broadcast socket */
1995 packet->send_fd = sock_array[i-1];
1996 } else {
1997 /* this is already a unicast socket */
1998 packet->send_fd = sock_array[i];
2001 queue_packet(packet);
2004 free_processed_packet_list(&processed_packet_list);
2005 return False;
2008 /****************************************************************************
2009 Construct and send a netbios DGRAM.
2010 **************************************************************************/
2012 bool send_mailslot(bool unique, const char *mailslot,char *buf, size_t len,
2013 const char *srcname, int src_type,
2014 const char *dstname, int dest_type,
2015 struct in_addr dest_ip,struct in_addr src_ip,
2016 int dest_port)
2018 bool loopback_this_packet = False;
2019 struct packet_struct p;
2020 struct dgram_packet *dgram = &p.packet.dgram;
2021 char *ptr,*p2;
2022 char tmp[4];
2024 memset((char *)&p,'\0',sizeof(p));
2026 if(ismyip_v4(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
2027 loopback_this_packet = True;
2029 /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
2031 /* DIRECT GROUP or UNIQUE datagram. */
2032 dgram->header.msg_type = unique ? 0x10 : 0x11;
2033 dgram->header.flags.node_type = M_NODE;
2034 dgram->header.flags.first = True;
2035 dgram->header.flags.more = False;
2036 dgram->header.dgm_id = generate_name_trn_id();
2037 dgram->header.source_ip = src_ip;
2038 dgram->header.source_port = DGRAM_PORT;
2039 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
2040 dgram->header.packet_offset = 0;
2042 make_nmb_name(&dgram->source_name,srcname,src_type);
2043 make_nmb_name(&dgram->dest_name,dstname,dest_type);
2045 ptr = &dgram->data[0];
2047 /* Setup the smb part. */
2048 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
2049 memcpy(tmp,ptr,4);
2051 if (smb_size + 17*2 + strlen(mailslot) + 1 + len > MAX_DGRAM_SIZE) {
2052 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
2053 return false;
2056 cli_set_message(ptr,17,strlen(mailslot) + 1 + len,True);
2057 memcpy(ptr,tmp,4);
2059 SCVAL(ptr,smb_com,SMBtrans);
2060 SSVAL(ptr,smb_vwv1,len);
2061 SSVAL(ptr,smb_vwv11,len);
2062 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
2063 SSVAL(ptr,smb_vwv13,3);
2064 SSVAL(ptr,smb_vwv14,1);
2065 SSVAL(ptr,smb_vwv15,1);
2066 SSVAL(ptr,smb_vwv16,2);
2067 p2 = smb_buf(ptr);
2068 safe_strcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
2069 p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2);
2071 if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
2072 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
2073 return False;
2074 } else {
2075 if (len) {
2076 memcpy(p2,buf,len);
2078 p2 += len;
2081 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
2083 p.ip = dest_ip;
2084 p.port = dest_port;
2085 p.recv_fd = -1;
2086 p.send_fd = find_subnet_mailslot_fd_for_address( src_ip );
2087 p.timestamp = time(NULL);
2088 p.packet_type = DGRAM_PACKET;
2090 DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
2091 nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
2092 DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
2094 debug_browse_data(buf, len);
2096 if(loopback_this_packet) {
2097 struct packet_struct *lo_packet = NULL;
2098 DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
2099 if((lo_packet = copy_packet(&p)) == NULL)
2100 return False;
2101 queue_packet(lo_packet);
2102 return True;
2103 } else {
2104 return(send_packet(&p));