Beispiel #1
0
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;
    }
}