void TRelMsg::decodeOpts(char * buf, int bufSize) { int pos=0; SPtr<TOpt> ptr; while (pos<bufSize) { if (pos+4>bufSize) { Log(Error) << "Message " << MsgType << " truncated. There are " << (bufSize-pos) << " bytes left to parse. Bytes ignored." << LogEnd; break; } unsigned short code = readUint16(buf+pos); pos += sizeof(uint16_t); unsigned short length = readUint16(buf+pos); pos += sizeof(uint16_t); if (pos+length>bufSize) { Log(Error) << "Invalid option (type=" << code << ", len=" << length << " received (msgtype=" << MsgType << "). Message dropped." << LogEnd; IsDone = true; return; } if (!allowOptInMsg(this->MsgType,code)) { Log(Warning) << "Option " << code << " not allowed in message type="<< MsgType <<". Ignoring." << LogEnd; pos+=length; continue; } if (!allowOptInOpt(this->MsgType,0,code)) { Log(Warning) <<"Option " << code << " can't be present in message (type=" << MsgType <<") directly. Ignoring." << LogEnd; pos+=length; continue; } ptr = 0; switch (code) { case OPTION_RELAY_MSG: ptr = new TRelOptRelayMsg(buf+pos,length,this); break; case OPTION_INTERFACE_ID: ptr = new TRelOptInterfaceID(buf+pos,length,this); break; case OPTION_CLIENTID: ptr = new TOptDUID(code, buf+pos, length, this); break; default: ptr = new TRelOptGeneric(code, buf+pos, length, this); break; } if ( (ptr) && (ptr->isValid()) ) Options.push_back( ptr ); else Log(Warning) << "Option " << code << " is invalid. Option ignored." << LogEnd; pos+=length; } }
TClntOptIAPrefix::TClntOptIAPrefix( char * buf, int bufSize, TMsg* parent) :TOptIAPrefix(buf, bufSize, parent) { SPtr<TOpt> opt = 0; int pos=0; int MsgType = 0; if (parent) MsgType = parent->getType(); while(pos<bufSize) { if (pos+4>bufSize) { Log(Error) << "Message " << MsgType << " truncated. There are " << (bufSize-pos) << " bytes left to parse. Bytes ignored." << LogEnd; break; } unsigned short code = readUint16(buf+pos); pos += sizeof(uint16_t); unsigned short length = readUint16(buf+pos); pos+= sizeof(uint16_t); if (pos+length>bufSize) { Log(Error) << "Invalid option (type=" << code << ", len=" << length << " received (msgtype=" << MsgType << "). Message dropped." << LogEnd; return; } if (allowOptInOpt(parent->getType(),OPTION_IAPREFIX,code)) { switch (code) { case OPTION_STATUS_CODE: opt = new TClntOptStatusCode(buf+pos,length, this->Parent); break; default: Log(Warning) <<"Option opttype=" << code<< "not supported " <<" in field of message (type="<< parent->getType() <<") in this version of client."<<LogEnd; break; } if((opt)&&(opt->isValid())) SubOptions.append(opt); } pos += length; } }
/** * Used to create object from received message * * @param buf * @param bufsize * @param parent */ TClntOptIA_PD::TClntOptIA_PD(char * buf,int bufsize, TMsg* parent) :TOptIA_PD(buf,bufsize, parent) { int pos=0; while(pos<bufsize) { int code=buf[pos]*256+buf[pos+1]; pos+=2; int length=buf[pos]*256+buf[pos+1]; pos+=2; if ((code>0)&&(code<=26)) { if(allowOptInOpt(parent->getType(),OPTION_IA_PD,code)) { SPtr<TOpt> opt= SPtr<TOpt>(); switch (code) { case OPTION_IAPREFIX: SubOptions.append( new TClntOptIAPrefix(buf+pos,length,this->Parent)); break; case OPTION_STATUS_CODE: SubOptions.append( new TClntOptStatusCode(buf+pos,length,this->Parent)); break; default: Log(Warning) << "Option opttype=" << code<< "not supported " << " in field of message (type="<< parent->getType() << ") in this version of server."<<LogEnd; break; } if((opt)&&(opt->isValid())) SubOptions.append(opt); } else Log(Warning) << "Illegal option received, opttype=" << code << " in field options of IA_PD option" << LogEnd; } else { Log(Warning) << "Unknown option in option IA_NA(optType=" << code << "). Option ignored." << LogEnd; }; pos+=length; } clearContext(); }
TSrvOptIAAddress::TSrvOptIAAddress( char * buf, int bufsize, TMsg* parent) :TOptIAAddress(buf,bufsize, parent) { int pos=0; while(pos<bufsize) { uint16_t code = readUint16(buf+pos); pos += sizeof(uint16_t); uint16_t length = readUint16(buf+pos); pos += sizeof(uint16_t); if ((code>0)&&(code<=24)) { if(allowOptInOpt(parent->getType(),OPTION_IAADDR,code)) { SPtr<TOpt> opt; opt.reset(); switch (code) { case OPTION_STATUS_CODE: opt.reset(new TOptStatusCode(buf+pos, length, Parent)); break; default: Log(Warning) << "Option " << code << " not supported " <<" in message (type="<< parent->getType() <<")." << LogEnd; break; } if (opt && opt->isValid()) SubOptions.append(opt); } else { Log(Warning) << "Illegal option received, opttype=" << code << " in field options of IA_NA option" << LogEnd; } } else { Log(Warning) <<"Unknown option in option IAADDR( optType=" << code << "). Option ignored." << LogEnd; }; pos += length; } }