/** * 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; }
/** * 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; }