worm.cc

Go to the documentation of this file.
00001 // simple worm model based on message passing
00002 // 
00003 
00004 #include "worm.h"
00005 #include "random.h"
00006 #include "math.h"
00007 
00008 // timer for sending probes
00009 void ProbingTimer::expire(Event*) {
00010   t_->timeout();
00011 }
00012 
00013 // base class for worm: host is invulnerable by default
00014 static class WormAppClass : public TclClass {
00015 public:
00016     WormAppClass() : TclClass("Application/Worm") {}
00017     TclObject* create(int, const char*const*) {
00018         return (new WormApp());
00019     }
00020 } class_app_worm;
00021 
00022 // Initialize static variables
00023 double WormApp::total_addr_ = pow(2, 32);
00024 int WormApp::first_probe_ = 0;
00025 
00026 WormApp::WormApp() : Application() {
00027   // get probing rate from configuration
00028   bind("ScanRate", &scan_rate_);
00029 
00030   // get probing port from configuration
00031   bind("ScanPort", &scan_port_);
00032 
00033   // get probing port from configuration
00034   bind("ScanPacketSize", &p_size_);
00035 }
00036 
00037 void WormApp::process_data(int nbytes, AppData* data) {
00038   recv(nbytes);
00039 }
00040 
00041 void WormApp::recv(int nbytes) {
00042   if (!first_probe_) {
00043     first_probe_ = 1;
00044     printf("D FP %.2f\n", Scheduler::instance().clock());
00045   }
00046 
00047   //printf("D U %.2f %d\n",
00048   //       Scheduler::instance().clock(), my_addr_);
00049 }
00050 
00051 void WormApp::timeout() {
00052 }
00053 
00054 int WormApp::command(int argc, const char*const* argv) {
00055   Tcl& tcl = Tcl::instance();
00056 
00057   if (argc == 3) {
00058     if (strcmp(argv[1], "attach-agent") == 0) {
00059       agent_ = (Agent*) TclObject::lookup(argv[2]);
00060       if (agent_ == 0) {
00061     tcl.resultf("no such agent %s", argv[2]);
00062     return(TCL_ERROR);
00063       }
00064       agent_->attachApp(this);
00065       my_addr_ = agent_->addr();
00066       //printf("%d\n", my_addr_);
00067       return(TCL_OK);
00068     }
00069   }
00070 
00071   return(Application::command(argc, argv));
00072 }
00073 
00074 // Initialize stats (number of infected hosts) for DN
00075 unsigned long DnhWormApp::infect_total_ = 0;
00076 unsigned long DnhWormApp::addr_high_ = 0;
00077 unsigned long DnhWormApp::addr_low_ = 0;
00078 unsigned long DnhWormApp::default_gw_ = 0;
00079 float DnhWormApp::local_p_ = 0;
00080 
00081 // class to model vulnerable hosts in detailed network
00082 static class DnhWormAppClass : public TclClass {
00083 public:
00084     DnhWormAppClass() : TclClass("Application/Worm/Dnh") {}
00085     TclObject* create(int, const char*const*) {
00086         return (new DnhWormApp());
00087     }
00088 } class_app_worm_dnh;
00089 
00090 DnhWormApp::DnhWormApp() : WormApp() {
00091   infected_ = false;
00092   timer_ = NULL;
00093 }
00094 
00095 void DnhWormApp::recv(int nbytes) {
00096   if (infected_) {
00097     //printf("Node %d is infected already...\n", my_addr_);
00098   } else {
00099     if (!first_probe_) {
00100         first_probe_ = 1;
00101         printf("D FP %.2f\n", Scheduler::instance().clock());
00102     }
00103 
00104     printf("D C %.2f %lu %lu\n", 
00105            Scheduler::instance().clock(), infect_total_, my_addr_);
00106     
00107     // start to probe other hosts
00108     probe();
00109   }
00110 }
00111 
00112 void DnhWormApp::timeout() {
00113   timer_->resched(p_inv_);
00114   send_probe();
00115 }
00116 
00117 void DnhWormApp::probe() {
00118   infected_ = true;
00119   infect_total_++;
00120 
00121 
00122   if (scan_rate_) {
00123     p_inv_ = 1.0 / scan_rate_;
00124 
00125     timer_ = new ProbingTimer((WormApp *)this);
00126     timer_->sched(p_inv_);
00127   }
00128 }
00129 
00130 void DnhWormApp::send_probe() {
00131   double range_low, range_high;
00132   unsigned long d_addr;
00133   ns_addr_t dst;
00134 
00135   // do not probe myself
00136   d_addr = my_addr_;
00137   
00138   if (Random::uniform(0.0, 1.0) < local_p_) {
00139     range_low = addr_low_;
00140     range_high = addr_high_;
00141   } else {
00142     range_low = 0;
00143     range_high = total_addr_;
00144   }
00145   
00146   while (d_addr == my_addr_)
00147     d_addr = static_cast<unsigned long>(Random::uniform(range_low, range_high));
00148 
00149   // probe within my AS
00150   if (addr_low_ <= d_addr && d_addr <= addr_high_) {
00151     //printf("D PD %.2f %d %d\n", 
00152     //   Scheduler::instance().clock(), my_addr_, d_addr);
00153   } else {
00154     //printf("Node %d is probing node %d, within AN, send to node %d\n", 
00155     //     my_addr_, d_addr, default_gw_);
00156   }
00157 
00158   dst.addr_ = d_addr;
00159   dst.port_ = scan_port_;
00160   agent_->sendto((int)p_size_, (const char *)NULL, dst);
00161 }
00162 
00163 int DnhWormApp::command(int argc, const char*const* argv) {
00164   if (argc == 3) {
00165     if (strcmp(argv[1], "gw") == 0) {
00166       default_gw_ = atol(argv[2]);
00167       return(TCL_OK);
00168     }
00169     if (strcmp(argv[1], "local-p") == 0) {
00170         local_p_ = atof(argv[2]);
00171         return(TCL_OK);
00172     }   
00173   }
00174   if (argc == 4) {
00175     if (strcmp(argv[1], "addr-range") == 0) {
00176       addr_low_ = atol(argv[2]);
00177       addr_high_ = atol(argv[3]);
00178       //printf("DN low: %d, high: %d\n", addr_low_, addr_high_);
00179       return(TCL_OK);
00180     }
00181   }
00182 
00183   return(WormApp::command(argc, argv));
00184 }
00185 
00186 // class to model vulnerable hosts in detailed network
00187 static class AnWormAppClass : public TclClass {
00188 public:
00189     AnWormAppClass() : TclClass("Application/Worm/An") {}
00190     TclObject* create(int, const char*const*) {
00191         return (new AnWormApp());
00192     }
00193 } class_app_worm_an;
00194 
00195 AnWormApp::AnWormApp() : WormApp() {
00196   // using 1 second as the unit of time step
00197   //time_step_ = 1;
00198   timer_ = NULL;
00199 
00200   addr_low_ = addr_high_ = my_addr_;
00201   s_ = i_ = 0;
00202   v_percentage_ = 0;
00203   beta_ = gamma_ = 0;
00204   n_ = r_ = 1;
00205   
00206   probe_in = probe_out = probe_recv = 0;
00207 
00208   // get time step from configuration
00209   bind("TimeStep", &time_step_);
00210 }
00211 
00212 void AnWormApp::start() {
00213   // initial value of i and s
00214   i_ = 1;
00215   s_ -= 1;
00216 
00217   timer_ = new ProbingTimer((WormApp *)this);
00218   timer_->sched((double)time_step_);
00219 
00220   //printf("start\n");
00221 }
00222 
00223 void AnWormApp::recv(int nbytes) {
00224   probe_recv++;
00225   
00226   //printf("AN (%d) received probes from outside...%f \n", my_addr_, probe_recv);
00227 }
00228 
00229 void AnWormApp::timeout() {
00230   //printf("timeout\n");
00231   timer_->resched((double)time_step_);
00232   update();
00233 }
00234 
00235 void AnWormApp::update() {
00236   // schedule next timeout
00237   timer_->resched(time_step_);
00238 
00239   probe_out = scan_rate_ * i_ * (dn_high_ - dn_low_ + 1)  * time_step_ / total_addr_;
00240   // not every probe received has effect
00241   probe_in = probe_recv * s_ / n_;
00242   probe_recv = 0;
00243 
00244   // update states in abstract networks
00245   // update r (recovered/removed)
00246   r_ = r_ + gamma_ * i_;
00247   if (r_ < 0)
00248     r_ = 0;
00249   if (r_ > n_)
00250     r_ = n_;
00251 
00252   // update i (infected)
00253   // contains four parts:
00254   // 1. i of last time period, 2. increase due to internal probing
00255   // 3. decrease due to internal recovery/removal,
00256   // 4. increase due to external probing
00257 
00258   // should use n_ or s_max_???
00259   //i_ = i_ + beta_ * i_ * (s_ / n_) * time_step_ - gamma_ * i_ + probe_in;
00260   i_ = i_ + beta_ * i_ * (s_ / s_max_) * time_step_ - gamma_ * i_ + probe_in;
00261   if (i_ < 0)
00262     i_ = 0;
00263   if (i_ > n_ - r_)
00264     i_ = n_ - r_;
00265  
00266   // update s (susceptible)
00267   // use n = r + i + s
00268   s_ = n_ - r_ - i_;
00269 
00270   printf("A %.2f %d %d %d %d %d\n",
00271      Scheduler::instance().clock(),
00272      (int)s_, (int)i_, (int)r_, (int)probe_in, (int)probe_out);
00273 
00274   // probe outside networks
00275   // should not be cumulated!!!
00276   //probe_out = 2;
00277   if (probe_out > 1) { 
00278     //printf("ANS %.2f %d %d %d %d %d\n", 
00279     //        Scheduler::instance().clock(), 
00280     //        (int)s_, (int)i_, (int)r_, (int)probe_in, (int)probe_out);
00281     probe((int)(probe_out + 0.5));
00282   }
00283 }
00284 
00285 void AnWormApp::probe(int times) {
00286   // send out probes in a batch
00287   int i;
00288   unsigned long d_addr;
00289   ns_addr_t dst;
00290 
00291   i = 0;
00292   while (i < times) {
00293     d_addr = dn_low_ + (int)Random::uniform(dn_high_ - dn_low_);
00294 
00295     // do not send to myself or AS
00296     if (dn_low_ < d_addr && d_addr < dn_high_) {
00297       // probe outside
00298       //printf("AN is probing node %d, outside AN\n", d_addr);
00299 
00300       dst.addr_ = d_addr;
00301       dst.port_ = scan_port_;
00302       agent_->sendto((int)p_size_, (const char *)NULL, dst);
00303 
00304       i++;
00305     }
00306   }
00307 }
00308 
00309 int AnWormApp::command(int argc, const char*const* argv) {
00310   if (argc == 3) {
00311     if (strcmp(argv[1], "v_percent") == 0) {
00312       if (n_ == 0) {
00313     printf("space range is not specificed!\n");
00314     return(TCL_ERROR);
00315       } else {
00316     v_percentage_ = atof(argv[2]);
00317     
00318     s_ = (int)(n_ * v_percentage_);
00319     if (s_ < 1)
00320       s_ = 1;
00321     s_max_ = s_;
00322     r_ = n_ - s_;
00323 
00324     // use the equation in Moore's Internet Quarantine paper:
00325     // beta = scan_rate * total_vulnerable / 2^32
00326     beta_ = scan_rate_ * s_max_ / total_addr_;
00327     //printf("inferred beta from scan rate: %f, %f, %d, %f\n", 
00328     //  beta_, scan_rate_, (int)s_max_, total_addr_);
00329     return(TCL_OK);
00330       }
00331     }
00332     if (strcmp(argv[1], "beta") == 0) {
00333       beta_ = atof(argv[2]);
00334       //printf("beta: %f\n", beta_);
00335 
00336       return(TCL_OK);
00337     }
00338     if (strcmp(argv[1], "gamma") == 0) {
00339       gamma_ = atof(argv[2]);
00340       //printf("gamma: %f\n", gamma_);
00341 
00342       return(TCL_OK);
00343     }
00344   }
00345   if (argc == 4) {
00346     if (strcmp(argv[1], "addr-range") == 0) {
00347       addr_low_ = atol(argv[2]);
00348       addr_high_ = atol(argv[3]);
00349 
00350       // initialize SIR model states
00351       n_ = addr_high_ - addr_low_ + 1;
00352       //printf("AN low: %d, high: %d, n: %f\n", addr_low_, addr_high_, n_);
00353       return(TCL_OK);
00354     }
00355     if (strcmp(argv[1], "dn-range") == 0) {
00356       dn_low_ = atoi(argv[2]);
00357       dn_high_ = atoi(argv[3]);
00358       //printf("AN-DN low: %d, high: %d\n", dn_low_, dn_high_);
00359 
00360       return(TCL_OK);
00361     }
00362   }
00363 
00364   return(WormApp::command(argc, argv));
00365 }

Generated on Tue Mar 6 16:47:53 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6