source: trunk/server/source3/nmbd/nmbd_packets.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 67.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 get_nb_flags(char *buf)
98{
99 return ((((uint16)*buf)&0xFFFF) & NB_FLGMSK);
100}
101
102void set_nb_flags(char *buf, uint16 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 name_trn_id=0;
149
150static uint16 generate_name_trn_id(void)
151{
152 if (!name_trn_id) {
153 name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_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 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 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 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 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 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 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 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 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 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 %s to ip %s \
967for id %hu\n", packet_type, nmb_namestr(&orig_nmb->question.question_name),
968 inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
969
970 nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
971 nmb->header.opcode = opcode;
972 nmb->header.response = True;
973 nmb->header.nm_flags.bcast = False;
974 nmb->header.nm_flags.trunc = False;
975 nmb->header.nm_flags.authoritative = True;
976
977 nmb->header.rcode = rcode;
978 nmb->header.qdcount = 0;
979 nmb->header.ancount = 1;
980 nmb->header.nscount = 0;
981 nmb->header.arcount = 0;
982
983 memset((char*)&nmb->question,'\0',sizeof(nmb->question));
984
985 nmb->answers = &answers;
986 memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
987
988 nmb->answers->rr_name = orig_nmb->question.question_name;
989 nmb->answers->rr_type = rr_type;
990 nmb->answers->rr_class = RR_CLASS_IN;
991 nmb->answers->ttl = ttl;
992
993 if (data && len) {
994 if (len < 0 || len > sizeof(nmb->answers->rdata)) {
995 DEBUG(5,("reply_netbios_packet: "
996 "invalid packet len (%d)\n",
997 len ));
998 return;
999 }
1000 nmb->answers->rdlength = len;
1001 memcpy(nmb->answers->rdata, data, len);
1002 }
1003
1004 packet.packet_type = NMB_PACKET;
1005 packet.recv_fd = -1;
1006 /* Ensure we send out on the same fd that the original
1007 packet came in on to give the correct source IP address. */
1008 if (orig_packet->send_fd != -1) {
1009 packet.send_fd = orig_packet->send_fd;
1010 } else {
1011 packet.send_fd = orig_packet->recv_fd;
1012 }
1013 packet.timestamp = time(NULL);
1014
1015 debug_nmb_packet(&packet);
1016
1017 if(loopback_this_packet) {
1018 struct packet_struct *lo_packet;
1019 DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
1020 if((lo_packet = copy_packet(&packet)) == NULL)
1021 return;
1022 queue_packet(lo_packet);
1023 } else if (!send_packet(&packet)) {
1024 DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
1025 inet_ntoa(packet.ip),packet.port));
1026 }
1027}
1028
1029/*******************************************************************
1030 Queue a packet into a packet queue
1031******************************************************************/
1032
1033void queue_packet(struct packet_struct *packet)
1034{
1035 DLIST_ADD_END(packet_queue, packet, struct packet_struct *);
1036}
1037
1038/****************************************************************************
1039 Try and find a matching subnet record for a datagram port 138 packet.
1040****************************************************************************/
1041
1042static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_struct *p)
1043{
1044 struct subnet_record *subrec;
1045
1046 /* Go through all the broadcast subnets and see if the mask matches. */
1047 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1048 if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
1049 return subrec;
1050 }
1051
1052 /* If the subnet record is the remote announce broadcast subnet,
1053 hack it here to be the first subnet. This is really gross and
1054 is needed due to people turning on port 137/138 broadcast
1055 forwarding on their routers. May fire and brimstone rain
1056 down upon them...
1057 */
1058
1059 return FIRST_SUBNET;
1060}
1061
1062/****************************************************************************
1063Dispatch a browse frame from port 138 to the correct processing function.
1064****************************************************************************/
1065
1066static void process_browse_packet(struct packet_struct *p, const char *buf,int len)
1067{
1068 struct dgram_packet *dgram = &p->packet.dgram;
1069 int command = CVAL(buf,0);
1070 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1071 char scope[64];
1072 unstring src_name;
1073
1074 /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
1075 pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
1076 if (!strequal(scope, global_scope())) {
1077 DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
1078mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
1079 return;
1080 }
1081
1082 pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
1083 if (is_myname(src_name)) {
1084 DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Source name \
1085%s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1086 return;
1087 }
1088
1089 switch (command) {
1090 case ANN_HostAnnouncement:
1091 debug_browse_data(buf, len);
1092 process_host_announce(subrec, p, buf+1);
1093 break;
1094 case ANN_DomainAnnouncement:
1095 debug_browse_data(buf, len);
1096 process_workgroup_announce(subrec, p, buf+1);
1097 break;
1098 case ANN_LocalMasterAnnouncement:
1099 debug_browse_data(buf, len);
1100 process_local_master_announce(subrec, p, buf+1);
1101 break;
1102 case ANN_AnnouncementRequest:
1103 debug_browse_data(buf, len);
1104 process_announce_request(subrec, p, buf+1);
1105 break;
1106 case ANN_Election:
1107 debug_browse_data(buf, len);
1108 process_election(subrec, p, buf+1);
1109 break;
1110 case ANN_GetBackupListReq:
1111 debug_browse_data(buf, len);
1112 process_get_backup_list_request(subrec, p, buf+1);
1113 break;
1114 case ANN_GetBackupListResp:
1115 debug_browse_data(buf, len);
1116 /* We never send ANN_GetBackupListReq so we should never get these. */
1117 DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
1118packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
1119 break;
1120 case ANN_ResetBrowserState:
1121 debug_browse_data(buf, len);
1122 process_reset_browser(subrec, p, buf+1);
1123 break;
1124 case ANN_MasterAnnouncement:
1125 /* Master browser datagrams must be processed on the unicast subnet. */
1126 subrec = unicast_subnet;
1127
1128 debug_browse_data(buf, len);
1129 process_master_browser_announce(subrec, p, buf+1);
1130 break;
1131 case ANN_BecomeBackup:
1132 /*
1133 * We don't currently implement this. Log it just in case.
1134 */
1135 debug_browse_data(buf, len);
1136 DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
1137command ANN_BecomeBackup from %s IP %s to %s\n", subrec->subnet_name, nmb_namestr(&dgram->source_name),
1138 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1139 break;
1140 default:
1141 debug_browse_data(buf, len);
1142 DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
1143command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1144 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1145 break;
1146 }
1147}
1148
1149/****************************************************************************
1150 Dispatch a LanMan browse frame from port 138 to the correct processing function.
1151****************************************************************************/
1152
1153static void process_lanman_packet(struct packet_struct *p, const char *buf,int len)
1154{
1155 struct dgram_packet *dgram = &p->packet.dgram;
1156 int command = SVAL(buf,0);
1157 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
1158 char scope[64];
1159 unstring src_name;
1160
1161 /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
1162
1163 pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
1164 if (!strequal(scope, global_scope())) {
1165 DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
1166mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
1167 return;
1168 }
1169
1170 pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
1171 if (is_myname(src_name)) {
1172 DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
1173%s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
1174 return;
1175 }
1176
1177 switch (command) {
1178 case ANN_HostAnnouncement:
1179 debug_browse_data(buf, len);
1180 process_lm_host_announce(subrec, p, buf+1, len > 1 ? len-1 : 0);
1181 break;
1182 case ANN_AnnouncementRequest:
1183 process_lm_announce_request(subrec, p, buf+1, len > 1 ? len-1 : 0);
1184 break;
1185 default:
1186 DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
1187command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
1188 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
1189 break;
1190 }
1191}
1192
1193/****************************************************************************
1194 Determine if a packet is for us on port 138. Note that to have any chance of
1195 being efficient we need to drop as many packets as possible at this
1196 stage as subsequent processing is expensive.
1197****************************************************************************/
1198
1199static bool listening(struct packet_struct *p,struct nmb_name *nbname)
1200{
1201 struct subnet_record *subrec = NULL;
1202
1203 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1204 if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
1205 break;
1206 }
1207
1208 if(subrec == NULL)
1209 subrec = unicast_subnet;
1210
1211 return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
1212}
1213
1214/****************************************************************************
1215 Process udp 138 datagrams
1216****************************************************************************/
1217
1218static void process_dgram(struct packet_struct *p)
1219{
1220 const char *buf;
1221 const char *buf2;
1222 int len;
1223 struct dgram_packet *dgram = &p->packet.dgram;
1224
1225 /* If we aren't listening to the destination name then ignore the packet */
1226 if (!listening(p,&dgram->dest_name)) {
1227 nb_packet_dispatch(packet_server, p);
1228 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
1229 nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
1230 return;
1231 }
1232
1233 if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) {
1234 nb_packet_dispatch(packet_server, p);
1235 /* Don't process error packets etc yet */
1236 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
1237an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
1238 return;
1239 }
1240
1241 /* Ensure we have a large enough packet before looking inside. */
1242 if (dgram->datasize < (smb_vwv12 - 2)) {
1243 /* That's the offset minus the 4 byte length + 2 bytes of offset. */
1244 DEBUG(0,("process_dgram: ignoring too short dgram packet (%u) sent to name %s from IP %s\n",
1245 (unsigned int)dgram->datasize,
1246 nmb_namestr(&dgram->dest_name),
1247 inet_ntoa(p->ip) ));
1248 return;
1249 }
1250
1251 buf = &dgram->data[0];
1252 buf -= 4; /* XXXX for the pseudo tcp length - someday I need to get rid of this */
1253
1254 if (CVAL(buf,smb_com) != SMBtrans)
1255 return;
1256
1257 len = SVAL(buf,smb_vwv11);
1258 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1259
1260 if (len <= 0 || len > dgram->datasize) {
1261 DEBUG(0,("process_dgram: ignoring malformed1 (datasize = %d, len = %d) datagram \
1262packet sent to name %s from IP %s\n",
1263 dgram->datasize,
1264 len,
1265 nmb_namestr(&dgram->dest_name),
1266 inet_ntoa(p->ip) ));
1267 return;
1268 }
1269
1270 if (buf2 < dgram->data || (buf2 >= dgram->data + dgram->datasize)) {
1271 DEBUG(0,("process_dgram: ignoring malformed2 (datasize = %d, len=%d, off=%d) datagram \
1272packet sent to name %s from IP %s\n",
1273 dgram->datasize,
1274 len,
1275 (int)PTR_DIFF(buf2, dgram->data),
1276 nmb_namestr(&dgram->dest_name),
1277 inet_ntoa(p->ip) ));
1278 return;
1279 }
1280
1281 if ((buf2 + len < dgram->data) || (buf2 + len > dgram->data + dgram->datasize)) {
1282 DEBUG(0,("process_dgram: ignoring malformed3 (datasize = %d, len=%d, off=%d) datagram \
1283packet sent to name %s from IP %s\n",
1284 dgram->datasize,
1285 len,
1286 (int)PTR_DIFF(buf2, dgram->data),
1287 nmb_namestr(&dgram->dest_name),
1288 inet_ntoa(p->ip) ));
1289 return;
1290 }
1291
1292 DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
1293 nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
1294 inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
1295
1296 /* Datagram packet received for the browser mailslot */
1297 if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
1298 process_browse_packet(p,buf2,len);
1299 return;
1300 }
1301
1302 /* Datagram packet received for the LAN Manager mailslot */
1303 if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
1304 process_lanman_packet(p,buf2,len);
1305 return;
1306 }
1307
1308 /* Datagram packet received for the domain logon mailslot */
1309 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
1310 process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
1311 return;
1312 }
1313
1314 /* Datagram packet received for the NT domain logon mailslot */
1315 if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT)) {
1316 process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
1317 return;
1318 }
1319
1320 nb_packet_dispatch(packet_server, p);
1321}
1322
1323/****************************************************************************
1324 Validate a response nmb packet.
1325****************************************************************************/
1326
1327static bool validate_nmb_response_packet( struct nmb_packet *nmb )
1328{
1329 bool ignore = False;
1330
1331 switch (nmb->header.opcode) {
1332 case NMB_NAME_REG_OPCODE:
1333 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1334 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1335 if (nmb->header.ancount == 0) {
1336 DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
1337 ignore = True;
1338 }
1339 break;
1340
1341 case NMB_NAME_QUERY_OPCODE:
1342 if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1)) {
1343 DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
1344 ignore = True;
1345 }
1346 break;
1347
1348 case NMB_NAME_RELEASE_OPCODE:
1349 if (nmb->header.ancount == 0) {
1350 DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
1351 ignore = True;
1352 }
1353 break;
1354
1355 case NMB_WACK_OPCODE:
1356 /* Check WACK response here. */
1357 if (nmb->header.ancount != 1) {
1358 DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
1359 ignore = True;
1360 }
1361 break;
1362 default:
1363 DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
1364 nmb->header.opcode));
1365 return True;
1366 }
1367
1368 if(ignore)
1369 DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
1370
1371 return ignore;
1372}
1373
1374/****************************************************************************
1375 Validate a request nmb packet.
1376****************************************************************************/
1377
1378static bool validate_nmb_packet( struct nmb_packet *nmb )
1379{
1380 bool ignore = False;
1381
1382 switch (nmb->header.opcode) {
1383 case NMB_NAME_REG_OPCODE:
1384 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1385 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
1386 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1387 if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
1388 DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
1389 ignore = True;
1390 }
1391 break;
1392
1393 case NMB_NAME_QUERY_OPCODE:
1394 if ((nmb->header.qdcount == 0) || ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
1395 (nmb->question.question_type != QUESTION_TYPE_NB_STATUS))) {
1396 DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
1397 ignore = True;
1398 }
1399 break;
1400
1401 case NMB_NAME_RELEASE_OPCODE:
1402 if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
1403 DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
1404 ignore = True;
1405 }
1406 break;
1407 default:
1408 DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
1409 nmb->header.opcode));
1410 return True;
1411 }
1412
1413 if(ignore)
1414 DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
1415
1416 return ignore;
1417}
1418
1419/****************************************************************************
1420 Find a subnet (and potentially a response record) for a packet.
1421****************************************************************************/
1422
1423static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,
1424 struct response_record **pprrec)
1425{
1426 struct nmb_packet *nmb = &p->packet.nmb;
1427 struct response_record *rrec = NULL;
1428 struct subnet_record *subrec = NULL;
1429
1430 if(pprrec != NULL)
1431 *pprrec = NULL;
1432
1433 if(nmb->header.response) {
1434 /* It's a response packet. Find a record for it or it's an error. */
1435
1436 rrec = find_response_record( &subrec, nmb->header.name_trn_id);
1437 if(rrec == NULL) {
1438 DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
1439 nmb->header.name_trn_id));
1440 nb_packet_dispatch(packet_server, p);
1441 return NULL;
1442 }
1443
1444 if(subrec == NULL) {
1445 DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
1446 nmb->header.name_trn_id));
1447 return NULL;
1448 }
1449
1450 if(pprrec != NULL)
1451 *pprrec = rrec;
1452 return subrec;
1453 }
1454
1455 /* Try and see what subnet this packet belongs to. */
1456
1457 /* WINS server ? */
1458 if(packet_is_for_wins_server(p))
1459 return wins_server_subnet;
1460
1461 /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
1462 if(nmb->header.nm_flags.bcast == False)
1463 return unicast_subnet;
1464
1465 /* Go through all the broadcast subnets and see if the mask matches. */
1466 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1467 if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
1468 return subrec;
1469 }
1470
1471 /* If none match it must have been a directed broadcast - assign the remote_broadcast_subnet. */
1472 return remote_broadcast_subnet;
1473}
1474
1475/****************************************************************************
1476 Process a nmb request packet - validate the packet and route it.
1477****************************************************************************/
1478
1479static void process_nmb_request(struct packet_struct *p)
1480{
1481 struct nmb_packet *nmb = &p->packet.nmb;
1482 struct subnet_record *subrec = NULL;
1483
1484 debug_nmb_packet(p);
1485
1486 /* Ensure we have a good packet. */
1487 if(validate_nmb_packet(nmb))
1488 return;
1489
1490 /* Allocate a subnet to this packet - if we cannot - fail. */
1491 if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
1492 return;
1493
1494 switch (nmb->header.opcode) {
1495 case NMB_NAME_REG_OPCODE:
1496 if(subrec == wins_server_subnet)
1497 wins_process_name_registration_request(subrec, p);
1498 else
1499 process_name_registration_request(subrec, p);
1500 break;
1501
1502 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
1503 case NMB_NAME_REFRESH_OPCODE_9:
1504 if(subrec == wins_server_subnet)
1505 wins_process_name_refresh_request(subrec, p);
1506 else
1507 process_name_refresh_request(subrec, p);
1508 break;
1509
1510 case NMB_NAME_MULTIHOMED_REG_OPCODE:
1511 if(subrec == wins_server_subnet) {
1512 wins_process_multihomed_name_registration_request(subrec, p);
1513 } else {
1514 DEBUG(0,("process_nmb_request: Multihomed registration request must be \
1515directed at a WINS server.\n"));
1516 }
1517 break;
1518
1519 case NMB_NAME_QUERY_OPCODE:
1520 switch (nmb->question.question_type) {
1521 case QUESTION_TYPE_NB_QUERY:
1522 if(subrec == wins_server_subnet)
1523 wins_process_name_query_request(subrec, p);
1524 else
1525 process_name_query_request(subrec, p);
1526 break;
1527 case QUESTION_TYPE_NB_STATUS:
1528 if(subrec == wins_server_subnet) {
1529 DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
1530not allowed.\n"));
1531 break;
1532 } else {
1533 process_node_status_request(subrec, p);
1534 }
1535 break;
1536 }
1537 break;
1538
1539 case NMB_NAME_RELEASE_OPCODE:
1540 if(subrec == wins_server_subnet)
1541 wins_process_name_release_request(subrec, p);
1542 else
1543 process_name_release_request(subrec, p);
1544 break;
1545 }
1546}
1547
1548/****************************************************************************
1549 Process a nmb response packet - validate the packet and route it.
1550 to either the WINS server or a normal response.
1551****************************************************************************/
1552
1553static void process_nmb_response(struct packet_struct *p)
1554{
1555 struct nmb_packet *nmb = &p->packet.nmb;
1556 struct subnet_record *subrec = NULL;
1557 struct response_record *rrec = NULL;
1558
1559 debug_nmb_packet(p);
1560
1561 if(validate_nmb_response_packet(nmb))
1562 return;
1563
1564 if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
1565 return;
1566
1567 if(rrec == NULL) {
1568 DEBUG(0,("process_nmb_response: response packet received but no response record \
1569found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));
1570 return;
1571 }
1572
1573 /* Increment the number of responses received for this record. */
1574 rrec->num_msgs++;
1575 /* Ensure we don't re-send the request. */
1576 rrec->repeat_count = 0;
1577
1578 /* Call the response received function for this packet. */
1579 (*rrec->resp_fn)(subrec, rrec, p);
1580}
1581
1582/*******************************************************************
1583 Run elements off the packet queue till its empty
1584******************************************************************/
1585
1586void run_packet_queue(void)
1587{
1588 struct packet_struct *p;
1589
1590 while ((p = packet_queue)) {
1591 DLIST_REMOVE(packet_queue, p);
1592
1593 switch (p->packet_type) {
1594 case NMB_PACKET:
1595 if(p->packet.nmb.header.response)
1596 process_nmb_response(p);
1597 else
1598 process_nmb_request(p);
1599 break;
1600
1601 case DGRAM_PACKET:
1602 process_dgram(p);
1603 break;
1604 }
1605 free_packet(p);
1606 }
1607}
1608
1609/*******************************************************************
1610 Retransmit or timeout elements from all the outgoing subnet response
1611 record queues. NOTE that this code must also check the WINS server
1612 subnet for response records to timeout as the WINS server code
1613 can send requests to check if a client still owns a name.
1614 (Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>).
1615******************************************************************/
1616
1617void retransmit_or_expire_response_records(time_t t)
1618{
1619 struct subnet_record *subrec;
1620
1621 for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
1622 struct response_record *rrec, *nextrrec;
1623
1624 restart:
1625
1626 for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
1627 nextrrec = rrec->next;
1628
1629 if (rrec->repeat_time <= t) {
1630 if (rrec->repeat_count > 0) {
1631 /* Resend while we have a non-zero repeat_count. */
1632 if(!send_packet(rrec->packet)) {
1633 DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
1634to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
1635 }
1636 rrec->repeat_time = t + rrec->repeat_interval;
1637 rrec->repeat_count--;
1638 } else {
1639 DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
1640on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
1641
1642 /*
1643 * Check the flag in this record to prevent recursion if we end
1644 * up in this function again via the timeout function call.
1645 */
1646
1647 if(!rrec->in_expiration_processing) {
1648
1649 /*
1650 * Set the recursion protection flag in this record.
1651 */
1652
1653 rrec->in_expiration_processing = True;
1654
1655 /* Call the timeout function. This will deal with removing the
1656 timed out packet. */
1657 if(rrec->timeout_fn) {
1658 (*rrec->timeout_fn)(subrec, rrec);
1659 } else {
1660 /* We must remove the record ourself if there is
1661 no timeout function. */
1662 remove_response_record(subrec, rrec);
1663 }
1664 /* We have changed subrec->responselist,
1665 * restart from the beginning of this list. */
1666 goto restart;
1667 } /* !rrec->in_expitation_processing */
1668 } /* rrec->repeat_count > 0 */
1669 } /* rrec->repeat_time <= t */
1670 } /* end for rrec */
1671 } /* end for subnet */
1672}
1673
1674/****************************************************************************
1675 Create an fd_set containing all the sockets in the subnet structures,
1676 plus the broadcast sockets.
1677***************************************************************************/
1678
1679struct socket_attributes {
1680 enum packet_type type;
1681 bool broadcast;
1682};
1683
1684static bool create_listen_pollfds(struct pollfd **pfds,
1685 struct socket_attributes **pattrs,
1686 int *pnum_sockets)
1687{
1688 struct subnet_record *subrec = NULL;
1689 int count = 0;
1690 int num = 0;
1691 struct pollfd *fds;
1692 struct socket_attributes *attrs;
1693
1694 /* The ClientNMB and ClientDGRAM sockets */
1695 count = 2;
1696
1697 /* Check that we can add all the fd's we need. */
1698 for (subrec = FIRST_SUBNET;
1699 subrec != NULL;
1700 subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1701 count += 2; /* nmb_sock and dgram_sock */
1702 if (subrec->nmb_bcast != -1) {
1703 count += 1;
1704 }
1705 if (subrec->dgram_bcast != -1) {
1706 count += 1;
1707 }
1708 }
1709
1710 fds = TALLOC_ZERO_ARRAY(NULL, struct pollfd, count);
1711 if (fds == NULL) {
1712 DEBUG(1, ("create_listen_pollfds: malloc fail for fds. "
1713 "size %d\n", count));
1714 return true;
1715 }
1716
1717 attrs = TALLOC_ARRAY(NULL, struct socket_attributes, count);
1718 if (fds == NULL) {
1719 DEBUG(1, ("create_listen_pollfds: malloc fail for attrs. "
1720 "size %d\n", count));
1721 SAFE_FREE(fds);
1722 return true;
1723 }
1724
1725 num = 0;
1726
1727 fds[num].fd = ClientNMB;
1728 attrs[num].type = NMB_PACKET;
1729 attrs[num].broadcast = false;
1730 num += 1;
1731
1732 fds[num].fd = ClientDGRAM;
1733 attrs[num].type = DGRAM_PACKET;
1734 attrs[num].broadcast = false;
1735 num += 1;
1736
1737 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
1738
1739 fds[num].fd = subrec->nmb_sock;
1740 attrs[num].type = NMB_PACKET;
1741 attrs[num].broadcast = false;
1742 num += 1;
1743
1744 if (subrec->nmb_bcast != -1) {
1745 fds[num].fd = subrec->nmb_bcast;
1746 attrs[num].type = NMB_PACKET;
1747 attrs[num].broadcast = true;
1748 num += 1;
1749 }
1750
1751 fds[num].fd = subrec->dgram_sock;
1752 attrs[num].type = DGRAM_PACKET;
1753 attrs[num].broadcast = false;
1754 num += 1;
1755
1756 if (subrec->dgram_bcast != -1) {
1757 fds[num].fd = subrec->dgram_bcast;
1758 attrs[num].type = DGRAM_PACKET;
1759 attrs[num].broadcast = true;
1760 num += 1;
1761 }
1762 }
1763
1764 TALLOC_FREE(*pfds);
1765 *pfds = fds;
1766
1767 TALLOC_FREE(*pattrs);
1768 *pattrs = attrs;
1769
1770 *pnum_sockets = count;
1771
1772 return False;
1773}
1774
1775/****************************************************************************
1776 List of packets we're processing this select.
1777***************************************************************************/
1778
1779struct processed_packet {
1780 struct processed_packet *next;
1781 struct processed_packet *prev;
1782 enum packet_type packet_type;
1783 struct in_addr ip;
1784 int packet_id;
1785};
1786
1787/****************************************************************************
1788 Have we seen this before ?
1789***************************************************************************/
1790
1791static bool is_processed_packet(struct processed_packet *processed_packet_list,
1792 struct packet_struct *packet)
1793{
1794 struct processed_packet *p = NULL;
1795
1796 for (p = processed_packet_list; p; p = p->next) {
1797 if (ip_equal_v4(p->ip, packet->ip) && p->packet_type == packet->packet_type) {
1798 if ((p->packet_type == NMB_PACKET) &&
1799 (p->packet_id ==
1800 packet->packet.nmb.header.name_trn_id)) {
1801 return true;
1802 } else if ((p->packet_type == DGRAM_PACKET) &&
1803 (p->packet_id ==
1804 packet->packet.dgram.header.dgm_id)) {
1805 return true;
1806 }
1807 }
1808 }
1809 return false;
1810}
1811
1812/****************************************************************************
1813 Keep a list of what we've seen before.
1814***************************************************************************/
1815
1816static bool store_processed_packet(struct processed_packet **pp_processed_packet_list,
1817 struct packet_struct *packet)
1818{
1819 struct processed_packet *p = SMB_MALLOC_P(struct processed_packet);
1820 if (!p) {
1821 return false;
1822 }
1823 p->packet_type = packet->packet_type;
1824 p->ip = packet->ip;
1825 if (packet->packet_type == NMB_PACKET) {
1826 p->packet_id = packet->packet.nmb.header.name_trn_id;
1827 } else if (packet->packet_type == DGRAM_PACKET) {
1828 p->packet_id = packet->packet.dgram.header.dgm_id;
1829 } else {
1830 SAFE_FREE(p);
1831 return false;
1832 }
1833
1834 DLIST_ADD(*pp_processed_packet_list, p);
1835 return true;
1836}
1837
1838/****************************************************************************
1839 Throw away what we've seen before.
1840***************************************************************************/
1841
1842static void free_processed_packet_list(struct processed_packet **pp_processed_packet_list)
1843{
1844 struct processed_packet *p = NULL, *next = NULL;
1845
1846 for (p = *pp_processed_packet_list; p; p = next) {
1847 next = p->next;
1848 DLIST_REMOVE(*pp_processed_packet_list, p);
1849 SAFE_FREE(p);
1850 }
1851}
1852
1853/****************************************************************************
1854 Listens for NMB or DGRAM packets, and queues them.
1855 return True if the socket is dead
1856***************************************************************************/
1857
1858bool listen_for_packets(bool run_election)
1859{
1860 static struct pollfd *fds = NULL;
1861 static struct socket_attributes *attrs = NULL;
1862 static int listen_number = 0;
1863 int num_sockets;
1864 int i;
1865
1866 int pollrtn;
1867 int timeout;
1868#ifndef SYNC_DNS
1869 int dns_fd;
1870 int dns_pollidx = -1;
1871#endif
1872 struct processed_packet *processed_packet_list = NULL;
1873
1874 if ((fds == NULL) || rescan_listen_set) {
1875 if (create_listen_pollfds(&fds, &attrs, &listen_number)) {
1876 DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
1877 return True;
1878 }
1879 rescan_listen_set = False;
1880 }
1881
1882 /*
1883 * "fds" can be enlarged by event_add_to_poll_args
1884 * below. Shrink it again to what was given to us by
1885 * create_listen_pollfds.
1886 */
1887
1888 fds = TALLOC_REALLOC_ARRAY(NULL, fds, struct pollfd, listen_number);
1889 if (fds == NULL) {
1890 return true;
1891 }
1892 num_sockets = listen_number;
1893
1894#ifndef SYNC_DNS
1895 dns_fd = asyncdns_fd();
1896 if (dns_fd != -1) {
1897 fds = TALLOC_REALLOC_ARRAY(NULL, fds, struct pollfd, num_sockets+1);
1898 if (fds == NULL) {
1899 return true;
1900 }
1901 dns_pollidx = num_sockets;
1902 fds[num_sockets].fd = dns_fd;
1903 num_sockets += 1;
1904 }
1905#endif
1906
1907 for (i=0; i<num_sockets; i++) {
1908 fds[i].events = POLLIN|POLLHUP;
1909 }
1910
1911 /* Process a signal and timer events now... */
1912 if (run_events_poll(nmbd_event_context(), 0, NULL, 0)) {
1913 return False;
1914 }
1915
1916 /*
1917 * During elections and when expecting a netbios response packet we
1918 * need to send election packets at tighter intervals.
1919 * Ideally it needs to be the interval (in ms) between time now and
1920 * the time we are expecting the next netbios packet.
1921 */
1922
1923 timeout = ((run_election||num_response_packets)
1924 ? 1 : NMBD_SELECT_LOOP) * 1000;
1925
1926 event_add_to_poll_args(nmbd_event_context(), NULL,
1927 &fds, &num_sockets, &timeout);
1928
1929 pollrtn = sys_poll(fds, num_sockets, timeout);
1930
1931 if (run_events_poll(nmbd_event_context(), pollrtn, fds, num_sockets)) {
1932 return False;
1933 }
1934
1935 if (pollrtn == -1) {
1936 return False;
1937 }
1938
1939#ifndef SYNC_DNS
1940 if ((dns_fd != -1) && (dns_pollidx != -1) &&
1941 (fds[dns_pollidx].revents & (POLLIN|POLLHUP|POLLERR))) {
1942 run_dns_queue();
1943 }
1944#endif
1945
1946 for(i = 0; i < listen_number; i++) {
1947 enum packet_type packet_type;
1948 struct packet_struct *packet;
1949 const char *packet_name;
1950 int client_fd;
1951 int client_port;
1952
1953 if ((fds[i].revents & (POLLIN|POLLHUP|POLLERR)) == 0) {
1954 continue;
1955 }
1956
1957 if (attrs[i].type == NMB_PACKET) {
1958 /* Port 137 */
1959 packet_type = NMB_PACKET;
1960 packet_name = "nmb";
1961 client_fd = ClientNMB;
1962 client_port = global_nmb_port;
1963 } else {
1964 /* Port 138 */
1965 packet_type = DGRAM_PACKET;
1966 packet_name = "dgram";
1967 client_fd = ClientDGRAM;
1968 client_port = DGRAM_PORT;
1969 }
1970
1971 packet = read_packet(fds[i].fd, packet_type);
1972 if (!packet) {
1973 continue;
1974 }
1975
1976 /*
1977 * If we got a packet on the broadcast socket and interfaces
1978 * only is set then check it came from one of our local nets.
1979 */
1980 if (lp_bind_interfaces_only() &&
1981 (fds[i].fd == client_fd) &&
1982 (!is_local_net_v4(packet->ip))) {
1983 DEBUG(7,("discarding %s packet sent to broadcast socket from %s:%d\n",
1984 packet_name, inet_ntoa(packet->ip), packet->port));
1985 free_packet(packet);
1986 continue;
1987 }
1988
1989 if ((is_loopback_ip_v4(packet->ip) || ismyip_v4(packet->ip)) &&
1990 packet->port == client_port)
1991 {
1992 if (client_port == DGRAM_PORT) {
1993 DEBUG(7,("discarding own dgram packet from %s:%d\n",
1994 inet_ntoa(packet->ip),packet->port));
1995 free_packet(packet);
1996 continue;
1997 }
1998
1999 if (packet->packet.nmb.header.nm_flags.bcast) {
2000 DEBUG(7,("discarding own nmb bcast packet from %s:%d\n",
2001 inet_ntoa(packet->ip),packet->port));
2002 free_packet(packet);
2003 continue;
2004 }
2005 }
2006
2007 if (is_processed_packet(processed_packet_list, packet)) {
2008 DEBUG(7,("discarding duplicate packet from %s:%d\n",
2009 inet_ntoa(packet->ip),packet->port));
2010 free_packet(packet);
2011 continue;
2012 }
2013
2014 store_processed_packet(&processed_packet_list, packet);
2015
2016 if (attrs[i].broadcast) {
2017 /* this is a broadcast socket */
2018 packet->send_fd = fds[i-1].fd;
2019 } else {
2020 /* this is already a unicast socket */
2021 packet->send_fd = fds[i].fd;
2022 }
2023
2024 queue_packet(packet);
2025 }
2026
2027 free_processed_packet_list(&processed_packet_list);
2028 return False;
2029}
2030
2031/****************************************************************************
2032 Construct and send a netbios DGRAM.
2033**************************************************************************/
2034
2035bool send_mailslot(bool unique, const char *mailslot,char *buf, size_t len,
2036 const char *srcname, int src_type,
2037 const char *dstname, int dest_type,
2038 struct in_addr dest_ip,struct in_addr src_ip,
2039 int dest_port)
2040{
2041 bool loopback_this_packet = False;
2042 struct packet_struct p;
2043 struct dgram_packet *dgram = &p.packet.dgram;
2044 char *ptr,*p2;
2045 char tmp[4];
2046
2047 memset((char *)&p,'\0',sizeof(p));
2048
2049 if(ismyip_v4(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
2050 loopback_this_packet = True;
2051
2052 /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
2053
2054 /* DIRECT GROUP or UNIQUE datagram. */
2055 dgram->header.msg_type = unique ? 0x10 : 0x11;
2056 dgram->header.flags.node_type = M_NODE;
2057 dgram->header.flags.first = True;
2058 dgram->header.flags.more = False;
2059 dgram->header.dgm_id = generate_name_trn_id();
2060 dgram->header.source_ip = src_ip;
2061 dgram->header.source_port = DGRAM_PORT;
2062 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
2063 dgram->header.packet_offset = 0;
2064
2065 make_nmb_name(&dgram->source_name,srcname,src_type);
2066 make_nmb_name(&dgram->dest_name,dstname,dest_type);
2067
2068 ptr = &dgram->data[0];
2069
2070 /* Setup the smb part. */
2071 ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
2072 memcpy(tmp,ptr,4);
2073
2074 if (smb_size + 17*2 + strlen(mailslot) + 1 + len > MAX_DGRAM_SIZE) {
2075 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
2076 return false;
2077 }
2078
2079 cli_set_message(ptr,17,strlen(mailslot) + 1 + len,True);
2080 memcpy(ptr,tmp,4);
2081
2082 SCVAL(ptr,smb_com,SMBtrans);
2083 SSVAL(ptr,smb_vwv1,len);
2084 SSVAL(ptr,smb_vwv11,len);
2085 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
2086 SSVAL(ptr,smb_vwv13,3);
2087 SSVAL(ptr,smb_vwv14,1);
2088 SSVAL(ptr,smb_vwv15,1);
2089 SSVAL(ptr,smb_vwv16,2);
2090 p2 = smb_buf(ptr);
2091 safe_strcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
2092 p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2);
2093
2094 if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
2095 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
2096 return False;
2097 } else {
2098 if (len) {
2099 memcpy(p2,buf,len);
2100 }
2101 p2 += len;
2102 }
2103
2104 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
2105
2106 p.ip = dest_ip;
2107 p.port = dest_port;
2108 p.recv_fd = -1;
2109 p.send_fd = find_subnet_mailslot_fd_for_address( src_ip );
2110 p.timestamp = time(NULL);
2111 p.packet_type = DGRAM_PACKET;
2112
2113 DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
2114 nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
2115 DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
2116
2117 debug_browse_data(buf, len);
2118
2119 if(loopback_this_packet) {
2120 struct packet_struct *lo_packet = NULL;
2121 DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
2122 if((lo_packet = copy_packet(&p)) == NULL)
2123 return False;
2124 queue_packet(lo_packet);
2125 return True;
2126 } else {
2127 return(send_packet(&p));
2128 }
2129}
Note: See TracBrowser for help on using the repository browser.