source: vendor/current/source3/nmbd/nmbd_packets.c

Last change on this file was 989, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.7

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