├── .gitignore ├── Makefile ├── Makefile.vc ├── README ├── simulations ├── omnetpp.ini ├── package.ned ├── run ├── topology_scada.ned.old ├── topology_tiny_servers.ned.old └── traffic_profiles.parameters └── src ├── Makefile ├── applications ├── ddos │ ├── TribeFloodNetwork.cc │ ├── TribeFloodNetwork.h │ └── TribeFloodNetwork.ned ├── generic │ ├── GenericApplication.cc │ ├── GenericApplication.h │ ├── GenericApplication.ned │ ├── GenericApplicationMessage.msg │ ├── GenericApplicationMessage_m.cc │ ├── GenericApplicationMessage_m.h │ ├── InetUser.cc │ ├── InetUser.h │ ├── InetUser.ned │ └── TransmissionConfig.h ├── modbusApp │ ├── ModbusTCP.cc │ ├── ModbusTCP.h │ └── ModbusTCP.ned ├── pingApp │ ├── GenericICMPPingApplication.cc │ ├── GenericICMPPingApplication.h │ └── GenericICMPPingApplication.ned ├── tcpApp │ ├── GenericTCPApplication.cc │ ├── GenericTCPApplication.h │ ├── GenericTCPApplication.ned │ ├── GenericTCPApplicationClientThread.cc │ ├── GenericTCPApplicationClientThread.h │ ├── GenericTCPApplicationServerThread.cc │ └── GenericTCPApplicationServerThread.h ├── udpApp │ ├── GenericUDPApplication.cc │ ├── GenericUDPApplication.h │ ├── GenericUDPApplication.ned │ ├── GenericUDPApplicationClientThread.cc │ ├── GenericUDPApplicationClientThread.h │ ├── GenericUDPApplicationServerThread.cc │ ├── GenericUDPApplicationServerThread.h │ ├── GenericUDPApplicationTimeout.cc │ └── GenericUDPApplicationTimeout.h └── worm │ ├── UDPWormQueryMessage.msg │ ├── UDPWormQueryMessage_m.cc │ ├── UDPWormQueryMessage_m.h │ ├── UDPWormVictim.cc │ ├── UDPWormVictim.h │ └── UDPWormVictim.ned ├── base ├── ConnectionManager.cc ├── ConnectionManager.h ├── ConnectionManager.ned ├── DebugUtil.h ├── ReaSEDefs.h ├── TrafficProfileManager.cc ├── TrafficProfileManager.h └── TrafficProfileManager.ned ├── external ├── ModbusGate.cc ├── ModbusGate.h ├── SSGate.cc ├── SSGate.h ├── SSProxy.cc ├── SSProxy.h ├── SSProxy.ned ├── SSScheduler.cc ├── SSScheduler.h ├── SSThread.cc ├── SSThread.h ├── modbus.cc └── modbus.h ├── networklayer ├── autorouting │ ├── TGMNetworkConfigurator.cc │ ├── TGMNetworkConfigurator.h │ └── TGMNetworkConfigurator.ned ├── contract │ ├── IPControlInfo_hacked.msg │ ├── IPControlInfo_hacked_m.cc │ ├── IPControlInfo_hacked_m.h │ ├── IPv6ControlInfo_hacked.msg │ ├── IPv6ControlInfo_hacked_m.cc │ └── IPv6ControlInfo_hacked_m.h ├── ipv4 │ ├── IPDatagram_hacked.msg │ ├── IPDatagram_hacked_m.cc │ ├── IPDatagram_hacked_m.h │ ├── IP_hack.cc │ ├── IP_hack.h │ └── IP_hack.ned └── queue │ ├── DropTailTraceQueue.cc │ ├── DropTailTraceQueue.h │ └── DropTailTraceQueue.ned ├── nodes ├── inet │ ├── BackupServer.ned │ ├── DDoSZombie.ned │ ├── DatabaseServer.ned │ ├── InetUserHost.ned │ ├── InteractiveServer.ned │ ├── MailServer.ned │ ├── NameServer.ned │ ├── NetworkLayer_hack.ned │ ├── StreamingServer.ned │ ├── TraceRouter.ned │ ├── WebServer.ned │ └── WormHost.ned └── scada │ ├── Historian.ned │ ├── MTU.ned │ └── PLC.ned ├── package.ned ├── scadasim ├── transport ├── contract │ ├── UDPSocketVector.cc │ └── UDPSocketVector.h ├── tcp │ ├── TCPConnection_hack.cc │ ├── TCPConnection_hack.h │ ├── TCP_hack.cc │ ├── TCP_hack.h │ └── TCP_hack.ned └── udp │ ├── UDP_hack.cc │ ├── UDP_hack.h │ └── UDP_hack.ned └── util ├── DataDump.cc ├── DataDump.h └── DataDump.ned /.gitignore: -------------------------------------------------------------------------------- 1 | src/simulations/results/*.* 2 | .tkenvrc 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: checkmakefiles 2 | cd src && $(MAKE) 3 | 4 | clean: checkmakefiles 5 | cd src && $(MAKE) clean 6 | 7 | cleanall: checkmakefiles 8 | cd src && $(MAKE) MODE=release clean 9 | cd src && $(MAKE) MODE=debug clean 10 | rm -f src/Makefile 11 | 12 | makefiles: 13 | cd src && opp_makemake -f --deep 14 | 15 | checkmakefiles: 16 | @if [ ! -f src/Makefile ]; then \ 17 | echo; \ 18 | echo '======================================================================='; \ 19 | echo 'src/Makefile does not exist. Please use "make makefiles" to generate it!'; \ 20 | echo '======================================================================='; \ 21 | echo; \ 22 | exit 1; \ 23 | fi 24 | -------------------------------------------------------------------------------- /Makefile.vc: -------------------------------------------------------------------------------- 1 | all: checkmakefiles 2 | cd src && $(MAKE) -f Makefile.vc 3 | 4 | clean: checkmakefiles 5 | cd src && $(MAKE) -f Makefile.vc clean 6 | 7 | cleanall: checkmakefiles 8 | cd src && $(MAKE) -f Makefile.vc MODE=release clean 9 | cd src && $(MAKE) -f Makefile.vc MODE=debug clean 10 | 11 | makefiles: 12 | cd src && call opp_nmakemake -f --deep 13 | 14 | checkmakefiles: 15 | @if not exist src\Makefile.vc ( \ 16 | echo. && \ 17 | echo ============================================================================ && \ 18 | echo src/Makefile.vc does not exist. Please use the following command to generate it: && \ 19 | echo nmake -f Makefile.vc makefiles && \ 20 | echo ============================================================================ && \ 21 | echo. && \ 22 | exit 1 ) 23 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | scadasim is licensed under GPLv2 (http://www.gnu.org/licenses/gpl.html). It uses part of Rease simulator (https://svn.tm.kit.edu/trac/ReaSE), therefore retains the same license type. -------------------------------------------------------------------------------- /simulations/omnetpp.ini: -------------------------------------------------------------------------------- 1 | # 2 | # This ini file runs a simulation generated by ReaSE. 3 | # Such a simulation uses a hierarchical realistic topology in 4 | # combination with realistic background traffic and large-scale 5 | # attacks, e.g. DDoS or worm propagation. 6 | # 7 | 8 | [General] 9 | #debug-on-errors = true 10 | num-rngs = 6 11 | ned-path = ./ 12 | network = SCADA 13 | 14 | cmdenv-express-mode = true 15 | 16 | #tkenv-plugin-path=../../../Etc/plugins 17 | 18 | #Tracing Start Time (no Tracing: StartTime after simulation end ) 19 | **.tracingInterval = 5s # trace every 5 seconds 20 | **.traceStartTime = 3601s 21 | 22 | #StartTime for routers, e.g. attack detection instances 23 | #**.core**.**.startTime = uniform(0s,10s) 24 | #**.gw**.**.startTime = uniform(0s,10s) 25 | #**.edge**.**.startTime = uniform(0s,10s) 26 | #StartTime for each InetUserClient (start during first Minute) 27 | **.startTime = uniform(0s,60s) 28 | #**.startTime = 0 29 | 30 | #Simulation Duration of 1 hour 31 | **.simulationDuration = 3600s 32 | 33 | #Traffic Profiles 34 | **.configFileName = "traffic_profiles.parameters" 35 | 36 | ## use ddos or worm parameters if either are used in topology 37 | #Parameter for DDoS Zombies (1 Attack) 38 | #**.attackStartTime = ${"1000","2000","3601"} 39 | **.attackStartTime = "3601" 40 | **.attackStartDiff = uniform(0s, 2s) 41 | **.timeBetweenPacketMin = 0.3s 42 | **.timeBetweenPacketDiff = uniform(0.01s, 0.02s) 43 | **.maxPacket = "-1" 44 | **.packetSize = "1024" 45 | **.attackType = "1" 46 | **.victimAddress = "Inet.sas0.host_WebServer40" #put the intended victim address here, e.g. "Inet.sas0.host_WebServer54" 47 | **.destinationPort = "80" 48 | **.addressSpoofingOn = false 49 | **.sourceAddressStart = "0.1.0.0" 50 | **.sourceAddressEnd = "0.1.0.0" 51 | **.sourcePort = "-1" 52 | **.attackOnProbability = 1.0 53 | **.attackSwitchProbability = 0.1 54 | **.attackOffProbability = 0.1 55 | 56 | #Parameter for Worm Hosts 57 | #**.timeBetweenProbingPackets = uniform(0.1s, 0.2s) 58 | #**.attackTag = 1 59 | #**.maxProbingPackets = 2000 60 | #**.sourcePort = 13876 61 | #**.listenAndVictimPort = 80 62 | #**.addressRangeStart = "0.0.0.0" 63 | #**.addressRangeEnd = "0.20.255.255" 64 | #**.startProbing = 1700s 65 | #**.startProbingDiff = uniform(0s, 60s) 66 | #**.startProbingProbability = 0.1 67 | #**.probingPacketLength = 460 68 | 69 | # tcp settings 70 | **.tcp.mss = 1024 71 | **.tcp.advertisedWindow = 14336 # 14*mss 72 | **.tcp.sendQueueClass="TCPMsgBasedSendQueue" 73 | **.tcp.receiveQueueClass="TCPMsgBasedRcvQueue" 74 | **.tcp.tcpAlgorithmClass="TCPReno" 75 | **.tcp.recordStats=false 76 | 77 | # ip settings 78 | **.routingFile="" 79 | **.ip.procDelay=10us 80 | #**.cli[*].IPForward=false 81 | #**.srv*.IPForward=false 82 | 83 | # ARP configuration 84 | **.arp.retryTimeout = 1s 85 | **.arp.retryCount = 3 86 | **.arp.cacheTimeout = 100s 87 | **.networkLayer.proxyARP = false # Host's is hardwired "false" 88 | **.networkLayer.tracingOn = false 89 | **.networkLayer.spoofingOn = false 90 | 91 | # NIC configuration 92 | **.ppp[*].queueType = "DropTailQueue" # in routers 93 | **.core**.ppp[*].queue.frameCapacity = 10000 # in routers 94 | **.gw**.ppp[*].queue.frameCapacity = 5000 95 | **.edge**.ppp[*].queue.frameCapacity = 1000 96 | **.ppp[*].queue.frameCapacity = 50 # in hosts 97 | 98 | # nam trace 99 | **.nam.logfile = "trace.nam" 100 | **.nam.prolog = "" 101 | **.namid = -1 # auto 102 | 103 | # MISC 104 | #TCP-Layer 105 | **.maxTCPThreadCount = 100 106 | #ApplicationLayer 107 | **.noThreads = 100 108 | 109 | 110 | # tcpdump 111 | 112 | #**.host_WebServer**.tcpdump.dumpFile="webserver.pcap" 113 | #**.host_MailServer**.tcpdump.dumpFile="mailserver.pcap" 114 | #**.host_RTU**.tcpdump.dumpFile="rtu.pcap" 115 | #**.host{1..200}.tcpdump.dumpFile="nodes.pcap" 116 | 117 | 118 | 119 | 120 | 121 | 122 | #DISABLE all output vectors 123 | **.trace history.enabled = yes 124 | **.enabled = no 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /simulations/package.ned: -------------------------------------------------------------------------------- 1 | package scadasim; 2 | 3 | @license(LGPL); 4 | -------------------------------------------------------------------------------- /simulations/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd `dirname $0` 3 | ../src/scadasim -n .:../src $* 4 | # for shared lib, use: opp_run -l ../src/scadasim -n .:../src $* 5 | -------------------------------------------------------------------------------- /simulations/traffic_profiles.parameters: -------------------------------------------------------------------------------- 1 | 2 | <2> 3 | 14 | 15 | <3> 16 | 27 | 28 | <4> 29 | 40 | 41 | <13> 42 | 53 | 54 | <21> 55 | -------------------------------------------------------------------------------- /src/applications/ddos/TribeFloodNetwork.h: -------------------------------------------------------------------------------- 1 | #ifndef TRIBEFLOODNETWORK_H_ 2 | #define TRIBEFLOODNETWORK_H_ 3 | 4 | #include 5 | #include "IPvXAddress.h" 6 | #include 7 | #include "ReaSEDefs.h" 8 | 9 | /// Attack tags describing different DDoS attack types 10 | /// @{ 11 | const int MIN_ATTACK_TYPE = 1; 12 | const int SYN_FLOODING = 1; 13 | const int SYN_ACK_FLOODING = 2; 14 | const int RST_FLOODING = 3; 15 | const int ICMP_FLOODING = 4; 16 | const int SMURF_FLOODING = 5; 17 | const int UDP_FLOODING = 6; 18 | const int FIN_FLOODING = 7; 19 | const int MAX_ATTACK_TYPE = 7; 20 | /// @} 21 | 22 | #define FLOODING_DELAY 0.001 23 | 24 | using std::vector; 25 | 26 | /** 27 | * @brief Simulates the real DDoS generation tool Tribe Flood Network (TFN) 28 | * 29 | * This class allows for simulation of realistic attack traffic according 30 | * to the real tool Tribe Flood Network (TFN). 31 | * Different types of attack can be simulated by this class. 32 | * Additionally, multiple attack waves and changing zombies can be simulated. 33 | * 34 | * @class TribeFloodNetwork 35 | */ 36 | class REASE_API TribeFloodNetwork: public cSimpleModule 37 | { 38 | typedef void (TribeFloodNetwork::*FloodingFunc)(); 39 | typedef vector START_TIME_VEC; 40 | typedef std::vector StringVector; 41 | 42 | protected: 43 | /// Packet sizes of the different attacks 44 | vector packetSize; 45 | /// Attack types of the different attacks 46 | vector attackType; 47 | /// Maximum number of packets of the different attacks 48 | vector maxPacket; 49 | /// IP addresses of the victims of the different attacks 50 | vector victimAddr; 51 | /// IP address range used in case of spoofing 52 | /// @{ 53 | IPvXAddress sourceAddrStart, sourceAddrEnd; 54 | /// @} 55 | /// Attacked port at the victim of the different attacks 56 | vector victimPort; 57 | /// Source port of attack packets of the different attacks 58 | vector sourcePort; 59 | /// Apply spoofing for attack packtes 60 | bool spoofingOn; 61 | /// If source port not specified it is increased every packet 62 | bool srcPortWalkOn; 63 | /// If victim Port not specified it is increased every packet 64 | bool dstPortWalkOn; 65 | /// Message for internally starting 66 | cMessage *floodingTime; 67 | /// Messages scheduled at start times of the different attacks 68 | START_TIME_VEC startMsg; 69 | 70 | /// Probability that a zombies takes part in the current attack 71 | double probAttackOn; 72 | /// Probability that a zombie switches to the new attack 73 | double probAttackSwitch; 74 | /// Probability that a zombie stops taking part in an attack 75 | double probAttackOff; 76 | 77 | /// Time to wait before sending next attack packet (min time + diff time) 78 | double floodingDelay; 79 | /// Number of attack packets sent 80 | int floodingTimes; 81 | 82 | /// Function to send an attack packet 83 | FloodingFunc floodFunc; 84 | /// Attack index 85 | int index; 86 | 87 | /// state variables for currently used values 88 | /// @{ 89 | int c_victimPort; 90 | int c_sourcePort; 91 | int c_packetSize; 92 | int c_attackType; 93 | int c_maxPacket; 94 | double c_floodingDelay; 95 | IPvXAddress c_victimAddr; 96 | /// @} 97 | 98 | /// Indicates if an attack currently is active 99 | bool isActive; 100 | 101 | /// state variables for output into scalar file 102 | /// @{ 103 | int attackIndex; 104 | long packetsSent; 105 | double attackStart; 106 | double attackEnd; 107 | IPvXAddress sourceIP; 108 | IPvXAddress destIP; 109 | /// @} 110 | public: 111 | TribeFloodNetwork(); 112 | virtual ~TribeFloodNetwork(); 113 | protected: 114 | /// @brief Start initialization in stage 5 115 | virtual int numInitStages() const { return 5; } 116 | /// @brief Read all necessary parameters from configuration 117 | virtual void initialize(int stages); 118 | /// @brief Handles self messages to start attack or send attack packet 119 | virtual void handleMessage(cMessage *msg); 120 | /// @brief Creates TCP attack packet and give it to IP layer 121 | virtual void handleTCPFlood(); 122 | /// @brief Creates UDP attack packet and give it to IP layer 123 | virtual void handleUDPFlood(); 124 | /// @brief Creates ICMP attack packet and give it to IP layer 125 | virtual void handlePingFlood(); 126 | /// @brief Set floodFunc pointer to appropriate packet generation method 127 | virtual void setFloodingFunc(int attackType); 128 | /// @brief Set parameters of current attack to the attack with the given index 129 | virtual void setCurrentFloodingParameter(unsigned int index); 130 | /// @brief Write attack path from zombie to victim to standard out 131 | void printAttackPath(); 132 | 133 | /// @brief Records scalar values for attack statistics 134 | void recordAttackScalars(); 135 | void finish(); 136 | }; 137 | 138 | #endif /*TRIBEFLOODNETWORK_H_*/ 139 | -------------------------------------------------------------------------------- /src/applications/ddos/TribeFloodNetwork.ned: -------------------------------------------------------------------------------- 1 | package scadasim.applications.ddos; 2 | 3 | // 4 | // many of the following parameters are a string-type. You can specify attack characteristics 5 | // as a char-list, seperated by whitespaces. So you can define more than one attack for the 6 | // current simulation 7 | // example: 8 | // attackStartTime = "10 15.3 40 52" --> means at sec. 10 a first attack begins, followed in sec 15.3... 9 | 10 | // 11 | // This simple module implements a generator for realistic DDoS attacks. 12 | // Multiple attack waves can be simulated as well as multiple attacks 13 | // on different victims. The zombies apply ramp-up behavior and can take 14 | // part in only one attack at a time. 15 | // 16 | simple TribeFloodNetwork 17 | 18 | { 19 | parameters: 20 | // 21 | // time when flooding begins and the delta value for each Zombie 22 | // 23 | string attackStartTime; 24 | double attackStartDiff @unit(s); 25 | // 26 | // total flooding packet amount. A negative value means flooding4livetime 27 | // 28 | string maxPacket; 29 | // 30 | // waittime between packets. Waittime = min-value + diff-value 31 | // 32 | double timeBetweenPacketMin @unit(s); 33 | double timeBetweenPacketDiff @unit(s); 34 | // 35 | // packet size for UDP or ICMP flooding 36 | // 37 | string packetSize; 38 | // 39 | // attack type: 40 | // SYN-Flood : 1 41 | // SYN-Ack-Flood: 2 //not yet implemented 42 | // RST-Flood: 3 //not yet implemented 43 | // ICMP-Flood: 4 44 | // SMURF-Flood: 5 //not yet implemented 45 | // UDP-Flood: 6 46 | // 47 | string attackType; 48 | // 49 | // ip-address of the victim. Instead of using the IP-Address use the module's fullPath 50 | // simulation.as.node 51 | // 52 | string victimAddress; 53 | // 54 | // value -1 means walk through possible ports 55 | // 56 | string destinationPort; 57 | // 58 | // activated addressspoofing needs a network prefix 59 | // 60 | bool addressSpoofingOn; 61 | string sourceAddressStart; 62 | string sourceAddressEnd; 63 | // 64 | // value -1 means walk through possible ports 65 | // 66 | string sourcePort; 67 | 68 | // 69 | // if you run multiple attacks, at each startTime (defined above attackStartTime) the zombie system 70 | // determines, if he starts, stops or switches to another attack type. 71 | // 72 | double attackOnProbability; 73 | double attackSwitchProbability; 74 | double attackOffProbability; 75 | 76 | // 77 | // only one way connection from DDoS-Application to network is used. 78 | // all incoming packets are just discarded 79 | // 80 | gates: 81 | input ipIn[]; 82 | input ipv6In[]; 83 | output to_ip_tcp; 84 | output to_ip_udp; 85 | output to_ip_ping; 86 | output to_ipv6_tcp; 87 | output to_ipv6_udp; 88 | output to_ipv6_ping; 89 | } 90 | -------------------------------------------------------------------------------- /src/applications/generic/GenericApplication.cc: -------------------------------------------------------------------------------- 1 | #include "GenericApplication.h" 2 | #include "ConnectionManager.h" 3 | #include "IPAddressResolver.h" 4 | #include "IPvXAddress.h" 5 | #include 6 | 7 | /** 8 | * @brief Abstract class for implementation of applications 9 | * 10 | * This class provides methods for the implementation of 11 | * applications that are used within the simulation in order 12 | * to generate realistic, self-similar background traffic. 13 | * 14 | * @class GenericApplication 15 | */ 16 | GenericApplication::GenericApplication() 17 | { 18 | user = NULL; 19 | applicationType = NOTSET; 20 | } 21 | 22 | GenericApplication::~GenericApplication() 23 | { 24 | } 25 | 26 | /** 27 | * Initialization: servers are registered at the connection 28 | * manager, clients in case of Ping and UDPMisc traffic. 29 | */ 30 | void GenericApplication::initialize(int stages) 31 | { 32 | if (stages == INITIALIZATION_STAGE_NECESSARY) 33 | { 34 | // checks if application was set correctly by sub-classes 35 | if (!applicationType) 36 | opp_error("invalid application type: did you forget to set a proper application type in constructor?"); 37 | 38 | isServer = par("isServer").boolValue(); 39 | profileNumber = par("profileNumber").longValue(); 40 | port = par("port").longValue(); 41 | 42 | // get the connectionManager 43 | cm = NULL; 44 | ConnectionManagerAccess cac; 45 | string asName = getParentModule()->getParentModule()->getFullName(); 46 | if(asName.find("corporate") != string::npos || asName.find("remote") != string::npos || asName.find("field") != string::npos) { 47 | // get AS-specific connection manager 48 | cm = cac.get(asName); 49 | 50 | } else { 51 | // get global connection manager 52 | cm = cac.get(); 53 | } 54 | if (cm == NULL) 55 | opp_error("couldn't get ConnectionManager"); 56 | 57 | // register servers at ConnectionManager 58 | if (isServer) 59 | cm->registerServer(IPAddressResolver().resolve(getParentModule()->getFullPath().data()), port, profileNumber); 60 | // if i'am not a server - this means a client, i have to 61 | // register myself to the current InetUser 62 | else 63 | { 64 | InetUserAccess uac; 65 | user = uac.get(); 66 | user->setApplication(applicationType, this,profileNumber); 67 | 68 | 69 | // if the client acts additionaly as a Ping Receiver or 70 | // a receiver for Misc UDP Packet 71 | // if (profileNumber == ICMP_PING || profileNumber == UDP_STREAMING || profileNumber == UDP_NAMESERVER) 72 | // cm->registerServer(IPAddressResolver().resolve(getParentModule()->getFullPath().data()), port, profileNumber, user->getId()); 73 | // 74 | // for client - create a TrafficProfile 75 | // and set necessary watches 76 | WATCH(curProfile.requestLength); 77 | WATCH(curProfile.requestsPerSession); 78 | WATCH(curProfile.replyLength); 79 | WATCH(curProfile.replyPerRequest); 80 | WATCH(curProfile.timeBetweenRequests); 81 | WATCH(curProfile.timeToRespond); 82 | WATCH(curProfile.timeBetweenSessions); 83 | WATCH(curProfile.probability); 84 | WATCH(curProfile.WANprob); 85 | WATCH(curProfile.profileID); 86 | } 87 | } 88 | } 89 | 90 | /** 91 | * Register server at the connection manager for given 92 | * profile ID and port. 93 | * 94 | * @param profileId Profile ID to register for 95 | * @param port Port to register for 96 | */ 97 | //void GenericApplication::registerServer(int profileId, int port) 98 | //{ 99 | // assert(cm); 100 | // cm->registerServer(IPAddressResolver().resolve(getParentModule()->getFullPath().data()), port, profileId); 101 | //} 102 | 103 | /* 104 | * Create transmission statistics after having finished a 105 | * communication. 106 | */ 107 | void GenericApplication::transmissionDone(TransmissionStatistics s) 108 | { 109 | if (user) 110 | user->transmissionDone(s); 111 | } 112 | -------------------------------------------------------------------------------- /src/applications/generic/GenericApplication.h: -------------------------------------------------------------------------------- 1 | #ifndef GENERICAPPLICATION_H_ 2 | #define GENERICAPPLICATION_H_ 3 | 4 | #include 5 | #include 6 | #include "InetUser.h" 7 | #include "ConnectionManager.h" 8 | #include "TransmissionConfig.h" 9 | #include "ReaSEDefs.h" 10 | #include 11 | 12 | using namespace std; 13 | 14 | /// Message Kind 15 | /// @{ 16 | #define UNDEF 0 17 | #define CONNECT 1 18 | #define SEND 2 19 | #define RESET 3 20 | ///@} 21 | 22 | // first initialization stage 23 | #define INITIALIZATION_STAGE_NECESSARY 4 24 | 25 | // Self-Timer configuration 26 | #define SELF_CALL_DELAY 0.001 27 | 28 | //#define CALL_ME(msg) scheduleAt(simTime() + SELF_CALL_DELAY, msg) 29 | //#define CALL_ME(msg, time) scheduleAt(simTime()+time, msg) 30 | 31 | class InetUser; 32 | 33 | /** 34 | * @brief Abstract class for implementation of applications 35 | * 36 | * This class provides methods for the implementation of 37 | * applications that are used within the simulation in order 38 | * to generate realistic, self-similar background traffic. 39 | * 40 | * @class GenericApplication 41 | */ 42 | class REASE_API GenericApplication : public cSimpleModule 43 | { 44 | protected: 45 | /// Pointer to the InetUser in case of a client 46 | InetUser *user; 47 | /// Currently used traffic profile 48 | TrafficProfile curProfile; 49 | /// Pointer to the connection manager 50 | ConnectionManager *cm; 51 | /// Indicates if host is a server of a client 52 | bool isServer; 53 | /// Number of associated profile 54 | long profileNumber; 55 | /// Port number of associated profile 56 | long port; 57 | /// Type of the associated application 58 | int applicationType; 59 | bool pingOn, udpOn; 60 | 61 | public: 62 | /// Application type has to be set in constructor 63 | GenericApplication(); 64 | virtual ~GenericApplication(); 65 | /// Virtual method for starting a communication 66 | virtual void transmissionStart(TrafficProfile &p, TargetInfo &i) = 0; 67 | /// Registering server at the connection manager 68 | void registerServer(int profileId, int port); 69 | 70 | protected: 71 | virtual int numInitStages() const {return INITIALIZATION_STAGE_NECESSARY+1; }; 72 | /// Initialization: Registering at the connection manager 73 | virtual void initialize(int stages); 74 | /// Creates communication statistics 75 | virtual void transmissionDone(TransmissionStatistics s); 76 | 77 | }; 78 | 79 | #endif /*GENERICAPPLICATION_H_*/ 80 | -------------------------------------------------------------------------------- /src/applications/generic/GenericApplication.ned: -------------------------------------------------------------------------------- 1 | package scadasim.applications.generic; 2 | 3 | // 4 | // Simple module for the implementation of an application. 5 | // These applications are used for generation of realistic 6 | // self-similar background traffic. 7 | // 8 | simple GenericApplication 9 | { 10 | // 11 | // ------------------------------------- 12 | // THIS IS AN ABSTRACT MODULE CLASS !!!! 13 | // ------------------------------------- 14 | // 15 | // 16 | parameters: 17 | // 18 | // should this application act as a server (true) or a client (false) 19 | // 20 | bool isServer; 21 | // 22 | // if it acts as a server, the server must know his traffic profile number. 23 | // If it acts as a client, the client can specify a profileNumber not equal -1 24 | // to register as a receiver for the specific profile 25 | // 26 | int profileNumber; 27 | // 28 | // and he has to know at which port he has to listen. Like above, a client 29 | // which set a profileNumber not equal to -1 has to specify a valid port 30 | // (for ICMP Ping the port is uninteresting) 31 | // 32 | int port; 33 | // 34 | // at least a udp or tcp server has to specify how many concurrently running 35 | // threads he will create. A Value of 0 say, that theres no limit for the 36 | // number of thread. (This value is ignored for the ICMP Application) 37 | // 38 | int noThreads; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/applications/generic/GenericApplicationMessage.msg: -------------------------------------------------------------------------------- 1 | cplusplus {{ 2 | #include "INETDefs.h" 3 | #include "ReaSEDefs.h" 4 | }} 5 | 6 | // 7 | // Defines a message format for the packets exchanged 8 | // during a client/server communication. These packets 9 | // contain all information necessary for the server to 10 | // create an appropriate reply. 11 | // 12 | 13 | packet GenericApplicationMessage 14 | { 15 | int replyLength; //bytes 16 | int replyPerRequest; //how often respond to incoming request 17 | double timeToRespond; //reply after this many seconds 18 | bool last; //this indicates the last packet --> close socket 19 | int packetNumber; //increasing number for each packet 20 | } 21 | -------------------------------------------------------------------------------- /src/applications/generic/GenericApplicationMessage_m.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file, do not edit! Created by opp_msgc 4.2 from applications/generic/GenericApplicationMessage.msg. 3 | // 4 | 5 | #ifndef _GENERICAPPLICATIONMESSAGE_M_H_ 6 | #define _GENERICAPPLICATIONMESSAGE_M_H_ 7 | 8 | #include 9 | 10 | // opp_msgc version check 11 | #define MSGC_VERSION 0x0402 12 | #if (MSGC_VERSION!=OMNETPP_VERSION) 13 | # error Version mismatch! Probably this file was generated by an earlier version of opp_msgc: 'make clean' should help. 14 | #endif 15 | 16 | // dll export symbol 17 | #ifndef SCADASim_API 18 | # if defined(SCADASim_EXPORT) 19 | # define SCADASim_API OPP_DLLEXPORT 20 | # elif defined(SCADASim_IMPORT) 21 | # define SCADASim_API OPP_DLLIMPORT 22 | # else 23 | # define SCADASim_API 24 | # endif 25 | #endif 26 | 27 | // cplusplus {{ 28 | #include "INETDefs.h" 29 | #include "ReaSEDefs.h" 30 | // }} 31 | 32 | 33 | 34 | /** 35 | * Class generated from applications/generic/GenericApplicationMessage.msg by opp_msgc. 36 | *
37 |  * packet GenericApplicationMessage
38 |  * {
39 |  *     int replyLength; 
40 |  *     int replyPerRequest; 
41 |  *     double timeToRespond; 
42 |  *     bool last; 
43 |  *     int packetNumber; 
44 |  * }
45 |  * 
46 | */ 47 | class SCADASim_API GenericApplicationMessage : public ::cPacket 48 | { 49 | protected: 50 | int replyLength_var; 51 | int replyPerRequest_var; 52 | double timeToRespond_var; 53 | bool last_var; 54 | int packetNumber_var; 55 | 56 | // protected and unimplemented operator==(), to prevent accidental usage 57 | bool operator==(const GenericApplicationMessage&); 58 | 59 | public: 60 | GenericApplicationMessage(const char *name=NULL, int kind=0); 61 | GenericApplicationMessage(const GenericApplicationMessage& other); 62 | virtual ~GenericApplicationMessage(); 63 | GenericApplicationMessage& operator=(const GenericApplicationMessage& other); 64 | virtual GenericApplicationMessage *dup() const {return new GenericApplicationMessage(*this);} 65 | virtual void parsimPack(cCommBuffer *b); 66 | virtual void parsimUnpack(cCommBuffer *b); 67 | 68 | // field getter/setter methods 69 | virtual int getReplyLength() const; 70 | virtual void setReplyLength(int replyLength); 71 | virtual int getReplyPerRequest() const; 72 | virtual void setReplyPerRequest(int replyPerRequest); 73 | virtual double getTimeToRespond() const; 74 | virtual void setTimeToRespond(double timeToRespond); 75 | virtual bool getLast() const; 76 | virtual void setLast(bool last); 77 | virtual int getPacketNumber() const; 78 | virtual void setPacketNumber(int packetNumber); 79 | }; 80 | 81 | inline void doPacking(cCommBuffer *b, GenericApplicationMessage& obj) {obj.parsimPack(b);} 82 | inline void doUnpacking(cCommBuffer *b, GenericApplicationMessage& obj) {obj.parsimUnpack(b);} 83 | 84 | 85 | #endif // _GENERICAPPLICATIONMESSAGE_M_H_ 86 | -------------------------------------------------------------------------------- /src/applications/generic/InetUser.h: -------------------------------------------------------------------------------- 1 | #ifndef INETUSER_H_ 2 | #define INETUSER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "ModuleAccess.h" 12 | #include "GenericApplication.h" 13 | #include "TrafficProfileManager.h" 14 | #include "ConnectionManager.h" 15 | #include "ReaSEDefs.h" 16 | 17 | class GenericApplication; 18 | 19 | /** 20 | * @brief Implementation of a client that generates background traffic. 21 | * 22 | * This class implements the client functionality. Clients start a first 23 | * transmission at startTime. Each time a new transmission is started 24 | * a random traffic profile and a server are requested at the connection 25 | * manager. 26 | * 27 | * In addition, clients may register at the connection manager for Ping 28 | * and UDPMisc traffic. 29 | * 30 | * @class InetUser 31 | */ 32 | class REASE_API InetUser: public cSimpleModule 33 | { 34 | protected: 35 | /// Map of available applications 36 | std::map applications; 37 | /// Connection manager for requesting a new traffic profile 38 | ConnectionManager *cm; 39 | /// Counters for the number of profiles based on the application protocol 40 | /// @{ 41 | int noICMPProfile, noUDPProfile, noTCPProfile; 42 | /// @} 43 | /// ID of currently used traffic profile 44 | int previousProfileId; 45 | // ID of pre-defined attachment traffic profile. 46 | int attachedProfileId; 47 | /// Currently used traffic profile 48 | TrafficProfile curTrafficProfile; 49 | /// Currently used server communication endpoint 50 | TargetInfo curTargetInfo; 51 | /// Container for collection of communication statistics 52 | UserCommunicationStatistics communicationStatistics; 53 | 54 | public: 55 | InetUser(); 56 | virtual ~InetUser(); 57 | /// @brief Collects some statistics of the previous transmission and starts a new one 58 | void transmissionDone(TransmissionStatistics t); 59 | /// @brief Sets application type to the given value 60 | void setApplication(int applicationType, GenericApplication *a, int attachedProfileNumber); 61 | 62 | 63 | protected: 64 | virtual void initialize(); 65 | /// @brief Actually starts the client at startTime 66 | virtual void handleMessage(cMessage *msg); 67 | /// @brief Actually starts a new transmission 68 | void transmissionDone(); 69 | /// @brief Updates the information displayed in the GUI 70 | void updateDisplay(); 71 | /// @brief Currently, nothing is done here 72 | virtual void finish(); 73 | }; 74 | 75 | /** 76 | * @brief Gives access to the InetUser instance within the host (client/server). 77 | * 78 | * @class InetUserAccess 79 | */ 80 | class REASE_API InetUserAccess : public ModuleAccess 81 | { 82 | public: 83 | InetUserAccess() : ModuleAccess("inetUser"){} 84 | }; 85 | 86 | #endif /*INETUSER_H_*/ 87 | -------------------------------------------------------------------------------- /src/applications/generic/InetUser.ned: -------------------------------------------------------------------------------- 1 | package scadasim.applications.generic; 2 | 3 | // 4 | // Simple module for implementation of the actual client host. 5 | // Clients are used for generation of realistic background traffic by 6 | // starting transmissions based on random traffic profile selection. 7 | // 8 | simple InetUser 9 | { 10 | parameters: 11 | // 12 | // Time to start the first transmission 13 | // 14 | double startTime @unit(s); 15 | } 16 | -------------------------------------------------------------------------------- /src/applications/modbusApp/ModbusTCP.cc: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | #include "ModbusTCP.h" 17 | 18 | Define_Module(ModbusTCP); 19 | 20 | void ModbusTCP::initialize() 21 | { 22 | // TODO - Generated method body 23 | } 24 | 25 | void ModbusTCP::handleMessage(cMessage *msg) 26 | { 27 | // TODO - Generated method body 28 | } 29 | -------------------------------------------------------------------------------- /src/applications/modbusApp/ModbusTCP.h: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | #ifndef __SCADASIM_MODBUSTCP_H_ 17 | #define __SCADASIM_MODBUSTCP_H_ 18 | 19 | #include 20 | 21 | /** 22 | * TODO - Generated class 23 | */ 24 | class ModbusTCP : public cSimpleModule 25 | { 26 | protected: 27 | virtual void initialize(); 28 | virtual void handleMessage(cMessage *msg); 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/applications/modbusApp/ModbusTCP.ned: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | package scadasim.applications.modbusApp; 17 | 18 | simple ModbusTCP { 19 | 20 | parameters: 21 | // 22 | // should this application act as a server (true) or a client (false) 23 | // 24 | bool isServer; 25 | // 26 | // if it acts as a server, the server must know his traffic profile number. 27 | // If it acts as a client, the client can specify a profileNumber not equal -1 28 | // to register as a receiver for the specific profile 29 | // 30 | int profileNumber; 31 | // 32 | // and he has to know at which port he has to listen. Like above, a client 33 | // which set a profileNumber not equal to -1 has to specify a valid port 34 | // (for ICMP Ping the port is uninteresting) 35 | // 36 | int port; 37 | // 38 | // at least a udp or tcp server has to specify how many concurrently running 39 | // threads he will create. A Value of 0 say, that theres no limit for the 40 | // number of thread. (This value is ignored for the ICMP Application) 41 | // 42 | int noThreads; 43 | 44 | gates: 45 | input tcpIn; 46 | output tcpOut; 47 | } 48 | -------------------------------------------------------------------------------- /src/applications/pingApp/GenericICMPPingApplication.cc: -------------------------------------------------------------------------------- 1 | #include "GenericICMPPingApplication.h" 2 | #include "PingPayload_m.h" 3 | #include "IPControlInfo.h" 4 | #include "IPv6ControlInfo.h" 5 | #include "IPAddressResolver.h" 6 | 7 | Define_Module( GenericICMPPingApplication); 8 | 9 | /** 10 | * @brief Implementation of an ICMP Ping application. 11 | * 12 | * This implementation only sends icmp ping requests. 13 | * It has no influence to the processing of the corresponding 14 | * ICMP Pong. 15 | * 16 | * @class GenericICMPPingApplication 17 | */ 18 | 19 | GenericICMPPingApplication::GenericICMPPingApplication() 20 | { 21 | applicationType = ICMP_APP; 22 | selfMsg = NULL; 23 | } 24 | 25 | GenericICMPPingApplication::~GenericICMPPingApplication() 26 | { 27 | if (selfMsg) 28 | { 29 | if (selfMsg->isScheduled()) 30 | cancelEvent(selfMsg); 31 | delete selfMsg; 32 | } 33 | } 34 | 35 | /** 36 | * Call initialization method of super class and set own IP address 37 | */ 38 | void GenericICMPPingApplication::initialize(int stages) 39 | { 40 | if (stages != INITIALIZATION_STAGE_NECESSARY) 41 | return; 42 | 43 | GenericApplication::initialize(stages); 44 | myAddr = IPAddressResolver().resolve(getParentModule()->getFullPath().data()); 45 | selfMsg = new cMessage("icmp ping"); 46 | } 47 | 48 | /** 49 | * In case of self message send another ping request message and schedule next 50 | * message with delay of timeBetweenRequests. 51 | * In case the transmission ends, send statistics to InetHost 52 | */ 53 | void GenericICMPPingApplication::handleMessage(cMessage *msg) 54 | { 55 | if (msg->isSelfMessage()) 56 | { 57 | if (noRequestsToSend--) 58 | { 59 | sendPing(); 60 | scheduleAt(simTime() + curProfile.getTimeBetweenRequests(true), selfMsg); 61 | } 62 | else 63 | { 64 | // send Statistics to InetUser 65 | TransmissionStatistics t(noBytesSend, noBytesReceived, noPacketSend, noPacketReceived); 66 | transmissionDone(t); 67 | } 68 | } 69 | else 70 | { 71 | // receive icmp pong 72 | receivePong(msg); 73 | } 74 | } 75 | 76 | void GenericICMPPingApplication::finish() 77 | { 78 | //TODO 79 | } 80 | 81 | void GenericICMPPingApplication::updateDisplay() 82 | { 83 | } 84 | 85 | /** 86 | * Starts a new ping/pong communication 87 | */ 88 | void GenericICMPPingApplication::transmissionStart(TrafficProfile &p, TargetInfo &i) 89 | { 90 | Enter_Method_Silent(); 91 | curProfile = p; 92 | noRequestsToSend = curProfile.getRequestsPerSession(true); 93 | noBytesSend = noBytesReceived = noPacketSend = noPacketReceived = 0; 94 | 95 | curTarget = i; 96 | 97 | scheduleAt(simTime() + SELF_CALL_DELAY, selfMsg); 98 | } 99 | 100 | /** 101 | * Creates ping message, fill it with necessary data and send it 102 | */ 103 | void GenericICMPPingApplication::sendPing() 104 | { 105 | PingPayload *msg = new PingPayload("ping", 1); 106 | msg->setOriginatorId(getId()); 107 | msg->setSeqNo(noPacketSend++); 108 | int packetSize = curProfile.getRequestLength(true); 109 | msg->setByteLength(packetSize); 110 | 111 | noBytesSend += packetSize; 112 | 113 | if (!curTarget.address.isIPv6()) 114 | { 115 | // send to IPv4 116 | IPControlInfo *ctrl = new IPControlInfo(); 117 | ctrl->setSrcAddr(myAddr.get4()); 118 | ctrl->setDestAddr(curTarget.address.get4()); 119 | ctrl->setTimeToLive(curProfile.hopLimit); 120 | msg->setControlInfo(ctrl); 121 | send(msg, "pingOut"); 122 | } 123 | else 124 | { 125 | // send to IPv6 126 | IPv6ControlInfo *ctrl = new IPv6ControlInfo(); 127 | ctrl->setSrcAddr(myAddr.get6()); 128 | ctrl->setDestAddr(curTarget.address.get6()); 129 | ctrl->setHopLimit(curProfile.hopLimit); 130 | msg->setControlInfo(ctrl); 131 | send(msg, "pingv6Out"); 132 | } 133 | } 134 | 135 | /** 136 | * Process pong messages. 137 | * Update statistics if ping request was initiated by myself 138 | */ 139 | void GenericICMPPingApplication::receivePong(cMessage *msg) 140 | { 141 | PingPayload *pmsg = dynamic_cast (msg); 142 | if (!pmsg) 143 | { 144 | delete msg; 145 | return; 146 | } 147 | if (pmsg->getOriginatorId() == getId()) 148 | { 149 | // this module is initiator of ping request - no more pong to send 150 | // 151 | //if(pmsg->controlInfo()) 152 | // delete pmsg->controlInfo(); 153 | noPacketReceived++; 154 | noBytesReceived += pmsg->getByteLength(); 155 | } 156 | delete msg; 157 | } 158 | -------------------------------------------------------------------------------- /src/applications/pingApp/GenericICMPPingApplication.h: -------------------------------------------------------------------------------- 1 | #ifndef GENERICICMPPINGAPPLICATION_H_ 2 | #define GENERICICMPPINGAPPLICATION_H_ 3 | 4 | #include 5 | #include "GenericApplication.h" 6 | #include "TransmissionConfig.h" 7 | #include "ReaSEDefs.h" 8 | 9 | /** 10 | * @brief Implementation of an ICMP Ping application. 11 | * 12 | * This implementation only sends icmp ping requests. 13 | * It has no influence to the processing of the corresponding 14 | * ICMP Pong. 15 | * 16 | * @class GenericICMPPingApplication 17 | */ 18 | class REASE_API GenericICMPPingApplication: public GenericApplication 19 | { 20 | private: 21 | /// IP address of the ICMP client 22 | IPvXAddress myAddr; 23 | /// Traffic profile used by this thread 24 | TrafficProfile curProfile; 25 | /// Communication partner of this thread 26 | TargetInfo curTarget; 27 | /// Connection statistics of this thread 28 | /// @{ 29 | int noRequestsToSend, noBytesSend, noBytesReceived, noPacketSend, noPacketReceived; 30 | /// @} 31 | /// Self message for UDP state transitions 32 | cMessage *selfMsg; 33 | /// Number of ping messages to send 34 | int pingToSend; 35 | protected: 36 | /// @brief Register at InetUser and ConnectionManager and open welcome socket (server only!) 37 | virtual void initialize(int stage); 38 | /// @brief Process packets of communication partners and self messages of threads 39 | virtual void handleMessage(cMessage *msg); 40 | virtual void finish(); 41 | void updateDisplay(); 42 | 43 | /// @brief Create an ICMP Ping message and send it to the server 44 | void sendPing(); 45 | /// @brief Process the ICMP Pong message from the server 46 | void receivePong(cMessage *msg); 47 | 48 | public: 49 | GenericICMPPingApplication(); 50 | virtual ~GenericICMPPingApplication(); 51 | /// @brief Starts a new connection to a server (client only!) 52 | virtual void transmissionStart(TrafficProfile &p, TargetInfo &i); 53 | 54 | }; 55 | 56 | #endif /*GENERICICMPPINGAPPLICATION_H_*/ 57 | -------------------------------------------------------------------------------- /src/applications/pingApp/GenericICMPPingApplication.ned: -------------------------------------------------------------------------------- 1 | package scadasim.applications.pingApp; 2 | 3 | // 4 | // Simple module for implementation of an application based on ICMP 5 | // 6 | simple GenericICMPPingApplication 7 | { 8 | parameters: 9 | // 10 | // should this application act as a server (true) or a client (false) 11 | // 12 | bool isServer; 13 | // 14 | // if it acts as a server, the server must know his traffic profile number. 15 | // If it acts as a client, the client can specify a profileNumber not equal -1 16 | // to register as a receiver for the specific profile 17 | // 18 | int profileNumber; 19 | // 20 | // and he has to know at which port he has to listen. Like above, a client 21 | // which set a profileNumber not equal to -1 has to specify a valid port 22 | // (for ICMP Ping the port is uninteresting) 23 | // 24 | int port; 25 | // 26 | // at least a udp or tcp server has to specify how many concurrently running 27 | // threads it will create. A Value of 0 means, that theres no limit for the 28 | // number of threads. (This value is ignored for the ICMP Application) 29 | // 30 | int noThreads; 31 | gates: 32 | input pingIn; 33 | output pingOut; 34 | } 35 | -------------------------------------------------------------------------------- /src/applications/tcpApp/GenericTCPApplication.h: -------------------------------------------------------------------------------- 1 | #ifndef GENERICTCPAPPLICATION_H_ 2 | #define GENERICTCPAPPLICATION_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "GenericApplication.h" 8 | #include "TCPSocket.h" 9 | #include "TCPSocketMap.h" 10 | 11 | class GenericTCPApplicationThreadBase; 12 | 13 | /** 14 | * @brief Implementation of a TCP application. 15 | * 16 | * TCP servers open a welcome socket and react on incoming connections. 17 | * New connections of TCP clients can be triggered by the connection 18 | * manager. 19 | * Overload situations at servers are simulated by limiting the number 20 | * of TCP connections that may open at the same time. 21 | * 22 | * @class GenericTCPApplication 23 | */ 24 | class REASE_API GenericTCPApplication: public GenericApplication 25 | { 26 | typedef std::list ThreadList; 27 | protected: 28 | /// Welcome socket in case of server instance 29 | TCPSocket *serverSocket; 30 | /// Map that contains sockets of all associated threads 31 | TCPSocketMap socketMap; 32 | /// List of all associated threads 33 | ThreadList threadList; 34 | /// Maximum number of threads that may be open at the same time 35 | int maxThreadCount; 36 | /// Number of threads that are open currently 37 | int threadCount; 38 | cMessage *selfMsg; 39 | 40 | public: 41 | GenericTCPApplication(); 42 | virtual ~GenericTCPApplication(); 43 | /// @brief Closes thread and associated socket 44 | void removeThread(GenericTCPApplicationThreadBase *thread); 45 | /// @brief Closes thread and associated socket and sends statistics to InetUser 46 | void removeThread(GenericTCPApplicationThreadBase *thread, TransmissionStatistics s); 47 | /// @brief Starts a new connection to a server (client only!) 48 | virtual void transmissionStart(TrafficProfile &p, TargetInfo &i); 49 | protected: 50 | /// @brief Register at InetUser and ConnectionManager and open welcome socket (server only!) 51 | virtual void initialize(int stages); 52 | /// @brief Process packets of communication partners and self messages of threads 53 | virtual void handleMessage(cMessage *msg); 54 | virtual void finish(); 55 | void updateDisplay(); 56 | 57 | }; 58 | 59 | /** 60 | * @brief Abstract class for implementation of client and server threads. 61 | * 62 | * These threads resemble the actual client and server functionality and 63 | * implement the communciation endpoints in case of a TCP transmission. 64 | * 65 | * @class GenericTCPApplicationThreadBase 66 | */ 67 | class REASE_API GenericTCPApplicationThreadBase : public cPolymorphic, public TCPSocket::CallbackInterface 68 | { 69 | protected: 70 | /// Pointer to application that started this thread 71 | GenericTCPApplication *ownerModule; 72 | /// Socket used by this thread 73 | TCPSocket *socket; 74 | 75 | 76 | protected: 77 | /// Interface Methods of TCPSocket 78 | /// @{ 79 | /// @brief Called in case packets arrived at the socket 80 | virtual void socketDataArrived(int connId, void *yourPtr, cPacket *msg, bool urgent) = 0; 81 | /// @brief Called in case socket is opened 82 | virtual void socketEstablished(int connId, void *yourPrt) = 0; 83 | /// @brief Called in case the peering socket is closed 84 | virtual void socketPeerClosed(int connId, void *yourPtr) = 0; 85 | /// @brief Called in case the socket is closed 86 | virtual void socketClosed(int connId, void *yourPtr) = 0; 87 | /// @brief Close thread in case of socket failure 88 | virtual void socketFailure(int connId, void *yourPtr, int code) {ownerModule->removeThread(this); }; 89 | /// @brief 90 | virtual void socketStatusArrived(int connId, void *yourPtr, TCPStatusInfo *status) {delete status; }; 91 | /// @} 92 | 93 | public: 94 | GenericTCPApplicationThreadBase() {socket = NULL; ownerModule = NULL; }; 95 | virtual ~GenericTCPApplicationThreadBase() {}; 96 | /// Set owner application module and socket of this thread 97 | virtual void init(GenericTCPApplication *owner, TCPSocket *sock) {ownerModule = owner; socket = sock; }; 98 | /// Handling of internal timer messages 99 | virtual void timerExpired(cMessage *msg) = 0; 100 | /// Return instance of TCPApplication that started the thread 101 | GenericTCPApplication *getOwnerModule() {return ownerModule; }; 102 | /// Return socket used for this thread 103 | TCPSocket *getSocket() {return socket; }; 104 | /// Delegate message scheduling to owner module 105 | void scheduleAt(simtime_t t, cMessage *msg) {msg->setContextPointer(this); ownerModule->scheduleAt(t, msg); }; 106 | /// Delegate message canceling to owner module 107 | void cancelEvent(cMessage *msg) {ownerModule->cancelEvent(msg); }; 108 | /// Delegate message canceling and deletion to owner module 109 | void cancelAndDelete(cMessage *msg) {ownerModule->cancelAndDelete(msg); }; 110 | }; 111 | 112 | #endif /*GENERICTCPAPPLICATION_H_*/ 113 | -------------------------------------------------------------------------------- /src/applications/tcpApp/GenericTCPApplication.ned: -------------------------------------------------------------------------------- 1 | package scadasim.applications.tcpApp; 2 | 3 | // 4 | // Simple module for implementation of an application based on TCP 5 | // 6 | simple GenericTCPApplication 7 | { 8 | parameters: 9 | // 10 | // should this application act as a server (true) or a client (false) 11 | // 12 | bool isServer; 13 | // 14 | // if it acts as a server, the server must know his traffic profile number. 15 | // If it acts as a client, the client can specify a profileNumber not equal -1 16 | // to register as a receiver for the specific profile 17 | // 18 | int profileNumber; 19 | // 20 | // and he has to know at which port he has to listen. Like above, a client 21 | // which set a profileNumber not equal to -1 has to specify a valid port 22 | // (for ICMP Ping the port is uninteresting) 23 | // 24 | int port; 25 | // 26 | // at least a udp or tcp server has to specify how many concurrently running 27 | // threads he will create. A Value of 0 say, that theres no limit for the 28 | // number of thread. (This value is ignored for the ICMP Application) 29 | // 30 | int noThreads; 31 | 32 | gates: 33 | input tcpIn; 34 | output tcpOut; 35 | } 36 | -------------------------------------------------------------------------------- /src/applications/tcpApp/GenericTCPApplicationClientThread.h: -------------------------------------------------------------------------------- 1 | #ifndef GENERICTCPAPPLICATIONCLIENTTHREAD_H_ 2 | #define GENERICTCPAPPLICATIONCLIENTTHREAD_H_ 3 | 4 | #include 5 | #include "GenericTCPApplication.h" 6 | #include "ReaSEDefs.h" 7 | 8 | /** 9 | * @brief A client thread implements the endpoint of a client/server connection. 10 | * 11 | * The client opens a socket and starts the communication by sending the first request. 12 | * Such a request contains all data necessary for the server to generate a reply. 13 | * After a maximum number of requests has been sent, the socket is closed and the 14 | * thread removed. 15 | * 16 | * @class GenericTCPApplicationClientThread 17 | */ 18 | class REASE_API GenericTCPApplicationClientThread : public GenericTCPApplicationThreadBase 19 | { 20 | private: 21 | /// Traffic profile used by this thread 22 | TrafficProfile curProfile; 23 | /// Communication partner of this thread 24 | TargetInfo curTarget; 25 | /// State of current thread 26 | int threadState; 27 | /// Connection statistics of this thread 28 | /// @{ 29 | unsigned long noRequestsToSend, noBytesSend, noBytesReceived, noPacketSend, noPacketReceived; 30 | /// @} 31 | /// Self message for TCP state transitions 32 | cMessage *selfMsg; 33 | 34 | 35 | public: 36 | GenericTCPApplicationClientThread(TrafficProfile &p, TargetInfo &i); 37 | virtual ~GenericTCPApplicationClientThread(); 38 | virtual void init(GenericTCPApplication *owner, TCPSocket *sock); 39 | virtual void timerExpired(cMessage *msg); 40 | 41 | protected: 42 | // Interface Methods 43 | virtual void socketDataArrived(int connId, void *youtPtr, cPacket *msg, bool urgent); 44 | virtual void socketEstablished(int connId, void *youtPtr); 45 | virtual void socketPeerClosed(int connId, void *youtPtr); 46 | virtual void socketClosed(int connId, void *youtPtr); 47 | virtual void socketFailure(int connId, void *youtPtr, int code); 48 | virtual void socketStatusArrived(int connId, void *youtPtr, TCPStatusInfo *status); 49 | 50 | /// @brief Create a request message and send it to the server 51 | virtual void sendRequest(); 52 | }; 53 | 54 | #endif /*GENERICTCPAPPLICATIONCLIENTTHREAD_H_*/ 55 | -------------------------------------------------------------------------------- /src/applications/tcpApp/GenericTCPApplicationServerThread.cc: -------------------------------------------------------------------------------- 1 | #include "GenericTCPApplicationServerThread.h" 2 | #include "GenericApplicationMessage_m.h" 3 | #include "TCPSocket.h" 4 | 5 | GenericTCPApplicationServerThread::GenericTCPApplicationServerThread() 6 | { 7 | selfMsg = new cMessage("replyTimer"); 8 | doClose = false; 9 | } 10 | 11 | GenericTCPApplicationServerThread::~GenericTCPApplicationServerThread() 12 | { 13 | if (selfMsg) 14 | { 15 | if (selfMsg->isScheduled()) 16 | cancelEvent(selfMsg); 17 | delete selfMsg; 18 | } 19 | while (!replies.empty()) 20 | { 21 | delete replies.front(); 22 | replies.pop(); 23 | } 24 | } 25 | 26 | /** 27 | * Send replies to the requesting client. 28 | * Furthermore, the socket is closed if the last request was received. 29 | */ 30 | void GenericTCPApplicationServerThread::timerExpired(cMessage *msg) 31 | { 32 | // time to respond to request 33 | if (!replies.empty()) 34 | { 35 | socket->send(replies.front()); 36 | replies.pop(); 37 | } 38 | 39 | // if this was the last packet, then close the socket (on my side) 40 | // 41 | if (doClose && (socket->getState() != TCPSocket::LOCALLY_CLOSED)) 42 | socket->close(); 43 | } 44 | 45 | /** 46 | * Process received client requests. 47 | * In case this was the last request (information contained in the message) 48 | * set doClose to true and close socket. 49 | */ 50 | void GenericTCPApplicationServerThread::socketDataArrived(int connId, void* yourPtr, cPacket *msg, bool urgent) 51 | { 52 | GenericApplicationMessage *appmsg = dynamic_cast (msg); 53 | if (!appmsg) 54 | opp_error("Message (%s) %s is not a GenericApplicationMessage", msg->getClassName(), msg->getName()); 55 | 56 | int replyLength = appmsg->getReplyLength(); 57 | 58 | doClose = appmsg->getLast(); 59 | if (replyLength == 0) 60 | { 61 | delete appmsg->removeControlInfo(); 62 | delete appmsg; 63 | } 64 | else 65 | { 66 | appmsg->setByteLength(replyLength); 67 | delete appmsg->removeControlInfo(); 68 | 69 | // delay the reply if required by the profile 70 | if (appmsg->getTimeToRespond() > 0) 71 | { 72 | replies.push(appmsg); 73 | int repliesSize = replies.size(); 74 | double timeToRespond = appmsg->getTimeToRespond(); 75 | scheduleAt(simTime() + appmsg->getTimeToRespond(), selfMsg); 76 | } 77 | else 78 | { 79 | socket->send(appmsg); 80 | 81 | // if this was the last packet and no delay is needed, 82 | // close the socket 83 | if (doClose && (socket->getState() != TCPSocket::LOCALLY_CLOSED)) 84 | socket->close(); 85 | } 86 | } 87 | } 88 | 89 | /** 90 | * Nothing to be done since communication is started by client 91 | */ 92 | void GenericTCPApplicationServerThread::socketEstablished(int connId, void *yourPtr) 93 | { 94 | //TODO: or not interested 95 | 96 | } 97 | 98 | /** 99 | * Close server socket if client socket was closed. 100 | */ 101 | void GenericTCPApplicationServerThread::socketPeerClosed(int connId, void *yourPtr) 102 | { 103 | // 104 | // just set a flag that i know - the client sends me no more request 105 | // and so i can close my socket after sending my replies 106 | // 107 | doClose = true; 108 | } 109 | 110 | /** 111 | * At the end of a transmission, close thread. 112 | */ 113 | void GenericTCPApplicationServerThread::socketClosed(int connId, void *yourPtr) 114 | { 115 | // both sides of connection are closed i can delete the server thread 116 | ownerModule->removeThread(this); 117 | } 118 | 119 | /** 120 | * Close thread in case of a socket failure. 121 | */ 122 | void GenericTCPApplicationServerThread::socketFailure(int connId, void *youtPtr, int code) 123 | { 124 | ownerModule->removeThread(this); 125 | } 126 | 127 | void GenericTCPApplicationServerThread::socketStatusArrived(int connId, void *yourPtr, TCPStatusInfo *status) 128 | { 129 | //TODO: or not interested 130 | delete status; 131 | } 132 | -------------------------------------------------------------------------------- /src/applications/tcpApp/GenericTCPApplicationServerThread.h: -------------------------------------------------------------------------------- 1 | #ifndef GENERICTCPAPPLICATIONSERVERTHREAD_H_ 2 | #define GENERICTCPAPPLICATIONSERVERTHREAD_H_ 3 | 4 | #include 5 | #include 6 | #include "GenericTCPApplication.h" 7 | #include "ReaSEDefs.h" 8 | 9 | /** 10 | * @brief A server thread implements the endpoint of a client/server connection. 11 | * 12 | * The server sends replies to all requests that are received on open sockets. 13 | * A reply to a client request can consists of multiple reply packets. These are sent 14 | * with a specified inter-packet delay. If the last request of a communication is 15 | * received, the socket is closed and the thread removed. 16 | * 17 | * @class GenericTCPApplicationServerThread 18 | */ 19 | class REASE_API GenericTCPApplicationServerThread : public GenericTCPApplicationThreadBase 20 | { 21 | private: 22 | /// Indicates that the socket should be closed due to end of the transmission 23 | bool doClose; 24 | /// Triggers sending of replies after waiting time specified by the profile 25 | cMessage *selfMsg; 26 | /// Set of replies that are sent as reaction to a request 27 | std::queue replies; 28 | public: 29 | GenericTCPApplicationServerThread(); 30 | virtual ~GenericTCPApplicationServerThread(); 31 | virtual void timerExpired(cMessage *msg); 32 | 33 | protected: 34 | // Interface Methods 35 | virtual void socketDataArrived(int connId, void *youtPtr, cPacket *msg, bool urgent); 36 | virtual void socketEstablished(int connId, void *youtPtr); 37 | virtual void socketPeerClosed(int connId, void *youtPtr); 38 | virtual void socketClosed(int connId, void *youtPtr); 39 | virtual void socketFailure(int connId, void *youtPtr, int code); 40 | virtual void socketStatusArrived(int connId, void *youtPtr, TCPStatusInfo *status); 41 | }; 42 | 43 | #endif /*GENERICTCPAPPLICATIONSERVERTHREAD_H_*/ 44 | -------------------------------------------------------------------------------- /src/applications/udpApp/GenericUDPApplication.h: -------------------------------------------------------------------------------- 1 | #ifndef GENERICUDPAPPLICATION_H_ 2 | #define GENERICUDPAPPLICATION_H_ 3 | 4 | #include 5 | #include "GenericApplication.h" 6 | #include "UDPSocket.h" 7 | #include "UDPSocketVector.h" 8 | #include 9 | #include 10 | 11 | class GenericUDPApplicationThreadBase; 12 | 13 | /** 14 | * @brief Implementation of a UDP application. 15 | * 16 | * UDP applications open a welcome socket and react on incoming connections. 17 | * (All clients are at least servers for UDPMisc traffic). 18 | * New connections of UDP clients can be triggered by the connection 19 | * manager. 20 | * Overload situations at servers are simulated by limiting the number 21 | * of UDP connections that may open at the same time. In case of overload 22 | * the welcome socket is closed and ICMP error message are generated. * 23 | * 24 | * @class GenericUDPApplication 25 | */ 26 | class REASE_API GenericUDPApplication: public GenericApplication 27 | { 28 | /** 29 | * Structure that contains information about a UDP thread 30 | */ 31 | struct threadInfo{ 32 | /// Indicates if thread belongs to a server 33 | bool isServer; 34 | /// Pointer to the actual thread 35 | GenericUDPApplicationThreadBase *thread; 36 | 37 | threadInfo(bool isServer, GenericUDPApplicationThreadBase *t) 38 | { 39 | this->isServer = isServer; 40 | this->thread = t; 41 | } 42 | }; 43 | 44 | typedef std::map ThreadMap; 45 | 46 | private: 47 | /// UDP socket in case of server instance 48 | UDPSocket *mySocket; 49 | /// Maximum number of threads that may be open at the same time 50 | int maxThreadCount; 51 | /// Number of threads that are open currently 52 | int threadCount; 53 | /** 54 | * This map is used for error handling. If an icmp error message 55 | * arrives, the corresponding socket and thread are killed. 56 | */ 57 | ThreadMap threadMap; 58 | cMessage *selfMsg; 59 | 60 | public: 61 | GenericUDPApplication(); 62 | virtual ~GenericUDPApplication(); 63 | /// @brief Closes thread and associated socket 64 | void removeThread(GenericUDPApplicationThreadBase *thread); 65 | /// @brief Closes thread and associated socket and sends statistics to InetUser 66 | void removeThread(GenericUDPApplicationThreadBase *thread, TransmissionStatistics s); 67 | /// @brief Starts a new connection to a server (client only!) 68 | virtual void transmissionStart(TrafficProfile &p, TargetInfo &i); 69 | 70 | protected: 71 | /// @brief Register at InetUser and ConnectionManager and open welcome socket (server only!) 72 | virtual void initialize(int stages); 73 | /// @brief Process packets of communication partners and self messages of threads 74 | virtual void handleMessage(cMessage *msg); 75 | virtual void finish(); 76 | void updateDisplay(); 77 | 78 | 79 | }; 80 | 81 | /** 82 | * @brief Abstract class for implementation of client and server threads. 83 | * 84 | * These threads resemble the actual client and server functionality and 85 | * implement the communciation endpoints in case of a UDP transmission. 86 | * 87 | * @class GenericUDPApplicationThreadBase 88 | */ 89 | 90 | class REASE_API GenericUDPApplicationThreadBase : public cPolymorphic, public UDPSocket::CallbackInterface 91 | { 92 | 93 | protected: 94 | const static double UDP_MAX_PAYLOAD; 95 | /// Pointer to application that started this thread 96 | GenericUDPApplication *ownerModule; 97 | /// Socket used by this thread 98 | UDPSocket *socket; 99 | /// State of current thread 100 | int threadState; 101 | 102 | protected: 103 | /// @brief Create a request message and send it to the server 104 | void sendRequest(); 105 | public: 106 | GenericUDPApplicationThreadBase() {ownerModule = NULL; socket = NULL;}; 107 | virtual ~GenericUDPApplicationThreadBase() {}; 108 | /// Set owner application module and socket of this thread 109 | virtual void init(GenericUDPApplication *owner, UDPSocket *sock) {ownerModule = owner; socket = sock; }; 110 | /// Handling of internal timer messages 111 | virtual void timerExpired(cMessage *msg) = 0; 112 | /// Return instance of UDPApplication that started the thread 113 | GenericUDPApplication *getOwnerModule() {return ownerModule; }; 114 | /// Delegate message scheduling to owner module 115 | void scheduleAt(simtime_t t, cMessage *msg) {msg->setContextPointer(this), ownerModule->scheduleAt(t, msg); }; 116 | /// Delegate message canceling to owner module 117 | void cancelEvent(cMessage *msg) {ownerModule->cancelEvent(msg); }; 118 | /// Delegate message canceling and deletion to owner module 119 | void cancelAndDelete(cMessage *msg) {ownerModule->cancelAndDelete(msg); }; 120 | 121 | /// Return socket of this thread 122 | UDPSocket *getSocket() {return socket; }; 123 | }; 124 | 125 | #endif /*GENERICUDPAPPLICATION_H_*/ 126 | -------------------------------------------------------------------------------- /src/applications/udpApp/GenericUDPApplication.ned: -------------------------------------------------------------------------------- 1 | package scadasim.applications.udpApp; 2 | 3 | // 4 | // Simple module for implementation of an application based on UDP 5 | // 6 | simple GenericUDPApplication 7 | 8 | { 9 | parameters: 10 | // 11 | // should this application act as a server (true) or a client (false) 12 | // 13 | bool isServer; 14 | // 15 | // if it acts as a server, the server must know his traffic profile number. 16 | // If it acts as a client, the client can specify a profileNumber not equal -1 17 | // to register as a receiver for the specific profile 18 | // 19 | int profileNumber; 20 | // 21 | // and he has to know at which port he has to listen. Like above, a client 22 | // which set a profileNumber not equal to -1 has to specify a valid port 23 | // (for ICMP Ping the port is uninteresting) 24 | // 25 | int port; 26 | // 27 | // at least a udp or tcp server has to specify how many concurrently running 28 | // threads he will create. A Value of 0 means, that there is no limit for the 29 | // number of threads. (This value is ignored for the ICMP Application) 30 | // 31 | int noThreads; 32 | 33 | gates: 34 | input udpIn; 35 | output udpOut; 36 | } 37 | -------------------------------------------------------------------------------- /src/applications/udpApp/GenericUDPApplicationClientThread.cc: -------------------------------------------------------------------------------- 1 | #include "GenericUDPApplicationClientThread.h" 2 | #include "IPvXAddress.h" 3 | #include "GenericApplicationMessage_m.h" 4 | #include 5 | 6 | /** 7 | * @brief A client thread implements the endpoint of a client/server connection. 8 | * 9 | * The client opens a socket and starts the communication by sending the first request. 10 | * Such a request, however, must be fragmented before sending. The last fragment contains 11 | * all data necessary for the server to generate a reply. 12 | * The UDPApplication gives only the last fragment of the replies to the client for 13 | * processing. 14 | * After a maximum number of requests has been sent, the socket is closed and the 15 | * thread removed. 16 | * 17 | * @class GenericUDPApplicationClientThread 18 | */ 19 | 20 | using std::cerr; 21 | using std::endl; 22 | 23 | /// Thread States 24 | /// @{ 25 | #define NOT_SET -1 26 | #define CONNECTED 2 27 | #define DISCONNECTED 3 28 | #define FINISH 4 29 | /// @} 30 | 31 | 32 | GenericUDPApplicationClientThread::GenericUDPApplicationClientThread(TrafficProfile &p, TargetInfo &i) 33 | { 34 | curProfile = p; 35 | curTarget = i; 36 | 37 | // maximum nuber of requests per session 38 | // TODO: Streaming Client should just make one request 39 | noRequestsToSend = curProfile.getRequestsPerSession(true); 40 | 41 | curResponseTime = curProfile.getTimeToRespond(true); 42 | 43 | packetsPerRequest = 1; 44 | packetSize = curProfile.getRequestLength(true); 45 | // Fragmentation must be done before sending UDP packets 46 | if (packetSize > UDP_MAX_PAYLOAD) 47 | { 48 | packetsPerRequest = (int) ceil(packetSize / UDP_MAX_PAYLOAD); 49 | packetSize = (int) UDP_MAX_PAYLOAD; 50 | curPacketsPerRequest = packetsPerRequest; 51 | } 52 | 53 | threadState = NOT_SET; 54 | } 55 | 56 | GenericUDPApplicationClientThread::~GenericUDPApplicationClientThread() 57 | { 58 | if (selfMsg) 59 | { 60 | if (selfMsg->isScheduled()) 61 | cancelAndDelete(selfMsg); 62 | else 63 | delete selfMsg; 64 | } 65 | } 66 | 67 | /** 68 | * Sets timer for starting the new communication and open socket to target. 69 | */ 70 | void GenericUDPApplicationClientThread::init(GenericUDPApplication *owner, UDPSocket *sock) 71 | { 72 | GenericUDPApplicationThreadBase::init(owner, sock); 73 | noBytesSend = noBytesReceived = noPacketSend = noPacketReceived = 0; 74 | 75 | // set socket to target 76 | socket->connect(curTarget.address, curTarget.port); 77 | threadState = CONNECTED; 78 | 79 | selfMsg = new cMessage("requestTimer"); 80 | scheduleAt(simTime() + SELF_CALL_DELAY, selfMsg); 81 | } 82 | 83 | /** 84 | * Manage UDP state transitions. 85 | * In case no more requests must be sent (DISCONNECTED), wait timeBetweenRequests 86 | * and then switch to FINISH. 87 | */ 88 | void GenericUDPApplicationClientThread::timerExpired(cMessage *msg) 89 | { 90 | switch (threadState) 91 | { 92 | case CONNECTED: 93 | // time to start a new request 94 | sendRequest(); 95 | break; 96 | case DISCONNECTED: 97 | { 98 | threadState = FINISH; 99 | scheduleAt(simTime() + curProfile.getTimeBetweenSessions(true), selfMsg); 100 | break; 101 | } 102 | case FINISH: 103 | socket->close(); 104 | TransmissionStatistics s(noBytesSend, noBytesReceived, noPacketSend, noPacketReceived); 105 | ownerModule->removeThread(this, s); 106 | break; 107 | } 108 | } 109 | 110 | /** 111 | * Creates a new request message and all its fragemts. All necessary data is set. 112 | * Then, the messages are sent via the socket associated to this thread. 113 | */ 114 | void GenericUDPApplicationClientThread::sendRequest() 115 | { 116 | noRequestsToSend--; 117 | if (noRequestsToSend <= 0) 118 | threadState = DISCONNECTED; 119 | 120 | int currentReplyLength = curProfile.getReplyLength(true); 121 | int curReplysToReceive = curProfile.getReplyPerRequest(true); 122 | 123 | noBytesReceived += currentReplyLength; 124 | noPacketReceived += ((int) ceil(packetSize / UDP_MAX_PAYLOAD)); 125 | 126 | for (int i = packetsPerRequest; i > 0; i--) 127 | { 128 | noBytesSend += packetSize; 129 | noPacketSend++; 130 | 131 | GenericApplicationMessage *appmsg = new GenericApplicationMessage("udp_request_data"); 132 | appmsg->setByteLength(packetSize); 133 | 134 | appmsg->setReplyLength(currentReplyLength); 135 | appmsg->setTimeToRespond(curResponseTime); 136 | appmsg->setReplyPerRequest(curReplysToReceive); 137 | appmsg->setLast(false); 138 | 139 | // the last fragment of request with packet number 1 will cause 140 | // a new server thread at the receiver side 141 | appmsg->setPacketNumber(i); 142 | 143 | socket->send(appmsg); 144 | } 145 | 146 | // static timer for next request 147 | 148 | // if the reply size is to big, the UDP packet will be queued at 149 | // source and will arrive delayed --> this could cause many ICMP-Error Msg 150 | scheduleAt(simTime() + curReplysToReceive * curResponseTime * 1.5, selfMsg); 151 | } 152 | 153 | /** 154 | * Process data received from server (only the last message is given to the thread by the UDPApplication). 155 | * In case no more requests must be sent, wait timeBetweenSessions and close the socket. 156 | */ 157 | void GenericUDPApplicationClientThread::socketDatagramArrived(int sockId, void *yourPtr, cMessage *msg, UDPControlInfo *ctrl) 158 | { 159 | // this method is only called for the last message of a server 160 | if (!noRequestsToSend) 161 | { 162 | threadState = FINISH; 163 | if (selfMsg->isScheduled()) 164 | cancelEvent(selfMsg); 165 | scheduleAt(simTime() + curProfile.getTimeBetweenSessions(true), selfMsg); 166 | } 167 | delete msg; 168 | delete ctrl; 169 | } 170 | -------------------------------------------------------------------------------- /src/applications/udpApp/GenericUDPApplicationClientThread.h: -------------------------------------------------------------------------------- 1 | #ifndef GENERICUDPAPPLICATIONCLIENTTHREAD_H_ 2 | #define GENERICUDPAPPLICATIONCLIENTTHREAD_H_ 3 | 4 | #include 5 | #include "GenericUDPApplication.h" 6 | 7 | /** 8 | * @brief A client thread implements the endpoint of a client/server connection. 9 | * 10 | * The client opens a socket and starts the communication by sending the first request. 11 | * Such a request, however, must be fragmented before sending. The last fragment contains 12 | * all data necessary for the server to generate a reply. 13 | * The UDPApplication gives only the last fragment of the replies to the client for 14 | * processing. 15 | * After a maximum number of requests has been sent, the socket is closed and the 16 | * thread removed. 17 | * 18 | * @class GenericUDPApplicationClientThread 19 | */ 20 | class REASE_API GenericUDPApplicationClientThread : public GenericUDPApplicationThreadBase 21 | { 22 | private: 23 | /// Traffic profile used by this thread 24 | TrafficProfile curProfile; 25 | /// Communication partner of this thread 26 | TargetInfo curTarget; 27 | /// Connection statistics of this thread 28 | /// @{ 29 | int noRequestsToSend, noBytesSend, noBytesReceived, noPacketSend, noPacketReceived; 30 | /// @} 31 | /// Self message for UDP state transitions 32 | cMessage *selfMsg; 33 | /// state variables required due to fragmentation 34 | /// @{ 35 | int packetsPerRequest; 36 | int packetSize; 37 | int curPacketsPerRequest; 38 | /// @} 39 | /// Necessary for static inter-packet wait time 40 | double curResponseTime; 41 | 42 | public: 43 | GenericUDPApplicationClientThread(TrafficProfile &p, TargetInfo &i); 44 | virtual ~GenericUDPApplicationClientThread(); 45 | virtual void init(GenericUDPApplication *owner, UDPSocket *sock); 46 | virtual void timerExpired(cMessage *msg); 47 | 48 | protected: 49 | // 50 | // Interface Methods 51 | // 52 | virtual void socketDatagramArrived(int sockId, void *yourPtr, cMessage *msg, UDPControlInfo *ctrl); 53 | virtual void socketPeerClosed(int sockId, void *yourPtr) {}; 54 | 55 | /// @brief Create a request message and send it to the server 56 | void sendRequest(); 57 | }; 58 | 59 | 60 | 61 | #endif /*GENERICUDPAPPLICATIONCLIENTTHREAD_H_*/ 62 | -------------------------------------------------------------------------------- /src/applications/udpApp/GenericUDPApplicationServerThread.cc: -------------------------------------------------------------------------------- 1 | #include "GenericUDPApplicationServerThread.h" 2 | #include "GenericApplicationMessage_m.h" 3 | #include "UDPControlInfo_m.h" 4 | 5 | /** 6 | * @brief A server thread implements the endpoint of a client/server connection. 7 | * 8 | * The server sends replies to the request that is received on the sockets. 9 | * A reply to a client request can consists of multiple reply packets. These are sent 10 | * with a specified inter-packet delay. 11 | * Such replies, however, must be fragmented before sending. 12 | * The socket is closed as soon as all replies to this single request have been sent. 13 | * 14 | * @class GenericUDPApplicationServerThread 15 | */ 16 | 17 | /// Thread States 18 | /// @{ 19 | #define NOT_SET -1 20 | #define CONNECTED 1 21 | #define DISCONNECTED 2 22 | #define LAST 3 23 | /// @} 24 | 25 | 26 | GenericUDPApplicationServerThread::GenericUDPApplicationServerThread() 27 | { 28 | selfMsg = NULL; 29 | threadState = NOT_SET; 30 | } 31 | 32 | GenericUDPApplicationServerThread::~GenericUDPApplicationServerThread() 33 | { 34 | if (selfMsg) 35 | { 36 | if (selfMsg->isScheduled()) 37 | cancelEvent(selfMsg); 38 | delete selfMsg; 39 | } 40 | selfMsg = NULL; 41 | } 42 | 43 | /** 44 | * Sets timer for sending replies to client. 45 | */ 46 | void GenericUDPApplicationServerThread::init(GenericUDPApplication *owner, UDPSocket *sock) 47 | { 48 | GenericUDPApplicationThreadBase::init(owner, sock); 49 | noReplysToSend = 0; 50 | noPacketSend = 0; 51 | timeBetweenReplys = -1.0; 52 | selfMsg = new cMessage("replyTimer"); 53 | threadState = CONNECTED; 54 | } 55 | 56 | /** 57 | * Manage UDP state transitions. 58 | * In case no more replies must be sent (DISCONNECTED), close socket 59 | * and remove thread. 60 | */ 61 | void GenericUDPApplicationServerThread::timerExpired(cMessage *msg) 62 | { 63 | switch (threadState) 64 | { 65 | case CONNECTED: 66 | case LAST: 67 | // time to send the next reply 68 | sendReply(); 69 | break; 70 | case DISCONNECTED: 71 | socket->close(); 72 | // last reply was sent -> end 73 | ownerModule->removeThread(this); 74 | break; 75 | } 76 | } 77 | 78 | /** 79 | * Creates a new reply message and all its fragemts. All necessary data is set. 80 | * Then, the messages are sent via the socket associated to this thread. 81 | * In case of the last reply the last flag is set, else the timer is restarted. 82 | */ 83 | void GenericUDPApplicationServerThread::sendReply() 84 | { 85 | noReplysToSend--; 86 | noPacketSend++; 87 | 88 | for (int i = 0; i < packetPerReply; i++) 89 | { 90 | // respond without delay 91 | GenericApplicationMessage *appmsg = new GenericApplicationMessage("udp_reply_data"); 92 | appmsg->setByteLength(packetSize); 93 | appmsg->setPacketNumber(noPacketSend); 94 | socket->send(appmsg); 95 | } 96 | 97 | // request was the last and all replys were send 98 | if (noReplysToSend <= 0) 99 | { 100 | threadState = DISCONNECTED; 101 | 102 | // self-call delay until termination 103 | scheduleAt(simTime() + SELF_CALL_DELAY, selfMsg); 104 | } 105 | else 106 | // set time for next reply 107 | scheduleAt(simTime() + timeBetweenReplys, selfMsg); 108 | } 109 | 110 | /** 111 | * Process data received from client (only the last message is given to the thread by the UDPApplication). 112 | * This method is invoked just once a time. After having sent the reply packets the socket is closed 113 | * and the server removed. 114 | * Wait timeBetweenReplies until the fragments of the first reply are sent to the client. 115 | */ 116 | void GenericUDPApplicationServerThread::socketDatagramArrived(int sockId, void *yourPtr, cMessage *msg, UDPControlInfo *ctrl) 117 | { 118 | packetPerReply = 1; 119 | GenericApplicationMessage *appmsg = dynamic_cast (msg); 120 | packetSize = appmsg->getReplyLength(); 121 | noReplysToSend = appmsg->getReplyPerRequest(); 122 | noPacketSend = appmsg->getPacketNumber(); 123 | timeBetweenReplys = appmsg->getTimeToRespond(); 124 | 125 | // Fragmentation must be done before sending UDP packets 126 | if (packetSize > UDP_MAX_PAYLOAD) 127 | { 128 | packetPerReply = (int) ceil(packetSize / UDP_MAX_PAYLOAD); 129 | packetSize = (int) UDP_MAX_PAYLOAD; 130 | } 131 | 132 | delete msg; 133 | delete ctrl; 134 | 135 | scheduleAt(simTime() + timeBetweenReplys, selfMsg); 136 | } 137 | -------------------------------------------------------------------------------- /src/applications/udpApp/GenericUDPApplicationServerThread.h: -------------------------------------------------------------------------------- 1 | #ifndef GENERICUDPAPPLICATIONSERVERTHREAD_H_ 2 | #define GENERICUDPAPPLICATIONSERVERTHREAD_H_ 3 | 4 | #include 5 | #include "GenericUDPApplication.h" 6 | #include "ReaSEDefs.h" 7 | 8 | /** 9 | * @brief A server thread implements the endpoint of a client/server connection. 10 | * 11 | * The server sends replies to the request that is received on the sockets. 12 | * A reply to a client request can consists of multiple reply packets. These are sent 13 | * with a specified inter-packet delay. 14 | * Such replies, however, must be fragmented before sending. 15 | * The socket is closed as soon as all replies to this single request have been sent. 16 | * 17 | * @class GenericUDPApplicationServerThread 18 | */ 19 | class REASE_API GenericUDPApplicationServerThread : public GenericUDPApplicationThreadBase 20 | { 21 | private: 22 | cMessage *selfMsg; 23 | int noReplysToSend, threadState, packetSize, noPacketSend; 24 | int packetPerReply; 25 | double timeBetweenReplys; 26 | 27 | protected: 28 | // 29 | // Interface Methods 30 | // 31 | virtual void socketDatagramArrived(int sockId, void *yourPtr, cMessage *msg, UDPControlInfo *ctrl); 32 | virtual void socketPeerClosed(int sockId, void *yourPtr) {}; 33 | 34 | /// @brief Create a reply message and send it to the client 35 | void sendReply(); 36 | 37 | public: 38 | GenericUDPApplicationServerThread(); 39 | virtual ~GenericUDPApplicationServerThread(); 40 | virtual void init(GenericUDPApplication *owner, UDPSocket *sock); 41 | virtual void timerExpired(cMessage *msg); 42 | 43 | }; 44 | 45 | #endif /*GENERICUDPAPPLICATIONSERVERTHREAD_H_*/ 46 | -------------------------------------------------------------------------------- /src/applications/udpApp/GenericUDPApplicationTimeout.cc: -------------------------------------------------------------------------------- 1 | #include "GenericUDPApplicationTimeout.h" 2 | 3 | GenericUDPApplicationTimeout::GenericUDPApplicationTimeout(GenericUDPApplicationThreadBase *user) 4 | { 5 | timeout = new cMessage("timeout"); 6 | timeout->setKind(MSG_KIND_TIMEOUT); 7 | lastTimeout = -1.0; 8 | this->user = user; 9 | } 10 | 11 | GenericUDPApplicationTimeout::GenericUDPApplicationTimeout(simtime_t defaultTimeout, GenericUDPApplicationThreadBase *user) 12 | { 13 | timeout = new cMessage("timeout"); 14 | timeout->setKind(MSG_KIND_TIMEOUT); 15 | this->defaultTimeout = defaultTimeout; 16 | lastTimeout = 0 - defaultTimeout; 17 | this->user = user; 18 | } 19 | 20 | GenericUDPApplicationTimeout::~GenericUDPApplicationTimeout() 21 | { 22 | if (timeout->isScheduled()) 23 | user->cancelEvent(timeout); 24 | delete timeout; 25 | timeout = NULL; 26 | } 27 | 28 | void GenericUDPApplicationTimeout::setTimeout(double RTT) 29 | { 30 | if (lastTimeout < 0) 31 | { 32 | if (timeout->isScheduled()) 33 | user->cancelEvent(timeout); 34 | user->scheduleAt(simTime() - lastTimeout, timeout); 35 | } 36 | else 37 | { 38 | // 39 | // timeout already set 40 | // 41 | if (timeout->isScheduled()) 42 | user->cancelEvent(timeout); 43 | // TODO: Timeout calculation seems to be incorrect 44 | user->scheduleAt(simTime() + 2 * (simTime() - lastTimeout + RTT), timeout); 45 | lastTimeout = simTime(); 46 | } 47 | } 48 | 49 | void GenericUDPApplicationTimeout::reset() 50 | { 51 | if (timeout->isScheduled()) 52 | user->cancelEvent(timeout); 53 | lastTimeout = 0 - defaultTimeout; 54 | } 55 | -------------------------------------------------------------------------------- /src/applications/udpApp/GenericUDPApplicationTimeout.h: -------------------------------------------------------------------------------- 1 | #ifndef GENERICAPPLICATIONTIMEOUT_H_ 2 | #define GENERICAPPLICATIONTIMEOUT_H_ 3 | 4 | #include 5 | #include "GenericUDPApplication.h" 6 | #include "ReaSEDefs.h" 7 | 8 | #define MSG_KIND_TIMEOUT 1033 9 | 10 | /** 11 | * @brief Timer for UDP messages 12 | * 13 | * @class GenericUDPApplicationTimeout 14 | */ 15 | class REASE_API GenericUDPApplicationTimeout : public cPolymorphic 16 | { 17 | private: 18 | /// Time of last timeout 19 | simtime_t lastTimeout; 20 | /// Default timer duration 21 | simtime_t defaultTimeout; 22 | /// Timeout message that is scheduled 23 | cMessage *timeout; 24 | /// Thread associated to this timeout 25 | GenericUDPApplicationThreadBase *user; 26 | public: 27 | GenericUDPApplicationTimeout(GenericUDPApplicationThreadBase *user); 28 | GenericUDPApplicationTimeout(simtime_t defaultTimeout, GenericUDPApplicationThreadBase *user); 29 | virtual ~GenericUDPApplicationTimeout(); 30 | /// Set timeout to two times the given RTT 31 | virtual void setTimeout(double RTT); 32 | /// Reset the timer 33 | virtual void reset(); 34 | }; 35 | 36 | #endif /*GENERICAPPLICATIONTIMEOUT_H_*/ 37 | -------------------------------------------------------------------------------- /src/applications/worm/UDPWormQueryMessage.msg: -------------------------------------------------------------------------------- 1 | // 2 | // Probing message sent by infected worm hosts in order to infect 3 | // further vulnerable hosts. 4 | // 5 | 6 | cplusplus {{ 7 | #include "ReaSEDefs.h" 8 | }} 9 | 10 | packet UDPWormQueryMessage 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/applications/worm/UDPWormQueryMessage_m.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file, do not edit! Created by opp_msgc 4.2 from applications/worm/UDPWormQueryMessage.msg. 3 | // 4 | 5 | #ifndef _UDPWORMQUERYMESSAGE_M_H_ 6 | #define _UDPWORMQUERYMESSAGE_M_H_ 7 | 8 | #include 9 | 10 | // opp_msgc version check 11 | #define MSGC_VERSION 0x0402 12 | #if (MSGC_VERSION!=OMNETPP_VERSION) 13 | # error Version mismatch! Probably this file was generated by an earlier version of opp_msgc: 'make clean' should help. 14 | #endif 15 | 16 | // dll export symbol 17 | #ifndef SCADASim_API 18 | # if defined(SCADASim_EXPORT) 19 | # define SCADASim_API OPP_DLLEXPORT 20 | # elif defined(SCADASim_IMPORT) 21 | # define SCADASim_API OPP_DLLIMPORT 22 | # else 23 | # define SCADASim_API 24 | # endif 25 | #endif 26 | 27 | // cplusplus {{ 28 | #include "ReaSEDefs.h" 29 | // }} 30 | 31 | 32 | 33 | /** 34 | * Class generated from applications/worm/UDPWormQueryMessage.msg by opp_msgc. 35 | *
36 |  * packet UDPWormQueryMessage
37 |  * {
38 |  * }
39 |  * 
40 | */ 41 | class SCADASim_API UDPWormQueryMessage : public ::cPacket 42 | { 43 | protected: 44 | 45 | // protected and unimplemented operator==(), to prevent accidental usage 46 | bool operator==(const UDPWormQueryMessage&); 47 | 48 | public: 49 | UDPWormQueryMessage(const char *name=NULL, int kind=0); 50 | UDPWormQueryMessage(const UDPWormQueryMessage& other); 51 | virtual ~UDPWormQueryMessage(); 52 | UDPWormQueryMessage& operator=(const UDPWormQueryMessage& other); 53 | virtual UDPWormQueryMessage *dup() const {return new UDPWormQueryMessage(*this);} 54 | virtual void parsimPack(cCommBuffer *b); 55 | virtual void parsimUnpack(cCommBuffer *b); 56 | 57 | // field getter/setter methods 58 | }; 59 | 60 | inline void doPacking(cCommBuffer *b, UDPWormQueryMessage& obj) {obj.parsimPack(b);} 61 | inline void doUnpacking(cCommBuffer *b, UDPWormQueryMessage& obj) {obj.parsimUnpack(b);} 62 | 63 | 64 | #endif // _UDPWORMQUERYMESSAGE_M_H_ 65 | -------------------------------------------------------------------------------- /src/applications/worm/UDPWormVictim.cc: -------------------------------------------------------------------------------- 1 | #include "UDPWormVictim.h" 2 | #include "IPControlInfo_hacked_m.h" 3 | #include "IPv6ControlInfo_hacked_m.h" 4 | #include "UDPPacket.h" 5 | #include "UDPControlInfo_m.h" 6 | #include "UDPWormQueryMessage_m.h" 7 | #include 8 | 9 | using std::cerr; 10 | using std::cout; 11 | using std::endl; 12 | 13 | const int UDP_HEADER_BYTES = 8; 14 | 15 | Define_Module( UDPWormVictim); 16 | 17 | UDPWormVictim::UDPWormVictim() 18 | { 19 | } 20 | 21 | UDPWormVictim::~UDPWormVictim() 22 | { 23 | if (probingTimer) 24 | { 25 | if (probingTimer->isScheduled()) 26 | cancelAndDelete(probingTimer); 27 | else 28 | delete probingTimer; 29 | } 30 | } 31 | 32 | /** 33 | * Initialize parameters for worm propagation. 34 | * Randomly set some hosts to infected at start of the 35 | * propagation. All other hosts get the state vulnerable. 36 | */ 37 | void UDPWormVictim::initialize(int stages) 38 | { 39 | if (stages != 3) 40 | return; 41 | 42 | probingDelay = par("timeBetweenProbingPackets"); 43 | maxProbingPackets = par("maxProbingPackets"); 44 | sourcePort = par("sourcePort"); 45 | victimPort = par("listenAndVictimPort"); 46 | packetLength = par("probingPacketLength"); 47 | 48 | // ensure differentiation from DDoS attacks 49 | attackTag = par("attackTag"); 50 | attackTag += FIRST_ATTACK_ID_OF_WORM_SPREAD; 51 | 52 | const char *beginString = par("addressRangeStart"); 53 | addrStart.set(beginString); 54 | const char *endString = par("addressRangeEnd"); 55 | addrEnd.set(endString); 56 | 57 | startTime = par("startProbing"); 58 | double startTimeDiff = par("startProbingDiff"); 59 | double startProbingProbability = par("startProbingProbability"); 60 | 61 | // set some worm hosts randomly to active at start of propagation 62 | if (startProbingProbability > uniform(0, 1, 4)) 63 | isActive = true; 64 | else 65 | isActive = false; 66 | 67 | probingTimer = new cMessage("timeoutForProbingPacket"); 68 | if (isActive) 69 | scheduleAt(simTime() + startTime + startTimeDiff, probingTimer); 70 | } 71 | 72 | /** 73 | * If self message a new probing packet should be sent. 74 | * In case of a UDP packet we received a probing packet. 75 | * This probing causes a state change to infected if we 76 | * were just vulnerable till now. 77 | * 78 | * @param msg Received message 79 | */ 80 | void UDPWormVictim::handleMessage(cMessage *msg) 81 | { 82 | if (msg->isSelfMessage()) 83 | { 84 | // time to send the probing packet 85 | if (maxProbingPackets != 0) 86 | { 87 | if (maxProbingPackets > 0) 88 | maxProbingPackets--; 89 | 90 | scheduleAt(simTime() + probingDelay, msg); 91 | sendProbingPacket(); 92 | } 93 | } 94 | else if (dynamic_cast (msg)) 95 | { 96 | cPacket *packet = (UDPPacket*) msg; 97 | if (isActive) 98 | { 99 | delete packet; 100 | return; 101 | } 102 | if (dynamic_cast (packet->getEncapsulatedMsg())) 103 | { 104 | isActive = true; 105 | 106 | // now i'm an active worm and start probing 107 | cout << "Worm at " << getFullPath() << " now active" << endl; 108 | 109 | scheduleAt(simTime() + probingDelay, probingTimer); 110 | } 111 | delete packet; 112 | } 113 | else 114 | delete msg; 115 | } 116 | 117 | /** 118 | * Create a probing packet and send it to a random host within the 119 | * probing address range. 120 | * Probing packet is encapsulated into a UDP packet. 121 | */ 122 | void UDPWormVictim::sendProbingPacket() 123 | { 124 | IPvXAddress targetAddr; 125 | UDPWormQueryMessage *probing = new UDPWormQueryMessage("probing"); 126 | 127 | probing->setByteLength(packetLength); 128 | targetAddr.set(intuniform(addrStart.get4().getInt(), addrEnd.get4().getInt(), 4)); 129 | probing->setKind(UDP_I_DATA); 130 | 131 | UDPPacket *udpPacket = new UDPPacket("worm_udp"); 132 | udpPacket->setByteLength(UDP_HEADER_BYTES); 133 | udpPacket->encapsulate(probing); 134 | udpPacket->setSourcePort(sourcePort); 135 | udpPacket->setDestinationPort(victimPort); 136 | 137 | if (!targetAddr.isIPv6()) 138 | { 139 | IPControlInfo_hacked *ctrl = new IPControlInfo_hacked(); 140 | ctrl->setProtocol(IP_PROT_UDP); 141 | ctrl->setSrcAddr(IPvXAddress().get4()); 142 | ctrl->setDestAddr(targetAddr.get4()); 143 | ctrl->setAttackTag(attackTag); 144 | udpPacket->setControlInfo(ctrl); 145 | send(udpPacket, "ipOut"); 146 | } 147 | else 148 | { 149 | IPv6ControlInfo_hacked *ctrl = new IPv6ControlInfo_hacked(); 150 | ctrl->setProtocol(IP_PROT_UDP); 151 | ctrl->setSrcAddr(IPvXAddress().get6()); 152 | ctrl->setDestAddr(targetAddr.get6()); 153 | ctrl->setAttackTag(attackTag); 154 | udpPacket->setControlInfo(ctrl); 155 | send(udpPacket, "to_ipv6_udp"); 156 | } 157 | } 158 | 159 | -------------------------------------------------------------------------------- /src/applications/worm/UDPWormVictim.h: -------------------------------------------------------------------------------- 1 | #ifndef UDPWORMVICTIM_H_ 2 | #define UDPWORMVICTIM_H_ 3 | 4 | #include 5 | #include "IPvXAddress.h" 6 | #include "UDPSocket.h" 7 | #include "ReaSEDefs.h" 8 | 9 | const int FIRST_ATTACK_ID_OF_WORM_SPREAD = 10000; 10 | 11 | /** 12 | * @brief This class implements a generator for a worm propagation. 13 | * 14 | * The infected hosts start sending probing packets to random addresses 15 | * of the given address range. If another UDPWormVictim, that is not yet 16 | * infected, receives such a probing packet it switches its state to 17 | * infected and starts itself sending probing packets. Having sent a 18 | * maximum number of probing packets, the host switch to inactive. 19 | * 20 | * @class UDPWormVictim 21 | */ 22 | class REASE_API UDPWormVictim : public cSimpleModule 23 | { 24 | protected: 25 | /// Fixed inter-packet delay for subsequent probing packets 26 | double probingDelay; 27 | /// Maximum number of probing packets sent by an infected host 28 | int maxProbingPackets; 29 | /// IP address range used for probing packets 30 | /// @{ 31 | IPvXAddress addrStart, addrEnd; 32 | /// @} 33 | /// Source port of probing packets 34 | int sourcePort; 35 | /// Destination port of probing packets 36 | int victimPort; 37 | /// Timer message indicating that a probing packet should be sent 38 | cMessage *probingTimer; 39 | /// Start time of worm propagation 40 | double startTime; 41 | /// Indicates if the host is already infected or just vulnerable 42 | bool isActive; 43 | /// Tag of this attack that identifies probing packets 44 | int attackTag; 45 | /// Length of probing packets 46 | int packetLength; 47 | 48 | public: 49 | UDPWormVictim(); 50 | virtual ~UDPWormVictim(); 51 | 52 | protected: 53 | virtual int numInitStages() const{return 4; }; 54 | /// @brief Decide if initially infected or just vulnerable 55 | virtual void initialize(int stages); 56 | /// @brief Send new own probing packet or received a probing packet 57 | virtual void handleMessage(cMessage *msg); 58 | /// @brief Actually send a probing packet 59 | void sendProbingPacket(); 60 | }; 61 | 62 | #endif /*UDPWORMVICTIM_H_*/ 63 | -------------------------------------------------------------------------------- /src/applications/worm/UDPWormVictim.ned: -------------------------------------------------------------------------------- 1 | package scadasim.applications.worm; 2 | 3 | 4 | // 5 | // This simple module implements a generator for a worm propagation. 6 | // The infected hosts start sending probing packets to random addresses 7 | // of the given address range. If another UDPWormVictim, that is not yet 8 | // infected, receives such a probing packet it switches its state to 9 | // infected and starts itself sending probing packets. Having sent a 10 | // maximum number of probing packets, the host switch to inactive. 11 | // 12 | simple UDPWormVictim 13 | 14 | { 15 | parameters: 16 | double timeBetweenProbingPackets @unit(s); 17 | int attackTag; 18 | int maxProbingPackets; 19 | int sourcePort; 20 | int listenAndVictimPort; 21 | string addressRangeStart; 22 | string addressRangeEnd; 23 | double startProbing @unit(s); 24 | double startProbingDiff @unit(s); 25 | double startProbingProbability; 26 | int probingPacketLength @unit(B); 27 | 28 | gates: 29 | input ipIn; 30 | output ipOut; 31 | } 32 | -------------------------------------------------------------------------------- /src/base/ConnectionManager.ned: -------------------------------------------------------------------------------- 1 | package scadasim.base; 2 | 3 | // 4 | // Simple module for connection manager 5 | // This manager is responsible for requesting traffic profiles and 6 | // server connection endpoints. 7 | // 8 | simple ConnectionManager 9 | { 10 | parameters: 11 | // 12 | // Duration of the simlation run 13 | // 14 | double simulationDuration @unit(s); 15 | } 16 | -------------------------------------------------------------------------------- /src/base/DebugUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUGUTIL_H_ 2 | #define DEBUGUTIL_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /** 9 | * @brief Sets current debug level of ReaSE 10 | * 11 | * The higher the level the more debug output is generated. 12 | * Maximum level: 2, minimum level: 0 (no debug output). 13 | */ 14 | #define DEBUG_LEVEL 2 15 | 16 | #if DEBUG_LEVEL == 2 17 | 18 | /// Call this method to generate detailed debugging output 19 | void debug2(const char *fmt, ...) 20 | { 21 | char buf[1024]; 22 | int n; 23 | va_list args; 24 | va_start(args, fmt); 25 | n = vsprintf(buf, fmt, args); 26 | va_end(args); 27 | std::cerr< 5 | #include 6 | #include "TransmissionConfig.h" 7 | #include "ModuleAccess.h" 8 | #include "ReaSEDefs.h" 9 | 10 | /** 11 | * @brief Manages available traffic profiles and randomly selects one for 12 | * the next client/server communication. 13 | * 14 | * The traffic profile manager reads all available traffic profiles from 15 | * a configuration file and returns a random traffic profile if requested. 16 | * In addition it decides if the server communication endpoints lies in 17 | * the current AS or in a foreign AS. 18 | * 19 | * @class TrafficProfileManager 20 | */ 21 | class REASE_API TrafficProfileManager : public cSimpleModule 22 | { 23 | private: 24 | /// Vector of available traffic profiles 25 | std::vector profiles; 26 | 27 | public: 28 | TrafficProfileManager(); 29 | virtual ~TrafficProfileManager(); 30 | /// Returns a random traffic profile 31 | void getTrafficProfile(TrafficProfile &t, double profileProb, double foreignServerProb, bool &isForeign); 32 | /// Returns a fix traffic profile 33 | void getFixTrafficProfile(TrafficProfile &t, bool &isForeign); 34 | 35 | protected: 36 | /// Sets initialization stage to 1 37 | virtual int numInitStages() const { return 1; }; 38 | /// Reads available profiles from config file 39 | virtual void initialize(int stages); 40 | /// No message handling is supported 41 | virtual void handleMessage(cMessage *msg); 42 | }; 43 | 44 | 45 | /** 46 | * @brief Gives access to the TrafficProfileManager instance. 47 | * 48 | * @class TrafficProfileManagerAccess 49 | */ 50 | class REASE_API TrafficProfileManagerAccess : public ModuleAccess 51 | { 52 | public: 53 | TrafficProfileManagerAccess() : ModuleAccess("trafficProfileManager"){}; 54 | }; 55 | 56 | 57 | #endif /*TRAFFICPROFILEMANAGER_H_*/ 58 | -------------------------------------------------------------------------------- /src/base/TrafficProfileManager.ned: -------------------------------------------------------------------------------- 1 | package scadasim.base; 2 | 3 | // 4 | // Defines simple module for implementation of traffic profile manager. 5 | // The traffic profile manager reads all available traffic profiles from 6 | // a configuration file and returns a random traffic profile if requested. 7 | // In addition it decides if the server communication endpoints lies in 8 | // the current AS or in a foreign AS. 9 | // 10 | simple TrafficProfileManager 11 | { 12 | parameters: 13 | // name of the config file containing availabe traffic profiles 14 | string configFileName; 15 | } 16 | -------------------------------------------------------------------------------- /src/external/ModbusGate.cc: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | /* 16 | * ModbusGate.cpp 17 | * 18 | * Created on: 09/05/2011 19 | * Author: cax 20 | */ 21 | 22 | #include "ModbusGate.h" 23 | 24 | ModbusGate::ModbusGate() : 25 | SSGate() { 26 | port = 1502; 27 | modbus_init_tcp(&mb_param, "localhost", port); 28 | modbus_set_debug(&mb_param, FALSE); 29 | bool ret = modbus_mapping_new(&mb_mapping, 500, 500, 500, 500); 30 | if (ret == FALSE) { 31 | printf("Memory allocation failed\n"); 32 | exit(1); 33 | } 34 | cout << "modbus db initialised" << endl; 35 | } 36 | 37 | ModbusGate::~ModbusGate() { 38 | modbus_mapping_free(&mb_mapping); 39 | modbus_close(&mb_param); 40 | cout << "modbus memory freed" << endl; 41 | } 42 | 43 | void ModbusGate::Open() { 44 | cout << "just got started" << endl; 45 | start(NULL); 46 | cout << "thread created." << endl; 47 | } 48 | void ModbusGate::execute(void * arg) { 49 | 50 | this->listen(); 51 | } 52 | 53 | void ModbusGate::processMessage(ssMsg * msg) { 54 | SSGate::processMessage(msg); 55 | 56 | } 57 | 58 | void ModbusGate::listen() { 59 | struct sockaddr_in addr; 60 | socklen_t addrlen; 61 | 62 | addr.sin_family = AF_INET; 63 | /* If the modbus port is < to 1024, we need the setuid root. */ 64 | addr.sin_port = htons(mb_param.port); 65 | addr.sin_addr.s_addr = INADDR_ANY; 66 | memset(&(addr.sin_zero), '\0', 8); 67 | addrlen = sizeof(struct sockaddr_in); 68 | 69 | socket_conn = modbus_init_listen_tcp(&mb_param); 70 | if (socket_conn) { 71 | while (1) { 72 | uint8_t query[MAX_MESSAGE_LENGTH]; 73 | int query_size; 74 | 75 | int ret = modbus_listen(&mb_param, query, &query_size); 76 | if (ret == 0) { 77 | ssMsg msg; 78 | msg.extAddress = mb_param.remote_ip; 79 | msg.payload = query; 80 | processMessage(&msg); 81 | modbus_manage_query(&mb_param, query, query_size, &mb_mapping); 82 | } else if (ret == CONNECTION_CLOSED) { 83 | /* Connection closed by the client, end of server */ 84 | mb_param.fd = accept(socket_conn, (struct sockaddr *) &addr, 85 | &addrlen); 86 | if (mb_param.fd < 0) { 87 | perror("accept"); 88 | close(socket_conn); 89 | socket_conn = 0; 90 | break; 91 | } else { 92 | printf("The client %s is connected\n", 93 | inet_ntoa(addr.sin_addr)); 94 | } 95 | 96 | } else { 97 | printf("Error in modbus_listen (%d)\n", ret); 98 | } 99 | } 100 | } 101 | 102 | } 103 | 104 | void ModbusGate::Close() { 105 | cout << "stop just got called" << endl; 106 | join(); 107 | cout << "thread finished" << endl; 108 | //close(socket_conn); 109 | } 110 | -------------------------------------------------------------------------------- /src/external/ModbusGate.h: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | /* 16 | * ModbusGate.h 17 | * 18 | * Created on: 09/05/2011 19 | * Author: cax 20 | */ 21 | 22 | #ifndef MODBUSGATE_H_ 23 | #define MODBUSGATE_H_ 24 | #include "modbus.h" 25 | #include "SSGate.h" 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | class ModbusGate: public SSGate { 37 | 38 | private: 39 | int socket_conn; 40 | modbus_param_t mb_param; 41 | modbus_mapping_t mb_mapping; 42 | 43 | void listen(); 44 | 45 | 46 | protected: 47 | virtual void execute(void * arg_); 48 | 49 | public: 50 | ModbusGate(); 51 | virtual ~ModbusGate(); 52 | virtual void processMessage(ssMsg *msg); 53 | virtual void Open(); 54 | virtual void Close(); 55 | 56 | }; 57 | 58 | #endif /* MODBUSGATE_H_ */ 59 | -------------------------------------------------------------------------------- /src/external/SSGate.cc: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | #include "SSGate.h" 17 | #include "SSScheduler.h" 18 | 19 | SSGate::SSGate() { 20 | cout << "Hi gate" << endl; 21 | scheduler = check_and_cast (simulation.getScheduler()); 22 | } 23 | 24 | SSGate::~SSGate() { 25 | cout << "Bye gate" << endl; 26 | } 27 | 28 | SSProxy *SSGate::getProxyDestination(const char * extAddress) { 29 | vector::iterator iter; 30 | 31 | for (iter = proxies.begin(); iter != proxies.end(); ++iter) { 32 | 33 | const char * extAddr = (*iter)->getExtAddress(); 34 | if (strcmp(extAddr, extAddress) == 0) { 35 | return *iter; 36 | } 37 | } 38 | return NULL; 39 | } 40 | 41 | int SSGate::nextMessage(long ms) { 42 | 43 | SSThread::lock(); 44 | int retcode; 45 | if (!nextMsg) { 46 | retcode = SSThread::wait(ms); 47 | } 48 | 49 | nextMsg = false; 50 | SSThread::notify(); 51 | SSThread::unlock(); 52 | return retcode; 53 | } 54 | void SSGate::nextMessage() { 55 | SSThread::lock(); 56 | if (!nextMsg) { 57 | SSThread::wait(); 58 | } 59 | nextMsg = false; 60 | SSThread::notify(); 61 | SSThread::unlock(); 62 | } 63 | 64 | void SSGate::proxyBinding(SSProxy *proxy) { 65 | proxies.push_back(proxy); 66 | cout << "proxy added" << endl; 67 | } 68 | 69 | void SSGate::processMessage(ssMsg *msg) { 70 | SSThread::lock(); 71 | if (nextMsg) { 72 | SSThread::wait(); 73 | } 74 | SSProxy *dest = getProxyDestination(msg->extAddress); 75 | if (dest != NULL) { 76 | timeval curTime; 77 | gettimeofday(&curTime, NULL); 78 | curTime = timeval_substract(curTime, scheduler->getBaseTime()); 79 | simtime_t t = curTime.tv_sec + curTime.tv_usec * 1e-6; 80 | cMessage *notificationMsg = dest->getNotificationMsg(); 81 | 82 | notificationMsg->setArrival(dest, -1, t); 83 | 84 | simulation.msgQueue.insert(notificationMsg); 85 | nextMsg = true; 86 | SSThread::notify(); 87 | 88 | //notify 89 | } 90 | SSThread::unlock(); 91 | // TBD assert that it's somehow not smaller than previous event's time 92 | // notificationMsg->setArrival(module, -1, t); 93 | // simulation.msgQueue.insert(notificationMsg); 94 | } 95 | -------------------------------------------------------------------------------- /src/external/SSGate.h: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | #ifndef SSGATE_H_ 17 | #define SSGATE_H_ 18 | #include 19 | #include "SSProxy.h" 20 | #include "SSThread.h" 21 | #include 22 | #include 23 | using namespace std; 24 | class SSScheduler; 25 | 26 | struct ssMsg { 27 | void * payload; 28 | char * extAddress; 29 | }; 30 | 31 | class SSGate: public SSThread { 32 | 33 | private: 34 | 35 | SSScheduler *scheduler; 36 | 37 | protected: 38 | int port; 39 | 40 | vector proxies; 41 | SSProxy *getProxyDestination(const char * extAddress); 42 | public: 43 | 44 | SSGate(); 45 | 46 | virtual ~SSGate(); 47 | 48 | virtual void proxyBinding(SSProxy *proxy); 49 | 50 | virtual void Open() = 0; 51 | 52 | virtual void Close() = 0; 53 | virtual void processMessage(ssMsg *msg); 54 | 55 | void nextMessage(); 56 | int nextMessage(long ms); 57 | }; 58 | 59 | #endif /* SSGATE_H_ */ 60 | -------------------------------------------------------------------------------- /src/external/SSProxy.cc: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | /* 17 | * SSProxy.cpp 18 | * 19 | * Created on: 21/04/2011 20 | * Author: cax 21 | */ 22 | 23 | #include "SSProxy.h" 24 | #include "SSScheduler.h" 25 | 26 | Define_Module(SSProxy); 27 | 28 | SSProxy::SSProxy() { 29 | 30 | } 31 | 32 | SSProxy::~SSProxy() { 33 | // TODO Auto-generated destructor stub 34 | } 35 | 36 | void SSProxy::initialize(){ 37 | extAddress = par("extAddress"); 38 | notificationMsg = new cMessage(extAddress); 39 | SSScheduler *ssScheduler = check_and_cast (simulation.getScheduler()); 40 | gate = ssScheduler->getGateway(0); 41 | gate->proxyBinding(this); 42 | } 43 | 44 | const char * SSProxy::getExtAddress(){ 45 | return extAddress; 46 | } 47 | void SSProxy::setGate(SSGate *gate){ 48 | this->gate = gate; 49 | } 50 | 51 | cMessage * SSProxy::getNotificationMsg(){ 52 | return notificationMsg; 53 | } 54 | 55 | void SSProxy::handleMessage(cMessage *msg){ 56 | 57 | if(msg==notificationMsg){ 58 | cMessage *msg0 = new cMessage("sender"); 59 | send(msg0,"out"); 60 | }else{ 61 | cout << "msg received from : " << msg << endl; 62 | delete msg; 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /src/external/SSProxy.h: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | /* 17 | * SSProxy.h 18 | * 19 | * Created on: 21/04/2011 20 | * Author: cax 21 | */ 22 | 23 | #ifndef SSPROXY_H_ 24 | #define SSPROXY_H_ 25 | #include 26 | 27 | 28 | class SSGate; 29 | 30 | class SSProxy : public cSimpleModule{ 31 | 32 | private: 33 | SSGate *gate; 34 | cMessage *notificationMsg; 35 | const char *extAddress; 36 | 37 | protected: 38 | 39 | virtual void initialize(); 40 | virtual void handleMessage(cMessage *msg); 41 | 42 | public: 43 | SSProxy(); 44 | virtual ~SSProxy(); 45 | 46 | virtual void setGate(SSGate *gate); 47 | virtual cMessage * getNotificationMsg(); 48 | const char * getExtAddress(); 49 | }; 50 | 51 | #endif /* SSPROXY_H_ */ 52 | -------------------------------------------------------------------------------- /src/external/SSProxy.ned: -------------------------------------------------------------------------------- 1 | package scadasim.external; 2 | 3 | simple SSProxy 4 | { 5 | parameters: 6 | string extAddress; 7 | // double aDelay; 8 | // volatile double serviceTime @unit(s); 9 | // volatile double sendIaTime @unit(s); 10 | @display("i=device/server2"); 11 | gates: 12 | input in; 13 | output out; 14 | } 15 | -------------------------------------------------------------------------------- /src/external/SSScheduler.cc: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | // 17 | // SSScheduler.cpp 18 | // RTScheduler 19 | // 20 | // Created by caxq on 11/05/11. 21 | // Copyright 2011 Carlos Queiroz. All rights reserved. 22 | // 23 | 24 | #include "SSScheduler.h" 25 | 26 | Register_Class(SSScheduler) 27 | ; 28 | 29 | SSScheduler::SSScheduler() { 30 | 31 | } 32 | 33 | SSScheduler::~SSScheduler() { 34 | // TODO Auto-generated destructor stub 35 | } 36 | 37 | void SSScheduler::startRun() { 38 | ModbusGate *gate; 39 | gate = new ModbusGate; 40 | gates.push_back(gate); 41 | gettimeofday(&baseTime, NULL); 42 | cout << "SSScheduler started at " << baseTime.tv_sec << endl; 43 | setupConnector(); 44 | } 45 | 46 | void SSScheduler::setupConnector() { 47 | vector::iterator iter; 48 | for (iter = gates.begin(); iter != gates.end(); ++iter) { 49 | (*iter)->Open(); 50 | } 51 | } 52 | 53 | void SSScheduler::executionResumed() { 54 | gettimeofday(&baseTime, NULL); 55 | baseTime = timeval_substract(baseTime, SIMTIME_DBL(simTime())); 56 | } 57 | 58 | void SSScheduler::endRun() { 59 | vector::iterator iter; 60 | for (iter = gates.begin(); iter != gates.end(); ++iter) { 61 | (*iter)->Close(); 62 | delete (*iter); 63 | } 64 | } 65 | 66 | timeval SSScheduler::getBaseTime() { 67 | return baseTime; 68 | } 69 | 70 | int SSScheduler::receiveUntil(const timeval& targetTime) { 71 | // if there's more than 200ms to wait, wait in 100ms chunks 72 | // in order to keep UI responsiveness by invoking ev.idle() 73 | timeval curTime; 74 | gettimeofday(&curTime, NULL); 75 | while (targetTime.tv_sec - curTime.tv_sec >= 2 || timeval_diff_usec(targetTime, curTime) >= 200000) { 76 | vector::iterator iter; 77 | for (iter = gates.begin(); iter != gates.end(); ++iter) { 78 | int retcode =(*iter)->nextMessage(100); //100 ms 79 | if (retcode == 0) 80 | return 1; 81 | } 82 | if (ev.idle()) 83 | return -1; 84 | gettimeofday(&curTime, NULL); 85 | } 86 | 87 | // difference is now at most 100ms, do it at once 88 | long usec = timeval_diff_usec(targetTime, curTime); 89 | if (usec > 0) { 90 | vector::iterator iter; 91 | for (iter = gates.begin(); iter != gates.end(); ++iter) { 92 | if((*iter)->nextMessage(usec) == 0); 93 | return 1; 94 | } 95 | } 96 | return 0; 97 | } 98 | 99 | cMessage *SSScheduler::getNextEvent() { 100 | //cout << "getNextEvent" << endl; 101 | //assert that we've been configured 102 | if (gates.size() == 0) 103 | throw cRuntimeError( 104 | "SSScheduler: setGate() not called: it must be called from a module's initialize() function"); 105 | 106 | // // calculate target time 107 | timeval targetTime; 108 | cMessage *msg = sim->msgQueue.peekFirst(); 109 | if (!msg) { 110 | // if there are no events, wait until something comes from outside 111 | // TBD: obey simtimelimit, cpu-time-limit 112 | targetTime.tv_sec = LONG_MAX; 113 | targetTime.tv_usec = 0; 114 | } else { 115 | // use time of next event 116 | simtime_t eventSimtime = msg->getArrivalTime(); 117 | targetTime = timeval_add(baseTime, SIMTIME_DBL(eventSimtime)); 118 | } 119 | //cout << "getting here" << endl; 120 | // 121 | // if needed, wait until that time arrives 122 | timeval curTime; 123 | gettimeofday(&curTime, NULL); 124 | if (timeval_greater(targetTime, curTime)) { 125 | int status = receiveUntil(targetTime); 126 | if (status == -1) 127 | return NULL; // interrupted by user 128 | if (status == 1) 129 | msg = sim->msgQueue.peekFirst(); // received something 130 | } else { 131 | // we're behind -- customized versions of this class may 132 | // alert if we're too much behind, whatever that means 133 | cout << "------ very behind -----" << endl; 134 | } 135 | 136 | // ok, return the message 137 | return msg; 138 | } 139 | 140 | SSGate *SSScheduler::getGateway(int gateType) { 141 | return gates[gateType]; 142 | } 143 | 144 | -------------------------------------------------------------------------------- /src/external/SSScheduler.h: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | // 17 | // SSScheduler.h 18 | // RTScheduler 19 | // 20 | // Created by cq on 11/05/11. 21 | // Copyright 2011 Carlos Queiroz. All rights reserved. 22 | // 23 | 24 | #ifndef SSSCHEDULER_H_ 25 | #define SSSCHEDULER_H_ 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "SSGate.h" 31 | #include "ModbusGate.h" 32 | #include 33 | 34 | using namespace std; 35 | 36 | class SSScheduler : public cScheduler{ 37 | 38 | private: 39 | vector gates; 40 | timeval baseTime; 41 | virtual void setupConnector(); 42 | // virtual bool receiveWithTimeout(long usec); 43 | virtual int receiveUntil(const timeval& targetTime); 44 | 45 | public: 46 | SSScheduler(); 47 | virtual ~SSScheduler(); 48 | 49 | /** 50 | * Called at the beginning of a simulation run. 51 | */ 52 | virtual void startRun(); 53 | 54 | /** 55 | * Called at the end of a simulation run. 56 | */ 57 | virtual void endRun(); 58 | 59 | /** 60 | * Recalculates "base time" from current wall clock time. 61 | */ 62 | virtual void executionResumed(); 63 | 64 | /** 65 | * To be called from the module which wishes to receive data from the 66 | * socket. The method must be called from the module's initialize() 67 | * function. 68 | */ 69 | // virtual void setInterfaceModule(cModule *module, cMessage *notificationMsg, 70 | // uint8_t *recvBuffer, int recvBufferSize, int *numBytesPtr); 71 | 72 | /** 73 | * Scheduler function -- it comes from cScheduler interface. 74 | */ 75 | virtual cMessage *getNextEvent(); 76 | 77 | /** 78 | * Send on the currently open connection 79 | */ 80 | //virtual void sendBytes(uint8_t * buf, size_t numBytes); 81 | 82 | virtual SSGate *getGateway(int gateType); 83 | virtual timeval getBaseTime(); 84 | }; 85 | 86 | #endif /* SSSCHEDULER_H_ */ 87 | 88 | -------------------------------------------------------------------------------- /src/external/SSThread.cc: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | /* 16 | * SSThread.cpp 17 | * 18 | * Created on: May 13, 2011 19 | * Author: root 20 | */ 21 | 22 | #include "SSThread.h" 23 | 24 | SSThread::SSThread() { 25 | 26 | } 27 | 28 | SSThread::~SSThread() { 29 | // TODO Auto-generated destructor stub 30 | } 31 | 32 | int SSThread::start(void * arg_) { 33 | arg(arg_); 34 | 35 | int code = pthread_create(&thread, 0, &SSThread::entryPoint, this); 36 | 37 | return code; 38 | } 39 | 40 | void SSThread::run(void * arg_) { 41 | setup(); 42 | execute(arg_); 43 | } 44 | 45 | /*static */ 46 | void * SSThread::entryPoint(void * pthis) { 47 | SSThread * pt = (SSThread*) pthis; 48 | pt->run(pt->arg()); 49 | return NULL; 50 | } 51 | 52 | int SSThread::wait() { 53 | return pthread_cond_wait(&cond, &mutex); 54 | } 55 | 56 | int SSThread::wait(long ms) { 57 | timeval now; 58 | timespec timeout; 59 | gettimeofday(&now, NULL); 60 | TIMEVAL_TO_TIMESPEC(&now, &timeout); 61 | if (ms > 1000) { 62 | timeout.tv_sec = timeout.tv_sec + (ms / 1000); 63 | timeout.tv_nsec = timeout.tv_nsec + ((ms % 1000) * 1000000); 64 | } else{ 65 | timeout.tv_nsec = timeout.tv_nsec + (ms * 1000000); 66 | } 67 | return pthread_cond_timedwait(&cond, &mutex, &timeout); 68 | } 69 | 70 | int SSThread::notify() { 71 | return pthread_cond_signal(&cond); 72 | } 73 | 74 | int SSThread::lock() { 75 | return pthread_mutex_lock(&mutex); 76 | } 77 | int SSThread::unlock() { 78 | return pthread_mutex_unlock(&mutex); 79 | } 80 | 81 | void SSThread::setup() { 82 | nextMsg = false; 83 | if (pthread_mutex_init(&mutex, NULL) != 0) { 84 | cout << "error initialising mutex" << endl; 85 | } 86 | if (pthread_cond_init(&cond, NULL) != 0) { 87 | cout << "error initialising cond" << endl; 88 | } 89 | 90 | } 91 | 92 | void SSThread::execute(void* arg) { 93 | // Your code goes here 94 | } 95 | 96 | int SSThread::join() { 97 | return pthread_join(thread, NULL); 98 | } 99 | -------------------------------------------------------------------------------- /src/external/SSThread.h: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | /* 16 | * Implementation is based on the following article: 17 | * http://www.linuxselfhelp.com/HOWTO/C++Programming-HOWTO-18.html 18 | * 19 | * SSThread.h 20 | * 21 | * Created on: May 13, 2011 22 | * Author: root 23 | */ 24 | 25 | #ifndef SSTHREAD_H_ 26 | #define SSTHREAD_H_ 27 | #include 28 | #include 29 | #include 30 | 31 | using namespace std; 32 | 33 | class SSThread { 34 | 35 | private: 36 | void * arg_; 37 | pthread_t thread; 38 | pthread_cond_t cond; 39 | pthread_mutex_t mutex; 40 | 41 | 42 | protected: 43 | bool nextMsg; 44 | void run(void * arg); 45 | static void * entryPoint(void*); 46 | virtual void setup(); 47 | virtual void execute(void*); 48 | int lock(); 49 | int unlock(); 50 | void * arg() const { 51 | return arg_; 52 | } 53 | void arg(void* a) { 54 | arg_ = a; 55 | } 56 | public: 57 | SSThread(); 58 | virtual ~SSThread(); 59 | int start(void * arg_); 60 | int join(); 61 | int wait(); 62 | int wait(long ms); 63 | int notify(); 64 | 65 | }; 66 | 67 | #endif /* SSTHREAD_H_ */ 68 | -------------------------------------------------------------------------------- /src/networklayer/autorouting/TGMNetworkConfigurator.ned: -------------------------------------------------------------------------------- 1 | package scadasim.networklayer.autorouting; 2 | 3 | // 4 | // This simple module is responsible for configuration of the simulated 5 | // topology, i.e. assignment of IP addresses to all nodes of the topology. 6 | // Furthermore, routing tables have to be filled and default routing 7 | // paths must be created. 8 | // Routing is separated into Intra-AS and Inter-AS routing. 9 | // 10 | simple TGMNetworkConfigurator 11 | { 12 | parameters: 13 | int totalCountOfAS; 14 | } 15 | -------------------------------------------------------------------------------- /src/networklayer/contract/IPControlInfo_hacked.msg: -------------------------------------------------------------------------------- 1 | cplusplus {{ 2 | #include "IPControlInfo.h" 3 | #include "ReaSEDefs.h" 4 | }} 5 | 6 | class noncobject IPControlInfo; 7 | 8 | class IPControlInfo_hacked extends IPControlInfo 9 | { 10 | // ReaSE: for attack tracing, each IP packet contains an attackTag 11 | short attackTag = 0; 12 | } 13 | -------------------------------------------------------------------------------- /src/networklayer/contract/IPControlInfo_hacked_m.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file, do not edit! Created by opp_msgc 4.2 from networklayer/contract/IPControlInfo_hacked.msg. 3 | // 4 | 5 | #ifndef _IPCONTROLINFO_HACKED_M_H_ 6 | #define _IPCONTROLINFO_HACKED_M_H_ 7 | 8 | #include 9 | 10 | // opp_msgc version check 11 | #define MSGC_VERSION 0x0402 12 | #if (MSGC_VERSION!=OMNETPP_VERSION) 13 | # error Version mismatch! Probably this file was generated by an earlier version of opp_msgc: 'make clean' should help. 14 | #endif 15 | 16 | // dll export symbol 17 | #ifndef SCADASim_API 18 | # if defined(SCADASim_EXPORT) 19 | # define SCADASim_API OPP_DLLEXPORT 20 | # elif defined(SCADASim_IMPORT) 21 | # define SCADASim_API OPP_DLLIMPORT 22 | # else 23 | # define SCADASim_API 24 | # endif 25 | #endif 26 | 27 | // cplusplus {{ 28 | #include "IPControlInfo.h" 29 | #include "ReaSEDefs.h" 30 | // }} 31 | 32 | 33 | 34 | /** 35 | * Class generated from networklayer/contract/IPControlInfo_hacked.msg by opp_msgc. 36 | *
37 |  * class IPControlInfo_hacked extends IPControlInfo
38 |  * {
39 |  * 	
40 |  * 	short attackTag = 0;
41 |  * }
42 |  * 
43 | */ 44 | class SCADASim_API IPControlInfo_hacked : public ::IPControlInfo 45 | { 46 | protected: 47 | short attackTag_var; 48 | 49 | // protected and unimplemented operator==(), to prevent accidental usage 50 | bool operator==(const IPControlInfo_hacked&); 51 | 52 | public: 53 | IPControlInfo_hacked(); 54 | IPControlInfo_hacked(const IPControlInfo_hacked& other); 55 | virtual ~IPControlInfo_hacked(); 56 | IPControlInfo_hacked& operator=(const IPControlInfo_hacked& other); 57 | virtual IPControlInfo_hacked *dup() const {return new IPControlInfo_hacked(*this);} 58 | virtual void parsimPack(cCommBuffer *b); 59 | virtual void parsimUnpack(cCommBuffer *b); 60 | 61 | // field getter/setter methods 62 | virtual short getAttackTag() const; 63 | virtual void setAttackTag(short attackTag); 64 | }; 65 | 66 | inline void doPacking(cCommBuffer *b, IPControlInfo_hacked& obj) {obj.parsimPack(b);} 67 | inline void doUnpacking(cCommBuffer *b, IPControlInfo_hacked& obj) {obj.parsimUnpack(b);} 68 | 69 | 70 | #endif // _IPCONTROLINFO_HACKED_M_H_ 71 | -------------------------------------------------------------------------------- /src/networklayer/contract/IPv6ControlInfo_hacked.msg: -------------------------------------------------------------------------------- 1 | cplusplus {{ 2 | #include "IPv6ControlInfo.h" 3 | #include "ReaSEDefs.h" 4 | }} 5 | 6 | class noncobject IPv6ControlInfo; 7 | 8 | class IPv6ControlInfo_hacked extends IPv6ControlInfo 9 | { 10 | // ReaSE: for attack tracing, each IP packet contains an attackTag 11 | short attackTag = 0; 12 | } 13 | -------------------------------------------------------------------------------- /src/networklayer/contract/IPv6ControlInfo_hacked_m.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file, do not edit! Created by opp_msgc 4.2 from networklayer/contract/IPv6ControlInfo_hacked.msg. 3 | // 4 | 5 | #ifndef _IPV6CONTROLINFO_HACKED_M_H_ 6 | #define _IPV6CONTROLINFO_HACKED_M_H_ 7 | 8 | #include 9 | 10 | // opp_msgc version check 11 | #define MSGC_VERSION 0x0402 12 | #if (MSGC_VERSION!=OMNETPP_VERSION) 13 | # error Version mismatch! Probably this file was generated by an earlier version of opp_msgc: 'make clean' should help. 14 | #endif 15 | 16 | // dll export symbol 17 | #ifndef SCADASim_API 18 | # if defined(SCADASim_EXPORT) 19 | # define SCADASim_API OPP_DLLEXPORT 20 | # elif defined(SCADASim_IMPORT) 21 | # define SCADASim_API OPP_DLLIMPORT 22 | # else 23 | # define SCADASim_API 24 | # endif 25 | #endif 26 | 27 | // cplusplus {{ 28 | #include "IPv6ControlInfo.h" 29 | #include "ReaSEDefs.h" 30 | // }} 31 | 32 | 33 | 34 | /** 35 | * Class generated from networklayer/contract/IPv6ControlInfo_hacked.msg by opp_msgc. 36 | *
37 |  * class IPv6ControlInfo_hacked extends IPv6ControlInfo
38 |  * {
39 |  * 	
40 |  * 	short attackTag = 0;
41 |  * }
42 |  * 
43 | */ 44 | class SCADASim_API IPv6ControlInfo_hacked : public ::IPv6ControlInfo 45 | { 46 | protected: 47 | short attackTag_var; 48 | 49 | // protected and unimplemented operator==(), to prevent accidental usage 50 | bool operator==(const IPv6ControlInfo_hacked&); 51 | 52 | public: 53 | IPv6ControlInfo_hacked(); 54 | IPv6ControlInfo_hacked(const IPv6ControlInfo_hacked& other); 55 | virtual ~IPv6ControlInfo_hacked(); 56 | IPv6ControlInfo_hacked& operator=(const IPv6ControlInfo_hacked& other); 57 | virtual IPv6ControlInfo_hacked *dup() const {return new IPv6ControlInfo_hacked(*this);} 58 | virtual void parsimPack(cCommBuffer *b); 59 | virtual void parsimUnpack(cCommBuffer *b); 60 | 61 | // field getter/setter methods 62 | virtual short getAttackTag() const; 63 | virtual void setAttackTag(short attackTag); 64 | }; 65 | 66 | inline void doPacking(cCommBuffer *b, IPv6ControlInfo_hacked& obj) {obj.parsimPack(b);} 67 | inline void doUnpacking(cCommBuffer *b, IPv6ControlInfo_hacked& obj) {obj.parsimUnpack(b);} 68 | 69 | 70 | #endif // _IPV6CONTROLINFO_HACKED_M_H_ 71 | -------------------------------------------------------------------------------- /src/networklayer/ipv4/IPDatagram_hacked.msg: -------------------------------------------------------------------------------- 1 | cplusplus {{ 2 | #include "IPDatagram.h" 3 | #include "ReaSEDefs.h" 4 | }} 5 | 6 | packet IPDatagram; 7 | 8 | packet IPDatagram_hacked extends IPDatagram 9 | { 10 | // ReaSE: for attack tracing each IP packet contains an attackTag 11 | short attackTag = 0; 12 | } 13 | -------------------------------------------------------------------------------- /src/networklayer/ipv4/IPDatagram_hacked_m.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file, do not edit! Created by opp_msgc 4.2 from networklayer/ipv4/IPDatagram_hacked.msg. 3 | // 4 | 5 | #ifndef _IPDATAGRAM_HACKED_M_H_ 6 | #define _IPDATAGRAM_HACKED_M_H_ 7 | 8 | #include 9 | 10 | // opp_msgc version check 11 | #define MSGC_VERSION 0x0402 12 | #if (MSGC_VERSION!=OMNETPP_VERSION) 13 | # error Version mismatch! Probably this file was generated by an earlier version of opp_msgc: 'make clean' should help. 14 | #endif 15 | 16 | // dll export symbol 17 | #ifndef SCADASim_API 18 | # if defined(SCADASim_EXPORT) 19 | # define SCADASim_API OPP_DLLEXPORT 20 | # elif defined(SCADASim_IMPORT) 21 | # define SCADASim_API OPP_DLLIMPORT 22 | # else 23 | # define SCADASim_API 24 | # endif 25 | #endif 26 | 27 | // cplusplus {{ 28 | #include "IPDatagram.h" 29 | #include "ReaSEDefs.h" 30 | // }} 31 | 32 | 33 | 34 | /** 35 | * Class generated from networklayer/ipv4/IPDatagram_hacked.msg by opp_msgc. 36 | *
37 |  * packet IPDatagram_hacked extends IPDatagram
38 |  * {
39 |  * 	
40 |  * 	short attackTag = 0;
41 |  * }
42 |  * 
43 | */ 44 | class SCADASim_API IPDatagram_hacked : public ::IPDatagram 45 | { 46 | protected: 47 | short attackTag_var; 48 | 49 | // protected and unimplemented operator==(), to prevent accidental usage 50 | bool operator==(const IPDatagram_hacked&); 51 | 52 | public: 53 | IPDatagram_hacked(const char *name=NULL, int kind=0); 54 | IPDatagram_hacked(const IPDatagram_hacked& other); 55 | virtual ~IPDatagram_hacked(); 56 | IPDatagram_hacked& operator=(const IPDatagram_hacked& other); 57 | virtual IPDatagram_hacked *dup() const {return new IPDatagram_hacked(*this);} 58 | virtual void parsimPack(cCommBuffer *b); 59 | virtual void parsimUnpack(cCommBuffer *b); 60 | 61 | // field getter/setter methods 62 | virtual short getAttackTag() const; 63 | virtual void setAttackTag(short attackTag); 64 | }; 65 | 66 | inline void doPacking(cCommBuffer *b, IPDatagram_hacked& obj) {obj.parsimPack(b);} 67 | inline void doUnpacking(cCommBuffer *b, IPDatagram_hacked& obj) {obj.parsimUnpack(b);} 68 | 69 | 70 | #endif // _IPDATAGRAM_HACKED_M_H_ 71 | -------------------------------------------------------------------------------- /src/networklayer/ipv4/IP_hack.h: -------------------------------------------------------------------------------- 1 | #ifndef IP_HACK_H_ 2 | #define IP_HACK_H_ 3 | 4 | #include 5 | #include "IP.h" 6 | #include "IPDatagram_hacked_m.h" 7 | #include "ReaSEDefs.h" 8 | 9 | /** 10 | * @brief Extension of the original IP protocol. 11 | * 12 | * Extends the original IP protocol of INET by address spoofing and 13 | * packet tracing. 14 | * These tasks are necessary for simulation of attacks 15 | */ 16 | class REASE_API IP_hack : public IP 17 | { 18 | protected: 19 | // service flags 20 | bool tracingOn, spoofingAllowed; 21 | 22 | // statistics 23 | cOutVector output, tcpout, udpout, icmpout; 24 | 25 | // state 26 | bool startTrace; 27 | int totalTrace, udpTrace, tcpTrace, icmpTrace; 28 | int totalPackets, udpPackets, tcpPackets, icmpPackets; 29 | double traceInterval; 30 | cMessage *traceMsg; 31 | 32 | public: 33 | IP_hack(); 34 | virtual ~IP_hack(); 35 | /// Dispatch received message to correct handler 36 | virtual void endService(cPacket *msg); 37 | void finish(); 38 | protected: 39 | virtual void initialize(); 40 | /// Includes new feature: Address spoofing 41 | IPDatagram *encapsulate(cPacket *transportPacket, InterfaceEntry *&destIE); 42 | /// Outputs packet counts into vector file 43 | virtual void handleMessage(cMessage *msg); 44 | /// Handle messages from higher layers 45 | virtual void handleMessageFromHL(cPacket *msg); 46 | /// Handle messages from lower layers 47 | virtual void handlePacketFromNetwork(IPDatagram *datagram); 48 | /// Processing of IP options 49 | virtual void processPacket(IPDatagram *datagram, InterfaceEntry *destIE, bool fromHL, bool checkOpts); 50 | }; 51 | 52 | #endif /*IP_HACK_H_*/ 53 | -------------------------------------------------------------------------------- /src/networklayer/ipv4/IP_hack.ned: -------------------------------------------------------------------------------- 1 | package scadasim.networklayer.ipv4; 2 | 3 | import inet.networklayer.ipv4.IP; 4 | 5 | // 6 | // An extension of inet.networklayer.ipv4.IP 7 | // This module additionally allows for address spoofing and 8 | // packet tracing 9 | // 10 | 11 | simple IP_hack extends IP 12 | { 13 | parameters: 14 | @class(IP_hack); 15 | bool tracingOn; 16 | double tracingInterval @unit(s); 17 | double traceStartTime @unit(s); 18 | bool spoofingOn; // allow IP-Address Spoofing 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/networklayer/queue/DropTailTraceQueue.cc: -------------------------------------------------------------------------------- 1 | #include "DropTailTraceQueue.h" 2 | 3 | Define_Module( DropTailTraceQueue); 4 | 5 | /** 6 | * @brief Drop-tail queue with additional tracing support. 7 | * 8 | * Divides traffic into intervals of equal time-based sizes 9 | * and writes out the packet counts of different aggregates 10 | * observed in the last interval. 11 | * 12 | * @class DropTailTraceQueue 13 | */ 14 | 15 | void DropTailTraceQueue::initialize() 16 | { 17 | PassiveQueueBase::initialize(); 18 | queue.setName("l2queue"); 19 | 20 | frameVec.setName("framesForQueue"); 21 | dropVec.setName("dropsForQueue"); 22 | 23 | // configuration 24 | frameCapacity = par("frameCapacity"); 25 | intervalSize = par("intervalSize"); 26 | tracingOn = par("traceOn"); 27 | if (tracingOn) 28 | scheduleAt(simTime() + intervalSize, traceMessage); 29 | 30 | traceMessage = new cMessage("traceMsg"); 31 | 32 | dropsInInterval = framesInInterval = 0; 33 | } 34 | 35 | /** 36 | * Checks if there is enough space in queue to enqueue this message. 37 | * State variables drops and frames are updated accordingly. 38 | * 39 | * @param msg Message to enqueue 40 | * @return True if message is enqueued, false if queue is full 41 | */ 42 | bool DropTailTraceQueue::enqueue(cMessage *msg) 43 | { 44 | if (frameCapacity && queue.length() >= frameCapacity) 45 | { 46 | dropsInInterval++; 47 | delete msg; 48 | return true; 49 | } 50 | else 51 | { 52 | framesInInterval++; 53 | queue.insert(msg); 54 | return false; 55 | } 56 | } 57 | 58 | /** 59 | * Dequeues first message if queue is not empty 60 | * 61 | * @return Dequeued Message 62 | */ 63 | cMessage *DropTailTraceQueue::dequeue() 64 | { 65 | if (queue.empty()) 66 | return NULL; 67 | 68 | cMessage *pk = (cMessage *) queue.pop(); 69 | return pk; 70 | } 71 | 72 | /** 73 | * Sends the given message to gate out. 74 | * 75 | * @param msg Message to be sent 76 | */ 77 | void DropTailTraceQueue::sendOut(cMessage *msg) 78 | { 79 | send(msg, "out"); 80 | } 81 | 82 | /** 83 | * Handles interval timer message. 84 | * 85 | * In case tracing support is activated, a periodic traceMessage is sent 86 | * and received. In case of reception the recorded values (drops, frames) 87 | * of the current interval are written out to vector file. 88 | * Then the state variables are reset to 0 for the next interval. 89 | * 90 | * @param msg Message to handle 91 | */ 92 | void DropTailTraceQueue::handleMessage(cMessage *msg) 93 | { 94 | if (!tracingOn) 95 | PassiveQueueBase::handleMessage(msg); 96 | else 97 | { 98 | if (msg->isSelfMessage()) 99 | { 100 | frameVec.recordWithTimestamp(simTime(), framesInInterval); 101 | framesInInterval = 0; 102 | dropVec.recordWithTimestamp(simTime(), dropsInInterval); 103 | dropsInInterval = 0; 104 | scheduleAt(simTime() + intervalSize, msg); 105 | } 106 | else 107 | PassiveQueueBase::handleMessage(msg); 108 | } 109 | } 110 | 111 | -------------------------------------------------------------------------------- /src/networklayer/queue/DropTailTraceQueue.h: -------------------------------------------------------------------------------- 1 | #ifndef DROPTAILTRACEQUEUE_H_ 2 | #define DROPTAILTRACEQUEUE_H_ 3 | 4 | #include 5 | #include "PassiveQueueBase.h" 6 | 7 | /** 8 | * @brief Drop-tail queue with additional tracing support. 9 | * 10 | * Divides traffic into intervals of equal time-based length 11 | * and writes out the packet counts of different aggregates 12 | * observed in the last interval into vector file. 13 | * 14 | * @class DropTailTraceQueue 15 | */ 16 | class DropTailTraceQueue : public PassiveQueueBase 17 | { 18 | protected: 19 | // configuration 20 | int frameCapacity; 21 | simtime_t intervalSize; 22 | bool tracingOn; 23 | 24 | // state 25 | cQueue queue; 26 | int dropsInInterval; 27 | int framesInInterval; 28 | 29 | // statistics 30 | cOutVector frameVec; 31 | cOutVector dropVec; 32 | 33 | // periodic message to trigger interval end 34 | cMessage *traceMessage; 35 | 36 | protected: 37 | virtual void initialize(); 38 | 39 | /** 40 | * Redefined from PassiveQueueBase. 41 | */ 42 | virtual bool enqueue(cMessage *msg); 43 | 44 | /** 45 | * Redefined from PassiveQueueBase. 46 | */ 47 | virtual cMessage *dequeue(); 48 | 49 | /** 50 | * Redefined from PassiveQueueBase. 51 | */ 52 | virtual void sendOut(cMessage *msg); 53 | 54 | //virtual void finish(){/*do nothing*/}; //FIXME: is this needed? -Claus 55 | 56 | /** 57 | * Handles interval timer message. 58 | */ 59 | virtual void handleMessage(cMessage *msg); 60 | 61 | }; 62 | 63 | #endif /*DROPTAILTRACEQUEUE_H_*/ 64 | -------------------------------------------------------------------------------- /src/networklayer/queue/DropTailTraceQueue.ned: -------------------------------------------------------------------------------- 1 | package scadasim.networklayer.queue; 2 | 3 | simple DropTailTraceQueue 4 | { 5 | parameters: 6 | int frameCapacity; 7 | double intervalSize @unit(s); 8 | bool traceOn; 9 | gates: 10 | input in; 11 | output out; 12 | } 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/nodes/inet/BackupServer.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.inet; 2 | 3 | import inet.base.NotificationBoard; 4 | import inet.linklayer.ethernet.EthernetInterface; 5 | import inet.linklayer.ppp.PPPInterface; 6 | import inet.networklayer.common.InterfaceTable; 7 | import inet.networklayer.ipv4.RoutingTable; 8 | import inet.nodes.inet.NetworkLayer; 9 | import inet.util.NAMTraceWriter; 10 | import scadasim.applications.pingApp.GenericICMPPingApplication; 11 | import scadasim.applications.tcpApp.GenericTCPApplication; 12 | import scadasim.transport.tcp.TCP_hack; 13 | import scadasim.transport.udp.UDP_hack; 14 | import inet.transport.tcp.TCP; 15 | 16 | // 17 | // BackupServer: Server system for backup traffic profile using TCP as 18 | // transport protocol. 19 | // This profile generates many large client requests and only few 20 | // server replies. 21 | // 22 | // \IP host with TCP, UDP layers and applications. 23 | // 24 | module BackupServer 25 | { 26 | parameters: 27 | @node(); 28 | int namid; 29 | int maxTCPThreadCount; 30 | gates: 31 | inout pppg[]; 32 | inout ethg[]; 33 | submodules: 34 | namTrace: NAMTraceWriter { 35 | parameters: 36 | namid = namid; 37 | @display("p=60,310;i=block/sink"); 38 | } 39 | notificationBoard: NotificationBoard { 40 | parameters: 41 | @display("p=60,70;i=block/control"); 42 | } 43 | interfaceTable: InterfaceTable { 44 | parameters: 45 | @display("p=60,150;i=block/table"); 46 | } 47 | routingTable: RoutingTable { 48 | parameters: 49 | IPForward = false; 50 | routerId = ""; 51 | routingFile = ""; 52 | @display("p=60,230;i=block/table"); 53 | } 54 | tcpApp: GenericTCPApplication { 55 | parameters: 56 | isServer = true; 57 | profileNumber = 1; 58 | port = 80; 59 | @display("p=163,67;i=block/app"); 60 | } 61 | tcp: TCP { 62 | parameters: 63 | // maxThreadCount = maxTCPThreadCount; 64 | @display("p=163,154;i=block/wheelbarrow"); 65 | } 66 | udp: UDP_hack { 67 | parameters: 68 | @display("p=272,154;i=block/transport"); 69 | } 70 | pingApp: GenericICMPPingApplication { 71 | parameters: 72 | isServer = true; 73 | profileNumber = 21; 74 | port = 0; 75 | @display("i=block/app;p=343,200"); 76 | } 77 | networkLayer: NetworkLayer { 78 | parameters: 79 | proxyARP = false; 80 | @display("p=248,247;i=block/fork;q=queue"); 81 | gates: 82 | ifIn[sizeof(pppg)+sizeof(ethg)]; 83 | ifOut[sizeof(pppg)+sizeof(ethg)]; 84 | } 85 | ppp[sizeof(pppg)]: PPPInterface { 86 | parameters: 87 | @display("p=205,350,row,90;q=txQueue;i=block/ifcard"); 88 | } 89 | eth[sizeof(ethg)]: EthernetInterface { 90 | parameters: 91 | @display("p=240,350,row,90;q=txQueue;i=block/ifcard"); 92 | } 93 | connections allowunconnected: 94 | tcpApp.tcpOut --> tcp.appIn++; 95 | tcpApp.tcpIn <-- tcp.appOut++; 96 | 97 | tcp.ipOut --> networkLayer.tcpIn; 98 | tcp.ipIn <-- networkLayer.tcpOut; 99 | 100 | udp.ipOut --> networkLayer.udpIn; 101 | udp.ipIn <-- networkLayer.udpOut; 102 | 103 | networkLayer.pingOut --> pingApp.pingIn; 104 | networkLayer.pingIn <-- pingApp.pingOut; 105 | 106 | // connections to network outside 107 | for i=0..sizeof(pppg)-1 { 108 | pppg[i] <--> ppp[i].phys; 109 | ppp[i].netwOut --> networkLayer.ifIn[i]; 110 | ppp[i].netwIn <-- networkLayer.ifOut[i]; 111 | } 112 | 113 | for i=0..sizeof(ethg)-1 { 114 | ethg[i] <--> eth[i].phys; 115 | eth[i].netwOut --> networkLayer.ifIn[sizeof(pppg)+i]; 116 | eth[i].netwIn <-- networkLayer.ifOut[sizeof(pppg)+i]; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/nodes/inet/DDoSZombie.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.inet; 2 | 3 | import inet.base.NotificationBoard; 4 | import inet.linklayer.ethernet.EthernetInterface; 5 | import inet.linklayer.ppp.PPPInterface; 6 | import inet.networklayer.common.InterfaceTable; 7 | import inet.networklayer.ipv4.RoutingTable; 8 | import inet.util.NAMTraceWriter; 9 | import scadasim.applications.ddos.TribeFloodNetwork; 10 | 11 | 12 | // 13 | // Compound module which behaves as zombie system in a DDoS attack. 14 | // Therefore, TribeFloodNetwork is included in addition to the normal 15 | // TCP/IP layers 16 | // 17 | // NetworkLayer_hack is used to spoof packets sent during the DDoS attack. 18 | // 19 | module DDoSZombie 20 | { 21 | parameters: 22 | @node(); 23 | int namid; 24 | gates: 25 | inout pppg[]; 26 | inout ethg[]; 27 | submodules: 28 | namTrace: NAMTraceWriter { 29 | parameters: 30 | namid = namid; 31 | @display("p=60,310;i=block/sink"); 32 | 33 | } 34 | notificationBoard: NotificationBoard { 35 | parameters: 36 | @display("p=60,70;i=block/control"); 37 | 38 | } 39 | interfaceTable: InterfaceTable { 40 | parameters: 41 | @display("p=60,150;i=block/table"); 42 | 43 | } 44 | routingTable: RoutingTable { 45 | parameters: 46 | IPForward = false; 47 | routerId = ""; 48 | routingFile = ""; 49 | @display("p=60,230;i=block/table"); 50 | 51 | } 52 | tribeFloodNetwork: TribeFloodNetwork { 53 | parameters: 54 | @display("p=272,154;i=old/telnet"); 55 | 56 | } 57 | networkLayer: NetworkLayer_hack { 58 | parameters: 59 | proxyARP = false; 60 | tracingOn = false; 61 | spoofingOn = true; 62 | @display("p=248,247;i=block/fork;q=queue"); 63 | 64 | gates: 65 | ifIn[sizeof(pppg)+sizeof(ethg)]; 66 | ifOut[sizeof(pppg)+sizeof(ethg)]; 67 | } 68 | ppp[sizeof(pppg)]: PPPInterface { 69 | parameters: 70 | @display("p=164,350,row,90;q=txQueue;i=block/ifcard"); 71 | 72 | } 73 | eth[sizeof(ethg)]: EthernetInterface { 74 | parameters: 75 | @display("p=272,350,row,90;q=txQueue;i=block/ifcard"); 76 | 77 | } 78 | connections allowunconnected: 79 | tribeFloodNetwork.to_ip_tcp --> networkLayer.tcpIn; 80 | tribeFloodNetwork.ipIn++ <-- networkLayer.tcpOut; 81 | 82 | tribeFloodNetwork.to_ip_udp --> networkLayer.udpIn; 83 | tribeFloodNetwork.ipIn++ <-- networkLayer.udpOut; 84 | 85 | tribeFloodNetwork.to_ip_ping --> networkLayer.pingIn; 86 | tribeFloodNetwork.ipIn++ <-- networkLayer.pingOut; 87 | 88 | // connections to network outside 89 | for i=0..sizeof(pppg)-1 { 90 | pppg[i] <--> ppp[i].phys; 91 | ppp[i].netwOut --> networkLayer.ifIn[i]; 92 | ppp[i].netwIn <-- networkLayer.ifOut[i]; 93 | } 94 | 95 | for i=0..sizeof(ethg)-1 { 96 | ethg[i] <--> eth[i].phys; 97 | eth[i].netwOut --> networkLayer.ifIn[sizeof(pppg)+i]; 98 | eth[i].netwIn <-- networkLayer.ifOut[sizeof(pppg)+i]; 99 | } 100 | 101 | } 102 | 103 | -------------------------------------------------------------------------------- /src/nodes/inet/DatabaseServer.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.inet; 2 | 3 | import inet.base.NotificationBoard; 4 | import inet.linklayer.ethernet.EthernetInterface; 5 | import inet.linklayer.ppp.PPPInterface; 6 | import inet.networklayer.common.InterfaceTable; 7 | import inet.networklayer.ipv4.RoutingTable; 8 | import inet.nodes.inet.NetworkLayer; 9 | import inet.util.NAMTraceWriter; 10 | import scadasim.applications.pingApp.GenericICMPPingApplication; 11 | import scadasim.applications.tcpApp.GenericTCPApplication; 12 | import scadasim.transport.tcp.TCP_hack; 13 | import scadasim.transport.udp.UDP_hack; 14 | import inet.transport.tcp.TCP; 15 | 16 | // 17 | // InteractiveServer: Server system for interactive traffic profile using 18 | // TCP as transport protocol. 19 | // This profile generates a similar number of equally large client requests 20 | // and server replies. 21 | // 22 | // \IP host with TCP, UDP layers and applications. 23 | // 24 | module DatabaseServer 25 | { 26 | parameters: 27 | @node(); 28 | int namid; 29 | int maxTCPThreadCount; 30 | gates: 31 | inout pppg[]; 32 | inout ethg[]; 33 | submodules: 34 | namTrace: NAMTraceWriter { 35 | parameters: 36 | namid = namid; 37 | @display("p=60,310;i=block/sink"); 38 | 39 | } 40 | notificationBoard: NotificationBoard { 41 | parameters: 42 | @display("p=60,70;i=block/control"); 43 | 44 | } 45 | interfaceTable: InterfaceTable { 46 | parameters: 47 | @display("p=60,150;i=block/table"); 48 | 49 | } 50 | routingTable: RoutingTable { 51 | parameters: 52 | IPForward = false; 53 | routerId = ""; 54 | routingFile = ""; 55 | @display("p=60,230;i=block/table"); 56 | 57 | } 58 | // tcpApp: GenericTCPApplication { 59 | // parameters: 60 | // isServer = true; 61 | // profileNumber = 2; 62 | // port = 80; 63 | // @display("p=163,67;i=block/app"); 64 | // 65 | // } 66 | tcp: TCP { 67 | parameters: 68 | // maxThreadCount = maxTCPThreadCount; 69 | @display("p=163,154;i=block/wheelbarrow"); 70 | 71 | } 72 | // udp: UDP_hack { 73 | // parameters: 74 | // @display("p=272,154;i=block/transport"); 75 | // 76 | // } 77 | // pingApp: GenericICMPPingApplication { 78 | // parameters: 79 | // isServer = true; 80 | // profileNumber = 21; 81 | // port = 0; 82 | // @display("i=block/app;p=343,200"); 83 | // 84 | // } 85 | networkLayer: NetworkLayer { 86 | parameters: 87 | proxyARP = false; 88 | @display("p=248,247;i=block/fork;q=queue"); 89 | 90 | gates: 91 | ifIn[sizeof(pppg)+sizeof(ethg)]; 92 | ifOut[sizeof(pppg)+sizeof(ethg)]; 93 | } 94 | ppp[sizeof(pppg)]: PPPInterface { 95 | parameters: 96 | @display("p=202,350,row,90;q=txQueue;i=block/ifcard"); 97 | 98 | } 99 | eth[sizeof(ethg)]: EthernetInterface { 100 | parameters: 101 | @display("p=349,350,row,90;q=txQueue;i=block/ifcard"); 102 | 103 | } 104 | connections allowunconnected: 105 | // tcpApp.tcpOut --> tcp.appIn++; 106 | // tcpApp.tcpIn <-- tcp.appOut++; 107 | 108 | tcp.ipOut --> networkLayer.tcpIn; 109 | tcp.ipIn <-- networkLayer.tcpOut; 110 | 111 | // udp.ipOut --> networkLayer.udpIn; 112 | // udp.ipIn <-- networkLayer.udpOut; 113 | // 114 | // networkLayer.pingOut --> pingApp.pingIn; 115 | // networkLayer.pingIn <-- pingApp.pingOut; 116 | 117 | // connections to network outside 118 | for i=0..sizeof(pppg)-1 { 119 | pppg[i] <--> ppp[i].phys; 120 | ppp[i].netwOut --> networkLayer.ifIn[i]; 121 | ppp[i].netwIn <-- networkLayer.ifOut[i]; 122 | } 123 | 124 | for i=0..sizeof(ethg)-1 { 125 | ethg[i] <--> eth[i].phys; 126 | eth[i].netwOut --> networkLayer.ifIn[sizeof(pppg)+i]; 127 | eth[i].netwIn <-- networkLayer.ifOut[sizeof(pppg)+i]; 128 | } 129 | } 130 | 131 | -------------------------------------------------------------------------------- /src/nodes/inet/InetUserHost.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.inet; 2 | 3 | import inet.base.NotificationBoard; 4 | import inet.linklayer.ethernet.EthernetInterface; 5 | import inet.linklayer.ppp.PPPInterface; 6 | import inet.networklayer.common.InterfaceTable; 7 | import inet.networklayer.ipv4.RoutingTable; 8 | import inet.nodes.inet.NetworkLayer; 9 | import inet.util.NAMTraceWriter; 10 | import scadasim.transport.tcp.TCP_hack; 11 | import scadasim.applications.generic.InetUser; 12 | import scadasim.applications.pingApp.GenericICMPPingApplication; 13 | import scadasim.applications.tcpApp.GenericTCPApplication; 14 | import scadasim.applications.udpApp.GenericUDPApplication; 15 | import scadasim.transport.udp.UDP_hack; 16 | import inet.transport.tcp.TCP; 17 | 18 | // 19 | // Default IP host which replaces the standard host of the original 20 | // INET framework. 21 | // This host system consists of TCP, UDP layers and applications. 22 | // In comparison to StandardHost TCP_hack and UDP_hack are used. 23 | // In addition the GenericXXApplications are used for traffic generation 24 | // instead of the original XXApp implementations. 25 | // Thus, only a single application is necessary per protocol type. 26 | // 27 | // Finally, the simple module InetUser is contained that actually requests 28 | // traffic profiles at random times and therefore, creates self-similar 29 | // background traffic. 30 | // 31 | module InetUserHost 32 | { 33 | parameters: 34 | @node(); 35 | int namid; 36 | int maxTCPThreadCount; 37 | gates: 38 | inout pppg[]; 39 | inout ethg[]; 40 | submodules: 41 | namTrace: NAMTraceWriter { 42 | parameters: 43 | namid = namid; 44 | @display("p=60,310;i=block/sink"); 45 | 46 | } 47 | inetUser: InetUser { 48 | parameters: 49 | @display("p=60,390;i=abstract/person"); 50 | 51 | } 52 | notificationBoard: NotificationBoard { 53 | parameters: 54 | @display("p=60,70;i=block/control"); 55 | 56 | } 57 | interfaceTable: InterfaceTable { 58 | parameters: 59 | @display("p=60,150;i=block/table"); 60 | 61 | } 62 | routingTable: RoutingTable { 63 | parameters: 64 | IPForward = false; 65 | routerId = ""; 66 | routingFile = ""; 67 | @display("p=60,230;i=block/table"); 68 | 69 | } 70 | clientTCP: GenericTCPApplication { 71 | parameters: 72 | isServer = false; 73 | profileNumber = 3; 74 | port = 1; 75 | @display("p=163,67;i=block/app"); 76 | 77 | } 78 | tcp: TCP { 79 | parameters: 80 | //maxThreadCount = maxTCPThreadCount; 81 | @display("p=163,154;i=block/wheelbarrow"); 82 | 83 | } 84 | // udpApp: GenericUDPApplication { 85 | // parameters: 86 | // isServer = false; 87 | // profileNumber = 13; 88 | // port = 2101; 89 | // noThreads = 0; 90 | // @display("i=block/app;p=272,67"); 91 | // 92 | // } 93 | // udp: UDP_hack { 94 | // parameters: 95 | // @display("p=272,154;i=block/transport"); 96 | // 97 | // } 98 | // pingApp: GenericICMPPingApplication { 99 | // parameters: 100 | // isServer = false; 101 | // profileNumber = 21; 102 | // port = 0; 103 | // noThreads = 0; 104 | // @display("i=block/app;p=343,200"); 105 | // 106 | // } 107 | networkLayer: NetworkLayer_hack { 108 | parameters: 109 | proxyARP = false; 110 | @display("p=248,247;i=block/fork;q=queue"); 111 | 112 | gates: 113 | ifIn[sizeof(pppg)+sizeof(ethg)]; 114 | ifOut[sizeof(pppg)+sizeof(ethg)]; 115 | } 116 | ppp[sizeof(pppg)]: PPPInterface { 117 | parameters: 118 | @display("p=163,350,row,90;q=txQueue;i=block/ifcard"); 119 | 120 | } 121 | eth[sizeof(ethg)]: EthernetInterface { 122 | parameters: 123 | @display("p=297,350,row,90;q=txQueue;i=block/ifcard"); 124 | 125 | } 126 | connections allowunconnected: 127 | clientTCP.tcpOut --> tcp.appIn++; 128 | clientTCP.tcpIn <-- tcp.appOut++; 129 | tcp.ipOut --> networkLayer.tcpIn; 130 | tcp.ipIn <-- networkLayer.tcpOut; 131 | 132 | // udpApp.udpOut --> udp.appIn++; 133 | // udpApp.udpIn <-- udp.appOut++; 134 | // 135 | // udp.ipOut --> networkLayer.udpIn; 136 | // udp.ipIn <-- networkLayer.udpOut; 137 | // 138 | // networkLayer.pingOut --> pingApp.pingIn; 139 | // networkLayer.pingIn <-- pingApp.pingOut; 140 | 141 | // connections to network outside 142 | for i=0..sizeof(pppg)-1 { 143 | pppg[i] <--> ppp[i].phys; 144 | ppp[i].netwOut --> networkLayer.ifIn[i]; 145 | ppp[i].netwIn <-- networkLayer.ifOut[i]; 146 | } 147 | 148 | for i=0..sizeof(ethg)-1 { 149 | ethg[i] <--> eth[i].phys; 150 | eth[i].netwOut --> networkLayer.ifIn[sizeof(pppg)+i]; 151 | eth[i].netwIn <-- networkLayer.ifOut[sizeof(pppg)+i]; 152 | } 153 | 154 | } 155 | 156 | -------------------------------------------------------------------------------- /src/nodes/inet/InteractiveServer.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.inet; 2 | 3 | import inet.base.NotificationBoard; 4 | import inet.linklayer.ethernet.EthernetInterface; 5 | import inet.linklayer.ppp.PPPInterface; 6 | import inet.networklayer.common.InterfaceTable; 7 | import inet.networklayer.ipv4.RoutingTable; 8 | import inet.nodes.inet.NetworkLayer; 9 | import inet.util.NAMTraceWriter; 10 | import scadasim.applications.pingApp.GenericICMPPingApplication; 11 | import scadasim.applications.tcpApp.GenericTCPApplication; 12 | import scadasim.transport.tcp.TCP_hack; 13 | import scadasim.transport.udp.UDP_hack; 14 | import inet.transport.tcp.TCP; 15 | 16 | // 17 | // InteractiveServer: Server system for interactive traffic profile using 18 | // TCP as transport protocol. 19 | // This profile generates a similar number of equally large client requests 20 | // and server replies. 21 | // 22 | // \IP host with TCP, UDP layers and applications. 23 | // 24 | module InteractiveServer 25 | { 26 | parameters: 27 | @node(); 28 | int namid; 29 | int maxTCPThreadCount; 30 | gates: 31 | inout pppg[]; 32 | inout ethg[]; 33 | submodules: 34 | namTrace: NAMTraceWriter { 35 | parameters: 36 | namid = namid; 37 | @display("p=60,310;i=block/sink"); 38 | 39 | } 40 | notificationBoard: NotificationBoard { 41 | parameters: 42 | @display("p=60,70;i=block/control"); 43 | 44 | } 45 | interfaceTable: InterfaceTable { 46 | parameters: 47 | @display("p=60,150;i=block/table"); 48 | 49 | } 50 | routingTable: RoutingTable { 51 | parameters: 52 | IPForward = false; 53 | routerId = ""; 54 | routingFile = ""; 55 | @display("p=60,230;i=block/table"); 56 | 57 | } 58 | tcpApp: GenericTCPApplication { 59 | parameters: 60 | isServer = true; 61 | profileNumber = 2; 62 | port = 80; 63 | @display("p=163,67;i=block/app"); 64 | 65 | } 66 | tcp: TCP { 67 | parameters: 68 | // maxThreadCount = maxTCPThreadCount; 69 | @display("p=163,154;i=block/wheelbarrow"); 70 | 71 | } 72 | udp: UDP_hack { 73 | parameters: 74 | @display("p=272,154;i=block/transport"); 75 | 76 | } 77 | pingApp: GenericICMPPingApplication { 78 | parameters: 79 | isServer = true; 80 | profileNumber = 21; 81 | port = 0; 82 | @display("i=block/app;p=343,200"); 83 | 84 | } 85 | networkLayer: NetworkLayer { 86 | parameters: 87 | proxyARP = false; 88 | @display("p=248,247;i=block/fork;q=queue"); 89 | 90 | gates: 91 | ifIn[sizeof(pppg)+sizeof(ethg)]; 92 | ifOut[sizeof(pppg)+sizeof(ethg)]; 93 | } 94 | ppp[sizeof(pppg)]: PPPInterface { 95 | parameters: 96 | @display("p=205,350,row,90;q=txQueue;i=block/ifcard"); 97 | 98 | } 99 | eth[sizeof(ethg)]: EthernetInterface { 100 | parameters: 101 | @display("p=240,350,row,90;q=txQueue;i=block/ifcard"); 102 | 103 | } 104 | connections allowunconnected: 105 | tcpApp.tcpOut --> tcp.appIn++; 106 | tcpApp.tcpIn <-- tcp.appOut++; 107 | 108 | tcp.ipOut --> networkLayer.tcpIn; 109 | tcp.ipIn <-- networkLayer.tcpOut; 110 | 111 | udp.ipOut --> networkLayer.udpIn; 112 | udp.ipIn <-- networkLayer.udpOut; 113 | 114 | networkLayer.pingOut --> pingApp.pingIn; 115 | networkLayer.pingIn <-- pingApp.pingOut; 116 | 117 | // connections to network outside 118 | for i=0..sizeof(pppg)-1 { 119 | pppg[i] <--> ppp[i].phys; 120 | ppp[i].netwOut --> networkLayer.ifIn[i]; 121 | ppp[i].netwIn <-- networkLayer.ifOut[i]; 122 | } 123 | 124 | for i=0..sizeof(ethg)-1 { 125 | ethg[i] <--> eth[i].phys; 126 | eth[i].netwOut --> networkLayer.ifIn[sizeof(pppg)+i]; 127 | eth[i].netwIn <-- networkLayer.ifOut[sizeof(pppg)+i]; 128 | } 129 | } 130 | 131 | -------------------------------------------------------------------------------- /src/nodes/inet/MailServer.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.inet; 2 | 3 | import inet.base.NotificationBoard; 4 | import inet.linklayer.ethernet.EthernetInterface; 5 | import inet.linklayer.ppp.PPPInterface; 6 | import inet.networklayer.common.InterfaceTable; 7 | import inet.networklayer.ipv4.RoutingTable; 8 | import inet.nodes.inet.NetworkLayer; 9 | import inet.util.NAMTraceWriter; 10 | import scadasim.applications.pingApp.GenericICMPPingApplication; 11 | import scadasim.applications.tcpApp.GenericTCPApplication; 12 | import scadasim.transport.tcp.TCP_hack; 13 | import scadasim.transport.udp.UDP_hack; 14 | import inet.transport.tcp.TCP; 15 | 16 | // 17 | // MailServer: Server system for mail traffic profile using TCP as 18 | // transport protocol. 19 | // This profile generates many small client requests and only few 20 | // server replies. 21 | // 22 | // \IP host with TCP, UDP layers and applications. 23 | // 24 | module MailServer 25 | { 26 | parameters: 27 | @node(); 28 | int namid; 29 | int maxTCPThreadCount; 30 | gates: 31 | inout pppg[]; 32 | inout ethg[]; 33 | submodules: 34 | namTrace: NAMTraceWriter { 35 | parameters: 36 | namid = namid; 37 | @display("p=60,310;i=block/sink"); 38 | 39 | } 40 | notificationBoard: NotificationBoard { 41 | parameters: 42 | @display("p=60,70;i=block/control"); 43 | 44 | } 45 | interfaceTable: InterfaceTable { 46 | parameters: 47 | @display("p=60,150;i=block/table"); 48 | 49 | } 50 | routingTable: RoutingTable { 51 | parameters: 52 | IPForward = false; 53 | routerId = ""; 54 | routingFile = ""; 55 | @display("p=60,230;i=block/table"); 56 | 57 | } 58 | tcpApp: GenericTCPApplication { 59 | parameters: 60 | isServer = true; 61 | profileNumber = 4; 62 | port = 125; 63 | @display("p=163,67;i=block/app"); 64 | 65 | } 66 | tcp: TCP { 67 | parameters: 68 | // maxThreadCount = maxTCPThreadCount; 69 | @display("p=163,154;i=block/wheelbarrow"); 70 | 71 | } 72 | udp: UDP_hack { 73 | parameters: 74 | @display("p=272,154;i=block/transport"); 75 | 76 | } 77 | pingApp: GenericICMPPingApplication { 78 | parameters: 79 | isServer = true; 80 | profileNumber = 21; 81 | port = 0; 82 | @display("i=block/app;p=343,200"); 83 | 84 | } 85 | networkLayer: NetworkLayer { 86 | parameters: 87 | proxyARP = false; 88 | @display("p=248,247;i=block/fork;q=queue"); 89 | 90 | gates: 91 | ifIn[sizeof(pppg)+sizeof(ethg)]; 92 | ifOut[sizeof(pppg)+sizeof(ethg)]; 93 | } 94 | ppp[sizeof(pppg)]: PPPInterface { 95 | parameters: 96 | @display("p=205,350,row,90;q=txQueue;i=block/ifcard"); 97 | 98 | } 99 | eth[sizeof(ethg)]: EthernetInterface { 100 | parameters: 101 | @display("p=240,350,row,90;q=txQueue;i=block/ifcard"); 102 | 103 | } 104 | connections allowunconnected: 105 | tcpApp.tcpOut --> tcp.appIn++; 106 | tcpApp.tcpIn <-- tcp.appOut++; 107 | 108 | tcp.ipOut --> networkLayer.tcpIn; 109 | tcp.ipIn <-- networkLayer.tcpOut; 110 | 111 | udp.ipOut --> networkLayer.udpIn; 112 | udp.ipIn <-- networkLayer.udpOut; 113 | 114 | networkLayer.pingOut --> pingApp.pingIn; 115 | networkLayer.pingIn <-- pingApp.pingOut; 116 | 117 | // connections to network outside 118 | for i=0..sizeof(pppg)-1 { 119 | pppg[i] <--> ppp[i].phys; 120 | ppp[i].netwOut --> networkLayer.ifIn[i]; 121 | ppp[i].netwIn <-- networkLayer.ifOut[i]; 122 | } 123 | 124 | for i=0..sizeof(ethg)-1 { 125 | ethg[i] <--> eth[i].phys; 126 | eth[i].netwOut --> networkLayer.ifIn[sizeof(pppg)+i]; 127 | eth[i].netwIn <-- networkLayer.ifOut[sizeof(pppg)+i]; 128 | } 129 | } 130 | 131 | -------------------------------------------------------------------------------- /src/nodes/inet/NameServer.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.inet; 2 | 3 | import inet.base.NotificationBoard; 4 | import inet.linklayer.ethernet.EthernetInterface; 5 | import inet.linklayer.ppp.PPPInterface; 6 | import inet.networklayer.common.InterfaceTable; 7 | import inet.networklayer.ipv4.RoutingTable; 8 | import inet.nodes.inet.NetworkLayer; 9 | import scadasim.transport.tcp.TCP_hack; 10 | import inet.util.NAMTraceWriter; 11 | import scadasim.applications.pingApp.GenericICMPPingApplication; 12 | import scadasim.applications.udpApp.GenericUDPApplication; 13 | import scadasim.transport.udp.UDP_hack; 14 | import inet.transport.tcp.TCP; 15 | import inet.transport.udp.UDP; 16 | // 17 | // NameServer: Server system for DNS traffic profile using UDP as 18 | // transport protocol. 19 | // This profile generates few small client requests and few small 20 | // server replies. 21 | // 22 | // \IP host with TCP, UDP layers and applications. 23 | // 24 | module NameServer 25 | { 26 | parameters: 27 | @node(); 28 | int namid; 29 | int maxTCPThreadCount; 30 | gates: 31 | inout pppg[]; 32 | inout ethg[]; 33 | submodules: 34 | namTrace: NAMTraceWriter { 35 | parameters: 36 | namid = namid; 37 | @display("p=60,310;i=block/sink"); 38 | 39 | } 40 | notificationBoard: NotificationBoard { 41 | parameters: 42 | @display("p=60,70;i=block/control"); 43 | 44 | } 45 | interfaceTable: InterfaceTable { 46 | parameters: 47 | @display("p=60,150;i=block/table"); 48 | 49 | } 50 | routingTable: RoutingTable { 51 | parameters: 52 | IPForward = false; 53 | routerId = ""; 54 | routingFile = ""; 55 | @display("p=60,230;i=block/table"); 56 | 57 | } 58 | tcp: TCP { 59 | parameters: 60 | @display("p=163,154;i=block/wheelbarrow"); 61 | // maxThreadCount = maxTCPThreadCount; 62 | 63 | 64 | } 65 | udpApp: GenericUDPApplication { 66 | parameters: 67 | isServer = true; 68 | profileNumber = 11; 69 | port = 1245; 70 | @display("i=block/app;p=272,67"); 71 | 72 | } 73 | udp: UDP { 74 | parameters: 75 | @display("p=272,154;i=block/transport"); 76 | 77 | } 78 | pingApp: GenericICMPPingApplication { 79 | parameters: 80 | isServer = true; 81 | profileNumber = 21; 82 | port = 0; 83 | @display("i=block/app;p=343,200"); 84 | 85 | } 86 | networkLayer: NetworkLayer { 87 | parameters: 88 | proxyARP = false; 89 | @display("p=248,247;i=block/fork;q=queue"); 90 | 91 | gates: 92 | ifIn[sizeof(pppg)+sizeof(ethg)]; 93 | ifOut[sizeof(pppg)+sizeof(ethg)]; 94 | } 95 | ppp[sizeof(pppg)]: PPPInterface { 96 | parameters: 97 | @display("p=205,350,row,90;q=txQueue;i=block/ifcard"); 98 | 99 | } 100 | eth[sizeof(ethg)]: EthernetInterface { 101 | parameters: 102 | @display("p=240,350,row,90;q=txQueue;i=block/ifcard"); 103 | 104 | } 105 | connections allowunconnected: 106 | tcp.ipOut --> networkLayer.tcpIn; 107 | tcp.ipIn <-- networkLayer.tcpOut; 108 | 109 | udpApp.udpOut --> udp.appIn++; 110 | udpApp.udpIn <-- udp.appOut++; 111 | 112 | udp.ipOut --> networkLayer.udpIn; 113 | udp.ipIn <-- networkLayer.udpOut; 114 | 115 | networkLayer.pingOut --> pingApp.pingIn; 116 | networkLayer.pingIn <-- pingApp.pingOut; 117 | 118 | // connections to network outside 119 | for i=0..sizeof(pppg)-1 { 120 | pppg[i] <--> ppp[i].phys; 121 | ppp[i].netwOut --> networkLayer.ifIn[i]; 122 | ppp[i].netwIn <-- networkLayer.ifOut[i]; 123 | } 124 | 125 | for i=0..sizeof(ethg)-1 { 126 | ethg[i] <--> eth[i].phys; 127 | eth[i].netwOut --> networkLayer.ifIn[sizeof(pppg)+i]; 128 | eth[i].netwIn <-- networkLayer.ifOut[sizeof(pppg)+i]; 129 | } 130 | } 131 | 132 | -------------------------------------------------------------------------------- /src/nodes/inet/NetworkLayer_hack.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.inet; 2 | 3 | // 4 | // Network layer of an \IP node that includes IP_hack instead of the original 5 | // IP implementation. 6 | // IP_hack allows for spoofing, packet tracing, etc. 7 | // 8 | // 9 | 10 | 11 | import inet.networklayer.arp.ARP; 12 | import inet.networklayer.ipv4.ErrorHandling; 13 | import inet.networklayer.ipv4.ICMP; 14 | import inet.networklayer.ipv4.IGMP; 15 | import scadasim.networklayer.ipv4.IP_hack; 16 | 17 | 18 | // 19 | // Network layer of an \IP node. 20 | // 21 | // Interfaces to transport layer: TCP, UDP, echo/ping, RSVP 22 | // 23 | module NetworkLayer_hack 24 | { 25 | parameters: 26 | bool proxyARP; 27 | bool tracingOn; 28 | bool spoofingOn; 29 | gates: 30 | input ifIn[]; 31 | input tcpIn; 32 | input udpIn; 33 | input sctpIn; //I.R. 34 | input rsvpIn; 35 | input ospfIn; 36 | input pingIn; 37 | output ifOut[]; 38 | output tcpOut; 39 | output udpOut; 40 | output sctpOut; //I.R. 41 | output rsvpOut; 42 | output ospfOut; 43 | output pingOut; 44 | submodules: 45 | ip: IP_hack { 46 | parameters: 47 | timeToLive = 125; 48 | multicastTimeToLive = 32; 49 | fragmentTimeout = 60s; 50 | protocolMapping = "6:0,17:1,1:2,2:3,46:4,89:5,132:6,254:7,135:7"; 51 | spoofingOn = spoofingOn; 52 | tracingOn = tracingOn; 53 | @display("p=85,95;i=block/routing;q=queue"); 54 | gates: 55 | transportIn[8]; 56 | transportOut[8]; 57 | queueIn[sizeof(ifIn)]; 58 | } 59 | arp: ARP { 60 | parameters: 61 | proxyARP = proxyARP; 62 | @display("p=163,206;i=block/layer;q=pendingQueue"); 63 | gates: 64 | nicOut[sizeof(ifOut)]; 65 | } 66 | icmp: ICMP { 67 | parameters: 68 | @display("p=160,63;i=block/control_s"); 69 | } 70 | igmp: IGMP { 71 | parameters: 72 | @display("p=160,122;i=block/cogwheel_s"); 73 | } 74 | errorHandling: ErrorHandling { 75 | parameters: 76 | @display("p=239,63;i=block/process_s"); 77 | } 78 | connections allowunconnected: 79 | // transport Layer 80 | ip.transportOut[0] --> tcpOut; 81 | ip.transportIn[0] <-- tcpIn; 82 | 83 | ip.transportOut[1] --> udpOut; 84 | ip.transportIn[1] <-- udpIn; 85 | 86 | ip.transportOut[2] --> icmp.localIn; 87 | ip.transportIn[2] <-- icmp.sendOut; 88 | 89 | ip.transportOut[3] --> igmp.localIn; 90 | ip.transportIn[3] <-- igmp.sendOut; 91 | 92 | ip.transportOut[4] --> rsvpOut; 93 | ip.transportIn[4] <-- rsvpIn; 94 | 95 | ip.transportOut[5] --> ospfOut; 96 | ip.transportIn[5] <-- ospfIn; 97 | 98 | ip.transportOut[6] --> sctpOut; //I.R. 99 | ip.transportIn[6] <-- sctpIn; 100 | 101 | icmp.pingOut --> pingOut; 102 | icmp.pingIn <-- pingIn; 103 | 104 | icmp.errorOut --> errorHandling.in; 105 | 106 | ip.queueOut --> arp.ipIn; 107 | 108 | // L2 interfaces to IP and from ARP 109 | for i=0..sizeof(ifOut)-1 { 110 | ifIn[i] --> { @display("m=s"); } --> ip.queueIn[i]; 111 | ifOut[i] <-- { @display("m=s"); } <-- arp.nicOut[i]; 112 | } 113 | } 114 | 115 | -------------------------------------------------------------------------------- /src/nodes/inet/StreamingServer.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.inet; 2 | 3 | import inet.base.NotificationBoard; 4 | import inet.linklayer.ethernet.EthernetInterface; 5 | import inet.linklayer.ppp.PPPInterface; 6 | import inet.networklayer.common.InterfaceTable; 7 | import inet.networklayer.ipv4.RoutingTable; 8 | import inet.nodes.inet.NetworkLayer; 9 | import scadasim.transport.tcp.TCP_hack; 10 | import inet.util.NAMTraceWriter; 11 | import scadasim.applications.pingApp.GenericICMPPingApplication; 12 | import scadasim.applications.udpApp.GenericUDPApplication; 13 | import scadasim.transport.udp.UDP_hack; 14 | import inet.transport.tcp.TCP; 15 | import inet.transport.udp.UDP; 16 | // 17 | // StreamingServer: Server system for streaming traffic profile using UDP as 18 | // transport protocol. 19 | // This profile generates few client requests and many server replies. 20 | // 21 | // \IP host with TCP, UDP layers and applications. 22 | // 23 | module StreamingServer 24 | { 25 | parameters: 26 | @node(); 27 | int namid; 28 | int maxTCPThreadCount; 29 | gates: 30 | inout pppg[]; 31 | inout ethg[]; 32 | submodules: 33 | namTrace: NAMTraceWriter { 34 | parameters: 35 | namid = namid; 36 | @display("p=60,310;i=block/sink"); 37 | 38 | } 39 | notificationBoard: NotificationBoard { 40 | parameters: 41 | @display("p=60,70;i=block/control"); 42 | 43 | } 44 | interfaceTable: InterfaceTable { 45 | parameters: 46 | @display("p=60,150;i=block/table"); 47 | 48 | } 49 | routingTable: RoutingTable { 50 | parameters: 51 | IPForward = false; 52 | routerId = ""; 53 | routingFile = ""; 54 | @display("p=60,230;i=block/table"); 55 | 56 | } 57 | tcp: TCP { 58 | parameters: 59 | // maxThreadCount = maxTCPThreadCount; 60 | @display("p=163,154;i=block/wheelbarrow"); 61 | } 62 | udpApp: GenericUDPApplication { 63 | parameters: 64 | isServer = true; 65 | profileNumber = 12; 66 | port = 1245; 67 | @display("i=block/app;p=272,67"); 68 | 69 | } 70 | udp: UDP { 71 | parameters: 72 | @display("p=272,154;i=block/transport"); 73 | 74 | } 75 | pingApp: GenericICMPPingApplication { 76 | parameters: 77 | isServer = true; 78 | profileNumber = 21; 79 | port = 0; 80 | @display("i=block/app;p=343,200"); 81 | 82 | } 83 | networkLayer: NetworkLayer { 84 | parameters: 85 | proxyARP = false; 86 | @display("p=248,247;i=block/fork;q=queue"); 87 | 88 | gates: 89 | ifIn[sizeof(pppg)+sizeof(ethg)]; 90 | ifOut[sizeof(pppg)+sizeof(ethg)]; 91 | } 92 | ppp[sizeof(pppg)]: PPPInterface { 93 | parameters: 94 | @display("p=205,350,row,90;q=txQueue;i=block/ifcard"); 95 | 96 | } 97 | eth[sizeof(ethg)]: EthernetInterface { 98 | parameters: 99 | @display("p=240,350,row,90;q=txQueue;i=block/ifcard"); 100 | 101 | } 102 | connections allowunconnected: 103 | tcp.ipOut --> networkLayer.tcpIn; 104 | tcp.ipIn <-- networkLayer.tcpOut; 105 | 106 | udpApp.udpOut --> udp.appIn++; 107 | udpApp.udpIn <-- udp.appOut++; 108 | 109 | udp.ipOut --> networkLayer.udpIn; 110 | udp.ipIn <-- networkLayer.udpOut; 111 | 112 | networkLayer.pingOut --> pingApp.pingIn; 113 | networkLayer.pingIn <-- pingApp.pingOut; 114 | 115 | // connections to network outside 116 | for i=0..sizeof(pppg)-1 { 117 | pppg[i] <--> ppp[i].phys; 118 | ppp[i].netwOut --> networkLayer.ifIn[i]; 119 | ppp[i].netwIn <-- networkLayer.ifOut[i]; 120 | } 121 | 122 | for i=0..sizeof(ethg)-1 { 123 | ethg[i] <--> eth[i].phys; 124 | eth[i].netwOut --> networkLayer.ifIn[sizeof(pppg)+i]; 125 | eth[i].netwIn <-- networkLayer.ifOut[sizeof(pppg)+i]; 126 | } 127 | } 128 | 129 | -------------------------------------------------------------------------------- /src/nodes/inet/TraceRouter.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.inet; 2 | 3 | // 4 | //Router-Module that traces packet 5 | // 6 | 7 | import inet.base.NotificationBoard; 8 | import inet.linklayer.ethernet.EthernetInterface; 9 | import inet.linklayer.ppp.PPPInterface; 10 | import inet.networklayer.common.InterfaceTable; 11 | import inet.networklayer.ipv4.RoutingTable; 12 | import inet.util.NAMTraceWriter; 13 | 14 | 15 | // 16 | // \IP router that is able to trace packets 17 | // Tracing means that the number of packets, observed within a certain 18 | // time period, is written to a file. This observation is done 19 | // periodically within fix interval lengths. 20 | // 21 | module TraceRouter 22 | { 23 | parameters: 24 | @node(); 25 | string routingFile; 26 | gates: 27 | inout pppg[]; 28 | inout ethg[]; 29 | submodules: 30 | namTrace: NAMTraceWriter { 31 | parameters: 32 | namid = -1; // auto 33 | @display("p=330,60;i=block/sink"); 34 | } 35 | notificationBoard: NotificationBoard { 36 | parameters: 37 | @display("p=60,60;i=block/control"); 38 | } 39 | interfaceTable: InterfaceTable { 40 | parameters: 41 | @display("p=150,60;i=block/table"); 42 | } 43 | routingTable: RoutingTable { 44 | parameters: 45 | IPForward = true; 46 | routerId = "auto"; 47 | routingFile = routingFile; 48 | @display("p=240,60;i=block/table"); 49 | } 50 | networkLayer: NetworkLayer_hack { 51 | parameters: 52 | tracingOn = true; 53 | spoofingOn = false; 54 | @display("p=200,141;i=block/fork;q=queue"); 55 | gates: 56 | ifIn[sizeof(pppg)+sizeof(ethg)]; 57 | ifOut[sizeof(pppg)+sizeof(ethg)]; 58 | } 59 | ppp[sizeof(pppg)]: PPPInterface { 60 | parameters: 61 | @display("p=90,257,row,110;q=l2queue;i=block/ifcard"); 62 | } 63 | eth[sizeof(ethg)]: EthernetInterface { 64 | parameters: 65 | @display("p=145,257,row,110;q=l2queue;i=block/ifcard"); 66 | } 67 | connections allowunconnected: 68 | // connections to network outside 69 | for i=0..sizeof(pppg)-1 { 70 | pppg[i] <--> ppp[i].phys; 71 | ppp[i].netwOut --> networkLayer.ifIn[i]; 72 | ppp[i].netwIn <-- networkLayer.ifOut[i]; 73 | } 74 | 75 | for i=0..sizeof(ethg)-1 { 76 | ethg[i] <--> eth[i].phys; 77 | eth[i].netwOut --> networkLayer.ifIn[sizeof(pppg)+i]; 78 | eth[i].netwIn <-- networkLayer.ifOut[sizeof(pppg)+i]; 79 | } 80 | } 81 | 82 | -------------------------------------------------------------------------------- /src/nodes/inet/WebServer.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.inet; 2 | 3 | import inet.base.NotificationBoard; 4 | import inet.linklayer.ethernet.EthernetInterface; 5 | import inet.linklayer.ppp.PPPInterface; 6 | import inet.networklayer.common.InterfaceTable; 7 | import inet.networklayer.ipv4.RoutingTable; 8 | import inet.nodes.inet.NetworkLayer; 9 | import inet.util.NAMTraceWriter; 10 | import inet.util.TCPDump; 11 | import scadasim.applications.pingApp.GenericICMPPingApplication; 12 | import scadasim.applications.tcpApp.GenericTCPApplication; 13 | import scadasim.transport.tcp.TCP_hack; 14 | import scadasim.transport.udp.UDP_hack; 15 | import inet.transport.tcp.TCP; 16 | 17 | // 18 | // WebServer: Server system for web traffic profile using TCP as 19 | // transport protocol. 20 | // This profile generates small client requests and many large 21 | // server replies. 22 | // 23 | // \IP host with TCP, UDP layers and applications. 24 | // 25 | module WebServer 26 | { 27 | parameters: 28 | @node(); 29 | int namid; 30 | int maxTCPThreadCount; 31 | gates: 32 | inout pppg[]; 33 | inout ethg[]; 34 | submodules: 35 | namTrace: NAMTraceWriter { 36 | parameters: 37 | namid = namid; 38 | @display("p=60,310;i=block/sink"); 39 | 40 | } 41 | notificationBoard: NotificationBoard { 42 | parameters: 43 | @display("p=60,70;i=block/control"); 44 | 45 | } 46 | interfaceTable: InterfaceTable { 47 | parameters: 48 | @display("p=60,150;i=block/table"); 49 | 50 | } 51 | routingTable: RoutingTable { 52 | parameters: 53 | IPForward = false; 54 | routerId = ""; 55 | routingFile = ""; 56 | @display("p=60,230;i=block/table"); 57 | 58 | } 59 | tcpApp: GenericTCPApplication { 60 | parameters: 61 | isServer = true; 62 | profileNumber = 3; 63 | port = 80; 64 | @display("p=163,67;i=block/app"); 65 | 66 | } 67 | tcp: TCP { 68 | parameters: 69 | // maxThreadCount = maxTCPThreadCount; 70 | @display("p=163,154;i=block/wheelbarrow"); 71 | 72 | } 73 | // udp: UDP_hack { 74 | // parameters: 75 | // @display("p=272,154;i=block/transport"); 76 | // 77 | // } 78 | // pingApp: GenericICMPPingApplication { 79 | // parameters: 80 | // isServer = true; 81 | // profileNumber = 21; 82 | // port = 0; 83 | // @display("i=block/app;p=343,200"); 84 | // 85 | // } 86 | networkLayer: NetworkLayer { 87 | parameters: 88 | proxyARP = false; 89 | @display("p=248,247;i=block/fork;q=queue"); 90 | 91 | gates: 92 | ifIn[sizeof(pppg)+sizeof(ethg)]; 93 | ifOut[sizeof(pppg)+sizeof(ethg)]; 94 | } 95 | ppp[sizeof(pppg)]: PPPInterface { 96 | parameters: 97 | @display("p=147,350,row,90;q=txQueue;i=block/ifcard"); 98 | 99 | } 100 | eth[sizeof(ethg)]: EthernetInterface { 101 | parameters: 102 | @display("p=240,350,row,90;q=txQueue;i=block/ifcard"); 103 | 104 | } 105 | // tcpdump: TCPDump { 106 | // parameters: 107 | // @display("p=336,302;i=abstract/cache_s"); 108 | // gates: 109 | // ifIn[sizeof(pppg)+sizeof(ethg)]; 110 | // in2[sizeof(pppg)+sizeof(ethg)]; 111 | // ifOut[sizeof(pppg)+sizeof(ethg)]; 112 | // out2[sizeof(pppg)+sizeof(ethg)]; 113 | // } 114 | connections allowunconnected: 115 | tcpApp.tcpOut --> tcp.appIn++; 116 | tcpApp.tcpIn <-- tcp.appOut++; 117 | 118 | tcp.ipOut --> networkLayer.tcpIn; 119 | tcp.ipIn <-- networkLayer.tcpOut; 120 | 121 | // udp.ipOut --> networkLayer.udpIn; 122 | // udp.ipIn <-- networkLayer.udpOut; 123 | 124 | // networkLayer.pingOut --> pingApp.pingIn; 125 | // networkLayer.pingIn <-- pingApp.pingOut; 126 | 127 | // connections to network outside 128 | for i=0..sizeof(pppg)-1 { 129 | pppg[i] <--> ppp[i].phys; 130 | ppp[i].netwOut --> networkLayer.ifIn[i]; 131 | ppp[i].netwIn <-- networkLayer.ifOut[i]; 132 | } 133 | 134 | for i=0..sizeof(ethg)-1 { 135 | ethg[i] <--> eth[i].phys; 136 | eth[i].netwOut --> networkLayer.ifIn[sizeof(pppg)+i]; 137 | eth[i].netwIn <-- networkLayer.ifOut[sizeof(pppg)+i]; 138 | } 139 | // connections to network outside 140 | // for i=0..sizeof(pppg)-1 { 141 | // pppg[i] <--> ppp[i].phys; 142 | // ppp[i].netwOut --> tcpdump.ifIn[i]; 143 | // tcpdump.out2[i] --> networkLayer.ifIn[i]; 144 | // ppp[i].netwIn <-- tcpdump.ifOut[i]; 145 | // tcpdump.in2[i] <-- networkLayer.ifOut[i]; 146 | // } 147 | // 148 | // for i=0..sizeof(ethg)-1 { 149 | // ethg[i] <--> eth[i].phys; 150 | // eth[i].netwOut --> tcpdump.ifIn[sizeof(pppg)+i]; 151 | // tcpdump.out2[sizeof(pppg)+i] --> networkLayer.ifIn[sizeof(pppg)+i]; 152 | // eth[i].netwIn <-- tcpdump.ifOut[sizeof(pppg)+i]; 153 | // tcpdump.in2[sizeof(pppg)+i] <-- networkLayer.ifOut[sizeof(pppg)+i]; 154 | // } 155 | 156 | } 157 | 158 | -------------------------------------------------------------------------------- /src/nodes/inet/WormHost.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.inet; 2 | 3 | import inet.base.NotificationBoard; 4 | import inet.linklayer.ethernet.EthernetInterface; 5 | import inet.linklayer.ppp.PPPInterface; 6 | import inet.networklayer.common.InterfaceTable; 7 | import inet.networklayer.ipv4.RoutingTable; 8 | import inet.util.NAMTraceWriter; 9 | import scadasim.applications.worm.UDPWormVictim; 10 | 11 | // 12 | // Compound module which behaves as infected or vulnerable worm host in a 13 | // worm propagation. 14 | // Therefore, UDPWormVictim is included in addition to the normal 15 | // TCP/IP layers 16 | // 17 | module WormHost 18 | { 19 | parameters: 20 | @node(); 21 | int namid; 22 | gates: 23 | inout pppg[]; 24 | inout ethg[]; 25 | submodules: 26 | namTrace: NAMTraceWriter { 27 | parameters: 28 | namid = namid; 29 | @display("p=60,310;i=block/sink"); 30 | } 31 | notificationBoard: NotificationBoard { 32 | parameters: 33 | @display("p=60,70;i=block/control"); 34 | } 35 | interfaceTable: InterfaceTable { 36 | parameters: 37 | @display("p=60,150;i=block/table"); 38 | } 39 | routingTable: RoutingTable { 40 | parameters: 41 | IPForward = false; 42 | routerId = ""; 43 | routingFile = ""; 44 | @display("p=60,230;i=block/table"); 45 | } 46 | udpWormVictim: UDPWormVictim { 47 | parameters: 48 | @display("p=272,154;i=old/telnet"); 49 | } 50 | networkLayer: NetworkLayer_hack { 51 | parameters: 52 | proxyARP = false; 53 | tracingOn = false; 54 | spoofingOn = false; 55 | @display("p=248,247;i=block/fork;q=queue"); 56 | gates: 57 | ifIn[sizeof(pppg)+sizeof(ethg)]; 58 | ifOut[sizeof(pppg)+sizeof(ethg)]; 59 | } 60 | ppp[sizeof(pppg)]: PPPInterface { 61 | parameters: 62 | @display("p=205,350,row,90;q=txQueue;i=block/ifcard"); 63 | 64 | } 65 | eth[sizeof(ethg)]: EthernetInterface { 66 | parameters: 67 | @display("p=240,350,row,90;q=txQueue;i=block/ifcard"); 68 | 69 | } 70 | connections allowunconnected: 71 | udpWormVictim.ipOut --> networkLayer.udpIn; 72 | udpWormVictim.ipIn <-- networkLayer.udpOut; 73 | 74 | 75 | // connections to network outside 76 | for i=0..sizeof(pppg)-1 { 77 | pppg[i] <--> ppp[i].phys; 78 | ppp[i].netwOut --> networkLayer.ifIn[i]; 79 | ppp[i].netwIn <-- networkLayer.ifOut[i]; 80 | } 81 | 82 | for i=0..sizeof(ethg)-1 { 83 | ethg[i] <--> eth[i].phys; 84 | eth[i].netwOut --> networkLayer.ifIn[sizeof(pppg)+i]; 85 | eth[i].netwIn <-- networkLayer.ifOut[sizeof(pppg)+i]; 86 | } 87 | } 88 | 89 | -------------------------------------------------------------------------------- /src/nodes/scada/Historian.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.scada; 2 | 3 | import inet.base.NotificationBoard; 4 | import inet.linklayer.ethernet.EthernetInterface; 5 | import inet.linklayer.ppp.PPPInterface; 6 | import inet.networklayer.common.InterfaceTable; 7 | import inet.networklayer.ipv4.RoutingTable; 8 | import inet.nodes.inet.NetworkLayer; 9 | import inet.util.NAMTraceWriter; 10 | import scadasim.applications.pingApp.GenericICMPPingApplication; 11 | import scadasim.applications.tcpApp.GenericTCPApplication; 12 | import scadasim.transport.tcp.TCP_hack; 13 | import scadasim.transport.udp.UDP_hack; 14 | import inet.transport.tcp.TCP; 15 | 16 | // 17 | // InteractiveServer: Server system for interactive traffic profile using 18 | // TCP as transport protocol. 19 | // This profile generates a similar number of equally large client requests 20 | // and server replies. 21 | // 22 | // \IP host with TCP, UDP layers and applications. 23 | // 24 | module Historian 25 | { 26 | parameters: 27 | @node(); 28 | int namid; 29 | int maxTCPThreadCount; 30 | gates: 31 | inout pppg[]; 32 | inout ethg[]; 33 | submodules: 34 | namTrace: NAMTraceWriter { 35 | parameters: 36 | namid = namid; 37 | @display("p=60,310;i=block/sink"); 38 | 39 | } 40 | notificationBoard: NotificationBoard { 41 | parameters: 42 | @display("p=60,70;i=block/control"); 43 | 44 | } 45 | interfaceTable: InterfaceTable { 46 | parameters: 47 | @display("p=60,150;i=block/table"); 48 | 49 | } 50 | routingTable: RoutingTable { 51 | parameters: 52 | IPForward = false; 53 | routerId = ""; 54 | routingFile = ""; 55 | @display("p=60,230;i=block/table"); 56 | 57 | } 58 | // tcpApp: GenericTCPApplication { 59 | // parameters: 60 | // isServer = true; 61 | // profileNumber = 2; 62 | // port = 80; 63 | // @display("p=163,67;i=block/app"); 64 | // 65 | // } 66 | tcp: TCP { 67 | parameters: 68 | // maxThreadCount = maxTCPThreadCount; 69 | @display("p=163,154;i=block/wheelbarrow"); 70 | 71 | } 72 | // udp: UDP_hack { 73 | // parameters: 74 | // @display("p=272,154;i=block/transport"); 75 | // 76 | // } 77 | // pingApp: GenericICMPPingApplication { 78 | // parameters: 79 | // isServer = true; 80 | // profileNumber = 21; 81 | // port = 0; 82 | // @display("i=block/app;p=343,200"); 83 | // 84 | // } 85 | networkLayer: NetworkLayer { 86 | parameters: 87 | proxyARP = false; 88 | @display("p=248,247;i=block/fork;q=queue"); 89 | 90 | gates: 91 | ifIn[sizeof(pppg)+sizeof(ethg)]; 92 | ifOut[sizeof(pppg)+sizeof(ethg)]; 93 | } 94 | ppp[sizeof(pppg)]: PPPInterface { 95 | parameters: 96 | @display("p=202,350,row,90;q=txQueue;i=block/ifcard"); 97 | 98 | } 99 | eth[sizeof(ethg)]: EthernetInterface { 100 | parameters: 101 | @display("p=349,350,row,90;q=txQueue;i=block/ifcard"); 102 | 103 | } 104 | connections allowunconnected: 105 | // tcpApp.tcpOut --> tcp.appIn++; 106 | // tcpApp.tcpIn <-- tcp.appOut++; 107 | 108 | tcp.ipOut --> networkLayer.tcpIn; 109 | tcp.ipIn <-- networkLayer.tcpOut; 110 | 111 | // udp.ipOut --> networkLayer.udpIn; 112 | // udp.ipIn <-- networkLayer.udpOut; 113 | // 114 | // networkLayer.pingOut --> pingApp.pingIn; 115 | // networkLayer.pingIn <-- pingApp.pingOut; 116 | 117 | // connections to network outside 118 | for i=0..sizeof(pppg)-1 { 119 | pppg[i] <--> ppp[i].phys; 120 | ppp[i].netwOut --> networkLayer.ifIn[i]; 121 | ppp[i].netwIn <-- networkLayer.ifOut[i]; 122 | } 123 | 124 | for i=0..sizeof(ethg)-1 { 125 | ethg[i] <--> eth[i].phys; 126 | eth[i].netwOut --> networkLayer.ifIn[sizeof(pppg)+i]; 127 | eth[i].netwIn <-- networkLayer.ifOut[sizeof(pppg)+i]; 128 | } 129 | } 130 | 131 | -------------------------------------------------------------------------------- /src/nodes/scada/MTU.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.scada; 2 | 3 | import inet.base.NotificationBoard; 4 | import inet.linklayer.ethernet.EthernetInterface; 5 | import inet.linklayer.ppp.PPPInterface; 6 | import inet.networklayer.common.InterfaceTable; 7 | import inet.networklayer.ipv4.RoutingTable; 8 | import inet.nodes.inet.NetworkLayer; 9 | import inet.util.NAMTraceWriter; 10 | import scadasim.applications.pingApp.GenericICMPPingApplication; 11 | import scadasim.applications.tcpApp.GenericTCPApplication; 12 | import scadasim.transport.tcp.TCP_hack; 13 | import scadasim.transport.udp.UDP_hack; 14 | import inet.transport.tcp.TCP; 15 | import scadasim.applications.generic.InetUser; 16 | 17 | 18 | // 19 | // WebServer: Server system for web traffic profile using TCP as 20 | // transport protocol. 21 | // This profile generates small client requests and many large 22 | // server replies. 23 | // 24 | // \IP host with TCP, UDP layers and applications. 25 | // 26 | module MTU 27 | { 28 | parameters: 29 | @node(); 30 | int namid; 31 | int maxTCPThreadCount; 32 | 33 | gates: 34 | inout pppg[]; 35 | inout ethg[]; 36 | submodules: 37 | namTrace: NAMTraceWriter { 38 | parameters: 39 | namid = namid; 40 | @display("p=60,310;i=block/sink"); 41 | 42 | } 43 | notificationBoard: NotificationBoard { 44 | parameters: 45 | @display("p=60,70;i=block/control"); 46 | 47 | } 48 | interfaceTable: InterfaceTable { 49 | parameters: 50 | @display("p=60,150;i=block/table"); 51 | 52 | } 53 | routingTable: RoutingTable { 54 | parameters: 55 | IPForward = false; 56 | routerId = ""; 57 | routingFile = ""; 58 | @display("p=60,230;i=block/table"); 59 | 60 | } 61 | 62 | inetUser: InetUser { 63 | parameters: 64 | @display("p=60,390;i=abstract/person"); 65 | 66 | } 67 | 68 | 69 | mtuServer: GenericTCPApplication { 70 | parameters: 71 | isServer = true; 72 | profileNumber = 3; 73 | port = 80; 74 | 75 | @display("p=163,67;i=block/app"); 76 | 77 | } 78 | 79 | mtuClient: GenericTCPApplication { 80 | parameters: 81 | isServer = false; 82 | profileNumber = 5; 83 | port = 1; 84 | @display("p=267,67;i=block/app"); 85 | 86 | } 87 | 88 | tcp: TCP { 89 | parameters: 90 | //maxThreadCount = maxTCPThreadCount; 91 | 92 | @display("p=163,154;i=block/wheelbarrow"); 93 | 94 | } 95 | // udp: UDP_hack { 96 | // parameters: 97 | // @display("p=272,154;i=block/transport"); 98 | // 99 | // } 100 | // pingApp: GenericICMPPingApplication { 101 | // parameters: 102 | // isServer = true; 103 | // profileNumber = 21; 104 | // port = 0; 105 | // @display("i=block/app;p=343,200"); 106 | // 107 | // } 108 | networkLayer: NetworkLayer { 109 | parameters: 110 | proxyARP = false; 111 | @display("p=248,247;i=block/fork;q=queue"); 112 | 113 | gates: 114 | ifIn[sizeof(pppg)+sizeof(ethg)]; 115 | ifOut[sizeof(pppg)+sizeof(ethg)]; 116 | } 117 | ppp[sizeof(pppg)]: PPPInterface { 118 | parameters: 119 | @display("p=147,350,row,90;q=txQueue;i=block/ifcard"); 120 | 121 | } 122 | eth[sizeof(ethg)]: EthernetInterface { 123 | parameters: 124 | @display("p=331,343,row,90;q=txQueue;i=block/ifcard"); 125 | 126 | } 127 | connections allowunconnected: 128 | mtuServer.tcpOut --> tcp.appIn++; 129 | mtuServer.tcpIn <-- tcp.appOut++; 130 | 131 | mtuClient.tcpIn <-- tcp.appOut++; 132 | mtuClient.tcpOut --> tcp.appIn++; 133 | 134 | tcp.ipOut --> networkLayer.tcpIn; 135 | tcp.ipIn <-- networkLayer.tcpOut; 136 | 137 | // udp.ipOut --> networkLayer.udpIn; 138 | // udp.ipIn <-- networkLayer.udpOut; 139 | 140 | // networkLayer.pingOut --> pingApp.pingIn; 141 | // networkLayer.pingIn <-- pingApp.pingOut; 142 | 143 | // connections to network outside 144 | for i=0..sizeof(pppg)-1 { 145 | pppg[i] <--> ppp[i].phys; 146 | ppp[i].netwOut --> networkLayer.ifIn[i]; 147 | ppp[i].netwIn <-- networkLayer.ifOut[i]; 148 | } 149 | 150 | for i=0..sizeof(ethg)-1 { 151 | ethg[i] <--> eth[i].phys; 152 | eth[i].netwOut --> networkLayer.ifIn[sizeof(pppg)+i]; 153 | eth[i].netwIn <-- networkLayer.ifOut[sizeof(pppg)+i]; 154 | } 155 | } 156 | 157 | -------------------------------------------------------------------------------- /src/nodes/scada/PLC.ned: -------------------------------------------------------------------------------- 1 | package scadasim.nodes.scada; 2 | 3 | import inet.base.NotificationBoard; 4 | import inet.linklayer.ethernet.EthernetInterface; 5 | import inet.linklayer.ppp.PPPInterface; 6 | import inet.networklayer.common.InterfaceTable; 7 | import inet.networklayer.ipv4.RoutingTable; 8 | import inet.nodes.inet.NetworkLayer; 9 | import inet.util.NAMTraceWriter; 10 | import scadasim.applications.pingApp.GenericICMPPingApplication; 11 | import scadasim.applications.tcpApp.GenericTCPApplication; 12 | import scadasim.transport.tcp.TCP_hack; 13 | import scadasim.transport.udp.UDP_hack; 14 | import inet.transport.tcp.TCP; 15 | 16 | // 17 | // WebServer: Server system for web traffic profile using TCP as 18 | // transport protocol. 19 | // This profile generates small client requests and many large 20 | // server replies. 21 | // 22 | // \IP host with TCP, UDP layers and applications. 23 | // 24 | module PLC 25 | { 26 | parameters: 27 | @node(); 28 | int namid; 29 | int maxTCPThreadCount; 30 | gates: 31 | inout pppg[]; 32 | inout ethg[]; 33 | submodules: 34 | namTrace: NAMTraceWriter { 35 | parameters: 36 | namid = namid; 37 | @display("p=60,310;i=block/sink"); 38 | 39 | } 40 | notificationBoard: NotificationBoard { 41 | parameters: 42 | @display("p=60,70;i=block/control"); 43 | 44 | } 45 | interfaceTable: InterfaceTable { 46 | parameters: 47 | @display("p=60,150;i=block/table"); 48 | 49 | } 50 | routingTable: RoutingTable { 51 | parameters: 52 | IPForward = false; 53 | routerId = ""; 54 | routingFile = ""; 55 | @display("p=60,230;i=block/table"); 56 | 57 | } 58 | plcServer: GenericTCPApplication { 59 | parameters: 60 | isServer = true; 61 | profileNumber = 5; 62 | port = 502; 63 | @display("p=163,67;i=block/app"); 64 | 65 | } 66 | tcp: TCP { 67 | parameters: 68 | //maxThreadCount = maxTCPThreadCount; 69 | @display("p=163,154;i=block/wheelbarrow"); 70 | 71 | } 72 | // udp: UDP_hack { 73 | // parameters: 74 | // @display("p=272,154;i=block/transport"); 75 | // 76 | // } 77 | // pingApp: GenericICMPPingApplication { 78 | // parameters: 79 | // isServer = true; 80 | // profileNumber = 21; 81 | // port = 0; 82 | // @display("i=block/app;p=343,200"); 83 | // 84 | // } 85 | networkLayer: NetworkLayer { 86 | parameters: 87 | proxyARP = false; 88 | @display("p=248,247;i=block/fork;q=queue"); 89 | 90 | gates: 91 | ifIn[sizeof(pppg)+sizeof(ethg)]; 92 | ifOut[sizeof(pppg)+sizeof(ethg)]; 93 | } 94 | ppp[sizeof(pppg)]: PPPInterface { 95 | parameters: 96 | @display("p=147,350,row,90;q=txQueue;i=block/ifcard"); 97 | 98 | } 99 | eth[sizeof(ethg)]: EthernetInterface { 100 | parameters: 101 | @display("p=240,350,row,90;q=txQueue;i=block/ifcard"); 102 | 103 | } 104 | connections allowunconnected: 105 | plcServer.tcpOut --> tcp.appIn++; 106 | plcServer.tcpIn <-- tcp.appOut++; 107 | 108 | tcp.ipOut --> networkLayer.tcpIn; 109 | tcp.ipIn <-- networkLayer.tcpOut; 110 | 111 | // udp.ipOut --> networkLayer.udpIn; 112 | // udp.ipIn <-- networkLayer.udpOut; 113 | 114 | // networkLayer.pingOut --> pingApp.pingIn; 115 | // networkLayer.pingIn <-- pingApp.pingOut; 116 | 117 | // connections to network outside 118 | for i=0..sizeof(pppg)-1 { 119 | pppg[i] <--> ppp[i].phys; 120 | ppp[i].netwOut --> networkLayer.ifIn[i]; 121 | ppp[i].netwIn <-- networkLayer.ifOut[i]; 122 | } 123 | 124 | for i=0..sizeof(ethg)-1 { 125 | ethg[i] <--> eth[i].phys; 126 | eth[i].netwOut --> networkLayer.ifIn[sizeof(pppg)+i]; 127 | eth[i].netwIn <-- networkLayer.ifOut[sizeof(pppg)+i]; 128 | } 129 | } 130 | 131 | -------------------------------------------------------------------------------- /src/package.ned: -------------------------------------------------------------------------------- 1 | package scadasim; 2 | 3 | @license(LGPL); 4 | -------------------------------------------------------------------------------- /src/scadasim: -------------------------------------------------------------------------------- 1 | ../out/gcc-debug/src/scadasim -------------------------------------------------------------------------------- /src/transport/contract/UDPSocketVector.cc: -------------------------------------------------------------------------------- 1 | #include "UDPSocketVector.h" 2 | 3 | /** 4 | * @brief Small utility class for managing a large number of UDPSocket objects. 5 | * 6 | * This class is just a copy of the functionality of TCPSocketMap. 7 | * In comparison to TCPSocketMap, however, remote Port and Address are used 8 | * for unique identification of a connection instead of connectionId. 9 | * 10 | * @class UDPSocketVector 11 | */ 12 | UDPSocketVector::UDPSocketVector() 13 | { 14 | } 15 | 16 | UDPSocketVector::~UDPSocketVector() 17 | { 18 | } 19 | 20 | /** 21 | * Searches for the UDPSocket that corresponds to the the remote information 22 | * of the received UDP message. This information is extracted of the 23 | * UDPControlInfo contained in UDP messages. 24 | * 25 | * @param msg Received UDP message 26 | * @return Corresponding UDP socket 27 | */ 28 | UDPSocket *UDPSocketVector::findSocketFor(cMessage *msg) 29 | { 30 | UDPControlInfo *ctrl = dynamic_cast (msg->getControlInfo()); 31 | if (!ctrl) 32 | opp_error("UDPSocketVector: findSocketFor(): no UDPControl info in message (not from UDP?)"); 33 | SocketVector::iterator i = socketVector.begin(); 34 | while (i != socketVector.end()) 35 | { 36 | if ((*i)->remoteAddr == ctrl->getSrcAddr()) 37 | if ((*i)->remotePort == ctrl->getSrcPort()) 38 | break; 39 | i++; 40 | } 41 | return (i == socketVector.end()) ? NULL : (*i)->socket; 42 | } 43 | 44 | /** 45 | * First the method checks if a socket with these remote informations 46 | * already exists. If not, the new socket is added. 47 | * 48 | * @param socket UDPSocket belonging to the received message information 49 | * @param init Received UDP message 50 | */ 51 | void UDPSocketVector::addSocket(UDPSocket *socket, cMessage *init) 52 | { 53 | UDPControlInfo *ctrl = dynamic_cast (init->getControlInfo()); 54 | if (!ctrl) 55 | opp_error("UDPSocketVector: findSocketFor(): no UDPControl info in message (not from UDP?)"); 56 | SocketVector::iterator i = socketVector.begin(); 57 | while (i != socketVector.end()) 58 | { 59 | if ((*i)->remoteAddr == ctrl->getSrcAddr()) 60 | if ((*i)->remotePort == ctrl->getSrcPort()) 61 | break; 62 | i++; 63 | } 64 | ASSERT(i == socketVector.end()); 65 | socketVector.push_back(new UDPSocketVectorInfo(socket, ctrl->getSrcAddr(), ctrl->getSrcPort())); 66 | } 67 | 68 | /** 69 | * First the method checks if a socket with these remote informations 70 | * already exists. If not, the new socket is added. 71 | * 72 | * @param socket UDPSocket belonging to the received message information 73 | * @param t TargetInfo of received UDP message 74 | */ 75 | void UDPSocketVector::addSocket(UDPSocket *socket, TargetInfo &t) 76 | { 77 | SocketVector::iterator i = socketVector.begin(); 78 | while (i != socketVector.end()) 79 | { 80 | if ((*i)->remoteAddr == t.address) 81 | if ((*i)->remotePort == t.port) 82 | break; 83 | i++; 84 | } 85 | ASSERT(i == socketVector.end()); 86 | socketVector.push_back(new UDPSocketVectorInfo(socket, t.address, t.port)); 87 | } 88 | 89 | /** 90 | * Checks if this socket really is contained in the vector. 91 | * If so, delete it from vector and return it. 92 | * 93 | * @param socket UDPSocket to delete 94 | * @return Returns UDPSocket that should be deleted 95 | */ 96 | UDPSocket *UDPSocketVector::removeSocket(UDPSocket *socket) 97 | { 98 | SocketVector::iterator i = socketVector.begin(); 99 | while (i != socketVector.end()) 100 | { 101 | if ((*i)->socket->getSocketId() == socket->getSocketId()) 102 | { 103 | socketVector.erase(i); 104 | break; 105 | } 106 | } 107 | return socket; 108 | } 109 | 110 | /** 111 | * Deletes all UDPSocket contained in the vector. 112 | */ 113 | void UDPSocketVector::deleteSockets() 114 | { 115 | for (SocketVector::iterator i = socketVector.begin(); i != socketVector.end(); ++i) 116 | delete *i; 117 | socketVector.clear(); 118 | } 119 | -------------------------------------------------------------------------------- /src/transport/contract/UDPSocketVector.h: -------------------------------------------------------------------------------- 1 | #ifndef UDPSOCKETVECTOR_H_ 2 | #define UDPSOCKETVECTOR_H_ 3 | 4 | #include 5 | #include 6 | #include "UDPSocket.h" 7 | #include "TransmissionConfig.h" 8 | #include "IPvXAddress.h" 9 | #include "ReaSEDefs.h" 10 | 11 | // 12 | // this is just a copy of the functionality of TCPSocketMap 13 | // 14 | // compared to TCPSocketMap we use the remote Port and Address 15 | // instead of using the connectionId. 16 | // 17 | // 18 | 19 | /** 20 | * This struct unites the informations of a UDP socket: UDPSocket, IPvX 21 | * address, and port. 22 | */ 23 | struct UDPSocketVectorInfo 24 | { 25 | UDPSocket *socket; 26 | IPvXAddress remoteAddr; 27 | int remotePort; 28 | UDPSocketVectorInfo(UDPSocket *sock, IPvXAddress addr, int port) 29 | { 30 | socket = sock; 31 | remoteAddr =addr; 32 | remotePort = port; 33 | } 34 | }; 35 | 36 | /** 37 | * @brief Small utility class for managing a large number of UDPSocket objects. 38 | * 39 | * This class is just a copy of the functionality of TCPSocketMap. 40 | * In comparison to TCPSocketMap, however, remote Port and Address are used 41 | * for unique identification of a connection instead of connectionId. 42 | * 43 | * @class UDPSocketVector 44 | */ 45 | class REASE_API UDPSocketVector 46 | { 47 | protected: 48 | typedef std::vector SocketVector; 49 | /// Vector of UDP Sockets 50 | SocketVector socketVector; 51 | public: 52 | UDPSocketVector(); 53 | ~UDPSocketVector(); 54 | /// Returns UDPSocket corresponding to a specific message 55 | UDPSocket *findSocketFor(cMessage *msg); 56 | /// Adds a new UDPSocket to the vector 57 | void addSocket(UDPSocket *socket, cMessage *initialMsg); 58 | /// Adds a new UDPSocket to the vector 59 | void addSocket(UDPSocket *socket, TargetInfo &t); 60 | /// Deletes a UDPSocket from the vector 61 | UDPSocket *removeSocket(UDPSocket *socket); 62 | /// Returns size of the current UDPSocket vector 63 | unsigned int size() {return socketVector.size();} 64 | /// Clear complete UDPSocket vector 65 | void deleteSockets(); 66 | }; 67 | 68 | #endif /*UDPSOCKETMAP_H_*/ 69 | -------------------------------------------------------------------------------- /src/transport/tcp/TCPConnection_hack.h: -------------------------------------------------------------------------------- 1 | #ifndef TCPCONNECTION_HACK_H_ 2 | #define TCPCONNECTION_HACK_H_ 3 | #include 4 | #include "TCPConnection.h" 5 | #include "ReaSEDefs.h" 6 | 7 | /** 8 | * @brief Extends the original TCP implementation by limited number of open 9 | * TCP connections 10 | * 11 | * This class is derived from the original TCPConnection class. 12 | * The extension allows for simulation of a limited number of open TCP 13 | * connections per host system. Thus, overload situations at endsystems 14 | * can be simulated, too. 15 | * 16 | * @class TCPConnection_hack 17 | */ 18 | class REASE_API TCPConnection_hack: public TCPConnection { 19 | protected: 20 | /// @brief state variable: Worker thread or not? 21 | bool worker; 22 | public: 23 | TCPConnection_hack(TCP *mod, int appGateIndex, int connId) : 24 | TCPConnection(mod, appGateIndex, connId) { 25 | this->worker = false; 26 | } 27 | ; 28 | ~TCPConnection_hack(); 29 | int getTCPQueueDrops(); 30 | int getTCPRecvQueueLen(); 31 | int getFreeSpaceRecvQueue(); 32 | int getMaxRecvQueueLimit(); 33 | const char * getTCPRecvQueueInfo(); 34 | protected: 35 | /// @brief Process incoming TCP segment 36 | TCPEventCode processSegmentInListen(TCPSegment *tcpseg, IPvXAddress src, 37 | IPvXAddress dest); 38 | /// @brief Sets this TCPConnection to the state of a worker thread 39 | void setWorkerThread() { 40 | this->worker = true; 41 | } 42 | ; 43 | /// @brief Returns if this connections is a worker thread or not 44 | bool isWorkerThread() { 45 | return worker; 46 | } 47 | ; 48 | /// @brief Clone a listening connection. Used for forking. 49 | TCPConnection *cloneListeningConnection(); 50 | /// @brief Implements the slightly changed TCP state machine 51 | bool performStateTransition(const TCPEventCode& event); 52 | 53 | void sendToApp(cMessage *msg); 54 | }; 55 | 56 | #endif /*TCPCONNECTION_HACK_H_*/ 57 | -------------------------------------------------------------------------------- /src/transport/tcp/TCP_hack.cc: -------------------------------------------------------------------------------- 1 | #include "TCP_hack.h" 2 | #include "TCPConnection_hack.h" 3 | #include "TCPSegment.h" 4 | #include "IPControlInfo.h" 5 | #include "TCPCommand_m.h" 6 | //#include "DataDump.h" 7 | Define_Module( TCP_hack); 8 | 9 | /** 10 | * @brief Extends the original TCP implementation by limited number of open 11 | * TCP connections 12 | * 13 | * This class is derived from the original TCP class. 14 | * The extension allows for simulation of a limited number of open TCP 15 | * connections per host system. Thus, overload situations at endsystems 16 | * can be simulated, too. 17 | * 18 | * @class TCP_hack 19 | */ 20 | 21 | /** 22 | * Initializes maxThreadCount to the number given in the NED file. 23 | * If a negative value is given, it will be set to INT_MAX. 24 | */ 25 | void TCP_hack::initialize() 26 | { 27 | TCP::initialize(); 28 | 29 | maxThreadCount = par("maxThreadCount"); 30 | currentConnectionCount = 0; 31 | droppedConnections = 0; 32 | WATCH(maxThreadCount); 33 | WATCH(currentConnectionCount); 34 | 35 | if (maxThreadCount <= 0) 36 | maxThreadCount = INT_MAX; 37 | } 38 | 39 | /** 40 | * Similar to the createConnection method of the original TCP implementation 41 | */ 42 | TCPConnection *TCP_hack::createConnection(int appGateIndex, int connId) 43 | { 44 | return new TCPConnection_hack(this, appGateIndex, connId); 45 | } 46 | 47 | int TCP_hack::getCurrentNumberOfConnection() { 48 | return currentConnectionCount; 49 | } 50 | 51 | int TCP_hack::getCurrentNumberOfDroppedConnections() { 52 | return droppedConnections; 53 | } 54 | 55 | int TCP_hack::getMaxThreadCount() { 56 | return maxThreadCount; 57 | } 58 | 59 | //void TCP_hack::dump(cMessage *msg, TCPConnection *conn, bool received) { 60 | // cModuleType *moduleType = cModuleType::get("scadasim.util.DataDump"); 61 | // cModule *mod = moduleType->createScheduleInit("datadump", this); 62 | // DataDump *dd = check_and_cast (mod); 63 | // dd->handleMessage(msg, conn, received); 64 | // dd->deleteModule(); 65 | //} 66 | /** 67 | * Handle method for message that arrivedOn "appIn". 68 | * Handling for other messages is done by original TCP implementation 69 | */ 70 | void TCP_hack::handleMessage(cMessage *msg) 71 | { 72 | if (msg->arrivedOn("appIn")) 73 | { 74 | TCPCommand *controlInfo = check_and_cast (msg->getControlInfo()); 75 | int appGateIndex = msg->getArrivalGate()->getIndex(); 76 | int connId = controlInfo->getConnId(); 77 | 78 | TCPConnection *conn = findConnForApp(appGateIndex, connId); 79 | 80 | if (!conn) 81 | { 82 | // 83 | // create a new connection that only accepts threadCountMax 84 | // concurrently connections. This is for forking-sockets only 85 | // 86 | conn = createConnection(appGateIndex, connId); 87 | 88 | // add into appConnMap here; it'll be added to connMap during processing 89 | // the OPEN command in TCPConnection's processAppCommand(). 90 | AppConnKey key; 91 | key.appGateIndex = appGateIndex; 92 | key.connId = connId; 93 | tcpAppConnMap[key] = conn; 94 | 95 | tcpEV<< "TCP connection created for " << msg << "\n"; 96 | } 97 | // else 98 | // if(msg->getKind()== TCP_C_SEND) 99 | // TCP_hack::dump(msg,conn,false); 100 | 101 | try { 102 | bool ret = conn->processAppCommand(msg); 103 | 104 | if (!ret) 105 | removeConnection(conn); 106 | } catch (cException& e) { 107 | printf("error: %s\n",e.what()); 108 | } 109 | if (ev.isGUI()) 110 | updateDisplayString(); 111 | } 112 | else 113 | TCP::handleMessage(msg); 114 | 115 | } 116 | 117 | 118 | /** 119 | * @return Returns true if another connection can be accepted and false if 120 | * connection limit already is reached. 121 | */ 122 | bool TCP_hack::acceptAnotherConnection() 123 | { 124 | if (maxThreadCount > currentConnectionCount) { 125 | currentConnectionCount++; 126 | droppedConnections = 0; 127 | return true; 128 | }else{ 129 | droppedConnections++; 130 | return false; 131 | } 132 | } 133 | 134 | /** 135 | * decreases number of open connections in case a half open connection is 136 | * closed (called by TCPConnection_hack). 137 | */ 138 | bool TCP_hack::canceledHalfOpenConnection() 139 | { 140 | if (currentConnectionCount <= 0) 141 | { 142 | return false; 143 | } 144 | else 145 | { 146 | currentConnectionCount--; 147 | return true; 148 | } 149 | } 150 | 151 | -------------------------------------------------------------------------------- /src/transport/tcp/TCP_hack.h: -------------------------------------------------------------------------------- 1 | #ifndef TCP_HACK_H_ 2 | #define TCP_HACK_H_ 3 | 4 | #include 5 | #include 6 | #include "TCP.h" 7 | #include "ReaSEDefs.h" 8 | 9 | /** 10 | * @brief Extends the original TCP implementation by limited number of open 11 | * TCP connections 12 | * 13 | * This class is derived from the original TCP class. 14 | * The extension allows for simulation of a limited number of open TCP 15 | * connections per host system. Thus, overload situations at endsystems 16 | * can be simulated, too. 17 | * 18 | * @class TCP_hack 19 | */ 20 | class REASE_API TCP_hack : public TCP 21 | { 22 | protected: 23 | /// Maximum number of open TCP connections allowed 24 | int maxThreadCount; 25 | /// Current number of open TCP connections 26 | int currentConnectionCount; 27 | int droppedConnections; 28 | public: 29 | /// @brief Checks wether another new connection can be opened 30 | bool acceptAnotherConnection(); 31 | /// @brief Decreases number of currently open connections 32 | bool canceledHalfOpenConnection(); 33 | 34 | //void dump(cMessage *msg, TCPConnection *tcpConn, bool received); 35 | int getCurrentNumberOfConnection(); 36 | int getCurrentNumberOfDroppedConnections(); 37 | int getMaxThreadCount(); 38 | protected: 39 | /// Factory method 40 | virtual TCPConnection *createConnection(int appGateIndex, int connId); 41 | /// Handle method for messages from application 42 | virtual void handleMessage(cMessage *msg); 43 | /// Initializiation of TCP instance and new parameters 44 | virtual void initialize(); 45 | }; 46 | 47 | #endif /*TCP_HACK_H_*/ 48 | -------------------------------------------------------------------------------- /src/transport/tcp/TCP_hack.ned: -------------------------------------------------------------------------------- 1 | package scadasim.transport.tcp; 2 | 3 | // 4 | // Overwrites original TCP.ned file. 5 | // This module allows for definition of a maximum number of open connections 6 | // that are accepted by a listening socket concurrently. 7 | // Such a limitation is necessary to simulate overload situations. 8 | // 9 | simple TCP_hack extends inet.transport.tcp.TCP 10 | { 11 | parameters: 12 | delayedAcksEnabled = default(false); // delayed ACKs enabled/disabled 13 | nagleEnabled = default(true); // Nagle's algorithm (RFC 896) enabled/disabled 14 | limitedTransmitEnabled = default(false); // Limited Transmit algorithm (RFC 3042) 15 | // enabled/disabled (can be used for TCPReno/TCPTahoe/TCPNewReno/TCPNoCongestionControl) 16 | increasedIWEnabled = default(false); // increased initial window (min(4*MSS, max (2*MSS, 4380 bytes))) 17 | // (RFC 3390) enabled/disabled 18 | sackSupport = default(false); // Selective Acknowledgment (RFC 2018, 2883, 3517) support (header option) 19 | // (SACK will be enabled for a connection if both endpoints support it) 20 | mss = default(1024); // maximum segment size 21 | advertisedWindow = default(14*this.mss); // in bytes (Note: normally, NIC queues should be at least this size) 22 | tcpAlgorithmClass = default("TCPReno"); // TCPTahoe/TCPReno/TCPNoCongestionControl/DumbTCP 23 | sendQueueClass = default("TCPMsgBasedSendQueue"); // TCPVirtualDataSendQueue/TCPMsgBasedSendQueue 24 | receiveQueueClass = default("TCPMsgBasedRcvQueue"); // TCPVirtualDataRcvQueue/TCPMsgBasedRcvQueue 25 | recordStats = default(true); // recording seqNum etc. into output vectors on/off 26 | int maxThreadCount; // how many concurrent Threads are accepted 27 | @class(TCP_hack); 28 | @display("i=block/wheelbarrow"); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/transport/udp/UDP_hack.cc: -------------------------------------------------------------------------------- 1 | #include "UDP_hack.h" 2 | #include "GenericApplicationMessage_m.h" 3 | 4 | Define_Module( UDP_hack); 5 | 6 | /** 7 | * @brief Overwrites original UDP in order to process 8 | * undeliverable GenericAppMsg messages. 9 | * 10 | * The original functionality is kept except of the processing of undeliverable 11 | * GenericAppMsg messages. Such undeliverable messages are caused by the fact 12 | * that a client's UDP socket connection is closed too early if a UDP profile 13 | * of our traffic generation is used. In the original implementation all 14 | * incoming UDP packets then are sent back to the source as ICMP error 15 | * messages. 16 | * 17 | * @class UDP_hack 18 | */ 19 | UDP_hack::UDP_hack() 20 | { 21 | } 22 | 23 | UDP_hack::~UDP_hack() 24 | { 25 | } 26 | 27 | /** 28 | * Undeliverable GenericAppMsg messages are silently discarded if the socket 29 | * connection has already been closed. All other messages are processed 30 | * according to the original UDP implementation. 31 | */ 32 | void UDP_hack::processUndeliverablePacket(UDPPacket *udpPacket, cPolymorphic *ctrl) 33 | { 34 | if (dynamic_cast (udpPacket->getEncapsulatedMsg())) 35 | { 36 | delete udpPacket; 37 | delete ctrl; 38 | } 39 | else 40 | UDP::processUndeliverablePacket(udpPacket, ctrl); 41 | } 42 | -------------------------------------------------------------------------------- /src/transport/udp/UDP_hack.h: -------------------------------------------------------------------------------- 1 | #ifndef UDP_HACK_H_ 2 | #define UDP_HACK_H_ 3 | 4 | #include 5 | #include "UDP.h" 6 | #include "UDPPacket.h" 7 | #include "UDPControlInfo_m.h" 8 | #include "ReaSEDefs.h" 9 | 10 | /** 11 | * @brief Overwrites original UDP in order to process 12 | * undeliverable GenericAppMsg messages. 13 | * 14 | * The original functionality is kept except of the processing of undeliverable 15 | * GenericAppMsg messages. Such undeliverable messages are caused by the fact 16 | * that a client's UDP socket connection is closed too early if a UDP profile 17 | * of our traffic generation is used. In the original implementation all 18 | * incoming UDP packets then are sent back to the source as ICMP error 19 | * messages. 20 | * 21 | * @class UDP_hack 22 | */ 23 | class REASE_API UDP_hack : public UDP 24 | { 25 | public: 26 | UDP_hack(); 27 | virtual ~UDP_hack(); 28 | protected: 29 | /// @brief Processes undeliverable GenericAppMsg messages 30 | virtual void processUndeliverablePacket(UDPPacket *udpPacket, cPolymorphic *ctrl); 31 | }; 32 | 33 | #endif /*UDP_HACK_H_*/ 34 | -------------------------------------------------------------------------------- /src/transport/udp/UDP_hack.ned: -------------------------------------------------------------------------------- 1 | package scadasim.transport.udp; 2 | 3 | 4 | // 5 | // Overwrites original UDP.ned file. 6 | // This module handles undeliverable GenericAppMsg messages tha otherwise 7 | // would cause ICMP error messages due to socket connections that are closed 8 | // too early. 9 | // 10 | simple UDP_hack 11 | { 12 | gates: 13 | input appIn[]; 14 | input ipIn; 15 | input ipv6In; 16 | output appOut[]; 17 | output ipOut; 18 | output ipv6Out; 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/util/DataDump.h: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | #ifndef __DATADUMP_H__ 17 | #define __DATADUMP_H__ 18 | 19 | #include 20 | #include 21 | #include "TCPConnection.h" 22 | #include 23 | #include 24 | #include 25 | 26 | /** 27 | * TODO - Generated class 28 | */ 29 | class DataDump : public cSimpleModule 30 | { 31 | private : 32 | 33 | const char *user; 34 | const char *passwd; 35 | const char *database; 36 | const char *addr; 37 | char *socket; 38 | unsigned int port; 39 | void tcpDump(cMessage *msg, MYSQL *conn, bool received, TCPConnection *tcpConn); 40 | protected: 41 | virtual void initialize(); 42 | virtual void finish(); 43 | public: 44 | void handleMessage(cMessage *msg,TCPConnection *tcpConn, bool received); 45 | const char * printPath(TCPConnection *tcpConn) ; 46 | }; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/util/DataDump.ned: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | package scadasim.util; 17 | 18 | // 19 | // TODO auto-generated module 20 | // 21 | simple DataDump 22 | { 23 | parameters: 24 | string databaseAddress = default("localhost"); 25 | string database = default("simulation"); 26 | string user = default("root"); 27 | string passwd = default("1303"); 28 | bool threadEnable = default(false); 29 | int port = default(3306); 30 | int verbosity = default(0); 31 | @display("i=block/filter"); 32 | 33 | 34 | } 35 | --------------------------------------------------------------------------------