/*
*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Yokogawa Electric Corporation,
* YDC Corporation, IPA (Information-technology Promotion Agency, Japan).
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms, with
* or without modification, are permitted provided that the following
* conditions and disclaimer are agreed and accepted by the user:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the names of the copyrighters, the name of the project which
* is related to this software (hereinafter referred to as "project") nor
* the names of the contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. No merchantable use may be permitted without prior written
* notification to the copyrighters. However, using this software for the
* purpose of testing or evaluating any products including merchantable
* products may be permitted without any notification to the copyrighters.
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHTERS, THE PROJECT AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING
* BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHTERS, THE PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT,STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $TAHI: v6eval/lib/Pz/McMobility.cc,v 1.21 2005/05/09 09:35:24 akisada Exp $
*
*/
#include "McMobility.h"
#include "ItPosition.h"
#include "WObject.h"
#include "RObject.h"
#include "PControl.h"
#include "PvObject.h"
#include "PvOctets.h"
#include "PcObject.h"
#include <stdio.h>
#include <string.h>
extern "C" {
#include <openssl/hmac.h>
}
////////////////////////////////////////////////////////////////
RmBAstatus::RmBAstatus(RObject *r_parent, const MObject *m, const ItPosition &offset, const ItPosition &size, PvObject *pv):
RmObject(r_parent, m, offset, size, pv) {}
RmBAstatus::~RmBAstatus() {}
void RmBAstatus::printName(uint32_t t, CSTR) const {
RObject::printName(t);
const PvObject *o = pvalue();
if(o) {
printf(" = ");
o->print();
uint32_t qtype = (uint32_t)(((PvNumber *)o)->value());
printBAstatus(qtype);
} else {
printf("NO OBJECT");
}
}
void RmBAstatus::logSelf(uint32_t t, CSTR cls) const {
RObject::logSelf(t, cls);
const PvObject *o = pvalue();
if(o) {
printf(" = ");
o->log();
uint32_t qtype = (uint32_t)(((PvNumber *)o)->value());
printBAstatus(qtype);
}
}
void RmBAstatus::printBAstatus(uint32_t status) const {
switch(status) {
case 0: printf(" (Binding Update accepted)"); break;
case 1: printf(" (Accepted but prefix discovery necessary)"); break;
case 128: printf(" (Reason unspecified)"); break;
case 129: printf(" (Administratively prohibited)"); break;
case 130: printf(" (Insufficient resources)"); break;
case 131: printf(" (Home registration not supported)"); break;
case 132: printf(" (Not home subnet)"); break;
case 133: printf(" (Not home agent for this mobile node)"); break;
case 134: printf(" (Duplicate Address Detection failed)"); break;
case 135: printf(" (Sequence number out of window)"); break;
case 136: printf(" (Expired home nonce index)"); break;
case 137: printf(" (Expired care-of nonce index)"); break;
case 138: printf(" (Expired nonces)"); break;
case 139: printf(" (Registration type change disallowed)"); break;
case 140: printf(" (Mobile Router Operation not permitted)"); break;
case 141: printf(" (Invalid Prefix)"); break;
case 142: printf(" (Not Authorized for Prefix)"); break;
case 143: printf(" (Forwarding Setup failed)"); break;
default: printf(" (Unknown)"); break;
}
return;
}
////////////////////////////////////////////////////////////////
MmBAstatus::MmBAstatus(CSTR s, uint16_t n, const PObject *g, const PObject *e, const ICVoverwriter *ow, METH_HC_ForIPinfo meth):
MmUint(s, n, g, e, ow, meth) {}
MmBAstatus::~MmBAstatus() {}
RObject *MmBAstatus::reverseRm(RControl &, RObject *r_parent, const ItPosition &at, const ItPosition &size, PvObject *pv) const {
return(new RmBAstatus(r_parent, this, at, size, pv));
}
////////////////////////////////////////////////////////////////
RmBEstatus::RmBEstatus(RObject *r_parent, const MObject *m, const ItPosition &offset, const ItPosition &size, PvObject *pv):
RmObject(r_parent, m, offset, size, pv) {}
RmBEstatus::~RmBEstatus() {}
void RmBEstatus::printName(uint32_t t, CSTR) const {
RObject::printName(t);
const PvObject *o = pvalue();
if(o) {
printf(" = ");
o->print();
uint32_t qtype = (uint32_t)(((PvNumber *)o)->value());
printBEstatus(qtype);
} else {
printf("NO OBJECT");
}
}
void RmBEstatus::logSelf(uint32_t t, CSTR cls) const {
RObject::logSelf(t, cls);
const PvObject *o = pvalue();
if(o) {
printf(" = ");
o->log();
uint32_t qtype = (uint32_t)(((PvNumber *)o)->value());
printBEstatus(qtype);
}
}
void RmBEstatus::printBEstatus(uint32_t status) const {
switch(status) {
case 1: printf(" (Unknown binding for Home Address destination option)"); break;
case 2: printf(" (Unrecognized MH Type value)"); break;
default: printf(" (Unknown)"); break;
}
return;
}
////////////////////////////////////////////////////////////////
MmBEstatus::MmBEstatus(CSTR s, uint16_t n, const PObject *g, const PObject *e, const ICVoverwriter *ow, METH_HC_ForIPinfo meth):
MmUint(s, n, g, e, ow, meth) {}
MmBEstatus::~MmBEstatus() {}
RObject *MmBEstatus::reverseRm(RControl &, RObject *r_parent, const ItPosition &at, const ItPosition &size, PvObject *pv) const {
return(new RmBEstatus(r_parent, this, at, size, pv));
}
//
// Mobility Header
//
////////////////////////////////////////////////////////////////////////////////
#define SUPER McHdr_Ext
McHdr_Ext_MH_ONE *McHdr_Ext_MH_ONE::instance_ = 0;
McHdr_Ext_MH_ONE *McHdr_Ext_MH_ONE::instance() {
if(!instance_) {
instance_ = new McHdr_Ext_MH_ONE("Ext_MH");
}
return(instance_);
}
McHdr_Ext_MH_ONE::McHdr_Ext_MH_ONE(CSTR key):SUPER(key) {
member(new MmHeader_onMH("mobility"));
// dict
MmExtent_onIP::add(this); // Packet_IPv6::exthdr=
}
McHdr_Ext_MH_ONE::~McHdr_Ext_MH_ONE() {}
// COMPOSE/REVERSE
bool McHdr_Ext_MH_ONE::containsMc(const MObject *mc) const {
bool rtn = SUPER::containsMc(mc);
return(rtn ? rtn : members_[0]->containsMc(mc));
}
RObject *McHdr_Ext_MH_ONE::reverse(RControl &c, RObject *r_parent, ItPosition &at, OCTBUF &buf) const {
return(members_[0]->reverse(c, r_parent, at, buf));
} // forward McHdr_Ext_MH
#undef SUPER
////////////////////////////////////////////////////////////////////////////////
#define SUPER McHdr_Ext
#define DEF_LENGTH_ELEM_MH 8
#define DEF_LENGTH_OFFSET_MH 8
McHdr_Ext_MH::McHdr_Ext_MH(CSTR key):SUPER(key), type_(0) {
LengthCtrl_ = new LengthCtrl();
McHdr_Ext_MH_ONE::instance(); // wake up
}
McHdr_Ext_MH::~McHdr_Ext_MH() {}
uint32_t McHdr_Ext_MH::length_for_reverse(RControl &c, ItPosition &at, OCTBUF &buf) const {
if(!length_) {
#if 0
uint32_t x = SUPER::length_for_reverse(c, at, buf);
set_LengthCtrl(x);
return(x);
#else
return(SUPER::length_for_reverse(c, at, buf));
#endif
}
uint32_t valulen = length_->value(at, buf);
uint32_t length = valulen * DEF_LENGTH_ELEM_MH + DEF_LENGTH_OFFSET_MH;
#if 0
set_LengthCtrl(length);
#endif
return(length);
}
bool McHdr_Ext_MH::HCGENE(HeaderExtLength)(WControl &cntr, WObject *wmem, OCTBUF &buf) const {
WObject *wc = wmem->parent(); // Hdr_Ext_XX
uint32_t reallen = wc->size().bytes();
uint32_t valulen = (reallen - DEF_LENGTH_OFFSET_MH) / DEF_LENGTH_ELEM_MH;
PvNumber def(valulen);
set_LengthCtrl(reallen);
return(def.generate(cntr, wmem, buf));
}
bool McHdr_Ext_MH::overwrite_DictType(RControl &c, ItPosition &at, OCTBUF &buf) const {
uint32_t limit = buf.remainLength(at.bytes());
if(!limit) {
return(false); // End of Ext Header
}
ItPosition tmpat = at;
RObject *r_self = SUPER::reverse(c, 0, tmpat, buf);
if(!r_self) {
return(false);
}
RObject *rtype = (RObject *)r_self->corresponding(type_);
if(!rtype) {
return(false); // Type field decode error
}
const PvNumber *pv = (const PvNumber *)rtype->pvalue();
uint32_t typevalue = pv->value();
c.DictType().type_Set(typevalue); // self Type set
delete rtype;
return(true);
}
bool McHdr_Ext_MH::HCGENE(Type)(WControl &cntr, WObject *wmem, OCTBUF &buf) const {
int32_t val = get_mobilityType(wmem);
if(val == -1) {
return false;
}
PvNumber def(val);
return(def.generate(cntr, wmem, buf));
}
PObject *McHdr_Ext_MH::HCEVAL(Type)(WObject *wmem) const {
int32_t val = get_mobilityType(wmem);
return(new PvNumber(val));
}
int32_t McHdr_Ext_MH::get_mobilityType(WObject *wmem) const {
WObject *wc = wmem->parent();
int32_t rtn = wc ? wc->meta()->mobilityType() : -1;
if(rtn == -1) {
wmem->mustDefine(0);
}
return(rtn);
}
RObject *McHdr_Ext_MH::reverse(RControl &c, RObject *r_parent, ItPosition &at, OCTBUF &buf) const {
RObject *r_self = SUPER::reverse(c, r_parent, at, buf);
if(!c.error()){
Con_IPinfo *info = c.IPinfo();
if(info) {
info->reverse_postBSA(c, r_self);
#if 0
{
RObject *rlength = (RObject *)r_self->corresponding(length_);
if(rlength) {
const PvNumber *pv = (const PvNumber *)rlength->pvalue();
if(pv) {
uint32_t lengthvalue = pv->value();
set_LengthCtrl(lengthvalue * DEF_LENGTH_ELEM_MH + DEF_LENGTH_OFFSET_MH);
}
}
}
#endif
info->reverse_postUppChecksum(c, r_self);
}
}
return(r_self);
}
bool McHdr_Ext_MH::generate(WControl &c, WObject *w_self, OCTBUF &buf) const {
bool rtn = SUPER::generate(c, w_self, buf);
if(!c.error()) {
Con_IPinfo *info = c.IPinfo();
if(info) {
info->generate_postBSA(c, buf, w_self);
{
WObject *wlength = (WObject *)w_self->corresponding(length_);
if(wlength) {
const PvNumber *pv = (const PvNumber *)wlength->pvalue();
if(pv) {
uint32_t lengthvalue = pv->value();
set_LengthCtrl(lengthvalue * DEF_LENGTH_ELEM_MH + DEF_LENGTH_OFFSET_MH);
}
}
}
info->generate_postUppChecksumWithLength(c, buf, w_self, get_LengthCtrl());
}
}
return(rtn);
}
#undef SUPER
////////////////////////////////////////////////////////////////////////////////
#define SUPER McHdr_Ext_MH
McHdr_Ext_MH_ANY::McHdr_Ext_MH_ANY(CSTR key):SUPER(key) {}
McHdr_Ext_MH_ANY::~McHdr_Ext_MH_ANY() {}
McHdr_Ext_MH_BRR::McHdr_Ext_MH_BRR(CSTR key):SUPER(key) {}
McHdr_Ext_MH_BRR::~McHdr_Ext_MH_BRR() {}
McHdr_Ext_MH_HoTI::McHdr_Ext_MH_HoTI(CSTR key):SUPER(key) {}
McHdr_Ext_MH_HoTI::~McHdr_Ext_MH_HoTI() {}
McHdr_Ext_MH_CoTI::McHdr_Ext_MH_CoTI(CSTR key):SUPER(key) {}
McHdr_Ext_MH_CoTI::~McHdr_Ext_MH_CoTI() {}
McHdr_Ext_MH_HoT::McHdr_Ext_MH_HoT(CSTR key):SUPER(key) {}
McHdr_Ext_MH_HoT::~McHdr_Ext_MH_HoT() {}
McHdr_Ext_MH_CoT::McHdr_Ext_MH_CoT(CSTR key):SUPER(key) {}
McHdr_Ext_MH_CoT::~McHdr_Ext_MH_CoT() {}
McHdr_Ext_MH_BU::McHdr_Ext_MH_BU(CSTR key):SUPER(key) {}
McHdr_Ext_MH_BU::~McHdr_Ext_MH_BU() {}
McHdr_Ext_MH_BA::McHdr_Ext_MH_BA(CSTR key):SUPER(key) {}
McHdr_Ext_MH_BA::~McHdr_Ext_MH_BA() {}
McHdr_Ext_MH_BE::McHdr_Ext_MH_BE(CSTR key):SUPER(key) {}
McHdr_Ext_MH_BE::~McHdr_Ext_MH_BE() {}
#undef SUPER
///////////////////////////////////////////////////////////////////////////////
MmHeader_onMH::MmHeader_onMH(CSTR key):MmReference_Must1(key) {}
MmHeader_onMH::~MmHeader_onMH() {}
void MmHeader_onMH::add(McHdr_Ext_MH *mc) {
dict_.add(mc->mobilityType(), mc);
}
void MmHeader_onMH::add_other(McHdr_Ext_MH *mc) {
dict_.add_other(mc);
}
TypevsMcDict MmHeader_onMH::dict_;
// REVERSE
bool MmHeader_onMH::overwrite_DictType(RControl &c, ItPosition &at, OCTBUF &buf) const {
McHdr_Ext_MH *any = (McHdr_Ext_MH *)dict_.find_other();
return(any->overwrite_DictType(c, at, buf));
}
//
// Mobility Options
//
////////////////////////////////////////////////////////////////////////////////
#define DEF_ALIGNMENT_OptMH 8
#define DEF_LENGTH_ELEM_OptMH 2
McOpt_MH::McOpt_MH(CSTR key):McOption(key), type_(0), length_(0) {}
McOpt_MH::~McOpt_MH() {}
// COMPOSE/REVERSE
uint32_t McOpt_MH::length_for_reverse(RControl &c, ItPosition &at, OCTBUF &buf) const {
if(!length_) {
return(McOption::length_for_reverse(c, at, buf));
}
uint32_t valulen = length_->value(at, buf);
uint32_t length = valulen + DEF_LENGTH_ELEM_OptMH;
return(length);
}
bool McOpt_MH::overwrite_DictType(RControl &c, ItPosition &at, OCTBUF &buf) const {
uint32_t limit = buf.remainLength(at.bytes());
if(limit == 0) {
return false; // End of Mobility Header
}
//
ItPosition tmpat = at;
RObject *rtype = type_->reverse(c, 0, tmpat, buf);
if(!rtype) {
return false; // Type field decode error
}
//
const PvNumber *pv = (const PvNumber*)rtype->pvalue();
uint32_t typevalue = pv->value();
c.DictType().type_Set(typevalue); // self Type set
delete rtype;
return true;
}
bool McOpt_MH::HCGENE(Length)(WControl &cntr, WObject *wmem, OCTBUF &buf) const {
WObject *wc = wmem->parent();
uint32_t reallen = wc->size().bytes();
uint32_t valulen = reallen - DEF_LENGTH_ELEM_OptMH;
PvNumber def(valulen);
return(def.generate(cntr, wmem, buf));
}
bool McOpt_MH::HCGENE(Type)(WControl &cntr, WObject *wmem, OCTBUF &buf) const {
int32_t val = get_mobilityOptionType(wmem);
if(val < 0) {
return(false);
}
PvNumber def(val);
return(def.generate(cntr, wmem, buf));
}
PObject *McOpt_MH::HCEVAL(Type)(WObject *wmem) const {
int32_t val = get_mobilityOptionType(wmem);
return(new PvNumber(val));
}
int32_t McOpt_MH::get_mobilityOptionType(WObject *wmem) const {
WObject *wc = wmem->parent();
int32_t rtn = wc ? wc->meta()->optionType() : -1;
if(rtn < 0) {
wmem->mustDefine(0);
}
return(rtn);
}
////////////////////////////////////////////////////////////////////////////////
McOpt_MH_ANY::McOpt_MH_ANY(CSTR key):McOpt_MH(key) {}
McOpt_MH_ANY::~McOpt_MH_ANY() {}
McOpt_MH_Pad1::McOpt_MH_Pad1(CSTR key):McOpt_MH(key) {}
McOpt_MH_Pad1::~McOpt_MH_Pad1() {}
McOpt_MH_PadN::McOpt_MH_PadN(CSTR key):McOpt_MH(key) {}
McOpt_MH_PadN::~McOpt_MH_PadN() {}
McOpt_MH_AlternateCoA::McOpt_MH_AlternateCoA(CSTR key):McOpt_MH(key) {}
McOpt_MH_AlternateCoA::~McOpt_MH_AlternateCoA() {}
McOpt_MH_NonceIndices::McOpt_MH_NonceIndices(CSTR key):McOpt_MH(key) {}
McOpt_MH_NonceIndices::~McOpt_MH_NonceIndices() {}
McOpt_MH_BindingAuthData::McOpt_MH_BindingAuthData(CSTR key):McOpt_MH(key) {}
McOpt_MH_BindingAuthData::~McOpt_MH_BindingAuthData() {}
PObject *McOpt_MH_BindingAuthData::tokenObject(int l, CSTR f) const {
return(new PaBSA(this, f, l));
}
McOpt_MH_BindingRefreshAdvice::McOpt_MH_BindingRefreshAdvice(CSTR key):McOpt_MH(key) {}
McOpt_MH_BindingRefreshAdvice::~McOpt_MH_BindingRefreshAdvice() {}
McOpt_MH_MobNetworkPrefix::McOpt_MH_MobNetworkPrefix(CSTR key):McOpt_MH(key) {}
McOpt_MH_MobNetworkPrefix::~McOpt_MH_MobNetworkPrefix() {}
////////////////////////////////////////////////////////////////////////////////
MmOption_onMH::MmOption_onMH(CSTR key):MmReference_More0(key, true) {}
MmOption_onMH::~MmOption_onMH() {}
void MmOption_onMH::add(McOpt_MH *mc) {
dict_.add(mc->optionType(), mc);
}
void MmOption_onMH::add_other(McOpt_MH *mc) {
dict_.add_other(mc);
}
TypevsMcDict MmOption_onMH::dict_;
// REVERSE
bool MmOption_onMH::overwrite_DictType(RControl &c, ItPosition &at, OCTBUF &buf) const {
McOpt_MH *any = (McOpt_MH *)dict_.find_other();
return(any->overwrite_DictType(c, at, buf));
}
////////////////////////////////////////////////////////////////////////////////
#define COOKIEZERO() PvCookie64::zerocookie()
MmMH_Cookie64::MmMH_Cookie64(CSTR s):MmOctets(s, 8, COOKIEZERO(), COOKIEZERO(), 0, 0) {}
MmMH_Cookie64::~MmMH_Cookie64() {}
// REVERSE
PvObject *MmMH_Cookie64::reversePv(RControl &, const ItPosition &at, const ItPosition &size, const OCTBUF &buf) const {
OCTSTR str = (OCTSTR)buf.string(at.bytes());
return(new PvCookie64(str, false));
}
#undef COOKIEZERO
////////////////////////////////////////////////////////////////////////////////
#define SUPER RmObject
RmBSA::RmBSA(RObject *r_parent, const MObject *m, const ItPosition &offset, const ItPosition &size, PvObject *pv, const PaBSA *bsa):
SUPER(r_parent, m, offset, size, pv), bsa_(bsa), calc_pvalue_(new OCTBUF()) {}
RmBSA::~RmBSA(){
if(calc_pvalue_) {
delete calc_pvalue_;
calc_pvalue_ = 0;
}
}
void RmBSA::set_calc_pvalue(PvObject *calc) {
if(calc_pvalue_) {
delete calc_pvalue_;
}
calc_pvalue_ = calc;
}
void RmBSA::post_reverse(Con_IPinfo &info, RControl &c, RObject *base) {
if(!parent()) {
return;
}
if(!parent()->parent()) {
return;
}
const OCTBUF *basebuf = (const OCTBUF *)base->pvalue();
uint32_t mhlen = base->size().bytes(); // Mobility Header
uint32_t mhoffset0 = base->offset().bytes();
OCTSTR mhbuf = (OCTSTR)basebuf->string();
uint32_t authlen = size().bytes(); // Authenticator
uint32_t authoffset = parent()->offset().bytes() + offset().bytes();
uint32_t mhoffset = parent()->parent()->offset().bytes();
if(mhoffset0 != mhoffset) {
return;
}
uint32_t restlen = mhlen - (authoffset + authlen);
OCTBUF bsabuf(mhlen - authlen, (OCTSTR)mhbuf, true);
#define CHECKSUM_OFFSET 4
#define CHECKSUM_LEN 2
memset((void *)(bsabuf.string() + CHECKSUM_OFFSET), 0, CHECKSUM_LEN);
#undef CHECKSUM_LEN
#undef CHECKSUM_OFFSET
if(restlen) {
memcpy((void *)(bsabuf.string() + authoffset), (void *)(mhbuf + authoffset + authlen), restlen);
}
OCTBUF *calc = 0;
if(bsa_) {
calc = bsa_->BSA_Calculate(bsabuf);
}
set_calc_pvalue(calc);
return;
}
#undef SUPER
////////////////////////////////////////////////////////////////////////////////
#define SUPER WmObject
WmBSA::WmBSA(WObject *p, const MObject *m, const PObject *po, const PaBSA *bsa):SUPER(p, m, po), bsa_(bsa) {}
WmBSA::~WmBSA(){}
void WmBSA::post_generate(Con_IPinfo &info, WControl &c, OCTBUF &buf, WObject *base) {
WObject *w_auth = (WObject *)info.postBSA();
if(!w_auth) {
return;
}
const OCTBUF *basebuf = (const OCTBUF *)base->pvalue();
uint32_t mhlen = base->size().bytes(); // Mobility Header
uint32_t mhoffset = base->offset().bytes();
OCTSTR mhbuf = (OCTSTR)basebuf->string();
uint32_t authlen = w_auth->size().bytes(); // Authenticator
uint32_t authoffset = w_auth->offset().bytes();
if(mhoffset > authoffset) {
return;
}
if(mhoffset + mhlen < authoffset + authlen) {
return;
}
uint32_t restlen = mhlen - ((authoffset - mhoffset) + authlen);
OCTBUF bsabuf(mhlen - authlen, (OCTSTR)mhbuf, true);
#define CHECKSUM_OFFSET 4
#define CHECKSUM_LEN 2
memset((void *)(bsabuf.string() + CHECKSUM_OFFSET), 0, CHECKSUM_LEN);
#undef CHECKSUM_LEN
#undef CHECKSUM_OFFSET
if(restlen) {
memcpy((void *)(bsabuf.string() + authoffset - mhoffset), (void *)(mhbuf + authoffset - mhoffset + authlen), restlen);
}
OCTBUF *calc = 0;
if(bsa_) {
calc = bsa_->BSA_Calculate(bsabuf);
}
if(calc) {
set_rgenerate(calc);
SUPER::generate(c, buf);
}
return;
}
bool WmBSA::doEvaluate(WControl &c, RObject &r) {
//typecheck be finished by metaEvaluate()
RmBSA &rm = (RmBSA &)r;
const PvObject *ro = rm.pvalue();
const PvObject *eo = rm.calc_pvalue();
if(!eo) {
eo = revaluate();
}
return(valueEvaluate(c, ro, eo));
}
#undef SUPER
////////////////////////////////////////////////////////////////////////////////
KeepBSA::KeepBSA() {
// bsa_ = 0;
current_ = 0;
bsa_ = new BSAList();
}
KeepBSA::~KeepBSA() {
current_ = 0;
if(bsa_) {
delete bsa_;
bsa_ = 0;
}
}
const PaBSA *KeepBSA::GetBSA(void) {
uint32_t i = current_ ++;
const PaBSA *bsa = 0;
if(bsa_) {
uint32_t i9 = bsa_->size();
bsa = i < i9 ? bsa_->index(i) : 0;
}
return(bsa);
}
void KeepBSA::SetBSA(const PaBSA *bsa) {
// bsa_ = bsa;
bsa_->append((PaBSA *)bsa);
}
////////////////////////////////////////////////////////////////////////////////
#define AUTHENTICATOR_LEN 12
#define BSAZERO() PvBSA96::zerobsa()
MmMH_Auth::MmMH_Auth(CSTR s):MmOctets(s, AUTHENTICATOR_LEN, BSAZERO(), BSAZERO(), 0, 0) {
keepbsa_ = new KeepBSA();
}
MmMH_Auth::~MmMH_Auth() {
if(keepbsa_) {
delete keepbsa_;
keepbsa_ = 0;
}
}
// REVERSE
PvObject *MmMH_Auth::reversePv(RControl &, const ItPosition &at, const ItPosition &, const OCTBUF &buf) const {
OCTSTR str = (OCTSTR)buf.string(at.bytes());
return(new PvBSA96(str, false));
}
RObject *MmMH_Auth::reverseRm(RControl &c, RObject *r_parent, const ItPosition &at, const ItPosition &size, PvObject *pv) const {
const PaBSA *bsa = 0;
if(keepbsa_) {
bsa = keepbsa_->GetBSA();
}
RmBSA *r_self = new RmBSA(r_parent, this, at, size, pv, bsa);
return(r_self);
}
WObject *MmMH_Auth::composeWm(WControl &c, WObject *w_parent, const PObject *pl) const {
const PaBSA *bsa = c.pushing_BSA();
if(keepbsa_) {
keepbsa_->SetBSA(bsa);
}
return(new WmBSA(w_parent, this, pl, bsa));
}
RObject *MmMH_Auth::reverse(RControl &c, RObject *r_parent, ItPosition &at, OCTBUF &buf) const {
RObject *r_self = MmOctets::reverse(c, r_parent, at, buf);
if(!c.error()){
Con_IPinfo *info = c.IPinfo();
if(info) {
info->postBSA(r_self);
}
} // post reverse calcBSA
return(r_self);
}
bool MmMH_Auth::generate(WControl &c, WObject *w_self, OCTBUF &buf) const {
bool rtn = MmOctets::generate(c, w_self, buf);
if(!c.error()) {
Con_IPinfo *info = c.IPinfo();
if(info) {
info->postBSA(w_self);
} // post generate calcBSA
}
return(rtn);
}
#undef BSAZERO
#undef AUTHENTICATOR_LEN
////////////////////////////////////////////////////////////////////////////////
PfBSA::PfBSA(const MfBSA *a, CSTR b, int c):PvFunction(a, b, c), meta_(a), context_(0) {}
PfBSA::~PfBSA() {};
const MObject *PfBSA::meta() const {
return(metaClass());
}
void PfBSA::init() {
const MfBSA *m = metaClass();
if(m) {
context_ = m->init(context_, args());
}
return;
}
void PfBSA::update(const OCTBUF &s) {
const MfBSA *m = metaClass();
if(m) {
m->update(context_, args(), s);
}
return;
}
PvOctets *PfBSA::result() {
const MfBSA *m = metaClass();
PvOctets *ret = 0;
if(m) {
ret = m->result(context_, args());
}
return(ret);
}
////////////////////////////////////////////////////////////////////////////////
PaBSA::PaBSA(const MObject *m, CSTR st, int l):PcObject(m ,st, l), bsa_(0) {}
PaBSA::~PaBSA() {
if(bsa_ != 0) {
delete bsa_;
bsa_ = 0;
}
}
PObject *PaBSA::bsa_member(PObject *p) {
return(bsa_ = (PfBSA *)(p));
}
OCTBUF *PaBSA::BSA_Calculate(const OCTBUF &s) const {
if(!bsa_) {
return(0);
}
bsa_->init();
bsa_->update(s);
PvOctets *icv = bsa_->result();
return(icv);
}
// COMPOSE
WObject *PaBSA::selfCompose(WControl &c, WObject *w_parent) const {
const MObject *m = meta();
c.set_push_BSA(this);
return(m != 0 ? m->compose(c, w_parent, this) : 0);
}
implementCmList(BSAList, PaBSA);
syntax highlighted by Code2HTML, v. 0.9.1