📄 simulator-codered-100run.cpp
字号:
//====================== simulator-codered-100run.cpp ===================================
// Simulate Code Red worm propagation ( also can be used for simulating Slammer worm).
// 1. First programmed in Jan, 2002 for our Code Red modeling paper in CCS'02.
// 2. Simulate uniform scan worm, such as Code Red and Slammer.
// 3. Because of uniform scan, there is no issue of vulnerable hosts distribution and distribution of monitored IP blocks.
// Therefore, we use probability to conduct simulation ( note that in simulation we use NO MODEL).
// 4. Worm scan rate is different for different host (normal distributed), the average scan rate is \eta.
// 5. Code Red simulation paramters: N=360000, \eta=358/min, monitoring space 2^{20}. simulate 100 runs.
// 6. Add background noise to monitored data C_t and Z_t according to the hourly data from Goldsmith:
// http://lists.jammed.com/incidents/2001/07/0149.html
// 7. Notations see our monitoring and early warning paper in CCS'03.
// 8. For 100 simulation runs with DIVIDE_MINUTE=2, this program will run about 10 hours on P4 2.6GHz Linux computer.
// Modification Date: 1/22/2004.
// Add detailed inline explanation for cooperation with other researchers.
//========================================================================
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#define NUM 360000 // System population: N
#define ENDSIMUL 800 // end of simulation time. For Code Red, we use one minute as the unit time.
#define INIT_INFECTED_NUM 10 // Number of initially infected hosts: I(0)
#define SAMPLE_RUN 100 // simulate 100 times.
const double SCAN_PER_MINUTE = 358; // average scan per minute: \eta. Each host has a scan rate that is normal distributed.
// For Slammer simulation, this variable is the number of scans per second when we use
// one second as the unit time. according to CAIDA's paper, for slammer \eta=4000.
const short MONITOR_SPACE_BIT = 20; // how many IP space is used for monitor: \Omega = 2^{20}.
const short DIVIDE_MINUTE = 5; // divide a minute into several steps for simulation to achieve better accuracy.
const double SIGMA1 = 100; // standard divination for normal distribution of scan rate.
typedef enum {
healthy = 0,
danger = 1,
infected = 2,
immunized = 3
}NodeStatus_type; // Node status.一个主机节点的四种状态:好的、危险的、已经感染的、具有免疫能力的;
typedef struct { // normal distribution structure.
double average; //均值
double variance; //方差
}Normal_type;
typedef struct {
NodeStatus_type nodeStatus;
char countSource; // flag: whether this node has been count in the monitor (for unique source)
double scanRate; //感染后悔发出扫描包,扫描速率;
double prob1; // probability of finding a target for scans sent out by one infected hosts within time 1/DIVIDE_MINUTE.
double prob2; // probability of hitting monitor for scans sent out by one infected hosts within time 1/DIVIDE_MINUTE.
// We assume that the probability for scans sent out from one host in a discrete time hitting the monitor twice
// or more is negligible.
}NodeData_type; //主机节点的数据,包括节点的状态,是否被监控;prob1是已经感染的主机扫描到目的的概率,在时间间隔内!
//prob2是扫描到监控器的概率
typedef struct {
long scan; // number of scans observed in a unit time: Z_t.
long source; // number of unique sources that the monitoring system has observed until now: C_t
}MonitorCounter_type; //监视器计数,单位时间内的 扫描数和唯一的源地址
//=========================================================================
NodeData_type NodeData[NUM];
MonitorCounter_type monitorCounter; // Record monitored data Z_t and C_t.
Normal_type ScanRate;
void initNode( NodeData_type[]); // initialized status of all vulnerable hosts.
short expGenerator( short ); // exponential distribution generator.
double normalGenerator( Normal_type); // non-negative normal distribution generator.
double rand01(void); // 0-1 uniform distribution.
void infection ( NodeData_type [], long);
int main ( int argc, char * argv[] ) {
if( argc !=2) {
printf("Usage: simulator outputfilename.\n"); exit(1);
};
long oldInfectedNum, infectedNum = INIT_INFECTED_NUM ; // total infected node number.
long timeTick = 0; // simulation time tick unit.
long i,j,k, finish_timeTick, firstCount=1;
double infectedPercentage, oldInfectedPercentage;
FILE *out;
if ((out = fopen(argv[1], "wt")) == NULL) {
printf("open output file error.\n"); exit(1);
};
int monitorBit = 20, timeUnit = 1;
// add normal distribution noise to Z_t and C_t according to the hourly data from Goldsmith.
double BaseBit = 16, BaseUnit = 60,BaseNZmean = 110.5, BaseNZstd = 30, BaseNCmean = 17.4, BaseNCstd = 3.3;
double ratio = 1/BaseUnit*pow(2, monitorBit-BaseBit);
double noiseZmean = BaseNZmean * ratio;
double noiseZstd = BaseNZstd * ratio;
double noiseCmean = BaseNCmean * ratio;
double noiseCstd = BaseNCstd * ratio;
double threshold = noiseZmean * 2;
int alarmTime = 3; // when Z_t is over threshold 3 times, the Kalman filter is activated and
// C_t begins to be collected. (See our paper in CCS'03)
Normal_type noiseZ, noiseC;
noiseZ.average = noiseZmean; noiseZ.variance = noiseZstd * noiseZstd;
noiseC.average = noiseCmean; noiseC.variance = noiseCstd * noiseCstd;
int beginCount = 0, alarmFlag = 0;
time_t beginTime, endTime;
long simulTime;
for(int m=0; m<SAMPLE_RUN;m++){
double scanNumber = 0;
infectedNum = INIT_INFECTED_NUM ;
timeTick = 1; firstCount=1;
beginCount = 0; alarmFlag = 0;
initNode( NodeData );
// simulation begin.
srand( (unsigned)time( NULL ) );
(void)time( &beginTime );
double prob1,prob2,scanRate;
oldInfectedPercentage = 0;
while ( timeTick <= ENDSIMUL) {
// determine if we need to count C_t, i.e., Z_t over threshold for three times.
if ( monitorCounter.scan >= threshold )
alarmFlag ++;
else
alarmFlag = 0;
if (alarmFlag >= alarmTime){
beginCount = 1;
};
// reset the monitor counter ( non-cumulative monitor).
monitorCounter.scan = 0; // monitorCounter.source = 0;
oldInfectedNum= infectedNum;
timeTick ++;
infectedPercentage = double( infectedNum ) / double( NUM );
scanNumber = 0;
double smallValue = 0.1;
for(k=0;k<DIVIDE_MINUTE;k++){ // simulate one unit time DIVIDE_MINUTE times
for ( i=0;i<NUM; i++)
if ( NodeData[i].nodeStatus == infected ) {
// determine whether this infected node hit a target or monitor during this minute.
scanNumber += NodeData[i].scanRate;
double temp = rand01();
if( temp>=smallValue && temp < smallValue + NodeData[i].prob1 ) // the worm finds a target.
infection( NodeData, i );
temp = rand01();
if( temp>=smallValue && temp < smallValue + NodeData[i].prob2 ) { // the worm scans hit monitor.
monitorCounter.scan ++;
if ( NodeData[i].countSource == 0 && beginCount == 1 ){
NodeData[i].countSource = 1;
monitorCounter.source ++;
};
};
}
for ( i=0 ;i<NUM; i++){
if ( NodeData[i].nodeStatus == danger ) { //update current status. A newly infected host becomes infectious in the next round.
NodeData[i].nodeStatus = infected;
infectedNum ++;
};
};
};
// add noise in to Z_t.
monitorCounter.scan += long(floor(0.5 + normalGenerator(noiseZ)));
// add noise into C_t if it starts to count.
if ( monitorCounter.source >0)
monitorCounter.source += long(floor(0.5 + normalGenerator(noiseC)));
// printout this step result into file.
fprintf(out, "%ld\t%ld\t%ld\t%ld\n", timeTick,infectedNum,
monitorCounter.scan, monitorCounter.source);
scanNumber = 0;
if ( infectedNum == NUM && firstCount == 1) {
finish_timeTick = timeTick; firstCount = 0;
};
}; // end while simulation.
}; // end 100 sampel runs.
fclose(out);
(void)time(&endTime);
simulTime = (long) ( endTime -beginTime );
printf("\n Simulation finished by using %ld seconds\n Infection is over at %ld.\n", simulTime, finish_timeTick );
return 0;
} // end main.
//==============================================================================
//-----------------------------------------------------------------
double rand01(void) {
return (double(rand()) + 0.5) / ((double)RAND_MAX + 1.0); // I add 0.5 and 1.0 to achieve a balanced distribution in (0,1).
}
short expGenerator( short average ) { // exponential distribution generator.
short temp = short( - log( 1.0 - rand01() ) * double(average) ) ;
if ( temp < 1) temp = 1; // minimum infection delay time.
return temp;
}
//-----------------------------------------------------------------------------------
void initNode( NodeData_type NodeData[]) {
long i; // iteration variable.
long x;
double scanRate;
ScanRate.average = SCAN_PER_MINUTE;
ScanRate.variance = SIGMA1 * SIGMA1;
for (i=0;i< NUM; i++){
NodeData[i].nodeStatus = healthy;
NodeData[i].countSource = 0; // not counted yet by monitor.
scanRate = normalGenerator(ScanRate); // normal distribution of scan rate for each host.
if (scanRate < 1 ) scanRate = 1; // minimal scan rate is 1 per unit time.
NodeData[i].scanRate = scanRate;
scanRate = NodeData[i].scanRate;
// probability of finding a target for scans sent out by one infected hosts within time 1/DIVIDE_MINUTE.
NodeData[i].prob1 = scanRate/DIVIDE_MINUTE * double(NUM)/ pow(2,32);
// probability of hitting monitor for scans sent out by one infected hosts within time 1/DIVIDE_MINUTE.
NodeData[i].prob2 = scanRate/DIVIDE_MINUTE/pow(2, 32-MONITOR_SPACE_BIT);
};
// determine which node is infected in the initial state.
for( i= 1;i<=INIT_INFECTED_NUM; i++) {
x = long( NUM * rand01() );
NodeData[x].nodeStatus = infected;
};
// initialize counters.
monitorCounter.scan = 0; monitorCounter.source = 0;
}
//---------------------------------------------------------------------------------
void infection ( NodeData_type NodeData[], long source) {
long IP_x;
IP_x = long( rand01()*NUM ); // uniformly scan ( no dependent on the original infected host's IP address )
// update node status.
if ( NodeData[IP_x].nodeStatus == healthy)
NodeData[IP_x].nodeStatus = danger;
}
//---------------------------------------------------------------------------
double normalGenerator( Normal_type normal){ // normal distribution generator.
double temp, x ;
static double Table[151]=
{0.5000, 0.5030, 0.5160, 0.5239, 0.5319,
0.5398, 0.5478, 0.5557, 0.5636, 0.5714,
0.5793, 0.5871, 0.5948, 0.6026, 0.6103,
0.6179, 0.6255, 0.6331, 0.6406, 0.6480,
0.6554, 0.6628, 0.6700, 0.6772, 0.6844,
0.6915, 0.6985, 0.7054, 0.7123, 0.7190,
0.7257, 0.7324, 0.7389, 0.7454, 0.7517,
0.7580, 0.7642, 0.7703, 0.7764, 0.7823,
0.7881, 0.7939, 0.7995, 0.8051, 0.8106,
0.8159, 0.8212, 0.8264, 0.8315, 0.8365,
0.8413, 0.8461, 0.8508, 0.8554, 0.8599,
0.8643, 0.8686, 0.8729, 0.8770, 0.8810,
0.8849, 0.8888, 0.8925, 0.8962, 0.8997,
0.90320, 0.90658, 0.90988, 0.91809, 0.91621,
0.91924, 0.92220, 0.92507, 0.92785, 0.93056,
0.93319, 0.93574, 0.93822, 0.94062, 0.94295,
0.94520, 0.94738, 0.94950, 0.95154, 0.95352,
0.95543, 0.95728, 0.95907, 0.96080, 0.96246,
0.96407, 0.96562, 0.96712, 0.96856, 0.96995,
0.97128, 0.97257, 0.97381, 0.97500, 0.97615,
0.97725, 0.97831, 0.97932, 0.98030, 0.98124,
0.98214, 0.98300, 0.98382, 0.98461, 0.98537,
0.98610, 0.98679, 0.98745, 0.98809, 0.98870,
0.98928, 0.98988, 0.99036, 0.99086, 0.99134,
0.99180, 0.99224, 0.99266, 0.99305, 0.99343,
0.99379, 0.99413, 0.99446, 0.99477, 0.99506,
0.99534, 0.99560, 0.99586, 0.99609, 0.99632,
0.99653, 0.99674, 0.99693, 0.99711, 0.99728,
0.99745, 0.99760, 0.99774, 0.99788, 0.99801,
0.99813, 0.99825, 0.99836, 0.99846, 0.99856,
1.0 };
temp =rand01();
int sign = 1, i;
if ( temp <0.5) {
sign = -1;
temp = 1 - temp;
};
x=0;
for (i=0;i< 150; i++)
if ( temp <= Table[i] ) {
x = double( i ) / 50.0;
break;
}
if ( sign == -1 )
x = 0 - x;
temp = normal.average + x * sqrt(normal.variance);
// experiment require that normal distribution number to be non-negative.
if ( temp <=0.000000000001) temp = 0.0000001;
return temp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -