0001-01-01 02:30:17 +02:30
/*
0001-01-01 02:30:17 +02:30
* Unix SMB / CIFS implementation .
0001-01-01 02:30:17 +02:30
* RPC Pipe client / server routines
* Copyright ( C ) Jean Fran <EFBFBD> ois Micouleau 1998 - 2002.
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
# include "wins_repl.h"
extern TALLOC_CTX * mem_ctx ;
/****************************************************************************
grow the send buffer if necessary
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
BOOL grow_buffer ( struct BUFFER * buffer , int more )
0001-01-01 02:30:17 +02:30
{
char * temp ;
DEBUG ( 10 , ( " grow_buffer: size is: %d offet is:%d growing by %d \n " , buffer - > length , buffer - > offset , more ) ) ;
0001-01-01 02:30:17 +02:30
/* grow by at least 256 bytes */
if ( more < 256 )
more = 256 ;
0001-01-01 02:30:17 +02:30
if ( buffer - > offset + more > = buffer - > length ) {
0001-01-01 02:30:17 +02:30
temp = ( char * ) talloc_realloc ( mem_ctx , buffer - > buffer , sizeof ( char ) * ( buffer - > length + more ) ) ;
0001-01-01 02:30:17 +02:30
if ( temp = = NULL ) {
DEBUG ( 0 , ( " grow_buffer: can't grow buffer \n " ) ) ;
return False ;
}
0001-01-01 02:30:17 +02:30
buffer - > length + = more ;
0001-01-01 02:30:17 +02:30
buffer - > buffer = temp ;
}
return True ;
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
check if the buffer has that much data
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL check_buffer ( struct BUFFER * buffer , int more )
{
DEBUG ( 10 , ( " check_buffer: size is: %d offet is:%d growing by %d \n " , buffer - > length , buffer - > offset , more ) ) ;
if ( buffer - > offset + more > buffer - > length ) {
DEBUG ( 10 , ( " check_buffer: buffer smaller than requested, size is: %d needed: %d \n " , buffer - > length , buffer - > offset + more ) ) ;
return False ;
}
return True ;
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
decode a WINS_OWNER struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
static void decode_wins_owner ( struct BUFFER * inbuf , WINS_OWNER * wins_owner )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( inbuf , 24 ) )
return ;
wins_owner - > address . s_addr = IVAL ( inbuf - > buffer , inbuf - > offset ) ;
wins_owner - > max_version = ( ( SMB_BIG_UINT ) RIVAL ( inbuf - > buffer , inbuf - > offset + 4 ) ) < < 32 ;
wins_owner - > max_version | = RIVAL ( inbuf - > buffer , inbuf - > offset + 8 ) ;
wins_owner - > min_version = ( ( SMB_BIG_UINT ) RIVAL ( inbuf - > buffer , inbuf - > offset + 12 ) ) < < 32 ;
wins_owner - > min_version | = RIVAL ( inbuf - > buffer , inbuf - > offset + 16 ) ;
wins_owner - > type = RIVAL ( inbuf - > buffer , inbuf - > offset + 20 ) ;
inbuf - > offset + = 24 ;
0001-01-01 02:30:17 +02:30
}
/****************************************************************************
decode a WINS_NAME struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
static void decode_wins_name ( struct BUFFER * outbuf , WINS_NAME * wins_name )
0001-01-01 02:30:17 +02:30
{
char * p ;
int i ;
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( outbuf , 40 ) )
return ;
wins_name - > name_len = RIVAL ( outbuf - > buffer , outbuf - > offset ) ;
outbuf - > offset + = 4 ;
memcpy ( wins_name - > name , outbuf - > buffer + outbuf - > offset , 15 ) ;
0001-01-01 02:30:17 +02:30
wins_name - > name [ 15 ] = ' \0 ' ;
0001-01-01 02:30:17 +02:30
if ( ( p = strchr ( wins_name - > name , ' ' ) ) ! = NULL )
* p = 0 ;
0001-01-01 02:30:17 +02:30
outbuf - > offset + = 15 ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
wins_name - > type = ( int ) outbuf - > buffer [ outbuf - > offset + + ] ;
0001-01-01 02:30:17 +02:30
/*
* fix to bug in WINS replication ,
* present in all versions including W2K SP2 !
*/
if ( wins_name - > name [ 0 ] = = 0x1B ) {
wins_name - > name [ 0 ] = ( char ) wins_name - > type ;
wins_name - > type = 0x1B ;
}
0001-01-01 02:30:17 +02:30
wins_name - > empty = RIVAL ( outbuf - > buffer , outbuf - > offset ) ;
outbuf - > offset + = 4 ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
wins_name - > name_flag = RIVAL ( outbuf - > buffer , outbuf - > offset ) ;
outbuf - > offset + = 4 ;
wins_name - > group_flag = RIVAL ( outbuf - > buffer , outbuf - > offset ) ;
outbuf - > offset + = 4 ;
wins_name - > id = ( ( SMB_BIG_UINT ) RIVAL ( outbuf - > buffer , outbuf - > offset ) ) < < 32 ;
outbuf - > offset + = 4 ;
wins_name - > id | = RIVAL ( outbuf - > buffer , outbuf - > offset ) ;
outbuf - > offset + = 4 ;
0001-01-01 02:30:17 +02:30
/* special groups have multiple address */
if ( wins_name - > name_flag & 2 ) {
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( outbuf , 4 ) )
return ;
wins_name - > num_ip = IVAL ( outbuf - > buffer , outbuf - > offset ) ;
outbuf - > offset + = 4 ;
0001-01-01 02:30:17 +02:30
}
else
wins_name - > num_ip = 1 ;
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( outbuf , 4 ) )
return ;
wins_name - > owner . s_addr = IVAL ( outbuf - > buffer , outbuf - > offset ) ;
outbuf - > offset + = 4 ;
0001-01-01 02:30:17 +02:30
if ( wins_name - > name_flag & 2 ) {
wins_name - > others = ( struct in_addr * ) talloc ( mem_ctx , sizeof ( struct in_addr ) * wins_name - > num_ip ) ;
if ( wins_name - > others = = NULL )
0001-01-01 02:30:17 +02:30
return ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( outbuf , 4 * wins_name - > num_ip ) )
return ;
0001-01-01 02:30:17 +02:30
for ( i = 0 ; i < wins_name - > num_ip ; i + + ) {
0001-01-01 02:30:17 +02:30
wins_name - > others [ i ] . s_addr = IVAL ( outbuf - > buffer , outbuf - > offset ) ;
outbuf - > offset + = 4 ;
0001-01-01 02:30:17 +02:30
}
}
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( outbuf , 4 ) )
return ;
wins_name - > foo = RIVAL ( outbuf - > buffer , outbuf - > offset ) ;
outbuf - > offset + = 4 ;
0001-01-01 02:30:17 +02:30
}
/****************************************************************************
decode a update notification request
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
static void decode_update_notify_request ( struct BUFFER * inbuf , UPDATE_NOTIFY_REQUEST * un_rq )
0001-01-01 02:30:17 +02:30
{
int i ;
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( inbuf , 4 ) )
return ;
un_rq - > partner_count = RIVAL ( inbuf - > buffer , inbuf - > offset ) ;
inbuf - > offset + = 4 ;
0001-01-01 02:30:17 +02:30
un_rq - > wins_owner = ( WINS_OWNER * ) talloc ( mem_ctx , un_rq - > partner_count * sizeof ( WINS_OWNER ) ) ;
if ( un_rq - > wins_owner = = NULL )
return ;
for ( i = 0 ; i < un_rq - > partner_count ; i + + )
0001-01-01 02:30:17 +02:30
decode_wins_owner ( inbuf , & un_rq - > wins_owner [ i ] ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( inbuf , 4 ) )
return ;
un_rq - > initiating_wins_server . s_addr = IVAL ( inbuf - > buffer , inbuf - > offset ) ;
inbuf - > offset + = 4 ;
0001-01-01 02:30:17 +02:30
}
/****************************************************************************
decode a send entries request
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
static void decode_send_entries_request ( struct BUFFER * inbuf , SEND_ENTRIES_REQUEST * se_rq )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
decode_wins_owner ( inbuf , & se_rq - > wins_owner ) ;
0001-01-01 02:30:17 +02:30
}
/****************************************************************************
decode a send entries reply
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
static void decode_send_entries_reply ( struct BUFFER * inbuf , SEND_ENTRIES_REPLY * se_rp )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
int i ;
if ( ! check_buffer ( inbuf , 4 ) )
return ;
se_rp - > max_names = RIVAL ( inbuf - > buffer , inbuf - > offset ) ;
inbuf - > offset + = 4 ;
0001-01-01 02:30:17 +02:30
se_rp - > wins_name = ( WINS_NAME * ) talloc ( mem_ctx , se_rp - > max_names * sizeof ( WINS_NAME ) ) ;
if ( se_rp - > wins_name = = NULL )
return ;
for ( i = 0 ; i < se_rp - > max_names ; i + + )
0001-01-01 02:30:17 +02:30
decode_wins_name ( inbuf , & se_rp - > wins_name [ i ] ) ;
0001-01-01 02:30:17 +02:30
}
/****************************************************************************
decode a add version number map table reply
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
static void decode_add_version_number_map_table_reply ( struct BUFFER * inbuf , AVMT_REP * avmt_rep )
0001-01-01 02:30:17 +02:30
{
int i ;
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( inbuf , 4 ) )
return ;
avmt_rep - > partner_count = RIVAL ( inbuf - > buffer , inbuf - > offset ) ;
inbuf - > offset + = 4 ;
0001-01-01 02:30:17 +02:30
avmt_rep - > wins_owner = ( WINS_OWNER * ) talloc ( mem_ctx , avmt_rep - > partner_count * sizeof ( WINS_OWNER ) ) ;
if ( avmt_rep - > wins_owner = = NULL )
return ;
for ( i = 0 ; i < avmt_rep - > partner_count ; i + + )
0001-01-01 02:30:17 +02:30
decode_wins_owner ( inbuf , & avmt_rep - > wins_owner [ i ] ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( inbuf , 4 ) )
return ;
avmt_rep - > initiating_wins_server . s_addr = IVAL ( inbuf - > buffer , inbuf - > offset ) ;
inbuf - > offset + = 4 ;
0001-01-01 02:30:17 +02:30
}
/****************************************************************************
decode a replicate packet and fill a structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
static void decode_replicate ( struct BUFFER * inbuf , REPLICATE * rep )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( inbuf , 4 ) )
return ;
rep - > msg_type = RIVAL ( inbuf - > buffer , inbuf - > offset ) ;
inbuf - > offset + = 4 ;
0001-01-01 02:30:17 +02:30
switch ( rep - > msg_type ) {
case 0 :
break ;
case 1 :
/* add version number map table reply */
0001-01-01 02:30:17 +02:30
decode_add_version_number_map_table_reply ( inbuf , & rep - > avmt_rep ) ;
0001-01-01 02:30:17 +02:30
break ;
case 2 :
/* send entry request */
0001-01-01 02:30:17 +02:30
decode_send_entries_request ( inbuf , & rep - > se_rq ) ;
0001-01-01 02:30:17 +02:30
break ;
case 3 :
/* send entry request */
0001-01-01 02:30:17 +02:30
decode_send_entries_reply ( inbuf , & rep - > se_rp ) ;
0001-01-01 02:30:17 +02:30
break ;
case 4 :
/* update notification request */
0001-01-01 02:30:17 +02:30
decode_update_notify_request ( inbuf , & rep - > un_rq ) ;
0001-01-01 02:30:17 +02:30
break ;
default :
DEBUG ( 0 , ( " decode_replicate: unknown message type:%d \n " , rep - > msg_type ) ) ;
break ;
}
}
/****************************************************************************
read the generic header and fill the struct .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
static void read_generic_header ( struct BUFFER * inbuf , generic_header * q )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( inbuf , 16 ) )
return ;
q - > data_size = RIVAL ( inbuf - > buffer , inbuf - > offset + 0 ) ;
q - > opcode = RIVAL ( inbuf - > buffer , inbuf - > offset + 4 ) ;
q - > assoc_ctx = RIVAL ( inbuf - > buffer , inbuf - > offset + 8 ) ;
q - > mess_type = RIVAL ( inbuf - > buffer , inbuf - > offset + 12 ) ;
0001-01-01 02:30:17 +02:30
}
/*******************************************************************
decode a start association request
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
static void decode_start_assoc_request ( struct BUFFER * inbuf , START_ASSOC_REQUEST * q )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( inbuf , 8 ) )
return ;
q - > assoc_ctx = RIVAL ( inbuf - > buffer , inbuf - > offset + 0 ) ;
q - > min_ver = RSVAL ( inbuf - > buffer , inbuf - > offset + 4 ) ;
q - > maj_ver = RSVAL ( inbuf - > buffer , inbuf - > offset + 6 ) ;
0001-01-01 02:30:17 +02:30
}
/*******************************************************************
decode a start association reply
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
static void decode_start_assoc_reply ( struct BUFFER * inbuf , START_ASSOC_REPLY * r )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( inbuf , 8 ) )
return ;
r - > assoc_ctx = RIVAL ( inbuf - > buffer , inbuf - > offset + 0 ) ;
r - > min_ver = RSVAL ( inbuf - > buffer , inbuf - > offset + 4 ) ;
r - > maj_ver = RSVAL ( inbuf - > buffer , inbuf - > offset + 6 ) ;
0001-01-01 02:30:17 +02:30
}
/*******************************************************************
decode a start association reply
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
static void decode_stop_assoc ( struct BUFFER * inbuf , STOP_ASSOC * r )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
if ( ! check_buffer ( inbuf , 4 ) )
return ;
r - > reason = RIVAL ( inbuf - > buffer , inbuf - > offset ) ;
0001-01-01 02:30:17 +02:30
}
/****************************************************************************
decode a packet and fill a generic structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
void decode_generic_packet ( struct BUFFER * inbuf , GENERIC_PACKET * q )
0001-01-01 02:30:17 +02:30
{
read_generic_header ( inbuf , & q - > header ) ;
0001-01-01 02:30:17 +02:30
inbuf - > offset + = 16 ;
0001-01-01 02:30:17 +02:30
switch ( q - > header . mess_type ) {
case 0 :
0001-01-01 02:30:17 +02:30
decode_start_assoc_request ( inbuf , & q - > sa_rq ) ;
0001-01-01 02:30:17 +02:30
break ;
case 1 :
0001-01-01 02:30:17 +02:30
decode_start_assoc_reply ( inbuf , & q - > sa_rp ) ;
0001-01-01 02:30:17 +02:30
break ;
case 2 :
0001-01-01 02:30:17 +02:30
decode_stop_assoc ( inbuf , & q - > so ) ;
0001-01-01 02:30:17 +02:30
break ;
case 3 :
0001-01-01 02:30:17 +02:30
decode_replicate ( inbuf , & q - > rep ) ;
0001-01-01 02:30:17 +02:30
break ;
default :
DEBUG ( 0 , ( " decode_generic_packet: unknown message type:%d \n " , q - > header . mess_type ) ) ;
break ;
}
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
encode a WINS_OWNER struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
static void encode_wins_owner ( struct BUFFER * outbuf , WINS_OWNER * wins_owner )
{
if ( ! grow_buffer ( outbuf , 24 ) )
return ;
SIVAL ( outbuf - > buffer , outbuf - > offset , wins_owner - > address . s_addr ) ;
outbuf - > offset + = 4 ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , ( int ) ( wins_owner - > max_version > > 32 ) ) ;
outbuf - > offset + = 4 ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , ( int ) ( wins_owner - > max_version & 0xffffffff ) ) ;
outbuf - > offset + = 4 ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , wins_owner - > min_version > > 32 ) ;
outbuf - > offset + = 4 ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , wins_owner - > min_version & 0xffffffff ) ;
outbuf - > offset + = 4 ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , wins_owner - > type ) ;
outbuf - > offset + = 4 ;
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
encode a WINS_NAME struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
static void encode_wins_name ( struct BUFFER * outbuf , WINS_NAME * wins_name )
{
int i ;
if ( ! grow_buffer ( outbuf , 48 + ( 4 * wins_name - > num_ip ) ) )
return ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , wins_name - > name_len ) ;
outbuf - > offset + = 4 ;
memset ( outbuf - > buffer + outbuf - > offset , ' ' , 15 ) ;
/* to prevent copying the leading \0 */
memcpy ( outbuf - > buffer + outbuf - > offset , wins_name - > name , strlen ( wins_name - > name ) ) ;
outbuf - > offset + = 15 ;
outbuf - > buffer [ outbuf - > offset + + ] = ( char ) wins_name - > type ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , wins_name - > empty ) ;
outbuf - > offset + = 4 ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , wins_name - > name_flag ) ;
outbuf - > offset + = 4 ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , wins_name - > group_flag ) ;
outbuf - > offset + = 4 ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , wins_name - > id > > 32 ) ;
outbuf - > offset + = 4 ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , wins_name - > id ) ;
outbuf - > offset + = 4 ;
if ( wins_name - > name_flag & 2 ) {
SIVAL ( outbuf - > buffer , outbuf - > offset , wins_name - > num_ip ) ;
outbuf - > offset + = 4 ;
}
SIVAL ( outbuf - > buffer , outbuf - > offset , wins_name - > owner . s_addr ) ;
outbuf - > offset + = 4 ;
if ( wins_name - > name_flag & 2 ) {
for ( i = 0 ; i < wins_name - > num_ip ; i + + ) {
SIVAL ( outbuf - > buffer , outbuf - > offset , wins_name - > others [ i ] . s_addr ) ;
outbuf - > offset + = 4 ;
}
}
RSIVAL ( outbuf - > buffer , outbuf - > offset , wins_name - > foo ) ;
outbuf - > offset + = 4 ;
}
/****************************************************************************
0001-01-01 02:30:17 +02:30
encode a update notification request
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void encode_update_notify_request ( struct BUFFER * outbuf , UPDATE_NOTIFY_REQUEST * un_rq )
{
int i ;
if ( ! grow_buffer ( outbuf , 8 ) )
return ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , un_rq - > partner_count ) ;
outbuf - > offset + = 4 ;
for ( i = 0 ; i < un_rq - > partner_count ; i + + )
encode_wins_owner ( outbuf , & un_rq - > wins_owner [ i ] ) ;
SIVAL ( outbuf - > buffer , outbuf - > offset , un_rq - > initiating_wins_server . s_addr ) ;
outbuf - > offset + = 4 ;
}
/****************************************************************************
decode a send entries request
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void encode_send_entries_request ( struct BUFFER * outbuf , SEND_ENTRIES_REQUEST * se_rq )
{
encode_wins_owner ( outbuf , & se_rq - > wins_owner ) ;
}
/****************************************************************************
decode a send entries reply
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void encode_send_entries_reply ( struct BUFFER * outbuf , SEND_ENTRIES_REPLY * se_rp )
{
int i ;
if ( ! grow_buffer ( outbuf , 4 ) )
return ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , se_rp - > max_names ) ;
outbuf - > offset + = 4 ;
for ( i = 0 ; i < se_rp - > max_names ; i + + )
encode_wins_name ( outbuf , & se_rp - > wins_name [ i ] ) ;
}
/****************************************************************************
encode a add version number map table reply
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void encode_add_version_number_map_table_reply ( struct BUFFER * outbuf , AVMT_REP * avmt_rep )
{
int i ;
if ( ! grow_buffer ( outbuf , 8 ) )
return ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , avmt_rep - > partner_count ) ;
outbuf - > offset + = 4 ;
for ( i = 0 ; i < avmt_rep - > partner_count ; i + + )
encode_wins_owner ( outbuf , & avmt_rep - > wins_owner [ i ] ) ;
SIVAL ( outbuf - > buffer , outbuf - > offset , avmt_rep - > initiating_wins_server . s_addr ) ;
outbuf - > offset + = 4 ;
}
/****************************************************************************
decode a replicate packet and fill a structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void encode_replicate ( struct BUFFER * outbuf , REPLICATE * rep )
{
if ( ! grow_buffer ( outbuf , 4 ) )
return ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , rep - > msg_type ) ;
outbuf - > offset + = 4 ;
switch ( rep - > msg_type ) {
case 0 :
break ;
case 1 :
/* add version number map table reply */
encode_add_version_number_map_table_reply ( outbuf , & rep - > avmt_rep ) ;
break ;
case 2 :
/* send entry request */
encode_send_entries_request ( outbuf , & rep - > se_rq ) ;
break ;
case 3 :
/* send entry request */
encode_send_entries_reply ( outbuf , & rep - > se_rp ) ;
break ;
case 4 :
/* update notification request */
encode_update_notify_request ( outbuf , & rep - > un_rq ) ;
break ;
default :
0001-01-01 02:30:17 +02:30
DEBUG ( 0 , ( " encode_replicate: unknown message type:%d \n " , rep - > msg_type ) ) ;
0001-01-01 02:30:17 +02:30
break ;
}
}
/****************************************************************************
write the generic header .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void write_generic_header ( struct BUFFER * outbuf , generic_header * r )
{
RSIVAL ( outbuf - > buffer , 0 , r - > data_size ) ;
RSIVAL ( outbuf - > buffer , 4 , r - > opcode ) ;
RSIVAL ( outbuf - > buffer , 8 , r - > assoc_ctx ) ;
RSIVAL ( outbuf - > buffer , 12 , r - > mess_type ) ;
}
/*******************************************************************
decode a start association request
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void encode_start_assoc_request ( struct BUFFER * outbuf , START_ASSOC_REQUEST * q )
{
if ( ! grow_buffer ( outbuf , 45 ) )
return ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , q - > assoc_ctx ) ;
RSSVAL ( outbuf - > buffer , outbuf - > offset + 4 , q - > min_ver ) ;
RSSVAL ( outbuf - > buffer , outbuf - > offset + 6 , q - > maj_ver ) ;
outbuf - > offset = 45 ;
}
/*******************************************************************
decode a start association reply
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void encode_start_assoc_reply ( struct BUFFER * outbuf , START_ASSOC_REPLY * r )
{
if ( ! grow_buffer ( outbuf , 45 ) )
return ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , r - > assoc_ctx ) ;
RSSVAL ( outbuf - > buffer , outbuf - > offset + 4 , r - > min_ver ) ;
RSSVAL ( outbuf - > buffer , outbuf - > offset + 6 , r - > maj_ver ) ;
outbuf - > offset = 45 ;
}
/*******************************************************************
decode a start association reply
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void encode_stop_assoc ( struct BUFFER * outbuf , STOP_ASSOC * r )
{
if ( ! grow_buffer ( outbuf , 44 ) )
return ;
RSIVAL ( outbuf - > buffer , outbuf - > offset , r - > reason ) ;
outbuf - > offset = 44 ;
}
/****************************************************************************
write the generic header size .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void write_generic_header_size ( generic_header * r , int size )
{
/* the buffer size is the total size minus the size field */
r - > data_size = size - 4 ;
}
/****************************************************************************
encode a packet and read a generic structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void encode_generic_packet ( struct BUFFER * outbuf , GENERIC_PACKET * q )
{
if ( ! grow_buffer ( outbuf , 16 ) )
return ;
outbuf - > offset = 16 ;
switch ( q - > header . mess_type ) {
case 0 :
encode_start_assoc_request ( outbuf , & q - > sa_rq ) ;
break ;
case 1 :
encode_start_assoc_reply ( outbuf , & q - > sa_rp ) ;
break ;
case 2 :
encode_stop_assoc ( outbuf , & q - > so ) ;
break ;
case 3 :
encode_replicate ( outbuf , & q - > rep ) ;
break ;
default :
DEBUG ( 0 , ( " encode_generic_packet: unknown message type:%d \n " , q - > header . mess_type ) ) ;
break ;
}
write_generic_header_size ( & q - > header , outbuf - > offset ) ;
write_generic_header ( outbuf , & q - > header ) ;
}
/****************************************************************************
dump a WINS_OWNER structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void dump_wins_owner ( WINS_OWNER * wins_owner )
{
DEBUGADD ( 10 , ( " \t \t \t \t address : %s \n " , inet_ntoa ( wins_owner - > address ) ) ) ;
DEBUGADD ( 10 , ( " \t \t \t \t max version: %d \n " , ( int ) wins_owner - > max_version ) ) ;
DEBUGADD ( 10 , ( " \t \t \t \t min version: %d \n " , ( int ) wins_owner - > min_version ) ) ;
DEBUGADD ( 10 , ( " \t \t \t \t type : %d \n " , wins_owner - > type ) ) ;
}
/****************************************************************************
dump a WINS_NAME structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void dump_wins_name ( WINS_NAME * wins_name )
{
fstring name ;
int i ;
strncpy ( name , wins_name - > name , 15 ) ;
DEBUGADD ( 10 , ( " name: %d, %s<%02x> %x,%x, %d %s %d " , wins_name - > name_len , name , wins_name - > type ,
wins_name - > name_flag , wins_name - > group_flag , ( int ) wins_name - > id ,
inet_ntoa ( wins_name - > owner ) , wins_name - > num_ip ) ) ;
if ( wins_name - > num_ip ! = 1 )
for ( i = 0 ; i < wins_name - > num_ip ; i + + )
DEBUGADD ( 10 , ( " %s " , inet_ntoa ( wins_name - > others [ i ] ) ) ) ;
DEBUGADD ( 10 , ( " \n " ) ) ;
}
/****************************************************************************
dump a replicate structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void dump_replicate ( REPLICATE * rep )
{
int i ;
DEBUGADD ( 5 , ( " \t \t msg_type: %d " , rep - > msg_type ) ) ;
switch ( rep - > msg_type ) {
case 0 :
DEBUGADD ( 5 , ( " (Add Version Map Table Request) \n " ) ) ;
break ;
case 1 :
DEBUGADD ( 5 , ( " (Add Version Map Table Reply) \n " ) ) ;
DEBUGADD ( 5 , ( " \t \t \t partner_count : %d \n " , rep - > avmt_rep . partner_count ) ) ;
for ( i = 0 ; i < rep - > avmt_rep . partner_count ; i + + )
dump_wins_owner ( & rep - > avmt_rep . wins_owner [ i ] ) ;
DEBUGADD ( 5 , ( " \t \t \t initiating_wins_server: %s \n " , inet_ntoa ( rep - > avmt_rep . initiating_wins_server ) ) ) ;
break ;
case 2 :
DEBUGADD ( 5 , ( " (Send Entries Request) \n " ) ) ;
dump_wins_owner ( & rep - > se_rq . wins_owner ) ;
break ;
case 3 :
DEBUGADD ( 5 , ( " (Send Entries Reply) \n " ) ) ;
DEBUGADD ( 5 , ( " \t \t \t max_names : %d \n " , rep - > se_rp . max_names ) ) ;
for ( i = 0 ; i < rep - > se_rp . max_names ; i + + )
dump_wins_name ( & rep - > se_rp . wins_name [ i ] ) ;
break ;
case 4 :
DEBUGADD ( 5 , ( " (Update Notify Request) \n " ) ) ;
DEBUGADD ( 5 , ( " \t \t \t partner_count : %d \n " , rep - > un_rq . partner_count ) ) ;
for ( i = 0 ; i < rep - > un_rq . partner_count ; i + + )
dump_wins_owner ( & rep - > un_rq . wins_owner [ i ] ) ;
DEBUGADD ( 5 , ( " \t \t \t initiating_wins_server: %s \n " , inet_ntoa ( rep - > un_rq . initiating_wins_server ) ) ) ;
break ;
default :
DEBUG ( 5 , ( " \n " ) ) ;
break ;
}
}
/****************************************************************************
dump a generic structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void dump_generic_packet ( GENERIC_PACKET * q )
{
DEBUG ( 5 , ( " dump_generic_packet: \n " ) ) ;
DEBUGADD ( 5 , ( " \t data_size: %08x \n " , q - > header . data_size ) ) ;
DEBUGADD ( 5 , ( " \t opcode : %08x \n " , q - > header . opcode ) ) ;
DEBUGADD ( 5 , ( " \t assoc_ctx: %08x \n " , q - > header . assoc_ctx ) ) ;
DEBUGADD ( 5 , ( " \t mess_type: %08x " , q - > header . mess_type ) ) ;
switch ( q - > header . mess_type ) {
case 0 :
DEBUGADD ( 5 , ( " (Start Association Request) \n " ) ) ;
DEBUGADD ( 5 , ( " \t \t assoc_ctx: %08x \n " , q - > sa_rq . assoc_ctx ) ) ;
DEBUGADD ( 5 , ( " \t \t min_ver : %04x \n " , q - > sa_rq . min_ver ) ) ;
DEBUGADD ( 5 , ( " \t \t maj_ver : %04x \n " , q - > sa_rq . maj_ver ) ) ;
break ;
case 1 :
DEBUGADD ( 5 , ( " (Start Association Reply) \n " ) ) ;
DEBUGADD ( 5 , ( " \t \t assoc_ctx: %08x \n " , q - > sa_rp . assoc_ctx ) ) ;
DEBUGADD ( 5 , ( " \t \t min_ver : %04x \n " , q - > sa_rp . min_ver ) ) ;
DEBUGADD ( 5 , ( " \t \t maj_ver : %04x \n " , q - > sa_rp . maj_ver ) ) ;
break ;
case 2 :
DEBUGADD ( 5 , ( " (Stop Association) \n " ) ) ;
DEBUGADD ( 5 , ( " \t \t reason: %08x \n " , q - > so . reason ) ) ;
break ;
case 3 :
DEBUGADD ( 5 , ( " (Replication Message) \n " ) ) ;
dump_replicate ( & q - > rep ) ;
break ;
default :
DEBUG ( 5 , ( " \n " ) ) ;
break ;
}
}
/****************************************************************************
generate a stop packet
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void stop_packet ( GENERIC_PACKET * q , GENERIC_PACKET * r , int reason )
{
r - > header . opcode = OPCODE_NON_NBT ;
r - > header . assoc_ctx = get_server_assoc ( q - > header . assoc_ctx ) ;
r - > header . mess_type = MESSAGE_TYPE_STOP_ASSOC ;
r - > so . reason = reason ;
}