~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/nmbd/nmbd_packets.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

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