//#include <ip

Similar documents
穨control.PDF

Simulator By SunLingxi 2003

Lorem ipsum dolor sit amet, consectetuer adipiscing elit

C o n t e n t s Acceptance Allow Love Apologize Archangel Metatron Archangel Michael Ask for

IP505SM_manual_cn.doc

Microsoft PowerPoint - Aqua-Sim.pptx

Master Thesis_專門用來製作目錄.doc

2-7.FIT)

財金資訊-80期.indd

Microsoft Word - 第四組心得.doc

4. 每 组 学 生 将 写 有 习 语 和 含 义 的 两 组 卡 片 分 别 洗 牌, 将 顺 序 打 乱, 然 后 将 两 组 卡 片 反 面 朝 上 置 于 课 桌 上 5. 学 生 依 次 从 两 组 卡 片 中 各 抽 取 一 张, 展 示 给 小 组 成 员, 并 大 声 朗 读 卡

(Microsoft Word - 10\246~\253\327\262\304\244@\264\301\256\325\260T_Version4)

Microsoft Word doc

Microsoft Word - template.doc

Windows XP

99 學年度班群總介紹 第 370 期 班群總導 陳怡靜 G45 班群總導 陳怡靜(河馬) A 家 惠如 家浩 T 格 宜蓁 小 霖 怡 家 M 璇 均 蓁 雴 家 數學領域 珈玲 國燈 英領域 Kent

可 愛 的 動 物 小 五 雷 雅 理 第 一 次 小 六 甲 黃 駿 朗 今 年 暑 假 發 生 了 一 件 令 人 非 常 難 忘 的 事 情, 我 第 一 次 參 加 宿 營, 離 開 父 母, 自 己 照 顧 自 己, 出 發 前, 我 的 心 情 十 分 緊 張 當 到 達 目 的 地 後

¶C¶L§§¬_™¨ A.PDF


Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc

els0xu_zh_nf_v8.book Page Wednesday, June, 009 9:5 AM ELS-0/0C.8

國立中山大學學位論文典藏.PDF

國 立 政 治 大 學 教 育 學 系 2016 新 生 入 學 手 冊 目 錄 表 11 國 立 政 治 大 學 教 育 學 系 博 士 班 資 格 考 試 抵 免 申 請 表 論 文 題 目 申 報 暨 指 導 教 授 表 12 國 立 政 治 大 學 碩 博 士 班 論

Microsoft Word - TIP006SCH Uni-edit Writing Tip - Presentperfecttenseandpasttenseinyourintroduction readytopublish

2005 5,,,,,,,,,,,,,,,,, , , 2174, 7014 %, % 4, 1961, ,30, 30,, 4,1976,627,,,,, 3 (1993,12 ),, 2

软件测试(TA07)第一学期考试

IP Access Lists IP Access Lists IP Access Lists

BC04 Module_antenna__ doc

Microsoft Word - 11月電子報1130.doc

[ 13 年 12 月 06 日, 下 午 6 点 24 分 ] Intel Hosts 新 加 入 的 同 学 们, 快 去 听 听 在 线 宣 讲 会 哦, 同 时 完 成 页 面 下 方 有 奖 调 查, 就 有 资 格 参 与 大 奖 抽 取 啦! [ 13 年 12 月 06 日, 下 午

管道建模基础.ppt

C/C++ 语言 - 循环

C 1

參 加 第 二 次 pesta 的 我, 在 是 次 交 流 營 上 除 了, 與 兩 年 沒 有 見 面 的 朋 友 再 次 相 聚, 加 深 友 誼 外, 更 獲 得 與 上 屆 不 同 的 體 驗 和 經 歴 比 較 起 香 港 和 馬 來 西 亞 的 活 動 模 式, 確 是 有 不 同 特

K301Q-D VRT中英文说明书141009

星河33期.FIT)

版权声明

TX-NR3030_BAS_Cs_ indd

124 第十三期 Conflicts in the Takeover of the Land in Taiwan after the Sino-Japanese War A Case in the Change of the Japanese Names of the Taiwanese Peopl

目 錄 實 施 計 畫 1 專 題 演 講 因 應 十 二 年 國 民 基 本 教 育 課 程 綱 要 學 校 本 位 課 程 的 整 體 布 局 A-1 推 動 十 二 年 國 民 基 本 教 育 課 程 綱 要 相 關 配 套 措 施 A-10 分 組 研 討 法 規 研 修 B-1 課 程 教

C/C++语言 - C/C++数据

天 主 教 輔 仁 大 學 社 會 學 系 學 士 論 文 小 別 勝 新 婚? 久 別 要 離 婚? 影 響 遠 距 家 庭 婚 姻 感 情 因 素 之 探 討 Separate marital relations are getting better or getting worse? -Exp


Open topic Bellman-Ford算法与负环

untitled

前 言 一 場 交 換 學 生 的 夢, 夢 想 不 只 是 敢 夢, 而 是 也 要 敢 去 實 踐 為 期 一 年 的 交 換 學 生 生 涯, 說 長 不 長, 說 短 不 短 再 長 的 路, 一 步 步 也 能 走 完 ; 再 短 的 路, 不 踏 出 起 步 就 無 法 到 達 這 次

Microsoft Word - No_HK doc

计算机网络概论

ch_code_infoaccess

從詩歌的鑒賞談生命價值的建構

Chapter #

VASP应用运行优化

國立中山大學學位論文典藏.PDF

第 1 章 概 述 1.1 计 算 机 网 络 在 信 息 时 代 中 的 作 用 1.2 计 算 机 网 络 的 发 展 过 程 *1.2.1 分 组 交 换 的 产 生 *1.2.2 因 特 网 时 代 *1.2.3 关 于 因 特 网 的 标 准 化 工 作 计 算 机 网 络 在

Important Notice SUNPLUS TECHNOLOGY CO. reserves the right to change this documentation without prior notice. Information provided by SUNPLUS TECHNOLO

计算机网络

Microsoft Word - 3D手册2.doc

Microsoft Word - Newsletter July 2007.doc

epub83-1


Microsoft PowerPoint - Performance Analysis of Video Streaming over LTE using.pptx

Some experiences in working with Madagascar: installa7on & development Tengfei Wang, Peng Zou Tongji university

: : : : : ISBN / C53:H : 19.50

ebook14-4

, (), 15,,,,, 2,,,1000 2,,, 5, ;, 5,,3,,,4 2,,, :, , , ,

untitled

202 The Sending Back of The Japanese People in Taiwan in The Beginning Years After the World War II Abstract Su-ying Ou* In August 1945, Japan lost th

Microsoft Word - SupplyIT manual 3_cn_david.doc

國立桃園高中96學年度新生始業輔導新生手冊目錄

<4D F736F F D205F FB942A5CEA668B443C5E9BB73A740B5D8A4E5B8C9A552B1D0A7F75FA6BFB1A4ACFC2E646F63>

untitled

03施琅「棄留臺灣議」探索.doc

錄...1 說...2 說 說...5 六 率 POST PAY PREPAY DEPOSIT 更

Untitiled

C


090507issue

2. 佔 中 對 香 港 帶 來 以 下 影 響 : 正 面 影 響 - 喚 起 市 民 對 人 權 及 ( 專 制 ) 管 治 的 關 注 和 討 論 o 香 港 市 民 總 不 能 一 味 認 命, 接 受 以 後 受 制 於 中 央, 沒 有 機 會 選 出 心 中 的 理 想 特 首 o 一

中国计算机软件专业技术资格和水平考试

_12-17.QXD


Microsoft PowerPoint - CH 04 Techniques of Circuit Analysis

Microsoft PowerPoint 馮天俊-問題分析與決策力

<4D F736F F D203033BDD7A16DA576B04FA145A4ADABD2A5BBACF6A16EADBAB6C0ABD2A4A7B74EB8712E646F63>


2011年高职语文考试大纲

C6_ppt.PDF

3.1 num = 3 ch = 'C' 2

Microsoft PowerPoint - 数据通信-ch1.ppt

AL-M200 Series

untitled

莊 子

ebook140-8

RAQMON Context Setting MG PDA Applications RTP / FTP/ HTTP TCP/UDP S ignaling control plane (e.g. RS VP, NS IS) Streaming Media, Transaction, Bulk dat

Collection of 2012 Examination Certificates

高中英文科教師甄試心得

Lorem ipsum dolor sit amet, consectetuer adipiscing elit

1505.indd

1 VLBI VLBI 2 32 MHz 2 Gbps X J VLBI [3] CDAS IVS [4,5] CDAS MHz, 16 MHz, 8 MHz, 4 MHz, 2 MHz [6] CDAS VLBI CDAS 2 CDAS CDAS 5 2

2013 C 1 #include <stdio.h> 2 int main(void) 3 { 4 int cases, i; 5 long long a, b; 6 scanf("%d", &cases); 7 for (i = 0; i < cases; i++) 8 { 9 scanf("%

Transcription:

NS-2 中 AODV 的 RREQ 與 RREP 訊息傳送過程 程榮祥. 郭俐君 chengrs@nsda.ee.ncku.edu.tw 簡介移動性 Ad hoc network (MANET) 是由一群配備無線設備而且可以任意移動的主機所構成的網路 由於在 MANET 中並沒有無集中式的網路管理設備 ( 例如基地台等 ) 且由於受限於電波傳輸範圍的限制, 因此若欲將一個封包 (Packet) 由來源端主機 (Source) 傳送到目的端主機 (Destination) 時, 可能必須藉由鄰近的行動式主機負責幫忙轉送, 但由於在 MANET 中的主機可以隨意移動, 因此為了確保應用程式的資料能在 MANET 上順利傳送,MANET 的路由協定 (Routing Protocol) 在設計時, 就必須考量到網路拓樸隨時會改變的情形 Ad hoc On Demand Distance Vector (AODV) protocol 是一個專門為 Ad hoc 移動網路所設計的通訊協定 AODV 是一個無迴路, 由來源主機開始啟動, 且能擴展到大量移動節點的一種通訊協定 ; 和 DSDV 不同的地方在於,AODV 是一種在需要時才啟用的路由協定, 意即當有來源端主機想傳送資料時, 才開始建立由來源主機至目的主機的路由 (Route) AODV 的路由方式 AODV 透過發出請求 (Route Request,RREQ) 與回覆 (Route Reply,RREP) 的機制來取得路由 首先, 若來源點主機想傳輸到目的主機的路由資訊未建立, 則 AODV 的來源主機會廣播 RREQ 訊息至整個網路, 收到此訊息的相鄰節點會更新收到來源點發出的資訊, 並建立向後端來源點的路由表 RREQ 中的訊息如下 : <source_addr,source_sequence#, broadcast_id, dest_addr, dest_sequence_#, hop_cnt> 這些訊息分別為 : 來源主機的 IP 位址 來源端的序列號碼 廣播 ID 目的主機的 IP 位址 目的端的序列號碼, 最後是經過的 hop 數 RREP 則會包含如下的訊息 : <source_addr, dest_addr, dest_sequence _#, hop_cnt, lifetime> 這些訊息分別為 : 來源主機的 IP 位址 目的主機的 IP 位址, 目的端的序列號碼, 經過的 hop 數以及連線的有效存活時間 有關 AODV 的運作過程, 簡單地介紹如下 : (1) 每個 Node 藉由 Hello_message 來確保相鄰的節點 (2) Source node 想傳資料時, 啟動 Route discovery 程序找出其它 Node 位置 藉由廣播 RREQ 給它相鄰的 Node, 接到此封包的 Node 再轉送給相鄰的 Node, 直到此封包到達目的主機為止 (3) 其中 <source_addr, broadcast_id> 唯一決定一個 RREQ 收到重覆 RREQ, 則丟棄或不理會後來抵達者 (4) 轉送 RREQ 過程中, 每個 node 會自動設定反向的路徑 (reverse path), 而收到 RREQ 的中間節點 (intermediate node) 會查看是從哪一個相鄰節點送來此封包, 接著把相鄰節點的 IP 紀錄在自己的路由表中 ( 建立反向路徑 ), 再把 hop_count 加 1, 轉送給下一個 Node (5) 在傳送過程中, 若某一個節點已含有到達目的的路徑資訊, 則會直接回覆 RREP 給 Source node ADOV 程式說明在這個例子中, 我們希望能觀察 AODV 的 RREQ 訊息在 NS-2 中是如何被 Source Node 送出, 網路上的 Node 在收到這個 RREQ 訊息時, 又是如何去產生 RREP 訊息的 首先我們先來看在 aodv.h 這個檔案 ( 相關函式如下 ) 中, 有關傳送及接收處理函式的定義 在 NS-2 中,AODV 封包的傳送及接收分別是由 sendrequest() 以及 recvrequest() 這兩個函式來處理 ; 至於 AODV 的 Reply 訊息, 則分別由 sendreply() 以及 recvreply() 這兩個函式來負責 // Packet TX Routines forward(aodv_rt_entry *rt, Packet *p, double delay); sendhello(); sendrequest(nsaddr_t dst);

sendreply(nsaddr_t ipdst, u_int32_t hop_count, nsaddr_t rpdst, u_int32_t rpseq, u_int32_t lifetime, double timestamp); senderror(packet *p, bool jitter = true); // Packet RX Routines recvaodv(packet *p); recvhello(packet *p); recvrequest(packet *p); recvreply(packet *p); recverror(packet *p); 接下來我們來看 aodv.cc 的部份, 為了簡單起見, 我們只列出 sendrequest() sendreply() recvrequest() 以及 recvreply() 這四個函式 ; 另外這些函式在執行的過程中, 會將傳送及接收訊息的時間以及 Hop count Latency 的資訊記錄在一個名為 out.aodv 的 trace 檔中 #include <aodv/aodv.h> #include <aodv/aodv_packet.h> #include <random.h> #include <cmu-trace.h> #include <stdio.h> #define max(a,b) ( (a) > (b)? (a) : (b) ) #define CURRENT_TIME Scheduler::instance().clock() //#define DEBUG //#define ERROR #define DUMP // 這是我自行增加的一個參數, 這個參數是一個開關, 在進行除錯的過程中時, 可用來開啟 // 或是關閉除錯訊息 AODV::recvRequest(Packet *p) { 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) { // 檢查這個 request 是不是自己送出來的 fprintf(stderr, "%s: got my own REQUEST\n", FUNCTION ); Packet::free(p); // 若是的話就將此封包丟棄 return; if (id_lookup(rq->rq_src, rq->rq_bcast_id)) { fprintf(stderr, "%s: discarding request\n", FUNCTION ); Packet::free(p); return; // Cache the broadcast ID id_insert(rq->rq_src, rq->rq_bcast_id); // We are either going to forward the REQUEST or generate a // REPLY. Before we do anything, we make sure that the REVERSE // route is in the route table. aodv_rt_entry *rt0; // rt0 is the reverse route rt0 = rtable.rt_lookup(rq->rq_src); if(rt0 == 0) { // if not in the route table // 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; // Find out whether any buffered packet can benefit from the reverse route. // May need some change in the following code - Mahesh 09/11/99 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 // We have taken care of the reverse route stuff. // Now see whether we can send a route reply. rt = rtable.rt_lookup(rq->rq_dst); // 若 Node 本身就是 Qequest 的 destination.. if(rq->rq_dst == index) { fprintf(stderr, "%d - %s: destination sending reply\n", index, FUNCTION ); #ifdef DUMP FILE *fp; if ((fp = fopen("out.aodv", "a"))!= NULL) { fprintf(fp, "%f %d -%s from %d\n", CURRENT_TIME, index, FUNCTION, rq->rq_src); fclose(fp); // 將收到 Request 的時間 接收節點 ID Action 發送節點 ID 等訊息記錄到 out.aodv 這個檔案中 // 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 MY_ROUTE_TIMEOUT, // Lifetime rq->rq_timestamp); // timestamp Packet::free(p);

// 若 Node 本身並不是 destination, 但是有 fresh enough route else if (rt && (rt->rt_hops!= INFINITY2) && (rt->rt_seqno >= rq->rq_dst_seqno) ) { #ifdef DUMP FILE *fp; if ((fp = fopen("out.aodv", "a"))!= NULL) { fprintf(fp, "%f %d -%s from %d (I may have flash enough route)\n", CURRENT_TIME, index, FUNCTION, rq->rq_src); fclose(fp); // 將收到 Request 的時間 接收節點 ID Action 發送節點 ID 等訊息記錄到 out.aodv 這個檔案 assert(rq->rq_dst == rt->rt_dst); sendreply(rq->rq_src, rt->rt_hops + 1, rq->rq_dst, rt->rt_seqno, (u_int32_t) (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, (u_int32_t) (rt->rt_expire - CURRENT_TIME), rq->rq_timestamp); // 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); // Can't reply. So forward the Route Request 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, DELAY); // 將這個封包繼續 forward 出去 AODV::recvReply(Packet *p) { struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p); aodv_rt_entry *rt; char suppress_reply = 0; double delay = 0.0; fprintf(stderr, "%d - %s: received a REPLY\n", index, FUNCTION ); #ifdef DUMP FILE *fp;

if ((fp = fopen("out.aodv", "a"))!= NULL) { fprintf(fp, "%f %d -%s from %d hop=%d latency=%f\n", CURRENT_TIME, index, FUNCTION, rp->rp_src, rp->rp_hop_count, (CURRENT_TIME - rp->rp_timestamp)); fclose(fp); // 將時間 Node ID 函式的功能 Source Node 的 ID Hop count 以及 Latency 等資料記錄在 out.aodv // 這個檔案中 /* * Got a reply. So reset the "soft state" maintained for * route requests in the request table. We don't really have * have a separate request table. It is just a part of the * routing table itself. */ // Note that rp_dst is the dest of the data packets, not the // the dest of the reply, which is the src of the data packets. rt = rtable.rt_lookup(rp->rp_dst); // If I don't have a rt entry to this host... adding if(rt == 0) { rt = rtable.rt_add(rp->rp_dst); // Add a forward route table entry... here I am following Perkins-Royer AODV paper almost literally - SRD // 5/99 if ( (rt->rt_seqno < rp->rp_dst_seqno) // newer route ((rt->rt_seqno == rp->rp_dst_seqno) && (rt->rt_hops > rp->rp_hop_count)) ) { // shorter or better route // Update the rt entry rt_update(rt, rp->rp_dst_seqno, rp->rp_hop_count, rp->rp_src, CURRENT_TIME + rp->rp_lifetime); // reset the soft state rt->rt_req_cnt = 0; rt->rt_req_timeout = 0.0; rt->rt_req_last_ttl = rp->rp_hop_count; if (ih->daddr() == index) { // If I am the original source // Update the route discovery latency statistics, rp->rp_timestamp is the time of request // origination rt->rt_disc_latency[(unsigned char)rt->hist_indx] = (CURRENT_TIME - rp->rp_timestamp) / (double) rp->rp_hop_count; // increment indx for next time rt->hist_indx = (rt->hist_indx + 1) % MAX_HISTORY; /* * Send all packets queued in the sendbuffer destined for * this destination. * XXX - observe the "second" use of p. */ Packet *buf_pkt; while((buf_pkt = rqueue.deque(rt->rt_dst))) { if(rt->rt_hops!= INFINITY2) { assert (rt->rt_flags == RTF_UP); // Delay them a little to help ARP. Otherwise ARP // may drop packets. -SRD 5/23/99 forward(rt, buf_pkt, delay); delay += ARP_DELAY; else {

suppress_reply = 1; /* If reply is for me, discard it. */ if(ih->daddr() == index suppress_reply) { Packet::free(p); else { /* Otherwise, forward the Route Reply. */ // Find the rt entry aodv_rt_entry *rt0 = rtable.rt_lookup(ih->daddr()); // If the rt is up, forward if(rt0 && (rt0->rt_hops!= INFINITY2)) { assert (rt0->rt_flags == RTF_UP); rp->rp_hop_count += 1; rp->rp_src = index; forward(rt0, p, NO_DELAY); // Insert the nexthop towards the RREQ source to // the precursor list of the RREQ destination rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source else { fprintf(stderr, "%s: dropping Route Reply\n", FUNCTION ); drop(p, DROP_RTR_NO_ROUTE); AODV::sendRequest(nsaddr_t dst) { // Allocate a RREQ packet Packet *p = Packet::alloc(); struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p); aodv_rt_entry *rt = rtable.rt_lookup(dst); assert(rt); /* * Rate limit sending of Route Requests. We are very conservative * about sending out route requests. */ if (rt->rt_flags == RTF_UP) { assert(rt->rt_hops!= INFINITY2); Packet::free((Packet *)p); return; if (rt->rt_req_timeout > CURRENT_TIME) { Packet::free((Packet *)p); return; // rt_req_cnt is the no. of times we did network-wide broadcast // RREQ_RETRIES is the maximum number we will allow before // going to a long timeout. if (rt->rt_req_cnt > RREQ_RETRIES) { rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT; rt->rt_req_cnt = 0; Packet *buf_pkt; while ((buf_pkt = rqueue.deque(rt->rt_dst))) { drop(buf_pkt, DROP_RTR_NO_ROUTE); Packet::free((Packet *)p); return;

fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d\n", ++route_request, index, rt->rt_dst); #ifdef DUMP FILE *fp; if ((fp = fopen("out.aodv", "a"))!= NULL) { fprintf(fp, "%f %d -%s to %d\n", CURRENT_TIME, index, FUNCTION, rt->rt_dst); fclose(fp); // 將時間 Node ID 函式功能以及 Request 的 Destination 記錄至 out.aodv 這個檔案中 // Determine the TTL to be used this time. // Dynamic TTL evaluation - SRD rt->rt_req_last_ttl = max(rt->rt_req_last_ttl,rt->rt_last_hop_count); if (0 == rt->rt_req_last_ttl) { // first time query broadcast ih->ttl_ = TTL_START; else { // Expanding ring search. if (rt->rt_req_last_ttl < TTL_THRESHOLD) ih->ttl_ = rt->rt_req_last_ttl + TTL_INCREMENT; else { // network-wide broadcast ih->ttl_ = NETWORK_DIAMETER; rt->rt_req_cnt += 1; // remember the TTL used for the next time rt->rt_req_last_ttl = ih->ttl_; // PerHopTime is the roundtrip time per hop for route requests. // The factor 2.0 is just to be safe.. SRD 5/22/99 // Also note that we are making timeouts to be larger if we have // done network wide broadcast before. rt->rt_req_timeout = 2.0 * (double) ih->ttl_ * PerHopTime(rt); if (rt->rt_req_cnt > 0) rt->rt_req_timeout *= rt->rt_req_cnt; rt->rt_req_timeout += CURRENT_TIME; // Don't let the timeout to be too large, however.. SRD 6/8/99 if (rt->rt_req_timeout > CURRENT_TIME + MAX_RREQ_TIMEOUT) rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT; rt->rt_expire = 0; fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d, tout %f ms\n", ++route_request, index, rt->rt_dst, rt->rt_req_timeout - CURRENT_TIME); // Fill out the RREQ packet // ch->uid() = 0; ch->ptype() = PT_AODV; ch->size() = IP_HDR_LEN + rq->size(); ch->iface() = -2; ch->error() = 0; ch->addr_type() = NS_AF_NONE; ch->prev_hop_ = index; // AODV hack

ih->saddr() = index; ih->daddr() = IP_BROADCAST; ih->sport() = RT_PORT; ih->dport() = RT_PORT; // index 就是 Source Node 自己本身的 Node ID // Fill up some more fields. rq->rq_type = AODVTYPE_RREQ; // AODV RREQ rq->rq_hop_count = 1; rq->rq_bcast_id = bid++; rq->rq_dst = dst; rq->rq_dst_seqno = (rt? rt->rt_seqno : 0); rq->rq_src = index; seqno += 2; assert ((seqno%2) == 0); rq->rq_src_seqno = seqno; rq->rq_timestamp = CURRENT_TIME; Scheduler::instance().schedule(target_, p, 0.); AODV::sendReply(nsaddr_t ipdst, u_int32_t hop_count, nsaddr_t rpdst, u_int32_t rpseq, u_int32_t lifetime, double timestamp) { Packet *p = Packet::alloc(); struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p); aodv_rt_entry *rt = rtable.rt_lookup(ipdst); fprintf(stderr, "sending Reply from %d at %.2f\n", index, Scheduler::instance().clock()); #ifdef DUMP FILE *fp; if ((fp = fopen("out.aodv", "a"))!= NULL) { fprintf(fp, "%f %d -%s to %d\n", CURRENT_TIME, index, FUNCTION, ipdst); fclose(fp); // 將時間 Node ID 函式功能以及 Reply 的 Destination 記錄至 out.aodv 這個檔案中 assert(rt); rp->rp_type = AODVTYPE_RREP; //rp->rp_flags = 0x00; rp->rp_hop_count = hop_count; rp->rp_dst = rpdst; rp->rp_dst_seqno = rpseq; rp->rp_src = index; rp->rp_lifetime = lifetime; rp->rp_timestamp = timestamp; // ch->uid() = 0; ch->ptype() = PT_AODV; ch->size() = IP_HDR_LEN + rp->size(); ch->iface() = -2; ch->error() = 0; ch->addr_type() = NS_AF_INET; ch->next_hop_ = rt->rt_nexthop; ch->prev_hop_ = index; // AODV hack ch->direction() = hdr_cmn::down; ih->saddr() = index; ih->daddr() = ipdst; ih->sport() = RT_PORT;

ih->dport() = RT_PORT; ih->ttl_ = NETWORK_DIAMETER; Scheduler::instance().schedule(target_, p, 0.); 模擬結果首先我們先將 TCL Script 的執行過程列出來給大家看一下 ($ 為 Linux 的命令列提示符號 ) 這個 TCP Script 在執行的過程中會產生 10 個 Node,Node 的位置 ( 在 X Y 軸上的位置 ) 都是以亂數的方式產生的 另外, 包括應用程式啟動的時也都是亂數產生的, 其中,ftp 3 在 2.305251 秒時開始傳資料,ftp 7 則是在 2.489969 開始傳資料, 最後一個傳資料的是 ftp 8, 流量產生的時間是在 9.968638 秒開始 $ ns random_pos_delay.tcl 10 random 257786189 Starting Simulation... node(0): x=226.36 y=375.28 node(1): x= 59.64 y=455.10 node(2): x=161.30 y= 16.69 node(3): x=317.45 y=241.36 node(4): x=496.28 y=302.26 node(5): x=492.77 y=250.63 node(6): x=175.43 y=424.38 node(7): x=246.15 y=182.01 node(8): x= 23.02 y=292.30 node(9): x=470.40 y=315.52 5.002775 ftp 0 ON 7.609607 ftp 1 ON 6.345164 ftp 2 ON 2.305251 ftp 3 ON 4.603531 ftp 4 ON 4.861860 ftp 5 ON 9.561685 ftp 6 ON 2.489969 ftp 7 ON 9.968638 ftp 8 ON num_nodes is set 10 channel.cc:sendup - Calc highestantennaz_ and distcst_ highestantennaz_ = 1.5, distcst_ = 550.0 接下來我們就透過我們自行產生的 out.aodv 這個 Trace 檔的來觀察到 AODV 的訊息是如何在網路上的 Node 之間運作的 : 2.305251 3 -sendrequest to 4 // 註 :ftp 3 準備開始傳資料 2.306068 4 -recvrequest from 3 2.306068 4 -sendreply to 3 2.307247 3 -recvreply from 4 hop=1 latency=0.001996 2.489969 7 -sendrequest to 8 // 註 :ftp 7 準備開始傳資料 2.490840 8 -recvrequest from 7 2.490840 8 -sendreply to 7 2.492371 7 -recvreply from 8 hop=1 latency=0.002402 4.603531 4 -sendrequest to 5 4.604492 5 -recvrequest from 4 4.604492 5 -sendreply to 4 4.604675 4 -recvreply from 5 hop=1 latency=0.001144 4.861860 5 -sendrequest to 6 4.873483 6 -recvrequest from 5 4.873483 6 -sendreply to 5 4.874585 3 -recvreply from 6 hop=1 latency=0.012725 4.875842 5 -recvreply from 3 hop=2 latency=0.013982 5.002775 0 -sendrequest to 1 5.004391 1 -recvrequest from 0 5.004391 1 -sendreply to 0

5.009988 0 -recvreply from 1 hop=1 latency=0.007213 6.346590 3 -sendrequest to 2 6.351998 2 -recvrequest from 3 6.351998 2 -sendreply to 3 6.352290 7 -recvreply from 2 hop=1 latency=0.005700 6.352766 3 -recvreply from 7 hop=2 latency=0.006177 7.609607 1 -sendrequest to 2 7.611540 3 -recvrequest from 1 (I may have a fresh enough route) 7.611540 3 -sendreply to 1 7.611540 7 -recvrequest from 1 (I may have a fresh enough route) 7.611540 7 -sendreply to 1 7.613417 0 -recvreply from 3 hop=3 latency=0.003810 7.613822 1 -recvreply from 0 hop=4 latency=0.004215 7.614355 0 -recvreply from 7 hop=2 latency=0.004748 7.615207 2 -sendrequest to 1 7.616209 7 -recvrequest from 2 (I may have a fresh enough route) 7.616209 7 -sendreply to 2 7.616573 2 -recvreply from 7 hop=3 latency=0.001366 7.616959 1 -recvreply from 0 hop=3 latency=0.007352 9.561685 6 -sendrequest to 7 9.567289 7 -recvrequest from 6 9.567289 7 -sendreply to 6 9.568074 0 -recvreply from 7 hop=1 latency=0.006389 9.568343 6 -recvreply from 0 hop=2 latency=0.006658 9.968638 8 -sendrequest to 9 // 註 :ftp 8 準備開始傳資料 9.977700 9 -recvrequest from 8 9.977700 9 -sendreply to 8 9.977848 3 -recvreply from 9 hop=1 latency=0.009210 9.978225 0 -recvreply from 3 hop=2 latency=0.009587 9.980091 8 -recvreply from 0 hop=3 latency=0.011453 由於 AODV 是一種 On deman 的 Protocl, 也就是只有在需要時,AODV 才會去尋找一個由 Source 至 Destination 之間的 Route 所以在 Application 有資料要準備開始傳時,AODV 才去把傳送這個資料所需要的找出來 Reference: http://nsda.ee.ncku.edu.te/chengrs/