Skip to main content

34 posts tagged with "OMNET++"

View All Tags

· One min read

原來 OMNET++ 4.0 有 IDE 可用了呀,真是相當驚人。

另外,3.2 版也有 xMIPv6 Framework 可以用了,可以根據 xMIPv6 修改,來支援 HMIPv6、SMIPv6、甚至是 NEMO 等衍生 protocol。 整個 Framework 是從 INET 修改而來,說明在這。要是早幾年出來,我的論文就不必用麻煩的 NS-2 模擬啦。

· One min read

From Tom Parker:

They are available by adding the following lines to your /etc/apt/sources.list

deb http://tevp.net/debian/ binary/ deb-src http://tevp.net/debian/ source/

and then running "apt-get update", followed by "apt-get install omnetpp-static". As the name suggests, the package only currently has static library versions of OMNeT++ not the shared versions, but I will be expanding this to include shared versions at a later date.

· 2 min read

修改模組就是由實際 class, procedure 到目標理想 class, procedure 的過程. 在動手修改模組之前必定先規劃好目標系統.

使用類似重構的開發方法,一次只做一點點的改動,

make (nmake) 的特性是只重編改動到的檔案,因此如果你一次只改動一兩個檔案, 並用上一個還行的 CPU (~1G), 就不用擔心重新編譯所需時間過長的問題.

每次作改動的時候將之清楚紀錄下來,這樣多作幾次下來的結果就會越來越熟悉,考慮的越來越完整,每步的幅度就越來越精準.

當 然,你對模擬工具組成架構越清楚,在模擬工具程式架構清楚的情況下,你的目標理想 class, procedure 可能就會越接近實際 class, procedure. 為了修改模組順暢,適當參考相關模擬程式提供的架構是必要的。不然會遇到規劃出來的目標架構無法從模擬程式順利修改的窘境.

OMNeT++ 比起 NS2 很大的優勢就在此, 感謝 Andras 開發的 IPv6SuiteWithINET 模組,讓我們可以用很接近實作的 Code 來模擬. 另一個例子是 S. Dulman 開發的 NesCT, 可以用此模組在 OMNeT++ 上跑 TinyOS 程式.

· 2 min read

Q: INET framework without dynamic nedfile

A: Easiest way to switch from dynamic NED to compiled-in NED for INET is to remove the "-N" flag from OPTS at the top of the makemake script, then regenerate the makefiles (./makemake) and make. (And of course remove preload-ned-files lines from omnetpp.ini's.)

Q:I'll use an example from Omnet Documentation:

module RoutingTestNetwork
parameters:
routingNodeType: string; // should hold the name
// of an existing module type
gates: //...
submodules:
node1: routingNodeType like RoutingNode;
node2: routingNodeType like RoutingNode;
//...
connections nocheck:
node1.out0 --> node2.in0;
//...
endmodule

What happens if I declare a routingNodeType in omnet.ini file which would be different from that declared in my .ned file? e.g. omnetpp.ini: *.node.routingNodeType = "Routingsomething"

Or perhaps I have to define this module in RoutingNode.ned and add some parameters in Routingsomething.ned if I want.

A:The setting in the NED file, if present, takes precedence over omnetpp.ini (basically, omnetpp.ini is only consulted if param is not set in the NED).

The module Routingsomething MUST have at least the parameters and gates RoutingNode has, but it can add new ones as well.

Q:I wish to create shared libs in each of the subdirectories then link them to an executable for each of the networks like the old IPv6Suite.

A: we haven't actually had this option available for the IPv6SuiteWithINET.

Currently, all c++ objects are statically linked into bin/INET. A batch file is provided in each network directory to run the executable, bin/INET and load omnetpp.ini (or -f <your_own_network_ini>) in the current network directory. (Eric)

Q:</your_own_network_ini> I've installed TCL/TK but while executing make command, it can't found them <your_own_network_ini>A:</your_own_network_ini> Go to the installing directory and edit configure.user. Specifiy the path to the TCL/TK header files. On my mashine tcl.h and tk.h are in /usr/include/:

TK_CFLAGS="-I/usr/include/tcl8

4 -fwritable-strings" TK_LIBS="-L/usr/lib -ltk8.4 -ltcl8.4"

You should change the compiler flags if you want to debug your sessions:

CFLAGS='-gstabs+3 -Wall'

· 2 min read

----in IPv6SuiteWithINET: work---- Applications/UDPApp 下新增 "NDSBasicApp.cc", "NDSBasicApp.h", "NDSBasicApp.ned".

makemake nmake -f makefile.vc depend (option) m.bat

----in INET: not work---- Our goal is to build a UDP based Application named NDSApp.

1. Add "NDSApp" folder in "INET/Applications" folder

2. Modifiy "INET/makemake.cmd" to generate makefile for the new App(If you add/remove/rename directories). set ALL_INET_INCLUDES: append -I%root%/Applications/NDSApp

We copied the line "cd %root%\Applications\UDPApp && ....." and change "UDPApp" to "NDSApp"

cd %root%\Nodes\INET: append -I....\Applications\NDSApp

3. Copy files "UDPApp.cc", "UDPApp.h", "UDPApp.ned" from "UDPApp" folder, Rename "UDPApp.cc", "UDPApp.h", "UDPApp.ned" to "NDSApp.cc", "NDSApp.h", "NDSApp.ned".

4. In file "NDSApp.cc" "#include "UDPApp.h"" to "#include "NDSApp.h"" Replace the class inherits and function names from "UDP"xx to "NDS"xx, ex: "UDPSink::initialize();" to "NDSSink::initialize();"

5. Add NDSApp to StandardHost Modifiy INET/Nodes/StandardHost.ned At import section: append "NDSApp,"

At module StandardHost parameters section: Append "numNdsApps : numeric const, "ndsAppType : string,"

At module StandardHost submodules section: Append ndsApp: ndsAppType[numNdsApps] like NDSApp; display: "i=block/app;p=392,67";

At module StandardHost connections section: Append "for i=0..numNdsApps-1 do ndsApp[i].to_udp --> udp.from_application++; ndsApp[i].from_udp <-- udp.to_application++; endfor;"

makemake nmake -f makefile.vc depend m.bat

Then test it in Example/INET/Multicast

modify its omnetpp.ini

set UDPApp off

udp app (off)

.numUdpApps=0 .udpAppType="UDPApp"

modified udp app configuration to nds app configuration, note the captions.

· 2 min read

If the dest_addresses parameter contains more than one address, one of them is randomly chosen for each packet.

An address may be given in the dotted decimal notation, or with the module name. (The IPAddressResolver class is used to resolve the address.)

To disable the model, set dest_addresses to "".

The peer can be UDPSink or another UDPBasicApp (it handles received packets exactly like UDPSink).


UDPAppBase: *** void UDPAppBase::bindToPort(int port)

cMessage msg = new cMessage ("UDP_C_BIND", UDP_C_BIND); 建立新 message "msg", 使用 UDP_C_BIND 格式

UDPControlInfo ctrl = new UDPControlInfo (); 建立新 record "ctrl"

ctrl->setSrcPort (port); 將 port 參數設定進 ctrl 的 SrcPort 參數中

msg->setControlInfo (ctrl); 將 ctrl 包進 msg 中的 ControlInfo 參數中

send (msg, "to_udp"); 送到傳輸層的 udp 做處理

void UDPAppBase::sendToUDP(cMessage *msg, int srcPort, const IPvXAddress& destAddr, int destPort)

msg->setKind(UDP_C_DATA); Send message to UDP, with the appropriate control info attached

其他類似 bindToPort ()


UDPSink: void UDPSink::initialize()

WATCH (numReceived); TKenv 中顯示 numReceived 變數

if (port!=-1) bindToPort (port); port 數字正常就將 port 參數繫結到埠號

void UDPSink::handleMessage (cMessage *msg) 處理封包並秀 numReceived 狀態在畫面中

void UDPSink::processPacket (cMessage *msg) 收到封包後刪除,numReceived 數 +1


UDPBaseApp

const char destAddrs = par ("dest_addresses"); 讀入目的位址 cStringTokenizer tokenizer (destAddrs); const char token; while ((token = tokenizer.nextToken ())!=NULL) destAddresses.push_back (IPAddressResolver ().resolve (token)); 解析 string 成可辨識的位址格式

void UDPBasicApp::sendPacket () IPvXAddress destAddr = chooseDestAddr (); 超過一個目的位址時從中選擇隨機目的位址

IPvXAddress UDPBasicApp::chooseDestAddr () { int k = intrand (destAddresses.size ()); destAddresses.size () 即目標位址數量,intrand (n) 從 n 中隨機取一數

return destAddresses[k];

}

· 2 min read

22th. Part: 修改 IPControlInfo.msg: 協定對應改成 IP6NextHeaderFieldId

檢討:在修改一陣子模組之後,對整個架構更了解的同時, 也更了解修改整個 IP 協定的難度. 因為了解,而越來越缺少每個部分改好兜起來就能跑的自信.

所以檢討了現在 porting 的方法,歸納出下面幾條新的 porting 步驟:

第一階段:多方嘗試 (完成) 1. 初步對各主要模組了解,trace code 同時並做初步 porting. 2. 儲存當前 porting slices 成果

第二階段:系統化調試 1. 一切修改都應該先以能執行,能隨時觀察模擬流程為目標. (每次修改都能編出可用的快照檔 (snapshot)) 2. 將 IP 相關模組複製一份,編譯,確定可用的新增協定方式 3. 階段修改 2. 修改 Mac 層加入訊息 3. 修改 IPDatagram.msg 新增協定 4. 修改協定訊息 5. 修改各 Class 名稱 6. 實際修改 Class 7. 路由表位址,位址解譯,flatconfigurator

第三階段:新增功能 1. Neighbor Discovery (Major Option). MIPv6 & NEMO (After Wireless Support) 2. DualStack 3. Extension Header Proccessing 4. RSVP, Multicast

· 2 min read

18th. Part: NetworkLayer6.ned: disable OSPF, RSVP 原 protocolMapping = "6:0,17:1,1:2,2:3,46:4,89:5"; 表示 TCP (6):0, UDP (17):1, ICMP (1):2, IGMP (2):3, RSVP (46):4, OSPF (89):5 考慮到保證將來 DualStack 相容性,因此不更改原對應數字,而從後面再繼續補加.

暫時補加 ICMPv6 (58):2, ROUTING (43), MOBILITY (135) protocolMapping 後添上 58:6,43:7,135:8

  • 應再找資料確認 Neighbor Discovery -- ND 模組是否應包含在 ICMPv6 模組裡

19th. Part: 照著 Winodws 步驟,以 TicToc10 為基礎編譯. OMNET++/Sample/INET6Test: 修改 IP6Datagram.msg 以通過 compiler.

這次是針對 "模擬" 來做修正:

  • 因為 20 bits 不好宣告 (RFC 中是連 version, Traffic Class 一同宣告在一起), 因此 flow label 欄位訂的較 RFC 小 (20->16) (反正沒在用,應該沒什麼關係)
  • 在訂 IPv6 options message struct 時,Padding 不加似乎也沒關係
  • IP6FRAGMENT identification 欄位訂的較 RFC 小 (32->16)

目前採用方式 -> 全改用 int , short, long 來宣告,皆遠大於所需位元數

· One min read

17th Part:

檔案管理方式決定: 用 freemind 畫好了 INET6 與 INET 檔案分佈圖, 隨時比較兩者間相應模組與進度

封包測試方式決定: 使用 tictoc scenario 先測試 IPv6, ICMPv6 封包格式的正確性

· One min read

The Mobility module provides a geographical position of the host and handles its movement.

The Blackboard module is used for cross layer communication. It provides information relevant to more than one layer like the actual energy status of the host, the display appearance or the status of the radio.

· One min read

15th Part:

模組組成

  • PING6, TraceRoute6
  • UDP6

IP6

  • ICMP6
  • ND (replace ARP) -- future --
  • MLD
  • IPSEC

封包處理流程: 收到封包 -> 判斷是給自己或給別人的封包 (Deliver locally/Addressed to another node) If 給別人 ->Look up routing table -> 轉送封包到對應介面上 (identified interface)

16th Part: 位址格式:

  • unicast
  • link-local
  • multicast
  • IPv4-compatible address 評估: flatconfigurator6 是否可以先使用 IPv4-compatible address 的方式設定?

Addressing format (參考 Smartbit-smartflow):

  • Full hexadecimal
  • No leading zero (前面的 0 省略)
  • Compact (最簡化 ex: 2001::1)
  • Mixed (最後四碼接 IPv4 位址 ex: 2001::192.168.0.1)

· 3 min read

13th. Part: 看 RFC3493RFC 2542 一邊處理 IP6Address.h 位址格式設定的問題.

原本 IPAddress 內部結構是 unsigned char addr[4]; 用來儲存 32bits IP 位址 改成 IP6Address 後, 內部結構要儲存 128 bits IPv6 位址,因此改成 uint8_t s6_addr[16];

取消輸入值或回傳值為 int 型態的函數,因為與 IPv6 位址表示方式不符, 這部分需弄更清楚後再作加強.

14th. Part: 聯想:

猜測 OMNET++ 中的 IPControInfo 應該就是 RFC 中的 sockaddr_in , 是用來與上層協定溝通的資料結構.

該詢問 INET Wireless 模組部分的進度 The routing information for wired nodes are based on connectivity of the topology, i.e how are nodes connected to one another through Links. This connectivity information is used to populate the forwarding tables in each wired node., however wireless nodes have no concept of "links".

Inorder to exchange pkts among these wired and wireless nodes, Base-stations(BS) is introduced to act as gateways between the two domains.

porting 學長模組時, 發現 OPNET/NS2 (Mobiwan2) 共同的缺點是模組用太多簡寫, 讓人剛開始沒有辦法一看就很清楚這模組的作用...... 若能減少花在辨認簡寫上的時間, 使用者可以更容易明瞭各模組的作用, 也能更容易去使用它們.

· 3 min read

從 UDPApp 或 TCPApp 一堆檔案中,總是要從 xxSinkApp 最先開始看, 最簡單又能猜測到大致流程的一定是這幾個檔案,透過這樣 tracing code 熟悉了大致架構後,看其他相關檔案時會事半功倍.

因為 xxSinkApp 明顯講的都會是如何收到這種類型的封包,還有收到後如何將封包消滅的過程


TCPSinkApp void TCPSinkApp::initialize()

TCPSocket socket; 宣告 TCPSocket

socket.setOutputGate(gate("tcpOut"));

socket.bind(address[0] ? IPAddress (address) : IPAddress (), port); 繫結 "位址 - 埠號"

socket.listen(true);

.... 參考一般 socket 連線相關文件

void TCPSinkApp::handleMessage (cMessage *msg) if (msg->kind ()==TCP_I_PEER_CLOSED) 如果狀態為 TCP_I_PEER_CLOSED

msg->setKind (TCP_C_CLOSE); 將狀態設成 TCP_C_CLOSE

send (msg, "tcpOut"); 將訊息送到 "tcpOut"

else if (msg->kind ()==TCP_I_DATA || msg->kind ()==TCP_I_URGENT_DATA) 如果狀態為 TCP_I_DATA 或 TCP_I_URGENT_DATA

bytesRcvd += msg->length ()/8; bytesRcvd += 收到的封包 bit 長度 / 8 (變成 byte)

delete msg; 並將訊息刪除

else delete msg; 收到其他狀態訊息的話都直接刪除


TCPEchoApp echoFactor=1 will result in sending back the same message unmodified The lengths of the messages are multiplied by echoFactor before sending them back

void TCPEchoApp::sendOrSchedule(cMessage *msg)

if (delay==0) 若 delay 變數值為 0

bytesSent += msg->length ()/8; 紀錄總共送出的封包 byte 長度

send (msg, "tcpOut"); 並送出訊息

else scheduleAt (simTime ()+delay, msg); 否則繼續等待 delay 這段時間

void TCPEchoApp::handleMessage(cMessage *msg)

if (msg->isSelfMessage ()) 若訊息來自本身 紀錄總共送出的封包 byte 長度 並送出訊息

else if (msg->kind ()==TCP_I_PEER_CLOSED) 如果狀態為 TCP_I_PEER_CLOSED

msg->setKind (TCP_C_CLOSE); 將狀態設成 TCP_C_CLOSE

sendOrSchedule (msg); 將訊息傳到 sendOrSchedule () 處理

else if (msg->kind ()==TCP_I_DATA || msg->kind ()==TCP_I_URGENT_DATA) 如果狀態為 TCP_I_DATA 或 TCP_I_URGENT_DATA 紀錄總共收到的封包 byte 長度

if (echoFactor==0) 若 echoFactor==0 將訊息刪除

else 其他: msg->setKind (TCP_C_SEND); 狀態設成 TCP_C_SEND

//reverse direction, modify length, and send it back

TCPCommand ind = check_and_cast<TCPCommand >(msg->removeControlInfo ()); 將 msg 的 ControlInfo 去掉後,強制轉換型別成 TCPCommand

TCPSendCommand *cmd = new TCPSendCommand();

cmd->setConnId(ind->connId()); msg->setControlInfo(cmd);

delete ind; 將不再用到的 ind 刪除

計算回傳訊息大小: long len = long (msg->length ()echoFactor) & ~7U; 將原訊息長度echoFactor

if (len<8) len=8; 若訊息長度小於 1 byte, 補足成 1 byte

msg->setLength (len); 設定回傳訊息長度 sendOrSchedule (msg); 排到 sendOrSchedule () 中

else delete msg; 收到其他狀態訊息的話都直接刪除

· One min read

void TCPGenericCliAppBase::setStatusString(const char *s) { if (ev.isGUI()) displayString().setTagArg("t", 0, s); }

void TCPGenericCliAppBase::socketEstablished(int, void ) { // redefine* to perform or schedule first sending ev << "connected\n"; setStatusString("connected"); }

· One min read

I found this paper through IEEE Xplore, and intrest in the topic "Eval freeBSD protocol stack in OMNeT++".

Integration of the FreeBSD TCP/IP-Stack into the Discrete Event Simulator OMNet++ Bless, R.; Doll, M.; Simulation Conference, 2004. Proceedings of the 2004 Winter Volume 2, December 5-8, 2004 Page(s):487 - 492

--

  • In asimulation environment one wants to run several hosts in parallel, So every required global and static FreeBSD variable must be made local to each host. -> a structure to store all the kernel variables for one host. -> Consequently,in the FreeBSD source every occurrence of the variables must be replaced by a reference into the corresponding structure.

ex: xyz is replaced to D->xyz

where D points to the current host structure that contains all the global and static kernel variables for this particular host.

  • Encapsulate the complete TCP/IP into one OMNeT++ simple module.

Others are out of my knowledge...... In consequence, I think porting protocol stacks from different architecture is still not an easy way....

· One min read

Define_Module (PingApp); 模組名稱是 PingApp

PingApp::initialize()

  1. 讀入 omnetpp.ini 中設定的參數.
  2. 在 TKenv 中監視
  • sendSeqNo
  • expectedReplySeqNo
  • dropCount
  • outOfOrderArrivalCount 這幾個結果 PingApp::handleMessage (cMessage *msg)

if (msg->isSelfMessage ()) 若訊息來自本身節點

destAddr = IPAddressResolver ().resolve (par ("destAddr")); 解析目的位址設定

來自其他節點則啟動回覆機制

processPingResponse(check_and_cast<pingpayload>(msg));

void PingApp::sendPing()

PingPayload msg = new PingPayload (name); 新增封包,接著下面照著宣告的格式填入對應的值 msg->setLength (8packetSize); //? 封包裡沒宣告

sendToICMP (msg, destAddr, srcAddr, hopLimit); 把訊息送到 ICMP 裡

PingApp::scheduleNextPing(cMessage *timer)

simtime_t nextPing = simTime () + intervalp->doubleValue (); 模擬時間加上間隔時間

void PingApp::sendToICMP(cMessage *msg, const IPvXAddress& destAddr, const IPvXAddress& srcAddr, int hopLimit) 判斷送出 v4/v6 icmp 格式封包

void PingApp::processPingResponse (PingPayload *msg) 收到 ICMP 封包,判斷</pingpayload> v4/v6 並<pingpayload>處理 </pingpayload>

· One min read

針對我所要用的編譯器 還有 執行檔 定義一些所需要的 set path

在命令提示字元底下一定要找得到以下幾個可執行的程式: nmake cl vcvars32.bat

我的電腦按右鍵 -> 內容 -> 進階 -> 環境變數 -> 系統變數 -> 編輯 path, 加入 C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\bin;

切換到目錄,執行 vcvars32.bat 以設定 vc71 環境. 若 path 變數未設好,則會出現找不到這檔案的訊息. 接著執行 m.bat 編譯即可.

若發生問題,可以試著鍵入 makemake 重新產生 makefiles. 再打入 nmake -f makefile.vc depend 確認相依性. 之後再執行 m.bat 重新編譯一次即可

參考網址 http://java.csie.nctu.edu.tw/~deryann/paper/HowToSTL.htm

· 2 min read

11th. Part: IPv4d/IPProcessing 模組功能等同 IPv4/IP 模組

因此 IPv4 資料夾即已實作 IPv4 協定 IPv4d 資料夾內程式則是將 IP 模組內容拆開成多個子模組, 以此推論,若模擬的目標是 IP 協定運作情形, 單單只看到 IP 模組並不能滿足要求時, 則將 Nodes/INET/ 各 .ned 檔中的 "IP" 改成 "IPProcessing" 應該 就可以看到更詳細的 IP 協定運作情形。建議名稱: Routerd / Router6d?

節點先做 Nodes/INET6/BurstHost6 與 Router6, StandardHost6 稍後再處理

  • 要寫自行設定模組的 Tutorial

12th. Part: INET 比 NS2 好的特色: FlatNetworkConfigurator, 只需指定網域 / 遮罩, INET 即自動配置各節點模擬用的位址.

  • 要研究 AutoRouting 中 FlatNetworkConfigurator 的做法 (怎麼與 ND 互補?(有 ND 那 FlatNetworkConfigurator 就不應作用於 '*Host' 上) ex:
  • 決定 Prefix/Prefix Lenth (Subnetmask),
  • 設定啟不啟動 DAD 等)

Neighbor Discovery vs ARP IPv6d/ND 將作為一個模組來對應 NetworkInterfaces/ARP

IP protocol header is represented by the IPDatagram message class

· 4 min read

9th. Part: 編輯 IP6Datagram.msg 參考 IANAPROTOCOL NUMBERS 來改寫 IP6Datagram.msg

Protocol field -> Next Header field 因此 enum 名稱 IP6ProtocolFieldId 改成 IP6NextHeaderFieldId

IPv4 上叫 Protocol field, IPv6 上稱 Next Header field 為了相容性,將原本定義的 Protocol field 全保留之外,另外新增

  • IP6_PROT_IPv6_Route = 43; //Routing Header for IPv6 [Deering]
  • IP6_PROT_IPv6_Frag = 44; //Fragment Header for IPv6 [Deering]
  • IP6_PROT_ESP = 50; //Encap Security Payload [RFC2406]
  • IP6_PROT_AH = 51; //Authentication Header [RFC2402]
  • IP6_PROT_IPv6_ICMP = 58; //ICMP for IPv6 [RFC1883] IP6_PROT_NONE = 59; --> IP6_PROT_NoNxt = 59; //No Next Header for IPv6 [RFC1883]
  • IP6_PROT_Opts = 60; //Destination Options for IPv6 [RFC1883]
  • IP6_PROT_ENCAP = 98; //Encapsulation Header [RFC1241,RXB3]

除了這些之外,順便把一些 Routing protocol 的號也加了上去.

IP6_PROT_IPv6_MOBILITY 原本給 62, 改成 IP6_PROT_IPv6_MOBILITY = 135; //Mobility Header for IPv6 [RFC3775]

從一串配給號碼中發現比較特別的是

61                 any host internal protocol           [IANA]
63 any local network [IANA]
68 any distributed file system [IANA]
99 any private encryption scheme [IANA]
114 any 0-hop protocol [IANA]

剛開始看不知有何特別作用,後來想想這幾個保留位看起來對模擬工具好像不賴 --> 有新協定要試作? 不必改到標頭定義,暫時先用這幾個吧! 不過沒有標頭名稱怎麼辦? Orz ..... 還是暫時不要加進去好了

本檔案編完的下一步應是編輯 IP6Address.h 或 IP6ControInfo.msg 吧

Ref: IP VERSION 6 PARAMETERS , ICMPv6 TYPE NUMBERS

10th. Part:

編輯 IP6Datagram.msg 中的 message IP6Datagram : 參考 IPv6Suite IP6Datagram.cc 來改寫 IP6Datagram.msg

ToDo: 1. 將相關各標頭定義在檔案裡. 2. 定義 flow_label 結構 (struct, 20 bit = double + short OR int + int + short OR?) 3. 訂 Options Types

IP6Datagram.cc 中標頭是如此定義出來的:

static const ipv6_hdr IPV6_INITIAL_HDR = { 0x60000000, //version 6, traffic class of 0, flow label of 0 0, //payload of 0 59, //No next header yet 0, //Hop Limit set to uninitialised IPv6_ADDR_UNSPECIFIED, IPv6_ADDR_UNSPECIFIED };

完整的標頭:

message IP6Datagram
{
properties:
//g Still unknown its func
omitGetVerb = true;
fields:
short version = 6; // version 6
int traffic_class = 0; // traffic class of 0
IP6FlowLabel flow_label; // flow label of 0
double payload_length = 0; // payload of 0
int next_header enum(IP6NextHeaderFieldId) = IP_PROT_NONxt; // No next header yet
int hop_limit = 0; //Hop Limit set to uninitialised
IP6Address srcAddress;
IP6Address destAddress;
}

即將碰到 day 3 提到的 延伸標頭處理 問題. RFC2460 上的敘述是這樣的

4.1 Extension Header Order [Page 6] When more than one extension header is used in the same packet, it is recommended that those headers appear in the following order:

IPv6 header Hop-by-Hop Options header Destination Options header (note 1) Routing header Authentication header (note 2) Encapsulating Security Payload header (note 2) Destination Options header (note 3) upper-layer header Fragment header

填 class IP6Options, 碰到 Option_Data: Variable-length field. Option-Type-specific data 的問題

經 majorlee 學長指點 RFC 3493 Basic Socket Interface Extensions for IPv6. RFC 3542 Advanced Sockets Application Program Interface (API) for IPv6 裡可能會有答案.

· 2 min read

7th Part: 為了對將來開發好的程式進行測試,新增目錄 INET/Tests/IPv6 同時也發現原本 INET 程式的測試數量明顯不足,但還好結果不差.

發現 Firebird 的 scratchbook extension 可以編輯已截取的網頁文件,可以在原文件上畫重點並加上註解, 我想應該充分將這個特點利用在 INET 與 IPv6Suite 線上文件注釋上.

8th. Part: 分析 Mobiwan2 架構,並與學長留下的舊版程式碼作比對. 為此使用 WinMerge 程式來協助版本比對的工作.

OMNET++ INET 與 NS2 的比較: 目錄名: INET mobiwan 架構:按照 TCP/IP 作分層目錄 / 平行資料夾目錄 相依性:放到 OMNET++ 3.0 以上版本目錄下,依照 Readme 即可安裝 / 需 Patch 特定版本的 NS2

Mobiwan 新舊檔案比較 檔案:新 / 舊 ipv6.cc, ipv6.h: Network --> NetworkAgent

ipv6.cc - line 416 r line 497: hdripinip ppinhdr = (hdr_ipinip )p->access(off_ipinip); 改成: hdr_ipinip ppinhdr = (hdr_ipinip )hdr_ipinip::access(p);

mipv6.cc 大修改 mipv6.h: Binding 訊息,Mobile IPv6 Base Agent, Mobile IPv6 Node

ipv6routing.h, classifer-src.h 完全相同

tcl/lib 2.27 版多了很多檔案,包含 2.1b1 版所有檔案。尚不知是否會造成什麼影響

· 2 min read

5th Part: 閱讀論文: KAME IPv6 Impliment issue 文中指出 IPv6 遵照 IPv4 基礎來修改,所以基本觀念不變. 文中也提出一些 porting 中遇上的問題: 1. Scope 位址處理 2. 多重位址應綁介面 (Interface) 而非綁節點 (Node) 3. 延伸標頭處理 4. IPSec

目前可能會遇到的問題還不只這些: 1. 位址分析 2. 明確的參考資料 ...., etc

6th. Part 閱讀書籍: C++ 風格與藝術 第二版 (Practical C++ Programming, 2e) 整本書說明都很清晰,應該買一本手邊隨時參考

程式碼要像文章一樣分段落章節,每段並加入主題說明, 變數避免用縮寫,以降低程式複雜度

原型:先寫規格中可以運作的部分, 當這一小部份運作正常之後, 再以它為基礎, 建立其他的功能.

程式檔中應包含: Header 標題 Author 作者 Purpose 目的 Usage 用法 References 參考資料 File Formats 列出讀取 / 寫入的檔案與格式 Restrictions 限制 (Q by myself: 是否可延伸成代辦事項?Revice: ToDo 集中管理會比較有效率) Revision History Error Handling Copyright and License Notes 補充說明

  • 編輯提供 .ned 架構檔在 NodePad++ 編輯關鍵字加亮的定義, 但還沒找到獨立提供這個設定檔的方法

3/11 update: 定義在 NodePad++ 資料夾下 userDefineLang.xml 檔中

· 3 min read

這系列文章僅記錄過程,目的是從紀錄中看到自己對的 ipv6 了解,對做事方法的改進. 不總結經驗。因為一但總結經驗就會陷入長段撰寫文件的誤區。而且在現在階段,甚至不能確定此專案能否成功。希望我能有寫出總結經驗文章來的一天吧:)

1st. Part: 第一步先從 ICMPv6 開始著手 Porting. 在熟悉 INET 目錄規劃後,首先是根據 INET 目錄規則來建立 INET 專案所應用到的目錄, 剛開始在 Network 目錄下先建立 IPv6 與 IPv6d 兩個目錄。並在 Nodes 目錄下建立 INET6 目錄.

從 IETF RFC 列表 中挖出了 RFC 2463, Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification, 依此為憑開始 porting.

編輯 Network/IPv6/ICMPv6.ned 參照 IPv6Suite, 從 IPv6Suite/IP/IPv6/Generic 目錄下的 ICMPv6.ned. 觀察它的 ICMPv6 模組組成. 發現該模組與 INET 的 ICMP.ned 大不相同,是由 IPv6Core, Neighbourdiscovery, ICMPv6Combine, 還有 MLD (multicast) 模組組成的複合模組. MLD 模組在剛開始 porting 時可以忽略暫時不處理。剩下的三塊中... 應不應分拆成三個檔案三個 simplemodule? , 是否要使用到 ICMPv6Combine 這塊呢?我馬上陷入了第一個難題中.

2nd. Part: 告解式除錯 (Confessional Debug): 為何不先弄好 IP header 呢?這絕對是問題. 還好意識到這件事情的時間點還算早。更堅定了我 "只有邊寫邊紀錄才能意識到自己的錯誤" 的想法,因此接下來應先搜尋 IP header 定義的部分,從這裡開始作修改.

暫時將 DualStack 放到一邊,完成純 IPv6 Support 的模組後再考慮 DualStack. 但一定會將之排入計畫裡. 因為雖然 DualStack 對我的論文模擬來說重要性不大, 但在實際工作上將會遇到. porting 過一遍心裡會先有點底,相信多少有些助益.

· 3 min read

3rd. Part:

再次瀏覽 INET 目錄,評估應該增修的檔案: 初步規劃大致如下:

  • Network/IPv6 //.ned, .msg 資源檔,IP6 實作
  • Network/IPv6d //IP6 分模組實作
  • Network/Autorouting/FlatNetworkConfigurator6.ned // 模擬用位址自動設定
  • Nodes/INET6 // 組合模組成為節點
  • Applications/PingApp6

這時又發現了 INET 的一個好處:模組所包含的目錄大致與 TCP/IP 架構分層符合, 對熟悉網路的我來說,很容易找到應該增修檔案的位址.

順便規劃 DualStack, 但暫時不做,原因如 Day1 2nd. Part:

  • Network/DualStack
  • Network/Autorouting/FlatNetworkConfiguratorDS.ned
  • Nodes/DualStack 應用層不必修改.

做 DualStack 的話還會另外引入 6to4 等 transition/tunnel 模組, 工作量會遠遠比目前列出的 DualStack 所需修改內容多上許多, 且現在自己還不具備白手疊床架屋的能力. 因此先弄好 IPv6 部分的 porting 才是最重要的.

昨天思考 ICMPv6 3 個模組部分,決定分拆成多個 simplemodule, 在 NetworkLayer6 裡再進行合作.

4th. Part: 編輯 Network/IPv6/IPv6.ned:

IPControlInfo: When IPv6 sends up a packet to a higher layer protocol, it will also attach an IP6ControlInfo to the packet, with the source and destination IPv6 address

  • 與上層溝通的訊息,若名稱不改的話。以後做 DualStack 從上層傳下來的封包會否出問題?

  • 另外弄個小 script 來判斷位址長度是否比改名造成的後果來的容易? When delivering packets to higher-layer protocols, the output gate is determined from the Protocol field in the IPv6 header. The protocol-to-gateindex mapping must be given in the protocolMapping string parameter

  • protocolMapping 應該被 NextHeader 或延伸標頭分析取代 routing table 儲存在 RoutingTable6 模組裡. if the route entry contained a next hop address, it will be passed to the interface in the attached IPRoutingDecision.

· 7 min read

//1.1.1 03/06/05 Doc is Included in INET6 Project //1.1 01/05/05 //1.0 12/31/04 //0.9 12/28/04 //0.5 12/26/04 init

Install and Using OMNET++ on Windows 對開發者來說,儘管在 Linux 環境下編譯 OMNET++ 模擬套件也是個好選擇, 但是也有不少人希望能在 Windows 環境下順利利用 OMNET++ 編譯模擬套件. 而目前相關文件仍然極少. 本文總結了作者如何在 Windows 環境下利用 Microsoft Visual C++ 6 (MSVC6) 編譯 OMNET++ 模擬套件的經驗

1. 安裝 MSVC6 & MSVC Service Pack 6 安裝 MSVC6 時 "註冊變數" 選項一定要勾選

2. 設定 打開選單 -> 工具 (Tools) -> 自訂 (Customize) 點選 Add-ins and Macro files 分頁標籤 (Tab) , 看到 omnetpp 選項,將之勾選

回到命令 (Commands) 分頁標籤 (Tab), 分頁左上角的分類 (Category) 選單會多出巨集 (Macros) 選項. 選擇巨集 (Macros) 選項,看到 addNEDfileToProject 巨集, 點選 addNEDfileToProject 巨集, 使用鼠標將巨集拖曳到工具列上, 選擇合適的位置,圖示後按確定.

在完成上兩步之後,我們已經將 VC 環境設定完成, 可以準備開始在 VC 上建立新的 OMNET++ 專案, 或是匯入原本不是在 Windows 環境下執行的專案

3. VC 中建立新專案 若要從頭開始建立新的模擬套件, 可以先在 Windows 檔案管理員中任意地點建立放置新專案的資料夾, 再從 OMNET++ 安裝目錄 /sample 中複製 .dsw, .dsp 專案檔到新專案的資料夾中.

複製範例專案檔的目的是因為範例專案檔已經將 OMNET++ 編譯所需的編譯器, 連結旗標,Tkenv/Cmdenv 參數等都設定好了,讓我們不需再重新設定.

點擊 .dsw 檔進入 VC 編輯畫面. 將檔案檢視 (File View) 中的檔案名稱清空後,即可開始編輯新的專案

4. VC 中匯入專案 有時我們會想使用別人在 OMNET++ 中已完成的模擬套件或成果, 而對方使用的平台並非 Windows, 此時我們可以用類似前一步驟的方式為這個模擬套件加入新的 VC 專案檔. 從 omnet 安裝目錄 /sample 中複製 .dsw, .dsp 專案檔到原來模擬套件的資料夾中. 點擊 .dsw 檔進入 VC 編輯畫面. 將 File View 中的檔案名稱清空後,即可開始編輯新的專案

5. VC 中編輯專案 在 IDE 環境下依照一般 VC 中編輯專案的方式增刪編輯檔案. 但要將其他平台上的 c++ 檔案拿來用時,注意檔案副檔名不能使用 .cc, 副檔名都要先改成 .cpp 後在 VC 下才能正常編譯 (這點好像不一定,至少在 INET 模組裡就不必改)

當遇到設計好 .ned 檔要加入 VC 時, 先點選工具列上新增的 addNEDfileToProject 巨集圖示, 輸入該 .ned 檔檔名 (包含副檔名), 之後 addNEDfileToProject 巨集會幫忙生成 .ned 對應的 cpp 檔.

詳細設定可參考 OMNeT++ 安裝目錄下 doc/Readme-MSVC.txt

6, VC 中編譯專案 首先打開命令列,準備開始編譯的動作. 命令列開啟流程為按作業系統左下角的 "開始", 在選單中選擇 "執行", 其後將跳出輸入視窗,在視窗中鍵入 cmd (或 Terminal) 按下確定後即彈出類似 Dos 視窗. 接著用一般 Dos 指令切換到專案目錄下準備開始編譯,鍵入 opp_nmakemake 這動作會根據目錄中的來源檔案生成 Makefile.vc 檔案

接著使用下面指令來生成模擬: nmake -f Makefile.vc 做完以上部驟之後就可以照一般 VC 編譯方式編譯啦:)

7, 重新編譯專案 之前已編譯過時資料夾中會存有舊的 Makefile.vc 檔案,可鍵入 opp_nmakemake -f 來強制覆寫 Makefile.vc .

在編譯前要清除過時連結資料,可以在命令列中輸入 nmake Makefile.vc clean 也可以在 VC 中使用 選單 / Build/Clean 選項將過時連結資料清除

8. 選擇 Tkenv 視窗模式模擬 在預設的情況下,使用 OMNET++ 編譯出來的檔案將是在 cmdenv 命令列環境下執行. 為了更容易檢視模擬結果, 我們可以透過以下方法將模擬切換到在 TKenv 環境下執行:

選單 / Build/Set Active Project Configuration 從四個選項中選取 xx- win32 Release Tkenv

參考資料: 1. OMNeT++ and MF build instructions for Windows 2. OMNeT/doc/Readme-MSVC.txt

refer: Make sure you enter these settings for all configurations (In the Project|Settings dialog, select 'All configurations' from the combo in the top-left corner.)

  • include path: You must tell MSVC the location of omnetpp.h and other header files. Add c:\omnetpp-2.3\include to the include path in Project|Settings --> 'C/C++' tab --> 'Preprocessor' category --> Additional include directories.
  • library path: MSVC needs to know where to find sim_std.lib, envir.lib and other libraries. Add omnetpp/lib to the linker path in Project|Settings --> 'Link' tab --> 'Input' category --> Additional library path.
  • nedc: It's advisable to put OMNeT++'s bin directory into the PATH so that MSVC will find the NED compiler. (An alternative is to enter explicit nedc path for each NED file's Custom build step, but that's much more cumbersome.)

Add the .ned files to the project and set custom build option for them: Description: NED Compiling $(InputPath) Command: nedc -s _n.cpp $(InputPath) Outputs: $(InputPath)_n.cpp Hint: you can select all .ned files together, and 'All configurations' from the combo at the left of the Settings dialog, and then you have to type this settings only once. Note: If you copied one of the sample projects, you'll have to adjust Command, because they contain explicit nedc path (....\bin\nedc).

· 3 min read

動機: 由於自己論文的模擬需求,嘗試了許多網路模擬工具,包括 OPNET, NS2, OMNET++ 等. 試用後發現 OPNET 架構完備,然而複雜度過高,因授權關係使用上亦受到重重限制. NS2 使用免費,牌子老又擁有不可忽視的模組群,然而 OTCL 與 C 之間模組關係處理複雜,模組使用時還必需與版本配合,毫無可攜性. 而 OMNET++ 具有許多 NS2 沒有的優點,例如是物件導向式的模擬工具。跨平台通用,使用 C++ 語言撰寫. 在網路模擬上目前則提供了 INET, Mobility Framework, IPv6Suite 等網路模擬模組. Mobility Framework 是一個相似於 NS2 的網路模擬模組,提供樣版檔案,讓使用者從 Mac 層至 Application 層自行挑選,組合出所需的網路. 而 INET 是三者中支援 OSI 七層最完整的網路模擬模組,使用上也最為簡便。然而目前並不支援 IPv6 與 IP Mobility. IPv6Suite 提供 IPv6, IPv4, MIPv6 等的模擬,, 功能最為強大. 然而問題頗多,由於綁定太過額外模組,僅限於 Linux 平台,也不容易修改, 在網路模擬上具有分層不夠清楚,安裝不夠簡單,文件不夠友善等缺點. 因此一個主要目的以 INET 模組為基礎,依據 INET 網路分層,並以 IPv6Suite 為參考, 使 INET 支援 IPv6 的 INET6 計畫於焉成型

INET6 計畫包含

  • IPv6 模組程式
  • nedDoc 模組程式碼生成文件
  • 安裝步驟
  • 導覽 Tutorial
  • 模擬寫作指引

未來計畫:

  • MIPv6 模組程式 (待 Mobility Framework 整合後繼續開發)
  • NEMO 模組程式
  • DualStack 模組程式

本計畫發展穩定後,最終將合併入 INET 模組中,提供 OMNET++ 平台上完整的網路模擬環境.

· One min read

網路模擬最重要應注意的事情,就是找一台穩定可靠的機器. 一台穩定可靠的機器可以省下無限多測試安裝麻煩.

以前在好幾台機器上怎麼試都不太順利,換到新的這台 X30 後一切順利的不得了. 感覺這次的投資真是值得:)