Exemple #1
0
/**
 * match parsed interfaces with interfaces detected in system.
 * ClntCfgIface objects copied to CfgMgr.
 *
 * @param parser
 *
 * @return true if ok, false if interface definitions are incorrect
 */
bool TClntCfgMgr::matchParsedSystemInterfaces(ClntParser *parser) {
    int cfgIfaceCnt;

    cfgIfaceCnt = parser->ClntCfgIfaceLst.count();
    Log(Debug) << cfgIfaceCnt << " interface(s) specified in " << CLNTCONF_FILE << LogEnd;

    SPtr<TClntCfgIface> cfgIface;
    SPtr<TIfaceIface> ifaceIface;

    if (cfgIfaceCnt) {
        // user specified some interfaces in config file
        parser->ClntCfgIfaceLst.first();
        while(cfgIface = parser->ClntCfgIfaceLst.get()) {
            // for each interface (from config file)
            if (cfgIface->getID()==-1) {
                ifaceIface = ClntIfaceMgr().getIfaceByName(cfgIface->getName());
            } else {
                ifaceIface = ClntIfaceMgr().getIfaceByID(cfgIface->getID());
            }

            if (!ifaceIface) {
                if (inactiveMode()) {
                    Log(Info) << "Interface " << cfgIface->getFullName()
                              << " is not currently available (that's ok, inactive-mode enabled)." << LogEnd;
                    continue;
                }
                Log(Error) << "Interface " << cfgIface->getFullName()
                           << " specified in " << CLNTCONF_FILE << " is not present or does not support IPv6."
                           << LogEnd;
                return false;
            }
            if (cfgIface->noConfig()) {
                Log(Info) << "Interface " << cfgIface->getFullName()
                          << " has flag no-config set, so it is ignored." << LogEnd;
                continue;
            }

#ifdef MOD_REMOTE_AUTOCONF
            if (RemoteAutoconf) {
                List(TIPv6Addr) emptyLst;
                SPtr<TOpt> optNeighbors = new TOptAddrLst(OPTION_NEIGHBORS, emptyLst, 0);
                Log(Debug) << "Enabled Neighbors option on " << cfgIface->getFullName() << LogEnd;
                cfgIface->addExtraOption(optNeighbors, false);
            }
#endif

            cfgIface->setIfaceName(ifaceIface->getName());
            cfgIface->setIfaceID(ifaceIface->getID());

            // setup default prefix length (used when IPv6 address is added to the interface)
            ifaceIface->setPrefixLength(cfgIface->getOnLinkPrefixLength());

            if (!ifaceIface->flagUp() || !ifaceIface->countLLAddress()) {
                if (inactiveMode()) {
                    Log(Notice) << "Interface " << ifaceIface->getFullName()
                                << " is not operational yet (does not have "
                                << "link-local address or is down), skipping it for now." << LogEnd;
                    addIface(cfgIface);
                    makeInactiveIface(cfgIface->getID(), true, true, true); // move it to InactiveLst
                    continue;
                }

                Log(Crit) << "Interface " << ifaceIface->getFullName()
                          << " is down or doesn't have any link-local address." << LogEnd;
                return false;
            }

            // Check if the interface is during bring-up phase
            // (i.e. DAD procedure for link-local addr is not complete yet)
            char tmp[64];
            ifaceIface->firstLLAddress();
            inet_ntop6(ifaceIface->getLLAddress(), tmp);
            if (is_addr_tentative(ifaceIface->getName(), ifaceIface->getID(), tmp)
                == LOWLEVEL_TENTATIVE_YES) {
                Log(Notice) << "Interface " << ifaceIface->getFullName()
                            << " has link-local address " << tmp
                            << ", but it is currently tentative." << LogEnd;

                if (this->inactiveMode()) {
                    Log(Notice) << "Interface " << ifaceIface->getFullName()
                                << " is not operational yet (link-local address "
                                << "is not ready), skipping it for now." << LogEnd;
                    addIface(cfgIface);
                    makeInactiveIface(cfgIface->getID(), true, true, true); // move it to InactiveLst
                    continue;
                }

                Log(Crit) << "Interface " << ifaceIface->getFullName()
                          << " has tentative link-local address (and inactive-mode is disabled)." << LogEnd;
                return false;
            }

            if (obeyRaBits()) {
                if (!ifaceIface->getMBit() && !ifaceIface->getOBit()) {
                    Log(Info) << "Interface " << cfgIface->getFullName()
                              << " configuration loaded, but did not receive a Router "
                              << "Advertisement with M or O bits set, adding to inactive."
                              << LogEnd;
                    addIface(cfgIface);
                    makeInactiveIface(cfgIface->getID(), true, true, true); // move it to inactive list
                    continue;
                }
                cfgIface->setMbit(ifaceIface->getMBit());
                cfgIface->setObit(ifaceIface->getOBit());
            }

            addIface(cfgIface);
            Log(Info) << "Interface " << cfgIface->getFullName()
                      << " configuration has been loaded." << LogEnd;
        }
        return countIfaces() || (inactiveMode() && inactiveIfacesCnt());
    } else {
        // user didn't specified any interfaces in config file, so
        // we'll try to configure each interface we could find
        Log(Warning) << "Config file does not contain any interface definitions. Trying to autodetect."
                     << LogEnd;

        List(TIPv6Addr) dnsList;
        dnsList.clear();
        parser->ParserOptStack.getLast()->setDNSServerLst(&dnsList);

        // Try to add a hostname
        char hostname[255];
        if (get_hostname(hostname, 255) == LOWLEVEL_NO_ERROR) {
            parser->ParserOptStack.getLast()->setFQDN(string(hostname));
	    } else {
            parser->ParserOptStack.getLast()->setFQDN(string(""));
        }

        int cnt = 0;
        ClntIfaceMgr().firstIface();
        while ( ifaceIface = ClntIfaceMgr().getIface() ) {
            // for each interface present in the system...
            if (!inactiveMode()) {
                if (!ifaceIface->flagUp()) {
                    Log(Notice) << "Interface " << ifaceIface->getFullName() << " is down, ignoring." << LogEnd;
                    continue;
                }
                if (!ifaceIface->flagRunning()) {
                    Log(Notice) << "Interface " << ifaceIface->getFullName()
                                << " has flag RUNNING not set, ignoring." << LogEnd;
                    continue;
                }
                if (!ifaceIface->flagMulticast()) {
                    Log(Notice) << "Interface " << ifaceIface->getFullName()
                                << " is not multicast capable, ignoring." << LogEnd;
                    continue;
                }
            }
            if ( !(ifaceIface->getMacLen() > 5) ) {
                Log(Notice) << "Interface " << ifaceIface->getFullName()
                            << " has MAC address length " << ifaceIface->getMacLen()
                            << " (6 or more required), ignoring." << LogEnd;
                continue;
            }

            // ignore disabled Teredo pseudo-interface on Win (and other similar useless junk)
            const static unsigned char zeros[] = {0,0,0,0,0,0,0,0};
            const static unsigned char ones[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
            if ( (ifaceIface->getMacLen()<=8) &&
                 (!memcmp(zeros, ifaceIface->getMac(), min(8,ifaceIface->getMacLen())) ||
                  !memcmp(ones, ifaceIface->getMac(), min(8,ifaceIface->getMacLen()))) ) {
                Log(Notice) << "Interface " << ifaceIface->getFullName()
                            << " has invalid MAC address "
                            << hexToText((uint8_t*)ifaceIface->getMac(), ifaceIface->getMacLen(), true)
                            << ", ignoring." << LogEnd;
                continue;
            }

            if (!ifaceIface->countLLAddress()) {
                Log(Notice) << "Interface " << ifaceIface->getFullName()
                            << " has no link-local address, ignoring. "
                            << "(Disconnected? Not associated? No-link?)" << LogEnd;
                continue;
            }

            // One address...
            SPtr<TClntCfgAddr> addr(new TClntCfgAddr());
            addr->setOptions(parser->ParserOptStack.getLast());

            // ... is stored in one IA...
            SPtr<TClntCfgIA> ia = new TClntCfgIA();
            ia->setOptions(parser->ParserOptStack.getLast());
            ia->addAddr(addr);

            // ... on this newly created interface...
            cfgIface = SPtr<TClntCfgIface>(new TClntCfgIface(ifaceIface->getID()));
            cfgIface->setIfaceName(ifaceIface->getName());
            cfgIface->setIfaceID(ifaceIface->getID());
            cfgIface->addIA(ia);
            cfgIface->setOptions(parser->ParserOptStack.getLast());

            // ... which is added to ClntCfgMgr
            addIface(cfgIface);

            Log(Info) << "Interface " << cfgIface->getFullName()
                      << " has been added." << LogEnd;

            if (inactiveMode() && !ifaceIface->flagRunning() ) {
                makeInactiveIface(cfgIface->getID(), true, true, true); // move it to InactiveLst
                Log(Notice) << "Interface " << ifaceIface->getFullName()
                            << " is not operational yet"
                            << " (not running), made inactive." << LogEnd;
            }
            cnt ++;
        }
        if (!cnt) {
            Log(Crit) << "Unable to detect any suitable interfaces. If there are any interfaces that you"
                      << " want to have configured, please specify them in client.conf file." << LogEnd;
            return false;
        }
    }
    return true;
}
Exemple #2
0
/**
 * match parsed interfaces with interfaces detected in system.
 * ClntCfgIface objects copied to CfgMgr.
 *
 * @param parser
 *
 * @return
 */
bool TClntCfgMgr::matchParsedSystemInterfaces(ClntParser *parser) {
    int cfgIfaceCnt;

    cfgIfaceCnt = parser->ClntCfgIfaceLst.count();
    Log(Debug) << cfgIfaceCnt << " interface(s) specified in " << CLNTCONF_FILE << LogEnd;

    SPtr<TClntCfgIface> cfgIface;
    SPtr<TIfaceIface> ifaceIface;

    if (cfgIfaceCnt) {
        // user specified some interfaces in config file
        parser->ClntCfgIfaceLst.first();
        while(cfgIface = parser->ClntCfgIfaceLst.get()) {
            // for each interface (from config file)
            if (cfgIface->getID()==-1) {
                ifaceIface = ClntIfaceMgr().getIfaceByName(cfgIface->getName());
            } else {
                ifaceIface = ClntIfaceMgr().getIfaceByID(cfgIface->getID());
            }

            if (!ifaceIface) {
                Log(Error) << "Interface " << cfgIface->getName() << "/" << cfgIface->getID()
                           << " specified in " << CLNTCONF_FILE << " is not present or does not support IPv6."
                           << LogEnd;
                return false;
            }
            if (cfgIface->noConfig()) {
                Log(Info) << "Interface " << cfgIface->getName() << "/" << cfgIface->getID()
                               << " has flag no-config set, so it is ignored." << LogEnd;
                continue;
            }

#ifdef MOD_REMOTE_AUTOCONF
            if (RemoteAutoconf) {
                List(TIPv6Addr) emptyLst;
                SPtr<TOpt> optNeighbors = new TOptAddrLst(OPTION_NEIGHBORS, emptyLst, 0);
                Log(Debug) << "Enabled Neighbors option on " << cfgIface->getFullName() << LogEnd;
                cfgIface->addExtraOption(optNeighbors, false);
            }
#endif

            cfgIface->setIfaceName(ifaceIface->getName());
            cfgIface->setIfaceID(ifaceIface->getID());

            // setup default prefix length (used when IPv6 address is added to the interface)
            ifaceIface->setPrefixLength(cfgIface->getPrefixLength());

            if (!ifaceIface->countLLAddress()) {
                if (this->inactiveMode()) {
                    Log(Notice) << "Interface " << ifaceIface->getFullName()
                                << " is not operational yet (does not have "
                                << "link-local address), skipping it for now." << LogEnd;
                    addIface(cfgIface);
                    makeInactiveIface(cfgIface->getID(), true); // move it to InactiveLst
                    return true;
                }

                Log(Crit) << "Interface " << ifaceIface->getFullName()
                          << " is down or doesn't have any link-local address." << LogEnd;
                return false;
            }

            // Check if the interface is during bring-up phase
            // (i.e. DAD procedure for link-local addr is not complete yet)
            char tmp[64];
            ifaceIface->firstLLAddress();
            inet_ntop6(ifaceIface->getLLAddress(), tmp);
            if (is_addr_tentative(ifaceIface->getName(), ifaceIface->getID(), tmp)
                == LOWLEVEL_TENTATIVE_YES) {
                Log(Notice) << "Interface " << ifaceIface->getFullName()
                            << " has link-local address " << tmp
                            << ", but it is currently tentative." << LogEnd;

                if (this->inactiveMode()) {
                    Log(Notice) << "Interface " << ifaceIface->getFullName()
                                << " is not operational yet (link-local address "
                                << "is not ready), skipping it for now." << LogEnd;
                    addIface(cfgIface);
                    makeInactiveIface(cfgIface->getID(), true); // move it to InactiveLst
                    return true;
                }

                Log(Crit) << "Interface " << ifaceIface->getFullName()
                          << " has tentative link-local address (and inactive-mode is disabled)." << LogEnd;
                return false;

            }

            this->addIface(cfgIface);
            Log(Info) << "Interface " << cfgIface->getName() << "/" << cfgIface->getID()
                                  << " configuation has been loaded." << LogEnd;
        }
    } else {
        // user didn't specified any interfaces in config file, so
        // we'll try to configure each interface we could find
        Log(Warning) << "Config file does not contain any interface definitions. Trying to autodetect."
                     << LogEnd;

        List(TIPv6Addr) dnsList;
        dnsList.clear();
        parser->ParserOptStack.getLast()->setDNSServerLst(&dnsList);

        int cnt = 0;
        ClntIfaceMgr().firstIface();
        while ( ifaceIface = ClntIfaceMgr().getIface() ) {
            // for each interface present in the system...
            if (!ifaceIface->flagUp()) {
                Log(Notice) << "Interface " << ifaceIface->getFullName() << " is down, ignoring." << LogEnd;
                continue;
            }
            if (!ifaceIface->flagRunning()) {
                Log(Notice) << "Interface " << ifaceIface->getFullName()
                            << " has flag RUNNING not set, ignoring." << LogEnd;
                continue;
            }
            if (!ifaceIface->flagMulticast()) {
                Log(Notice) << "Interface " << ifaceIface->getFullName()
                            << " is not multicast capable, ignoring." << LogEnd;
                continue;
            }
            if ( !(ifaceIface->getMacLen() > 5) ) {
                Log(Notice) << "Interface " << ifaceIface->getFullName()
                            << " has MAC address length " << ifaceIface->getMacLen()
                            << " (6 or more required), ignoring." << LogEnd;
                continue;
            }
            ifaceIface->firstLLAddress();
            if (!ifaceIface->getLLAddress()) {
                Log(Notice) << "Interface " << ifaceIface->getFullName()
                            << " has no link-local address, ignoring. "
                            << "(Disconnected? Not associated? No-link?)" << LogEnd;
                continue;
            }

            // One address...
            SPtr<TClntCfgAddr> addr(new TClntCfgAddr());
            addr->setOptions(parser->ParserOptStack.getLast());

            // ... is stored in one IA...
            SPtr<TClntCfgIA> ia = new TClntCfgIA();
            ia->setOptions(parser->ParserOptStack.getLast());
            ia->addAddr(addr);

            // ... on this newly created interface...
            cfgIface = SPtr<TClntCfgIface>(new TClntCfgIface(ifaceIface->getID()));
            cfgIface->setIfaceName(ifaceIface->getName());
            cfgIface->setIfaceID(ifaceIface->getID());
            cfgIface->addIA(ia);
            cfgIface->setOptions(parser->ParserOptStack.getLast());

            // ... which is added to ClntCfgMgr
            this->addIface(cfgIface);

            Log(Info) << "Interface " << cfgIface->getName() << "/" << cfgIface->getID()
                      << " has been added." << LogEnd;
            cnt ++;
        }
        if (!cnt) {
            Log(Crit) << "Unable to detect any suitable interfaces. If there are any interfaces that you"
                      << " want to have configured, please specify them in client.conf file." << LogEnd;
            return false;
        }
    }
    return true;
}