diff --git a/tools/src/librw11/RethBuf.cpp b/tools/src/librw11/RethBuf.cpp index 41519d4c..55147b5e 100644 --- a/tools/src/librw11/RethBuf.cpp +++ b/tools/src/librw11/RethBuf.cpp @@ -1,9 +1,10 @@ -// $Id: RethBuf.cpp 1378 2023-02-23 10:45:17Z mueller $ +// $Id: RethBuf.cpp 1379 2023-02-24 09:17:23Z mueller $ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright 2017-2023 by Walter F.J. Mueller // // Revision History: // Date Rev Version Comment +// 2023-02-24 1379 1.1.1 add copy constructor // 2023-02-22 1378 1.1 improved Info/Dump methods // 2017-04-16 880 1.0 Initial version // 2017-02-12 850 0.1 First draft @@ -19,6 +20,7 @@ #include #include +#include #include "librtools/RosFill.hpp" #include "librtools/RosPrintf.hpp" @@ -82,6 +84,15 @@ RethBuf::RethBuf() fSize(0) {} +//------------------------------------------+----------------------------------- +//! Copy constructor +RethBuf::RethBuf(const RethBuf& src) + : fTime(src.fTime), + fSize(src.fSize) +{ + memcpy(fBuf, src.fBuf, src.fSize); +} + //------------------------------------------+----------------------------------- //! Destructor RethBuf::~RethBuf() @@ -183,9 +194,11 @@ std::string RethBuf::HeaderInfo1() const auto prot = GetB(kElength+kIpOffProt); auto tlen = GetS(kElength+kIpOffLen); auto flags = GetB(kElength+kIpOffFlags); + auto ipsrc = RethTools::IpAddr2String(Buf8()+kElength+kIpOffSrcIP); + auto ipdst = RethTools::IpAddr2String(Buf8()+kElength+kIpOffDstIP); sos << "IPv4: prot " << RosPrintf(prot,"d",3) - << ": " << RethTools::IpAddr2String(Buf8()+kElength+kIpOffSrcIP) - << " > " << RethTools::IpAddr2String(Buf8()+kElength+kIpOffDstIP) + << ": " << RosPrintf(ipsrc.c_str(),"-s", 15) + << " > " << RosPrintf(ipdst.c_str(),"-s", 15) << " siz: " << RosPrintf(tlen,"d", 4); if (flags & 0x04) sos << " DF"; if (flags & 0x08) sos << " MF"; diff --git a/tools/src/librw11/RethBuf.hpp b/tools/src/librw11/RethBuf.hpp index dd90800d..f4edb449 100644 --- a/tools/src/librw11/RethBuf.hpp +++ b/tools/src/librw11/RethBuf.hpp @@ -1,9 +1,10 @@ -// $Id: RethBuf.hpp 1378 2023-02-23 10:45:17Z mueller $ +// $Id: RethBuf.hpp 1379 2023-02-24 09:17:23Z mueller $ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright 2017-2023 by Walter F.J. Mueller // // Revision History: // Date Rev Version Comment +// 2023-02-24 1379 1.1.1 add copy constructor // 2023-02-22 1378 1.1 improved Info/Dump methods // 2018-12-22 1091 1.0.1 Dump() not longer virtual (-Wnon-virtual-dtor fix) // 2017-04-17 880 1.0 Initial version @@ -30,6 +31,7 @@ namespace Retro { typedef std::shared_ptr pbuf_t; RethBuf(); + RethBuf(const RethBuf& src); ~RethBuf(); void Clear(); diff --git a/tools/src/librw11/Rw11CntlDEUNA.cpp b/tools/src/librw11/Rw11CntlDEUNA.cpp index 0c01c0c1..5f9fbec4 100644 --- a/tools/src/librw11/Rw11CntlDEUNA.cpp +++ b/tools/src/librw11/Rw11CntlDEUNA.cpp @@ -1,9 +1,10 @@ -// $Id: Rw11CntlDEUNA.cpp 1378 2023-02-23 10:45:17Z mueller $ +// $Id: Rw11CntlDEUNA.cpp 1379 2023-02-24 09:17:23Z mueller $ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright 2014-2023 by Walter F.J. Mueller // // Revision History: // Date Rev Version Comment +// 2023-02-24 1379 0.6.2 add simulated tx and rx packet loss mechanism // 2023-02-22 1378 0.6.1 use RethBuf::HeaderInfoAll // 2023-02-21 1377 0.6 add EtherType filter // 2023-02-20 1376 0.5.11 log transitions into and out of kStateRxPoll @@ -226,6 +227,8 @@ Rw11CntlDEUNA::Rw11CntlDEUNA() fMcastCnt(0), fEtfEnable(false), fEtfTrace(false), + fTxLoss(0.0), + fRxLoss(0.0), fPr0Last(0), fPr1Pcto(false), fPr1Delua(false), @@ -248,7 +251,7 @@ Rw11CntlDEUNA::Rw11CntlDEUNA() fRxDscCur{}, fRxDscNxt{}, fRxPollTime(0.01), - fRxQueLimit(1000), + fRxQueLimit(64), fRxPollTimer("Rw11CntlDEUNA::fRxPollTimer."), fRxBufQueue(), fRxBufCurr(), @@ -265,7 +268,9 @@ Rw11CntlDEUNA::Rw11CntlDEUNA() fCtrTxByt(0), fCtrTxBytMcast(0), fCtrTxFraAbort(0), - fCtrFraLoop(0) + fCtrFraLoop(0), + fRanEngine(), + fRanGen(0.0,1.0) { // must be here because Units have a back-ptr (not available at Rw11CntlBase) fspUnit[0].reset(new Rw11UnitDEUNA(this, 0)); // single unit controller @@ -314,6 +319,7 @@ Rw11CntlDEUNA::Rw11CntlDEUNA() fStats.Define(kStatNRxFraQLDrop, "NRxFraQLDrop", "in frames drop queue lim"); fStats.Define(kStatNRxFraNRDrop, "NRxFraNRDrop", "in frames drop not running"); fStats.Define(kStatNRxFraETDrop, "NRxFraETDrop", "in frames drop etf miss"); + fStats.Define(kStatNRxFraLoss, "NRxFraLoss", "in frames loss"); fStats.Define(kStatNRxFra , "NRxFra" , "rcvd frames"); fStats.Define(kStatNRxFraMcast , "NRxFraMcast" , "rcvd bcast+mcast frames"); fStats.Define(kStatNRxFraBcast , "NRxFraBcast" , "rcvd bcast frames"); @@ -329,6 +335,7 @@ Rw11CntlDEUNA::Rw11CntlDEUNA() fStats.Define(kStatNTxBytMcast , "NTxBytMcast" , "xmit mcast bytes"); fStats.Define(kStatNTxFraAbort , "NTxFraAbort" , "xmit aborted frames"); fStats.Define(kStatNTxFraPad , "NTxFraPad" , "xmit padded frames"); + fStats.Define(kStatNTxFraLoss, "NTxFraLoss", "xmit frames loss"); fStats.Define(kStatNFraLoop , "NFraLoop" , "loopback frames"); } @@ -489,6 +496,30 @@ void Rw11CntlDEUNA::SetRxQueLimit(size_t rxqlim) return; } +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rw11CntlDEUNA::SetTxLoss(float txloss) +{ + if (txloss < 0.0 || txloss > 0.9) + throw Rexception("Rw11CntlDEUNA::SetTxLoss", + string("Bad args: not in [0.0,0.9]")); + fTxLoss = txloss; + return; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rw11CntlDEUNA::SetRxLoss(float rxloss) +{ + if (rxloss < 0.0 || rxloss > 0.9) + throw Rexception("Rw11CntlDEUNA::SetRxLoss", + string("Bad args: not in [0.0,0.9]")); + fRxLoss = rxloss; + return; +} + //--------------------------------------+----------------------------------- //! FIXME_docs @@ -570,6 +601,19 @@ bool Rw11CntlDEUNA::RcvCallback(RethBuf::pbuf_t& pbuf) } } + if (fRxLoss > 0.0) { // rx loss enabled ? + float ran = fRanGen(fRanEngine); + if (ran < fRxLoss) { // simulated rx loss + fStats.Inc(kStatNRxFraLoss); + if (fTraceLevel>1) { + RlogMsg lmsg(LogFile()); + lmsg << "-I " << Name() << ": rlo " + << pbuf->HeaderInfoAll(fTraceLevel>2, 12) << endl; + } + return true; + } + } + uint64_t macdst = pbuf->MacDestination(); int matchdst = MacFilter(macdst); @@ -669,6 +713,8 @@ void Rw11CntlDEUNA::Dump(std::ostream& os, int ind, const char* text, } os << bl << " fEtfEnable: " << RosPrintf(fEtfEnable) << endl; os << bl << " fEtfTrace: " << RosPrintf(fEtfTrace) << endl; + os << bl << " fTxLoss: " << RosPrintf(fTxLoss,"f",5,3) << endl; + os << bl << " fRxLoss: " << RosPrintf(fRxLoss,"f",5,3) << endl; os << bl << " fPr0Last*: " << RosPrintf(fPr0Last,"o0", 6) << endl; os << bl << " fPr1*: " @@ -1211,13 +1257,19 @@ bool Rw11CntlDEUNA::ExecGetcmd(RlinkCommandList& clist) uint16_t txelen, rxelen; uint16_t txsize, rxsize; Wlist2UBAddrLen(&udb[0], txbase, txelen); - if (txbase & ~kUBA_M) return false; txsize = udb[2]; - if (txsize <= 1) return false; Wlist2UBAddrLen(&udb[3], rxbase, rxelen); - if (rxbase & ~kUBA_M) return false; rxsize = udb[5]; - if (rxsize <= 1) return false; + if (txbase & ~kUBA_M || txsize <= 1 || + rxbase & ~kUBA_M || rxsize <= 1) { + RlogMsg lmsg(LogFile()); + lmsg << "-E " << Name() << ": bad WRF" + << " txbase=" << RosPrintf(txbase,"o", 8) + << " txsize=" << RosPrintf(txsize,"d", 2) + << " rxbase=" << RosPrintf(rxbase,"o", 8) + << " rxsize=" << RosPrintf(rxsize,"d", 2); + return false; + } fRingValid = true; fTxRingBase = txbase; fTxRingELen = txelen; @@ -1617,10 +1669,19 @@ int Rw11CntlDEUNA::TxRingHandler() LogFrameInfo('t', fTxBuf); // log transmitted frame if (unit.HasVirt()) { // attached ? - RerrMsg emsg; - unit.Virt().Snd(fTxBuf, emsg); - // FIXME_code: error handling - } + if (fTxLoss > 0.0 && fRanGen(fRanEngine) < fTxLoss) { // tx loss enabled ? + fStats.Inc(kStatNTxFraLoss); + if (fTraceLevel>1) { + RlogMsg lmsg(LogFile()); + lmsg << "-I " << Name() << ": tlo " + << fTxBuf.HeaderInfoAll(fTraceLevel>2, 12) << endl; + } + } else { + RerrMsg emsg; + unit.Virt().Snd(fTxBuf, emsg); + // FIXME_code: error handling + } + } LogRingInfo('t','>'); // log final ring dsc state Server().Exec(clist); diff --git a/tools/src/librw11/Rw11CntlDEUNA.hpp b/tools/src/librw11/Rw11CntlDEUNA.hpp index d8defc9c..6c71cc76 100644 --- a/tools/src/librw11/Rw11CntlDEUNA.hpp +++ b/tools/src/librw11/Rw11CntlDEUNA.hpp @@ -1,9 +1,10 @@ -// $Id: Rw11CntlDEUNA.hpp 1377 2023-02-21 10:05:30Z mueller $ +// $Id: Rw11CntlDEUNA.hpp 1379 2023-02-24 09:17:23Z mueller $ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright 2014-2023 by Walter F.J. Mueller // // Revision History: // Date Rev Version Comment +// 2023-02-24 1379 0.6.1 add simulated tx and rx packet loss mechanism // 2023-02-21 1377 0.6 add EtherType filter // 2017-04-14 875 0.5 Initial version (minimal functions, 211bsd ready) // 2014-06-09 561 0.1 First draft @@ -18,6 +19,7 @@ #define included_Retro_Rw11CntlDEUNA 1 #include +#include #include "librtools/Rtime.hpp" #include "librtools/RtimerFd.hpp" @@ -47,12 +49,16 @@ namespace Retro { void SetRxQueLimit(size_t rxqlim); void SetEtfEnable(bool etfena); void SetEtfTrace(bool etftra); + void SetTxLoss(float txloss); + void SetRxLoss(float txloss); std::string MacDefault() const; const Rtime& RxPollTime() const; size_t RxQueLimit() const; bool EtfEnable() const; bool EtfTrace() const; + float TxLoss() const; + float RxLoss() const; bool Running() const; @@ -248,6 +254,7 @@ namespace Retro { kStatNRxFraQLDrop, kStatNRxFraNRDrop, kStatNRxFraETDrop, + kStatNRxFraLoss, kStatNRxFra, kStatNRxFraMcast, kStatNRxFraBcast, @@ -263,6 +270,7 @@ namespace Retro { kStatNTxBytMcast, kStatNTxFraAbort, kStatNTxFraPad, + kStatNTxFraLoss, kStatNFraLoop, kDimStat }; @@ -364,7 +372,9 @@ namespace Retro { uint64_t fMacList[2+kDimMcast]; //!< MAC list:0=phys,1=bcast,2+=mcast int fMcastCnt; //!< mcast count bool fEtfEnable; //!< EtherType filter enable - bool fEtfTrace; //!< EtherType filter trave + bool fEtfTrace; //!< EtherType filter trace + float fTxLoss; //!< tx loss fraction + float fRxLoss; //!< rx loss fraction uint16_t fPr0Last; //!< last pr0 value bool fPr1Pcto; //!< pr1 pcto flag bool fPr1Delua; //!< pr1 delua flag @@ -405,6 +415,8 @@ namespace Retro { uint32_t fCtrTxBytMcast; //!< ctr: xmit mcast bytes uint32_t fCtrTxFraAbort; //!< ctr: xmit aborted frames uint32_t fCtrFraLoop; //!< ctr: loopback frames + std::default_random_engine fRanEngine; //!< random engine + std::uniform_real_distribution fRanGen; //!< random generator }; } // end namespace Retro diff --git a/tools/src/librw11/Rw11CntlDEUNA.ipp b/tools/src/librw11/Rw11CntlDEUNA.ipp index cf13f334..af1694aa 100644 --- a/tools/src/librw11/Rw11CntlDEUNA.ipp +++ b/tools/src/librw11/Rw11CntlDEUNA.ipp @@ -1,4 +1,4 @@ -// $Id: Rw11CntlDEUNA.ipp 1377 2023-02-21 10:05:30Z mueller $ +// $Id: Rw11CntlDEUNA.ipp 1379 2023-02-24 09:17:23Z mueller $ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright 2017-2023 by Walter F.J. Mueller // @@ -59,6 +59,20 @@ inline bool Rw11CntlDEUNA::EtfTrace() const return fEtfTrace; } +//--------------------------------------+----------------------------------- +//! FIXME_docs +inline float Rw11CntlDEUNA::TxLoss() const +{ + return fTxLoss; +} + +//--------------------------------------+----------------------------------- +//! FIXME_docs +inline float Rw11CntlDEUNA::RxLoss() const +{ + return fRxLoss; +} + //--------------------------------------+----------------------------------- //! FIXME_docs inline bool Rw11CntlDEUNA::Running() const diff --git a/tools/src/librwxxtpp/RtclRw11CntlDEUNA.cpp b/tools/src/librwxxtpp/RtclRw11CntlDEUNA.cpp index 50551386..e1d8d141 100644 --- a/tools/src/librwxxtpp/RtclRw11CntlDEUNA.cpp +++ b/tools/src/librwxxtpp/RtclRw11CntlDEUNA.cpp @@ -1,9 +1,10 @@ -// $Id: RtclRw11CntlDEUNA.cpp 1377 2023-02-21 10:05:30Z mueller $ +// $Id: RtclRw11CntlDEUNA.cpp 1379 2023-02-24 09:17:23Z mueller $ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright 2014-2023 by Walter F.J. Mueller // // Revision History: // Date Rev Version Comment +// 2023-02-24 1379 1.0.4 add simulated tx and rx packet loss mechanism // 2023-02-21 1377 1.0.3 add EtherType filter // 2019-02-23 1114 1.0.2 use std::bind instead of lambda // 2018-12-15 1082 1.0.1 use lambda instead of boost::bind @@ -47,6 +48,8 @@ RtclRw11CntlDEUNA::RtclRw11CntlDEUNA() fGets.Add ("rxqlim", bind(&Rw11CntlDEUNA::RxQueLimit, pobj)); fGets.Add ("etfena", bind(&Rw11CntlDEUNA::EtfEnable, pobj)); fGets.Add ("etftra", bind(&Rw11CntlDEUNA::EtfTrace, pobj)); + fGets.Add ("txloss", bind(&Rw11CntlDEUNA::TxLoss, pobj)); + fGets.Add ("rxloss", bind(&Rw11CntlDEUNA::RxLoss, pobj)); fGets.Add ("run", bind(&Rw11CntlDEUNA::Running, pobj)); fSets.Add ("type", @@ -61,6 +64,10 @@ RtclRw11CntlDEUNA::RtclRw11CntlDEUNA() bind(&Rw11CntlDEUNA::SetEtfEnable,pobj, _1)); fSets.Add ("etftra", bind(&Rw11CntlDEUNA::SetEtfTrace,pobj, _1)); + fSets.Add ("txloss", + bind(&Rw11CntlDEUNA::SetTxLoss,pobj, _1)); + fSets.Add ("rxloss", + bind(&Rw11CntlDEUNA::SetRxLoss,pobj, _1)); } //------------------------------------------+-----------------------------------