INET Framework for OMNeT++/OMNEST
AclContainer Class Reference

#include <AclContainer.h>

List of all members.

Public Member Functions

bool matchPacketToAcl (std::string name, cMessage *msg)
bool existAcl (std::string name)

Protected Member Functions

virtual void handleMessage (cMessage *msg)
virtual void initialize (int stage)
virtual int numInitStages () const

Private Member Functions

bool loadConfigFromXML (const char *filename)
bool processPacket (IPDatagram *packet, TRULES *acl)
bool compareValues (TRULES *acl, TIP source, TIP dest, int protocol)
TRULESgetRulesByAclName (std::string name)
bool ipIsEqual (TIP *ip, TIP *packet)
bool portIsEqual (TIP *ip, TIP *packet)
void getAction (std::string action, TRule *rule)
void getProtocol (std::string pom, TRule *rule)
void getPort (std::string pom, std::string p_beg, std::string p_end, TIP *ip)
void andIpWithMask (TRule *rule)
IPAddress negateWildcard (IPAddress wc)

Private Attributes

std::list< TACLacls
std::list< Statstats

Detailed Description

Definition at line 99 of file AclContainer.h.


Member Function Documentation

void AclContainer::andIpWithMask ( TRule rule) [private]

Definition at line 96 of file AclContainer.cc.

{
        rule->source.ipAddr =   rule->source.ipAddr.doAnd(rule->source.netmask);
        rule->dest.ipAddr =     rule->dest.ipAddr.doAnd(rule->dest.netmask);
}
bool AclContainer::compareValues ( TRULES acl,
TIP  source,
TIP  dest,
int  protocol 
) [private]

Definition at line 475 of file AclContainer.cc.

{
        for (TRULES_it it = acl->begin(); it != acl->end(); it++)
        {
                if (!(it->protocol == protocol || it->protocol == PROT_IP))
                  continue;
                ev << "acl::filterPacket: PROTOCOL MATCH" << endl;
                if (!ipIsEqual(&(it->source), &source))
                  continue;
                ev << "acl::filterPacket: SOURCE IP MATCH" << endl;
                if (it->protocol == PROT_UDP || it->protocol == PROT_TCP)
                {
                  if (!portIsEqual(&(it->source), &source))
                          continue;
                  else
                          ev << "acl::filterPacket: SOURCE PORT MATCH" << endl;
                }
                if (!ipIsEqual(&(it->dest), &dest))
                  continue;
                ev << "acl::filterPacket: DESTINATION IP MATCH" << endl;
                if (it->protocol == PROT_UDP || it->protocol == PROT_TCP)
                {
                  if (!portIsEqual(&(it->dest), &dest))
                          continue;
                  else
                          ev << "acl::filterPacket: DESTINATION PORT MATCH" << endl;
                }
                (*(it->used))++;
                return it->action; // if match is found with current record of ACL, action is returned
        }
        cout << "BUG" << endl;
        return false; // if no match in whole ACL is found
}
bool AclContainer::existAcl ( std::string  name)

Definition at line 532 of file AclContainer.cc.

{
  if (getRulesByAclName(name) == NULL)
    return false;
  return true;
  
}
void AclContainer::getAction ( std::string  action,
TRule rule 
) [private]

Definition at line 121 of file AclContainer.cc.

{
        if (action == "deny")
                rule->action = A_DENY;
        else if (action == "permit")
                rule->action = A_PERMIT;
}
void AclContainer::getPort ( std::string  pom,
std::string  p_beg,
std::string  p_end,
TIP ip 
) [private]

Definition at line 166 of file AclContainer.cc.

{
        int p1, p2;
        stringstream ss (stringstream::in | stringstream::out);
        /* if port is given as text string, it is converted to short int number */
        if (p_beg == "ftp-data") p1 = 20;
        if (p_beg == "ftp") p1 = 21;
        if (p_beg == "telnet") p1 = 23;
        if (p_beg == "smtp") p1 = 25;
        if (p_beg == "tftp") p1 = 69;
        if ((p_beg == "www") || (p_beg == "http") || (p_beg == "www-http")) p1 = 80;
        if ((p_beg == "pop3") || (p_beg == "pop")) p1 = 110;
        if (p_beg == "snmp") p1 = 161;
        if (p_beg == "irc") p1 = 194;
        if (p_beg == "ipx") p1 = 213;
        if (p_beg == "ldap") p1 = 389;
        if (p_beg == "https") p1 = 443;

        ss << p_beg;
        ss >> p1;
        ss << p_end;
        ss >> p2;

        /* resolution of port operators*/
        if (pom == "eq")                        // EQ
                ip->port_op = PORT_EQ;
        else if (pom == "neq")          // NEQ
                ip->port_op = PORT_NEQ;
        else if (pom == "gt")           // GT
                ip->port_op = PORT_GT;
        else if (pom == "lt")           // LT
                ip->port_op = PORT_LT;
        else if (pom == "range")        // RANGE
                ip->port_op = PORT_RNG;
        else // if port operator is "" or not defined: NDEF
        {
                ip->port_op = PORT_NDEF;
        }
        switch (ip->port_op) { // based on presence of current port operator
                case PORT_EQ:
                case PORT_NEQ:
                case PORT_GT:
                case PORT_LT: // if operator is any of following [eq, neq, gt, lt]: load only one port no. from portBeg
                        ip->portBeg = p1;
                        break;
                case PORT_RNG: // if operator = RANGE, load two port number in the range of portBeg to portEnd
                        ip->portBeg = p1;
                        ip->portEnd = p2;
                        break;
                case PORT_NDEF: // if any port operator is present, port range is full range of ports [0 - 65535]
                        ip->portBeg = 0;
                        ip->portEnd = 65535;
                        break;
        }
}
void AclContainer::getProtocol ( std::string  pom,
TRule rule 
) [private]

Definition at line 138 of file AclContainer.cc.

{
        if (pom == "ip" || pom == "4")
                rule->protocol = PROT_IP;
        else if (pom == "tcp" || pom == "6")
                rule->protocol = PROT_TCP;
        else if (pom == "udp" || pom == "17")
                rule->protocol = PROT_UDP;
        else if (pom == "icmp" || pom == "1")
                rule->protocol = PROT_ICMP;
        else if (pom == "igmp" || pom == "2")
                rule->protocol = PROT_IGMP;
        else if (pom == "eigrp" || pom == "igrp" || pom == "88")
                rule->protocol = PROT_EIGRP;
        else if (pom == "ospf" || pom == "89")
                rule->protocol = PROT_OSPF;
}
TRULES * AclContainer::getRulesByAclName ( std::string  name) [private]

Definition at line 402 of file AclContainer.cc.

{
        for (TACL_itc it = this->acls.begin(); it != this->acls.end(); it++)
        {
    if(it->aclName == name)
      return &it->rules;
        }
        return NULL;
}
void AclContainer::handleMessage ( cMessage *  msg) [protected, virtual]

Definition at line 552 of file AclContainer.cc.

{
  opp_error("This module doesn't process messages");
}
void AclContainer::initialize ( int  stage) [protected, virtual]

Definition at line 228 of file AclContainer.cc.

{
        if (stage == 4)
        {
                                const char *fileName = par("configFile"); // XML file name read from parameter
                                if (loadConfigFromXML(fileName)) // success loading configuration data from XML file
                                {
                                        //cout << "ACL: Configuration successfully loaded." << endl;
                                }
                                else // error loading configuration data from XML file
                                {
                                        //cout << "ACL: Error loading configuration." << endl;
                                }

                                /* added class of statistics information onto Watch list */
                                WATCH_LIST(stats);
        }
}
bool AclContainer::ipIsEqual ( TIP ip,
TIP packet 
) [private]

Definition at line 35 of file AclContainer.cc.

{
        ev << "ACL rule, ip  : " << ip->ipAddr.str() << endl;
        ev << "ACL rule, mask: " << ip->netmask.str() << endl;
        ev << "packet, ip    : " << packet->ipAddr.str() << endl;
        ev << "packet_masked : " << packet->ipAddr.doAnd(ip->netmask).str() << endl;
        if (ip->ipAddr != (packet->ipAddr.doAnd(ip->netmask)))
        {
                ev << "IP DOESN'T MATCH" << endl;
                return false;
        }
        ev << "IP MATCH OK" << endl;
        return true;
}
bool AclContainer::loadConfigFromXML ( const char *  filename) [private]

Definition at line 256 of file AclContainer.cc.

{
        /* get access into Routing Table and Interface Table modules */
        IRoutingTable* rt = RoutingTableAccess().get();

        /* resolution of configuration XML file according to specified filename */
        cXMLElement* document = ev.getXMLDocument(fileName);
        if (document == NULL)
        {       /* if no file with such name is provided, error is recognized */
                error("Cannot read AS configuration from file %s", fileName);
                return false;
        }

        /* try to find current router in XML on running instance of this ACL module */
        std::string routerXPath("Router[@id='");
        std::string routerId = rt->getRouterId().str();
        routerXPath += routerId;
        routerXPath += "']";

        cXMLElement* router = document->getElementByPath(routerXPath.c_str());
        if (router == NULL)
        {       /* current router configuration is completely missing in XML configuration - error */
                error("No configuration for Router ID: %s", routerId.c_str());
                return false;
        }
        cXMLElement* ACLs = router->getFirstChildWithTag("ACLs"); // find ACL configuration part
        if (ACLs == NULL)
        {       /* ACL configuration part is missing in XML configuration */
                //cout << "ACL: ACL is NOT ENABLED on Router id = " << routerId.c_str() << endl;
                return true;
        }
        cXMLElement* ACL = ACLs->getFirstChildWithTag("ACL");
        if (ACL == NULL)
        {
                //cout << "ACL: ACL is NOT ENABLED on Router id = " << routerId.c_str() << endl;
                return true;
        }
  
        while (ACL != NULL)
        {
                cXMLElement *entry = ACL->getFirstChildWithTag("entry");
                TACL _acl;
                _acl.aclName = ACL->getAttribute("no");
    
                while (entry != NULL)
                {
                        cXMLElement *leaf = entry->getFirstChild();
                        TRule rule;
                        Stat stat;
                        stat.used = 0;

                        std::string src_port_op = "";
                        std::string src_port_beg = "";
                        std::string src_port_end = "";
                        std::string dst_port_op = "";
                        std::string dst_port_beg = "";
                        std::string dst_port_end = "";

                        /* processing current leaf under XML node <entry> */
                        while (leaf != NULL)
                        {
                                const char* tagName = leaf->getTagName();
                                const char* value = leaf->getNodeValue();

                                if (strcmp(tagName, "action") == 0)
                                        getAction(value, &rule);
                                else if (strcmp(tagName, "IP_src") == 0)
                                        rule.source.ipAddr.set(value);
                                else if (strcmp(tagName, "WC_src") == 0)
                                        rule.source.netmask = negateWildcard(IPAddress(value));
                                else if (strcmp(tagName, "protocol") == 0)
                                        getProtocol(value, &rule);
                                else if (strcmp(tagName, "IP_dst") == 0)
                                        rule.dest.ipAddr.set(value);
                                else if (strcmp(tagName, "WC_dst") == 0)
                                        rule.dest.netmask = negateWildcard(IPAddress(value));
                                else if (strcmp(tagName, "port_op_src") == 0)
                                        src_port_op = value;
                                else if (strcmp(tagName, "port_beg_src") == 0)
                                        src_port_beg = value;
                                else if (strcmp(tagName, "port_end_src") == 0)
                                        src_port_end = value;
                                else if (strcmp(tagName, "port_op_dst") == 0)
                                        dst_port_op = value;
                                else if (strcmp(tagName, "port_beg_dst") == 0)
                                        dst_port_beg = value;
                                else if (strcmp(tagName, "port_end_dst") == 0)
                                        dst_port_end = value;
                                else if (strcmp(tagName, "orig") == 0)
                                        stat.text = value;
                                leaf = leaf->getNextSibling();
                        }
      
                        /* AND (&) IP ADDRESS WITH NETWORK MASK IN CURRENT ACL RULE */
                        andIpWithMask(&rule);
                        /* PROCESS PORT INFORMATION FROM XML CONFIGURATION FILE */
                        getPort(src_port_op, src_port_beg, src_port_end, &rule.source);
                        getPort(dst_port_op, dst_port_beg, dst_port_end, &rule.dest);

                        /* generate statistics for processed rule */
                        stats.push_back(stat);
                        Stat* pStat = &this->stats.back();
                        rule.used = &(pStat->used);

                        _acl.rules.push_back(rule); // processed rule is added at the end of ACL list

                        entry = entry->getNextSiblingWithTag("entry");
                }
                /* create default rule at the end of the ACL list - deny ip any any */
                TRule rule;
                Stat stat;
                stat.used = 0;
                rule.action = A_DENY;
                rule.protocol = PROT_IP;
                stat.text = "access-list " + _acl.aclName +" deny ip any any";
                rule.source.ipAddr.set("0.0.0.0");
                rule.dest.ipAddr.set("0.0.0.0");
                rule.source.netmask.set("0.0.0.0");
                rule.dest.netmask.set("0.0.0.0");
                getPort("", "", "", &rule.source);
                getPort("", "", "", &rule.dest);

                /* generate statistics for the default rule*/
                stats.push_back(stat);
                Stat* pStat = &this->stats.back();
                rule.used = &(pStat->used);
    
                _acl.rules.push_back(rule); // implicit rule is finally added at the end of the list

                this->acls.push_back(_acl); // current ACL list is added at the end of ACLs (list of lists)

    
                ACL = ACL->getNextSiblingWithTag("ACL");
        }
        return true;
}
bool AclContainer::matchPacketToAcl ( std::string  name,
cMessage *  msg 
)

Definition at line 510 of file AclContainer.cc.

{
  TRULES* acl = getRulesByAclName(name);
  if (acl == NULL)
    return false;
  
  cMessage *copy = msg->dup(); // duplicate the message due to instability during operations with an original message

        cPacket *test = (cPacket*)(copy);
        string typ = test->getClassName();
        if (typ == "IPDatagram")
        {
           IPDatagram *packet = dynamic_cast<IPDatagram*> (copy);
           bool result =  processPacket(packet, acl);
     delete copy;
     return result;   
  }
  
  delete copy;
  return false;
}

Definition at line 108 of file AclContainer.cc.

{
        return (IPAddress(~(wc.getInt())));
}
virtual int AclContainer::numInitStages ( ) const [inline, protected, virtual]

Definition at line 125 of file AclContainer.h.

{ return 5;}
bool AclContainer::portIsEqual ( TIP ip,
TIP packet 
) [private]

Definition at line 59 of file AclContainer.cc.

{
        switch (ip->port_op) {
                case PORT_EQ:
                        if (ip->portBeg == packet->portBeg)
                                return true;
                        break;
                case PORT_NEQ:
                        if (ip->portBeg != packet->portBeg)
                                return true;
                        break;
                case PORT_GT:
                        if (ip->portBeg < packet->portBeg)
                                return true;
                        break;
                case PORT_LT:
                        if (ip->portBeg > packet->portBeg)
                                return true;
                        break;
                case PORT_RNG:
                case PORT_NDEF:
                        if ((ip->portBeg <= packet->portBeg) && (ip->portEnd >= packet->portBeg))
                                return true;
                        break;
                default:
                        cout << "BUG" << endl;
        }
        return false;
}
bool AclContainer::processPacket ( IPDatagram packet,
TRULES acl 
) [private]

Definition at line 423 of file AclContainer.cc.

{
        TIP source, dest;
        source.ipAddr = packet->getSrcAddress();
        dest.ipAddr = packet->getDestAddress();
        int protocol = packet->getTransportProtocol();

        ev << "Packet Source IP Address: " << source.ipAddr.str() << endl;
        ev << "Packet Dest.  IP Address: " << dest.ipAddr.str() << endl;
        ev << "Packet Protocol ID      : " << protocol << endl;

        UDPPacket *udppacket;
        TCPSegment *tcppacket;

        switch (protocol)
        {
                case PROT_UDP: // if protocol is UDP, ports need to be checked
                        udppacket = dynamic_cast<UDPPacket *> (packet->decapsulate());
                        source.portBeg = udppacket->getSourcePort();
                        ev << "UDP packet, source port: " << source.portBeg << endl;
                        dest.portBeg = udppacket->getDestinationPort();
                        ev << "UDP packet, dest.  port: " << dest.portBeg << endl;
                        delete udppacket;
                        break;
                case PROT_TCP: // if protocol is TCP, ports need to be checked
                        tcppacket = dynamic_cast<TCPSegment *> (packet->decapsulate());
                        source.portBeg = tcppacket->getSrcPort();
                        ev << "TCP packet, source port: " << source.portBeg << endl;
                        dest.portBeg = tcppacket->getDestPort();
                        ev << "TCP packet, dest.  port: " << dest.portBeg << endl;
                        delete tcppacket;
                        break;
                default:
                        ev << "Protocol is other than TCP or UDP, ports don't need to be checked..." << endl;
                        break;
        }
        
  return compareValues(acl, source, dest, protocol);
}

Member Data Documentation

std::list<TACL> AclContainer::acls [private]

Definition at line 115 of file AclContainer.h.

std::list<Stat> AclContainer::stats [private]

Definition at line 116 of file AclContainer.h.


The documentation for this class was generated from the following files: