在NS2 AODV协议中添加blackhole attacker(黑洞攻击) [转载]

原文地址:http://blog.csdn.net/qinleopard/article/details/6426379

---------------------------------------------


在NS2-3.34中添加黑洞攻击的过程还是比较简单的,具体过程大致如下描述:

1. 首先我们在aodv/aodv.h中的AODV类中添加一个标志该Agent(该节点是blackhole的标志)

   

[cpp]  view plain copy
  1. class AODV:  public Agent {  
  2. int blackhole;  //是否是攻击节点  
  3. }  

2.修改aodv/aodv.cc以实现blackhole 攻击

首先是在command 中定义相应的TCL “blackhole”

[cpp]  view plain copy
  1. if (strcmp(argv[1], "blackhole") == 0) {  
  2.                         printf("exsits blackhole/n");  
  3.             blackhole = 1;  
  4.             return TCL_OK;  
  5.         }  

接下来根据AODV协议和blackhole attack 的特点,我们实现blackhole attack的攻击过程(具体的攻击手段就是

在接收到某个节点发来的路由请求后,黑洞攻击节点不是查看路由表是否由到达目的节点的路由,从而转发或回复一个RREP。

取而代之的是,在它接收到一个RREQ后,立即回复一个RREP路由回复包,说他有到达目的节点的最优路径。而且当黑洞攻击节点

接收到数据包时,全部丢掉,从而形成一个像黑洞一样的攻击,数据包只进不出。具体详细关于黑洞攻击请google了解):

修改aodv.cc 中的recvRequest(Packet *p)函数:

[cpp]  view plain copy
  1. void  
  2. AODV::recvRequest(Packet *p) {  
  3.     if(debug>1) printf("recvRequest/n");  
  4.     struct hdr_ip *ih = HDR_IP(p);  
  5.     struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);  
  6.     aodv_rt_entry *rt;  
  7.     /* 
  8.      * Drop if: 
  9.      *      - I'm the source 
  10.      *      - I recently heard this request. 
  11.      */  
  12.     if (rq->rq_src == index) {  
  13. #ifdef DEBUG  
  14.         //fprintf(stderr, "%s: got my own REQUEST/n", __FUNCTION__);  
  15. #endif // DEBUG  
  16.         Packet::free(p); //如果是自己发出来的就直接丢弃  
  17.         return;  
  18.     }  
  19.     if (id_lookup(rq->rq_src, rq->rq_bcast_id)) {  
  20. #ifdef DEBUG  
  21.         //fprintf(stderr, "%s: discarding request/n", __FUNCTION__);  
  22. #endif // DEBUG  
  23.       // printf("我之前已经接收到了这个分组!and my id is %d /n", index);  
  24.         Packet::free(p); //这个分组已经收到过  
  25.         return;  
  26.     }  
  27.     /* 
  28.      * Cache the broadcast ID 
  29.      */  
  30.     id_insert(rq->rq_src, rq->rq_bcast_id);  
  31.     /* 
  32.      * We are either going to forward the REQUEST or generate a 
  33.      * REPLY. Before we do anything, we make sure that the REVERSE 
  34.      * route is in the route table. 
  35.      */  
  36.     aodv_rt_entry *rt0; // rt0 is the reverse route  
  37.     rt0 = rtable.rt_lookup(rq->rq_src);  
  38.     if (rt0 == 0) { /* if not in the route table */  
  39.         // create an entry for the reverse route.  
  40.         rt0 = rtable.rt_add(rq->rq_src);  
  41.     }  
  42.     rt0->rt_expire = max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE));  
  43.     if ( (rq->rq_src_seqno > rt0->rt_seqno ) ||  
  44.             ((rq->rq_src_seqno == rt0->rt_seqno) &&  
  45.              (rq->rq_hop_count < rt0->rt_hops)) ) {  
  46.         // If we have a fresher seq no. or lesser #hops for the  
  47.         // same seq no., update the rt entry. Else don't bother.  
  48.         rt_update(rt0, rq->rq_src_seqno, rq->rq_hop_count, ih->saddr(),  
  49.                 max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)) );  
  50.         if (rt0->rt_req_timeout > 0.0) {  
  51.             // Reset the soft state and  
  52.             // Set expiry time to CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT  
  53.             // This is because route is used in the forward direction,  
  54.             // but only sources get benefited by this change  
  55.             rt0->rt_req_cnt = 0;  
  56.             rt0->rt_req_timeout = 0.0;  
  57.             rt0->rt_req_last_ttl = rq->rq_hop_count;  
  58.             rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;  
  59.         }  
  60.         /* Find out whether any buffered packet can benefit from the 
  61.          * reverse route. 
  62.          * May need some change in the following code - Mahesh 09/11/99 
  63.          */  
  64.         assert (rt0->rt_flags == RTF_UP);  
  65.         Packet *buffered_pkt;  
  66.         while ((buffered_pkt = rqueue.deque(rt0->rt_dst))) {  
  67.             if (rt0 && (rt0->rt_flags == RTF_UP)) {  
  68.                 assert(rt0->rt_hops != INFINITY2);  
  69.                 forward(rt0, buffered_pkt, NO_DELAY);  
  70.             }  
  71.         }  
  72.     }  
  73.     // End for putting reverse route in rt table  
  74.     /* 
  75.      * We have taken care of the reverse route stuff. 
  76.      * Now see whether we can send a route reply. 
  77.      */  
  78.     rt = rtable.rt_lookup(rq->rq_dst);  
  79. // First check if I am the destination ..  
  80.     if (rq->rq_dst == index) {  
  81. #ifdef DEBUG  
  82.         fprintf(stderr, "%d - %s: destination sending reply/n",  
  83.                 index, __FUNCTION__);  
  84. #endif // DEBUG  
  85.         //printf("I am the desitination and my ip address is %d/n", index);  
  86.         // Just to be safe, I use the max. Somebody may have  
  87.         // incremented the dst seqno.  
  88.         seqno = max(seqno, rq->rq_dst_seqno) + 1;  
  89.         if (seqno % 2) seqno++;  
  90.         sendReply(rq->rq_src,           // IP Destination  
  91.                 1,                    // Hop Count  
  92.                 index,                // Dest IP Address  
  93.                 seqno,                // Dest Sequence Num  
  94.                         rq->rq_src,  
  95.                 MY_ROUTE_TIMEOUT,     // Lifetime  
  96.                 rq->rq_timestamp);    // timestamp  
  97.         Packet::free(p);  
  98.     }  
  99. // I am not the destination, but I may have a fresh enough route.  
  100. //Start balckhole Code  
  101. //a Blackhole attacker always say that have the route to be a sink.  
  102.     else if ((rt && blackhole == 1)) {  
  103.         assert(rq->rq_dst == rt->rt_dst);  
  104.                 //printf("I am the blackhole node and blackhole = %d/n", index);  
  105.         sendReply(rq->rq_src,  
  106.                     1,  
  107.             //rt->rt_hops, //Blackhole gravity.  
  108.                 rq->rq_dst,  
  109.             //rt->rt_seqno + 10, //Blackhole gravity.  
  110.                         4294967295,  
  111.                         rq->rq_src,  
  112.                 (u_int32_t) (rt->rt_expire - CURRENT_TIME),  
  113.                 rq->rq_timestamp);  
  114.         rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source  
  115.         rt0->pc_insert(rt->rt_nexthop); // nexthop to RREQ destination  
  116.           
  117.         //printf("node ip = %d,rt->rt_hops = %d, rt->rt_seqno = %d/n",index,rt->rt_hops, rt->rt_seqno);  
  118. #ifdef RREQ_GRAT_RREP  
  119.         sendReply(rq->rq_dst,  
  120.                 rq->rq_hop_count,  
  121.                 rq->rq_src,  
  122.                 rq->rq_src_seqno,  
  123.             rq->rq_src,  
  124.                 (u_int32_t) (rt->rt_expire - CURRENT_TIME),  
  125.                 rq->rq_timestamp);  
  126.         printf("ifndef RREQ_GRAT_RREP....../n");  
  127. #endif  
  128.         Packet::free(p);  
  129. }  
  130. //End balckhole Code   
  131. /*Sniffer IDS 假设中间节点是不能回复RREP的,但是黑洞攻击节点却必须可疑回复,其实这种做法明显是存在很大的缺陷的。 
  132.   这样即使可以有效隔离黑洞攻击节点,但是这只能说是路由协议的一种特殊条件的下的检测方法。 
  133.   后面我希望在此基础上做进一步的改进,可以把这种攻击手段扩大化,也就是更加普遍话。适应各种路由情况,而不仅限于某种特殊情况 
  134. */  
  135.     } else if ((rt && (rt->rt_hops != INFINITY2) &&  
  136.             (rt->rt_seqno >= rq->rq_dst_seqno) )) {  
  137.             
  138.         //printf("I am not the desitination, but is may have a fresh enough route/n");  
  139.         //assert (rt->rt_flags == RTF_UP);  
  140.         assert(rq->rq_dst == rt->rt_dst);  
  141.         //assert ((rt->rt_seqno%2) == 0);    // is the seqno even?  
  142.         sendReply(rq->rq_src,  
  143.                 rt->rt_hops + 1,  
  144.                 rq->rq_dst,  
  145.                 rt->rt_seqno,   
  146.             rq->rq_src,  
  147.                 (u_int32_t) (rt->rt_expire - CURRENT_TIME),  
  148.                 //             rt->rt_expire - CURRENT_TIME,  
  149.                 rq->rq_timestamp);  
  150.         // Insert nexthops to RREQ source and RREQ destination in the  
  151.         // precursor lists of destination and source respectively  
  152.         rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source  
  153.         rt0->pc_insert(rt->rt_nexthop); // nexthop to RREQ destination  
  154. #ifdef RREQ_GRAT_RREP  
  155.         sendReply(rq->rq_dst,  
  156.                 rq->rq_hop_count,  
  157.                 rq->rq_src,  
  158.                 rq->rq_src_seqno,  
  159.             rq->rq_src,  
  160.                 (u_int32_t) (rt->rt_expire - CURRENT_TIME),  
  161.                 //             rt->rt_expire - CURRENT_TIME,  
  162.                 rq->rq_timestamp);  
  163. printf("I am not the desitination, but is may have a fresh enough route , RREQ_GRAT_RREP/n");  
  164. #endif  
  165. // TODO: send grat RREP to dst if G flag set in RREQ using rq->rq_src_seqno, rq->rq_hop_counT  
  166. // DONE: Included gratuitous replies to be sent as per IETF aodv draft specification. As of now, G flag has not been dynamically used and is always set or reset in aodv-packet.h --- Anant Utgikar, 09/16/02.  
  167.         Packet::free(p);  
  168.     }  
  169.     /* 
  170.      * Can't reply. So forward the  Route Request 
  171.      */  
  172.     else {  
  173.           
  174.         //Start Blackhole Code  
  175.                   
  176.         if(blackhole == 1) //是黑洞攻击节点  
  177.         {  
  178.              //printf("%d can't replay, but %d is a attacker, so i will replay the RREP packets/n", index, index);  
  179.             sendReply(rq->rq_src,        // IP Destination  
  180.                  1,         // Hop Count  
  181.                  rq->rq_dst,     // Dest IP Address  
  182.                  4294967295, // Highest Dest Sequence Num that is largest 32-bit integers from -2147483647 to +2147483647                 
  183.                 rq->rq_src,                       
  184.                        //rt->rt_seqno + 10,  
  185.                 MY_ROUTE_TIMEOUT,   // Lifetime  
  186.                 rq->rq_timestamp); // timestamp  
  187.                     Packet::free(p);  
  188.         }//End Blackhole Code  
  189.                  else  
  190.                  {      
  191.               ih->saddr() = index;  
  192.           ih->daddr() = IP_BROADCAST;  
  193.           rq->rq_hop_count += 1;  
  194.          // Maximum sequence number seen en route  
  195.           if (rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno);  
  196.           forward((aodv_rt_entry*) 0, p, DELA   

 

这里面的sendReply我是修改过了的,就是添加一个字段。这个和实现黑洞攻击没有关系。可以忽略!

然后实现所有的黑洞攻击节点在接收到数据包时(自己不是目的节点),把所有接收到的数据包直接丢掉

在AODV::rt_resolve(Packet *p) 函数中添加:

[cpp]  view plain copy
  1. //if (rt->rt_flags == RTF_UP){  
  2.         if ((rt->rt_flags == RTF_UP) &&  
  3.             //Start Watchdog Code  
  4.             (blackhole != 1)) {  
  5.             //End Watchdog Code  
  6.             assert(rt->rt_hops != INFINITY2);  
  7.             forward(rt, p, NO_DELAY);  
  8.                        // printf("%f forward this packet by not need the REQUEST, dst = %d/n and next_hop = %d/n", Scheduler::instance().clock(),ih->daddr(), rt->rt_nexthop);  
  9.         }  
  10.         //Start Watchdog Code  
  11.         else if(blackhole == 1 && ih->daddr() != index){ //黑洞节点并且我不是目的节点  
  12.             if(blackholed == 0 && packets_dropped >= PACKETS_TO_CONSIDER_AN_ATTACK){  
  13.                 blackholed=1;  
  14.                 printAttackMessage(p);                
  15.             }  
  16.             packets_dropped++;  
  17.             drop(p, DROP_IFQ_FILTER);  
  18.             return;  
  19.         }  
  20.         //End Watchdog Code  

 

3.最后我们还需要在tcl/lib/ns-mobilenode.tcl中添加

#Blackhole
Node/MobileNode instproc set_Blackhole {} {
    $self instvar ragent_
        puts "Installing new blackhole...................."
        return $ragent_
}

 

4.这样我们可以直接在tcl脚本中使用黑洞攻击节点了:

set n3 [$ns node]
$n3 set X_ 372
$n3 set Y_ 400
$n3 set Z_ 0.0
$ns initial_node_pos $n3 20
$ns at 0.01 "[$n3 set ragent_] blackhole"
$ns at 0.01 "$n3 label /"blackhole node/" "

这里就是把节点3定义为一个黑洞攻击节点。

 

 

注:在协议中添加攻击行为还可以使用另外一种方法进行添加,就是像创建一种新的协议过程一样,比如说创建一种叫做blackholeAODV

整个协议的创建过程跟很多树上描述的创建一个新的MyPing协议过程一样。这里面的blackholeAODV协议创建过程按照AODV协议创建过程,然后修改AODV协议,使得这个协议能够实现黑洞攻击。最后在tcl脚本中使用是,和使用AODV协议配置一样。比如说你协议的定义的TCL为blackholeAODV,则可以这样子调用:

[c-sharp]  view plain copy
  1. set val(brp)    blackholeAODV              ;# blackhole attack in AODV  
  2. $ns node-config -adhocRouting $val(brp)  
  3. set n3 [$ns node]  
  4. $n3 set X_ 372  
  5. $n3 set Y_ 400  
  6. $n3 set Z_ 0.0  
  7. $ns initial_node_pos $n3 20  

这样同样可以实现上面的黑洞攻击的功能。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值