~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/wrepld/parser.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
 
 *  RPC Pipe client / server routines
4
 
 *  Copyright (C) Jean Fran�ois Micouleau      1998-2002.
5
 
 *  
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; either version 2 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *  
11
 
 *  This program is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *  
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with this program; if not, write to the Free Software
18
 
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
 
 */
20
 
 
21
 
#include "includes.h"
22
 
#include "wins_repl.h"
23
 
 
24
 
extern TALLOC_CTX *mem_ctx;
25
 
 
26
 
/****************************************************************************
27
 
grow the send buffer if necessary
28
 
****************************************************************************/
29
 
BOOL grow_buffer(struct BUFFER *buffer, int more)
30
 
{
31
 
        char *temp;
32
 
 
33
 
        DEBUG(10,("grow_buffer: size is: %d offet is:%d growing by %d\n", buffer->length, buffer->offset, more));
34
 
        
35
 
        /* grow by at least 256 bytes */
36
 
        if (more<256)
37
 
                more=256;
38
 
 
39
 
        if (buffer->offset+more >= buffer->length) {
40
 
                temp=talloc_realloc(mem_ctx, buffer->buffer, char, buffer->length + more);
41
 
                if (temp==NULL) {
42
 
                        DEBUG(0,("grow_buffer: can't grow buffer\n"));
43
 
                        return False;
44
 
                }
45
 
                buffer->length+=more;
46
 
                buffer->buffer=temp;
47
 
        }
48
 
 
49
 
        return True;
50
 
}
51
 
 
52
 
/****************************************************************************
53
 
check if the buffer has that much data
54
 
****************************************************************************/
55
 
static BOOL check_buffer(struct BUFFER *buffer, int more)
56
 
{
57
 
        DEBUG(10,("check_buffer: size is: %d offet is:%d growing by %d\n", buffer->length, buffer->offset, more));
58
 
        
59
 
        if (buffer->offset+more > buffer->length) {
60
 
                DEBUG(10,("check_buffer: buffer smaller than requested, size is: %d needed: %d\n", buffer->length, buffer->offset+more));
61
 
                return False;
62
 
        }
63
 
 
64
 
        return True;
65
 
}
66
 
 
67
 
/****************************************************************************
68
 
decode a WINS_OWNER struct
69
 
****************************************************************************/
70
 
static void decode_wins_owner(struct BUFFER *inbuf, WINS_OWNER *wins_owner)
71
 
{
72
 
        if(!check_buffer(inbuf, 24))
73
 
                return;
74
 
 
75
 
        wins_owner->address.s_addr=IVAL(inbuf->buffer, inbuf->offset);
76
 
        wins_owner->max_version=((SMB_BIG_UINT)RIVAL(inbuf->buffer, inbuf->offset+4))<<32;
77
 
        wins_owner->max_version|=RIVAL(inbuf->buffer, inbuf->offset+8);
78
 
        wins_owner->min_version=((SMB_BIG_UINT)RIVAL(inbuf->buffer, inbuf->offset+12))<<32;
79
 
        wins_owner->min_version|=RIVAL(inbuf->buffer, inbuf->offset+16);
80
 
        wins_owner->type=RIVAL(inbuf->buffer, inbuf->offset+20);
81
 
        inbuf->offset+=24;
82
 
 
83
 
}
84
 
 
85
 
/****************************************************************************
86
 
decode a WINS_NAME struct
87
 
****************************************************************************/
88
 
static void decode_wins_name(struct BUFFER *outbuf, WINS_NAME *wins_name)
89
 
{       
90
 
        char *p;
91
 
        int i;
92
 
 
93
 
        if(!check_buffer(outbuf, 40))
94
 
                return;
95
 
 
96
 
        wins_name->name_len=RIVAL(outbuf->buffer, outbuf->offset);
97
 
        outbuf->offset+=4;
98
 
        memcpy(wins_name->name,outbuf->buffer+outbuf->offset, 15);
99
 
        wins_name->name[15]='\0';
100
 
        if((p = strchr(wins_name->name,' ')) != NULL)
101
 
                *p = 0;
102
 
 
103
 
        outbuf->offset+=15;
104
 
 
105
 
        wins_name->type=(int)outbuf->buffer[outbuf->offset++];
106
 
        
107
 
        /*
108
 
         * fix to bug in WINS replication,
109
 
         * present in all versions including W2K SP2 !
110
 
         */
111
 
        if (wins_name->name[0]==0x1B) {
112
 
                wins_name->name[0]=(char)wins_name->type;
113
 
                wins_name->type=0x1B;
114
 
        }
115
 
        
116
 
        wins_name->empty=RIVAL(outbuf->buffer, outbuf->offset);
117
 
        outbuf->offset+=4;
118
 
        
119
 
        wins_name->name_flag=RIVAL(outbuf->buffer, outbuf->offset);
120
 
        outbuf->offset+=4;
121
 
        wins_name->group_flag=RIVAL(outbuf->buffer, outbuf->offset);
122
 
        outbuf->offset+=4;
123
 
        wins_name->id=((SMB_BIG_UINT)RIVAL(outbuf->buffer, outbuf->offset))<<32;
124
 
        outbuf->offset+=4;
125
 
        wins_name->id|=RIVAL(outbuf->buffer, outbuf->offset);
126
 
        outbuf->offset+=4;
127
 
        
128
 
        /* special groups have multiple address */
129
 
        if (wins_name->name_flag & 2) {
130
 
                if(!check_buffer(outbuf, 4))
131
 
                        return;
132
 
                wins_name->num_ip=IVAL(outbuf->buffer, outbuf->offset);
133
 
                outbuf->offset+=4;
134
 
        }
135
 
        else
136
 
                wins_name->num_ip=1;
137
 
 
138
 
        if(!check_buffer(outbuf, 4))
139
 
                return;
140
 
        wins_name->owner.s_addr=IVAL(outbuf->buffer, outbuf->offset);
141
 
        outbuf->offset+=4;
142
 
 
143
 
        if (wins_name->name_flag & 2) {
144
 
                wins_name->others=talloc_array(mem_ctx, struct in_addr, wins_name->num_ip);
145
 
                if (wins_name->others==NULL)
146
 
                        return;
147
 
 
148
 
                if(!check_buffer(outbuf, 4*wins_name->num_ip))
149
 
                        return;
150
 
                for (i=0; i<wins_name->num_ip; i++) {
151
 
                        wins_name->others[i].s_addr=IVAL(outbuf->buffer, outbuf->offset);
152
 
                        outbuf->offset+=4;
153
 
                }
154
 
        }
155
 
 
156
 
        if(!check_buffer(outbuf, 4))
157
 
                return;
158
 
        wins_name->foo=RIVAL(outbuf->buffer, outbuf->offset);
159
 
        outbuf->offset+=4;
160
 
 
161
 
}
162
 
 
163
 
/****************************************************************************
164
 
decode a update notification request
165
 
****************************************************************************/
166
 
static void decode_update_notify_request(struct BUFFER *inbuf, UPDATE_NOTIFY_REQUEST *un_rq)
167
 
{
168
 
        int i;
169
 
 
170
 
        if(!check_buffer(inbuf, 4))
171
 
                return;
172
 
        un_rq->partner_count=RIVAL(inbuf->buffer, inbuf->offset);
173
 
        inbuf->offset+=4;
174
 
 
175
 
        un_rq->wins_owner=talloc_array(mem_ctx, WINS_OWNER, un_rq->partner_count);
176
 
        if (un_rq->wins_owner==NULL)
177
 
                return;
178
 
 
179
 
        for (i=0; i<un_rq->partner_count; i++)
180
 
                decode_wins_owner(inbuf, &un_rq->wins_owner[i]);
181
 
 
182
 
        if(!check_buffer(inbuf, 4))
183
 
                return;
184
 
        un_rq->initiating_wins_server.s_addr=IVAL(inbuf->buffer, inbuf->offset);
185
 
        inbuf->offset+=4;
186
 
}
187
 
 
188
 
/****************************************************************************
189
 
decode a send entries request
190
 
****************************************************************************/
191
 
static void decode_send_entries_request(struct BUFFER *inbuf, SEND_ENTRIES_REQUEST *se_rq)
192
 
{
193
 
        decode_wins_owner(inbuf, &se_rq->wins_owner);
194
 
}
195
 
 
196
 
/****************************************************************************
197
 
decode a send entries reply
198
 
****************************************************************************/
199
 
static void decode_send_entries_reply(struct BUFFER *inbuf, SEND_ENTRIES_REPLY *se_rp)
200
 
{
201
 
        int i;
202
 
 
203
 
        if(!check_buffer(inbuf, 4))
204
 
                return;
205
 
        se_rp->max_names = RIVAL(inbuf->buffer, inbuf->offset);
206
 
        inbuf->offset+=4;
207
 
 
208
 
        se_rp->wins_name=talloc_array(mem_ctx, WINS_NAME, se_rp->max_names);
209
 
        if (se_rp->wins_name==NULL)
210
 
                return;
211
 
 
212
 
        for (i=0; i<se_rp->max_names; i++)
213
 
                decode_wins_name(inbuf, &se_rp->wins_name[i]);
214
 
}
215
 
 
216
 
/****************************************************************************
217
 
decode a add version number map table reply
218
 
****************************************************************************/
219
 
static void decode_add_version_number_map_table_reply(struct BUFFER *inbuf, AVMT_REP *avmt_rep)
220
 
{
221
 
        int i;
222
 
 
223
 
        if(!check_buffer(inbuf, 4))
224
 
                return;
225
 
 
226
 
        avmt_rep->partner_count=RIVAL(inbuf->buffer, inbuf->offset);
227
 
        inbuf->offset+=4;
228
 
 
229
 
        avmt_rep->wins_owner=talloc_array(mem_ctx, WINS_OWNER, avmt_rep->partner_count);
230
 
        if (avmt_rep->wins_owner==NULL)
231
 
                return;
232
 
 
233
 
        for (i=0; i<avmt_rep->partner_count; i++)
234
 
                decode_wins_owner(inbuf, &avmt_rep->wins_owner[i]);
235
 
 
236
 
        if(!check_buffer(inbuf, 4))
237
 
                return;
238
 
        avmt_rep->initiating_wins_server.s_addr=IVAL(inbuf->buffer, inbuf->offset);
239
 
        inbuf->offset+=4;
240
 
}
241
 
 
242
 
/****************************************************************************
243
 
decode a replicate packet and fill a structure
244
 
****************************************************************************/
245
 
static void decode_replicate(struct BUFFER *inbuf, REPLICATE *rep)
246
 
{
247
 
        if(!check_buffer(inbuf, 4))
248
 
                return;
249
 
 
250
 
        rep->msg_type = RIVAL(inbuf->buffer, inbuf->offset);
251
 
 
252
 
        inbuf->offset+=4;
253
 
 
254
 
        switch (rep->msg_type) {
255
 
                case 0:
256
 
                        break;
257
 
                case 1:
258
 
                        /* add version number map table reply */
259
 
                        decode_add_version_number_map_table_reply(inbuf, &rep->avmt_rep);
260
 
                        break;
261
 
                case 2:
262
 
                        /* send entry request */
263
 
                        decode_send_entries_request(inbuf, &rep->se_rq);
264
 
                        break;
265
 
                case 3:
266
 
                        /* send entry request */
267
 
                        decode_send_entries_reply(inbuf, &rep->se_rp);
268
 
                        break;
269
 
                case 4:
270
 
                        /* update notification request */
271
 
                        decode_update_notify_request(inbuf, &rep->un_rq);
272
 
                        break;
273
 
                default:
274
 
                        DEBUG(0,("decode_replicate: unknown message type:%d\n", rep->msg_type));
275
 
                        break;
276
 
        }
277
 
}
278
 
 
279
 
/****************************************************************************
280
 
read the generic header and fill the struct.
281
 
****************************************************************************/
282
 
static void read_generic_header(struct BUFFER *inbuf, generic_header *q)
283
 
{
284
 
        if(!check_buffer(inbuf, 16))
285
 
                return;
286
 
 
287
 
        q->data_size = RIVAL(inbuf->buffer, inbuf->offset+0);
288
 
        q->opcode    = RIVAL(inbuf->buffer, inbuf->offset+4);
289
 
        q->assoc_ctx = RIVAL(inbuf->buffer, inbuf->offset+8);
290
 
        q->mess_type = RIVAL(inbuf->buffer, inbuf->offset+12);
291
 
}
292
 
 
293
 
/*******************************************************************
294
 
decode a start association request
295
 
********************************************************************/
296
 
static void decode_start_assoc_request(struct BUFFER *inbuf, START_ASSOC_REQUEST *q)
297
 
{
298
 
        if(!check_buffer(inbuf, 8))
299
 
                return;
300
 
 
301
 
        q->assoc_ctx = RIVAL(inbuf->buffer, inbuf->offset+0);
302
 
        q->min_ver = RSVAL(inbuf->buffer, inbuf->offset+4);
303
 
        q->maj_ver = RSVAL(inbuf->buffer, inbuf->offset+6);
304
 
}
305
 
 
306
 
/*******************************************************************
307
 
decode a start association reply
308
 
********************************************************************/
309
 
static void decode_start_assoc_reply(struct BUFFER *inbuf, START_ASSOC_REPLY *r)
310
 
{
311
 
        if(!check_buffer(inbuf, 8))
312
 
                return;
313
 
 
314
 
        r->assoc_ctx=RIVAL(inbuf->buffer, inbuf->offset+0);
315
 
        r->min_ver = RSVAL(inbuf->buffer, inbuf->offset+4);
316
 
        r->maj_ver = RSVAL(inbuf->buffer, inbuf->offset+6);
317
 
}
318
 
 
319
 
/*******************************************************************
320
 
decode a start association reply
321
 
********************************************************************/
322
 
static void decode_stop_assoc(struct BUFFER *inbuf, STOP_ASSOC *r)
323
 
{
324
 
        if(!check_buffer(inbuf, 4))
325
 
                return;
326
 
 
327
 
        r->reason=RIVAL(inbuf->buffer, inbuf->offset);
328
 
}
329
 
 
330
 
/****************************************************************************
331
 
decode a packet and fill a generic structure
332
 
****************************************************************************/
333
 
void decode_generic_packet(struct BUFFER *inbuf, GENERIC_PACKET *q)
334
 
{
335
 
        read_generic_header(inbuf, &q->header);
336
 
 
337
 
        inbuf->offset+=16;
338
 
 
339
 
        switch (q->header.mess_type) {
340
 
                case 0:
341
 
                        decode_start_assoc_request(inbuf, &q->sa_rq);
342
 
                        break;
343
 
                case 1:
344
 
                        decode_start_assoc_reply(inbuf, &q->sa_rp);
345
 
                        break;
346
 
                case 2:
347
 
                        decode_stop_assoc(inbuf, &q->so);
348
 
                        break;
349
 
                case 3:
350
 
                        decode_replicate(inbuf, &q->rep);
351
 
                        break;
352
 
                default:
353
 
                        DEBUG(0,("decode_generic_packet: unknown message type:%d\n", q->header.mess_type));
354
 
                        break;
355
 
        }
356
 
}
357
 
 
358
 
/****************************************************************************
359
 
encode a WINS_OWNER struct
360
 
****************************************************************************/
361
 
static void encode_wins_owner(struct BUFFER *outbuf, WINS_OWNER *wins_owner)
362
 
{
363
 
        if (!grow_buffer(outbuf, 24))
364
 
                return;
365
 
 
366
 
        SIVAL(outbuf->buffer, outbuf->offset, wins_owner->address.s_addr);
367
 
        outbuf->offset+=4;
368
 
        RSIVAL(outbuf->buffer, outbuf->offset, (int)(wins_owner->max_version>>32));
369
 
        outbuf->offset+=4;
370
 
        RSIVAL(outbuf->buffer, outbuf->offset, (int)(wins_owner->max_version&0xffffffff));
371
 
        outbuf->offset+=4;
372
 
        RSIVAL(outbuf->buffer, outbuf->offset, wins_owner->min_version>>32);
373
 
        outbuf->offset+=4;
374
 
        RSIVAL(outbuf->buffer, outbuf->offset, wins_owner->min_version&0xffffffff);
375
 
        outbuf->offset+=4;
376
 
        RSIVAL(outbuf->buffer, outbuf->offset, wins_owner->type);
377
 
        outbuf->offset+=4;
378
 
        
379
 
}
380
 
 
381
 
/****************************************************************************
382
 
encode a WINS_NAME struct
383
 
****************************************************************************/
384
 
static void encode_wins_name(struct BUFFER *outbuf, WINS_NAME *wins_name)
385
 
{       
386
 
        int i;
387
 
 
388
 
        if (!grow_buffer(outbuf, 48+(4*wins_name->num_ip)))
389
 
                return;
390
 
 
391
 
        RSIVAL(outbuf->buffer, outbuf->offset, wins_name->name_len);
392
 
        outbuf->offset+=4;
393
 
        
394
 
        memset(outbuf->buffer+outbuf->offset, ' ', 15);
395
 
 
396
 
        /* to prevent copying the leading \0 */
397
 
        memcpy(outbuf->buffer+outbuf->offset, wins_name->name, strlen(wins_name->name));
398
 
        outbuf->offset+=15;             
399
 
 
400
 
        outbuf->buffer[outbuf->offset++]=(char)wins_name->type;
401
 
 
402
 
        RSIVAL(outbuf->buffer, outbuf->offset, wins_name->empty);
403
 
        outbuf->offset+=4;
404
 
 
405
 
        RSIVAL(outbuf->buffer, outbuf->offset, wins_name->name_flag);
406
 
        outbuf->offset+=4;
407
 
        RSIVAL(outbuf->buffer, outbuf->offset, wins_name->group_flag);
408
 
        outbuf->offset+=4;
409
 
        RSIVAL(outbuf->buffer, outbuf->offset, wins_name->id>>32);
410
 
        outbuf->offset+=4;
411
 
        RSIVAL(outbuf->buffer, outbuf->offset, wins_name->id);
412
 
        outbuf->offset+=4;
413
 
 
414
 
        if (wins_name->name_flag & 2) {
415
 
                SIVAL(outbuf->buffer, outbuf->offset, wins_name->num_ip);
416
 
                outbuf->offset+=4;
417
 
        }       
418
 
 
419
 
        SIVAL(outbuf->buffer, outbuf->offset, wins_name->owner.s_addr);
420
 
        outbuf->offset+=4;
421
 
 
422
 
        if (wins_name->name_flag & 2) {
423
 
                for (i=0;i<wins_name->num_ip;i++) {
424
 
                        SIVAL(outbuf->buffer, outbuf->offset, wins_name->others[i].s_addr);
425
 
                        outbuf->offset+=4;
426
 
                }
427
 
        }       
428
 
 
429
 
        RSIVAL(outbuf->buffer, outbuf->offset, wins_name->foo);
430
 
        outbuf->offset+=4;
431
 
}
432
 
 
433
 
/****************************************************************************
434
 
encode a update notification request
435
 
****************************************************************************/
436
 
static void encode_update_notify_request(struct BUFFER *outbuf, UPDATE_NOTIFY_REQUEST *un_rq)
437
 
{
438
 
        int i;
439
 
 
440
 
        if (!grow_buffer(outbuf, 8))
441
 
                return;
442
 
                
443
 
        RSIVAL(outbuf->buffer, outbuf->offset, un_rq->partner_count);
444
 
        outbuf->offset+=4;
445
 
 
446
 
        for (i=0; i<un_rq->partner_count; i++)
447
 
                encode_wins_owner(outbuf,  &un_rq->wins_owner[i]);
448
 
 
449
 
        SIVAL(outbuf->buffer, outbuf->offset, un_rq->initiating_wins_server.s_addr);
450
 
        outbuf->offset+=4;
451
 
        
452
 
}
453
 
 
454
 
/****************************************************************************
455
 
decode a send entries request
456
 
****************************************************************************/
457
 
static void encode_send_entries_request(struct BUFFER *outbuf, SEND_ENTRIES_REQUEST *se_rq)
458
 
{
459
 
        encode_wins_owner(outbuf, &se_rq->wins_owner);
460
 
}
461
 
 
462
 
/****************************************************************************
463
 
decode a send entries reply
464
 
****************************************************************************/
465
 
static void encode_send_entries_reply(struct BUFFER *outbuf, SEND_ENTRIES_REPLY *se_rp)
466
 
{
467
 
        int i;
468
 
 
469
 
        if (!grow_buffer(outbuf, 4))
470
 
                return;
471
 
                
472
 
        RSIVAL(outbuf->buffer, outbuf->offset, se_rp->max_names);
473
 
        outbuf->offset+=4;
474
 
 
475
 
        for (i=0; i<se_rp->max_names; i++)
476
 
                encode_wins_name(outbuf, &se_rp->wins_name[i]);
477
 
 
478
 
}
479
 
 
480
 
/****************************************************************************
481
 
encode a add version number map table reply
482
 
****************************************************************************/
483
 
static void encode_add_version_number_map_table_reply(struct BUFFER *outbuf, AVMT_REP *avmt_rep)
484
 
{
485
 
        int i;
486
 
 
487
 
        if (!grow_buffer(outbuf, 8))
488
 
                return;
489
 
 
490
 
        RSIVAL(outbuf->buffer, outbuf->offset, avmt_rep->partner_count);
491
 
        outbuf->offset+=4;
492
 
        
493
 
        for (i=0; i<avmt_rep->partner_count; i++)
494
 
                encode_wins_owner(outbuf, &avmt_rep->wins_owner[i]);
495
 
 
496
 
        SIVAL(outbuf->buffer, outbuf->offset, avmt_rep->initiating_wins_server.s_addr);
497
 
        outbuf->offset+=4;
498
 
        
499
 
}
500
 
 
501
 
/****************************************************************************
502
 
decode a replicate packet and fill a structure
503
 
****************************************************************************/
504
 
static void encode_replicate(struct BUFFER *outbuf, REPLICATE *rep)
505
 
{
506
 
        if (!grow_buffer(outbuf, 4))
507
 
                return;
508
 
 
509
 
        RSIVAL(outbuf->buffer, outbuf->offset, rep->msg_type);
510
 
        outbuf->offset+=4;
511
 
 
512
 
        switch (rep->msg_type) {
513
 
                case 0:
514
 
                        break;
515
 
                case 1:
516
 
                        /* add version number map table reply */
517
 
                        encode_add_version_number_map_table_reply(outbuf, &rep->avmt_rep);
518
 
                        break;
519
 
                case 2:
520
 
                        /* send entry request */
521
 
                        encode_send_entries_request(outbuf, &rep->se_rq);
522
 
                        break;
523
 
                case 3:
524
 
                        /* send entry request */
525
 
                        encode_send_entries_reply(outbuf, &rep->se_rp);
526
 
                        break;
527
 
                case 4:
528
 
                        /* update notification request */
529
 
                        encode_update_notify_request(outbuf, &rep->un_rq);
530
 
                        break;
531
 
                default:
532
 
                        DEBUG(0,("encode_replicate: unknown message type:%d\n", rep->msg_type));
533
 
                        break;
534
 
        }
535
 
}
536
 
 
537
 
/****************************************************************************
538
 
write the generic header.
539
 
****************************************************************************/
540
 
static void write_generic_header(struct BUFFER *outbuf, generic_header *r)
541
 
{
542
 
        RSIVAL(outbuf->buffer, 0, r->data_size);
543
 
        RSIVAL(outbuf->buffer, 4, r->opcode);
544
 
        RSIVAL(outbuf->buffer, 8, r->assoc_ctx);
545
 
        RSIVAL(outbuf->buffer,12, r->mess_type);
546
 
}
547
 
 
548
 
/*******************************************************************
549
 
decode a start association request
550
 
********************************************************************/
551
 
static void encode_start_assoc_request(struct BUFFER *outbuf, START_ASSOC_REQUEST *q)
552
 
{
553
 
        if (!grow_buffer(outbuf, 45))
554
 
                return;
555
 
 
556
 
        RSIVAL(outbuf->buffer, outbuf->offset, q->assoc_ctx);
557
 
        RSSVAL(outbuf->buffer, outbuf->offset+4, q->min_ver);
558
 
        RSSVAL(outbuf->buffer, outbuf->offset+6, q->maj_ver);
559
 
        
560
 
        outbuf->offset=45;
561
 
}
562
 
 
563
 
/*******************************************************************
564
 
decode a start association reply
565
 
********************************************************************/
566
 
static void encode_start_assoc_reply(struct BUFFER *outbuf, START_ASSOC_REPLY *r)
567
 
{
568
 
        if (!grow_buffer(outbuf, 45))
569
 
                return;
570
 
 
571
 
        RSIVAL(outbuf->buffer, outbuf->offset, r->assoc_ctx);
572
 
        RSSVAL(outbuf->buffer, outbuf->offset+4, r->min_ver);
573
 
        RSSVAL(outbuf->buffer, outbuf->offset+6, r->maj_ver);
574
 
 
575
 
        outbuf->offset=45;
576
 
}
577
 
 
578
 
/*******************************************************************
579
 
decode a start association reply
580
 
********************************************************************/
581
 
static void encode_stop_assoc(struct BUFFER *outbuf, STOP_ASSOC *r)
582
 
{
583
 
        if (!grow_buffer(outbuf, 44))
584
 
                return;
585
 
 
586
 
        RSIVAL(outbuf->buffer, outbuf->offset, r->reason);
587
 
        
588
 
        outbuf->offset=44;
589
 
}
590
 
 
591
 
/****************************************************************************
592
 
write the generic header size.
593
 
****************************************************************************/
594
 
static void write_generic_header_size(generic_header *r, int size)
595
 
{
596
 
        /* the buffer size is the total size minus the size field */
597
 
        r->data_size=size-4;
598
 
}
599
 
 
600
 
/****************************************************************************
601
 
encode a packet and read a generic structure
602
 
****************************************************************************/
603
 
void encode_generic_packet(struct BUFFER *outbuf, GENERIC_PACKET *q)
604
 
{
605
 
        if (!grow_buffer(outbuf, 16))
606
 
                return;
607
 
 
608
 
        outbuf->offset=16;
609
 
 
610
 
        switch (q->header.mess_type) {
611
 
                case 0:
612
 
                        encode_start_assoc_request(outbuf, &q->sa_rq);
613
 
                        break;
614
 
                case 1:
615
 
                        encode_start_assoc_reply(outbuf, &q->sa_rp);
616
 
                        break;
617
 
                case 2:
618
 
                        encode_stop_assoc(outbuf, &q->so);
619
 
                        break;
620
 
                case 3:
621
 
                        encode_replicate(outbuf, &q->rep);
622
 
                        break;
623
 
                default:
624
 
                        DEBUG(0,("encode_generic_packet: unknown message type:%d\n", q->header.mess_type));
625
 
                        break;
626
 
        }
627
 
        
628
 
        write_generic_header_size(&q->header, outbuf->offset);
629
 
        write_generic_header(outbuf, &q->header);
630
 
}
631
 
 
632
 
 
633
 
/****************************************************************************
634
 
dump a WINS_OWNER structure
635
 
****************************************************************************/
636
 
static void dump_wins_owner(WINS_OWNER *wins_owner)
637
 
{
638
 
        DEBUGADD(10,("\t\t\t\taddress         : %s\n", inet_ntoa(wins_owner->address)));
639
 
        DEBUGADD(10,("\t\t\t\tmax version: %d\n", (int)wins_owner->max_version));
640
 
        DEBUGADD(10,("\t\t\t\tmin version: %d\n", (int)wins_owner->min_version));
641
 
        DEBUGADD(10,("\t\t\t\ttype            : %d\n", wins_owner->type));
642
 
}
643
 
 
644
 
/****************************************************************************
645
 
dump a WINS_NAME structure
646
 
****************************************************************************/
647
 
static void dump_wins_name(WINS_NAME *wins_name)
648
 
{
649
 
        fstring name;
650
 
        int i;
651
 
 
652
 
        strncpy(name, wins_name->name, 15);
653
 
 
654
 
        DEBUGADD(10,("name: %d, %s<%02x> %x,%x, %d %s %d ", wins_name->name_len, name, wins_name->type,
655
 
                    wins_name->name_flag, wins_name->group_flag, (int)wins_name->id,
656
 
                    inet_ntoa(wins_name->owner), wins_name->num_ip));
657
 
 
658
 
        if (wins_name->num_ip!=1)
659
 
                for (i=0; i<wins_name->num_ip; i++)
660
 
                        DEBUGADD(10,("%s ", inet_ntoa(wins_name->others[i])));  
661
 
 
662
 
        DEBUGADD(10,("\n"));
663
 
}
664
 
 
665
 
/****************************************************************************
666
 
dump a replicate structure
667
 
****************************************************************************/
668
 
static void dump_replicate(REPLICATE *rep)
669
 
{
670
 
        int i;
671
 
 
672
 
        DEBUGADD(5,("\t\tmsg_type: %d ", rep->msg_type));
673
 
 
674
 
        switch (rep->msg_type) {
675
 
                case 0:
676
 
                        DEBUGADD(5,("(Add Version Map Table Request)\n"));
677
 
                        break;
678
 
                case 1:
679
 
                        DEBUGADD(5,("(Add Version Map Table Reply)\n"));
680
 
                        DEBUGADD(5,("\t\t\tpartner_count         : %d\n", rep->avmt_rep.partner_count));
681
 
                        for (i=0; i<rep->avmt_rep.partner_count; i++)
682
 
                                dump_wins_owner(&rep->avmt_rep.wins_owner[i]);
683
 
                        DEBUGADD(5,("\t\t\tinitiating_wins_server: %s\n", inet_ntoa(rep->avmt_rep.initiating_wins_server)));
684
 
                        break;
685
 
                case 2:
686
 
                        DEBUGADD(5,("(Send Entries Request)\n"));
687
 
                        dump_wins_owner(&rep->se_rq.wins_owner);
688
 
                        break;
689
 
                case 3:
690
 
                        DEBUGADD(5,("(Send Entries Reply)\n"));
691
 
                        DEBUGADD(5,("\t\t\tmax_names         : %d\n", rep->se_rp.max_names));
692
 
                        for (i=0; i<rep->se_rp.max_names; i++)
693
 
                                dump_wins_name(&rep->se_rp.wins_name[i]);
694
 
                        break;
695
 
                case 4:
696
 
                        DEBUGADD(5,("(Update Notify Request)\n"));
697
 
                        DEBUGADD(5,("\t\t\tpartner_count         : %d\n", rep->un_rq.partner_count));
698
 
                        for (i=0; i<rep->un_rq.partner_count; i++)
699
 
                                dump_wins_owner(&rep->un_rq.wins_owner[i]);
700
 
                        DEBUGADD(5,("\t\t\tinitiating_wins_server: %s\n", inet_ntoa(rep->un_rq.initiating_wins_server)));
701
 
                        break;
702
 
                default:
703
 
                        DEBUG(5,("\n"));
704
 
                        break;
705
 
        }
706
 
}
707
 
 
708
 
/****************************************************************************
709
 
dump a generic structure
710
 
****************************************************************************/
711
 
void dump_generic_packet(GENERIC_PACKET *q)
712
 
{
713
 
        DEBUG(5,("dump_generic_packet:\n"));
714
 
        DEBUGADD(5,("\tdata_size: %08x\n", q->header.data_size));
715
 
        DEBUGADD(5,("\topcode   : %08x\n", q->header.opcode));
716
 
        DEBUGADD(5,("\tassoc_ctx: %08x\n", q->header.assoc_ctx));
717
 
        DEBUGADD(5,("\tmess_type: %08x ", q->header.mess_type));
718
 
 
719
 
        switch (q->header.mess_type) {
720
 
                case 0:
721
 
                        DEBUGADD(5,("(Start Association Request)\n"));
722
 
                        DEBUGADD(5,("\t\tassoc_ctx: %08x\n", q->sa_rq.assoc_ctx));
723
 
                        DEBUGADD(5,("\t\tmin_ver  : %04x\n", q->sa_rq.min_ver));
724
 
                        DEBUGADD(5,("\t\tmaj_ver  : %04x\n", q->sa_rq.maj_ver));
725
 
                        break;
726
 
                case 1:
727
 
                        DEBUGADD(5,("(Start Association Reply)\n"));
728
 
                        DEBUGADD(5,("\t\tassoc_ctx: %08x\n", q->sa_rp.assoc_ctx));
729
 
                        DEBUGADD(5,("\t\tmin_ver  : %04x\n", q->sa_rp.min_ver));
730
 
                        DEBUGADD(5,("\t\tmaj_ver  : %04x\n", q->sa_rp.maj_ver));
731
 
                        break;
732
 
                case 2:
733
 
                        DEBUGADD(5,("(Stop Association)\n"));
734
 
                        DEBUGADD(5,("\t\treason: %08x\n", q->so.reason));
735
 
                        break;
736
 
                case 3:
737
 
                        DEBUGADD(5,("(Replication Message)\n"));
738
 
                        dump_replicate(&q->rep);
739
 
                        break;
740
 
                default:
741
 
                        DEBUG(5,("\n"));
742
 
                        break;
743
 
        }
744
 
 
745
 
}
746
 
 
747
 
/****************************************************************************
748
 
generate a stop packet
749
 
****************************************************************************/
750
 
void stop_packet(GENERIC_PACKET *q, GENERIC_PACKET *r, int reason)
751
 
{
752
 
        r->header.opcode=OPCODE_NON_NBT;
753
 
        r->header.assoc_ctx=get_server_assoc(q->header.assoc_ctx);
754
 
        r->header.mess_type=MESSAGE_TYPE_STOP_ASSOC;
755
 
        r->so.reason=reason;
756
 
        
757
 
}
758
 
 
759