source: branches/samba-3.3.x/source/nmbd/nmbd_packets.c

Last change on this file was 578, checked in by Herwig Bauernfeind, 14 years ago

Update Samba 3.3 to 3.3.15 (security update)

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