|
INET Framework for OMNeT++/OMNEST
|
00001 /* 00002 * acl.cc 00003 * 00004 * Created on: 24.2.2009 00005 * Finished on: 7.5.2009 00006 * Author: Tomas Suchomel, xsucho00 00007 */ 00008 00009 #include "acl.h" 00010 00011 Define_Module(acl); 00012 00013 using namespace std; 00014 00015 /* 00016 * ipIsEqual(): IP IS EQUAL 00017 * Method that compares IP address from the packet header 00018 * to IP address presents in current ACL rule. 00019 * @param ip - struct with IP address from ACL rule 00020 * @param packet - struct with IP address from packet 00021 * @see filterPacket() 00022 * @return result of IP address comparison 00023 */ 00024 bool acl::ipIsEqual(TIP* ip, TIP* packet) 00025 { 00026 ev << "ACL rule, ip : " << ip->ipAddr.str() << endl; 00027 ev << "ACL rule, mask: " << ip->netmask.str() << endl; 00028 ev << "packet, ip : " << packet->ipAddr.str() << endl; 00029 ev << "packet_masked : " << packet->ipAddr.doAnd(ip->netmask).str() << endl; 00030 if (ip->ipAddr != (packet->ipAddr.doAnd(ip->netmask))) 00031 { 00032 ev << "IP DOESN'T MATCH" << endl; 00033 return false; 00034 } 00035 ev << "IP MATCH OK" << endl; 00036 return true; 00037 } 00038 00039 /* 00040 * portIsEqual(): PORT IS EQUAL 00041 * Method that compares port number(s) from the packet header 00042 * to port number(s) present in current ACL rule. 00043 * @param ip - struct with ports from ACL rule 00044 * @param packet - struct with ports from packet 00045 * @see filterPacket() 00046 * @return result of port comparison 00047 */ 00048 bool acl::portIsEqual(TIP* ip, TIP* packet) 00049 { 00050 switch (ip->port_op) { 00051 case PORT_EQ: 00052 if (ip->portBeg == packet->portBeg) 00053 return true; 00054 break; 00055 case PORT_NEQ: 00056 if (ip->portBeg != packet->portBeg) 00057 return true; 00058 break; 00059 case PORT_GT: 00060 if (ip->portBeg < packet->portBeg) 00061 return true; 00062 break; 00063 case PORT_LT: 00064 if (ip->portBeg > packet->portBeg) 00065 return true; 00066 break; 00067 case PORT_RNG: 00068 case PORT_NDEF: 00069 if ((ip->portBeg <= packet->portBeg) && (ip->portEnd >= packet->portBeg)) 00070 return true; 00071 break; 00072 default: 00073 cout << "BUG" << endl; 00074 } 00075 return false; 00076 } 00077 00078 /* 00079 * andIpWithMask(): AND IP WITH MASK 00080 * Method that does AND operation between IP Address and network mask in current ACL rule. 00081 * @param rule - struct with ACL rule 00082 * @return Negated wildcard mask [bits(O -> 1, 1 -> 0)]. 00083 * @see loadConfigFromXML() 00084 */ 00085 void acl::andIpWithMask(TRule* rule) 00086 { 00087 rule->source.ipAddr = rule->source.ipAddr.doAnd(rule->source.netmask); 00088 rule->dest.ipAddr = rule->dest.ipAddr.doAnd(rule->dest.netmask); 00089 } 00090 00091 /* 00092 * negateWildcard(): NEGATE WILD CARD MASKs 00093 * Method that negates all the bits of given wildcard mask in ACL rule. 00094 * @param wc - IPAddress structure with wildcard mask 00095 * @see loadConfigFromXML() 00096 */ 00097 IPAddress acl::negateWildcard(IPAddress wc) 00098 { 00099 return (IPAddress(~(wc.getInt()))); 00100 } 00101 00102 /* 00103 * getAction(): GET ACTION 00104 * Method that gets "action" field from XML string and puts it 00105 * to current ACL rule. 00106 * @param action - string with text from XML config file 00107 * @param rule - struct with ACL rule 00108 * @see loadConfigFromXML() 00109 */ 00110 void acl::getAction(std::string action, TRule* rule) 00111 { 00112 if (action == "deny") 00113 rule->action = A_DENY; 00114 else if (action == "permit") 00115 rule->action = A_PERMIT; 00116 } 00117 00118 /* 00119 * getProtocol(): GET PROTOCOL 00120 * Method that gets protocol field from XML string and puts it 00121 * to current ACL rule. It can handle protocol typed as text 00122 * or as a number (according to RFC). 00123 * @param pom - string with text/number from XML config file 00124 * @param rule - struct with ACL rule 00125 * @see loadConfigFromXML() 00126 */ 00127 void acl::getProtocol(std::string pom, TRule* rule) 00128 { 00129 if (pom == "ip" || pom == "4") 00130 rule->protocol = PROT_IP; 00131 else if (pom == "tcp" || pom == "6") 00132 rule->protocol = PROT_TCP; 00133 else if (pom == "udp" || pom == "17") 00134 rule->protocol = PROT_UDP; 00135 else if (pom == "icmp" || pom == "1") 00136 rule->protocol = PROT_ICMP; 00137 else if (pom == "igmp" || pom == "2") 00138 rule->protocol = PROT_IGMP; 00139 else if (pom == "eigrp" || pom == "igrp" || pom == "88") 00140 rule->protocol = PROT_EIGRP; 00141 else if (pom == "ospf" || pom == "89") 00142 rule->protocol = PROT_OSPF; 00143 } 00144 00145 /* 00146 * getPort(): GET PORT 00147 * Method that gets all port information fields from XML string. 00148 * It can handle ports typed as text or as a number (according to RFC). 00149 * @param pom - string contains the port operator from XML file 00150 * @param p_beg - string contains the beginning port no. from XML file 00151 * @param p_end - string contains the ending port no. from XML file 00152 * @param ip - struct with an IP Address in current ACL rule 00153 * @see loadConfigFromXML() 00154 */ 00155 void acl::getPort(std::string pom, std::string p_beg, std::string p_end, TIP *ip) 00156 { 00157 int p1, p2; 00158 stringstream ss (stringstream::in | stringstream::out); 00159 /* if port is given as text string, it is converted to short int number */ 00160 if (p_beg == "ftp-data") p1 = 20; 00161 if (p_beg == "ftp") p1 = 21; 00162 if (p_beg == "telnet") p1 = 23; 00163 if (p_beg == "smtp") p1 = 25; 00164 if (p_beg == "tftp") p1 = 69; 00165 if ((p_beg == "www") || (p_beg == "http") || (p_beg == "www-http")) p1 = 80; 00166 if ((p_beg == "pop3") || (p_beg == "pop")) p1 = 110; 00167 if (p_beg == "snmp") p1 = 161; 00168 if (p_beg == "irc") p1 = 194; 00169 if (p_beg == "ipx") p1 = 213; 00170 if (p_beg == "ldap") p1 = 389; 00171 if (p_beg == "https") p1 = 443; 00172 00173 ss << p_beg; 00174 ss >> p1; 00175 ss << p_end; 00176 ss >> p2; 00177 00178 /* resolution of port operators*/ 00179 if (pom == "eq") // EQ 00180 ip->port_op = PORT_EQ; 00181 else if (pom == "neq") // NEQ 00182 ip->port_op = PORT_NEQ; 00183 else if (pom == "gt") // GT 00184 ip->port_op = PORT_GT; 00185 else if (pom == "lt") // LT 00186 ip->port_op = PORT_LT; 00187 else if (pom == "range") // RANGE 00188 ip->port_op = PORT_RNG; 00189 else // if port operator is "" or not defined: NDEF 00190 { 00191 ip->port_op = PORT_NDEF; 00192 } 00193 switch (ip->port_op) { // based on presence of current port operator 00194 case PORT_EQ: 00195 case PORT_NEQ: 00196 case PORT_GT: 00197 case PORT_LT: // if operator is any of following [eq, neq, gt, lt]: load only one port no. from portBeg 00198 ip->portBeg = p1; 00199 break; 00200 case PORT_RNG: // if operator = RANGE, load two port number in the range of portBeg to portEnd 00201 ip->portBeg = p1; 00202 ip->portEnd = p2; 00203 break; 00204 case PORT_NDEF: // if any port operator is present, port range is full range of ports [0 - 65535] 00205 ip->portBeg = 0; 00206 ip->portEnd = 65535; 00207 break; 00208 } 00209 } 00210 00211 /* 00212 * loadConfigFromXML(): LOAD CONFIG FROM XML 00213 * Method that loads configuration from XML file to IP ACL structures. 00214 * Also binds list of ACL rules to interface and direction. 00215 * @param fileName - configuration filename (XML) 00216 * @see initialize() 00217 * @return correct/incorrect load of ACL configuration on Router 00218 */ 00219 bool acl::loadConfigFromXML(const char* fileName) 00220 { 00221 /* get access into Routing Table and Interface Table modules */ 00222 IRoutingTable* rt = RoutingTableAccess().get(); 00223 IInterfaceTable* ift = InterfaceTableAccess().get(); 00224 00225 /* resolution of configuration XML file according to specified filename */ 00226 cXMLElement* document = ev.getXMLDocument(fileName); 00227 if (document == NULL) 00228 { /* if no file with such name is provided, error is recognized */ 00229 error("Cannot read AS configuration from file %s", fileName); 00230 return false; 00231 } 00232 00233 /* try to find current router in XML on running instance of this ACL module */ 00234 std::string routerXPath("Router[@id='"); 00235 std::string routerId = rt->getRouterId().str(); 00236 routerXPath += routerId; 00237 routerXPath += "']"; 00238 00239 cXMLElement* router = document->getElementByPath(routerXPath.c_str()); 00240 if (router == NULL) 00241 { /* current router configuration is completely missing in XML configuration - error */ 00242 error("No configuration for Router ID: %s", routerId.c_str()); 00243 this->aclEnabled = false; 00244 return true; 00245 } 00246 cXMLElement* ACLs = router->getFirstChildWithTag("ACLs"); // find ACL configuration part 00247 if (ACLs == NULL) 00248 { /* ACL configuration part is missing in XML configuration */ 00249 //cout << "ACL: ACL is NOT ENABLED on Router id = " << routerId.c_str() << endl; 00250 this->aclEnabled = false; // ACL indicator is FALSE 00251 return true; 00252 } 00253 cXMLElement* ACL = ACLs->getFirstChildWithTag("ACL"); 00254 if (ACL == NULL) 00255 { 00256 //cout << "ACL: ACL is NOT ENABLED on Router id = " << routerId.c_str() << endl; 00257 this->aclEnabled = false; 00258 return true; 00259 } 00260 else 00261 { 00262 this->aclEnabled = true; 00263 //cout << "ACL: Loading ACL entries for Router id = " << routerId.c_str() << "\n"; 00264 } 00265 while (ACL != NULL) 00266 { 00267 cXMLElement *entry = ACL->getFirstChildWithTag("entry"); 00268 TACL _acl; 00269 00270 while (entry != NULL) 00271 { 00272 cXMLElement *leaf = entry->getFirstChild(); 00273 TRule rule; 00274 Stat stat; 00275 stat.used = 0; 00276 00277 std::string src_port_op = ""; 00278 std::string src_port_beg = ""; 00279 std::string src_port_end = ""; 00280 std::string dst_port_op = ""; 00281 std::string dst_port_beg = ""; 00282 std::string dst_port_end = ""; 00283 00284 /* processing current leaf under XML node <entry> */ 00285 while (leaf != NULL) 00286 { 00287 const char* tagName = leaf->getTagName(); 00288 const char* value = leaf->getNodeValue(); 00289 00290 if (strcmp(tagName, "action") == 0) 00291 getAction(value, &rule); 00292 else if (strcmp(tagName, "IP_src") == 0) 00293 rule.source.ipAddr.set(value); 00294 else if (strcmp(tagName, "WC_src") == 0) 00295 rule.source.netmask = negateWildcard(IPAddress(value)); 00296 else if (strcmp(tagName, "protocol") == 0) 00297 getProtocol(value, &rule); 00298 else if (strcmp(tagName, "IP_dst") == 0) 00299 rule.dest.ipAddr.set(value); 00300 else if (strcmp(tagName, "WC_dst") == 0) 00301 rule.dest.netmask = negateWildcard(IPAddress(value)); 00302 else if (strcmp(tagName, "port_op_src") == 0) 00303 src_port_op = value; 00304 else if (strcmp(tagName, "port_beg_src") == 0) 00305 src_port_beg = value; 00306 else if (strcmp(tagName, "port_end_src") == 0) 00307 src_port_end = value; 00308 else if (strcmp(tagName, "port_op_dst") == 0) 00309 dst_port_op = value; 00310 else if (strcmp(tagName, "port_beg_dst") == 0) 00311 dst_port_beg = value; 00312 else if (strcmp(tagName, "port_end_dst") == 0) 00313 dst_port_end = value; 00314 else if (strcmp(tagName, "orig") == 0) 00315 stat.text = value; 00316 leaf = leaf->getNextSibling(); 00317 } 00318 00319 /* AND (&) IP ADDRESS WITH NETWORK MASK IN CURRENT ACL RULE */ 00320 andIpWithMask(&rule); 00321 /* PROCESS PORT INFORMATION FROM XML CONFIGURATION FILE */ 00322 getPort(src_port_op, src_port_beg, src_port_end, &rule.source); 00323 getPort(dst_port_op, dst_port_beg, dst_port_end, &rule.dest); 00324 00325 /* generate statistics for processed rule */ 00326 stats.push_back(stat); 00327 Stat* pStat = &this->stats.back(); 00328 rule.used = &(pStat->used); 00329 00330 _acl.push_back(rule); // processed rule is added at the end of ACL list 00331 00332 entry = entry->getNextSiblingWithTag("entry"); 00333 } 00334 /* create default rule at the end of the ACL list - deny ip any any */ 00335 TRule rule; 00336 Stat stat; 00337 stat.used = 0; 00338 rule.action = A_DENY; 00339 rule.protocol = PROT_IP; 00340 stat.text = "access-list deny ip any any"; 00341 rule.source.ipAddr.set("0.0.0.0"); 00342 rule.dest.ipAddr.set("0.0.0.0"); 00343 rule.source.netmask.set("0.0.0.0"); 00344 rule.dest.netmask.set("0.0.0.0"); 00345 getPort("", "", "", &rule.source); 00346 getPort("", "", "", &rule.dest); 00347 00348 /* generate statistics for the default rule*/ 00349 stats.push_back(stat); 00350 Stat* pStat = &this->stats.back(); 00351 rule.used = &(pStat->used); 00352 00353 _acl.push_back(rule); // implicit rule is finally added at the end of the list 00354 00355 this->acls.push_back(_acl); // current ACL list is added at the end of ACLs (list of lists) 00356 00357 cXMLElement *interfaces = ACL->getFirstChildWithTag("interfaces"); 00358 cXMLElement *interface = interfaces->getFirstChildWithTag("interface"); 00359 00360 /* processing interface information - binding ACL list to interface and direction */ 00361 while (interface != NULL) 00362 { 00363 InterfaceEntry *targetInt = ift->getInterfaceByName(interface->getNodeValue()); 00364 TInterface _if; 00365 00366 _if.gateIndex = targetInt->getNetworkLayerGateIndex(); 00367 if (interface->getAttribute("dir") == std::string("in")) 00368 _if.dir = true; 00369 else 00370 _if.dir = false; 00371 _if.rules = &this->acls.back(); 00372 00373 this->interfaces.push_back(_if); 00374 interface = interface->getNextSibling(); 00375 } 00376 00377 ACL = ACL->getNextSiblingWithTag("ACL"); 00378 } 00379 return true; 00380 } 00381 00382 /* 00383 * getRules(): GET RULES 00384 * Method that gets specific ACL list, which is about to be applied 00385 * on current in/outgoing packet. 00386 * @param gateIndex - index of the arrival gate 00387 * @param dir - direction of data communication 00388 * @see handleMessage() 00389 * @return ACL list corresponding to packet or NULL if it's not 00390 */ 00391 TACL* acl::getRules(int gateIndex, bool dir) 00392 { 00393 for (std::list<TInterface>::iterator it = this->interfaces.begin(); it != this->interfaces.end(); it++) 00394 { 00395 TInterface* _if = &(*it); 00396 if (_if->gateIndex == gateIndex && _if->dir == dir) 00397 return _if->rules; 00398 } 00399 return NULL; 00400 } 00401 00402 /* 00403 * processPacket(): PROCESS PACKET 00404 * Method that is processing current packet, which is casted to IPDatagram. 00405 * It decapsulates packet and save the information such as source address, 00406 * destination address, transport protocol and transfer port numbers. 00407 * It also decides, whether the packet is about to be sent to upper/lower layer, 00408 * or is about to be dropped. 00409 * @param packet - current IP packet casted to IPDatagram 00410 * @param acl - list of ACL rules which fits current packet 00411 * @return Decision of action taken with current packet (permit/deny) 00412 */ 00413 bool acl::processPacket(IPDatagram* packet, TACL* acl) 00414 { 00415 TIP source, dest; 00416 source.ipAddr = packet->getSrcAddress(); 00417 dest.ipAddr = packet->getDestAddress(); 00418 int protocol = packet->getTransportProtocol(); 00419 00420 ev << "Packet Source IP Address: " << source.ipAddr.str() << endl; 00421 ev << "Packet Dest. IP Address: " << dest.ipAddr.str() << endl; 00422 ev << "Packet Protocol ID : " << protocol << endl; 00423 00424 UDPPacket *udppacket; 00425 TCPSegment *tcppacket; 00426 00427 switch (protocol) 00428 { 00429 case PROT_UDP: // if protocol is UDP, ports need to be checked 00430 udppacket = dynamic_cast<UDPPacket *> (packet->decapsulate()); 00431 source.portBeg = udppacket->getSourcePort(); 00432 ev << "UDP packet, source port: " << source.portBeg << endl; 00433 dest.portBeg = udppacket->getDestinationPort(); 00434 ev << "UDP packet, dest. port: " << dest.portBeg << endl; 00435 delete udppacket; 00436 break; 00437 case PROT_TCP: // if protocol is TCP, ports need to be checked 00438 tcppacket = dynamic_cast<TCPSegment *> (packet->decapsulate()); 00439 source.portBeg = tcppacket->getSrcPort(); 00440 ev << "TCP packet, source port: " << source.portBeg << endl; 00441 dest.portBeg = tcppacket->getDestPort(); 00442 ev << "TCP packet, dest. port: " << dest.portBeg << endl; 00443 delete tcppacket; 00444 break; 00445 default: 00446 ev << "Protocol is other than TCP or UDP, ports don't need to be checked..." << endl; 00447 break; 00448 } 00449 if (filterPacket(acl, source, dest, protocol)) 00450 { 00451 // rule is 'permit' 00452 this->packetsPermitted++; 00453 return true; 00454 } 00455 else 00456 { 00457 ev << "- ACL ACTION: DENY, packet dropped ---" << endl; 00458 this->packetsDropped++; 00459 return false; 00460 } 00461 } 00462 00463 /* 00464 * filterPacket(): FILTER PACKET 00465 * Method that compares information from the packet with whole 00466 * ACL list bound to current packet. Depending on this comparison, 00467 * indication of action is taken. (true = permit, false = deny). 00468 * @param acl - list of ACL rules which fits current packet 00469 * @param source - structure with source data from packet 00470 * @param dest - structure with destination data from packet 00471 * @param protocol - type of transport protocol of the packet 00472 * @return action taken with the current packet (permit/deny) 00473 * @see processPacket() 00474 */ 00475 bool acl::filterPacket(TACL* acl, TIP source, TIP dest, int protocol) 00476 { 00477 for (TACL_it it = acl->begin(); it != acl->end(); it++) 00478 { 00479 if (!(it->protocol == protocol || it->protocol == PROT_IP)) 00480 continue; 00481 ev << "acl::filterPacket: PROTOCOL MATCH" << endl; 00482 if (!ipIsEqual(&(it->source), &source)) 00483 continue; 00484 ev << "acl::filterPacket: SOURCE IP MATCH" << endl; 00485 if (it->protocol == PROT_UDP || it->protocol == PROT_TCP) 00486 { 00487 if (!portIsEqual(&(it->source), &source)) 00488 continue; 00489 else 00490 ev << "acl::filterPacket: SOURCE PORT MATCH" << endl; 00491 } 00492 if (!ipIsEqual(&(it->dest), &dest)) 00493 continue; 00494 ev << "acl::filterPacket: DESTINATION IP MATCH" << endl; 00495 if (it->protocol == PROT_UDP || it->protocol == PROT_TCP) 00496 { 00497 if (!portIsEqual(&(it->dest), &dest)) 00498 continue; 00499 else 00500 ev << "acl::filterPacket: DESTINATION PORT MATCH" << endl; 00501 } 00502 (*(it->used))++; 00503 return it->action; // if match is found with current record of ACL, action is returned 00504 } 00505 cout << "BUG" << endl; 00506 return false; // if no match in whole ACL is found 00507 } 00508 00509 /* 00510 * handleMessage(): HANDLE MESSAGE 00511 * Method that is processing current message arrived to gate. 00512 * It checks the index of the arrival gate, its name and index, 00513 * direction of communication according to which gate a packet came. 00514 * Some action is done with the message, it is being forwarded if no 00515 * ACL configuration is found for this router in XML file. 00516 * It also checks the type of packet. If it differs from IPDatagram, 00517 * it just forwards the message. Else it casts it to IPDatagram type. 00518 * @param msg - original message arriving to gate 00519 */ 00520 void acl::handleMessage(cMessage* msg) 00521 { 00522 cGate* gate = msg->getArrivalGate(); 00523 string name = gate->getBaseName(); 00524 int index = gate->getIndex(); 00525 bool dir = true; // packet heading from networkLayer IN to interface (pres ACL); ifIn, ifOut (in == true) 00526 TACL* acl; 00527 00528 if (name == "toNetworkLayerIn") 00529 dir = false; // packet heading from interface OUT to networkLayer (pres ACL); toNetworkLayerIn, toNetworkLayerOut 00530 // (out == false) 00531 if (!(this->aclEnabled)) 00532 { // if ACLs part is NOT listed in XML configuration file for current router 00533 if (dir) 00534 { /* send packet to upper layer: from interface out to networkLayer */ 00535 this->send(msg, "toNetworkLayerOut", index); 00536 ev << "ACL DISABLED, just directly send from interface out to networkLayer" << endl; 00537 } 00538 else 00539 { /* send packet to lower layer: from networkLayer out to interface */ 00540 this->send(msg, "ifOut", index); 00541 ev << "ACL DISABLED, just directly send from networkLayer out to interface" << endl; 00542 } 00543 } 00544 else /* ACL configuration part is found on current router (however, ACL list still might be empty */ 00545 { 00546 acl = getRules(index, dir); // get pointer to ACL list bound within current packet 00547 00548 cMessage *copy = msg->dup(); // duplicate the message due to instability during operations with an original message 00549 00550 cPacket *test = (cPacket*)(copy); 00551 string typ = test->getClassName(); 00552 if (typ != "IPDatagram") 00553 { // if the message is not an IP packet, message is just forwarded 00554 if (dir) 00555 { 00556 ev << "Not an IP packet, sending directly from interface out to networkLayer" << endl; 00557 this->send (msg, "toNetworkLayerOut", index); 00558 } 00559 else 00560 { 00561 ev << "Not an IP packet, sending directly from networkLayer out to interface..." << endl; 00562 this->send (msg, "ifOut", index); 00563 } 00564 } 00565 else // if dynamic_cast is correctly done - message is IPDatagram (an IP packet) 00566 { 00567 this->numPackets++; 00568 if (acl == NULL) // doesn't exist ACL for packet's interface and direction 00569 { 00570 ev << "No ACL found for this router/interface." << endl; 00571 this->packetsAllowed++; 00572 if (dir) 00573 { /* send packet to upper layer: from interface out to networkLayer */ 00574 this->send(msg, "toNetworkLayerOut", index); 00575 ev << "+packet sent to upper layer without ACL action" << endl; 00576 } 00577 else 00578 { /* send packet to lower layer: from networkLayer out to interface */ 00579 this->send(msg, "ifOut", index); 00580 ev << "+packet sent to lower layer without ACL action" << endl; 00581 } 00582 } 00583 else // ACL is bound within packet's interface and direction, need to filter 00584 { 00585 ev << "An ACL list bound correctly for this router/interface." << endl; 00586 IPDatagram *packet = dynamic_cast<IPDatagram*> (copy); // dynamic_cast is taken 00587 if (processPacket(packet, acl)) // action according to ACL is "permit" 00588 { 00589 if (dir) 00590 { /* send packet to upper layer: from interface out to networkLayer */ 00591 this->send(msg, "toNetworkLayerOut", index); 00592 ev << "+ACL ACTION: PERMIT +++ from interface out to networkLayer" << endl; 00593 } 00594 else 00595 { /* send packet to lower layer: from networkLayer out to interface */ 00596 this->send(msg, "ifOut", index); 00597 ev << "+ACL ACTION: PERMIT +++ from networkLayer out to interface" << endl; 00598 } 00599 } 00600 else // action according to ACL is "deny" 00601 { 00602 delete msg; 00603 } 00604 } 00605 } 00606 delete copy; 00607 } 00608 } 00609 00610 /* 00611 * initialize(): INITIALIZE 00612 * An autonomous method that's been called whenever simulation is started. 00613 * It initializes the ACL filtering module for the simulation needs. 00614 * @param stage - phase of simulation init 00615 */ 00616 void acl::initialize(int stage) 00617 { 00618 switch (stage) 00619 { 00620 case 0: // get access to notification board 00621 notificationBoard = NotificationBoardAccess().get(); 00622 notificationBoard->subscribe(this, NF_INTERFACE_STATE_CHANGED); 00623 break; 00624 case 4: // initialization of the ACL module 00625 const char *fileName = par("configFile"); // XML file name read from parameter 00626 if (loadConfigFromXML(fileName)) // success loading configuration data from XML file 00627 { 00628 //cout << "ACL: Configuration successfully loaded." << endl; 00629 } 00630 else // error loading configuration data from XML file 00631 { 00632 //cout << "ACL: Error loading configuration." << endl; 00633 } 00634 /* initialization of ACL action counters - usage in statistics */ 00635 this->packetsAllowed = 0; 00636 this->packetsDropped = 0; 00637 this->packetsPermitted = 0; 00638 this->numPackets = 0; 00639 00640 /* added class of statistics information onto Watch list */ 00641 WATCH_LIST(stats); 00642 } 00643 } 00644 00645 /* 00646 * finish(): FINISH 00647 * An autonomous method that's been called when simulation ends. 00648 * It displays all possible statistics from ACL module activities on console output. 00649 */ 00650 void acl::finish() 00651 { 00652 /* 00653 cout << "IP datagrams received: " << this->numPackets << endl; 00654 cout << "IP packets permitted without ACL action: " << this->packetsAllowed << endl; 00655 cout << "IP packets permitted by ACL action: " << this->packetsPermitted << endl; 00656 cout << "IP packets denied by an ACL action: " << this->packetsDropped << endl; 00657 for (std::list<Stat>::iterator it = this->stats.begin(); it != this->stats.end(); it++) 00658 { 00659 cout << it->text << " (" << it->used << " matches)" << endl; 00660 } 00661 cout << "--------------------------------------------------------" << endl; 00662 */ 00663 }