Hey guys,
Lately I've been really busy with everything related to RCE, debugging and exploitation. I needed a very simple fuzzer to see if I could exploit some old ftp software found on the net. I have no use for the fuzzer anymore, so I'm posting the source here!
It's designed to be simple and easy to use, so you don't have to study a complex API or pour over the code to see what it's doing. On the other hand, this means that the fuzzer needs more attending, and that it's logging capability are less then 0. Any target should be run under a debugger, since the fuzzer will only notify you that the target is down, and not what killed the target.
Ps the socket class is not mine, but stolen from somewhere w\e.
Howto
There are basically 6 functions that you need to worry about:
cFuzz::AddConstant( string Const );
Will add a piece of string that will never change.
Code:
cFuzz c;
c.AddConstant("<html>");
the first word in the sentence will always be <html>
cFuzz::AddMutable (string Mutatbles, string Delimiter = " " );
Adds a piece of text that will change with each iteration of the fuzzer. The mutables are strings or words separated by the Delimiter .
Code:
cFuzz c;
c.AddMutable( "<body> <head> <title> <a href=\">", " " );
Example output:
<html><head>
<html><title>
cFuzz::Repeat( nTimes );
Instructs the fuzzer to extend the iteration nTimes, even after the maximum amount of permutations is reached (the counter will reset)
Code:
cFuzz c;
c.Repeat( 10 );
extern int DoRound( cFuzz &c, string Address, int Port );
extern int DoRound( cFuzz &c, char* Address, int Port );
Executes all possible permutations of the fuzzer, and reports if the target is still up after every possible combination has been made and sent to the target.
Code:
string Address = "localhost";
int Port = 2424;
cFuzz c;
c.AddConstant( "<html>" );
c.AddMutable( "<body> <head> <title> <a href=\">", " " );
c.AddMutable( "</body> </head> </title> </a>", " " );
c.AddMutable( "</head> </html> </body>", " " );
c.Repeat( 10 );
if( DoRound( c, Address, Port ) == TARGET_UP )
{
printf("Target still up!\n");
}
else
{
printf("Target down!\n");
}
Init() does all initial preparation;
Cleanup() cleans everything up;
Special tokens
The c::AddMutable() can take a special token, RND<int32>. This token specifies a random string of characters with <int32> length. For example:
c.AddMutable( "RND2 RND2", " " );
Could produce:
A3 4C
or
#5 $J
c::Repeat until you feel like you've gotten enough combinations.
Sources!
cFuzzClass.h
Code:
#ifndef C_FUZZ_CLASS_H
#define C_FUZZ_CLASS_H
#include <vector>
#include <string>
#include "cMutable.h"
#include "Socket.h"
using namespace std;
class cFuzz{
vector< cMutable > _M;
vector< string > _C;
vector< bool > _F;
unsigned int _mP;
unsigned int _cP;
unsigned int _eC;
void GetNextPermutationIndex();
public:
cFuzz();
void Cleanup();
void Repeat( unsigned int nTimes );
void AddMutable( string Mutes, string Delim );
void AddConstant( string Constant );
double GetNumberOfPermutations();
string GetNextPermutation();
};
#endif
cMutable.h
Code:
#ifndef C_MUTABLE_H
#define C_MUTABLE_H
#include <vector>
#include <string>
using namespace std;
class cMutable{
vector< string > _v;
vector< string > _s;
unsigned int _i;
string GetRandomString( unsigned int Size );
public:
cMutable( string Mutes, string Delim );
void Reset();
string GetNextPermutation();
string GetCurrentPermutation();
bool GetNextPermutationSentence( string &s, string delim );
double GetNumberOfPermutations();
double GetNumberOfPermuationSentences();
unsigned int GetCurrentPermutationIndex();
};
#endif
Hostinfo.h
Code:
#ifndef _myHostInfo
#define _myHostInfo
#include <string>
using namespace std;
// this version is for both Windows and UNIX, the following line
// specifies that this is for WINDOWS
#include <winsock.h>
#include <stdio.h>
enum hostType {NAME, ADDRESS};
const int HOST_NAME_LENGTH = 64;
class myHostInfo
{
private:
#ifdef UNIX
char searchHostDB; // search the host database flag
#endif
struct hostent *hostPtr; // Entry within the host address database
public:
// Default constructor
myHostInfo();
// Retrieves the host entry based on the host name or address
myHostInfo(string& hostName, hostType type);
// Destructor. Closes the host entry database.
~myHostInfo()
{
#ifdef UNIX
endhostent();
#endif
}
// Retrieves the hosts IP address
char* getHostIPAddress()
{
struct in_addr *addr_ptr;
// the first address in the list of host addresses
addr_ptr = (struct in_addr *)*hostPtr->h_addr_list;
// changed the address format to the Internet address in standard dot notation
return inet_ntoa(*addr_ptr);
}
// Retrieves the hosts name
char* getHostName()
{
return hostPtr->h_name;
}
};
#endif
Network.h
Code:
#ifndef NETWORK_H
#define NETWORK_H
#include <string>
using namespace std;
extern void Init();
extern void Cleanup();
extern bool IsTargetStillALive( char* IpAddress, unsigned int port );
extern bool IsTargetStillALive( string Address, unsigned int port );
extern int DoRound( cFuzz &c, string Address, int Port );
extern int DoRound( cFuzz &c, char* Address, int Port );
#define TARGET_UP 1
#define TARGET_DOWN 2
#endif
Socket.h
Code:
#ifndef _mySocket
#define _mySocket
#include "Hostinfo.h"
#include <winsock.h>
extern void StartWSA();
extern void StopWSA();
// so far we only consider the TCP socket, UDP will be added in later release
//const int MAX_RECV_LEN = 1048576;
const int MAX_RECV_LEN = 8096;
const int MAX_MSG_LEN = 1024;
const int PORTNUM = 1200;
class mySocket
{
protected:
/*
only used when the socket is used for client communication
once this is done, the next necessary call is setSocketId(int)
*/
mySocket() {}
void setSocketId(int socketFd) { socketId = socketFd; }
protected:
int portNumber; // Socket port number
int socketId; // Socket file descriptor
int blocking; // Blocking flag
int bindFlag; // Binding flag
struct sockaddr_in clientAddr; // Address of the client that sent data
public:
mySocket(int); // given a port number, create a socket
virtual ~mySocket()
{
closesocket(socketId);
}
public:
// socket options : ON/OFF
void setDebug(int);
void setReuseAddr(int);
void setKeepAlive(int);
void setLingerOnOff(bool);
void setLingerSeconds(int);
void setSocketBlocking(int);
// size of the send and receive buffer
void setSendBufSize(int);
void setReceiveBufSize(int);
// retrieve socket option settings
int getDebug();
int getReuseAddr();
int getKeepAlive();
int getSendBufSize();
int getReceiveBufSize();
int getSocketBlocking() { return blocking; }
int getLingerSeconds();
bool getLingerOnOff();
// returns the socket file descriptor
int getSocketId() { return socketId; }
// returns the port number
int getPortNumber() { return portNumber; }
private:
};
class myTcpSocket : public mySocket
{
public:
/*
Constructor. used for creating instances dedicated to client
communication:
when accept() is successful, a socketId is generated and returned
this socket id is then used to build a new socket using the following
constructor, therefore, the next necessary call should be setSocketId()
using this newly generated socket fd
*/
myTcpSocket() {};
~myTcpSocket() {};
// Constructor. Used to create a new TCP socket given a port
myTcpSocket(int portId) : mySocket(portId) { };
/*
sends a string to the server
*/
int sends(string&);
/*
receives a character from the stream
*/
char getc();
/*
receive messages and stores the message in a buffer
*/
int gets(string&);
/*
Binds the socket to an address and port number
a server call
*/
void bindSocket();
/*
accepts a connecting client. The address of the connected client
is stored in the parameter
a server call
*/
myTcpSocket* acceptClient(string&);
// Listens to connecting clients, a server call
void listenToClient(int numPorts = 5);
// connect to the server, a client call
virtual void connectToServer(string&,hostType);
};
#endif
cFuzzClass.cpp
Code:
#include <vector>
#include <string>
#include "cMutable.h"
#include "cFuzzClass.h"
#include "Socket.h"
cFuzz::cFuzz() {
_mP = 0;
_cP = 0;
_eC = 0;
}
void cFuzz::GetNextPermutationIndex()
{
for( unsigned int i = 0; i < _M.size(); i++ )
{
unsigned int s = _M.at( i ).GetCurrentPermutationIndex() + 1;
if( s == _M.at( i ).GetNumberOfPermutations() )
{
_M.at( i ).Reset();
continue;
}
else
{
_M.at( i ).GetNextPermutation();
break;
}
}
}
void cFuzz::Cleanup()
{
_mP = 0;
_cP = 0;
_eC = 0;
_M.clear();
_C.clear();
_F.clear();
}
void cFuzz::Repeat( unsigned int nTimes )
{
_eC += nTimes;
}
void cFuzz::AddMutable( string Mutes, string Delim )
{
cMutable c( Mutes, Delim );
_M.push_back( c );
_F.push_back( true );
}
void cFuzz::AddConstant( string Constant )
{
_C.push_back( Constant );
_F.push_back( false );
}
double cFuzz::GetNumberOfPermutations()
{
double Result = 0;
vector< double > Numbers;
for( unsigned int i = 0; i < _M.size(); i++ )
{
Numbers.push_back( _M.at( i ).GetNumberOfPermutations() );
}
Result = Numbers.at( 0 );
for( unsigned int i = 1; i < Numbers.size(); i++ )
{
Result *= Numbers.at( i );
}
return Result + _eC;
}
string cFuzz::GetNextPermutation()
{
string Result = "";
GetNextPermutationIndex();
_mP = 0;
_cP = 0;
for( unsigned int i = 0; i < _F.size(); i++ )
{
if( _F.at( i ) )
{
Result += _M.at( _mP++ ).GetCurrentPermutation();
}
else
{
Result += _C.at( _cP++ );
}
}
return Result;
}
cMutable.cpp
Code:
#include <string>
#include <sstream>
#include <algorithm>
#include <time.h>
#include "cMutable.h"
using namespace std;
cMutable::cMutable( string Mutes, string Delim = " " )
{
stringstream ss(Mutes);
string item;
while( getline(ss, item, *Delim.c_str())) {
_v.push_back(item);
}
Reset();
}
string cMutable::GetRandomString( unsigned int Size )
{
string str;
str.resize( Size );
srand( time( NULL ) ^ rand() );
for( unsigned int i = 0; i < Size; i++)
{
str[i] = rand() % 255;
str[i] = str[i] >> 2;
str[i] ^ ( rand() >> 3 );
str[i] = str[i] << 3;
}
return str;
}
void cMutable::Reset()
{
sort( _v.begin(), _v.end() );
_s = _v;
_i = 0;
}
string cMutable::GetNextPermutation()
{
if( ++_i == _v.size() )
Reset();
if( _v.at( _i ).substr( 0, 3 ) == "RND" )
{
unsigned int Size = atoi( _v.at( _i ).substr( 3 ).c_str() );
return GetRandomString( Size );
}
return _v.at( _i );
}
string cMutable::GetCurrentPermutation()
{
if( _v.at( _i ).substr( 0, 3 ) == "RND" )
{
unsigned int Size = atoi( _v.at( _i ).substr( 3 ).c_str() );
return GetRandomString( Size );
}
return _v.at( _i );
}
bool cMutable::GetNextPermutationSentence( string &s, string delim )
{
if( next_permutation( _s.begin(), _s.end() ) )
{
for( unsigned int i = 0; i < _s.size(); i++ )
{
s += _s.at( i );
if( delim.size() )
s += delim;
}
return true;
}
return false;
}
double cMutable::GetNumberOfPermutations()
{
return _v.size();
}
double cMutable::GetNumberOfPermuationSentences()
{
double Result = 1;
for( unsigned int i = 1; i < _s.size(); i++)
{
Result *= i;
}
return Result;
}
unsigned int cMutable::GetCurrentPermutationIndex()
{
return _i;
}
Hostinfo.cpp
Code:
#include "HostInfo.h"
myHostInfo::myHostInfo()
{
#ifdef WINDOWS_XP
char sName[HOST_NAME_LENGTH+1];
memset(sName,0,sizeof(sName));
gethostname(sName,HOST_NAME_LENGTH);
try
{
hostPtr = gethostbyname(sName);
}
catch( ... )
{
exit(1);
}
#endif
}
myHostInfo::myHostInfo(string& hostName,hostType type)
{
try
{
if (type == NAME)
{
// Retrieve host by name
hostPtr = gethostbyname(hostName.c_str());
}
else if (type == ADDRESS)
{
// Retrieve host by address
unsigned long netAddr = inet_addr(hostName.c_str());
if (netAddr == -1)
{
throw "Error: Could not get host ip address!";
}
hostPtr = gethostbyaddr((char *)&netAddr, sizeof(netAddr), AF_INET);
if (hostPtr == NULL)
{
throw "Error: Could not get host ip address!";
}
}
else
{
throw "Error: Could not get host ip address!";
}
} catch( ... ){
throw "Exception: cpp exception!";
}
}
main.cpp
Code:
#include <iostream>
#include <string>
#include "cFuzzClass.h"
#include "Network.h"
using namespace std;
const char* ErrorFile = "CU_ERR.txt";
void LogCOMMUError( char* Error )
{
FILE *_f = fopen( ErrorFile, "a+" );
if( !_f )
return;
fprintf( _f, Error );
fclose( _f );
}
int main( int argc, char* argv[] )
{
/*
if( argc < 4 )
{
LogCOMMUError( "Error: Invailid number of arguments\n" );
return 0;
}
*/
string Address = "localhost";
int Port = 2424;
cFuzz c;
Init();
c.AddConstant( "<html>" );
c.AddMutable( "<body> <head> <title> <a href=\">", " " );
c.AddMutable( "</body> </head> </title> </a>", " " );
c.AddMutable( "RND10", "" );
c.AddMutable( "</head> </html> </body>", " " );
c.Repeat( 10 );
if( DoRound( c, Address, Port ) == TARGET_UP )
{
printf("Target still up!\n");
}
else
{
printf("Target down!\n");
}
c.Cleanup();
c.AddMutable( "RND25 RND25", " " );
c.AddMutable( "RND25 RND25", " " );
c.Repeat( 100000 );
if( DoRound( c, Address, Port ) == TARGET_UP )
{
printf("Target still up!\n");
}
else
{
printf("Target down!\n");
}
c.Cleanup();
Cleanup();
system("pause");
return 0;
}
Network.cpp
Code:
#include <vector>
#include <string>
#include "cMutable.h"
#include "cFuzzClass.h"
#include "Socket.h"
#include "Network.h"
void DoRound( cFuzz &c, myTcpSocket &s );
void Init()
{
StartWSA();
}
void Cleanup()
{
StopWSA();
}
bool IsTargetStillALive( char* IpAddress, unsigned int port )
{
try
{
myTcpSocket s( port );
s.connectToServer( (string)IpAddress, ADDRESS );
s.~myTcpSocket();
return true;
}
catch( ... )
{
return false;
}
}
bool IsTargetStillALive( string Address, unsigned int port )
{
try
{
myTcpSocket s( port );
s.connectToServer( Address, NAME );
s.~myTcpSocket();
return true;
}
catch( ... )
{
return false;
}
}
int DoRound( cFuzz &c, string Address, int Port )
{
myTcpSocket s( Port );
s.connectToServer( Address, NAME );
DoRound( c, s );
s.~myTcpSocket();
if( IsTargetStillALive( Address, Port ) )
return TARGET_UP;
else
return TARGET_DOWN;
}
int DoRound( cFuzz &c, char* Address, int Port )
{
myTcpSocket s( Port );
s.connectToServer( (string&)Address, ADDRESS );
DoRound( c, s );
s.~myTcpSocket();
if( IsTargetStillALive( Address, Port ) )
return TARGET_UP;
else
return TARGET_DOWN;
}
void DoRound( cFuzz &c, myTcpSocket &s )
{
for( unsigned int i = 0; i < c.GetNumberOfPermutations(); i++ )
{
s.sends( c.GetNextPermutation() );
}
}
Socket.cpp
Code:
#include "Socket.h"
#pragma comment(lib, "ws2_32.lib")
const int MSG_HEADER_LEN = 6;
void StartWSA(){
WSADATA wsaData;
WSAStartup(0x202, &wsaData);
return;
}
void StopWSA(){
WSACleanup();
}
mySocket::mySocket(int pNumber)
{
portNumber = pNumber;
blocking = 1;
__try
{
if ( (socketId=socket(AF_INET,SOCK_STREAM,0)) == -1)
{
throw "Error: socket() failed!";
}
}
__except(1)
{
throw "Exception: mySocket()";
}
/*
set the initial address of client that shall be communicated with to
any address as long as they are using the same port number.
The clientAddr structure is used in the future for storing the actual
address of client applications with which communication is going
to start
*/
clientAddr.sin_family = AF_INET;
clientAddr.sin_addr.s_addr = htonl(INADDR_ANY);
clientAddr.sin_port = htons(portNumber);
}
void mySocket::setDebug(int debugToggle)
{
__try
{
if ( setsockopt(socketId,SOL_SOCKET,SO_DEBUG,(char *)&debugToggle,sizeof(debugToggle)) == -1 )
{
throw "Error: setsockopt() failed!";
}
}
__except(1)
{
throw "Exception: setDebug()";
}
}
void mySocket::setReuseAddr(int reuseToggle)
{
__try
{
if ( setsockopt(socketId,SOL_SOCKET,SO_REUSEADDR,(char *)&reuseToggle,sizeof(reuseToggle)) == -1 )
{
throw "Error: setsockopt() failed!";
}
}
__except(1)
{
throw "Exception: setReuseAddr()";
}
}
void mySocket::setKeepAlive(int aliveToggle)
{
__try
{
if ( setsockopt(socketId,SOL_SOCKET,SO_KEEPALIVE,(char *)&aliveToggle,sizeof(aliveToggle)) == -1 )
{
throw "Error: setsockopt() failed!";
}
}
__except(1)
{
throw "Exception: setKeepAlive()";
}
}
void mySocket::setLingerSeconds(int seconds)
{
struct linger lingerOption;
if ( seconds > 0 )
{
lingerOption.l_linger = seconds;
lingerOption.l_onoff = 1;
}
else lingerOption.l_onoff = 0;
__try
{
if ( setsockopt(socketId,SOL_SOCKET,SO_LINGER,(char *)&lingerOption,sizeof(struct linger)) == -1 )
{
throw "Error: setsockopt() failed!";
}
}
__except(1)
{
throw "Exception: setLingerSeconds()";
}
}
void mySocket::setLingerOnOff(bool lingerOn)
{
struct linger lingerOption;
if ( lingerOn ) lingerOption.l_onoff = 1;
else lingerOption.l_onoff = 0;
__try
{
if ( setsockopt(socketId,SOL_SOCKET,SO_LINGER,(char *)&lingerOption,sizeof(struct linger)) == -1 )
{
throw "Error: setsockopt() failed!";
}
}
__except(1)
{
throw "Exception: setLingerOnOff()!";
}
}
void mySocket::setSendBufSize(int sendBufSize)
{
__try
{
if ( setsockopt(socketId,SOL_SOCKET,SO_SNDBUF,(char *)&sendBufSize,sizeof(sendBufSize)) == -1 )
{
throw "Error: setSendBufSize() failed!";
}
}
__except(1)
{
throw "Exception: setSendBufSize()";
}
}
void mySocket::setReceiveBufSize(int receiveBufSize)
{
__try
{
if ( setsockopt(socketId,SOL_SOCKET,SO_RCVBUF,(char *)&receiveBufSize,sizeof(receiveBufSize)) == -1 )
{
throw "Error: setsockopt() failed!";
}
}
__except(1)
{
throw "Exception: setReceiveBufSize()";
}
}
void mySocket::setSocketBlocking(int blockingToggle)
{
blockingToggle =! blockingToggle;
__try
{
if (ioctlsocket(socketId,FIONBIO,(unsigned long *)&blockingToggle) == -1)
{
throw "Error: ioctlsocket() failed!";
}
}
__except(1)
{
throw "Exception: setSocketBlocking()";
}
}
int mySocket::getDebug()
{
int myOption;
int myOptionLen = sizeof(myOption);
__try
{
if ( getsockopt(socketId,SOL_SOCKET,SO_DEBUG,(char *)&myOption,&myOptionLen) == -1 )
{
throw "Error: getDebug() failed!";
}
}
__except(1)
{
throw "Exception: getDebug()";
}
return myOption;
}
int mySocket::getReuseAddr()
{
int myOption;
int myOptionLen = sizeof(myOption);
__try
{
if ( getsockopt(socketId,SOL_SOCKET,SO_REUSEADDR,(char *)&myOption,&myOptionLen) == -1 )
{
throw "Error: getsockopt() failed!";
}
}
__except(1)
{
throw "Exception: getReuseAddr()";
}
return myOption;
}
int mySocket::getKeepAlive()
{
int myOption;
int myOptionLen = sizeof(myOption);
__try
{
if ( getsockopt(socketId,SOL_SOCKET,SO_KEEPALIVE,(char *)&myOption,&myOptionLen) == -1 )
{
throw "Error: getsockopt() failed!";
}
}
__except(1)
{
throw "Exception: getKeepAlive()";
}
return myOption;
}
int mySocket::getLingerSeconds()
{
struct linger lingerOption;
int myOptionLen = sizeof(struct linger);
__try
{
if ( getsockopt(socketId,SOL_SOCKET,SO_LINGER,(char *)&lingerOption,&myOptionLen) == -1 )
{
throw "Error: getLingerSeconds() failed!";
}
}
__except(1)
{
throw "Exception: getLingerSeconds()";
}
return lingerOption.l_linger;
}
bool mySocket::getLingerOnOff()
{
struct linger lingerOption;
int myOptionLen = sizeof(struct linger);
__try
{
if ( getsockopt(socketId,SOL_SOCKET,SO_LINGER,(char *)&lingerOption,&myOptionLen) == -1 )
{
throw "Error: getsockopt() failed!";
}
}
__except(1)
{
throw "Exception: getLingerOnOff()";
}
if ( lingerOption.l_onoff == 1 ) return true;
else return false;
}
int mySocket::getSendBufSize()
{
int sendBuf;
int myOptionLen = sizeof(sendBuf);
__try
{
if ( getsockopt(socketId,SOL_SOCKET,SO_SNDBUF,(char *)&sendBuf,&myOptionLen) == -1 )
{
throw "Error: getsockopt() failed!";
}
}
__except(1)
{
throw "Exception: getSendBufSize()!";
}
return sendBuf;
}
int mySocket::getReceiveBufSize()
{
int rcvBuf;
int myOptionLen = sizeof(rcvBuf);
__try
{
if ( getsockopt(socketId,SOL_SOCKET,SO_RCVBUF,(char *)&rcvBuf,&myOptionLen) == -1 )
{
throw "Error: getsockopt() failed!";
}
}
__except(1)
{
throw "Exception: getReceiveBufSize()!";
}
return rcvBuf;
}
void myTcpSocket::bindSocket()
{
__try
{
if (bind(socketId,(struct sockaddr *)&clientAddr,sizeof(struct sockaddr_in))==-1)
{
throw "Error: Bind() failed!";
}
}
__except(1)
{
throw "Exception: bindSocket()!";
}
}
void myTcpSocket::connectToServer(string& serverNameOrAddr,hostType hType)
{
/*
when this method is called, a client socket has been built already,
so we have the socketId and portNumber ready.
a myHostInfo instance is created, no matter how the server's name is
given (such as www.yuchen.net) or the server's address is given (such
as 169.56.32.35), we can use this myHostInfo instance to get the
IP address of the server
*/
myHostInfo serverInfo(serverNameOrAddr,hType);
// Store the IP address and socket port number
struct sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = inet_addr(serverInfo.getHostIPAddress());
serverAddress.sin_port = htons(portNumber);
// Connect to the given address
if (connect(socketId,(struct sockaddr *)&serverAddress,sizeof(serverAddress)) == -1)
{
throw "Error: Connect failed!";
}
}
myTcpSocket* myTcpSocket::acceptClient(string& clientHost)
{
int newSocket; // the new socket file descriptor returned by the accept systme call
// the length of the client's address
int clientAddressLen = sizeof(struct sockaddr_in);
struct sockaddr_in clientAddress; // Address of the client that sent data
// Accepts a new client connection and stores its socket file descriptor
if ((newSocket = accept(socketId, (struct sockaddr *)&clientAddress,&clientAddressLen)) == -1)
{
throw "Error: Accept failed!";
}
// Get the host name given the address
char *sAddress = inet_ntoa((struct in_addr)clientAddress.sin_addr);
myHostInfo clientInfo(string(sAddress),ADDRESS);
char* hostName = clientInfo.getHostName();
clientHost += string(hostName);
// Create and return the new myTcpSocket object
myTcpSocket* retSocket = new myTcpSocket();
retSocket->setSocketId(newSocket);
return retSocket;
}
void myTcpSocket::listenToClient(int totalNumPorts)
{
__try
{
if (listen(socketId,totalNumPorts) == -1)
{
throw "Error: Listen failed!";
}
}
__except(1)
{
throw "Exception: listenToClient()";
}
}
int myTcpSocket::sends(string& message)
{
int numBytes; // the number of bytes sent
// Sends the message to the connected host
__try
{
if (numBytes = send(socketId, (char*)message.c_str(), message.size(), 0) == -1)
{
return -1;
}
}
__except( 1 )
{
throw "Exception: sends()!";
}
return numBytes;
}
char myTcpSocket::getc(){
char c = 0;
if( recv( socketId, &c, 1, 0 ) == SOCKET_ERROR )
return -1;
return c;
}
int myTcpSocket::gets(string& message)
{
char c = 0;
do{
c = getc();
message += c;
if( c == -1 )
return -1;
} while( c != '\n' );
return 1;
}