|
Listing 1.14 Session Retargeting
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void PrintL1Name( uchar *src, int max )
/* ---------------------------------------------------- **
* Decode and pretty-print an L1-encoded NetBIOS name.
* ---------------------------------------------------- **
*/
{
int suffix;
static char namestr[16];
suffix = L1_Decode( namestr, src, 1, max );
Hex_Print( namestr, strlen( namestr ) );
printf( "<%.2x>", suffix );
}/* PrintL1Name */
int Get_SS_Length( uchar *hdr )
/* ---------------------------------------------------- **
* Read the length field from an SMB Session Service
* header.
* ---------------------------------------------------- **
*/
{
int tmp;
tmp = (hdr[1] & 1) << 16;
tmp |= hdr[2] << 8;
tmp |= hdr[3];
return( tmp );
} /* Get_SS_Length */
int OpenPort139( void )
/* ---------------------------------------------------- **
* Open port 139 for listening.
* Note: this requires root privilege, and Samba's
* SMBD daemon must not be running on its
* default port.
* ---------------------------------------------------- **
*/
{
int result;
int sock;
struct sockaddr_in sox;
/* Create the socket. */
sock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
if( sock < 0 )
{
printf( "Failed to create socket(); %s.\n",
strerror( errno ) );
exit( EXIT_FAILURE );
}
/* Bind the socket to any interface, port TCP/139. */
sox.sin_addr.s_addr = INADDR_ANY;
sox.sin_family = AF_INET;
sox.sin_port = htons( 139 );
result = bind( sock,
(struct sockaddr *)&sox,
sizeof(struct sockaddr_in) );
if( result < 0 )
{
printf( "Failed to bind() socket; %s.\n",
strerror( errno ) );
exit( EXIT_FAILURE );
}
/* Post the listen request. */
result = listen( sock, 5 );
if( result < 0 )
{
printf( "Failed to listen() on socket; %s.\n",
strerror( errno ) );
exit( EXIT_FAILURE );
}
/* Ready... */
return( sock );
} /* OpenPort139 */
void Listen( struct in_addr trg_addr, int trg_port )
/* ---------------------------------------------------- **
* Accepts incoming connections, sends a retarget
* message, and then disconnects.
* ---------------------------------------------------- **
*/
{
int listen_sock;
int reply_sock;
int result;
struct sockaddr_in remote_addr;
socklen_t addr_len;
uchar recvbufr[1536];
uchar replymsg[10];
listen_sock = OpenPort139();
/* Fill in the redirect message. */
replymsg[0] = 0x84; /* Retarget code. */
replymsg[1] = 0;
replymsg[2] = 0;
replymsg[3] = 6; /* Remaining length. */
(void)memcpy( &(replymsg[4]), &trg_addr.s_addr, 4 );
trg_port = htons( trg_port );
(void)memcpy( &(replymsg[8]), &trg_port, 2 );
printf( "Waiting for connections...\n" );
for(;;) /* Until killed. */
{
/* Wait for a connection. */
addr_len = sizeof( struct sockaddr_in );
reply_sock = accept( listen_sock,
(struct sockaddr *)&remote_addr,
&addr_len );
/* If the accept() failed exit with an error message. */
if( reply_sock < 0 )
{
printf( "Error accept()ing a connection: %s\n",
strerror(errno) );
exit( EXIT_FAILURE );
}
result = recv( reply_sock, recvbufr, 1536, 0 );
if( result < 0 )
{
printf( "Error receiving packet: %s\n",
strerror(errno) );
}
else
{
printf( "SESSION MESSAGE\n {\n" );
printf( " TYPE = 0x%.2x\n", recvbufr[0] );
printf( " LENGTH = %d\n", Get_SS_Length( recvbufr ) );
if( 0x81 == recvbufr[0] )
{
int offset;
printf( " CALLED_NAME = " );
PrintL1Name( &recvbufr[4], result );
offset = 5 + strlen( &(recvbufr[4]) );
printf( "\n CALLING_NAME = " );
PrintL1Name( &recvbufr[offset], result );
printf( "\n }\nSending Retarget message.\n" );
(void)send( reply_sock, (void *)replymsg, 10, 0 );
}
else
printf( " }\nPacket Dropped.\n" );
}
close( reply_sock );
}
} /* Listen */
int main( int argc, char *argv[] )
/* ---------------------------------------------------- **
* Simple daemon that listens on port TCP/139 and
* redirects incoming traffic to another IP and port.
* ---------------------------------------------------- **
*/
{
int target_port;
struct in_addr target_address;
if( argc != 3 )
{
printf( "Usage: %s <IP> <PORT>\n", argv[0] );
exit( EXIT_FAILURE );
}
if( 0 == inet_aton( argv[1], &target_address ) )
{
printf( "Invalid IP.\n" );
printf( "Usage: %s <IP> <PORT>\n", argv[0] );
exit( EXIT_FAILURE );
}
target_port = atoi( argv[2] );
if( 0 == target_port )
{
printf( "Invalid Port number.\n" );
printf( "Usage: %s <IP> <PORT>\n", argv[0] );
exit( EXIT_FAILURE );
}
Listen( target_address, target_port );
return( EXIT_SUCCESS );
} /* main */
$Revision: 1.7 $
$Date: 2003/02/18 21:43:58 $
|
Copyright © 2002-2003 Christopher R. Hertel
Released under the terms of the
LGPL
|
|