source: branches/samba-3.0/source/nmbd/nmbd_packets.c

Last change on this file was 124, checked in by Paul Smedley, 17 years ago

Update source to 3.0.28a

File size: 63.2 KB
Line 
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
7
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.
12
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.
17
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.
21
22*/
23
24#include "includes.h"
25
26extern int ClientNMB;
27extern int ClientDGRAM;
28extern int global_nmb_port;
29
30extern int num_response_packets;
31
32extern struct in_addr loopback_ip;
33
34static void queue_packet(struct packet_struct *packet);
35
36BOOL rescan_listen_set = False;
37
38
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******************************************************************/
44
45static struct packet_struct *packet_queue = NULL;
46
47/***************************************************************************
48Utility function to find the specific fd to send a packet out on.
49**************************************************************************/
50
51static int find_subnet_fd_for_address( struct in_addr local_ip )
52{
53 struct subnet_record *subrec;
54
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;
58
59 return ClientNMB;
60}
61
62/***************************************************************************
63Utility function to find the specific fd to send a mailslot packet out on.
64**************************************************************************/
65
66static int find_subnet_mailslot_fd_for_address( struct in_addr local_ip )
67{
68 struct subnet_record *subrec;
69
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;
73
74 return ClientDGRAM;
75}
76
77/***************************************************************************
78Get/Set problematic nb_flags as network byte order 16 bit int.
79**************************************************************************/
80
81uint16 get_nb_flags(char *buf)
82{
83 return ((((uint16)*buf)&0xFFFF) & NB_FLGMSK);
84}
85
86void set_nb_flags(char *buf, uint16 nb_flags)
87{
88 *buf++ = ((nb_flags & NB_FLGMSK) & 0xFF);
89 *buf = '\0';
90}
91
92/***************************************************************************
93Dumps out the browse packet data.
94**************************************************************************/
95
96static void debug_browse_data(char *outbuf, int len)
97{
98 int i,j;
99
100 DEBUG( 4, ( "debug_browse_data():\n" ) );
101 for (i = 0; i < len; i+= 16) {
102 DEBUGADD( 4, ( "%3x char ", i ) );
103
104 for (j = 0; j < 16; j++) {
105 unsigned char x;
106 if (i+j >= len)
107 break;
108
109 x = outbuf[i+j];
110 if (x < 32 || x > 127)
111 x = '.';
112
113 DEBUGADD( 4, ( "%c", x ) );
114 }
115
116 DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
117
118 for (j = 0; j < 16; j++) {
119 if (i+j >= len)
120 break;
121 DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
122 }
123
124 DEBUGADD( 4, ("\n") );
125 }
126}
127
128/***************************************************************************
129 Generates the unique transaction identifier
130**************************************************************************/
131
132static uint16 name_trn_id=0;
133
134static uint16 generate_name_trn_id(void)
135{
136 if (!name_trn_id) {
137 name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
138 }
139 name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
140 return name_trn_id;
141}
142
143/***************************************************************************
144 Either loops back or sends out a completed NetBIOS packet.
145**************************************************************************/
146
147static BOOL send_netbios_packet(struct packet_struct *p)
148{
149 BOOL loopback_this_packet = False;
150
151 /* Check if we are sending to or from ourselves as a WINS server. */
152 if(ismyip(p->ip) && (p->port == global_nmb_port))
153 loopback_this_packet = True;
154
155 if(loopback_this_packet) {
156 struct packet_struct *lo_packet = NULL;
157 DEBUG(5,("send_netbios_packet: sending packet to ourselves.\n"));
158 if((lo_packet = copy_packet(p)) == NULL)
159 return False;
160 queue_packet(lo_packet);
161 } else if (!send_packet(p)) {
162 DEBUG(0,("send_netbios_packet: send_packet() to IP %s port %d failed\n",
163 inet_ntoa(p->ip),p->port));
164 return False;
165 }
166
167 return True;
168}
169
170/***************************************************************************
171 Sets up the common elements of an outgoing NetBIOS packet.
172
173 Note: do not attempt to rationalise whether rec_des should be set or not
174 in a particular situation. Just follow rfc_1002 or look at examples from WinXX.
175 It does NOT follow the rule that requests to the wins server always have
176 rec_des true. See for example name releases and refreshes
177**************************************************************************/
178
179static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmbname,
180 BOOL bcast, BOOL rec_des,
181 struct in_addr to_ip)
182{
183 struct packet_struct *packet = NULL;
184 struct nmb_packet *nmb = NULL;
185
186 /* Allocate the packet_struct we will return. */
187 if((packet = SMB_MALLOC_P(struct packet_struct)) == NULL) {
188 DEBUG(0,("create_and_init_netbios_packet: malloc fail (1) for packet struct.\n"));
189 return NULL;
190 }
191
192 memset((char *)packet,'\0',sizeof(*packet));
193
194 nmb = &packet->packet.nmb;
195
196 nmb->header.name_trn_id = generate_name_trn_id();
197 nmb->header.response = False;
198 nmb->header.nm_flags.recursion_desired = rec_des;
199 nmb->header.nm_flags.recursion_available = False;
200 nmb->header.nm_flags.trunc = False;
201 nmb->header.nm_flags.authoritative = False;
202 nmb->header.nm_flags.bcast = bcast;
203
204 nmb->header.rcode = 0;
205 nmb->header.qdcount = 1;
206 nmb->header.ancount = 0;
207 nmb->header.nscount = 0;
208
209 nmb->question.question_name = *nmbname;
210 nmb->question.question_type = QUESTION_TYPE_NB_QUERY;
211 nmb->question.question_class = QUESTION_CLASS_IN;
212
213 packet->ip = to_ip;
214 packet->port = NMB_PORT;
215 packet->fd = ClientNMB;
216 packet->timestamp = time(NULL);
217 packet->packet_type = NMB_PACKET;
218 packet->locked = False;
219
220 return packet; /* Caller must free. */
221}
222
223/***************************************************************************
224 Sets up the common elements of register, refresh or release packet.
225**************************************************************************/
226
227static BOOL create_and_init_additional_record(struct packet_struct *packet,
228 uint16 nb_flags,
229 struct in_addr *register_ip)
230{
231 struct nmb_packet *nmb = &packet->packet.nmb;
232
233 if((nmb->additional = SMB_MALLOC_P(struct res_rec)) == NULL) {
234 DEBUG(0,("initiate_name_register_packet: malloc fail for additional record.\n"));
235 return False;
236 }
237
238 memset((char *)nmb->additional,'\0',sizeof(struct res_rec));
239
240 nmb->additional->rr_name = nmb->question.question_name;
241 nmb->additional->rr_type = RR_TYPE_NB;
242 nmb->additional->rr_class = RR_CLASS_IN;
243
244 /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
245 if (nmb->header.nm_flags.bcast)
246 nmb->additional->ttl = PERMANENT_TTL;
247 else
248 nmb->additional->ttl = lp_max_ttl();
249
250 nmb->additional->rdlength = 6;
251
252 set_nb_flags(nmb->additional->rdata,nb_flags);
253
254 /* Set the address for the name we are registering. */
255 putip(&nmb->additional->rdata[2], register_ip);
256
257 /*
258 it turns out that Jeremys code was correct, we are supposed
259 to send registrations from the IP we are registering. The
260 trick is what to do on timeouts! When we send on a
261 non-routable IP then the reply will timeout, and we should
262 treat this as success, not failure. That means we go into
263 our standard refresh cycle for that name which copes nicely
264 with disconnected networks.
265 */
266 packet->fd = find_subnet_fd_for_address(*register_ip);
267
268 return True;
269}
270
271/***************************************************************************
272 Sends out a name query.
273**************************************************************************/
274
275static BOOL initiate_name_query_packet( struct packet_struct *packet)
276{
277 struct nmb_packet *nmb = NULL;
278
279 nmb = &packet->packet.nmb;
280
281 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
282 nmb->header.arcount = 0;
283
284 nmb->header.nm_flags.recursion_desired = True;
285
286 DEBUG(4,("initiate_name_query_packet: sending query for name %s (bcast=%s) to IP %s\n",
287 nmb_namestr(&nmb->question.question_name),
288 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
289
290 return send_netbios_packet( packet );
291}
292
293/***************************************************************************
294 Sends out a name query - from a WINS server.
295**************************************************************************/
296
297static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
298{
299 struct nmb_packet *nmb = NULL;
300
301 nmb = &packet->packet.nmb;
302
303 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
304 nmb->header.arcount = 0;
305
306 nmb->header.nm_flags.recursion_desired = False;
307
308 DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
309 nmb_namestr(&nmb->question.question_name),
310 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
311
312 return send_netbios_packet( packet );
313}
314
315/***************************************************************************
316 Sends out a name register.
317**************************************************************************/
318
319static BOOL initiate_name_register_packet( struct packet_struct *packet,
320 uint16 nb_flags, struct in_addr *register_ip)
321{
322 struct nmb_packet *nmb = &packet->packet.nmb;
323
324 nmb->header.opcode = NMB_NAME_REG_OPCODE;
325 nmb->header.arcount = 1;
326
327 nmb->header.nm_flags.recursion_desired = True;
328
329 if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
330 return False;
331
332 DEBUG(4,("initiate_name_register_packet: sending registration for name %s (bcast=%s) to IP %s\n",
333 nmb_namestr(&nmb->additional->rr_name),
334 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
335
336 return send_netbios_packet( packet );
337}
338
339/***************************************************************************
340 Sends out a multihomed name register.
341**************************************************************************/
342
343static BOOL initiate_multihomed_name_register_packet(struct packet_struct *packet,
344 uint16 nb_flags, struct in_addr *register_ip)
345{
346 struct nmb_packet *nmb = &packet->packet.nmb;
347 fstring second_ip_buf;
348
349 fstrcpy(second_ip_buf, inet_ntoa(packet->ip));
350
351 nmb->header.opcode = NMB_NAME_MULTIHOMED_REG_OPCODE;
352 nmb->header.arcount = 1;
353
354 nmb->header.nm_flags.recursion_desired = True;
355
356 if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
357 return False;
358
359 DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
360for name %s IP %s (bcast=%s) to IP %s\n",
361 nmb_namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
362 BOOLSTR(nmb->header.nm_flags.bcast), second_ip_buf ));
363
364 return send_netbios_packet( packet );
365}
366
367/***************************************************************************
368 Sends out a name refresh.
369**************************************************************************/
370
371static BOOL initiate_name_refresh_packet( struct packet_struct *packet,
372 uint16 nb_flags, struct in_addr *refresh_ip)
373{
374 struct nmb_packet *nmb = &packet->packet.nmb;
375
376 nmb->header.opcode = NMB_NAME_REFRESH_OPCODE_8;
377 nmb->header.arcount = 1;
378
379 nmb->header.nm_flags.recursion_desired = False;
380
381 if(create_and_init_additional_record(packet, nb_flags, refresh_ip) == False)
382 return False;
383
384 DEBUG(4,("initiate_name_refresh_packet: sending refresh for name %s (bcast=%s) to IP %s\n",
385 nmb_namestr(&nmb->additional->rr_name),
386 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
387
388 return send_netbios_packet( packet );
389}
390
391/***************************************************************************
392 Sends out a name release.
393**************************************************************************/
394
395static BOOL initiate_name_release_packet( struct packet_struct *packet,
396 uint16 nb_flags, struct in_addr *release_ip)
397{
398 struct nmb_packet *nmb = &packet->packet.nmb;
399
400 nmb->header.opcode = NMB_NAME_RELEASE_OPCODE;
401 nmb->header.arcount = 1;
402
403 nmb->header.nm_flags.recursion_desired = False;
404
405 if(create_and_init_additional_record(packet, nb_flags, release_ip) == False)
406 return False;
407
408 DEBUG(4,("initiate_name_release_packet: sending release for name %s (bcast=%s) to IP %s\n",
409 nmb_namestr(&nmb->additional->rr_name),
410 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
411
412 return send_netbios_packet( packet );
413}
414
415/***************************************************************************
416 Sends out a node status.
417**************************************************************************/
418
419static BOOL initiate_node_status_packet( struct packet_struct *packet )
420{
421 struct nmb_packet *nmb = &packet->packet.nmb;
422
423 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
424 nmb->header.arcount = 0;
425
426 nmb->header.nm_flags.recursion_desired = False;
427
428 nmb->question.question_type = QUESTION_TYPE_NB_STATUS;
429
430 DEBUG(4,("initiate_node_status_packet: sending node status request for name %s to IP %s\n",
431 nmb_namestr(&nmb->question.question_name),
432 inet_ntoa(packet->ip)));
433
434 return send_netbios_packet( packet );
435}
436
437/****************************************************************************
438 Simplification functions for queuing standard packets.
439 These should be the only publicly callable functions for sending
440 out packets.
441****************************************************************************/
442
443/****************************************************************************
444 Assertion - we should never be sending nmbd packets on the remote
445 broadcast subnet.
446****************************************************************************/
447
448static BOOL assert_check_subnet(struct subnet_record *subrec)
449{
450 if( subrec == remote_broadcast_subnet) {
451 DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
452This is a bug.\n"));
453 return True;
454 }
455 return False;
456}
457
458/****************************************************************************
459 Queue a register name packet to the broadcast address of a subnet.
460****************************************************************************/
461
462struct response_record *queue_register_name( struct subnet_record *subrec,
463 response_function resp_fn,
464 timeout_response_function timeout_fn,
465 register_name_success_function success_fn,
466 register_name_fail_function fail_fn,
467 struct userdata_struct *userdata,
468 struct nmb_name *nmbname,
469 uint16 nb_flags)
470{
471 struct packet_struct *p;
472 struct response_record *rrec;
473
474 if(assert_check_subnet(subrec))
475 return NULL;
476
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;
481
482 if(initiate_name_register_packet( p, nb_flags, iface_ip(subrec->bcast_ip)) == False) {
483 p->locked = False;
484 free_packet(p);
485 return NULL;
486 }
487
488 if((rrec = make_response_record(subrec, /* subnet record. */
489 p, /* packet we sent. */
490 resp_fn, /* function to call on response. */
491 timeout_fn, /* function to call on timeout. */
492 (success_function)success_fn, /* function to call on operation success. */
493 (fail_function)fail_fn, /* function to call on operation fail. */
494 userdata)) == NULL) {
495 p->locked = False;
496 free_packet(p);
497 return NULL;
498 }
499
500 return rrec;
501}
502
503/****************************************************************************
504 Queue a refresh name packet to the broadcast address of a subnet.
505****************************************************************************/
506
507void queue_wins_refresh(struct nmb_name *nmbname,
508 response_function resp_fn,
509 timeout_response_function timeout_fn,
510 uint16 nb_flags,
511 struct in_addr refresh_ip,
512 const char *tag)
513{
514 struct packet_struct *p;
515 struct response_record *rrec;
516 struct in_addr wins_ip;
517 struct userdata_struct *userdata;
518 fstring ip_str;
519
520 wins_ip = wins_srv_ip_tag(tag, refresh_ip);
521
522 if ((p = create_and_init_netbios_packet(nmbname, False, False, wins_ip)) == NULL) {
523 return;
524 }
525
526 if (!initiate_name_refresh_packet(p, nb_flags, &refresh_ip)) {
527 p->locked = False;
528 free_packet(p);
529 return;
530 }
531
532 fstrcpy(ip_str, inet_ntoa(refresh_ip));
533
534 DEBUG(6,("Refreshing name %s IP %s with WINS server %s using tag '%s'\n",
535 nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
536
537 userdata = (struct userdata_struct *)SMB_MALLOC(sizeof(*userdata) + strlen(tag) + 1);
538 if (!userdata) {
539 p->locked = False;
540 free_packet(p);
541 DEBUG(0,("Failed to allocate userdata structure!\n"));
542 return;
543 }
544 ZERO_STRUCTP(userdata);
545 userdata->userdata_len = strlen(tag) + 1;
546 strlcpy(userdata->data, tag, userdata->userdata_len);
547
548 if ((rrec = make_response_record(unicast_subnet,
549 p,
550 resp_fn, timeout_fn,
551 NULL,
552 NULL,
553 userdata)) == NULL) {
554 p->locked = False;
555 free_packet(p);
556 return;
557 }
558
559 free(userdata);
560
561 /* we don't want to repeat refresh packets */
562 rrec->repeat_count = 0;
563}
564
565
566/****************************************************************************
567 Queue a multihomed register name packet to a given WINS server IP
568****************************************************************************/
569
570struct response_record *queue_register_multihomed_name( struct subnet_record *subrec,
571 response_function resp_fn,
572 timeout_response_function timeout_fn,
573 register_name_success_function success_fn,
574 register_name_fail_function fail_fn,
575 struct userdata_struct *userdata,
576 struct nmb_name *nmbname,
577 uint16 nb_flags,
578 struct in_addr register_ip,
579 struct in_addr wins_ip)
580{
581 struct packet_struct *p;
582 struct response_record *rrec;
583 BOOL ret;
584
585 /* Sanity check. */
586 if(subrec != unicast_subnet) {
587 DEBUG(0,("queue_register_multihomed_name: should only be done on \
588unicast subnet. subnet is %s\n.", subrec->subnet_name ));
589 return NULL;
590 }
591
592 if(assert_check_subnet(subrec))
593 return NULL;
594
595 if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL)
596 return NULL;
597
598 if (nb_flags & NB_GROUP)
599 ret = initiate_name_register_packet( p, nb_flags, &register_ip);
600 else
601 ret = initiate_multihomed_name_register_packet(p, nb_flags, &register_ip);
602
603 if (ret == False) {
604 p->locked = False;
605 free_packet(p);
606 return NULL;
607 }
608
609 if ((rrec = make_response_record(subrec, /* subnet record. */
610 p, /* packet we sent. */
611 resp_fn, /* function to call on response. */
612 timeout_fn, /* function to call on timeout. */
613 (success_function)success_fn, /* function to call on operation success. */
614 (fail_function)fail_fn, /* function to call on operation fail. */
615 userdata)) == NULL) {
616 p->locked = False;
617 free_packet(p);
618 return NULL;
619 }
620
621 return rrec;
622}
623
624/****************************************************************************
625 Queue a release name packet to the broadcast address of a subnet.
626****************************************************************************/
627
628struct response_record *queue_release_name( struct subnet_record *subrec,
629 response_function resp_fn,
630 timeout_response_function timeout_fn,
631 release_name_success_function success_fn,
632 release_name_fail_function fail_fn,
633 struct userdata_struct *userdata,
634 struct nmb_name *nmbname,
635 uint16 nb_flags,
636 struct in_addr release_ip,
637 struct in_addr dest_ip)
638{
639 struct packet_struct *p;
640 struct response_record *rrec;
641
642 if(assert_check_subnet(subrec))
643 return NULL;
644
645 if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False, dest_ip)) == NULL)
646 return NULL;
647
648 if(initiate_name_release_packet( p, nb_flags, &release_ip) == False) {
649 p->locked = False;
650 free_packet(p);
651 return NULL;
652 }
653
654 if((rrec = make_response_record(subrec, /* subnet record. */
655 p, /* packet we sent. */
656 resp_fn, /* function to call on response. */
657 timeout_fn, /* function to call on timeout. */
658 (success_function)success_fn, /* function to call on operation success. */
659 (fail_function)fail_fn, /* function to call on operation fail. */
660 userdata)) == NULL) {
661 p->locked = False;
662 free_packet(p);
663 return NULL;
664 }
665
666 /*
667 * For a broadcast release packet, only send once.
668 * This will cause us to remove the name asap. JRA.
669 */
670
671 if (subrec != unicast_subnet) {
672 rrec->repeat_count = 0;
673 rrec->repeat_time = 0;
674 }
675
676 return rrec;
677}
678
679/****************************************************************************
680 Queue a query name packet to the broadcast address of a subnet.
681****************************************************************************/
682
683struct response_record *queue_query_name( struct subnet_record *subrec,
684 response_function resp_fn,
685 timeout_response_function timeout_fn,
686 query_name_success_function success_fn,
687 query_name_fail_function fail_fn,
688 struct userdata_struct *userdata,
689 struct nmb_name *nmbname)
690{
691 struct packet_struct *p;
692 struct response_record *rrec;
693 struct in_addr to_ip;
694
695 if(assert_check_subnet(subrec))
696 return NULL;
697
698 to_ip = subrec->bcast_ip;
699
700 /* queries to the WINS server turn up here as queries to IP 0.0.0.0
701 These need to be handled a bit differently */
702 if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
703 /* What we really need to do is loop over each of our wins
704 * servers and wins server tags here, but that just doesn't
705 * fit our architecture at the moment (userdata may already
706 * be used when we get here). For now we just query the first
707 * active wins server on the first tag.
708 */
709 char **tags = wins_srv_tags();
710 if (!tags) {
711 return NULL;
712 }
713 to_ip = wins_srv_ip_tag(tags[0], to_ip);
714 wins_srv_tags_free(tags);
715 }
716
717 if(( p = create_and_init_netbios_packet(nmbname,
718 (subrec != unicast_subnet),
719 (subrec == unicast_subnet),
720 to_ip)) == NULL)
721 return NULL;
722
723 if(lp_bind_interfaces_only()) {
724 int i;
725
726 DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
727 for(i = 0; i < iface_count(); i++) {
728 struct in_addr *ifip = iface_n_ip(i);
729
730 if(ifip == NULL) {
731 DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
732 continue;
733 }
734
735 if (ip_equal(*ifip,loopback_ip)) {
736 DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
737 continue;
738 }
739
740 DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
741 p->fd = find_subnet_fd_for_address( *ifip );
742 break;
743 }
744 }
745
746 if(initiate_name_query_packet( p ) == False) {
747 p->locked = False;
748 free_packet(p);
749 return NULL;
750 }
751
752 if((rrec = make_response_record(subrec, /* subnet record. */
753 p, /* packet we sent. */
754 resp_fn, /* function to call on response. */
755 timeout_fn, /* function to call on timeout. */
756 (success_function)success_fn, /* function to call on operation success. */
757 (fail_function)fail_fn, /* function to call on operation fail. */
758 userdata)) == NULL) {
759 p->locked = False;
760 free_packet(p);
761 return NULL;
762 }
763
764 return rrec;
765}
766
767/****************************************************************************
768 Queue a query name packet to a given address from the WINS subnet.
769****************************************************************************/
770
771struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
772 response_function resp_fn,
773 timeout_response_function timeout_fn,
774 query_name_success_function success_fn,
775 query_name_fail_function fail_fn,
776 struct userdata_struct *userdata,
777 struct nmb_name *nmbname)
778{
779 struct packet_struct *p;
780 struct response_record *rrec;
781
782 if ((p = create_and_init_netbios_packet(nmbname, False, False, to_ip)) == NULL)
783 return NULL;
784
785 if(initiate_name_query_packet_from_wins_server( p ) == False) {
786 p->locked = False;
787 free_packet(p);
788 return NULL;
789 }
790
791 if((rrec = make_response_record(wins_server_subnet, /* subnet record. */
792 p, /* packet we sent. */
793 resp_fn, /* function to call on response. */
794 timeout_fn, /* function to call on timeout. */
795 (success_function)success_fn, /* function to call on operation success. */
796 (fail_function)fail_fn, /* function to call on operation fail. */
797 userdata)) == NULL) {
798 p->locked = False;
799 free_packet(p);
800 return NULL;
801 }
802
803 return rrec;
804}
805
806/****************************************************************************
807 Queue a node status packet to a given name and address.
808****************************************************************************/
809
810struct response_record *queue_node_status( struct subnet_record *subrec,
811 response_function resp_fn,
812 timeout_response_function timeout_fn,
813 node_status_success_function success_fn,
814 node_status_fail_function fail_fn,
815 struct userdata_struct *userdata,
816 struct nmb_name *nmbname,
817 struct in_addr send_ip)
818{
819 struct packet_struct *p;
820 struct response_record *rrec;
821
822 /* Sanity check. */
823 if(subrec != unicast_subnet) {
824 DEBUG(0,("queue_register_multihomed_name: should only be done on \
825unicast subnet. subnet is %s\n.", subrec->subnet_name ));
826 return NULL;
827 }
828
829 if(assert_check_subnet(subrec))
830 return NULL;
831
832 if(( p = create_and_init_netbios_packet(nmbname, False, False, send_ip)) == NULL)
833 return NULL;
834
835 if(initiate_node_status_packet(p) == False) {
836 p->locked = False;
837 free_packet(p);
838 return NULL;
839 }
840
841 if((rrec = make_response_record(subrec, /* subnet record. */
842 p, /* packet we sent. */
843 resp_fn, /* function to call on response. */
844 timeout_fn, /* function to call on timeout. */
845 (success_function)success_fn, /* function to call on operation success. */
846 (fail_function)fail_fn, /* function to call on operation fail. */
847 userdata)) == NULL) {
848 p->locked = False;
849 free_packet(p);
850 return NULL;
851 }
852
853 return rrec;
854}
855
856/****************************************************************************
857 Reply to a netbios name packet. see rfc1002.txt
858****************************************************************************/
859
860void reply_netbios_packet(struct packet_struct *orig_packet,
861 int rcode, enum netbios_reply_type_code rcv_code, int opcode,
862 int ttl, char *data,int len)
863{
864 struct packet_struct packet;
865 struct nmb_packet *nmb = NULL;
866 struct res_rec answers;
867 struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
868 BOOL loopback_this_packet = False;
869 int rr_type = RR_TYPE_NB;
870 const char *packet_type = "unknown";
871
872 /* Check if we are sending to or from ourselves. */
873 if(ismyip(orig_packet->ip) && (orig_packet->port == global_nmb_port))
874 loopback_this_packet = True;
875
876 nmb = &packet.packet.nmb;
877
878 /* Do a partial copy of the packet. We clear the locked flag and
879 the resource record pointers. */
880 packet = *orig_packet; /* Full structure copy. */
881 packet.locked = False;
882 nmb->answers = NULL;
883 nmb->nsrecs = NULL;
884 nmb->additional = NULL;
885
886 switch (rcv_code) {
887 case NMB_STATUS:
888 packet_type = "nmb_status";
889 nmb->header.nm_flags.recursion_desired = False;
890 nmb->header.nm_flags.recursion_available = False;
891 rr_type = RR_TYPE_NBSTAT;
892 break;
893 case NMB_QUERY:
894 packet_type = "nmb_query";
895 nmb->header.nm_flags.recursion_desired = True;
896 nmb->header.nm_flags.recursion_available = True;
897 if (rcode) {
898 rr_type = RR_TYPE_NULL;
899 }
900 break;
901 case NMB_REG:
902 case NMB_REG_REFRESH:
903 packet_type = "nmb_reg";
904 nmb->header.nm_flags.recursion_desired = True;
905 nmb->header.nm_flags.recursion_available = True;
906 break;
907 case NMB_REL:
908 packet_type = "nmb_rel";
909 nmb->header.nm_flags.recursion_desired = False;
910 nmb->header.nm_flags.recursion_available = False;
911 break;
912 case NMB_WAIT_ACK:
913 packet_type = "nmb_wack";
914 nmb->header.nm_flags.recursion_desired = False;
915 nmb->header.nm_flags.recursion_available = False;
916 rr_type = RR_TYPE_NULL;
917 break;
918 case WINS_REG:
919 packet_type = "wins_reg";
920 nmb->header.nm_flags.recursion_desired = True;
921 nmb->header.nm_flags.recursion_available = True;
922 break;
923 case WINS_QUERY:
924 packet_type = "wins_query";
925 nmb->header.nm_flags.recursion_desired = True;
926 nmb->header.nm_flags.recursion_available = True;
927 if (rcode) {
928 rr_type = RR_TYPE_NULL;
929 }
930 break;
931 default:
932 DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
933 packet_type, nmb_namestr(&orig_nmb->question.question_name),
934 inet_ntoa(packet.ip)));
935 return;
936 }
937
938 DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
939for id %hu\n", packet_type, nmb_namestr(&orig_nmb->question.question_name),
940 inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
941
942 nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
943 nmb->header.opcode = opcode;
944 nmb->header.response = True;
945 nmb->header.nm_flags.bcast = False;
946 nmb->header.nm_flags.trunc = False;
947 nmb->header.nm_flags.authoritative = True;
948
949 nmb->header.rcode = rcode;
950 nmb->header.qdcount = 0;
951 nmb->header.ancount = 1;
952 nmb->header.nscount = 0;
953 nmb->header.arcount = 0;
954
955 memset((char*)&nmb->question,'\0',sizeof(nmb->question));
956
957 nmb->answers = &answers;
958 memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
959
960 nmb->answers->rr_name = orig_nmb->question.question_name;
961 nmb->answers->rr_type = rr_type;
962 nmb->answers->rr_class = RR_CLASS_IN;
963 nmb->answers->ttl = ttl;
964
965 if (data && len) {
966 if (len < 0 || len > sizeof(nmb->answers->rdata)) {
967 DEBUG(5,("reply_netbios_packet: "
968 "invalid packet len (%d)\n",
969 len ));
970 return;
971 }
972 nmb->answers->rdlength = len;
973 memcpy(nmb->answers->rdata, data, len);
974 }
975
976 packet.packet_type = NMB_PACKET;
977 /* Ensure we send out on the same fd that the original
978 packet came in on to give the correct source IP address. */
979 packet.fd = orig_packet->fd;
980 packet.timestamp = time(NULL);
981
982 debug_nmb_packet(&packet);
983
984 if(loopback_this_packet) {
985 struct packet_struct *lo_packet;
986 DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
987 if((lo_packet = copy_packet(&packet)) == NULL)
988 return;
989 queue_packet(lo_packet);
990 } else if (!send_packet(&packet)) {
991 DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
992 inet_ntoa(packet.ip),packet.port));
993 }
994}
995
996/*******************************************************************
997 Queue a packet into a packet queue
998******************************************************************/
999
1000static void queue_packet(struct packet_struct *packet)
1001{
1002 struct packet_struct *p;
1003
1004 if (!packet_queue) {
1005 packet->prev = NULL;
1006 packet->next = NULL;
1007 packet_queue = packet;
1008 return;
1009 }
1010
1011 /* find the bottom */
1012 for (p=packet_queue;p->next;p=p->next)
1013 ;
1014
1015 p->next = packet;
1016 packet->next = NULL;
1017 packet->prev = p;
1018}
1019
1020/****************************************************************************
1021 Try and find a matching subnet record for a datagram port 138 packet.
1022****************************************************************************/
1023
1024static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_struct *p)
1025{
1026 struct subnet_record *subrec;
1027
1028 /* Go through all the broadcast subnets and see if the mask matches. */
1029 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1030 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1031 return subrec;
1032 }
1033
1034 /* If the subnet record is the remote announce broadcast subnet,
1035 hack it here to be the first subnet. This is really gross and
1036 is needed due to people turning on port 137/138 broadcast
1037 forwarding on their routers. May fire and brimstone rain
1038 down upon them...
1039 */
1040
1041 return FIRST_SUBNET;
1042}
1043
1044/****************************************************************************
1045Dispatch a browse frame from port 138 to the correct processing function.
1046****************************************************************************/
1047
1048static void process_browse_packet(struct packet_struct *p, char *buf,int len)
1049{
1050 struct dgram_packet *dgram = &p->packet.dgram;
1051 int command = CVAL(buf,0);
1052 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1053 char scope[64];
1054 unstring src_name;
1055
1056 /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
1057 pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
1058 if (!strequal(scope, global_scope())) {
1059 DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
1060mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
1061 return;
1062 }
1063
1064 pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
1065 if (is_myname(src_name)) {
1066 DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
1067%s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1068 return;
1069 }
1070
1071 switch (command) {
1072 case ANN_HostAnnouncement:
1073 debug_browse_data(buf, len);
1074 process_host_announce(subrec, p, buf+1);
1075 break;
1076 case ANN_DomainAnnouncement:
1077 debug_browse_data(buf, len);
1078 process_workgroup_announce(subrec, p, buf+1);
1079 break;
1080 case ANN_LocalMasterAnnouncement:
1081 debug_browse_data(buf, len);
1082 process_local_master_announce(subrec, p, buf+1);
1083 break;
1084 case ANN_AnnouncementRequest:
1085 debug_browse_data(buf, len);
1086 process_announce_request(subrec, p, buf+1);
1087 break;
1088 case ANN_Election:
1089 debug_browse_data(buf, len);
1090 process_election(subrec, p, buf+1);
1091 break;
1092 case ANN_GetBackupListReq:
1093 debug_browse_data(buf, len);
1094 process_get_backup_list_request(subrec, p, buf+1);
1095 break;
1096 case ANN_GetBackupListResp:
1097 debug_browse_data(buf, len);
1098 /* We never send ANN_GetBackupListReq so we should never get these. */
1099 DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
1100packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
1101 break;
1102 case ANN_ResetBrowserState:
1103 debug_browse_data(buf, len);
1104 process_reset_browser(subrec, p, buf+1);
1105 break;
1106 case ANN_MasterAnnouncement:
1107 /* Master browser datagrams must be processed on the unicast subnet. */
1108 subrec = unicast_subnet;
1109
1110 debug_browse_data(buf, len);
1111 process_master_browser_announce(subrec, p, buf+1);
1112 break;
1113 case ANN_BecomeBackup:
1114 /*
1115 * We don't currently implement this. Log it just in case.
1116 */
1117 debug_browse_data(buf, len);
1118 DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
1119command ANN_BecomeBackup from %s IP %s to %s\n", subrec->subnet_name, nmb_namestr(&dgram->source_name),
1120 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1121 break;
1122 default:
1123 debug_browse_data(buf, len);
1124 DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
1125command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1126 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1127 break;
1128 }
1129}
1130
1131/****************************************************************************
1132 Dispatch a LanMan browse frame from port 138 to the correct processing function.
1133****************************************************************************/
1134
1135static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
1136{
1137 struct dgram_packet *dgram = &p->packet.dgram;
1138 int command = SVAL(buf,0);
1139 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1140 char scope[64];
1141 unstring src_name;
1142
1143 /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
1144
1145 pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
1146 if (!strequal(scope, global_scope())) {
1147 DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
1148mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
1149 return;
1150 }
1151
1152 pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
1153 if (is_myname(src_name)) {
1154 DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
1155%s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1156 return;
1157 }
1158
1159 switch (command) {
1160 case ANN_HostAnnouncement:
1161 debug_browse_data(buf, len);
1162 process_lm_host_announce(subrec, p, buf+1, len > 1 ? len-1 : 0);
1163 break;
1164 case ANN_AnnouncementRequest:
1165 process_lm_announce_request(subrec, p, buf+1, len > 1 ? len-1 : 0);
1166 break;
1167 default:
1168 DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
1169command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1170 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1171 break;
1172 }
1173}
1174
1175/****************************************************************************
1176 Determine if a packet is for us on port 138. Note that to have any chance of
1177 being efficient we need to drop as many packets as possible at this
1178 stage as subsequent processing is expensive.
1179****************************************************************************/
1180
1181static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
1182{
1183 struct subnet_record *subrec = NULL;
1184
1185 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1186 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1187 break;
1188 }
1189
1190 if(subrec == NULL)
1191 subrec = unicast_subnet;
1192
1193 return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
1194}
1195
1196/****************************************************************************
1197 Process udp 138 datagrams
1198****************************************************************************/
1199
1200static void process_dgram(struct packet_struct *p)
1201{
1202 char *buf;
1203 char *buf2;
1204 int len;
1205 struct dgram_packet *dgram = &p->packet.dgram;
1206
1207 /* If we aren't listening to the destination name then ignore the packet */
1208 if (!listening(p,&dgram->dest_name)) {
1209 unexpected_packet(p);
1210 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
1211 nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
1212 return;
1213 }
1214
1215 if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) {
1216 unexpected_packet(p);
1217 /* Don't process error packets etc yet */
1218 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
1219an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
1220 return;
1221 }
1222
1223 /* Ensure we have a large enough packet before looking inside. */
1224 if (dgram->datasize < (smb_vwv12 - 2)) {
1225 /* That's the offset minus the 4 byte length + 2 bytes of offset. */
1226 DEBUG(0,("process_dgram: ignoring too short dgram packet (%u) sent to name %s from IP %s\n",
1227 (unsigned int)dgram->datasize,
1228 nmb_namestr(&dgram->dest_name),
1229 inet_ntoa(p->ip) ));
1230 return;
1231 }
1232
1233 buf = &dgram->data[0];
1234 buf -= 4; /* XXXX for the pseudo tcp length - someday I need to get rid of this */
1235
1236 if (CVAL(buf,smb_com) != SMBtrans)
1237 return;
1238
1239 len = SVAL(buf,smb_vwv11);
1240 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1241
1242 if (len <= 0 || len > dgram->datasize) {
1243 DEBUG(0,("process_dgram: ignoring malformed1 (datasize = %d, len = %d) datagram \
1244packet sent to name %s from IP %s\n",
1245 dgram->datasize,
1246 len,
1247 nmb_namestr(&dgram->dest_name),
1248 inet_ntoa(p->ip) ));
1249 return;
1250 }
1251
1252 if (buf2 < dgram->data || (buf2 >= dgram->data + dgram->datasize)) {
1253 DEBUG(0,("process_dgram: ignoring malformed2 (datasize = %d, len=%d, off=%d) datagram \
1254packet sent to name %s from IP %s\n",
1255 dgram->datasize,
1256 len,
1257 (int)PTR_DIFF(buf2, dgram->data),
1258 nmb_namestr(&dgram->dest_name),
1259 inet_ntoa(p->ip) ));
1260 return;
1261 }
1262
1263 if ((buf2 + len < dgram->data) || (buf2 + len > dgram->data + dgram->datasize)) {
1264 DEBUG(0,("process_dgram: ignoring malformed3 (datasize = %d, len=%d, off=%d) datagram \
1265packet sent to name %s from IP %s\n",
1266 dgram->datasize,
1267 len,
1268 (int)PTR_DIFF(buf2, dgram->data),
1269 nmb_namestr(&dgram->dest_name),
1270 inet_ntoa(p->ip) ));
1271 return;
1272 }
1273
1274 DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
1275 nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
1276 inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
1277
1278 /* Datagram packet received for the browser mailslot */
1279 if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
1280 process_browse_packet(p,buf2,len);
1281 return;
1282 }
1283
1284 /* Datagram packet received for the LAN Manager mailslot */
1285 if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
1286 process_lanman_packet(p,buf2,len);
1287 return;
1288 }
1289
1290 /* Datagram packet received for the domain logon mailslot */
1291 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
1292 process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
1293 return;
1294 }
1295
1296 /* Datagram packet received for the NT domain logon mailslot */
1297 if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT)) {
1298 process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
1299 return;
1300 }
1301
1302 unexpected_packet(p);
1303}
1304
1305/****************************************************************************
1306 Validate a response nmb packet.
1307****************************************************************************/
1308
1309static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
1310{
1311 BOOL ignore = False;
1312
1313 switch (nmb->header.opcode) {
1314 case NMB_NAME_REG_OPCODE:
1315 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1316 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1317 if (nmb->header.ancount == 0) {
1318 DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
1319 ignore = True;
1320 }
1321 break;
1322
1323 case NMB_NAME_QUERY_OPCODE:
1324 if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1)) {
1325 DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
1326 ignore = True;
1327 }
1328 break;
1329
1330 case NMB_NAME_RELEASE_OPCODE:
1331 if (nmb->header.ancount == 0) {
1332 DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
1333 ignore = True;
1334 }
1335 break;
1336
1337 case NMB_WACK_OPCODE:
1338 /* Check WACK response here. */
1339 if (nmb->header.ancount != 1) {
1340 DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
1341 ignore = True;
1342 }
1343 break;
1344 default:
1345 DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
1346 nmb->header.opcode));
1347 return True;
1348 }
1349
1350 if(ignore)
1351 DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
1352
1353 return ignore;
1354}
1355
1356/****************************************************************************
1357 Validate a request nmb packet.
1358****************************************************************************/
1359
1360static BOOL validate_nmb_packet( struct nmb_packet *nmb )
1361{
1362 BOOL ignore = False;
1363
1364 switch (nmb->header.opcode) {
1365 case NMB_NAME_REG_OPCODE:
1366 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1367 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1368 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1369 if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
1370 DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
1371 ignore = True;
1372 }
1373 break;
1374
1375 case NMB_NAME_QUERY_OPCODE:
1376 if ((nmb->header.qdcount == 0) || ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
1377 (nmb->question.question_type != QUESTION_TYPE_NB_STATUS))) {
1378 DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
1379 ignore = True;
1380 }
1381 break;
1382
1383 case NMB_NAME_RELEASE_OPCODE:
1384 if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
1385 DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
1386 ignore = True;
1387 }
1388 break;
1389 default:
1390 DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
1391 nmb->header.opcode));
1392 return True;
1393 }
1394
1395 if(ignore)
1396 DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
1397
1398 return ignore;
1399}
1400
1401/****************************************************************************
1402 Find a subnet (and potentially a response record) for a packet.
1403****************************************************************************/
1404
1405static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,
1406 struct response_record **pprrec)
1407{
1408 struct nmb_packet *nmb = &p->packet.nmb;
1409 struct response_record *rrec = NULL;
1410 struct subnet_record *subrec = NULL;
1411
1412 if(pprrec != NULL)
1413 *pprrec = NULL;
1414
1415 if(nmb->header.response) {
1416 /* It's a response packet. Find a record for it or it's an error. */
1417
1418 rrec = find_response_record( &subrec, nmb->header.name_trn_id);
1419 if(rrec == NULL) {
1420 DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
1421 nmb->header.name_trn_id));
1422 unexpected_packet(p);
1423 return NULL;
1424 }
1425
1426 if(subrec == NULL) {
1427 DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
1428 nmb->header.name_trn_id));
1429 return NULL;
1430 }
1431
1432 if(pprrec != NULL)
1433 *pprrec = rrec;
1434 return subrec;
1435 }
1436
1437 /* Try and see what subnet this packet belongs to. */
1438
1439 /* WINS server ? */
1440 if(packet_is_for_wins_server(p))
1441 return wins_server_subnet;
1442
1443 /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
1444 if(nmb->header.nm_flags.bcast == False)
1445 return unicast_subnet;
1446
1447 /* Go through all the broadcast subnets and see if the mask matches. */
1448 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1449 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
1450 return subrec;
1451 }
1452
1453 /* If none match it must have been a directed broadcast - assign the remote_broadcast_subnet. */
1454 return remote_broadcast_subnet;
1455}
1456
1457/****************************************************************************
1458 Process a nmb request packet - validate the packet and route it.
1459****************************************************************************/
1460
1461static void process_nmb_request(struct packet_struct *p)
1462{
1463 struct nmb_packet *nmb = &p->packet.nmb;
1464 struct subnet_record *subrec = NULL;
1465
1466 debug_nmb_packet(p);
1467
1468 /* Ensure we have a good packet. */
1469 if(validate_nmb_packet(nmb))
1470 return;
1471
1472 /* Allocate a subnet to this packet - if we cannot - fail. */
1473 if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
1474 return;
1475
1476 switch (nmb->header.opcode) {
1477 case NMB_NAME_REG_OPCODE:
1478 if(subrec == wins_server_subnet)
1479 wins_process_name_registration_request(subrec, p);
1480 else
1481 process_name_registration_request(subrec, p);
1482 break;
1483
1484 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1485 case NMB_NAME_REFRESH_OPCODE_9:
1486 if(subrec == wins_server_subnet)
1487 wins_process_name_refresh_request(subrec, p);
1488 else
1489 process_name_refresh_request(subrec, p);
1490 break;
1491
1492 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1493 if(subrec == wins_server_subnet) {
1494 wins_process_multihomed_name_registration_request(subrec, p);
1495 } else {
1496 DEBUG(0,("process_nmb_request: Multihomed registration request must be \
1497directed at a WINS server.\n"));
1498 }
1499 break;
1500
1501 case NMB_NAME_QUERY_OPCODE:
1502 switch (nmb->question.question_type) {
1503 case QUESTION_TYPE_NB_QUERY:
1504 if(subrec == wins_server_subnet)
1505 wins_process_name_query_request(subrec, p);
1506 else
1507 process_name_query_request(subrec, p);
1508 break;
1509 case QUESTION_TYPE_NB_STATUS:
1510 if(subrec == wins_server_subnet) {
1511 DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
1512not allowed.\n"));
1513 break;
1514 } else {
1515 process_node_status_request(subrec, p);
1516 }
1517 break;
1518 }
1519 break;
1520
1521 case NMB_NAME_RELEASE_OPCODE:
1522 if(subrec == wins_server_subnet)
1523 wins_process_name_release_request(subrec, p);
1524 else
1525 process_name_release_request(subrec, p);
1526 break;
1527 }
1528}
1529
1530/****************************************************************************
1531 Process a nmb response packet - validate the packet and route it.
1532 to either the WINS server or a normal response.
1533****************************************************************************/
1534
1535static void process_nmb_response(struct packet_struct *p)
1536{
1537 struct nmb_packet *nmb = &p->packet.nmb;
1538 struct subnet_record *subrec = NULL;
1539 struct response_record *rrec = NULL;
1540
1541 debug_nmb_packet(p);
1542
1543 if(validate_nmb_response_packet(nmb))
1544 return;
1545
1546 if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
1547 return;
1548
1549 if(rrec == NULL) {
1550 DEBUG(0,("process_nmb_response: response packet received but no response record \
1551found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));
1552 return;
1553 }
1554
1555 /* Increment the number of responses received for this record. */
1556 rrec->num_msgs++;
1557 /* Ensure we don't re-send the request. */
1558 rrec->repeat_count = 0;
1559
1560 /* Call the response received function for this packet. */
1561 (*rrec->resp_fn)(subrec, rrec, p);
1562}
1563
1564/*******************************************************************
1565 Run elements off the packet queue till its empty
1566******************************************************************/
1567
1568void run_packet_queue(void)
1569{
1570 struct packet_struct *p;
1571
1572 while ((p = packet_queue)) {
1573 packet_queue = p->next;
1574 if (packet_queue)
1575 packet_queue->prev = NULL;
1576 p->next = p->prev = NULL;
1577
1578 switch (p->packet_type) {
1579 case NMB_PACKET:
1580 if(p->packet.nmb.header.response)
1581 process_nmb_response(p);
1582 else
1583 process_nmb_request(p);
1584 break;
1585
1586 case DGRAM_PACKET:
1587 process_dgram(p);
1588 break;
1589 }
1590 free_packet(p);
1591 }
1592}
1593
1594/*******************************************************************
1595 Retransmit or timeout elements from all the outgoing subnet response
1596 record queues. NOTE that this code must also check the WINS server
1597 subnet for response records to timeout as the WINS server code
1598 can send requests to check if a client still owns a name.
1599 (Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>).
1600******************************************************************/
1601
1602void retransmit_or_expire_response_records(time_t t)
1603{
1604 struct subnet_record *subrec;
1605
1606 for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
1607 struct response_record *rrec, *nextrrec;
1608
1609 restart:
1610
1611 for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
1612 nextrrec = rrec->next;
1613
1614 if (rrec->repeat_time <= t) {
1615 if (rrec->repeat_count > 0) {
1616 /* Resend while we have a non-zero repeat_count. */
1617 if(!send_packet(rrec->packet)) {
1618 DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
1619to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
1620 }
1621 rrec->repeat_time = t + rrec->repeat_interval;
1622 rrec->repeat_count--;
1623 } else {
1624 DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
1625on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
1626
1627 /*
1628 * Check the flag in this record to prevent recursion if we end
1629 * up in this function again via the timeout function call.
1630 */
1631
1632 if(!rrec->in_expiration_processing) {
1633
1634 /*
1635 * Set the recursion protection flag in this record.
1636 */
1637
1638 rrec->in_expiration_processing = True;
1639
1640 /* Call the timeout function. This will deal with removing the
1641 timed out packet. */
1642 if(rrec->timeout_fn) {
1643 (*rrec->timeout_fn)(subrec, rrec);
1644 } else {
1645 /* We must remove the record ourself if there is
1646 no timeout function. */
1647 remove_response_record(subrec, rrec);
1648 }
1649 /* We have changed subrec->responselist,
1650 * restart from the beginning of this list. */
1651 goto restart;
1652 } /* !rrec->in_expitation_processing */
1653 } /* rrec->repeat_count > 0 */
1654 } /* rrec->repeat_time <= t */
1655 } /* end for rrec */
1656 } /* end for subnet */
1657}
1658
1659/****************************************************************************
1660 Create an fd_set containing all the sockets in the subnet structures,
1661 plus the broadcast sockets.
1662***************************************************************************/
1663
1664static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number, int *maxfd)
1665{
1666 int *sock_array = NULL;
1667 struct subnet_record *subrec = NULL;
1668 int count = 0;
1669 int num = 0;
1670 fd_set *pset = SMB_MALLOC_P(fd_set);
1671
1672 if(pset == NULL) {
1673 DEBUG(0,("create_listen_fdset: malloc fail !\n"));
1674 return True;
1675 }
1676
1677 /* Check that we can add all the fd's we need. */
1678 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
1679 count++;
1680
1681 if((count*2) + 2 > FD_SETSIZE) {
1682 DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
1683only use %d.\n", (count*2) + 2, FD_SETSIZE));
1684 SAFE_FREE(pset);
1685 return True;
1686 }
1687
1688 if((sock_array = SMB_MALLOC_ARRAY(int, (count*2) + 2)) == NULL) {
1689 DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
1690 SAFE_FREE(pset);
1691 return True;
1692 }
1693
1694 FD_ZERO(pset);
1695
1696 /* Add in the broadcast socket on 137. */
1697 FD_SET(ClientNMB,pset);
1698 sock_array[num++] = ClientNMB;
1699 *maxfd = MAX( *maxfd, ClientNMB);
1700
1701 /* Add in the 137 sockets on all the interfaces. */
1702 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1703 FD_SET(subrec->nmb_sock,pset);
1704 sock_array[num++] = subrec->nmb_sock;
1705 *maxfd = MAX( *maxfd, subrec->nmb_sock);
1706 }
1707
1708 /* Add in the broadcast socket on 138. */
1709 FD_SET(ClientDGRAM,pset);
1710 sock_array[num++] = ClientDGRAM;
1711 *maxfd = MAX( *maxfd, ClientDGRAM);
1712
1713 /* Add in the 138 sockets on all the interfaces. */
1714 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1715 FD_SET(subrec->dgram_sock,pset);
1716 sock_array[num++] = subrec->dgram_sock;
1717 *maxfd = MAX( *maxfd, subrec->dgram_sock);
1718 }
1719
1720 *listen_number = (count*2) + 2;
1721
1722 SAFE_FREE(*ppset);
1723 SAFE_FREE(*psock_array);
1724
1725 *ppset = pset;
1726 *psock_array = sock_array;
1727
1728 return False;
1729}
1730
1731/****************************************************************************
1732 Listens for NMB or DGRAM packets, and queues them.
1733 return True if the socket is dead
1734***************************************************************************/
1735
1736BOOL listen_for_packets(BOOL run_election)
1737{
1738 static fd_set *listen_set = NULL;
1739 static int listen_number = 0;
1740 static int *sock_array = NULL;
1741 int i;
1742 static int maxfd = 0;
1743
1744 fd_set fds;
1745 int selrtn;
1746 struct timeval timeout;
1747#ifndef SYNC_DNS
1748 int dns_fd;
1749#endif
1750
1751 if(listen_set == NULL || rescan_listen_set) {
1752 if(create_listen_fdset(&listen_set, &sock_array, &listen_number, &maxfd)) {
1753 DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
1754 return True;
1755 }
1756 rescan_listen_set = False;
1757 }
1758
1759 memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
1760
1761#ifndef SYNC_DNS
1762 dns_fd = asyncdns_fd();
1763 if (dns_fd != -1) {
1764 FD_SET(dns_fd, &fds);
1765 maxfd = MAX( maxfd, dns_fd);
1766 }
1767#endif
1768
1769 /*
1770 * During elections and when expecting a netbios response packet we
1771 * need to send election packets at tighter intervals.
1772 * Ideally it needs to be the interval (in ms) between time now and
1773 * the time we are expecting the next netbios packet.
1774 */
1775
1776 timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
1777 timeout.tv_usec = 0;
1778
1779 /* Prepare for the select - allow certain signals. */
1780
1781 BlockSignals(False, SIGTERM);
1782
1783 selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&timeout);
1784
1785 /* We can only take signals when we are in the select - block them again here. */
1786
1787 BlockSignals(True, SIGTERM);
1788
1789 if(selrtn == -1) {
1790 return False;
1791 }
1792
1793#ifndef SYNC_DNS
1794 if (dns_fd != -1 && FD_ISSET(dns_fd,&fds)) {
1795 run_dns_queue();
1796 }
1797#endif
1798
1799 for(i = 0; i < listen_number; i++) {
1800 if (i < (listen_number/2)) {
1801 /* Processing a 137 socket. */
1802 if (FD_ISSET(sock_array[i],&fds)) {
1803 struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
1804 if (packet) {
1805 /*
1806 * If we got a packet on the broadcast socket and interfaces
1807 * only is set then check it came from one of our local nets.
1808 */
1809 if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) &&
1810 (!is_local_net(packet->ip))) {
1811 DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
1812 inet_ntoa(packet->ip),packet->port));
1813 free_packet(packet);
1814 } else if ((ip_equal(loopback_ip, packet->ip) ||
1815 ismyip(packet->ip)) && packet->port == global_nmb_port &&
1816 packet->packet.nmb.header.nm_flags.bcast) {
1817 DEBUG(7,("discarding own bcast packet from %s:%d\n",
1818 inet_ntoa(packet->ip),packet->port));
1819 free_packet(packet);
1820 } else {
1821 /* Save the file descriptor this packet came in on. */
1822 packet->fd = sock_array[i];
1823 queue_packet(packet);
1824 }
1825 }
1826 }
1827 } else {
1828 /* Processing a 138 socket. */
1829 if (FD_ISSET(sock_array[i],&fds)) {
1830 struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
1831 if (packet) {
1832 /*
1833 * If we got a packet on the broadcast socket and interfaces
1834 * only is set then check it came from one of our local nets.
1835 */
1836 if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) &&
1837 (!is_local_net(packet->ip))) {
1838 DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
1839 inet_ntoa(packet->ip),packet->port));
1840 free_packet(packet);
1841 } else if ((ip_equal(loopback_ip, packet->ip) ||
1842 ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
1843 DEBUG(7,("discarding own dgram packet from %s:%d\n",
1844 inet_ntoa(packet->ip),packet->port));
1845 free_packet(packet);
1846 } else {
1847 /* Save the file descriptor this packet came in on. */
1848 packet->fd = sock_array[i];
1849 queue_packet(packet);
1850 }
1851 }
1852 }
1853 } /* end processing 138 socket. */
1854 } /* end for */
1855 return False;
1856}
1857
1858/****************************************************************************
1859 Construct and send a netbios DGRAM.
1860**************************************************************************/
1861
1862BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
1863 const char *srcname, int src_type,
1864 const char *dstname, int dest_type,
1865 struct in_addr dest_ip,struct in_addr src_ip,
1866 int dest_port)
1867{
1868 BOOL loopback_this_packet = False;
1869 struct packet_struct p;
1870 struct dgram_packet *dgram = &p.packet.dgram;
1871 char *ptr,*p2;
1872 char tmp[4];
1873
1874 memset((char *)&p,'\0',sizeof(p));
1875
1876 if(ismyip(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
1877 loopback_this_packet = True;
1878
1879 /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
1880
1881 /* DIRECT GROUP or UNIQUE datagram. */
1882 dgram->header.msg_type = unique ? 0x10 : 0x11;
1883 dgram->header.flags.node_type = M_NODE;
1884 dgram->header.flags.first = True;
1885 dgram->header.flags.more = False;
1886 dgram->header.dgm_id = generate_name_trn_id();
1887 dgram->header.source_ip = src_ip;
1888 dgram->header.source_port = DGRAM_PORT;
1889 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1890 dgram->header.packet_offset = 0;
1891
1892 make_nmb_name(&dgram->source_name,srcname,src_type);
1893 make_nmb_name(&dgram->dest_name,dstname,dest_type);
1894
1895 ptr = &dgram->data[0];
1896
1897 /* Setup the smb part. */
1898 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1899 memcpy(tmp,ptr,4);
1900
1901 if (smb_size + 17*2 + strlen(mailslot) + 1 + len > MAX_DGRAM_SIZE) {
1902 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
1903 return False;
1904 }
1905
1906 set_message(ptr,17,strlen(mailslot) + 1 + len,True);
1907 memcpy(ptr,tmp,4);
1908
1909 SCVAL(ptr,smb_com,SMBtrans);
1910 SSVAL(ptr,smb_vwv1,len);
1911 SSVAL(ptr,smb_vwv11,len);
1912 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1913 SSVAL(ptr,smb_vwv13,3);
1914 SSVAL(ptr,smb_vwv14,1);
1915 SSVAL(ptr,smb_vwv15,1);
1916 SSVAL(ptr,smb_vwv16,2);
1917 p2 = smb_buf(ptr);
1918 safe_strcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
1919 p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2);
1920
1921 if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
1922 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
1923 return False;
1924 } else {
1925 memcpy(p2,buf,len);
1926 p2 += len;
1927 }
1928
1929 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1930
1931 p.ip = dest_ip;
1932 p.port = dest_port;
1933 p.fd = find_subnet_mailslot_fd_for_address( src_ip );
1934 p.timestamp = time(NULL);
1935 p.packet_type = DGRAM_PACKET;
1936
1937 DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
1938 nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
1939 DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
1940
1941 debug_browse_data(buf, len);
1942
1943 if(loopback_this_packet) {
1944 struct packet_struct *lo_packet = NULL;
1945 DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
1946 if((lo_packet = copy_packet(&p)) == NULL)
1947 return False;
1948 queue_packet(lo_packet);
1949 return True;
1950 } else {
1951 return(send_packet(&p));
1952 }
1953}
Note: See TracBrowser for help on using the repository browser.