|
INET Framework for OMNeT++/OMNEST
|
00001 // Author: Matej Hrncirik 00002 // FIT VUT 2012 00003 // 00004 // 00005 // This program is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU Lesser General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with this program. If not, see http://www.gnu.org/licenses/. 00017 // 00018 00019 #ifndef ISIS_H_ 00020 #define ISIS_H_ 00021 00022 #include <algorithm> 00023 #include <stdlib.h> 00024 #include <omnetpp.h> 00025 #include <string> 00026 #include <vector> 00027 #include <queue> 00028 #include <iomanip> 00029 00030 #include "ISISMessage_m.h" 00031 //#include "ISISLSPPacket.h" 00032 #include "Ieee802Ctrl_m.h" 00033 #include "MACAddress.h" 00034 #include "AnsaInterfaceTable.h" 00035 #include "AnsaInterfaceTableAccess.h" 00036 #include "NotificationBoard.h" 00037 #include "NotifierConsts.h" 00038 #include "InterfaceStateManager.h" 00039 #include "RoutingTableAccess.h" 00040 #include "IRoutingTable.h" 00041 #include "IPRoute.h" 00042 #include "ISISTimer_m.h" 00043 #include "xmlParser.h" 00044 #include "ISIStypes.h" 00045 #include <cmessage.h> 00046 #include <crng.h> 00047 00048 //class ISISLSPPacket; 00052 class ISIS : public cSimpleModule 00053 { 00054 private: 00055 00056 IInterfaceTable *ift; 00057 std::vector<ISISinterface> ISISIft; 00058 const char *deviceType; 00059 const char *deviceId; 00060 const char *configFile; 00061 const char *netAddr; 00062 const unsigned char *areaId; 00063 const unsigned char *sysId; 00064 const unsigned char *NSEL; 00065 std::vector<ISISadj> adjL1Table; 00066 std::vector<ISISadj> adjL2Table; 00067 short isType; 00068 std::vector<LSPrecord> L1LSP; 00069 std::vector<LSPrecord> L2LSP; 00070 LSPRecQ_t *L1LSPDb; 00071 LSPRecQ_t *L2LSPDb; 00072 FlagRecQQ_t *L1SRMBQueue; 00073 FlagRecQQ_t *L1SRMPTPQueue; 00074 FlagRecQQ_t *L2SRMBQueue; 00075 FlagRecQQ_t *L2SRMPTPQueue; 00076 00077 FlagRecQQ_t *L1SSNBQueue; 00078 FlagRecQQ_t *L1SSNPTPQueue; 00079 FlagRecQQ_t *L2SSNBQueue; 00080 FlagRecQQ_t *L2SSNPTPQueue; 00081 00082 //ISISPaths_t ISISPaths; 00083 //ISISPaths_t ISISTent; 00084 //ISISCons_t ISISInit; 00085 00086 int L1HelloInterval; 00087 int L2HelloInterval; 00088 short L1HelloMultiplier; 00089 short L2HelloMultiplier; 00090 int lspInterval; 00091 int lspRefreshInterval; 00092 int lspMaxLifetime; 00093 int L1LspGenInterval; 00094 int L2LspGenInterval; 00095 int L1LspSendInterval; 00096 int L2LspSendInterval; 00097 int L1LspInitWait; 00098 int L2LspInitWait; 00099 int L1CsnpInterval; 00100 int L2CsnpInterval; 00101 int L1PsnpInterval; 00102 int L2PsnpInterval; 00103 int L1SPFFullInterval; 00104 int L2SPFFullInterval; 00105 unsigned long helloCounter; 00109 /* Init */ 00110 void initISIS(); // main init 00111 void initHello(); 00112 void initGenerate(); 00113 void initRefresh(); 00114 void initPeriodicSend(); 00115 void initCsnp(); 00116 void initPsnp(); 00117 void initSPF(); 00118 00119 /* Hello */ 00120 void handlePTPHelloMsg(ISISMessage *inMsg); // 00121 void sendBroadcastHelloMsg(int interfaceIndex, short circuitType); 00122 void sendPTPHelloMsg(int interfaceIndex, short circuitType); 00123 00124 unsigned short getHoldTime(int interfaceIndex, short circuitType = L1_TYPE); 00125 double getHelloInterval(int interfaceIndex, short circuitType); //return hello interval for specified interface and circuitType. For DIS interface returns only 1/3 of actual value; 00126 00127 ISISadj* getAdjByGateIndex(int gateIndex, short circuitType, int offset = 0); // return something corresponding to adjacency on specified link 00128 ISISadj* getAdjBySystemID(unsigned char *systemID, short circuitType, int gateIndex = -1); 00129 ISISadj* getAdj(ISISMessage *inMsg, short circuitType = L1_TYPE); //returns adjacency representing sender of inMsg or NULL when ANY parameter of System-ID, MAC address and gate index doesn't match 00130 00131 ISISinterface* getIfaceByGateIndex(int gateIndex); //return ISISinterface for specified gateIndex 00132 bool isAdjBySystemID(unsigned char *systemID, short circuitType); //do we have adjacency for systemID on specified circuitType 00133 bool isUp(int gateIndex, short circuitType); //returns true if ISISInterface specified by the corresponding gateIndex have at least one adjacency in state UP 00134 00135 bool amIL1DIS(int interfaceIndex); //returns true if specified interface is DIS 00136 bool amIL2DIS(int interfaceIndex); //returns true if specified interface is DIS 00137 00138 /* LSP */ 00139 00140 00141 void handleL1Lsp(ISISLSPPacket *lsp); 00142 void handleL1Csnp(ISISCSNPPacket *csnp); 00143 void handleL1Psnp(ISISPSNPPacket *psnp); 00144 00145 std::vector<unsigned char *>* getLspRange(unsigned char *startLspID, unsigned char * endLspID, 00146 short circuitType); 00147 unsigned char * getStartLspID(ISISCSNPPacket *csnp); 00148 unsigned char * getEndLspID(ISISCSNPPacket *csnp); 00149 00150 unsigned char* getLspID(ISISLSPPacket *msg); 00151 void setLspID(ISISLSPPacket *msg, unsigned char * lspID); 00152 void updateLSP(ISISLSPPacket* lsp, short circuitType); 00153 00154 void replaceLSP(ISISLSPPacket *lsp, LSPRecord *lspRecord, short circuitType); 00155 void purgeRemainLSP(unsigned char * lspId, short circuitType); 00156 void purgeLSP(unsigned char *lspId, short circuitType); //purge in-memory LSP 00157 void purgeLSP(ISISLSPPacket *lsp, short circuitType); //purge incomming LSP 00158 void purgeMyLSPs(short circuitType); 00159 00160 void deleteLSP(ISISTimer *timer); //delete (already purged)LSP from DB when appropriate timer expires 00161 00162 void sendLSP(LSPRecord *lspRec, int gateIndex); 00163 00164 std::vector<ISISLSPPacket *>* genLSP(short circuitType); 00165 void generateLSP(ISISTimer *timer); 00166 void generateLSP(short circuitType); 00167 00168 void refreshLSP(ISISTimer *timer); 00169 void refreshLSP(short circuitType); 00170 00171 std::vector<LSPRecord *> * getLSPDb(short circuitType); 00172 00173 void periodicSend(ISISTimer *timer, short circuitType); 00174 void sendL1Csnp(ISISTimer *timer); 00175 void sendL1Psnp(ISISTimer *timer); 00176 00177 unsigned char * getLSPID(); 00178 00179 //double getHoldtimeInterval(int interfaceIndex, short circuitType); //return hold time interval for specified interface and circuitType. 00180 00181 LSPRecord* getLSPFromDbByID(unsigned char *LSPID, short circuitType); 00182 bool compareLSP(ISISLSPPacket *lsp1, ISISLSPPacket *lsp2); 00183 00184 LSPRecord * installLSP(ISISLSPPacket *lsp, short circuitType); //install lsp into local LSP database 00185 00186 00187 00188 00189 /* SPF */ 00190 void fullSPF(ISISTimer *timer); 00191 bool extractISO(ISISCons_t *initial, short circuitType); 00192 ISISPath * getPath(ISISPaths_t *paths, unsigned char* id); 00193 ISISCons_t * getCons(ISISCons_t *cons, unsigned char* from); 00194 void getBestMetric(ISISPaths_t *paths); 00195 ISISPath * getBestPath(ISISPaths_t *paths); 00196 void twoWayCheck(ISISCons_t *cons); 00197 bool isCon(ISISCons_t *cons, unsigned char *from, unsigned char *to); 00198 void bestToPath(ISISCons_t *cons, ISISPaths_t *ISISTent, ISISPaths_t *ISISPaths); 00199 void moveToTent(ISISCons_t *initial, unsigned char *from, uint32_t metric, ISISPaths_t *ISISTent); 00200 void moveToPath(ISISPath *path); 00201 00202 00203 00204 /* Flags */ 00205 std::vector<std::vector<FlagRecord*>*> * getSRMPTPQueue(short circuitType); 00206 std::vector<std::vector<FlagRecord*>*> * getSRMBQueue(short circuitType); 00207 00208 std::vector<std::vector<FlagRecord*>*> * getSSNPTPQueue(short circuitType); 00209 std::vector<std::vector<FlagRecord*>*> * getSSNBQueue(short circuitType); 00210 00211 std::vector<FlagRecord*>* getSRMQ(bool network, int index, short circuitType); 00212 std::vector<FlagRecord*>* getSSNQ(bool network, int index, short circuitType); 00213 00214 void setSRMflag(LSPRecord * lspRec, int index, short circuitType); 00215 void setSRMflags(LSPRecord *lspRec, short circuitType); 00216 void setSRMflagsBut(LSPRecord *lspRec, unsigned int index, short circuitType); 00217 00218 void clearSRMflag(LSPRecord *lspRec, int index, short circuitType); 00219 void clearSRMflags(LSPRecord *lspRec, short circuitType); 00220 void clearSRMflagsBut(LSPRecord *lspRec, unsigned int index, short circuitType); 00221 00222 void setSSNflag(LSPRecord * lspRec, int index, short circuitType); 00223 void setSSNflags(LSPRecord *lspRec, short circuitType); 00224 void setSSNflagsBut(LSPRecord *lspRec, unsigned int index, short circuitType); 00225 00226 void clearSSNflag(LSPRecord *lspRec, int index, short circuitType); 00227 void clearSSNflags(LSPRecord *lspRec, short circuitType); 00228 void clearSSNflagsBut(LSPRecord *lspRec, unsigned int index, short circuitType); 00229 00230 void addFlags(LSPRecord *lspRec, short circuitType); //add and set SRM and SSN flags for lspRec 00231 00232 00233 /* Print */ 00234 00235 void printLSP(ISISLSPPacket *lsp, char *from); 00236 void printSysId(unsigned char *sysId); 00237 void printLspId(unsigned char *lspId); 00238 00239 void printPaths(ISISPaths_t *paths); 00240 00241 00242 00243 00244 void schedule(ISISTimer* timer, double timee = -1); //if timer needs additional information there is msg 00245 00246 00247 00248 unsigned char* getSysID(ISISMessage *msg); 00249 unsigned char* getSysID(ISISTimer *timer); 00250 unsigned char* getLspID(ISISTimer *timer); 00251 00252 /* unsigned char* getSysID(ISISL1HelloPacket *msg); 00253 unsigned char* getSysID(ISISL2HelloPacket *msg); 00254 unsigned char* getSysID(ISISPTPHelloPacket *msg);*/ 00255 00256 00257 00258 void addTLV(ISISMessage *inMsg, enum TLVtypes tlvType); //generate and add this tlvType LSP to message 00259 void addTLV(ISISMessage *inMsg, TLV_t *tlv); //add this TLV in message 00260 void addTLV(std::vector<TLV_t *> *tlvtable, enum TLVtypes tlvType, short circuitType, unsigned char nsel = 0); 00261 00262 bool isAdjUp(short circuitType); //returns true if ANY adjacency is up on specified circuit level 00263 bool isAdjUp(ISISMessage *msg, short circuitType); 00264 00265 TLV_t* getTLVByType(ISISMessage *inMsg, enum TLVtypes tlvType, int offset = 0); 00266 /* TLV_t* getTLVByType(ISISL1HelloPacket *msg,enum TLVtypes tlvType, int offset = 0); 00267 TLV_t* getTLVByType(ISISL2HelloPacket *msg,enum TLVtypes tlvType, int offset = 0); 00268 TLV_t* getTLVByType(ISISPTPHelloPacket *msg,enum TLVtypes tlvType, int offset = 0);*/ 00269 bool isMessageOK(ISISMessage *inMsg); 00270 bool isAreaIDOK(TLV_t* areaAddressTLV, unsigned char *compare = NULL); //if compare is NULL then use this->areaId for comparison 00271 int getIfaceIndex(ISISinterface *interface); //returns index to ISISIft 00272 00273 00274 00275 00276 00277 00278 00279 std::vector<ISISadj> * getAdjTab(short circuitType); 00280 00281 00282 00283 00284 00285 00286 void insertIft(InterfaceEntry *entry, cXMLElement *device); //insert new interface to vector 00287 void sendHelloMsg(ISISTimer* timer); // send hello messages 00288 bool parseNetAddr(); // validate and parse net address format 00289 void handleL1HelloMsg(ISISMessage *inMsg); // handle L1 hello messages 00290 void handleL2HelloMsg(ISISMessage *inMsg); // handle L2 hello messages 00291 void removeDeadNeighbour(ISISTimer *msg); //remove dead neighbour when timer message arrives 00292 void electL1DesignatedIS(ISISL1HelloPacket *msg); //starts election of L1 designated intermediate system 00293 void electL2DesignatedIS(ISISL2HelloPacket *msg); //starts election of L2 designated intermediate system 00294 void resetDIS(unsigned char* systemID, int gateIndex, short circuitType); //resetDIS only if system specified in timer was DIS on interface specified in timer //resets DIS on al interfaces for L1/L2 00295 void sendMyL1LSPs(); //send content of my L1 link-state DB 00296 void sendMyL2LSPs(); //send content of my L2 link-state DB 00297 void floodFurtherL1LSP(ISISLSPL1Packet *msg); //send recived LSP packet further to all other neighbours 00298 void sendSpecificL1LSP(unsigned char *LSPid); //send only specific LSP 00299 void handleL1LSP(ISISMessage * msg); //handle L1 LSP packets 00300 void handleL2LSP(ISISMessage * msg); //handle L2 LSP packets 00301 void sendL1CSNP(); //send L1 CSNP packets 00302 void sendL2CSNP(); //send L2 CSNP packets 00303 void handleL1CSNP(ISISMessage * msg); //handle L1 CSNP packets 00304 void handleL2CSNP(ISISMessage * msg); //handle L2 CSNP packets 00305 void sendL1PSNP(std::vector<unsigned char *> * LSPlist, int gateIndex); //send L1 PSNP packets 00306 void sendL2PSNP(); //send L2 PSNP packets 00307 void handleL1PSNP(ISISMessage * msg); //handle L1 PSNP packets 00308 void handleL2PSNP(ISISMessage * msg); //handle L2 PSNP packets 00309 bool checkDuplicateSysID(ISISMessage * msg); //check sysId field from received hello packet for duplicated sysId 00310 void removeDeadLSP(ISISTimer *msg); //remove expired LSP 00311 void updateMyLSP(); //create or update my own LSPs 00312 00313 protected: 00314 virtual void initialize(int stage); //init 00315 virtual void handleMessage(cMessage* msg); //basic message handling 00316 virtual int numInitStages() const 00317 { 00318 return 5; 00319 } 00320 bool compareArrays(unsigned char * first, unsigned char * second, unsigned int size); //method for comparison of two unsigned int arrays 00321 void copyArrayContent(unsigned char * src, unsigned char * dst, unsigned int size, unsigned int startSrc, 00322 unsigned int startDst); //copy content from one array to another 00323 00324 public: 00325 ISIS(); 00326 virtual ~ISIS(); //destructor 00327 void printAdjTable(); //print adjacency table 00328 void printLSPDB(); //print content of link-state database 00329 }; 00330 00331 00332 #endif /* ISIS_H_ */