Files
vwifi/src/vwifi-server.cc
T
Guy Resheff 92df7a383a Upstream vwifi v7.0 (Raizo62/vwifi @ 4a9842e)
Unmodified upstream source from https://github.com/Raizo62/vwifi
Commit: 4a9842e "CMakeLists.txt : VERSION = 7.0"

Simulator of WiFi (802.11) interfaces to communicate between
several Virtual Machines via mac80211_hwsim + TCP relay.

License: Apache-2.0
2026-03-08 08:19:45 -07:00

310 lines
8.1 KiB
C++

#include <iostream> // cout
#include <string.h> // strcmp
#include "config.h"
#include "tools.h" // isPositiveInt
#include "cwifiserveritcp.h"
#ifdef ENABLE_VHOST
#include "cwifiservervtcp.h"
#endif
#include "cctrlserver.h"
#include "cselect.h"
#include "cdynbuffer.h"
using namespace std;
CDynBuffer Buffer; // Buffer to stock received values
#ifdef ENABLE_VHOST
TPort Port_VHOST = DEFAULT_WIFI_CLIENT_PORT_VHOST;
#endif
TPort Port_TCP = DEFAULT_WIFI_CLIENT_PORT_INET;
TPort Port_Spy = DEFAULT_WIFI_SPY_PORT;
TPort Port_Ctrl = DEFAULT_CTRL_PORT;
CSelect Scheduler;
void RemoveClient(CWifiServer* srv, bool srvIsSpy, TIndex i, TDescriptor socket)
{
if( ! srvIsSpy )
{
cout<<"Client disconnected : "; srv->ShowInfoWifi(i) ; cout<<endl;
}
else
cout<<"Spy disconnected : "<< srv->GetReferenceOnInfoWifiByIndex(i)->GetCid() <<endl;
srv->CloseClient(i);
//del master socket to set
Scheduler.DelNode(socket);
}
void ForwardData(bool srcIsSpy, CWifiServer* src, CWifiServer* otherDst)
{
int valread;
TPower power;
for ( TIndex i = 0 ; i < src->GetNumberClient() ; )
{
TDescriptor socket = (*src)[i];
if( ! src->IsEnable(i) )
{
RemoveClient(src, srcIsSpy , i, socket);
continue;
}
if( Scheduler.DescriptorHasAction(socket) )
{
//Check if it was for closing , and also read the
//incoming message
valread=src->RecvSignal(socket,&power,&Buffer);
if( valread <=0 )
{
RemoveClient(src, srcIsSpy , i, socket);
continue;
}
if( ! srcIsSpy )
{
src->SendAllOtherClients(i,power,Buffer.GetBuffer(),valread);
otherDst->SendAllClientsWithoutLoss(power,Buffer.GetBuffer(),valread);
}
else
{
src->SendAllOtherClientsWithoutLoss(i,power,Buffer.GetBuffer(),valread);
otherDst->SendAllClientsWithoutLoss(power,Buffer.GetBuffer(),valread);
}
}
i++;
}
}
int vwifi_server()
{
TDescriptor socket;
CListInfo<CInfoSocket> infoSockets;
CListInfo<CInfoWifi> infoWifis;
CListInfo<CInfoWifi> infoWifisDeconnected;
#ifdef ENABLE_VHOST
CWifiServerVTCP wifiServerVTCP(&infoSockets,&infoWifis,&infoWifisDeconnected);
cout<<"CLIENT VHOST : ";
wifiServerVTCP.Init(Port_VHOST);
if( ! wifiServerVTCP.Listen(WIFI_MAX_DECONNECTED_CLIENT) )
{
cerr<<"Error : wifiServerVTCP.Listen"<<endl;
exit(EXIT_FAILURE);
}
#endif
CWifiServerITCP wifiServerITCP(&infoSockets,&infoWifis,&infoWifisDeconnected);
cout<<"CLIENT TCP : ";
wifiServerITCP.Init(Port_TCP);
if( ! wifiServerITCP.Listen(WIFI_MAX_DECONNECTED_CLIENT) )
{
cerr<<"Error : wifiServerITCP.Listen"<<endl;
exit(EXIT_FAILURE);
}
CWifiServer* wifiServer=&wifiServerITCP; // or wifiServerVTCP, if exist, it doesn't change anything
cout<<"SPY : ";
CWifiServerITCP wifiServerSPY;
wifiServerSPY.Init(Port_Spy);
if( ! wifiServerSPY.Listen(1) )
{
cerr<<"Error : wifiServerSPY.Listen"<<endl;
exit(EXIT_FAILURE);
}
cout<<"CTRL : ";
#ifdef ENABLE_VHOST
CCTRLServer ctrlServer(&wifiServerVTCP, &wifiServerITCP, &wifiServerSPY,&Scheduler);
#else
CCTRLServer ctrlServer(NULL, &wifiServerITCP, &wifiServerSPY,&Scheduler);
#endif
ctrlServer.Init(Port_Ctrl);
if( ! ctrlServer.Listen() )
{
cerr<<"Error : ctrlServer.Listen"<<endl;
exit(EXIT_FAILURE);
}
cout<<"Size of disconnected : "<<WIFI_MAX_DECONNECTED_CLIENT<<endl;
if( CanLostPackets )
cout<<"Packet loss : Enable"<<endl;
else
cout<<"Packet loss : disable"<<endl;
cout<<"Scale : "<<Scale<<endl;
//add master socket to set
#ifdef ENABLE_VHOST
Scheduler.AddNode(wifiServerVTCP);
#endif
Scheduler.AddNode(wifiServerITCP);
Scheduler.AddNode(wifiServerSPY);
Scheduler.AddNode(ctrlServer);
while( true )
{
//wait for an activity on one of the sockets , timeout is NULL ,
//so wait indefinitely
if( Scheduler.Wait() == SCHEDULER_ERROR )
{
cerr<<"Error : scheduler.Wait"<<endl;
return 1;
}
else {
//If something happened on the master socket ,
//then its an incoming connection
#ifdef ENABLE_VHOST
if( Scheduler.DescriptorHasAction(wifiServerVTCP) )
{
socket = wifiServerVTCP.Accept();
if ( socket == SOCKET_ERROR )
{
cerr<<"Error : wifiServerVTCP.Accept"<<endl;
exit(EXIT_FAILURE);
}
//add child sockets to set
Scheduler.AddNode(socket);
//inform user of socket number - used in send and receive commands
cout<<"New connection from Client VHost : "; wifiServer->ShowInfoWifi(wifiServer->GetNumberClient()-1) ; cout<<endl;
}
#endif
if( Scheduler.DescriptorHasAction(wifiServerITCP) )
{
socket = wifiServerITCP.Accept();
if ( socket == SOCKET_ERROR )
{
cerr<<"Error : wifiServerITCP.Accept"<<endl;
exit(EXIT_FAILURE);
}
//add child sockets to set
Scheduler.AddNode(socket);
//inform user of socket number - used in send and receive commands
cout<<"New connection from Client TCP : "; wifiServer->ShowInfoWifi(wifiServer->GetNumberClient()-1) ; cout<<endl;
}
if( Scheduler.DescriptorHasAction(wifiServerSPY) )
{
socket = wifiServerSPY.Accept();
if ( socket == SOCKET_ERROR )
{
cerr<<"Error : wifiSpyServer.Accept"<<endl;
exit(EXIT_FAILURE);
}
//add child sockets to set
Scheduler.AddNode(socket);
//inform user of socket number - used in send and receive commands
cout<<"New connection from Spy : "<<wifiServerSPY.GetReferenceOnInfoWifiByIndex(wifiServerSPY.GetNumberClient()-1)->GetCid()<<endl;
}
if( Scheduler.DescriptorHasAction(ctrlServer) )
{
ctrlServer.ReceiveOrder();
}
//else its some IO operation on some other socket
ForwardData(false, wifiServer, &wifiServerSPY);
ForwardData(true, &wifiServerSPY, wifiServer);
}
}
return 0;
}
void help()
{
#ifdef ENABLE_VHOST
cout<<"Usage: vwifi-server [-h] [-v] [-l] [-u] [-p PORT_VHOST] [-t PORT_TCP] [-s PORT_SPY] [-c PORT_CTRL]"<<endl;
cout<<" [--help] [--version] [--lost-packets] [--use-port-in-hash] [--port-vhost PORT_VHOST] [--port-tcp PORT_TCP] [--port-spy PORT_SPY] [--port-ctrl PORT_CTRL]"<<endl;
cout<<" By default : PORT_VHOST="<< DEFAULT_WIFI_CLIENT_PORT_VHOST <<
" PORT_TCP=" << DEFAULT_WIFI_CLIENT_PORT_INET <<
" PORT_SPY=" << DEFAULT_WIFI_SPY_PORT <<
" PORT_CTRL=" << DEFAULT_CTRL_PORT <<endl;
#else
cout<<"Usage: vwifi-server [-h] [-v] [-l] [-u] [-t PORT_TCP] [-s PORT_SPY] [-c PORT_CTRL]"<<endl;
cout<<" [--help] [--version] [--lost-packets] [--use-port-in-hash] [--port-tcp PORT_TCP] [--port-spy PORT_SPY] [--port-ctrl PORT_CTRL]"<<endl;
cout<<" By default : PORT_TCP=" << DEFAULT_WIFI_CLIENT_PORT_INET <<
" PORT_SPY=" << DEFAULT_WIFI_SPY_PORT <<
" PORT_CTRL=" << DEFAULT_CTRL_PORT <<endl;
#endif
}
int main(int argc, char** argv)
{
int arg_idx = 1;
while (arg_idx < argc)
{
if( ! strcmp("-v", argv[arg_idx]) || ! strcmp("--version", argv[arg_idx]) )
{
cout<<"Version : "<<VERSION<<endl;
return 0;
}
if( ! strcmp("-h", argv[arg_idx]) || ! strcmp("--help", argv[arg_idx]) )
{
help();
return 0;
}
if( ! strcmp("-l", argv[arg_idx]) || ! strcmp("--lost-packets", argv[arg_idx]) )
{
CanLostPackets=true;
}
else if( ! strcmp("-u", argv[arg_idx]) || ! strcmp("--use-port-in-hash", argv[arg_idx]) )
{
HashUsesPort=true;
}
#ifdef ENABLE_VHOST
else if( ( ! strcmp("-p", argv[arg_idx]) || ! strcmp("--port-vhost", argv[arg_idx]) ) && (arg_idx + 1) < argc && isPositiveInt(argv[arg_idx+1]) )
{
Port_VHOST = stoi(argv[arg_idx+1]);
arg_idx++;
}
#endif
else if( ( ! strcmp("-t", argv[arg_idx]) || ! strcmp("--port-tcp", argv[arg_idx]) ) && (arg_idx + 1) < argc && isPositiveInt(argv[arg_idx+1]) )
{
Port_TCP = stoi(argv[arg_idx+1]);
arg_idx++;
}
else if( ( ! strcmp("-s", argv[arg_idx]) || ! strcmp("--port-spy", argv[arg_idx]) ) && (arg_idx + 1) < argc && isPositiveInt(argv[arg_idx+1]) )
{
Port_Spy = stoi(argv[arg_idx+1]);
arg_idx++;
}
else if( ( ! strcmp("-c", argv[arg_idx]) || ! strcmp("--port-ctrl", argv[arg_idx]) ) && (arg_idx + 1) < argc && isPositiveInt(argv[arg_idx+1]) )
{
Port_Ctrl = stoi(argv[arg_idx+1]);
arg_idx++;
}
else
{
cerr<<"Error : problem with this parameter : "<< argv[arg_idx] <<endl;
help();
return 1;
}
arg_idx++;
}
return vwifi_server();
}