|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // Copyright (C) 2011 Martin Danko 00003 // 00004 // This program is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU General Public License 00006 // as published by the Free Software Foundation; either version 2 00007 // of the License, or (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 // 00018 00019 #include "AnsaQosClassifiers.h" 00020 00021 /* 00022 * Pretazenie operatoru "==" pre porovnanie tokov 00023 */ 00024 00025 bool ANSAQOS::Flow::operator==(const Flow& flow) const 00026 { 00027 if(srcAddress != flow.srcAddress) 00028 return false; 00029 if(destAddress != flow.destAddress) 00030 return false; 00031 if(transportProtocol != flow.transportProtocol) 00032 return false; 00033 if(ipPrec != flow.ipPrec) 00034 return false; 00035 if(srcPort != flow.srcPort) 00036 return false; 00037 if(destPort != flow.destPort) 00038 return false; 00039 00040 return true; 00041 } 00042 00043 /* 00044 * parseFromMsg(): 00045 * Konstruktor toku, ktory nacita hodnoty zo spravy (TCP/UDP paketu) 00046 * @param msg - sprava z ktora definuje parametre toku 00047 */ 00048 00049 void ANSAQOS::Flow::parseFromMsg(cMessage *msg) 00050 { 00051 cMessage *copy = msg->dup(); 00052 00053 if (dynamic_cast<IPDatagram *>(copy)) 00054 { 00055 IPDatagram *datagram = (IPDatagram *)copy; 00056 00057 srcAddress = datagram->getSrcAddress(); 00058 destAddress = datagram->getDestAddress(); 00059 transportProtocol = datagram->getTransportProtocol(); 00060 ipPrec = (short) datagram->getDiffServCodePoint()/32; // prve 3 bity ToS 00061 if(transportProtocol == IP_PROT_TCP) 00062 { 00063 TCPSegment *tcpSegm = dynamic_cast<TCPSegment *> (datagram->decapsulate()); 00064 srcPort = tcpSegm->getSrcPort(); 00065 destPort = tcpSegm->getDestPort(); 00066 delete tcpSegm; 00067 } 00068 else if(transportProtocol == IP_PROT_UDP) 00069 { 00070 UDPPacket *udpDatag = dynamic_cast<UDPPacket *> (datagram->decapsulate()); 00071 srcPort = udpDatag->getSourcePort(); 00072 destPort = udpDatag->getDestinationPort(); 00073 delete udpDatag; 00074 } 00075 else 00076 { 00077 srcPort = 0; 00078 destPort = 0; 00079 } 00080 } 00081 else 00082 { 00083 srcAddress = IPAddress::UNSPECIFIED_ADDRESS; 00084 destAddress = IPAddress::UNSPECIFIED_ADDRESS; 00085 transportProtocol = 0; 00086 ipPrec = 0; 00087 srcPort = 0; 00088 destPort = 0; 00089 } 00090 00091 delete copy; 00092 00093 } 00094 00095 /* 00096 * WFQClassifier(): 00097 * Konstruktor klasifikatoru WFQ fronty, ktory je vytvoreny 00098 * na zaklade spravy (TCP/UDP paketu) 00099 * @param msg - sprava z ktora definuje parametre toku 00100 */ 00101 00102 ANSAQOS::WFQClassifier::WFQClassifier(cMessage *msg) 00103 { 00104 /* Nacita tok na zaklade hlaviciek spravy */ 00105 flowID.parseFromMsg(msg); 00106 00107 /* Vytvorenie stringu pre graficke rozhranie */ 00108 std::stringstream info; 00109 info << "Flow: src: "; 00110 info << flowID.srcAddress.str(); 00111 info << ":"; 00112 info << flowID.srcPort; 00113 info << " dest: "; 00114 info << flowID.destAddress.str(); 00115 info << ":"; 00116 info << flowID.destPort; 00117 info << " prec: "; 00118 info << flowID.ipPrec; 00119 info << " prot: "; 00120 info << flowID.transportProtocol; 00121 infoString = info.str(); 00122 } 00123 00124 /* 00125 * classifyPacket(): 00126 * Funkcia rozhoduje o klasifikacii spravy do daneho toku 00127 * @param msg - sprava, ktora ma byt klasifikovana 00128 * @return - Vrati true pokial je sprava klasifikovana 00129 */ 00130 00131 bool ANSAQOS::WFQClassifier::classifyPacket(cMessage *msg) 00132 { 00133 if (flowID == Flow(msg)) 00134 return true; 00135 return false; 00136 } 00137 00138 /* 00139 * ACLClassifier(): 00140 * Konstruktor ACL klasifikatoru, ktory nacita parametre zo XML. 00141 * @param clsfrConfig - XML blok s konfiguraciou klasifikatora 00142 */ 00143 00144 ANSAQOS::ACLClassifier::ACLClassifier(cXMLElement& clsfrConfig) 00145 { 00146 /* Ziska pristup do ACL kontajneru smerovaca */ 00147 aclAccess = AclContainerAccess().get(); 00148 00149 /* Do retazca uklada informacie pre graficke rozhranie */ 00150 infoString = "ACL:="; 00151 00152 /* Prechadzanie elementov XML konfiguracie */ 00153 cXMLElementList aclDetails = clsfrConfig.getChildren(); 00154 for (cXMLElementList::iterator aclElemIt = aclDetails.begin(); aclElemIt != aclDetails.end(); ++aclElemIt) 00155 { 00156 std::string nodeName = (*aclElemIt)->getTagName(); 00157 if (nodeName == "acl") 00158 { 00159 std::string aclname = (*aclElemIt)->getNodeValue(); 00160 if (aclname.length() > 0 ) 00161 { 00162 acls.push_back(aclname); 00163 infoString += " "; 00164 infoString += aclname; 00165 if(!aclAccess->existAcl(aclname)) 00166 infoString += " (not defined)"; 00167 } 00168 } 00169 } 00170 00171 } 00172 00173 /* 00174 * classifyPacket(): 00175 * Funkcia rozhoduje o klasifikacii spravy danym ACL 00176 * @param msg - sprava, ktora ma byt klasifikovana 00177 * @return - Vrati true pokial je sprava klasifikovana 00178 */ 00179 00180 bool ANSAQOS::ACLClassifier::classifyPacket(cMessage *msg) 00181 { 00182 std::vector<std::string>::iterator it; 00183 00184 for(it = acls.begin(); it != acls.end(); ++it ) 00185 { 00186 if (aclAccess->matchPacketToAcl(*it, msg)) 00187 return true; 00188 } 00189 return false; 00190 } 00191 00192 /* 00193 * readDscp(): 00194 * Funkcia prevedie string z DSCP hodnotou na 8 bitovu hodotu ToS 00195 * @param dscpString - retazec DSCP hodnoty 00196 * @return - Vrati hodnotu ToS zakodovanu v DSCP retazcu 00197 */ 00198 00199 unsigned char ANSAQOS::DSCPClassifier::readDscp(std::string dscpString) 00200 { 00201 00202 if(dscpString.size() == 3) 00203 { 00204 std::string prf = dscpString.substr(0,2); 00205 unsigned char cls = dscpString[2] - '0'; 00206 if((prf == "CS" || prf == "Cs" || prf == "cs") && cls > 0 && cls < 8) 00207 return cls*32; 00208 } 00209 else if (dscpString.size() == 4) 00210 { 00211 std::string prf = dscpString.substr(0,2); 00212 unsigned char cls = dscpString[2] - '0'; 00213 unsigned char dp = dscpString[3] - '0'; 00214 if((prf == "AF" || prf == "Af" || prf == "af") && cls > 0 && cls < 5 && dp > 0 && dp < 4) 00215 return cls*32 + dp*8; 00216 } 00217 else if(dscpString == "EF" || dscpString == "Ef" || dscpString == "ef") 00218 return 184; 00219 00220 return atoi(dscpString.c_str()); 00221 } 00222 00223 /* 00224 * DSCPClassifier(): 00225 * Konstruktor DSCP klasifikatoru, ktory nacita parametre zo XML. 00226 * @param clsfrConfig - XML blok s konfiguraciou klasifikatora 00227 */ 00228 00229 ANSAQOS::DSCPClassifier::DSCPClassifier(cXMLElement& clsfrConfig) 00230 { 00231 /* Do retazca uklada informacie pre graficke rozhranie */ 00232 infoString = "DSCP:="; 00233 00234 /* Prechadzanie elementov XML konfiguracie */ 00235 cXMLElementList dscpDetails = clsfrConfig.getChildren(); 00236 for (cXMLElementList::iterator dscpElemIt = dscpDetails.begin(); dscpElemIt != dscpDetails.end(); ++dscpElemIt) 00237 { 00238 std::string nodeName = (*dscpElemIt)->getTagName(); 00239 if (nodeName == "value") 00240 { 00241 std::string val = (*dscpElemIt)->getNodeValue(); 00242 values.push_back(readDscp(val)); 00243 infoString += " "; 00244 infoString += val; 00245 } 00246 } 00247 00248 } 00249 00250 /* 00251 * classifyPacket(): 00252 * Funkcia rozhoduje o klasifikacii spravy danymi hodnotami DSCP 00253 * @param msg - sprava, ktora ma byt klasifikovana 00254 * @return - Vrati true pokial je sprava klasifikovana 00255 */ 00256 00257 bool ANSAQOS::DSCPClassifier::classifyPacket(cMessage *msg) 00258 { 00259 unsigned char tos; 00260 std::vector<unsigned char>::iterator it; 00261 cMessage *copy = msg->dup(); 00262 00263 if (dynamic_cast<IPDatagram *>(copy)) 00264 { 00265 IPDatagram *datagram = (IPDatagram *)copy; 00266 tos = datagram->getDiffServCodePoint(); 00267 } 00268 delete copy; 00269 00270 for(it = values.begin(); it != values.end(); ++it ) 00271 { 00272 if (*it == tos) 00273 return true; 00274 } 00275 return false; 00276 } 00277 00278 /* 00279 * PRECClassifier(): 00280 * Konstruktor IP precedence klasifikatoru, ktory nacita parametre zo XML. 00281 * @param clsfrConfig - XML blok s konfiguraciou klasifikatora 00282 */ 00283 00284 ANSAQOS::PRECClassifier::PRECClassifier(cXMLElement& clsfrConfig) 00285 { 00286 /* Do retazca uklada informacie pre graficke rozhranie */ 00287 infoString = "PREC:="; 00288 00289 /* Prechadzanie elementov XML konfiguracie */ 00290 cXMLElementList dscpDetails = clsfrConfig.getChildren(); 00291 for (cXMLElementList::iterator dscpElemIt = dscpDetails.begin(); dscpElemIt != dscpDetails.end(); ++dscpElemIt) 00292 { 00293 std::string nodeName = (*dscpElemIt)->getTagName(); 00294 if (nodeName == "value") 00295 { 00296 short val = (short) atoi((*dscpElemIt)->getNodeValue()); 00297 if (val >= 0 && val <8) // IP precedence musi byt z rozsahu 0-7 00298 { 00299 values.push_back(val); 00300 infoString += " "; 00301 infoString += (*dscpElemIt)->getNodeValue(); 00302 } 00303 } 00304 } 00305 00306 } 00307 00308 /* 00309 * classifyPacket(): 00310 * Funkcia rozhoduje o klasifikacii spravy danymi hodnotami IP precedence 00311 * @param msg - sprava, ktora ma byt klasifikovana 00312 * @return - Vrati true pokial je sprava klasifikovana 00313 */ 00314 00315 bool ANSAQOS::PRECClassifier::classifyPacket(cMessage *msg) 00316 { 00317 short prec; 00318 std::vector<short>::iterator it; 00319 cMessage *copy = msg->dup(); 00320 00321 if (dynamic_cast<IPDatagram *>(copy)) 00322 { 00323 IPDatagram *datagram = (IPDatagram *)copy; 00324 prec = (short) datagram->getDiffServCodePoint()/32; // prve 3bity TOS 00325 } 00326 delete copy; 00327 00328 for(it = values.begin(); it != values.end(); ++it ) 00329 { 00330 if (*it == prec) 00331 return true; 00332 } 00333 return false; 00334 } 00335 00336