TClntMsgInfRequest::TClntMsgInfRequest(SPtr<TClntCfgIface> iface) :TClntMsg(iface->getID(), 0, INFORMATION_REQUEST_MSG) { IRT = INF_TIMEOUT; MRT = INF_MAX_RT; MRC = 0; MRD = 0; RT= 0 ; Iface=iface->getID(); IsDone=false; if (!ClntCfgMgr().anonInfRequest()) { Options.push_back(new TOptDUID(OPTION_CLIENTID, ClntCfgMgr().getDUID(), this)); } else { Log(Info) << "Sending anonymous INF-REQUEST (ClientID not included)." << LogEnd; } // Append the options we want to configure appendRequestedOptions(); // If there is no ORO (or it is empty), skip the message. SPtr<TClntOptOptionRequest> oro = (Ptr*) getOption(OPTION_ORO); if (!oro || !oro->count()) { IsDone = true; return; } appendAuthenticationOption(); appendElapsedOption(); send(); }
bool TClntIfaceMgr::fqdnAdd(SPtr<TClntIfaceIface> iface, string fqdn) { SPtr<TIPv6Addr> DNSAddr; SPtr<TIPv6Addr> addr; SPtr<TClntCfgIface> cfgIface; cfgIface = ClntCfgMgr().getIface(iface->getID()); if (!cfgIface) { Log(Error) << "Unable to find interface with ifindex=" << iface->getID() << "." << LogEnd; return false; } // For the moment, we just take the first DNS entry. List(TIPv6Addr) DNSSrvLst = iface->getDNSServerLst(); if (!DNSSrvLst.count()) { Log(Error) << "Unable to find DNS Server. FQDN add failed." << LogEnd; return false; } DNSSrvLst.first(); DNSAddr = DNSSrvLst.get(); // And the first IP address SPtr<TAddrIA> ptrAddrIA; ClntAddrMgr().firstIA(); ptrAddrIA = ClntAddrMgr().getIA(); if (ptrAddrIA->countAddr() > 0) { ptrAddrIA->firstAddr(); addr = ptrAddrIA->getAddr()->get(); Log(Notice) << "FQDN: About to perform DNS Update: DNS server=" << *DNSAddr << ", IP=" << *addr << " and FQDN=" << fqdn << LogEnd; // remember DNS Address (used during address release) ptrAddrIA->setFQDNDnsServer(DNSAddr); TCfgMgr::DNSUpdateProtocol proto = ClntCfgMgr().getDDNSProtocol(); DNSUpdate::DnsUpdateProtocol proto2 = DNSUpdate::DNSUPDATE_TCP; if (proto == TCfgMgr::DNSUPDATE_UDP) proto2 = DNSUpdate::DNSUPDATE_UDP; if (proto == TCfgMgr::DNSUPDATE_ANY) proto2 = DNSUpdate::DNSUPDATE_ANY; unsigned int timeout = ClntCfgMgr().getDDNSTimeout(); #ifndef MOD_CLNT_DISABLE_DNSUPDATE /* add AAAA record */ DNSUpdate *act = new DNSUpdate(DNSAddr->getPlain(), "", fqdn, addr->getPlain(), DNSUPDATE_AAAA, proto2); int result = act->run(timeout); act->showResult(result); delete act; #else Log(Error) << "This version is compiled without DNS Update support." << LogEnd; return false; #endif } return true; }
bool TClntIfaceMgr::doDuties() { SPtr<TClntIfaceIface> iface; SPtr<TClntCfgIface> cfgIface; this->firstIface(); while (iface = (Ptr*)this->getIface()) { cfgIface = ClntCfgMgr().getIface(iface->getID()); if (cfgIface) { // Log(Debug) << "FQDN State: " << cfgIface->getFQDNState() << " on " << iface->getFullName() << LogEnd; if (cfgIface->getFQDNState() == STATE_INPROCESS) { // Here we check if all parameters are set, and do the DNS update if possible List(TIPv6Addr) DNSSrvLst = iface->getDNSServerLst(); string fqdn = iface->getFQDN(); if (ClntAddrMgr().countIA() > 0 && DNSSrvLst.count() > 0 && fqdn.size() > 0) { Log(Warning) << "Sleeping 3 seconds before performing DNS Update." << LogEnd; /** @todo: sleep cannot be performed here. What if client has to perform other action during those 3 seconds? */ #ifdef WIN32 Sleep(3); #else sleep(3); #endif this->fqdnAdd(iface, fqdn); } } } } ClntAddrMgr().dump(); this->dump(); return true; }
void TClntMsgInfRequest::answer(SPtr<TClntMsg> msg) { copyAAASPI(msg); TClntMsg::answer(msg); #if 0 //which option have we requested from server SPtr<TClntOptOptionRequest> ptrORO; ptrORO = (Ptr*)getOption(OPTION_ORO); SPtr<TOpt> option; msg->firstOption(); while(option = msg->getOption()) { //if option did what it was supposed to do ??? if (!option->doDuties()) { // Log(Debug) << "Setting option " << option->getOptType() << " failed." << LogEnd; continue; } if ( ptrORO && (ptrORO->isOption(option->getOptType())) ) ptrORO->delOption(option->getOptType()); SPtr<TOpt> requestOpt; this->firstOption(); while ( requestOpt = this->getOption()) { if (requestOpt->getOptType()==option->getOptType()) { delOption(requestOpt->getOptType()); break; } }//while } ptrORO->delOption(OPTION_INFORMATION_REFRESH_TIME); if (ptrORO && ptrORO->count()) { if (ClntCfgMgr().insistMode()){ Log(Notice) << "Insist-mode enabled. Not all options were assigned ("; for (int i=0; i<ptrORO->count(); i++) Log(Cont) << ptrORO->getReqOpt(i) << " "; Log(Cont) << "). Sending new INFORMATION-REQUEST." << LogEnd; ClntTransMgr().sendInfRequest(Options,Iface); } else { Log(Notice) << "Insist-mode disabled. Not all options were assigned ("; for (int i=0; i<ptrORO->count(); i++) Log(Cont) << ptrORO->getReqOpt(i) << " "; Log(Cont) << "). They will remain unconfigured." << LogEnd; IsDone = true; } } else { Log(Debug) << "All requested options were assigned." << LogEnd; IsDone=true; } return; #endif }
bool TClntIfaceMgr::fqdnDel(SPtr<TClntIfaceIface> iface, SPtr<TAddrIA> ia, string fqdn) { SPtr<TIPv6Addr> dns = ia->getFQDNDnsServer(); // let's do deleting update SPtr<TIPv6Addr> clntAddr; ia->firstAddr(); SPtr<TAddrAddr> tmpAddr = ia->getAddr(); if (!tmpAddr) { Log(Error) << "FQDN: Unable to delete FQDN: IA (IAID=" << ia->getIAID() << ") does not have any addresses." << LogEnd; return false; } SPtr<TIPv6Addr> myAddr = tmpAddr->get(); SPtr<TClntCfgIface> ptrIface = ClntCfgMgr().getIface(iface->getID()); TCfgMgr::DNSUpdateProtocol proto = ClntCfgMgr().getDDNSProtocol(); DNSUpdate::DnsUpdateProtocol proto2 = DNSUpdate::DNSUPDATE_TCP; if (proto == TCfgMgr::DNSUPDATE_UDP) proto2 = DNSUpdate::DNSUPDATE_UDP; if (proto == TCfgMgr::DNSUPDATE_ANY) proto2 = DNSUpdate::DNSUPDATE_ANY; unsigned int timeout = ClntCfgMgr().getDDNSTimeout(); Log(Debug) << "FQDN: Cleaning up DNS AAAA record in server " << *dns << ", for IP=" << *myAddr << " and FQDN=" << fqdn << LogEnd; #ifndef MOD_CLNT_DISABLE_DNSUPDATE DNSUpdate *act = new DNSUpdate(dns->getPlain(), "", fqdn, myAddr->getPlain(), DNSUPDATE_AAAA_CLEANUP, proto2); int result = act->run(timeout); act->showResult(result); delete act; #else Log(Error) << "This Dibbler version is compiled without DNS Update support." << LogEnd; #endif return false; }
TClntMsgInfRequest::TClntMsgInfRequest(SPtr<TClntCfgIface> iface) :TClntMsg(iface->getID(), 0, INFORMATION_REQUEST_MSG) { IRT = INF_TIMEOUT; MRT = INF_MAX_RT; MRC = 0; MRD = 0; RT= 0 ; Iface=iface->getID(); IsDone=false; if (!ClntCfgMgr().anonInfRequest()) { Options.push_back(new TOptDUID(OPTION_CLIENTID, ClntCfgMgr().getDUID(), this)); } else { Log(Info) << "Sending anonymous INF-REQUEST (ClientID not included)." << LogEnd; } this->appendRequestedOptions(); appendAuthenticationOption(); appendElapsedOption(); send(); }
bool TClntOptLifetime::doDuties() { string reason = "trying to set Lifetime timer."; int ifindex = this->Parent->getIface(); if (!DUID) { Log(Error) << "Unable to find proper DUID while " << reason << LogEnd; return false; } SPtr<TClntIfaceIface> iface = (Ptr*)ClntIfaceMgr().getIfaceByID(ifindex); if (!iface) { Log(Error) << "Unable to find interface ifindex=" << ifindex << reason << LogEnd; return false; } SPtr<TClntCfgIface> cfgIface = ClntCfgMgr().getIface(ifindex); return iface->setLifetime(DUID, Parent->getAddr(), Value); }
bool TClntOptNTPServers::doDuties() { string reason = "trying to set NTP server(s)."; int ifindex = this->Parent->getIface(); if (!this->DUID) { Log(Error) << "Unable to find proper DUID while " << reason << LogEnd; return false; } SPtr<TClntIfaceIface> iface = (Ptr*)ClntIfaceMgr().getIfaceByID(ifindex); if (!iface) { Log(Error) << "Unable to find interface ifindex=" << ifindex << reason << LogEnd; return false; } SPtr<TClntCfgIface> cfgIface = ClntCfgMgr().getIface(ifindex); cfgIface->setNTPServerState(STATE_CONFIGURED); return iface->setNTPServerLst(DUID, Parent->getAddr(), AddrLst); }
void TClntOptIA_PD::setState(EState state) { SPtr<TClntCfgIface> cfgIface = ClntCfgMgr().getIface(this->Iface); SPtr<TClntCfgPD> cfgPD = cfgIface->getPD(getIAID()); if (!cfgPD) { Log(Error) << "Unable to find PD with iaid=" << getIAID() << " on the " << cfgIface->getFullName() << " interface (CfgMgr)." << LogEnd; return; } cfgPD->setState(state); SPtr<TAddrIA> addrPD = ClntAddrMgr().getPD(getIAID()); if (!addrPD) { /* Log(Error) << "Unable to find PD with iaid=" << getIAID() << " on the " << cfgIface->getFullName() << " interface (AddrMgr)." << LogEnd; */ /* Don't complain about it. It is normal that IA is being deleted when there are no more prefixes in it */ return; } addrPD->setState(state); }
bool TClntOptIA_PD::modifyPrefixes(TClntIfaceMgr::PrefixModifyMode mode) { bool status = false; EState state = STATE_NOTCONFIGURED; SPtr<TClntOptIAPrefix> prefix; string action; switch(mode) { case TClntIfaceMgr::PREFIX_MODIFY_ADD: action = "addition"; state = STATE_CONFIGURED; break; case TClntIfaceMgr::PREFIX_MODIFY_UPDATE: action = "update"; state = STATE_CONFIGURED; break; case TClntIfaceMgr::PREFIX_MODIFY_DEL: action = "delete"; state = STATE_NOTCONFIGURED; break; } if ( (mode==TClntIfaceMgr::PREFIX_MODIFY_ADD) || (mode==TClntIfaceMgr::PREFIX_MODIFY_UPDATE) ) { if ( (T1==0) && (T2==0) ) { firstPrefix(); if (prefix = getPrefix()) { T1 = prefix->getPref()/2; T2 = (int)((prefix->getPref())*0.7); Log(Notice) << "Server set T1 and T2 to 0. Choosing default (50%, 70% * prefered-lifetime): T1=" << T1 << ", T2=" << T2 << LogEnd; } } } this->firstPrefix(); while (prefix = this->getPrefix() ) { switch (mode) { case TClntIfaceMgr::PREFIX_MODIFY_ADD: ClntAddrMgr().addPrefix(this->DUID, this->Prefix, this->Iface, this->IAID, this->T1, this->T2, prefix->getPrefix(), prefix->getPref(), prefix->getValid(), prefix->getPrefixLength(), false); status = ClntIfaceMgr().addPrefix(this->Iface, prefix->getPrefix(), prefix->getPrefixLength(), prefix->getPref(), prefix->getValid()); Log(Debug) << "RENEW will be sent (T1) after " << T1 << ", REBIND (T2) after " << T2 << " seconds." << LogEnd; action = "addition"; break; case TClntIfaceMgr::PREFIX_MODIFY_UPDATE: ClntAddrMgr().updatePrefix(this->DUID, this->Prefix, this->Iface, this->IAID, this->T1, this->T2, prefix->getPrefix(), prefix->getPref(), prefix->getValid(), prefix->getPrefixLength(), false); status = ClntIfaceMgr().updatePrefix(this->Iface, prefix->getPrefix(), prefix->getPrefixLength(), prefix->getPref(), prefix->getValid()); Log(Debug) << "RENEW will be sent (T1) after " << T1 << ", REBIND (T2) after " << T2 << " seconds." << LogEnd; action = "update"; break; case TClntIfaceMgr::PREFIX_MODIFY_DEL: ClntAddrMgr().delPrefix(ClntCfgMgr().getDUID(), this->IAID, prefix->getPrefix(), false); status = ClntIfaceMgr().delPrefix(this->Iface, prefix->getPrefix(), prefix->getPrefixLength() ); action = "delete"; break; } if (!status) { string tmp = error_message(); Log(Error) << "Prefix error encountered during prefix " << action << " operation: " << tmp << LogEnd; // Let's pretend it was configured and renew it // setState(STATE_FAILED); //return true; } } setState(state); return true; }
/// @brief check if received message should be accepted. /// /// The following conditions are checked: /// - is server on the black-list? /// - are all requested options present? /// - is there requested IA option? /// - is there requested TA option? /// /// @param msg server's REPLY /// /// @return true if REPLY is rejected bool TClntMsgSolicit::shallRejectAnswer(SPtr<TClntMsg> msg) { bool somethingAssigned = false; // this == solicit or request // msg == reply SPtr<TOptDUID> srvDUID = (Ptr*) msg->getOption(OPTION_SERVERID); if (!srvDUID) { Log(Notice) << "No server identifier provided. Message ignored." << LogEnd; return true; } //is this server rejected? SPtr<TClntCfgIface> iface = ClntCfgMgr().getIface(this->Iface); if (!iface) { Log(Error) << "Unable to find iface=" << this->Iface << "." << LogEnd; return true; } if (iface->isServerRejected(msg->getAddr(), srvDUID->getDUID())) { Log(Notice) << "Server was rejected (duid=" << srvDUID->getDUID() << ")." << LogEnd; return true; } // have we asked for IA? bool iaOk = true; if (this->getOption(OPTION_IA_NA)) { /// @todo Check if proper IAIDs are returned, also if all IA were answered (if requested /// several IAs were requested) /// @todo Check all IA_NAs, not just first one SPtr<TClntOptIA_NA> ia = (Ptr*)msg->getOption(OPTION_IA_NA); if (!ia) { Log(Notice) << "IA_NA option requested, but not present in this message. Ignored." << LogEnd; iaOk = false; } else { if (!ia->getOption(OPTION_IAADDR)) { Log(Notice) << "IA_NA option returned, but without any addresses. Ignored." << LogEnd; iaOk = false; } SPtr<TClntOptStatusCode> st = (Ptr*)ia->getOption(OPTION_STATUS_CODE); if (st && st->getCode()!= STATUSCODE_SUCCESS) { Log(Notice) << "IA_NA has status code!=SUCCESS: " << st->getCode() << "(" << st->getText() << "). Ignored." << LogEnd; iaOk = false; } } if (iaOk) somethingAssigned = true; } // have we asked for TA? bool taOk = true; if (this->getOption(OPTION_IA_TA)) { SPtr<TClntOptTA> ta = (Ptr*)msg->getOption(OPTION_IA_TA); if (!ta) { Log(Notice) << "TA option requested, but not present in this message. Ignored." << LogEnd; taOk = false; } else { if (!ta->getOption(OPTION_IAADDR)) { Log(Notice) << "TA option received, but without IAADDR" << LogEnd; taOk = false; } SPtr<TClntOptStatusCode> st = (Ptr*)ta->getOption(OPTION_STATUS_CODE); if (st && st->getCode()!= STATUSCODE_SUCCESS) { Log(Notice) << "IA_TA has status code!=SUCCESS: " << st->getCode() << "(" << st->getText() << "). Ignored." << LogEnd; taOk = false; } } if (taOk) somethingAssigned = true; } // have we asked for PD? bool pdOk = true; if (getOption(OPTION_IA_PD)) { SPtr<TClntOptIA_PD> pd = (Ptr*) msg->getOption(OPTION_IA_PD); if (!pd) { Log(Notice) << "PD option requested, but not returned in this message. Ignored." << LogEnd; pdOk = false; } else { if (!pd->getOption(OPTION_IAPREFIX)) { Log(Notice) << "Received PD without any prefixes." << LogEnd; pdOk = false; } /// @todo: We should check all iaprefix instances, not just one. /// We should accept the PD if there's at least one valid prefix. if (!pd->getOption(OPTION_IAPREFIX)->isValid()) { Log(Warning) << "IA_Prefix option is not valid." << LogEnd; pdOk = false; } SPtr<TClntOptStatusCode> st = (Ptr*)pd->getOption(OPTION_STATUS_CODE); if (st && st->getCode()!= STATUSCODE_SUCCESS) { Log(Notice) << "IA_NA has status code!=SUCCESS: " << st->getCode() << "(" << st->getText() << "). Ignored." << LogEnd; pdOk = false; } } if (pdOk) somethingAssigned = true; } if (!somethingAssigned) return true; // this advertise does not offers us anything if (!ClntCfgMgr().insistMode()) return false; // accept this advertise // insist-mode enabled. We MUST get everything we wanted or we reject this answer if (iaOk && taOk && pdOk) return false; else return true; }
bool TClntOptIA_NA::doDuties() { // find this IA in addrMgr... SPtr<TAddrIA> ptrIA=ClntAddrMgr().getIA(this->getIAID()); if (!ptrIA) { // unknown IAID, ignore it Log(Warning) << "Received message contains unknown IA (IAID=" << this->getIAID() << "). We didn't order it. Weird... ignoring it." << LogEnd; return true; } // IAID found, set up new received options. SPtr<TAddrAddr> ptrAddrAddr; SPtr<TOptIAAddress> ptrOptAddr; SPtr<TIfaceIface> ptrIface; ptrIface = ClntIfaceMgr().getIfaceByID(Iface_); if (!ptrIface) { Log(Error) << "Interface with ifindex=" << Iface_ << " not found." << LogEnd; return true; } // for each address in IA option... this->firstAddr(); while (ptrOptAddr = this->getAddr() ) { ptrAddrAddr = ptrIA->getAddr( ptrOptAddr->getAddr() ); // no such address in DB ?? if (!ptrAddrAddr) { if (ptrOptAddr->getValid()) { int prefixLen = ptrIface->getPrefixLength(); if (ptrOptAddr->getOption(OPTION_ADDRPARAMS)) { Log(Debug) << "Experimental addr-params found." << LogEnd; SPtr<TOptAddrParams> optAddrParams = SPtr_cast<TOptAddrParams>(ptrOptAddr->getOption(OPTION_ADDRPARAMS)); prefixLen = optAddrParams->getPrefix(); } // add this address in addrDB... ptrIA->addAddr(ptrOptAddr->getAddr(), ptrOptAddr->getPref(), ptrOptAddr->getValid(), prefixLen); ptrIA->setDUID(this->DUID); // ... and in IfaceMgr - ptrIface->addAddr(ptrOptAddr->getAddr(), ptrOptAddr->getPref(), ptrOptAddr->getValid(), prefixLen); } else { Log(Warning) << "Server send new addr with valid lifetime 0." << LogEnd; } } else { // we have this addr in DB if ( ptrOptAddr->getValid() == 0 ) { // valid=0, release this address // delete address from addrDB ptrIA->delAddr(ptrOptAddr->getAddr()); // delete address from IfaceMgr ptrIface->delAddr(ptrOptAddr->getAddr(), ptrIface->getPrefixLength()); break; // analyze next option OPTION_IA_NA } // set up new options in IfaceMgr SPtr<TIfaceIface> ptrIface = ClntIfaceMgr().getIfaceByID(Iface_); if (ptrIface) ptrIface->updateAddr(ptrOptAddr->getAddr(), ptrOptAddr->getPref(), ptrOptAddr->getValid()); // set up new options in addrDB ptrAddrAddr->setPref(ptrOptAddr->getPref()); ptrAddrAddr->setValid(ptrOptAddr->getValid()); ptrAddrAddr->setTimestamp(); } } SPtr<TClntCfgIA> ptrCfgIA; ptrCfgIA=ClntCfgMgr().getIA(ptrIA->getIAID()); if (getT1() && getT2()) { ptrIA->setT1( this->getT1() ); ptrIA->setT2( this->getT2() ); Log(Debug) << "RENEW(IA_NA) will be sent (T1) after " << ptrIA->getT1() << ", REBIND (T2) after " << ptrIA->getT2() << " seconds." << LogEnd; } else { this->firstAddr(); ptrOptAddr = this->getAddr(); if (ptrOptAddr) { ptrIA->setT1( ptrOptAddr->getPref()/2); ptrIA->setT2( (int)((ptrOptAddr->getPref())*0.7) ); Log(Notice) << "Server set T1 and T2 to 0. Choosing default (50%, " << "70% * prefered-lifetime): T1=" << ptrIA->getT1() << ", T2=" << ptrIA->getT2() << LogEnd; } } ptrIA->setTimestamp(); ptrIA->setState(STATE_CONFIGURED); ptrCfgIA->setState(STATE_CONFIGURED); return true; }
*/bool TClntOptTA::doDuties() { // find this TA in addrMgr... SPtr<TAddrIA> ta = ClntAddrMgr().getTA(this->getIAID()); if (!ta) { Log(Debug) << "Creating TA (iaid=" << this->getIAID() << ") in the addrDB." << LogEnd; ta = new TAddrIA(this->Iface, TAddrIA::TYPE_TA, 0 /*if unicast, then this->Addr*/, this->DUID, DHCPV6_INFINITY, DHCPV6_INFINITY, this->getIAID()); ClntAddrMgr().addTA(ta); } // IAID found, set up new received options. SPtr<TAddrAddr> addr; SPtr<TClntOptIAAddress> optAddr; SPtr<TIfaceIface> ptrIface; ptrIface = ClntIfaceMgr().getIfaceByID(this->Iface); if (!ptrIface) { Log(Error) << "Interface " << this->Iface << " not found." << LogEnd; return true; } // for each address in IA option... this->firstAddr(); while (optAddr = this->getAddr() ) { addr = ta->getAddr( optAddr->getAddr() ); if (!addr) { // - no such address in DB - if (!optAddr->getValid()) { Log(Warning) << "Server send new addr with valid=0." << LogEnd; continue; } // add this address in addrDB... ta->addAddr(optAddr->getAddr(), optAddr->getPref(), optAddr->getValid()); ta->setDUID(this->DUID); // ... and in IfaceMgr - ptrIface->addAddr(optAddr->getAddr(), optAddr->getPref(), optAddr->getValid(), ptrIface->getPrefixLength()); Log(Notice) << "Temp. address " << *optAddr->getAddr() << " has been added to " << ptrIface->getName() << "/" << ptrIface->getID() << " interface." << LogEnd; } else { // - we have this addr in DB - if ( optAddr->getValid() == 0 ) { // valid=0, release this address and delete address from addrDB ta->delAddr(optAddr->getAddr()); // delete address from IfaceMgr ptrIface->delAddr(optAddr->getAddr(), ptrIface->getPrefixLength()); continue; // analyze next option OPTION_IA } // set up new options in IfaceMgr ptrIface->updateAddr(optAddr->getAddr(), optAddr->getPref(), optAddr->getValid()); // set up new options in addrDB addr->setPref(optAddr->getPref()); addr->setValid(optAddr->getValid()); addr->setTimestamp(); } } // mark this TA as configured SPtr<TClntCfgTA> cfgTA; SPtr<TClntCfgIface> cfgIface; if (! (cfgIface = ClntCfgMgr().getIface(this->Iface)) ) { Log(Error) << "Unable to find TA class in the CfgMgr, on the " << this->Iface << " interface." << LogEnd; return true; } cfgIface->firstTA(); cfgTA = cfgIface->getTA(); cfgTA->setState(STATE_CONFIGURED); ta->setState(STATE_CONFIGURED); return true; }
SPtr<TClntMsg> TClntIfaceMgr::select(unsigned int timeout) { int bufsize=4096; static char buf[4096]; SPtr<TIPv6Addr> peer(new TIPv6Addr()); int sockid; int msgtype; int ifaceid; sockid = TIfaceMgr::select(timeout, buf, bufsize, peer); if (sockid>0) { if (bufsize<4) { if (buf[0]!=CONTROL_MSG) { Log(Warning) << "Received message is too short (" << bufsize << ") bytes." << LogEnd; } else { Log(Warning) << "Control message received." << LogEnd; } return 0; // NULL } msgtype = buf[0]; SPtr<TClntMsg> ptr; SPtr<TIfaceIface> ptrIface; ptrIface = this->getIfaceBySocket(sockid); ifaceid = ptrIface->getID(); Log(Debug) << "Received " << bufsize << " bytes on interface " << ptrIface->getName() << "/" << ptrIface->getID() << " (socket=" << sockid << ", addr=" << *peer << "." << ")." << LogEnd; switch (msgtype) { case ADVERTISE_MSG: ptr = new TClntMsgAdvertise(ifaceid,peer,buf,bufsize); #ifndef MOD_DISABLE_AUTH if (!ptr->validateAuthInfo(buf, bufsize, ClntCfgMgr().getAuthAcceptMethods())) { Log(Error) << "Message dropped, authentication validation failed." << LogEnd; return 0; } #endif return ptr; case SOLICIT_MSG: case REQUEST_MSG: case CONFIRM_MSG: case RENEW_MSG: case REBIND_MSG: case RELEASE_MSG: case DECLINE_MSG: case INFORMATION_REQUEST_MSG: Log(Warning) << "Illegal message type " << msgtype << " received." << LogEnd; return 0; // NULL case REPLY_MSG: ptr = new TClntMsgReply(ifaceid, peer, buf, bufsize); #ifndef MOD_DISABLE_AUTH if (!ptr->validateAuthInfo(buf, bufsize, ClntCfgMgr().getAuthAcceptMethods())) { Log(Error) << "Message dropped, authentication validation failed." << LogEnd; return 0; } #endif return ptr; case RECONFIGURE_MSG: Log(Warning) << "Reconfigure Message is currently not supported." << LogEnd; return 0; // NULL case RELAY_FORW_MSG: // those two msgs should not be visible for client case RELAY_REPL_MSG: default: Log(Warning) << "Message type " << msgtype << " is not supposed to " << "be received by client. Check your relay/server configuration." << LogEnd; return 0; } } else { return 0; } }
bool TClntIfaceMgr::modifyPrefix(int iface, SPtr<TIPv6Addr> prefix, int prefixLen, unsigned int pref, unsigned int valid, PrefixModifyMode mode) { SPtr<TClntIfaceIface> ptrIface = (Ptr*)getIfaceByID(iface); if (!ptrIface) { Log(Error) << "Unable to find interface with ifindex=" << iface << ", prefix add/modify operation failed." << LogEnd; return false; } string action; int conf = 0; // number of successfully configured prefixes int status = -1; switch (mode) { case PREFIX_MODIFY_ADD: action = "Adding"; break; case PREFIX_MODIFY_UPDATE: action = "Updating"; break; case PREFIX_MODIFY_DEL: action = "Deleting"; break; } // option: split this prefix and add it to all interfaces Log(Notice) << "PD: " << action << " prefix " << prefix->getPlain() << "/" << (int)prefixLen << " to all interfaces (prefix will be split to /" << int(prefixLen+8) << " prefixes if necessary)." << LogEnd; if (prefixLen>120) { Log(Error) << "PD: Unable to perform prefix operation: prefix /" << prefixLen << " can't be split. At least /120 prefix is required." << LogEnd; return false; } // get a list of interfaces that we will assign prefixes to TIfaceIfaceLst ifaceLst; vector<string> ifaceNames = ClntCfgMgr().getDownlinkPrefixIfaces(); for (vector<string>::const_iterator name = ifaceNames.begin(); name != ifaceNames.end(); ++name) { SPtr<TIfaceIface> x = getIfaceByName(*name); if (x) ifaceLst.push_back(x); else Log(Warning) << "Interface " << *name << " specified in downlink-prefix-ifaces is missing." << LogEnd; } if (ifaceLst.size() == 0) { SPtr<TIfaceIface> x; firstIface(); while ( x = (Ptr*)getIface() ) { if (x->getID() == ptrIface->getID()) { Log(Debug) << "PD: Interface " << x->getFullName() << " is the interface, where prefix has been obtained, skipping." << LogEnd; continue; } // for each interface present in the system... if (!x->flagUp()) { Log(Debug) << "PD: Interface " << x->getFullName() << " is down, ignoring." << LogEnd; continue; } if (!x->flagRunning()) { Log(Debug) << "PD: Interface " << x->getFullName() << " has flag RUNNING not set, ignoring." << LogEnd; continue; } if (!x->flagMulticast()) { Log(Debug) << "PD: Interface " << x->getFullName() << " is not multicast capable, ignoring." << LogEnd; continue; } if ( !(x->getMacLen() > 5) ) { Log(Debug) << "PD: Interface " << x->getFullName() << " has MAC address length " << x->getMacLen() << " (6 or more required), ignoring." << LogEnd; continue; } x->firstLLAddress(); if (!x->getLLAddress()) { Log(Debug) << "PD: Interface " << x->getFullName() << " has no link-local address, ignoring. (Disconnected? Not associated? No-link?)" << LogEnd; continue; } ifaceLst.push_back(x); } } Log(Info) << "PD: Using " << ifaceLst.size() << " suitable interface(s):"; TIfaceIfaceLst::const_iterator i; for (TIfaceIfaceLst::const_iterator i=ifaceLst.begin(); i!=ifaceLst.end(); ++i) { Log(Cont) << (*i)->getName() << " "; } Log(Cont) << LogEnd; if (ifaceLst.size() == 0) { Log(Warning) << "Suitable interfaces not found. Delegated prefix not split." << LogEnd; return true; } for (TIfaceIfaceLst::const_iterator i=ifaceLst.begin(); i!=ifaceLst.end(); ++i) { char buf[16]; int subprefixLen; memmove(buf, prefix->getAddr(), 16); if (ifaceLst.size() == 1) { // just one interface - use delegated prefix as is subprefixLen = prefixLen; } else if (ifaceLst.size()<256) { subprefixLen = prefixLen + 8; int offset = prefixLen/8; if (prefixLen%8 == 0) { // that's easy, just put ID in the next octet buf[offset] = (*i)->getID(); } else { // here's fun uint16_t existing = readUint16(buf+offset); uint16_t bitmask = 0xff00; uint16_t infixmask = ((uint8_t)(*i)->getID()) << 8; bitmask = bitmask >> (prefixLen%8); infixmask = infixmask >> (prefixLen%8); // clear out if there is anything there, i.e. server assigned prefix // with garbage in host section existing = existing & (~bitmask); existing = existing | (bitmask & infixmask); writeUint16(buf+offset, existing); } } else {
:TClntMsg(iface, addr, RELEASE_MSG) { SPtr<TDUID> srvDUID; IRT=REL_TIMEOUT; MRT=0; MRC=REL_MAX_RC; MRD=0; RT=0; // obtain IA, TA or PD, so server DUID can be obtained SPtr<TAddrIA> x = 0; if (iaLst.count()) { iaLst.first(); x=iaLst.get(); } if (!x) x = ta; if (!x) { pdLst.first(); x = pdLst.get(); } if (!x) { Log(Error) << "Unable to send RELEASE. No IA, TA or PD provided." << LogEnd; this->IsDone = true; return; } if (!x->getDUID()) { Log(Error) << "Unable to send RELEASE. Unable to find DUID. " << LogEnd; this->IsDone = true; return; } srvDUID = x->getDUID(); Options.push_back(new TOptDUID(OPTION_SERVERID, srvDUID,this)); Options.push_back(new TOptDUID(OPTION_CLIENTID, ClntCfgMgr().getDUID(),this)); #if 0 if (ClntCfgMgr().getNotifyScripts()) { // release workaround (add removed IAs) /// @todo: WTF? Why are those IAs removed? iaLst.first(); SPtr<TAddrIA> ia; while (ia = iaLst.get()) { ClntAddrMgr().addIA(ia); } iaLst.first(); while (ia = iaLst.get()) { ClntAddrMgr().delIA(ia->getIAID()); } } #endif // --- RELEASE IA --- iaLst.first(); while(x=iaLst.get()) { Options.push_back(new TClntOptIA_NA(x,this)); SPtr<TAddrAddr> ptrAddr; SPtr<TClntIfaceIface> ptrIface; ptrIface = (Ptr*)ClntIfaceMgr().getIfaceByID(x->getIface()); x->firstAddr(); while (ptrAddr = x->getAddr()) { ptrIface->delAddr(ptrAddr->get(), ptrAddr->getPrefix()); } // --- DNS Update --- SPtr<TIPv6Addr> dns = x->getFQDNDnsServer(); if (dns) { string fqdn = ptrIface->getFQDN(); ClntIfaceMgr().fqdnDel(ptrIface, x, fqdn); } // --- DNS Update --- } // --- RELEASE TA --- if (ta) Options.push_back(new TClntOptTA(ta, this)); // --- RELEASE PD --- SPtr<TAddrIA> pd = 0; pdLst.first(); while(pd=pdLst.get()) { SPtr<TClntOptIA_PD> pdOpt = new TClntOptIA_PD(pd,this); Options.push_back( (Ptr*)pdOpt ); pdOpt->setContext(srvDUID, addr, this); pdOpt->delPrefixes(); ClntAddrMgr().delPD(pd->getIAID() ); } appendElapsedOption(); appendAuthenticationOption(); IsDone = false; send(); }
bool TClntMsgReply::check() { bool anonInfReq = ClntCfgMgr().anonInfRequest(); return TClntMsg::check(!anonInfReq /* clientID mandatory */, true /* serverID mandatory */ ); }