原文地址:http://blog.csdn.net/qinleopard/article/details/6426379
---------------------------------------------
在NS2-3.34中添加黑洞攻击的过程还是比较简单的,具体过程大致如下描述:
1. 首先我们在aodv/aodv.h中的AODV类中添加一个标志该Agent(该节点是blackhole的标志)
[cpp] view plain copy
- class AODV: public Agent {
- int blackhole; //是否是攻击节点
- }
2.修改aodv/aodv.cc以实现blackhole 攻击
首先是在command 中定义相应的TCL “blackhole”
[cpp] view plain copy
- if (strcmp(argv[1], "blackhole") == 0) {
- printf("exsits blackhole/n");
- blackhole = 1;
- return TCL_OK;
- }
接下来根据AODV协议和blackhole attack 的特点,我们实现blackhole attack的攻击过程(具体的攻击手段就是
在接收到某个节点发来的路由请求后,黑洞攻击节点不是查看路由表是否由到达目的节点的路由,从而转发或回复一个RREP。
取而代之的是,在它接收到一个RREQ后,立即回复一个RREP路由回复包,说他有到达目的节点的最优路径。而且当黑洞攻击节点
接收到数据包时,全部丢掉,从而形成一个像黑洞一样的攻击,数据包只进不出。具体详细关于黑洞攻击请google了解):
修改aodv.cc 中的recvRequest(Packet *p)函数:
[cpp] view plain copy
- void
- AODV::recvRequest(Packet *p) {
- if(debug>1) printf("recvRequest/n");
- struct hdr_ip *ih = HDR_IP(p);
- struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);
- aodv_rt_entry *rt;
- if (rq->rq_src == index) {
- #ifdef DEBUG
- //fprintf(stderr, "%s: got my own REQUEST/n", __FUNCTION__);
- #endif // DEBUG
- Packet::free(p); //如果是自己发出来的就直接丢弃
- return;
- }
- if (id_lookup(rq->rq_src, rq->rq_bcast_id)) {
- #ifdef DEBUG
- //fprintf(stderr, "%s: discarding request/n", __FUNCTION__);
- #endif // DEBUG
- // printf("我之前已经接收到了这个分组!and my id is %d /n", index);
- Packet::free(p); //这个分组已经收到过
- return;
- }
- id_insert(rq->rq_src, rq->rq_bcast_id);
- aodv_rt_entry *rt0; // rt0 is the reverse route
- rt0 = rtable.rt_lookup(rq->rq_src);
- if (rt0 == 0) {
- // create an entry for the reverse route.
- rt0 = rtable.rt_add(rq->rq_src);
- }
- rt0->rt_expire = max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE));
- if ( (rq->rq_src_seqno > rt0->rt_seqno ) ||
- ((rq->rq_src_seqno == rt0->rt_seqno) &&
- (rq->rq_hop_count < rt0->rt_hops)) ) {
- // If we have a fresher seq no. or lesser #hops for the
- // same seq no., update the rt entry. Else don't bother.
- rt_update(rt0, rq->rq_src_seqno, rq->rq_hop_count, ih->saddr(),
- max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)) );
- if (rt0->rt_req_timeout > 0.0) {
- // Reset the soft state and
- // Set expiry time to CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT
- // This is because route is used in the forward direction,
- // but only sources get benefited by this change
- rt0->rt_req_cnt = 0;
- rt0->rt_req_timeout = 0.0;
- rt0->rt_req_last_ttl = rq->rq_hop_count;
- rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;
- }
- assert (rt0->rt_flags == RTF_UP);
- Packet *buffered_pkt;
- while ((buffered_pkt = rqueue.deque(rt0->rt_dst))) {
- if (rt0 && (rt0->rt_flags == RTF_UP)) {
- assert(rt0->rt_hops != INFINITY2);
- forward(rt0, buffered_pkt, NO_DELAY);
- }
- }
- }
- // End for putting reverse route in rt table
- rt = rtable.rt_lookup(rq->rq_dst);
- // First check if I am the destination ..
- if (rq->rq_dst == index) {
- #ifdef DEBUG
- fprintf(stderr, "%d - %s: destination sending reply/n",
- index, __FUNCTION__);
- #endif // DEBUG
- //printf("I am the desitination and my ip address is %d/n", index);
- // Just to be safe, I use the max. Somebody may have
- // incremented the dst seqno.
- seqno = max(seqno, rq->rq_dst_seqno) + 1;
- if (seqno % 2) seqno++;
- sendReply(rq->rq_src, // IP Destination
- 1, // Hop Count
- index, // Dest IP Address
- seqno, // Dest Sequence Num
- rq->rq_src,
- MY_ROUTE_TIMEOUT, // Lifetime
- rq->rq_timestamp); // timestamp
- Packet::free(p);
- }
- // I am not the destination, but I may have a fresh enough route.
- //Start balckhole Code
- //a Blackhole attacker always say that have the route to be a sink.
- else if ((rt && blackhole == 1)) {
- assert(rq->rq_dst == rt->rt_dst);
- //printf("I am the blackhole node and blackhole = %d/n", index);
- sendReply(rq->rq_src,
- 1,
- //rt->rt_hops, //Blackhole gravity.
- rq->rq_dst,
- //rt->rt_seqno + 10, //Blackhole gravity.
- 4294967295,
- rq->rq_src,
- (u_int32_t) (rt->rt_expire - CURRENT_TIME),
- rq->rq_timestamp);
- rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source
- rt0->pc_insert(rt->rt_nexthop); // nexthop to RREQ destination
- //printf("node ip = %d,rt->rt_hops = %d, rt->rt_seqno = %d/n",index,rt->rt_hops, rt->rt_seqno);
- #ifdef RREQ_GRAT_RREP
- sendReply(rq->rq_dst,
- rq->rq_hop_count,
- rq->rq_src,
- rq->rq_src_seqno,
- rq->rq_src,
- (u_int32_t) (rt->rt_expire - CURRENT_TIME),
- rq->rq_timestamp);
- printf("ifndef RREQ_GRAT_RREP....../n");
- #endif
- Packet::free(p);
- }
- //End balckhole Code
- } else if ((rt && (rt->rt_hops != INFINITY2) &&
- (rt->rt_seqno >= rq->rq_dst_seqno) )) {
- //printf("I am not the desitination, but is may have a fresh enough route/n");
- //assert (rt->rt_flags == RTF_UP);
- assert(rq->rq_dst == rt->rt_dst);
- //assert ((rt->rt_seqno%2) == 0); // is the seqno even?
- sendReply(rq->rq_src,
- rt->rt_hops + 1,
- rq->rq_dst,
- rt->rt_seqno,
- rq->rq_src,
- (u_int32_t) (rt->rt_expire - CURRENT_TIME),
- // rt->rt_expire - CURRENT_TIME,
- rq->rq_timestamp);
- // Insert nexthops to RREQ source and RREQ destination in the
- // precursor lists of destination and source respectively
- rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source
- rt0->pc_insert(rt->rt_nexthop); // nexthop to RREQ destination
- #ifdef RREQ_GRAT_RREP
- sendReply(rq->rq_dst,
- rq->rq_hop_count,
- rq->rq_src,
- rq->rq_src_seqno,
- rq->rq_src,
- (u_int32_t) (rt->rt_expire - CURRENT_TIME),
- // rt->rt_expire - CURRENT_TIME,
- rq->rq_timestamp);
- printf("I am not the desitination, but is may have a fresh enough route , RREQ_GRAT_RREP/n");
- #endif
- // TODO: send grat RREP to dst if G flag set in RREQ using rq->rq_src_seqno, rq->rq_hop_counT
- // 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.
- Packet::free(p);
- }
- else {
- //Start Blackhole Code
- if(blackhole == 1) //是黑洞攻击节点
- {
- //printf("%d can't replay, but %d is a attacker, so i will replay the RREP packets/n", index, index);
- sendReply(rq->rq_src, // IP Destination
- 1, // Hop Count
- rq->rq_dst, // Dest IP Address
- 4294967295, // Highest Dest Sequence Num that is largest 32-bit integers from -2147483647 to +2147483647
- rq->rq_src,
- //rt->rt_seqno + 10,
- MY_ROUTE_TIMEOUT, // Lifetime
- rq->rq_timestamp); // timestamp
- Packet::free(p);
- }//End Blackhole Code
- else
- {
- ih->saddr() = index;
- ih->daddr() = IP_BROADCAST;
- rq->rq_hop_count += 1;
- // Maximum sequence number seen en route
- if (rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno);
- forward((aodv_rt_entry*) 0, p, DELA
这里面的sendReply我是修改过了的,就是添加一个字段。这个和实现黑洞攻击没有关系。可以忽略!
然后实现所有的黑洞攻击节点在接收到数据包时(自己不是目的节点),把所有接收到的数据包直接丢掉
在AODV::rt_resolve(Packet *p) 函数中添加:
[cpp] view plain copy
- //if (rt->rt_flags == RTF_UP){
- if ((rt->rt_flags == RTF_UP) &&
- //Start Watchdog Code
- (blackhole != 1)) {
- //End Watchdog Code
- assert(rt->rt_hops != INFINITY2);
- forward(rt, p, NO_DELAY);
- // 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);
- }
- //Start Watchdog Code
- else if(blackhole == 1 && ih->daddr() != index){ //黑洞节点并且我不是目的节点
- if(blackholed == 0 && packets_dropped >= PACKETS_TO_CONSIDER_AN_ATTACK){
- blackholed=1;
- printAttackMessage(p);
- }
- packets_dropped++;
- drop(p, DROP_IFQ_FILTER);
- return;
- }
- //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
- set val(brp) blackholeAODV ;# blackhole attack in AODV
- $ns node-config -adhocRouting $val(brp)
- set n3 [$ns node]
- $n3 set X_ 372
- $n3 set Y_ 400
- $n3 set Z_ 0.0
- $ns initial_node_pos $n3 20
这样同样可以实现上面的黑洞攻击的功能。