Exemplo n.º 1
0
string RoutingCompiler::debugPrintRule(Rule *r)
{
    RoutingRule *rule = RoutingRule::cast(r);

    RuleElementRDst *dstrel = rule->getRDst();
    RuleElementRItf *itfrel = rule->getRItf();
    RuleElementRGtw *gtwrel = rule->getRGtw();

    ostringstream str;

//    str << setw(70) << setfill('-') << "-";

    string dst, itf, gtw;
   
    FWObject *obj = FWReference::getObject(itfrel->front());
    itf = (obj) ? obj->getName() : "NULL";

    obj = FWReference::getObject(gtwrel->front());
    gtw = (obj) ? obj->getName() : "NULL";
     
    
    int no = 0;
    FWObject::iterator i1 = dstrel->begin();
    while ( i1!=dstrel->end())
    {
        str << endl;

        dst = " ";

        if (i1 != dstrel->end())
        {
            FWObject *o = FWReference::getObject(*i1);
            dst = (o) ? o->getName() : "NULL";
        }

        int w = 0;
        if (no==0)
        {
            str << rule->getLabel();
            w = rule->getLabel().length();
        }
        
        str <<  setw(10-w)  << setfill(' ') << " ";

        str <<  setw(18) << setfill(' ') << dst.c_str() << " ";
        str <<  setw(18) << setfill(' ') << itf.c_str() << " ";
        str <<  setw(18) << setfill(' ') << gtw.c_str() << " ";
        str <<  setw(18) << setfill(' ') << " ";

        ++no;

        if ( i1 != dstrel->end() ) ++i1;
    }
    return str.str();
}
string RoutingCompiler_cisco::PrintRule::_printRGtw(RoutingRule *rule)
{
    FWObject *ref;
    
    RuleElementRGtw *gtwrel = rule->getRGtw();
    ref = gtwrel->front();
    Address *gtw = Address::cast(FWReference::cast(ref)->getPointer());
    if (gtw == NULL) compiler->abort(rule, "Broken GTW");

    string gateway = _printAddr(gtw);
    if (gateway != "default ") return gateway;
    else return " ";
}
/*
 * Replace objects in dst and gw with their ip addresses, except if
 * interface of the firewall is found in gw, it is left intact because
 * IOS allows for using interface name as gateway in "ip route"
 * command.
 */
bool RoutingCompiler_iosacl::ExpandMultipleAddressesExceptInterface::processNext()
{
    RoutingRule *rule=getNext(); if (rule==NULL) return false;
    tmp_queue.push_back(rule);

    RuleElementRDst *dst = rule->getRDst();    assert(dst);
    compiler->_expand_addr(rule, dst, true);

    RuleElementRGtw *gtwrel = rule->getRGtw();    assert(gtwrel);
    Address *gtw = Address::cast(
        FWReference::cast(gtwrel->front())->getPointer());
    if (gtw == NULL)
        compiler->abort(rule, "Broken GTW");
    if (Interface::isA(gtw) && gtw->isChildOf(compiler->fw)) return true;
    compiler->_expand_addr(rule, gtwrel, false);
    return true;
}
Exemplo n.º 4
0
/*
 * Call this after converting to atomic rules by DST to be sure there
 * is just one object in DST.
 */
bool RoutingCompiler::sameDestinationDifferentGateways::processNext()
{
    slurp();
    if (tmp_queue.size()==0) return false;

    // map destination to gateway.
    std::map<string, string> dst_to_gw;
    std::map<string, string> dst_to_rule;

    for (deque<Rule*>::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k)
    {
        RoutingRule *rule = RoutingRule::cast( *k );
        
        RuleElementRDst *dstrel = rule->getRDst();
        Address *dst = Address::cast(FWReference::getObject(dstrel->front()));
        const InetAddr* dst_addr = dst->getAddressPtr();
        const InetAddr* dst_netm = dst->getNetmaskPtr();
        string key = dst_addr->toString() + "/" + dst_netm->toString();

        // RuleElementRItf *itfrel = rule->getRItf();
        // FWObject *itf = FWReference::cast(itfrel->front())->getPointer();
    
        RuleElementRGtw *gtwrel = rule->getRGtw();
        Address *gtw = Address::cast(FWReference::getObject(gtwrel->front()));
        const InetAddr* gtw_addr = gtw->getAddressPtr();
        const InetAddr* gtw_netm = gtw->getNetmaskPtr();
        string val = gtw_addr->toString() + "/" + gtw_netm->toString();

        if (!dst_to_gw[key].empty() && dst_to_gw[key] != val)
        {
            compiler->abort(
                rule,
                "Rules " + dst_to_rule[key] + " and " + rule->getLabel() +
                " define routes to the same destination " + key +
                " via different gateways. This configuration is not supported"
                " for " + compiler->fw->getStr("host_OS"));
        } else
        {
            dst_to_gw[key] = val;
            dst_to_rule[key] = rule->getLabel();
        }
    }

    return true;
}
string RoutingCompiler_iosacl::PrintRule::_printRGtw(RoutingRule *rule)
{
    FWObject *ref;
    
    RuleElementRGtw *gtwrel = rule->getRGtw();
    ref = gtwrel->front();
    Address *gtw = Address::cast(FWReference::cast(ref)->getPointer());

    if (Interface::isA(gtw) && gtw->isChildOf(compiler->fw))
    {
        // gateway is interface of this firewall. Generate command
        // ip route A.B.C.D N.N.N.N interface metric
        return gtw->getName() + " ";
    }
        
    string gateway = _printAddr(gtw);
    if (gateway != "default ") return gateway;
    else return " ";
}
Exemplo n.º 6
0
bool RoutingCompiler::competingRules::processNext()
{
    RoutingRule *rule = getNext(); if (rule==NULL) return false;
        
    RuleElementRItf *itfrel = rule->getRItf();
    FWObject *itf = FWReference::cast(itfrel->front())->getPointer();
    
    RuleElementRGtw *gtwrel = rule->getRGtw();
    FWObject *gtw = FWReference::cast(gtwrel->front())->getPointer();
     
    string metric = rule->getMetricAsString();
    string label  = rule->getSortedDstIds();
    ostringstream ostr;
    ostr << gtw->getId() << "_" << itf->getId();
    string combiId = ostr.str();
    
    if( label == "") compiler->abort(
        
            rule,         
            "Place 'createSortedDstIdsLabel()' before 'competingRules()' "
            "in the rule processor chain");
    
    dest_it = rules_seen_so_far.find(label);
    if( dest_it != rules_seen_so_far.end()) {
        
        // a rule with the same destination was already seen
        ///std::cout << "NO NEW DEST" << std::endl;
        
        gtwitf_it = dest_it->second.find(combiId);
        if( gtwitf_it != dest_it->second.end() )
        {
            // ... this gateway and interface combination were already
            // seen for this destination
            ///std::cout << "NO NEW GTWITF" << std::endl;
            
            if( gtwitf_it->second.first == metric) {
                
                // ... and same metric => rule already exists, skip
                ///std::cout << "SAME METRIC" << std::endl;
                
                string msg;
                msg = "Routing rules " + gtwitf_it->second.second +
                    " and " + rule->getLabel() +
                    " are identical, skipping the second one. " +
                    "Delete one of them to avoid this warning";
                compiler->warning(rule,  msg.c_str());
            } else {
                
                // ... but different metric => what metric should I use? => abort
                ///std::cout << "DIFFERENT METRIC" << std::endl;
                
                string msg;
                msg = "Routing rules " + gtwitf_it->second.second +
                    " and " + rule->getLabel() +
                    " are identical except for the metric, " +
                    "please delete one of them";
                compiler->abort(rule,  msg.c_str());
            }
        
        } else
        {
            // ... this gateway and interface combination is new for
            // this destination
            ///std::cout << "NEW GTWITF" << std::endl;///
            
            if(false)
            {
                // TODO_lowPrio: if (
                // !compiler->fw->getOptionsObject()->getBool
                // ("equal_cost_multi_path") ) ...If multipath is
                // turned off, perform this check.

                // iterate all gtwitf combis in the map
                // dest_it->second and search for the current metric
                
                // ... but has the same metric => what route should I
                // use for this destination? => abort
                    
                string msg;
                msg = "Routing rules " + gtwitf_it->second.second + " and " +
                    rule->getLabel() +
                    " have the same destination and same metric,"
                    "but different gateway and interface combination. "
                    "Set the metrics to different values or "
                    "enable ECMP (Equal Cost MultiPath) routing";
                compiler->abort( msg.c_str() );
            
            } else
            {
                // ... and different metric OR equal_cost_multi_path enabled => OK
                tmp_queue.push_back(rule);
            }
            
            dest_it->second[combiId] =
                pair< string, string>( metric, rule->getLabel());
        }
        
    } else {
        
        // this destination is new
        //std::cout << "NEW DEST" << std::endl;
        ///
        
        //ruleinfo tmpRuleInfo = { gtw->getStr("id") + itf->getStr("id"), metric, rule->getLabel()};
        //rules_seen_so_far[label] = tmpRuleInfo;
        
        map< string, pair< string, string> > gtw_itf_tmp;
        gtw_itf_tmp[combiId] = pair< string, string>( metric, rule->getLabel());
        
        rules_seen_so_far[label] = gtw_itf_tmp;
        
        
        tmp_queue.push_back(rule);
    }

    return true;
}